@byline/cli 4.9.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.
Files changed (198) hide show
  1. package/README.md +56 -15
  2. package/dist/cli.js +16 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/doctor.d.ts +8 -0
  5. package/dist/commands/doctor.d.ts.map +1 -1
  6. package/dist/commands/doctor.js +8 -5
  7. package/dist/commands/doctor.js.map +1 -1
  8. package/dist/commands/init.d.ts +2 -1
  9. package/dist/commands/init.d.ts.map +1 -1
  10. package/dist/commands/init.js.map +1 -1
  11. package/dist/commands/setup-checks.d.ts +2 -0
  12. package/dist/commands/setup-checks.d.ts.map +1 -1
  13. package/dist/commands/setup-checks.js +14 -6
  14. package/dist/commands/setup-checks.js.map +1 -1
  15. package/dist/commands/setup-flow.test.d.ts +2 -0
  16. package/dist/commands/setup-flow.test.d.ts.map +1 -0
  17. package/dist/commands/setup-flow.test.js +230 -0
  18. package/dist/commands/setup-flow.test.js.map +1 -0
  19. package/dist/commands/setup.d.ts +30 -1
  20. package/dist/commands/setup.d.ts.map +1 -1
  21. package/dist/commands/setup.js +71 -35
  22. package/dist/commands/setup.js.map +1 -1
  23. package/dist/context.d.ts +4 -1
  24. package/dist/context.d.ts.map +1 -1
  25. package/dist/context.js +3 -0
  26. package/dist/context.js.map +1 -1
  27. package/dist/lib/baseline-drift.test.d.ts +2 -0
  28. package/dist/lib/baseline-drift.test.d.ts.map +1 -0
  29. package/dist/lib/baseline-drift.test.js +97 -0
  30. package/dist/lib/baseline-drift.test.js.map +1 -0
  31. package/dist/lib/baseline.d.ts +10 -0
  32. package/dist/lib/baseline.d.ts.map +1 -0
  33. package/dist/lib/baseline.js +12 -0
  34. package/dist/lib/baseline.js.map +1 -0
  35. package/dist/lib/database/adapters.d.ts +54 -0
  36. package/dist/lib/database/adapters.d.ts.map +1 -0
  37. package/dist/lib/database/adapters.js +83 -0
  38. package/dist/lib/database/adapters.js.map +1 -0
  39. package/dist/lib/database/adapters.test.d.ts +2 -0
  40. package/dist/lib/database/adapters.test.d.ts.map +1 -0
  41. package/dist/lib/database/adapters.test.js +36 -0
  42. package/dist/lib/database/adapters.test.js.map +1 -0
  43. package/dist/lib/database/dialect.d.ts +12 -0
  44. package/dist/lib/database/dialect.d.ts.map +1 -0
  45. package/dist/lib/database/dialect.js +53 -0
  46. package/dist/lib/database/dialect.js.map +1 -0
  47. package/dist/lib/database/dialect.test.d.ts +2 -0
  48. package/dist/lib/database/dialect.test.d.ts.map +1 -0
  49. package/dist/lib/database/dialect.test.js +58 -0
  50. package/dist/lib/database/dialect.test.js.map +1 -0
  51. package/dist/lib/database/mysql.d.ts +21 -0
  52. package/dist/lib/database/mysql.d.ts.map +1 -0
  53. package/dist/lib/database/mysql.js +152 -0
  54. package/dist/lib/database/mysql.js.map +1 -0
  55. package/dist/lib/database/mysql.test.d.ts +2 -0
  56. package/dist/lib/database/mysql.test.d.ts.map +1 -0
  57. package/dist/lib/database/mysql.test.js +45 -0
  58. package/dist/lib/database/mysql.test.js.map +1 -0
  59. package/dist/lib/database/postgres.d.ts +8 -0
  60. package/dist/lib/database/postgres.d.ts.map +1 -0
  61. package/dist/lib/database/postgres.js +142 -0
  62. package/dist/lib/database/postgres.js.map +1 -0
  63. package/dist/lib/database/postgres.test.d.ts +2 -0
  64. package/dist/lib/database/postgres.test.d.ts.map +1 -0
  65. package/dist/lib/database/postgres.test.js +14 -0
  66. package/dist/lib/database/postgres.test.js.map +1 -0
  67. package/dist/lib/database/provisioner.d.ts +35 -0
  68. package/dist/lib/database/provisioner.d.ts.map +1 -0
  69. package/dist/lib/database/provisioner.js +20 -0
  70. package/dist/lib/database/provisioner.js.map +1 -0
  71. package/dist/lib/database/provisioner.test.d.ts +2 -0
  72. package/dist/lib/database/provisioner.test.d.ts.map +1 -0
  73. package/dist/lib/database/provisioner.test.js +32 -0
  74. package/dist/lib/database/provisioner.test.js.map +1 -0
  75. package/dist/lib/database/selection.d.ts +11 -0
  76. package/dist/lib/database/selection.d.ts.map +1 -0
  77. package/dist/lib/database/selection.js +52 -0
  78. package/dist/lib/database/selection.js.map +1 -0
  79. package/dist/lib/database/selection.test.d.ts +2 -0
  80. package/dist/lib/database/selection.test.d.ts.map +1 -0
  81. package/dist/lib/database/selection.test.js +58 -0
  82. package/dist/lib/database/selection.test.js.map +1 -0
  83. package/dist/lib/database/state.d.ts +4 -0
  84. package/dist/lib/database/state.d.ts.map +1 -0
  85. package/dist/lib/database/state.js +10 -0
  86. package/dist/lib/database/state.js.map +1 -0
  87. package/dist/lib/database/state.test.d.ts +2 -0
  88. package/dist/lib/database/state.test.d.ts.map +1 -0
  89. package/dist/lib/database/state.test.js +17 -0
  90. package/dist/lib/database/state.test.js.map +1 -0
  91. package/dist/lib/database/urls.d.ts +19 -0
  92. package/dist/lib/database/urls.d.ts.map +1 -0
  93. package/dist/lib/database/urls.js +14 -0
  94. package/dist/lib/database/urls.js.map +1 -0
  95. package/dist/lib/database/urls.test.d.ts +2 -0
  96. package/dist/lib/database/urls.test.d.ts.map +1 -0
  97. package/dist/lib/database/urls.test.js +31 -0
  98. package/dist/lib/database/urls.test.js.map +1 -0
  99. package/dist/lib/dependency-version.d.ts.map +1 -1
  100. package/dist/lib/dependency-version.js +5 -4
  101. package/dist/lib/dependency-version.js.map +1 -1
  102. package/dist/lib/template-hook-boundary.test.node.js +9 -4
  103. package/dist/lib/template-hook-boundary.test.node.js.map +1 -1
  104. package/dist/manifest/deps.d.ts +8 -1
  105. package/dist/manifest/deps.d.ts.map +1 -1
  106. package/dist/manifest/deps.js +40 -13
  107. package/dist/manifest/deps.js.map +1 -1
  108. package/dist/manifest/env.d.ts +4 -1
  109. package/dist/manifest/env.d.ts.map +1 -1
  110. package/dist/manifest/env.js +12 -6
  111. package/dist/manifest/env.js.map +1 -1
  112. package/dist/phases/db-init.d.ts +2 -1
  113. package/dist/phases/db-init.d.ts.map +1 -1
  114. package/dist/phases/db-init.js +141 -124
  115. package/dist/phases/db-init.js.map +1 -1
  116. package/dist/phases/db-init.test.d.ts +2 -0
  117. package/dist/phases/db-init.test.d.ts.map +1 -0
  118. package/dist/phases/db-init.test.js +144 -0
  119. package/dist/phases/db-init.test.js.map +1 -0
  120. package/dist/phases/db.d.ts +0 -8
  121. package/dist/phases/db.d.ts.map +1 -1
  122. package/dist/phases/db.js +69 -49
  123. package/dist/phases/db.js.map +1 -1
  124. package/dist/phases/db.test.d.ts +2 -0
  125. package/dist/phases/db.test.d.ts.map +1 -0
  126. package/dist/phases/db.test.js +69 -0
  127. package/dist/phases/db.test.js.map +1 -0
  128. package/dist/phases/deps.d.ts.map +1 -1
  129. package/dist/phases/deps.js +7 -4
  130. package/dist/phases/deps.js.map +1 -1
  131. package/dist/phases/deps.test.js +67 -5
  132. package/dist/phases/deps.test.js.map +1 -1
  133. package/dist/phases/env.d.ts.map +1 -1
  134. package/dist/phases/env.js +30 -21
  135. package/dist/phases/env.js.map +1 -1
  136. package/dist/phases/env.test.d.ts +2 -0
  137. package/dist/phases/env.test.d.ts.map +1 -0
  138. package/dist/phases/env.test.js +79 -0
  139. package/dist/phases/env.test.js.map +1 -0
  140. package/dist/phases/scaffold-smoke.test.js +44 -10
  141. package/dist/phases/scaffold-smoke.test.js.map +1 -1
  142. package/dist/phases/scaffold.d.ts.map +1 -1
  143. package/dist/phases/scaffold.js +32 -23
  144. package/dist/phases/scaffold.js.map +1 -1
  145. package/dist/phases/scaffold.test.js +22 -0
  146. package/dist/phases/scaffold.test.js.map +1 -1
  147. package/dist/phases/wire/index.d.ts.map +1 -1
  148. package/dist/phases/wire/index.js +5 -0
  149. package/dist/phases/wire/index.js.map +1 -1
  150. package/dist/phases/wire/vite-config-merge.d.ts +61 -0
  151. package/dist/phases/wire/vite-config-merge.d.ts.map +1 -0
  152. package/dist/phases/wire/vite-config-merge.js +319 -0
  153. package/dist/phases/wire/vite-config-merge.js.map +1 -0
  154. package/dist/phases/wire/vite-config-merge.test.d.ts +2 -0
  155. package/dist/phases/wire/vite-config-merge.test.d.ts.map +1 -0
  156. package/dist/phases/wire/vite-config-merge.test.js +134 -0
  157. package/dist/phases/wire/vite-config-merge.test.js.map +1 -0
  158. package/dist/phases/wire/vite-config.d.ts.map +1 -1
  159. package/dist/phases/wire/vite-config.js +68 -10
  160. package/dist/phases/wire/vite-config.js.map +1 -1
  161. package/dist/phases/wire/vite-config.test.js +82 -12
  162. package/dist/phases/wire/vite-config.test.js.map +1 -1
  163. package/dist/state.d.ts +6 -0
  164. package/dist/state.d.ts.map +1 -1
  165. package/dist/state.js +40 -4
  166. package/dist/state.js.map +1 -1
  167. package/dist/state.test.d.ts +2 -0
  168. package/dist/state.test.d.ts.map +1 -0
  169. package/dist/state.test.js +77 -0
  170. package/dist/state.test.js.map +1 -0
  171. package/dist/templates/byline/seed-admin.ts +17 -0
  172. package/dist/templates/byline/seeds/admin.ts +6 -9
  173. package/dist/templates/byline-examples/collections/docs/schema.ts +7 -7
  174. package/dist/templates/byline-examples/collections/media/schema.ts +6 -6
  175. package/dist/templates/byline-examples/collections/news/schema.ts +6 -6
  176. package/dist/templates/byline-examples/collections/news-categories/schema.ts +6 -6
  177. package/dist/templates/byline-examples/collections/pages/schema.ts +6 -6
  178. package/dist/templates/byline-examples/scripts/import-docs.ts +9 -5
  179. package/dist/templates/byline-examples/seed-docs.ts +9 -0
  180. package/dist/templates/dialects/mysql/byline/server.config.ts +105 -0
  181. package/dist/templates/dialects/mysql/byline-examples/server.config.ts +115 -0
  182. package/dist/templates/host/vite.config.ts +4 -3
  183. package/dist/templates/migrations/mysql/0000_unknown_kulan_gath.sql +412 -0
  184. package/dist/templates/migrations/mysql/meta/_journal.json +13 -0
  185. package/dist/test-helpers.d.ts +14 -2
  186. package/dist/test-helpers.d.ts.map +1 -1
  187. package/dist/test-helpers.js +12 -9
  188. package/dist/test-helpers.js.map +1 -1
  189. package/dist/types.d.ts +3 -0
  190. package/dist/types.d.ts.map +1 -1
  191. package/package.json +7 -2
  192. package/dist/templates/migrations/meta/0000_snapshot.json +0 -3471
  193. /package/dist/templates/{byline → dialects/postgres/byline}/server.config.ts +0 -0
  194. /package/dist/templates/{byline-examples → dialects/postgres/byline-examples}/scripts/backfill-version-locales.ts +0 -0
  195. /package/dist/templates/{byline-examples → dialects/postgres/byline-examples}/scripts/re-anchor.ts +0 -0
  196. /package/dist/templates/{byline-examples → dialects/postgres/byline-examples}/server.config.ts +0 -0
  197. /package/dist/templates/migrations/{0000_mushy_luckman.sql → postgres/0000_mushy_luckman.sql} +0 -0
  198. /package/dist/templates/migrations/{meta → postgres/meta}/_journal.json +0 -0
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=vite-config-merge.test.d.ts.map
@@ -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":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,aAAa,CAAA;AAczD,eAAO,MAAM,cAAc,EAAE,OAS5B,CAAA"}
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,10 +1,21 @@
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([
17
+ // Canonical config immediately before MySQL became a scaffold option.
18
+ 'b6ca128489e49f5efd40dd49b30a0adf33c7d9285453087d673e2b6c2a2b3696',
8
19
  // Canonical config with the app-owned client-hook build boundary.
9
20
  'c85b9ed94e70e4d7854e73a71c0021642fcb72353d7af0ace0cb3192b447b94e',
10
21
  // Canonical config immediately before the client-hook build boundary shipped.
@@ -44,8 +55,11 @@ function inspect(ctx) {
44
55
  if (normalize(userText) === normalize(canonical)) {
45
56
  return { status: 'skipped', message: `${REL}: already matches the canonical Byline config` };
46
57
  }
47
- const backupPath = ctx.resolve('vite.config.bak');
48
- if (PREDECESSOR_HASHES.has(hashConfig(userText)) && !existsSync(backupPath)) {
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))) {
49
63
  return {
50
64
  status: 'done',
51
65
  message: `${REL}: recognized canonical predecessor; will back up and replace it`,
@@ -55,16 +69,58 @@ function inspect(ctx) {
55
69
  ],
56
70
  };
57
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.
58
109
  return {
59
- status: 'manual',
60
- message: `${REL}: divergent user config was left untouched; merge the canonical requirements manually`,
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`,
61
114
  snippet: canonical,
62
115
  };
63
116
  }
64
117
  function apply(ctx, plannedWrites) {
65
118
  const path = ctx.resolve(REL);
66
- const backupPath = ctx.resolve('vite.config.bak');
67
- const writes = plannedWrites.filter((write) => write.path === path || write.path === backupPath);
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));
68
124
  if (writes.length === 0) {
69
125
  const current = inspect(ctx);
70
126
  if (!current.writes?.length)
@@ -83,11 +139,13 @@ function apply(ctx, plannedWrites) {
83
139
  snippet: readCanonical(ctx),
84
140
  };
85
141
  }
142
+ const backup = writes.find(isBackup);
143
+ if (!backup) {
144
+ return { status: 'done', message: `${REL}: created canonical Byline config` };
145
+ }
86
146
  return {
87
147
  status: 'done',
88
- message: writes.some((write) => write.path === backupPath)
89
- ? `${REL}: canonical predecessor backed up and replaced`
90
- : `${REL}: created canonical Byline config`,
148
+ message: `${REL}: updated with Byline's required settings (backup: ${basename(backup.path)})`,
91
149
  };
92
150
  }
93
151
  function readCanonical(ctx) {
@@ -1 +1 @@
1
- {"version":3,"file":"vite-config.js","sourceRoot":"","sources":["../../../src/phases/wire/vite-config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vite-config.js","sourceRoot":"","sources":["../../../src/phases/wire/vite-config.ts"],"names":[],"mappings":"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"}