@deltabox/toolchain 1.11.4 → 2.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.
Files changed (222) hide show
  1. package/CHANGELOG.md +308 -4
  2. package/README.md +21 -14
  3. package/dist/_virtual/_rolldown/runtime.js +1 -1
  4. package/dist/changelog.d.ts +7 -6
  5. package/dist/changelog.js +1 -1
  6. package/dist/cli/commands/index.js +1 -1
  7. package/dist/cli/commands/providers.js +1 -1
  8. package/dist/cli/commands/reset.js +1 -1
  9. package/dist/cli/commands/shared.js +1 -1
  10. package/dist/cli/commands/sync.js +1 -1
  11. package/dist/cli/commands/watch.js +1 -1
  12. package/dist/cli/config-selection.d.ts +23 -0
  13. package/dist/cli/config-selection.js +1 -0
  14. package/dist/cli/context.js +1 -1
  15. package/dist/cli/index.d.ts +5 -3
  16. package/dist/cli/index.js +1 -1
  17. package/dist/cli/register.js +1 -1
  18. package/dist/config.d.ts +8 -8
  19. package/dist/config.js +1 -1
  20. package/dist/core.d.ts +7 -6
  21. package/dist/core.js +1 -1
  22. package/dist/globals.d.ts +31 -0
  23. package/dist/globals.js +1 -0
  24. package/dist/index.d.ts +32 -11
  25. package/dist/index.js +1 -1
  26. package/dist/migrate.d.ts +3 -2
  27. package/dist/migrate.js +1 -1
  28. package/dist/package.js +1 -1
  29. package/dist/packages/biome/src/index.d.ts +2 -1
  30. package/dist/packages/biome/src/index.js +1 -1
  31. package/dist/packages/changelog/src/cli/index.js +1 -1
  32. package/dist/packages/changelog/src/index.d.ts +8 -7
  33. package/dist/packages/changelog/src/index.js +1 -1
  34. package/dist/packages/changelog/src/run-workflows.d.ts +19 -4
  35. package/dist/packages/changelog/src/run-workflows.js +1 -1
  36. package/dist/packages/changelog/src/run.d.ts +3 -3
  37. package/dist/packages/changelog/src/run.js +1 -1
  38. package/dist/packages/changelog/src/sync.d.ts +7 -4
  39. package/dist/packages/changelog/src/sync.js +1 -1
  40. package/dist/packages/changelog/src/utils/format.d.ts +2 -1
  41. package/dist/packages/changelog/src/utils/format.js +5 -5
  42. package/dist/packages/changelog/src/utils/git.js +1 -1
  43. package/dist/packages/changelog/src/utils/reformat.d.ts +2 -1
  44. package/dist/packages/changelog/src/utils/reformat.js +3 -3
  45. package/dist/packages/changelog/src/utils/summary.d.ts +25 -2
  46. package/dist/packages/changelog/src/utils/summary.js +3 -1
  47. package/dist/packages/changelog/src/utils/types.d.ts +34 -2
  48. package/dist/packages/changelog/src/utils/version.d.ts +1 -0
  49. package/dist/packages/changelog/src/utils/versioning.d.ts +25 -4
  50. package/dist/packages/changelog/src/utils/versioning.js +1 -1
  51. package/dist/packages/changelog/src/utils/write.js +1 -1
  52. package/dist/packages/changelog/src/workflows.d.ts +27 -7
  53. package/dist/packages/changelog/src/workflows.js +5 -5
  54. package/dist/packages/config/src/cli/index.js +1 -1
  55. package/dist/packages/config/src/collect.d.ts +10 -8
  56. package/dist/packages/config/src/collect.js +1 -1
  57. package/dist/packages/config/src/config-json.d.ts +4 -4
  58. package/dist/packages/config/src/config-json.js +1 -1
  59. package/dist/packages/config/src/engine.d.ts +14 -25
  60. package/dist/packages/config/src/engine.js +1 -1
  61. package/dist/packages/config/src/env-file.d.ts +4 -4
  62. package/dist/packages/config/src/env-file.js +2 -2
  63. package/dist/packages/config/src/env.d.ts +4 -6
  64. package/dist/packages/config/src/env.js +1 -1
  65. package/dist/packages/config/src/generators/cli.d.ts +6 -6
  66. package/dist/packages/config/src/generators/cli.js +1 -1
  67. package/dist/packages/config/src/generators/env.d.ts +9 -9
  68. package/dist/packages/config/src/generators/env.js +2 -2
  69. package/dist/packages/config/src/generators/index.d.ts +4 -4
  70. package/dist/packages/config/src/generators/index.js +1 -1
  71. package/dist/packages/config/src/generators/json.d.ts +5 -7
  72. package/dist/packages/config/src/generators/json.js +1 -1
  73. package/dist/packages/config/src/generators/markdown.d.ts +57 -35
  74. package/dist/packages/config/src/generators/markdown.js +18 -19
  75. package/dist/packages/config/src/generators/types.d.ts +28 -23
  76. package/dist/packages/config/src/generators/types.js +3 -3
  77. package/dist/packages/config/src/index.d.ts +9 -9
  78. package/dist/packages/config/src/index.js +1 -1
  79. package/dist/packages/config/src/schema.d.ts +31 -3
  80. package/dist/packages/config/src/schema.js +1 -1
  81. package/dist/packages/config/src/types.d.ts +134 -28
  82. package/dist/packages/core/src/editor-config.d.ts +14 -0
  83. package/dist/packages/core/src/editor-config.js +1 -0
  84. package/dist/packages/core/src/graph.js +1 -1
  85. package/dist/packages/core/src/index.d.ts +8 -7
  86. package/dist/packages/core/src/index.js +1 -1
  87. package/dist/packages/core/src/loader.d.ts +20 -2
  88. package/dist/packages/core/src/loader.js +1 -1
  89. package/dist/packages/core/src/manifest.d.ts +20 -1
  90. package/dist/packages/core/src/manifest.js +1 -1
  91. package/dist/packages/core/src/provider-registry.d.ts +48 -3
  92. package/dist/packages/core/src/provider-registry.js +1 -1
  93. package/dist/packages/core/src/reset.d.ts +15 -0
  94. package/dist/packages/core/src/reset.js +1 -1
  95. package/dist/packages/core/src/sync.d.ts +10 -0
  96. package/dist/packages/core/src/sync.js +1 -1
  97. package/dist/packages/core/src/watch.d.ts +9 -0
  98. package/dist/packages/core/src/watch.js +1 -1
  99. package/dist/packages/migrate/src/cli/index.js +1 -1
  100. package/dist/packages/migrate/src/index.d.ts +3 -2
  101. package/dist/packages/migrate/src/index.js +1 -1
  102. package/dist/packages/migrate/src/oxc.d.ts +13 -0
  103. package/dist/packages/migrate/src/oxc.js +1 -0
  104. package/dist/packages/migrate/src/registry.js +1 -1
  105. package/dist/packages/migrate/src/vite-target.js +1 -1
  106. package/dist/packages/migrate/src/vite.d.ts +25 -3
  107. package/dist/packages/migrate/src/vite.js +7 -2
  108. package/dist/packages/project/src/catalogs.d.ts +7 -0
  109. package/dist/packages/project/src/catalogs.js +1 -1
  110. package/dist/packages/project/src/cli/index.js +1 -1
  111. package/dist/packages/project/src/config.d.ts +6 -0
  112. package/dist/packages/project/src/config.js +1 -1
  113. package/dist/packages/project/src/index.d.ts +5 -4
  114. package/dist/packages/project/src/index.js +1 -1
  115. package/dist/packages/project/src/sync.js +1 -1
  116. package/dist/packages/project/src/typescript.d.ts +64 -12
  117. package/dist/packages/project/src/typescript.js +12 -7
  118. package/dist/packages/shared/src/changelog-groups.d.ts +59 -0
  119. package/dist/packages/shared/src/config-schema/biome.d.ts +10 -0
  120. package/dist/packages/shared/src/config-schema/biome.js +1 -0
  121. package/dist/packages/shared/src/config-schema/catalogs.d.ts +14 -0
  122. package/dist/packages/shared/src/config-schema/catalogs.js +1 -0
  123. package/dist/packages/shared/src/config-schema/changelog.d.ts +245 -0
  124. package/dist/packages/shared/src/config-schema/changelog.js +1 -0
  125. package/dist/packages/shared/src/config-schema/ci.d.ts +389 -0
  126. package/dist/packages/shared/src/config-schema/ci.js +1 -0
  127. package/dist/packages/shared/src/config-schema/format.d.ts +38 -0
  128. package/dist/packages/shared/src/config-schema/format.js +1 -0
  129. package/dist/packages/shared/src/config-schema/index.d.ts +1648 -0
  130. package/dist/packages/shared/src/config-schema/index.js +1 -0
  131. package/dist/packages/shared/src/config-schema/logger.d.ts +19 -0
  132. package/dist/packages/shared/src/config-schema/logger.js +1 -0
  133. package/dist/packages/shared/src/config-schema/meta.d.ts +16 -0
  134. package/dist/packages/shared/src/config-schema/meta.js +1 -0
  135. package/dist/packages/shared/src/config-schema/project.d.ts +35 -0
  136. package/dist/packages/shared/src/config-schema/project.js +1 -0
  137. package/dist/packages/shared/src/config-schema/providers.d.ts +9 -0
  138. package/dist/packages/shared/src/config-schema/providers.js +1 -0
  139. package/dist/packages/shared/src/config-schema/registry.d.ts +21 -0
  140. package/dist/packages/shared/src/config-schema/registry.js +1 -0
  141. package/dist/packages/shared/src/config-schema/templates.d.ts +81 -0
  142. package/dist/packages/shared/src/config-schema/templates.js +1 -0
  143. package/dist/packages/shared/src/config-schema/tsconfig.d.ts +30 -0
  144. package/dist/packages/shared/src/config-schema/tsconfig.js +1 -0
  145. package/dist/packages/shared/src/config-schema/vite.d.ts +26 -0
  146. package/dist/packages/shared/src/config-schema/vite.js +1 -0
  147. package/dist/packages/shared/src/config-schema/watch.d.ts +11 -0
  148. package/dist/packages/shared/src/config-schema/watch.js +1 -0
  149. package/dist/packages/shared/src/config-schema/workflow.d.ts +590 -0
  150. package/dist/packages/shared/src/config-schema/workflow.js +1 -0
  151. package/dist/packages/shared/src/config-types.d.ts +290 -90
  152. package/dist/packages/shared/src/fs-utils.js +1 -1
  153. package/dist/packages/shared/src/index.d.ts +26 -7
  154. package/dist/packages/shared/src/index.js +1 -1
  155. package/dist/packages/shared/src/logger.d.ts +26 -3
  156. package/dist/packages/shared/src/logger.js +1 -1
  157. package/dist/packages/shared/src/messages.d.ts +36 -0
  158. package/dist/packages/shared/src/messages.js +1 -0
  159. package/dist/packages/shared/src/object-utils.d.ts +5 -0
  160. package/dist/packages/shared/src/object-utils.js +1 -1
  161. package/dist/packages/shared/src/registry-policy.d.ts +17 -0
  162. package/dist/packages/shared/src/registry-policy.js +1 -0
  163. package/dist/packages/shared/src/toolchain.d.ts +90 -11
  164. package/dist/packages/shared/src/toolchain.js +1 -1
  165. package/dist/packages/shared/src/types.d.ts +6 -0
  166. package/dist/packages/shared/src/vite-defaults.d.ts +29 -0
  167. package/dist/packages/shared/src/vite-defaults.js +1 -0
  168. package/dist/packages/template/src/builtin.js +1 -1
  169. package/dist/packages/template/src/cli/index.js +1 -1
  170. package/dist/packages/template/src/global.d.ts +130 -0
  171. package/dist/packages/template/src/global.js +3 -0
  172. package/dist/packages/template/src/index.d.ts +3 -2
  173. package/dist/packages/template/src/index.js +1 -1
  174. package/dist/packages/template/src/online.d.ts +13 -4
  175. package/dist/packages/template/src/online.js +1 -1
  176. package/dist/packages/template/src/registry.d.ts +2 -1
  177. package/dist/packages/template/src/registry.js +1 -1
  178. package/dist/packages/template/src/scaffold.d.ts +5 -1
  179. package/dist/packages/template/src/scaffold.js +1 -1
  180. package/dist/packages/tsconfig/src/cli/generate/index.d.ts +3 -0
  181. package/dist/packages/tsconfig/src/cli/generate/index.js +1 -1
  182. package/dist/packages/tsconfig/src/cli/generate/utils.d.ts +10 -1
  183. package/dist/packages/tsconfig/src/cli/generate/utils.js +1 -1
  184. package/dist/packages/tsconfig/src/cli/index.js +1 -1
  185. package/dist/packages/tsconfig/src/index.d.ts +7 -4
  186. package/dist/packages/tsconfig/src/index.js +1 -1
  187. package/dist/packages/tsconfig/src/overrides.d.ts +74 -0
  188. package/dist/packages/tsconfig/src/overrides.js +1 -0
  189. package/dist/packages/tsconfig/src/resolve.d.ts +62 -0
  190. package/dist/packages/tsconfig/src/resolve.js +3 -0
  191. package/dist/packages/tsconfig/src/snapshots.d.ts +50 -0
  192. package/dist/packages/tsconfig/src/snapshots.js +1 -0
  193. package/dist/packages/tsconfig/src/sync.d.ts +14 -5
  194. package/dist/packages/tsconfig/src/sync.js +1 -1
  195. package/dist/packages/tsconfig/src/templates/tsconfig.default.js +1 -1
  196. package/dist/packages/tsconfig/src/templates.d.ts +12 -4
  197. package/dist/packages/tsconfig/src/templates.js +1 -1
  198. package/dist/packages/vite/src/index.d.ts +2 -2
  199. package/dist/packages/vite/src/index.js +1 -1
  200. package/dist/packages/vite/src/resolve.d.ts +13 -3
  201. package/dist/packages/vite/src/resolve.js +1 -1
  202. package/dist/packages/vite/src/sync.d.ts +46 -5
  203. package/dist/packages/vite/src/sync.js +5 -2
  204. package/dist/project.d.ts +4 -3
  205. package/dist/project.js +1 -1
  206. package/dist/providers.d.ts +11 -4
  207. package/dist/providers.js +1 -1
  208. package/dist/shared.d.ts +25 -6
  209. package/dist/shared.js +1 -1
  210. package/dist/sync.js +1 -1
  211. package/dist/template.d.ts +3 -2
  212. package/dist/template.js +1 -1
  213. package/dist/tooling.d.ts +21 -0
  214. package/dist/tooling.js +1 -0
  215. package/dist/tsconfig.d.ts +6 -3
  216. package/dist/tsconfig.js +1 -1
  217. package/dist/vite.d.ts +2 -2
  218. package/dist/vite.js +1 -1
  219. package/package.json +28 -23
  220. package/dist/packages/config/src/types.js +0 -1
  221. package/dist/packages/shared/src/config-schema.d.ts +0 -3928
  222. package/dist/packages/shared/src/config-schema.js +0 -1
