edge-functions 1.4.0 → 1.6.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.
Files changed (38) hide show
  1. package/.eslintrc.json +4 -0
  2. package/.github/workflows/release.yml +36 -0
  3. package/.releaserc +31 -0
  4. package/aliases.js +1 -0
  5. package/examples/simple-js-esm/main.js +2 -2
  6. package/jsconfig.json +3 -0
  7. package/lib/build/dispatcher/dispatcher.js +30 -21
  8. package/lib/commands/auth.commands.js +85 -0
  9. package/lib/commands/build.commands.js +47 -0
  10. package/lib/commands/deploy.commands.js +45 -0
  11. package/lib/commands/dev.commands.js +26 -0
  12. package/lib/commands/index.js +13 -0
  13. package/lib/commands/init.commands.js +71 -0
  14. package/lib/commands/logs.commands.js +34 -0
  15. package/lib/commands/presets.commands.js +97 -0
  16. package/lib/commands/storage.commands.js +22 -0
  17. package/lib/constants/framework-initializer.constants.js +2 -2
  18. package/lib/constants/messages/build.messages.js +1 -0
  19. package/lib/constants/messages/global.messages.js +1 -0
  20. package/lib/env/polyfills/fetch.polyfills.js +10 -10
  21. package/lib/env/runtime.env.js +1 -1
  22. package/lib/env/server.env.js +101 -23
  23. package/lib/env/vulcan.env.js +64 -29
  24. package/lib/main.js +29 -254
  25. package/lib/platform/actions/core/auth.actions.js +3 -3
  26. package/lib/platform/services/base.service.js +1 -2
  27. package/lib/presets/custom/next/deliver/prebuild.js +4 -1
  28. package/lib/utils/exec/exec.utils.js +16 -8
  29. package/lib/utils/getUrlFromResource/getUrlFromResource.utils.js +16 -0
  30. package/lib/utils/getUrlFromResource/index.js +3 -0
  31. package/lib/utils/index.js +2 -0
  32. package/package.json +9 -9
  33. package/.github/workflows/major.yml +0 -28
  34. package/.github/workflows/minor.yml +0 -30
  35. package/lib/polyfills/FetchEvent.polyfills.js +0 -13
  36. package/lib/polyfills/fetch.polyfills.js +0 -39
  37. package/lib/polyfills/index.js +0 -4
  38. package/releaserc.json +0 -87
package/.eslintrc.json CHANGED
@@ -65,6 +65,10 @@
65
65
  [
66
66
  "#edge",
67
67
  "./lib/platform/edgehooks/index.js"
68
+ ],
69
+ [
70
+ "#commands",
71
+ "./lib/commands/index.js"
68
72
  ]
69
73
  ],
