edge-functions 2.5.0 → 2.6.0-stage.1
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 +7 -0
- package/README.md +11 -7
- package/docs/nextjs.md +66 -0
- package/docs/overview.md +8 -1
- package/docs/presets.md +2 -0
- package/lib/build/bundlers/polyfills/polyfills-manager.js +5 -1
- package/lib/env/polyfills/azion/network-list/context/index.js +3 -0
- package/lib/env/polyfills/azion/network-list/context/network-list.context.js +232 -0
- package/lib/env/polyfills/azion/network-list/context/network-list.context.test.js +44 -0
- package/lib/env/polyfills/azion/network-list/index.js +3 -0
- package/lib/env/polyfills/azion/network-list/network-list.polyfills.js +16 -0
- package/lib/env/polyfills/index.js +2 -0
- package/lib/env/runtime.env.js +4 -0
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [2.6.0-stage.1](https://github.com/aziontech/vulcan/compare/v2.5.0...v2.6.0-stage.1) (2024-03-05)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* add support to network list api ([#260](https://github.com/aziontech/vulcan/issues/260)) ([79c20be](https://github.com/aziontech/vulcan/commit/79c20be283c32829a9eb2a1db2b0996bb3246d83))
|
|
7
|
+
|
|
1
8
|
## [2.5.0](https://github.com/aziontech/vulcan/compare/v2.4.0...v2.5.0) (2024-02-28)
|
|
2
9
|
|
|
3
10
|
|
package/README.md
CHANGED
|
@@ -91,7 +91,7 @@ Here's a detailed breakdown of the configuration properties available in `vulcan
|
|
|
91
91
|
|
|
92
92
|
**Type:** String
|
|
93
93
|
|
|
94
|
-
**Description:**
|
|
94
|
+
**Description:**
|
|
95
95
|
This represents the primary entry point for your application, where the building process begins.
|
|
96
96
|
|
|
97
97
|
**Note:** `Entry` will be ignored for jamstack solutions.
|
|
@@ -100,28 +100,28 @@ This represents the primary entry point for your application, where the building
|
|
|
100
100
|
|
|
101
101
|
**Type:** String ('esbuild' or 'webpack')
|
|
102
102
|
|
|
103
|
-
**Description:**
|
|
103
|
+
**Description:**
|
|
104
104
|
Defines which build tool to use. The available options are `esbuild` and `webpack`.
|
|
105
105
|
|
|
106
106
|
### UseNodePolyfills
|
|
107
107
|
|
|
108
108
|
**Type:** Boolean
|
|
109
109
|
|
|
110
|
-
**Description:**
|
|
110
|
+
**Description:**
|
|
111
111
|
Determines whether Node.js polyfills should be applied. This is useful for projects that leverage specific Node.js functionality but target environments without these built-in features. The use of useNodePolyfills is ignored when used in mode `deliver` presets, as Node.js features must be resolved at build time by the framework process itself.
|
|
112
112
|
|
|
113
113
|
### UseOwnWorker
|
|
114
114
|
|
|
115
115
|
**Type:** Boolean
|
|
116
116
|
|
|
117
|
-
**Description:**
|
|
117
|
+
**Description:**
|
|
118
118
|
This flag indicates that the constructed code inserts its own worker expression, such as `addEventListener("fetch")` or similar, without the need to inject a provider.
|
|
119
119
|
|
|
120
120
|
### Preset
|
|
121
121
|
|
|
122
122
|
**Type:** Object
|
|
123
123
|
|
|
124
|
-
**Description:**
|
|
124
|
+
**Description:**
|
|
125
125
|
Provides preset-specific configurations.
|
|
126
126
|
|
|
127
127
|
- **Name (Type: String):** Refers to the preset name, e.g., "vue" or "next".
|
|
@@ -131,7 +131,7 @@ Provides preset-specific configurations.
|
|
|
131
131
|
|
|
132
132
|
**Type:** Object
|
|
133
133
|
|
|
134
|
-
**Description:**
|
|
134
|
+
**Description:**
|
|
135
135
|
Configurations related to the in-memory filesystem.
|
|
136
136
|
|
|
137
137
|
- **InjectionDirs (Type: Array of Strings):** Directories to be injected into memory for runtime access via the fs API.
|
|
@@ -142,7 +142,7 @@ Configurations related to the in-memory filesystem.
|
|
|
142
142
|
|
|
143
143
|
**Type:** Object
|
|
144
144
|
|
|
145
|
-
**Description:**
|
|
145
|
+
**Description:**
|
|
146
146
|
Allows you to extend the capabilities of the chosen bundler (either `webpack` or `esbuild`) with custom plugins or configurations.
|
|
147
147
|
|
|
148
148
|
- **Plugins (Type: Object):** Add your custom plugins for your chosen bundler here.
|
|
@@ -177,8 +177,12 @@ module.exports = {
|
|
|
177
177
|
|
|
178
178
|
- [Overview](docs/overview.md)
|
|
179
179
|
- [Presets](docs/presets.md)
|
|
180
|
+
- [Nextjs](docs/nextjs.md)
|
|
180
181
|
- [Rust/Wasm example](examples/rust-wasm-yew-ssr/)
|
|
181
182
|
- [Emscripten/Wasm example](examples/emscripten-wasm/)
|
|
183
|
+
- [Env vars example](examples/simple-js-env-vars)
|
|
184
|
+
- [Storage example](examples/simple-js-esm-storage)
|
|
185
|
+
- [Firewall example](examples/simple-js-firewall-event)
|
|
182
186
|
|
|
183
187
|
## Wasm Notes
|
|
184
188
|
|
package/docs/nextjs.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Nextjs Support
|
|
2
|
+
|
|
3
|
+
Vulcan supports Nextjs in compute and deliver modes.
|
|
4
|
+
|
|
5
|
+
## Deliver
|
|
6
|
+
|
|
7
|
+
Static site delivered by edge without a function.
|
|
8
|
+
Check static examples in [Nextjs examples dir](/examples//next/) for more details.
|
|
9
|
+
|
|
10
|
+
### References
|
|
11
|
+
|
|
12
|
+
- [Pages Router - Static Export](https://nextjs.org/docs/pages/building-your-application/deploying/static-exports)
|
|
13
|
+
- [App Router - Static Export](https://nextjs.org/docs/app/building-your-application/deploying/static-exports)
|
|
14
|
+
|
|
15
|
+
## Compute
|
|
16
|
+
|
|
17
|
+
In compute mode the nextjs handler uses a routing system (based on vercel multiple steps routing) to handle the request.
|
|
18
|
+
|
|
19
|
+
After a route match in the routing system takes one of these actions:
|
|
20
|
+
|
|
21
|
+
- deliver a static;
|
|
22
|
+
- make a request override;
|
|
23
|
+
- call a builded edge module;
|
|
24
|
+
- call a node custom server;
|
|
25
|
+
|
|
26
|
+
This solution was created based on fastly ([next-compute-js v1](https://github.com/fastly/next-compute-js)) and cloudflare ([next-on-pages](https://github.com/cloudflare/next-on-pages)) Nextjs solutions.
|
|
27
|
+
|
|
28
|
+
Check edge or node examples in [Nextjs examples dir](/examples//next/) for more details.
|
|
29
|
+
|
|
30
|
+
### Supported Features
|
|
31
|
+
|
|
32
|
+
| Runtime | Versions | Format/Router | Feature |
|
|
33
|
+
| ------- | ---------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
34
|
+
| Edge | 12.2.x, 12.3.x | Pages Router | Static Pages |
|
|
35
|
+
| | | | SSR |
|
|
36
|
+
| | | | SSG |
|
|
37
|
+
| | | | Edge API Routes |
|
|
38
|
+
| | | | Dynamic Routes |
|
|
39
|
+
| | | | Middleware (rewrite, redirect, continue to response, set request header, throw error, set response header, set response cookie) |
|
|
40
|
+
| | | | Next configs (rewrite before files, rewrite after files, rewrite fallback, redirects, header definition) |
|
|
41
|
+
| | | | i18n routing |
|
|
42
|
+
| Edge | 13.0.x, 13.1.x, 13.2.x, 13.3.x, 13.4.x, 13.5.x | Pages Router | Static Pages |
|
|
43
|
+
| | | | SSR |
|
|
44
|
+
| | | | SSG |
|
|
45
|
+
| | | | Edge API Routes |
|
|
46
|
+
| | | | Dynamic Routes |
|
|
47
|
+
| | | | Middleware (rewrite, redirect, continue to response, set request header, throw error, return response, set response header, set response cookie) |
|
|
48
|
+
| | | | Next configs (rewrite before files, rewrite after files, rewrite fallback, redirects, header definition) |
|
|
49
|
+
| | | | i18n routing |
|
|
50
|
+
| | | | Custom Errors |
|
|
51
|
+
| Edge | 13.0.x, 13.1.x, 13.2.x, 13.3.x, 13.4.x, 13.5.x | App Router | App router (basic structure, routing, layouts) |
|
|
52
|
+
| | | | Server Components |
|
|
53
|
+
| | | | Route Handlers |
|
|
54
|
+
| | | | Dynamic Routes |
|
|
55
|
+
| | | | Middleware (rewrite, redirect, continue to response, set request header, throw error, return response, set response header, set response cookie) |
|
|
56
|
+
| | | | Next configs (rewrite before files, rewrite after files, redirects, header definition) |
|
|
57
|
+
| | | | Internationalization |
|
|
58
|
+
| | | | Custom Errors (error.js and not-found.js) |
|
|
59
|
+
| Node | 12.3.x | Pages Router | Static Pages |
|
|
60
|
+
| | | | SSR |
|
|
61
|
+
| | | | SSG |
|
|
62
|
+
| | | | API Routes |
|
|
63
|
+
| | | | Dynamic Routes |
|
|
64
|
+
| | | | Next configs (rewrite before files, rewrite after files, rewrite fallback, redirects, header definition) |
|
|
65
|
+
| | | | i18n routing |
|
|
66
|
+
| | | | Custom Errors |
|
package/docs/overview.md
CHANGED
|
@@ -8,7 +8,8 @@ flowchart LR
|
|
|
8
8
|
A[Trigger] -->|args| B(Dispatcher)
|
|
9
9
|
B --> C(Prebuild)
|
|
10
10
|
C -->|args| D(Common Build)
|
|
11
|
-
D --> E
|
|
11
|
+
D --> E(Postbuild)
|
|
12
|
+
E --> F[Artifacts]
|
|
12
13
|
```
|
|
13
14
|
|
|
14
15
|
### Trigger
|
|
@@ -35,6 +36,10 @@ Polyfills can be used to generate the worker(s) file(s).
|
|
|
35
36
|
|
|
36
37
|
Some configs can be passed to the builder but if user tries to override `azion worker configs` this passed configs will be ignored.
|
|
37
38
|
|
|
39
|
+
### Post Build
|
|
40
|
+
|
|
41
|
+
Optional step to run post build actions after common build (bundlers action).
|
|
42
|
+
|
|
38
43
|
### Artifacts
|
|
39
44
|
|
|
40
45
|
The **'.edge'** folder will be generated representing the edge locally. Files generated to run on the infrastructure:
|
|
@@ -42,3 +47,5 @@ The **'.edge'** folder will be generated representing the edge locally. Files ge
|
|
|
42
47
|
- JS worker(s) => '.edge/workers.js';
|
|
43
48
|
- Assets => '.edge/storage/\*';
|
|
44
49
|
- Environment variables => '.edge/.env'.
|
|
50
|
+
|
|
51
|
+
The **'.vulcan'** file also will be generated. This file contains build infos that can be used by local env or other tools.
|
package/docs/presets.md
CHANGED
|
@@ -37,6 +37,8 @@ Each preset is made up of three primary files: `config.js`, `prebuild.js`, and `
|
|
|
37
37
|
- mountSSG: This function takes the request and sets up routes according to the SSG structure.
|
|
38
38
|
- ErrorHTML: This edgehook provides a return of an HTML template showing the error and the description passed as a parameter. You can pass the captured error as the third parameter, and it will be displayed on the screen (it's a good way to debug).
|
|
39
39
|
|
|
40
|
+
4. `postbuild.js`: this file is optional. Here you can run actions after the common build done by bundlers.
|
|
41
|
+
|
|
40
42
|
# How to add a new preset
|
|
41
43
|
|
|
42
44
|
Here's a step-by-step guide on how to add a new preset in Vulcan:
|
|
@@ -161,9 +161,13 @@ class PolyfillsManager {
|
|
|
161
161
|
|
|
162
162
|
// globalThis.Azion
|
|
163
163
|
this.setExternal(
|
|
164
|
-
'Azion',
|
|
164
|
+
'Azion.env',
|
|
165
165
|
`${externalPolyfillsPath}/azion/env-vars/env-vars.polyfills.js`,
|
|
166
166
|
);
|
|
167
|
+
this.setExternal(
|
|
168
|
+
'Azion.networkList',
|
|
169
|
+
`${externalPolyfillsPath}/azion/network-list/network-list.polyfills.js`,
|
|
170
|
+
);
|
|
167
171
|
|
|
168
172
|
return {
|
|
169
173
|
libs: this.libs,
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import ipLib from 'ip';
|
|
2
|
+
import nodePath from 'node:path';
|
|
3
|
+
import { readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* This class is a VM context (NETWORK_LIST_CONTEXT) to handle with network list
|
|
11
|
+
* @class NetworkListContext
|
|
12
|
+
* @description Class to manage the network list
|
|
13
|
+
*/
|
|
14
|
+
class NetworkListContext {
|
|
15
|
+
/**
|
|
16
|
+
* Cache Dynamic Import flag - If true, the file will be reloaded every time default: true
|
|
17
|
+
*/
|
|
18
|
+
#cacheDynamicImport;
|
|
19
|
+
|
|
20
|
+
#networkList = [];
|
|
21
|
+
|
|
22
|
+
#workDir = '.edge';
|
|
23
|
+
|
|
24
|
+
#configFile = 'azion.config.js';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Creates an instance of NetworkListContext.
|
|
28
|
+
* @param {boolean} [cacheDynamicImport=true] - Cache Dynamic Import flag - If false, the file will be reloaded every time default: true
|
|
29
|
+
*/
|
|
30
|
+
constructor(cacheDynamicImport = true) {
|
|
31
|
+
this.#cacheDynamicImport = cacheDynamicImport;
|
|
32
|
+
this.#init();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Check if the network list contains the value
|
|
37
|
+
* @param {string} networkListId - The network list id
|
|
38
|
+
* @param {string} value - The value to check
|
|
39
|
+
* @returns {boolean} - Return true if the network list contains the value
|
|
40
|
+
* @memberof NetworkListContext
|
|
41
|
+
*/
|
|
42
|
+
contains(networkListId, value) {
|
|
43
|
+
const network = this.#networkList.find(
|
|
44
|
+
(networkItem) =>
|
|
45
|
+
parseInt(networkItem.id, 10) === parseInt(networkListId, 10),
|
|
46
|
+
);
|
|
47
|
+
return this.#containsType(network, value);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
#containsType(network, value) {
|
|
51
|
+
switch (network?.listType) {
|
|
52
|
+
case 'ip_cidr':
|
|
53
|
+
return this.#networkCIDR(value, network);
|
|
54
|
+
case 'asn':
|
|
55
|
+
return this.#networkAsn(value, network);
|
|
56
|
+
case 'countries':
|
|
57
|
+
return this.#networkCountries(value, network);
|
|
58
|
+
default:
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// eslint-disable-next-line class-methods-use-this
|
|
64
|
+
#networkCIDR(ipAddress, network) {
|
|
65
|
+
const listContent = network?.listContent;
|
|
66
|
+
if (!listContent || listContent.length === 0) return false;
|
|
67
|
+
return listContent.some((currentIp) => {
|
|
68
|
+
if (currentIp.includes('/')) {
|
|
69
|
+
return ipLib.cidrSubnet(currentIp).contains(ipAddress);
|
|
70
|
+
}
|
|
71
|
+
return currentIp === ipAddress;
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// eslint-disable-next-line class-methods-use-this
|
|
76
|
+
#networkAsn(asn, network) {
|
|
77
|
+
const listContent = network?.listContent;
|
|
78
|
+
if (!listContent || listContent.length === 0) return false;
|
|
79
|
+
return listContent.some((currentAsn) => {
|
|
80
|
+
return parseInt(currentAsn, 10) === parseInt(asn, 10);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// eslint-disable-next-line class-methods-use-this
|
|
85
|
+
#networkCountries(country, network) {
|
|
86
|
+
const listContent = network?.listContent;
|
|
87
|
+
if (!listContent || listContent.length === 0) return false;
|
|
88
|
+
return listContent.some((currentCountry) => {
|
|
89
|
+
return currentCountry === country;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// eslint-disable-next-line class-methods-use-this
|
|
94
|
+
async #init() {
|
|
95
|
+
try {
|
|
96
|
+
const config = await this.#loadConfigFile();
|
|
97
|
+
this.#networkList = config.networkList;
|
|
98
|
+
} catch (error) {
|
|
99
|
+
this.#networkList = [];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// eslint-disable-next-line class-methods-use-this
|
|
104
|
+
async #loadConfigFile() {
|
|
105
|
+
const { configFilePath, rootPath } = this.#getConfigFilePath();
|
|
106
|
+
|
|
107
|
+
const {
|
|
108
|
+
type: typeImport,
|
|
109
|
+
changed,
|
|
110
|
+
currentConfigPath,
|
|
111
|
+
matchPaths,
|
|
112
|
+
} = this.#checkFileImportType(configFilePath);
|
|
113
|
+
|
|
114
|
+
let config;
|
|
115
|
+
if (typeImport === 'esm') {
|
|
116
|
+
config = await this.#importEsmModule(
|
|
117
|
+
rootPath,
|
|
118
|
+
currentConfigPath,
|
|
119
|
+
changed,
|
|
120
|
+
);
|
|
121
|
+
} else {
|
|
122
|
+
config = await this.#importCjsModule(
|
|
123
|
+
rootPath,
|
|
124
|
+
currentConfigPath,
|
|
125
|
+
changed,
|
|
126
|
+
matchPaths,
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return config?.default || config;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// eslint-disable-next-line class-methods-use-this
|
|
134
|
+
#getConfigFilePath() {
|
|
135
|
+
const projectRoot = process.cwd();
|
|
136
|
+
const isWindows = process.platform === 'win32';
|
|
137
|
+
const rootPath = isWindows
|
|
138
|
+
? fileURLToPath(new URL(`file:///${nodePath.resolve(projectRoot, '.')}`))
|
|
139
|
+
: nodePath.resolve(projectRoot, '.');
|
|
140
|
+
return {
|
|
141
|
+
configFilePath: nodePath.resolve(rootPath, this.#configFile),
|
|
142
|
+
rootPath,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// eslint-disable-next-line class-methods-use-this
|
|
147
|
+
async #importEsmModule(rootPath, originalConfigPath, changed) {
|
|
148
|
+
let pathCache = originalConfigPath;
|
|
149
|
+
if (!this.#cacheDynamicImport) {
|
|
150
|
+
pathCache = `${originalConfigPath}?u=${Date.now()}`;
|
|
151
|
+
}
|
|
152
|
+
const config = (await import(pathCache)).default;
|
|
153
|
+
if (changed) {
|
|
154
|
+
rmSync(originalConfigPath);
|
|
155
|
+
}
|
|
156
|
+
return config;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// eslint-disable-next-line class-methods-use-this
|
|
160
|
+
async #importCjsModule(rootPath, configFilePath, changed, matchPaths) {
|
|
161
|
+
if (!this.#cacheDynamicImport) {
|
|
162
|
+
delete require.cache[configFilePath];
|
|
163
|
+
if (changed && matchPaths?.length > 0) {
|
|
164
|
+
matchPaths.forEach((match) => {
|
|
165
|
+
delete require.cache[nodePath.resolve(rootPath, match)];
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return new Promise((resolve) => {
|
|
170
|
+
// eslint-disable-next-line import/no-dynamic-require
|
|
171
|
+
resolve(require(configFilePath));
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// eslint-disable-next-line class-methods-use-this
|
|
176
|
+
#checkFileImportType(originalConfigPath) {
|
|
177
|
+
const file = readFileSync(originalConfigPath, 'utf8');
|
|
178
|
+
if (file?.includes('export default')) {
|
|
179
|
+
const { changed, currentConfigPath } = this.#changeEsmImports(
|
|
180
|
+
originalConfigPath,
|
|
181
|
+
file,
|
|
182
|
+
);
|
|
183
|
+
return { type: 'esm', changed, currentConfigPath };
|
|
184
|
+
}
|
|
185
|
+
const { changed, matchPaths } = this.#changeCjsImports(file);
|
|
186
|
+
return {
|
|
187
|
+
type: 'cjs',
|
|
188
|
+
changed,
|
|
189
|
+
currentConfigPath: originalConfigPath,
|
|
190
|
+
matchPaths,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// eslint-disable-next-line class-methods-use-this
|
|
195
|
+
#changeEsmImports(originalConfigPath, file) {
|
|
196
|
+
const regex = /import\s+(.*)\s+from\s+['"]\.(.*)['"]/g;
|
|
197
|
+
let changed = false;
|
|
198
|
+
let fileUpdated = file;
|
|
199
|
+
if (file.match(regex)) {
|
|
200
|
+
changed = true;
|
|
201
|
+
fileUpdated = file.replace(
|
|
202
|
+
regex,
|
|
203
|
+
`import $1 from "..$2?u=${Date.now()}"`,
|
|
204
|
+
);
|
|
205
|
+
const tmpFile = this.#configFile.replace('.js', '.temp.js');
|
|
206
|
+
const tmpConfigPath = nodePath.join(
|
|
207
|
+
process.cwd(),
|
|
208
|
+
this.#workDir,
|
|
209
|
+
tmpFile,
|
|
210
|
+
);
|
|
211
|
+
writeFileSync(tmpConfigPath, fileUpdated, 'utf8');
|
|
212
|
+
return { changed, currentConfigPath: tmpConfigPath };
|
|
213
|
+
}
|
|
214
|
+
return { changed, currentConfigPath: originalConfigPath };
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// eslint-disable-next-line class-methods-use-this
|
|
218
|
+
#changeCjsImports(file) {
|
|
219
|
+
let changed = false;
|
|
220
|
+
const regex = /require\(['"]([^'"]+)['"]\)/g;
|
|
221
|
+
const matchPaths = [];
|
|
222
|
+
let match = regex.exec(file);
|
|
223
|
+
while (match !== null) {
|
|
224
|
+
changed = true;
|
|
225
|
+
matchPaths.push(match[1]);
|
|
226
|
+
match = regex.exec(file);
|
|
227
|
+
}
|
|
228
|
+
return { changed, matchPaths };
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export default NetworkListContext;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { it } from '@jest/globals';
|
|
2
|
+
import mockFs from 'mock-fs';
|
|
3
|
+
import NetworkListContext from './network-list.context.js';
|
|
4
|
+
|
|
5
|
+
describe('Network List Context', () => {
|
|
6
|
+
let networkListContext;
|
|
7
|
+
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
// eslint-disable-next-line jest/no-standalone-expect
|
|
10
|
+
const typeImport = expect.getState().currentTestName.includes('commonjs')
|
|
11
|
+
? 'module.exports ='
|
|
12
|
+
: 'export default';
|
|
13
|
+
const code = `${typeImport} {
|
|
14
|
+
networkList: [
|
|
15
|
+
{ id: 1, listType: "ip_cidr", listContent: ["10.0.0.1"] },
|
|
16
|
+
{ id: 2, listType: "asn", listContent: [123, 456, 789]},
|
|
17
|
+
{ id: 3, listType: "countries", listContent: ["United States", "Brazil"]}
|
|
18
|
+
]};`;
|
|
19
|
+
mockFs({
|
|
20
|
+
'azion.config.js': code,
|
|
21
|
+
});
|
|
22
|
+
networkListContext = new NetworkListContext();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
mockFs.restore();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should contain the valid ip in the network list and list type is ip_cidr', async () => {
|
|
30
|
+
expect(networkListContext.contains(1, '10.0.0.1')).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should contain the valid asn in the network list and list type is asn', async () => {
|
|
34
|
+
expect(networkListContext.contains(2, 123)).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should contain the valid country in the network list and list type is countries', async () => {
|
|
38
|
+
expect(networkListContext.contains(3, 'United States')).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should type import be commonjs and contain the valid ip in the network list and list type is ip_cidr', async () => {
|
|
42
|
+
expect(networkListContext.contains(1, '10.0.0.1')).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
globalThis.Azion = globalThis.Azion || {};
|
|
3
|
+
|
|
4
|
+
globalThis.Azion.networkList = {};
|
|
5
|
+
// unique context for each instance
|
|
6
|
+
const instanceNetworkList = new NETWORK_LIST_CONTEXT(false);
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param {string} network_list_id - The network list id
|
|
11
|
+
* @param {string} value - The value to check
|
|
12
|
+
* @returns
|
|
13
|
+
*/
|
|
14
|
+
globalThis.Azion.networkList.contains = (network_list_id, value) => {
|
|
15
|
+
return instanceNetworkList.contains(network_list_id, value);
|
|
16
|
+
};
|
|
@@ -3,6 +3,7 @@ import FetchEventContext from './azion/fetch-event/index.js';
|
|
|
3
3
|
import { AsyncHooksContext } from './async-hooks/index.js';
|
|
4
4
|
import { StorageContext } from './azion/storage/index.js';
|
|
5
5
|
import EnvVarsContext from './azion/env-vars/index.js';
|
|
6
|
+
import NetworkListContext from './azion/network-list/index.js';
|
|
6
7
|
|
|
7
8
|
export {
|
|
8
9
|
fetchContext,
|
|
@@ -10,4 +11,5 @@ export {
|
|
|
10
11
|
AsyncHooksContext,
|
|
11
12
|
StorageContext,
|
|
12
13
|
EnvVarsContext,
|
|
14
|
+
NetworkListContext,
|
|
13
15
|
};
|
package/lib/env/runtime.env.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
AsyncHooksContext,
|
|
7
7
|
StorageContext,
|
|
8
8
|
EnvVarsContext,
|
|
9
|
+
NetworkListContext,
|
|
9
10
|
} from './polyfills/index.js';
|
|
10
11
|
import FirewallEventContext from './polyfills/azion/firewall-event/index.js';
|
|
11
12
|
|
|
@@ -77,6 +78,9 @@ function runtime(code, isFirewallEvent = false) {
|
|
|
77
78
|
// EnvVars Context
|
|
78
79
|
context.ENV_VARS_CONTEXT = EnvVarsContext;
|
|
79
80
|
|
|
81
|
+
// Network List Context
|
|
82
|
+
context.NETWORK_LIST_CONTEXT = NetworkListContext;
|
|
83
|
+
|
|
80
84
|
return context;
|
|
81
85
|
};
|
|
82
86
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "edge-functions",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.6.0-stage.1",
|
|
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": {
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"https-browserify": "^1.0.0",
|
|
69
69
|
"inquirer": "^9.2.7",
|
|
70
70
|
"install": "^0.13.0",
|
|
71
|
+
"ip": "^2.0.1",
|
|
71
72
|
"lodash": "^4.17.21",
|
|
72
73
|
"lodash.merge": "^4.6.2",
|
|
73
74
|
"log-update": "^5.0.1",
|