This commit is contained in:
Sameer Doshi 2021-10-19 10:58:34 -05:00
Родитель 42683c9403
Коммит 3229a02754
35 изменённых файлов: 28766 добавлений и 10 удалений

159
README.md
Просмотреть файл

@ -1,16 +1,155 @@
# Project # React / GraphQL / NoSQL Starter-Kit
Create a modern web app with modern middle ware, and a modern backend. For less than $1 / month you can run this app with:
* A Custom Domain
* SSL
* Authentication
> This repo has been populated by an initial template to help get you started. Please [Jump to < 2 step quickstart>](quickstart)
> make sure to update the content to build a great experience for community-building.
As the maintainer of this project, please make a few updates: # Quickstart
## Prereqs
* [npm](https://nodejs.org/en/download)
* functions tool kit ([windows](https://go.microsoft.com/fwlink/?linkid=2174087),[Linux](https://go.microsoft.com/fwlink/?linkid=2174087),[mac](https://go.microsoft.com/fwlink/?linkid=2174087))
* [visual studio code](https://code.visualstudio.com/Download)
- Improving this README.MD file to provide a great experience ## Start Local
- Updating SUPPORT.MD with content about this project's support experience 1. Fork this repo
- Understanding the security reporting process in SECURITY.MD 2. Clone the repo
- Remove this section from the README 3. Start the react app:
```
cd react-app
npm start
```
4. Start the GraphQL Service
```
cd graphql
func start
```
## Contributing 5. edit away! ([see detailed explanation of app](detailed description))
## Transition to the Cloud
### Run front end and graphql in the cloud (Free)
1. Follow this [quickstart to deploy an Azure Static Site](https://docs.microsoft.com/en-us/azure/static-web-apps/get-started-portal?tabs=vanilla-javascript#create-a-static-web-app)
2. After completing the above, whenever you push to main your code will be auto-deployed to the cloud!
### Run backend (nosql) in the cloud
1. Follow [this quickstart to create a Cosmos DB](https://docs.microsoft.com/en-us/azure/cosmos-db/sql/create-cosmosdb-resources-portal) For low use, or just getting started a "serverless" Cosmos will be adequate and cost pennies per month.
2. Once done copy the connection string for this Azure Cosmos DB
3. Set up to use Cosmos DB from local dev: add connection string to graphql\local.settings.json ex:
```json
{
"IsEncrypted": false,
"Values": {
"cosmos":"<your connection string",
"FUNCTIONS_WORKER_RUNTIME": "node",
"AzureWebJobsStorage": "UseDevelopmentStorage=true"
}
}
```
4. Set up to use Cosmos DB from cloud: open your Azure Static Website in the Azure Portal and click on Configuration. Add an app setting named cosmos with a value of the connection string.
## Scale up in the Cloud
1. [Add a custom domain to your static site]()
2. Increase throughput of Azure Cosmos DB:
3. Add additional indexes to Azure Cosmos DB:
# Maturity Model
## How It Starts
* Develop 100% locally
* Customize your front-end
* Use a file "JSON backend"
* Customize your GraphQL schema
## How it matures
* Setup Continuous Deployment
* Host for free in the cloud (with SSL)
* Continue using a file-based backend
OR
* Transition to a No-SQL backend
## How it Ends
(optional)
* Use a custom domain name
* Scale cloud hosting to meet demand
* Scale nosql to scale backend
Your app can then be scaled up to support
* Thousands of users
* Global distribution
* Scaled up security
* Additional backeds
This is a starter kit. It shows you how to create and deploy the basic platform. You'll need to adapt the a] to include your won code to solve your specific task. Depending on the complexity of your app, or use of other Azure service it might cost you more than $1 to run this app.
## How to Use
You can run this app locally or in Azure. Typically you will need to do the following:
1. Develop your own GraphQL Schmea
2. Modify the React APP buisness logic.
3. Modify the React APP UI/UX.
4. Modify NoSQL index properties
5. Modify NoSQL queries to reduce operations
## What is this?
# Detailed Description
## React App
This is a Create React App with only Functional components.
It uses:
* Apollo Client: to execute graphql queiries and mutations
* React Router: to select which component to render
* React Bootsrap: as a UI Library
URL: http://localhost:3000
## GraphQL
This app uses Apollo GraphQL server.
Schmea from graphql/schema.js
Datasources/HardcodedAPI.js or datasources/CosmosAPI.js. It selects Cosmos is local.settings.json or an app setting contains cosmos.
Resolvers: are coded into index.js
CORS: by default the app also sends cors headers in non prod environments (so that localhost:3000 can access data)
Playground: Prod: DISABLED. Local: http://localhost:7071/api/graphql
## NoSQL
If you have not setup CosmosDB yet then graphql\datasources\HardCodedAPI.js is used as a datasrouce
At the top of the file is the const that defines the data.
### Notes
1. You'll need to index the 'posted' field in order to use the ORDER DESC
# What do I do now?
# Refernce Links
* [Azure Static Web Apps](https://azure.microsoft.com/en-us/services/app-service/static/)
* [Apollo Server](https://www.apollographql.com/docs/apollo-server/getting-started/)
* [Cosmos DB](https://azure.microsoft.com/en-us/services/cosmos-db/)
# Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
@ -24,7 +163,7 @@ This project has adopted the [Microsoft Open Source Code of Conduct](https://ope
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Trademarks # Trademarks
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
trademarks or logos is subject to and must follow trademarks or logos is subject to and must follow

43
graphql/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,43 @@
bin
obj
csx
.vs
edge
Publish
*.user
*.suo
*.cscfg
*.Cache
project.lock.json
/packages
/TestResults
/tools/NuGet.exe
/App_Data
/secrets
/data
.secrets
appsettings.json
local.settings.json
node_modules
dist
# Local python packages
.python_packages/
# Python Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

Просмотреть файл

@ -0,0 +1,50 @@
const { CosmosDataSource } =require('apollo-datasource-cosmosdb');
const { nanoid } = require('nanoid');
class CosmosAPI extends CosmosDataSource {
async getAllItems(){
let {resources} = await this.findManyByQuery(
{
query: `SELECT * FROM c`,
});
return resources;
}
async getAllITaggedtems(tagname) {
let {resources} = await this.findManyByQuery(
{
query: `SELECT * FROM c WHERE c.tag = @tagName `,
parameters: [{ name: "@tagName", value: tagname }],
});
return resources;
}
async getItemById(id){
return this.findOneById(id);
}
async updateItem(item){
const { resource } = await this.getCollection().item(item.id, item.tag).read();
if (!resource) return false;
resource.title=item.title;
resource.text=item.text;
resource.imgurl=item.imgurl;
let {resource: replaced } = await this.geCollection()
.item(item.id, item.tag)
.replace(resource);
if(!replaced) return false;
return true;
}
async addNewItem(newitem){
newitem.id=nanoid();
let {resource: createdItem} = await this.getCollection()
.items.create(newitem);
return createdItem.id;
}
}
module.exports = CosmosAPI;

Просмотреть файл

@ -0,0 +1,49 @@
const { DataSource, DataSourceConfig } = require('apollo-datasource');
const hardcodedItems=[
{ tag:"random", id:"abd",title:"First Item",text:"This is some text", imgurl:"",posted:"2021-12-10"},
{ tag:"random", id:"babd",title:"Second Item",text:"More random text", imgurl:"",posted:"2021-12-11"},
{ tag:"article", id:"cabd",title:"Check out this great site",text:"Lots of good information here: https://docs.microsoft.com ", imgurl:"",posted:"2021-12-12"},
{ tag:"article", id:"dabd",title:"Put your source code here",text:"Migrate your code to https://github.com", imgurl:"",posted:"2021-12-13"},
];
class CosmosAPI extends DataSource {
async getAllItems(){
return hardcodedItems;
}
async getAllTaggedItems(tagname) {
let items = [];
hardcodedItems.map((i) => {
if (i.tag === tagname) {
items.push(i);
}
});
return items;
}
async getItemById(id){
let item=null;
hardcodedItems.map((i) => {
if (i.id === id) {
item=i;
}
});
return item;
}
async updateItem(item){
return true;
}
async addNewItem(newitem){
return "abcde";
}
}
module.exports = CosmosAPI;

Просмотреть файл

@ -0,0 +1,19 @@
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post",
"options"
]
},
{
"type": "http",
"direction": "out",
"name": "$return" }
]
}

43
graphql/graphql/index.js Normal file
Просмотреть файл

@ -0,0 +1,43 @@
const { ApolloServer } = require("apollo-server-azure-functions");
const typeDefs = require('./schema');
const resolvers = {
Query: {
hello: () => "Hello world",
getAllItems:(_,{},{dataSources})=>dataSources.cosmosAPI.getAllItems(),
getAllTaggedItems: (_,{tag},{dataSources})=>dataSources.cosmosAPI.getAllTaggedItems(tag),
getItemByID:(_,{id },{dataSources})=> dataSources.cosmosAPI.getItemByID(id),
},
Mutation:{
addNewItem:(_,{tag,text, title, imgurl},{dataSources}) => dataSources.cosmosAPI.addNewItem({tag:tag,text:text ,title:title,imgurl:imgurl}),
updateItem:(_,{id,tag,text, title, imgurl},{dataSources}) => dataSources.cosmosAPI.updateItem({id:id,tag:tag,text:text ,title:title,imgurl:imgurl}),
}
};
const dsFile= process.env.cosmos ?'CosmosAPI' : 'HardcodedAPI';
const CosmosAPI = require('./datasources/'+dsFile);
const server = new ApolloServer(
{ typeDefs,
dataSources: () => {
let cc=new CosmosAPI();
if( process.env.cosmos){
const cosmosClient = new CosmosClient(process.env.cosmosConnStr);
const cosmosContainer = cosmosClient.database(process.env.cosmosDBName).container(process.env.cosmosContainerName);
cc=new CosmosAPI(cosmosContainer);
}
return { cosmosAPI: cc };
},
resolvers,
introspection: (process.env.NODE_ENV !== 'production'),
playground: (process.env.NODE_ENV !== 'production'),
});
cors=(process.env.NODE_ENV !== 'production') ? {
cors: {
origin: 'http://localhost:3000',
allowedHeaders:['Content-Type', 'Authorization']
}} :{};
exports.graphqlHandler = server.createHandler(cors);

38
graphql/graphql/schema.js Normal file
Просмотреть файл

@ -0,0 +1,38 @@
const { gql } = require('apollo-server-azure-functions');
const typeDefs = gql`
type Item {
id: ID
tag: String
title: String
draft: Boolean
text: String
posted: String
imgurl: String
}
type Query {
hello: String
getItemByID(id:String): Item
getAllItems:[Item]
getAllTaggedItems(tag:String):[Item]
}
type Mutation {
addNewItem(
tag: String
title: String
text: String
imgurl: String
): String
updateItem(
id: ID
tag: String
title: String
text: String
imgurl: String
):Boolean
}
`;
module.exports = typeDefs;

15
graphql/host.json Normal file
Просмотреть файл

@ -0,0 +1,15 @@
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}
}

785
graphql/package-lock.json сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,785 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"@apollo/protobufjs": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.2.tgz",
"integrity": "sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==",
"requires": {
"@protobufjs/aspromise": "^1.1.2",
"@protobufjs/base64": "^1.1.2",
"@protobufjs/codegen": "^2.0.4",
"@protobufjs/eventemitter": "^1.1.0",
"@protobufjs/fetch": "^1.1.0",
"@protobufjs/float": "^1.0.2",
"@protobufjs/inquire": "^1.1.0",
"@protobufjs/path": "^1.1.2",
"@protobufjs/pool": "^1.1.0",
"@protobufjs/utf8": "^1.1.0",
"@types/long": "^4.0.0",
"@types/node": "^10.1.0",
"long": "^4.0.0"
}
},
"@apollographql/apollo-tools": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/@apollographql/apollo-tools/-/apollo-tools-0.5.1.tgz",
"integrity": "sha512-ZII+/xUFfb9ezDU2gad114+zScxVFMVlZ91f8fGApMzlS1kkqoyLnC4AJaQ1Ya/X+b63I20B4Gd+eCL8QuB4sA=="
},
"@apollographql/graphql-playground-html": {
"version": "1.6.29",
"resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.29.tgz",
"integrity": "sha512-xCcXpoz52rI4ksJSdOCxeOCn2DLocxwHf9dVT/Q90Pte1LX+LY+91SFtJF3KXVHH8kEin+g1KKCQPKBjZJfWNA==",
"requires": {
"xss": "^1.0.8"
}
},
"@azure/functions": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/@azure/functions/-/functions-1.2.3.tgz",
"integrity": "sha512-dZITbYPNg6ay6ngcCOjRUh1wDhlFITS0zIkqplyH5KfKEAVPooaoaye5mUFnR+WP9WdGRjlNXyl/y2tgWKHcRg=="
},
"@graphql-tools/merge": {
"version": "8.1.2",
"resolved": "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.1.2.tgz",
"integrity": "sha512-kFLd4kKNJXYXnKIhM8q9zgGAtbLmsy3WmGdDxYq3YHBJUogucAxnivQYyRIseUq37KGmSAIWu3pBQ23TKGsGOw==",
"requires": {
"@graphql-tools/utils": "^8.2.2",
"tslib": "~2.3.0"
}
},
"@graphql-tools/mock": {
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/@graphql-tools/mock/-/mock-8.4.0.tgz",
"integrity": "sha512-RKcqmw7P5pC2ULh2/kg/erxxsd7lEV/wnI5jNgahkCw8wiSC8OI3SwNMwjfrlpYogs7eEhiXi7Ix6abCiFUURw==",
"requires": {
"@graphql-tools/schema": "^8.2.0",
"@graphql-tools/utils": "^8.2.3",
"fast-json-stable-stringify": "^2.1.0",
"tslib": "~2.3.0"
}
},
"@graphql-tools/schema": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.2.0.tgz",
"integrity": "sha512-ufmI5mJQa8NJczzfkh0pUttKvspqDcT5LLakA3jUmOrrE4d4NVj6onZlazdTzF5sAepSNqanFnwhrxZpCAJMKg==",
"requires": {
"@graphql-tools/merge": "^8.1.0",
"@graphql-tools/utils": "^8.2.0",
"tslib": "~2.3.0",
"value-or-promise": "1.0.10"
}
},
"@graphql-tools/utils": {
"version": "8.2.5",
"resolved": "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.2.5.tgz",
"integrity": "sha512-k/Rktklhy22dQfbJLKiLGfQymQCTr6Rd2BilC7g2Yk6wFSzVLYr8jeXNoTD+/p61XBQzBjTVayskvaMvNS3BDg==",
"requires": {
"tslib": "~2.3.0"
}
},
"@josephg/resolvable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz",
"integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg=="
},
"@protobufjs/aspromise": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
"integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
},
"@protobufjs/base64": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
"integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
},
"@protobufjs/codegen": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
"integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
},
"@protobufjs/eventemitter": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
"integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
},
"@protobufjs/fetch": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
"integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
"requires": {
"@protobufjs/aspromise": "^1.1.1",
"@protobufjs/inquire": "^1.1.0"
}
},
"@protobufjs/float": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
"integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
},
"@protobufjs/inquire": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
"integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
},
"@protobufjs/path": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
"integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
},
"@protobufjs/pool": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
"integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
},
"@protobufjs/utf8": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
"integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
},
"@types/long": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
"integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
},
"@types/node": {
"version": "10.17.60",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
"integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="
},
"apollo-datasource": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-3.1.0.tgz",
"integrity": "sha512-ywcVjuWNo84eMB9uBOYygQI+00+Ne4ShyPIxJzT//sn1j1Fu3J+KStMNd6s1jyERWgjGZzxkiLn6nLmwsGymBg==",
"requires": {
"apollo-server-caching": "^3.1.0",
"apollo-server-env": "^4.0.3"
}
},
"apollo-datasource-cosmosdb": {
"version": "0.0.17",
"resolved": "https://registry.npmjs.org/apollo-datasource-cosmosdb/-/apollo-datasource-cosmosdb-0.0.17.tgz",
"integrity": "sha512-vrlrHXXgibn75s8gpeGxAsttW7hojl/evJGNb5qLZbvgyZxOpoU57M62hnyRbxxzDy0TBwlI0hz+Xnp9N/1NIQ==",
"requires": {
"apollo-datasource": "0.7.3",
"apollo-server-caching": "0.5.3",
"apollo-server-errors": "2.4.2",
"bson": "4.2.2",
"dataloader": "2.0.0"
},
"dependencies": {
"apollo-datasource": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.7.3.tgz",
"integrity": "sha512-PE0ucdZYjHjUyXrFWRwT02yLcx2DACsZ0jm1Mp/0m/I9nZu/fEkvJxfsryXB6JndpmQO77gQHixf/xGCN976kA==",
"requires": {
"apollo-server-caching": "^0.5.3",
"apollo-server-env": "^3.0.0"
}
},
"apollo-server-caching": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.5.3.tgz",
"integrity": "sha512-iMi3087iphDAI0U2iSBE9qtx9kQoMMEWr6w+LwXruBD95ek9DWyj7OeC2U/ngLjRsXM43DoBDXlu7R+uMjahrQ==",
"requires": {
"lru-cache": "^6.0.0"
}
},
"apollo-server-env": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-3.1.0.tgz",
"integrity": "sha512-iGdZgEOAuVop3vb0F2J3+kaBVi4caMoxefHosxmgzAbbSpvWehB8Y1QiSyyMeouYC38XNVk5wnZl+jdGSsWsIQ==",
"requires": {
"node-fetch": "^2.6.1",
"util.promisify": "^1.0.0"
}
},
"apollo-server-errors": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.4.2.tgz",
"integrity": "sha512-FeGxW3Batn6sUtX3OVVUm7o56EgjxDlmgpTLNyWcLb0j6P8mw9oLNyAm3B+deHA4KNdNHO5BmHS2g1SJYjqPCQ=="
}
}
},
"apollo-graphql": {
"version": "0.9.3",
"resolved": "https://registry.npmjs.org/apollo-graphql/-/apollo-graphql-0.9.3.tgz",
"integrity": "sha512-rcAl2E841Iko4kSzj4Pt3PRBitmyq1MvoEmpl04TQSpGnoVgl1E/ZXuLBYxMTSnEAm7umn2IsoY+c6Ll9U/10A==",
"requires": {
"core-js-pure": "^3.10.2",
"lodash.sortby": "^4.7.0",
"sha.js": "^2.4.11"
}
},
"apollo-reporting-protobuf": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/apollo-reporting-protobuf/-/apollo-reporting-protobuf-3.0.0.tgz",
"integrity": "sha512-jmCD+6gECt8KS7PxP460hztT/5URTbv2Kg0zgnR6iWPGce88IBmSUjcqf1Z6wJJq7Teb8Hu7WbyyMhn0vN5TxQ==",
"requires": {
"@apollo/protobufjs": "1.2.2"
}
},
"apollo-server-azure-functions": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/apollo-server-azure-functions/-/apollo-server-azure-functions-3.3.0.tgz",
"integrity": "sha512-mpqhAESA7b4hfC7/0AV2X9k3Uw2LHTSRHLLCqGF0yrpqlHxDtz5IDkrnGzUTgJ1Fb0FG+2byZE/b9s89mXRp6Q==",
"requires": {
"@azure/functions": "1.2.3",
"apollo-server-core": "^3.3.0",
"apollo-server-env": "^4.0.3",
"apollo-server-types": "^3.2.0"
}
},
"apollo-server-caching": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-3.1.0.tgz",
"integrity": "sha512-bZ4bo0kSAsax9LbMQPlpuMTkQ657idF2ehOYe4Iw+8vj7vfAYa39Ii9IlaVAFMC1FxCYzLNFz+leZBm/Stn/NA==",
"requires": {
"lru-cache": "^6.0.0"
}
},
"apollo-server-core": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-3.3.0.tgz",
"integrity": "sha512-KmkzKVG3yjybouDyUX6Melv39u1EOFipvAKP17IlPis/TjVbubJmb6hkE0am/g2RipyhRvlpxAjHqPaCTXR1dQ==",
"requires": {
"@apollographql/apollo-tools": "^0.5.1",
"@apollographql/graphql-playground-html": "1.6.29",
"@graphql-tools/mock": "^8.1.2",
"@graphql-tools/schema": "^8.0.0",
"@graphql-tools/utils": "^8.0.0",
"@josephg/resolvable": "^1.0.0",
"apollo-datasource": "^3.1.0",
"apollo-graphql": "^0.9.0",
"apollo-reporting-protobuf": "^3.0.0",
"apollo-server-caching": "^3.1.0",
"apollo-server-env": "^4.0.3",
"apollo-server-errors": "^3.1.0",
"apollo-server-plugin-base": "^3.2.0",
"apollo-server-types": "^3.2.0",
"async-retry": "^1.2.1",
"fast-json-stable-stringify": "^2.1.0",
"graphql-tag": "^2.11.0",
"loglevel": "^1.6.8",
"lru-cache": "^6.0.0",
"sha.js": "^2.4.11",
"uuid": "^8.0.0"
}
},
"apollo-server-env": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-4.0.3.tgz",
"integrity": "sha512-B32+RUOM4GUJAwnQqQE1mT1BG7+VfW3a0A87Bp3gv/q8iNnhY2BIWe74Qn03pX8n27g3EGVCt0kcBuHhjG5ltA==",
"requires": {
"node-fetch": "^2.6.1"
}
},
"apollo-server-errors": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-3.1.0.tgz",
"integrity": "sha512-bUmobPEvtcBFt+OVHYqD390gacX/Cm5s5OI5gNZho8mYKAA6OjgnRlkm/Lti6NzniXVxEQyD5vjkC6Ox30mGFg=="
},
"apollo-server-plugin-base": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/apollo-server-plugin-base/-/apollo-server-plugin-base-3.2.0.tgz",
"integrity": "sha512-anjyiw79wxU4Cj2bYZFWQqZPjuaZ4mVJvxCoyvkFrNvjPua9dovCOfpng43C5NwdsqJpz78Vqs236eFM2QoeaA==",
"requires": {
"apollo-server-types": "^3.2.0"
}
},
"apollo-server-types": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/apollo-server-types/-/apollo-server-types-3.2.0.tgz",
"integrity": "sha512-Fh7QP84ufDZHbLzoLyyxyzznlW8cpgEZYYkGsS1i36zY4VaAt5OUOp1f+FxWdLGehq0Arwb6D1W7y712IoZ/JQ==",
"requires": {
"apollo-reporting-protobuf": "^3.0.0",
"apollo-server-caching": "^3.1.0",
"apollo-server-env": "^4.0.3"
}
},
"async-retry": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz",
"integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==",
"requires": {
"retry": "0.13.1"
}
},
"azure-function-log-intercept": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/azure-function-log-intercept/-/azure-function-log-intercept-1.0.10.tgz",
"integrity": "sha512-NssHTq2S3P1rZzztpdmny0gDbk7HD5rs7BX2NOxzo0gpUTR8yI28NW3c0HxXM7b/tm5MM1YGLwu6ih5Rd1obtw=="
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"bson": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/bson/-/bson-4.2.2.tgz",
"integrity": "sha512-9fX257PVHAUpiRGmY3356RVWKQxLA73BgjA/x5MGuJkTEMeG7yzjuBrsiFB67EXRJnFVKrbJY9t/M+oElKYktQ==",
"requires": {
"buffer": "^5.6.0"
}
},
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
"requires": {
"function-bind": "^1.1.1",
"get-intrinsic": "^1.0.2"
}
},
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
"core-js-pure": {
"version": "3.18.2",
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.18.2.tgz",
"integrity": "sha512-4hMMLUlZhKJKOWbbGD1/VDUxGPEhEoN/T01k7bx271WiBKCvCfkgPzy0IeRS4PB50p6/N1q/SZL4B/TRsTE5bA=="
},
"cssfilter": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz",
"integrity": "sha1-xtJnJjKi5cg+AT5oZKQs6N79IK4="
},
"dataloader": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.0.0.tgz",
"integrity": "sha512-YzhyDAwA4TaQIhM5go+vCLmU0UikghC/t9DTQYZR2M/UvZ1MdOhPezSDZcjj9uqQJOMqjLcpWtyW2iNINdlatQ=="
},
"define-properties": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
"integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
"requires": {
"object-keys": "^1.0.12"
}
},
"es-abstract": {
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz",
"integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==",
"requires": {
"call-bind": "^1.0.2",
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"get-intrinsic": "^1.1.1",
"get-symbol-description": "^1.0.0",
"has": "^1.0.3",
"has-symbols": "^1.0.2",
"internal-slot": "^1.0.3",
"is-callable": "^1.2.4",
"is-negative-zero": "^2.0.1",
"is-regex": "^1.1.4",
"is-shared-array-buffer": "^1.0.1",
"is-string": "^1.0.7",
"is-weakref": "^1.0.1",
"object-inspect": "^1.11.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.2",
"string.prototype.trimend": "^1.0.4",
"string.prototype.trimstart": "^1.0.4",
"unbox-primitive": "^1.0.1"
}
},
"es-to-primitive": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
"requires": {
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
"is-symbol": "^1.0.2"
}
},
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
"for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
"requires": {
"is-callable": "^1.1.3"
}
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"get-intrinsic": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz",
"integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==",
"requires": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
"has-symbols": "^1.0.1"
}
},
"get-symbol-description": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
"integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
"requires": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.1.1"
}
},
"graphql": {
"version": "15.6.1",
"resolved": "https://registry.npmjs.org/graphql/-/graphql-15.6.1.tgz",
"integrity": "sha512-3i5lu0z6dRvJ48QP9kFxBkJ7h4Kso7PS8eahyTFz5Jm6CvQfLtNIE8LX9N6JLnXTuwR+sIYnXzaWp6anOg0QQw=="
},
"graphql-tag": {
"version": "2.12.5",
"resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.5.tgz",
"integrity": "sha512-5xNhP4063d16Pz3HBtKprutsPrmHZi5IdUGOWRxA2B6VF7BIRGOHZ5WQvDmJXZuPcBg7rYwaFxvQYjqkSdR3TQ==",
"requires": {
"tslib": "^2.1.0"
}
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"requires": {
"function-bind": "^1.1.1"
}
},
"has-bigints": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz",
"integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA=="
},
"has-symbols": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz",
"integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw=="
},
"has-tostringtag": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
"integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
"requires": {
"has-symbols": "^1.0.2"
}
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"internal-slot": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
"integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
"requires": {
"get-intrinsic": "^1.1.0",
"has": "^1.0.3",
"side-channel": "^1.0.4"
}
},
"is-bigint": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
"integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
"requires": {
"has-bigints": "^1.0.1"
}
},
"is-boolean-object": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
"integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
"requires": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
}
},
"is-callable": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz",
"integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w=="
},
"is-date-object": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
"integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
"requires": {
"has-tostringtag": "^1.0.0"
}
},
"is-negative-zero": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
"integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w=="
},
"is-number-object": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz",
"integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==",
"requires": {
"has-tostringtag": "^1.0.0"
}
},
"is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
"requires": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
}
},
"is-shared-array-buffer": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz",
"integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA=="
},
"is-string": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
"integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
"requires": {
"has-tostringtag": "^1.0.0"
}
},
"is-symbol": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
"integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
"requires": {
"has-symbols": "^1.0.2"
}
},
"is-weakref": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz",
"integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==",
"requires": {
"call-bind": "^1.0.0"
}
},
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg="
},
"loglevel": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz",
"integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw=="
},
"long": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
},
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"requires": {
"yallist": "^4.0.0"
}
},
"nanoid": {
"version": "3.1.29",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.29.tgz",
"integrity": "sha512-dW2pUSGZ8ZnCFIlBIA31SV8huOGCHb6OwzVCc7A69rb/a+SgPBwfmLvK5TKQ3INPbRkcI8a/Owo0XbiTNH19wg=="
},
"node-fetch": {
"version": "2.6.5",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz",
"integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==",
"requires": {
"whatwg-url": "^5.0.0"
}
},
"object-inspect": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz",
"integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg=="
},
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
},
"object.assign": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
"integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
"requires": {
"call-bind": "^1.0.0",
"define-properties": "^1.1.3",
"has-symbols": "^1.0.1",
"object-keys": "^1.1.1"
}
},
"object.getownpropertydescriptors": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz",
"integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==",
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3",
"es-abstract": "^1.19.1"
}
},
"retry": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
"integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg=="
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"sha.js": {
"version": "2.4.11",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"requires": {
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
}
},
"side-channel": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
"requires": {
"call-bind": "^1.0.0",
"get-intrinsic": "^1.0.2",
"object-inspect": "^1.9.0"
}
},
"string.prototype.trimend": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz",
"integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==",
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3"
}
},
"string.prototype.trimstart": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz",
"integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==",
"requires": {
"call-bind": "^1.0.2",
"define-properties": "^1.1.3"
}
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
},
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"unbox-primitive": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
"integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==",
"requires": {
"function-bind": "^1.1.1",
"has-bigints": "^1.0.1",
"has-symbols": "^1.0.2",
"which-boxed-primitive": "^1.0.2"
}
},
"util.promisify": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.1.1.tgz",
"integrity": "sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==",
"requires": {
"call-bind": "^1.0.0",
"define-properties": "^1.1.3",
"for-each": "^0.3.3",
"has-symbols": "^1.0.1",
"object.getownpropertydescriptors": "^2.1.1"
}
},
"uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
},
"value-or-promise": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.10.tgz",
"integrity": "sha512-1OwTzvcfXkAfabk60UVr5NdjtjJ0Fg0T5+B1bhxtrOEwSH2fe8y4DnLgoksfCyd8yZCOQQHB0qLMQnwgCjbXLQ=="
},
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
},
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"which-boxed-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
"integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
"requires": {
"is-bigint": "^1.0.1",
"is-boolean-object": "^1.1.0",
"is-number-object": "^1.0.4",
"is-string": "^1.0.5",
"is-symbol": "^1.0.3"
}
},
"xss": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/xss/-/xss-1.0.9.tgz",
"integrity": "sha512-2t7FahYnGJys6DpHLhajusId7R0Pm2yTmuL0GV9+mV0ZlaLSnb2toBmppATfg5sWIhZQGlsTLoecSzya+l4EAQ==",
"requires": {
"commander": "^2.20.3",
"cssfilter": "0.0.10"
}
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
}
}
}

