@webflow/cloud-app 0.1.0-beta.7

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 (174) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -0
  3. package/dist/bindings.d.ts +185 -0
  4. package/dist/bindings.d.ts.map +1 -0
  5. package/dist/bindings.js +120 -0
  6. package/dist/bindings.js.map +1 -0
  7. package/dist/config/package-json.d.ts +57 -0
  8. package/dist/config/package-json.d.ts.map +1 -0
  9. package/dist/config/package-json.js +94 -0
  10. package/dist/config/package-json.js.map +1 -0
  11. package/dist/config/webflow-json.d.ts +53 -0
  12. package/dist/config/webflow-json.d.ts.map +1 -0
  13. package/dist/config/webflow-json.js +72 -0
  14. package/dist/config/webflow-json.js.map +1 -0
  15. package/dist/create-webflow-json.d.ts +24 -0
  16. package/dist/create-webflow-json.d.ts.map +1 -0
  17. package/dist/create-webflow-json.js +170 -0
  18. package/dist/create-webflow-json.js.map +1 -0
  19. package/dist/errors.d.ts +13 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +23 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/frameworks/astro/adapter-patches/ensure-fixed-cloudflare-adapter.d.ts +36 -0
  24. package/dist/frameworks/astro/adapter-patches/ensure-fixed-cloudflare-adapter.d.ts.map +1 -0
  25. package/dist/frameworks/astro/adapter-patches/ensure-fixed-cloudflare-adapter.js +94 -0
  26. package/dist/frameworks/astro/adapter-patches/ensure-fixed-cloudflare-adapter.js.map +1 -0
  27. package/dist/frameworks/astro/adapter-patches/strip-cloudflare-base-nesting.d.ts +2 -0
  28. package/dist/frameworks/astro/adapter-patches/strip-cloudflare-base-nesting.d.ts.map +1 -0
  29. package/dist/frameworks/astro/adapter-patches/strip-cloudflare-base-nesting.js +97 -0
  30. package/dist/frameworks/astro/adapter-patches/strip-cloudflare-base-nesting.js.map +1 -0
  31. package/dist/frameworks/astro/astro5.d.ts +28 -0
  32. package/dist/frameworks/astro/astro5.d.ts.map +1 -0
  33. package/dist/frameworks/astro/astro5.js +259 -0
  34. package/dist/frameworks/astro/astro5.js.map +1 -0
  35. package/dist/frameworks/astro/astro6.d.ts +28 -0
  36. package/dist/frameworks/astro/astro6.d.ts.map +1 -0
  37. package/dist/frameworks/astro/astro6.js +286 -0
  38. package/dist/frameworks/astro/astro6.js.map +1 -0
  39. package/dist/frameworks/astro/astro7.d.ts +28 -0
  40. package/dist/frameworks/astro/astro7.d.ts.map +1 -0
  41. package/dist/frameworks/astro/astro7.js +283 -0
  42. package/dist/frameworks/astro/astro7.js.map +1 -0
  43. package/dist/frameworks/astro/index.d.ts +10 -0
  44. package/dist/frameworks/astro/index.d.ts.map +1 -0
  45. package/dist/frameworks/astro/index.js +16 -0
  46. package/dist/frameworks/astro/index.js.map +1 -0
  47. package/dist/frameworks/astro/templates/astro.config.webflow.ts +61 -0
  48. package/dist/frameworks/astro/templates/v5/astro.config.mjs.template +25 -0
  49. package/dist/frameworks/astro/templates/v5/webflow-loader.ts +103 -0
  50. package/dist/frameworks/astro/templates/v5/wrangler.json +6 -0
  51. package/dist/frameworks/astro/templates/v6/astro.config.mjs.template +35 -0
  52. package/dist/frameworks/astro/templates/v6/webflow-loader.ts +112 -0
  53. package/dist/frameworks/astro/templates/v6/wrangler.json +9 -0
  54. package/dist/frameworks/astro/templates/v7/astro.config.mjs.template +34 -0
  55. package/dist/frameworks/astro/templates/v7/webflow-loader.ts +113 -0
  56. package/dist/frameworks/astro/templates/v7/wrangler.json +9 -0
  57. package/dist/frameworks/base.d.ts +134 -0
  58. package/dist/frameworks/base.d.ts.map +1 -0
  59. package/dist/frameworks/base.js +175 -0
  60. package/dist/frameworks/base.js.map +1 -0
  61. package/dist/frameworks/errors.d.ts +72 -0
  62. package/dist/frameworks/errors.d.ts.map +1 -0
  63. package/dist/frameworks/errors.js +120 -0
  64. package/dist/frameworks/errors.js.map +1 -0
  65. package/dist/frameworks/nextjs/adapter-resolver.d.ts +72 -0
  66. package/dist/frameworks/nextjs/adapter-resolver.d.ts.map +1 -0
  67. package/dist/frameworks/nextjs/adapter-resolver.js +246 -0
  68. package/dist/frameworks/nextjs/adapter-resolver.js.map +1 -0
  69. package/dist/frameworks/nextjs/index.d.ts +38 -0
  70. package/dist/frameworks/nextjs/index.d.ts.map +1 -0
  71. package/dist/frameworks/nextjs/index.js +268 -0
  72. package/dist/frameworks/nextjs/index.js.map +1 -0
  73. package/dist/frameworks/nextjs/templates/next.config.ts.template +13 -0
  74. package/dist/frameworks/nextjs/templates/next.config.webflow.ts +46 -0
  75. package/dist/frameworks/nextjs/templates/open-next.config.ts +3 -0
  76. package/dist/frameworks/nextjs/templates/webflow-loader.ts +44 -0
  77. package/dist/frameworks/nextjs/templates/wrangler.json +6 -0
  78. package/dist/frameworks/registry.d.ts +127 -0
  79. package/dist/frameworks/registry.d.ts.map +1 -0
  80. package/dist/frameworks/registry.js +257 -0
  81. package/dist/frameworks/registry.js.map +1 -0
  82. package/dist/frameworks/static/index.d.ts +93 -0
  83. package/dist/frameworks/static/index.d.ts.map +1 -0
  84. package/dist/frameworks/static/index.js +352 -0
  85. package/dist/frameworks/static/index.js.map +1 -0
  86. package/dist/frameworks/static/templates/wrangler.json +7 -0
  87. package/dist/frameworks/types.d.ts +138 -0
  88. package/dist/frameworks/types.d.ts.map +1 -0
  89. package/dist/frameworks/types.js +3 -0
  90. package/dist/frameworks/types.js.map +1 -0
  91. package/dist/frameworks/vite/index.d.ts +46 -0
  92. package/dist/frameworks/vite/index.d.ts.map +1 -0
  93. package/dist/frameworks/vite/index.js +303 -0
  94. package/dist/frameworks/vite/index.js.map +1 -0
  95. package/dist/frameworks/vite/templates/vite.config.ts.template +14 -0
  96. package/dist/frameworks/vite/templates/vite.config.webflow.ts +52 -0
  97. package/dist/frameworks/vite/templates/wrangler.json +10 -0
  98. package/dist/index.d.ts +44 -0
  99. package/dist/index.d.ts.map +1 -0
  100. package/dist/index.js +118 -0
  101. package/dist/index.js.map +1 -0
  102. package/dist/pipeline.d.ts +8 -0
  103. package/dist/pipeline.d.ts.map +1 -0
  104. package/dist/pipeline.js +263 -0
  105. package/dist/pipeline.js.map +1 -0
  106. package/dist/ports/command-runner.d.ts +60 -0
  107. package/dist/ports/command-runner.d.ts.map +1 -0
  108. package/dist/ports/command-runner.js +116 -0
  109. package/dist/ports/command-runner.js.map +1 -0
  110. package/dist/ports/filesystem.d.ts +19 -0
  111. package/dist/ports/filesystem.d.ts.map +1 -0
  112. package/dist/ports/filesystem.js +68 -0
  113. package/dist/ports/filesystem.js.map +1 -0
  114. package/dist/ports/index.d.ts +17 -0
  115. package/dist/ports/index.d.ts.map +1 -0
  116. package/dist/ports/index.js +14 -0
  117. package/dist/ports/index.js.map +1 -0
  118. package/dist/ports/logger.d.ts +22 -0
  119. package/dist/ports/logger.d.ts.map +1 -0
  120. package/dist/ports/logger.js +18 -0
  121. package/dist/ports/logger.js.map +1 -0
  122. package/dist/ports/telemetry.d.ts +23 -0
  123. package/dist/ports/telemetry.d.ts.map +1 -0
  124. package/dist/ports/telemetry.js +12 -0
  125. package/dist/ports/telemetry.js.map +1 -0
  126. package/dist/toolchain/errors.d.ts +32 -0
  127. package/dist/toolchain/errors.d.ts.map +1 -0
  128. package/dist/toolchain/errors.js +31 -0
  129. package/dist/toolchain/errors.js.map +1 -0
  130. package/dist/toolchain/resolver.d.ts +25 -0
  131. package/dist/toolchain/resolver.d.ts.map +1 -0
  132. package/dist/toolchain/resolver.js +200 -0
  133. package/dist/toolchain/resolver.js.map +1 -0
  134. package/dist/toolchain/types.d.ts +52 -0
  135. package/dist/toolchain/types.d.ts.map +1 -0
  136. package/dist/toolchain/types.js +10 -0
  137. package/dist/toolchain/types.js.map +1 -0
  138. package/dist/types.d.ts +66 -0
  139. package/dist/types.d.ts.map +1 -0
  140. package/dist/types.js +3 -0
  141. package/dist/types.js.map +1 -0
  142. package/dist/utils/fs.d.ts +29 -0
  143. package/dist/utils/fs.d.ts.map +1 -0
  144. package/dist/utils/fs.js +126 -0
  145. package/dist/utils/fs.js.map +1 -0
  146. package/dist/utils/index.d.ts +11 -0
  147. package/dist/utils/index.d.ts.map +1 -0
  148. package/dist/utils/index.js +27 -0
  149. package/dist/utils/index.js.map +1 -0
  150. package/dist/utils/node-version.d.ts +20 -0
  151. package/dist/utils/node-version.d.ts.map +1 -0
  152. package/dist/utils/node-version.js +113 -0
  153. package/dist/utils/node-version.js.map +1 -0
  154. package/dist/utils/process.d.ts +25 -0
  155. package/dist/utils/process.d.ts.map +1 -0
  156. package/dist/utils/process.js +40 -0
  157. package/dist/utils/process.js.map +1 -0
  158. package/dist/utils/reserved-env.d.ts +26 -0
  159. package/dist/utils/reserved-env.d.ts.map +1 -0
  160. package/dist/utils/reserved-env.js +51 -0
  161. package/dist/utils/reserved-env.js.map +1 -0
  162. package/dist/utils/template.d.ts +15 -0
  163. package/dist/utils/template.d.ts.map +1 -0
  164. package/dist/utils/template.js +75 -0
  165. package/dist/utils/template.js.map +1 -0
  166. package/dist/utils/version.d.ts +9 -0
  167. package/dist/utils/version.d.ts.map +1 -0
  168. package/dist/utils/version.js +52 -0
  169. package/dist/utils/version.js.map +1 -0
  170. package/dist/wrangler.d.ts +192 -0
  171. package/dist/wrangler.d.ts.map +1 -0
  172. package/dist/wrangler.js +246 -0
  173. package/dist/wrangler.js.map +1 -0
  174. package/package.json +47 -0
