edge-functions 1.0.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 (230) hide show
  1. package/.babelrc +13 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc.json +42 -0
  4. package/.github/workflows/major.yml +28 -0
  5. package/.github/workflows/minor.yml +31 -0
  6. package/.vscode/settings.json +20 -0
  7. package/CODEOWNERS +2 -0
  8. package/CODE_OF_CONDUCT.md +73 -0
  9. package/CONTRIBUTING.md +90 -0
  10. package/LICENSE.md +21 -0
  11. package/README.md +60 -0
  12. package/aliases.js +13 -0
  13. package/docs/overview.md +36 -0
  14. package/docs/presets.md +115 -0
  15. package/examples/angular-static/.editorconfig +16 -0
  16. package/examples/angular-static/README.md +27 -0
  17. package/examples/angular-static/angular.json +98 -0
  18. package/examples/angular-static/package.json +39 -0
  19. package/examples/angular-static/src/app/app-routing.module.ts +10 -0
  20. package/examples/angular-static/src/app/app.component.css +0 -0
  21. package/examples/angular-static/src/app/app.component.html +484 -0
  22. package/examples/angular-static/src/app/app.component.spec.ts +29 -0
  23. package/examples/angular-static/src/app/app.component.ts +10 -0
  24. package/examples/angular-static/src/app/app.module.ts +18 -0
  25. package/examples/angular-static/src/assets/.gitkeep +0 -0
  26. package/examples/angular-static/src/favicon.ico +0 -0
  27. package/examples/angular-static/src/index.html +13 -0
  28. package/examples/angular-static/src/main.ts +7 -0
  29. package/examples/angular-static/src/styles.css +1 -0
  30. package/examples/angular-static/tsconfig.app.json +14 -0
  31. package/examples/angular-static/tsconfig.json +33 -0
  32. package/examples/angular-static/tsconfig.spec.json +14 -0
  33. package/examples/astro-static/README.md +55 -0
  34. package/examples/astro-static/astro.config.mjs +5 -0
  35. package/examples/astro-static/package.json +15 -0
  36. package/examples/astro-static/public/favicon.svg +9 -0
  37. package/examples/astro-static/src/components/Card.astro +63 -0
  38. package/examples/astro-static/src/env.d.ts +1 -0
  39. package/examples/astro-static/src/layouts/Layout.astro +36 -0
  40. package/examples/astro-static/src/pages/edge/index.astro +55 -0
  41. package/examples/astro-static/src/pages/index.astro +81 -0
  42. package/examples/astro-static/tsconfig.json +3 -0
  43. package/examples/hexo-static/.github/dependabot.yml +7 -0
  44. package/examples/hexo-static/_config.landscape.yml +0 -0
  45. package/examples/hexo-static/_config.yml +105 -0
  46. package/examples/hexo-static/package.json +26 -0
  47. package/examples/hexo-static/scaffolds/draft.md +4 -0
  48. package/examples/hexo-static/scaffolds/page.md +4 -0
  49. package/examples/hexo-static/scaffolds/post.md +5 -0
  50. package/examples/hexo-static/source/_posts/hello-world.md +38 -0
  51. package/examples/hexo-static/source/_posts/other-page.md +62 -0
  52. package/examples/hexo-static/themes/.gitkeep +0 -0
  53. package/examples/hexo-static/yarn.lock +1625 -0
  54. package/examples/next-12-static/.babelrc +3 -0
  55. package/examples/next-12-static/README.md +21 -0
  56. package/examples/next-12-static/components/post.jsx +27 -0
  57. package/examples/next-12-static/package-lock.json +6191 -0
  58. package/examples/next-12-static/package.json +18 -0
  59. package/examples/next-12-static/pages/index.jsx +34 -0
  60. package/examples/next-12-static/pages/post/[id].jsx +63 -0
  61. package/examples/next-static/README.md +34 -0
  62. package/examples/next-static/jsconfig.json +7 -0
  63. package/examples/next-static/next.config.js +9 -0
  64. package/examples/next-static/package.json +16 -0
  65. package/examples/next-static/public/next.svg +1 -0
  66. package/examples/next-static/public/vercel.svg +1 -0
  67. package/examples/next-static/src/app/blog/[slug]/page.js +27 -0
  68. package/examples/next-static/src/app/favicon.ico +0 -0
  69. package/examples/next-static/src/app/globals.css +107 -0
  70. package/examples/next-static/src/app/layout.js +17 -0
  71. package/examples/next-static/src/app/misty-mountains/moria/page.js +15 -0
  72. package/examples/next-static/src/app/page.js +96 -0
  73. package/examples/next-static/src/app/page.module.css +229 -0
  74. package/examples/next-static/yarn.lock +199 -0
  75. package/examples/react-static/README.md +70 -0
  76. package/examples/react-static/package.json +38 -0
  77. package/examples/react-static/public/favicon.ico +0 -0
  78. package/examples/react-static/public/index.html +43 -0
  79. package/examples/react-static/public/logo192.png +0 -0
  80. package/examples/react-static/public/logo512.png +0 -0
  81. package/examples/react-static/public/manifest.json +25 -0
  82. package/examples/react-static/public/robots.txt +3 -0
  83. package/examples/react-static/src/App.css +38 -0
  84. package/examples/react-static/src/App.js +25 -0
  85. package/examples/react-static/src/App.test.js +8 -0
  86. package/examples/react-static/src/index.css +13 -0
  87. package/examples/react-static/src/index.js +17 -0
  88. package/examples/react-static/src/logo.svg +1 -0
  89. package/examples/react-static/src/reportWebVitals.js +13 -0
  90. package/examples/react-static/src/setupTests.js +5 -0
  91. package/examples/simple-js-esm/main.js +14 -0
  92. package/examples/simple-js-esm/messages.js +7 -0
  93. package/examples/simple-js-node/main.js +18 -0
  94. package/examples/vue-static/README.md +24 -0
  95. package/examples/vue-static/babel.config.js +5 -0
  96. package/examples/vue-static/jsconfig.json +19 -0
  97. package/examples/vue-static/package.json +45 -0
  98. package/examples/vue-static/public/favicon.ico +0 -0
  99. package/examples/vue-static/public/index.html +17 -0
  100. package/examples/vue-static/src/App.vue +16 -0
  101. package/examples/vue-static/src/assets/logo.png +0 -0
  102. package/examples/vue-static/src/components/HelloWorld.vue +58 -0
  103. package/examples/vue-static/src/main.js +28 -0
  104. package/examples/vue-static/src/views/Home.vue +14 -0
  105. package/examples/vue-static/vue.config.js +4 -0
  106. package/jest.config.js +6 -0
  107. package/jsconfig.json +40 -0
  108. package/jsdoc.json +52 -0
  109. package/lib/build/bundlers/index.js +4 -0
  110. package/lib/build/bundlers/webpack/index.js +40 -0
  111. package/lib/build/bundlers/webpack/webpack.config.js +38 -0
  112. package/lib/build/dispatcher/dispatcher.js +211 -0
  113. package/lib/build/dispatcher/dispatcher.test.js +0 -0
  114. package/lib/build/dispatcher/index.js +3 -0
  115. package/lib/build/polyfills/index.js +0 -0
  116. package/lib/constants/azion-edges.constants.js +98 -0
  117. package/lib/constants/index.js +5 -0
  118. package/lib/constants/messages/build.messages.js +23 -0
  119. package/lib/constants/messages/env.messages.js +38 -0
  120. package/lib/constants/messages/global.messages.js +19 -0
  121. package/lib/constants/messages/index.js +10 -0
  122. package/lib/constants/messages/platform.messages.js +84 -0
  123. package/lib/constants/runtime-apis.constants.js +118 -0
  124. package/lib/env/index.js +5 -0
  125. package/lib/env/runtime.env.js +69 -0
  126. package/lib/env/server.env.js +90 -0
  127. package/lib/env/vulcan.env.js +93 -0
  128. package/lib/main.js +260 -0
  129. package/lib/notations/namespaces.js +30 -0
  130. package/lib/notations/typedef.js +10 -0
  131. package/lib/platform/actions/application/createApplication.actions.js +33 -0
  132. package/lib/platform/actions/application/enableEdgeFunctions.actions.js +34 -0
  133. package/lib/platform/actions/application/instantiateFunction.actions.js +37 -0
  134. package/lib/platform/actions/application/setFunctionAsDefaultRule.actions.js +33 -0
  135. package/lib/platform/actions/core/auth.actions.js +67 -0
  136. package/lib/platform/actions/core/deploy.actions.js +73 -0
  137. package/lib/platform/actions/core/propagation.actions.js +75 -0
  138. package/lib/platform/actions/core/storage.actions.js +84 -0
  139. package/lib/platform/actions/domain/createDomain.actions.js +42 -0
  140. package/lib/platform/actions/function/createFunction.actions.js +79 -0
  141. package/lib/platform/actions/function/showFunctionLogs.actions.js +149 -0
  142. package/lib/platform/edgehooks/ErrorHTML/ErrorHTML.hooks.js +101 -0
  143. package/lib/platform/edgehooks/ErrorHTML/index.js +3 -0
  144. package/lib/platform/edgehooks/index.js +5 -0
  145. package/lib/platform/edgehooks/mountSPA/index.js +3 -0
  146. package/lib/platform/edgehooks/mountSPA/mountSPA.hooks.js +55 -0
  147. package/lib/platform/edgehooks/mountSPA/mountSPA.hooks.test.js +19 -0
  148. package/lib/platform/edgehooks/mountSSG/index.js +3 -0
  149. package/lib/platform/edgehooks/mountSSG/mountSSG.hooks.js +61 -0
  150. package/lib/platform/edgehooks/mountSSG/mountSSG.hooks.test.js +0 -0
  151. package/lib/platform/index.js +65 -0
  152. package/lib/platform/services/application.service.js +140 -0
  153. package/lib/platform/services/base.service.js +200 -0
  154. package/lib/platform/services/domain.service.js +80 -0
  155. package/lib/platform/services/events.service.js +65 -0
  156. package/lib/platform/services/function.service.js +105 -0
  157. package/lib/platform/services/index.js +8 -0
  158. package/lib/platform/services/storage.service.js +59 -0
  159. package/lib/platform/services/tokens.service.js +55 -0
  160. package/lib/presets/custom/angular/deliver/config.js +12 -0
  161. package/lib/presets/custom/angular/deliver/handler.js +8 -0
  162. package/lib/presets/custom/angular/deliver/prebuild.js +20 -0
  163. package/lib/presets/custom/astro/deliver/config.js +12 -0
  164. package/lib/presets/custom/astro/deliver/handler.js +8 -0
  165. package/lib/presets/custom/astro/deliver/prebuild.js +37 -0
  166. package/lib/presets/custom/hexo/deliver/config.js +12 -0
  167. package/lib/presets/custom/hexo/deliver/handler.js +8 -0
  168. package/lib/presets/custom/hexo/deliver/prebuild.js +37 -0
  169. package/lib/presets/custom/next/deliver/config.js +14 -0
  170. package/lib/presets/custom/next/deliver/handler.js +9 -0
  171. package/lib/presets/custom/next/deliver/prebuild.js +193 -0
  172. package/lib/presets/custom/react/deliver/config.js +12 -0
  173. package/lib/presets/custom/react/deliver/handler.js +8 -0
  174. package/lib/presets/custom/react/deliver/prebuild.js +16 -0
  175. package/lib/presets/custom/vue/deliver/config.js +12 -0
  176. package/lib/presets/custom/vue/deliver/handler.js +8 -0
  177. package/lib/presets/custom/vue/deliver/prebuild.js +20 -0
  178. package/lib/presets/default/html/deliver/config.js +13 -0
  179. package/lib/presets/default/html/deliver/handler.js +9 -0
  180. package/lib/presets/default/html/deliver/prebuild.js +15 -0
  181. package/lib/presets/default/javascript/compute/config.js +13 -0
  182. package/lib/presets/default/javascript/compute/handler.js +5 -0
  183. package/lib/presets/default/javascript/compute/prebuild.js +6 -0
  184. package/lib/presets/default/typescript/compute/config.js +0 -0
  185. package/lib/presets/default/typescript/compute/handler.js +0 -0
  186. package/lib/presets/default/typescript/compute/prebuild.js +0 -0
  187. package/lib/providers/azion/worker.js +12 -0
  188. package/lib/utils/copyDirectory/copyDirectory.utils.js +54 -0
  189. package/lib/utils/copyDirectory/copyDirectory.utils.test.js +43 -0
  190. package/lib/utils/copyDirectory/index.js +3 -0
  191. package/lib/utils/debug/debug.utils.js +36 -0
  192. package/lib/utils/debug/debug.utils.test.js +43 -0
  193. package/lib/utils/debug/index.js +3 -0
  194. package/lib/utils/exec/exec.utils.js +58 -0
  195. package/lib/utils/exec/exec.utils.test.js +84 -0
  196. package/lib/utils/exec/index.js +3 -0
  197. package/lib/utils/feedback/feedback.utils.js +81 -0
  198. package/lib/utils/feedback/feedback.utils.test.js +11 -0
  199. package/lib/utils/feedback/index.js +3 -0
  200. package/lib/utils/generateTimestamp/generateTimestamp.utils.js +25 -0
  201. package/lib/utils/generateTimestamp/generateTimestamp.utils.test.js +10 -0
  202. package/lib/utils/generateTimestamp/index.js +3 -0
  203. package/lib/utils/getAbsoluteLibDirPath/getAbsoluteLibDirPath.utils.js +21 -0
  204. package/lib/utils/getAbsoluteLibDirPath/getAbsoluteLibDirPath.utils.test.js +13 -0
  205. package/lib/utils/getAbsoluteLibDirPath/index.js +3 -0
  206. package/lib/utils/getPackageManager/getPackageManager.utils.js +118 -0
  207. package/lib/utils/getPackageManager/getPackageManager.utils.test.js +35 -0
  208. package/lib/utils/getPackageManager/index.js +3 -0
  209. package/lib/utils/getPackageVersion/getPackageVersion.utils.js +25 -0
  210. package/lib/utils/getPackageVersion/getPackageVersion.utils.test.js +48 -0
  211. package/lib/utils/getPackageVersion/index.js +3 -0
  212. package/lib/utils/getPresetsList/getPresetsList.utils.js +50 -0
  213. package/lib/utils/getPresetsList/getPresetsList.utils.test.js +19 -0
  214. package/lib/utils/getPresetsList/index.js +3 -0
  215. package/lib/utils/getProjectJsonFile/getProjectJsonFile.utils.js +21 -0
  216. package/lib/utils/getProjectJsonFile/getProjectJsonFile.utils.test.js +39 -0
  217. package/lib/utils/getProjectJsonFile/index.js +3 -0
  218. package/lib/utils/getVulcanBuildId/getVulcanBuildId.utils.js +49 -0
  219. package/lib/utils/getVulcanBuildId/getVulcanBuildId.utils.test.js +36 -0
  220. package/lib/utils/getVulcanBuildId/index.js +3 -0
  221. package/lib/utils/index.js +29 -0
  222. package/lib/utils/overrideStaticOutputPath/index.js +3 -0
  223. package/lib/utils/overrideStaticOutputPath/overrideStaticOutputPath.utils.js +47 -0
  224. package/lib/utils/overrideStaticOutputPath/overrideStaticOutputPath.utils.test.js +35 -0
  225. package/lib/utils/readWorkerFile/index.js +3 -0
  226. package/lib/utils/readWorkerFile/readWorkerFile.utils.js +36 -0
  227. package/lib/utils/readWorkerFile/readWorkerFile.utils.test.js +24 -0
  228. package/package.json +99 -0
  229. package/releaserc.json +87 -0
  230. package/tasks/sync-aliases.js +115 -0