@@ -1 +1 @@
1
- import{default as e}from"node:path";import{pathToFileURL as t}from"node:url";import.meta.url;import{deepMerge as n}from"../../shared/src/object-utils.js";import{readJsonAt as r}from"../../shared/src/fs-utils.js";import{projectFromPackageJson as i}from"../../shared/src/project.js";import{CONFIG_FILE_NAMES as a,resolveTokens as o}from"../../shared/src/toolchain.js";import"../../shared/src/index.js";import{resolveProjectType as s}from"./project-type.js";import c from"node:fs";function l(e){return e instanceof Error?e.message:String(e)}function u(t=process.cwd()){for(let n of a){let r=e.resolve(t,n);if(c.existsSync(r))return r}}function d(t=process.cwd()){let n=e.resolve(t);if(c.existsSync(e.join(n,`.git`)))return;let r=e.dirname(n);for(;;){let t=u(r);if(t)return t;if(c.existsSync(e.join(r,`.git`)))return;let n=e.dirname(r);if(n===r)return;r=n}}function f(e){let t=e?.code;return t===`ERR_UNKNOWN_FILE_EXTENSION`||t===`ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX`}function p(e){let t=e;for(let e=0;e<2&&t&&typeof t==`object`&&`default`in t&&Object.keys(t).every(e=>e==="default"||e==="__esModule");e++)t=t.default;return t}async function m(e){if(e.endsWith(`.json`))return JSON.parse(c.readFileSync(e,`utf-8`).replace(/^\uFEFF/,``));let n=t(e).href;try{let e=await import(n);return e.default??e}catch(e){if(!f(e))throw e;let{tsImport:t}=await import(`tsx/esm/api`);return p(await t(n,import.meta.url))}}async function h(e){let t=await m(e),n=t&&typeof t==`object`?t.toolchain:void 0;return n&&typeof n==`object`?n:{}}const g=/* @__PURE__ */ new Set([`name`,`scope`,`description`,`type`]);function _(e,t){let{hooks:r,project:i,...a}=e,o=a;if(t.project?.inherit!==!1&&i){let e=Object.fromEntries(Object.entries(i).filter(([e])=>!g.has(e)));Object.keys(e).length>0&&(o={...a,project:e})}return n(o,t)}async function v(e=process.cwd(),t={}){let n=u(e),a=d(e),c=t.tolerant??!1,f={},p;if(a)try{f=await h(a)}catch(e){if(!c)throw e;p=`failed to load ${a}: ${l(e)}`}if(n)try{let e=await h(n);f=a&&!p?_(f,e):e}catch(e){if(!c)throw e;p=`failed to load ${n}: ${l(e)}`}let m=r(e,`package.json`),g={...m?i(m):void 0,...f.project??void 0},v=o({...f,project:g});return await f.hooks?.afterLoad?.({cwd:e,config:f,tokens:v,...n?{path:n}:{}}),{config:f,...n?{path:n}:{},...a?{parentPath:a}:{},...p?{error:p}:{},tokens:v,projectType:s(e,f)}}export{u as findConfigFile,d as findParentConfigFile,v as loadToolchainConfig,_ as mergeToolchainConfig};
1
+ import{default as e}from"node:path";import{pathToFileURL as t}from"node:url";import.meta.url;import{deepMerge as n,isPlainObject as r}from"../../shared/src/object-utils.js";import{readJsonAt as i}from"../../shared/src/fs-utils.js";import{projectFromPackageJson as a}from"../../shared/src/project.js";import{CONFIG_FILE_NAMES as o,resolveTokens as s}from"../../shared/src/toolchain.js";import"../../shared/src/index.js";import{resolveProjectType as c}from"./project-type.js";import{createRequire as l}from"node:module";import u from"node:fs";function d(e){return e instanceof Error?e.message:String(e)}function f(t=process.cwd()){for(let n of o){let r=e.resolve(t,n);if(u.existsSync(r))return r}}function p(t=process.cwd()){let n=e.resolve(t);if(u.existsSync(e.join(n,`.git`)))return;let r=e.dirname(n);for(;;){let t=f(r);if(t)return t;if(u.existsSync(e.join(r,`.git`)))return;let n=e.dirname(r);if(n===r)return;r=n}}function m(e){let t=e?.code;return t===`ERR_UNKNOWN_FILE_EXTENSION`||t===`ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX`}function h(e){let t=e;for(let e=0;e<2&&t&&typeof t==`object`&&`default`in t&&Object.keys(t).every(e=>e==="default"||e==="__esModule");e++)t=t.default;return t}const g=l(import.meta.url);let _=0;async function v(e,n=!1){if(e.endsWith(`.json`))return JSON.parse(u.readFileSync(e,`utf-8`).replace(/^\uFEFF/,``));if(n)try{delete g.cache[e]}catch{}let r=t(e).href,i=n?`${r}?dbx=${Date.now()}-${++_}`:r;try{let e=await import(i);return e.default??e}catch(e){if(!m(e))throw e;let{tsImport:t}=await import(`tsx/esm/api`);return h(await t(i,import.meta.url))}}async function y(e,t=!1){let n=await b(await v(e,t)),r=n&&typeof n==`object`?n.toolchain:void 0;return r&&typeof r==`object`?r:{}}async function b(e){let t=await e;return typeof t==`function`&&(t=await t()),t}const x=/* @__PURE__ */ new Set([`name`,`scope`,`description`,`type`]),S=/* @__PURE__ */ new Set([`test`,`run`]);function C(e){if(!r(e))return e;let t=Object.fromEntries(Object.entries(e).filter(([e])=>!S.has(e)));return Object.keys(t).length>0?t:void 0}function w(e,t){let{hooks:r,project:i,ci:a,changelog:o,catalogs:s,tsconfig:c,vite:l,...u}=e,d=u,f=C(l);if(f!==void 0&&(d={...d,vite:f}),t.project?.inherit!==!1&&i){let e=Object.fromEntries(Object.entries(i).filter(([e])=>!x.has(e)));Object.keys(e).length>0&&(d={...d,project:e})}return n(d,t)}async function T(t=process.cwd(),n={}){let r=n.noConfig?void 0:n.config?e.isAbsolute(n.config)?n.config:e.resolve(t,n.config):f(t),o=n.noConfig?void 0:p(t),l=n.tolerant??!1,u=n.fresh??!1,m={},h={},g,_;if(o)try{g=await y(o,u),m=g}catch(e){if(!l)throw e;_=`failed to load ${o}: ${d(e)}`}if(r)try{let e=await y(r,u);h=e,m=o&&!_?w(m,e):e}catch(e){if(!l)throw e;_=`failed to load ${r}: ${d(e)}`}let v=i(t,`package.json`),b={...v?a(v):void 0,...m.project??void 0},x=s({...m,project:b});n.skipHooks||await m.hooks?.afterLoad?.({cwd:t,config:m,tokens:x,...r?{path:r}:{}});let S=m.tsconfig===void 0&&g?.tsconfig!==void 0?{...m,tsconfig:g.tsconfig}:m;return{config:m,ownConfig:h,...r?{path:r}:{},...o?{parentPath:o}:{},..._?{error:_}:{},tokens:x,projectType:c(t,S)}}export{f as findConfigFile,p as findParentConfigFile,T as loadToolchainConfig,w as mergeToolchainConfig};
@@ -9,15 +9,34 @@ export declare const MANIFEST_FILE = "manifest.json";
9
9
  * dirties the committed `manifest.json`, which tracks only the file list.
10
10
  */
11
11
  export declare const TIMESTAMPS_FILE = "timestamps.json";
12
+ /** Whether dbx created a managed file or adopted a pre-existing one. */
13
+ export type FileOrigin = 'created' | 'adopted';
12
14
  export interface Manifest {
13
15
  /** Repo-relative paths of every generated/managed file. */
14
16
  files: string[];
17
+ /** Per-file origin, so a sync only deletes files that dbx created. */
18
+ origins?: Record<string, FileOrigin>;
15
19
  /**
16
20
  * ISO timestamp of the last successful sync (absent when never synced).
17
21
  * Read from {@link TIMESTAMPS_FILE}, falling back to a legacy inline
18
22
  * `syncedAt` in the manifest until the next sync migrates it.
19
23
  */
20
24
  syncedAt?: string;
25
+ /**
26
+ * The `tsconfig.overrides` currently applied, keyed by the repo-relative
27
+ * target file (`{ kind, override }`), so a removed override can be reverted.
28
+ */
29
+ tsconfigOverrides?: Record<string, unknown>;
30
+ /**
31
+ * The original (pre-override) tsconfig contents, nested by repo-relative
32
+ * path (`{ packages: { core: { "tsconfig.build.json": { ... } } } }`).
33
+ */
34
+ snapshots?: Record<string, unknown>;
35
+ /**
36
+ * Task-defined metadata persisted across syncs (everything a task writes to
37
+ * `SyncContext.manifest` that is not one of the reserved keys).
38
+ */
39
+ extras?: Record<string, unknown>;
21
40
  }
22
41
  /**
23
42
  * The last-sync timestamp for a project: {@link TIMESTAMPS_FILE} first, then a
@@ -32,5 +51,5 @@ export declare function readManifest(cwd: string): Manifest;
32
51
  * creating the directory as needed. Rewriting `manifest.json` without
33
52
  * `syncedAt` is what migrates a legacy inline timestamp on the next sync.
34
53
  */
35
- export declare function writeManifest(cwd: string, files: string[], syncedAt?: string): void;
54
+ export declare function writeManifest(cwd: string, files: string[], syncedAt?: string, origins?: Record<string, FileOrigin>, extras?: Record<string, unknown>): void;
36
55
  //#endregion
@@ -1 +1 @@
1
- import{default as e}from"node:path";import"node:url";import.meta.url;import{toJson as t}from"../../shared/src/fs-utils.js";import"../../shared/src/index.js";import n from"node:fs";const r=`.dbx/toolchain`,i=`manifest.json`,a=`timestamps.json`;function o(t){return e.resolve(t,r)}function s(t,r){try{return JSON.parse(n.readFileSync(e.join(o(t),r),`utf-8`))}catch{return}}function c(e){let t=s(e,a);if(typeof t?.syncedAt==`string`)return t.syncedAt;let n=s(e,i);return typeof n?.syncedAt==`string`?n.syncedAt:void 0}function l(e){let t=s(e,i),n=c(e);return{files:Array.isArray(t?.files)?t.files:[],...n?{syncedAt:n}:{}}}function u(r,s,c){let l=o(r);n.mkdirSync(l,{recursive:!0}),n.writeFileSync(e.join(l,i),t({files:[...new Set(s)].sort()}),`utf-8`),n.writeFileSync(e.join(l,a),t({syncedAt:c??(/* @__PURE__ */ new Date()).toISOString()}),`utf-8`)}export{r as MANIFEST_DIR,i as MANIFEST_FILE,a as TIMESTAMPS_FILE,l as readManifest,c as readSyncedAt,u as writeManifest};
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{toJson as t}from"../../shared/src/fs-utils.js";import"../../shared/src/index.js";import n from"node:fs";const r=`.dbx/toolchain`,i=`manifest.json`,a=`timestamps.json`;function o(t){return e.resolve(t,r)}function s(t,r){try{return JSON.parse(n.readFileSync(e.join(o(t),r),`utf-8`).replace(/^\uFEFF/,``))}catch{return}}function c(e){let t=s(e,a);if(typeof t?.syncedAt==`string`)return t.syncedAt;let n=s(e,i);return typeof n?.syncedAt==`string`?n.syncedAt:void 0}function l(e){let t=s(e,i),n=c(e),r=t?.origins&&typeof t.origins==`object`?t.origins:void 0,a=t?.tsconfigOverrides&&typeof t.tsconfigOverrides==`object`?t.tsconfigOverrides:void 0,o=t?.snapshots&&typeof t.snapshots==`object`?t.snapshots:void 0,l=/* @__PURE__ */ new Set([`files`,`origins`,`syncedAt`,`tsconfigOverrides`,`snapshots`]),u=Object.fromEntries(Object.entries(t??{}).filter(([e])=>!l.has(e)));return{files:Array.isArray(t?.files)?t.files:[],...r?{origins:r}:{},...a?{tsconfigOverrides:a}:{},...o?{snapshots:o}:{},...Object.keys(u).length>0?{extras:u}:{},...n?{syncedAt:n}:{}}}function u(r,s,c,l,u){let d=o(r);n.mkdirSync(d,{recursive:!0});let f=[...new Set(s)].sort();n.writeFileSync(e.join(d,i),t({...u,files:f,...l?{origins:Object.fromEntries(f.filter(e=>l[e]!==void 0).map(e=>[e,l[e]]))}:{}}),`utf-8`),n.writeFileSync(e.join(d,a),t({syncedAt:c??(/* @__PURE__ */ new Date()).toISOString()}),`utf-8`)}export{r as MANIFEST_DIR,i as MANIFEST_FILE,a as TIMESTAMPS_FILE,l as readManifest,c as readSyncedAt,u as writeManifest};
@@ -1,12 +1,57 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
3
  import { ToolchainProvider } from "../../shared/src/provider.js";
4
+ import { RegistryPolicy } from "../../shared/src/registry-policy.js";
4
5
  import "../../shared/src/index.js";
5
6
  //#region packages/core/src/provider-registry.d.ts
6
- /** The absolute path of a project's provider registry file. */
7
+ /** The absolute path of the legacy project provider file. */
8
+ export declare function legacyProviderRegistryPath(cwd?: string): string;
9
+ /** The default project provider registry file. */
7
10
  export declare function providerRegistryPath(cwd?: string): string;
8
- /** Read a project's custom providers (empty when the registry is absent/invalid). */
11
+ /** The `~/.dbx/toolchain/.registry/providers` default global directory. */
12
+ export declare function defaultGlobalProvidersDir(): string;
13
+ /** The legacy global provider file. */
14
+ export declare function globalProviderRegistryPath(): string;
15
+ /** Add a project-scoped provider registry path (or remote URL). */
16
+ export declare function addProjectProviderRegistry(cwd: string, entry: string): void;
17
+ /** Remove a project-scoped provider registry path (never the implicit default). */
18
+ export declare function removeProjectProviderRegistry(cwd: string, entry: string): void;
19
+ /** Add a global provider registry path (or remote URL). */
20
+ export declare function addGlobalProviderRegistry(entry: string): void;
21
+ /** Remove a global provider registry path. */
22
+ export declare function removeGlobalProviderRegistry(entry: string): void;
23
+ /** Replace the global provider search paths. */
24
+ export declare function setGlobalProviderRegistries(paths: string[]): void;
25
+ /** Replace the project-scoped provider search paths. */
26
+ export declare function setProjectProviderRegistries(cwd: string, paths: string[]): void;
27
+ export interface ProviderRegistryPath {
28
+ path: string;
29
+ scope: 'project' | 'global';
30
+ remote: boolean;
31
+ }
32
+ /**
33
+ * Every provider registry path, project first (implicit dir + project entries +
34
+ * the legacy project file), then global (CLI config paths or the default dir,
35
+ * plus the legacy global file). Duplicates are removed.
36
+ */
37
+ export declare function providerRegistryPaths(cwd?: string, policy?: RegistryPolicy): ProviderRegistryPath[];
38
+ /** Read a project's custom providers from its provider search paths. */
9
39
  export declare function readProviderRegistry(cwd?: string): ToolchainProvider[];
10
- /** Write a project's custom providers (removing the file when the list is empty). */
40
+ /** Write a project's custom providers to the default project registry file. */
11
41
  export declare function writeProviderRegistry(cwd: string, providers: ToolchainProvider[]): void;
42
+ /** Read the global providers from the global search paths. */
43
+ export declare function readGlobalProviders(): ToolchainProvider[];
44
+ /** Write the global providers to the default global providers file. */
45
+ export declare function writeGlobalProviders(providers: ToolchainProvider[]): void;
46
+ /**
47
+ * The project + global providers from local registries, deduped by id (a
48
+ * project provider wins). Remote registries are skipped; use
49
+ * {@link readAllProviders} for those.
50
+ */
51
+ export declare function readAllProvidersSync(cwd?: string, policy?: RegistryPolicy): ToolchainProvider[];
52
+ /**
53
+ * The project + global providers from every search path, including remote
54
+ * registries, deduped by id (a project provider wins).
55
+ */
56
+ export declare function readAllProviders(cwd?: string, policy?: RegistryPolicy): Promise<ToolchainProvider[]>;
12
57
  //#endregion
