@fjall/generator 22.0.0 → 23.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.
- package/dist/.build-source-hash +8 -8
- package/dist/.minified +1 -1
- package/dist/src/ast/astTestHelpers.d.ts +1 -1
- package/dist/src/detection/index.d.ts +123 -5
- package/dist/src/detection/index.js +1 -1
- package/dist/src/planning/staticSitePlanning.d.ts +2 -1
- package/dist/src/schemas/applicationSchemas.d.ts +2 -0
- package/dist/src/schemas/patternSchemas.d.ts +8 -4
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +2 -2
package/dist/.build-source-hash
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"package.json",
|
|
10
10
|
"tsconfig.json"
|
|
11
11
|
],
|
|
12
|
-
"hash": "
|
|
12
|
+
"hash": "19b345119eb917e0377fe84ebb7731c95085d6cfaa991d807331c079fc33835a",
|
|
13
13
|
"files": {
|
|
14
14
|
"src/ast/astTestHelpers.ts": "026cac849eb88bdb",
|
|
15
15
|
"src/ast/domain/astDomainParser.ts": "a88b990396db0a46",
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
"src/codemod/validationGate/gates/schema.ts": "7ed5acaec0620a46",
|
|
112
112
|
"src/codemod/validationGate/index.ts": "bbe1f460330a11cf",
|
|
113
113
|
"src/codemod/validationGate/types.ts": "4a1cfa054e3383d5",
|
|
114
|
-
"src/detection/index.ts": "
|
|
114
|
+
"src/detection/index.ts": "cd321fd291b7388b",
|
|
115
115
|
"src/dns/bindParser.ts": "2b463c4dd1395ae5",
|
|
116
116
|
"src/dns/bindWriter.ts": "c296911ce5aef77c",
|
|
117
117
|
"src/dns/domainFileGenerator.ts": "f2d0ba8cca5ab1c9",
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
"src/planning/resourceAddition.ts": "7d0320620a74fdcd",
|
|
144
144
|
"src/planning/resourceConnections.ts": "a6b7db8f733e560f",
|
|
145
145
|
"src/planning/resourcePlanning.ts": "d6bb9fa8e1419908",
|
|
146
|
-
"src/planning/staticSitePlanning.ts": "
|
|
146
|
+
"src/planning/staticSitePlanning.ts": "ee0b100e081061be",
|
|
147
147
|
"src/presets/clickhouseTierPreset.ts": "1758d991c81d769a",
|
|
148
148
|
"src/presets/index.ts": "8332c0198b2a6fe9",
|
|
149
149
|
"src/presets/patternTierPresets.ts": "f4fc368fc623aae4",
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
"src/projection/types.ts": "68045bc02a36cee9",
|
|
159
159
|
"src/projection/unresolved.ts": "885c8d3c1624b328",
|
|
160
160
|
"src/schemas/alarmSchemas.ts": "beb19255d37ed43d",
|
|
161
|
-
"src/schemas/applicationSchemas.ts": "
|
|
161
|
+
"src/schemas/applicationSchemas.ts": "12ee3bc2654717f0",
|
|
162
162
|
"src/schemas/baseSchemas.ts": "93d9bd1c0adfcaa0",
|
|
163
163
|
"src/schemas/buildkiteSchemas.ts": "a28ec3b40f7851ec",
|
|
164
164
|
"src/schemas/cdnSchemas.ts": "16784f15894c62ba",
|
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
"src/schemas/messagingSchemas.ts": "2c1975fac903fd1b",
|
|
172
172
|
"src/schemas/networkSchemas.ts": "c3a5f30e440dd2f8",
|
|
173
173
|
"src/schemas/organisationSchemas.ts": "50d793aa7ff7f749",
|
|
174
|
-
"src/schemas/patternSchemas.ts": "
|
|
174
|
+
"src/schemas/patternSchemas.ts": "8b48dfb02852a7ba",
|
|
175
175
|
"src/schemas/resourceSchemas.ts": "cd050813242ea213",
|
|
176
176
|
"src/schemas/securityBoundary.ts": "54d216807103bab8",
|
|
177
177
|
"src/schemas/sharedTypes.ts": "45210e600bea393e",
|
|
@@ -181,11 +181,11 @@
|
|
|
181
181
|
"src/validation/patterns.ts": "f9629eafdad7ac3e",
|
|
182
182
|
"src/validation/validationMessages.ts": "b03413b3953c3e79",
|
|
183
183
|
"src/validation/validationPatterns.ts": "865f3d688975b7c8",
|
|
184
|
-
"src/version.ts": "
|
|
184
|
+
"src/version.ts": "015088b6ef4cbedd",
|
|
185
185
|
"../scripts/minify-dist.mjs": "6b2e4b0df8aec601",
|
|
186
|
-
"package.json": "
|
|
186
|
+
"package.json": "3de28ee21a5c3ad7",
|
|
187
187
|
"tsconfig.json": "1929cf3f99fe9b1e"
|
|
188
188
|
},
|
|
189
|
-
"outputHash": "
|
|
189
|
+
"outputHash": "208627559db4c045bfda8ce4fac13eedddbfc17b43bbefcf5d092a98ba22a944",
|
|
190
190
|
"outputFileCount": 343
|
|
191
191
|
}
|
package/dist/.minified
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
171 files minified at 2026-08-
|
|
1
|
+
171 files minified at 2026-08-30T05:34:06.382Z
|
|
@@ -342,7 +342,7 @@ export declare function parseAndConvert(code: string): {
|
|
|
342
342
|
command: string;
|
|
343
343
|
outputDir: string;
|
|
344
344
|
};
|
|
345
|
-
routing?: "multipage" | "spa" | undefined;
|
|
345
|
+
routing?: "multipage" | "directory" | "spa" | undefined;
|
|
346
346
|
security?: {
|
|
347
347
|
headers?: boolean | undefined;
|
|
348
348
|
contentSecurityPolicy?: string | undefined;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* `apps detect --output json` frame and the MCP `detect_app_framework`
|
|
11
11
|
* tool's `outputSchema`.
|
|
12
12
|
*/
|
|
13
|
-
import { type Framework } from "@fjall/util";
|
|
13
|
+
import { type Framework, type StaticSiteRouting } from "@fjall/util";
|
|
14
14
|
import { z } from "zod";
|
|
15
15
|
/**
|
|
16
16
|
* The framework vocabulary now lives in `@fjall/util/patterns`, beside the
|
|
@@ -104,24 +104,132 @@ export declare const CreatePrefillSchema: z.ZodObject<{
|
|
|
104
104
|
outputDir: z.ZodNullable<z.ZodString>;
|
|
105
105
|
routing: z.ZodNullable<z.ZodEnum<{
|
|
106
106
|
multipage: "multipage";
|
|
107
|
+
directory: "directory";
|
|
107
108
|
spa: "spa";
|
|
108
109
|
}>>;
|
|
109
110
|
}, z.core.$strict>;
|
|
110
111
|
export type CreatePrefill = z.infer<typeof CreatePrefillSchema>;
|
|
112
|
+
export declare const PACKAGE_MANAGER_VALUES: readonly ["npm", "pnpm", "yarn", "bun"];
|
|
113
|
+
export type PackageManager = (typeof PACKAGE_MANAGER_VALUES)[number];
|
|
114
|
+
/**
|
|
115
|
+
* The lockfile that proves each manager.
|
|
116
|
+
*
|
|
117
|
+
* Keyed on the MANAGER, not on the file, so the vocabulary cannot grow a member
|
|
118
|
+
* that no evidence can ever reach — a manager without a lockfile here fails to
|
|
119
|
+
* compile rather than becoming silently undetectable. That is the shape of the
|
|
120
|
+
* bug this table exists to close: the manager vocabulary and the set of files
|
|
121
|
+
* actually probed drifted apart, so pnpm was only recognised through
|
|
122
|
+
* `pnpm-workspace.yaml` and never through its lockfile.
|
|
123
|
+
*
|
|
124
|
+
* The value is a NON-EMPTY tuple. A manager whose evidence list is empty would
|
|
125
|
+
* satisfy a plain `string[]` while being exactly as undetectable as one that is
|
|
126
|
+
* missing, so the type refuses to let detectability be claimed without naming a
|
|
127
|
+
* file that proves it.
|
|
128
|
+
*/
|
|
129
|
+
export declare const PACKAGE_MANAGER_LOCKFILES: {
|
|
130
|
+
readonly npm: readonly ["package-lock.json"];
|
|
131
|
+
readonly pnpm: readonly ["pnpm-lock.yaml"];
|
|
132
|
+
readonly yarn: readonly ["yarn.lock"];
|
|
133
|
+
readonly bun: readonly ["bun.lock", "bun.lockb"];
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* Which package manager runs this repo's scripts.
|
|
137
|
+
*
|
|
138
|
+
* Deliberately orthogonal to `MonorepoTool`. The two were conflated — the build
|
|
139
|
+
* command was chosen by asking `inferMonorepoTool`, whose ladder returns the
|
|
140
|
+
* ORCHESTRATOR in preference to the manager — so turbo-on-pnpm (a common pair,
|
|
141
|
+
* not an exotic one) reported `npm run build`, and so did every yarn repo, every
|
|
142
|
+
* bun repo, and every flat pnpm repo that has a lockfile but no
|
|
143
|
+
* `pnpm-workspace.yaml`. A repo has both a manager and, sometimes, an
|
|
144
|
+
* orchestrator; asking one question cannot answer the other.
|
|
145
|
+
*
|
|
146
|
+
* Absent evidence resolves to npm: it ships with Node, so a repo with no
|
|
147
|
+
* lockfile and no declared manager is npm's by default rather than by guess.
|
|
148
|
+
* Contradictory evidence (two lockfiles committed) is not a tie to break — the
|
|
149
|
+
* declared field decides, and npm is the fallback.
|
|
150
|
+
*/
|
|
151
|
+
export declare function inferPackageManager(rootPackageJson: ParsedPackageJson | null, markers: MarkerFiles): PackageManager;
|
|
152
|
+
/**
|
|
153
|
+
* Astro's `build.format` vocabulary — the setting that decides which object
|
|
154
|
+
* each page becomes, and therefore which routing mode serves the site.
|
|
155
|
+
*/
|
|
156
|
+
export declare const ASTRO_BUILD_FORMAT_VALUES: readonly ["file", "directory", "preserve"];
|
|
157
|
+
export type AstroBuildFormat = (typeof ASTRO_BUILD_FORMAT_VALUES)[number];
|
|
158
|
+
/**
|
|
159
|
+
* Config filenames Astro will load, in the order the CLI probes them. Owned
|
|
160
|
+
* here beside the parser so the I/O wrapper cannot probe a spelling the
|
|
161
|
+
* parser was never taught about.
|
|
162
|
+
*/
|
|
163
|
+
export declare const ASTRO_CONFIG_FILENAMES: readonly ["astro.config.mjs", "astro.config.js", "astro.config.ts", "astro.config.cjs", "astro.config.mts", "astro.config.cts"];
|
|
164
|
+
/**
|
|
165
|
+
* Read `build.format` out of an Astro config's text.
|
|
166
|
+
*
|
|
167
|
+
* A bounded regex over comment-stripped text, not an AST: this runs on the
|
|
168
|
+
* CLI and MCP detect paths, and pulling a TypeScript parser into those
|
|
169
|
+
* bundles for one key is weight no other detection signal pays. The match is
|
|
170
|
+
* bounded on both sides — the key must be `format` and the value must be one
|
|
171
|
+
* of Astro's three format literals — so `format:` keys with other values (an
|
|
172
|
+
* image config, a date format) cannot match. Returns null when the text
|
|
173
|
+
* states no format; callers resolve that to Astro's default ("directory").
|
|
174
|
+
*/
|
|
175
|
+
export declare function parseAstroBuildFormat(configText: string): AstroBuildFormat | null;
|
|
176
|
+
/**
|
|
177
|
+
* The routing mode that serves each Astro build format, total over the format
|
|
178
|
+
* vocabulary so a format Astro adds cannot silently fall through to a wrong
|
|
179
|
+
* default.
|
|
180
|
+
*
|
|
181
|
+
* `preserve` maps to null deliberately: it keeps whichever shape each source
|
|
182
|
+
* file already had, so no single rewrite serves the whole site — the gap is
|
|
183
|
+
* left marked for the user rather than filled with a plausible mode.
|
|
184
|
+
*/
|
|
185
|
+
export declare const ASTRO_FORMAT_TO_ROUTING: {
|
|
186
|
+
readonly file: "multipage";
|
|
187
|
+
readonly directory: "directory";
|
|
188
|
+
readonly preserve: null;
|
|
189
|
+
};
|
|
190
|
+
/**
|
|
191
|
+
* Routing for an Astro workspace, from its config text (null when no config
|
|
192
|
+
* file exists). Absence of the file, and absence of `build.format` inside
|
|
193
|
+
* it, both mean Astro's default: "directory".
|
|
194
|
+
*/
|
|
195
|
+
export declare function inferAstroRouting(configText: string | null): StaticSiteRouting | null;
|
|
196
|
+
/**
|
|
197
|
+
* Re-frame a repo-root-relative workspace path as the `source` value the
|
|
198
|
+
* static-site pattern is actually read in.
|
|
199
|
+
*
|
|
200
|
+
* `source` is not repo-root-relative, though it long claimed to be. deploy-core
|
|
201
|
+
* runs the build in `resolve(appPath, buildCommand.cwd)` and the CDK construct
|
|
202
|
+
* uploads `resolve(this.props.source, build.outputDir)` from a child process
|
|
203
|
+
* whose cwd is that same `appPath` — the app's config directory. Emitting the
|
|
204
|
+
* repo-root path put both one boundary too deep, and neither consumer errors:
|
|
205
|
+
* the value simply resolves somewhere else, which is why this shipped. Every
|
|
206
|
+
* hand-written example in `components/infrastructure` carries the climb
|
|
207
|
+
* (`source: "../.."`), and this makes the generated value agree with them.
|
|
208
|
+
*
|
|
209
|
+
* An absolute path is returned untouched. `relativise` yields one for a
|
|
210
|
+
* workspace that resolves outside the scanned root (a `workspaces` glob may
|
|
211
|
+
* escape it), and an absolute source already resolves correctly from any cwd —
|
|
212
|
+
* prefixing a climb would corrupt a value that was right.
|
|
213
|
+
*/
|
|
214
|
+
export declare function toConfigDirRelativeSource(relativePath: string): string;
|
|
111
215
|
/**
|
|
112
216
|
* Assemble the create prefill for one detected workspace. Pure: the caller
|
|
113
|
-
* supplies the parsed `package.json
|
|
217
|
+
* supplies the parsed `package.json`, the repo's package manager, and the
|
|
218
|
+
* framework's own routing verdict (`inferAstroRouting` for Astro; null when
|
|
219
|
+
* the framework states none — the gap rides through rather than being
|
|
220
|
+
* defaulted here).
|
|
114
221
|
*/
|
|
115
222
|
export declare function inferCreatePrefill(input: {
|
|
116
223
|
framework: Framework;
|
|
117
224
|
relativePath: string;
|
|
118
225
|
pkg: ParsedPackageJson | null;
|
|
119
|
-
|
|
226
|
+
packageManager: PackageManager;
|
|
227
|
+
routing: StaticSiteRouting | null;
|
|
120
228
|
}): CreatePrefill | null;
|
|
121
229
|
export declare const MONOREPO_TOOL_VALUES: readonly ["npm-workspaces", "pnpm", "lerna", "turbo", "nx"];
|
|
122
230
|
export declare const MonorepoToolSchema: z.ZodEnum<{
|
|
123
|
-
"npm-workspaces": "npm-workspaces";
|
|
124
231
|
pnpm: "pnpm";
|
|
232
|
+
"npm-workspaces": "npm-workspaces";
|
|
125
233
|
lerna: "lerna";
|
|
126
234
|
turbo: "turbo";
|
|
127
235
|
nx: "nx";
|
|
@@ -181,6 +289,7 @@ export declare const AppDetectionSchema: z.ZodObject<{
|
|
|
181
289
|
outputDir: z.ZodNullable<z.ZodString>;
|
|
182
290
|
routing: z.ZodNullable<z.ZodEnum<{
|
|
183
291
|
multipage: "multipage";
|
|
292
|
+
directory: "directory";
|
|
184
293
|
spa: "spa";
|
|
185
294
|
}>>;
|
|
186
295
|
}, z.core.$strict>>;
|
|
@@ -189,8 +298,8 @@ export type AppDetection = z.infer<typeof AppDetectionSchema>;
|
|
|
189
298
|
export declare const RepositoryDetectionSchema: z.ZodObject<{
|
|
190
299
|
isMonorepo: z.ZodBoolean;
|
|
191
300
|
monorepoTool: z.ZodNullable<z.ZodEnum<{
|
|
192
|
-
"npm-workspaces": "npm-workspaces";
|
|
193
301
|
pnpm: "pnpm";
|
|
302
|
+
"npm-workspaces": "npm-workspaces";
|
|
194
303
|
lerna: "lerna";
|
|
195
304
|
turbo: "turbo";
|
|
196
305
|
nx: "nx";
|
|
@@ -250,6 +359,7 @@ export declare const RepositoryDetectionSchema: z.ZodObject<{
|
|
|
250
359
|
outputDir: z.ZodNullable<z.ZodString>;
|
|
251
360
|
routing: z.ZodNullable<z.ZodEnum<{
|
|
252
361
|
multipage: "multipage";
|
|
362
|
+
directory: "directory";
|
|
253
363
|
spa: "spa";
|
|
254
364
|
}>>;
|
|
255
365
|
}, z.core.$strict>>;
|
|
@@ -265,12 +375,20 @@ export interface ParsedPackageJson {
|
|
|
265
375
|
dependencies?: Record<string, string>;
|
|
266
376
|
devDependencies?: Record<string, string>;
|
|
267
377
|
scripts?: Record<string, string>;
|
|
378
|
+
/** Corepack's declared manager, e.g. `"pnpm@9.1.0"`. */
|
|
379
|
+
packageManager?: string;
|
|
268
380
|
}
|
|
269
381
|
export interface MarkerFiles {
|
|
270
382
|
pnpmWorkspaceYaml: boolean;
|
|
271
383
|
lernaJson: boolean;
|
|
272
384
|
turboJson: boolean;
|
|
273
385
|
nxJson: boolean;
|
|
386
|
+
/**
|
|
387
|
+
* Which manager's lockfile is present. Total over `PackageManager` so the
|
|
388
|
+
* probe cannot fall behind the vocabulary: adding a manager fails to compile
|
|
389
|
+
* here and at every collection site until its lockfile is actually stat'd.
|
|
390
|
+
*/
|
|
391
|
+
lockfiles: Record<PackageManager, boolean>;
|
|
274
392
|
}
|
|
275
393
|
/**
|
|
276
394
|
* Determine the monorepo tool from root package.json + marker files.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var d=Object.defineProperty;var o=(e,r)=>d(e,"name",{value:r,configurable:!0});import{buildAppConfigPath as l,FRAMEWORK_VALUES as b,PATTERN_TYPE_VALUES as p,STATIC_SITE_ROUTING_VALUES as g,recommendPatternForFramework as A}from"@fjall/util";import{z as t}from"zod";import{FRAMEWORK_VALUES as re,FRAMEWORKS as te,isFramework as ne,FRAMEWORK_PATTERN_RECOMMENDATIONS as oe,recommendPatternForFramework as ae,CREATABLE_FRAMEWORKS as se}from"@fjall/util";const k=t.enum(b),x=["application","library"],h=t.enum(x);function K(e,r){return e!=="unknown"||r?"application":"library"}o(K,"inferAppRole");const R=t.discriminatedUnion("kind",[t.object({kind:t.literal("recommended"),pattern:t.enum(p),rationale:t.string()}).strict(),t.object({kind:t.literal("blocked"),pattern:t.enum(p),reason:t.string()}).strict(),t.object({kind:t.literal("unsupported"),reason:t.string()}).strict()]),w={astro:"dist",nextjs:"out","nextjs+payload":null,payload:null,remix:null,express:null,unknown:null},y=t.object({pattern:t.enum(p),source:t.string().describe("Pass verbatim to `--source`. Relative to the app's `fjall/<name>` config directory, NOT the repo root \u2014 that is the frame every consumer resolves it in, so the leading `../..` is part of the value rather than a mistake. Assumes the app is scaffolded at `<repo root>/fjall/<name>`, which is where `apps create` puts it."),buildCommand:t.string().nullable().describe("Build command, from the workspace's own build script. Null when it declares none."),outputDir:t.string().nullable().describe("Build output directory relative to `source`, by framework convention \u2014 NOT verified against disk. Confirm it exists after building before deploying."),routing:t.enum(g).nullable().describe("Pass to `--routing`. Read from the framework's own build configuration (for Astro, `build.format`): 'multipage' when the build emits `about.html`, 'directory' when it emits `about/index.html`. Null when no single mode serves the layout (e.g. Astro's 'preserve') \u2014 ask rather than guess.")}).strict(),c=["npm","pnpm","yarn","bun"],E={npm:"npm run build",pnpm:"pnpm run build",yarn:"yarn run build",bun:"bun run build"},W={npm:["package-lock.json"],pnpm:["pnpm-lock.yaml"],yarn:["yarn.lock"],bun:["bun.lock","bun.lockb"]};function _(e){if(typeof e!="string")return null;const r=e.trim().split("@")[0];return c.find(n=>n===r)??null}o(_,"packageManagerFromField");function I(e,r){const n=_(e?.packageManager);if(n!==null)return n;const a=c.filter(i=>r.lockfiles[i]);return a.length===1?a[0]:"npm"}o(I,"inferPackageManager");function O(e){return E[e]}o(O,"buildCommandFor");const S=["file","directory","preserve"],G=["astro.config.mjs","astro.config.js","astro.config.ts","astro.config.cjs","astro.config.mts","astro.config.cts"];function D(e){const r=e.replace(/\/\*[\s\S]*?\*\//g,"").replace(/\/\/[^\n]*/g,""),n=new RegExp(`format\\s*:\\s*["'](${S.join("|")})["']`).exec(r);return n===null?null:n[1]}o(D,"parseAstroBuildFormat");const F={file:"multipage",directory:"directory",preserve:null};function V(e){const r=e===null?"directory":D(e)??"directory";return F[r]}o(V,"inferAstroRouting");const u=l("probe").split("/").map(()=>"..").join("/");function T(e){const r=e.trim().replace(/^\.\/+/,"").replace(/\/+$/,"");return r.startsWith("/")?r:r===""||r==="."?u:`${u}/${r}`}o(T,"toConfigDirRelativeSource");function B(e){const r=A(e.framework);if(r.kind!=="recommended")return null;const n=typeof e.pkg?.scripts?.build=="string"&&e.pkg.scripts.build.trim().length>0;return{pattern:r.pattern,source:T(e.relativePath),buildCommand:n?O(e.packageManager):null,outputDir:w[e.framework],routing:r.pattern==="staticsite"?e.routing:null}}o(B,"inferCreatePrefill");const j=["npm-workspaces","pnpm","lerna","turbo","nx"],v=t.enum(j),M=t.object({relativePath:t.string().describe("Path relative to repo root. '.' for flat repo, e.g. 'apps/website' for monorepo workspace."),framework:k,packageName:t.string().nullable(),hasDockerfile:t.boolean(),docker:t.object({path:t.string().describe("Path to chosen Dockerfile, relative to relativePath.")}).strict().nullable().describe("Docker build descriptor. Null if no Dockerfile present."),inferredPort:t.number().int().min(1).max(65535),suggestedAppName:t.string().describe("kebab-case app name suggestion derived from packageName or relativePath."),suggestedConfigPath:t.string().describe("Suggested fjall config path relative to repo root, e.g. 'fjall/website' or 'apps/website/fjall/website'."),role:h.describe("'application' if deployable evidence was found (a framework, or a Dockerfile); 'library' otherwise. Do not scaffold libraries."),recommendation:R.describe("What this workspace's framework means for `fjall apps create --pattern`. Pass `pattern` from here; never pass the framework name."),create:y.nullable().describe("Values to pass to `fjall apps create`, read from the repository. Null when no pattern applies.")}).strict(),$=t.object({isMonorepo:t.boolean(),monorepoTool:v.nullable(),rootPackageName:t.string().nullable(),apps:t.array(M).describe("Detected apps. Empty if nothing scaffoldable was found. Single-element for flat repos, multi-element for monorepos."),warnings:t.array(t.string()).describe("Non-fatal observations (e.g. 'apps/legacy has no package.json \u2014 skipped').")}).strict();function J(e,r){return r.turboJson?"turbo":r.nxJson?"nx":r.pnpmWorkspaceYaml?"pnpm":r.lernaJson?"lerna":e?.workspaces?"npm-workspaces":null}o(J,"inferMonorepoTool");function Y(e){return e?.workspaces?Array.isArray(e.workspaces)?e.workspaces:e.workspaces.packages??[]:[]}o(Y,"extractWorkspaceGlobs");const f={"nextjs+payload":["next","payload"],nextjs:["next"],payload:["payload"],remix:["@remix-run/node"],astro:["astro"],express:["express"]},m={"nextjs+payload":0,nextjs:1,payload:2,remix:3,astro:4,express:5},P=Object.keys(f).sort((e,r)=>m[e]-m[r]);function H(e){if(!e)return"unknown";const r={...e.dependencies??{},...e.devDependencies??{}};for(const n of P)if(f[n].every(a=>a in r))return n;return"unknown"}o(H,"inferFrameworkFromDeps");const C={nextjs:3e3,"nextjs+payload":3e3,payload:3e3,remix:3e3,astro:4321,express:3e3,unknown:3e3};function z(e){return C[e]}o(z,"inferPortForFramework");function q(e){if(e.length===0)return null;const r=e.find(s=>s==="Dockerfile");if(r)return{name:r,isDev:!1};const n=e.find(s=>s.startsWith("Dockerfile")&&!/\.(dev|local|test)$/i.test(s));if(n)return{name:n,isDev:!1};const a=e.find(s=>/\.dev$/i.test(s));if(a)return{name:a,isDev:!0};const i=e[0];return i===void 0?null:{name:i,isDev:!1}}o(q,"pickPreferredDockerfile");function Q(e,r){if(e){const a=e.replace(/^@[^/]+\//,"");if(a.length>0)return a}return r==="."||r===""?"app":r.split("/").pop()??"app"}o(Q,"suggestAppName");function X(e,r){return r==="."||r===""?l(e):l(e,r)}o(X,"suggestConfigPath");export{x as APP_ROLE_VALUES,S as ASTRO_BUILD_FORMAT_VALUES,G as ASTRO_CONFIG_FILENAMES,F as ASTRO_FORMAT_TO_ROUTING,M as AppDetectionSchema,h as AppRoleSchema,se as CREATABLE_FRAMEWORKS,y as CreatePrefillSchema,te as FRAMEWORKS,w as FRAMEWORK_OUTPUT_DIRS,oe as FRAMEWORK_PATTERN_RECOMMENDATIONS,re as FRAMEWORK_VALUES,k as FrameworkSchema,j as MONOREPO_TOOL_VALUES,v as MonorepoToolSchema,W as PACKAGE_MANAGER_LOCKFILES,c as PACKAGE_MANAGER_VALUES,R as PatternRecommendationSchema,$ as RepositoryDetectionSchema,Y as extractWorkspaceGlobs,K as inferAppRole,V as inferAstroRouting,B as inferCreatePrefill,H as inferFrameworkFromDeps,J as inferMonorepoTool,I as inferPackageManager,z as inferPortForFramework,ne as isFramework,D as parseAstroBuildFormat,q as pickPreferredDockerfile,ae as recommendPatternForFramework,Q as suggestAppName,X as suggestConfigPath,T as toConfigDirRelativeSource};
|
|
@@ -14,7 +14,8 @@ export interface StaticSiteResourceOptions {
|
|
|
14
14
|
source: string;
|
|
15
15
|
/** Build command + output directory (both required — deploy SSoT). */
|
|
16
16
|
build: StaticSiteBuildConfig;
|
|
17
|
-
/**
|
|
17
|
+
/** "multipage" (/about → /about.html), "directory" (/about →
|
|
18
|
+
* /about/index.html) or "spa" (index.html fallback). */
|
|
18
19
|
routing?: StaticSiteRouting;
|
|
19
20
|
/** Custom domain (auto-creates certificate + DNS). Required for forms. */
|
|
20
21
|
domain?: string;
|
|
@@ -271,6 +271,7 @@ export declare const ApplicationResourcePlanSchema: z.ZodObject<{
|
|
|
271
271
|
}, z.core.$strict>;
|
|
272
272
|
routing: z.ZodOptional<z.ZodEnum<{
|
|
273
273
|
multipage: "multipage";
|
|
274
|
+
directory: "directory";
|
|
274
275
|
spa: "spa";
|
|
275
276
|
}>>;
|
|
276
277
|
security: z.ZodOptional<z.ZodObject<{
|
|
@@ -939,6 +940,7 @@ export declare const ApplicationGeneratorSchema: z.ZodObject<{
|
|
|
939
940
|
outputDir: z.ZodOptional<z.ZodString>;
|
|
940
941
|
routing: z.ZodOptional<z.ZodEnum<{
|
|
941
942
|
multipage: "multipage";
|
|
943
|
+
directory: "directory";
|
|
942
944
|
spa: "spa";
|
|
943
945
|
}>>;
|
|
944
946
|
formsTo: z.ZodOptional<z.ZodString>;
|
|
@@ -412,13 +412,15 @@ export declare const NextJSPatternConfigSchema: z.ZodObject<{
|
|
|
412
412
|
environment: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
413
413
|
}, z.core.$strict>;
|
|
414
414
|
/**
|
|
415
|
-
* Routing mode for a static site: "multipage" (
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
415
|
+
* Routing mode for a static site: "multipage" (/about → /about.html),
|
|
416
|
+
* "directory" (/about → /about/index.html — Astro's default layout) or "spa"
|
|
417
|
+
* (unknown paths fall back to /index.html). The accept-set is derived from
|
|
418
|
+
* `@fjall/util` — the CDN construct reads the same tuple, so a mode cannot
|
|
419
|
+
* be added to one side alone.
|
|
419
420
|
*/
|
|
420
421
|
export declare const StaticSiteRoutingSchema: z.ZodEnum<{
|
|
421
422
|
multipage: "multipage";
|
|
423
|
+
directory: "directory";
|
|
422
424
|
spa: "spa";
|
|
423
425
|
}>;
|
|
424
426
|
export type StaticSiteRouting = z.infer<typeof StaticSiteRoutingSchema>;
|
|
@@ -483,6 +485,7 @@ export declare const StaticSitePatternConfigSchema: z.ZodObject<{
|
|
|
483
485
|
}, z.core.$strict>;
|
|
484
486
|
routing: z.ZodOptional<z.ZodEnum<{
|
|
485
487
|
multipage: "multipage";
|
|
488
|
+
directory: "directory";
|
|
486
489
|
spa: "spa";
|
|
487
490
|
}>>;
|
|
488
491
|
security: z.ZodOptional<z.ZodObject<{
|
|
@@ -757,6 +760,7 @@ export declare const PatternConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
757
760
|
}, z.core.$strict>;
|
|
758
761
|
routing: z.ZodOptional<z.ZodEnum<{
|
|
759
762
|
multipage: "multipage";
|
|
763
|
+
directory: "directory";
|
|
760
764
|
spa: "spa";
|
|
761
765
|
}>>;
|
|
762
766
|
security: z.ZodOptional<z.ZodObject<{
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const GENERATOR_VERSION = "
|
|
1
|
+
export declare const GENERATOR_VERSION = "23.0.0";
|
package/dist/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const E="
|
|
1
|
+
const E="23.0.0";export{E as GENERATOR_VERSION};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/generator",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "23.0.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/fjall-tech/fjall.git",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"license": "SEE LICENSE IN LICENSE",
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@babel/parser": "^7.29.8",
|
|
61
|
-
"@fjall/util": "^
|
|
61
|
+
"@fjall/util": "^23.0.0",
|
|
62
62
|
"ast-types": "^0.16.1",
|
|
63
63
|
"recast": "^0.23.12",
|
|
64
64
|
"ts-morph": "^28.0.0",
|