@deltabox/toolchain 1.11.3 → 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 +316 -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,6 +1,6 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { ToolchainChangelogConfig } from "../../shared/src/config-types.js";
3
+ import { ChangelogConfig } from "../../shared/src/config-types.js";
4
4
  import "../../shared/src/index.js";
5
5
  import { parseArgsCli } from "./utils/args.js";
6
6
  import { formatBody, groupItems, parseCcSubject, renderGroups, ruleTitle, splitInlineDescription } from "./utils/format.js";
@@ -11,10 +11,10 @@ import { renderChangelogEntry } from "./utils/version.js";
11
11
  //#region packages/changelog/src/run.d.ts
12
12
  /**
13
13
  * Run the changelog pipeline (bump versions + write changelogs). `changelog` is
14
- * the consumer's `toolchain.changelog` section (threaded from `dbx changelog`);
14
+ * the consumer's `toolchain.ci.changelog` config (threaded from `dbx changelog`);
15
15
  * the standalone bin runs with the defaults (`versioning: true`, uniform).
16
16
  */
17
- export declare function runChangelog(argv?: string[], changelog?: ToolchainChangelogConfig): void;
17
+ export declare function runChangelog(argv?: string[], changelog?: ChangelogConfig): void;
18
18
  /** Alias kept for backwards compatibility. */
19
19
  export declare const main: typeof runChangelog;
20
20
  //#endregion
@@ -1 +1 @@
1
- import{resolve as e}from"node:path";import{fileURLToPath as t}from"node:url";import.meta.url;import{logger as n}from"../../shared/src/logger.js";import"../../shared/src/index.js";import{parseArgsCli as r}from"./utils/args.js";import{deriveBump as i,readCommits as a}from"./utils/git.js";import{changelogFiles as o,readRootVersion as s,repoRoot as c,writeVersion as l}from"./utils/repo.js";import{packageChangesForCurrent as u}from"./utils/packages.js";import"./utils/format.js";import{insertNewEntry as d,renderChangelogEntry as f,retagChangelogs as p}from"./utils/version.js";import{formatExistingChangelogs as m,parseExistingChangelog as h,reformatRootChangelog as g}from"./utils/reformat.js";import{buildSummary as _}from"./utils/summary.js";import{planVersions as v,resolveVersioning as y,writePackageVersion as b}from"./utils/versioning.js";import{writeChangelogs as x}from"./utils/write.js";import{existsSync as S,readFileSync as C,realpathSync as w,writeFileSync as T}from"node:fs";function E(t=process.argv.slice(2),w){let E=r(t);if(E.formatOnly){n.info(`[format-only] Reformatting ${o().length} changelog file(s)${E.dryRun?` (dry run)`:``}.`),m(E.dryRun,E.packageChanges);return}let D=s();if(E.version){let e=E.version.trim();if(!/^\d+\.\d+\.\d+$/.test(e))throw Error(`Invalid version: ${e}`);if(e===D){n.info(`Version is already ${e}; nothing to do.`);return}l(e),p(D,e),n.info(`Retagged versions ${D} -> ${e}.`);return}let O=D;if(E.baseVersion){if(!/^\d+\.\d+\.\d+$/.test(E.baseVersion.trim()))throw Error(`Invalid base version: ${E.baseVersion}`);O=E.baseVersion.trim()}let k=E.processingMethod,A=k===`all`,j=k!==`latest`&&k!==`all`?k:E.range,M=a(j),N=i(M),P=_(M),F=y(w),I=v({versioning:F,rootVersion:O,bump:N,range:j}),L=I.rootVersion;if(E.dryRun){let t=c(),r=e(t,`CHANGELOG.md`),i=S(r)?C(r,`utf8`):``,a=h(i)[0]?.version,o=E.packageChanges&&a?u(a):``,s=f(L,P,/* @__PURE__ */ new Date,!0,o);n.info(`[DRY-RUN] Range: ${j}`),n.info(`[DRY-RUN] Processing method: ${k}${A?` (backward reformat)`:``}`),n.info(`[DRY-RUN] Bump: ${N} (\`${O}\` -> \`${L}\`)`),n.info(`[DRY-RUN] Versioning: ${F.enabled?F.target:`disabled`}`),n.info(`[DRY-RUN] ${M.length} commit(s) scanned. Project files untouched.`),n.info(``),n.info(`Proposed new CHANGELOG.md entry (new version only):`),n.info(``),n.raw(s),n.info(`--- end of proposed entry ---`);let l=A?g(E.packageChanges):i,p=d(l,s),m=e(t,`CHANGELOG.proposed.md`);T(m,p,`utf8`),n.info(`Wrote ${m}`)}else{for(let[e,t]of I.writes)b(e,t);x(L,j,M,P,A,E.packageChanges,I.entries),F.enabled?n.info(`Bumped ${O} -> ${L} (${N}) from ${M.length} commit(s).`):n.info(`Wrote changelogs for ${L} (${N}) from ${M.length} commit(s); versioning disabled.`)}}const D=E,O=t(import.meta.url);process.argv[1]&&/[\\/]run\.[cm]?[jt]s$/.test(O)&&k(process.argv[1])===O&&E();function k(e){try{return w(e)}catch{return e}}export{D as main,E as runChangelog};
1
+ import{resolve as e}from"node:path";import{fileURLToPath as t}from"node:url";import.meta.url;import{logger as n}from"../../shared/src/logger.js";import{resolveCommitlintEnabled as r}from"../../shared/src/toolchain.js";import"../../shared/src/index.js";import{parseArgsCli as i}from"./utils/args.js";import{readCommits as a}from"./utils/git.js";import{changelogFiles as o,readRootVersion as s,repoRoot as c,writeVersion as l}from"./utils/repo.js";import{packageChangesForCurrent as u}from"./utils/packages.js";import"./utils/format.js";import{insertNewEntry as d,renderChangelogEntry as f,retagChangelogs as p}from"./utils/version.js";import{formatExistingChangelogs as m,parseExistingChangelog as h,reformatRootChangelog as g}from"./utils/reformat.js";import{buildSummary as _}from"./utils/summary.js";import{deriveCustomBump as v,planVersions as y,resolveVersioning as b,writePackageVersion as x}from"./utils/versioning.js";import{writeChangelogs as S}from"./utils/write.js";import{existsSync as C,readFileSync as w,realpathSync as T,writeFileSync as E}from"node:fs";import{spawnSync as D}from"node:child_process";function O(t=process.argv.slice(2),T){let O=i(t),k=T?.groups;if(O.formatOnly){n.info(`[format-only] Reformatting ${o().length} changelog file(s)${O.dryRun?` (dry run)`:``}.`),m(O.dryRun,O.packageChanges,k);return}let A=s();if(O.version){let e=O.version.trim();if(!/^\d+\.\d+\.\d+$/.test(e))throw Error(`Invalid version: ${e}`);if(e===A){n.info(`Version is already ${e}; nothing to do.`);return}l(e),p(A,e),n.info(`Retagged versions ${A} -> ${e}.`);return}let j=A;if(O.baseVersion){if(!/^\d+\.\d+\.\d+$/.test(O.baseVersion.trim()))throw Error(`Invalid base version: ${O.baseVersion}`);j=O.baseVersion.trim()}let M=O.processingMethod,N=M===`all`,P=M!==`latest`&&M!==`all`?M:O.range,F=a(P),I=b(T),L=I.provider;if(!O.dryRun&&L===`changesets`){if(D(`npx`,[`--yes`,`changeset`,`version`],{cwd:c(),stdio:`inherit`,shell:process.platform===`win32`}).status!==0)throw Error(`changesets provider failed.`);n.info(`Ran the changesets provider; changesets owns the changelog/version output.`);return}let R=v(F,I.bump,I.allowOverBump),z=r(T),B=_(F,{commitlint:z,range:P,...k?{groups:k}:{},...I.commit?{commit:I.commit}:{}});if(L&&typeof L==`object`&&typeof L.run==`function`){let e=L.run({cwd:c(),changelog:T,records:F});typeof e==`string`&&(B=e)}else if(typeof L==`function`){let e=L({cwd:c(),changelog:T,records:F});typeof e==`string`&&(B=e)}let V=y({versioning:I,rootVersion:j,bump:R,range:P,...I.bump?{bumpRules:I.bump}:{},...I.allowOverBump?{allowOverBump:!0}:{}}),H=V.rootVersion;if(O.dryRun){let t=c(),r=e(t,`CHANGELOG.md`),i=C(r)?w(r,`utf8`):``,a=h(i)[0]?.version,o=O.packageChanges&&a?u(a):``,s=f(H,B,/* @__PURE__ */ new Date,!0,o);n.info(`[DRY-RUN] Range: ${P}`),n.info(`[DRY-RUN] Processing method: ${M}${N?` (backward reformat)`:``}`),n.info(`[DRY-RUN] Bump: ${R} (\`${j}\` -> \`${H}\`)`),n.info(`[DRY-RUN] Versioning: ${I.enabled?I.target:`disabled`}`),n.info(`[DRY-RUN] ${F.length} commit(s) scanned. Project files untouched.`),n.info(``),n.info(`Proposed new CHANGELOG.md entry (new version only):`),n.info(``),n.raw(s),n.info(`--- end of proposed entry ---`);let l=N?g(O.packageChanges,k):i,p=d(l,s),m=e(t,`CHANGELOG.proposed.md`);E(m,p,`utf8`),n.info(`Wrote ${m}`)}else{for(let[e,t]of V.writes)x(e,t);S(H,P,F,B,N,O.packageChanges,V.entries,z,k),I.enabled?n.info(`Bumped ${j} -> ${H} (${R}) from ${F.length} commit(s).`):n.info(`Wrote changelogs for ${H} (${R}) from ${F.length} commit(s); versioning disabled.`)}}const k=O,A=t(import.meta.url);process.argv[1]&&/[\\/]run\.[cm]?[jt]s$/.test(A)&&j(process.argv[1])===A&&O();function j(e){try{return T(e)}catch{return e}}export{k as main,O as runChangelog};
@@ -19,12 +19,15 @@ export declare const HOOK_HEADER = "# Generated by @deltabox/toolchain — edit
19
19
  export declare function commitMsgHook(commitlintPath?: string): string;
20
20
  /** The default husky `commit-msg` hook body (config at the project root). */
21
21
  export declare const COMMIT_MSG_HOOK: string;
22
- /** The workflow file names produced for a config. */
22
+ /** The workflow file paths produced for a config. */
23
+ export declare function workflowFilePaths(config: ToolchainConfig): string[];
24
+ /** The workflow file names (basenames) produced for a config. */
23
25
  export declare function workflowFilenames(config: ToolchainConfig): string[];
24
26
  /**
25
- * The changelog sync task: writes the GitHub workflows, the commitlint config
26
- * and the husky `commit-msg` hook from the loaded `dbx.config.*`. Branches,
27
- * triggers, steps, jobs and per-workflow tokens are all taken from the config.
27
+ * The CI/changelog sync task: writes the opted-in GitHub workflows, the
28
+ * commitlint config and the husky `commit-msg` hook from the loaded
29
+ * `dbx.config.*`. Branches, triggers, steps, jobs and per-workflow tokens are
30
+ * all taken from the config.
28
31
  */
29
32
  export declare function changelogSyncTask(): SyncTask;
30
33
  //#endregion
