@bleedingdev/modern-js-app-tools 3.2.0-ultramodern.99 → 3.4.0-ultramodern.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 (165) hide show
  1. package/dist/cjs/baseline.js +12 -92
  2. package/dist/cjs/builder/builder-rspack/index.js +9 -5
  3. package/dist/cjs/builder/generator/adapterCopy.js +9 -5
  4. package/dist/cjs/builder/generator/createBuilderProviderConfig.js +9 -5
  5. package/dist/cjs/builder/generator/createCopyPattern.js +9 -5
  6. package/dist/cjs/builder/generator/getBuilderEnvironments.js +41 -9
  7. package/dist/cjs/builder/generator/index.js +16 -5
  8. package/dist/cjs/builder/index.js +9 -5
  9. package/dist/cjs/builder/shared/builderPlugins/adapterBasic.js +9 -5
  10. package/dist/cjs/builder/shared/builderPlugins/adapterHtml.js +10 -6
  11. package/dist/cjs/builder/shared/builderPlugins/adapterPrecompress.js +9 -5
  12. package/dist/cjs/builder/shared/builderPlugins/adapterSSR.js +39 -9
  13. package/dist/cjs/builder/shared/builderPlugins/builderHooks.js +12 -8
  14. package/dist/cjs/builder/shared/builderPlugins/index.js +9 -5
  15. package/dist/cjs/builder/shared/bundlerPlugins/HtmlAsyncChunkPlugin.js +9 -5
  16. package/dist/cjs/builder/shared/bundlerPlugins/HtmlBottomTemplate.js +12 -8
  17. package/dist/cjs/builder/shared/bundlerPlugins/RouterPlugin.js +41 -8
  18. package/dist/cjs/builder/shared/bundlerPlugins/index.js +9 -5
  19. package/dist/cjs/builder/shared/createCopyInfo.js +9 -5
  20. package/dist/cjs/builder/shared/index.js +9 -5
  21. package/dist/cjs/builder/shared/lazyCompilation.js +94 -0
  22. package/dist/cjs/builder/shared/loaders/serverModuleLoader.js +12 -8
  23. package/dist/cjs/commands/build.js +9 -5
  24. package/dist/cjs/commands/deploy.js +9 -5
  25. package/dist/cjs/commands/dev.js +9 -5
  26. package/dist/cjs/commands/index.js +12 -11
  27. package/dist/cjs/commands/info.js +9 -5
  28. package/dist/cjs/commands/inspect.js +12 -8
  29. package/dist/cjs/commands/runtime.js +50 -13
  30. package/dist/cjs/commands/serve.js +9 -5
  31. package/dist/cjs/compat/hooks.js +9 -5
  32. package/dist/cjs/compat/index.js +9 -5
  33. package/dist/cjs/compat/utils.js +9 -5
  34. package/dist/cjs/config/default.js +27 -7
  35. package/dist/cjs/config/index.js +9 -5
  36. package/dist/cjs/config/initialize/index.js +9 -5
  37. package/dist/cjs/config/initialize/inits.js +9 -5
  38. package/dist/cjs/constants.js +13 -9
  39. package/dist/cjs/defineConfig.js +12 -8
  40. package/dist/cjs/esm/register-esm.js +12 -8
  41. package/dist/cjs/esm/ts-paths-loader.js +9 -5
  42. package/dist/cjs/index.js +23 -17
  43. package/dist/cjs/locale/en.js +12 -8
  44. package/dist/cjs/locale/index.js +9 -5
  45. package/dist/cjs/locale/zh.js +12 -8
  46. package/dist/cjs/plugins/analyze/constants.js +14 -10
  47. package/dist/cjs/plugins/analyze/getBundleEntry.js +9 -5
  48. package/dist/cjs/plugins/analyze/getFileSystemEntry.js +9 -5
  49. package/dist/cjs/plugins/analyze/getHtmlTemplate.js +9 -5
  50. package/dist/cjs/plugins/analyze/getServerRoutes.js +9 -5
  51. package/dist/cjs/plugins/analyze/index.js +12 -6
  52. package/dist/cjs/plugins/analyze/isDefaultExportFunction.js +10 -6
  53. package/dist/cjs/plugins/analyze/templates.js +12 -8
  54. package/dist/cjs/plugins/analyze/utils.js +9 -5
  55. package/dist/cjs/plugins/deploy/index.js +9 -5
  56. package/dist/cjs/plugins/deploy/platforms/cloudflare.js +185 -7
  57. package/dist/cjs/plugins/deploy/platforms/gh-pages.js +9 -5
  58. package/dist/cjs/plugins/deploy/platforms/netlify.js +9 -5
  59. package/dist/cjs/plugins/deploy/platforms/node.js +9 -5
  60. package/dist/cjs/plugins/deploy/platforms/templates/cloudflare-entry.mjs +141 -16
  61. package/dist/cjs/plugins/deploy/platforms/vercel.js +9 -5
  62. package/dist/cjs/plugins/deploy/utils/generator.js +9 -5
  63. package/dist/cjs/plugins/deploy/utils/index.js +19 -40
  64. package/dist/cjs/plugins/initialize/index.js +19 -6
  65. package/dist/cjs/plugins/serverBuild.js +9 -5
  66. package/dist/cjs/plugins/serverRuntime.js +12 -8
  67. package/dist/cjs/presetUltramodern.js +96 -7
  68. package/dist/cjs/rsbuild.js +55 -67
  69. package/dist/cjs/run/index.js +9 -5
  70. package/dist/cjs/types/config/cloudflareDeploy.js +18 -0
  71. package/dist/cjs/types/config/index.js +9 -5
  72. package/dist/cjs/types/config/precompress.js +18 -0
  73. package/dist/cjs/types/index.js +9 -5
  74. package/dist/cjs/ultramodern/designSystem.js +16 -12
  75. package/dist/cjs/utils/config.js +9 -5
  76. package/dist/cjs/utils/createServer.js +14 -10
  77. package/dist/cjs/utils/env.js +9 -5
  78. package/dist/cjs/utils/generateWatchFiles.js +9 -5
  79. package/dist/cjs/utils/getConfigFile.js +9 -5
  80. package/dist/cjs/utils/getSelectedEntries.js +9 -5
  81. package/dist/cjs/utils/initAppContext.js +9 -5
  82. package/dist/cjs/utils/loadPlugins.js +9 -5
  83. package/dist/cjs/utils/printInstructions.js +9 -5
  84. package/dist/cjs/utils/register.js +9 -5
  85. package/dist/cjs/utils/restart.js +9 -5
  86. package/dist/cjs/utils/routes.js +9 -5
  87. package/dist/esm/baseline.mjs +3 -77
  88. package/dist/esm/builder/generator/getBuilderEnvironments.mjs +32 -4
  89. package/dist/esm/builder/generator/index.mjs +7 -0
  90. package/dist/esm/builder/shared/builderPlugins/adapterHtml.mjs +1 -1
  91. package/dist/esm/builder/shared/builderPlugins/adapterSSR.mjs +31 -5
  92. package/dist/esm/builder/shared/bundlerPlugins/RouterPlugin.mjs +32 -3
  93. package/dist/esm/builder/shared/lazyCompilation.mjs +44 -0
  94. package/dist/esm/commands/index.mjs +2 -5
  95. package/dist/esm/commands/runtime.mjs +33 -3
  96. package/dist/esm/config/default.mjs +14 -1
  97. package/dist/esm/index.mjs +3 -2
  98. package/dist/esm/plugins/analyze/index.mjs +3 -1
  99. package/dist/esm/plugins/analyze/isDefaultExportFunction.mjs +1 -1
  100. package/dist/esm/plugins/deploy/platforms/cloudflare.mjs +176 -2
  101. package/dist/esm/plugins/deploy/platforms/templates/cloudflare-entry.mjs +141 -16
  102. package/dist/esm/plugins/deploy/utils/index.mjs +11 -36
  103. package/dist/esm/plugins/initialize/index.mjs +11 -2
  104. package/dist/esm/presetUltramodern.mjs +77 -3
  105. package/dist/esm/rsbuild.mjs +1 -8
  106. package/dist/esm/types/config/cloudflareDeploy.mjs +0 -0
  107. package/dist/esm/types/config/precompress.mjs +0 -0
  108. package/dist/esm-node/baseline.mjs +3 -77
  109. package/dist/esm-node/builder/generator/getBuilderEnvironments.mjs +32 -4
  110. package/dist/esm-node/builder/generator/index.mjs +7 -0
  111. package/dist/esm-node/builder/shared/builderPlugins/adapterHtml.mjs +1 -1
  112. package/dist/esm-node/builder/shared/builderPlugins/adapterSSR.mjs +31 -5
  113. package/dist/esm-node/builder/shared/bundlerPlugins/RouterPlugin.mjs +32 -3
  114. package/dist/esm-node/builder/shared/lazyCompilation.mjs +45 -0
  115. package/dist/esm-node/commands/index.mjs +2 -5
  116. package/dist/esm-node/commands/runtime.mjs +33 -3
  117. package/dist/esm-node/config/default.mjs +14 -1
  118. package/dist/esm-node/index.mjs +3 -2
  119. package/dist/esm-node/plugins/analyze/index.mjs +3 -1
  120. package/dist/esm-node/plugins/analyze/isDefaultExportFunction.mjs +1 -1
  121. package/dist/esm-node/plugins/deploy/platforms/cloudflare.mjs +176 -2
  122. package/dist/esm-node/plugins/deploy/platforms/templates/cloudflare-entry.mjs +141 -16
  123. package/dist/esm-node/plugins/deploy/utils/index.mjs +12 -36
  124. package/dist/esm-node/plugins/initialize/index.mjs +11 -2
  125. package/dist/esm-node/presetUltramodern.mjs +77 -3
  126. package/dist/esm-node/rsbuild.mjs +1 -8
  127. package/dist/esm-node/types/config/cloudflareDeploy.mjs +1 -0
  128. package/dist/esm-node/types/config/precompress.mjs +1 -0
  129. package/dist/types/baseline.d.ts +16 -46
  130. package/dist/types/builder/builder-rspack/index.d.ts +1 -1
  131. package/dist/types/builder/generator/index.d.ts +1 -1
  132. package/dist/types/builder/shared/bundlerPlugins/RouterPlugin.d.ts +3 -1
  133. package/dist/types/builder/shared/createCopyInfo.d.ts +1 -1
  134. package/dist/types/builder/shared/lazyCompilation.d.ts +43 -0
  135. package/dist/types/builder/shared/types.d.ts +10 -0
  136. package/dist/types/commands/index.d.ts +1 -1
  137. package/dist/types/commands/inspect.d.ts +1 -1
  138. package/dist/types/commands/runtime.d.ts +1 -0
  139. package/dist/types/config/default.d.ts +6 -0
  140. package/dist/types/locale/index.d.ts +89 -2
  141. package/dist/types/plugins/analyze/getFileSystemEntry.d.ts +2 -2
  142. package/dist/types/plugins/analyze/index.d.ts +1 -1
  143. package/dist/types/plugins/analyze/utils.d.ts +1 -1
  144. package/dist/types/plugins/deploy/index.d.ts +1 -1
  145. package/dist/types/plugins/deploy/platforms/templates/cloudflare-entry.d.mts +1 -1
  146. package/dist/types/plugins/deploy/platforms/templates/netlify-entry.d.cts +1 -1
  147. package/dist/types/plugins/deploy/platforms/templates/vercel-entry.d.cts +1 -1
  148. package/dist/types/plugins/deploy/utils/generator.d.ts +2 -2
  149. package/dist/types/plugins/deploy/utils/index.d.ts +1 -1
  150. package/dist/types/plugins/initialize/index.d.ts +1 -1
  151. package/dist/types/plugins/serverBuild.d.ts +1 -1
  152. package/dist/types/plugins/serverRuntime.d.ts +1 -1
  153. package/dist/types/presetUltramodern.d.ts +52 -2
  154. package/dist/types/rsbuild.d.ts +1 -1
  155. package/dist/types/run/index.d.ts +1 -1
  156. package/dist/types/types/config/cloudflareDeploy.d.ts +79 -0
  157. package/dist/types/types/config/deploy.d.ts +9 -15
  158. package/dist/types/types/config/output.d.ts +4 -20
  159. package/dist/types/types/config/precompress.d.ts +20 -0
  160. package/dist/types/types/plugin.d.ts +20 -0
  161. package/dist/types/utils/getConfigFile.d.ts +1 -1
  162. package/dist/types/utils/loadPlugins.d.ts +2 -2
  163. package/package.json +26 -21
  164. package/dist/esm/rslib-runtime.mjs +0 -18
  165. package/dist/esm-node/rslib-runtime.mjs +0 -19