@@ -0,0 +1,55 @@
1
+ import BaseService from './base.service.js';
2
+
3
+ /**
4
+ * Service class for managing tokens.
5
+ * Extends the BaseService class.
6
+ */
7
+ class TokensService extends BaseService {
8
+ /**
9
+ * Constructs an instance of TokensService.
10
+ * Initializes the base URL for tokens.
11
+ */
12
+ constructor() {
13
+ super('/tokens');
14
+ }
15
+
16
+ /**
17
+ * Creates a new token.
18
+ * @param {string} username - The username for authentication.
19
+ * @param {string} password - The password for authentication.
20
+ * @returns {Promise} A promise that resolves to the created token.
21
+ */
22
+ create(username, password) {
23
+ const base64Credentials = Buffer.from(`${username}:${password}`).toString('base64');
24
+ return super.post('', '', {
25
+ headers: {
26
+ Authorization: `Basic ${base64Credentials}`,
27
+ },
28
+ });
29
+ }
30
+ }
31
+
32
+ /**
33
+ * @name TokensService
34
+ * @memberof Services
35
+ * Instance of the Tokens Service.
36
+ * This instance provides methods to interact with Azion's Tokens service,
37
+ * such as creating a new token for authentication.
38
+ * @type {BaseService}
39
+ * @function create
40
+ * @example
41
+ *
42
+ * // Example usage
43
+ * const username = 'myUsername';
44
+ * const password = 'myPassword';
45
+ *
46
+ * TokensService.create(username, password)
47
+ * .then((token) => {
48
+ * console.log(token);
49
+ * })
50
+ * .catch((error) => {
51
+ * feedback.error(error);
52
+ * });
53
+ */
54
+ const TokensServiceInstance = new TokensService();
55
+ export default TokensServiceInstance;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Config to be used in build context.
3
+ */
4
+ const config = {
5
+ builder: 'webpack',
6
+ webpack: {
7
+ config: {},
8
+ plugins: [],
9
+ },
10
+ };
11
+
12
+ export default config;
@@ -0,0 +1,8 @@
1
+ import { mountSPA, ErrorHTML } from '#edge';
2
+
3
+ try {
4
+ const myApp = await mountSPA(event.request.url, AZION.VERSION_ID);
5
+ return myApp;
6
+ } catch (e) {
7
+ return ErrorHTML('404');
8
+ }
@@ -0,0 +1,20 @@
1
+ import { exec, feedback, getPackageManager } from '#utils';
2
+
3
+ const packageManager = await getPackageManager();
4
+
5
+ /**
6
+ * Runs custom prebuild actions
7
+ */
8
+ async function prebuild() {
9
+ try {
10
+ // This is because npm interprets arguments passed directly
11
+ // after the script as options for npm itself, not the script itself.
12
+ const npmArgsForward = packageManager === 'npm' ? '--' : '';
13
+ // support npm, yarn, pnpm
14
+ await exec(`${packageManager} run build ${npmArgsForward} --output-path=.edge/statics`, 'Angular', true);
15
+ } catch (error) {
16
+ feedback.prebuild.error(error);
17
+ }
18
+ }
19
+
20
+ export default prebuild;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Config to be used in build context.
3
+ */
4
+ const config = {
5
+ builder: 'webpack',
6
+ webpack: {
7
+ config: {},
8
+ plugins: [],
9
+ },
10
+ };
11
+
12
+ export default config;
@@ -0,0 +1,8 @@
1
+ import { mountSSG, ErrorHTML } from "#edge";
2
+
3
+ try {
4
+ const myApp = await mountSSG(event.request.url, AZION.VERSION_ID);
5
+ return myApp;
6
+ } catch (error) {
7
+ return ErrorHTML("404");
8
+ }
@@ -0,0 +1,37 @@
1
+ import { rm, readFile } from 'fs/promises';
2
+ import {
3
+ exec, getPackageManager, feedback, copyDirectory,
4
+ } from '#utils';
5
+
6
+ const packageManager = await getPackageManager();
7
+
8
+ /**
9
+ * Runs custom prebuild actions
10
+ */
11
+ async function prebuild() {
12
+ try {
13
+ const newOutDir = '.edge/statics';
14
+ let outDir = 'dist';
15
+
16
+ // check if an output path is specified in config file
17
+ const configFileContent = await readFile('./astro.config.mjs', 'utf-8');
18
+ const attributeMatch = Array.from(
19
+ configFileContent.matchAll(/outDir:(.*)\n/g),
20
+ (match) => match,
21
+ )[0];
22
+ if (attributeMatch) {
23
+ // get the specified value in config
24
+ outDir = attributeMatch[1].trim();
25
+ }
26
+
27
+ await exec(`${packageManager} run build`, 'Astro', true);
28
+
29
+ // move files to vulcan default path
30
+ copyDirectory(outDir, newOutDir);
31
+ rm(outDir, { recursive: true, force: true });
32
+ } catch (error) {
33
+ feedback.prebuild.error(error);
34
+ }
35
+ }
36
+
37
+ export default prebuild;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Config to be used in build context.
3
+ */
4
+ const config = {
5
+ builder: 'webpack',
6
+ webpack: {
7
+ config: {},
8
+ plugins: [],
9
+ },
10
+ };
11
+
12
+ export default config;
@@ -0,0 +1,8 @@
1
+ import { mountSSG, ErrorHTML } from "#edge";
2
+
3
+ try {
4
+ const myApp = await mountSSG(event.request.url, AZION.VERSION_ID);
5
+ return myApp;
6
+ } catch (e) {
7
+ return ErrorHTML("404");
8
+ }
@@ -0,0 +1,37 @@
1
+ import { readFile, rm } from 'fs/promises';
2
+ import {
3
+ exec, getPackageManager, feedback, copyDirectory,
4
+ } from '#utils';
5
+
6
+ const packageManager = await getPackageManager();
7
+
8
+ /**
9
+ * Runs custom prebuild actions
10
+ */
11
+ async function prebuild() {
12
+ try {
13
+ const newOutDir = '.edge/statics';
14
+ let outDir = 'public';
15
+
16
+ // check if an output path is specified in config file
17
+ const configFileContent = await readFile('./_config.yml', 'utf-8');
18
+ const attributeMatch = Array.from(
19
+ configFileContent.matchAll(/public_dir:(.*)\n/g),
20
+ (match) => match,
21
+ )[0];
22
+ if (attributeMatch) {
23
+ // get the specified value in config
24
+ outDir = attributeMatch[1].trim().replace(/["']/g, '');
25
+ }
26
+
27
+ await exec(`${packageManager} hexo generate`, 'Hexo', true);
28
+
29
+ // move files to vulcan default path
30
+ copyDirectory(outDir, newOutDir);
31
+ rm(outDir, { recursive: true, force: true });
32
+ } catch (error) {
33
+ feedback.prebuild.error(error);
34
+ }
35
+ }
36
+
37
+ export default prebuild;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Config to be used in build context.
3
+ */
4
+ const config = {
5
+ builder: 'webpack',
6
+ webpack: {
7
+ config: {
8
+ distDir: '.edge/statics',
9
+ },
10
+ plugins: [],
11
+ },
12
+ };
13
+
14
+ export default config;
@@ -0,0 +1,9 @@
1
+ import { mountSSG } from "#edge";
2
+
3
+ try {
4
+ const myApp = await mountSSG(event.request.url, AZION.VERSION_ID);
5
+ return myApp;
6
+ } catch (e) {
7
+ const notFoundError = new URL(`${AZION.VERSION_ID}/404.html`, 'file://')
8
+ return fetch(notFoundError)
9
+ }
@@ -0,0 +1,193 @@
1
+ import { gte, coerce, valid } from 'semver';
2
+ import {
3
+ exec, feedback, getPackageManager, getPackageVersion, copyDirectory,
4
+ } from '#utils';
5
+
6
+ import {
7
+ readdir, stat, rename, mkdir, readFile, rm,
8
+ } from 'fs/promises';
9
+ import {
10
+ join, extname, basename, dirname,
11
+ } from 'path';
12
+
13
+ const packageManager = await getPackageManager();
14
+
15
+ /**
16
+ * Moves HTML and corresponding TXT files to subdirectories and
17
+ * renames the HTML files to 'index.html'.
18
+ * This function is used to organize the static files generated by Next.js during the build process.
19
+ * It looks for HTML files in the specified directory and its subdirectories.
20
+ * When it finds an HTML file,
21
+ * it creates a new subdirectory with the same name as the HTML file (without the .html extension),
22
+ * and moves the HTML file to that subdirectory, renaming it to 'index.html'.
23
+ * If there is a corresponding TXT file with the same base name (before .html extension),
24
+ * it will also be moved
25
+ * to the same subdirectory with its original name.
26
+ * @param {string} directory - The root directory to start moving files.
27
+ * @example
28
+ * // Before:
29
+ * // Root directory: '/path/to/project/.edge/statics'
30
+ * // Files in the directory: ['home.html', 'about.html', 'contact.html', 'styles.css']
31
+ *
32
+ * // After calling moveFiles('/path/to/project/.edge/statics'):
33
+ * // Root directory: '/path/to/project/.edge/statics'
34
+ * // Files in the directory: ['styles.css']
35
+ * // Subdirectory 'home':
36
+ * // - index.html (previously home.html)
37
+ * // - home.txt
38
+ * // Subdirectory 'about':
39
+ * // - index.html (previously about.html)
40
+ * // - about.txt
41
+ * // Subdirectory 'contact':
42
+ * // - index.html (previously contact.html)
43
+ * // - contact.txt
44
+ */
45
+ async function moveFiles(directory) {
46
+ const files = await readdir(directory);
47
+
48
+ await Promise.all(
49
+ files.map(async (file) => {
50
+ const filePath = join(directory, file);
51
+ const fileStat = await stat(filePath);
52
+
53
+ if (fileStat.isDirectory()) {
54
+ await moveFiles(filePath); // Recursive call for subdirectories
55
+ } else if (
56
+ extname(file) === '.html'
57
+ && file !== 'index.html'
58
+ && file !== '404.html'
59
+ ) {
60
+ const newDirectoryName = basename(file, '.html');
61
+ const newDirectoryPath = join(directory, newDirectoryName);
62
+
63
+ await mkdir(newDirectoryPath, { recursive: true });
64
+
65
+ const newHTMLPath = join(newDirectoryPath, 'index.html');
66
+ await rename(filePath, newHTMLPath);
67
+ feedback.prebuild.info(`Moved ${filePath} to ${newHTMLPath}`);
68
+
69
+ const correspondingTXTFile = `${basename(file, '.html')}.txt`;
70
+ const correspondingTXTPath = join(directory, correspondingTXTFile);
71
+
72
+ if (files.includes(correspondingTXTFile)) {
73
+ const newTXTParentDirectory = dirname(newHTMLPath);
74
+ const newTXTPath = join(newTXTParentDirectory, correspondingTXTFile);
75
+ await rename(correspondingTXTPath, newTXTPath);
76
+ feedback.prebuild.info(`Moved ${correspondingTXTPath} to ${newTXTPath}`);
77
+ }
78
+ }
79
+ }),
80
+ );
81
+ }
82
+
83
+ /**
84
+ * Detect if version is >= 13.3.0
85
+ * In this version the static site had significant changes in how to use and how to build.
86
+ * doc reference:
87
+ * https://nextjs.org/docs/pages/building-your-application/deploying/static-exports
88
+ * @param {string} version - Next.js version ("latest" or in "x.x.x" format).
89
+ * @returns {boolean} - a boolean indicating if is a recent version or not.
90
+ * @example
91
+ * isANewerVersion('^14.2.3') returns true.
92
+ * isANewerVersion('~13.0.0') returns false.
93
+ * isANewerVersion('*') returns true.
94
+ * isANewerVersion('>returns13.3.0<14.0.0') returns true.
95
+ * isANewerVersion('13.x') returns false.
96
+ * isANewerVersion('>=12.0<13') returns false.
97
+ * isANewerVersion('13.4') returns true.
98
+ * isANewerVersion('latest') returns true.
99
+ * isANewerVersion('x') returns true.
100
+ * isANewerVersion('11') returns false.
101
+ */
102
+ function isANewerVersion(version) {
103
+ if (['latest', '*', 'x', 'X'].includes(version)) {
104
+ return true;
105
+ }
106
+
107
+ const targetVersion = '13.3.0';
108
+ // use semver to check if is a greater or equal version
109
+ if (gte(valid(coerce(version)), targetVersion)) {
110
+ return true;
111
+ }
112
+
113
+ return false;
114
+ }
115
+
116
+ /**
117
+ * Get next config file
118
+ * @returns {object} - next config as a JSON
119
+ */
120
+ async function getNextConfig() {
121
+ try {
122
+ const configPath = join(process.cwd(), 'next.config.js');
123
+ const configModule = await import(configPath);
124
+
125
+ return configModule.default;
126
+ } catch (error) {
127
+ throw Error('Error reading next config file:', error);
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Validates if static site mode is enabled in next config.
133
+ * @param {object} nextConfig - the config as JSON object.
134
+ */
135
+ function validateStaticSiteMode(nextConfig) {
136
+ if (!nextConfig.output || nextConfig.output !== 'export') {
137
+ throw Error('Static site mode not enabled in config!');
138
+ }
139
+ }
140
+
141
+ /**
142
+ * Runs custom prebuild actions.
143
+ */
144
+ async function prebuild() {
145
+ try {
146
+ feedback.prebuild.info('Starting Next.js static build process...');
147
+
148
+ const nextVersion = getPackageVersion('next');
149
+ feedback.prebuild.info('Detected Next.js version:', nextVersion);
150
+
151
+ const staticsOutputDir = '.edge/statics';
152
+
153
+ if (isANewerVersion(nextVersion)) {
154
+ const nextConfig = await getNextConfig();
155
+
156
+ validateStaticSiteMode(nextConfig);
157
+
158
+ // check if an output path is specified in config file
159
+ let outDir = 'out';
160
+ const configFileContent = await readFile('./next.config.js', 'utf-8');
161
+ const attributeMatch = Array.from(
162
+ configFileContent.matchAll(/distDir:(.*),/g),
163
+ (match) => match,
164
+ )[0];
165
+ if (attributeMatch) {
166
+ // get the specified value in config
167
+ outDir = attributeMatch[1].trim().replace(/["']/g, '');
168
+ }
169
+
170
+ await exec(`${packageManager} run build`, true);
171
+
172
+ // move files to vulcan default path
173
+ copyDirectory(outDir, staticsOutputDir);
174
+ rm(outDir, { recursive: true, force: true });
175
+
176
+ feedback.prebuild.info('Adapting Next.js build output...');
177
+ await moveFiles(`${process.cwd()}/${staticsOutputDir}`);
178
+ } else {
179
+ await exec(`${packageManager} run build`, true);
180
+
181
+ await exec(`npx next export -o ${staticsOutputDir}`, true);
182
+
183
+ feedback.prebuild.info('Adapting Next.js build output...');
184
+ await moveFiles(`${process.cwd()}/${staticsOutputDir}`);
185
+ }
186
+
187
+ feedback.prebuild.success('Next.js build adaptation completed successfully.');
188
+ } catch (error) {
189
+ feedback.prebuild.error('Error occurred during Next.js build adaptation:', error);
190
+ }
191
+ }
192
+
193
+ export default prebuild;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Config to be used in build context.
3
+ */
4
+ const config = {
5
+ builder: 'webpack',
6
+ webpack: {
7
+ config: {},
8
+ plugins: [],
9
+ },
10
+ };
11
+
12
+ export default config;
@@ -0,0 +1,8 @@
1
+ import { mountSPA, ErrorHTML } from "#edge";
2
+
3
+ try {
4
+ const myApp = await mountSPA(event.request.url, AZION.VERSION_ID);
5
+ return myApp;
6
+ } catch (e) {
7
+ return ErrorHTML("404");
8
+ }
@@ -0,0 +1,16 @@
1
+ import { exec, feedback, getPackageManager } from '#utils';
2
+
3
+ const packageManager = await getPackageManager();
4
+
5
+ /**
6
+ * Runs custom prebuild actions
7
+ */
8
+ async function prebuild() {
9
+ try {
10
+ await exec(`BUILD_PATH="./.edge/statics" ${packageManager} run build`, 'React', true);
11
+ } catch (error) {
12
+ feedback.prebuild.error(error);
13
+ }
14
+ }
15
+
16
+ export default prebuild;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Config to be used in build context.
3
+ */
4
+ const config = {
5
+ builder: 'webpack',
6
+ webpack: {
7
+ config: {},
8
+ plugins: [],
9
+ },
10
+ };
11
+
12
+ export default config;
@@ -0,0 +1,8 @@
1
+ import { mountSPA, ErrorHTML } from "#edge";
2
+
3
+ try {
4
+ const myApp = await mountSPA(event.request.url, AZION.VERSION_ID);
5
+ return myApp;
6
+ } catch (e) {
7
+ return ErrorHTML("404");
8
+ }
@@ -0,0 +1,20 @@
1
+ import { exec, feedback, getPackageManager } from '#utils';
2
+
3
+ const packageManager = await getPackageManager();
4
+
5
+ /**
6
+ * Runs custom prebuild actions
7
+ */
8
+ async function prebuild() {
9
+ try {
10
+ // This is because npm interprets arguments passed directly
11
+ // after the script as options for npm itself, not the script itself.
12
+ const npmArgsForward = packageManager === 'npm' ? '--' : '';
13
+ // support npm, yarn, pnpm
14
+ await exec(`${packageManager} run build ${npmArgsForward} --dest .edge/statics`, 'Vue', true);
15
+ } catch (error) {
16
+ feedback.prebuild.error(error);
17
+ }
18
+ }
19
+
20
+ export default prebuild;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Config to be used in build context.
3
+ */
4
+ const config = {
5
+ builder: 'webpack',
6
+ useNodePolyfills: false,
7
+ custom: {
8
+ config: {},
9
+ plugins: [],
10
+ },
11
+ };
12
+
13
+ export default config;
@@ -0,0 +1,9 @@
1
+ import { mountSSG } from "#edge";
2
+
3
+ try {
4
+ const myApp = await mountSSG(event.request.url, AZION.VERSION_ID);
5
+ return myApp;
6
+ } catch (e) {
7
+ const notFoundError = new URL(`${AZION.VERSION_ID}/404.html`, 'file://')
8
+ return fetch(notFoundError)
9
+ }
@@ -0,0 +1,15 @@
1
+ import { join } from 'path';
2
+
3
+ import { copyDirectory } from '#utils';
4
+
5
+ /**
6
+ * Runs custom prebuild actions
7
+ */
8
+ async function prebuild() {
9
+ const sourceDir = process.cwd();
10
+ const targetDir = join('.', '.edge', 'statics');
11
+
12
+ copyDirectory(sourceDir, targetDir);
13
+ }
14
+
15
+ export default prebuild;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Config to be used in build context.
3
+ */
4
+ const config = {
5
+ builder: 'webpack',
6
+ useNodePolyfills: false,
7
+ custom: {
8
+ config: {},
9
+ plugins: [],
10
+ },
11
+ };
12
+
13
+ export default config;
@@ -0,0 +1,5 @@
1
+ try {
2
+ __JS_CODE__;
3
+ } catch (e) {
4
+ return new Response(e.message || e.toString(), { status: 500 });
5
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Runs custom prebuild actions
3
+ */
4
+ function prebuild() {}
5
+
6
+ export default prebuild;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Handles the 'fetch' event.
3
+ * @param {FetchEvent} event - The fetch event.
4
+ * @returns {Promise<Response>} The response for the request.
5
+ */
6
+ async function handleEvent(event) {
7
+ __HANDLER__
8
+ }
9
+
10
+ addEventListener('fetch', (event) => {
11
+ event.respondWith(handleEvent(event));
12
+ });
@@ -0,0 +1,54 @@
1
+ import {
2
+ existsSync, mkdirSync, readdirSync, lstatSync, copyFileSync,
3
+ } from 'fs';
4
+ import { join, resolve } from 'path';
5
+
6
+ /**
7
+ * Recursively copies a directory to the target directory, excluding any files or directories
8
+ * that would result in the target directory being copied into itself.
9
+ * @function
10
+ * @name copyDirectory
11
+ * @memberof utils
12
+ * @param {string} source - The path of the source directory.
13
+ * @param {string} target - The path of the target directory. If the target directory is a
14
+ * subdirectory of the source directory, this function will avoid copying the target directory into
15
+ * itself.
16
+ * @example
17
+ * // Copy a directory to the target directory
18
+ * copyDirectory('path/to/source', 'path/to/target');
19
+ * @example
20
+ * // If the target directory is a subdirectory
21
+ * of the source directory, this function will avoid copying the target directory into itself
22
+ * copyDirectory('path/to/source', 'path/to/source/subdirectory');
23
+ */
24
+ function copyDirectory(source, target) {
25
+ const absoluteSource = resolve(source);
26
+ const absoluteTarget = resolve(target);
27
+
28
+ // Do not copy if source and target are the same
29
+ if (absoluteSource === absoluteTarget) { return; }
30
+
31
+ if (!existsSync(absoluteTarget)) {
32
+ mkdirSync(absoluteTarget, { recursive: true });
33
+ }
34
+
35
+ const files = readdirSync(absoluteSource);
36
+
37
+ files.forEach((file) => {
38
+ const sourcePath = join(absoluteSource, file);
39
+ const targetPath = join(absoluteTarget, file);
40
+
41
+ // If the target path is a subdirectory of the source path, skip copying
42
+ if (targetPath.startsWith(sourcePath)) { return; }
43
+
44
+ const fileStat = lstatSync(sourcePath);
45
+
46
+ if (fileStat.isDirectory()) {
47
+ copyDirectory(sourcePath, targetPath);
48
+ } else {
49
+ copyFileSync(sourcePath, targetPath);
50
+ }
51
+ });
52
+ }
53
+
54
+ export default copyDirectory;