70
74
  "extensions": [
@@ -0,0 +1,36 @@
1
+ name: Release
2
+ on:
3
+ push:
4
+ branches:
5
+ - main
6
+ - dev
7
+
8
+ permissions:
9
+ contents: read #
10
+
11
+ jobs:
12
+ release:
13
+ name: Release
14
+ runs-on: ubuntu-latest
15
+ permissions:
16
+ contents: write
17
+ issues: write
18
+ pull-requests: write
19
+ id-token: write
20
+ steps:
21
+ - name: Checkout
22
+ uses: actions/checkout@v3
23
+ with:
24
+ fetch-depth: 0
25
+ - name: Setup Node.js
26
+ uses: actions/setup-node@v3
27
+ with:
28
+ node-version: "lts/*"
29
+ - name: Install dependencies
30
+ run: yarn install
31
+ - name: Release
32
+ env:
33
+ GITHUB_TOKEN: ${{ secrets.NPM_TOKEN }}
34
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
35
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
36
+ run: npx semantic-release
package/.releaserc ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "branches": [
3
+ "main",
4
+ {
5
+ "name": "dev",
6
+ "prerelease": true,
7
+ "channel": "stage"
8
+ }
9
+ ],
10
+ "analyzeCommits": {
11
+ "preset": "conventionalcommits",
12
+ "parserOpts": {
13
+ "headerPattern": "^(\\[ISSUE-.*])?\\s?(\\w+):\\s(.*)$",
14
+ "headerCorrespondence": ["scope", "type", "subject"]
15
+ }
16
+ },
17
+ "generateNotes": {
18
+ "preset": "conventionalcommits",
19
+ "parserOpts": {
20
+ "headerPattern": "^(\\[ISSUE-.*])?\\s?(\\w+):\\s(.*)$",
21
+ "headerCorrespondence": ["scope", "type", "subject"]
22
+ },
23
+ "options": {
24
+ "preset": {
25
+ "name": "conventionalchangelog",
26
+ "issuePrefixes": ["ISSUE-"],
27
+ "issueUrlFormat": "https://github.com/aziontech/vulcan/issues/{id}"
28
+ }
29
+ }
30
+ }
31
+ }
package/aliases.js CHANGED
@@ -10,4 +10,5 @@ export default [
10
10
  ['#platform', './lib/platform/index.js'],
11
11
  ['#constants', './lib/constants/index.js'],
12
12
  ['#edge', './lib/platform/edgehooks/index.js'],
13
+ ['#commands', './lib/commands/index.js'],
13
14
  ];
@@ -2,9 +2,9 @@
2
2
 
3
3
  import messages from './messages.js';
4
4
 
5
- const message = messages[Math.floor(Math.random() * messages.length)];
6
-
7
5
  function main(event) {
6
+ const message = messages[Math.floor(Math.random() * messages.length)];
7
+
8
8
  console.log('selected message:', message);
9
9
  console.log('VERSION_ID =', AZION_VERSION_ID);
10
10
 
package/jsconfig.json CHANGED
@@ -34,6 +34,9 @@
34
34
  ],
35
35
  "#edge": [
36
36
  "./lib/platform/edgehooks/index.js"
37
+ ],
38
+ "#commands": [
39
+ "./lib/commands/index.js"
37
40
  ]
38
41
  }
39
42
  }
@@ -8,6 +8,7 @@ import {
8
8
  feedback, debug, generateTimestamp, getAbsoluteLibDirPath, presets,
9
9
  } from '#utils';
10
10
  import { Messages } from '#constants';
11
+ import { vulcan } from '#env';
11
12
 
12
13
  const vulcanLibPath = getAbsoluteLibDirPath();
13
14
  const vulcanRootPath = resolve(vulcanLibPath, '..');
@@ -148,21 +149,24 @@ async function loadBuildContext(preset, entry, mode) {
148
149
  }
149
150
 
150
151
  /**
151
- * Generates a build ID and saves it in the .env file (for deploy).
152
- * @returns {Promise<string>} The generated build ID.
152
+ Create a .env file in the build folder with specified parameters.
153
+ * @param {string} buildId - The version ID to write into the .env file.
154
+ * @param {string} entry - Entrypoint path.
155
+ * @param {string} preset - The preset to write into the .env file.
156
+ * @param {string} mode - The mode to write into the .env file.
157
+ * @param {boolean} useNodePolyfills - The flag to indicates polyfills use.
153
158
  */