@@ -0,0 +1,268 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.NextJsBuilder = void 0;
37
+ /**
38
+ * Next.js Framework Builder
39
+ *
40
+ * Builds Next.js projects for Cloudflare Workers deployment using
41
+ * @opennextjs/cloudflare.
42
+ *
43
+ * - Requires @opennextjs/cloudflare
44
+ * - Build command: opennextjs-cloudflare build
45
+ * - Build output: .open-next/assets (static) + .open-next/worker.js (worker)
46
+ */
47
+ const path = __importStar(require("node:path"));
48
+ const fs = __importStar(require("node:fs"));
49
+ const base_1 = require("../base");
50
+ const errors_1 = require("../errors");
51
+ const utils_1 = require("../../utils");
52
+ const adapter_resolver_1 = require("./adapter-resolver");
53
+ /** Base path for Next.js templates. */
54
+ const TEMPLATE_BASE = path.join(__dirname, 'templates');
55
+ class NextJsBuilder extends base_1.FrameworkBuilder {
56
+ static frameworkName = 'nextjs';
57
+ // ───────────────────────────────────────────────────────────────────────────
58
+ // FRAMEWORK INFO
59
+ // ───────────────────────────────────────────────────────────────────────────
60
+ get info() {
61
+ return {
62
+ name: 'nextjs',
63
+ version: '*',
64
+ displayName: 'Next.js',
65
+ packageName: 'next',
66
+ };
67
+ }
68
+ getFrameworkVersion() {
69
+ return this.resolveFrameworkVersion('next');
70
+ }
71
+ // ───────────────────────────────────────────────────────────────────────────
72
+ // DETECTION
73
+ // ───────────────────────────────────────────────────────────────────────────
74
+ /**
75
+ * Detect if this is a Next.js project.
76
+ */
77
+ static detect(packageJson, webflowJson) {
78
+ const specifiedFramework = webflowJson?.cloud?.framework;
79
+ if (specifiedFramework === 'nextjs') {
80
+ return { detected: true, reason: 'Specified as nextjs in webflow.json' };
81
+ }
82
+ // If webflow.json specifies a DIFFERENT framework, don't match.
83
+ if (specifiedFramework && specifiedFramework !== 'nextjs') {
84
+ return { detected: false };
85
+ }
86
+ const hasNext = packageJson.dependencies?.next !== undefined ||
87
+ packageJson.devDependencies?.next !== undefined;
88
+ if (hasNext) {
89
+ return { detected: true, reason: 'Found "next" in package.json' };
90
+ }
91
+ return { detected: false };
92
+ }
93
+ // ───────────────────────────────────────────────────────────────────────────
94
+ // VALIDATION
95
+ // ───────────────────────────────────────────────────────────────────────────
96
+ async validate() {
97
+ const { log, packageJson } = this.ctx;
98
+ const nextVersion = packageJson.dependencies?.next || packageJson.devDependencies?.next;
99
+ if (!nextVersion) {
100
+ throw new errors_1.FrameworkValidationError('Next.js is not installed in this project.', {
101
+ remediation: 'Install Next.js by running: npm install next',
102
+ documentationUrl: 'https://nextjs.org/docs/getting-started/installation',
103
+ });
104
+ }
105
+ log.info(`Validated Next.js project: next@${nextVersion}`);
106
+ }
107
+ // ───────────────────────────────────────────────────────────────────────────
108
+ // DEPENDENCIES
109
+ // ───────────────────────────────────────────────────────────────────────────
110
+ getCloudflareAdapter() {
111
+ return {
112
+ name: '@opennextjs/cloudflare',
113
+ // Fallback used only when a compatible version can't be resolved from the
114
+ // user's Next.js pin; installDependencies() normally pins an exact version.
115
+ version: '*',
116
+ };
117
+ }
118
+ getRequiredIntegrations() {
119
+ // No additional integrations required.
120
+ return [];
121
+ }
122
+ async installDependencies() {
123
+ const { log, cwd, runCommand } = this.ctx;
124
+ const adapter = this.getCloudflareAdapter();
125
+ // Respect an adapter version the user already pinned — don't second-guess it.
126
+ if (this.hasDependency(adapter.name)) {
127
+ return;
128
+ }
129
+ log.warn(`nextjs integration requires ${adapter.name} and this project doesn't have it. installing now...`);
130
+ // Pin the adapter to a release whose `next` peer range accepts the user's
131
+ // pinned Next.js, avoiding npm ERESOLVE peer-dependency dead zones. A null
132
+ // result means the Next.js version couldn't be determined — fall back to the
133
+ // latest adapter (prior behaviour); a genuinely incompatible Next.js throws.
134
+ const nextSpec = this.getDependencyVersion('next') ?? '';
135
+ const resolvedVersion = await (0, adapter_resolver_1.resolveCompatibleAdapterVersion)(log, adapter.name, nextSpec, cwd);
136
+ const args = resolvedVersion === null
137
+ ? ['install', '--save', adapter.name]
138
+ : ['install', '--save', '--save-exact', `${adapter.name}@${resolvedVersion}`];
139
+ await (0, utils_1.npm)({ log, runCommand, cwd, args });
140
+ }
141
+ // ───────────────────────────────────────────────────────────────────────────
142
+ // CONFIGURATION
143
+ // ───────────────────────────────────────────────────────────────────────────
144
+ getWebflowLoader() {
145
+ return {
146
+ templatePath: path.join(TEMPLATE_BASE, 'webflow-loader.ts'),
147
+ destinationName: 'webflow-loader.ts',
148
+ configPath: './webflow-loader.ts',
149
+ };
150
+ }
151
+ getUserConfigPatterns() {
152
+ return ['next.config.mjs', 'next.config.cjs', 'next.config.js', 'next.config.ts'];
153
+ }
154
+ getWranglerTemplatePath() {
155
+ return path.join(TEMPLATE_BASE, 'wrangler.json');
156
+ }
157
+ getAdditionalConfigFiles() {
158
+ const loader = this.getWebflowLoader();
159
+ return [loader.templatePath, path.join(TEMPLATE_BASE, 'open-next.config.ts')];
160
+ }
161
+ /** Checks if open-next.config.ts exists. */
162
+ findOpenNextConfig() {
163
+ const filename = 'open-next.config.ts';
164
+ if (fs.existsSync(path.join(this.cwd, filename))) {
165
+ return filename;
166
+ }
167
+ return undefined;
168
+ }
169
+ /**
170
+ * Ensures open-next.config.ts exists.
171
+ * - If it exists: leave it alone for opennextjs-cloudflare to validate.
172
+ * - If missing: create it from the template.
173
+ */
174
+ ensureOpenNextConfig(templatePath) {
175
+ const { log, cwd } = this.ctx;
176
+ const existingConfig = this.findOpenNextConfig();
177
+ if (existingConfig) {
178
+ log.info(`${existingConfig} found, skipping creation (opennextjs-cloudflare will validate)`);
179
+ return;
180
+ }
181
+ log.info('open-next.config not found, creating open-next.config.ts with default Webflow Cloud configuration...');
182
+ if (!fs.existsSync(templatePath)) {
183
+ throw new Error(`open-next.config.ts template not found at ${templatePath}. This is a Webflow Cloud build system error.`);
184
+ }
185
+ const configPath = path.join(cwd, 'open-next.config.ts');
186
+ fs.copyFileSync(templatePath, configPath);
187
+ log.info('open-next.config.ts created successfully');
188
+ }
189
+ async prepareConfig() {
190
+ const { log, cwd, userEnv } = this.ctx;
191
+ // Rename user's next.config.* to clouduser.next.config.*; if there is no
192
+ // user config, write an empty stub so the generated template's static
193
+ // import always resolves.
194
+ const renamedUserConfig = (0, utils_1.renameUserConfig)(log, cwd, 'next.config', ['mjs', 'cjs', 'js', 'ts']);
195
+ if (renamedUserConfig === null) {
196
+ log.info('no user next.config.{mjs,cjs,js,ts} found — writing empty clouduser.next.config.ts stub');
197
+ fs.writeFileSync(path.join(cwd, 'clouduser.next.config.ts'), 'export default {};\n');
198
+ }
199
+ else if (path.extname(renamedUserConfig) !== '.ts') {
200
+ // Next.js 16 type-checks next.config.ts with tsc, whose default module
201
+ // resolution can't find `.mjs`/`.cjs`/`.js` siblings of an extensionless
202
+ // import. Write a type-only shim so tsc resolves the import; runtime
203
+ // resolution is handled by Next.js's TS config loader and ignores .d.ts.
204
+ log.info(`writing clouduser.next.config.d.ts shim for ${path.basename(renamedUserConfig)}`);
205
+ fs.writeFileSync(path.join(cwd, 'clouduser.next.config.d.ts'), "import type { UserNextConfig } from './next.config.webflow';\ndeclare const config: UserNextConfig;\nexport default config;\n");
206
+ }
207
+ // Copy the merge-logic library (real source, not a template).
208
+ const webflowConfigSrc = path.join(TEMPLATE_BASE, 'next.config.webflow.ts');
209
+ if ((0, utils_1.fileExists)(webflowConfigSrc)) {
210
+ log.info('Copying next.config.webflow.ts...');
211
+ fs.copyFileSync(webflowConfigSrc, path.join(cwd, 'next.config.webflow.ts'));
212
+ }
213
+ // Render the single next.config.ts template.
214
+ const templatePath = path.join(TEMPLATE_BASE, 'next.config.ts.template');
215
+ const destPath = path.join(cwd, 'next.config.ts');
216
+ log.info('Generating next.config.ts from template...');
217
+ await (0, utils_1.envsubst)(log, templatePath, destPath, {
218
+ ...process.env,
219
+ ...userEnv,
220
+ });
221
+ // Copy webflow-loader.ts.
222
+ const loader = this.getWebflowLoader();
223
+ if ((0, utils_1.fileExists)(loader.templatePath)) {
224
+ log.info(`Copying ${loader.destinationName}...`);
225
+ fs.copyFileSync(loader.templatePath, path.join(cwd, loader.destinationName));
226
+ }
227
+ // Ensure open-next.config.ts exists.
228
+ this.ensureOpenNextConfig(path.join(TEMPLATE_BASE, 'open-next.config.ts'));
229
+ // wrangler.json is owned exclusively by `handleWranglerJson`, which runs
230
+ // before this hook and is the only function permitted to write
231
+ // /wrangler.json. Copying the framework template here would clobber its
232
+ // user-binding merge.
233
+ }
234
+ // ───────────────────────────────────────────────────────────────────────────
235
+ // BUILD
236
+ // ───────────────────────────────────────────────────────────────────────────
237
+ getBuildCommand() {
238
+ return 'opennextjs-cloudflare build';
239
+ }
240
+ getNodeVersionRequirement() {
241
+ return {
242
+ minimum: '18.0.0',
243
+ severity: 'error',
244
+ };
245
+ }
246
+ // ───────────────────────────────────────────────────────────────────────────
247
+ // OUTPUT
248
+ // ───────────────────────────────────────────────────────────────────────────
249
+ static getOutputDeployMetadata() {
250
+ return {
251
+ staticAssetsPath: '.open-next/assets',
252
+ workerEntryPath: '.open-next/worker.js',
253
+ deploymentType: 'ssr',
254
+ // After wrangler dry-run, the bundled output is ./worker.js
255
+ dryRunEntryPath: './worker.js',
256
+ };
257
+ }
258
+ /**
259
+ * Detect Next.js from built output: presence of `./worker.js` (the bundled
260
+ * entrypoint produced by `opennextjs-cloudflare build`). Mirrors the legacy
261
+ * fallback the deploy phase used to hardcode.
262
+ */
263
+ static detectFromBuiltOutput(cwd) {
264
+ return fs.statSync(path.join(cwd, './worker.js'), { throwIfNoEntry: false })?.isFile() ?? false;
265
+ }
266
+ }
267
+ exports.NextJsBuilder = NextJsBuilder;
268
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/frameworks/nextjs/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;GASG;AACH,gDAAkC;AAClC,4CAA8B;AAE9B,kCAA2C;AAY3C,sCAAqD;AACrD,uCAA0E;AAC1E,yDAAqE;AAErE,uCAAuC;AACvC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AAExD,MAAa,aAAc,SAAQ,uBAAgB;IACjD,MAAM,CAAU,aAAa,GAAG,QAAQ,CAAC;IAEzC,8EAA8E;IAC9E,iBAAiB;IACjB,8EAA8E;IAE9E,IAAI,IAAI;QACN,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,GAAG;YACZ,WAAW,EAAE,SAAS;YACtB,WAAW,EAAE,MAAM;SACpB,CAAC;IACJ,CAAC;IAEQ,mBAAmB;QAC1B,OAAO,IAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,8EAA8E;IAC9E,YAAY;IACZ,8EAA8E;IAE9E;;OAEG;IACH,MAAM,CAAU,MAAM,CAAC,WAAwB,EAAE,WAAyB;QACxE,MAAM,kBAAkB,GAAG,WAAW,EAAE,KAAK,EAAE,SAAS,CAAC;QAEzD,IAAI,kBAAkB,KAAK,QAAQ,EAAE,CAAC;YACpC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,qCAAqC,EAAE,CAAC;QAC3E,CAAC;QAED,gEAAgE;QAChE,IAAI,kBAAkB,IAAI,kBAAkB,KAAK,QAAQ,EAAE,CAAC;YAC1D,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC7B,CAAC;QAED,MAAM,OAAO,GACX,WAAW,CAAC,YAAY,EAAE,IAAI,KAAK,SAAS;YAC5C,WAAW,CAAC,eAAe,EAAE,IAAI,KAAK,SAAS,CAAC;QAElD,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC;QACpE,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,8EAA8E;IAC9E,aAAa;IACb,8EAA8E;IAE9E,KAAK,CAAC,QAAQ;QACZ,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC;QAEtC,MAAM,WAAW,GAAG,WAAW,CAAC,YAAY,EAAE,IAAI,IAAI,WAAW,CAAC,eAAe,EAAE,IAAI,CAAC;QAExF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,IAAI,iCAAwB,CAAC,2CAA2C,EAAE;gBAC9E,WAAW,EAAE,8CAA8C;gBAC3D,gBAAgB,EAAE,sDAAsD;aACzE,CAAC,CAAC;QACL,CAAC;QAED,GAAG,CAAC,IAAI,CAAC,mCAAmC,WAAW,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,8EAA8E;IAC9E,eAAe;IACf,8EAA8E;IAE9E,oBAAoB;QAClB,OAAO;YACL,IAAI,EAAE,wBAAwB;YAC9B,0EAA0E;YAC1E,4EAA4E;YAC5E,OAAO,EAAE,GAAG;SACb,CAAC;IACJ,CAAC;IAED,uBAAuB;QACrB,uCAAuC;QACvC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,KAAK,CAAC,mBAAmB;QACvB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC;QAE1C,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAE5C,8EAA8E;QAC9E,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,OAAO;QACT,CAAC;QAED,GAAG,CAAC,IAAI,CACN,+BAA+B,OAAO,CAAC,IAAI,sDAAsD,CAClG,CAAC;QAEF,0EAA0E;QAC1E,2EAA2E;QAC3E,6EAA6E;QAC7E,6EAA6E;QAC7E,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACzD,MAAM,eAAe,GAAG,MAAM,IAAA,kDAA+B,EAAC,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;QAEhG,MAAM,IAAI,GACR,eAAe,KAAK,IAAI;YACtB,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC;YACrC,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,eAAe,EAAE,CAAC,CAAC;QAElF,MAAM,IAAA,WAAG,EAAC,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,8EAA8E;IAC9E,gBAAgB;IAChB,8EAA8E;IAE9E,gBAAgB;QACd,OAAO;YACL,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,mBAAmB,CAAC;YAC3D,eAAe,EAAE,mBAAmB;YACpC,UAAU,EAAE,qBAAqB;SAClC,CAAC;IACJ,CAAC;IAED,qBAAqB;QACnB,OAAO,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IACpF,CAAC;IAED,uBAAuB;QACrB,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;IACnD,CAAC;IAED,wBAAwB;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACvC,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,4CAA4C;IACpC,kBAAkB;QACxB,MAAM,QAAQ,GAAG,qBAAqB,CAAC;QACvC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACK,oBAAoB,CAAC,YAAoB;QAC/C,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC;QAC9B,MAAM,cAAc,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAEjD,IAAI,cAAc,EAAE,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC,GAAG,cAAc,iEAAiE,CAAC,CAAC;YAC7F,OAAO;QACT,CAAC;QAED,GAAG,CAAC,IAAI,CACN,sGAAsG,CACvG,CAAC;QAEF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,6CAA6C,YAAY,+CAA+C,CACzG,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;QACzD,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAC1C,GAAG,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC;QAEvC,yEAAyE;QACzE,sEAAsE;QACtE,0BAA0B;QAC1B,MAAM,iBAAiB,GAAG,IAAA,wBAAgB,EAAC,GAAG,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QAChG,IAAI,iBAAiB,KAAK,IAAI,EAAE,CAAC;YAC/B,GAAG,CAAC,IAAI,CACN,yFAAyF,CAC1F,CAAC;YACF,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,0BAA0B,CAAC,EAAE,sBAAsB,CAAC,CAAC;QACvF,CAAC;aAAM,IAAI,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,KAAK,EAAE,CAAC;YACrD,uEAAuE;YACvE,yEAAyE;YACzE,qEAAqE;YACrE,yEAAyE;YACzE,GAAG,CAAC,IAAI,CAAC,+CAA+C,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;YAC5F,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,4BAA4B,CAAC,EAC5C,+HAA+H,CAChI,CAAC;QACJ,CAAC;QAED,8DAA8D;QAC9D,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,wBAAwB,CAAC,CAAC;QAC5E,IAAI,IAAA,kBAAU,EAAC,gBAAgB,CAAC,EAAE,CAAC;YACjC,GAAG,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;YAC9C,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAC9E,CAAC;QAED,6CAA6C;QAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,yBAAyB,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAElD,GAAG,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QACvD,MAAM,IAAA,gBAAQ,EAAC,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE;YAC1C,GAAG,OAAO,CAAC,GAAG;YACd,GAAG,OAAO;SACX,CAAC,CAAC;QAEH,0BAA0B;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACvC,IAAI,IAAA,kBAAU,EAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;YACpC,GAAG,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,eAAe,KAAK,CAAC,CAAC;YACjD,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;QAC/E,CAAC;QAED,qCAAqC;QACrC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC,CAAC;QAE3E,yEAAyE;QACzE,+DAA+D;QAC/D,wEAAwE;QACxE,sBAAsB;IACxB,CAAC;IAED,8EAA8E;IAC9E,QAAQ;IACR,8EAA8E;IAE9E,eAAe;QACb,OAAO,6BAA6B,CAAC;IACvC,CAAC;IAED,yBAAyB;QACvB,OAAO;YACL,OAAO,EAAE,QAAQ;YACjB,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC;IAED,8EAA8E;IAC9E,SAAS;IACT,8EAA8E;IAE9E,MAAM,CAAU,uBAAuB;QACrC,OAAO;YACL,gBAAgB,EAAE,mBAAmB;YACrC,eAAe,EAAE,sBAAsB;YACvC,cAAc,EAAE,KAAK;YACrB,4DAA4D;YAC5D,eAAe,EAAE,aAAa;SAC/B,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAU,qBAAqB,CAAC,GAAW;QAC/C,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,EAAE,EAAE,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,KAAK,CAAC;IAClG,CAAC;;AAhRH,sCAiRC"}
@@ -0,0 +1,13 @@
1
+ // Generated by the Webflow Cloud builder. Merge logic lives in ./next.config.webflow.ts.
2
+ import userConfig from './clouduser.next.config';
3
+ import { withWebflowOverrides } from './next.config.webflow';
4
+
5
+ // Next.js disallows '/' as basePath, so '/' maps to ''.
6
+ const mountPath: string = '${COSMIC_MOUNT_PATH}';
7
+ export const webflowBasePath = mountPath === '/' ? '' : mountPath;
8
+ export const webflowAssetPrefix = '${COSMIC_DEPLOY_URL}' + webflowBasePath;
9
+
10
+ export default withWebflowOverrides(userConfig, {
11
+ basePath: webflowBasePath,
12
+ assetPrefix: webflowAssetPrefix,
13
+ });
@@ -0,0 +1,46 @@
1
+ // Merge logic for the generated next.config.ts. Copied verbatim into the
2
+ // user's project; types are local to avoid Next.js cross-version drift.
3
+ import type { NextConfig } from 'next';
4
+
5
+ type NextConfigContext = { defaultConfig: NextConfig };
6
+ type UserNextConfigFn = (phase: string, ctx: NextConfigContext) => NextConfig | Promise<NextConfig>;
7
+
8
+ export type UserNextConfig = NextConfig | UserNextConfigFn;
9
+ export type WebflowOverridesOptions = { basePath: string; assetPrefix: string };
10
+
11
+ /**
12
+ * Wrap the user's Next.js config with Webflow Cloud's required overrides.
13
+ * `userExport` is always provided — `{}` when the user ships no next.config.
14
+ */
15
+ export function withWebflowOverrides(
16
+ userExport: UserNextConfig,
17
+ opts: WebflowOverridesOptions,
18
+ ): UserNextConfigFn {
19
+ return async function nextConfig(phase: string, ctx: NextConfigContext): Promise<NextConfig> {
20
+ const resolved = await resolveUserConfig(userExport, phase, ctx);
21
+ return {
22
+ ...resolved,
23
+ basePath: opts.basePath,
24
+ assetPrefix: opts.assetPrefix,
25
+ images: {
26
+ ...resolved.images,
27
+ // TODO: support non-custom loaders (imgix, cloudinary, akamai) if they work
28
+ loader: 'custom',
29
+ loaderFile: resolved.images?.loaderFile || './webflow-loader.ts',
30
+ },
31
+ };
32
+ };
33
+ }
34
+
35
+ async function resolveUserConfig(
36
+ userExport: UserNextConfig,
37
+ phase: string,
38
+ ctx: NextConfigContext,
39
+ ): Promise<NextConfig> {
40
+ if (typeof userExport === 'function') {
41
+ return (await userExport(phase, ctx)) ?? {};
42
+ }
43
+ // `export default null` is rare but not impossible; guard so the spread in
44
+ // withWebflowOverrides can't NPE.
45
+ return userExport ?? {};
46
+ }
@@ -0,0 +1,3 @@
1
+ import { defineCloudflareConfig } from '@opennextjs/cloudflare';
2
+
3
+ export default defineCloudflareConfig();
@@ -0,0 +1,44 @@
1
+ import { webflowAssetPrefix, webflowBasePath } from './next.config';
2
+
3
+ const basePath = webflowBasePath;
4
+ const assetPrefix = webflowAssetPrefix || basePath;
5
+
6
+ function normalizeSrc(src: string) {
7
+ // For local assets, include the base path but not the asset prefix
8
+ if (assetPrefix && src.startsWith(assetPrefix)) {
9
+ return `${basePath}${src.slice(assetPrefix.length)}`;
10
+ } else if (basePath && src.startsWith(basePath)) {
11
+ return src;
12
+ } else if (src.startsWith('/')) {
13
+ return basePath + src;
14
+ }
15
+ return src;
16
+ }
17
+
18
+ export default function cloudflareLoader({
19
+ src,
20
+ width,
21
+ quality,
22
+ }: {
23
+ src: string;
24
+ width: number;
25
+ quality?: number;
26
+ }) {
27
+ const normalizedSrc = normalizeSrc(src);
28
+
29
+ // Our cloudflare zone doesn't allow optimizing external images for security reasons, so just load the original image
30
+ // For now, also skip optimization for images hosted on regular webflow sites (cdn.website-files.com)
31
+ // because optimizing them would result in two bandwidth charges: one from the website-files zone (for the full image)
32
+ // and one from the cosmic.webflow.services zone (for the resized image)
33
+ if (normalizedSrc.startsWith('http://') || normalizedSrc.startsWith('https://')) {
34
+ return normalizedSrc;
35
+ }
36
+
37
+ const params = [`width=${width}`];
38
+ if (quality) {
39
+ params.push(`quality=${quality}`);
40
+ }
41
+ const paramsString = params.join(',');
42
+ const workerUrl = basePath ? assetPrefix.slice(0, -basePath.length) : assetPrefix;
43
+ return `${workerUrl}/cdn-cgi/image/${paramsString}${normalizedSrc}`;
44
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "cosmic-builder-dry-run",
3
+ "main": ".open-next/worker.js",
4
+ "compatibility_date": "2025-03-03",
5
+ "compatibility_flags": ["nodejs_compat"]
6
+ }
@@ -0,0 +1,127 @@
1
+ import type { BuildContext, BuildOutput, PackageJson, WebflowJson, DetectionResult } from './types';
2
+ import { FrameworkBuilder } from './base';
3
+ /** Type for a builder class with static detect method. */
4
+ export interface BuilderClass {
5
+ /** Canonical framework name (e.g. 'nextjs', 'astro', 'vite'). */
6
+ frameworkName: string;
7
+ detect(packageJson: PackageJson, webflowJson?: WebflowJson): DetectionResult;
8
+ detectFromBuiltOutput(cwd: string): boolean;
9
+ getOutputDeployMetadata(): BuildOutput;
10
+ new (ctx: BuildContext): FrameworkBuilder;
11
+ }
12
+ /** Detection result with the matched builder. */
13
+ export interface DetectionMatch {
14
+ Builder: BuilderClass;
15
+ result: DetectionResult;
16
+ }
17
+ /**
18
+ * All registered framework builders, in detection order.
19
+ *
20
+ * IMPORTANT: Order matters — first match wins. More specific frameworks must
21
+ * come before generic ones.
22
+ *
23
+ * - Astro 7 before Astro 6 before Astro 5 (version-specific, newest first)
24
+ * - Next.js before Vite (uses Vite internally)
25
+ * - Vite before Static (Vite catches generic Vite SPAs)
26
+ * - Static last: matches only an explicit `framework: "static"` here; implicit
27
+ * no-framework detection is a filesystem fallback the host resolves via
28
+ * `resolveIsStaticApp` before calling into detection.
29
+ */
30
+ export declare const FRAMEWORK_BUILDERS: BuilderClass[];
31
+ /**
32
+ * Allowed framework names for webflow.json. Single source of truth is the
33
+ * deploy contract's `Framework` enum — what's deployable is what's allowed.
34
+ *
35
+ * Note: Astro version (5 vs 6) is detected automatically from package.json.
36
+ * Users should always specify 'astro', not 'astro5' or 'astro6'.
37
+ */
38
+ export declare const ALLOWED_FRAMEWORKS: ["astro", "nextjs", "vite", "static"];
39
+ export type AllowedFramework = (typeof ALLOWED_FRAMEWORKS)[number];
40
+ /**
41
+ * Detect which framework builder should handle this project. First-match-wins;
42
+ * order in FRAMEWORK_BUILDERS determines precedence.
43
+ *
44
+ * @returns The first matching builder class, or null if no match.
45
+ */
46
+ export declare function detectFrameworkBuilder(packageJson: PackageJson, webflowJson?: WebflowJson): DetectionMatch | null;
47
+ /**
48
+ * Detect which framework produced the build artifacts in `cwd`.
49
+ *
50
+ * Used at deploy time when webflow.json may not have been written by the
51
+ * producer. Iterates registered builders and returns the first one whose
52
+ * `detectFromBuiltOutput` recognizes the output. Returns null if none match.
53
+ */
54
+ export declare function detectFrameworkFromBuiltOutput(cwd: string): BuilderClass | null;
55
+ /**
56
+ * Detect and create the appropriate framework builder.
57
+ *
58
+ * @throws FrameworkDetectionError if no framework can be detected
59
+ */
60
+ export declare function detectAndCreateBuilder(ctx: BuildContext, webflowJson?: WebflowJson): FrameworkBuilder;
61
+ /**
62
+ * Decide whether a project is a no-framework static app.
63
+ *
64
+ * Two ways in:
65
+ * - **explicit**: webflow.json declares `framework: "static"`. This wins
66
+ * unconditionally — even with a package.json present — so the explicit
67
+ * opt-in is honored ahead of the package/index guard in the build flow.
68
+ * - **inferred (zero-config)**: no package.json, a real `index.html` file at
69
+ * the root, no *other* framework explicitly declared, and **no runtime/build
70
+ * indicators** (`hasRuntimeIndicators`). `index.html` + no package.json is
71
+ * only a preflight signal; a repo that also ships a build/server manifest
72
+ * (requirements.txt, composer.json, Gemfile, Dockerfile, …) is a mixed
73
+ * static+runtime repo and must NOT be silently published — the caller
74
+ * rejects that case. The caller resolves `hasRootIndexHtmlFile` with a
75
+ * regular-file check (not `existsSync`), so a directory or symlink named
76
+ * `index.html` does not trigger inference.
77
+ */
78
+ export declare function resolveIsStaticApp(params: {
79
+ hasPackageJson: boolean;
80
+ specifiedFramework?: string;
81
+ hasRootIndexHtmlFile: boolean;
82
+ hasRuntimeIndicators: boolean;
83
+ }): boolean;
84
+ /**
85
+ * Resolve whether `cwd` is a no-framework static app, doing the filesystem
86
+ * checks that `resolveIsStaticApp` needs: a regular-file root index.html and a
87
+ * recursive scan for runtime indicators. This is the single implementation both
88
+ * producers (cosmic-builder, webflow-cli) call, so static detection is
89
+ * identical everywhere.
90
+ *
91
+ * `index.html` + no package.json is only a preflight signal: a repo that also
92
+ * ships a build/server manifest is a mixed static+runtime repo whose source
93
+ * must not be silently published as assets. On the inference path (no explicit
94
+ * framework) such a repo is rejected loudly, naming the offending files. An
95
+ * explicit `framework: "static"` is honored even when those files are present.
96
+ *
97
+ * Requires a regular file for the inferred index.html (lstat, not existsSync)
98
+ * so a directory or symlink named index.html can't trigger inference.
99
+ *
100
+ * @throws FrameworkDetectionError for a mixed static+runtime repo on inference.
101
+ */
102
+ export declare function detectStaticApp(cwd: string, packageJson: PackageJson | undefined, webflowJson?: WebflowJson): {
103
+ isStatic: boolean;
104
+ };
105
+ /**
106
+ * Read the customer's installed major version of a framework's primary npm
107
+ * package. Used only for metric tagging.
108
+ *
109
+ * `getMajorVersion` is defensive on empty/non-semver input (dist-tags, git
110
+ * URLs, 'workspace:*', etc.), so the 'unknown' fallback is unreachable in the
111
+ * normal path — kept for resilience to silent dep-tree changes.
112
+ */
113
+ export declare function getCustomerMajorVersion(packageName: string, packageJson: PackageJson): string;
114
+ /**
115
+ * Validate that a framework name from webflow.json is supported.
116
+ *
117
+ * @throws FrameworkDetectionError if framework is not supported
118
+ */
119
+ export declare function validateFrameworkName(frameworkName: string): asserts frameworkName is AllowedFramework;
120
+ export { Astro5Builder, Astro6Builder, Astro7Builder } from './astro';
121
+ export { NextJsBuilder } from './nextjs';
122
+ export { ViteBuilder } from './vite';
123
+ export { StaticBuilder } from './static';
124
+ export { FrameworkBuilder } from './base';
125
+ export * from './types';
126
+ export * from './errors';
127
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/frameworks/registry.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAa1C,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,eAAe,CAAC;IAC7E,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5C,uBAAuB,IAAI,WAAW,CAAC;IACvC,KAAK,GAAG,EAAE,YAAY,GAAG,gBAAgB,CAAC;CAC3C;AAED,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;CACzB;AAMD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,EAAE,YAAY,EAO5C,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,uCAAoB,CAAC;AAEpD,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAMnE;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,WAAW,EACxB,WAAW,CAAC,EAAE,WAAW,GACxB,cAAc,GAAG,IAAI,CAQvB;AAED;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAO/E;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,YAAY,EACjB,WAAW,CAAC,EAAE,WAAW,GACxB,gBAAgB,CAiBlB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,oBAAoB,EAAE,OAAO,CAAC;CAC/B,GAAG,OAAO,CASV;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,WAAW,GAAG,SAAS,EACpC,WAAW,CAAC,EAAE,WAAW,GACxB;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,CAkCvB;AAMD;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,GAAG,MAAM,CAK7F;AAMD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,aAAa,IAAI,gBAAgB,CAM3C;AAMD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAC1C,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC"}