edge-functions 1.0.0 → 1.3.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/.eslintrc.json +60 -15
- package/.github/workflows/major.yml +1 -1
- package/.github/workflows/minor.yml +1 -2
- package/README.md +36 -0
- package/aliases.js +1 -1
- package/docs/overview.md +4 -3
- package/docs/presets.md +18 -6
- package/examples/angular-static/package.json +0 -1
- package/examples/simple-js-esm/main.js +13 -8
- package/examples/simple-js-esm-node/index.js +45 -0
- package/examples/simple-ts-esm/main.ts +24 -0
- package/examples/simple-ts-esm/messages.ts +11 -0
- package/examples/simple-ts-esm/package.json +9 -0
- package/examples/simple-ts-esm/tsconfig.json +109 -0
- package/examples/simple-ts-esm/yarn.lock +8 -0
- package/examples/vue-vite-static/README.md +29 -0
- package/examples/vue-vite-static/index.html +13 -0
- package/examples/vue-vite-static/package.json +18 -0
- package/examples/vue-vite-static/public/favicon.ico +0 -0
- package/examples/vue-vite-static/src/App.vue +85 -0
- package/examples/vue-vite-static/src/assets/base.css +73 -0
- package/examples/vue-vite-static/src/assets/logo.svg +1 -0
- package/examples/vue-vite-static/src/assets/main.css +35 -0
- package/examples/vue-vite-static/src/components/HelloWorld.vue +44 -0
- package/examples/vue-vite-static/src/components/TheWelcome.vue +86 -0
- package/examples/vue-vite-static/src/components/WelcomeItem.vue +86 -0
- package/examples/vue-vite-static/src/components/icons/IconCommunity.vue +7 -0
- package/examples/vue-vite-static/src/components/icons/IconDocumentation.vue +7 -0
- package/examples/vue-vite-static/src/components/icons/IconEcosystem.vue +7 -0
- package/examples/vue-vite-static/src/components/icons/IconSupport.vue +7 -0
- package/examples/vue-vite-static/src/components/icons/IconTooling.vue +19 -0
- package/examples/vue-vite-static/src/main.js +11 -0
- package/examples/vue-vite-static/src/router/index.js +23 -0
- package/examples/vue-vite-static/src/views/AboutView.vue +15 -0
- package/examples/vue-vite-static/src/views/HomeView.vue +9 -0
- package/examples/vue-vite-static/vite.config.js +16 -0
- package/jsconfig.json +1 -1
- package/lib/build/bundlers/esbuild/esbuild.config.js +12 -0
- package/lib/build/bundlers/esbuild/index.js +46 -0
- package/lib/build/bundlers/esbuild/plugins/node-polyfills/index.js +147 -0
- package/lib/build/bundlers/esbuild/plugins/node-polyfills/node-polyfills-paths.js +124 -0
- package/lib/build/bundlers/index.js +2 -2
- package/lib/build/bundlers/webpack/index.js +16 -7
- package/lib/build/bundlers/webpack/webpack.config.js +5 -25
- package/lib/build/dispatcher/dispatcher.js +116 -66
- package/lib/constants/framework-initializer.constants.js +51 -0
- package/lib/constants/index.js +4 -1
- package/lib/constants/messages/build.messages.js +2 -0
- package/lib/constants/messages/env.messages.js +5 -3
- package/lib/constants/messages/global.messages.js +4 -1
- package/lib/env/polyfills/FetchEvent.polyfills.js +13 -0
- package/lib/env/polyfills/fetch.polyfills.js +39 -0
- package/lib/env/polyfills/index.js +4 -0
- package/lib/env/runtime.env.js +57 -63
- package/lib/env/server.env.js +32 -76
- package/lib/main.js +234 -90
- package/lib/notations/namespaces.js +5 -0
- package/lib/platform/actions/core/auth.actions.js +1 -1
- package/lib/platform/actions/core/propagation.actions.js +8 -5
- package/lib/platform/actions/core/storage.actions.js +1 -1
- package/lib/platform/actions/function/showFunctionLogs.actions.js +71 -92
- package/lib/platform/edgehooks/debugRequest/debugRequest.hooks.js +28 -0
- package/lib/platform/edgehooks/debugRequest/index.js +3 -0
- package/lib/platform/edgehooks/index.js +4 -1
- package/lib/polyfills/FetchEvent.polyfills.js +13 -0
- package/lib/polyfills/fetch.polyfills.js +39 -0
- package/lib/polyfills/index.js +4 -0
- package/lib/presets/custom/angular/deliver/config.js +2 -4
- package/lib/presets/custom/angular/deliver/handler.js +12 -5
- package/lib/presets/custom/angular/deliver/prebuild.js +8 -11
- package/lib/presets/custom/astro/deliver/config.js +2 -4
- package/lib/presets/custom/astro/deliver/handler.js +14 -7
- package/lib/presets/custom/astro/deliver/prebuild.js +18 -21
- package/lib/presets/custom/hexo/deliver/config.js +2 -4
- package/lib/presets/custom/hexo/deliver/handler.js +13 -6
- package/lib/presets/custom/hexo/deliver/prebuild.js +18 -21
- package/lib/presets/custom/next/deliver/config.js +2 -6
- package/lib/presets/custom/next/deliver/handler.js +14 -7
- package/lib/presets/custom/next/deliver/prebuild.js +37 -40
- package/lib/presets/custom/react/deliver/config.js +2 -4
- package/lib/presets/custom/react/deliver/handler.js +10 -3
- package/lib/presets/custom/react/deliver/prebuild.js +4 -7
- package/lib/presets/custom/vue/deliver/config.js +2 -4
- package/lib/presets/custom/vue/deliver/handler.js +10 -3
- package/lib/presets/custom/vue/deliver/prebuild.js +66 -10
- package/lib/presets/default/html/deliver/config.js +1 -4
- package/lib/presets/default/html/deliver/handler.js +14 -7
- package/lib/presets/default/html/deliver/prebuild.js +3 -2
- package/lib/presets/default/javascript/compute/config.js +2 -5
- package/lib/presets/default/javascript/compute/handler.js +15 -4
- package/lib/presets/default/javascript/compute/prebuild.js +2 -1
- package/lib/presets/default/typescript/compute/config.js +10 -0
- package/lib/presets/default/typescript/compute/handler.js +16 -0
- package/lib/presets/default/typescript/compute/prebuild.js +7 -0
- package/lib/providers/azion/worker.js +6 -2
- package/lib/utils/exec/exec.utils.js +34 -23
- package/lib/utils/feedback/feedback.utils.js +6 -2
- package/lib/utils/getAbsoluteLibDirPath/getAbsoluteLibDirPath.utils.js +11 -2
- package/lib/utils/getVulcanBuildId/getVulcanBuildId.utils.js +1 -1
- package/lib/utils/index.js +4 -2
- package/lib/utils/overrideStaticOutputPath/overrideStaticOutputPath.utils.js +2 -2
- package/lib/utils/presets/index.js +3 -0
- package/lib/utils/presets/presets.utils.js +169 -0
- package/lib/utils/spinner/index.js +3 -0
- package/lib/utils/spinner/spinner.utils.js +32 -0
- package/package.json +17 -4
- package/examples/hexo-static/yarn.lock +0 -1625
- package/lib/build/polyfills/index.js +0 -0
- package/lib/utils/getPresetsList/getPresetsList.utils.js +0 -50
- package/lib/utils/getPresetsList/index.js +0 -3
- /package/lib/utils/{getPresetsList/getPresetsList.utils.test.js → presets/presets.utils.test.js} +0 -0
package/lib/main.js
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import { join, resolve } from 'path';
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
3
4
|
import { Command } from 'commander';
|
|
4
5
|
import { createPromptModule } from 'inquirer';
|
|
5
6
|
import { satisfies } from 'semver';
|
|
6
|
-
import {
|
|
7
|
-
|
|
7
|
+
import {
|
|
8
|
+
feedback, debug, getAbsoluteLibDirPath,
|
|
9
|
+
} from '#utils';
|
|
10
|
+
import { Messages, FrameworkInitializer } from '#constants';
|
|
8
11
|
|
|
9
12
|
const MIN_NODE_VERSION = '18.0.0';
|
|
10
13
|
|
|
14
|
+
const vulcanLibPath = getAbsoluteLibDirPath();
|
|
15
|
+
const vulcanRootPath = resolve(vulcanLibPath, '..');
|
|
16
|
+
const vulcanPackageJSON = JSON.parse(readFileSync(`${vulcanRootPath}/package.json`, 'utf8'));
|
|
17
|
+
const vulcanVersion = vulcanPackageJSON.version;
|
|
18
|
+
|
|
11
19
|
const debugEnabled = process.env.DEBUG === 'true';
|
|
12
|
-
|
|
20
|
+
|
|
13
21
|
const program = new Command();
|
|
14
22
|
const prompt = createPromptModule();
|
|
15
23
|
|
|
@@ -33,21 +41,231 @@ function validateNodeMinVersion() {
|
|
|
33
41
|
* setVulcanEnvironment();
|
|
34
42
|
*/
|
|
35
43
|
function setVulcanEnvironment() {
|
|
36
|
-
const
|
|
37
|
-
|
|
44
|
+
const vulcanContext = {
|
|
45
|
+
env: 'production',
|
|
46
|
+
root: vulcanRootPath,
|
|
47
|
+
package: vulcanPackageJSON,
|
|
48
|
+
debug: debugEnabled,
|
|
49
|
+
version: vulcanVersion,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const AZION_ENV = process.env.AZION_ENV || vulcanContext.env;
|
|
53
|
+
if (!['production', 'stage', 'local'].includes(AZION_ENV)) {
|
|
38
54
|
feedback.error(Messages.env.errors.invalid_environment);
|
|
39
55
|
process.exit(1);
|
|
40
56
|
} else {
|
|
41
|
-
|
|
57
|
+
vulcanContext.env = AZION_ENV;
|
|
42
58
|
}
|
|
59
|
+
globalThis.vulcan = vulcanContext;
|
|
43
60
|
}
|
|
44
61
|
/**
|
|
45
62
|
* Starts the command-line interface program.
|
|
46
63
|
* @example
|
|
47
|
-
*
|
|
64
|
+
* startVulcanProgram();
|
|
48
65
|
*/
|
|
49
66
|
function startVulcanProgram() {
|
|
50
|
-
program.version(
|
|
67
|
+
program.version(vulcanVersion);
|
|
68
|
+
|
|
69
|
+
program
|
|
70
|
+
.command('init')
|
|
71
|
+
.option('--name <project_name>', 'Project name')
|
|
72
|
+
.description('Initialize a new project')
|
|
73
|
+
.action(async (options) => {
|
|
74
|
+
const AVALIABLE_TEMPLATES = Object.keys(FrameworkInitializer);
|
|
75
|
+
let projectName = options.name;
|
|
76
|
+
|
|
77
|
+
const { frameworkChoice } = await prompt([
|
|
78
|
+
{
|
|
79
|
+
type: 'list',
|
|
80
|
+
name: 'frameworkChoice',
|
|
81
|
+
message: 'Choose a template for your project:',
|
|
82
|
+
choices: AVALIABLE_TEMPLATES,
|
|
83
|
+
},
|
|
84
|
+
]);
|
|
85
|
+
|
|
86
|
+
while (!projectName) {
|
|
87
|
+
// eslint-disable-next-line no-await-in-loop
|
|
88
|
+
const { projectName: inputName } = await prompt([
|
|
89
|
+
{
|
|
90
|
+
type: 'input',
|
|
91
|
+
name: 'projectName',
|
|
92
|
+
message: 'Enter your project name:',
|
|
93
|
+
},
|
|
94
|
+
]);
|
|
95
|
+
|
|
96
|
+
if (inputName) {
|
|
97
|
+
projectName = inputName;
|
|
98
|
+
}
|
|
99
|
+
if (!inputName) {
|
|
100
|
+
feedback.pending(Messages.info.name_required);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const createFrameworkTemplate = FrameworkInitializer[frameworkChoice];
|
|
105
|
+
|
|
106
|
+
if (createFrameworkTemplate) {
|
|
107
|
+
await createFrameworkTemplate(projectName);
|
|
108
|
+
} else {
|
|
109
|
+
feedback.error(Messages.errors.invalid_choice);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
program
|
|
114
|
+
.command('build')
|
|
115
|
+
.description('Build a project for edge deployment')
|
|
116
|
+
.option(
|
|
117
|
+
'--preset <type>',
|
|
118
|
+
'Preset of build target (e.g., vue, next, javascript)',
|
|
119
|
+
'javascript',
|
|
120
|
+
)
|
|
121
|
+
.option(
|
|
122
|
+
'--mode <type>',
|
|
123
|
+
'Mode of build target (e.g., deliver, compute)',
|
|
124
|
+
'compute',
|
|
125
|
+
)
|
|
126
|
+
.option(
|
|
127
|
+
'--entry <string>',
|
|
128
|
+
'Code entrypoint (default: ./main.js)',
|
|
129
|
+
'./main.js',
|
|
130
|
+
)
|
|
131
|
+
.option(
|
|
132
|
+
'--useNodePolyfills',
|
|
133
|
+
'Use node polyfills in build.',
|
|
134
|
+
)
|
|
135
|
+
.action(async ({
|
|
136
|
+
preset, mode, entry, versionId, useNodePolyfills,
|
|
137
|
+
}) => {
|
|
138
|
+
let entryPoint = entry;
|
|
139
|
+
|
|
140
|
+
if (preset === 'javascript') {
|
|
141
|
+
feedback.info('Using main.js as entrypoint by default');
|
|
142
|
+
}
|
|
143
|
+
if (preset === 'typescript') {
|
|
144
|
+
feedback.info('Using main.ts as entrypoint by default');
|
|
145
|
+
entryPoint = './main.ts';
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const BuildDispatcher = (await import('#build')).default;
|
|
149
|
+
const buildDispatcher = new BuildDispatcher(
|
|
150
|
+
preset,
|
|
151
|
+
mode,
|
|
152
|
+
entryPoint,
|
|
153
|
+
versionId,
|
|
154
|
+
useNodePolyfills,
|
|
155
|
+
);
|
|
156
|
+
await buildDispatcher.run();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
program
|
|
160
|
+
.command('dev')
|
|
161
|
+
.description('Start local environment')
|
|
162
|
+
.arguments('[file]')
|
|
163
|
+
.option('-p, --port <port>', 'Specify the port', '3000')
|
|
164
|
+
.action(async (file, options) => {
|
|
165
|
+
const { port } = options;
|
|
166
|
+
const parsedPort = parseInt(port, 10);
|
|
167
|
+
const { server } = await import('#env');
|
|
168
|
+
const entryPoint = file || join(process.cwd(), '.edge/worker.js');
|
|
169
|
+
server(entryPoint, parsedPort);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
program
|
|
173
|
+
.command('presets <type>')
|
|
174
|
+
.description('Create or use defined project presets for Edge')
|
|
175
|
+
.action(async (type) => {
|
|
176
|
+
const { presets } = await import('#utils');
|
|
177
|
+
|
|
178
|
+
let name;
|
|
179
|
+
let mode;
|
|
180
|
+
|
|
181
|
+
switch (type) {
|
|
182
|
+
case 'create':
|
|
183
|
+
// eslint-disable-next-line no-constant-condition
|
|
184
|
+
while (true) {
|
|
185
|
+
// eslint-disable-next-line no-await-in-loop
|
|
186
|
+
const { inputPresetName } = await prompt([
|
|
187
|
+
{
|
|
188
|
+
type: 'input',
|
|
189
|
+
name: 'inputPresetName',
|
|
190
|
+
message: 'Enter the preset name:',
|
|
191
|
+
},
|
|
192
|
+
]);
|
|
193
|
+
|
|
194
|
+
const presetExists = presets
|
|
195
|
+
.getKeys()
|
|
196
|
+
.map((existingPresetName) => existingPresetName.toLowerCase())
|
|
197
|
+
.includes(inputPresetName.toLowerCase());
|
|
198
|
+
|
|
199
|
+
if (presetExists) {
|
|
200
|
+
feedback.error('A preset with this name already exists.');
|
|
201
|
+
} else if (!inputPresetName) {
|
|
202
|
+
feedback.error('Preset name cannot be empty.');
|
|
203
|
+
} else {
|
|
204
|
+
name = inputPresetName;
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// eslint-disable-next-line no-constant-condition
|
|
210
|
+
while (true) {
|
|
211
|
+
// eslint-disable-next-line no-await-in-loop
|
|
212
|
+
const { inputMode } = await prompt([
|
|
213
|
+
{
|
|
214
|
+
type: 'list',
|
|
215
|
+
name: 'inputMode',
|
|
216
|
+
message: 'Choose the mode:',
|
|
217
|
+
choices: ['compute', 'deliver'],
|
|
218
|
+
},
|
|
219
|
+
]);
|
|
220
|
+
|
|
221
|
+
if (['compute', 'deliver'].includes(inputMode)) {
|
|
222
|
+
mode = inputMode;
|
|
223
|
+
break;
|
|
224
|
+
} else {
|
|
225
|
+
feedback.error('Invalid mode. Choose either "compute" or "deliver".');
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
presets.set(name, mode);
|
|
231
|
+
feedback.success(`${name}(${mode}) created with success!`);
|
|
232
|
+
feedback.info(`Now open './lib/presets/${name}/${mode}' and work on your preset.`);
|
|
233
|
+
} catch (error) {
|
|
234
|
+
debug.error(error);
|
|
235
|
+
feedback.error(Messages.errors.folder_creation_failed(name));
|
|
236
|
+
}
|
|
237
|
+
break;
|
|
238
|
+
|
|
239
|
+
case 'ls':
|
|
240
|
+
presets.getBeautify().forEach((preset) => feedback.option(preset));
|
|
241
|
+
break;
|
|
242
|
+
|
|
243
|
+
default:
|
|
244
|
+
feedback.error('Invalid argument provided.');
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
program
|
|
250
|
+
.command('logs <type> [id]')
|
|
251
|
+
.description('Perform operations on function or application logs')
|
|
252
|
+
.option('-w, --watch', 'Show real-time logs')
|
|
253
|
+
.action(async (type, id, options) => {
|
|
254
|
+
const { functions } = await import('#platform');
|
|
255
|
+
const { watch } = options;
|
|
256
|
+
|
|
257
|
+
if (!['function', 'application'].includes(type)) {
|
|
258
|
+
feedback.error(Messages.platform.logs.errors.invalid_log_type);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (type === 'function') {
|
|
263
|
+
functions.actions.showFunctionLogs(id, watch);
|
|
264
|
+
}
|
|
265
|
+
if (type === 'application') {
|
|
266
|
+
feedback.info(Messages.platform.logs.info.unsupported_log_type);
|
|
267
|
+
}
|
|
268
|
+
});
|
|
51
269
|
|
|
52
270
|
if (debugEnabled) {
|
|
53
271
|
program
|
|
@@ -120,51 +338,17 @@ function startVulcanProgram() {
|
|
|
120
338
|
}
|
|
121
339
|
});
|
|
122
340
|
|
|
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
341
|
program
|
|
158
342
|
.command('storage sync')
|
|
159
343
|
.description(
|
|
160
|
-
'Synchronize local .edge/
|
|
344
|
+
'Synchronize local .edge/storage with the Edge Function storage',
|
|
161
345
|
)
|
|
162
346
|
.action(async () => {
|
|
163
347
|
const { core } = await import('#platform');
|
|
164
348
|
const { getVulcanBuildId } = await import('#utils');
|
|
165
349
|
|
|
166
350
|
const versionId = getVulcanBuildId();
|
|
167
|
-
const basePath =
|
|
351
|
+
const basePath = join(process.cwd(), '.edge/storage/');
|
|
168
352
|
await core.actions.uploadStatics(versionId, basePath);
|
|
169
353
|
});
|
|
170
354
|
|
|
@@ -176,7 +360,7 @@ function startVulcanProgram() {
|
|
|
176
360
|
const { getVulcanBuildId } = await import('#utils');
|
|
177
361
|
|
|
178
362
|
const versionId = getVulcanBuildId();
|
|
179
|
-
const staticsPath =
|
|
363
|
+
const staticsPath = join(process.cwd(), '/.edge/storage');
|
|
180
364
|
|
|
181
365
|
const answers = await prompt([
|
|
182
366
|
{
|
|
@@ -201,49 +385,6 @@ function startVulcanProgram() {
|
|
|
201
385
|
});
|
|
202
386
|
}
|
|
203
387
|
|
|
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
388
|
program.parse(process.argv);
|
|
248
389
|
}
|
|
249
390
|
|
|
@@ -251,10 +392,13 @@ try {
|
|
|
251
392
|
if (validateNodeMinVersion()) {
|
|
252
393
|
setVulcanEnvironment();
|
|
253
394
|
startVulcanProgram();
|
|
254
|
-
}
|
|
395
|
+
}
|
|
396
|
+
if (!validateNodeMinVersion()) {
|
|
255
397
|
feedback.error(Messages.errors.invalid_node_version(MIN_NODE_VERSION));
|
|
398
|
+
process.exit(1);
|
|
256
399
|
}
|
|
257
400
|
} catch (error) {
|
|
258
401
|
feedback.error(Messages.errors.unknown_error);
|
|
259
402
|
debug.error(error);
|
|
403
|
+
process.exit(1);
|
|
260
404
|
}
|
|
@@ -45,7 +45,7 @@ async function auth(loginOption, credentials) {
|
|
|
45
45
|
}
|
|
46
46
|
if (responseJSON.token) {
|
|
47
47
|
await vulcan.createVulcanEnv('API_TOKEN', responseJSON.token);
|
|
48
|
-
feedback.success(Messages.platform.auth.success.
|
|
48
|
+
feedback.success(Messages.platform.auth.success.auth_success);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
if (loginOption === 'token') {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { AzionEdges, Messages } from '#constants';
|
|
2
|
-
import { feedback, debug } from '#utils';
|
|
3
|
-
|
|
2
|
+
import { feedback, debug, exec } from '#utils';
|
|
3
|
+
|
|
4
|
+
const isWindows = process.platform === 'win32';
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
* @function
|
|
6
8
|
* @memberof platform
|
|
@@ -38,13 +40,14 @@ function watchPropagation(domain) {
|
|
|
38
40
|
clearInterval(intervalId);
|
|
39
41
|
|
|
40
42
|
let remainingEdgeIndex = currentEdgeIndex + 1;
|
|
41
|
-
const remainingEdgesIntervalId = setInterval(() => {
|
|
43
|
+
const remainingEdgesIntervalId = setInterval(async () => {
|
|
42
44
|
if (remainingEdgeIndex >= AzionEdges.length) {
|
|
43
45
|
clearInterval(remainingEdgesIntervalId);
|
|
44
46
|
f.interactive.complete(
|
|
45
47
|
Messages.platform.propagation.success.propagation_complete,
|
|
46
48
|
);
|
|
47
|
-
open
|
|
49
|
+
await exec(`${isWindows ? 'start ' : 'open '} https://${domain} `);
|
|
50
|
+
|
|
48
51
|
process.exit(0);
|
|
49
52
|
} else {
|
|
50
53
|
const remainingEdge = AzionEdges[remainingEdgeIndex];
|
|
@@ -72,4 +75,4 @@ function watchPropagation(domain) {
|
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
// eslint-disable-next-line import/prefer-default-export
|
|
75
|
-
export { watchPropagation };
|
|
78
|
+
export { watchPropagation };
|
|
@@ -43,7 +43,7 @@ async function uploadStatics(versionId, basePath, currentPath = '') {
|
|
|
43
43
|
if (fileStat.isFile()) {
|
|
44
44
|
const fileContent = await promisify(fs.readFile)(fullFilePath, 'utf8');
|
|
45
45
|
const mimeType = mime.lookup(fullFilePath);
|
|
46
|
-
const staticPath = path.join(currentPath, filePath);
|
|
46
|
+
const staticPath = path.join(currentPath, filePath).replace(/\\/g, '/');
|
|
47
47
|
|
|
48
48
|
try {
|
|
49
49
|
const response = await StorageService.upload(versionId, fileContent, staticPath, mimeType);
|
|
@@ -5,36 +5,19 @@ import eventsService from '../../services/events.service.js';
|
|
|
5
5
|
/**
|
|
6
6
|
*
|
|
7
7
|
* @param {object} log - View logs organized in a box.
|
|
8
|
-
* @param {boolean} [watch=false] - Whether to observe logs in real time.
|
|
9
8
|
*/
|
|
10
|
-
function displayLogInBox(log
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
...log.logs.map((line) => line.length),
|
|
22
|
-
);
|
|
23
|
-
const horizontalLine = '═'.repeat(maxLength + 2);
|
|
24
|
-
|
|
25
|
-
console.log(`╔${horizontalLine}╗`);
|
|
26
|
-
console.log(`║ ${functionIdLine.padEnd(maxLength)} ║`);
|
|
27
|
-
console.log(`║ ${eventIdLine.padEnd(maxLength)} ║`);
|
|
28
|
-
console.log(`║ ${dateLine.padEnd(maxLength)} ║`);
|
|
29
|
-
console.log(`╠${horizontalLine}╣`);
|
|
30
|
-
log.logs.forEach((line) => {
|
|
31
|
-
console.log(`║ ${line.padEnd(maxLength)} ║`);
|
|
9
|
+
function displayLogInBox(log) {
|
|
10
|
+
log.logLines.forEach((line) => {
|
|
11
|
+
try {
|
|
12
|
+
const trimmedLine = line.trim();
|
|
13
|
+
const parsedJSON = JSON.parse(trimmedLine);
|
|
14
|
+
const formattedJSON = JSON.stringify(parsedJSON, null, 2);
|
|
15
|
+
feedback.logs(log.functionId, log.eventId, log.date.toLocaleString()).debug(`\n${formattedJSON}`);
|
|
16
|
+
} catch (error) {
|
|
17
|
+
console.log(error);
|
|
18
|
+
feedback.logs(`Function ID: ${log.functionId}`, log.eventId, log.date.toLocaleString()).debug(`\n${line}`);
|
|
19
|
+
}
|
|
32
20
|
});
|
|
33
|
-
console.log(`╚${horizontalLine}╝`);
|
|
34
|
-
|
|
35
|
-
if (watch) {
|
|
36
|
-
console.log(Messages.platform.logs.info.watch_true);
|
|
37
|
-
}
|
|
38
21
|
}
|
|
39
22
|
|
|
40
23
|
/**
|
|
@@ -60,90 +43,86 @@ function displayLogInBox(log, watch = false) {
|
|
|
60
43
|
* showFunctionLogs();
|
|
61
44
|
*/
|
|
62
45
|
async function showFunctionLogs(functionId, watch = false) {
|
|
63
|
-
let
|
|
46
|
+
let watchStartTime = new Date();
|
|
47
|
+
let logsToDisplay = {};
|
|
64
48
|
|
|
65
49
|
/**
|
|
66
50
|
* Mounts the structure for a console log.
|
|
67
51
|
* @param {object} azionLog - The Azion log event.
|
|
68
|
-
* @param {string} azionLog.id - The ID of the
|
|
52
|
+
* @param {string} azionLog.id - The ID of the event.
|
|
69
53
|
* @param {string} azionLog.ts - The timestamp of the event.
|
|
70
54
|
* @returns {object} - The log event structure.
|
|
71
55
|
* @property {string} eventId - The ID of the event.
|
|
72
|
-
* @property {string}
|
|
73
|
-
* @property {
|
|
56
|
+
* @property {string} functionId - The ID of the function.
|
|
57
|
+
* @property {Date} date - The date object of the event.
|
|
58
|
+
* @property {string[]} logLines - The array of log lines.
|
|
74
59
|
*/
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
60
|
+
function mountEventLogStructure(azionLog) {
|
|
61
|
+
return {
|
|
62
|
+
eventId: azionLog.id,
|
|
63
|
+
functionId: azionLog.functionId,
|
|
64
|
+
date: new Date(azionLog.ts),
|
|
65
|
+
logLines: [],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
81
68
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
* @returns {void}
|
|
85
|
-
*/
|
|
86
|
-
const startPoll = async () => {
|
|
87
|
-
try {
|
|
69
|
+
try {
|
|
70
|
+
const getLogs = async () => {
|
|
88
71
|
const response = await eventsService.getFunctionsLogs(functionId);
|
|
89
|
-
const responseJSON = await response.json();
|
|
90
|
-
const { cellsConsoleEvents } = responseJSON.data;
|
|
91
|
-
const requestSuccess = !!cellsConsoleEvents;
|
|
92
72
|
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
73
|
+
if (response.status === 200) {
|
|
74
|
+
const responseJSON = await response.json();
|
|
75
|
+
|
|
76
|
+
const { cellsConsoleEvents } = responseJSON.data;
|
|
77
|
+
const requestSuccess = !!cellsConsoleEvents;
|
|
98
78
|
|
|
99
|
-
if (!
|
|
100
|
-
|
|
79
|
+
if (!requestSuccess) {
|
|
80
|
+
throw new Error(JSON.stringify(responseJSON));
|
|
101
81
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// eslint-disable-next-line max-len
|
|
107
|
-
const logsGroupedByRequest = cellsConsoleEvents.filter((item) => item.id === nextConsoleLog.id);
|
|
108
|
-
logsGroupedByRequest.forEach((log) => {
|
|
109
|
-
event.logs.push(log.line);
|
|
110
|
-
});
|
|
111
|
-
displayLogInBox(event, watch);
|
|
112
|
-
previousConsoleLogId = nextConsoleLog.id;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (!watch) {
|
|
116
|
-
const logsGroupedByRequest = Object.values(cellsConsoleEvents
|
|
117
|
-
.reduce((result, event) => {
|
|
118
|
-
const { id, line } = event;
|
|
119
|
-
|
|
120
|
-
if (!result[id]) {
|
|
121
|
-
// eslint-disable-next-line no-param-reassign
|
|
122
|
-
result[id] = mountEventLogStructure(event);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
result[id].logs.push(line);
|
|
126
|
-
|
|
127
|
-
return result;
|
|
128
|
-
}, {}));
|
|
129
|
-
|
|
130
|
-
logsGroupedByRequest.forEach((log) => {
|
|
131
|
-
displayLogInBox(log, watch);
|
|
132
|
-
});
|
|
133
|
-
}
|
|
82
|
+
|
|
83
|
+
if (watch) {
|
|
84
|
+
if (watch) {
|
|
85
|
+
feedback.watch(Messages.platform.logs.info.watch_true);
|
|
134
86
|
}
|
|
87
|
+
logsToDisplay = {}; // Clear logsToDisplay on each poll when in watch mode
|
|
135
88
|
}
|
|
89
|
+
|
|
90
|
+
cellsConsoleEvents.forEach((event) => {
|
|
91
|
+
const { id, line, ts } = event;
|
|
92
|
+
const eventDate = new Date(ts);
|
|
93
|
+
|
|
94
|
+
if (watch && eventDate < watchStartTime) {
|
|
95
|
+
return; // Skip logs that are older than watchStartTime
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!logsToDisplay[id]) {
|
|
99
|
+
logsToDisplay[id] = mountEventLogStructure(event);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
logsToDisplay[id].logLines.push(line);
|
|
103
|
+
logsToDisplay[id].date = eventDate;
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
Object.values(logsToDisplay).forEach((log) => {
|
|
107
|
+
displayLogInBox(log, watch);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
watchStartTime = new Date();
|
|
136
111
|
}
|
|
137
112
|
|
|
138
113
|
if (watch) {
|
|
139
|
-
setTimeout(
|
|
114
|
+
setTimeout(getLogs, 3000);
|
|
140
115
|
}
|
|
141
|
-
}
|
|
142
|
-
debug.error(error);
|
|
143
|
-
}
|
|
144
|
-
};
|
|
116
|
+
};
|
|
145
117
|
|
|
146
|
-
|
|
118
|
+
getLogs();
|
|
119
|
+
} catch (error) {
|
|
120
|
+
debug.error(error);
|
|
121
|
+
}
|
|
147
122
|
}
|
|
148
123
|
|
|
124
|
+
process.on('exit', () => {
|
|
125
|
+
feedback.interactive.breakInteractiveChain();
|
|
126
|
+
});
|
|
127
|
+
|
|
149
128
|
export default showFunctionLogs;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @function
|
|
3
|
+
* @name DebugRequest
|
|
4
|
+
* @memberof edge
|
|
5
|
+
* @description
|
|
6
|
+
* The `DebugRequest` function is used to debug and display the details of an incoming request.
|
|
7
|
+
* It takes the request as a parameter and logs the request URL, method, and headers to the console.
|
|
8
|
+
* @param {FetchEvent} event - The incoming FetchEvent object.
|
|
9
|
+
* @returns {Promise<void>} A promise that resolves once the request details are logged.
|
|
10
|
+
*/
|
|
11
|
+
async function DebugRequest(event) {
|
|
12
|
+
const { request } = event;
|
|
13
|
+
const headers = new Headers(request.headers);
|
|
14
|
+
|
|
15
|
+
const requestData = {
|
|
16
|
+
url: request.url,
|
|
17
|
+
method: request.method,
|
|
18
|
+
headers: {},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
headers.forEach((value, name) => {
|
|
22
|
+
requestData.headers[name] = value;
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
return event.console.log(requestData);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default DebugRequest;
|