@@ -10,11 +10,15 @@ var __webpack_require__ = {};
10
10
  };
11
11
  })();
12
12
  (()=>{
13
- __webpack_require__.d = (exports1, definition)=>{
14
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
- enumerable: true,
16
- get: definition[key]
17
- });
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
18
22
  };
19
23
  })();
20
24
  (()=>{
@@ -59,7 +63,7 @@ const isDefaultExportFunction = (file)=>{
59
63
  [
60
64
  'pipelineOperator',
61
65
  {
62
- proposal: 'minimal'
66
+ proposal: 'fsharp'
63
67
  }
64
68
  ],
65
69
  'optionalChaining',
@@ -1,11 +1,15 @@
1
1
  "use strict";
2
2
  var __webpack_require__ = {};
3
3
  (()=>{
4
- __webpack_require__.d = (exports1, definition)=>{
5
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
- enumerable: true,
7
- get: definition[key]
8
- });
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
9
13
  };
10
14
  })();
11
15
  (()=>{
@@ -23,9 +27,6 @@ var __webpack_require__ = {};
23
27
  })();
24
28
  var __webpack_exports__ = {};
25
29
  __webpack_require__.r(__webpack_exports__);
26
- __webpack_require__.d(__webpack_exports__, {
27
- html: ()=>html
28
- });
29
30
  const html = (partials)=>`
30
31
  <!DOCTYPE html>
31
32
  <html>
@@ -47,6 +48,9 @@ const html = (partials)=>`
47
48
 
48
49
  </html>
49
50
  `;
51
+ __webpack_require__.d(__webpack_exports__, {}, {
52
+ html: html
53
+ });
50
54
  exports.html = __webpack_exports__.html;
51
55
  for(var __rspack_i in __webpack_exports__)if (-1 === [
52
56
  "html"
@@ -10,11 +10,15 @@ var __webpack_require__ = {};
10
10
  };
11
11
  })();
12
12
  (()=>{
13
- __webpack_require__.d = (exports1, definition)=>{
14
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
- enumerable: true,
16
- get: definition[key]
17
- });
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
18
22
  };
19
23
  })();
20
24
  (()=>{
@@ -1,11 +1,15 @@
1
1
  "use strict";
2
2
  var __webpack_require__ = {};
3
3
  (()=>{
4
- __webpack_require__.d = (exports1, definition)=>{
5
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
6
- enumerable: true,
7
- get: definition[key]
8
- });
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
7
+ enumerable: true,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get");
12
+ define(values, "value");
9
13
  };
10
14
  })();
11
15
  (()=>{
@@ -10,11 +10,15 @@ var __webpack_require__ = {};
10
10
  };
11
11
  })();
12
12
  (()=>{
13
- __webpack_require__.d = (exports1, definition)=>{
14
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
- enumerable: true,
16
- get: definition[key]
17
- });
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
18
22
  };
19
23
  })();
20
24
  (()=>{
@@ -50,7 +54,88 @@ const PUBLIC_ASSETS_DIRECTORY = 'public';
50
54
  const WORKER_BUNDLE_DIRECTORY = 'worker';
51
55
  const SERVER_BUNDLE_DIRECTORY = 'bundles';
52
56
  const BFF_EFFECT_WORKER_ENTRY = `${WORKER_BUNDLE_DIRECTORY}/__modern_bff_effect.js`;
53
- const getCompatibilityDate = ()=>new Date().toISOString().slice(0, 10);
57
+ const DEFAULT_COMPATIBILITY_DATE = '2026-06-02';
58
+ const COMPATIBILITY_DATE_PATTERN = /^\d{4}-\d{2}-\d{2}$/u;
59
+ const DEFAULT_SECURITY_HEADERS = {
60
+ referrerPolicy: 'strict-origin-when-cross-origin',
61
+ contentTypeOptions: 'nosniff',
62
+ permissionsPolicy: 'camera=(), geolocation=(), microphone=(), payment=(), usb=()'
63
+ };
64
+ const DEFAULT_CORS_ALLOWED_METHODS = [
65
+ 'GET',
66
+ 'HEAD',
67
+ 'POST',
68
+ 'PUT',
69
+ 'PATCH',
70
+ 'DELETE',
71
+ 'OPTIONS'
72
+ ];
73
+ const DEFAULT_CSP_DIRECTIVES = {
74
+ 'base-uri': [
75
+ "'self'"
76
+ ],
77
+ 'connect-src': [
78
+ "'self'",
79
+ 'https:',
80
+ 'http:',
81
+ 'wss:',
82
+ 'ws:'
83
+ ],
84
+ 'default-src': [
85
+ "'self'"
86
+ ],
87
+ 'font-src': [
88
+ "'self'",
89
+ 'data:',
90
+ 'https:',
91
+ 'http:'
92
+ ],
93
+ 'form-action': [
94
+ "'self'"
95
+ ],
96
+ 'frame-ancestors': [
97
+ "'self'"
98
+ ],
99
+ 'img-src': [
100
+ "'self'",
101
+ 'data:',
102
+ 'blob:',
103
+ 'https:',
104
+ 'http:'
105
+ ],
106
+ 'manifest-src': [
107
+ "'self'",
108
+ 'https:',
109
+ 'http:'
110
+ ],
111
+ 'object-src': [
112
+ "'none'"
113
+ ],
114
+ "script-src": [
115
+ "'self'",
116
+ "'unsafe-inline'",
117
+ "'unsafe-eval'",
118
+ 'https:',
119
+ 'http:',
120
+ 'blob:'
121
+ ],
122
+ 'style-src': [
123
+ "'self'",
124
+ "'unsafe-inline'",
125
+ 'https:',
126
+ 'http:'
127
+ ],
128
+ 'worker-src': [
129
+ "'self'",
130
+ 'blob:'
131
+ ]
132
+ };
133
+ const getCompatibilityDate = (modernConfig)=>{
134
+ const configuredDate = modernConfig.deploy?.worker?.compatibilityDate?.trim();
135
+ const compatibilityDate = configuredDate || DEFAULT_COMPATIBILITY_DATE;
136
+ if (!COMPATIBILITY_DATE_PATTERN.test(compatibilityDate)) throw new Error(`deploy.worker.compatibilityDate must use YYYY-MM-DD, received ${JSON.stringify(compatibilityDate)}.`);
137
+ return compatibilityDate;
138
+ };
54
139
  const getWorkerName = (appDirectory)=>{
55
140
  const basename = external_node_path_default().basename(appDirectory);
56
141
  return basename.replace(/[^a-zA-Z0-9-_]/g, '-') || 'modern-cloudflare-worker';
@@ -59,6 +144,98 @@ const getConfiguredWorkerName = (appDirectory, modernConfig)=>{
59
144
  const configuredName = modernConfig.deploy?.worker?.name?.trim();
60
145
  return configuredName || getWorkerName(appDirectory);
61
146
  };
147
+ const normalizeDirectiveValues = (value)=>{
148
+ const values = Array.isArray(value) ? value : [
149
+ value
150
+ ];
151
+ return [
152
+ ...new Set(values.map((entry)=>entry.trim()).filter(Boolean))
153
+ ];
154
+ };
155
+ const appendDirectiveValues = (directives, name, values)=>{
156
+ if (!values?.length) return;
157
+ directives[name] = normalizeDirectiveValues([
158
+ ...directives[name] ?? [],
159
+ ...values
160
+ ]);
161
+ };
162
+ const createContentSecurityPolicy = (config)=>{
163
+ const mode = config?.mode ?? 'report-only';
164
+ if ('off' === mode) return {
165
+ mode,
166
+ directives: {},
167
+ reason: config?.reason
168
+ };
169
+ const directives = Object.fromEntries(Object.entries(DEFAULT_CSP_DIRECTIVES).map(([name, values])=>[
170
+ name,
171
+ [
172
+ ...values
173
+ ]
174
+ ]));
175
+ for (const [name, value] of Object.entries(config?.directives ?? {}))if (false === value) delete directives[name];
176
+ else directives[name] = normalizeDirectiveValues(value);
177
+ if (config?.frameAncestors === false) delete directives['frame-ancestors'];
178
+ else if (config?.frameAncestors) directives['frame-ancestors'] = normalizeDirectiveValues(config.frameAncestors);
179
+ appendDirectiveValues(directives, "script-src", config?.additionalScriptSrc);
180
+ appendDirectiveValues(directives, 'style-src', config?.additionalStyleSrc);
181
+ appendDirectiveValues(directives, 'connect-src', config?.additionalConnectSrc);
182
+ appendDirectiveValues(directives, 'img-src', config?.additionalImgSrc);
183
+ if (config?.reportUri) directives['report-uri'] = [
184
+ config.reportUri
185
+ ];
186
+ return {
187
+ mode,
188
+ directives,
189
+ reason: config?.reason
190
+ };
191
+ };
192
+ const createNoindexPolicy = (noindex)=>{
193
+ if (false === noindex) return {
194
+ workersDev: false,
195
+ localhost: false,
196
+ previewHostnames: []
197
+ };
198
+ if (true === noindex || void 0 === noindex) return {
199
+ workersDev: true,
200
+ localhost: true,
201
+ previewHostnames: []
202
+ };
203
+ return {
204
+ workersDev: noindex.workersDev ?? true,
205
+ localhost: noindex.localhost ?? true,
206
+ previewHostnames: noindex.previewHostnames ?? [],
207
+ reason: noindex.reason
208
+ };
209
+ };
210
+ const createCloudflareWorkerCorsPolicy = (cors)=>({
211
+ assets: cors?.assets ?? true,
212
+ allowedOrigins: normalizeDirectiveValues(cors?.allowedOrigins ?? []),
213
+ allowedMethods: cors?.allowedMethods?.length ? normalizeDirectiveValues(cors.allowedMethods.map((method)=>method.toUpperCase())) : DEFAULT_CORS_ALLOWED_METHODS,
214
+ allowedHeaders: cors?.allowedHeaders?.length ? normalizeDirectiveValues(cors.allowedHeaders) : [
215
+ '*'
216
+ ],
217
+ reason: cors?.reason
218
+ });
219
+ const createCloudflareWorkerSecurityPolicy = (modernConfig)=>{
220
+ const security = modernConfig.deploy?.worker?.security;
221
+ if (security?.enabled === false) return {
222
+ enabled: false,
223
+ cors: createCloudflareWorkerCorsPolicy(security.cors),
224
+ reason: security.reason
225
+ };
226
+ return {
227
+ enabled: true,
228
+ headers: {
229
+ referrerPolicy: security?.headers?.referrerPolicy ?? DEFAULT_SECURITY_HEADERS.referrerPolicy,
230
+ contentTypeOptions: security?.headers?.contentTypeOptions ?? DEFAULT_SECURITY_HEADERS.contentTypeOptions,
231
+ permissionsPolicy: security?.headers?.permissionsPolicy ?? DEFAULT_SECURITY_HEADERS.permissionsPolicy
232
+ },
233
+ contentSecurityPolicy: createContentSecurityPolicy(security?.contentSecurityPolicy),
234
+ noindex: createNoindexPolicy(security?.noindex),
235
+ cors: createCloudflareWorkerCorsPolicy(security?.cors),
236
+ reason: security?.reason
237
+ };
238
+ };
62
239
  const readRouteSpec = async (outputDirectory)=>{
63
240
  const routeSpecPath = external_node_path_default().join(outputDirectory, ROUTE_SPEC_OUTPUT);
64
241
  if (!await utils_namespaceObject.fs.pathExists(routeSpecPath)) return {
@@ -114,6 +291,7 @@ const createWorkerManifest = async (outputDirectory, modernConfig)=>{
114
291
  loadableStats: LOADABLE_STATS_FILE,
115
292
  routeManifest: ROUTE_MANIFEST_FILE
116
293
  },
294
+ security: createCloudflareWorkerSecurityPolicy(modernConfig),
117
295
  bff: isEffectBff && primaryBffPrefix && effectBffWorkerExists ? {
118
296
  runtimeFramework: 'effect',
119
297
  prefix: primaryBffPrefix,
@@ -186,7 +364,7 @@ const createCloudflarePreset = ({ appContext, modernConfig })=>{
186
364
  $schema: 'node_modules/wrangler/config-schema.json',
187
365
  name: workerName,
188
366
  main: WORKER_ENTRY,
189
- compatibility_date: getCompatibilityDate(),
367
+ compatibility_date: getCompatibilityDate(modernConfig),
190
368
  compatibility_flags: [
191
369
  'nodejs_compat',
192
370
  'global_fetch_strictly_public'
@@ -10,11 +10,15 @@ var __webpack_require__ = {};
10
10
  };
11
11
  })();
12
12
  (()=>{
13
- __webpack_require__.d = (exports1, definition)=>{
14
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
- enumerable: true,
16
- get: definition[key]
17
- });
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
18
22
  };
19
23
  })();
20
24
  (()=>{
@@ -10,11 +10,15 @@ var __webpack_require__ = {};
10
10
  };
11
11
  })();
12
12
  (()=>{
13
- __webpack_require__.d = (exports1, definition)=>{
14
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
- enumerable: true,
16
- get: definition[key]
17
- });
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
18
22
  };
19
23
  })();
20
24
  (()=>{
@@ -10,11 +10,15 @@ var __webpack_require__ = {};
10
10
  };
11
11
  })();
12
12
  (()=>{
13
- __webpack_require__.d = (exports1, definition)=>{
14
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
- enumerable: true,
16
- get: definition[key]
17
- });
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
18
22
  };
19
23
  })();
20
24
  (()=>{
@@ -3,27 +3,129 @@ const MODERN_WORKER_MANIFEST = p_workerManifest;
3
3
  const WORKER_MODULE_LOADERS = p_workerModuleLoaders;
4
4
  const workerModulePromises = new Map();
5
5
  const remoteJsonPromises = new Map();
6
- const CORS_HEADERS = {
6
+ const CORS_POLICY = MODERN_WORKER_MANIFEST.security?.cors || {};
7
+ const ASSET_CORS_ENABLED = false !== CORS_POLICY.assets;
8
+ const APP_CORS_ALLOWED_ORIGINS = (CORS_POLICY.allowedOrigins || []).map((origin)=>String(origin).toLowerCase());
9
+ const APP_CORS_ALLOWED_METHODS = (CORS_POLICY.allowedMethods?.length ? CORS_POLICY.allowedMethods : [
10
+ 'GET',
11
+ 'HEAD',
12
+ 'POST',
13
+ 'PUT',
14
+ 'PATCH',
15
+ 'DELETE',
16
+ 'OPTIONS'
17
+ ]).join(', ');
18
+ const APP_CORS_ALLOWED_HEADERS = (CORS_POLICY.allowedHeaders?.length ? CORS_POLICY.allowedHeaders : [
19
+ '*'
20
+ ]).join(', ');
21
+ const ASSET_CORS_HEADERS = {
7
22
  'access-control-allow-headers': '*',
8
23
  'access-control-allow-methods': 'GET, HEAD, OPTIONS',
9
24
  'access-control-allow-origin': '*'
10
25
  };
11
26
  globalThis.__dirname ??= '/';
12
27
  globalThis.__filename ??= '/index.js';
13
- function withCorsHeaders(response) {
28
+ function getAllowedAppCorsOrigin(request) {
29
+ if (0 === APP_CORS_ALLOWED_ORIGINS.length) return null;
30
+ const origin = request.headers.get('origin');
31
+ if (!origin) return null;
32
+ if (APP_CORS_ALLOWED_ORIGINS.includes('*')) return '*';
33
+ return APP_CORS_ALLOWED_ORIGINS.includes(origin.toLowerCase()) ? origin : null;
34
+ }
35
+ function appendVaryOrigin(headers) {
36
+ const vary = headers.get('vary');
37
+ if (!vary) return void headers.set('vary', 'origin');
38
+ const varyValues = vary.split(',').map((value)=>value.trim().toLowerCase());
39
+ if (!varyValues.includes('origin')) headers.set('vary', `${vary}, origin`);
40
+ }
41
+ function withAppCorsHeaders(response, request) {
42
+ const allowedOrigin = getAllowedAppCorsOrigin(request);
43
+ if (!allowedOrigin) return response;
14
44
  const headers = new Headers(response.headers);
15
- for (const [name, value] of Object.entries(CORS_HEADERS))if (!headers.has(name)) headers.set(name, value);
45
+ if (!headers.has('access-control-allow-origin')) headers.set('access-control-allow-origin', allowedOrigin);
46
+ if ('*' !== allowedOrigin) appendVaryOrigin(headers);
16
47
  return new Response(response.body, {
17
48
  headers,
18
49
  status: response.status,
19
50
  statusText: response.statusText
20
51
  });
21
52
  }
53
+ function withAssetCorsHeaders(response) {
54
+ if (!ASSET_CORS_ENABLED) return response;
55
+ const headers = new Headers(response.headers);
56
+ for (const [name, value] of Object.entries(ASSET_CORS_HEADERS))if (!headers.has(name)) headers.set(name, value);
57
+ return new Response(response.body, {
58
+ headers,
59
+ status: response.status,
60
+ statusText: response.statusText
61
+ });
62
+ }
63
+ function setHeaderIfEnabled(headers, name, value) {
64
+ if (false === value || 'string' != typeof value || '' === value.trim()) return;
65
+ if (!headers.has(name)) headers.set(name, value);
66
+ }
67
+ function renderContentSecurityPolicy(directives) {
68
+ return Object.entries(directives || {}).filter(([, values])=>Array.isArray(values) && values.length > 0).sort(([left], [right])=>left.localeCompare(right)).map(([name, values])=>`${name} ${values.join(' ')}`).join('; ');
69
+ }
70
+ function isHtmlResponse(response) {
71
+ return (response.headers.get('content-type') || '').includes('text/html');
72
+ }
73
+ function matchesPreviewHostname(hostname, pattern) {
74
+ const normalizedHostname = hostname.toLowerCase();
75
+ const normalizedPattern = String(pattern || '').toLowerCase();
76
+ if (!normalizedPattern) return false;
77
+ if (normalizedPattern.startsWith('*.')) return normalizedHostname.endsWith(normalizedPattern.slice(1));
78
+ return normalizedHostname === normalizedPattern;
79
+ }
80
+ function shouldNoindex(request, noindex) {
81
+ if (!noindex || false === noindex) return false;
82
+ const { hostname } = new URL(request.url);
83
+ const normalizedHostname = hostname.toLowerCase();
84
+ if (false !== noindex.localhost && ('localhost' === normalizedHostname || '127.0.0.1' === normalizedHostname || '[::1]' === normalizedHostname)) return true;
85
+ if (false !== noindex.workersDev && normalizedHostname.endsWith('.workers.dev')) return true;
86
+ return (noindex.previewHostnames || []).some((pattern)=>matchesPreviewHostname(normalizedHostname, pattern));
87
+ }
88
+ function withCloudflareSecurityHeaders(response, request) {
89
+ const security = MODERN_WORKER_MANIFEST.security;
90
+ if (!security || false === security.enabled) return response;
91
+ const headers = new Headers(response.headers);
92
+ const configuredHeaders = security.headers || {};
93
+ setHeaderIfEnabled(headers, 'referrer-policy', configuredHeaders.referrerPolicy);
94
+ setHeaderIfEnabled(headers, 'x-content-type-options', configuredHeaders.contentTypeOptions);
95
+ setHeaderIfEnabled(headers, 'permissions-policy', configuredHeaders.permissionsPolicy);
96
+ const csp = security.contentSecurityPolicy;
97
+ const cspHeader = csp?.mode === 'enforce' ? 'content-security-policy' : 'content-security-policy-report-only';
98
+ const cspValue = renderContentSecurityPolicy(csp?.directives);
99
+ if (isHtmlResponse(response) && csp?.mode !== 'off' && cspValue && !headers.has(cspHeader)) headers.set(cspHeader, cspValue);
100
+ if (shouldNoindex(request, security.noindex)) headers.set('x-robots-tag', 'noindex, nofollow');
101
+ return new Response(response.body, {
102
+ headers,
103
+ status: response.status,
104
+ statusText: response.statusText
105
+ });
106
+ }
107
+ function createRenderableRequest(request) {
108
+ if ('HEAD' !== request.method) return request;
109
+ return new Request(request, {
110
+ method: 'GET'
111
+ });
112
+ }
113
+ function finalizeResponseForRequest(response, request) {
114
+ const securedResponse = withCloudflareSecurityHeaders(response, request);
115
+ if ('HEAD' !== request.method) return securedResponse;
116
+ const headers = new Headers(securedResponse.headers);
117
+ headers.delete('content-length');
118
+ return new Response(null, {
119
+ headers,
120
+ status: securedResponse.status,
121
+ statusText: securedResponse.statusText
122
+ });
123
+ }
22
124
  function isFingerprintedAssetPathname(pathname) {
23
125
  return /(?:^|\/)[^/]+\.[a-f0-9]{8,}\.(?:css|js|mjs|json|svg|png|jpe?g|webp|avif|gif|woff2?|ttf)$/iu.test(pathname);
24
126
  }
25
127
  function withAssetHeaders(response, request) {
26
- const corsResponse = withCorsHeaders(response);
128
+ const corsResponse = withAssetCorsHeaders(response);
27
129
  const headers = new Headers(corsResponse.headers);
28
130
  const { pathname } = new URL(request.url);
29
131
  if (isFingerprintedAssetPathname(pathname)) headers.set('cache-control', 'public, max-age=31536000, immutable');
@@ -33,10 +135,30 @@ function withAssetHeaders(response, request) {
33
135
  statusText: corsResponse.statusText
34
136
  });
35
137
  }
36
- function createCorsPreflightResponse(request) {
138
+ async function createCorsPreflightResponse(request, env) {
37
139
  if ('OPTIONS' !== request.method) return null;
140
+ const allowedOrigin = getAllowedAppCorsOrigin(request);
141
+ if (allowedOrigin) {
142
+ const headers = new Headers({
143
+ 'access-control-allow-headers': APP_CORS_ALLOWED_HEADERS,
144
+ 'access-control-allow-methods': APP_CORS_ALLOWED_METHODS,
145
+ 'access-control-allow-origin': allowedOrigin
146
+ });
147
+ if ('*' !== allowedOrigin) headers.set('vary', 'origin');
148
+ return new Response(null, {
149
+ headers,
150
+ status: 204
151
+ });
152
+ }
153
+ if (!ASSET_CORS_ENABLED) return null;
154
+ const assets = env?.[ASSETS_BINDING];
155
+ if (!assets || 'function' != typeof assets.fetch) return null;
156
+ const assetResponse = await assets.fetch(new Request(request.url, {
157
+ method: 'HEAD'
158
+ }));
159
+ if (!assetResponse || 404 === assetResponse.status) return null;
38
160
  return new Response(null, {
39
- headers: CORS_HEADERS,
161
+ headers: ASSET_CORS_HEADERS,
40
162
  status: 204
41
163
  });
42
164
  }
@@ -417,22 +539,25 @@ async function dispatchBffRequest(request, env) {
417
539
  }
418
540
  export default {
419
541
  async fetch (request, env, ctx) {
420
- const corsPreflightResponse = createCorsPreflightResponse(request);
421
- if (corsPreflightResponse) return corsPreflightResponse;
542
+ const corsPreflightResponse = await createCorsPreflightResponse(request, env);
543
+ if (corsPreflightResponse) return finalizeResponseForRequest(corsPreflightResponse, request);
422
544
  const assetResponse = await fetchAsset(request, env);
423
- if (assetResponse) return assetResponse;
545
+ if (assetResponse) return finalizeResponseForRequest(assetResponse, request);
424
546
  const bffResponse = await dispatchBffRequest(request, env);
425
- if (bffResponse) return withCorsHeaders(bffResponse);
547
+ if (bffResponse) return finalizeResponseForRequest(withAppCorsHeaders(bffResponse, request), request);
426
548
  const route = findRoute(request);
427
549
  const { pathname } = new URL(request.url);
428
- if (isAssetLikePathname(pathname) && !routeMatchesExactly(route, pathname)) return withCorsHeaders(new Response('Not found', {
550
+ if (isAssetLikePathname(pathname) && !routeMatchesExactly(route, pathname)) return finalizeResponseForRequest(withAppCorsHeaders(new Response('Not found', {
429
551
  status: 404
430
- }));
431
- if (route?.worker) return withCorsHeaders(await dispatchRouteWorker(route, request, env, ctx));
552
+ }), request), request);
553
+ if (route?.worker) {
554
+ const renderableRequest = createRenderableRequest(request);
555
+ return finalizeResponseForRequest(withAppCorsHeaders(await dispatchRouteWorker(route, renderableRequest, env, ctx), request), request);
556
+ }
432
557
  const htmlResponse = await fetchRouteHtml(route, request, env);
433
- if (htmlResponse) return htmlResponse;
434
- return withCorsHeaders(new Response('Not found', {
558
+ if (htmlResponse) return finalizeResponseForRequest(htmlResponse, request);
559
+ return finalizeResponseForRequest(withAppCorsHeaders(new Response('Not found', {
435
560
  status: 404
436
- }));
561
+ }), request), request);
437
562
  }
438
563
  };
@@ -10,11 +10,15 @@ var __webpack_require__ = {};
10
10
  };
11
11
  })();
12
12
  (()=>{
13
- __webpack_require__.d = (exports1, definition)=>{
14
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
- enumerable: true,
16
- get: definition[key]
17
- });
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
18
22
  };
19
23
  })();
20
24
  (()=>{
@@ -10,11 +10,15 @@ var __webpack_require__ = {};
10
10
  };
11
11
  })();
12
12
  (()=>{
13
- __webpack_require__.d = (exports1, definition)=>{
14
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
15
- enumerable: true,
16
- get: definition[key]
17
- });
13
+ __webpack_require__.d = (exports1, getters, values)=>{
14
+ var define = (defs, kind)=>{
15
+ for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
16
+ enumerable: true,
17
+ [kind]: defs[key]
18
+ });
19
+ };
20
+ define(getters, "get");
21
+ define(values, "value");
18
22
  };
19
23
  })();
20
24
  (()=>{