154
- function generateBuildId() {
159
+ function createDotEnvFile(buildId) {
155
160
  const projectRoot = process.cwd();
156
161
  const outputPath = isWindows ? fileURLToPath(new URL(`file:///${join(projectRoot, '.edge')}`)) : join(projectRoot, '.edge');
157
-
158
162
  const envFilePath = join(outputPath, '.env');
159
- const BUILD_VERSION___AKA__VERSION_ID = generateTimestamp();
160
- const envContent = `VERSION_ID=${BUILD_VERSION___AKA__VERSION_ID}`;
163
+
164
+ const envContent = [
165
+ `VERSION_ID=${buildId}`,
166
+ ].join('\n');
161
167
 
162
168
  mkdirSync(outputPath, { recursive: true });
163
169
  writeFileSync(envFilePath, envContent);
164
-
165
- return BUILD_VERSION___AKA__VERSION_ID;
166
170
  }
167
171
 
168
172
  /**
@@ -177,15 +181,14 @@ class Dispatcher {
177
181
  * @param {string} preset - The preset for the build.
178
182
  * @param {string} mode - The mode of build target.
179
183
  * @param {string} entry - The entry point for the build.
180
- * @param {string} versionId - The version ID for the build.
181
184
  * @param {boolean} useNodePolyfills - The flag to indicates polyfills use.
182
185
  */
183
- constructor(preset, mode, entry, versionId, useNodePolyfills) {
186
+ constructor(preset, mode, entry, useNodePolyfills) {
184
187
  this.preset = preset;
185
188
  this.mode = mode;
186
189
  this.entry = entry;
187
- this.versionId = versionId;
188
190
  this.useNodePolyfills = useNodePolyfills;
191
+ this.buildId = generateTimestamp();
189
192
  }
190
193
 
191
194
  /**
@@ -199,29 +202,27 @@ class Dispatcher {
199
202
  this.mode,
200
203
  );
201
204
 
202
- const buildId = generateBuildId();
203
-
204
205
  const buildContext = {
205
206
  preset: this.preset,
206
- entry: this.entry,
207
207
  mode: this.mode,
208
- cliVersionId: this.versionId,
209
- useNodePolyfills: this.useNodePolyfills,
210
- buildId,
211
- config,
208
+ entry: this.entry,
212
209
  entryContent,
210
+ config,
211
+ useNodePolyfills: this.useNodePolyfills,
212
+ buildId: this.buildId,
213
213
  };
214
214
 
215
215
  // Run prebuild actions
216
216
  try {
217
217
  feedback.prebuild.info(Messages.build.info.prebuild_starting);
218
218
  await prebuild(buildContext);
219
+ createDotEnvFile(this.buildId);
219
220
  feedback.prebuild.success(Messages.build.success.prebuild_succeeded);
220
221
 
221
222
  feedback.build.info(Messages.build.info.vulcan_build_starting);
222
223
  // create tmp entrypoint
223
224
  const currentDir = process.cwd();
224
- let tempEntryFile = `vulcan-${buildId}.temp.`;
225
+ let tempEntryFile = `vulcan-${this.buildId}.temp.`;
225
226
  tempEntryFile += (this.preset === 'typescript') ? 'ts' : 'js';
226
227
  const tempBuilderEntryPath = join(currentDir, tempEntryFile);
227
228
 
@@ -229,7 +230,7 @@ class Dispatcher {
229
230
 
230
231
  // builder entry
231
232
  config.entry = tempBuilderEntryPath;
232
- config.buildId = buildId;
233
+ config.buildId = this.buildId;
233
234
  config.useNodePolyfills = this.useNodePolyfills;
234
235
 
235
236
  let builder;
@@ -250,9 +251,17 @@ class Dispatcher {
250
251
 
251
252
  // delete .temp files
252
253
  rmSync(tempBuilderEntryPath);
254
+
255
+ await vulcan.createVulcanEnv({
256
+ entry: this.entry,
257
+ preset: this.preset,
258
+ mode: this.mode,
259
+ useNodePolyfills: this.useNodePolyfills,
260
+ }, 'local');
261
+
253
262
  feedback.build.success(Messages.build.success.vulcan_build_succeeded);
254
263
  } catch (error) {
255
- debug.error(error);
264
+ feedback.build.error(error);
256
265
  process.exit(1);
257
266
  }
258
267
  };
@@ -0,0 +1,85 @@
1
+ import { createPromptModule } from 'inquirer';
2
+
3
+ const prompt = createPromptModule();
4
+ /**
5
+ * A command to handle authentication through various methods.
6
+ * @memberof commands
7
+ * @param {object} options - Configuration options for authentication
8
+ * @param {string} [options.password] - Credentials in the format "username:password"
9
+ * @param {string} [options.token] - Personal authentication token
10
+ * @returns {Promise<void>} - A promise that resolves when authentication is complete
11
+ * @example
12
+ *
13
+ * authCommand({
14
+ * password: 'username:password'
15
+ * });
16
+ *
17
+ * authCommand({
18
+ * token: 'your_personal_token'
19
+ * });
20
+ *
21
+ * authCommand({});
22
+ */
23
+ async function authCommand(options) {
24
+ const { core } = await import('#platform');
25
+
26
+ const authOptions = [
27
+ {
28
+ name: 'Username and Password',
29
+ value: 'password',
30
+ },
31
+ {
32
+ name: 'Personal Token',
33
+ value: 'token',
34
+ },
35
+ ];
36
+
37
+ if (options.password) {
38
+ const [username, password] = options.password.split(':');
39
+ core.actions.auth('password', { username, password });
40
+ }
41
+
42
+ if (options.token) {
43
+ const { token } = options;
44
+ core.actions.auth('token', { token });
45
+ }
46
+
47
+ if (!options.token && !options.password) {
48
+ const { authOption } = await prompt([
49
+ {
50
+ type: 'list',
51
+ name: 'authOption',
52
+ message: 'Choose your login option:',
53
+ choices: authOptions.map((option) => option.name),
54
+ },
55
+ ]);
56
+
57
+ if (authOption === 'Username and Password') {
58
+ const { username, password } = await prompt([
59
+ {
60
+ type: 'input',
61
+ name: 'username',
62
+ message: 'Enter your username:',
63
+ },
64
+ {
65
+ type: 'password',
66
+ name: 'password',
67
+ message: 'Enter your password:',
68
+ },
69
+ ]);
70
+ core.actions.auth('password', { username, password });
71
+ }
72
+ if (authOption === 'Personal Token') {
73
+ const { token } = await prompt([
74
+ {
75
+ type: 'password',
76
+ name: 'token',
77
+ message: 'Enter your personal token:',
78
+ },
79
+ ]);
80
+ core.actions.auth('token', { token });
81
+ }
82
+ }
83
+ }
84
+
85
+ export default authCommand;
@@ -0,0 +1,47 @@
1
+ import { feedback } from '#utils';
2
+
3
+ /**
4
+ * A command to initiate the build process.
5
+ * @memberof commands
6
+ * @param {object} options - Configuration options for the build command
7
+ * @param {string} options.entry - The entry point file for the build
8
+ * @param {string} options.preset - Preset to be used (e.g., 'javascript', 'typescript')
9
+ * @param {string} options.mode - Mode in which to run the build (e.g., 'deliver', 'compute')
10
+ * @param {boolean} options.useNodePolyfills - Whether to use Node.js polyfills
11
+ * @returns {Promise<void>} - A promise that resolves when the build is complete
12
+ * @example
13
+ *
14
+ * buildCommand({
15
+ * entry: './src/index.js',
16
+ * preset: 'javascript',
17
+ * mode: 'compute',
18
+ * useNodePolyfills: false
19
+ * });
20
+ */
21
+ async function buildCommand({
22
+ entry, preset, mode, useNodePolyfills,
23
+ }) {
24
+ let entryPoint = null;
25
+
26
+ if (preset === 'javascript') {
27
+ entryPoint = entry;
28
+ feedback.info('Using main.js as entrypoint by default');
29
+ }
30
+ if (preset === 'typescript') {
31
+ if (entry) { entryPoint = entry; }
32
+ feedback.info('Using main.ts as entrypoint by default');
33
+ if (!entry) { entryPoint = './main.ts'; }
34
+ }
35
+
36
+ const BuildDispatcher = (await import('#build')).default;
37
+ const buildDispatcher = new BuildDispatcher(
38
+ preset,
39
+ mode,
40
+ entryPoint,
41
+ useNodePolyfills,
42
+ );
43
+
44
+ await buildDispatcher.run();
45
+ }
46
+
47
+ export default buildCommand;
@@ -0,0 +1,45 @@
1
+ import { join } from 'path';
2
+ import { createPromptModule } from 'inquirer';
3
+
4
+ const prompt = createPromptModule();
5
+ /**
6
+ * A Command to deploy a web application.
7
+ * @memberof commands
8
+ * This command will ask for the application name and function name via the terminal.
9
+ * Then, it will upload static files and deploy the application.
10
+ * Finally, it watches for the propagation of the deployment.
11
+ * @returns {Promise<void>} - A promise that resolves when the deployment is complete.
12
+ * @example
13
+ *
14
+ * deployCommand();
15
+ */
16
+ async function deployCommand() {
17
+ const { core } = await import('#platform');
18
+ const { getVulcanBuildId } = await import('#utils');
19
+
20
+ const versionId = getVulcanBuildId();
21
+ const staticsPath = join(process.cwd(), '/.edge/storage');
22
+
23
+ const answers = await prompt([
24
+ {
25
+ type: 'input',
26
+ name: 'applicationName',
27
+ message:
28
+ 'Enter the name of the application (optional, leave empty for random name):',
29
+ },
30
+ {
31
+ type: 'input',
32
+ name: 'functionName',
33
+ message:
34
+ 'Enter the name of the function (optional, leave empty for random name):',
35
+ },
36
+ ]);
37
+
38
+ const { applicationName, functionName } = answers;
39
+
40
+ await core.actions.uploadStatics(versionId, staticsPath);
41
+ const domain = await core.actions.deploy(applicationName, functionName);
42
+ core.actions.watchPropagation(domain);
43
+ }
44
+
45
+ export default deployCommand;
@@ -0,0 +1,26 @@
1
+ import { join } from 'path';
2
+
3
+ /**
4
+ * A command to start the development server.
5
+ * @memberof commands
6
+ *
7
+ * This function takes a file path and options object as arguments.
8
+ * The file path is the entry point for the development server,
9
+ * and the options object contains the port number.
10
+ * @param {string} entry - The path to the file that serves as the
11
+ * entry point for the development server.
12
+ * @param {object} options - An object containing configuration options.
13
+ * @param {string|number} options.port - The port number on which the development server will run.
14
+ * @returns {Promise<void>} - A promise that resolves when the development server starts.
15
+ * @example
16
+ *
17
+ * devCommand('./path/to/entry.js', { port: 3000 });
18
+ */
19
+ async function devCommand(entry, { port }) {
20
+ const parsedPort = parseInt(port, 10);
21
+ const { server } = await import('#env');
22
+ const entryPoint = entry || join(process.cwd(), '.edge/worker.js');
23
+ server(entryPoint, parsedPort);
24
+ }
25
+
26
+ export default devCommand;
@@ -0,0 +1,13 @@
1
+ import authCommand from './auth.commands.js';
2
+ import buildCommand from './build.commands.js';
3
+ import deployCommand from './deploy.commands.js';
4
+ import devCommand from './dev.commands.js';
5
+ import initCommand from './init.commands.js';
6
+ import logsCommand from './logs.commands.js';
7
+ import presetsCommand from './presets.commands.js';
8
+ import storageCommand from './storage.commands.js';
9
+
10
+ export {
11
+ authCommand, buildCommand, deployCommand, devCommand,
12
+ initCommand, logsCommand, presetsCommand, storageCommand,
13
+ };
@@ -0,0 +1,71 @@
1
+ import { join } from 'path';
2
+ import { existsSync } from 'fs';
3
+ import { createPromptModule } from 'inquirer';
4
+ import { FrameworkInitializer, Messages } from '#constants';
5
+ import { feedback, debug } from '#utils';
6
+ import { vulcan } from '#env';
7
+
8
+ const prompt = createPromptModule();
9
+
10
+ /**
11
+ * Initializes a new project based on the selected framework template.
12
+ * @param {object} options - Configuration options for initialization.
13
+ * @param {string} options.name - Name of the new project.
14
+ * If not provided, the function will prompt for it.
15
+ * @example
16
+ * initCommand({ name: 'my_new_project' });
17
+ */
18
+ async function initComamnd({ name }) {
19
+ try {
20
+ const AVALIABLE_TEMPLATES = Object.keys(FrameworkInitializer);
21
+ let projectName = name;
22
+
23
+ const { frameworkChoice } = await prompt([
24
+ {
25
+ type: 'list',
26
+ name: 'frameworkChoice',
27
+ message: 'Choose a template for your project:',
28
+ choices: AVALIABLE_TEMPLATES,
29
+ },
30
+ ]);
31
+
32
+ while (!projectName) {
33
+ const dirExists = (dirName) => existsSync(join(process.cwd(), dirName));
34
+
35
+ // eslint-disable-next-line no-await-in-loop
36
+ const { projectName: inputName } = await prompt([
37
+ {
38
+ type: 'input',
39
+ name: 'projectName',
40
+ message: 'Enter your project name:',
41
+ },
42
+ ]);
43
+
44
+ if (inputName && !dirExists(inputName)) {
45
+ projectName = inputName;
46
+ } else if (dirExists(inputName)) {
47
+ feedback.pending(
48
+ Messages.errors.folder_name_already_exists(inputName),
49
+ );
50
+ } else {
51
+ feedback.pending(Messages.info.name_required);
52
+ }
53
+ }
54
+
55
+ const createFrameworkTemplate = FrameworkInitializer[frameworkChoice];
56
+ if (createFrameworkTemplate) {
57
+ const dest = join(process.cwd(), projectName);
58
+ await createFrameworkTemplate(projectName);
59
+ await vulcan.createVulcanEnv(
60
+ { preset: frameworkChoice.toLowerCase() },
61
+ dest,
62
+ );
63
+ } else {
64
+ feedback.error(Messages.errors.invalid_choice);
65
+ }
66
+ } catch (error) {
67
+ debug.error(error);
68
+ }
69
+ }
70
+
71
+ export default initComamnd;
@@ -0,0 +1,34 @@
1
+ import { feedback } from '#utils';
2
+ import { Messages } from '#constants';
3
+ /**
4
+ * A comamnd to display logs for a specified function or application.
5
+ * @memberof commands
6
+ * This function allows the user to view logs for a specific function or application.
7
+ * Note that viewing logs for applications is currently unsupported.
8
+ * @param {string} type - The type of entity to show logs for.
9
+ * Accepted values are 'function' and 'application'.
10
+ * @param {string} id - The identifier for the function or application.
11
+ * @param {object} options - Additional options for fetching logs.
12
+ * @param {boolean} options.watch - If true, keep watching the logs and updating in real-time.
13
+ * @returns {Promise<void>} - A promise that resolves when logs are fetched and displayed.
14
+ * @example
15
+ *
16
+ * logsCommand('function', 'functionId123', { watch: true });
17
+ */
18
+ async function logsCommand(type, id, { watch }) {
19
+ const { functions } = await import('#platform');
20
+
21
+ if (!['function', 'application'].includes(type)) {
22
+ feedback.error(Messages.platform.logs.errors.invalid_log_type);
23
+ return;
24
+ }
25
+
26
+ if (type === 'function') {
27
+ functions.actions.showFunctionLogs(id, watch);
28
+ }
29
+ if (type === 'application') {
30
+ feedback.info(Messages.platform.logs.info.unsupported_log_type);
31
+ }
32
+ }
33
+
34
+ export default logsCommand;
@@ -0,0 +1,97 @@
1
+ import { createPromptModule } from 'inquirer';
2
+ import { Messages } from '#constants';
3
+ import { feedback, debug } from '#utils';
4
+
5
+ const prompt = createPromptModule();
6
+
7
+ /**
8
+ * Manages presets for the application.
9
+ * @memberof commands
10
+ * This command allows the user to create or list presets.
11
+ * The user is guided by a series of prompts to enter a preset name and mode.
12
+ * @param {string} command - The operation to be performed:
13
+ * 'create' to create a preset, 'ls' to list presets.
14
+ * @returns {Promise<void>} - A promise that resolves when the action is complete.
15
+ * @example
16
+ *
17
+ * // To create a new preset
18
+ * presetsCommand('create');
19
+ *
20
+ * // To list existing presets
21
+ * presetsCommand('ls');
22
+ */
23
+ async function presetsCommand(command) {
24
+ const { presets } = await import('#utils');
25
+
26
+ let name;
27
+ let mode;
28
+
29
+ switch (command) {
30
+ case 'create':
31
+ // eslint-disable-next-line no-constant-condition
32
+ while (true) {
33
+ // eslint-disable-next-line no-await-in-loop
34
+ const { inputPresetName } = await prompt([
35
+ {
36
+ type: 'input',
37
+ name: 'inputPresetName',
38
+ message: 'Enter the preset name:',
39
+ },
40
+ ]);
41
+
42
+ const presetExists = presets
43
+ .getKeys()
44
+ .map((existingPresetName) => existingPresetName.toLowerCase())
45
+ .includes(inputPresetName.toLowerCase());
46
+
47
+ if (presetExists) {
48
+ feedback.error('A preset with this name already exists.');
49
+ } else if (!inputPresetName) {
50
+ feedback.error('Preset name cannot be empty.');
51
+ } else {
52
+ name = inputPresetName;
53
+ break;
54
+ }
55
+ }
56
+
57
+ // eslint-disable-next-line no-constant-condition
58
+ while (true) {
59
+ // eslint-disable-next-line no-await-in-loop
60
+ const { inputMode } = await prompt([
61
+ {
62
+ type: 'list',
63
+ name: 'inputMode',
64
+ message: 'Choose the mode:',
65
+ choices: ['compute', 'deliver'],
66
+ },
67
+ ]);
68
+
69
+ if (['compute', 'deliver'].includes(inputMode)) {
70
+ mode = inputMode;
71
+ break;
72
+ } else {
73
+ feedback.error('Invalid mode. Choose either "compute" or "deliver".');
74
+ }
75
+ }
76
+
77
+ try {
78
+ presets.set(name, mode);
79
+ feedback.success(`${name}(${mode}) created with success!`);
80
+ feedback.info(`Now open './lib/presets/${name}/${mode}' and work on your preset.`);
81
+ } catch (error) {
82
+ debug.error(error);
83
+ feedback.error(Messages.errors.folder_creation_failed(name));
84
+ }
85
+ break;
86
+
87
+ case 'ls':
88
+ presets.getBeautify().forEach((preset) => feedback.option(preset));
89
+ break;
90
+
91
+ default:
92
+ feedback.error('Invalid argument provided.');
93
+ break;
94
+ }
95
+ }
96
+
97
+ export default presetsCommand;
@@ -0,0 +1,22 @@
1
+ import { join } from 'path';
2
+
3
+ /**
4
+ * A command to uploads static files for a given version of the application.
5
+ * @memberof commands
6
+ * The function identifies the build version, prepares a base path for static files,
7
+ * and uploads these files to the storage of the core platform.
8
+ * @returns {Promise<void>} - A promise that resolves when static files are successfully uploaded.
9
+ * @example
10
+ *
11
+ * storageCommand();
12
+ */
13
+ async function storageCommand() {
14
+ const { core } = await import('#platform');
15
+ const { getVulcanBuildId } = await import('#utils');
16
+
17
+ const versionId = getVulcanBuildId();
18
+ const basePath = join(process.cwd(), '.edge/storage/');
19
+ await core.actions.uploadStatics(versionId, basePath);
20
+ }
21
+
22
+ export default storageCommand;