@@ -1 +1 @@
1
- import{default as e}from"node:path";import"node:url";import.meta.url;import t from"node:fs";const n=e.join(`.dbx`,`toolchain`);function r(t=process.cwd()){return e.join(t,n,`providers.json`)}function i(e=process.cwd()){try{let n=JSON.parse(t.readFileSync(r(e),`utf-8`));return Array.isArray(n)?n:[]}catch{return[]}}function a(n,i){let a=r(n);i.length===0?t.rmSync(a,{force:!0}):(t.mkdirSync(e.dirname(a),{recursive:!0}),t.writeFileSync(a,`${JSON.stringify(i,null,4)}\n`,`utf-8`))}export{r as providerRegistryPath,i as readProviderRegistry,a as writeProviderRegistry};
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{registrySourceAllowed as t}from"../../shared/src/registry-policy.js";import"../../shared/src/index.js";import n from"node:fs";import r from"node:os";const i=e.join(`.dbx`,`toolchain`),a=`providers.json`;function o(t){return t===`~`?r.homedir():t.startsWith(`~/`)||t.startsWith(`~\\`)?e.join(r.homedir(),t.slice(2)):t}function s(e){return/^https?:\/\//i.test(e)}function c(e){return e?(Array.isArray(e)?e:[e]).map(e=>o(String(e))).filter(Boolean):[]}function l(t=process.cwd()){return e.join(t,i,`providers.json`)}function u(t=process.cwd()){return e.join(t,i,`.registry`,`providers`,a)}function d(){return e.join(r.homedir(),`.dbx`,`toolchain`,`.registry`,`providers`)}function f(){return e.join(r.homedir(),`.dbx`,`toolchain`,`.registry`,a)}function p(){return e.join(r.homedir(),`.dbx`,`toolchain`,`cli`,`config.json`)}function m(){try{let e=n.readFileSync(p(),`utf-8`).replace(/^\uFEFF/,``),t=JSON.parse(e);return t&&typeof t==`object`?t:{}}catch{return{}}}function h(e=m()){if(e.providerRegistrySearchPaths!==void 0)return c(e.providerRegistrySearchPaths);let t=e.registrySearchPaths;return t&&typeof t==`object`&&!Array.isArray(t)?c(t.providers):[]}function g(t){return e.join(t,i,`registries.json`)}function _(e){try{let t=n.readFileSync(g(e),`utf-8`).replace(/^\uFEFF/,``),r=JSON.parse(t);return{templates:c(r.templates),providers:c(r.providers)}}catch{return{}}}function v(t,r){let i=g(t),a={...r.templates&&r.templates.length>0?{templates:r.templates}:{},...r.providers&&r.providers.length>0?{providers:r.providers}:{}};Object.keys(a).length===0?n.rmSync(i,{force:!0}):(n.mkdirSync(e.dirname(i),{recursive:!0}),n.writeFileSync(i,`${JSON.stringify(a,null,4)}\n`,`utf-8`))}function y(t){let r={...m(),...t},i=p();return n.mkdirSync(e.dirname(i),{recursive:!0}),n.writeFileSync(i,`${JSON.stringify(r,null,4)}\n`,`utf-8`),r}function b(t,n,r){let i=n=>s(n)?n:e.resolve(t,o(n));return i(n)===i(r)}function x(e,t){let n=_(e),r=n.providers??[];r.some(n=>b(e,n,t))||v(e,{...n.templates?{templates:n.templates}:{},providers:[...r,t]})}function S(e,t){let n=_(e);v(e,{...n.templates?{templates:n.templates}:{},...n.providers?{providers:n.providers.filter(n=>!b(e,n,t))}:{}})}function C(e){let t=h(m()),n=o(e);t.some(e=>b(process.cwd(),e,n))||y({providerRegistrySearchPaths:[...t,n]})}function w(e){let t=m(),n=o(e);y({providerRegistrySearchPaths:h(t).filter(e=>!b(process.cwd(),e,n))})}function T(e){y({providerRegistrySearchPaths:e.map(o)})}function E(e,t){let n=_(e);v(e,{...n.templates?{templates:n.templates}:{},providers:t})}function D(t){return(_(t).providers??[]).map(n=>s(n)?n:e.resolve(t,n))}function O(r=process.cwd(),a){let o=m(),c=[],u=e.join(r,i,`.registry`,`providers`);n.existsSync(u)&&c.push(u),c.push(...D(r)),n.existsSync(l(r))&&c.push(l(r));let p=[...h(o)],g=d();n.existsSync(g)&&p.push(g),n.existsSync(f())&&p.push(f());let _=/* @__PURE__ */ new Set,v=[];for(let[n,r]of[[`project`,c],[`global`,p]])for(let i of r){let r=s(i)?i:e.resolve(i);_.has(r)||t(r,a)&&(_.add(r),v.push({path:i,scope:n,remote:s(i)}))}return v}function k(e){return!!e&&typeof e==`object`&&typeof e.id==`string`&&typeof e.name==`string`&&Array.isArray(e.commands)}function A(e){return(Array.isArray(e)?e:e&&typeof e==`object`&&Array.isArray(e.providers)?e.providers:[]).filter(k)}function j(t){try{if(n.statSync(t).isDirectory()){let r=[];for(let i of n.readdirSync(t))i.toLowerCase().endsWith(`.json`)&&r.push(...j(e.join(t,i)));return r}return A(JSON.parse(n.readFileSync(t,`utf-8`)))}catch{return[]}}function M(t,r){r.length===0?n.rmSync(t,{force:!0}):(n.mkdirSync(e.dirname(t),{recursive:!0}),n.writeFileSync(t,`${JSON.stringify(r,null,4)}\n`,`utf-8`))}function N(e=process.cwd()){let t=/* @__PURE__ */ new Set,n=[];for(let r of O(e))if(!(r.scope!==`project`||r.remote))for(let e of j(r.path))t.has(e.id)||(t.add(e.id),n.push(e));return n}function P(e,t){M(u(e),t)}function F(){let e=/* @__PURE__ */ new Set,t=[];for(let n of O())if(!(n.scope!==`global`||n.remote))for(let r of j(n.path))e.has(r.id)||(e.add(r.id),t.push(r));return t}function I(t){M(e.join(d(),a),t)}function L(e){let t=/* @__PURE__ */ new Set,n=[];for(let r of e)t.has(r.id)||(t.add(r.id),n.push(r));return n}function R(e=process.cwd(),t){let n=O(e,t),r=n.filter(e=>e.scope===`project`&&!e.remote),i=n.filter(e=>e.scope===`global`&&!e.remote);return L([...r.flatMap(e=>j(e.path)),...i.flatMap(e=>j(e.path))])}async function z(e){try{let t=await fetch(e,{headers:{accept:`application/json`}});return t.ok?A(await t.json()):[]}catch{return[]}}async function B(e=process.cwd(),t){let n=O(e,t),r=[];for(let e of n)e.remote?r.push(...await z(e.path)):r.push(...j(e.path));return L(r)}export{C as addGlobalProviderRegistry,x as addProjectProviderRegistry,d as defaultGlobalProvidersDir,f as globalProviderRegistryPath,l as legacyProviderRegistryPath,u as providerRegistryPath,O as providerRegistryPaths,B as readAllProviders,R as readAllProvidersSync,F as readGlobalProviders,N as readProviderRegistry,w as removeGlobalProviderRegistry,S as removeProjectProviderRegistry,T as setGlobalProviderRegistries,E as setProjectProviderRegistries,I as writeGlobalProviders,P as writeProviderRegistry};
@@ -11,15 +11,27 @@ export interface ResetSelectors {
11
11
  /** Remove the `dbx.config.*` file(s). */
12
12
  config?: boolean;
13
13
  }
14
+ /**
15
+ * Undo the state a sync applied to user-owned files before the manifest that
16
+ * records it is removed (eg. `tsconfig.overrides`). Returns the repo-relative
17
+ * files it restored (or would restore on a dry run).
18
+ */
19
+ export type ResetRestore = (cwd: string, options: {
20
+ dryRun: boolean;
21
+ }) => string[];
14
22
  export interface ResetToolchainOptions extends ResetSelectors {
15
23
  /** The project directory to reset. */
16
24
  cwd: string;
17
25
  /** Report what would be removed without deleting anything. */
18
26
  dryRun?: boolean;
27
+ /** Run before the manifest is removed, while its recorded state still exists. */
28
+ restore?: ResetRestore;
19
29
  }
20
30
  export interface ResetToolchainResult {
21
31
  /** Repo-relative paths removed (or that would be removed). */
22
32
  removed: string[];
33
+ /** User-owned files restored before the manifest was removed. */
34
+ restored: string[];
23
35
  /** Whether this was a dry run. */
24
36
  dryRun: boolean;
25
37
  }
@@ -34,12 +46,15 @@ export interface ResetProjectsOptions extends ResetSelectors, Omit<SelectProject
34
46
  /** Apply to every discovered project under `root` (not just `root`). */
35
47
  recursive?: boolean;
36
48
  dryRun?: boolean;
49
+ /** Run per project before its manifest is removed (see {@link ResetRestore}). */
50
+ restore?: ResetRestore;
37
51
  }
38
52
  export interface ResetProjectsResult {
39
53
  results: {
40
54
  dir: string;
41
55
  rel: string;
42
56
  removed: string[];
57
+ restored: string[];
43
58
  }[];
44
59
  dryRun: boolean;
45
60
  }