16
graphql/package.json Normal file
Просмотреть файл

@ -0,0 +1,16 @@
{
"name": "",
"version": "",
"description": "",
"scripts": {
"test": "echo \"No tests yet...\""
},
"author": "",
"dependencies": {
"apollo-datasource-cosmosdb": "0.0.17",
"apollo-server-azure-functions": "^3.3.0",
"azure-function-log-intercept": "^1.0.10",
"graphql": "^15.6.1",
"nanoid": "^3.1.29"
}
}

23
react-app/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

70
react-app/README.md Normal file
Просмотреть файл

@ -0,0 +1,70 @@
# Getting Started with Create React App
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
## Available Scripts
In the project directory, you can run:
### `yarn start`
Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
The page will reload if you make edits.\
You will also see any lint errors in the console.
### `yarn test`
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `yarn build`
Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `yarn eject`
**Note: this is a one-way operation. Once you `eject`, you cant go back!**
If you arent satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point youre on your own.
You dont have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldnt feel obligated to use this feature. However we understand that this tool wouldnt be useful if you couldnt customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
### Analyzing the Bundle Size
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
### Making a Progressive Web App
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
### Advanced Configuration
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
### Deployment
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
### `yarn build` fails to minify
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)

15520
react-app/package-lock.json сгенерированный Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

