@byline/cli 4.10.0 → 4.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/phases/wire/index.d.ts.map +1 -1
- package/dist/phases/wire/index.js +5 -0
- package/dist/phases/wire/index.js.map +1 -1
- package/dist/phases/wire/vite-config-merge.d.ts +61 -0
- package/dist/phases/wire/vite-config-merge.d.ts.map +1 -0
- package/dist/phases/wire/vite-config-merge.js +319 -0
- package/dist/phases/wire/vite-config-merge.js.map +1 -0
- package/dist/phases/wire/vite-config-merge.test.d.ts +2 -0
- package/dist/phases/wire/vite-config-merge.test.d.ts.map +1 -0
- package/dist/phases/wire/vite-config-merge.test.js +134 -0
- package/dist/phases/wire/vite-config-merge.test.js.map +1 -0
- package/dist/phases/wire/vite-config.d.ts.map +1 -1
- package/dist/phases/wire/vite-config.js +66 -10
- package/dist/phases/wire/vite-config.js.map +1 -1
- package/dist/phases/wire/vite-config.test.js +58 -11
- package/dist/phases/wire/vite-config.test.js.map +1 -1
- package/dist/templates/byline/seed-admin.ts +17 -0
- package/dist/templates/byline/seeds/admin.ts +6 -9
- package/dist/templates/byline-examples/scripts/import-docs.ts +9 -5
- package/dist/templates/byline-examples/seed-docs.ts +9 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/phases/wire/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAa,KAAK,EAA2B,MAAM,gBAAgB,CAAA;AAgB/E,eAAO,MAAM,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/phases/wire/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAa,KAAK,EAA2B,MAAM,gBAAgB,CAAA;AAgB/E,eAAO,MAAM,SAAS,EAAE,KAuDvB,CAAA"}
|
|
@@ -57,6 +57,11 @@ export const wirePhase = {
|
|
|
57
57
|
break;
|
|
58
58
|
case 'blocked':
|
|
59
59
|
ctx.logger.error(` ${sub.key}: ${r.message}`);
|
|
60
|
+
// A blocked sub-edit halts the run, so this note is the user's only
|
|
61
|
+
// instruction for how to unblock it — always show it when present.
|
|
62
|
+
if (r.snippet) {
|
|
63
|
+
ctx.prompter.note(r.snippet, `${sub.key}: required configuration`);
|
|
64
|
+
}
|
|
60
65
|
break;
|
|
61
66
|
}
|
|
62
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/phases/wire/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAIjD,mEAAmE;AACnE,4EAA4E;AAC5E,0EAA0E;AAC1E,sEAAsE;AACtE,oDAAoD;AACpD,MAAM,SAAS,GAAc;IAC3B,YAAY;IACZ,iBAAiB;IACjB,WAAW;IACX,YAAY;IACZ,cAAc;CACf,CAAA;AAED,MAAM,CAAC,MAAM,SAAS,GAAU;IAC9B,EAAE,EAAE,MAAM;IACV,KAAK,EAAE,+DAA+D;IACtE,WAAW,EAAE,SAAS;IAEtB,KAAK,CAAC,MAAM,CAAC,GAAG;QACd,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;QAC3E,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC;YAAE,OAAO,SAAS,CAAA;QAC3E,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;IACpF,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAG;QACZ,MAAM,KAAK,GAAa,EAAE,CAAA;QAC1B,MAAM,MAAM,GAAgB,EAAE,CAAA;QAC9B,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAChC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;YAClC,IAAI,CAAC,CAAC,MAAM;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAA;QACxC,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,CAAA;IACxC,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG;QACnB,MAAM,OAAO,GAA6C,EAAE,CAAA;QAC5D,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;YAC3C,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAA;YACzC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;YAE9D,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC;gBACjB,KAAK,MAAM;oBACT,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;oBAChD,MAAK;gBACP,KAAK,SAAS;oBACZ,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;oBAC7C,MAAK;gBACP,KAAK,QAAQ;oBACX,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;oBAC7C,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;wBACd,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,GAAG,uBAAuB,CAAC,CAAA;oBACjE,CAAC;oBACD,MAAK;gBACP,KAAK,SAAS;oBACZ,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;oBAC9C,MAAK;YACT,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAA;IAChE,CAAC;CACF,CAAA;AAED,SAAS,UAAU,CAAC,GAAW,EAAE,CAAgB;IAC/C,MAAM,GAAG,GACP,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;IAC9F,OAAO,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAA;AACxC,CAAC;AAED,SAAS,iBAAiB,CAAC,CAA0B;IACnD,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IACrC,OAAO,CAAC,CAAA;AACV,CAAC;AAED,SAAS,cAAc,CAAC,OAAwB;IAC9C,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC;QAAE,OAAO,SAAS,CAAA;IACjE,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAA;IAChE,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/phases/wire/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merge Byline's required Vite settings into a host application's own
|
|
3
|
+
* `vite.config.ts`.
|
|
4
|
+
*
|
|
5
|
+
* The settings themselves are never written out by hand here. They are
|
|
6
|
+
* extracted from the canonical template (`templates/host/vite.config.ts`) at
|
|
7
|
+
* runtime, so that file stays the single source of truth and this module
|
|
8
|
+
* cannot drift from it. `extractCanonicalPieces` is pinned by a contract test.
|
|
9
|
+
*
|
|
10
|
+
* Merging is deliberately conservative: every insertion must land in a key the
|
|
11
|
+
* host config does not already define. If the config declares any of the keys
|
|
12
|
+
* Byline owns, or is shaped in a way this module does not recognise, the caller
|
|
13
|
+
* is told which pieces could not be placed and falls back to asking the user to
|
|
14
|
+
* merge them by hand. A wrong merge is worse than no merge — it moves the
|
|
15
|
+
* failure from install time, where the CLI can explain it, to a confusing
|
|
16
|
+
* runtime or production-build failure.
|
|
17
|
+
*/
|
|
18
|
+
export interface CanonicalPieces {
|
|
19
|
+
/** Source text of each module-level statement, keyed by declaration name. */
|
|
20
|
+
statements: Map<string, string>;
|
|
21
|
+
/** Source text of each `defineConfig` property, keyed by property name. */
|
|
22
|
+
configProps: Map<string, string>;
|
|
23
|
+
/** Source text of each `nitro()` option, keyed by property name. */
|
|
24
|
+
nitroProps: Map<string, string>;
|
|
25
|
+
}
|
|
26
|
+
export interface MergePlan {
|
|
27
|
+
/** Human-readable description of each edit, for the phase preview. */
|
|
28
|
+
changes: string[];
|
|
29
|
+
/** Pieces that could not be placed; the caller surfaces these for hand-merge. */
|
|
30
|
+
unplaced: string[];
|
|
31
|
+
/** Applies the plan and returns the edited source text. */
|
|
32
|
+
apply(): string;
|
|
33
|
+
}
|
|
34
|
+
export type MergeAnalysis = {
|
|
35
|
+
kind: 'canonical';
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'mergeable';
|
|
38
|
+
plan: MergePlan;
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'unrecognized';
|
|
41
|
+
reason: string;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Pull the Byline-owned pieces out of the canonical template. Throws if the
|
|
45
|
+
* template no longer contains an expected piece — that is a build-time bug in
|
|
46
|
+
* Byline, not a problem with the user's config, and it must fail loudly.
|
|
47
|
+
*/
|
|
48
|
+
export declare function extractCanonicalPieces(canonicalSource: string): CanonicalPieces;
|
|
49
|
+
/**
|
|
50
|
+
* Decide whether the host's config can take Byline's settings, and if so return
|
|
51
|
+
* a plan that applies them.
|
|
52
|
+
*
|
|
53
|
+
* The async-hooks alias references `byline/async-hooks.browser.ts`, which the
|
|
54
|
+
* scaffold phase writes. Wire runs *before* scaffold, so that file does not
|
|
55
|
+
* exist yet at this point — we still emit the reference, exactly as the
|
|
56
|
+
* canonical full-replace path does, because scaffold always follows wire in a
|
|
57
|
+
* normal `init`. Gating on the file's presence would silently drop the alias
|
|
58
|
+
* from every fresh install.
|
|
59
|
+
*/
|
|
60
|
+
export declare function analyzeUserConfig(userSource: string, canonical: CanonicalPieces): MergeAnalysis;
|
|
61
|
+
//# sourceMappingURL=vite-config-merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-config-merge.d.ts","sourceRoot":"","sources":["../../../src/phases/wire/vite-config-merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAkDH,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,2EAA2E;IAC3E,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,oEAAoE;IACpE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,sEAAsE;IACtE,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,iFAAiF;IACjF,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,2DAA2D;IAC3D,KAAK,IAAI,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAM5C;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,eAAe,EAAE,MAAM,GAAG,eAAe,CAwC/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,GAAG,aAAa,CA0H/F"}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merge Byline's required Vite settings into a host application's own
|
|
3
|
+
* `vite.config.ts`.
|
|
4
|
+
*
|
|
5
|
+
* The settings themselves are never written out by hand here. They are
|
|
6
|
+
* extracted from the canonical template (`templates/host/vite.config.ts`) at
|
|
7
|
+
* runtime, so that file stays the single source of truth and this module
|
|
8
|
+
* cannot drift from it. `extractCanonicalPieces` is pinned by a contract test.
|
|
9
|
+
*
|
|
10
|
+
* Merging is deliberately conservative: every insertion must land in a key the
|
|
11
|
+
* host config does not already define. If the config declares any of the keys
|
|
12
|
+
* Byline owns, or is shaped in a way this module does not recognise, the caller
|
|
13
|
+
* is told which pieces could not be placed and falls back to asking the user to
|
|
14
|
+
* merge them by hand. A wrong merge is worse than no merge — it moves the
|
|
15
|
+
* failure from install time, where the CLI can explain it, to a confusing
|
|
16
|
+
* runtime or production-build failure.
|
|
17
|
+
*/
|
|
18
|
+
import { Node, Project, SyntaxKind, } from 'ts-morph';
|
|
19
|
+
/** Statements Byline adds above `defineConfig`, in declaration order. */
|
|
20
|
+
const CANONICAL_STATEMENTS = [
|
|
21
|
+
'browserAsyncHooksShim',
|
|
22
|
+
'browserAsyncHooksAlias',
|
|
23
|
+
'bylineSsrNoExternal',
|
|
24
|
+
'ssrExternal',
|
|
25
|
+
];
|
|
26
|
+
/** Top-level `defineConfig({...})` keys Byline owns. */
|
|
27
|
+
const CANONICAL_CONFIG_KEYS = ['environments', 'ssr', 'optimizeDeps'];
|
|
28
|
+
/** Keys Byline adds to the `nitro({...})` plugin call. */
|
|
29
|
+
const CANONICAL_NITRO_KEYS = ['noExternals', 'rolldownConfig'];
|
|
30
|
+
/** The plugin Byline prepends to the `plugins` array. */
|
|
31
|
+
const BYLINE_PLUGIN_CALL = 'browserAsyncHooksAlias()';
|
|
32
|
+
/**
|
|
33
|
+
* A substring that only appears in Byline's own value for a given key.
|
|
34
|
+
*
|
|
35
|
+
* A key being present is not the same as a key being *ours*. Re-running `init`,
|
|
36
|
+
* or inspecting the canonical config itself, must recognise Byline's settings as
|
|
37
|
+
* already applied rather than reporting them as host-owned conflicts. Byline's
|
|
38
|
+
* values always reference a Byline identifier or scope, so that is the tell.
|
|
39
|
+
*/
|
|
40
|
+
const KEY_MARKERS = {
|
|
41
|
+
environments: 'bylineSsrNoExternal',
|
|
42
|
+
ssr: 'bylineSsrNoExternal',
|
|
43
|
+
optimizeDeps: 'ssrExternal',
|
|
44
|
+
noExternals: '@byline/',
|
|
45
|
+
rolldownConfig: '@byline/',
|
|
46
|
+
};
|
|
47
|
+
function isBylineOwnedValue(key, text) {
|
|
48
|
+
const marker = KEY_MARKERS[key];
|
|
49
|
+
return marker != null && text.includes(marker);
|
|
50
|
+
}
|
|
51
|
+
function newProject() {
|
|
52
|
+
return new Project({ useInMemoryFileSystem: true, skipAddingFilesFromTsConfig: true });
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Pull the Byline-owned pieces out of the canonical template. Throws if the
|
|
56
|
+
* template no longer contains an expected piece — that is a build-time bug in
|
|
57
|
+
* Byline, not a problem with the user's config, and it must fail loudly.
|
|
58
|
+
*/
|
|
59
|
+
export function extractCanonicalPieces(canonicalSource) {
|
|
60
|
+
const source = newProject().createSourceFile('canonical.ts', canonicalSource);
|
|
61
|
+
const statements = new Map();
|
|
62
|
+
for (const name of CANONICAL_STATEMENTS) {
|
|
63
|
+
const declaration = source.getVariableStatement((statement) => statement.getDeclarations().some((d) => d.getName() === name));
|
|
64
|
+
if (!declaration) {
|
|
65
|
+
throw new Error(`canonical vite.config.ts no longer declares \`${name}\``);
|
|
66
|
+
}
|
|
67
|
+
statements.set(name, declaration.getText());
|
|
68
|
+
}
|
|
69
|
+
const configObject = findDefineConfigObject(source);
|
|
70
|
+
if (!configObject) {
|
|
71
|
+
throw new Error('canonical vite.config.ts has no recognisable defineConfig({...}) call');
|
|
72
|
+
}
|
|
73
|
+
const configProps = new Map();
|
|
74
|
+
for (const key of CANONICAL_CONFIG_KEYS) {
|
|
75
|
+
const property = configObject.getProperty(key);
|
|
76
|
+
if (!property)
|
|
77
|
+
throw new Error(`canonical vite.config.ts no longer sets \`${key}\``);
|
|
78
|
+
configProps.set(key, property.getText());
|
|
79
|
+
}
|
|
80
|
+
const nitroCall = findNitroCall(configObject);
|
|
81
|
+
const nitroObject = nitroCall ? firstObjectArgument(nitroCall) : undefined;
|
|
82
|
+
if (!nitroObject) {
|
|
83
|
+
throw new Error('canonical vite.config.ts has no recognisable nitro({...}) call');
|
|
84
|
+
}
|
|
85
|
+
const nitroProps = new Map();
|
|
86
|
+
for (const key of CANONICAL_NITRO_KEYS) {
|
|
87
|
+
const property = nitroObject.getProperty(key);
|
|
88
|
+
if (!property)
|
|
89
|
+
throw new Error(`canonical vite.config.ts no longer sets nitro \`${key}\``);
|
|
90
|
+
nitroProps.set(key, property.getText());
|
|
91
|
+
}
|
|
92
|
+
return { statements, configProps, nitroProps };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Decide whether the host's config can take Byline's settings, and if so return
|
|
96
|
+
* a plan that applies them.
|
|
97
|
+
*
|
|
98
|
+
* The async-hooks alias references `byline/async-hooks.browser.ts`, which the
|
|
99
|
+
* scaffold phase writes. Wire runs *before* scaffold, so that file does not
|
|
100
|
+
* exist yet at this point — we still emit the reference, exactly as the
|
|
101
|
+
* canonical full-replace path does, because scaffold always follows wire in a
|
|
102
|
+
* normal `init`. Gating on the file's presence would silently drop the alias
|
|
103
|
+
* from every fresh install.
|
|
104
|
+
*/
|
|
105
|
+
export function analyzeUserConfig(userSource, canonical) {
|
|
106
|
+
const project = newProject();
|
|
107
|
+
let source;
|
|
108
|
+
try {
|
|
109
|
+
source = project.createSourceFile('vite.config.ts', userSource);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return { kind: 'unrecognized', reason: 'could not be parsed as TypeScript' };
|
|
113
|
+
}
|
|
114
|
+
// Only syntactic problems disqualify a config. This project loads no lib or
|
|
115
|
+
// type information, so semantic diagnostics (codes >= 2000) are dominated by
|
|
116
|
+
// "cannot find module 'vite'" and say nothing about whether the file parses.
|
|
117
|
+
// TypeScript reserves codes below 2000 for the parser.
|
|
118
|
+
if (source.getPreEmitDiagnostics().some((d) => d.getCode() < 2000)) {
|
|
119
|
+
return { kind: 'unrecognized', reason: 'contains syntax errors' };
|
|
120
|
+
}
|
|
121
|
+
const configObject = findDefineConfigObject(source);
|
|
122
|
+
if (!configObject) {
|
|
123
|
+
return {
|
|
124
|
+
kind: 'unrecognized',
|
|
125
|
+
reason: 'no `defineConfig({ ... })` call with an inline object literal was found',
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const changes = [];
|
|
129
|
+
const unplaced = [];
|
|
130
|
+
const missingStatements = CANONICAL_STATEMENTS.filter((name) => !declaresName(source, name));
|
|
131
|
+
// Byline only claims keys the host has not already set. A key holding a
|
|
132
|
+
// host-authored value is reported rather than merged into — we cannot know
|
|
133
|
+
// whether that value was deliberate. A key already holding Byline's own value
|
|
134
|
+
// is simply done.
|
|
135
|
+
const configKeysToAdd = [];
|
|
136
|
+
for (const key of CANONICAL_CONFIG_KEYS) {
|
|
137
|
+
const property = configObject.getProperty(key);
|
|
138
|
+
if (!property) {
|
|
139
|
+
configKeysToAdd.push(key);
|
|
140
|
+
}
|
|
141
|
+
else if (!isBylineOwnedValue(key, property.getText())) {
|
|
142
|
+
unplaced.push(`\`${key}\` is already set`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const pluginsArray = getPluginsArray(configObject);
|
|
146
|
+
const nitroCall = pluginsArray ? findNitroCallInArray(pluginsArray) : undefined;
|
|
147
|
+
const nitroObject = nitroCall ? firstObjectArgument(nitroCall) : undefined;
|
|
148
|
+
const nitroKeysToAdd = [];
|
|
149
|
+
if (!pluginsArray) {
|
|
150
|
+
unplaced.push('no inline `plugins: [ ... ]` array to register Byline plugins in');
|
|
151
|
+
}
|
|
152
|
+
else if (!nitroCall) {
|
|
153
|
+
unplaced.push('no `nitro( ... )` plugin call found');
|
|
154
|
+
}
|
|
155
|
+
else if (!nitroObject) {
|
|
156
|
+
unplaced.push('`nitro( ... )` is not called with an inline object literal');
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
for (const key of CANONICAL_NITRO_KEYS) {
|
|
160
|
+
const property = nitroObject.getProperty(key);
|
|
161
|
+
if (!property) {
|
|
162
|
+
nitroKeysToAdd.push(key);
|
|
163
|
+
}
|
|
164
|
+
else if (!isBylineOwnedValue(key, property.getText())) {
|
|
165
|
+
unplaced.push(`nitro \`${key}\` is already set`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const addsPlugin = pluginsArray != null && !pluginsArrayHasByline(pluginsArray);
|
|
170
|
+
if (missingStatements.length > 0)
|
|
171
|
+
changes.push(`add ${missingStatements.join(', ')}`);
|
|
172
|
+
if (configKeysToAdd.length > 0)
|
|
173
|
+
changes.push(`set ${configKeysToAdd.join(', ')}`);
|
|
174
|
+
if (nitroKeysToAdd.length > 0)
|
|
175
|
+
changes.push(`set nitro ${nitroKeysToAdd.join(', ')}`);
|
|
176
|
+
if (addsPlugin)
|
|
177
|
+
changes.push('register browserAsyncHooksAlias()');
|
|
178
|
+
if (changes.length === 0 && unplaced.length === 0) {
|
|
179
|
+
return { kind: 'canonical' };
|
|
180
|
+
}
|
|
181
|
+
if (changes.length === 0) {
|
|
182
|
+
return {
|
|
183
|
+
kind: 'unrecognized',
|
|
184
|
+
reason: `nothing could be applied automatically (${unplaced.join('; ')})`,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
kind: 'mergeable',
|
|
189
|
+
plan: {
|
|
190
|
+
changes,
|
|
191
|
+
unplaced,
|
|
192
|
+
apply() {
|
|
193
|
+
// Re-parse so the plan owns a clean tree; analysis must not mutate.
|
|
194
|
+
const applyProject = newProject();
|
|
195
|
+
const applySource = applyProject.createSourceFile('vite.config.ts', userSource);
|
|
196
|
+
const applyConfig = findDefineConfigObject(applySource);
|
|
197
|
+
if (!applyConfig)
|
|
198
|
+
return userSource;
|
|
199
|
+
ensureNamedImport(applySource, 'node:url', 'fileURLToPath');
|
|
200
|
+
ensureTypeOnlyNamedImport(applySource, 'vite', 'Plugin');
|
|
201
|
+
insertStatementsBeforeConfig(applySource, canonical, missingStatements);
|
|
202
|
+
for (const key of configKeysToAdd) {
|
|
203
|
+
const text = canonical.configProps.get(key);
|
|
204
|
+
if (text)
|
|
205
|
+
applyConfig.addProperty(text);
|
|
206
|
+
}
|
|
207
|
+
const applyPlugins = getPluginsArray(applyConfig);
|
|
208
|
+
if (applyPlugins) {
|
|
209
|
+
if (addsPlugin)
|
|
210
|
+
applyPlugins.insertElement(0, BYLINE_PLUGIN_CALL);
|
|
211
|
+
const applyNitro = findNitroCallInArray(applyPlugins);
|
|
212
|
+
const applyNitroObject = applyNitro ? firstObjectArgument(applyNitro) : undefined;
|
|
213
|
+
if (applyNitroObject) {
|
|
214
|
+
for (const key of nitroKeysToAdd) {
|
|
215
|
+
const text = canonical.nitroProps.get(key);
|
|
216
|
+
if (text)
|
|
217
|
+
applyNitroObject.addProperty(text);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
applySource.formatText({ indentSize: 2 });
|
|
222
|
+
return applySource.getFullText();
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
function declaresName(source, name) {
|
|
228
|
+
return source
|
|
229
|
+
.getVariableStatements()
|
|
230
|
+
.some((statement) => statement.getDeclarations().some((d) => d.getName() === name));
|
|
231
|
+
}
|
|
232
|
+
function insertStatementsBeforeConfig(source, canonical, names) {
|
|
233
|
+
if (names.length === 0)
|
|
234
|
+
return;
|
|
235
|
+
const anchor = source
|
|
236
|
+
.getStatements()
|
|
237
|
+
.find((statement) => statement.getDescendantsOfKind(SyntaxKind.CallExpression).some(isDefineConfigCall));
|
|
238
|
+
const index = anchor ? anchor.getChildIndex() : source.getStatements().length;
|
|
239
|
+
const texts = names
|
|
240
|
+
.map((name) => canonical.statements.get(name))
|
|
241
|
+
.filter((text) => text != null);
|
|
242
|
+
source.insertStatements(index, texts);
|
|
243
|
+
}
|
|
244
|
+
function isDefineConfigCall(call) {
|
|
245
|
+
return call.getExpression().getText() === 'defineConfig';
|
|
246
|
+
}
|
|
247
|
+
function findDefineConfigObject(source) {
|
|
248
|
+
for (const call of source.getDescendantsOfKind(SyntaxKind.CallExpression)) {
|
|
249
|
+
if (!isDefineConfigCall(call))
|
|
250
|
+
continue;
|
|
251
|
+
const object = firstObjectArgument(call);
|
|
252
|
+
if (object)
|
|
253
|
+
return object;
|
|
254
|
+
}
|
|
255
|
+
return undefined;
|
|
256
|
+
}
|
|
257
|
+
function firstObjectArgument(call) {
|
|
258
|
+
const [first] = call.getArguments();
|
|
259
|
+
if (first && Node.isObjectLiteralExpression(first))
|
|
260
|
+
return first;
|
|
261
|
+
return undefined;
|
|
262
|
+
}
|
|
263
|
+
function getPluginsArray(config) {
|
|
264
|
+
const property = config.getProperty('plugins');
|
|
265
|
+
if (!property || !Node.isPropertyAssignment(property))
|
|
266
|
+
return undefined;
|
|
267
|
+
const initializer = property.getInitializer();
|
|
268
|
+
if (initializer && Node.isArrayLiteralExpression(initializer))
|
|
269
|
+
return initializer;
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
function findNitroCall(config) {
|
|
273
|
+
const plugins = getPluginsArray(config);
|
|
274
|
+
return plugins ? findNitroCallInArray(plugins) : undefined;
|
|
275
|
+
}
|
|
276
|
+
function findNitroCallInArray(plugins) {
|
|
277
|
+
for (const element of plugins.getElements()) {
|
|
278
|
+
if (Node.isCallExpression(element) && element.getExpression().getText() === 'nitro') {
|
|
279
|
+
return element;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return undefined;
|
|
283
|
+
}
|
|
284
|
+
function pluginsArrayHasByline(plugins) {
|
|
285
|
+
return plugins
|
|
286
|
+
.getElements()
|
|
287
|
+
.some((element) => element.getText().includes('browserAsyncHooksAlias'));
|
|
288
|
+
}
|
|
289
|
+
function ensureNamedImport(source, moduleSpecifier, name) {
|
|
290
|
+
const existing = source
|
|
291
|
+
.getImportDeclarations()
|
|
292
|
+
.find((d) => d.getModuleSpecifierValue() === moduleSpecifier);
|
|
293
|
+
if (existing) {
|
|
294
|
+
if (!existing.getNamedImports().some((n) => n.getName() === name)) {
|
|
295
|
+
existing.addNamedImport(name);
|
|
296
|
+
}
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
source.insertImportDeclaration(source.getImportDeclarations().length, {
|
|
300
|
+
moduleSpecifier,
|
|
301
|
+
namedImports: [name],
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
function ensureTypeOnlyNamedImport(source, moduleSpecifier, name) {
|
|
305
|
+
const existing = source
|
|
306
|
+
.getImportDeclarations()
|
|
307
|
+
.find((d) => d.getModuleSpecifierValue() === moduleSpecifier);
|
|
308
|
+
if (existing) {
|
|
309
|
+
if (!existing.getNamedImports().some((n) => n.getName() === name)) {
|
|
310
|
+
existing.addNamedImport({ name, isTypeOnly: true });
|
|
311
|
+
}
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
source.insertImportDeclaration(source.getImportDeclarations().length, {
|
|
315
|
+
moduleSpecifier,
|
|
316
|
+
namedImports: [{ name, isTypeOnly: true }],
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=vite-config-merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-config-merge.js","sourceRoot":"","sources":["../../../src/phases/wire/vite-config-merge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-config-merge.test.d.ts","sourceRoot":"","sources":["../../../src/phases/wire/vite-config-merge.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { analyzeUserConfig, extractCanonicalPieces } from './vite-config-merge.js';
|
|
6
|
+
const CANONICAL = readFileSync(join(dirname(fileURLToPath(import.meta.url)), '../../templates/host/vite.config.ts'), 'utf8');
|
|
7
|
+
/**
|
|
8
|
+
* The shape the TanStack Start CLI emits. The Sentry external is deliberate:
|
|
9
|
+
* it lives under `rollupConfig`, a different key from the `rolldownConfig`
|
|
10
|
+
* Byline writes, and must survive the merge untouched.
|
|
11
|
+
*/
|
|
12
|
+
const STOCK_STARTER = `import { defineConfig } from 'vite'
|
|
13
|
+
import { devtools } from '@tanstack/devtools-vite'
|
|
14
|
+
|
|
15
|
+
import { tanstackStart } from '@tanstack/react-start/plugin/vite'
|
|
16
|
+
|
|
17
|
+
import viteReact from '@vitejs/plugin-react'
|
|
18
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
19
|
+
import { nitro } from 'nitro/vite'
|
|
20
|
+
|
|
21
|
+
const config = defineConfig({
|
|
22
|
+
resolve: { tsconfigPaths: true },
|
|
23
|
+
plugins: [
|
|
24
|
+
devtools(),
|
|
25
|
+
nitro({ rollupConfig: { external: [/^@sentry\\//] } }),
|
|
26
|
+
tailwindcss(),
|
|
27
|
+
tanstackStart(),
|
|
28
|
+
viteReact(),
|
|
29
|
+
],
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
export default config
|
|
33
|
+
`;
|
|
34
|
+
describe('canonical extraction', () => {
|
|
35
|
+
// A contract test against the real template: if someone renames or removes a
|
|
36
|
+
// Byline-owned piece there, the merge silently stops applying it. Extraction
|
|
37
|
+
// must fail loudly instead.
|
|
38
|
+
it('finds every Byline-owned piece in the shipped canonical config', () => {
|
|
39
|
+
const pieces = extractCanonicalPieces(CANONICAL);
|
|
40
|
+
expect([...pieces.statements.keys()]).toEqual([
|
|
41
|
+
'browserAsyncHooksShim',
|
|
42
|
+
'browserAsyncHooksAlias',
|
|
43
|
+
'bylineSsrNoExternal',
|
|
44
|
+
'ssrExternal',
|
|
45
|
+
]);
|
|
46
|
+
expect([...pieces.configProps.keys()]).toEqual(['environments', 'ssr', 'optimizeDeps']);
|
|
47
|
+
expect([...pieces.nitroProps.keys()]).toEqual(['noExternals', 'rolldownConfig']);
|
|
48
|
+
});
|
|
49
|
+
it('throws rather than silently omitting a renamed piece', () => {
|
|
50
|
+
const renamed = CANONICAL.replace('const ssrExternal =', 'const somethingElse =');
|
|
51
|
+
expect(() => extractCanonicalPieces(renamed)).toThrow(/ssrExternal/);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
describe('merging into a host config', () => {
|
|
55
|
+
const canonical = extractCanonicalPieces(CANONICAL);
|
|
56
|
+
it('plans every insertion for a stock TanStack Start config', () => {
|
|
57
|
+
const analysis = analyzeUserConfig(STOCK_STARTER, canonical);
|
|
58
|
+
expect(analysis.kind).toBe('mergeable');
|
|
59
|
+
if (analysis.kind !== 'mergeable')
|
|
60
|
+
return;
|
|
61
|
+
expect(analysis.plan.unplaced).toEqual([]);
|
|
62
|
+
expect(analysis.plan.changes.join('\n')).toContain('browserAsyncHooksShim');
|
|
63
|
+
expect(analysis.plan.changes.join('\n')).toContain('environments, ssr, optimizeDeps');
|
|
64
|
+
expect(analysis.plan.changes.join('\n')).toContain('nitro noExternals, rolldownConfig');
|
|
65
|
+
});
|
|
66
|
+
it('produces a config carrying every required setting', () => {
|
|
67
|
+
const analysis = analyzeUserConfig(STOCK_STARTER, canonical);
|
|
68
|
+
if (analysis.kind !== 'mergeable')
|
|
69
|
+
throw new Error('expected mergeable');
|
|
70
|
+
const merged = analysis.plan.apply();
|
|
71
|
+
// Boot-critical.
|
|
72
|
+
expect(merged).toContain('noExternal: bylineSsrNoExternal');
|
|
73
|
+
// Hydration-critical.
|
|
74
|
+
expect(merged).toContain('use-sync-external-store/shim');
|
|
75
|
+
// Production-critical.
|
|
76
|
+
expect(merged).toContain("noExternals: ['@byline/ui'");
|
|
77
|
+
expect(merged).toContain('rolldownConfig');
|
|
78
|
+
// Imports the inserted code depends on.
|
|
79
|
+
expect(merged).toContain('fileURLToPath');
|
|
80
|
+
expect(merged).toContain('Plugin');
|
|
81
|
+
// Registered ahead of the host's own plugins.
|
|
82
|
+
expect(merged.indexOf('browserAsyncHooksAlias()')).toBeLessThan(merged.indexOf('devtools()'));
|
|
83
|
+
});
|
|
84
|
+
it("leaves the host's own settings intact", () => {
|
|
85
|
+
const analysis = analyzeUserConfig(STOCK_STARTER, canonical);
|
|
86
|
+
if (analysis.kind !== 'mergeable')
|
|
87
|
+
throw new Error('expected mergeable');
|
|
88
|
+
const merged = analysis.plan.apply();
|
|
89
|
+
// The Sentry external sits under `rollupConfig` — a different key from the
|
|
90
|
+
// `rolldownConfig` Byline adds. Losing it would be a silent regression in
|
|
91
|
+
// the host's own build.
|
|
92
|
+
expect(merged).toContain('rollupConfig');
|
|
93
|
+
expect(merged).toContain('@sentry');
|
|
94
|
+
expect(merged).toContain('tanstackStart()');
|
|
95
|
+
expect(merged).toContain('viteReact()');
|
|
96
|
+
expect(merged).toContain('tsconfigPaths: true');
|
|
97
|
+
});
|
|
98
|
+
it('is idempotent — a merged config needs no further changes', () => {
|
|
99
|
+
const first = analyzeUserConfig(STOCK_STARTER, canonical);
|
|
100
|
+
if (first.kind !== 'mergeable')
|
|
101
|
+
throw new Error('expected mergeable');
|
|
102
|
+
expect(analyzeUserConfig(first.plan.apply(), canonical).kind).toBe('canonical');
|
|
103
|
+
});
|
|
104
|
+
it('recognises the canonical config itself as already complete', () => {
|
|
105
|
+
expect(analyzeUserConfig(CANONICAL, canonical).kind).toBe('canonical');
|
|
106
|
+
});
|
|
107
|
+
it('reports a key it cannot claim rather than overwriting it', () => {
|
|
108
|
+
// A host that already sets `ssr` may have done so deliberately; merging into
|
|
109
|
+
// it could silently change their externalization.
|
|
110
|
+
const withSsr = STOCK_STARTER.replace('resolve: { tsconfigPaths: true },', "resolve: { tsconfigPaths: true },\n ssr: { external: ['left-alone'] },");
|
|
111
|
+
const analysis = analyzeUserConfig(withSsr, canonical);
|
|
112
|
+
expect(analysis.kind).toBe('mergeable');
|
|
113
|
+
if (analysis.kind !== 'mergeable')
|
|
114
|
+
return;
|
|
115
|
+
expect(analysis.plan.unplaced.join(' ')).toContain('`ssr` is already set');
|
|
116
|
+
expect(analysis.plan.apply()).toContain('left-alone');
|
|
117
|
+
});
|
|
118
|
+
it('declines a config with no inline defineConfig object', () => {
|
|
119
|
+
const indirect = `import { defineConfig } from 'vite'
|
|
120
|
+
const options = { plugins: [] }
|
|
121
|
+
export default defineConfig(options)
|
|
122
|
+
`;
|
|
123
|
+
const analysis = analyzeUserConfig(indirect, canonical);
|
|
124
|
+
expect(analysis.kind).toBe('unrecognized');
|
|
125
|
+
if (analysis.kind !== 'unrecognized')
|
|
126
|
+
return;
|
|
127
|
+
expect(analysis.reason).toContain('defineConfig');
|
|
128
|
+
});
|
|
129
|
+
it('declines a config that does not parse', () => {
|
|
130
|
+
const analysis = analyzeUserConfig('export default defineConfig({ plugins: [ }\n', canonical);
|
|
131
|
+
expect(analysis.kind).toBe('unrecognized');
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
//# sourceMappingURL=vite-config-merge.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-config-merge.test.js","sourceRoot":"","sources":["../../../src/phases/wire/vite-config-merge.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-config.d.ts","sourceRoot":"","sources":["../../../src/phases/wire/vite-config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vite-config.d.ts","sourceRoot":"","sources":["../../../src/phases/wire/vite-config.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,aAAa,CAAA;AAyBzD,eAAO,MAAM,cAAc,EAAE,OAS5B,CAAA"}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { existsSync, readFileSync } from 'node:fs';
|
|
3
|
-
import { join } from 'node:path';
|
|
3
|
+
import { basename, join } from 'node:path';
|
|
4
4
|
import { applyPlannedWrites } from '../../lib/planned-writes.js';
|
|
5
|
+
import { analyzeUserConfig, extractCanonicalPieces, } from './vite-config-merge.js';
|
|
5
6
|
const REL = 'vite.config.ts';
|
|
6
7
|
const TEMPLATE_REL = 'host/vite.config.ts';
|
|
8
|
+
const BACKUP_PREFIX = 'vite.config.ts.bak-';
|
|
9
|
+
/** `20260729T014500` — sortable, filesystem-safe, no collisions across runs. */
|
|
10
|
+
function backupStamp() {
|
|
11
|
+
return new Date()
|
|
12
|
+
.toISOString()
|
|
13
|
+
.replace(/[-:]/g, '')
|
|
14
|
+
.replace(/\.\d+Z$/, '');
|
|
15
|
+
}
|
|
7
16
|
const PREDECESSOR_HASHES = new Set([
|
|
8
17
|
// Canonical config immediately before MySQL became a scaffold option.
|
|
9
18
|
'b6ca128489e49f5efd40dd49b30a0adf33c7d9285453087d673e2b6c2a2b3696',
|
|
@@ -46,8 +55,11 @@ function inspect(ctx) {
|
|
|
46
55
|
if (normalize(userText) === normalize(canonical)) {
|
|
47
56
|
return { status: 'skipped', message: `${REL}: already matches the canonical Byline config` };
|
|
48
57
|
}
|
|
49
|
-
|
|
50
|
-
|
|
58
|
+
// Timestamped so a second run never collides with an earlier backup. The
|
|
59
|
+
// previous fixed `vite.config.bak` name meant a re-run found the file already
|
|
60
|
+
// present and silently degraded to a manual instruction.
|
|
61
|
+
const backupPath = ctx.resolve(`${BACKUP_PREFIX}${backupStamp()}`);
|
|
62
|
+
if (PREDECESSOR_HASHES.has(hashConfig(userText))) {
|
|
51
63
|
return {
|
|
52
64
|
status: 'done',
|
|
53
65
|
message: `${REL}: recognized canonical predecessor; will back up and replace it`,
|
|
@@ -57,16 +69,58 @@ function inspect(ctx) {
|
|
|
57
69
|
],
|
|
58
70
|
};
|
|
59
71
|
}
|
|
72
|
+
// Not canonical and not a predecessor — the ordinary first-install case, where
|
|
73
|
+
// the host app brought its own config. Merge Byline's settings into it rather
|
|
74
|
+
// than replacing it, but only where every insertion lands in a key the host
|
|
75
|
+
// has not already claimed.
|
|
76
|
+
let analysis;
|
|
77
|
+
try {
|
|
78
|
+
analysis = analyzeUserConfig(userText, extractCanonicalPieces(canonical));
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
return {
|
|
82
|
+
status: 'blocked',
|
|
83
|
+
message: `${REL}: could not read Byline's canonical settings (${error.message})`,
|
|
84
|
+
snippet: canonical,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (analysis.kind === 'canonical') {
|
|
88
|
+
return { status: 'skipped', message: `${REL}: already provides Byline's required settings` };
|
|
89
|
+
}
|
|
90
|
+
if (analysis.kind === 'mergeable') {
|
|
91
|
+
const merged = analysis.plan.apply();
|
|
92
|
+
const leftover = analysis.plan.unplaced.length > 0
|
|
93
|
+
? ` Left for you to merge by hand: ${analysis.plan.unplaced.join('; ')}.`
|
|
94
|
+
: '';
|
|
95
|
+
return {
|
|
96
|
+
status: 'done',
|
|
97
|
+
message: `${REL}: will back up and ${analysis.plan.changes.join(', ')}.${leftover}`,
|
|
98
|
+
writes: [
|
|
99
|
+
{ path: backupPath, contents: userText, mode: 'create' },
|
|
100
|
+
{ path, contents: merged, mode: 'patch', before: userText },
|
|
101
|
+
],
|
|
102
|
+
...(analysis.plan.unplaced.length > 0 ? { snippet: canonical } : {}),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
// Nothing could be placed safely. Block rather than warn: without these
|
|
106
|
+
// settings Vite resolves `@byline/ui`'s CSS-module imports through Node's ESM
|
|
107
|
+
// loader and the app fails to boot with `ERR_UNKNOWN_FILE_EXTENSION ".css"`.
|
|
108
|
+
// Reporting "installation complete" over that is worse than stopping here.
|
|
60
109
|
return {
|
|
61
|
-
status: '
|
|
62
|
-
message: `${REL}:
|
|
110
|
+
status: 'blocked',
|
|
111
|
+
message: `${REL}: left untouched — ${analysis.reason}. Byline's SSR settings are required; without ` +
|
|
112
|
+
`them the app fails to boot with ERR_UNKNOWN_FILE_EXTENSION ".css". Merge the settings ` +
|
|
113
|
+
`below, then re-run: byline init --from wire`,
|
|
63
114
|
snippet: canonical,
|
|
64
115
|
};
|
|
65
116
|
}
|
|
66
117
|
function apply(ctx, plannedWrites) {
|
|
67
118
|
const path = ctx.resolve(REL);
|
|
68
|
-
|
|
69
|
-
|
|
119
|
+
// Backups are timestamped, so match by prefix — the exact name was decided
|
|
120
|
+
// during preview and must not be recomputed here.
|
|
121
|
+
const backupPrefix = ctx.resolve(BACKUP_PREFIX);
|
|
122
|
+
const isBackup = (write) => write.path.startsWith(backupPrefix);
|
|
123
|
+
const writes = plannedWrites.filter((write) => write.path === path || isBackup(write));
|
|
70
124
|
if (writes.length === 0) {
|
|
71
125
|
const current = inspect(ctx);
|
|
72
126
|
if (!current.writes?.length)
|
|
@@ -85,11 +139,13 @@ function apply(ctx, plannedWrites) {
|
|
|
85
139
|
snippet: readCanonical(ctx),
|
|
86
140
|
};
|
|
87
141
|
}
|
|
142
|
+
const backup = writes.find(isBackup);
|
|
143
|
+
if (!backup) {
|
|
144
|
+
return { status: 'done', message: `${REL}: created canonical Byline config` };
|
|
145
|
+
}
|
|
88
146
|
return {
|
|
89
147
|
status: 'done',
|
|
90
|
-
message:
|
|
91
|
-
? `${REL}: canonical predecessor backed up and replaced`
|
|
92
|
-
: `${REL}: created canonical Byline config`,
|
|
148
|
+
message: `${REL}: updated with Byline's required settings (backup: ${basename(backup.path)})`,
|
|
93
149
|
};
|
|
94
150
|
}
|
|
95
151
|
function readCanonical(ctx) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-config.js","sourceRoot":"","sources":["../../../src/phases/wire/vite-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"vite-config.js","sourceRoot":"","sources":["../../../src/phases/wire/vite-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { afterEach, describe, expect, it } from 'vitest';
|
|
3
3
|
import { DATABASE_ADAPTER_IDS, databaseAdapterDefinition } from '../../lib/database/adapters.js';
|
|
4
4
|
import { createTestContext } from '../../test-helpers.js';
|
|
@@ -14,6 +14,13 @@ function fixture() {
|
|
|
14
14
|
contexts.push(ctx);
|
|
15
15
|
return ctx;
|
|
16
16
|
}
|
|
17
|
+
/** Backups are timestamped, so tests resolve them by prefix rather than name. */
|
|
18
|
+
function readBackup(ctx) {
|
|
19
|
+
const backups = readdirSync(ctx.cwd).filter((name) => name.startsWith('vite.config.ts.bak-'));
|
|
20
|
+
if (backups.length !== 1)
|
|
21
|
+
throw new Error(`expected one backup, found ${backups.length}`);
|
|
22
|
+
return readFileSync(ctx.resolve(backups[0]), 'utf8');
|
|
23
|
+
}
|
|
17
24
|
describe('Vite config safety', () => {
|
|
18
25
|
it('surfaces a missing Vite config in the parent wire plan', async () => {
|
|
19
26
|
const ctx = fixture();
|
|
@@ -71,7 +78,7 @@ describe('Vite config safety', () => {
|
|
|
71
78
|
expect(preview.writes).toHaveLength(2);
|
|
72
79
|
expect(preview.writes?.find((write) => write.path.endsWith('vite.config.ts'))?.before).toBe(predecessor);
|
|
73
80
|
expect(await wireViteConfig.apply(ctx, preview.writes)).toMatchObject({ status: 'done' });
|
|
74
|
-
expect(
|
|
81
|
+
expect(readBackup(ctx)).toBe(predecessor);
|
|
75
82
|
expect(readFileSync(ctx.resolve('vite.config.ts'), 'utf8')).toBe(canonical);
|
|
76
83
|
});
|
|
77
84
|
it('replaces the exact canonical predecessor from before MySQL externalization', async () => {
|
|
@@ -83,7 +90,7 @@ describe('Vite config safety', () => {
|
|
|
83
90
|
expect(preview).toMatchObject({ status: 'done' });
|
|
84
91
|
expect(preview.writes).toHaveLength(2);
|
|
85
92
|
expect(await wireViteConfig.apply(ctx, preview.writes)).toMatchObject({ status: 'done' });
|
|
86
|
-
expect(
|
|
93
|
+
expect(readBackup(ctx)).toBe(predecessor);
|
|
87
94
|
expect(readFileSync(ctx.resolve('vite.config.ts'), 'utf8')).toBe(canonical);
|
|
88
95
|
});
|
|
89
96
|
it('replaces the canonical config that carried an app-owned build guard', async () => {
|
|
@@ -97,17 +104,57 @@ describe('Vite config safety', () => {
|
|
|
97
104
|
const preview = await wireViteConfig.preview(ctx);
|
|
98
105
|
expect(preview).toMatchObject({ status: 'done' });
|
|
99
106
|
expect(await wireViteConfig.apply(ctx, preview.writes)).toMatchObject({ status: 'done' });
|
|
100
|
-
expect(
|
|
107
|
+
expect(readBackup(ctx)).toBe(predecessor);
|
|
101
108
|
expect(readFileSync(ctx.resolve('vite.config.ts'), 'utf8')).toBe(canonical);
|
|
102
109
|
});
|
|
103
|
-
it('
|
|
110
|
+
it('merges Byline settings into a host config and backs up the original', async () => {
|
|
111
|
+
// The ordinary first-install case: a stock TanStack Start app brings its own
|
|
112
|
+
// vite.config.ts, matching neither the canonical config nor any predecessor
|
|
113
|
+
// hash. Byline's settings are merged in rather than replacing the file.
|
|
104
114
|
const ctx = fixture();
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
115
|
+
const host = `import { defineConfig } from 'vite'
|
|
116
|
+
import { nitro } from 'nitro/vite'
|
|
117
|
+
|
|
118
|
+
const config = defineConfig({
|
|
119
|
+
plugins: [nitro({ rollupConfig: { external: [/^@sentry\\//] } })],
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
export default config
|
|
123
|
+
`;
|
|
124
|
+
writeFileSync(ctx.resolve('vite.config.ts'), host);
|
|
125
|
+
const preview = await wireViteConfig.preview(ctx);
|
|
126
|
+
expect(preview).toMatchObject({ status: 'done' });
|
|
127
|
+
expect(await wireViteConfig.apply(ctx, preview.writes)).toMatchObject({ status: 'done' });
|
|
128
|
+
const merged = readFileSync(ctx.resolve('vite.config.ts'), 'utf8');
|
|
129
|
+
expect(merged).toContain('noExternal: bylineSsrNoExternal');
|
|
130
|
+
expect(merged).toContain('browserAsyncHooksAlias()');
|
|
131
|
+
// The host's own nitro option must survive — it lives under `rollupConfig`,
|
|
132
|
+
// a different key from the `rolldownConfig` Byline writes.
|
|
133
|
+
expect(merged).toContain('@sentry');
|
|
134
|
+
// The original is preserved under a timestamped name, so a later run cannot
|
|
135
|
+
// collide with it the way the old fixed `vite.config.bak` did.
|
|
136
|
+
const backups = readdirSync(ctx.cwd).filter((name) => name.startsWith('vite.config.ts.bak-'));
|
|
137
|
+
expect(backups).toHaveLength(1);
|
|
138
|
+
expect(readFileSync(ctx.resolve(backups[0]), 'utf8')).toBe(host);
|
|
139
|
+
});
|
|
140
|
+
it('blocks, without editing, on a config it cannot place settings into', async () => {
|
|
141
|
+
// No inline `defineConfig({ ... })` to work with. This must block rather
|
|
142
|
+
// than warn: `init` treats anything short of `blocked` as a soft warning and
|
|
143
|
+
// would go on to report "installation complete" over an app that cannot boot.
|
|
144
|
+
const ctx = fixture();
|
|
145
|
+
const opaque = `import { defineConfig } from 'vite'
|
|
146
|
+
const options = { plugins: [] }
|
|
147
|
+
export default defineConfig(options)
|
|
148
|
+
`;
|
|
149
|
+
writeFileSync(ctx.resolve('vite.config.ts'), opaque);
|
|
150
|
+
for (const result of [await wireViteConfig.preview(ctx), await wireViteConfig.apply(ctx)]) {
|
|
151
|
+
expect(result).toMatchObject({ status: 'blocked' });
|
|
152
|
+
// Blocking halts the run, so the snippet is the user's only instruction.
|
|
153
|
+
expect(result.snippet).toBeTruthy();
|
|
154
|
+
expect(result.message).toContain('byline init --from wire');
|
|
155
|
+
}
|
|
156
|
+
expect(readFileSync(ctx.resolve('vite.config.ts'), 'utf8')).toBe(opaque);
|
|
157
|
+
expect(readdirSync(ctx.cwd).some((name) => name.startsWith('vite.config.ts.bak-'))).toBe(false);
|
|
111
158
|
});
|
|
112
159
|
});
|
|
113
160
|
function withoutMysqlExternalization(canonical) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite-config.test.js","sourceRoot":"","sources":["../../../src/phases/wire/vite-config.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"vite-config.test.js","sourceRoot":"","sources":["../../../src/phases/wire/vite-config.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,4 +16,21 @@ async function run() {
|
|
|
16
16
|
await seedAdmin()
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
// Exit explicitly rather than waiting for the event loop to drain. The
|
|
20
|
+
// configured adapter's connection pool holds a live timer, so the process
|
|
21
|
+
// stays alive long after the seed has committed:
|
|
22
|
+
//
|
|
23
|
+
// • `pgAdapter` defaults `idleTimeoutMillis: 2000`, so on Postgres the pool
|
|
24
|
+
// goes quiet after ~2s and the script appeared to exit on its own.
|
|
25
|
+
// • `mysqlAdapter` leaves mysql2's defaults in place — `idleTimeout` 60s with
|
|
26
|
+
// `maxIdle` equal to `connectionLimit` — and mysql2's idle-sweep timer is
|
|
27
|
+
// not unref'd, so the script looks frozen even though the work is done.
|
|
28
|
+
//
|
|
29
|
+
// The `.catch` also matters: `run()` called bare surfaces a rejected seed as an
|
|
30
|
+
// unhandled rejection rather than a non-zero exit.
|
|
19
31
|
run()
|
|
32
|
+
.then(() => process.exit(0))
|
|
33
|
+
.catch((err) => {
|
|
34
|
+
console.error(err)
|
|
35
|
+
process.exit(1)
|
|
36
|
+
})
|
|
@@ -48,15 +48,12 @@ export async function seedAdmin() {
|
|
|
48
48
|
)
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
console.log('Seeding super-admin')
|
|
52
|
+
|
|
51
53
|
const result = await seedSuperAdmin(bylineCore.adminStore, { email, password })
|
|
52
54
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (parts.length === 0) {
|
|
58
|
-
console.log(`Super-admin already present (${email}) — no changes.`)
|
|
59
|
-
} else {
|
|
60
|
-
console.log(`Super-admin seed: created ${parts.join(', ')} for ${email}.`)
|
|
61
|
-
}
|
|
55
|
+
const created = result.created.role || result.created.user || result.created.assignment
|
|
56
|
+
console.log(
|
|
57
|
+
created ? ` - seeded super-admin (${email})` : ` - super-admin already present (${email})`
|
|
58
|
+
)
|
|
62
59
|
}
|
|
@@ -459,8 +459,12 @@ async function run(): Promise<void> {
|
|
|
459
459
|
if (failed > 0) process.exit(1)
|
|
460
460
|
}
|
|
461
461
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
process.exit(
|
|
466
|
-
|
|
462
|
+
// Exit explicitly on success too — the adapter's pool holds a live timer, so
|
|
463
|
+
// the process does not terminate on its own. See the note in `seed-admin.ts`.
|
|
464
|
+
run()
|
|
465
|
+
.then(() => process.exit(0))
|
|
466
|
+
.catch((err) => {
|
|
467
|
+
console.error('import-docs: fatal error')
|
|
468
|
+
console.error(err)
|
|
469
|
+
process.exit(1)
|
|
470
|
+
})
|
|
@@ -18,4 +18,13 @@ async function run() {
|
|
|
18
18
|
await seedDocs()
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
// Exit explicitly — the adapter's pool holds a live timer, so the process does
|
|
22
|
+
// not terminate on its own once the seed commits. See the fuller note in
|
|
23
|
+
// `seed-admin.ts`; the short version is that `pgAdapter`'s 2-second idle
|
|
24
|
+
// timeout masked this and mysql2's 60-second, non-unref'd idle sweep does not.
|
|
21
25
|
run()
|
|
26
|
+
.then(() => process.exit(0))
|
|
27
|
+
.catch((err) => {
|
|
28
|
+
console.error(err)
|
|
29
|
+
process.exit(1)
|
|
30
|
+
})
|