edge-functions 2.7.2 → 2.7.3

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/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ ### [2.7.3](https://github.com/aziontech/vulcan/compare/v2.7.2...v2.7.3) (2024-05-10)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * restore overwritten features ([#328](https://github.com/aziontech/vulcan/issues/328)) ([99142dd](https://github.com/aziontech/vulcan/commit/99142dd711a7375bf877a5e79d6c8ab3960fa3a3))
7
+
8
+ ### [2.7.3-stage.1](https://github.com/aziontech/vulcan/compare/v2.7.2...v2.7.3-stage.1) (2024-05-10)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * react with vite ([d1eb167](https://github.com/aziontech/vulcan/commit/d1eb1676df781eca28271da29a0fbdfe1e4676a3))
14
+ * react/vue with vite (preset) ([#325](https://github.com/aziontech/vulcan/issues/325)) ([976bb2e](https://github.com/aziontech/vulcan/commit/976bb2e23a8ccd5ffce5ffb85fb7ea812f4be5d6))
15
+ * recover overwritten commits ([#327](https://github.com/aziontech/vulcan/issues/327)) ([47350a4](https://github.com/aziontech/vulcan/commit/47350a4689ee06b891c9d4bf05a28735bae0053d))
16
+ * vite/vue with ts ([5446750](https://github.com/aziontech/vulcan/commit/54467505644c34f60330e14074786ddda6169fea))
17
+
1
18
  ### [2.7.2](https://github.com/aziontech/vulcan/compare/v2.7.1...v2.7.2) (2024-05-10)
2
19
 
3
20
 
@@ -123,7 +123,7 @@ class Dispatcher {
123
123
  * @returns {object} - Preset files
124
124
  */
125
125
  async loadPreset() {
126
- feedback.build.info('Loading build context ...');
126
+ feedback.build.info('Loading build context...');
127
127
 
128
128
  const VALID_BUILD_PRESETS = presets.getKeys();
129
129
  const vulcanRootPath = resolve(this.vulcanLibPath, '..');
@@ -347,11 +347,8 @@ class Dispatcher {
347
347
  'Checking Azion Edge Application configuration file...',
348
348
  );
349
349
  const buildConfigPath = join(process.cwd(), 'azion.config.js');
350
- let vulcanCustomConfigModule = {};
351
- if (existsSync(buildConfigPath)) {
352
- vulcanCustomConfigModule = (await import(buildConfigPath)).default;
353
- }
354
- await generateManifest(vulcanCustomConfigModule, true);
350
+ const vulcanCustomConfigModule = (await import(buildConfigPath)).default;
351
+ await generateManifest(vulcanCustomConfigModule);
355
352
  feedback.build.success('Manifest generated successfully.');
356
353
  }
357
354
 
@@ -5,12 +5,6 @@
5
5
  */
6
6
  const Utils = {};
7
7
 
8
- /**
9
- * @namespace Platform
10
- * @description Contains functions and actions to interact with the edge platform (Azion).
11
- */
12
- const Platform = {};
13
-
14
8
  /**
15
9
  * @namespace Build
16
10
  * @description Represents the structure responsible for pre-build and build processes for the edge.
@@ -48,20 +42,4 @@ const Commands = {};
48
42
  */
49
43
  const Polyfills = {};
50
44
 
51
- /**
52
- * @namespace Services
53
- * @description Azion Platform Services.
54
- */
55
- const Services = {};
56
-
57
- export {
58
- Utils,
59
- Platform,
60
- Build,
61
- Env,
62
- Presets,
63
- Edge,
64
- Polyfills,
65
- Commands,
66
- Services,
67
- };
45
+ export { Utils, Build, Env, Presets, Edge, Polyfills, Commands };
@@ -40,9 +40,9 @@ const methods = {
40
40
  logLevel: 'info',
41
41
  },
42
42
  option: {
43
- badge: '🟣',
44
- color: 'magenta',
45
- label: 'option',
43
+ badge: '🌋',
44
+ color: 'green',
45
+ label: '',
46
46
  logLevel: 'info',
47
47
  },
48
48
  };
@@ -106,33 +106,6 @@ const scopes = {
106
106
  types: methods,
107
107
  }),
108
108
  },
109
- platform: {
110
- ...global.scope('Vulcan', 'Platform'),
111
- interactive: getLogger({
112
- interactive: true,
113
- scope: ['Vulcan', 'Platform'],
114
- types: methods,
115
- }),
116
- },
117
- statics: {
118
- ...global.scope('Vulcan', 'Storage'),
119
- interactive: getLogger({
120
- interactive: true,
121
- scope: ['Vulcan', 'storage'],
122
- types: methods,
123
- }),
124
- },
125
- logs: (scope1, scope2, scope3) => ({
126
- ...global.scope('Azion', `${scope1}`, scope2, scope3),
127
- }),
128
- propagation: {
129
- ...global.scope('Azion', 'Edge Network'),
130
- interactive: getLogger({
131
- interactive: true,
132
- scope: ['Vulcan', 'Azion Network'],
133
- types: methods,
134
- }),
135
- },
136
109
  };
137
110
 
138
111
  /**
@@ -1,14 +1,10 @@
1
- import { existsSync, writeFileSync, readFileSync, mkdirSync, rm } from 'fs';
1
+ import { writeFileSync, existsSync, mkdirSync, readFileSync } from 'fs';
2
2
  import { join } from 'path';
3
3
  import Ajv from 'ajv';
4
4
  import ajvErrors from 'ajv-errors';
5
5
  import addKeywords from 'ajv-keywords';
6
- import os from 'node:os';
7
- import lodash from 'lodash';
8
6
 
9
7
  import azionConfigSchema from './fixtures/schema.js';
10
- import debug from '../debug/debug.utils.js';
11
-
12
8
  /**
13
9
  * Validates the provided configuration against a JSON Schema.
14
10
  * This function uses AJV (Another JSON Schema Validator) to validate the configuration.
@@ -253,34 +249,44 @@ function processManifestConfig(config) {
253
249
  }
254
250
 
255
251
  /**
256
- * Removes the temporary folder used to store the manifest file.
257
- * This function is typically called after the manifest is generated and copied to the edge directory.
252
+ * Loads the Azion deploy configuration from a local file or a provided module.
253
+ * If a custom configuration file 'azion.config.js' exists in the root directory, it takes precedence and is loaded.
254
+ * If the file does not exist, the function will attempt to use the provided configuration module.
255
+ * If no module is provided, a minimal default configuration is returned.
256
+ * @param {string} configPath - The path to the custom configuration file.
257
+ * @param {object} configModule - An alternative configuration module provided as a fallback.
258
+ * @returns {Promise<object>} A promise that resolves to the loaded configuration object.
258
259
  */
259
- function removeTmpFolder() {
260
- const manifestPath = globalThis.vulcan.tmpManifestFile;
261
- if (manifestPath) {
262
- const dirName = manifestPath.substring(0, manifestPath.lastIndexOf('/'));
263
- rm(dirName, { recursive: true }, (err) => {
264
- if (err) {
265
- debug.error(err);
266
- }
267
- });
260
+ async function loadAzionConfig(configPath, configModule) {
261
+ const existCustomAzionConfig = existsSync(configPath); // user created azion.config.js in root directory
262
+
263
+ // the file created has priorty over preset
264
+ if (existCustomAzionConfig) {
265
+ return (await import(configPath)).default;
266
+ }
267
+ if (!existCustomAzionConfig && configModule) {
268
+ return configModule;
268
269
  }
269
- globalThis.vulcan.tmpManifestFile = null;
270
+ return {
271
+ rules: {
272
+ request: [{}], // minimal configuration
273
+ },
274
+ };
270
275
  }
271
276
 
272
277
  /**
273
- * Create the final manifest file to the edge directory.
278
+ * Determines if the project uses the CommonJS module system by default.
279
+ * It checks the 'type' key in the 'package.json' file at the project root.
280
+ * If 'type' is 'commonjs' or absent, returns true. Otherwise, returns false.
281
+ * @returns {boolean} True if the project uses CommonJS, false if it uses ES Modules.
274
282
  */
275
- async function generateFinalManifest() {
276
- const manifestPath = globalThis.vulcan.tmpManifestFile;
277
- const finalManifestPath = join(process.cwd(), '.edge', 'manifest.json');
278
- if (existsSync(manifestPath)) {
279
- writeFileSync(finalManifestPath, readFileSync(manifestPath));
280
- removeTmpFolder();
281
- } else {
282
- throw new Error('Manifest file not found');
283
+ function useCommonJS() {
284
+ const packageJsonPath = join(process.cwd(), 'package.json');
285
+ if (existsSync(packageJsonPath)) {
286
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
287
+ return packageJson.type !== 'module'; // Returns true for 'commonjs' or no 'type' specified
283
288
  }
289
+ return true; // Default to CommonJS if 'package.json' does not exist or 'type' key is absent
284
290
  }
285
291
 
286
292
  /**
@@ -288,64 +294,50 @@ async function generateFinalManifest() {
288
294
  * If an existing manifest is found, it merges the configurations, prioritizing the custom module.
289
295
  * This function is typically called during the prebuild stage to prepare the CDN configuration.
290
296
  * @param {object} configModule - The custom configuration module provided by the user.
291
- * @param {boolean} shouldGenerateFinalManifest - A flag indicating whether the final manifest should be generated after the temporary manifest is created.
292
297
  * @async
293
298
  */
294
- async function generateManifest(
295
- configModule,
296
- shouldGenerateFinalManifest = false,
297
- ) {
298
- const edgeDirPath = join(process.cwd(), '.edge');
299
- const tmpDirPath = join(os.tmpdir(), 'vulcan');
300
-
301
- if (!existsSync(tmpDirPath)) {
302
- mkdirSync(tmpDirPath);
303
- }
299
+ async function generateManifest(configModule) {
300
+ const configPath = join(process.cwd(), 'azion.config.js');
301
+ const dotEdgeDir = join(process.cwd(), '.edge');
302
+ const finalManifestPath = join(dotEdgeDir, 'manifest.json');
304
303
 
305
- let manifestPath = globalThis.vulcan.tmpManifestFile;
306
- if (!manifestPath) {
307
- manifestPath = join(tmpDirPath, `manifest-${new Date().getTime()}.json`);
308
- globalThis.vulcan.tmpManifestFile = manifestPath;
304
+ if (!existsSync(dotEdgeDir)) {
305
+ mkdirSync(dotEdgeDir);
309
306
  }
310
307
 
311
- // preset configuration (existingManifest) have priority over user azion.config.js
312
- let existingManifest = {};
308
+ const AzionConfig = await loadAzionConfig(configPath, configModule);
309
+ const manifest = processManifestConfig(AzionConfig);
313
310
 
314
- if (!existsSync(edgeDirPath)) {
315
- mkdirSync(edgeDirPath);
316
- }
311
+ if (!existsSync(configPath)) {
312
+ const moduleExportStyle = useCommonJS()
313
+ ? 'module.exports ='
314
+ : 'export default';
317
315
 
318
- if (existsSync(manifestPath)) {
319
- const existingManifestRaw = readFileSync(manifestPath, 'utf8');
320
- existingManifest = JSON.parse(existingManifestRaw);
321
- }
322
-
323
- const newManifestConfig = processManifestConfig(configModule);
324
-
325
- // eslint-disable-next-line
326
- function customizer(objValue, srcValue) {
327
- if (Array.isArray(objValue)) {
328
- return objValue.concat(
329
- srcValue.filter(
330
- (srcItem) =>
331
- !objValue.some((objItem) => objItem?.name === srcItem?.name),
332
- ),
333
- );
334
- }
335
- }
316
+ // Function to convert functions to strings in a customized way
317
+ const replacer = (key, value) => {
318
+ if (typeof value === 'function') {
319
+ // Convert the function to a string, adding a unique marker
320
+ return `__FUNCTION_START__${value.toString()}__FUNCTION_END__`;
321
+ }
322
+ return value;
323
+ };
336
324
 
337
- // Merge the new configuration with the existing manifest with priority to the existing manifest
338
- const mergeManifest = lodash.mergeWith(
339
- existingManifest,
340
- newManifestConfig,
341
- customizer,
342
- );
325
+ // Serialize the object with the replacer function
326
+ let jsonString = JSON.stringify(AzionConfig, replacer, 2);
343
327
 
344
- writeFileSync(manifestPath, JSON.stringify(mergeManifest, null, 2));
328
+ // Replace the markers with a clean representation of the function
329
+ jsonString = jsonString.replace(
330
+ /"__FUNCTION_START__(.*?)__FUNCTION_END__"/g,
331
+ (match, p1) => {
332
+ return p1.replace(/\\n/g, ' ').replace(/\\'/g, "'");
333
+ },
334
+ );
345
335
 
346
- if (shouldGenerateFinalManifest) {
347
- await generateFinalManifest();
336
+ // Write the configuration file with the correct module export style
337
+ writeFileSync(configPath, `${moduleExportStyle} ${jsonString};`);
348
338
  }
339
+
340
+ writeFileSync(finalManifestPath, JSON.stringify(manifest, null, 2));
349
341
  }
350
342
 
351
343
  export { processManifestConfig, generateManifest };
@@ -1,113 +1,7 @@
1
1
  import { describe, expect } from '@jest/globals';
2
- import { readFileSync } from 'node:fs';
3
- import mockFs from 'mock-fs';
4
- import {
5
- generateManifest,
6
- processManifestConfig,
7
- } from './generateManifest.utils.js';
2
+ import { processManifestConfig } from './generateManifest.utils.js';
8
3
 
9
4
  describe('Utils - generateManifest', () => {
10
- it('should correctly merge config when generateManifest is called multiple times', async () => {
11
- globalThis.vulcan = {};
12
- const presetConfig = {
13
- rules: {
14
- request: [
15
- {
16
- name: 'Main_Rule',
17
- match: '^\\/',
18
- runFunction: {
19
- path: '.edge/worker.js',
20
- },
21
- },
22
- ],
23
- },
24
- };
25
- const azionConfig = {
26
- origin: [
27
- {
28
- name: 'my origin storage',
29
- type: 'object_storage',
30
- bucket: 'mybucket',
31
- prefix: 'myfolder',
32
- },
33
- ],
34
- rules: {
35
- request: [
36
- {
37
- name: 'my-rule-origin',
38
- match: '/^/_statics/;',
39
- setOrigin: {
40
- name: 'my origin storage',
41
- type: 'object_storage',
42
- },
43
- },
44
- ],
45
- },
46
- };
47
- mockFs({
48
- '.edge/manifest.json': '{}',
49
- });
50
- await generateManifest(presetConfig);
51
- await generateManifest(azionConfig, true);
52
- const manifest = readFileSync('.edge/manifest.json', 'utf8');
53
- mockFs.restore();
54
- expect(JSON.parse(manifest)).toEqual(
55
- expect.objectContaining({
56
- origin: expect.arrayContaining([
57
- {
58
- name: 'my origin storage',
59
- origin_type: 'object_storage',
60
- bucket: 'mybucket',
61
- prefix: 'myfolder',
62
- },
63
- ]),
64
- rules: expect.arrayContaining([
65
- {
66
- name: 'my-rule-origin',
67
- criteria: [
68
- [
69
- {
70
- // eslint-disable-next-line no-template-curly-in-string
71
- variable: '${uri}',
72
- operator: 'matches',
73
- conditional: 'if',
74
- input_value: '/^/_statics/;',
75
- },
76
- ],
77
- ],
78
- behaviors: [
79
- {
80
- name: 'set_origin',
81
- target: 'my origin storage',
82
- },
83
- ],
84
- },
85
- {
86
- name: 'Main_Rule',
87
- criteria: [
88
- [
89
- {
90
- // eslint-disable-next-line no-template-curly-in-string
91
- variable: '${uri}',
92
- operator: 'matches',
93
- conditional: 'if',
94
- input_value: '^\\/',
95
- },
96
- ],
97
- ],
98
- behaviors: [
99
- {
100
- name: 'run_function',
101
- target: '.edge/worker.js',
102
- },
103
- ],
104
- },
105
- ]),
106
- cache: [],
107
- }),
108
- );
109
- });
110
-
111
5
  describe('processManifestConfig', () => {
112
6
  it('should throw an error for invalid mathematical expressions', () => {
113
7
  const azionConfig = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "edge-functions",
3
3
  "type": "module",
4
- "version": "2.7.2",
4
+ "version": "2.7.3",
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": {