@@ -1 +1 @@
1
- import{default as e}from"node:path";import"node:url";import.meta.url;import{findConfigFile as t}from"./loader.js";import{MANIFEST_DIR as n,readManifest as r}from"./manifest.js";import{selectProjects as i}from"./select.js";import a from"node:fs";function o(e){return e.replace(/\\/g,`/`)}function s(e){let t=e.generated!==void 0||e.manifest!==void 0||e.config!==void 0;return{generated:e.generated??!t,manifest:e.manifest??!t,config:e.config??!1}}function c(i){let{cwd:c}=i,l=i.dryRun??!1,u=s(i),d=[],f=(e,t)=>{a.existsSync(e)&&(l||a.rmSync(e,{force:!0}),d.push(t))};if(u.generated)for(let t of r(c).files)f(e.resolve(c,t),t);if(u.config){let n=t(c);n&&f(n,o(e.relative(c,n)))}if(u.manifest){let t=e.resolve(c,n);a.existsSync(t)&&(l||a.rmSync(t,{recursive:!0,force:!0}),d.push(`${n}/`))}return{removed:d,dryRun:l}}function l(e){let n=e.dryRun??!1;return{results:(e.recursive?i({root:e.root,...e.include?{include:e.include}:{},...e.exclude?{exclude:e.exclude}:{},...e.maxDepth===void 0?{}:{maxDepth:e.maxDepth}}):[{dir:e.root,rel:`.`,hasConfig:!!t(e.root)}]).map(t=>({dir:t.dir,rel:t.rel,removed:c({cwd:t.dir,...e.generated===void 0?{}:{generated:e.generated},...e.manifest===void 0?{}:{manifest:e.manifest},...e.config===void 0?{}:{config:e.config},dryRun:n}).removed})),dryRun:n}}export{l as resetProjects,c as resetToolchain};
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{findConfigFile as t}from"./loader.js";import{MANIFEST_DIR as n,readManifest as r}from"./manifest.js";import{selectProjects as i}from"./select.js";import a from"node:fs";function o(e){return e.replace(/\\/g,`/`)}function s(e){let t=e.generated!==void 0||e.manifest!==void 0||e.config!==void 0;return{generated:e.generated??!t,manifest:e.manifest??!t,config:e.config??!1}}function c(i){let{cwd:c}=i,l=i.dryRun??!1,u=s(i),d=[],f=(e,t)=>{a.existsSync(e)&&(l||a.rmSync(e,{force:!0}),d.push(t))};if(u.generated){let t=r(c);for(let n of t.files)t.origins?.[n]!==`adopted`&&f(e.resolve(c,n),n)}if(u.config){let n=t(c);n&&f(n,o(e.relative(c,n)))}let p=[];if(u.manifest&&i.restore&&p.push(...i.restore(c,{dryRun:l})),u.manifest){let t=e.resolve(c,n);a.existsSync(t)&&(l||a.rmSync(t,{recursive:!0,force:!0}),d.push(`${n}/`))}return{removed:d,restored:p,dryRun:l}}function l(e){let n=e.dryRun??!1;return{results:(e.recursive?i({root:e.root,...e.include?{include:e.include}:{},...e.exclude?{exclude:e.exclude}:{},...e.maxDepth===void 0?{}:{maxDepth:e.maxDepth}}):[{dir:e.root,rel:`.`,hasConfig:!!t(e.root)}]).map(t=>{let{removed:r,restored:i}=c({cwd:t.dir,...e.generated===void 0?{}:{generated:e.generated},...e.manifest===void 0?{}:{manifest:e.manifest},...e.config===void 0?{}:{config:e.config},...e.restore?{restore:e.restore}:{},dryRun:n});return{dir:t.dir,rel:t.rel,removed:r,restored:i}}),dryRun:n}}export{l as resetProjects,c as resetToolchain};
@@ -12,6 +12,8 @@ export interface RunSyncOptions {
12
12
  cwd: string;
13
13
  /** The loaded config. */
14
14
  config: ToolchainConfig;
15
+ /** The project's own (unmerged) config, when known. */
16
+ ownConfig?: ToolchainConfig;
15
17
  /** The resolved replacement tokens. */
16
18
  tokens: Replacements;
17
19
  /** The project kind (resolved from the config/cwd when omitted). */
@@ -23,6 +25,12 @@ export interface RunSyncOptions {
23
25
  /** Custom logger (default `logger.info`). */
24
26
  log?: (message: string) => void;
25
27
  }
28
+ export interface RemovedFile {
29
+ /** Repo-relative path. */
30
+ path: string;
31
+ /** The content before removal, so an editor can offer "Restore". */
32
+ content: string;
33
+ }
26
34
  export interface SyncResult {
27
35
  /** Paths written (empty in check mode). */
28
36
  written: string[];
@@ -30,6 +38,8 @@ export interface SyncResult {
30
38
  changed: string[];
31
39
  /** Previously-managed paths removed because they are no longer generated. */
32
40
  removed: string[];
41
+ /** The removed files' previous content (for a Restore action). */
42
+ removedFiles: RemovedFile[];
33
43
  /** Whether disk already matched the generated output. */
34
44
  upToDate: boolean;
35
45
  }
@@ -1 +1 @@
1
- import{default as e}from"node:path";import"node:url";import.meta.url;import{logger as t}from"../../shared/src/logger.js";import"../../shared/src/index.js";import{ensureDbxGitignore as n}from"./gitignore.js";import{resolveProjectType as r}from"./project-type.js";import{readManifest as i,writeManifest as a}from"./manifest.js";import o from"node:fs";function s(e){return e.replace(/\\/g,`/`)}async function c(c){let{tasks:l,cwd:u,config:d,tokens:f}=c,p=c.quiet?()=>{}:c.log??(e=>t.info(e)),m=c.quiet?()=>{}:e=>t.warn(e),h=c.projectType??r(u,d),g={cwd:u,projectType:h,config:d,tokens:f,log:p,warn:m},_=d.hooks??{};await _.beforeSync?.(g);let v=l.filter(e=>(!e.projectTypes||e.projectTypes.includes(h))&&(!e.enabled||e.enabled(d)));p(`running ${v.length} task(s)${c.check?` (check)`:``} [${h}]`);let y=[];for(let e of v){p(` - ${e.name}`),await _.beforeTask?.({task:e,ctx:g});let t=await e.run(g),n=Array.isArray(t)?t:void 0;n&&y.push(...n),await _.afterTask?.({task:e,ctx:g,...n?{files:n}:{}})}let b=new Map(y.map(e=>[s(e.path),e.content])),x=i(u),S=/* @__PURE__ */ new Set;for(let e of v)for(let t of e.keep??[])S.add(t);let C=e=>{for(let t of S)if(e===t||e.endsWith(`/${t}`)||e.endsWith(t))return!0;return!1},w=[];for(let[t,n]of b){let r=e.resolve(u,t);(o.existsSync(r)?o.readFileSync(r,`utf-8`):void 0)!==n&&w.push(t)}let T=x.files.filter(t=>!b.has(t)&&!C(t)&&o.existsSync(e.resolve(u,t))),E=w.length===0&&T.length===0;if(c.check){if(E)p(`generated files are in sync.`);else{p(`generated files are out of date:`);for(let e of w)p(` M ${e}`);for(let e of T)p(` D ${e}`);p("Run `dbx sync` to regenerate them.")}let e={written:[],changed:w,removed:T,upToDate:E};return await _.afterSync?.({cwd:u,config:d,result:e}),e}let D=[];for(let[t,n]of b){let r=e.resolve(u,t);o.mkdirSync(e.dirname(r),{recursive:!0}),o.writeFileSync(r,n,`utf-8`),D.push(t)}for(let t of T)o.rmSync(e.resolve(u,t),{force:!0});a(u,[...b.keys()]),n(u)&&p(` I .gitignore (added the .dbx ignore block)`),p(`wrote ${D.length}, removed ${T.length} file(s)${w.length?`, updated ${w.length}`:``}.`);let O={written:D,changed:w,removed:T,upToDate:E};return await _.afterSync?.({cwd:u,config:d,result:O}),O}export{c as runSync};
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{logger as t}from"../../shared/src/logger.js";import"../../shared/src/index.js";import{ensureDbxGitignore as n}from"./gitignore.js";import{resolveProjectType as r}from"./project-type.js";import{readManifest as i,writeManifest as a}from"./manifest.js";import o from"node:fs";function s(e){return e.replace(/\\/g,`/`)}async function c(c){let{tasks:l,cwd:u,config:d,ownConfig:f,tokens:p}=c,m=c.quiet?()=>{}:c.log??(e=>t.info(e)),h=c.quiet?()=>{}:(e,n)=>t.warn(e,n),g=c.projectType??r(u,d),_=i(u),v={cwd:u,projectType:g,config:d,ownConfig:f??d,tokens:p,log:m,warn:h,check:c.check===!0,managedFiles:_.files,manifest:{..._.extras,..._.tsconfigOverrides?{tsconfigOverrides:_.tsconfigOverrides}:{},..._.snapshots?{snapshots:_.snapshots}:{}}},y=d.hooks??{};await y.beforeSync?.(v);let b=l.filter(e=>(!e.projectTypes||e.projectTypes.includes(g))&&(!e.enabled||e.enabled(d)));m(`running ${b.length} task(s)${c.check?` (check)`:``} [${g}]`);let x=[];for(let e of b){m(` - ${e.name}`),await y.beforeTask?.({task:e,ctx:v});let t=await e.run(v),n=Array.isArray(t)?t:void 0;n&&x.push(...n),await y.afterTask?.({task:e,ctx:v,...n?{files:n}:{}})}let S=new Map(x.map(e=>[s(e.path),e.content])),C=new Set(x.filter(e=>e.track===!1).map(e=>s(e.path))),w=/* @__PURE__ */ new Set;for(let e of b){let t=typeof e.keep==`function`?e.keep(d):e.keep??[];for(let e of t)w.add(e)}let T=e=>{for(let t of w)if(e===t||e.endsWith(`/${t}`)||e.endsWith(t))return!0;return!1},E=[];for(let[t,n]of S){let r=e.resolve(u,t);(o.existsSync(r)?o.readFileSync(r,`utf-8`):void 0)!==n&&E.push(t)}let D=new Map([...S.keys()].map(t=>[t,o.existsSync(e.resolve(u,t))])),O=e=>_.origins?.[e]??(_.files.includes(e)?`created`:D.get(e)?`adopted`:`created`),k=_.files.filter(t=>!S.has(t)&&!C.has(t)&&!T(t)&&o.existsSync(e.resolve(u,t))&&O(t)===`created`),A=k.map(t=>({path:t,content:o.readFileSync(e.resolve(u,t),`utf-8`)})),j=E.length===0&&k.length===0;if(c.check){if(j)m(`generated files are in sync.`);else{m(`generated files are out of date:`);for(let e of E)m(` M ${e}`);for(let e of k)m(` D ${e}`);m("Run `dbx sync` to regenerate them.")}let e={written:[],changed:E,removed:k,removedFiles:A,upToDate:j};return await y.afterSync?.({cwd:u,config:d,result:e}),e}let M=[];for(let[t,n]of S){let r=e.resolve(u,t);o.mkdirSync(e.dirname(r),{recursive:!0}),o.writeFileSync(r,n,`utf-8`),M.push(t)}for(let t of k)o.rmSync(e.resolve(u,t),{force:!0});let N=[...S.keys()].filter(e=>!C.has(e)),P={};for(let e of N)P[e]=O(e);a(u,N,void 0,P,v.manifest),n(u)&&m(` I .gitignore (added the .dbx ignore block)`),m(`wrote ${M.length}, removed ${k.length} file(s)${E.length?`, updated ${E.length}`:``}.`);let F={written:M,changed:E,removed:k,removedFiles:A,upToDate:j};return await y.afterSync?.({cwd:u,config:d,result:F}),F}export{c as runSync};
@@ -1,5 +1,8 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
+ import { ProjectType } from "../../shared/src/config-types.js";
4
+ import { SyncTask, ToolchainConfig } from "../../shared/src/toolchain.js";
5
+ import "../../shared/src/index.js";
3
6
  import { RunSyncOptions } from "./sync.js";
4
7
  //#region packages/core/src/watch.d.ts
5
8
  export interface RunWatchOptions extends Omit<RunSyncOptions, 'check'> {
@@ -12,6 +15,12 @@ export interface RunWatchOptions extends Omit<RunSyncOptions, 'check'> {
12
15
  /** Respect `.gitignore` files (default true). */
13
16
  gitignore?: boolean;
14
17
  }
18
+ /**
19
+ * The repo-relative input globs of the tasks that run for `config` (and
20
+ * `projectType`, when given): each task's `watch` globs, with function forms
21
+ * resolved against the config (eg. custom tsconfig file names).
22
+ */
23
+ export declare function resolveWatchGlobs(tasks: SyncTask[], config: ToolchainConfig, projectType?: ProjectType): string[];
15
24
  /**
16
25
  * Run one sync, then watch the config file + every task's `watch` globs and
17
26
  * re-run on change. Writing generated files must not re-trigger a run, so a
@@ -1 +1 @@
1
- import{default as e}from"node:path";import"node:url";import.meta.url;import{isIgnoredPath as t,resolveIgnorePatterns as n}from"../../shared/src/ignore.js";import{logger as r}from"../../shared/src/logger.js";import"../../shared/src/index.js";import{runSync as i}from"./sync.js";import a from"node:fs";import{Glob as o}from"glob";async function s(s){let{cwd:c,tasks:l}=s,u=s.debounce??150,d=s.quiet?()=>{}:s.log??(e=>r.info(e)),f=0,p,m=!1,h=!1,g=async()=>{if(m)h=!0;else{m=!0;try{await i(s)}finally{m=!1,f=Date.now()+Math.max(u*3,300),h&&(h=!1,_())}}},_=()=>{clearTimeout(p),p=setTimeout(g,u)};await g();let v=n(c,{...s.exclude===void 0?{}:{exclude:s.exclude},...s.gitignore===void 0?{}:{gitignore:s.gitignore}}),y=/* @__PURE__ */ new Set([c]),b=/* @__PURE__ */ new Set;for(let e of l)for(let t of e.watch??[])b.add(t);for(let n of b)try{let r=new o(n,{cwd:c,dot:!0,ignore:v}).walkSync();for(let n of r){let r=e.resolve(c,n),i=e.relative(c,r).replace(/\\/g,`/`);t(i,v)||y.add(e.dirname(r))}}catch{}let x=[],S=n=>{if(!(Date.now()<f)){if(n){let r=e.relative(c,n).replace(/\\/g,`/`);if(t(r,v))return}s.config?.hooks?.onChange?.(n?{path:n}:{}),_()}};if(s.configPath)try{x.push(a.watch(s.configPath,()=>{d(`config changed; re-syncing`),S(s.configPath)}))}catch{}for(let t of y){let n=n=>S(e.join(t,n??``));try{x.push(a.watch(t,{recursive:!0},(e,t)=>n(t)))}catch{try{x.push(a.watch(t,(e,t)=>n(t)))}catch{}}}d(`watching for changes (Ctrl+C to stop)`),await new Promise(e=>{let t=()=>{p&&clearTimeout(p),p=void 0;for(let e of x)e.close();process.off(`SIGINT`,t),process.off(`SIGTERM`,t),e()};process.on(`SIGINT`,t),process.on(`SIGTERM`,t)})}export{s as runWatch};
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{isIgnoredPath as t,resolveIgnorePatterns as n}from"../../shared/src/ignore.js";import{logger as r}from"../../shared/src/logger.js";import{sectionConfig as i}from"../../shared/src/toolchain.js";import"../../shared/src/index.js";import{resolveProjectType as a}from"./project-type.js";import{findConfigFile as o,loadToolchainConfig as s}from"./loader.js";import{runSync as c}from"./sync.js";import l from"node:fs";import{Glob as u}from"glob";function d(e,t,n){let r=/* @__PURE__ */ new Set;for(let i of e){if(n&&i.projectTypes&&!i.projectTypes.includes(n)||i.enabled&&!i.enabled(t))continue;let e=typeof i.watch==`function`?i.watch(t):i.watch??[];for(let t of e)r.add(t)}return[...r]}async function f(f){let{cwd:p,tasks:m}=f,h=f.configPath?e.resolve(p,f.configPath):void 0,g=f.quiet?()=>{}:f.log??(e=>r.info(e)),_={...f},v=[],y=[],b=0,x,S=!1,C=!1,w=!1,T=!1,E=()=>i(_.config.watch)?.debounce??f.debounce??150,D=()=>{for(let e of y)e.close();y=[]},O=async()=>{let e=f.configPath?o(p):void 0,t=h&&l.existsSync(h)?h:e;if(!t)return!1;h=t;try{let e=await s(p,{config:t,fresh:!0});return _={..._,config:e.config,ownConfig:e.ownConfig,tokens:e.tokens,projectType:e.projectType},!0}catch(e){return r.error(`failed to reload ${h}: ${e instanceof Error?e.message:String(e)}`),!1}},k=async()=>{if(S)C=!0;else{S=!0;try{w&&(w=!1,await O()&&(T=!0)),await c(_)}finally{S=!1,b=Date.now()+Math.max(E()*3,300),T&&(T=!1,M()),C&&(C=!1,A())}}},A=()=>{clearTimeout(x),x=setTimeout(k,E())},j=n=>{if(!(Date.now()<b)){if(n){let r=e.relative(p,n).replace(/\\/g,`/`);if(t(r,v))return;e.basename(n).startsWith(`dbx.config.`)&&(w=!0)}_.config?.hooks?.onChange?.(n?{path:n}:{}),A()}};function M(){D();let r=i(_.config.watch);v=n(p,{...(r?.exclude??f.exclude)===void 0?{}:{exclude:r?.exclude??f.exclude},...(r?.gitignore??f.gitignore)===void 0?{}:{gitignore:r?.gitignore??f.gitignore}});let o=/* @__PURE__ */ new Set([p]),s=_.projectType??a(p,_.config);for(let n of d(m,_.config,s))try{let r=new u(n,{cwd:p,dot:!0,ignore:v}).walkSync();for(let n of r){let r=e.resolve(p,n),i=e.relative(p,r).replace(/\\/g,`/`);t(i,v)||o.add(e.dirname(r))}}catch{}if(h)try{y.push(l.watch(h,()=>{g(`config changed; re-syncing`),w=!0,j(h)}))}catch{}for(let t of o){let n=n=>j(e.join(t,n??``));try{y.push(l.watch(t,{recursive:!0},(e,t)=>n(t)))}catch{try{y.push(l.watch(t,(e,t)=>n(t)))}catch{}}}}await k(),M(),g(`watching for changes (Ctrl+C to stop)`),await new Promise(e=>{let t=()=>{x&&clearTimeout(x),x=void 0,D(),process.off(`SIGINT`,t),process.off(`SIGTERM`,t),e()};process.on(`SIGINT`,t),process.on(`SIGTERM`,t)})}export{d as resolveWatchGlobs,f as runWatch};
@@ -1 +1 @@
1
- import{default as e}from"node:path";import"node:url";import.meta.url;import{logger as t}from"../../../shared/src/logger.js";import"../../../shared/src/index.js";import{loadToolchainConfig as n}from"../../../core/src/loader.js";import{selectProjects as r}from"../../../core/src/select.js";import{runSync as i}from"../../../core/src/sync.js";import"../../../core/src/index.js";import{diffFiles as a,hasPending as o}from"../check.js";import{listMigrations as s,migrations as c}from"../registry.js";import{cancel as l,isCancel as u,multiselect as d}from"@clack/prompts";function f(e){return!!(process.stdin.isTTY&&process.stdout.isTTY)&&e.json!==!0}function p(){l(`Cancelled.`),process.exitCode=1}function m(){return[{name:`migrate`,description:`Migrate Biome / ESLint / Prettier / Dprint config to Oxc, or fold vite.config.* into dbx.config.`,options:[{flags:`--from <tool>`,description:`Source tool: biome | eslint | prettier | dprint | vite | all.`},{flags:`--to <tool>`,description:`Target tool (default: oxc).`,default:`oxc`},{flags:`--cwd <dir>`,description:`Project root (default: cwd).`},{flags:`--recursive`,description:`Also migrate the discovered projects under the root (default: root only).`},{flags:`--write`,description:`Write the files (default: dry-run).`},{flags:`--dry-run`,description:`Do not write anything (default).`},{flags:`--check`,description:`CI: exit non-zero when the oxc config is stale.`},{flags:`--target <target>`,description:`files (default) | vite.`},{flags:`--online`,description:`Allow network (e.g. @oxlint/migrate).`},{flags:`--ignore-vite-config-file`,description:"Do not remove the folded `vite.config.*`."},{flags:`--ignore-managed-files`,description:`Skip the post-migration sync (leave the toolchain-managed files as-is).`},{flags:`--ignore-changelog`,description:`Skip the changelog task in the post-migration sync.`},{flags:`--json`,description:`Print the result as JSON.`}],run:async(s,l)=>{let m=s.cwd??l.cwd,h=!!s.check,g=!!s.write&&!s.dryRun&&!h,_=!!s.online,v=s.from,y=s.target??`files`,b=!!s.recursive,x=e=>c().filter(t=>(!v||v===`all`||t.from===v)&&t.detect(e)),S=[m];if(b){let n=r({root:m}).filter(e=>x(e.dir).length>0);if(n.length===0){t.info(`nothing to migrate under ${m}.`);return}let i=n;if(f(s)){let t=await d({message:`Which projects should I migrate?`,required:!0,options:[{value:`__all__`,label:`All projects`},...n.map(t=>({value:t.dir,label:t.rel===`.`?e.basename(m):t.rel,...t.name?{hint:t.name}:{}}))]});if(u(t)){p();return}let r=t;i=r.includes(`__all__`)?n:n.filter(e=>r.includes(e.dir))}S=i.map(e=>e.dir)}let C=[];for(let e of S)for(let t of x(e))C.push({dir:e,result:await t.run({cwd:e,write:g,online:_,target:y,ignoreViteConfigFile:!!s.ignoreViteConfigFile,ignoreManagedFiles:!!s.ignoreManagedFiles,ignoreChangelog:!!s.ignoreChangelog})});if(C.length===0){t.info(v&&v!==`all`?`no "${v}" migration is registered.`:`nothing to migrate (no Biome/ESLint/Prettier/Dprint/vite config detected).`);return}let w=t=>b?`${e.relative(m,t)||`.`}: `:``,T=[...new Set(C.filter(({result:e})=>e.written.length>0||(e.removed?.length??0)>0).map(({dir:e})=>e))];if(h){let n=C.flatMap(({result:e})=>a(e.files??[])),r=n.filter(e=>e.status!==`same`);if(s.json)t.raw(JSON.stringify(C.map(e=>e.result),null,4));else if(r.length){for(let n of r)t.info(`${n.status} ${e.relative(m,n.path)||n.path}`);t.info(`${r.length} file(s) out of date — run \`migrate --write\` to apply.`)}else t.info(`up to date.`);o(n)&&(process.exitCode=1);return}let E=async()=>{if(!g||T.length===0||s.ignoreManagedFiles||!l.syncTasks?.length)return;let e=s.ignoreChangelog?l.syncTasks.filter(e=>e.name!==`changelog`):l.syncTasks;for(let r of T){let a=await n(r);s.json||t.info(`${w(r)}regenerating managed files.`),await i({tasks:e,cwd:r,projectType:a.projectType,config:a.config,tokens:a.tokens,quiet:s.json===!0})}};if(s.json)await E(),t.raw(JSON.stringify(C.map(e=>e.result),null,4));else{for(let{dir:e,result:n}of C){t.info(`${w(e)}${n.from} -> ${n.to} ${g?`wrote`:`would write`}`);for(let e of n.written)t.info(` ${g?`+`:`?`} ${e}`);for(let e of n.removed??[])t.info(` ${g?`-`:`?`} ${e}`);for(let e of n.notes??[])t.info(` ${e}`);if(n.unmapped?.length){t.info(` unmapped (${n.unmapped.length}):`);for(let e of n.unmapped.slice(0,25))t.info(` - ${e.source}: ${e.reason}`)}}!g&&T.length>0&&!s.ignoreManagedFiles&&t.info(`managed files are regenerated after --write; pass --ignore-managed-files to skip.`),await E(),g||t.info(`dry-run — re-run with --write to apply.`)}}},{name:`migrate:list`,description:`List the registered migrations and whether each is detected.`,options:[{flags:`--cwd <dir>`,description:`Project root (default: cwd).`},{flags:`--json`,description:`Print as JSON.`}],run:(e,n)=>{let r=e.cwd??n.cwd,i=s(r);if(e.json)t.raw(JSON.stringify(i,null,4));else for(let e of i)t.info(` ${e.id.padEnd(16)} ${e.from} -> ${e.to} [${e.detected?`detected`:`not found`}]`),t.info(` ${e.description}`)}}]}export{m as migrateCommands};
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{logger as t}from"../../../shared/src/logger.js";import"../../../shared/src/index.js";import{loadToolchainConfig as n}from"../../../core/src/loader.js";import{selectProjects as r}from"../../../core/src/select.js";import{runSync as i}from"../../../core/src/sync.js";import"../../../core/src/index.js";import{diffFiles as a,hasPending as o}from"../check.js";import{listMigrations as s,migrations as c}from"../registry.js";import{cancel as l,isCancel as u,multiselect as d}from"@clack/prompts";function f(e){return!!(process.stdin.isTTY&&process.stdout.isTTY)&&e.json!==!0}function p(){l(`Cancelled.`),process.exitCode=1}function m(){return[{name:`migrate`,description:`Migrate Biome / ESLint / Prettier / Dprint / Oxc config, or fold vite.config.* into dbx.config.`,options:[{flags:`--from <tool>`,description:`Source tool (repeatable): biome | eslint | prettier | dprint | oxc | vite | all.`,multiple:!0},{flags:`--to <tool>`,description:`Target tool (default: oxc).`,default:`oxc`},{flags:`--cwd <dir>`,description:`Project root (default: cwd).`},{flags:`--recursive`,description:`Also migrate the discovered projects under the root (default: root only).`},{flags:`--write`,description:`Write the files (default: dry-run).`},{flags:`--dry-run`,description:`Do not write anything (default).`},{flags:`--check`,description:`CI: exit non-zero when the oxc config is stale.`},{flags:`--target <target>`,description:`files (default) | vite.`},{flags:`--online`,description:`Allow network (e.g. @oxlint/migrate).`},{flags:`--ignore-vite-config-file`,description:"Do not remove the folded `vite.config.*`."},{flags:`--ignore-managed-files`,description:`Skip the post-migration sync (leave the toolchain-managed files as-is).`},{flags:`--ignore-changelog`,description:`Skip the changelog task in the post-migration sync.`},{flags:`--json`,description:`Print the result as JSON.`}],run:async(s,l)=>{let m=s.cwd??l.cwd,h=!!s.check,g=!!s.write&&!s.dryRun&&!h,_=!!s.online,v=s.from,y=Array.isArray(v)?v:v?[v]:[],b=y.includes(`all`),x=y.filter(e=>e!==`all`),S=e=>y.length===0||b||x.includes(e.from),C=s.target??`files`,w=!!s.recursive,T=e=>c().filter(t=>S(t)&&t.detect(e)),E=[m];if(w){let n=r({root:m}).filter(e=>T(e.dir).length>0);if(n.length===0){t.info(`nothing to migrate under ${m}.`);return}let i=n;if(f(s)){let t=await d({message:`Which projects should I migrate?`,required:!0,options:[{value:`__all__`,label:`All projects`},...n.map(t=>({value:t.dir,label:t.rel===`.`?e.basename(m):t.rel,...t.name?{hint:t.name}:{}}))]});if(u(t)){p();return}let r=t;i=r.includes(`__all__`)?n:n.filter(e=>r.includes(e.dir))}E=i.map(e=>e.dir)}let D=[];for(let e of E)for(let t of T(e))D.push({dir:e,result:await t.run({cwd:e,write:g,online:_,target:C,ignoreViteConfigFile:!!s.ignoreViteConfigFile,ignoreManagedFiles:!!s.ignoreManagedFiles,ignoreChangelog:!!s.ignoreChangelog})});if(D.length===0){let e=c().some(e=>S(e));t.info(x.length>0&&!b&&!e?`no migration registered for: ${x.join(`, `)}.`:`nothing to migrate (no Biome/ESLint/Prettier/Dprint/Oxc/vite config detected).`);return}let O=t=>w?`${e.relative(m,t)||`.`}: `:``,k=[...new Set(D.filter(({result:e})=>e.written.length>0||(e.removed?.length??0)>0).map(({dir:e})=>e))];if(h){let n=D.flatMap(({result:e})=>a(e.files??[])),r=n.filter(e=>e.status!==`same`);if(s.json)t.raw(JSON.stringify(D.map(e=>e.result),null,4));else if(r.length){for(let n of r)t.info(`${n.status} ${e.relative(m,n.path)||n.path}`);t.info(`${r.length} file(s) out of date — run \`migrate --write\` to apply.`)}else t.info(`up to date.`);o(n)&&(process.exitCode=1);return}let A=async()=>{if(!g||k.length===0||s.ignoreManagedFiles||!l.syncTasks?.length)return;let e=s.ignoreChangelog?l.syncTasks.filter(e=>e.name!==`changelog`):l.syncTasks;for(let r of k){let a=await n(r);s.json||t.info(`${O(r)}regenerating managed files.`),await i({tasks:e,cwd:r,projectType:a.projectType,config:a.config,ownConfig:a.ownConfig,tokens:a.tokens,quiet:s.json===!0})}};if(s.json)await A(),t.raw(JSON.stringify(D.map(e=>e.result),null,4));else{for(let{dir:e,result:n}of D){t.info(`${O(e)}${n.from} -> ${n.to} ${g?`wrote`:`would write`}`);for(let e of n.written)t.info(` ${g?`+`:`?`} ${e}`);for(let e of n.removed??[])t.info(` ${g?`-`:`?`} ${e}`);for(let e of n.notes??[])t.info(` ${e}`);if(n.unmapped?.length){t.info(` unmapped (${n.unmapped.length}):`);for(let e of n.unmapped.slice(0,25))t.info(` - ${e.source}: ${e.reason}`)}}!g&&k.length>0&&!s.ignoreManagedFiles&&t.info(`managed files are regenerated after --write; pass --ignore-managed-files to skip.`),await A(),g||t.info(`dry-run — re-run with --write to apply.`)}}},{name:`migrate:list`,description:`List the registered migrations and whether each is detected.`,options:[{flags:`--cwd <dir>`,description:`Project root (default: cwd).`},{flags:`--json`,description:`Print as JSON.`}],run:(e,n)=>{let r=e.cwd??n.cwd,i=s(r);if(e.json)t.raw(JSON.stringify(i,null,4));else for(let e of i)t.info(` ${e.id.padEnd(16)} ${e.from} -> ${e.to} [${e.detected?`detected`:`not found`}]`),t.info(` ${e.description}`)}}]}export{m as migrateCommands};
@@ -6,10 +6,11 @@ import { FileDiff, FileStatus, diffFiles, hasPending } from "./check.js";
6
6
  import { migrateCommands } from "./cli/index.js";
7
7
  import { dprintToOx, findDprintConfig, mapDprintToOxfmt } from "./dprint.js";
8
8
  import { eslintToOx, findEslintConfig, mapRuleName, runOxlintMigrate } from "./eslint.js";
9
+ import { OXC_FMT_FILE, OXC_LINT_FILE, findOxcConfigs, oxcToToolchain } from "./oxc.js";
9
10
  import { DEFAULT_IGNORE, OxfmtMapping, mapBiomeFormatter, mapBiomeIncludes, mapBiomeToOxfmt, mapOrganizeImports } from "./oxfmt-map.js";
10
11
  import { OxlintMapping, RULE_MAP, mapBiomeToOxlint } from "./oxlint-map.js";
11
12
  import { findPrettierConfig, mapPrettierToOxfmt, prettierToOx, readPrettierIgnore } from "./prettier.js";
12
13
  import { MigrationInfo, detectMigrations, findMigration, listMigrations, migrations, runDetectedMigrations, runMigration } from "./registry.js";
13
- import { VITE_CONFIG_FILES, ensureViteFmtIgnore, extractViteObject, findDbxConfig, findViteConfig, foldViteIntoConfig, scanLiteralObject, viteToToolchain } from "./vite.js";
14
+ import { VITE_CONFIG_FILES, ensureViteFmtIgnore, extractViteObject, findDbxConfig, findViteConfig, foldToolchainSection, foldViteIntoConfig, mergeViteObjects, renderFreshSectionsConfig, scanLiteralObject, viteToToolchain } from "./vite.js";
14
15
  import { findTopLevelValue, matchBracket, mergeViteConfig, renderViteTarget, serializeTs, writeViteTarget } from "./vite-target.js";
15
- export { BIOME_CONFIG_FILES, DEFAULT_IGNORE, FileDiff, FileStatus, MigrateTarget, MigrateTool, MigrationContext, MigrationFile, MigrationInfo, MigrationResult, OxfmtMapping, OxlintMapping, RULE_MAP, ToolchainMigration, UnmappedItem, VITE_CONFIG_FILES, biomeToOx, detectMigrations, diffFiles, dprintToOx, ensureViteFmtIgnore, eslintToOx, extractViteObject, findBiomeConfig, findDbxConfig, findDprintConfig, findEslintConfig, findMigration, findPrettierConfig, findTopLevelValue, findViteConfig, foldViteIntoConfig, hasPending, listMigrations, mapBiomeFormatter, mapBiomeIncludes, mapBiomeToOxfmt, mapBiomeToOxlint, mapDprintToOxfmt, mapOrganizeImports, mapPrettierToOxfmt, mapRuleName, matchBracket, mergeViteConfig, migrateCommands, migrations, prettierToOx, readJsonc, readPrettierIgnore, renderViteTarget, runDetectedMigrations, runMigration, runOxlintMigrate, scanLiteralObject, serializeTs, stripJsonc, viteToToolchain, writeViteTarget };
16
+ export { BIOME_CONFIG_FILES, DEFAULT_IGNORE, FileDiff, FileStatus, MigrateTarget, MigrateTool, MigrationContext, MigrationFile, MigrationInfo, MigrationResult, OXC_FMT_FILE, OXC_LINT_FILE, OxfmtMapping, OxlintMapping, RULE_MAP, ToolchainMigration, UnmappedItem, VITE_CONFIG_FILES, biomeToOx, detectMigrations, diffFiles, dprintToOx, ensureViteFmtIgnore, eslintToOx, extractViteObject, findBiomeConfig, findDbxConfig, findDprintConfig, findEslintConfig, findMigration, findOxcConfigs, findPrettierConfig, findTopLevelValue, findViteConfig, foldToolchainSection, foldViteIntoConfig, hasPending, listMigrations, mapBiomeFormatter, mapBiomeIncludes, mapBiomeToOxfmt, mapBiomeToOxlint, mapDprintToOxfmt, mapOrganizeImports, mapPrettierToOxfmt, mapRuleName, matchBracket, mergeViteConfig, mergeViteObjects, migrateCommands, migrations, oxcToToolchain, prettierToOx, readJsonc, readPrettierIgnore, renderFreshSectionsConfig, renderViteTarget, runDetectedMigrations, runMigration, runOxlintMigrate, scanLiteralObject, serializeTs, stripJsonc, viteToToolchain, writeViteTarget };
@@ -1 +1 @@
1
- import"node:path";import"node:url";import.meta.url;import{diffFiles as e,hasPending as t}from"./check.js";import{DEFAULT_IGNORE as n,mapBiomeFormatter as r,mapBiomeIncludes as i,mapBiomeToOxfmt as a,mapOrganizeImports as o}from"./oxfmt-map.js";import{RULE_MAP as s,mapBiomeToOxlint as c}from"./oxlint-map.js";import{findTopLevelValue as l,matchBracket as u,mergeViteConfig as d,renderViteTarget as f,serializeTs as p,writeViteTarget as m}from"./vite-target.js";import{BIOME_CONFIG_FILES as h,biomeToOx as g,findBiomeConfig as _,readJsonc as v,stripJsonc as y}from"./biome.js";import{dprintToOx as b,findDprintConfig as x,mapDprintToOxfmt as S}from"./dprint.js";import{eslintToOx as C,findEslintConfig as w,mapRuleName as T,runOxlintMigrate as E}from"./eslint.js";import{findPrettierConfig as D,mapPrettierToOxfmt as O,prettierToOx as k,readPrettierIgnore as A}from"./prettier.js";import{VITE_CONFIG_FILES as j,ensureViteFmtIgnore as M,extractViteObject as N,findDbxConfig as P,findViteConfig as F,foldViteIntoConfig as I,scanLiteralObject as L,viteToToolchain as R}from"./vite.js";import{detectMigrations as z,findMigration as B,listMigrations as V,migrations as H,runDetectedMigrations as U,runMigration as W}from"./registry.js";import{migrateCommands as G}from"./cli/index.js";export{h as BIOME_CONFIG_FILES,n as DEFAULT_IGNORE,s as RULE_MAP,j as VITE_CONFIG_FILES,g as biomeToOx,z as detectMigrations,e as diffFiles,b as dprintToOx,M as ensureViteFmtIgnore,C as eslintToOx,N as extractViteObject,_ as findBiomeConfig,P as findDbxConfig,x as findDprintConfig,w as findEslintConfig,B as findMigration,D as findPrettierConfig,l as findTopLevelValue,F as findViteConfig,I as foldViteIntoConfig,t as hasPending,V as listMigrations,r as mapBiomeFormatter,i as mapBiomeIncludes,a as mapBiomeToOxfmt,c as mapBiomeToOxlint,S as mapDprintToOxfmt,o as mapOrganizeImports,O as mapPrettierToOxfmt,T as mapRuleName,u as matchBracket,d as mergeViteConfig,G as migrateCommands,H as migrations,k as prettierToOx,v as readJsonc,A as readPrettierIgnore,f as renderViteTarget,U as runDetectedMigrations,W as runMigration,E as runOxlintMigrate,L as scanLiteralObject,p as serializeTs,y as stripJsonc,R as viteToToolchain,m as writeViteTarget};
1
+ import"node:path";import"node:url";import.meta.url;import{DEFAULT_IGNORE as e,mapBiomeFormatter as t,mapBiomeIncludes as n,mapBiomeToOxfmt as r,mapOrganizeImports as i}from"./oxfmt-map.js";import{RULE_MAP as a,mapBiomeToOxlint as o}from"./oxlint-map.js";import{findTopLevelValue as s,matchBracket as c,mergeViteConfig as l,renderViteTarget as u,serializeTs as d,writeViteTarget as f}from"./vite-target.js";import{BIOME_CONFIG_FILES as p,biomeToOx as m,findBiomeConfig as h,readJsonc as g,stripJsonc as _}from"./biome.js";import{diffFiles as v,hasPending as y}from"./check.js";import{dprintToOx as b,findDprintConfig as x,mapDprintToOxfmt as S}from"./dprint.js";import{eslintToOx as C,findEslintConfig as w,mapRuleName as T,runOxlintMigrate as E}from"./eslint.js";import{VITE_CONFIG_FILES as D,ensureViteFmtIgnore as O,extractViteObject as k,findDbxConfig as A,findViteConfig as j,foldToolchainSection as M,foldViteIntoConfig as N,mergeViteObjects as P,renderFreshSectionsConfig as F,scanLiteralObject as I,viteToToolchain as L}from"./vite.js";import{OXC_FMT_FILE as R,OXC_LINT_FILE as z,findOxcConfigs as B,oxcToToolchain as V}from"./oxc.js";import{findPrettierConfig as H,mapPrettierToOxfmt as U,prettierToOx as W,readPrettierIgnore as G}from"./prettier.js";import{detectMigrations as K,findMigration as q,listMigrations as J,migrations as Y,runDetectedMigrations as X,runMigration as Z}from"./registry.js";import{migrateCommands as Q}from"./cli/index.js";export{p as BIOME_CONFIG_FILES,e as DEFAULT_IGNORE,R as OXC_FMT_FILE,z as OXC_LINT_FILE,a as RULE_MAP,D as VITE_CONFIG_FILES,m as biomeToOx,K as detectMigrations,v as diffFiles,b as dprintToOx,O as ensureViteFmtIgnore,C as eslintToOx,k as extractViteObject,h as findBiomeConfig,A as findDbxConfig,x as findDprintConfig,w as findEslintConfig,q as findMigration,B as findOxcConfigs,H as findPrettierConfig,s as findTopLevelValue,j as findViteConfig,M as foldToolchainSection,N as foldViteIntoConfig,y as hasPending,J as listMigrations,t as mapBiomeFormatter,n as mapBiomeIncludes,r as mapBiomeToOxfmt,o as mapBiomeToOxlint,S as mapDprintToOxfmt,i as mapOrganizeImports,U as mapPrettierToOxfmt,T as mapRuleName,c as matchBracket,l as mergeViteConfig,P as mergeViteObjects,Q as migrateCommands,Y as migrations,V as oxcToToolchain,W as prettierToOx,g as readJsonc,G as readPrettierIgnore,F as renderFreshSectionsConfig,u as renderViteTarget,X as runDetectedMigrations,Z as runMigration,E as runOxlintMigrate,I as scanLiteralObject,d as serializeTs,_ as stripJsonc,L as viteToToolchain,f as writeViteTarget};
@@ -0,0 +1,13 @@
1
+ import __tsdown_shims_path from 'node:path';
2
+ import __tsdown_shims_url from 'node:url';
3
+ import { ToolchainMigration } from "./types.js";
4
+ //#region packages/migrate/src/oxc.d.ts
5
+ export declare const OXC_FMT_FILE = ".oxfmtrc.json";
6
+ export declare const OXC_LINT_FILE = ".oxlintrc.json";
7
+ /** A source Oxc config in `cwd`, when it is not managed by dbx itself. */
8
+ export declare function findOxcConfigs(cwd: string): {
9
+ fmt?: string;
10
+ lint?: string;
11
+ };
12
+ export declare const oxcToToolchain: ToolchainMigration;
13
+ //#endregion
@@ -0,0 +1 @@
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{readManifest as t}from"../../core/src/manifest.js";import"../../core/src/index.js";import{serializeTs as n}from"./vite-target.js";import{readJsonc as r}from"./biome.js";import{foldToolchainSection as i,renderFreshSectionsConfig as a}from"./vite.js";import o from"node:fs";const s=`.oxfmtrc.json`,c=`.oxlintrc.json`;function l(e,n){try{return t(e).files.includes(n)}catch{return!1}}function u(t){let n=e.join(t,s),r=e.join(t,c);return{...o.existsSync(n)&&!l(t,`.oxfmtrc.json`)?{fmt:n}:{},...o.existsSync(r)&&!l(t,`.oxlintrc.json`)?{lint:r}:{}}}function d(e){let{$schema:t,...n}=e;return n}function f(t){for(let n of[`dbx.config.ts`,`dbx.config.mts`,`dbx.config.js`,`dbx.config.mjs`,`dbx.config.cjs`,`dbx.config.json`]){let r=e.join(t,n);if(o.existsSync(r))return r}}const p={id:`oxc-to-toolchain`,from:`oxc`,to:`toolchain`,description:`Fold .oxfmtrc.json / .oxlintrc.json into toolchain.fmt/lint.oxc.`,detect:e=>!!(u(e).fmt||u(e).lint),run:async t=>{let s=u(t.cwd);if(!s.fmt&&!s.lint)throw Error(`oxc-to-toolchain: no Oxc config found.`);let c=s.fmt?d(r(s.fmt)):void 0,l=s.lint?d(r(s.lint)):void 0,m=[...s.fmt?[`Source: ${e.basename(s.fmt)} (Oxfmt).`]:[],...s.lint?[`Source: ${e.basename(s.lint)} (Oxlint).`]:[]],h=[...c?[{key:`fmt`,objectText:n({oxc:c})}]:[],...l?[{key:`lint`,objectText:n({oxc:l})}]:[]],g=f(t.cwd),_,v;if(!g)_=e.join(t.cwd,`dbx.config.ts`),v=a(h);else if(g.endsWith(`.json`))return{id:p.id,from:`oxc`,to:`toolchain`,written:[],files:[],oxfmt:c,oxlint:l,unmapped:[{source:e.basename(g),reason:`JSON configs cannot hold the folded object by text-splice`}],notes:[...m,`Fold into the JSON config by hand.`]};else{let t=o.readFileSync(g,`utf-8`).replace(/^\uFEFF/,``);for(let n of h){let r=i(t,n.key,n.objectText);if(`error`in r)return{id:p.id,from:`oxc`,to:`toolchain`,written:[],files:[],oxfmt:c,oxlint:l,unmapped:[{source:e.basename(g),reason:r.error}],notes:[...m,`Left dbx.config.* unchanged; fold it by hand.`]};t=r.content}_=g,v=t}let y={path:_,content:v};t.write&&o.writeFileSync(_,v,`utf-8`);let b=[s.fmt,s.lint].filter(e=>!!e),x=t.ignoreManagedFiles?[]:b;if(t.ignoreManagedFiles)m.push(`Kept the source Oxc files (ignoreManagedFiles).`);else{if(t.write)for(let e of x)o.rmSync(e,{force:!0});x.length>0&&m.push(`${t.write?`Removed`:`Would remove`} the source Oxc files; \`dbx sync\` regenerates them.`)}return{id:p.id,from:`oxc`,to:`toolchain`,written:[_],removed:x,files:[y],oxfmt:c,oxlint:l,notes:[...m,"Folded into `toolchain.fmt.oxc` / `toolchain.lint.oxc`."]}}};export{s as OXC_FMT_FILE,c as OXC_LINT_FILE,u as findOxcConfigs,p as oxcToToolchain};
@@ -1 +1 @@
1
- import"node:path";import"node:url";import.meta.url;import{biomeToOx as e}from"./biome.js";import{dprintToOx as t}from"./dprint.js";import{eslintToOx as n}from"./eslint.js";import{prettierToOx as r}from"./prettier.js";import{viteToToolchain as i}from"./vite.js";function a(){return[e,r,t,n,i]}function o(e){return a().map(t=>({id:t.id,from:t.from,to:t.to,description:t.description,detected:t.detect(e)}))}function s(e){return a().filter(t=>t.detect(e))}function c(e){return a().find(t=>t.id===e||t.from===e)}async function l(e,t){let n=c(e);if(!n)throw Error(`Unknown migration "${e}".`);return n.run(t)}async function u(e){let t=[];for(let n of s(e.cwd))t.push(await n.run(e));return t}export{s as detectMigrations,c as findMigration,o as listMigrations,a as migrations,u as runDetectedMigrations,l as runMigration};
1
+ import"node:path";import"node:url";import.meta.url;import{biomeToOx as e}from"./biome.js";import{dprintToOx as t}from"./dprint.js";import{eslintToOx as n}from"./eslint.js";import{viteToToolchain as r}from"./vite.js";import{oxcToToolchain as i}from"./oxc.js";import{prettierToOx as a}from"./prettier.js";function o(){return[e,a,t,n,i,r]}function s(e){return o().map(t=>({id:t.id,from:t.from,to:t.to,description:t.description,detected:t.detect(e)}))}function c(e){return o().filter(t=>t.detect(e))}function l(e){return o().find(t=>t.id===e||t.from===e)}async function u(e,t){let n=l(e);if(!n)throw Error(`Unknown migration "${e}".`);return n.run(t)}async function d(e){let t=[];for(let n of c(e.cwd))t.push(await n.run(e));return t}export{c as detectMigrations,l as findMigration,s as listMigrations,o as migrations,d as runDetectedMigrations,u as runMigration};
@@ -1,5 +1,5 @@
1
1
  import{default as e}from"node:path";import"node:url";import.meta.url;import t from"node:fs";const n=/^[A-Za-z_$][\w$]*$/;function r(e,t=0){let i=` `.repeat(t),a=` `.repeat(t+1);if(e==null)return`null`;if(typeof e==`string`)return`'${e.replace(/\\/g,`\\\\`).replace(/'/g,`\\'`)}'`;if(typeof e==`number`||typeof e==`boolean`)return String(e);if(Array.isArray(e))return e.length===0?`[]`:`[\n${e.map(e=>`${a}${r(e,t+1)}`).join(`,
2
2
  `)},\n${i}]`;if(typeof e==`object`){let o=Object.entries(e);return o.length===0?`{}`:`{\n${o.map(([e,i])=>{let o=n.test(e)?e:JSON.stringify(e);return`${a}${o}: ${r(i,t+1)}`}).join(`,
3
3
  `)},\n${i}}`}return JSON.stringify(e)}function i(e,t){let n=e[t],r=e[t+1];if(n===`/`&&r===`/`){for(;t<e.length&&e[t]!==`
4
- `;)t++;return t}if(n===`/`&&r===`*`){for(t+=2;t<e.length&&(e[t]!==`*`||e[t+1]!==`/`);)t++;return t+2}if(n===`"`||n===`'`||n==="`"){let r=n;for(t++;t<e.length&&e[t]!==r;)e[t]===`\\`&&t++,t++;return t+1}return t}function a(e,t){let n={"{":`}`,"[":`]`}[e[t]];if(!n)return-1;let r=0;for(let a=t;a<e.length;a++){let o=i(e,a);if(o!==a)a=o-1;else if(e[a]===e[t])r++;else if(e[a]===n&&(r--,r===0))return a+1}return-1}function o(e,t,r,o){let s=1;for(let c=t+1;c<r;c++){let t=i(e,c);if(t!==c){c=t-1;continue}let l=e[c];if(l===`{`||l===`[`)s++;else if(l===`}`||l===`]`)s--;else if(s===1&&n.test(l)){let t=c;for(;t<r&&/[\w$]/.test(e[t]);)t++;let n=e.slice(c,t),i=t;for(;i<r&&/\s/.test(e[i]);)i++;if(n===o&&e[i]===`:`){let t=i+1;for(;t<r&&/\s/.test(e[t]);)t++;let n=e[t];if(n===`{`||n===`[`)return[t,a(e,t)];let o=t;for(;o<r&&e[o]!==`,`;)o++;return[t,o]}c=t-1}}}function s(e,t){let n=Object.entries(t).filter(([,e])=>e!==void 0);if(!e)return`import { defineConfig } from 'vite-plus';\n\nexport default defineConfig({\n${n.map(([e,t])=>` ${e}: ${r(t,1)},`).join(`
4
+ `;)t++;return t}if(n===`/`&&r===`*`){for(t+=2;t<e.length&&(e[t]!==`*`||e[t+1]!==`/`);)t++;return t+2}if(n===`"`||n===`'`||n==="`"){let r=n;for(t++;t<e.length&&e[t]!==r;)e[t]===`\\`&&t++,t++;return t+1}return t}function a(e,t){let n={"{":`}`,"[":`]`}[e[t]];if(!n)return-1;let r=0;for(let a=t;a<e.length;a++){let o=i(e,a);if(o!==a)a=o-1;else if(e[a]===e[t])r++;else if(e[a]===n&&(r--,r===0))return a+1}return-1}function o(e,t,r,o){let s=1;for(let c=t+1;c<r;c++){let t=i(e,c);if(t!==c){c=t-1;continue}let l=e[c];if(l===`{`||l===`[`)s++;else if(l===`}`||l===`]`)s--;else if(s===1&&n.test(l)){let t=c;for(;t<r&&/[\w$]/.test(e[t]);)t++;let n=e.slice(c,t),i=t;for(;i<r&&/\s/.test(e[i]);)i++;if(n===o&&e[i]===`:`){let t=i+1;for(;t<r&&/\s/.test(e[t]);)t++;let n=e[t];if(n===`{`||n===`[`)return[t,a(e,t)];let o=t;for(;o<r&&e[o]!==`,`&&e[o]!==`}`;)o++;for(;o>t&&/\s/.test(e[o-1]);)o--;return[t,o]}c=t-1}}}function s(e,t){let n=Object.entries(t).filter(([,e])=>e!==void 0);if(!e)return`import { defineConfig } from 'vite-plus';\n\nexport default defineConfig({\n${n.map(([e,t])=>` ${e}: ${r(t,1)},`).join(`
5
5
  `)}\n});\n`;let i=e,s=i.match(/defineConfig\s*\(\s*\{/);if(!s||s.index===void 0)return i;for(let[e,t]of n){let n=i.match(/defineConfig\s*\(\s*\{/);if(!n||n.index===void 0)break;let s=i.indexOf(`{`,n.index),c=a(i,s);if(c===-1)break;let l=r(t,1),u=o(i,s,c,e);i=u?`${i.slice(0,u[0])}${l}${i.slice(u[1])}`:`${i.slice(0,s+1)}\n ${e}: ${l},${i.slice(s+1)}`}return i}function c(n,r){let i=e.join(n,`vite.config.ts`);return{path:i,content:s(t.existsSync(i)?t.readFileSync(i,`utf-8`):void 0,r)}}function l(e,n,r){let i=c(e,n);return r&&t.writeFileSync(i.path,i.content,`utf-8`),i.path}export{o as findTopLevelValue,a as matchBracket,s as mergeViteConfig,c as renderViteTarget,r as serializeTs,l as writeViteTarget};
@@ -8,6 +8,14 @@ export declare const VITE_CONFIG_FILES: readonly ['vite.config.ts', 'vite.config
8
8
  export declare function findViteConfig(cwd: string): string | undefined;
9
9
  /** The nearest `dbx.config.*` in `cwd`, if present. */
10
10
  export declare function findDbxConfig(cwd: string): string | undefined;
11
+ /**
12
+ * Deep-merge two object-literal texts: nested objects are merged recursively and
13
+ * every other value (arrays included) from `incoming` replaces the base's.
14
+ *
15
+ * Used when folding a hand-written `vite.config.*` into an existing
16
+ * `toolchain.vite`, so the settings already there are kept instead of replaced.
17
+ */
18
+ export declare function mergeViteObjects(base: string, incoming: string): string;
11
19
  /**
12
20
  * Extract the object literal passed to `defineConfig(...)`, or the
13
21
  * default-exported object when there is no `defineConfig`.
@@ -31,15 +39,29 @@ export declare function scanLiteralObject(text: string): {
31
39
  };
32
40
  /**
33
41
  * Fold `objectText` into the `toolchain.vite` of a `dbx.config.*` source by
34
- * text-splicing (inserting or replacing the `vite` value), never rewriting the
35
- * whole file. Returns the new source, or an error when the `toolchain` object
36
- * cannot be located.
42
+ * text-splicing (inserting the `vite` key, or deep-merging into an existing
43
+ * object), never rewriting the whole file. Returns the new source, or an error
44
+ * when the `toolchain` object cannot be located.
37
45
  */
38
46
  export declare function foldViteIntoConfig(source: string, objectText: string): {
39
47
  content: string;
40
48
  } | {
41
49
  error: string;
42
50
  };
51
+ /**
52
+ * Fold an object literal into a top-level `toolchain.<section>` (or deep-merge
53
+ * into the existing object), without the Vite-specific `config: true` rewrite.
54
+ */
55
+ export declare function foldToolchainSection(source: string, section: string, objectText: string): {
56
+ content: string;
57
+ } | {
58
+ error: string;
59
+ };
60
+ /** Render a fresh `dbx.config.ts` with one or more folded toolchain sections. */
61
+ export declare function renderFreshSectionsConfig(sections: {
62
+ key: string;
63
+ objectText: string;
64
+ }[]): string;
43
65
  /**
44
66
  * Ensure `fmt.ignorePatterns` contains `'/vite.config.ts'` in a folded Vite
45
67
  * object literal, so Oxfmt does not reformat the generated root `vite.config.ts`
@@ -2,5 +2,10 @@ import{default as e}from"node:path";import"node:url";import.meta.url;import{CONF
2
2
  `;)t++;return t}if(n===`/`&&r===`*`){for(t+=2;t<e.length&&(e[t]!==`*`||e[t+1]!==`/`);)t++;return t+2}if(n===`"`||n===`'`){let r=n;for(t++;t<e.length&&e[t]!==r;)e[t]===`\\`&&t++,t++;return t+1}return t}function l(e,t){let n=e.lastIndexOf(`
3
3
  `,t-1)+1;return e.slice(n).match(/^[ \t]*/)?.[0]??``}function u(e,t){return e.split(`
4
4
  `).map((e,n)=>n===0?e:`${t}${e}`).join(`
5
- `)}function d(e){let t=e.match(/\bdefineConfig\s*\(/),n=0;if(t&&t.index!==void 0)n=t.index+t[0].length;else{let t=e.match(/export\s+default\s*/);if(!t||t.index===void 0)return;n=t.index+t[0].length}let i=n;for(;i<e.length&&e[i]!==`{`;)i++;if(i>=e.length)return;let a=r(e,i);return a===-1?void 0:[i,a]}function f(e){let t=e.match(/\bdefineConfig\s*\(/),n=-1;if(t&&t.index!==void 0)n=t.index+t[0].length;else{let t=e.match(/export\s+default\s*/);t&&t.index!==void 0&&(n=t.index+t[0].length)}if(n===-1)return{error:"no `defineConfig(...)` call or default-exported object found"};for(;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]!==`{`)return{error:`the config value is not an object literal (it is a variable or an expression)`};let i=r(e,n);return i===-1?{error:`unbalanced braces in the config object`}:{text:e.slice(n,i)}}function p(e){let t=0;for(;t<e.length;){let n=e[t];if(n==="`")return{ok:!1,reason:`template literal`};let r=c(e,t);if(r!==t)t=r;else{if(n===`.`&&e[t+1]===`.`&&e[t+2]===`.`)return{ok:!1,reason:"spread (`...`)"};if(/[A-Za-z_$]/.test(n)){let n=t;for(;n<e.length&&/[\w$]/.test(e[n]);)n++;let r=e.slice(t,n),i=n;for(;i<e.length&&/\s/.test(e[i]);)i++;if(e[i]!==`:`&&![`true`,`false`,`null`,`undefined`].includes(r))return{ok:!1,reason:`non-literal value \`${r}\``};t=n}else t++}}return{ok:!0}}function m(e,t){let r=d(e);if(!r)return{error:`could not locate the config root object`};let[i,a]=r,o=n(e,i,a,`toolchain`);if(!o)return{error:"the config has no `toolchain` object to add `vite` to"};let[s,c]=o,f=n(e,s,c,`vite`);if(f){let[n,r]=f,i=u(t,l(e,n));return{content:`${e.slice(0,n)}${i}${e.slice(r)}`}}let p=`${l(e,s)} `,m=u(t,p);return{content:`${e.slice(0,s+1)}\n${p}vite: ${m},${e.slice(s+1)}`}}const h=`/vite.config.ts`;function g(e){return e.includes(`resolveVite(`)&&e.includes(`@deltabox/toolchain/vite`)}function _(e){return[`import { defineConfig } from '@deltabox/toolchain';`,``,`export default defineConfig({`,` toolchain: {`,` vite: ${u(e,` `)},`,` },`,`});`,``].join(`
6
- `)}function v(e){let t=e.indexOf(`{`);if(t===-1)return e;let i=r(e,t);if(i===-1)return e;let a=`'${h}'`,o=n(e,t,i,`fmt`);if(o&&e[o[0]]===`{`&&e[o[1]-1]===`}`){let[t,r]=o,i=n(e,t,r,`ignorePatterns`);if(i){let[t,n]=i;return e.slice(t,n).includes(h)?e:e[t]===`[`?`${e.slice(0,t+1)}${a}, ${e.slice(t+1)}`:`${e.slice(0,t)}[${a}]${e.slice(n)}`}return`${e.slice(0,t+1)} ignorePatterns: [${a}],${e.slice(t+1)}`}return o?`${e.slice(0,o[0])}{ ignorePatterns: [${a}] }${e.slice(o[1])}`:`${e.slice(0,t+1)} fmt: { ignorePatterns: [${a}] },${e.slice(t+1)}`}const y={id:`vite-to-toolchain`,from:`vite`,to:`toolchain`,description:"Fold a hand-written vite.config.* into dbx.config.* (`toolchain.vite`).",detect:e=>{let t=o(e);if(!t)return!1;try{return!g(i.readFileSync(t,`utf-8`))}catch{return!0}},run:async t=>{let n=o(t.cwd);if(!n)throw Error(`vite-to-toolchain: no vite.config.* found.`);let r=i.readFileSync(n,`utf-8`).replace(/^\uFEFF/,``),a=[`Source: ${e.basename(n)}.`],c=[],l=()=>({id:y.id,from:`vite`,to:`toolchain`,written:[],files:[],unmapped:c,notes:a});if(g(r))return a.push("Already managed by `dbx sync`; nothing to fold."),l();let u=f(r);if(`error`in u)return c.push({source:e.basename(n),reason:u.error}),a.push(`Left vite.config.* unchanged; fold it by hand.`),l();let d=p(u.text);if(!d.ok)return c.push({source:e.basename(n),reason:`cannot fold faithfully (${d.reason})`}),a.push(`The config references helpers/imports or non-literal expressions; fold it by hand.`),l();let b=v(u.text),x=`added \`${h}\` to \`fmt.ignorePatterns\`; run \`dbx sync\` to regenerate vite.config.ts.`,S=s(t.cwd),C=()=>t.ignoreViteConfigFile?(a.push(`Kept \`${e.basename(n)}\` (ignoreViteConfigFile).`),[]):(t.write&&i.rmSync(n,{force:!0}),a.push(`Removed \`${e.basename(n)}\` (recreated by \`dbx sync\`).`),[n]);if(S&&S.endsWith(`.json`))return c.push({source:e.basename(S),reason:`JSON configs cannot hold the extracted object by text-splice`}),a.push(`Fold into the JSON config by hand.`),l();if(!S){let n=e.join(t.cwd,`dbx.config.ts`),r={path:n,content:_(b)};t.write&&i.writeFileSync(n,r.content,`utf-8`);let o=C();return a.push(`Created \`${e.basename(n)}\` with the folded \`toolchain.vite\`; ${x}`),{id:y.id,from:`vite`,to:`toolchain`,written:[n],removed:o,files:[r],notes:a}}let w=m(i.readFileSync(S,`utf-8`).replace(/^\uFEFF/,``),b);if(`error`in w)return c.push({source:e.basename(S),reason:w.error}),a.push("Left dbx.config.* unchanged; fold `toolchain.vite` in by hand."),l();let T={path:S,content:w.content};t.write&&i.writeFileSync(S,T.content,`utf-8`);let E=C();return a.push(`Folded into \`toolchain.vite\` (${e.basename(S)}); ${x}`),{id:y.id,from:`vite`,to:`toolchain`,written:[S],removed:E,files:[T],notes:a}}};export{a as VITE_CONFIG_FILES,v as ensureViteFmtIgnore,f as extractViteObject,s as findDbxConfig,o as findViteConfig,m as foldViteIntoConfig,p as scanLiteralObject,y as viteToToolchain};
5
+ `)}function d(e,t){return t?e.split(`
6
+ `).map((e,n)=>n>0&&e.startsWith(t)?e.slice(t.length):e).join(`
7
+ `):e}function f(e,t,n){let r=[],i=1;for(let a=t+1;a<n;a++){let t=c(e,a);if(t!==a){a=t-1;continue}let o=e[a];if(o===`{`||o===`[`)i++;else if(o===`}`||o===`]`)i--;else if(i===1&&/[A-Za-z_$]/.test(o)){let t=a;for(;t<n&&/[\w$]/.test(e[t]);)t++;let i=t;for(;i<n&&/\s/.test(e[i]);)i++;i<n&&e[i]===`:`&&r.push(e.slice(a,t)),a=t-1}}return r}function p(e,t){let i=e.indexOf(`{`),a=i===-1?-1:r(e,i);if(i===-1||a===-1)return e;let o=a-1,s=e.slice(0,o),c=e.slice(o),u=s.replace(/\s+$/,``),d=l(e,o),p=f(e,i,a)[0],m=p===void 0?void 0:n(e,i,a,p),h=s.includes(`
8
+ `)&&m?l(e,m[0]):`${d} `;return`${u}${u.endsWith(`{`)||u.endsWith(`,`)?``:`,`}${t.map(({key:e,value:t})=>`\n${h}${e}: ${t},`).join(``)}\n${d}${c}`}function m(e,t){let i=e.indexOf(`{`),a=t.indexOf(`{`),o=i===-1?-1:r(e,i),s=a===-1?-1:r(t,a);if(i===-1||o===-1||a===-1||s===-1)return t;let c=[],l=[];for(let r of f(t,a,s)){let u=n(t,a,s,r);if(!u)continue;let d=t.slice(u[0],u[1]),f=n(e,i,o,r);if(f){let t=e.slice(f[0],f[1]),n=t.trimStart().startsWith(`{`)&&d.trimStart().startsWith(`{`)?m(t,d):d;c.push({start:f[0],end:f[1],text:n})}else l.push({key:r,value:d})}let u=e;for(let e of c.sort((e,t)=>t.start-e.start))u=`${u.slice(0,e.start)}${e.text}${u.slice(e.end)}`;return l.length>0?p(u,l):u}function h(e){let t=e.indexOf(`{`),i=t===-1?-1:r(e,t);if(t===-1||i===-1)return e;let a=n(e,t,i,`config`);return!a||e.slice(a[0],a[1]).trim()!==`false`?e:`${e.slice(0,a[0])}true${e.slice(a[1])}`}function g(e){let t=e.match(/\bdefineConfig\s*\(/),n=0;if(t&&t.index!==void 0)n=t.index+t[0].length;else{let t=e.match(/export\s+default\s*/);if(!t||t.index===void 0)return;n=t.index+t[0].length}let i=n;for(;i<e.length&&e[i]!==`{`;)i++;if(i>=e.length)return;let a=r(e,i);return a===-1?void 0:[i,a]}function _(e){let t=e.match(/\bdefineConfig\s*\(/),n=-1;if(t&&t.index!==void 0)n=t.index+t[0].length;else{let t=e.match(/export\s+default\s*/);t&&t.index!==void 0&&(n=t.index+t[0].length)}if(n===-1)return{error:"no `defineConfig(...)` call or default-exported object found"};for(;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]!==`{`)return{error:`the config value is not an object literal (it is a variable or an expression)`};let i=r(e,n);return i===-1?{error:`unbalanced braces in the config object`}:{text:e.slice(n,i)}}function v(e){let t=0;for(;t<e.length;){let n=e[t];if(n==="`")return{ok:!1,reason:`template literal`};let r=c(e,t);if(r!==t)t=r;else{if(n===`.`&&e[t+1]===`.`&&e[t+2]===`.`)return{ok:!1,reason:"spread (`...`)"};if(/[A-Za-z_$]/.test(n)){let n=t;for(;n<e.length&&/[\w$]/.test(e[n]);)n++;let r=e.slice(t,n),i=n;for(;i<e.length&&/\s/.test(e[i]);)i++;if(e[i]!==`:`&&![`true`,`false`,`null`,`undefined`].includes(r))return{ok:!1,reason:`non-literal value \`${r}\``};t=n}else t++}}return{ok:!0}}function y(e,t){let r=g(e);if(!r)return{error:`could not locate the config root object`};let[i,a]=r,o=n(e,i,a,`toolchain`);if(!o)return{error:"the config has no `toolchain` object to add `vite` to"};let[s,c]=o,f=n(e,s,c,`vite`);if(f){let[n,r]=f,i=l(e,n),a=d(e.slice(n,r),i),o=u(h(a.trimStart().startsWith(`{`)&&t.trimStart().startsWith(`{`)?m(a,t):t),i);return{content:`${e.slice(0,n)}${o}${e.slice(r)}`}}let p=`${l(e,s)} `,_=u(t,p);return{content:`${e.slice(0,s+1)}\n${p}vite: ${_},${e.slice(s+1)}`}}function b(e,t,r){let i=g(e);if(!i)return{error:`could not locate the config root object`};let[a,o]=i,s=n(e,a,o,`toolchain`);if(!s)return{error:`the config has no \`toolchain\` object to add \`${t}\` to`};let[c,f]=s,p=n(e,c,f,t);if(p){let[t,n]=p,i=l(e,t),a=d(e.slice(t,n),i),o=a.trimStart().startsWith(`{`)&&r.trimStart().startsWith(`{`)?m(a,r):r;return{content:`${e.slice(0,t)}${u(o,i)}${e.slice(n)}`}}let h=`${l(e,c)} `;return{content:`${e.slice(0,c+1)}\n${h}${t}: ${u(r,h)},${e.slice(c+1)}`}}function x(e){return[`import { defineConfig } from '@deltabox/toolchain';`,``,`export default defineConfig({`,` toolchain: {`,e.map(({key:e,objectText:t})=>` ${e}: ${u(t,` `)},`).join(`
9
+ `),` },`,`});`,``].join(`
10
+ `)}const S=`/vite.config.ts`;function C(e){return/resolveVite\s*(?:<[^>]*>)?\s*\(/.test(e)&&e.includes(`@deltabox/toolchain/vite`)}function w(e){return[`import { defineConfig } from '@deltabox/toolchain';`,``,`export default defineConfig({`,` toolchain: {`,` vite: ${u(e,` `)},`,` },`,`});`,``].join(`
11
+ `)}function T(e){let t=e.indexOf(`{`);if(t===-1)return e;let i=r(e,t);if(i===-1)return e;let a=`'${S}'`,o=n(e,t,i,`fmt`);if(o&&e[o[0]]===`{`&&e[o[1]-1]===`}`){let[t,r]=o,i=n(e,t,r,`ignorePatterns`);if(i){let[t,n]=i;return e.slice(t,n).includes(S)?e:e[t]===`[`?`${e.slice(0,t+1)}${a}, ${e.slice(t+1)}`:`${e.slice(0,t)}[${a}]${e.slice(n)}`}return`${e.slice(0,t+1)} ignorePatterns: [${a}],${e.slice(t+1)}`}return o?`${e.slice(0,o[0])}{ ignorePatterns: [${a}] }${e.slice(o[1])}`:`${e.slice(0,t+1)} fmt: { ignorePatterns: [${a}] },${e.slice(t+1)}`}const E={id:`vite-to-toolchain`,from:`vite`,to:`toolchain`,description:"Fold a hand-written vite.config.* into dbx.config.* (`toolchain.vite`).",detect:e=>{let t=o(e);if(!t)return!1;try{return!C(i.readFileSync(t,`utf-8`))}catch{return!0}},run:async t=>{let n=o(t.cwd);if(!n)throw Error(`vite-to-toolchain: no vite.config.* found.`);let r=i.readFileSync(n,`utf-8`).replace(/^\uFEFF/,``),a=[`Source: ${e.basename(n)}.`],c=[],l=()=>({id:E.id,from:`vite`,to:`toolchain`,written:[],files:[],unmapped:c,notes:a});if(C(r))return a.push("Already managed by `dbx sync`; nothing to fold."),l();let u=_(r);if(`error`in u)return c.push({source:e.basename(n),reason:u.error}),a.push(`Left vite.config.* unchanged; fold it by hand.`),l();let d=v(u.text);if(!d.ok)return c.push({source:e.basename(n),reason:`cannot fold faithfully (${d.reason})`}),a.push(`The config references helpers/imports or non-literal expressions; fold it by hand.`),l();let f=T(u.text),p=`added \`${S}\` to \`fmt.ignorePatterns\`; run \`dbx sync\` to regenerate vite.config.ts.`,m=s(t.cwd),h=()=>t.ignoreViteConfigFile?(a.push(`Kept \`${e.basename(n)}\` (ignoreViteConfigFile).`),[]):(t.write&&i.rmSync(n,{force:!0}),a.push(`Removed \`${e.basename(n)}\` (recreated by \`dbx sync\`).`),[n]);if(m&&m.endsWith(`.json`))return c.push({source:e.basename(m),reason:`JSON configs cannot hold the extracted object by text-splice`}),a.push(`Fold into the JSON config by hand.`),l();if(!m){let n=e.join(t.cwd,`dbx.config.ts`),r={path:n,content:w(f)};t.write&&i.writeFileSync(n,r.content,`utf-8`);let o=h();return a.push(`Created \`${e.basename(n)}\` with the folded \`toolchain.vite\`; ${p}`),{id:E.id,from:`vite`,to:`toolchain`,written:[n],removed:o,files:[r],notes:a}}let g=y(i.readFileSync(m,`utf-8`).replace(/^\uFEFF/,``),f);if(`error`in g)return c.push({source:e.basename(m),reason:g.error}),a.push("Left dbx.config.* unchanged; fold `toolchain.vite` in by hand."),l();let b={path:m,content:g.content};t.write&&i.writeFileSync(m,b.content,`utf-8`);let x=h();return a.push(`Folded into \`toolchain.vite\` (${e.basename(m)}); ${p}`),{id:E.id,from:`vite`,to:`toolchain`,written:[m],removed:x,files:[b],notes:a}}};export{a as VITE_CONFIG_FILES,T as ensureViteFmtIgnore,_ as extractViteObject,s as findDbxConfig,o as findViteConfig,b as foldToolchainSection,y as foldViteIntoConfig,m as mergeViteObjects,x as renderFreshSectionsConfig,v as scanLiteralObject,E as viteToToolchain};
@@ -18,6 +18,13 @@ export declare const CATALOG_MARKER = "# Managed by @deltabox/toolchain (catalog
18
18
  export declare const CATALOG_PACKAGE_MANAGERS: readonly ['yarn', 'pnpm', 'bun'];
19
19
  /** Whether a package manager supports catalogs (defaults to Yarn). */
20
20
  export declare function supportsCatalogs(packageManager: string | undefined): boolean;
21
+ /**
22
+ * Whether a directory already declares a default catalog its workspaces can
23
+ * reference with `catalog:`. Bun keeps it in `package.json`; Yarn/pnpm in their
24
+ * catalog file. When `required` is given, every package must be present (so a
25
+ * partial catalog never produces dangling `catalog:` references).
26
+ */
27
+ export declare function hasCatalog(root: string, packageManager: string | undefined, required?: string[]): boolean;
21
28
  /** A resolved catalog: a default map and/or named catalogs. */
22
29
  export interface Catalog {
23
30
  /** The default catalog (`package -> version range`). */
@@ -1 +1 @@
1
- import{default as e}from"node:path";import"node:url";import.meta.url;import{sectionConfig as t,sectionEnabled as n}from"../../shared/src/toolchain.js";import{toYaml as r}from"../../shared/src/yaml.js";import"../../shared/src/index.js";import i from"node:fs";const a="# Managed by @deltabox/toolchain (catalogs) - edit dbx.config.* and run `dbx sync`.",o=[`yarn`,`pnpm`,`bun`];function s(e){let t=e??`yarn`;return o.includes(t)}function c(e){switch(e??`yarn`){case`yarn`:return`.yarnrc.yml`;case`pnpm`:return`pnpm-workspace.yaml`;default:return}}function l(e){return`${a}\n${e}`}function u(e){let t={nodeLinker:`node-modules`};return e.packages&&Object.keys(e.packages).length>0&&(t.catalog=e.packages),e.named&&Object.keys(e.named).length>0&&(t.catalogs=e.named),l(r(t))}function d(e,t){let n={};return t&&t.length>0&&(n.packages=t),e.packages&&Object.keys(e.packages).length>0&&(n.catalog=e.packages),e.named&&Object.keys(e.named).length>0&&(n.catalogs=e.named),l(r(n))}function f(){return{name:`catalogs`,projectTypes:[`monorepo-root`,`project`,`monorepo-workspace`],keep:[`.yarnrc.yml`,`pnpm-workspace.yaml`],enabled:e=>n(e.catalogs),run:n=>{let r=t(n.config.catalogs)??{},a=n.config.project?.packageManager??`yarn`,o={...r.packages?{packages:r.packages}:{},...r.named?{named:r.named}:{}};if(Object.keys(o.packages??{}).length===0&&!o.named)return[];if(!s(a))return n.warn(`catalogs: ${a} has no catalog support; nothing written.`),[];if(a===`bun`)return n.warn(`catalogs: Bun catalogs live in package.json; declare them there (or use yarn/pnpm).`),[];let l=c(a);if(!l)return[];let f=e.resolve(n.cwd,l);return i.existsSync(f)&&!i.readFileSync(f,`utf-8`).includes("# Managed by @deltabox/toolchain (catalogs) - edit dbx.config.* and run `dbx sync`.")?(n.warn(`catalogs: ${l} exists and is not toolchain-managed; leaving it untouched.`),[]):[{path:l,content:a===`pnpm`?d(o,n.projectType===`monorepo-root`?[`packages/*`]:void 0):u(o)}]}}}export{a as CATALOG_MARKER,o as CATALOG_PACKAGE_MANAGERS,c as catalogFileFor,f as catalogsSyncTask,d as renderPnpmWorkspace,u as renderYarnrc,s as supportsCatalogs};
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{readJsonFile as t}from"../../shared/src/fs-utils.js";import{sectionConfig as n,sectionEnabled as r}from"../../shared/src/toolchain.js";import{toYaml as i}from"../../shared/src/yaml.js";import"../../shared/src/index.js";import a from"node:fs";const o="# Managed by @deltabox/toolchain (catalogs) - edit dbx.config.* and run `dbx sync`.",s=[`yarn`,`pnpm`,`bun`];function c(e){let t=e??`yarn`;return s.includes(t)}function l(e){let t=[],n=!1;for(let r of e.split(/\r?\n/)){if(/^catalog:\s*(?:#.*)?$/.test(r)){n=!0;continue}if(!n)continue;if(/^\S/.test(r))break;let e=r.match(/^\s+"?([^":\s][^":]*)"?:\s*/);e?.[1]&&t.push(e[1])}return t}function u(n,r,i=[]){let o=r??`yarn`;if(!c(o))return!1;let s=e=>i.length===0?e.length>0:i.every(t=>e.includes(t));if(o===`bun`){let r=t(e.join(n,`package.json`));return r?s(Object.keys(r.workspaces?.catalog??{})):!1}let u=d(o);if(!u)return!1;try{return s(l(a.readFileSync(e.join(n,u),`utf-8`).replace(/^\uFEFF/,``)))}catch{return!1}}function d(e){switch(e??`yarn`){case`yarn`:return`.yarnrc.yml`;case`pnpm`:return`pnpm-workspace.yaml`;default:return}}function f(e){return`${o}\n${e}`}function p(e){let t={nodeLinker:`node-modules`};return e.packages&&Object.keys(e.packages).length>0&&(t.catalog=e.packages),e.named&&Object.keys(e.named).length>0&&(t.catalogs=e.named),f(i(t))}function m(e,t){let n={};return t&&t.length>0&&(n.packages=t),e.packages&&Object.keys(e.packages).length>0&&(n.catalog=e.packages),e.named&&Object.keys(e.named).length>0&&(n.catalogs=e.named),f(i(n))}function h(){return{name:`catalogs`,projectTypes:[`monorepo-root`,`project`],keep:[`.yarnrc.yml`,`pnpm-workspace.yaml`],enabled:e=>r(e.catalogs),run:t=>{let r=n(t.config.catalogs)??{},i=String(t.tokens.packageManager??`yarn`),o={...r.packages?{packages:r.packages}:{},...r.named?{named:r.named}:{}};if(Object.keys(o.packages??{}).length===0&&!o.named)return[];if(!c(i))return t.warn(`catalogs: ${i} has no catalog support; nothing written.`),[];if(i===`bun`)return t.warn(`catalogs: Bun catalogs live in package.json; declare them there (or use yarn/pnpm).`),[];let s=d(i);if(!s)return[];let l=e.resolve(t.cwd,s);return a.existsSync(l)&&!a.readFileSync(l,`utf-8`).includes("# Managed by @deltabox/toolchain (catalogs) - edit dbx.config.* and run `dbx sync`.")?(t.warn(`catalogs: ${s} exists and is not toolchain-managed; leaving it untouched.`),[]):[{path:s,content:i===`pnpm`?m(o,t.projectType===`monorepo-root`?[`packages/*`]:void 0):p(o)}]}}}export{o as CATALOG_MARKER,s as CATALOG_PACKAGE_MANAGERS,d as catalogFileFor,h as catalogsSyncTask,u as hasCatalog,m as renderPnpmWorkspace,p as renderYarnrc,c as supportsCatalogs};
@@ -1 +1 @@
1
- import{default as e}from"node:path";import"node:url";import.meta.url;import{logger as t}from"../../../shared/src/logger.js";import"../../../shared/src/index.js";import{createMonorepoRootFiles as n,createRootProjectFiles as r,createWorkspaceFiles as i,writeGeneratedFiles as a}from"../typescript.js";import{generateProjectConfigs as o}from"../config.js";const s=[{flags:`--no-config`,description:`Skip the dbx.config.ts file.`},{flags:`--type <type>`,description:`Project type: project | monorepo-root | monorepo-workspace.`}],c={flags:`--package-manager <pm>`,description:`Package manager: yarn (default) | pnpm | npm | bun.`},l=[`project`,`monorepo-root`,`monorepo-workspace`];function u(e,t){let n=String(e.name??t.project?.name??``).trim();if(!n)throw Error("a project name is required: pass `--name <name>` or set `project.name` in dbx.config.*.");return n}function d(t,n){return t===`.`?e.basename(e.resolve(n)):t}function f(e,t){let n=e.type??t;if(!l.includes(n))throw Error(`invalid project type "${n}" (expected one of: ${l.join(`, `)}).`);return n}function p(){return[{name:`project:init`,description:`Scaffold a single-package TypeScript project.`,options:[{flags:`-n, --name <name>`,description:`Project name.`},{flags:`-s, --scope <scope>`,description:`npm scope, eg. @acme.`},{flags:`-o, --out <dir>`,description:`Output directory (default: cwd).`},c,...s],run:(e,n)=>{let i=e.out??n.cwd,o=d(u(e,n.config),i),s=r({name:o,...e.scope?{scope:e.scope}:{},...e.packageManager?{packageManager:e.packageManager}:{},type:f(e,`project`),includeConfig:e.config??!0}),c=a(s,i);for(let e of c)t.info(`Created ${e}`)}},{name:`project:init:monorepo`,description:`Scaffold a monorepo root (add --example for one example workspace).`,options:[{flags:`-n, --name <name>`,description:`Project name.`},{flags:`-s, --scope <scope>`,description:`npm scope, eg. @acme.`},{flags:`-o, --out <dir>`,description:`Output directory (default: cwd).`},{flags:`--example`,description:`Also scaffold one example workspace package.`},c,...s],run:(e,r)=>{let o=e.out??r.cwd,s=d(u(e,r.config),o),c=e.scope??r.config.project?.scope??`@${s}`,l=e.config??!0,p=f(e,`monorepo-root`),m=!!e.example,h=e.packageManager,g=n({name:s,scope:c,type:p,includeConfig:l,...h?{packageManager:h}:{},workspaces:m?[{alias:`core`,dir:`packages/core`}]:[]});m&&g.push(...i({name:s,scope:c,wsName:`core`,wsDir:`packages/core`,type:`monorepo-workspace`,includeConfig:l,useCatalog:!0,...h?{packageManager:h}:{}}).map(e=>({...e,path:`packages/core/${e.path}`})));let _=a(g,o);for(let e of _)t.info(`Created ${e}`)}},{name:`project:init:workspace`,description:`Scaffold a monorepo workspace package into an existing monorepo root.`,options:[{flags:`-n, --name <name>`,description:`Workspace package name (unscoped).`},{flags:`-s, --scope <scope>`,description:`npm scope, eg. @acme.`},{flags:`-r, --root <dir>`,description:`Monorepo root (default: cwd).`},{flags:`-d, --dir <dir>`,description:`Workspace dir relative to the root (default: packages/<name>).`},c,...s],run:(e,n)=>{let r=e.root??n.cwd,o=d(u(e,n.config),r),s=e.scope??n.config.project?.scope??`@${o}`,c=(e.dir??`packages/${o}`).replace(/\\/g,`/`).replace(/\/+$/,``),l=e.config??!0,p=f(e,`monorepo-workspace`),m=e.packageManager,h=i({name:o,scope:s,wsName:o,wsDir:c,type:p,includeConfig:l,...m?{packageManager:m}:{}}).map(e=>({...e,path:`${c}/${e.path}`})),g=a(h,r);for(let e of g)t.info(`Created ${e}`)}},{name:`project:config`,description:`Generate dbx.config.ts for existing projects that are missing one.`,options:[{flags:`--cwd <dir>`,description:`Root to scan (default: cwd).`},{flags:`--include <pattern...>`,description:`Only projects matching these patterns (glob or substring).`},{flags:`--exclude <pattern...>`,description:`Skip projects matching these patterns (glob or substring).`},{flags:`--type <type>`,description:`Force a project type for every config.`},{flags:`--force`,description:`Overwrite configs that already exist.`},{flags:`--dry-run`,description:`Report what would be written without writing.`},{flags:`--json`,description:`Print the result as JSON.`}],run:(e,n)=>{let r=e.cwd??n.cwd,i=o({root:r,...e.include?{include:e.include}:{},...e.exclude?{exclude:e.exclude}:{},...e.type?{type:e.type}:{},force:!!e.force,dryRun:!!e.dryRun});if(e.json){t.raw(JSON.stringify(i,null,4));return}let a=i.dryRun?`would create`:`created`;t.info(`${a} ${i.created.length} config(s), skipped ${i.skipped.length}.`);for(let e of i.configs)e.created&&t.info(` + ${e.rel===`.`?`dbx.config.ts`:`${e.rel}/dbx.config.ts`} [${e.type}]`)}}]}export{p as projectCommands};
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{logger as t}from"../../../shared/src/logger.js";import{sectionConfig as n}from"../../../shared/src/toolchain.js";import"../../../shared/src/index.js";import{loadToolchainConfig as r}from"../../../core/src/loader.js";import"../../../core/src/index.js";import{hasCatalog as i}from"../catalogs.js";import{tsconfigFileNames as a}from"../../../tsconfig/src/sync.js";import"../../../tsconfig/src/index.js";import{SCAFFOLD_CATALOG as o,createMonorepoRootFiles as s,createRootProjectFiles as c,createWorkspaceFiles as l,findRootOxcFiles as u,upsertWorkspaceTsconfig as d,writeGeneratedFiles as f}from"../typescript.js";import{generateProjectConfigs as p}from"../config.js";const m=[{flags:`--no-config`,description:`Skip the dbx.config.ts file.`},{flags:`--type <type>`,description:`Project type: project | monorepo-root | monorepo-workspace.`},{flags:`--force`,description:`Overwrite existing files in the output directory.`}],h={flags:`--package-manager <pm>`,description:`Package manager: yarn (default) | pnpm | npm | bun.`},g=[`project`,`monorepo-root`,`monorepo-workspace`];function _(e){if(e!=null&&e!==``)return String(e)}function v(e,t={}){let n=_(e.description);return{...t.description!==!1&&n?{description:n}:{},..._(e.author)?{author:_(e.author)}:{},..._(e.license)?{license:_(e.license)}:{},..._(e.homepage)?{homepage:_(e.homepage)}:{},..._(e.repo)?{repo:_(e.repo)}:{},..._(e.nodeVersion)?{nodeVersion:_(e.nodeVersion)}:{}}}function y(e,t){let n=_(t.packageManager),r=e.packageManager??n??`yarn`,i=r===n?_(t.packageManagerVersion)??_(t.yarnVersion):void 0;return{packageManager:r,...i?{packageManagerVersion:i}:{}}}function b(e,t){let n=String(e.name??t.project?.name??``).trim();if(!n)throw Error("a project name is required: pass `--name <name>` or set `project.name` in dbx.config.*.");return n}function x(t,n){return t===`.`?e.basename(e.resolve(n)):t}function S(e,t){let n=e.type??t;if(!g.includes(n))throw Error(`invalid project type "${n}" (expected one of: ${g.join(`, `)}).`);return n}function C(e){return n(e.tsconfig)?.extends}function w(){return[{name:`project:init`,description:`Scaffold a single-package TypeScript project.`,options:[{flags:`-n, --name <name>`,description:`Project name.`},{flags:`-s, --scope <scope>`,description:`npm scope, eg. @acme.`},{flags:`-o, --out <dir>`,description:`Output directory (default: cwd).`},h,...m],run:(e,n)=>{let r=e.out??n.cwd,i=x(b(e,n.config),r),a=C(n.config),o=e.scope??_(n.tokens.scope),s=c({...v(n.tokens),name:i,...o?{scope:o}:{},...y(e,n.tokens),type:S(e,`project`),includeConfig:n.noConfig?!1:e.config??!0,rootOxc:u(r),...a?{tsconfigExtends:a}:{}}),l=f(s,r,{force:!!e.force});for(let e of l)t.info(`Created ${e}`)}},{name:`project:init:monorepo`,description:`Scaffold a monorepo root (add --example for one example workspace).`,options:[{flags:`-n, --name <name>`,description:`Project name.`},{flags:`-s, --scope <scope>`,description:`npm scope, eg. @acme.`},{flags:`-o, --out <dir>`,description:`Output directory (default: cwd).`},{flags:`--example`,description:`Also scaffold one example workspace package.`},h,...m],run:(e,n)=>{let r=e.out??n.cwd,i=x(b(e,n.config),r),a=e.scope??_(n.tokens.scope)??`@${i}`,o=n.noConfig?!1:e.config??!0,c=S(e,`monorepo-root`),u=!!e.example,d=y(e,n.tokens),p=C(n.config),m=s({...v(n.tokens),name:i,scope:a,type:c,includeConfig:o,...d,...p?{tsconfigExtends:p}:{},workspaces:u?[{alias:`core`,dir:`packages/core`}]:[]});u&&m.push(...l({...v(n.tokens,{description:!1}),name:i,scope:a,wsName:`core`,wsDir:`packages/core`,type:`monorepo-workspace`,includeConfig:o,useCatalog:!0,...d,...p?{tsconfigExtends:p}:{}}).map(e=>({...e,path:`packages/core/${e.path}`})));let h=f(m,r,{force:!!e.force});for(let e of h)t.info(`Created ${e}`)}},{name:`project:init:workspace`,description:`Scaffold a monorepo workspace package into an existing monorepo root.`,options:[{flags:`-n, --name <name>`,description:`Workspace package name (unscoped).`},{flags:`-s, --scope <scope>`,description:`npm scope, eg. @acme.`},{flags:`-r, --root <dir>`,description:`Monorepo root (default: cwd).`},{flags:`-d, --dir <dir>`,description:`Workspace dir relative to the root (default: packages/<name>).`},h,...m],run:async(n,s)=>{let c=n.root??s.cwd,{config:u,tokens:p}=e.resolve(c)===e.resolve(s.cwd)?{config:s.config,tokens:s.tokens}:await r(c,{tolerant:!0,skipHooks:!0,...s.noConfig?{noConfig:!0}:{}}),m=String(n.name??``).trim();if(!m)throw Error("a workspace name is required: pass `--name <name>` (the root project name is not the workspace name).");let h=x(m,c),g=_(p.name)??e.basename(e.resolve(c)),b=n.scope??_(p.scope)??`@${g}`,w=(n.dir??`packages/${h}`).replace(/\\/g,`/`).replace(/\/+$/,``),T=s.noConfig?!1:n.config??!0,E=S(n,`monorepo-workspace`),D=y(n,p),O=C(u),k=l({...v(p,{description:!1}),name:h,scope:b,wsName:h,wsDir:w,type:E,includeConfig:T,useCatalog:i(c,D.packageManager,Object.keys(o)),...D,...O?{tsconfigExtends:O}:{}}).map(e=>({...e,path:`${w}/${e.path}`})),A=f(k,c,{force:!!n.force});d(c,{alias:h,dir:w},b,a(u).rootFile);for(let e of A)t.info(`Created ${e}`)}},{name:`project:config`,description:`Generate dbx.config.ts for existing projects that are missing one.`,options:[{flags:`--cwd <dir>`,description:`Root to scan (default: cwd).`},{flags:`--include <pattern...>`,description:`Only projects matching these patterns (glob or substring).`},{flags:`--exclude <pattern...>`,description:`Skip projects matching these patterns (glob or substring).`},{flags:`--type <type>`,description:`Force a project type for every config.`},{flags:`--force`,description:`Overwrite configs that already exist.`},{flags:`--dry-run`,description:`Report what would be written without writing.`},{flags:`--json`,description:`Print the result as JSON.`}],run:(n,r)=>{let i=n.cwd??r.cwd,a=p({root:i,...n.include?{include:n.include}:{},...n.exclude?{exclude:n.exclude}:{},...n.type?{type:n.type}:{},force:!!n.force,dryRun:!!n.dryRun});if(n.json){t.raw(JSON.stringify(a,null,4));return}let o=a.dryRun?`would create`:`created`;t.info(`${o} ${a.created.length} config(s), skipped ${a.skipped.length}.`);for(let n of a.configs)n.created&&(t.info(` + ${n.rel===`.`?`dbx.config.ts`:`${n.rel}/dbx.config.ts`} [${n.type}]`),n.vite&&t.info(n.vite.folded?` vite: folded ${e.basename(n.vite.path)} into toolchain.vite (run \`dbx sync\`)`:` vite: left ${e.basename(n.vite.path)} alone (${n.vite.error})`))}}]}export{w as projectCommands};
@@ -37,6 +37,12 @@ export interface GeneratedProjectConfig {
37
37
  created: boolean;
38
38
  /** Why the project was skipped, when it was. */
39
39
  skipped?: string;
40
+ /** How an existing hand-written `vite.config.*` was handled. */
41
+ vite?: {
42
+ path: string;
43
+ folded: boolean;
44
+ error?: string;
45
+ };
40
46
  }
41
47
  export interface GenerateProjectConfigsResult {
42
48
  configs: GeneratedProjectConfig[];