diff --git a/package-lock.json b/package-lock.json index 56057f1..1e0c017 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,8 @@ "name": "azure-functions-prototype", "version": "1.0.0", "dependencies": { - "@azure/functions": "^4.0.0-alpha.2" + "@azure/functions": "^4.0.0-alpha.2", + "durable-functions": "^2.0.2" }, "devDependencies": { "@types/chai": "^4.0.0", @@ -119,6 +120,14 @@ "node": "*" } }, + "node_modules/axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "dependencies": { + "follow-redirects": "^1.14.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -347,6 +356,50 @@ "node": ">=0.3.1" } }, + "node_modules/durable-functions": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/durable-functions/-/durable-functions-2.0.2.tgz", + "integrity": "sha512-DKJ8mDvTDdZ6Ej4h6Oa+tbxawNLPpQjBEIvTkxBkeUMdfSyJn9LSCRRUwnVxdhwB9LAE2dUgsrN5wZUzAN27Hg==", + "dependencies": { + "@azure/functions": "^1.2.3", + "axios": "^0.21.1", + "debug": "~2.6.9", + "lodash": "^4.17.15", + "moment": "^2.29.2", + "uuid": "~3.3.2", + "validator": "~13.7.0" + }, + "engines": { + "node": ">=6.5.0" + } + }, + "node_modules/durable-functions/node_modules/@azure/functions": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@azure/functions/-/functions-1.2.3.tgz", + "integrity": "sha512-dZITbYPNg6ay6ngcCOjRUh1wDhlFITS0zIkqplyH5KfKEAVPooaoaye5mUFnR+WP9WdGRjlNXyl/y2tgWKHcRg==" + }, + "node_modules/durable-functions/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/durable-functions/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/durable-functions/node_modules/uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -411,6 +464,25 @@ "flat": "cli.js" } }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -1179,6 +1251,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -1264,6 +1341,14 @@ "url": "https://opencollective.com/mochajs" } }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -1539,6 +1624,14 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -1726,6 +1819,14 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, + "axios": { + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", + "requires": { + "follow-redirects": "^1.14.0" + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1897,6 +1998,45 @@ "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, + "durable-functions": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/durable-functions/-/durable-functions-2.0.2.tgz", + "integrity": "sha512-DKJ8mDvTDdZ6Ej4h6Oa+tbxawNLPpQjBEIvTkxBkeUMdfSyJn9LSCRRUwnVxdhwB9LAE2dUgsrN5wZUzAN27Hg==", + "requires": { + "@azure/functions": "^1.2.3", + "axios": "^0.21.1", + "debug": "~2.6.9", + "lodash": "^4.17.15", + "moment": "^2.29.2", + "uuid": "~3.3.2", + "validator": "~13.7.0" + }, + "dependencies": { + "@azure/functions": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@azure/functions/-/functions-1.2.3.tgz", + "integrity": "sha512-dZITbYPNg6ay6ngcCOjRUh1wDhlFITS0zIkqplyH5KfKEAVPooaoaye5mUFnR+WP9WdGRjlNXyl/y2tgWKHcRg==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" + } + } + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -1940,6 +2080,11 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, "fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -2552,6 +2697,11 @@ "p-locate": "^5.0.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "log-symbols": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", @@ -2617,6 +2767,11 @@ "yargs-unparser": "2.0.0" } }, + "moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -2796,6 +2951,11 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, + "validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==" + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 0406c62..3513b6a 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,17 @@ "test": "mocha 'dist/test/**/*.test.js'" }, "dependencies": { - "@azure/functions": "^4.0.0-alpha.2" + "@azure/functions": "^4.0.0-alpha.2", + "durable-functions": "^2.0.2" }, "devDependencies": { "@types/chai": "^4.0.0", "@types/mocha": "^9.0.0", "@types/node": "^18.0.0", "chai": "^4.0.0", + "func-cli-nodejs-v4": "4.0.4764", "mocha": "^9.0.0", - "typescript": "^4.0.0", - "func-cli-nodejs-v4": "4.0.4764" + "typescript": "^4.0.0" }, "main": "dist/src/index.js" -} \ No newline at end of file +} diff --git a/src/functions/durable-generic.ts b/src/functions/durable-generic.ts new file mode 100644 index 0000000..08b8642 --- /dev/null +++ b/src/functions/durable-generic.ts @@ -0,0 +1,51 @@ +import { app, HttpRequest, input, InvocationContext, trigger } from "@azure/functions"; +import * as df from "durable-functions"; + +app.generic('DurableFunctionsOrchestratorJS', { + trigger: trigger.generic({ + type: 'orchestrationTrigger' + }), + handler: df.orchestrator(function* (context) { + const outputs = []; + outputs.push(yield context.df.callActivity("Hello", "Tokyo")); + outputs.push(yield context.df.callActivity("Hello", "Seattle")); + outputs.push(yield context.df.callActivity("Hello", "Cairo")); + + return outputs; + }) +}) + +app.generic('Hello', { + trigger: trigger.generic({ + type: 'activityTrigger', + }), + handler: async function(context: InvocationContext, name: string): Promise { + return `Hello ${name}` + } +}) + +const clientInput = input.generic({ + type: 'orchestrationClient' +}); + +app.generic('DurableFunctionsHttpStart', { + trigger: trigger.generic({ + type: 'httpTrigger', + authLevel: 'function', + route: 'orchestrators/{functionName}', + methods: [ + 'post', 'get' + ], + }), + extraInputs: [clientInput], + return: {name: "$return", type:'http'}, + handler: async function (context: InvocationContext, req: HttpRequest): Promise { + // @ts-expect-error: whatever + const client = df.getClient(context, clientInput); + const instanceId = await client.startNew(req.params.functionName, undefined, req.body); + + context.log(`Started orchestration with ID = '${instanceId}'.`); + + return client.createCheckStatusResponse(req, instanceId); + } +}) \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index d3f5ca2..49a8c8c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,7 +13,5 @@ app.timer('timerTrigger1', { handler: (context: InvocationContext, myTimer: Timer) => { var timeStamp = new Date().toISOString(); context.log('The current time is: ', timeStamp); - } -}); - - + } +}); \ No newline at end of file