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
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// Based on https://github.com/remorses/esbuild-plugins/blob/master/node-modules-polyfill/src/index.ts
|
|
2
|
+
|
|
3
|
+
import escapeStringRegexp from 'escape-string-regexp';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
|
|
7
|
+
import builtinsPolyfills from './node-polyfills-paths.js';
|
|
8
|
+
|
|
9
|
+
const NAME = 'node-modules-polyfills';
|
|
10
|
+
const NAMESPACE = NAME;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Remove ending slash
|
|
14
|
+
* @param {string} importee - the imported path
|
|
15
|
+
* @returns {string} the new path without ending slash
|
|
16
|
+
*/
|
|
17
|
+
function removeEndingSlash(importee) {
|
|
18
|
+
if (importee && importee.slice(-1) === '/') {
|
|
19
|
+
return importee.slice(0, -1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return importee;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Generates a template for commonjs with module require
|
|
27
|
+
* @param {string} importPath - the import path
|
|
28
|
+
* @returns {string} the template
|
|
29
|
+
*/
|
|
30
|
+
function commonJsTemplate({ importPath }) {
|
|
31
|
+
return `
|
|
32
|
+
const polyfill = require('${importPath}')
|
|
33
|
+
|
|
34
|
+
if (polyfill && polyfill.default) {
|
|
35
|
+
module.exports = polyfill.default
|
|
36
|
+
for (let k in polyfill) {
|
|
37
|
+
module.exports[k] = polyfill[k]
|
|
38
|
+
}
|
|
39
|
+
} else if (polyfill) {
|
|
40
|
+
module.exports = polyfill
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Plugin to use nodejs polyfills
|
|
49
|
+
* @param {object} options - Options to use with the plugin
|
|
50
|
+
* @returns {object} - the plugin
|
|
51
|
+
*/
|
|
52
|
+
export function NodeModulesPolyfillPlugin(
|
|
53
|
+
options = {},
|
|
54
|
+
) {
|
|
55
|
+
const { namespace = NAMESPACE, name = NAME } = options;
|
|
56
|
+
if (namespace.endsWith('commonjs')) {
|
|
57
|
+
throw new Error(`namespace ${namespace} must not end with commonjs`);
|
|
58
|
+
}
|
|
59
|
+
// this namespace is needed to make ES modules expose their default export to require:
|
|
60
|
+
// require('assert') will give you import('assert').default
|
|
61
|
+
const commonjsNamespace = `${namespace}-commonjs`;
|
|
62
|
+
const polyfilledBuiltins = builtinsPolyfills();
|
|
63
|
+
const polyfilledBuiltinsNames = [...polyfilledBuiltins.keys()];
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
name,
|
|
67
|
+
setup: function setup({ onLoad, onResolve, initialOptions }) {
|
|
68
|
+
// polyfills contain global keyword, it must be defined
|
|
69
|
+
if (initialOptions?.define && !initialOptions.define?.global) {
|
|
70
|
+
// eslint-disable-next-line
|
|
71
|
+
initialOptions.define.global = 'globalThis';
|
|
72
|
+
} else if (!initialOptions?.define) {
|
|
73
|
+
// eslint-disable-next-line
|
|
74
|
+
initialOptions.define = { global: 'globalThis' };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// TODO these polyfill module cannot import anything, is that ok?
|
|
78
|
+
async function loader(
|
|
79
|
+
args,
|
|
80
|
+
) {
|
|
81
|
+
try {
|
|
82
|
+
const argsPath = args.path.replace(/^node:/, '');
|
|
83
|
+
const isCommonjs = args.namespace.endsWith('commonjs');
|
|
84
|
+
|
|
85
|
+
const resolved = polyfilledBuiltins.get(
|
|
86
|
+
removeEndingSlash(argsPath),
|
|
87
|
+
);
|
|
88
|
+
const contents = await (
|
|
89
|
+
await fs.promises.readFile(resolved)
|
|
90
|
+
).toString();
|
|
91
|
+
const resolveDir = path.dirname(resolved);
|
|
92
|
+
|
|
93
|
+
if (isCommonjs) {
|
|
94
|
+
return {
|
|
95
|
+
loader: 'js',
|
|
96
|
+
contents: commonJsTemplate({
|
|
97
|
+
importPath: argsPath,
|
|
98
|
+
}),
|
|
99
|
+
resolveDir,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
loader: 'js',
|
|
104
|
+
contents,
|
|
105
|
+
resolveDir,
|
|
106
|
+
};
|
|
107
|
+
} catch (e) {
|
|
108
|
+
console.error('node-modules-polyfill', e);
|
|
109
|
+
return {
|
|
110
|
+
contents: 'export {}',
|
|
111
|
+
loader: 'js',
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
onLoad({ filter: /.*/, namespace }, loader);
|
|
116
|
+
onLoad({ filter: /.*/, namespace: commonjsNamespace }, loader);
|
|
117
|
+
const filter = new RegExp(
|
|
118
|
+
[
|
|
119
|
+
...polyfilledBuiltinsNames,
|
|
120
|
+
...polyfilledBuiltinsNames.map((n) => `node:${n}`),
|
|
121
|
+
]
|
|
122
|
+
.map(escapeStringRegexp)
|
|
123
|
+
.join('|'), // TODO builtins could end with slash, keep in mind in regex
|
|
124
|
+
);
|
|
125
|
+
async function resolver(args) {
|
|
126
|
+
const argsPath = args.path.replace(/^node:/, '');
|
|
127
|
+
const ignoreRequire = args.namespace === commonjsNamespace;
|
|
128
|
+
|
|
129
|
+
if (!polyfilledBuiltins.has(argsPath)) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const isCommonjs = !ignoreRequire && args.kind === 'require-call';
|
|
134
|
+
|
|
135
|
+
// eslint-disable-next-line
|
|
136
|
+
return {
|
|
137
|
+
namespace: isCommonjs ? commonjsNamespace : namespace,
|
|
138
|
+
path: argsPath,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
onResolve({ filter }, resolver);
|
|
142
|
+
// onResolve({ filter: /.*/, namespace }, resolver)
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export default NodeModulesPolyfillPlugin;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// Taken from https://github.com/ionic-team/rollup-plugin-node-polyfills/blob/master/src/modules.ts
|
|
2
|
+
|
|
3
|
+
import { createRequire } from 'module';
|
|
4
|
+
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generates a Map composed by the module name and location
|
|
9
|
+
* @returns {Map} - the map with module locations
|
|
10
|
+
*/
|
|
11
|
+
function builtinsPolyfills() {
|
|
12
|
+
const libs = new Map();
|
|
13
|
+
|
|
14
|
+
libs.set(
|
|
15
|
+
'process',
|
|
16
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/process-es6'),
|
|
17
|
+
);
|
|
18
|
+
libs.set(
|
|
19
|
+
'buffer',
|
|
20
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/buffer-es6'),
|
|
21
|
+
);
|
|
22
|
+
libs.set(
|
|
23
|
+
'util',
|
|
24
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/util'),
|
|
25
|
+
);
|
|
26
|
+
libs.set('sys', libs.get('util'));
|
|
27
|
+
libs.set(
|
|
28
|
+
'events',
|
|
29
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/events'),
|
|
30
|
+
);
|
|
31
|
+
libs.set(
|
|
32
|
+
'stream',
|
|
33
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/stream'),
|
|
34
|
+
);
|
|
35
|
+
libs.set(
|
|
36
|
+
'path',
|
|
37
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/path'),
|
|
38
|
+
);
|
|
39
|
+
libs.set(
|
|
40
|
+
'querystring',
|
|
41
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/qs'),
|
|
42
|
+
);
|
|
43
|
+
libs.set(
|
|
44
|
+
'punycode',
|
|
45
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/punycode'),
|
|
46
|
+
);
|
|
47
|
+
libs.set(
|
|
48
|
+
'url',
|
|
49
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/url'),
|
|
50
|
+
);
|
|
51
|
+
libs.set(
|
|
52
|
+
'string_decoder',
|
|
53
|
+
require.resolve(
|
|
54
|
+
'rollup-plugin-node-polyfills/polyfills/string-decoder',
|
|
55
|
+
),
|
|
56
|
+
);
|
|
57
|
+
libs.set(
|
|
58
|
+
'http',
|
|
59
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/http'),
|
|
60
|
+
);
|
|
61
|
+
libs.set(
|
|
62
|
+
'https',
|
|
63
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/http'),
|
|
64
|
+
);
|
|
65
|
+
libs.set('os', require.resolve('rollup-plugin-node-polyfills/polyfills/os'));
|
|
66
|
+
libs.set(
|
|
67
|
+
'assert',
|
|
68
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/assert'),
|
|
69
|
+
);
|
|
70
|
+
libs.set(
|
|
71
|
+
'constants',
|
|
72
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/constants'),
|
|
73
|
+
);
|
|
74
|
+
libs.set(
|
|
75
|
+
'_stream_duplex',
|
|
76
|
+
require.resolve(
|
|
77
|
+
'rollup-plugin-node-polyfills/polyfills/readable-stream/duplex',
|
|
78
|
+
),
|
|
79
|
+
);
|
|
80
|
+
libs.set(
|
|
81
|
+
'_stream_passthrough',
|
|
82
|
+
require.resolve(
|
|
83
|
+
'rollup-plugin-node-polyfills/polyfills/readable-stream/passthrough',
|
|
84
|
+
),
|
|
85
|
+
);
|
|
86
|
+
libs.set(
|
|
87
|
+
'_stream_readable',
|
|
88
|
+
require.resolve(
|
|
89
|
+
'rollup-plugin-node-polyfills/polyfills/readable-stream/readable',
|
|
90
|
+
),
|
|
91
|
+
);
|
|
92
|
+
libs.set(
|
|
93
|
+
'_stream_writable',
|
|
94
|
+
require.resolve(
|
|
95
|
+
'rollup-plugin-node-polyfills/polyfills/readable-stream/writable',
|
|
96
|
+
),
|
|
97
|
+
);
|
|
98
|
+
libs.set(
|
|
99
|
+
'_stream_transform',
|
|
100
|
+
require.resolve(
|
|
101
|
+
'rollup-plugin-node-polyfills/polyfills/readable-stream/transform',
|
|
102
|
+
),
|
|
103
|
+
);
|
|
104
|
+
libs.set(
|
|
105
|
+
'console',
|
|
106
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/console'),
|
|
107
|
+
);
|
|
108
|
+
libs.set(
|
|
109
|
+
'zlib',
|
|
110
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/zlib'),
|
|
111
|
+
);
|
|
112
|
+
libs.set(
|
|
113
|
+
'tty',
|
|
114
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/tty'),
|
|
115
|
+
);
|
|
116
|
+
libs.set(
|
|
117
|
+
'domain',
|
|
118
|
+
require.resolve('rollup-plugin-node-polyfills/polyfills/domain'),
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
return libs;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export default builtinsPolyfills;
|
|
@@ -1,26 +1,35 @@
|
|
|
1
|
-
import webpack from 'webpack';
|
|
2
1
|
import { promisify } from 'util';
|
|
2
|
+
import webpack from 'webpack';
|
|
3
|
+
import { merge } from 'webpack-merge';
|
|
4
|
+
|
|
3
5
|
import { feedback, debug } from '#utils';
|
|
4
6
|
import { Messages } from '#constants';
|
|
5
7
|
|
|
6
8
|
import AzionWebpackConfig from './webpack.config.js';
|
|
7
9
|
|
|
8
10
|
class Webpack {
|
|
9
|
-
constructor(
|
|
10
|
-
this.
|
|
11
|
-
this.
|
|
11
|
+
constructor(builderConfig) {
|
|
12
|
+
this.builderConfig = builderConfig;
|
|
13
|
+
this.customConfig = builderConfig.custom;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
run = async () => {
|
|
15
17
|
const runWebpack = promisify(webpack);
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
config.entry = this.
|
|
19
|
+
let config = AzionWebpackConfig;
|
|
20
|
+
config.entry = this.builderConfig.entry;
|
|
19
21
|
config.plugins = [
|
|
20
|
-
new webpack.
|
|
22
|
+
new webpack.DefinePlugin({
|
|
23
|
+
AZION_VERSION_ID: JSON.stringify(this.builderConfig.buildId),
|
|
24
|
+
}),
|
|
21
25
|
...config.plugins,
|
|
22
26
|
];
|
|
23
27
|
|
|
28
|
+
const hasCustomConfig = Object.keys(this.customConfig).length > 0;
|
|
29
|
+
if (hasCustomConfig) {
|
|
30
|
+
config = merge(this.customConfig, config);
|
|
31
|
+
}
|
|
32
|
+
|
|
24
33
|
try {
|
|
25
34
|
const stats = await runWebpack(config);
|
|
26
35
|
|
|
@@ -1,24 +1,10 @@
|
|
|
1
1
|
import webpack from 'webpack';
|
|
2
2
|
import { join } from 'path';
|
|
3
|
-
import {
|
|
4
|
-
import { generateTimestamp } from '#utils';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
5
4
|
|
|
6
5
|
const projectRoot = process.cwd();
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Generates a build ID and saves it in the .env file (for deploy).
|
|
11
|
-
* @returns {Promise<string>} The generated build ID.
|
|
12
|
-
*/
|
|
13
|
-
async function generateBuildId() {
|
|
14
|
-
const envFilePath = join(outputPath, '.env');
|
|
15
|
-
const BUILD_VERSION___AKA__VERSION_ID = generateTimestamp();
|
|
16
|
-
const envContent = `VERSION_ID=${BUILD_VERSION___AKA__VERSION_ID}`;
|
|
17
|
-
|
|
18
|
-
await mkdir(outputPath, { recursive: true });
|
|
19
|
-
await writeFile(envFilePath, envContent);
|
|
20
|
-
return BUILD_VERSION___AKA__VERSION_ID;
|
|
21
|
-
}
|
|
6
|
+
const isWindows = process.platform === 'win32';
|
|
7
|
+
const outputPath = isWindows ? fileURLToPath(new URL(`file:///${join(projectRoot, '.edge')}`)) : join(projectRoot, '.edge');
|
|
22
8
|
|
|
23
9
|
export default {
|
|
24
10
|
output: {
|
|
@@ -27,12 +13,6 @@ export default {
|
|
|
27
13
|
globalObject: 'this',
|
|
28
14
|
},
|
|
29
15
|
mode: 'production',
|
|
30
|
-
target: 'webworker',
|
|
31
|
-
plugins: [
|
|
32
|
-
new webpack.DefinePlugin({
|
|
33
|
-
AZION: {
|
|
34
|
-
VERSION_ID: JSON.stringify(await generateBuildId()),
|
|
35
|
-
},
|
|
36
|
-
}),
|
|
37
|
-
],
|
|
16
|
+
target: ['webworker', 'es2022'],
|
|
17
|
+
plugins: [new webpack.ProgressPlugin()],
|
|
38
18
|
};
|
|
@@ -1,34 +1,28 @@
|
|
|
1
1
|
import { join, resolve } from 'path';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
readFileSync, existsSync, mkdirSync, writeFileSync, rmSync,
|
|
4
|
+
} from 'fs';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { Esbuild, Webpack } from '#bundlers';
|
|
7
|
+
import {
|
|
8
|
+
feedback, debug, generateTimestamp, getAbsoluteLibDirPath, presets,
|
|
9
|
+
} from '#utils';
|
|
6
10
|
import { Messages } from '#constants';
|
|
7
11
|
|
|
8
12
|
const vulcanLibPath = getAbsoluteLibDirPath();
|
|
9
13
|
const vulcanRootPath = resolve(vulcanLibPath, '..');
|
|
14
|
+
const isWindows = process.platform === 'win32';
|
|
10
15
|
|
|
11
16
|
/**
|
|
12
|
-
* Get the
|
|
13
|
-
*
|
|
14
|
-
* @returns {string
|
|
17
|
+
* Get the path corresponding to a specific alias defined in the package.json.
|
|
18
|
+
* @param {string} alias - The desired alias.
|
|
19
|
+
* @returns {string} The path corresponding to the alias.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Get the path corresponding to a specific alias defined in the package.json.
|
|
23
|
+
* @param {string} alias - The desired alias.
|
|
24
|
+
* @returns {string} The path corresponding to the alias.
|
|
15
25
|
*/
|
|
16
|
-
function getValidPresets() {
|
|
17
|
-
const types = ['default', 'custom'];
|
|
18
|
-
const validPresets = [];
|
|
19
|
-
|
|
20
|
-
types.forEach((type) => {
|
|
21
|
-
const presetsPath = join(vulcanLibPath, 'presets', type);
|
|
22
|
-
const directories = readdirSync(presetsPath, { withFileTypes: true })
|
|
23
|
-
.filter((dirent) => dirent.isDirectory())
|
|
24
|
-
.map((dirent) => dirent.name);
|
|
25
|
-
|
|
26
|
-
validPresets.push(...directories);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
return validPresets;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
26
|
/**
|
|
33
27
|
* Get the path corresponding to a specific alias defined in the package.json.
|
|
34
28
|
* @param {string} alias - The desired alias.
|
|
@@ -40,9 +34,12 @@ async function getAliasPath(alias) {
|
|
|
40
34
|
const packageJson = JSON.parse(packageJsonContent);
|
|
41
35
|
let aliasPath = packageJson.imports[`#${alias}`];
|
|
42
36
|
aliasPath = aliasPath.replace('./', `${vulcanRootPath}/`);
|
|
37
|
+
if (isWindows) {
|
|
38
|
+
aliasPath = aliasPath.replace(/[\\/]/g, '\\\\');
|
|
39
|
+
}
|
|
40
|
+
|
|
43
41
|
return aliasPath;
|
|
44
42
|
}
|
|
45
|
-
|
|
46
43
|
/**
|
|
47
44
|
* Move requires and imports to file init
|
|
48
45
|
* @param {string} entryContent - The file content to be fixed.
|
|
@@ -64,7 +61,6 @@ function fixImportsAndRequestsPlace(entryContent) {
|
|
|
64
61
|
|
|
65
62
|
return newCode;
|
|
66
63
|
}
|
|
67
|
-
|
|
68
64
|
/**
|
|
69
65
|
* Get a build context based on arguments
|
|
70
66
|
* @param {string} preset - The build preset.
|
|
@@ -73,14 +69,13 @@ function fixImportsAndRequestsPlace(entryContent) {
|
|
|
73
69
|
* @returns {any} The context that will be used in build.
|
|
74
70
|
*/
|
|
75
71
|
async function loadBuildContext(preset, entry, mode) {
|
|
76
|
-
const VALID_BUILD_PRESETS =
|
|
72
|
+
const VALID_BUILD_PRESETS = presets.getKeys();
|
|
73
|
+
|
|
77
74
|
const validPreset = VALID_BUILD_PRESETS.includes(preset);
|
|
78
75
|
|
|
79
76
|
if (!validPreset) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
VALID_BUILD_PRESETS.concat(','),
|
|
83
|
-
);
|
|
77
|
+
feedback.build.error(Messages.build.error.invalid_preset);
|
|
78
|
+
process.exit(1);
|
|
84
79
|
}
|
|
85
80
|
|
|
86
81
|
let configFilePath;
|
|
@@ -102,8 +97,14 @@ async function loadBuildContext(preset, entry, mode) {
|
|
|
102
97
|
configFilePath = join(modePath, 'config.js');
|
|
103
98
|
prebuildFilePath = join(modePath, 'prebuild.js');
|
|
104
99
|
handlerFilePath = join(modePath, 'handler.js');
|
|
100
|
+
} else {
|
|
101
|
+
feedback.build.error(Messages.build.error.invalid_preset_mode(mode, preset));
|
|
102
|
+
process.exit(1);
|
|
105
103
|
}
|
|
106
104
|
|
|
105
|
+
configFilePath = new URL(`file://${configFilePath}`).href;
|
|
106
|
+
prebuildFilePath = new URL(`file://${prebuildFilePath}`).href;
|
|
107
|
+
|
|
107
108
|
const config = (await import(configFilePath)).default;
|
|
108
109
|
const prebuild = (await import(prebuildFilePath)).default;
|
|
109
110
|
const handlerTemplate = readFileSync(handlerFilePath, 'utf-8');
|
|
@@ -123,10 +124,16 @@ async function loadBuildContext(preset, entry, mode) {
|
|
|
123
124
|
const edgehooksPath = await getAliasPath('edge');
|
|
124
125
|
newEntryContent = newEntryContent.replace('#edge', edgehooksPath);
|
|
125
126
|
|
|
126
|
-
if (mode === '
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
127
|
+
if ((preset === 'javascript' || preset === 'typescript') && (mode === 'compute')) {
|
|
128
|
+
try {
|
|
129
|
+
const filePath = join(process.cwd(), entry);
|
|
130
|
+
const entryContent = readFileSync(filePath, 'utf-8');
|
|
131
|
+
newEntryContent = newEntryContent.replace('__JS_CODE__', entryContent);
|
|
132
|
+
} catch (error) {
|
|
133
|
+
feedback.build.error(Messages.errors.file_doesnt_exist(entry));
|
|
134
|
+
debug.error(error);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
130
137
|
}
|
|
131
138
|
|
|
132
139
|
newEntryContent = fixImportsAndRequestsPlace(newEntryContent);
|
|
@@ -140,6 +147,24 @@ async function loadBuildContext(preset, entry, mode) {
|
|
|
140
147
|
return buildContext;
|
|
141
148
|
}
|
|
142
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Generates a build ID and saves it in the .env file (for deploy).
|
|
152
|
+
* @returns {Promise<string>} The generated build ID.
|
|
153
|
+
*/
|
|
154
|
+
function generateBuildId() {
|
|
155
|
+
const projectRoot = process.cwd();
|
|
156
|
+
const outputPath = isWindows ? fileURLToPath(new URL(`file:///${join(projectRoot, '.edge')}`)) : join(projectRoot, '.edge');
|
|
157
|
+
|
|
158
|
+
const envFilePath = join(outputPath, '.env');
|
|
159
|
+
const BUILD_VERSION___AKA__VERSION_ID = generateTimestamp();
|
|
160
|
+
const envContent = `VERSION_ID=${BUILD_VERSION___AKA__VERSION_ID}`;
|
|
161
|
+
|
|
162
|
+
mkdirSync(outputPath, { recursive: true });
|
|
163
|
+
writeFileSync(envFilePath, envContent);
|
|
164
|
+
|
|
165
|
+
return BUILD_VERSION___AKA__VERSION_ID;
|
|
166
|
+
}
|
|
167
|
+
|
|
143
168
|
/**
|
|
144
169
|
* Class representing a Dispatcher for build operations.
|
|
145
170
|
* @example
|
|
@@ -153,12 +178,14 @@ class Dispatcher {
|
|
|
153
178
|
* @param {string} mode - The mode of build target.
|
|
154
179
|
* @param {string} entry - The entry point for the build.
|
|
155
180
|
* @param {string} versionId - The version ID for the build.
|
|
181
|
+
* @param {boolean} useNodePolyfills - The flag to indicates polyfills use.
|
|
156
182
|
*/
|
|
157
|
-
constructor(preset, mode, entry, versionId) {
|
|
183
|
+
constructor(preset, mode, entry, versionId, useNodePolyfills) {
|
|
158
184
|
this.preset = preset;
|
|
159
185
|
this.mode = mode;
|
|
160
186
|
this.entry = entry;
|
|
161
187
|
this.versionId = versionId;
|
|
188
|
+
this.useNodePolyfills = useNodePolyfills;
|
|
162
189
|
}
|
|
163
190
|
|
|
164
191
|
/**
|
|
@@ -166,45 +193,68 @@ class Dispatcher {
|
|
|
166
193
|
*/
|
|
167
194
|
run = async () => {
|
|
168
195
|
// Load Context based on preset
|
|
169
|
-
feedback.prebuild.info(Messages.build.info.prebuild_starting);
|
|
170
|
-
|
|
171
196
|
const { entryContent, prebuild, config } = await loadBuildContext(
|
|
172
197
|
this.preset,
|
|
173
198
|
this.entry,
|
|
174
199
|
this.mode,
|
|
175
200
|
);
|
|
176
201
|
|
|
177
|
-
|
|
178
|
-
await prebuild(); // TODO: send context to prebuild
|
|
179
|
-
feedback.prebuild.success(Messages.build.success.prebuild_succeeded);
|
|
180
|
-
feedback.prebuild.info(Messages.build.info.vulcan_build_starting);
|
|
181
|
-
|
|
182
|
-
// create tmp entrypoint
|
|
183
|
-
const buildId = generateTimestamp(); // TODO: use versionID
|
|
184
|
-
const currentDir = process.cwd();
|
|
185
|
-
const tempBuilderEntryPath = join(currentDir, `vulcan-${buildId}.temp.js`);
|
|
186
|
-
|
|
187
|
-
await writeFile(tempBuilderEntryPath, entryContent);
|
|
188
|
-
|
|
189
|
-
// builder entry
|
|
190
|
-
config.entry = tempBuilderEntryPath;
|
|
191
|
-
|
|
192
|
-
let builder;
|
|
193
|
-
switch (config.builder) {
|
|
194
|
-
case 'webpack':
|
|
195
|
-
builder = new Webpack(config, config.useNodePolyfills);
|
|
196
|
-
break;
|
|
197
|
-
default:
|
|
198
|
-
builder = new Webpack(config, config.useNodePolyfills);
|
|
199
|
-
break;
|
|
200
|
-
}
|
|
202
|
+
const buildId = generateBuildId();
|
|
201
203
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
+
const buildContext = {
|
|
205
|
+
preset: this.preset,
|
|
206
|
+
entry: this.entry,
|
|
207
|
+
mode: this.mode,
|
|
208
|
+
cliVersionId: this.versionId,
|
|
209
|
+
useNodePolyfills: this.useNodePolyfills,
|
|
210
|
+
buildId,
|
|
211
|
+
config,
|
|
212
|
+
entryContent,
|
|
213
|
+
};
|
|
204
214
|
|
|
205
|
-
//
|
|
206
|
-
|
|
207
|
-
|
|
215
|
+
// Run prebuild actions
|
|
216
|
+
try {
|
|
217
|
+
feedback.prebuild.info(Messages.build.info.prebuild_starting);
|
|
218
|
+
await prebuild(buildContext);
|
|
219
|
+
feedback.prebuild.success(Messages.build.success.prebuild_succeeded);
|
|
220
|
+
|
|
221
|
+
feedback.build.info(Messages.build.info.vulcan_build_starting);
|
|
222
|
+
// create tmp entrypoint
|
|
223
|
+
const currentDir = process.cwd();
|
|
224
|
+
let tempEntryFile = `vulcan-${buildId}.temp.`;
|
|
225
|
+
tempEntryFile += (this.preset === 'typescript') ? 'ts' : 'js';
|
|
226
|
+
const tempBuilderEntryPath = join(currentDir, tempEntryFile);
|
|
227
|
+
|
|
228
|
+
writeFileSync(tempBuilderEntryPath, entryContent);
|
|
229
|
+
|
|
230
|
+
// builder entry
|
|
231
|
+
config.entry = tempBuilderEntryPath;
|
|
232
|
+
config.buildId = buildId;
|
|
233
|
+
config.useNodePolyfills = this.useNodePolyfills;
|
|
234
|
+
|
|
235
|
+
let builder;
|
|
236
|
+
switch (config.builder) {
|
|
237
|
+
case 'webpack':
|
|
238
|
+
builder = new Webpack(config);
|
|
239
|
+
break;
|
|
240
|
+
case 'esbuild':
|
|
241
|
+
builder = new Esbuild(config);
|
|
242
|
+
break;
|
|
243
|
+
default:
|
|
244
|
+
builder = new Webpack(config);
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Run common build
|
|
249
|
+
await builder.run();
|
|
250
|
+
|
|
251
|
+
// delete .temp files
|
|
252
|
+
rmSync(tempBuilderEntryPath);
|
|
253
|
+
feedback.build.success(Messages.build.success.vulcan_build_succeeded);
|
|
254
|
+
} catch (error) {
|
|
255
|
+
debug.error(error);
|
|
256
|
+
process.exit(1);
|
|
257
|
+
}
|
|
208
258
|
};
|
|
209
259
|
}
|
|
210
260
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FrameworkInitializer contains various methods to initialize new projects
|
|
3
|
+
* in different JavaScript frameworks.
|
|
4
|
+
*
|
|
5
|
+
* Each method is an asynchronous function that takes a `projectName` as an argument.
|
|
6
|
+
* This `projectName` is then used to initialize a new project in the respective framework.
|
|
7
|
+
* @namespace FrameworkInitializer
|
|
8
|
+
* @typedef {object} FrameworkInitializer
|
|
9
|
+
* @property {Function} Angular - Initializes a new Angular project.
|
|
10
|
+
* @property {Function} Astro - Initializes a new Astro project.
|
|
11
|
+
* @property {Function} Hexo - Initializes a new Hexo project.
|
|
12
|
+
* @property {Function} Next - Initializes a new Next.js project.
|
|
13
|
+
* @property {Function} React - Initializes a new React project.
|
|
14
|
+
* @property {Function} Vue - Initializes a new Vue project.
|
|
15
|
+
* @property {Function} Vite - Initializes a new Vue project with Vite.
|
|
16
|
+
* @example
|
|
17
|
+
* const { Angular, React } = FrameworkInitializer;
|
|
18
|
+
*
|
|
19
|
+
* // Initialize a new Angular project called 'myAngularProject'
|
|
20
|
+
* await Angular('myAngularProject');
|
|
21
|
+
*
|
|
22
|
+
* // Initialize a new React project called 'myReactProject'
|
|
23
|
+
* await React('myReactProject');
|
|
24
|
+
*/
|
|
25
|
+
import { exec } from '#utils';
|
|
26
|
+
|
|
27
|
+
const FrameworkInitializer = {
|
|
28
|
+
Angular: async (projectName) => {
|
|
29
|
+
await exec(`npx ng new ${projectName}`, 'Angular', false, true);
|
|
30
|
+
},
|
|
31
|
+
Astro: async (projectName) => {
|
|
32
|
+
await exec(`npx create-astro ${projectName}`, 'Astro', false, true);
|
|
33
|
+
},
|
|
34
|
+
Hexo: async (projectName) => {
|
|
35
|
+
await exec(`npx hexo init ${projectName}`, 'Hexo', false, true);
|
|
36
|
+
},
|
|
37
|
+
Next: async (projectName) => {
|
|
38
|
+
await exec(`npx create-next-app ${projectName}`, 'Next', false, true);
|
|
39
|
+
},
|
|
40
|
+
React: async (projectName) => {
|
|
41
|
+
await exec(`npx create-react-app ${projectName}`, 'React', false, true);
|
|
42
|
+
},
|
|
43
|
+
Vue: async (projectName) => {
|
|
44
|
+
await exec(`npx vue create ${projectName}`, 'Vue', false, true);
|
|
45
|
+
},
|
|
46
|
+
Vite: async (projectName) => {
|
|
47
|
+
await exec(`npx create-vue ${projectName}`, 'Vue/Vite', false, true);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default FrameworkInitializer;
|
package/lib/constants/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import RuntimeApis from './runtime-apis.constants.js';
|
|
2
2
|
import AzionEdges from './azion-edges.constants.js';
|
|
3
3
|
import Messages from './messages/index.js';
|
|
4
|
+
import FrameworkInitializer from './framework-initializer.constants.js';
|
|
4
5
|
|
|
5
|
-
export {
|
|
6
|
+
export {
|
|
7
|
+
AzionEdges, RuntimeApis, Messages, FrameworkInitializer,
|
|
8
|
+
};
|