edge-functions 1.3.0 → 1.5.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 +4 -0
- package/aliases.js +1 -0
- package/examples/vue-static/yarn.lock +13094 -0
- package/examples/vue-vite-static/yarn.lock +333 -0
- package/jsconfig.json +3 -0
- package/lib/build/dispatcher/dispatcher.js +30 -21
- package/lib/commands/auth.commands.js +85 -0
- package/lib/commands/build.commands.js +47 -0
- package/lib/commands/deploy.commands.js +45 -0
- package/lib/commands/dev.commands.js +26 -0
- package/lib/commands/index.js +13 -0
- package/lib/commands/init.commands.js +61 -0
- package/lib/commands/logs.commands.js +34 -0
- package/lib/commands/presets.commands.js +97 -0
- package/lib/commands/storage.commands.js +22 -0
- package/lib/constants/framework-initializer.constants.js +2 -2
- package/lib/constants/messages/build.messages.js +1 -0
- package/lib/env/polyfills/fetch.polyfills.js +10 -10
- package/lib/env/runtime.env.js +1 -1
- package/lib/env/server.env.js +101 -23
- package/lib/env/vulcan.env.js +43 -21
- package/lib/main.js +36 -261
- package/lib/platform/actions/core/auth.actions.js +3 -3
- package/lib/platform/services/base.service.js +1 -2
- package/lib/presets/custom/next/deliver/prebuild.js +4 -1
- package/lib/presets/custom/vue/deliver/prebuild.js +2 -5
- package/lib/utils/getUrlFromResource/getUrlFromResource.utils.js +16 -0
- package/lib/utils/getUrlFromResource/index.js +3 -0
- package/lib/utils/index.js +2 -0
- package/package.json +4 -3
- package/releaserc.json +1 -0
- package/lib/polyfills/FetchEvent.polyfills.js +0 -13
- package/lib/polyfills/fetch.polyfills.js +0 -39
- package/lib/polyfills/index.js +0 -4
package/lib/main.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { resolve } from 'path';
|
|
3
3
|
import { readFileSync } from 'fs';
|
|
4
4
|
import { Command } from 'commander';
|
|
5
|
-
import { createPromptModule } from 'inquirer';
|
|
6
5
|
import { satisfies } from 'semver';
|
|
7
6
|
import {
|
|
8
7
|
feedback, debug, getAbsoluteLibDirPath,
|
|
9
8
|
} from '#utils';
|
|
10
|
-
import { Messages
|
|
9
|
+
import { Messages } from '#constants';
|
|
11
10
|
|
|
12
11
|
const MIN_NODE_VERSION = '18.0.0';
|
|
13
12
|
|
|
@@ -19,7 +18,6 @@ const vulcanVersion = vulcanPackageJSON.version;
|
|
|
19
18
|
const debugEnabled = process.env.DEBUG === 'true';
|
|
20
19
|
|
|
21
20
|
const program = new Command();
|
|
22
|
-
const prompt = createPromptModule();
|
|
23
21
|
|
|
24
22
|
/**
|
|
25
23
|
* Validates if user is using the minimum Node version
|
|
@@ -27,7 +25,6 @@ const prompt = createPromptModule();
|
|
|
27
25
|
*/
|
|
28
26
|
function validateNodeMinVersion() {
|
|
29
27
|
const isAValidVersion = satisfies(process.version, `>= ${MIN_NODE_VERSION}`);
|
|
30
|
-
|
|
31
28
|
return isAValidVersion;
|
|
32
29
|
}
|
|
33
30
|
|
|
@@ -71,48 +68,18 @@ function startVulcanProgram() {
|
|
|
71
68
|
.option('--name <project_name>', 'Project name')
|
|
72
69
|
.description('Initialize a new project')
|
|
73
70
|
.action(async (options) => {
|
|
74
|
-
const
|
|
75
|
-
|
|
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
|
-
}
|
|
71
|
+
const { initCommand } = await import('#commands');
|
|
72
|
+
await initCommand(options);
|
|
111
73
|
});
|
|
112
74
|
|
|
113
75
|
program
|
|
114
76
|
.command('build')
|
|
115
77
|
.description('Build a project for edge deployment')
|
|
78
|
+
.option(
|
|
79
|
+
'--entry <string>',
|
|
80
|
+
'Code entrypoint (default: ./main.js)',
|
|
81
|
+
'./main.js',
|
|
82
|
+
)
|
|
116
83
|
.option(
|
|
117
84
|
'--preset <type>',
|
|
118
85
|
'Preset of build target (e.g., vue, next, javascript)',
|
|
@@ -123,151 +90,44 @@ function startVulcanProgram() {
|
|
|
123
90
|
'Mode of build target (e.g., deliver, compute)',
|
|
124
91
|
'compute',
|
|
125
92
|
)
|
|
126
|
-
.option(
|
|
127
|
-
'--entry <string>',
|
|
128
|
-
'Code entrypoint (default: ./main.js)',
|
|
129
|
-
'./main.js',
|
|
130
|
-
)
|
|
131
93
|
.option(
|
|
132
94
|
'--useNodePolyfills',
|
|
133
95
|
'Use node polyfills in build.',
|
|
96
|
+
'false',
|
|
134
97
|
)
|
|
135
|
-
.action(async ({
|
|
136
|
-
|
|
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();
|
|
98
|
+
.action(async (options) => {
|
|
99
|
+
const { buildCommand } = await import('#commands');
|
|
100
|
+
await buildCommand(options);
|
|
157
101
|
});
|
|
158
102
|
|
|
159
103
|
program
|
|
160
104
|
.command('dev')
|
|
161
105
|
.description('Start local environment')
|
|
162
|
-
.arguments('[
|
|
106
|
+
.arguments('[entry]')
|
|
163
107
|
.option('-p, --port <port>', 'Specify the port', '3000')
|
|
164
|
-
.action(async (
|
|
165
|
-
const {
|
|
166
|
-
|
|
167
|
-
const { server } = await import('#env');
|
|
168
|
-
const entryPoint = file || join(process.cwd(), '.edge/worker.js');
|
|
169
|
-
server(entryPoint, parsedPort);
|
|
108
|
+
.action(async (entry, options) => {
|
|
109
|
+
const { devCommand } = await import('#commands');
|
|
110
|
+
await devCommand(entry, options);
|
|
170
111
|
});
|
|
171
112
|
|
|
172
113
|
program
|
|
173
|
-
.command('presets <
|
|
114
|
+
.command('presets <command>')
|
|
174
115
|
.description('Create or use defined project presets for Edge')
|
|
175
|
-
.action(async (
|
|
176
|
-
const {
|
|
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
|
-
}
|
|
116
|
+
.action(async (command) => {
|
|
117
|
+
const { presetsCommand } = await import('#commands');
|
|
118
|
+
await presetsCommand(command);
|
|
268
119
|
});
|
|
269
120
|
|
|
270
121
|
if (debugEnabled) {
|
|
122
|
+
program
|
|
123
|
+
.command('logs <type> [id]')
|
|
124
|
+
.description('Perform operations on function or application logs')
|
|
125
|
+
.option('-w, --watch', 'Show real-time logs')
|
|
126
|
+
.action(async (type, id, options) => {
|
|
127
|
+
const { logsCommand } = await import('#commands');
|
|
128
|
+
await logsCommand(type, id, options);
|
|
129
|
+
});
|
|
130
|
+
|
|
271
131
|
program
|
|
272
132
|
.command('auth')
|
|
273
133
|
.option(
|
|
@@ -277,65 +137,8 @@ function startVulcanProgram() {
|
|
|
277
137
|
.option('--token <token>', 'Authenticate using personal token')
|
|
278
138
|
.description('Authenticate the CLI')
|
|
279
139
|
.action(async (options) => {
|
|
280
|
-
const {
|
|
281
|
-
|
|
282
|
-
const authOptions = [
|
|
283
|
-
{
|
|
284
|
-
name: 'Username and Password',
|
|
285
|
-
value: 'password',
|
|
286
|
-
},
|
|
287
|
-
{
|
|
288
|
-
name: 'Personal Token',
|
|
289
|
-
value: 'token',
|
|
290
|
-
},
|
|
291
|
-
];
|
|
292
|
-
|
|
293
|
-
if (options.password) {
|
|
294
|
-
const [username, password] = options.password.split(':');
|
|
295
|
-
core.actions.auth('password', { username, password });
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
if (options.token) {
|
|
299
|
-
const { token } = options;
|
|
300
|
-
core.actions.auth('token', { token });
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (!options.token && !options.password) {
|
|
304
|
-
const { authOption } = await prompt([
|
|
305
|
-
{
|
|
306
|
-
type: 'list',
|
|
307
|
-
name: 'authOption',
|
|
308
|
-
message: 'Choose your login option:',
|
|
309
|
-
choices: authOptions.map((option) => option.name),
|
|
310
|
-
},
|
|
311
|
-
]);
|
|
312
|
-
|
|
313
|
-
if (authOption === 'Username and Password') {
|
|
314
|
-
const { username, password } = await prompt([
|
|
315
|
-
{
|
|
316
|
-
type: 'input',
|
|
317
|
-
name: 'username',
|
|
318
|
-
message: 'Enter your username:',
|
|
319
|
-
},
|
|
320
|
-
{
|
|
321
|
-
type: 'password',
|
|
322
|
-
name: 'password',
|
|
323
|
-
message: 'Enter your password:',
|
|
324
|
-
},
|
|
325
|
-
]);
|
|
326
|
-
core.actions.auth('password', { username, password });
|
|
327
|
-
}
|
|
328
|
-
if (authOption === 'Personal Token') {
|
|
329
|
-
const { token } = await prompt([
|
|
330
|
-
{
|
|
331
|
-
type: 'password',
|
|
332
|
-
name: 'token',
|
|
333
|
-
message: 'Enter your personal token:',
|
|
334
|
-
},
|
|
335
|
-
]);
|
|
336
|
-
core.actions.auth('token', { token });
|
|
337
|
-
}
|
|
338
|
-
}
|
|
140
|
+
const { authCommand } = await import('#commands');
|
|
141
|
+
await authCommand(options);
|
|
339
142
|
});
|
|
340
143
|
|
|
341
144
|
program
|
|
@@ -344,44 +147,16 @@ function startVulcanProgram() {
|
|
|
344
147
|
'Synchronize local .edge/storage with the Edge Function storage',
|
|
345
148
|
)
|
|
346
149
|
.action(async () => {
|
|
347
|
-
const {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
const versionId = getVulcanBuildId();
|
|
351
|
-
const basePath = join(process.cwd(), '.edge/storage/');
|
|
352
|
-
await core.actions.uploadStatics(versionId, basePath);
|
|
150
|
+
const { storageCommand } = await import('#commands');
|
|
151
|
+
await storageCommand();
|
|
353
152
|
});
|
|
354
153
|
|
|
355
154
|
program
|
|
356
155
|
.command('deploy')
|
|
357
156
|
.description('Create and deploy an application with a function')
|
|
358
157
|
.action(async () => {
|
|
359
|
-
const {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
const versionId = getVulcanBuildId();
|
|
363
|
-
const staticsPath = join(process.cwd(), '/.edge/storage');
|
|
364
|
-
|
|
365
|
-
const answers = await prompt([
|
|
366
|
-
{
|
|
367
|
-
type: 'input',
|
|
368
|
-
name: 'applicationName',
|
|
369
|
-
message:
|
|
370
|
-
'Enter the name of the application (optional, leave empty for random name):',
|
|
371
|
-
},
|
|
372
|
-
{
|
|
373
|
-
type: 'input',
|
|
374
|
-
name: 'functionName',
|
|
375
|
-
message:
|
|
376
|
-
'Enter the name of the function (optional, leave empty for random name):',
|
|
377
|
-
},
|
|
378
|
-
]);
|
|
379
|
-
|
|
380
|
-
const { applicationName, functionName } = answers;
|
|
381
|
-
|
|
382
|
-
await core.actions.uploadStatics(versionId, staticsPath);
|
|
383
|
-
const domain = await core.actions.deploy(applicationName, functionName);
|
|
384
|
-
core.actions.watchPropagation(domain);
|
|
158
|
+
const { deployCommand } = await import('#commands');
|
|
159
|
+
await deployCommand();
|
|
385
160
|
});
|
|
386
161
|
}
|
|
387
162
|
|
|
@@ -44,12 +44,12 @@ async function auth(loginOption, credentials) {
|
|
|
44
44
|
feedback.error(responseJSON);
|
|
45
45
|
}
|
|
46
46
|
if (responseJSON.token) {
|
|
47
|
-
await vulcan.createVulcanEnv(
|
|
47
|
+
await vulcan.createVulcanEnv({ API_TOKEN: credentials.token }, 'global');
|
|
48
48
|
feedback.success(Messages.platform.auth.success.auth_success);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
if (loginOption === 'token') {
|
|
52
|
-
await vulcan.createVulcanEnv(
|
|
52
|
+
await vulcan.createVulcanEnv({ API_TOKEN: credentials.token }, 'global');
|
|
53
53
|
const validateTokenJSON = await (await FunctionService.getAll()).json();
|
|
54
54
|
if (validateTokenJSON.results) {
|
|
55
55
|
feedback.success(Messages.platform.auth.success.auth_success);
|
|
@@ -59,8 +59,8 @@ async function auth(loginOption, credentials) {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
} catch (error) {
|
|
62
|
+
feedback.error(Messages.platform.auth.error.auth_failed);
|
|
62
63
|
debug.error(error);
|
|
63
|
-
feedback.success(Messages.platform.auth.error.auth_failed);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -2,7 +2,6 @@ import { vulcan } from '#env';
|
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
|
|
4
4
|
const env = globalThis.vulcan?.env ? globalThis.vulcan.env : 'production';
|
|
5
|
-
|
|
6
5
|
const APIS = {
|
|
7
6
|
local: 'http://localhost:8082',
|
|
8
7
|
stage: 'https://stage-api.azion.net',
|
|
@@ -29,7 +28,7 @@ and returns it as a header object.
|
|
|
29
28
|
* containing the token in the format { headers: { Authorization: 'Token ${value}' } }.
|
|
30
29
|
*/
|
|
31
30
|
const getAuthHeaders = async () => {
|
|
32
|
-
const token = (await vulcan.readVulcanEnv()).API_TOKEN;
|
|
31
|
+
const token = (await vulcan.readVulcanEnv('global')).API_TOKEN;
|
|
33
32
|
return { headers: { Authorization: `Token ${token}` } };
|
|
34
33
|
};
|
|
35
34
|
|
|
@@ -134,7 +134,10 @@ async function getNextConfig() {
|
|
|
134
134
|
*/
|
|
135
135
|
function validateStaticSiteMode(nextConfig) {
|
|
136
136
|
if (!nextConfig.output || nextConfig.output !== 'export') {
|
|
137
|
-
|
|
137
|
+
const errorMessage = `Static site mode not enabled in project config.
|
|
138
|
+
You must add 'output: "export"' in your 'next.config.js' file if you are trying to build a Next.js v >= 13.3 static project.
|
|
139
|
+
For more details go to https://nextjs.org/docs/pages/building-your-application/deploying/static-exports \n`;
|
|
140
|
+
throw Error(errorMessage);
|
|
138
141
|
}
|
|
139
142
|
}
|
|
140
143
|
|
|
@@ -2,7 +2,6 @@ import {
|
|
|
2
2
|
exec, getPackageManager, copyDirectory,
|
|
3
3
|
} from '#utils';
|
|
4
4
|
import { lstat, readFile, rm } from 'fs/promises';
|
|
5
|
-
import { join } from 'path';
|
|
6
5
|
|
|
7
6
|
const packageManager = await getPackageManager();
|
|
8
7
|
const edgeStorageDir = '.edge/storage';
|
|
@@ -41,7 +40,7 @@ async function prebuild() {
|
|
|
41
40
|
const npmArgsForward = packageManager === 'npm' ? '--' : '';
|
|
42
41
|
|
|
43
42
|
let outDir = defaultViteOutDir;
|
|
44
|
-
|
|
43
|
+
const destPath = edgeStorageDir;
|
|
45
44
|
|
|
46
45
|
const isViteProject = await viteConfigExists();
|
|
47
46
|
|
|
@@ -58,9 +57,7 @@ async function prebuild() {
|
|
|
58
57
|
outDir = config.build.outDir;
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
|
|
62
|
-
destPath = join(edgeStorageDir);
|
|
63
|
-
copyDirectory(outDir, srcPath);
|
|
60
|
+
copyDirectory(outDir, destPath);
|
|
64
61
|
rm(outDir, { recursive: true, force: true });
|
|
65
62
|
}
|
|
66
63
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a URL object based on a received resource
|
|
3
|
+
* @param {URL|Request|string} resource received resource.
|
|
4
|
+
* @returns {URL} Generated URL object.
|
|
5
|
+
*/
|
|
6
|
+
function getUrlFromResource(resource) {
|
|
7
|
+
if (typeof resource === 'string') return new URL(resource);
|
|
8
|
+
|
|
9
|
+
if (resource instanceof Request) return new URL(resource.url);
|
|
10
|
+
|
|
11
|
+
if (resource instanceof URL) return resource;
|
|
12
|
+
|
|
13
|
+
throw new Error('Invalid resource input. \'resource\' must be \'URL\', \'Request\' or \'string\'.');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default getUrlFromResource;
|
package/lib/utils/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import overrideStaticOutputPath from './overrideStaticOutputPath/index.js';
|
|
|
12
12
|
import getProjectJsonFile from './getProjectJsonFile/index.js';
|
|
13
13
|
import getPackageVersion from './getPackageVersion/index.js';
|
|
14
14
|
import Spinner from './spinner/index.js';
|
|
15
|
+
import getUrlFromResource from './getUrlFromResource/index.js';
|
|
15
16
|
|
|
16
17
|
export {
|
|
17
18
|
copyDirectory,
|
|
@@ -24,6 +25,7 @@ export {
|
|
|
24
25
|
getPackageVersion,
|
|
25
26
|
getProjectJsonFile,
|
|
26
27
|
getVulcanBuildId,
|
|
28
|
+
getUrlFromResource,
|
|
27
29
|
presets,
|
|
28
30
|
overrideStaticOutputPath,
|
|
29
31
|
readWorkerFile,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "edge-functions",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.0",
|
|
5
5
|
"description": "Tool to launch and build JavaScript/Frameworks. This tool automates polyfills for Edge Computing and assists in creating Workers, notably for the Azion platform.",
|
|
6
6
|
"main": "lib/main.js",
|
|
7
7
|
"bin": {
|
|
@@ -99,7 +99,8 @@
|
|
|
99
99
|
"#env": "./lib/env/index.js",
|
|
100
100
|
"#platform": "./lib/platform/index.js",
|
|
101
101
|
"#constants": "./lib/constants/index.js",
|
|
102
|
-
"#edge": "./lib/platform/edgehooks/index.js"
|
|
102
|
+
"#edge": "./lib/platform/edgehooks/index.js",
|
|
103
|
+
"#commands": "./lib/commands/index.js"
|
|
103
104
|
},
|
|
104
105
|
"repository": {
|
|
105
106
|
"type": "git",
|
|
@@ -109,4 +110,4 @@
|
|
|
109
110
|
"url": "https://github.com/aziontech/vulcan/issues"
|
|
110
111
|
},
|
|
111
112
|
"homepage": "https://github.com/aziontech/vulcan#readme"
|
|
112
|
-
}
|
|
113
|
+
}
|
package/releaserc.json
CHANGED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import primitives from '@edge-runtime/primitives';
|
|
2
|
-
import { feedback } from '#utils';
|
|
3
|
-
|
|
4
|
-
class FetchEventPolyfill extends primitives.FetchEvent {
|
|
5
|
-
constructor(request) {
|
|
6
|
-
super(request);
|
|
7
|
-
this.console = {
|
|
8
|
-
log: (log) => feedback.server.log(log),
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export default FetchEventPolyfill;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { join } from 'path';
|
|
2
|
-
import { readFileSync } from 'fs';
|
|
3
|
-
import mime from 'mime-types';
|
|
4
|
-
import { EdgeRuntime } from 'edge-runtime';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* A custom fetch implementation that adds an additional path to the URL if it starts with 'file://'.
|
|
8
|
-
* This function is used to simulate the local edge environment. When a 'file://' request is made,
|
|
9
|
-
* it behaves as if the request is made from within the edge itself. In this case, an additional
|
|
10
|
-
* '.edge/storage' folder is appended to the URL to represent the edge environment.
|
|
11
|
-
* @param {EdgeRuntime} context - VMContext
|
|
12
|
-
* @param {URL} url - The URL to fetch.
|
|
13
|
-
* @param {object} [options] - The fetch options.
|
|
14
|
-
* @returns {Promise<Response>} A Promise that resolves to the Response object.
|
|
15
|
-
*/
|
|
16
|
-
async function fetchPolyfill(context, url, options) {
|
|
17
|
-
const {
|
|
18
|
-
URL, Headers, Response,
|
|
19
|
-
} = context;
|
|
20
|
-
|
|
21
|
-
const urlOBJ = new URL(url);
|
|
22
|
-
if (urlOBJ.href.startsWith('file://')) {
|
|
23
|
-
// url pathname = /VERSION_ID/filePath
|
|
24
|
-
const file = url.pathname.slice(15);
|
|
25
|
-
const filePath = join(process.cwd(), '.edge', 'storage', file);
|
|
26
|
-
const fileContent = readFileSync(filePath);
|
|
27
|
-
const contentType = mime.lookup(filePath) || 'application/octet-stream';
|
|
28
|
-
|
|
29
|
-
const headers = new Headers();
|
|
30
|
-
headers.append('Content-Type', contentType);
|
|
31
|
-
|
|
32
|
-
const response = new Response(fileContent, { headers, ...options });
|
|
33
|
-
return response;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return fetch(url, options);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export default fetchPolyfill;
|
package/lib/polyfills/index.js
DELETED