mirror of
https://github.com/jlengrand/aswa-mongoose-tutorial.git
synced 2026-03-09 23:51:24 +00:00
Initial commit
This commit is contained in:
5
.vscode/extensions.json
vendored
Normal file
5
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"ms-azuretools.vscode-azurefunctions"
|
||||
]
|
||||
}
|
||||
12
.vscode/launch.json
vendored
Normal file
12
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Attach to Node Functions",
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"port": 9229,
|
||||
"preLaunchTask": "func: host start"
|
||||
}
|
||||
]
|
||||
}
|
||||
8
.vscode/settings.json
vendored
Normal file
8
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"azureFunctions.deploySubpath": "api",
|
||||
"azureFunctions.postDeployTask": "npm install",
|
||||
"azureFunctions.projectLanguage": "JavaScript",
|
||||
"azureFunctions.projectRuntime": "~3",
|
||||
"debug.internalConsoleOptions": "neverOpen",
|
||||
"azureFunctions.preDeployTask": "npm prune"
|
||||
}
|
||||
32
.vscode/tasks.json
vendored
Normal file
32
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "func",
|
||||
"command": "host start",
|
||||
"problemMatcher": "$func-node-watch",
|
||||
"isBackground": true,
|
||||
"dependsOn": "npm install",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/api"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "npm install",
|
||||
"command": "npm install",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/api"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "npm prune",
|
||||
"command": "npm prune --production",
|
||||
"problemMatcher": [],
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/api"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
11
README.md
Normal file
11
README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Static Web Apps - Mongoose starter
|
||||
|
||||
This project is designed to be a starter [Azure Static Web Apps](https://docs.microsoft.com/azure/static-web-apps/overview) with [Mongoose](https://mongoosejs.com/). It uses the following resources:
|
||||
|
||||
- Azure resources
|
||||
- Azure Static Web Apps
|
||||
- Cosmos DB with Mongo API
|
||||
- Application libraries
|
||||
- Vanilla JavaScript
|
||||
- Mongoose
|
||||
- Azure Functions
|
||||
7
api/.funcignore
Normal file
7
api/.funcignore
Normal file
@@ -0,0 +1,7 @@
|
||||
*.js.map
|
||||
*.ts
|
||||
.git*
|
||||
.vscode
|
||||
local.settings.json
|
||||
test
|
||||
tsconfig.json
|
||||
94
api/.gitignore
vendored
Normal file
94
api/.gitignore
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# nuxt.js build output
|
||||
.nuxt
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TypeScript output
|
||||
dist
|
||||
out
|
||||
|
||||
# Azure Functions artifacts
|
||||
bin
|
||||
obj
|
||||
appsettings.json
|
||||
local.settings.json
|
||||
15
api/host.json
Normal file
15
api/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)"
|
||||
}
|
||||
}
|
||||
241
api/package-lock.json
generated
Normal file
241
api/package-lock.json
generated
Normal file
@@ -0,0 +1,241 @@
|
||||
{
|
||||
"name": "api",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"bl": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz",
|
||||
"integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==",
|
||||
"requires": {
|
||||
"readable-stream": "^2.3.5",
|
||||
"safe-buffer": "^5.1.1"
|
||||
}
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
|
||||
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
|
||||
},
|
||||
"bson": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz",
|
||||
"integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg=="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
}
|
||||
}
|
||||
},
|
||||
"denque": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
|
||||
"integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"kareem": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz",
|
||||
"integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw=="
|
||||
},
|
||||
"memory-pager": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
|
||||
"integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
|
||||
"optional": true
|
||||
},
|
||||
"mongodb": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.2.tgz",
|
||||
"integrity": "sha512-sSZOb04w3HcnrrXC82NEh/YGCmBuRgR+C1hZgmmv4L6dBz4BkRse6Y8/q/neXer9i95fKUBbFi4KgeceXmbsOA==",
|
||||
"requires": {
|
||||
"bl": "^2.2.1",
|
||||
"bson": "^1.1.4",
|
||||
"denque": "^1.4.1",
|
||||
"require_optional": "^1.0.1",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"saslprep": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"mongoose": {
|
||||
"version": "5.10.11",
|
||||
"resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.10.11.tgz",
|
||||
"integrity": "sha512-R5BFitKW94/S/Z48w+X+qi/eto66jWBcVEVA8nYVkBoBAPFGq7JSYP/0uso+ZHs+7XjSzTuui+SUllzxIrf9yA==",
|
||||
"requires": {
|
||||
"bson": "^1.1.4",
|
||||
"kareem": "2.3.1",
|
||||
"mongodb": "3.6.2",
|
||||
"mongoose-legacy-pluralize": "1.0.2",
|
||||
"mpath": "0.7.0",
|
||||
"mquery": "3.2.2",
|
||||
"ms": "2.1.2",
|
||||
"regexp-clone": "1.0.0",
|
||||
"safe-buffer": "5.2.1",
|
||||
"sift": "7.0.1",
|
||||
"sliced": "1.0.1"
|
||||
}
|
||||
},
|
||||
"mongoose-legacy-pluralize": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz",
|
||||
"integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
|
||||
},
|
||||
"mpath": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/mpath/-/mpath-0.7.0.tgz",
|
||||
"integrity": "sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg=="
|
||||
},
|
||||
"mquery": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz",
|
||||
"integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==",
|
||||
"requires": {
|
||||
"bluebird": "3.5.1",
|
||||
"debug": "3.1.0",
|
||||
"regexp-clone": "^1.0.0",
|
||||
"safe-buffer": "5.1.2",
|
||||
"sliced": "1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"regexp-clone": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz",
|
||||
"integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw=="
|
||||
},
|
||||
"require_optional": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
|
||||
"integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
|
||||
"requires": {
|
||||
"resolve-from": "^2.0.0",
|
||||
"semver": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"resolve-from": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
|
||||
"integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
|
||||
},
|
||||
"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=="
|
||||
},
|
||||
"saslprep": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
|
||||
"integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"sparse-bitfield": "^3.0.3"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
|
||||
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
|
||||
},
|
||||
"sift": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz",
|
||||
"integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g=="
|
||||
},
|
||||
"sliced": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
|
||||
"integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
|
||||
},
|
||||
"sparse-bitfield": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
|
||||
"integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"memory-pager": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
}
|
||||
}
|
||||
}
|
||||
13
api/package.json
Normal file
13
api/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "api",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {
|
||||
"start": "func start",
|
||||
"test": "echo \"No tests yet...\""
|
||||
},
|
||||
"dependencies": {
|
||||
"mongoose": "^5.10.11"
|
||||
},
|
||||
"devDependencies": {}
|
||||
}
|
||||
4
api/proxies.json
Normal file
4
api/proxies.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/proxies",
|
||||
"proxies": {}
|
||||
}
|
||||
21
api/tasks/function.json
Normal file
21
api/tasks/function.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"bindings": [
|
||||
{
|
||||
"authLevel": "anonymous",
|
||||
"type": "httpTrigger",
|
||||
"direction": "in",
|
||||
"name": "req",
|
||||
"methods": [
|
||||
"get",
|
||||
"post",
|
||||
"put"
|
||||
],
|
||||
"route": "tasks/{id?}"
|
||||
},
|
||||
{
|
||||
"type": "http",
|
||||
"direction": "out",
|
||||
"name": "res"
|
||||
}
|
||||
]
|
||||
}
|
||||
88
api/tasks/index.js
Normal file
88
api/tasks/index.js
Normal file
@@ -0,0 +1,88 @@
|
||||
// Load mongoose
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
// Connect to the database
|
||||
mongoose.connect(
|
||||
process.env.CONNECTION_STRING, // Retrieve connection string
|
||||
{ // boiler plate values
|
||||
useNewUrlParser: true,
|
||||
useUnifiedTopology: true,
|
||||
}
|
||||
);
|
||||
|
||||
// Create the schema or structure of our object in Mongoose
|
||||
const taskSchema = new mongoose.Schema({
|
||||
title: String, // Add title property of type string
|
||||
completed: { // Add completed property
|
||||
type: Boolean, // Set type to boolean
|
||||
default: false // Set default to false
|
||||
}
|
||||
});
|
||||
|
||||
// Create a model using our schema
|
||||
// This model will be used to access the database
|
||||
const TaskModel = mongoose.model('task', taskSchema);
|
||||
|
||||
// Export our function
|
||||
module.exports = async function (context, req) {
|
||||
// setup our default content type (we always return JSON)
|
||||
context.res = {
|
||||
header: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
}
|
||||
|
||||
// Read the method and determine the requested action
|
||||
switch (req.method) {
|
||||
// If get, return all tasks
|
||||
case 'GET':
|
||||
await getTasks(context);
|
||||
break;
|
||||
// If post, create new task
|
||||
case 'POST':
|
||||
await createTask(context);
|
||||
break;
|
||||
// If put, update task
|
||||
case 'PUT':
|
||||
await updateTask(context);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// Return all tasks
|
||||
async function getTasks(context) {
|
||||
// load all tasks from database
|
||||
const tasks = await TaskModel.find();
|
||||
// return all tasks
|
||||
context.res.body = { tasks: tasks };
|
||||
}
|
||||
|
||||
// Create new task
|
||||
async function createTask(context) {
|
||||
// Read the uploaded task
|
||||
const body = context.req.body;
|
||||
// Save to database
|
||||
const task = await TaskModel.create(body);
|
||||
// Set the HTTP status to created
|
||||
context.res.status = 201;
|
||||
// return new object
|
||||
context.res.body = task;
|
||||
}
|
||||
|
||||
// Update an existing function
|
||||
async function updateTask(context) {
|
||||
// Grab the id from the URL (stored in bindingData)
|
||||
const id = context.bindingData.id;
|
||||
// Get the task from the body
|
||||
const task = context.req.body;
|
||||
// Update the item in the database
|
||||
const result = await TaskModel.updateOne({ _id: id }, task);
|
||||
// Check to ensure an item was modified
|
||||
if (result.nModified === 1) {
|
||||
// Updated an item, status 204 (empty update)
|
||||
context.res.status = 204;
|
||||
} else {
|
||||
// Item not found, status 404
|
||||
context.res.status = 404;
|
||||
}
|
||||
}
|
||||
3
api/tasks/sample.dat
Normal file
3
api/tasks/sample.dat
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"name": "Azure"
|
||||
}
|
||||
12
public/index.css
Normal file
12
public/index.css
Normal file
@@ -0,0 +1,12 @@
|
||||
body {
|
||||
font-family: Verdana, Geneva, Tahoma, sans-serif;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.completed {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
30
public/index.html
Normal file
30
public/index.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>Tasks</title>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<!-- Bootstrap CSS -->
|
||||
<link rel="stylesheet" href="index.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<article>
|
||||
<h1>My tasks</h1>
|
||||
<!-- List for tasks -->
|
||||
<ul id="task-list"></ul>
|
||||
|
||||
<div>
|
||||
<label for="name">Title: </label><input type="text" id="task-title" />
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" id="task-register">Add task</button>
|
||||
</div>
|
||||
</article>
|
||||
<script src="./local-index.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
135
public/local-index.js
Normal file
135
public/local-index.js
Normal file
@@ -0,0 +1,135 @@
|
||||
// run the code
|
||||
main();
|
||||
|
||||
// stores all tasks
|
||||
const tasks = [];
|
||||
|
||||
// entry function
|
||||
async function main() {
|
||||
await loadTasks();
|
||||
displayTasks();
|
||||
}
|
||||
|
||||
// Calls server to retrieve all tasks
|
||||
async function loadTasks() {
|
||||
try {
|
||||
// Uses fetch to call server
|
||||
const response = await fetch('/api/tasks');
|
||||
// Reads returned JSON, which contains one property called tasks
|
||||
const retrievedData = await response.json();
|
||||
// Retrieve tasks, which contains an array of all tasks in database
|
||||
const retrievedTasks = retrievedData.tasks;
|
||||
// Loop through all tasks
|
||||
for (let task of retrievedTasks) {
|
||||
// Add each task to the array
|
||||
tasks.push(task);
|
||||
}
|
||||
} catch {
|
||||
// If there is an error, display a generic message on the page
|
||||
const messageElement = document.createElement('li');
|
||||
messageElement.innerHTML = "Could not pull data. Make sure you've <a href='https://github.com/geektrainer/aswa-starter/docs/add-database.md'>configured the database</a>."
|
||||
document.getElementById('task-list').appendChild(messageElement);
|
||||
}
|
||||
}
|
||||
|
||||
// Displays all tasks on page (called on load)
|
||||
function displayTasks() {
|
||||
// Loop through all tasks in the local array
|
||||
for (let task of tasks) {
|
||||
// Call helper function to add to UI
|
||||
addTaskToDisplay(task);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to add task to UI
|
||||
function addTaskToDisplay(task) {
|
||||
// Create li element to store task display
|
||||
const taskElement = document.createElement('li');
|
||||
|
||||
// create checkbox
|
||||
const taskCompleteCheckbox = document.createElement('input');
|
||||
taskCompleteCheckbox.type = 'checkbox';
|
||||
// Set the ID of the checkbox to the id of the task
|
||||
taskCompleteCheckbox.id = task._id;
|
||||
// Set the checked property to the completion status of the task
|
||||
// (Completed tasks will be checked)
|
||||
taskCompleteCheckbox.checked = task.completed;
|
||||
// Add event handler to each item for clicking on the checkbox
|
||||
// When the checkbox is clicked, we will make a server call to toggle completed
|
||||
taskCompleteCheckbox.addEventListener('change', updateTask);
|
||||
// Add checkbox to li created earlier
|
||||
taskElement.appendChild(taskCompleteCheckbox);
|
||||
|
||||
// Create label for the task
|
||||
const taskLabel = document.createElement('label');
|
||||
// Set the for attribute so the checkbox is toggled when the label is clicked
|
||||
taskLabel.setAttribute('for', task._id);
|
||||
// Set the text to the title of the task
|
||||
taskLabel.innerText = task.title;
|
||||
// Set the completed CSS class if the task is completed
|
||||
taskLabel.className = task.completed ? 'completed' : '';
|
||||
// Add the label to the end of the li element
|
||||
taskElement.appendChild(taskLabel);
|
||||
|
||||
// Get the ul element from the page
|
||||
const taskListElement = document.getElementById('task-list');
|
||||
// Add the new task to the list on the page
|
||||
taskListElement.appendChild(taskElement);
|
||||
}
|
||||
|
||||
// Event listener for checkbox change
|
||||
async function updateTask(e) {
|
||||
// Get the ID of the task
|
||||
const taskId = e.target.id;
|
||||
|
||||
// Find the task from the array
|
||||
const task = tasks.find(t => t._id === taskId);
|
||||
// If no task is found (shouldn't happen), just return
|
||||
if (!task) return;
|
||||
// Toggle completed status
|
||||
task.completed = !task.completed;
|
||||
|
||||
// Get the label for the task, which contains the string
|
||||
// We find this by using nextSibling
|
||||
// It is next to the checkbox, which is in e.target
|
||||
const taskLabel = e.target.nextSibling;
|
||||
// Set the class for the task based on completed status
|
||||
taskLabel.className = task.completed ? 'completed' : '';
|
||||
// Call the server to save the changes
|
||||
await fetch(
|
||||
`/api/tasks/${taskId}`, // URL of the API
|
||||
{
|
||||
method: 'PUT', // method to modify items
|
||||
body: JSON.stringify(task), // put task in body
|
||||
headers: {
|
||||
'Content-Type': 'application/json' // indicate return type of JSON
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Event listener for new tasks being created
|
||||
document.getElementById('task-register').addEventListener('click', async () => {
|
||||
// Create task by retrieving text from textbox
|
||||
const task = {
|
||||
title: document.getElementById('task-title').value
|
||||
};
|
||||
// Call server
|
||||
const response = await fetch(
|
||||
'/api/tasks', // API location
|
||||
{
|
||||
method: 'POST', // POST to create new item
|
||||
body: JSON.stringify(task), // Add task to body
|
||||
headers: {
|
||||
'Content-Type': 'application/json' // Set return type to JSON
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Get the task returned from the server (it will have a new id)
|
||||
const loadedTask = await response.json();
|
||||
// Add the task to the array for local storage
|
||||
tasks.push(loadedTask);
|
||||
// Add the new task to the display
|
||||
addTaskToDisplay(loadedTask);
|
||||
});
|
||||
Reference in New Issue
Block a user