45
react-app/package.json Normal file
Просмотреть файл

@ -0,0 +1,45 @@
{
"name": "react-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@apollo/client": "^3.4.16",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"bootstrap": "^5.1.1",
"graphql": "^15.6.1",
"react": "^17.0.2",
"react-bootstrap": "^2.0.0-rc.0",
"react-dom": "^17.0.2",
"react-router": "^5.2.1",
"react-router-dom": "^5.3.0",
"react-scripts": "4.0.3",
"web-vitals": "^1.0.1"
},
"scripts": {
"startnew": "concurrently --names \"REACT,GRAPHQL\" -c \"bgBlue.bold,bgMagenta.bold\" \"./react-app/react-scripts start\" \"./graphql/func start\"",
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

Двоичные данные
react-app/public/favicon.ico Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.8 KiB

Просмотреть файл

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Двоичные данные
react-app/public/logo192.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.2 KiB

Двоичные данные
react-app/public/logo512.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 9.4 KiB

Просмотреть файл

@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

Просмотреть файл

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

41
react-app/src/App.jsx Normal file
Просмотреть файл

@ -0,0 +1,41 @@
import {
ApolloClient,
createHttpLink,
InMemoryCache,
ApolloProvider,
} from "@apollo/client";
import { setContext } from '@apollo/client/link/context';
import Routing from './components/Routing';
import {Config} from './components/Config';
export default function App() {
const httpLink = createHttpLink({
uri:Config.graphqluri
});
const authLink = setContext((_, { headers }) => {
const token = localStorage.getItem('token');
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
return (
<ApolloProvider client={client}>
<Routing/>
</ApolloProvider>
);
}

Просмотреть файл

@ -0,0 +1,8 @@
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

7
react-app/src/components/Config.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,7 @@
const prod = {
graphqluri: '/api/graphql'
};
const dev = {
graphqluri: 'http://localhost:7071/api/graphql',
};
export const Config = process.env.NODE_ENV === 'development' ? dev: prod;

Просмотреть файл

@ -0,0 +1,8 @@
export default function Footer(){
return(
<footer>
Social Media Links
Company Information
</footer>
);
}

Просмотреть файл

@ -0,0 +1,51 @@
import { useParams } from 'react-router';
import { Spinner , Container } from 'react-bootstrap';
import ItemShort from "./ItemShort";
import { useQuery, gql} from "@apollo/client";
const ALLITEM_QUERY=gql`
query {
items:getAllItems {
title
text posted
id tag imgurl
}
}
`;
const TAGGEDITEMQUERY = gql`
query ($tname:String) {
items:getAllTaggedItems(tag:$tname) {
title
text posted
id tag imgurl
}
}
`;
export default function ItemList() {
let { tname } = useParams();
const QUERY=tname?TAGGEDITEMQUERY:ALLITEM_QUERY;
const { loading, error, data } = useQuery(QUERY,{variables:{tname:"random"}});
if (loading) return (
<Container>
<Spinner animation="border" />
</Container>
);
if (error){
console.log(error) ;
return <p>Error Fetching Items :(</p>;}
let items=data.items.map((i)=>{return (<ItemShort key={i.id} item={i}/>);});;
return(
<Container>
{items}
</Container>
);
}

Просмотреть файл

@ -0,0 +1,26 @@
import {Config} from './Config';
import {Link} from "react-router-dom";
import {Card} from 'react-bootstrap';
export default function ItemShort(props) {
const url="/s/"+props.item.id;
const tagurl="/t/"+props.item.tag;
return(
<Card style={{ width: '18rem' }}>
<Link to={url}>
<Card.Img variant="top" src={props.item.imgurl} />
</Link>
<Card.Link href={tagurl}>
More {props.item.tag}
</Card.Link>
<Card.Body>
<Card.Title>{props.item.title}</Card.Title>
<Card.Text>
{props.item.text}
</Card.Text>
<Card.Link href={url}>Link To This Item</Card.Link>
</Card.Body>
<Card.Footer className="text-muted">{props.item.posted}</Card.Footer>
</Card>
);
}

Просмотреть файл

@ -0,0 +1,30 @@
import SiteMenu from './SiteMenu.jsx';
import ItemList from './ItemList';
import Footer from './Footer';
import {
BrowserRouter as Router,
Switch, Route } from "react-router-dom";
export default function Routing(props) {
return(
<Router>
<SiteMenu/>
<main>
<Switch>
<Route path="/about">
<div>ABOUT Page!</div>
</Route>
<Route path="/submit/:sid?" component={ItemList}/>:""}
<Route path="/i/:sid" component={ItemList}/>
<Route path="/t/:tname" component={ItemList}/>
<Route path="/" component={ItemList}/>
</Switch>
</main>
<Footer/>
</Router>
);
}

Просмотреть файл

@ -0,0 +1,33 @@
import {Nav,NavDropdown , Navbar,Container} from 'react-bootstrap'
export default function SiteMenu(){
return (
<Navbar collapseOnSelect expand="lg" bg="dark" variant="dark">
<Container>
<Navbar.Brand href="/">Azure Lightning Starer-Kit for JS</Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" />
<Navbar.Collapse id="responsive-navbar-nav">
<Nav className="me-auto">
<Nav.Link href="/t/random">Add New Item</Nav.Link>
<Nav.Link href="/t/random">News</Nav.Link>
<NavDropdown title="Getting Started" id="collasible-nav-dropdown">
<NavDropdown.Item href="#action/3.1">GitHub Home</NavDropdown.Item>
<NavDropdown.Item href="#action/3.1">Azure Static WebSites</NavDropdown.Item>
<NavDropdown.Item href="#action/3.1">Azure Cosmos DB</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href="#action/3.2">React Bootstrap</NavDropdown.Item>
<NavDropdown.Item href="#action/3.3">Apollo GraphQL</NavDropdown.Item>
<NavDropdown.Item href="#action/3.2">React Hook Forms</NavDropdown.Item>
</NavDropdown>
</Nav>
<Nav>
<Nav.Link href="#deets">More deets</Nav.Link>
<Nav.Link eventKey={2} href="#memes">
Dank memes
</Nav.Link>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
);
}

13
react-app/src/index.css Normal file
Просмотреть файл

@ -0,0 +1,13 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

17
react-app/src/index.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,17 @@
import React from 'react';
import ReactDOM from 'react-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

1
react-app/src/logo.svg Normal file
Просмотреть файл

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

После

Ширина:  |  Высота:  |  Размер: 2.6 KiB

13
react-app/src/reportWebVitals.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,13 @@
const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

5
react-app/src/setupTests.js поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

11571
react-app/yarn.lock Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

6
staticwebapp.config.json Normal file
Просмотреть файл

@ -0,0 +1,6 @@
{
"navigationFallback": {
"rewrite": "index.html",
"exclude": ["/images/*.{png,jpg,gif}", "/css/*"]
}
}