edge-functions 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +13 -0
- package/.eslintignore +3 -0
- package/.eslintrc.json +42 -0
- package/.github/workflows/major.yml +28 -0
- package/.github/workflows/minor.yml +31 -0
- package/.vscode/settings.json +20 -0
- package/CODEOWNERS +2 -0
- package/CODE_OF_CONDUCT.md +73 -0
- package/CONTRIBUTING.md +90 -0
- package/LICENSE.md +21 -0
- package/README.md +60 -0
- package/aliases.js +13 -0
- package/docs/overview.md +36 -0
- package/docs/presets.md +115 -0
- package/examples/angular-static/.editorconfig +16 -0
- package/examples/angular-static/README.md +27 -0
- package/examples/angular-static/angular.json +98 -0
- package/examples/angular-static/package.json +39 -0
- package/examples/angular-static/src/app/app-routing.module.ts +10 -0
- package/examples/angular-static/src/app/app.component.css +0 -0
- package/examples/angular-static/src/app/app.component.html +484 -0
- package/examples/angular-static/src/app/app.component.spec.ts +29 -0
- package/examples/angular-static/src/app/app.component.ts +10 -0
- package/examples/angular-static/src/app/app.module.ts +18 -0
- package/examples/angular-static/src/assets/.gitkeep +0 -0
- package/examples/angular-static/src/favicon.ico +0 -0
- package/examples/angular-static/src/index.html +13 -0
- package/examples/angular-static/src/main.ts +7 -0
- package/examples/angular-static/src/styles.css +1 -0
- package/examples/angular-static/tsconfig.app.json +14 -0
- package/examples/angular-static/tsconfig.json +33 -0
- package/examples/angular-static/tsconfig.spec.json +14 -0
- package/examples/astro-static/README.md +55 -0
- package/examples/astro-static/astro.config.mjs +5 -0
- package/examples/astro-static/package.json +15 -0
- package/examples/astro-static/public/favicon.svg +9 -0
- package/examples/astro-static/src/components/Card.astro +63 -0
- package/examples/astro-static/src/env.d.ts +1 -0
- package/examples/astro-static/src/layouts/Layout.astro +36 -0
- package/examples/astro-static/src/pages/edge/index.astro +55 -0
- package/examples/astro-static/src/pages/index.astro +81 -0
- package/examples/astro-static/tsconfig.json +3 -0
- package/examples/hexo-static/.github/dependabot.yml +7 -0
- package/examples/hexo-static/_config.landscape.yml +0 -0
- package/examples/hexo-static/_config.yml +105 -0
- package/examples/hexo-static/package.json +26 -0
- package/examples/hexo-static/scaffolds/draft.md +4 -0
- package/examples/hexo-static/scaffolds/page.md +4 -0
- package/examples/hexo-static/scaffolds/post.md +5 -0
- package/examples/hexo-static/source/_posts/hello-world.md +38 -0
- package/examples/hexo-static/source/_posts/other-page.md +62 -0
- package/examples/hexo-static/themes/.gitkeep +0 -0
- package/examples/hexo-static/yarn.lock +1625 -0
- package/examples/next-12-static/.babelrc +3 -0
- package/examples/next-12-static/README.md +21 -0
- package/examples/next-12-static/components/post.jsx +27 -0
- package/examples/next-12-static/package-lock.json +6191 -0
- package/examples/next-12-static/package.json +18 -0
- package/examples/next-12-static/pages/index.jsx +34 -0
- package/examples/next-12-static/pages/post/[id].jsx +63 -0
- package/examples/next-static/README.md +34 -0
- package/examples/next-static/jsconfig.json +7 -0
- package/examples/next-static/next.config.js +9 -0
- package/examples/next-static/package.json +16 -0
- package/examples/next-static/public/next.svg +1 -0
- package/examples/next-static/public/vercel.svg +1 -0
- package/examples/next-static/src/app/blog/[slug]/page.js +27 -0
- package/examples/next-static/src/app/favicon.ico +0 -0
- package/examples/next-static/src/app/globals.css +107 -0
- package/examples/next-static/src/app/layout.js +17 -0
- package/examples/next-static/src/app/misty-mountains/moria/page.js +15 -0
- package/examples/next-static/src/app/page.js +96 -0
- package/examples/next-static/src/app/page.module.css +229 -0
- package/examples/next-static/yarn.lock +199 -0
- package/examples/react-static/README.md +70 -0
- package/examples/react-static/package.json +38 -0
- package/examples/react-static/public/favicon.ico +0 -0
- package/examples/react-static/public/index.html +43 -0
- package/examples/react-static/public/logo192.png +0 -0
- package/examples/react-static/public/logo512.png +0 -0
- package/examples/react-static/public/manifest.json +25 -0
- package/examples/react-static/public/robots.txt +3 -0
- package/examples/react-static/src/App.css +38 -0
- package/examples/react-static/src/App.js +25 -0
- package/examples/react-static/src/App.test.js +8 -0
- package/examples/react-static/src/index.css +13 -0
- package/examples/react-static/src/index.js +17 -0
- package/examples/react-static/src/logo.svg +1 -0
- package/examples/react-static/src/reportWebVitals.js +13 -0
- package/examples/react-static/src/setupTests.js +5 -0
- package/examples/simple-js-esm/main.js +14 -0
- package/examples/simple-js-esm/messages.js +7 -0
- package/examples/simple-js-node/main.js +18 -0
- package/examples/vue-static/README.md +24 -0
- package/examples/vue-static/babel.config.js +5 -0
- package/examples/vue-static/jsconfig.json +19 -0
- package/examples/vue-static/package.json +45 -0
- package/examples/vue-static/public/favicon.ico +0 -0
- package/examples/vue-static/public/index.html +17 -0
- package/examples/vue-static/src/App.vue +16 -0
- package/examples/vue-static/src/assets/logo.png +0 -0
- package/examples/vue-static/src/components/HelloWorld.vue +58 -0
- package/examples/vue-static/src/main.js +28 -0
- package/examples/vue-static/src/views/Home.vue +14 -0
- package/examples/vue-static/vue.config.js +4 -0
- package/jest.config.js +6 -0
- package/jsconfig.json +40 -0
- package/jsdoc.json +52 -0
- package/lib/build/bundlers/index.js +4 -0
- package/lib/build/bundlers/webpack/index.js +40 -0
- package/lib/build/bundlers/webpack/webpack.config.js +38 -0
- package/lib/build/dispatcher/dispatcher.js +211 -0
- package/lib/build/dispatcher/dispatcher.test.js +0 -0
- package/lib/build/dispatcher/index.js +3 -0
- package/lib/build/polyfills/index.js +0 -0
- package/lib/constants/azion-edges.constants.js +98 -0
- package/lib/constants/index.js +5 -0
- package/lib/constants/messages/build.messages.js +23 -0
- package/lib/constants/messages/env.messages.js +38 -0
- package/lib/constants/messages/global.messages.js +19 -0
- package/lib/constants/messages/index.js +10 -0
- package/lib/constants/messages/platform.messages.js +84 -0
- package/lib/constants/runtime-apis.constants.js +118 -0
- package/lib/env/index.js +5 -0
- package/lib/env/runtime.env.js +69 -0
- package/lib/env/server.env.js +90 -0
- package/lib/env/vulcan.env.js +93 -0
- package/lib/main.js +260 -0
- package/lib/notations/namespaces.js +30 -0
- package/lib/notations/typedef.js +10 -0
- package/lib/platform/actions/application/createApplication.actions.js +33 -0
- package/lib/platform/actions/application/enableEdgeFunctions.actions.js +34 -0
- package/lib/platform/actions/application/instantiateFunction.actions.js +37 -0
- package/lib/platform/actions/application/setFunctionAsDefaultRule.actions.js +33 -0
- package/lib/platform/actions/core/auth.actions.js +67 -0
- package/lib/platform/actions/core/deploy.actions.js +73 -0
- package/lib/platform/actions/core/propagation.actions.js +75 -0
- package/lib/platform/actions/core/storage.actions.js +84 -0
- package/lib/platform/actions/domain/createDomain.actions.js +42 -0
- package/lib/platform/actions/function/createFunction.actions.js +79 -0
- package/lib/platform/actions/function/showFunctionLogs.actions.js +149 -0
- package/lib/platform/edgehooks/ErrorHTML/ErrorHTML.hooks.js +101 -0
- package/lib/platform/edgehooks/ErrorHTML/index.js +3 -0
- package/lib/platform/edgehooks/index.js +5 -0
- package/lib/platform/edgehooks/mountSPA/index.js +3 -0
- package/lib/platform/edgehooks/mountSPA/mountSPA.hooks.js +55 -0
- package/lib/platform/edgehooks/mountSPA/mountSPA.hooks.test.js +19 -0
- package/lib/platform/edgehooks/mountSSG/index.js +3 -0
- package/lib/platform/edgehooks/mountSSG/mountSSG.hooks.js +61 -0
- package/lib/platform/edgehooks/mountSSG/mountSSG.hooks.test.js +0 -0
- package/lib/platform/index.js +65 -0
- package/lib/platform/services/application.service.js +140 -0
- package/lib/platform/services/base.service.js +200 -0
- package/lib/platform/services/domain.service.js +80 -0
- package/lib/platform/services/events.service.js +65 -0
- package/lib/platform/services/function.service.js +105 -0
- package/lib/platform/services/index.js +8 -0
- package/lib/platform/services/storage.service.js +59 -0
- package/lib/platform/services/tokens.service.js +55 -0
- package/lib/presets/custom/angular/deliver/config.js +12 -0
- package/lib/presets/custom/angular/deliver/handler.js +8 -0
- package/lib/presets/custom/angular/deliver/prebuild.js +20 -0
- package/lib/presets/custom/astro/deliver/config.js +12 -0
- package/lib/presets/custom/astro/deliver/handler.js +8 -0
- package/lib/presets/custom/astro/deliver/prebuild.js +37 -0
- package/lib/presets/custom/hexo/deliver/config.js +12 -0
- package/lib/presets/custom/hexo/deliver/handler.js +8 -0
- package/lib/presets/custom/hexo/deliver/prebuild.js +37 -0
- package/lib/presets/custom/next/deliver/config.js +14 -0
- package/lib/presets/custom/next/deliver/handler.js +9 -0
- package/lib/presets/custom/next/deliver/prebuild.js +193 -0
- package/lib/presets/custom/react/deliver/config.js +12 -0
- package/lib/presets/custom/react/deliver/handler.js +8 -0
- package/lib/presets/custom/react/deliver/prebuild.js +16 -0
- package/lib/presets/custom/vue/deliver/config.js +12 -0
- package/lib/presets/custom/vue/deliver/handler.js +8 -0
- package/lib/presets/custom/vue/deliver/prebuild.js +20 -0
- package/lib/presets/default/html/deliver/config.js +13 -0
- package/lib/presets/default/html/deliver/handler.js +9 -0
- package/lib/presets/default/html/deliver/prebuild.js +15 -0
- package/lib/presets/default/javascript/compute/config.js +13 -0
- package/lib/presets/default/javascript/compute/handler.js +5 -0
- package/lib/presets/default/javascript/compute/prebuild.js +6 -0
- package/lib/presets/default/typescript/compute/config.js +0 -0
- package/lib/presets/default/typescript/compute/handler.js +0 -0
- package/lib/presets/default/typescript/compute/prebuild.js +0 -0
- package/lib/providers/azion/worker.js +12 -0
- package/lib/utils/copyDirectory/copyDirectory.utils.js +54 -0
- package/lib/utils/copyDirectory/copyDirectory.utils.test.js +43 -0
- package/lib/utils/copyDirectory/index.js +3 -0
- package/lib/utils/debug/debug.utils.js +36 -0
- package/lib/utils/debug/debug.utils.test.js +43 -0
- package/lib/utils/debug/index.js +3 -0
- package/lib/utils/exec/exec.utils.js +58 -0
- package/lib/utils/exec/exec.utils.test.js +84 -0
- package/lib/utils/exec/index.js +3 -0
- package/lib/utils/feedback/feedback.utils.js +81 -0
- package/lib/utils/feedback/feedback.utils.test.js +11 -0
- package/lib/utils/feedback/index.js +3 -0
- package/lib/utils/generateTimestamp/generateTimestamp.utils.js +25 -0
- package/lib/utils/generateTimestamp/generateTimestamp.utils.test.js +10 -0
- package/lib/utils/generateTimestamp/index.js +3 -0
- package/lib/utils/getAbsoluteLibDirPath/getAbsoluteLibDirPath.utils.js +21 -0
- package/lib/utils/getAbsoluteLibDirPath/getAbsoluteLibDirPath.utils.test.js +13 -0
- package/lib/utils/getAbsoluteLibDirPath/index.js +3 -0
- package/lib/utils/getPackageManager/getPackageManager.utils.js +118 -0
- package/lib/utils/getPackageManager/getPackageManager.utils.test.js +35 -0
- package/lib/utils/getPackageManager/index.js +3 -0
- package/lib/utils/getPackageVersion/getPackageVersion.utils.js +25 -0
- package/lib/utils/getPackageVersion/getPackageVersion.utils.test.js +48 -0
- package/lib/utils/getPackageVersion/index.js +3 -0
- package/lib/utils/getPresetsList/getPresetsList.utils.js +50 -0
- package/lib/utils/getPresetsList/getPresetsList.utils.test.js +19 -0
- package/lib/utils/getPresetsList/index.js +3 -0
- package/lib/utils/getProjectJsonFile/getProjectJsonFile.utils.js +21 -0
- package/lib/utils/getProjectJsonFile/getProjectJsonFile.utils.test.js +39 -0
- package/lib/utils/getProjectJsonFile/index.js +3 -0
- package/lib/utils/getVulcanBuildId/getVulcanBuildId.utils.js +49 -0
- package/lib/utils/getVulcanBuildId/getVulcanBuildId.utils.test.js +36 -0
- package/lib/utils/getVulcanBuildId/index.js +3 -0
- package/lib/utils/index.js +29 -0
- package/lib/utils/overrideStaticOutputPath/index.js +3 -0
- package/lib/utils/overrideStaticOutputPath/overrideStaticOutputPath.utils.js +47 -0
- package/lib/utils/overrideStaticOutputPath/overrideStaticOutputPath.utils.test.js +35 -0
- package/lib/utils/readWorkerFile/index.js +3 -0
- package/lib/utils/readWorkerFile/readWorkerFile.utils.js +36 -0
- package/lib/utils/readWorkerFile/readWorkerFile.utils.test.js +24 -0
- package/package.json +99 -0
- package/releaserc.json +87 -0
- package/tasks/sync-aliases.js +115 -0
package/lib/main.js
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
#! /usr/bin/env node
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { createPromptModule } from 'inquirer';
|
|
5
|
+
import { satisfies } from 'semver';
|
|
6
|
+
import { feedback, debug } from '#utils';
|
|
7
|
+
import { Messages } from '#constants';
|
|
8
|
+
|
|
9
|
+
const MIN_NODE_VERSION = '18.0.0';
|
|
10
|
+
|
|
11
|
+
const debugEnabled = process.env.DEBUG === 'true';
|
|
12
|
+
const version = process.env.npm_package_version;
|
|
13
|
+
const program = new Command();
|
|
14
|
+
const prompt = createPromptModule();
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Validates if user is using the minimum Node version
|
|
18
|
+
* @returns {boolean} - indicates if is a valid version
|
|
19
|
+
*/
|
|
20
|
+
function validateNodeMinVersion() {
|
|
21
|
+
const isAValidVersion = satisfies(process.version, `>= ${MIN_NODE_VERSION}`);
|
|
22
|
+
|
|
23
|
+
return isAValidVersion;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Sets the global Vulcan environment.
|
|
28
|
+
*
|
|
29
|
+
* Validates the ENV value and sets it as the environment in the global 'vulcan' object.
|
|
30
|
+
* If the ENV value is invalid, it throws an error and terminates the process.
|
|
31
|
+
* @throws {Error} If ENV is not one of 'production', 'stage', 'dev'.
|
|
32
|
+
* @example
|
|
33
|
+
* setVulcanEnvironment();
|
|
34
|
+
*/
|
|
35
|
+
function setVulcanEnvironment() {
|
|
36
|
+
const ENV = process.env.AZION_ENV || 'production';
|
|
37
|
+
if (!['production', 'stage', 'local'].includes(ENV)) {
|
|
38
|
+
feedback.error(Messages.env.errors.invalid_environment);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
} else {
|
|
41
|
+
globalThis.vulcan = { env: ENV };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Starts the command-line interface program.
|
|
46
|
+
* @example
|
|
47
|
+
* startProgram();
|
|
48
|
+
*/
|
|
49
|
+
function startVulcanProgram() {
|
|
50
|
+
program.version(version);
|
|
51
|
+
|
|
52
|
+
if (debugEnabled) {
|
|
53
|
+
program
|
|
54
|
+
.command('auth')
|
|
55
|
+
.option(
|
|
56
|
+
'--password <username>:<password>',
|
|
57
|
+
'Authenticate using username and password',
|
|
58
|
+
)
|
|
59
|
+
.option('--token <token>', 'Authenticate using personal token')
|
|
60
|
+
.description('Authenticate the CLI')
|
|
61
|
+
.action(async (options) => {
|
|
62
|
+
const { core } = await import('#platform');
|
|
63
|
+
|
|
64
|
+
const authOptions = [
|
|
65
|
+
{
|
|
66
|
+
name: 'Username and Password',
|
|
67
|
+
value: 'password',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'Personal Token',
|
|
71
|
+
value: 'token',
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
|
|
75
|
+
if (options.password) {
|
|
76
|
+
const [username, password] = options.password.split(':');
|
|
77
|
+
core.actions.auth('password', { username, password });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (options.token) {
|
|
81
|
+
const { token } = options;
|
|
82
|
+
core.actions.auth('token', { token });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (!options.token && !options.password) {
|
|
86
|
+
const { authOption } = await prompt([
|
|
87
|
+
{
|
|
88
|
+
type: 'list',
|
|
89
|
+
name: 'authOption',
|
|
90
|
+
message: 'Choose your login option:',
|
|
91
|
+
choices: authOptions.map((option) => option.name),
|
|
92
|
+
},
|
|
93
|
+
]);
|
|
94
|
+
|
|
95
|
+
if (authOption === 'Username and Password') {
|
|
96
|
+
const { username, password } = await prompt([
|
|
97
|
+
{
|
|
98
|
+
type: 'input',
|
|
99
|
+
name: 'username',
|
|
100
|
+
message: 'Enter your username:',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
type: 'password',
|
|
104
|
+
name: 'password',
|
|
105
|
+
message: 'Enter your password:',
|
|
106
|
+
},
|
|
107
|
+
]);
|
|
108
|
+
core.actions.auth('password', { username, password });
|
|
109
|
+
}
|
|
110
|
+
if (authOption === 'Personal Token') {
|
|
111
|
+
const { token } = await prompt([
|
|
112
|
+
{
|
|
113
|
+
type: 'password',
|
|
114
|
+
name: 'token',
|
|
115
|
+
message: 'Enter your personal token:',
|
|
116
|
+
},
|
|
117
|
+
]);
|
|
118
|
+
core.actions.auth('token', { token });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
program
|
|
124
|
+
.command('run')
|
|
125
|
+
.description('Run Edge Function')
|
|
126
|
+
.arguments('<file>')
|
|
127
|
+
.option('-p, --port <port>', 'Specify the port', '3000')
|
|
128
|
+
.action(async (file, options) => {
|
|
129
|
+
const { port } = options;
|
|
130
|
+
const parsedPort = parseInt(port, 10);
|
|
131
|
+
const { server } = await import('#env');
|
|
132
|
+
const entryPoint = file || path.join(process.cwd(), '.edge/woker.js');
|
|
133
|
+
server(entryPoint, parsedPort);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
program
|
|
137
|
+
.command('logs <type> [id]')
|
|
138
|
+
.description('Perform operations on function or application logs')
|
|
139
|
+
.option('-w, --watch', 'Show real-time logs')
|
|
140
|
+
.action(async (type, id, options) => {
|
|
141
|
+
const { functions } = await import('#platform');
|
|
142
|
+
const { watch } = options;
|
|
143
|
+
|
|
144
|
+
if (!['function', 'application'].includes(type)) {
|
|
145
|
+
feedback.error(Messages.platform.logs.errors.invalid_log_type);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (type === 'function') {
|
|
150
|
+
functions.actions.showFunctionLogs(id, watch);
|
|
151
|
+
}
|
|
152
|
+
if (type === 'application') {
|
|
153
|
+
feedback.info(Messages.platform.logs.info.unsupported_log_type);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
program
|
|
158
|
+
.command('storage sync')
|
|
159
|
+
.description(
|
|
160
|
+
'Synchronize local .edge/statics with the Edge Function storage',
|
|
161
|
+
)
|
|
162
|
+
.action(async () => {
|
|
163
|
+
const { core } = await import('#platform');
|
|
164
|
+
const { getVulcanBuildId } = await import('#utils');
|
|
165
|
+
|
|
166
|
+
const versionId = getVulcanBuildId();
|
|
167
|
+
const basePath = path.join(process.cwd(), '.edge/statics/');
|
|
168
|
+
await core.actions.uploadStatics(versionId, basePath);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
program
|
|
172
|
+
.command('deploy')
|
|
173
|
+
.description('Create and deploy an application with a function')
|
|
174
|
+
.action(async () => {
|
|
175
|
+
const { core } = await import('#platform');
|
|
176
|
+
const { getVulcanBuildId } = await import('#utils');
|
|
177
|
+
|
|
178
|
+
const versionId = getVulcanBuildId();
|
|
179
|
+
const staticsPath = path.join(process.cwd(), '/.edge/statics');
|
|
180
|
+
|
|
181
|
+
const answers = await prompt([
|
|
182
|
+
{
|
|
183
|
+
type: 'input',
|
|
184
|
+
name: 'applicationName',
|
|
185
|
+
message:
|
|
186
|
+
'Enter the name of the application (optional, leave empty for random name):',
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
type: 'input',
|
|
190
|
+
name: 'functionName',
|
|
191
|
+
message:
|
|
192
|
+
'Enter the name of the function (optional, leave empty for random name):',
|
|
193
|
+
},
|
|
194
|
+
]);
|
|
195
|
+
|
|
196
|
+
const { applicationName, functionName } = answers;
|
|
197
|
+
|
|
198
|
+
await core.actions.uploadStatics(versionId, staticsPath);
|
|
199
|
+
const domain = await core.actions.deploy(applicationName, functionName);
|
|
200
|
+
core.actions.watchPropagation(domain);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
program
|
|
205
|
+
.command('build')
|
|
206
|
+
.description('Build a project for edge deployment')
|
|
207
|
+
.option(
|
|
208
|
+
'--preset <type>',
|
|
209
|
+
'Preset of build target (e.g., vue, next, javascript)',
|
|
210
|
+
'javascript',
|
|
211
|
+
)
|
|
212
|
+
.option(
|
|
213
|
+
'--mode <type>',
|
|
214
|
+
'Mode of build target (e.g., deliver, compute)',
|
|
215
|
+
'compute',
|
|
216
|
+
)
|
|
217
|
+
.option(
|
|
218
|
+
'--entry <string>',
|
|
219
|
+
'Code entrypoint (default: ./main.js)',
|
|
220
|
+
'./main.js',
|
|
221
|
+
)
|
|
222
|
+
.action(async ({
|
|
223
|
+
preset, mode, entry, versionId,
|
|
224
|
+
}) => {
|
|
225
|
+
// TODO: generate versionID in dispatcher (currently generated for webpackconfig)
|
|
226
|
+
const BuildDispatcher = (await import('#build')).default;
|
|
227
|
+
const buildDispatcher = new BuildDispatcher(
|
|
228
|
+
preset,
|
|
229
|
+
mode,
|
|
230
|
+
entry,
|
|
231
|
+
versionId,
|
|
232
|
+
);
|
|
233
|
+
await buildDispatcher.run();
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
program
|
|
237
|
+
.command('presets <type>')
|
|
238
|
+
.description('Create or use defined project presets for Edge.')
|
|
239
|
+
.action(async (type) => {
|
|
240
|
+
const { getPresetsList } = await import('#utils');
|
|
241
|
+
const presets = getPresetsList();
|
|
242
|
+
|
|
243
|
+
if (type === 'ls') {
|
|
244
|
+
presets.forEach((preset) => feedback.option(preset));
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
program.parse(process.argv);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
try {
|
|
251
|
+
if (validateNodeMinVersion()) {
|
|
252
|
+
setVulcanEnvironment();
|
|
253
|
+
startVulcanProgram();
|
|
254
|
+
} else {
|
|
255
|
+
feedback.error(Messages.errors.invalid_node_version(MIN_NODE_VERSION));
|
|
256
|
+
}
|
|
257
|
+
} catch (error) {
|
|
258
|
+
feedback.error(Messages.errors.unknown_error);
|
|
259
|
+
debug.error(error);
|
|
260
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @namespace utils
|
|
3
|
+
* @description Provides utility functions for various tasks.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @namespace platform
|
|
8
|
+
* @description Contains functions and actions to interact with the edge platform (Azion).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @namespace build
|
|
13
|
+
* @description Represents the structure responsible for pre-build and build processes for the edge.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @namespace env
|
|
18
|
+
* @description Contains codes and functions responsible for managing the local environment.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @namespace presets
|
|
23
|
+
* @description Contains presets with pre-configured workers and
|
|
24
|
+
* Presets available to run on the edge.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @namespace edge
|
|
29
|
+
* @description Contains imported and computer-ready functions for use on the edge.
|
|
30
|
+
*/
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} FetchEvent
|
|
3
|
+
* @property {Request} request - This interface represents a resource request.
|
|
4
|
+
* @property {Promise<Response>} respondWith - This interface prevents the browser's
|
|
5
|
+
* default fetch handling, and allows you to provide a promise for a Response yourself.
|
|
6
|
+
* @property {function(): void} waitUntil - his interface is used to inform the browser
|
|
7
|
+
* not to terminate the Service Worker until
|
|
8
|
+
* the promise passed to `waitUntil` is either resolved or rejected.
|
|
9
|
+
* @description Represents an event that is dispatched to a worker when a fetch event occurs.
|
|
10
|
+
*/
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { debug } from '#utils';
|
|
2
|
+
import ApplicationService from '../../services/application.service.js';
|
|
3
|
+
/**
|
|
4
|
+
* @function
|
|
5
|
+
* @memberof platform
|
|
6
|
+
* @name createApplication
|
|
7
|
+
* @description Creates a new application using the specified application name.
|
|
8
|
+
* @param {string} applicationName - The name of the new application.
|
|
9
|
+
* @returns {Promise<object>} A promise that resolves to the newly created application object.
|
|
10
|
+
* @throws Will throw an error if the creation process fails.
|
|
11
|
+
* @example
|
|
12
|
+
* try {
|
|
13
|
+
* const newApp = await createApplication('My New Application');
|
|
14
|
+
* console.log(newApp);
|
|
15
|
+
* } catch (error) {
|
|
16
|
+
* console.error(error);
|
|
17
|
+
* }
|
|
18
|
+
*/
|
|
19
|
+
async function createApplication(applicationName) {
|
|
20
|
+
try {
|
|
21
|
+
const payload = {
|
|
22
|
+
name: applicationName,
|
|
23
|
+
delivery_protocol: 'http,https',
|
|
24
|
+
};
|
|
25
|
+
const response = await (await ApplicationService.create(payload)).json();
|
|
26
|
+
return response.results;
|
|
27
|
+
} catch (error) {
|
|
28
|
+
debug.error(error);
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default createApplication;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { debug } from '#utils';
|
|
2
|
+
import ApplicationService from '../../services/application.service.js';
|
|
3
|
+
/**
|
|
4
|
+
* @function
|
|
5
|
+
* @memberof platform
|
|
6
|
+
* @name enableEdgeFunctions
|
|
7
|
+
* @description Enables edge functions for the specified application.
|
|
8
|
+
* @param {number} applicationId - The unique identifier of the application.
|
|
9
|
+
* @returns {Promise<object>} A promise that resolves to the updated application
|
|
10
|
+
* object with edge functions enabled.
|
|
11
|
+
* @throws Will throw an error if the update process fails.
|
|
12
|
+
* @example
|
|
13
|
+
* try {
|
|
14
|
+
* const updatedApp = await enableEdgeFunctions(12345);
|
|
15
|
+
* console.log(updatedApp);
|
|
16
|
+
* } catch (error) {
|
|
17
|
+
* console.error(error);
|
|
18
|
+
* }
|
|
19
|
+
*/
|
|
20
|
+
async function enableEdgeFunctions(applicationId) {
|
|
21
|
+
try {
|
|
22
|
+
const payload = {
|
|
23
|
+
edge_functions: true,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const response = await (await ApplicationService.update(applicationId, payload)).json();
|
|
27
|
+
return response.results;
|
|
28
|
+
} catch (error) {
|
|
29
|
+
debug.error(error);
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default enableEdgeFunctions;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { debug } from '#utils';
|
|
2
|
+
import ApplicationService from '../../services/application.service.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @function
|
|
6
|
+
* @memberof platform
|
|
7
|
+
* @name instantiateFunction
|
|
8
|
+
* @description Instantiates an edge function in the specified application.
|
|
9
|
+
* @param {string} functionName - The name of the function to be instantiated.
|
|
10
|
+
* @param {number} functionId - The unique identifier of the function to be instantiated.
|
|
11
|
+
* @param {number} applicationId - The unique identifier of the application.
|
|
12
|
+
* @returns {Promise<object>} A promise that resolves to the instantiated edge function object.
|
|
13
|
+
* @throws Will throw an error if the instantiation process fails.
|
|
14
|
+
* @example
|
|
15
|
+
* try {
|
|
16
|
+
* const instantiatedFunc = await instantiateFunction('My Function', 123, 456);
|
|
17
|
+
* console.log(instantiatedFunc);
|
|
18
|
+
* } catch (error) {
|
|
19
|
+
* console.error(error);
|
|
20
|
+
* }
|
|
21
|
+
*/
|
|
22
|
+
async function instantiateFunction(functionName, functionId, applicationId) {
|
|
23
|
+
const payload = {
|
|
24
|
+
name: functionName,
|
|
25
|
+
edge_function_id: functionId,
|
|
26
|
+
args: {},
|
|
27
|
+
};
|
|
28
|
+
try {
|
|
29
|
+
const response = await (await ApplicationService.instantiate(applicationId, payload)).json();
|
|
30
|
+
return response.results;
|
|
31
|
+
} catch (error) {
|
|
32
|
+
debug.error(error);
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default instantiateFunction;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { debug } from '#utils';
|
|
2
|
+
import ApplicationService from '../../services/application.service.js';
|
|
3
|
+
/**
|
|
4
|
+
* Sets a function as the default rule in an application's rules engine.
|
|
5
|
+
* @param {number} applicationId - The ID of the application.
|
|
6
|
+
* @param {number} functionInstanceId - The ID of the edge function instance.
|
|
7
|
+
* @returns {Promise<object>} The updated rules engine rules.
|
|
8
|
+
*/
|
|
9
|
+
async function setFunctionAsDefaultRule(applicationId, functionInstanceId) {
|
|
10
|
+
try {
|
|
11
|
+
const rulesResponse = await (await ApplicationService.getRules(applicationId)).json();
|
|
12
|
+
const defaultRuleId = rulesResponse.results[0].id;
|
|
13
|
+
|
|
14
|
+
const payload = {
|
|
15
|
+
behaviors: [
|
|
16
|
+
{
|
|
17
|
+
name: 'run_function',
|
|
18
|
+
target: functionInstanceId,
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const response = await
|
|
24
|
+
(await ApplicationService.updateRule(applicationId, defaultRuleId, payload))
|
|
25
|
+
.json();
|
|
26
|
+
return response.results;
|
|
27
|
+
} catch (error) {
|
|
28
|
+
debug.error(error);
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default setFunctionAsDefaultRule;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { vulcan } from '#env';
|
|
2
|
+
import { Messages } from '#constants';
|
|
3
|
+
import { feedback, debug } from '#utils';
|
|
4
|
+
import TokensService from '../../services/tokens.service.js';
|
|
5
|
+
import FunctionService from '../../services/function.service.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @function
|
|
9
|
+
* @memberof platform
|
|
10
|
+
* @name auth
|
|
11
|
+
* @description Authenticates the user with the provided credentials.
|
|
12
|
+
* @param {string} loginOption - The chosen login method. Valid values are
|
|
13
|
+
* 'username/password' and 'token'.
|
|
14
|
+
* @param {object} credentials - The user credentials required for authentication.
|
|
15
|
+
* @param {string} [credentials.username] - Required for 'username/password' option.
|
|
16
|
+
* Represents the username for password-based authentication.
|
|
17
|
+
* @param {string} [credentials.password] - Required for 'username/password' option.
|
|
18
|
+
* Represents the password for password-based authentication.
|
|
19
|
+
* @param {string} [credentials.token] - Required for 'token' option.
|
|
20
|
+
* Represents the personal token for token-based authentication.
|
|
21
|
+
* @returns {void}
|
|
22
|
+
* @throws Will throw an error if the authentication process fails.
|
|
23
|
+
* @example
|
|
24
|
+
* // For 'username/password' option
|
|
25
|
+
* try {
|
|
26
|
+
* await auth('password', { username: 'exampleUser', password: 'examplePass' });
|
|
27
|
+
* } catch (error) {
|
|
28
|
+
* console.error(error);
|
|
29
|
+
* }
|
|
30
|
+
* // For 'token' option
|
|
31
|
+
* try {
|
|
32
|
+
* await auth('token', { token: 'exampleToken' });
|
|
33
|
+
* } catch (error) {
|
|
34
|
+
* console.error(error);
|
|
35
|
+
* }
|
|
36
|
+
*/
|
|
37
|
+
async function auth(loginOption, credentials) {
|
|
38
|
+
try {
|
|
39
|
+
if (loginOption === 'password') {
|
|
40
|
+
const response = await TokensService.create(credentials.username, credentials.password);
|
|
41
|
+
const responseJSON = await response.json();
|
|
42
|
+
|
|
43
|
+
if (!responseJSON.token) {
|
|
44
|
+
feedback.error(responseJSON);
|
|
45
|
+
}
|
|
46
|
+
if (responseJSON.token) {
|
|
47
|
+
await vulcan.createVulcanEnv('API_TOKEN', responseJSON.token);
|
|
48
|
+
feedback.success(Messages.platform.auth.success.api_auth_success);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (loginOption === 'token') {
|
|
52
|
+
await vulcan.createVulcanEnv('API_TOKEN', credentials.token);
|
|
53
|
+
const validateTokenJSON = await (await FunctionService.getAll()).json();
|
|
54
|
+
if (validateTokenJSON.results) {
|
|
55
|
+
feedback.success(Messages.platform.auth.success.auth_success);
|
|
56
|
+
}
|
|
57
|
+
if (!validateTokenJSON.results) {
|
|
58
|
+
throw new Error(JSON.stringify(validateTokenJSON));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
} catch (error) {
|
|
62
|
+
debug.error(error);
|
|
63
|
+
feedback.success(Messages.platform.auth.error.auth_failed);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default auth;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { feedback, generateTimestamp, debug } from '#utils';
|
|
2
|
+
import { Messages } from '#constants';
|
|
3
|
+
|
|
4
|
+
import createApplication from '../application/createApplication.actions.js';
|
|
5
|
+
|
|
6
|
+
import instantiateFunction from '../application/instantiateFunction.actions.js';
|
|
7
|
+
import enableEdgeFunctions from '../application/enableEdgeFunctions.actions.js';
|
|
8
|
+
import setFunctionAsDefaultRule from '../application/setFunctionAsDefaultRule.actions.js';
|
|
9
|
+
import createDomain from '../domain/createDomain.actions.js';
|
|
10
|
+
import createFunction from '../function/createFunction.actions.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @function
|
|
14
|
+
* @memberof platform
|
|
15
|
+
* @name deploy
|
|
16
|
+
* @description Creates a new application from scratch, performing several steps including
|
|
17
|
+
* function creation, application creation, enabling edge functions, function instantiation,
|
|
18
|
+
* rule setting, and domain creation. If names are not provided, they will be auto-generated
|
|
19
|
+
* using a timestamp.
|
|
20
|
+
* @param {string} [applicationName] - The name of the application to be created. If not provided,
|
|
21
|
+
* it will be auto-generated as `vulcan-${generateTimestamp()}`.
|
|
22
|
+
* @param {string} [functionName] - The name of the function to be instantiated. If not provided,
|
|
23
|
+
* it will be auto-generated as `vulcan-${generateTimestamp()}`.
|
|
24
|
+
* @param {string} [domainName] - The name of the domain to be created. If not provided, it will be
|
|
25
|
+
* auto-generated as `vulcan-${generateTimestamp()}`.
|
|
26
|
+
* @returns {Promise<string>} A promise that resolves to the domain of the newly
|
|
27
|
+
* created application.
|
|
28
|
+
* @throws Will throw an error if any step in the deployment process fails.
|
|
29
|
+
* @example
|
|
30
|
+
* try {
|
|
31
|
+
* const domain = await deploy('myApplication', 'myFunction', 'myDomain');
|
|
32
|
+
* console.log('Domain of the new application:', domain);
|
|
33
|
+
* } catch (error) {
|
|
34
|
+
* console.error(error);
|
|
35
|
+
* }
|
|
36
|
+
*/
|
|
37
|
+
async function deploy(applicationName, functionName, domainName) {
|
|
38
|
+
try {
|
|
39
|
+
const timestamp = generateTimestamp();
|
|
40
|
+
const deployId = `vulcan-${timestamp}`;
|
|
41
|
+
|
|
42
|
+
feedback.platform.interactive.await(`[%d/6] - ${Messages.platform.deploy.info.creating_edge_function}`, 1);
|
|
43
|
+
const generatedFunctionName = functionName || deployId;
|
|
44
|
+
const edgeFunctionId = (await createFunction(generatedFunctionName)).id;
|
|
45
|
+
|
|
46
|
+
feedback.platform.interactive.await(`[%d/6] - ${Messages.platform.deploy.info.creating_edge_application}`, 2);
|
|
47
|
+
const generatedApplicationName = applicationName || deployId;
|
|
48
|
+
const edgeApplicationId = (await createApplication(generatedApplicationName)).id;
|
|
49
|
+
|
|
50
|
+
feedback.platform.interactive.await(`[%d/6] - ${Messages.platform.deploy.info.activating_edge_function}`, 3);
|
|
51
|
+
await enableEdgeFunctions(edgeApplicationId);
|
|
52
|
+
|
|
53
|
+
feedback.platform.interactive.await(`[%d/6] - ${Messages.platform.deploy.info.instantiating_edge_function}`, 4);
|
|
54
|
+
const functionInstanceId = (await
|
|
55
|
+
instantiateFunction(generatedFunctionName, edgeFunctionId, edgeApplicationId)).id;
|
|
56
|
+
|
|
57
|
+
feedback.platform.interactive.await(`[%d/6] - ${Messages.platform.deploy.info.creating_rule_engine}`, 5);
|
|
58
|
+
await setFunctionAsDefaultRule(edgeApplicationId, functionInstanceId);
|
|
59
|
+
|
|
60
|
+
feedback.platform.interactive.await(`[%d/6] - ${Messages.platform.deploy.info.creating_domain}`, 6);
|
|
61
|
+
const generatedDomainName = domainName || deployId;
|
|
62
|
+
const domain = (await createDomain(generatedDomainName, edgeApplicationId)).domain_name;
|
|
63
|
+
feedback.platform.interactive.complete(Messages.platform.deploy.success.deploy_finished);
|
|
64
|
+
feedback.platform.interactive.breakInteractiveChain();
|
|
65
|
+
|
|
66
|
+
return domain;
|
|
67
|
+
} catch (error) {
|
|
68
|
+
feedback.platform.error(Messages.platform.deploy.error.deploy_failed);
|
|
69
|
+
debug.error(error);
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export default deploy;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { AzionEdges, Messages } from '#constants';
|
|
2
|
+
import { feedback, debug } from '#utils';
|
|
3
|
+
import open from 'open';
|
|
4
|
+
/**
|
|
5
|
+
* @function
|
|
6
|
+
* @memberof platform
|
|
7
|
+
* @name watchPropagation
|
|
8
|
+
* @description Monitors the propagation of a domain across the edge networks after the FIRST
|
|
9
|
+
* deployment. This function fetches the specified domain at regular intervals to check for
|
|
10
|
+
* propagation status. It interprets a 404 response as indicating that the domain is still
|
|
11
|
+
* propagating. Any other response is taken to mean that the domain has successfully
|
|
12
|
+
* propagated to the edge networks and is ready for access.
|
|
13
|
+
* @param {string} domain - The domain to monitor for propagation across the edge networks.
|
|
14
|
+
* @throws Will throw an error if there is a failure during the monitoring process.
|
|
15
|
+
* @example
|
|
16
|
+
* try {
|
|
17
|
+
* watchPropagation('myDomain.com');
|
|
18
|
+
* } catch (error) {
|
|
19
|
+
* console.error(error);
|
|
20
|
+
* }
|
|
21
|
+
*/
|
|
22
|
+
function watchPropagation(domain) {
|
|
23
|
+
let currentEdgeIndex = 0;
|
|
24
|
+
let intervalId = null;
|
|
25
|
+
const f = feedback.propagation; // TODO: workaround -> improve
|
|
26
|
+
|
|
27
|
+
const performFetch = async () => {
|
|
28
|
+
try {
|
|
29
|
+
const response = await fetch(`https://${domain}`);
|
|
30
|
+
if (response.status === 404) {
|
|
31
|
+
f.interactive.await(
|
|
32
|
+
Messages.platform.propagation.info.propagating(
|
|
33
|
+
AzionEdges[currentEdgeIndex],
|
|
34
|
+
),
|
|
35
|
+
);
|
|
36
|
+
currentEdgeIndex = (currentEdgeIndex + 1) % AzionEdges.length;
|
|
37
|
+
} else {
|
|
38
|
+
clearInterval(intervalId);
|
|
39
|
+
|
|
40
|
+
let remainingEdgeIndex = currentEdgeIndex + 1;
|
|
41
|
+
const remainingEdgesIntervalId = setInterval(() => {
|
|
42
|
+
if (remainingEdgeIndex >= AzionEdges.length) {
|
|
43
|
+
clearInterval(remainingEdgesIntervalId);
|
|
44
|
+
f.interactive.complete(
|
|
45
|
+
Messages.platform.propagation.success.propagation_complete,
|
|
46
|
+
);
|
|
47
|
+
open(`https://${domain}`);
|
|
48
|
+
process.exit(0);
|
|
49
|
+
} else {
|
|
50
|
+
const remainingEdge = AzionEdges[remainingEdgeIndex];
|
|
51
|
+
f.interactive.await(
|
|
52
|
+
Messages.platform.propagation.info.propagating(remainingEdge),
|
|
53
|
+
);
|
|
54
|
+
// eslint-disable-next-line no-plusplus
|
|
55
|
+
remainingEdgeIndex++;
|
|
56
|
+
}
|
|
57
|
+
}, 150);
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
debug.error(error);
|
|
61
|
+
f.interactive.fatal(
|
|
62
|
+
Messages.propagation.errors.watch_propagation_failed,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Perform the first fetch immediately
|
|
68
|
+
performFetch();
|
|
69
|
+
|
|
70
|
+
// Start the interval
|
|
71
|
+
intervalId = setInterval(performFetch, 10000);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// eslint-disable-next-line import/prefer-default-export
|
|
75
|
+
export { watchPropagation };
|