@@ -1 +1 @@
1
- import"node:path";import"node:url";import.meta.url;import{resolveChangelogBranches as e,sectionConfig as t,sectionEnabled as n}from"../../shared/src/toolchain.js";import"../../shared/src/index.js";import{WORKFLOW_FILENAMES as r,isEnabled as i,renderWorkflow as a,renderWorkflows as o}from"./workflows.js";import{renderCommitlintConfig as s}from"./templates.js";function c(e,t){return e===!1?{enabled:!1}:typeof e==`string`?e:e===!0||e===void 0?{pushBranches:t}:{pushBranches:t,...e}}function l(e,t){return{...e,ci:c(e.ci,t.main),release:c(e.release,t.main),changelog:c(e.changelog,t.dev),sync:c(e.sync,[.../* @__PURE__ */ new Set([...t.main,...t.dev])])}}const u="# Generated by @deltabox/toolchain — edit dbx.config.* and run `dbx sync`.",d="// Generated by @deltabox/toolchain — edit dbx.config.* and run `dbx sync`.",f="# Generated by @deltabox/toolchain — edit dbx.config.* and run `dbx sync`.";function p(e){let t=`npx --no -- commitlint --edit "$1"`;return e?`${t} --config ${e}`:t}const m=p();function h(e){return e?e.replace(/\\/g,`/`).replace(/^\.?\//,``).replace(/\/+$/,``):``}function g(e){return Object.keys(o({},t(e.changelog)?.workflows??{}))}function _(){return{name:`changelog`,projectTypes:[`monorepo-root`,`project`],enabled:e=>n(e.changelog),run:n=>{let o=t(n.config.changelog)??{},c=[],m=h(o.commitlint?.dir),g=m?`${m}/commitlint.config.mjs`:`commitlint.config.mjs`,_=l(o.workflows??{},e(o)),v={...n.tokens,commitlintConfig:g};for(let[e,t]of Object.entries(r)){let n=_[e];if(!i(n))continue;let r=typeof n==`string`,o=r?n:a(e,{tokens:v,config:typeof n==`object`?n:{}});o&&c.push({path:`.github/workflows/${t}`,content:r?o:`${u}\n${o}`})}return c.push({path:g,content:`${d}\n${s({...o.types?{types:o.types}:{},...o.scopes?{scopes:o.scopes}:{}})}`}),c.push({path:`.husky/commit-msg`,content:`${f}\n${p(m?g:void 0)}\n`}),c}}}export{d as COMMITLINT_HEADER,m as COMMIT_MSG_HOOK,f as HOOK_HEADER,u as WORKFLOW_HEADER,_ as changelogSyncTask,p as commitMsgHook,g as workflowFilenames};
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{changelogSectionEnabled as t,resolveChangelogBranches as n,resolveChangelogConfig as r,resolveCommitlintEnabled as i,sectionConfig as a,sectionEnabled as o}from"../../shared/src/toolchain.js";import"../../shared/src/index.js";import{WORKFLOW_FILENAMES as s,isEnabled as c,renderCustomWorkflow as l,renderWorkflow as u,workflowFilePath as d}from"./workflows.js";import{renderCommitlintConfig as f}from"./templates.js";import p from"node:fs";function m(e,t){return e===!1?{enabled:!1}:typeof e==`string`?e:e===!0||e===void 0?{pushBranches:t}:{pushBranches:t,...e}}function h(e){let t=o(e.ci)?a(e.ci)??{}:{};return{ci:t.ci,changelog:t.changelog,release:t.release,issues:t.issues,sync:t.sync}}function g(e,t){let n={...e},r=(e,t)=>{n[e]!==void 0&&(n[e]=m(n[e],t))};return r(`ci`,t.main),r(`release`,t.main),r(`changelog`,t.dev),r(`sync`,[.../* @__PURE__ */ new Set([...t.main,...t.dev])]),n}const _="# Generated by @deltabox/toolchain — edit dbx.config.* and run `dbx sync`.",v="// Generated by @deltabox/toolchain — edit dbx.config.* and run `dbx sync`.",y="# Generated by @deltabox/toolchain — edit dbx.config.* and run `dbx sync`.";function b(e){let t=`npx --no -- commitlint --edit "$1"`;return e?`${t} --config ${e}`:t}const x=b();function S(e){return e?e.replace(/\\/g,`/`).replace(/^\.?\//,``).replace(/\/+$/,``):``}function C(e){let t=h(e),n=[];for(let[e,r]of Object.entries(s)){let i=t[e];c(i)&&n.push(d(e,i,r))}let r=o(e.ci)?a(e.ci)?.custom??{}:{};for(let[e,t]of Object.entries(r)){let r=t;c(r)&&n.push(d(e,r))}return[...new Set(n)]}function w(e){return[...new Set(C(e).map(e=>e.split(`/`).pop()??e))]}function T(){return{name:`changelog`,projectTypes:[`monorepo-root`,`project`],enabled:e=>o(e.ci),run:m=>{let x=r(m.config)??{},C=a(x.commitlint),w=t(m.config)&&i(x),T=[],E=/* @__PURE__ */ new Set,D={},O=new Set(m.managedFiles??[]),k=t=>{if(O.has(t))return!0;let n=e.resolve(m.cwd,t);if(!p.existsSync(n))return!0;try{return p.readFileSync(n,`utf-8`).replace(/^\uFEFF/,``).startsWith(_)}catch{return!1}},A=(e,t,n,r=!1)=>{if(E.has(t))m.warn(`changelog: workflow path "${t}" is declared more than once; skipping the duplicate.`);else if(k(t))E.add(t),T.push({path:t,content:n});else{let n=r?`ci.custom.${e}`:`ci.${e}`;D[t]=n,m.warn(`changelog: ${t} already exists and is not managed by dbx; leaving it untouched. Set \`${n}: { enabled: false }\` in dbx.config to keep it explicit.`,`changelog.existing-workflow`)}},j=S(C?.dir),M=j?`${j}/commitlint.config.mjs`:`commitlint.config.mjs`,N=g(h(m.config),n(x)),P={...m.tokens,commitlintConfig:M};for(let[e,t]of Object.entries(s)){let n=N[e];if(!c(n))continue;let r=typeof n==`string`,i=r?n:u(e,{tokens:P,config:typeof n==`object`?n:{},commitlint:w});i&&A(e,d(e,n,t),r?i:`${_}\n${i}`)}let F=o(m.config.ci)?a(m.config.ci)?.custom??{}:{};for(let[e,t]of Object.entries(F)){let n=t;if(!c(n))continue;let r=typeof n==`string`,i=r?n:l(e,{tokens:P,config:typeof n==`object`?n:{},commitlint:w});i&&A(e,d(e,n),r?i:`${_}\n${i}`,!0)}return w&&(T.push({path:M,content:`${v}\n${f({...C?.types?{types:C.types}:{},...C?.scopes?{scopes:C.scopes}:{}})}`}),T.push({path:`.husky/commit-msg`,content:`${y}\n${b(j?M:void 0)}\n`})),m.manifest&&(Object.keys(D).length>0?m.manifest.workflowConflicts=D:delete m.manifest.workflowConflicts),T}}}export{v as COMMITLINT_HEADER,x as COMMIT_MSG_HOOK,y as HOOK_HEADER,_ as WORKFLOW_HEADER,T as changelogSyncTask,b as commitMsgHook,C as workflowFilePaths,w as workflowFilenames};
@@ -1,12 +1,13 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
+ import { ChangelogGroupsSetting } from "../../../shared/src/changelog-groups.js";
3
4
  import { GroupedItem, GroupedRule, ParsedCommit } from "./types.js";
4
5
  //#region packages/changelog/src/utils/format.d.ts
5
6
  export declare function ruleTitle(type: string): string;
6
7
  /** Parse a Conventional-Commits subject into its parts. */
7
8
  export declare function parseCcSubject(subject: string): ParsedCommit;
8
9
  /** Group a list of parsed commits by CC rule, then by scope. */
9
- export declare function groupItems(items: GroupedItem[]): GroupedRule[];
10
+ export declare function groupItems(items: GroupedItem[], setting?: ChangelogGroupsSetting): GroupedRule[];
10
11
  export declare function renderGroups(groups: GroupedRule[]): string;
11
12
  /**
12
13
  * Split a changelog bullet's trailing inline content (after the commit credit
@@ -1,5 +1,5 @@
1
- import"node:path";import"node:url";import.meta.url;import{logger as e}from"../../../shared/src/logger.js";import{sanitizeText as t}from"../../../shared/src/string-utils.js";import"../../../shared/src/index.js";import{readFileSync as n,writeFileSync as r}from"node:fs";const i={feat:`New features`,fix:`Bug fixes`,refactor:`Refactors`,docs:`Documentation`,style:`Styles`,chore:`Chores`,test:`Tests`,perf:`Performance`,build:`Build system`,ci:`CI`,revert:`Reverts`,breaking:`Breaking changes`},a=[`breaking`,`feat`,`fix`,`perf`,`refactor`,`docs`,`style`,`test`,`build`,`ci`,`chore`,`revert`];function o(e){return i[e]??i[e.toLowerCase()]??`Other changes`}function s(e){let t=/^([a-zA-Z][a-zA-Z0-9]*)(\(([^)]*)\))?(!)?:\s*(.*)$/.exec(e);return t?{type:t[1].toLowerCase(),scope:t[3]?.trim()||void 0,breaking:!!t[4],rest:t[5]??``}:{type:`chore`,breaking:!1,rest:e}}function c(e){let t=/* @__PURE__ */ new Map;for(let n of e){let{parsed:e}=n,r=t.get(e.type)??{title:o(e.type),ungrouped:[],scopes:/* @__PURE__ */ new Map};if(e.scope){let t=r.scopes.get(e.scope)??[];t.push(n),r.scopes.set(e.scope,t)}else r.ungrouped.push(n);t.set(e.type,r)}return[...t.entries()].sort((e,t)=>{let n=a.indexOf(e[0]),r=a.indexOf(t[0]);return(n===-1?a.length:n)-(r===-1?a.length:r)}).map(([,e])=>e)}function l(e){if(e.length===0)return`- No description provided.`;let t=[];for(let n of e){t.push(`### ${n.title}`);for(let e of n.ungrouped)t.push(e.text),t.push(...u(e.bodyParagraphs));for(let[e,r]of n.scopes){t.push(`#### ${d(e)}`);for(let e of r)t.push(e.text),t.push(...u(e.bodyParagraphs))}}return t.join(`
2
- `)}function u(e){let t=[];for(let n of e){let[e,...r]=n;e&&(t.push(` - ${e}`),t.push(...r.map(e=>` ${e}`)))}return t}function d(e){return e.charAt(0).toUpperCase()+e.slice(1)}function f(e){return e.length>0?e.charAt(0).toUpperCase()+e.slice(1):e}function p(e){let t=e.lastIndexOf(`([#`);if(t===-1)return{main:e,inline:``};let n=e.slice(t),r=/^(\(\[#[^\]]+\]\([^)]*\) by [^)]*\)\)?)(?:\(fixes [^)]*\)\)?)?/.exec(n);if(!r)return{main:e,inline:``};let i=r[0]??``;return{main:e.slice(0,t)+i,inline:e.slice(t+i.length).trim()}}function m(e){let n=[],r=[];for(let i of e.split(`
3
- `)){let e=t(i.trim());if(!e){r.length>0&&(n.push(r),r=[]);continue}if(e.startsWith(`-`)||e.startsWith(`*`)||/^[0-9]+[.)]/.test(e)||!e.replace(/(?:close[sd]?|fixe?s|fixed|resolves?|resolved)\b\s*:?\s*#\d+\s*[,;]?\s*/gi,``).trim())continue;let a=/^(BREAKING CHANGE|Reviewed-by|Signed-off-by|Co-authored-by|Acked-by|Co-developed-by|Helped-by|Reported-by|Suggested-by|Tested-by|Cc):\s+(.+)$/i.exec(e);a&&!/^(http|https)\b/.test(e)?(r.length>0&&(n.push(r),r=[]),n.push([`**${(a[1]??``).trim()}:** ${(a[2]??``).trim()}`])):r.push(e)}return r.length>0&&n.push(r),n}function h(e,t){return`https://github.com/${e}/commit/${t}`}function g(e,t){return`https://github.com/${e}/issues/${t}`}function _(e,t){return e.replace(/\[(#[0-9a-fA-F]{6,40})\]\(([^)]*)\)/g,(e,n)=>{let r=n.replace(`#`,``).slice(0,7);return`[#${r}](${h(t,r)})`}).replace(/(^|[^\w[])#([0-9a-fA-F]{7,40})(?![0-9a-fA-F])(?=[)\].,;:\s]|$)/g,(e,n,r)=>{let i=r.slice(0,7);return`${n}[#${i}](${h(t,i)})`})}function v(e,t){return e.replace(/\[#(\d+)(?=[ \]])(?:[^\]]*)\]\([^)]*\)/g,(e,n)=>`[#${n}](${g(t,n)})`).replace(/(^|[^\w[])#(\d+)(?=[)\].,;:\s]|$)/g,(e,n,r)=>`${n}[#${r}](${g(t,r)})`)}function y(e,t){if(!t)return e;let n=_(e,t);return n=v(n,t),n}function b(t,i){if(!i)return;let a=n(t,`utf8`),o=a.split(`
4
- `).map(e=>y(e,i)).join(`
5
- `);o!==a&&(r(t,o,`utf8`),e.info(` formatted ${t}`))}export{f as capitalize,m as formatBody,b as formatChangelogFile,y as formatLine,c as groupItems,s as parseCcSubject,l as renderGroups,o as ruleTitle,p as splitInlineDescription};
1
+ import"node:path";import"node:url";import.meta.url;import{logger as e}from"../../../shared/src/logger.js";import{sanitizeText as t}from"../../../shared/src/string-utils.js";import"../../../shared/src/index.js";import{readFileSync as n,writeFileSync as r}from"node:fs";const i={feat:`New features`,fix:`Bug fixes`,refactor:`Refactors`,docs:`Documentation`,style:`Styles`,chore:`Chores`,test:`Tests`,perf:`Performance`,build:`Build system`,ci:`CI`,revert:`Reverts`,breaking:`Breaking changes`},a=[`breaking`,`feat`,`fix`,`perf`,`refactor`,`docs`,`style`,`test`,`build`,`ci`,`chore`,`revert`];function o(e){return i[e]??i[e.toLowerCase()]??`Other changes`}function s(e){let t=/^([a-zA-Z][a-zA-Z0-9]*)(\(([^)]*)\))?(!)?:\s*(.*)$/.exec(e);return t?{type:t[1].toLowerCase(),scope:t[3]?.trim()||void 0,breaking:!!t[4],rest:t[5]??``}:{type:`chore`,breaking:!1,rest:e}}function c(e,t){if(typeof e==`function`){let n=e(t);return typeof n==`function`?void 0:n}return e}function l(e){if(!e)return[];if(Array.isArray(e)){let t=[];for(let[n,r]of e.entries())typeof r==`string`?t.push({type:r.toLowerCase(),index:n}):r&&typeof r==`object`&&r.type&&t.push({type:r.type.toLowerCase(),...r.title===void 0?{}:{title:r.title},...r.order===void 0?{}:{order:r.order},...r.hidden===void 0?{}:{hidden:r.hidden},index:n});return t}if(typeof e!=`object`)return[];let t=[];for(let[n,[r,i]]of Object.entries(e).entries()){let e=i===!1?{hidden:!0}:i===!0||i==null?{}:typeof i==`string`?{title:i}:i;t.push({type:r.toLowerCase(),...e.title===void 0?{}:{title:e.title},...e.order===void 0?{}:{order:e.order},...e.hidden===void 0?{}:{hidden:e.hidden},index:n})}return t}function u(e,t){if(typeof e==`function`){let n=e(t);return typeof n==`string`&&n.length>0?n:t.defaultTitle}return e??t.defaultTitle}function d(e,t,n){let r=typeof e==`function`?e(n):e;return typeof r==`number`&&Number.isFinite(r)?r:t}function f(e,t){return typeof e==`function`?!!e(t):e===!0}function p(e){let t=a.indexOf(e);return t===-1?a.length:t}function m(e,t){let n=/* @__PURE__ */ new Map;for(let t of e){let{parsed:e}=t,r=n.get(e.type)??{title:o(e.type),ungrouped:[],scopes:/* @__PURE__ */ new Map};if(e.scope){let n=r.scopes.get(e.scope)??[];n.push(t),r.scopes.set(e.scope,n)}else r.ungrouped.push(t);n.set(e.type,r)}let r=[...n.keys()],i={types:r,items:e},a=l(c(t,i)),s=[],m=/* @__PURE__ */ new Set,h=-1;for(let e of a){if(m.has(e.type))continue;let t=n.get(e.type);if(!t)continue;m.add(e.type);let r=[...t.ungrouped,...[...t.scopes.values()].flat()],a={...i,type:e.type,defaultTitle:o(e.type),index:e.index,groupItems:r},c=d(e.order,e.index,a);h=Math.max(h,c),!f(e.hidden,a)&&s.push({rule:{...t,title:u(e.title,a)},order:c,seq:e.index})}let g=r.filter(e=>!m.has(e)).sort((e,t)=>p(e)-p(t));for(let[e,t]of g.entries()){let r=n.get(t);s.push({rule:r,order:h+1+p(t),seq:a.length+e})}return s.sort((e,t)=>e.order-t.order||e.seq-t.seq).map(e=>e.rule)}function h(e){if(e.length===0)return`- No description provided.`;let t=[];for(let n of e){t.push(`### ${n.title}`);for(let e of n.ungrouped)t.push(e.text),t.push(...g(e.bodyParagraphs));for(let[e,r]of n.scopes){t.push(`#### ${_(e)}`);for(let e of r)t.push(e.text),t.push(...g(e.bodyParagraphs))}}return t.join(`
2
+ `)}function g(e){let t=[];for(let n of e){let[e,...r]=n;e&&(t.push(` - ${e}`),t.push(...r.map(e=>` ${e}`)))}return t}function _(e){return e.charAt(0).toUpperCase()+e.slice(1)}function v(e){return e.length>0?e.charAt(0).toUpperCase()+e.slice(1):e}function y(e){let t=e.lastIndexOf(`([#`);if(t===-1)return{main:e,inline:``};let n=e.slice(t),r=/^(\(\[#[^\]]+\]\([^)]*\) by [^)]*\)\)?)(?:\(fixes [^)]*\)\)?)?/.exec(n);if(!r)return{main:e,inline:``};let i=r[0]??``;return{main:e.slice(0,t)+i,inline:e.slice(t+i.length).trim()}}function b(e){let n=[],r=[];for(let i of e.split(`
3
+ `)){let e=t(i.trim());if(!e){r.length>0&&(n.push(r),r=[]);continue}if(e.startsWith(`-`)||e.startsWith(`*`)||/^[0-9]+[.)]/.test(e)||!e.replace(/(?:close[sd]?|fixe?s|fixed|resolves?|resolved)\b\s*:?\s*#\d+\s*[,;]?\s*/gi,``).trim())continue;let a=/^(BREAKING CHANGE|Reviewed-by|Signed-off-by|Co-authored-by|Acked-by|Co-developed-by|Helped-by|Reported-by|Suggested-by|Tested-by|Cc):\s+(.+)$/i.exec(e);a&&!/^(http|https)\b/.test(e)?(r.length>0&&(n.push(r),r=[]),n.push([`**${(a[1]??``).trim()}:** ${(a[2]??``).trim()}`])):r.push(e)}return r.length>0&&n.push(r),n}function x(e,t){return`https://github.com/${e}/commit/${t}`}function S(e,t){return`https://github.com/${e}/issues/${t}`}function C(e,t){return e.replace(/\[(#[0-9a-fA-F]{6,40})\]\(([^)]*)\)/g,(e,n)=>{let r=n.replace(`#`,``).slice(0,7);return`[#${r}](${x(t,r)})`}).replace(/(^|[^\w[])#([0-9a-fA-F]{7,40})(?![0-9a-fA-F])(?=[)\].,;:\s]|$)/g,(e,n,r)=>{let i=r.slice(0,7);return`${n}[#${i}](${x(t,i)})`})}function w(e,t){return e.replace(/\[#(\d+)(?=[ \]])(?:[^\]]*)\]\([^)]*\)/g,(e,n)=>`[#${n}](${S(t,n)})`).replace(/(^|[^\w[])#(\d+)(?=[)\].,;:\s]|$)/g,(e,n,r)=>`${n}[#${r}](${S(t,r)})`)}function T(e,t){if(!t)return e;let n=C(e,t);return n=w(n,t),n}function E(t,i){if(!i)return;let a=n(t,`utf8`),o=a.split(`
4
+ `).map(e=>T(e,i)).join(`
5
+ `);o!==a&&(r(t,o,`utf8`),e.info(` formatted ${t}`))}export{v as capitalize,b as formatBody,E as formatChangelogFile,T as formatLine,m as groupItems,s as parseCcSubject,h as renderGroups,o as ruleTitle,y as splitInlineDescription};
@@ -1 +1 @@
1
- import{default as e}from"node:path";import"node:url";import.meta.url;import{sanitizeText as t}from"../../../shared/src/string-utils.js";import"../../../shared/src/index.js";import n from"node:fs";import{execFileSync as r}from"node:child_process";function i(e,n){let i=n===void 0?[]:Array.isArray(n)?n:[n],a=[`log`,`--no-merges`,`--pretty=format:%H%x1f%s%x1f%b%x1f%an%x1f%ae%x1e`,e];return i.length>0&&a.push(`--`,...i),r(`git`,a,{encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`]}).split(``).filter(e=>e.length>0).map(e=>{let[n,r,i,a,o]=e.split(``);return{hash:n.trim(),subject:t((r??``).trim()),body:t((i??``).trim()),author:(a??``).trim(),authorEmail:(o??``).trim()}}).filter(e=>e.subject.length>0)}function a(e){let t=e.match(/(?:github\.com[/:])([^/]+)\/([^/.]+?)(?:\.git)?$/);if(t?.[1]&&t[2])return`${t[1]}/${t[2]}`}function o(){try{let e=a(r(`git`,[`remote`,`get-url`,`origin`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim());if(e)return e}catch{}try{let t=n.readFileSync(e.join(process.cwd(),`package.json`),`utf8`),r=JSON.parse(t),i=typeof r.repository==`string`?r.repository:r.repository?.url;if(i)return a(i)}catch{}}let s;function c(){if(s!==void 0)return s;try{r(`gh`,[`auth`,`status`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`]}),s=!0}catch{s=!1}return s}const l=/* @__PURE__ */ new Map;function u(e,t,n){if(!c())return;let i=`repos/${e}${t}::${n}`;if(l.has(i))return l.get(i);let a;try{let i=r(`gh`,[`api`,`repos/${e}${t}`,`--jq`,n],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`]}).trim();a=i&&i!==`null`?i:void 0}catch{a=void 0}return l.set(i,a),a}function d(e){return/^(\d+)\+([^@]+)@users\.noreply\.github\.com$/.exec(e.trim())?.[2]}function f(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}function p(e,t){let n;t&&(n=u(t,`/commits/${e.hash}/pulls`,`.[0].user.login`),n||=u(t,`/commits/${e.hash}`,`.author.login`)),n||=d(e.authorEmail);let r=n??e.author;return f(r)&&(r=d(r)??r.split(`@`)[0]??r),{name:r,url:n?`https://github.com/${n}`:void 0}}function m(e){return e.url?`[${e.name}](${e.url})`:e.name}function h(e){let t=/* @__PURE__ */ new Set;for(let n of e.matchAll(/\b(?:close[sd]?|fixe?s|fixed|resolves?|resolved)\b\s*:?\s*#(\d+)/gi)){let e=Number(n[1]);Number.isInteger(e)&&t.add(e)}return[...t]}function g(e,t){let n={number:t},r=u(e,`/issues/${t}`,`[.title,.html_url]`);if(r)try{let e=JSON.parse(r);n.title=e[0]||void 0,n.url=e[1]||void 0}catch{}return n}function _(e,t){let n=h(`${e.subject}\n${e.body}`);return n.length===0?[]:t?n.map(e=>g(t,e)):n.map(e=>({number:e}))}function v(e){return e.length===0?``:` (fixes ${e.map(e=>e.url&&e.title?`[#${e.number} ${e.title}](${e.url})`:e.url?`[#${e.number}](${e.url})`:`#${e.number}`).join(`, `)})`}function y(e){return/\[(#[0-9a-fA-F]{6,40})\]\([^)]*\)/.exec(e)?.[1]?.replace(`#`,``)}function b(e){try{return r(`git`,[`log`,`-1`,`--format=%aI`,e],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{return}}function x(e){for(let t of[`v${e}`,e])try{let e=r(`git`,[`log`,`-1`,`--format=%aI`,t],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim();if(e)return e}catch{}}function S(e,t){let n=x(e);if(n)return new Date(n);for(let e of t){let t=y(e);if(t){let e=b(t);if(e)return new Date(e)}}}let C;function w(){if(C)return C;let e=/* @__PURE__ */ new Map;try{let t=r(`git`,[`log`,`--no-merges`,`--all`,`--format=%H%x1f%s%x1f%b%x1e`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`],maxBuffer:134217728});for(let n of t.split(``)){if(!n.trim())continue;let[t=``,r=``,i=``]=n.split(``);if(!t)continue;let a={subject:r.trim(),body:i.trim()};e.set(t.trim(),a),e.set(t.trim().slice(0,7),a)}}catch{}return C=e,e}function T(e){return w().get(e)}function E(e){let t=`patch`;for(let n of e){let e=`${n.subject}\n${n.body}`;/\bBREAKING CHANGE\b/.test(e)||/^[a-zA-Z]+(\([^)]*\))?!:/.test(n.subject)?t=`major`:t!==`major`&&/^feat(\([^)]*\))?:/i.test(n.subject)&&(t=`minor`)}return t}export{y as bulletHash,E as deriveBump,S as deriveVersionDate,T as readCommit,i as readCommits,_ as recordIssues,m as renderAuthor,v as renderIssues,o as repoSlug,p as resolveAuthorInfo};
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{sanitizeText as t}from"../../../shared/src/string-utils.js";import"../../../shared/src/index.js";import n from"node:fs";import{execFileSync as r}from"node:child_process";function i(e,n){let i=n===void 0?[]:Array.isArray(n)?n:[n],a=[`log`,`--no-merges`,`--pretty=format:%H%x1f%s%x1f%b%x1f%an%x1f%ae%x1e`,e];return i.length>0&&a.push(`--`,...i),r(`git`,a,{encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`]}).split(``).filter(e=>e.length>0).map(e=>{let[n,r,i,a,o]=e.split(``);return{hash:n.trim(),subject:t((r??``).trim()),body:t((i??``).trim()),author:(a??``).trim(),authorEmail:(o??``).trim()}}).filter(e=>e.subject.length>0)}function a(e){let t=e.match(/(?:github\.com[/:])([^/]+)\/([^/.]+?)(?:\.git)?$/);if(t?.[1]&&t[2])return`${t[1]}/${t[2]}`}function o(){try{let e=a(r(`git`,[`remote`,`get-url`,`origin`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim());if(e)return e}catch{}try{let t=n.readFileSync(e.join(process.cwd(),`package.json`),`utf8`),r=JSON.parse(t),i=typeof r.repository==`string`?r.repository:r.repository?.url;if(i)return a(i)}catch{}}let s;function c(){if(process.env.DBX_NO_GH)return s=!1,!1;if(s!==void 0)return s;try{r(`gh`,[`auth`,`status`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`],timeout:2e3}),s=!0}catch{s=!1}return s}const l=/* @__PURE__ */ new Map;function u(e,t,n){if(!c())return;let i=`repos/${e}${t}::${n}`;if(l.has(i))return l.get(i);let a;try{let i=r(`gh`,[`api`,`repos/${e}${t}`,`--jq`,n],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`pipe`],timeout:5e3}).trim();a=i&&i!==`null`?i:void 0}catch{a=void 0}return l.set(i,a),a}function d(e){return/^(\d+)\+([^@]+)@users\.noreply\.github\.com$/.exec(e.trim())?.[2]}function f(e){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)}function p(e,t){let n;t&&(n=u(t,`/commits/${e.hash}/pulls`,`.[0].user.login`),n||=u(t,`/commits/${e.hash}`,`.author.login`)),n||=d(e.authorEmail);let r=n??e.author;return f(r)&&(r=d(r)??r.split(`@`)[0]??r),{name:r,url:n?`https://github.com/${n}`:void 0}}function m(e){return e.url?`[${e.name}](${e.url})`:e.name}function h(e){let t=/* @__PURE__ */ new Set;for(let n of e.matchAll(/\b(?:close[sd]?|fixe?s|fixed|resolves?|resolved)\b\s*:?\s*#(\d+)/gi)){let e=Number(n[1]);Number.isInteger(e)&&t.add(e)}return[...t]}function g(e,t){let n={number:t},r=u(e,`/issues/${t}`,`[.title,.html_url]`);if(r)try{let e=JSON.parse(r);n.title=e[0]||void 0,n.url=e[1]||void 0}catch{}return n}function _(e,t){let n=h(`${e.subject}\n${e.body}`);return n.length===0?[]:t?n.map(e=>g(t,e)):n.map(e=>({number:e}))}function v(e){return e.length===0?``:` (fixes ${e.map(e=>e.url&&e.title?`[#${e.number} ${e.title}](${e.url})`:e.url?`[#${e.number}](${e.url})`:`#${e.number}`).join(`, `)})`}const y=/* @__PURE__ */ new Map;function b(e,t){let n=`${e}::${t??``}`;if(y.has(n))return y.get(n);let i=e.trim(),a=(i.includes(`..`)?(i.split(`..`)[0]??``).trim():``)||(t?`${t}^`:void 0);if(!a){y.set(n,void 0);return}let o;try{o=r(`git`,[`log`,`--no-merges`,`--format=%ae%x1f%an%x1e`,a],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`],maxBuffer:134217728})}catch{y.set(n,void 0);return}let s=/* @__PURE__ */ new Set;for(let e of o.split(``)){if(!e.trim())continue;let[t=``,n=``]=e.split(``);for(let e of[t,n]){let t=e.trim().toLowerCase();t&&s.add(t)}}return y.set(n,s),s}function x(e){return/\[(#[0-9a-fA-F]{6,40})\]\([^)]*\)/.exec(e)?.[1]?.replace(`#`,``)}function S(e){try{return r(`git`,[`log`,`-1`,`--format=%aI`,e],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim()}catch{return}}function C(e){for(let t of[`v${e}`,e])try{let e=r(`git`,[`log`,`-1`,`--format=%aI`,t],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim();if(e)return e}catch{}}function w(e,t){let n=C(e);if(n)return new Date(n);for(let e of t){let t=x(e);if(t){let e=S(t);if(e)return new Date(e)}}}let T;function E(){if(T)return T;let e=/* @__PURE__ */ new Map;try{let t=r(`git`,[`log`,`--no-merges`,`--all`,`--format=%H%x1f%s%x1f%b%x1e`],{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`],maxBuffer:134217728});for(let n of t.split(``)){if(!n.trim())continue;let[t=``,r=``,i=``]=n.split(``);if(!t)continue;let a={subject:r.trim(),body:i.trim()};e.set(t.trim(),a),e.set(t.trim().slice(0,7),a)}}catch{}return T=e,e}function D(e){return E().get(e)}function O(e){let t=`patch`;for(let n of e){let e=`${n.subject}\n${n.body}`;/\bBREAKING CHANGE\b/.test(e)||/^[a-zA-Z]+(\([^)]*\))?!:/.test(n.subject)?t=`major`:t!==`major`&&/^feat(\([^)]*\))?:/i.test(n.subject)&&(t=`minor`)}return t}export{x as bulletHash,O as deriveBump,w as deriveVersionDate,D as readCommit,i as readCommits,b as readPriorAuthors,_ as recordIssues,m as renderAuthor,v as renderIssues,o as repoSlug,p as resolveAuthorInfo};
@@ -1,9 +1,10 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
+ import { ChangelogGroupsSetting } from "../../../shared/src/changelog-groups.js";
3
4
  import { ExistingEntry } from "./types.js";
4
5
  //#region packages/changelog/src/utils/reformat.d.ts
5
6
  /** Split a changelog into `## <version>` sections with their bullet lines. */
6
7
  export declare function parseExistingChangelog(content: string): ExistingEntry[];
7
8
  /** Backward-reformat an entire changelog file's content (all versions). */
8
- export declare function reformatChangelogContent(content: string, repo: string | undefined, markersOnNewest?: boolean, includePackageChanges?: boolean): string;
9
+ export declare function reformatChangelogContent(content: string, repo: string | undefined, markersOnNewest?: boolean, includePackageChanges?: boolean, groups?: ChangelogGroupsSetting): string;
9
10
  //#endregion
@@ -1,6 +1,6 @@
1
1
  import{resolve 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{bulletHash as n,deriveVersionDate as r,readCommit as i,repoSlug as a}from"./git.js";import{changelogFiles as o,repoRoot as s}from"./repo.js";import{packageChangesForVersion as c}from"./packages.js";import{capitalize as l,formatBody as u,formatLine as d,groupItems as f,parseCcSubject as p,renderGroups as m}from"./format.js";import{renderChangelogEntry as h}from"./version.js";import{existsSync as g,readFileSync as _,writeFileSync as v}from"node:fs";function y(e){let t=[],n;for(let r of e.split(`
2
- `)){let e=/^##\s+([0-9]+\.[0-9]+\.[0-9]+)(?:\s*\(.*\))?\s*$/.exec(r);e?(n={version:e[1],bullets:[]},t.push(n)):n&&(r.includes(`<!-- release:`)||r.startsWith(`- `)&&n.bullets.push(r))}return t}function b(e){let t=e.lastIndexOf(`([#`);if(t===-1)return``;let n=e.slice(t);return/^(\(\[#[^\]]+\]\([^)]*\) by [^)]*\)\)?)(?:\(fixes [^)]*\)\)?)?/.exec(n)?.[0]??``}function x(e,t,a=!1,o=``){let s=[];for(let r of e.bullets){let e=r.replace(/^-\s+/,``),a=n(r),o=a?i(a):void 0,c=o?.subject??e.replace(/\*\*/g,``),f=p(c),m=b(e),h=`- ${[d(l(f.rest),t),m].filter(Boolean).join(` `)}`,g=o?u(o.body):[];s.push({parsed:f,text:h,bodyParagraphs:g})}let c=r(e.version,e.bullets);return h(e.version,m(f(s)),c,a,o)}function S(e,t,n=!1,r=!1){let i=y(e);if(i.length===0)return e;let a=e.split(`
3
- `)[0]??`# Changelog`;return`${a.startsWith(`# `)?a:`# Changelog`}\n\n${i.map((e,a)=>{let o=i[a+1],s=r&&o?c(e.version,o.version):``;return x(e,t,n&&a===0,s)}).filter(Boolean).join(`
2
+ `)){let e=/^##\s+([0-9]+\.[0-9]+\.[0-9]+)(?:\s*\(.*\))?\s*$/.exec(r);e?(n={version:e[1],bullets:[]},t.push(n)):n&&(r.includes(`<!-- release:`)||r.startsWith(`- `)&&n.bullets.push(r))}return t}function b(e){let t=e.lastIndexOf(`([#`);if(t===-1)return``;let n=e.slice(t);return/^(\(\[#[^\]]+\]\([^)]*\) by [^)]*\)\)?)(?:\(fixes [^)]*\)\)?)?/.exec(n)?.[0]??``}function x(e,t,a=!1,o=``,s){let c=[];for(let r of e.bullets){let e=r.replace(/^-\s+/,``),a=n(r),o=a?i(a):void 0,s=o?.subject??e.replace(/\*\*/g,``),f=p(s),m=b(e),h=`- ${[d(l(f.rest),t),m].filter(Boolean).join(` `)}`,g=o?u(o.body):[];c.push({parsed:f,text:h,bodyParagraphs:g})}let g=r(e.version,e.bullets);return h(e.version,m(f(c,s)),g,a,o)}function S(e,t,n=!1,r=!1,i){let a=y(e);if(a.length===0)return e;let o=e.split(`
3
+ `)[0]??`# Changelog`;return`${o.startsWith(`# `)?o:`# Changelog`}\n\n${a.map((e,o)=>{let s=a[o+1],l=r&&s?c(e.version,s.version):``;return x(e,t,n&&o===0,l,i)}).filter(Boolean).join(`
4
4
 
5
5
 
6
- `)}\n`}function C(t=!1){let n=s(),r=e(n,`CHANGELOG.md`);return g(r)?S(_(r,`utf8`),a(),!1,t):``}function w(n,r=!1){let i=e(s(),`CHANGELOG.md`);for(let e of o()){let o=S(_(e,`utf8`),a(),!0,r&&e===i);if(n){let n=e.replace(/CHANGELOG\.md$/,`CHANGELOG.proposed.md`);v(n,o,`utf8`),t.info(`[DRY-RUN] Wrote ${n}`)}else v(e,o,`utf8`),t.info(` formatted ${e}`)}}export{w as formatExistingChangelogs,y as parseExistingChangelog,S as reformatChangelogContent,C as reformatRootChangelog};
6
+ `)}\n`}function C(t=!1,n){let r=s(),i=e(r,`CHANGELOG.md`);return g(i)?S(_(i,`utf8`),a(),!1,t,n):``}function w(n,r=!1,i){let c=e(s(),`CHANGELOG.md`);for(let e of o()){let o=S(_(e,`utf8`),a(),!0,r&&e===c,i);if(n){let n=e.replace(/CHANGELOG\.md$/,`CHANGELOG.proposed.md`);v(n,o,`utf8`),t.info(`[DRY-RUN] Wrote ${n}`)}else v(e,o,`utf8`),t.info(` formatted ${e}`)}}export{w as formatExistingChangelogs,y as parseExistingChangelog,S as reformatChangelogContent,C as reformatRootChangelog};
@@ -1,6 +1,7 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { CommitRecord } from "./types.js";
3
+ import { ChangelogGroupsSetting } from "../../../shared/src/changelog-groups.js";
4
+ import { CommitFormatOptions, CommitRecord } from "./types.js";
4
5
  //#region packages/changelog/src/utils/summary.d.ts
5
6
  /**
6
7
  * Render a commit reference for a changelog bullet. With a resolvable repo slug
@@ -9,6 +10,28 @@ import { CommitRecord } from "./types.js";
9
10
  * short hash rather than a broken `github.com/undefined/...` link.
10
11
  */
11
12
  export declare function renderCommitRef(repo: string | undefined, hash: string): string;
13
+ export interface BuildSummaryOptions {
14
+ /**
15
+ * Use the Conventional-Commits grouping (default true). When commitlint is
16
+ * disabled, commits are hoisted into coarse Major/Minor/Patch buckets
17
+ * instead, so a non-CC history still produces a readable changelog.
18
+ */
19
+ commitlint?: boolean;
20
+ /**
21
+ * The scanned git range. Used to detect first-time contributors by looking
22
+ * for their authors before the range starts.
23
+ */
24
+ range?: string;
25
+ /**
26
+ * Explicit prior-contributor keys (author name/email), for tests or callers
27
+ * that already know the history. When omitted, the range is inspected.
28
+ */
29
+ priorAuthors?: Iterable<string>;
30
+ /** Commit line formatting/credit options. */
31
+ commit?: CommitFormatOptions;
32
+ /** Conventional-Commits group order/titles/hiding. */
33
+ groups?: ChangelogGroupsSetting;
34
+ }
12
35
  /** Render the grouped changelog summary for a set of commits. */
13
- export declare function buildSummary(records: CommitRecord[]): string;
36
+ export declare function buildSummary(records: CommitRecord[], options?: BuildSummaryOptions): string;
14
37
  //#endregion
@@ -1 +1,3 @@
1
- import"node:path";import"node:url";import.meta.url;import{recordIssues as e,renderAuthor as t,renderIssues as n,repoSlug as r,resolveAuthorInfo as i}from"./git.js";import{capitalize as a,formatBody as o,groupItems as s,parseCcSubject as c,renderGroups as l}from"./format.js";function u(e,t){let n=t.slice(0,7);return e?`[#${n}](https://github.com/${e}/commit/${t})`:`#${n}`}function d(d){let f=r(),p=s(d.map(r=>{let s=c(r.subject),l=t(i(r,f));return{parsed:s,text:`- ${a(s.rest)} (${u(f,r.hash)} by ${l})${n(e(r,f))}`,bodyParagraphs:o(r.body)}}));return l(p)}export{d as buildSummary,u as renderCommitRef};
1
+ import"node:path";import"node:url";import.meta.url;import{readPriorAuthors as e,recordIssues as t,renderAuthor as n,renderIssues as r,repoSlug as i,resolveAuthorInfo as a}from"./git.js";import{capitalize as o,formatBody as s,groupItems as c,parseCcSubject as l,renderGroups as u}from"./format.js";function d(e,t){let n=t.slice(0,7);return e?`[#${n}](https://github.com/${e}/commit/${t})`:`#${n}`}const f=[`major`,`minor`,`patch`],p={major:`Major changes`,minor:`Minor changes`,patch:`Patch changes`};function m(e){let t=l(e.subject);return t.breaking||/BREAKING[ -]CHANGE/i.test(e.body)||/^[a-zA-Z][a-zA-Z0-9]*(\([^)]*\))?!:\s/.test(e.subject)?`major`:t.type===`feat`?`minor`:`patch`}function h(e,i,c={}){let u=l(e.subject),f=a(e,i),p=t(e,i),m;if(c.format)m=`- ${c.format({commit:e,repo:i,author:f,issues:p,options:c})}`;else{let t=[];if(c.commitSha!==!1&&t.push(d(i,e.hash)),c.author!==!1){let e=c.authorAvatar&&f.url?`![${f.name}](${f.url}) `:``;t.push(`by ${e}${n(f)}`)}let a=t.length>0?` (${t.join(` `)})`:``,s=c.issues===!1?``:r(p);m=`- ${o(u.rest)}${a}${s}`}return{parsed:u,text:m,bodyParagraphs:c.body===!1?[]:s(e.body)}}function g(e){let t=[e.text];for(let n of e.bodyParagraphs){let[e,...r]=n;e&&(t.push(` - ${e}`),t.push(...r.map(e=>` ${e}`)))}return t}function _(e,t){let n=i(),r=/* @__PURE__ */ new Map;for(let i of e){let e=m(i),a=r.get(e)??[];a.push(h(i,n,t??{})),r.set(e,a)}if(r.size===0)return`- No description provided.`;let a=[];for(let e of f){let t=r.get(e);if(t&&t.length!==0){a.push(`### ${p[e]}`);for(let e of t)a.push(...g(e))}}return a.join(`
2
+ `)}function v(e){return e.trim().toLowerCase()}function y(e){return[e.authorEmail,e.author].map(v).filter(e=>e.length>0)}function b(t,n,r){let i;if(r.priorAuthors!==void 0)i=new Set([...r.priorAuthors].map(v));else if(r.range){let n=t[t.length-1]?.hash;i=e(r.range,n)}if(!i)return[];let o=/* @__PURE__ */ new Map;for(let e of t){let t=y(e);if(t.length===0||t.some(e=>i.has(e)))continue;let r=t[0],s=o.get(r);s?s.commits.push(e):o.set(r,{key:r,author:a(e,n),commits:[e]})}return[...o.values()].sort((e,t)=>e.author.name.localeCompare(t.author.name))}function x(e,t,r){let i=b(e,t,r);if(i.length===0)return``;let a=[`### New contributors`];for(let e of i){a.push(`- ${n(e.author)}`);for(let n of e.commits)a.push(...g(h(n,t,{author:!1,body:!1})).map(e=>` ${e}`))}return a.join(`
3
+ `)}function S(e,t={}){let n=i(),r=t.commitlint===!1?_(e,t.commit):u(c(e.map(e=>h(e,n,t.commit??{})),t.groups)),a=x(e,n,t);return a?`${r}\n\n${a}`:r}export{S as buildSummary,d as renderCommitRef};
@@ -1,7 +1,8 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
+ import { ChangelogGroupConfig, ChangelogGroupContext, ChangelogGroupEntry, ChangelogGroupHidden, ChangelogGroupItem, ChangelogGroupOrder, ChangelogGroupTitle, ChangelogGroupsContext, ChangelogGroupsSetting } from "../../../shared/src/changelog-groups.js";
4
+ import "../../../shared/src/index.js";
3
5
  //#region packages/changelog/src/utils/types.d.ts
4
- /** Shared types for the changelog pipeline. */
5
6
  export type BumpType = 'major' | 'minor' | 'patch';
6
7
  export type ProcessingMethod = 'latest' | 'all' | string;
7
8
  export interface CommitRecord {
@@ -50,9 +51,40 @@ export interface GroupedItem {
50
51
  /** Description paragraphs; each becomes one nested bullet with wrapped continuations. */
51
52
  bodyParagraphs: string[][];
52
53
  }
54
+ /** Options for rendering a commit bullet/credit line. */
55
+ export interface CommitFormatOptions {
56
+ /** Include the `by <author>` credit (default true). */
57
+ author?: boolean;
58
+ /** Include the commit hash link (default true). */
59
+ commitSha?: boolean;
60
+ /** Include issue/fixes links (default true). */
61
+ issues?: boolean;
62
+ /** Prefix the author with their GitHub avatar (default false). */
63
+ authorAvatar?: boolean;
64
+ /** Fully custom commit line formatter. */
65
+ format?: (ctx: CommitFormatContext) => string;
66
+ }
67
+ export interface CommitFormatContext {
68
+ commit: CommitRecord;
69
+ repo?: string;
70
+ author: AuthorInfo;
71
+ issues: IssueInfo[];
72
+ options: CommitFormatOptions;
73
+ }
74
+ /** A custom changelog provider. */
75
+ export interface ChangelogProviderContext {
76
+ cwd: string;
77
+ changelog?: unknown;
78
+ records: CommitRecord[];
79
+ }
80
+ export interface ChangelogProvider {
81
+ id: string;
82
+ run: (ctx: ChangelogProviderContext) => string | void;
83
+ }
53
84
  /** A `## <version>` section parsed out of an existing changelog. */
54
85
  export interface ExistingEntry {
55
86
  version: string;
56
87
  bullets: string[];
57
88
  }
58
- //#endregion
89
+ //#endregion
90
+ export type { ChangelogGroupConfig, ChangelogGroupContext, ChangelogGroupEntry, ChangelogGroupHidden, ChangelogGroupItem, ChangelogGroupOrder, ChangelogGroupTitle, ChangelogGroupsContext, ChangelogGroupsSetting };
@@ -1,5 +1,6 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
+ import "./types.js";
3
4
  //#region packages/changelog/src/utils/version.d.ts
4
5
  /** Render a `## <version> (Month Year)` heading + summary, optionally marked. */
5
6
  export declare function renderChangelogEntry(version: string, summary: string, date?: Date, withMarkers?: boolean, packageChanges?: string): string;
@@ -1,12 +1,13 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { ToolchainChangelogConfig } from "../../../shared/src/config-types.js";
3
+ import { logger } from "../../../shared/src/logger.js";
4
+ import { ChangelogConfig } from "../../../shared/src/config-types.js";
4
5
  import "../../../shared/src/index.js";
5
6
  import { BumpType, CommitRecord } from "./types.js";
6
7
  //#region packages/changelog/src/utils/versioning.d.ts
7
8
  /** How/where a changelog run applies its version bump. */
8
9
  export type VersioningTarget = 'uniform' | 'root-only' | 'individual';
9
- /** The normalized `changelog.versioning` config. */
10
+ /** The normalized `ci.changelog.versioning` config. */
10
11
  export interface ResolvedVersioning {
11
12
  /** Whether versions are written to `package.json` at all. */
12
13
  enabled: boolean;
@@ -14,13 +15,21 @@ export interface ResolvedVersioning {
14
15
  target: VersioningTarget;
15
16
  /** Explicit workspace globs (when configured). */
16
17
  workspaces?: string[];
18
+ /** Custom bump rules keyed by version index. */
19
+ bump?: Record<string, unknown>;
20
+ /** Apply a bump per matching change instead of once. */
21
+ allowOverBump?: boolean;
22
+ /** Changelog provider id, callback, or custom provider object. */
23
+ provider?: unknown;
24
+ /** Commit formatting options. */
25
+ commit?: unknown;
17
26
  }
18
27
  /**
19
- * Normalize the `changelog.versioning` union (`boolean | { target, workspaces }`)
28
+ * Normalize the `ci.changelog.versioning` union (`boolean | { target, workspaces }`)
20
29
  * into a concrete plan input. `true`/absent means uniform with defaults; `false`
21
30
  * disables writing versions while still generating changelog entries.
22
31
  */
23
- export declare function resolveVersioning(changelog?: ToolchainChangelogConfig): ResolvedVersioning;
32
+ export declare function resolveVersioning(changelog?: ChangelogConfig): ResolvedVersioning;
24
33
  /** The packages a changelog run versions. */
25
34
  export interface VersionPackages {
26
35
  /** The repository root. */
@@ -41,6 +50,14 @@ export declare function writePackageVersion(dir: string, version: string): void;
41
50
  * workspace is found, so a broken checkout can't wedge a release.
42
51
  */
43
52
  export declare function discoverVersionPackages(workspaces?: string[], root?: string): VersionPackages;
53
+ /** Context handed to custom bump callbacks. */
54
+ export interface BumpRuleContext {
55
+ env: NodeJS.ProcessEnv;
56
+ logger: typeof logger;
57
+ packageJson?: Record<string, unknown>;
58
+ }
59
+ /** Resolve a bump from custom rules, falling back to Conventional Commits. */
60
+ export declare function deriveCustomBump(records: CommitRecord[], rules?: Record<string, unknown>, allowOverBump?: boolean, context?: BumpRuleContext): BumpType;
44
61
  /** The version bump plan for a changelog run. */
45
62
  export interface VersionPlan {
46
63
  /** The version heading for the root changelog. */
@@ -56,6 +73,10 @@ export interface PlanVersionsOptions {
56
73
  rootVersion: string;
57
74
  /** The bump derived from all scanned commits. */
58
75
  bump: BumpType;
76
+ /** Custom bump rules (used for per-workspace derivation). */
77
+ bumpRules?: Record<string, unknown>;
78
+ /** Allow over-bumping (default false). */
79
+ allowOverBump?: boolean;
59
80
  /** The git revision range the commits were read from. */
60
81
  range: string;
61
82
  /** The repository root (default: resolved from cwd). */
@@ -1 +1 @@
1
- import{resolve 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{deriveBump as n,readCommits as r}from"./git.js";import{repoRoot as i}from"./repo.js";import{bumpVersion as a}from"./version.js";import{relatedWorkspacePaths as o}from"./graph.js";import{existsSync as s,globSync as c,readFileSync as l,writeFileSync as u}from"node:fs";function d(e){let t=e?.versioning;return t===!1?{enabled:!1,target:`uniform`}:t===void 0||t===!0?{enabled:!0,target:`uniform`}:{enabled:!0,target:t.target??`uniform`,...t.workspaces?{workspaces:t.workspaces}:{}}}function f(t){try{let n=JSON.parse(l(e(t,`package.json`),`utf8`));return typeof n.version==`string`?n.version:void 0}catch{return}}function p(n,r){let i=e(n,`package.json`),a=l(i,`utf8`),o=a.replace(/("version"\s*:\s*)"[^"]*"/,`$1"${r}"`);o!==a&&(u(i,o,`utf8`),t.info(` bumped ${i}`))}function m(n,r=i()){let a=s(e(r,`package.json`)),o=n;if(o===void 0&&a)try{o=JSON.parse(l(e(r,`package.json`),`utf8`)).workspaces}catch{o=void 0}let u=/* @__PURE__ */ new Set;for(let t of o??[])if(t===`.`)u.add(r);else for(let n of c(t,{cwd:r})){let t=e(r,n);s(e(t,`package.json`))&&u.add(t)}return u.delete(r),!a&&u.size===0&&t.warn(`[changelog] versioning: no root package.json and no matching workspaces — nothing to version.`),{root:r,rootHasPackage:a,workspaces:[...u]}}function h(e){let{versioning:t,bump:s,range:c}=e,l=e.root??i(),{rootHasPackage:u,workspaces:d}=m(t.workspaces,l),p=e.commitsFor??(e=>r(c,o(e,l))),h=a(e.rootVersion,s),g=/* @__PURE__ */ new Map,_=/* @__PURE__ */ new Map,v=t.enabled?t.target:`uniform`;if(u&&t.enabled&&g.set(l,h),v===`individual`)for(let e of d){let r=p(e);if(r.length===0)continue;let i=a(f(e)??`0.0.0`,n(r));_.set(e,i),t.enabled&&g.set(e,i)}else if(v===`uniform`)for(let e of d)_.set(e,h),t.enabled&&g.set(e,h);return{rootVersion:h,writes:g,entries:_}}export{m as discoverVersionPackages,h as planVersions,f as readPackageVersion,d as resolveVersioning,p as writePackageVersion};
1
+ import{resolve 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{deriveBump as n,readCommits as r}from"./git.js";import{repoRoot as i}from"./repo.js";import{parseCcSubject as a}from"./format.js";import{bumpVersion as o}from"./version.js";import{relatedWorkspacePaths as s}from"./graph.js";import{existsSync as c,globSync as l,readFileSync as u,writeFileSync as d}from"node:fs";function f(e){let t=e?.versioning;return t===!1?{enabled:!1,target:`uniform`}:t===void 0||t===!0?{enabled:!0,target:`uniform`}:{enabled:!0,target:t.target??`uniform`,...t.workspaces?{workspaces:t.workspaces}:{},...t.bump?{bump:t.bump}:{},...t.allowOverBump?{allowOverBump:!0}:{},...t.provider?{provider:t.provider}:{},...t.commit?{commit:t.commit}:{}}}function p(t){try{let n=JSON.parse(u(e(t,`package.json`),`utf8`));return typeof n.version==`string`?n.version:void 0}catch{return}}function m(n,r){let i=e(n,`package.json`),a=u(i,`utf8`),o=a.replace(/("version"\s*:\s*)"[^"]*"/,`$1"${r}"`);o!==a&&(d(i,o,`utf8`),t.info(` bumped ${i}`))}function h(n,r=i()){let a=c(e(r,`package.json`)),o=n;if(o===void 0&&a)try{let t=JSON.parse(u(e(r,`package.json`),`utf8`)).workspaces;o=Array.isArray(t)?t.filter(e=>typeof e==`string`):t&&typeof t==`object`&&Array.isArray(t.packages)?t.packages.filter(e=>typeof e==`string`):void 0}catch{o=void 0}let s=/* @__PURE__ */ new Set;for(let t of o??[])if(t===`.`)s.add(r);else for(let n of l(t,{cwd:r})){let t=e(r,n);c(e(t,`package.json`))&&s.add(t)}return s.delete(r),!a&&s.size===0&&t.warn(`[changelog] versioning: no root package.json and no matching workspaces — nothing to version.`),{root:r,rootHasPackage:a,workspaces:[...s]}}function g(e,t,n){if(e===!0)return!0;if(e===!1||e==null)return!1;if(typeof e==`string`){if(e.startsWith(`/`)&&e.lastIndexOf(`/`)>0){let n=e.lastIndexOf(`/`);try{return new RegExp(e.slice(1,n),e.slice(n+1)).test(`${t.subject}\n${t.body}`)}catch{return!1}}return`${t.subject}\n${t.body}`.includes(e)}if(Array.isArray(e))return e.some(e=>g(e,t,n));if(typeof e==`function`)return!!e({...n,commit:t});if(typeof e==`object`){let n=e,r=a(t.subject);return!(n.breaking===!0&&!r.breaking&&!/BREAKING[ -]CHANGE/i.test(t.body)||typeof n.type==`string`&&r.type!==n.type||Array.isArray(n.types)&&!n.types.includes(r.type)||typeof n.scope==`string`&&r.scope!==n.scope||Array.isArray(n.scopes)&&!n.scopes.includes(r.scope)||typeof n.pattern==`string`&&!new RegExp(n.pattern).test(`${t.subject}\n${t.body}`)||typeof n.match==`string`&&!`${t.subject}\n${t.body}`.includes(n.match))}return!1}const _=[`patch`,`minor`,`major`];function v(e,r,i=!1,a={env:process.env,logger:t}){if(!r||Object.keys(r).length===0)return n(e);let o=`patch`,s=0;for(let t of _){let n=r[t];for(let r of e)(typeof n==`function`?(()=>{let e=n({...a,commit:r,level:t});return typeof e==`string`?e===t:!!e})():g(n,r,a))&&(s+=1,_.indexOf(t)>_.indexOf(o)&&(o=t))}if(i&&s>1)for(let e=1;e<s&&o!==`major`;e+=1)o=o===`patch`?`minor`:`major`;return o}function y(e){let{versioning:t,bump:n,range:a}=e,c=e.root??i(),{rootHasPackage:l,workspaces:u}=h(t.workspaces,c),d=e.commitsFor??(e=>r(a,s(e,c))),f=o(e.rootVersion,n),m=/* @__PURE__ */ new Map,g=/* @__PURE__ */ new Map,_=t.enabled?t.target:`uniform`;if(l&&t.enabled&&m.set(c,f),_===`individual`)for(let n of u){let r=d(n);if(r.length===0)continue;let i=o(p(n)??`0.0.0`,v(r,e.bumpRules,e.allowOverBump));g.set(n,i),t.enabled&&m.set(n,i)}else if(_===`uniform`)for(let e of u)g.set(e,f),t.enabled&&m.set(e,f);return{rootVersion:f,writes:m,entries:g}}export{v as deriveCustomBump,h as discoverVersionPackages,y as planVersions,p as readPackageVersion,f as resolveVersioning,m as writePackageVersion};
@@ -1 +1 @@
1
- import{resolve 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{readCommits as n,repoSlug as r}from"./git.js";import{discoverWorkspaceDirs as i,repoRoot as a}from"./repo.js";import{packageChangesForCurrent as o}from"./packages.js";import{formatChangelogFile as s}from"./format.js";import{prependChangelogEntry as c,renderChangelogEntry as l}from"./version.js";import{parseExistingChangelog as u,reformatRootChangelog as d}from"./reformat.js";import{buildSummary as f}from"./summary.js";import{relatedWorkspacePaths as p}from"./graph.js";import{existsSync as m,readFileSync as h,writeFileSync as g}from"node:fs";function _(_,v,y,b,x,S=!1,C){let w=a(),T=r(),E=e(w,`CHANGELOG.md`),D=``;if(S&&m(E)){let e=u(h(E,`utf8`))[0];e&&(D=o(e.version))}if(x){let e=d(S);e&&(g(E,e,`utf8`),t.info(` reformatted ${E}`))}let O=l(_,b,/* @__PURE__ */ new Date,!0,D);c(E,O),t.info(` updated ${E}`);let k=C??new Map(i().filter(t=>e(t)!==e(w)).map(e=>[e,_]));for(let[r,i]of k){let a=e(r,`CHANGELOG.md`),o=n(v,p(r,w));if(o.length===0){t.info(` skipped ${a} (no related commits)`);continue}let s=!m(a),u=f(o);c(a,l(i,u,/* @__PURE__ */ new Date)),t.info(` ${s?`created`:`updated`} ${a}`)}let A=/* @__PURE__ */ new Set([...i(),...k.keys()]);for(let t of A){let n=e(t,`CHANGELOG.md`);m(n)&&s(n,T)}}export{_ as writeChangelogs};
1
+ import{resolve 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{readCommits as n,repoSlug as r}from"./git.js";import{discoverWorkspaceDirs as i,repoRoot as a}from"./repo.js";import{packageChangesForCurrent as o}from"./packages.js";import{formatChangelogFile as s}from"./format.js";import{prependChangelogEntry as c,renderChangelogEntry as l}from"./version.js";import{parseExistingChangelog as u,reformatRootChangelog as d}from"./reformat.js";import{buildSummary as f}from"./summary.js";import{relatedWorkspacePaths as p}from"./graph.js";import{existsSync as m,readFileSync as h,writeFileSync as g}from"node:fs";function _(_,v,y,b,x,S=!1,C,w=!0,T){let E=a(),D=r(),O=e(E,`CHANGELOG.md`),k=``;if(S&&m(O)){let e=u(h(O,`utf8`))[0];e&&(k=o(e.version))}if(x){let e=d(S,T);e&&(g(O,e,`utf8`),t.info(` reformatted ${O}`))}let A=l(_,b,/* @__PURE__ */ new Date,!0,k);c(O,A),t.info(` updated ${O}`);let j=C??new Map(i().filter(t=>e(t)!==e(E)).map(e=>[e,_]));for(let[r,i]of j){let a=e(r,`CHANGELOG.md`),o=n(v,p(r,E));if(o.length===0){t.info(` skipped ${a} (no related commits)`);continue}let s=!m(a),u=f(o,{commitlint:w,range:v,groups:T});c(a,l(i,u,/* @__PURE__ */ new Date)),t.info(` ${s?`created`:`updated`} ${a}`)}let M=/* @__PURE__ */ new Set([...i(),...j.keys()]);for(let t of M){let n=e(t,`CHANGELOG.md`);m(n)&&s(n,D)}}export{_ as writeChangelogs};
@@ -1,6 +1,6 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { WorkflowConfig, WorkflowSetting, WorkflowStep } from "../../shared/src/config-types.js";
3
+ import { WorkflowOptions, WorkflowSetting, WorkflowStep } from "../../shared/src/config-types.js";
4
4
  import { Replacements } from "../../shared/src/template.js";
5
5
  import "../../shared/src/index.js";
6
6
  //#region packages/changelog/src/workflows.d.ts
@@ -31,27 +31,47 @@ export declare const DEFAULT_WORKFLOW_TOKENS: Replacements;
31
31
  export type WorkflowId = 'ci' | 'changelog' | 'release' | 'sync' | 'issues';
32
32
  /** Default file name per workflow id. */
33
33
  export declare const WORKFLOW_FILENAMES: Record<WorkflowId, string>;
34
- /** Whether a workflow setting enables the workflow (default true). */
34
+ /** The default directory for generated workflows. */
35
+ export declare const DEFAULT_WORKFLOW_DIR = ".github/workflows";
36
+ /**
37
+ * The path a workflow is written to. A setting may override the directory
38
+ * (`dir`) and file name (`filename`); custom ids default to `<id>.yml`.
39
+ */
40
+ export declare function workflowFilePath(id: string, setting: WorkflowSetting | undefined, defaultFilename?: string): string;
41
+ /** Whether a workflow setting enables the workflow (opt-in: absent is disabled). */
35
42
  export declare function isEnabled(setting: WorkflowSetting | undefined): boolean;
43
+ export interface DefaultWorkflowOptions {
44
+ /** Include commitlint in the CI workflow (default true). */
45
+ commitlint?: boolean;
46
+ /** Config-defined workflows (enabled by presence; no boolean form). */
47
+ custom?: Record<string, string | WorkflowOptions>;
48
+ }
36
49
  /** Build all default workflows for a set of tokens. */
37
- export declare function defaultWorkflows(tokens: Replacements): Record<WorkflowId, Workflow>;
38
- /** Merge a consumer's {@link WorkflowConfig} over a default workflow. */
39
- export declare function applyWorkflowConfig(workflow: Workflow, config?: WorkflowConfig): Workflow;
50
+ export declare function defaultWorkflows(tokens: Replacements, options?: DefaultWorkflowOptions): Record<WorkflowId, Workflow>;
51
+ /** Merge a consumer's {@link WorkflowOptions} over a default workflow. */
52
+ export declare function applyWorkflowConfig(workflow: Workflow, config?: WorkflowOptions): Workflow;
40
53
  export interface RenderWorkflowOptions {
41
54
  /** Base replacement tokens (merged with the workflow's own `tokens`). */
42
55
  tokens: Replacements;
43
56
  /** The consumer's per-workflow config. */
44
- config?: WorkflowConfig;
57
+ config?: WorkflowOptions;
58
+ /** Include commitlint in the CI workflow (default true). */
59
+ commitlint?: boolean;
45
60
  }
46
61
  /**
47
62
  * Build one workflow as a YAML string, applying the consumer's config. Returns
48
63
  * `undefined` when the workflow is disabled.
49
64
  */
50
65
  export declare function renderWorkflow(id: WorkflowId, options: RenderWorkflowOptions): string | undefined;
66
+ /**
67
+ * Build a custom workflow from an empty skeleton, merging the consumer's
68
+ * settings over it (`triggers` -> `on`, `jobs` -> jobs, `extra` -> top-level).
69
+ */
70
+ export declare function renderCustomWorkflow(id: string, options: RenderWorkflowOptions): string | undefined;
51
71
  /**
52
72
  * Render every workflow, keyed by file name (disabled ones are omitted). A raw
53
73
  * string setting is used verbatim as the workflow content (no default merge and
54
74
  * no token replacement).
55
75
  */
56
- export declare function renderWorkflows(tokens: Replacements, workflows?: Partial<Record<WorkflowId, WorkflowSetting>>): Record<string, string>;
76
+ export declare function renderWorkflows(tokens: Replacements, workflows?: Partial<Record<WorkflowId, WorkflowSetting>>, options?: DefaultWorkflowOptions): Record<string, string>;
57
77
  //#endregion
@@ -1,5 +1,5 @@
1
- import"node:path";import"node:url";import.meta.url;import{applyReplacementsDeep as e}from"../../shared/src/template.js";import{toYaml as t}from"../../shared/src/yaml.js";import"../../shared/src/index.js";const n={nodeVersion:`22`,yarnVersion:`4.17.1`,packageManager:`yarn`,mainBranch:`main`,devBranch:`main`,tooling:`dbx`,commitlintConfig:`commitlint.config.mjs`},r={ci:`ci.yml`,changelog:`changelog.yml`,release:`release.yml`,sync:`sync.yml`,issues:`issues.yml`};function i(e){return e===void 0?!0:typeof e==`boolean`?e:typeof e==`string`?e.trim().length>0:e.enabled!==!1}function a(e){return`${e.packageManager} ${e.tooling}`}function o(e){return[{name:`Checkout`,uses:`actions/checkout@v4`,with:{"fetch-depth":0,token:"${{ secrets.GITHUB_TOKEN }}"}},{name:`Setup Node`,uses:`actions/setup-node@v4`,with:{"node-version":String(e.nodeVersion)}},{name:`Enable Corepack`,run:`corepack enable\ncorepack prepare ${e.packageManager}@${e.yarnVersion} --activate`},{name:`Install dependencies`,run:`${e.packageManager} install --immutable`}]}function s(e){let t=a(e),n=String(e.mainBranch),r=String(e.devBranch);return{ci:{name:`CI`,on:{push:{branches:[n]},pull_request:{branches:[`release/**`,`feat/**`,`feature/**`,`fix/**`,`chore/**`]}},jobs:{ci:{"runs-on":`ubuntu-latest`,steps:[...o(e),{name:`Commitlint (Conventional Commits)`,if:"${{ github.event_name == 'pull_request' || github.event.before != '0000000000000000000000000000000000000000' }}",run:`set -euo pipefail\nbase="\${{ github.event.pull_request.base.sha || github.event.before }}"\nhead="\${{ github.event.pull_request.head.sha || github.event.after }}"\n${e.packageManager} commitlint --from "$base" --to "$head" --config ${e.commitlintConfig}`},{name:`Verify generated files are in sync`,run:`${t} sync --check`},{name:`Build`,run:`${e.packageManager} build`}]}}},changelog:{name:`Changelog (dev)`,on:{push:{branches:[r]}},permissions:{contents:`write`},concurrency:{group:`changelog-dev`,"cancel-in-progress":!1},jobs:{"generate-changelog":{"runs-on":`ubuntu-latest`,if:`!startsWith(github.event.head_commit.message, 'chore: version packages ') && !startsWith(github.event.head_commit.message, 'release: ')`,env:{GITHUB_TOKEN:"${{ secrets.GITHUB_TOKEN }}"},steps:[...o(e),{name:`Generate changelog + bump versions`,env:{GITHUB_TOKEN:"${{ secrets.GITHUB_TOKEN }}"},run:[`set -euo pipefail`,'after="${{ github.event.after }}"; [ -n "$after" ] || after="HEAD"',`boundary="$(git log --format=%H --grep='^chore: version packages ' -1 || true)"`,`if [ -n "$boundary" ]; then range="$boundary..$after"; else range="$after"; fi`,`${t} changelog --range "$range"`].join(`
2
- `)},{name:`Commit + push changelog updates`,env:{GITHUB_TOKEN:"${{ secrets.GITHUB_TOKEN }}"},run:[`set -euo pipefail`,`git diff --quiet && { echo "No changelog changes."; exit 0; }`,`git config user.name "github-actions[bot]"`,`git config user.email "41898282+github-actions[bot]@users.noreply.github.com"`,`git add -u -- "*package.json" "*CHANGELOG.md"`,`git commit -m "chore: version packages ($(node -p "require('./package.json').version"))"`,`git push origin ${r}`].join(`
3
- `)}]}}},release:{name:`Release`,on:{push:{branches:[n]},workflow_dispatch:null},permissions:{contents:`write`,"pull-requests":`write`},concurrency:{group:`release`,"cancel-in-progress":!1},jobs:{"create-release-pr":{"runs-on":`ubuntu-latest`,if:`(github.event_name == 'push' || github.event_name == 'workflow_dispatch') && !startsWith(github.event.head_commit.message, 'chore: version packages ') && !startsWith(github.event.head_commit.message, 'release: ')`,env:{GITHUB_TOKEN:"${{ secrets.GITHUB_TOKEN }}"},steps:[...o(e),{name:`Open release PR`,env:{GITHUB_TOKEN:"${{ secrets.GITHUB_TOKEN }}"},run:[`set -euo pipefail`,`version="$(node -p "require('./package.json').version")"`,`branch="release/$version"`,`if git ls-remote --exit-code --heads origin "$branch" >/dev/null 2>&1; then`,` echo "Release PR already open for $version."; exit 0`,`fi`,`git config user.name "github-actions[bot]"`,`git config user.email "41898282+github-actions[bot]@users.noreply.github.com"`,`git checkout -b "$branch"`,`git add -A`,`git commit -m "chore: version packages ($version)" || true`,`git push origin "$branch"`,`last_tag="$(git describe --tags --abbrev=0 2>/dev/null || true)"`,`if [ -n "$last_tag" ]; then`,' last_version="${last_tag#v}"',` notes="$(awk -v v="$last_version" '/^## / { if ($2 == v) exit; started = 1 } started { print }' CHANGELOG.md 2>/dev/null || true)"`,`else`,` notes="$(cat CHANGELOG.md 2>/dev/null || true)"`,`fi`,`[ -n "$notes" ] || notes="Release $version"`,`gh pr create --base ${n} --head "$branch" --title "release: $version" --body "$notes"`].join(`
4
- `)}]}}},sync:{name:`Toolchain sync`,on:{push:{branches:[.../* @__PURE__ */ new Set([n,r])]},pull_request:null},jobs:{sync:{"runs-on":`ubuntu-latest`,steps:[...o(e),{name:`Verify generated files are in sync`,run:`${t} sync --check`}]}}},issues:{name:`Issues`,on:{issues:{types:[`opened`]}},permissions:{issues:`write`},jobs:{"enforce-title":{"runs-on":`ubuntu-latest`,steps:[{name:`Check and rename issue title`,env:{GH_TOKEN:"${{ github.token }}",ISSUE_NUMBER:"${{ github.event.issue.number }}"},run:[`set -euo pipefail`,`labels=$(gh issue view "$ISSUE_NUMBER" --json labels -q '.labels[].name' || true)`,`title=$(gh issue view "$ISSUE_NUMBER" --json title -q '.title')`,`type=""`,`for label in $labels; do case "$label" in *bug*) type="bug" ;; esac; done`,`if [ -z "$type" ]; then for label in $labels; do case "$label" in *enhancement*|*feature*|*feat*) type="feat" ;; esac; done; fi`,`if [ -z "$type" ]; then echo "No bug/enhancement label on issue #$ISSUE_NUMBER; skipping."; exit 0; fi`,`prefix="[bug]"; [ "$type" = "feat" ] && prefix="[feat]"`,`stripped=$(printf '%s' "$title" | sed -E 's/^\\[(bug|feat)\\] *//i')`,`new_title="$prefix $stripped"`,`if [ "$new_title" = "$title" ]; then echo "Issue #$ISSUE_NUMBER title already conforms."; exit 0; fi`,`gh issue edit "$ISSUE_NUMBER" --title "$new_title"`].join(`
5
- `)}]}}}}}function c(e){return e.steps?Array.isArray(e.steps)?e.steps:[e.steps]:[]}function l(e,t={}){let n=structuredClone(e);if(t.pushBranches){let e=n.on.push??{};n.on.push={...e,branches:t.pushBranches}}if(t.pullRequestBranches){let e=n.on.pull_request??{};n.on.pull_request={...e,branches:t.pullRequestBranches}}t.triggers&&(n.on={...n.on,...t.triggers}),t.extra&&Object.assign(n,t.extra),t.jobs&&(n.jobs={...n.jobs,...t.jobs});let r=Object.keys(n.jobs)[0];for(let e of c(t)){let t=e.job??r;if(!t)continue;let i=n.jobs[t];i&&(i.steps=[...e.before??[],...i.steps,...e.after??[]])}return n}function u(r,i){let a=i.config??{};if(a.enabled===!1)return;let o={...n,...i.tokens,...a.tokens},c=s(o)[r],u=e(l(c,a),o);return t(u)}function d(e,t={}){let n={};for(let a of Object.keys(r)){let o=t[a];if(!i(o))continue;if(typeof o==`string`){n[r[a]]=o;continue}let s=u(a,{tokens:e,config:typeof o==`object`?o:{}});s&&(n[r[a]]=s)}return n}export{n as DEFAULT_WORKFLOW_TOKENS,r as WORKFLOW_FILENAMES,l as applyWorkflowConfig,s as defaultWorkflows,i as isEnabled,u as renderWorkflow,d as renderWorkflows};
1
+ import"node:path";import"node:url";import.meta.url;import{applyReplacementsDeep as e}from"../../shared/src/template.js";import{DEFAULT_PACKAGE_MANAGER_VERSIONS as t}from"../../shared/src/toolchain.js";import{toYaml as n}from"../../shared/src/yaml.js";import"../../shared/src/index.js";const r={nodeVersion:`22`,yarnVersion:`4.17.1`,packageManager:`yarn`,mainBranch:`main`,devBranch:`main`,tooling:`dbx`,commitlintConfig:`commitlint.config.mjs`},i={ci:`ci.yml`,changelog:`changelog.yml`,release:`release.yml`,sync:`sync.yml`,issues:`issues.yml`},a=`.github/workflows`;function o(e){let t=(e??`.github/workflows`).replace(/\\/g,`/`).replace(/^\.?\//,``).replace(/\/+$/,``);if(/^[a-zA-Z]:/.test(t)||t.split(`/`).includes(`..`))throw Error(`invalid workflow directory "${e}" (must stay inside the project).`);return t}function s(e,t){let n=(e??t).trim();if(!n||/[\\/]/.test(n)||n===`.`||n===`..`)throw Error(`invalid workflow filename "${e}" (expected a file name).`);return n}function c(e,t,n=`${e}.yml`){let r=t&&typeof t==`object`?t:void 0,i=o(r?.dir),a=s(r?.filename,n);return i?`${i}/${a}`:a}function l(e){return e===void 0?!1:typeof e==`boolean`?e:typeof e==`string`?e.trim().length>0:e.enabled!==!1}function u(e){let n=String(e.packageManager??`yarn`);return String(e.packageManagerVersion??e.yarnVersion??t[n]??`4.17.1`)}function d(e){let t=e.config?.tokens??{},n={...r,...e.tokens,...t},i=t.packageManager;return i!==void 0&&i!==e.tokens.packageManager&&t.packageManagerVersion===void 0&&t.yarnVersion===void 0&&(delete n.packageManagerVersion,delete n.yarnVersion),t.packageManagerVersion===void 0&&t.yarnVersion!==void 0&&(n.packageManagerVersion=t.yarnVersion),n}function f(e){let t=String(e.tooling??`dbx`);switch(String(e.packageManager??`yarn`)){case`pnpm`:return`pnpm exec ${t}`;case`npm`:return`npx ${t}`;case`bun`:return`bunx ${t}`;default:return`${e.packageManager??`yarn`} ${t}`}}function p(e){let t=String(e.packageManager??`yarn`),n=u(e),r=[{name:`Checkout`,uses:`actions/checkout@v4`,with:{"fetch-depth":0,token:"${{ secrets.GITHUB_TOKEN }}"}},{name:`Setup Node`,uses:`actions/setup-node@v4`,with:{"node-version":String(e.nodeVersion)}}];return t===`bun`?[...r,{name:`Setup Bun`,uses:`oven-sh/setup-bun@v2`,with:{"bun-version":n}},{name:`Install dependencies`,run:`bun install --frozen-lockfile`}]:t===`npm`?[...r,{name:`Install dependencies`,run:`npm install -g npm@${n}\nnpm ci`}]:[...r,{name:`Enable Corepack`,run:`corepack enable\ncorepack prepare ${t}@${n} --activate`},{name:`Install dependencies`,run:t===`pnpm`?`pnpm install --frozen-lockfile`:`yarn install --immutable`}]}function m(e,t={}){let n=f(e),r=String(e.mainBranch),i=String(e.devBranch),a=t.commitlint!==!1;return{ci:{name:`CI`,on:{push:{branches:[r]},pull_request:{branches:[`release/**`,`feat/**`,`feature/**`,`fix/**`,`chore/**`]}},jobs:{ci:{"runs-on":`ubuntu-latest`,steps:[...p(e),...a?[{name:`Commitlint (Conventional Commits)`,if:"${{ github.event_name == 'pull_request' || github.event.before != '0000000000000000000000000000000000000000' }}",run:`set -euo pipefail\nbase="\${{ github.event.pull_request.base.sha || github.event.before }}"\nhead="\${{ github.event.pull_request.head.sha || github.event.after }}"\n${e.packageManager} commitlint --from "$base" --to "$head" --config ${e.commitlintConfig}`}]:[],{name:`Verify generated files are in sync`,run:`${n} sync --check`},{name:`Build`,run:`${e.packageManager} build`}]}}},changelog:{name:`Changelog (dev)`,on:{push:{branches:[i]}},permissions:{contents:`write`},concurrency:{group:`changelog-dev`,"cancel-in-progress":!1},jobs:{"generate-changelog":{"runs-on":`ubuntu-latest`,if:`!startsWith(github.event.head_commit.message, 'chore: version packages ') && !startsWith(github.event.head_commit.message, 'release: ')`,env:{GITHUB_TOKEN:"${{ secrets.GITHUB_TOKEN }}"},steps:[...p(e),{name:`Generate changelog + bump versions`,env:{GITHUB_TOKEN:"${{ secrets.GITHUB_TOKEN }}"},run:[`set -euo pipefail`,'after="${{ github.event.after }}"; [ -n "$after" ] || after="HEAD"',`boundary="$(git log --format=%H --grep='^chore: version packages ' -1 || true)"`,`if [ -n "$boundary" ]; then range="$boundary..$after"; else range="$after"; fi`,`${n} changelog --range "$range"`].join(`
2
+ `)},{name:`Commit + push changelog updates`,env:{GITHUB_TOKEN:"${{ secrets.GITHUB_TOKEN }}"},run:[`set -euo pipefail`,`git diff --quiet && { echo "No changelog changes."; exit 0; }`,`git config user.name "github-actions[bot]"`,`git config user.email "41898282+github-actions[bot]@users.noreply.github.com"`,`git add -u -- "*package.json" "*CHANGELOG.md"`,`git commit -m "chore: version packages ($(node -p "require('./package.json').version"))"`,`git push origin ${i}`].join(`
3
+ `)}]}}},release:{name:`Release`,on:{push:{branches:[r]},workflow_dispatch:null},permissions:{contents:`write`,"pull-requests":`write`},concurrency:{group:`release`,"cancel-in-progress":!1},jobs:{"create-release-pr":{"runs-on":`ubuntu-latest`,if:`(github.event_name == 'push' || github.event_name == 'workflow_dispatch') && !startsWith(github.event.head_commit.message, 'chore: version packages ') && !startsWith(github.event.head_commit.message, 'release: ')`,env:{GITHUB_TOKEN:"${{ secrets.GITHUB_TOKEN }}"},steps:[...p(e),{name:`Open release PR`,env:{GITHUB_TOKEN:"${{ secrets.GITHUB_TOKEN }}"},run:[`set -euo pipefail`,`version="$(node -p "require('./package.json').version")"`,`branch="release/$version"`,`if git ls-remote --exit-code --heads origin "$branch" >/dev/null 2>&1; then`,` echo "Release PR already open for $version."; exit 0`,`fi`,`git config user.name "github-actions[bot]"`,`git config user.email "41898282+github-actions[bot]@users.noreply.github.com"`,`git checkout -b "$branch"`,`git add -A`,`git commit -m "chore: version packages ($version)" || true`,`git push origin "$branch"`,`last_tag="$(git describe --tags --abbrev=0 2>/dev/null || true)"`,`if [ -n "$last_tag" ]; then`,' last_version="${last_tag#v}"',` notes="$(awk -v v="$last_version" '/^## / { if ($2 == v) exit; started = 1 } started { print }' CHANGELOG.md 2>/dev/null || true)"`,`else`,` notes="$(cat CHANGELOG.md 2>/dev/null || true)"`,`fi`,`[ -n "$notes" ] || notes="Release $version"`,`gh pr create --base ${r} --head "$branch" --title "release: $version" --body "$notes"`].join(`
4
+ `)}]}}},sync:{name:`Toolchain sync`,on:{push:{branches:[.../* @__PURE__ */ new Set([r,i])]},pull_request:null},jobs:{sync:{"runs-on":`ubuntu-latest`,steps:[...p(e),{name:`Verify generated files are in sync`,run:`${n} sync --check`}]}}},issues:{name:`Issues`,on:{issues:{types:[`opened`]}},permissions:{issues:`write`},jobs:{"enforce-title":{"runs-on":`ubuntu-latest`,steps:[{name:`Check and rename issue title`,env:{GH_TOKEN:"${{ github.token }}",ISSUE_NUMBER:"${{ github.event.issue.number }}"},run:[`set -euo pipefail`,`labels=$(gh issue view "$ISSUE_NUMBER" --json labels -q '.labels[].name' || true)`,`title=$(gh issue view "$ISSUE_NUMBER" --json title -q '.title')`,`type=""`,`for label in $labels; do case "$label" in *bug*) type="bug" ;; esac; done`,`if [ -z "$type" ]; then for label in $labels; do case "$label" in *enhancement*|*feature*|*feat*) type="feat" ;; esac; done; fi`,`if [ -z "$type" ]; then echo "No bug/enhancement label on issue #$ISSUE_NUMBER; skipping."; exit 0; fi`,`prefix="[bug]"; [ "$type" = "feat" ] && prefix="[feat]"`,`stripped=$(printf '%s' "$title" | sed -E 's/^\\[(bug|feat)\\] *//i')`,`new_title="$prefix $stripped"`,`if [ "$new_title" = "$title" ]; then echo "Issue #$ISSUE_NUMBER title already conforms."; exit 0; fi`,`gh issue edit "$ISSUE_NUMBER" --title "$new_title"`].join(`
5
+ `)}]}}}}}function h(e){return e.steps?Array.isArray(e.steps)?e.steps:[e.steps]:[]}function g(e,t={}){let n=structuredClone(e);if(t.pushBranches){let e=n.on.push??{};n.on.push={...e,branches:t.pushBranches}}if(t.pullRequestBranches){let e=n.on.pull_request??{};n.on.pull_request={...e,branches:t.pullRequestBranches}}t.triggers&&(n.on={...n.on,...t.triggers}),t.extra&&Object.assign(n,t.extra),t.jobs&&(n.jobs={...n.jobs,...t.jobs});let r=Object.keys(n.jobs)[0];for(let e of h(t)){let t=e.job??r;if(!t)continue;let i=n.jobs[t];i&&(i.steps=[...e.before??[],...i.steps,...e.after??[]])}return n}function _(t,r){let i=r.config??{};if(i.enabled===!1)return;let a=d(r),o=m(a,{commitlint:r.commitlint!==!1})[t],s=e(g(o,i),a);return n(s)}function v(t,r){let i=r.config??{};if(i.enabled===!1)return;let a=d(r),o=e(g({name:t,on:{},jobs:{}},i),a),s=o.on&&typeof o.on==`object`&&Object.keys(o.on).length>0,c=o.jobs&&typeof o.jobs==`object`&&Object.keys(o.jobs).length>0;if(!s||!c)throw Error(`custom workflow "${t}" must define at least one trigger and one job (use \`triggers\` and \`jobs\`, or \`extra\`).`);return n(o)}function y(e,t={},n={}){let r={};for(let a of Object.keys(i)){let o=t[a];if(!l(o))continue;let s=c(a,o,i[a]),u=s.split(`/`).pop()??s;if(typeof o==`string`){r[u]=o;continue}let d=_(a,{tokens:e,config:typeof o==`object`?o:{},...n});d&&(r[u]=d)}for(let[t,i]of Object.entries(n.custom??{})){if(!l(i))continue;let a=c(t,i),o=a.split(`/`).pop()??a;if(typeof i==`string`){r[o]=i;continue}let s=v(t,{tokens:e,config:i,...n});s&&(r[o]=s)}return r}export{a as DEFAULT_WORKFLOW_DIR,r as DEFAULT_WORKFLOW_TOKENS,i as WORKFLOW_FILENAMES,g as applyWorkflowConfig,m as defaultWorkflows,l as isEnabled,v as renderCustomWorkflow,_ as renderWorkflow,y as renderWorkflows,c as workflowFilePath};
@@ -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 n from"node:fs";function r(t,n){return e.resolve(t??n)}function i(i){let{engine:a}=i,o=i.defaults??{};return[{name:`config:env`,description:`Generate .env.example from the config schemas.`,options:[{flags:`-o, --out <dir>`,description:`Output directory.`}],run:({out:n})=>{let i=e.join(r(n,o.envDir??a.root),`.env.example`);a.writeEnvFile({output:i}),t.info(`Generated ${e.relative(process.cwd(),i)}`)}},{name:`config:types`,description:`Generate the config and env types.`,options:[{flags:`-o, --out <dir>`,description:`Output directory.`},{flags:`--env`,description:`Also write the env type files.`}],run:({out:n,env:i})=>{let s=r(n,o.typesDir??a.root),c=a.writeConfigTypes({outputDir:s});i&&c.push(...a.writeEnvTypes({outputDir:s}));for(let n of c)t.info(`Generated ${e.relative(process.cwd(),n)}`)}},{name:`config:json`,description:`Generate the config metadata JSON.`,options:[{flags:`-o, --out <file>`,description:`Output file.`}],run:({out:i})=>{let s=r(i,o.configJsonPath??e.join(a.root,`config.json`)),c=a.buildConfigJson();n.mkdirSync(e.dirname(s),{recursive:!0}),n.writeFileSync(s,`${JSON.stringify(c,null,4)}\n`,`utf-8`),t.info(`Generated ${e.relative(process.cwd(),s)}`)}},{name:`config:schema`,description:`Generate the untyped JSON Schema.`,options:[{flags:`-o, --out <file>`,description:`Output file.`}],run:async({out:n})=>{let i=r(n,o.schemaPath??e.join(a.root,`config.schema.json`));await a.writeJsonSchema({output:i}),t.info(`Generated ${e.relative(process.cwd(),i)}`)}},{name:`config:markdown`,description:`Generate the markdown configuration reference.`,options:[{flags:`-o, --out <dir>`,description:`Output directory.`}],run:({out:n})=>{let i=r(n,o.docsDir??e.join(a.root,`docs/reference/configuration`)),s=a.writeMarkdown({outDir:i});for(let n of s)t.info(`Generated ${e.relative(process.cwd(),n)}`)}},{name:`config:cli`,description:`Generate the CLI options JSON.`,options:[{flags:`-o, --out <file>`,description:`Output file.`}],run:({out:n})=>{let i=r(n,o.cliOptionsPath??e.join(a.root,`cli-options.json`));a.generateCliOptions({output:i}),t.info(`Generated ${e.relative(process.cwd(),i)}`)}},{name:`config:all`,description:`Run every config generator.`,options:[{flags:`-o, --out <dir>`,description:`Base output directory.`}],run:async({out:n})=>{let i=r(n,a.root),o=[];o.push(a.writeEnvFile({output:e.join(i,`.env.example`)})),o.push(...a.writeConfigTypes({outputDir:e.join(i,`types`)}),...a.writeEnvTypes({outputDir:e.join(i,`types`)}),...a.writeMarkdown({outDir:e.join(i,`docs/reference/configuration`)})),o.push(await a.writeJsonSchema({output:e.join(i,`config.schema.json`)})),o.push(a.generateCliOptions({output:e.join(i,`cli-options.json`)}));for(let n of o.filter(e=>typeof e==`string`))t.info(`Generated ${e.relative(process.cwd(),n)}`)}}]}export{i as configCommands};
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 n from"node:fs";function r(t,n){return e.resolve(t??n)}function i(i){let{engine:a}=i,o=i.defaults??{};return[{name:`config:env`,description:`Generate .env.example from the config schemas.`,options:[{flags:`-o, --out <dir>`,description:`Output directory.`}],run:({out:n})=>{let i=e.join(r(n,o.envDir??a.root),`.env.example`);a.writeEnvFile({output:i}),t.info(`Generated ${e.relative(process.cwd(),i)}`)}},{name:`config:types`,description:`Generate the config and env types.`,options:[{flags:`-o, --out <dir>`,description:`Output directory.`},{flags:`--env`,description:`Also write the env type files.`}],run:({out:n,env:i})=>{let s=r(n,o.typesDir??a.root),c=a.writeConfigTypes({outputDir:s});i&&c.push(...a.writeEnvTypes({outputDir:s}));for(let n of c)t.info(`Generated ${e.relative(process.cwd(),n)}`)}},{name:`config:json`,description:`Generate the config metadata JSON.`,options:[{flags:`-o, --out <file>`,description:`Output file.`}],run:({out:i})=>{let s=r(i,o.configJsonPath??e.join(a.root,`config.json`)),c=a.buildConfigJson();n.mkdirSync(e.dirname(s),{recursive:!0}),n.writeFileSync(s,`${JSON.stringify(c,null,4)}\n`,`utf-8`),t.info(`Generated ${e.relative(process.cwd(),s)}`)}},{name:`config:schema`,description:`Generate the untyped JSON Schema.`,options:[{flags:`-o, --out <file>`,description:`Output file.`}],run:async({out:n})=>{let i=r(n,o.schemaPath??e.join(a.root,`config.schema.json`));await a.writeJsonSchema({output:i}),t.info(`Generated ${e.relative(process.cwd(),i)}`)}},{name:`config:markdown`,description:`Generate the markdown configuration reference.`,options:[{flags:`-o, --out <dir>`,description:`Output directory.`}],run:({out:n})=>{let i=r(n,o.docsDir??e.join(a.root,`docs/reference/configuration`)),s=a.writeMarkdown({outputDir:i});for(let n of s)t.info(`Generated ${e.relative(process.cwd(),n)}`)}},{name:`config:cli`,description:`Generate the CLI options JSON.`,options:[{flags:`-o, --out <file>`,description:`Output file.`}],run:({out:n})=>{let i=r(n,o.cliOptionsPath??e.join(a.root,`cli-options.json`));a.generateCliOptions({output:i}),t.info(`Generated ${e.relative(process.cwd(),i)}`)}},{name:`config:all`,description:`Run every config generator.`,options:[{flags:`-o, --out <dir>`,description:`Base output directory.`}],run:async({out:n})=>{let i=r(n,a.root),o=[];o.push(a.writeEnvFile({output:e.join(i,`.env.example`)})),o.push(...a.writeConfigTypes({outputDir:e.join(i,`types`)}),...a.writeEnvTypes({outputDir:e.join(i,`types`)}),...a.writeMarkdown({outputDir:e.join(i,`docs/reference/configuration`)})),o.push(await a.writeJsonSchema({output:e.join(i,`config.schema.json`)})),o.push(a.generateCliOptions({output:e.join(i,`cli-options.json`)}));for(let n of o.filter(e=>typeof e==`string`))t.info(`Generated ${e.relative(process.cwd(),n)}`)}}]}export{i as configCommands};
@@ -1,19 +1,21 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { ConfigScopes, EnvVarDef } from "./types.js";
3
+ import { ConfigDef, ConfigSchema } from "./types.js";
4
4
  //#region packages/config/src/collect.d.ts
5
5
  /** The default env-var prefix used when none is configured. */
6
6
  export declare const DEFAULT_ENV_PREFIX = "APP_";
7
- /** Options for {@link collectEnvVars}. */
8
- export interface CollectEnvVarsOptions {
7
+ /** Options for {@link collectVars}. */
8
+ export interface CollectVarsOptions {
9
9
  /**
10
10
  * Custom env-name -> dotted-path derivation, used when a leaf does not set
11
- * an explicit `path` (eg. to handle dual `PROXIFIED_`/`VITE_` prefixes).
11
+ * an explicit `envPath` (eg. to handle dual `PROXIFIED_`/`VITE_` prefixes).
12
12
  */
13
13
  envPathOf?: (env: string) => string;
14
14
  }
15
- /** Collect every env-var-backed leaf from the scope schemas. */
16
- export declare function collectEnvVars(scopes: ConfigScopes, envPrefix?: string, options?: CollectEnvVarsOptions): EnvVarDef[];
17
- /** Collect the env var names marked `required` for a scope. */
18
- export declare function collectRequiredEnvVars(scopes: ConfigScopes, scope: string, envPrefix?: string, options?: CollectEnvVarsOptions): string[];
15
+ /** Collect every config leaf from scoped schemas. */
16
+ export declare function collectVars(schema: ConfigSchema, envPrefix?: string, options?: CollectVarsOptions): ConfigDef[];
17
+ /** Collect the config paths marked `required` for a scope. */
18
+ export declare function collectRequired(schema: ConfigSchema, scope?: string, envPrefix?: string, options?: CollectVarsOptions): ConfigDef[];
19
+ /** Normalize a config path for the collected definitions. */
20
+ export declare function pathOf(def: ConfigDef): string;
19
21
  //#endregion
@@ -1 +1 @@
1
- import"node:path";import"node:url";import.meta.url;import{envMetaOf as e}from"./schema.js";import{envPathOf as t}from"./types.js";const n=`APP_`;function r(e){let t=Array.isArray(e)?e:[e];if(t.includes(`array`))return`array`;if(t.includes(`object`))return`object`;if(t.includes(`boolean`))return`boolean`;if(t.includes(`number`))return`number`;if(t.includes(`string`))return`string`}function i(n,a,o,s){let c=e(n);if(c?.env){let e;try{e=n.toJSONSchema?.()}catch{}a.push({name:c.env,path:c.path??s.envPathOf?.(c.env)??t(c.env,o),...c.description?{description:c.description}:{},...e?.default===void 0?{}:{default:e.default},...c.required?{required:!0}:{},...c.secret?{secret:!0}:{},scope:c.scope??`default`,...c.public?{public:!0}:{},...r(e?.type)?{envType:r(e?.type)}:{}});return}let l=n.shape;if(l)for(let e of Object.values(l))i(e,a,o,s)}function a(e,t=n,r={}){let a=[];for(let[n,o]of Object.entries(e)){let e=a.length;i(o.zodSchema,a,t,r);for(let t=e;t<a.length;t++)(!a[t].scope||a[t].scope==="default")&&(a[t].scope=n)}return a}function o(e,t,r=n,i={}){return a(e,r,i).filter(e=>e.scope===t&&e.required).map(e=>e.name)}export{n as DEFAULT_ENV_PREFIX,a as collectEnvVars,o as collectRequiredEnvVars};
1
+ import"node:path";import"node:url";import.meta.url;import{isZodSchema as e,metaOf as t,normalizeConfigSchema as n}from"./schema.js";const r=`APP_`;function i(e){let t=Array.isArray(e)?e:[e];if(t.includes(`array`))return`array`;if(t.includes(`object`))return`object`;if(t.includes(`boolean`))return`boolean`;if(t.includes(`number`)||t.includes(`integer`))return`number`;if(t.includes(`string`))return`string`}function a(t){return e(t)?t.shape:t.properties}function o(t){if(e(t))try{return i(t.toJSONSchema().type)}catch{return}return i(t.type)}function s(t){if(e(t))try{return t.toJSONSchema().default}catch{return}return t.default}function c(e){let t=Object.entries(e).map(([e,t])=>[e,s(t)]).filter(([,e])=>e!==void 0);return t.length>0?Object.fromEntries(t):void 0}function l(e,n,r,i,u,d=[]){let f=t(e),p=a(e),m=f?.envPath??f?.path??d.join(`.`),h=f?.envName??f?.env,g=f?.cliFlag??(h?`--${h.slice(h.startsWith(i)?i.length:0).toLowerCase().replace(/_/g,`-`)}`:void 0),_=p?c(p):void 0,v=p?`object`:o(e);if((!p||h||f?.cliFlag)&&n.push({path:m||(f?.id??`config`),...h?{name:h}:{},...g?{cliFlag:g}:{},...f?.description?{description:f.description}:{},...s(e)===void 0?_===void 0?{}:{default:_}:{default:s(e)},...f?.required?{required:!0}:{},...f?.secret?{secret:!0}:{},...f?.public?{public:!0}:{},...f?.scope?{scope:f.scope}:{scope:r},...v?{type:v}:{},...f?{meta:f}:{}}),p)for(let[e,t]of Object.entries(p))l(t,n,r,i,u,[...d,e])}function u(e,t=r,i={}){let a=n(e),o=[];for(let[e,n]of Object.entries(a)){let r=o.length;l(n,o,e,t,i);for(let t=r;t<o.length;t++)(!o[t].scope||o[t].scope==="default")&&(o[t].scope=e)}return o}function d(e,t,n=r,i={}){return u(e,n,i).filter(e=>e.required&&(t===void 0||e.scope===t))}function f(e){return e.meta?.envPath??e.meta?.path??e.path}export{r as DEFAULT_ENV_PREFIX,d as collectRequired,u as collectVars,f as pathOf};