@deltabox/toolchain 1.11.4 → 2.1.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 (229) hide show
  1. package/CHANGELOG.md +336 -4
  2. package/README.md +21 -14
  3. package/dist/_virtual/_rolldown/runtime.js +1 -1
  4. package/dist/changelog.d.ts +10 -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 +33 -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 +11 -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 +4 -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/args.js +1 -1
  41. package/dist/packages/changelog/src/utils/breaking.d.ts +16 -0
  42. package/dist/packages/changelog/src/utils/breaking.js +1 -0
  43. package/dist/packages/changelog/src/utils/format.d.ts +2 -1
  44. package/dist/packages/changelog/src/utils/format.js +5 -5
  45. package/dist/packages/changelog/src/utils/git.d.ts +3 -1
  46. package/dist/packages/changelog/src/utils/git.js +1 -1
  47. package/dist/packages/changelog/src/utils/reformat.d.ts +4 -1
  48. package/dist/packages/changelog/src/utils/reformat.js +4 -4
  49. package/dist/packages/changelog/src/utils/release-notes.d.ts +18 -0
  50. package/dist/packages/changelog/src/utils/release-notes.js +1 -0
  51. package/dist/packages/changelog/src/utils/summary.d.ts +29 -2
  52. package/dist/packages/changelog/src/utils/summary.js +3 -1
  53. package/dist/packages/changelog/src/utils/types.d.ts +39 -2
  54. package/dist/packages/changelog/src/utils/version.d.ts +1 -0
  55. package/dist/packages/changelog/src/utils/versioning.d.ts +30 -4
  56. package/dist/packages/changelog/src/utils/versioning.js +1 -1
  57. package/dist/packages/changelog/src/utils/write.js +1 -1
  58. package/dist/packages/changelog/src/workflows.d.ts +27 -7
  59. package/dist/packages/changelog/src/workflows.js +5 -5
  60. package/dist/packages/config/src/cli/index.js +1 -1
  61. package/dist/packages/config/src/collect.d.ts +10 -8
  62. package/dist/packages/config/src/collect.js +1 -1
  63. package/dist/packages/config/src/config-json.d.ts +4 -4
  64. package/dist/packages/config/src/config-json.js +1 -1
  65. package/dist/packages/config/src/engine.d.ts +14 -25
  66. package/dist/packages/config/src/engine.js +1 -1
  67. package/dist/packages/config/src/env-file.d.ts +4 -4
  68. package/dist/packages/config/src/env-file.js +2 -2
  69. package/dist/packages/config/src/env.d.ts +4 -6
  70. package/dist/packages/config/src/env.js +1 -1
  71. package/dist/packages/config/src/generators/cli.d.ts +6 -6
  72. package/dist/packages/config/src/generators/cli.js +1 -1
  73. package/dist/packages/config/src/generators/env.d.ts +9 -9
  74. package/dist/packages/config/src/generators/env.js +2 -2
  75. package/dist/packages/config/src/generators/index.d.ts +4 -4
  76. package/dist/packages/config/src/generators/index.js +1 -1
  77. package/dist/packages/config/src/generators/json.d.ts +5 -7
  78. package/dist/packages/config/src/generators/json.js +1 -1
  79. package/dist/packages/config/src/generators/markdown.d.ts +57 -35
  80. package/dist/packages/config/src/generators/markdown.js +18 -19
  81. package/dist/packages/config/src/generators/types.d.ts +28 -23
  82. package/dist/packages/config/src/generators/types.js +3 -3
  83. package/dist/packages/config/src/index.d.ts +9 -9
  84. package/dist/packages/config/src/index.js +1 -1
  85. package/dist/packages/config/src/schema.d.ts +31 -3
  86. package/dist/packages/config/src/schema.js +1 -1
  87. package/dist/packages/config/src/types.d.ts +134 -28
  88. package/dist/packages/core/src/editor-config.d.ts +14 -0
  89. package/dist/packages/core/src/editor-config.js +1 -0
  90. package/dist/packages/core/src/graph.js +1 -1
  91. package/dist/packages/core/src/index.d.ts +8 -7
  92. package/dist/packages/core/src/index.js +1 -1
  93. package/dist/packages/core/src/loader.d.ts +20 -2
  94. package/dist/packages/core/src/loader.js +1 -1
  95. package/dist/packages/core/src/manifest.d.ts +20 -1
  96. package/dist/packages/core/src/manifest.js +1 -1
  97. package/dist/packages/core/src/provider-registry.d.ts +48 -3
  98. package/dist/packages/core/src/provider-registry.js +1 -1
  99. package/dist/packages/core/src/reset.d.ts +15 -0
  100. package/dist/packages/core/src/reset.js +1 -1
  101. package/dist/packages/core/src/sync.d.ts +10 -0
  102. package/dist/packages/core/src/sync.js +1 -1
  103. package/dist/packages/core/src/watch.d.ts +9 -0
  104. package/dist/packages/core/src/watch.js +1 -1
  105. package/dist/packages/migrate/src/cli/index.js +1 -1
  106. package/dist/packages/migrate/src/index.d.ts +3 -2
  107. package/dist/packages/migrate/src/index.js +1 -1
  108. package/dist/packages/migrate/src/oxc.d.ts +13 -0
  109. package/dist/packages/migrate/src/oxc.js +1 -0
  110. package/dist/packages/migrate/src/registry.js +1 -1
  111. package/dist/packages/migrate/src/vite-target.js +1 -1
  112. package/dist/packages/migrate/src/vite.d.ts +25 -3
  113. package/dist/packages/migrate/src/vite.js +7 -2
  114. package/dist/packages/project/src/catalogs.d.ts +7 -0
  115. package/dist/packages/project/src/catalogs.js +1 -1
  116. package/dist/packages/project/src/cli/index.js +1 -1
  117. package/dist/packages/project/src/config.d.ts +6 -0
  118. package/dist/packages/project/src/config.js +1 -1
  119. package/dist/packages/project/src/index.d.ts +5 -4
  120. package/dist/packages/project/src/index.js +1 -1
  121. package/dist/packages/project/src/sync.js +1 -1
  122. package/dist/packages/project/src/typescript.d.ts +64 -12
  123. package/dist/packages/project/src/typescript.js +12 -7
  124. package/dist/packages/shared/src/changelog-breaking.d.ts +31 -0
  125. package/dist/packages/shared/src/changelog-groups.d.ts +59 -0
  126. package/dist/packages/shared/src/config-schema/biome.d.ts +10 -0
  127. package/dist/packages/shared/src/config-schema/biome.js +1 -0
  128. package/dist/packages/shared/src/config-schema/catalogs.d.ts +14 -0
  129. package/dist/packages/shared/src/config-schema/catalogs.js +1 -0
  130. package/dist/packages/shared/src/config-schema/changelog.d.ts +248 -0
  131. package/dist/packages/shared/src/config-schema/changelog.js +1 -0
  132. package/dist/packages/shared/src/config-schema/ci.d.ts +390 -0
  133. package/dist/packages/shared/src/config-schema/ci.js +1 -0
  134. package/dist/packages/shared/src/config-schema/format.d.ts +38 -0
  135. package/dist/packages/shared/src/config-schema/format.js +1 -0
  136. package/dist/packages/shared/src/config-schema/index.d.ts +1654 -0
  137. package/dist/packages/shared/src/config-schema/index.js +1 -0
  138. package/dist/packages/shared/src/config-schema/logger.d.ts +19 -0
  139. package/dist/packages/shared/src/config-schema/logger.js +1 -0
  140. package/dist/packages/shared/src/config-schema/meta.d.ts +16 -0
  141. package/dist/packages/shared/src/config-schema/meta.js +1 -0
  142. package/dist/packages/shared/src/config-schema/project.d.ts +35 -0
  143. package/dist/packages/shared/src/config-schema/project.js +1 -0
  144. package/dist/packages/shared/src/config-schema/providers.d.ts +9 -0
  145. package/dist/packages/shared/src/config-schema/providers.js +1 -0
  146. package/dist/packages/shared/src/config-schema/registry.d.ts +21 -0
  147. package/dist/packages/shared/src/config-schema/registry.js +1 -0
  148. package/dist/packages/shared/src/config-schema/templates.d.ts +81 -0
  149. package/dist/packages/shared/src/config-schema/templates.js +1 -0
  150. package/dist/packages/shared/src/config-schema/tsconfig.d.ts +30 -0
  151. package/dist/packages/shared/src/config-schema/tsconfig.js +1 -0
  152. package/dist/packages/shared/src/config-schema/vite.d.ts +26 -0
  153. package/dist/packages/shared/src/config-schema/vite.js +1 -0
  154. package/dist/packages/shared/src/config-schema/watch.d.ts +11 -0
  155. package/dist/packages/shared/src/config-schema/watch.js +1 -0
  156. package/dist/packages/shared/src/config-schema/workflow.d.ts +590 -0
  157. package/dist/packages/shared/src/config-schema/workflow.js +1 -0
  158. package/dist/packages/shared/src/config-types.d.ts +295 -90
  159. package/dist/packages/shared/src/fs-utils.js +1 -1
  160. package/dist/packages/shared/src/index.d.ts +27 -7
  161. package/dist/packages/shared/src/index.js +1 -1
  162. package/dist/packages/shared/src/logger.d.ts +26 -3
  163. package/dist/packages/shared/src/logger.js +1 -1
  164. package/dist/packages/shared/src/messages.d.ts +36 -0
  165. package/dist/packages/shared/src/messages.js +1 -0
  166. package/dist/packages/shared/src/object-utils.d.ts +5 -0
  167. package/dist/packages/shared/src/object-utils.js +1 -1
  168. package/dist/packages/shared/src/registry-policy.d.ts +17 -0
  169. package/dist/packages/shared/src/registry-policy.js +1 -0
  170. package/dist/packages/shared/src/toolchain.d.ts +90 -11
  171. package/dist/packages/shared/src/toolchain.js +1 -1
  172. package/dist/packages/shared/src/types.d.ts +6 -0
  173. package/dist/packages/shared/src/vite-defaults.d.ts +29 -0
  174. package/dist/packages/shared/src/vite-defaults.js +1 -0
  175. package/dist/packages/template/src/builtin.js +1 -1
  176. package/dist/packages/template/src/cli/index.js +1 -1
  177. package/dist/packages/template/src/global.d.ts +130 -0
  178. package/dist/packages/template/src/global.js +3 -0
  179. package/dist/packages/template/src/index.d.ts +3 -2
  180. package/dist/packages/template/src/index.js +1 -1
  181. package/dist/packages/template/src/online.d.ts +13 -4
  182. package/dist/packages/template/src/online.js +1 -1
  183. package/dist/packages/template/src/registry.d.ts +2 -1
  184. package/dist/packages/template/src/registry.js +1 -1
  185. package/dist/packages/template/src/scaffold.d.ts +5 -1
  186. package/dist/packages/template/src/scaffold.js +1 -1
  187. package/dist/packages/tsconfig/src/cli/generate/index.d.ts +3 -0
  188. package/dist/packages/tsconfig/src/cli/generate/index.js +1 -1
  189. package/dist/packages/tsconfig/src/cli/generate/utils.d.ts +10 -1
  190. package/dist/packages/tsconfig/src/cli/generate/utils.js +1 -1
  191. package/dist/packages/tsconfig/src/cli/index.js +1 -1
  192. package/dist/packages/tsconfig/src/index.d.ts +7 -4
  193. package/dist/packages/tsconfig/src/index.js +1 -1
  194. package/dist/packages/tsconfig/src/overrides.d.ts +74 -0
  195. package/dist/packages/tsconfig/src/overrides.js +1 -0
  196. package/dist/packages/tsconfig/src/resolve.d.ts +62 -0
  197. package/dist/packages/tsconfig/src/resolve.js +3 -0
  198. package/dist/packages/tsconfig/src/snapshots.d.ts +50 -0
  199. package/dist/packages/tsconfig/src/snapshots.js +1 -0
  200. package/dist/packages/tsconfig/src/sync.d.ts +14 -5
  201. package/dist/packages/tsconfig/src/sync.js +1 -1
  202. package/dist/packages/tsconfig/src/templates/tsconfig.default.js +1 -1
  203. package/dist/packages/tsconfig/src/templates.d.ts +12 -4
  204. package/dist/packages/tsconfig/src/templates.js +1 -1
  205. package/dist/packages/vite/src/index.d.ts +2 -2
  206. package/dist/packages/vite/src/index.js +1 -1
  207. package/dist/packages/vite/src/resolve.d.ts +13 -3
  208. package/dist/packages/vite/src/resolve.js +1 -1
  209. package/dist/packages/vite/src/sync.d.ts +46 -5
  210. package/dist/packages/vite/src/sync.js +5 -2
  211. package/dist/project.d.ts +4 -3
  212. package/dist/project.js +1 -1
  213. package/dist/providers.d.ts +11 -4
  214. package/dist/providers.js +1 -1
  215. package/dist/shared.d.ts +26 -6
  216. package/dist/shared.js +1 -1
  217. package/dist/sync.js +1 -1
  218. package/dist/template.d.ts +3 -2
  219. package/dist/template.js +1 -1
  220. package/dist/tooling.d.ts +21 -0
  221. package/dist/tooling.js +1 -0
  222. package/dist/tsconfig.d.ts +6 -3
  223. package/dist/tsconfig.js +1 -1
  224. package/dist/vite.d.ts +2 -2
  225. package/dist/vite.js +1 -1
  226. package/package.json +28 -23
  227. package/dist/packages/config/src/types.js +0 -1
  228. package/dist/packages/shared/src/config-schema.d.ts +0 -3928
  229. 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 { 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"`,`notes="$(${n} changelog --release-notes "$version")"`,`[ -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};
@@ -1,7 +1,7 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { ConfigScopes } from "./types.js";
4
- import { CollectEnvVarsOptions } from "./collect.js";
3
+ import { ConfigSchema } from "./types.js";
4
+ import { CollectVarsOptions } from "./collect.js";
5
5
  //#region packages/config/src/config-json.d.ts
6
6
  /** A serialized env var entry in `config.json`. */
7
7
  export interface ConfigJsonEntry {
@@ -26,8 +26,8 @@ export interface BuildConfigJsonOptions {
26
26
  /** Override the `$comment` banner. */
27
27
  comment?: string;
28
28
  /** Custom env-name -> dotted-path derivation. */
29
- envPathOf?: CollectEnvVarsOptions['envPathOf'];
29
+ envPathOf?: CollectVarsOptions['envPathOf'];
30
30
  }
31
31
  /** Build the config metadata JSON document. */
32
- export declare function buildConfigJson(scopes: ConfigScopes, options?: BuildConfigJsonOptions): ConfigJsonDoc;
32
+ export declare function buildConfigJson(schema: ConfigSchema, options?: BuildConfigJsonOptions): ConfigJsonDoc;
33
33
  //#endregion
@@ -1 +1 @@
1
- import"node:path";import"node:url";import.meta.url;import{collectEnvVars as e}from"./collect.js";function t(t,n={}){let r=e(t,n.envPrefix,{envPathOf:n.envPathOf});return{$comment:n.comment??`Generated from the config engine — edit the config schemas instead.`,version:1,env:r.map(e=>({name:e.name,path:e.path,scope:e.scope,...e.description?{description:e.description}:{},...e.default===void 0?{}:{default:e.default},...e.required?{required:!0}:{},...e.secret?{secret:!0}:{},...e.public?{public:!0}:{}}))}}export{t as buildConfigJson};
1
+ import"node:path";import"node:url";import.meta.url;import{collectVars as e}from"./collect.js";function t(t,n={}){let r=e(t,n.envPrefix,{envPathOf:n.envPathOf}).filter(e=>e.name);return{$comment:n.comment??`Generated from the config engine — edit the config schemas instead.`,version:1,env:r.map(e=>({name:e.name??``,path:e.path,scope:e.scope,...e.description?{description:e.description}:{},...e.default===void 0?{}:{default:e.default},...e.required?{required:!0}:{},...e.secret?{secret:!0}:{},...e.public?{public:!0}:{}}))}}export{t as buildConfigJson};
@@ -1,6 +1,6 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { ConfigEngineOptions, ConfigScopes, EnvVarDef } from "./types.js";
3
+ import { ConfigDef, ConfigEngineOptions, ConfigSchema } from "./types.js";
4
4
  import { BuildConfigJsonOptions, ConfigJsonDoc } from "./config-json.js";
5
5
  import { EnvFileOptions } from "./env-file.js";
6
6
  import { CliOptionDef, GenerateCliOptionsOptions } from "./generators/cli.js";
@@ -9,48 +9,37 @@ import { GenerateJsonSchemaOptions } from "./generators/json.js";
9
9
  import { GenerateMarkdownOptions } from "./generators/markdown.js";
10
10
  import { GenerateTypesOptions } from "./generators/types.js";
11
11
  //#region packages/config/src/engine.d.ts
12
- /** The bound, reusable config engine. */
13
12
  export interface ConfigEngine {
14
- readonly scopes: ConfigScopes;
13
+ readonly schema: ConfigSchema;
15
14
  readonly envPrefix: string;
16
15
  readonly baseGroup: string;
17
16
  readonly root: string;
18
- /** Every env-var-backed leaf across the registered scopes. */
19
- collectEnvVars(): EnvVarDef[];
20
- /** The names of the required env vars for a scope. */
21
- requiredEnvVars(scope: string): string[];
22
- /** Render `.env` content. */
23
- renderEnvFile(options?: EnvFileOptions): string;
24
- /** Write a `.env` file. Returns the path written. */
25
- writeEnvFile(options: EnvFileOptions & {
26
- output: string;
27
- }): string;
28
- /** Build the config metadata JSON document. */
17
+ collectVars(): ConfigDef[];
18
+ requiredVars(scope?: string): ConfigDef[];
19
+ generateEnvFile(options?: EnvFileOptions): string;
29
20
  buildConfigJson(options?: BuildConfigJsonOptions): ConfigJsonDoc;
30
- /** Build (and optionally write) the untyped JSON Schema document. */
31
21
  generateJsonSchema(options?: GenerateJsonSchemaOptions): Promise<Record<string, unknown>>;
32
- /** Write the JSON Schema document. Returns the path written. */
33
22
  writeJsonSchema(options: GenerateJsonSchemaOptions & {
34
23
  output: string;
35
24
  }): Promise<string>;
36
- /** Render every config type file, keyed by scope name. */
37
- renderConfigTypes(options?: GenerateTypesOptions): Record<string, string>;
38
- /** Write the config type files into `outputDir`. */
25
+ generateConfigTypes(options?: GenerateTypesOptions): Record<string, string>;
26
+ generateConfigEnv(options?: GenerateEnvTypesOptions): Record<string, string>;
27
+ generateConfigMarkdown(options?: GenerateMarkdownOptions): Record<string, string>;
28
+ generateConfigCli(options?: GenerateCliOptionsOptions): CliOptionDef[];
29
+ writeEnvFile(options: EnvFileOptions & {
30
+ output: string;
31
+ }): string;
39
32
  writeConfigTypes(options: GenerateTypesOptions & {
40
33
  outputDir: string;
41
34
  }): string[];
42
- /** Write the env type files into `outputDir`. */
43
35
  writeEnvTypes(options: GenerateEnvTypesOptions & {
44
36
  outputDir: string;
45
37
  }): string[];
46
- /** Write the markdown reference into `outDir`. */
47
38
  writeMarkdown(options: GenerateMarkdownOptions & {
48
- outDir: string;
39
+ outputDir: string;
49
40
  }): string[];
50
- /** Generate (and optionally write) the CLI option definitions. */
51
41
  generateCliOptions(options?: GenerateCliOptionsOptions): CliOptionDef[];
52
42
  }
53
- /** Create a reusable config engine. */
54
43
  export declare function createConfigEngine(options: ConfigEngineOptions): ConfigEngine;
55
44
  //#endregion
56
- export type { ConfigEngineOptions, ConfigScopes };
45
+ export type { ConfigEngineOptions };
@@ -1 +1 @@
1
- import{default as e}from"node:path";import"node:url";import.meta.url;import{collectEnvVars as t,collectRequiredEnvVars as n}from"./collect.js";import{buildConfigJson as r}from"./config-json.js";import{generateEnvFile as i}from"./env-file.js";import{generateCliOptions as a}from"./generators/cli.js";import{generateEnvTypes as o}from"./generators/env.js";import{generateConfigJsonSchema as s,generateJsonSchemaFile as c}from"./generators/json.js";import{generateConfigMarkdown as l}from"./generators/markdown.js";import{generateConfigTypes as u,renderAllConfigTypes as d}from"./generators/types.js";import{findProjectRoot as f}from"./root.js";import p from"node:fs";function m(m){let h=m.scopes,g=m.envPrefix??`APP_`,_=m.baseGroup??`base`,v=m.root??f(),y=m.envPathOf;return{scopes:h,envPrefix:g,baseGroup:_,root:v,collectEnvVars:()=>t(h,g,{envPathOf:y}),requiredEnvVars:e=>n(h,e,g,{envPathOf:y}),renderEnvFile:(e={})=>i(h,{envPrefix:g,envPathOf:y,...e}),writeEnvFile:t=>{let n=i(h,{envPrefix:g,envPathOf:y,...t});return p.mkdirSync(e.dirname(t.output),{recursive:!0}),p.writeFileSync(t.output,n,`utf-8`),t.output},buildConfigJson:(e={})=>r(h,{envPrefix:g,envPathOf:y,...e}),generateJsonSchema:(e={})=>s(h,{baseGroup:_,...e}),writeJsonSchema:e=>c(h,{baseGroup:_,...e}),renderConfigTypes:(e={})=>d(h,{baseGroup:_,...e}),writeConfigTypes:e=>u(h,{baseGroup:_,...e}),writeEnvTypes:e=>o(h,{envPrefix:g,envPathOf:y,...e}),writeMarkdown:e=>l(h,{baseGroup:_,envPrefix:g,envPathOf:y,...e}),generateCliOptions:(e={})=>a(h,{envPrefix:g,envPathOf:y,...e})}}export{m as createConfigEngine};
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{collectVars as t}from"./collect.js";import{buildConfigJson as n}from"./config-json.js";import{generateEnvFile as r}from"./env-file.js";import{generateCliOptions as i}from"./generators/cli.js";import{generateConfigEnv as a}from"./generators/env.js";import{generateConfigJsonSchema as o,generateJsonSchemaFile as s}from"./generators/json.js";import{generateConfigMarkdown as c}from"./generators/markdown.js";import{generateConfigTypes as l}from"./generators/types.js";import{findProjectRoot as u}from"./root.js";import d from"node:fs";function f(f){let p=f.schema,m=f.envPrefix??`APP_`,h=f.baseGroup??`base`,g=f.root??u(),_=f.envPathOf,v=String(Array.isArray(h)?h[0]??`base`:h);return{schema:p,envPrefix:m,baseGroup:v,root:g,collectVars:()=>t(p,m,{envPathOf:_}),requiredVars:e=>t(p,m,{envPathOf:_}).filter(t=>t.required&&(e===void 0||t.scope===e)),generateEnvFile:(e={})=>r(p,{envPrefix:m,envPathOf:_,...e}),buildConfigJson:(e={})=>n(p,{envPrefix:m,envPathOf:_,...e}),generateJsonSchema:(e={})=>o(p,{baseGroup:v,...e}),writeJsonSchema:e=>s(p,{baseGroup:v,...e}),generateConfigTypes:(e={})=>l(p,{baseGroup:v,...e}),generateConfigEnv:(e={})=>a(p,{envPrefix:m,envPathOf:_,...e}),generateConfigMarkdown:(e={})=>c(p,{baseGroup:v,envPrefix:m,envPathOf:_,...e}),generateConfigCli:(e={})=>i(p,{envPrefix:m,envPathOf:_,...e}),writeEnvFile:t=>{let n=r(p,{envPrefix:m,envPathOf:_,...t});return d.mkdirSync(e.dirname(t.output),{recursive:!0}),d.writeFileSync(t.output,n,`utf-8`),t.output},writeConfigTypes:t=>{let n=l(p,{baseGroup:v,...t});return Object.keys(n).map(n=>e.join(t.outputDir,`${n}.ts`))},writeEnvTypes:t=>{let n=a(p,{envPrefix:m,envPathOf:_,...t});return Object.keys(n).map(n=>e.join(t.outputDir,n))},writeMarkdown:t=>{let n=c(p,{baseGroup:v,envPrefix:m,envPathOf:_,...t});return Object.keys(n).map(n=>e.join(t.outputDir,n))},generateCliOptions:(e={})=>i(p,{envPrefix:m,envPathOf:_,...e})}}export{f as createConfigEngine};
@@ -1,7 +1,7 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { ConfigScopes } from "./types.js";
4
- import { CollectEnvVarsOptions } from "./collect.js";
3
+ import { ConfigSchema } from "./types.js";
4
+ import { CollectVarsOptions } from "./collect.js";
5
5
  //#region packages/config/src/env-file.d.ts
6
6
  export interface EnvFileOptions {
7
7
  /** Env vars to include (defaults to all). */
@@ -23,11 +23,11 @@ export interface EnvFileOptions {
23
23
  /** The characters wrapping a scope's section header (default `----`). */
24
24
  scopeSeparator?: string;
25
25
  /** Custom env-name -> dotted-path derivation. */
26
- envPathOf?: CollectEnvVarsOptions['envPathOf'];
26
+ envPathOf?: CollectVarsOptions['envPathOf'];
27
27
  }
28
28
  /**
29
29
  * Generate `.env` content from the config schemas. Secrets and required-without-
30
30
  * default vars are emitted blank so operators fill them in.
31
31
  */
32
- export declare function generateEnvFile(scopes: ConfigScopes, options?: EnvFileOptions): string;
32
+ export declare function generateEnvFile(schema: ConfigSchema, options?: EnvFileOptions): string;
33
33
  //#endregion
@@ -1,3 +1,3 @@
1
- import"node:path";import"node:url";import.meta.url;import{collectEnvVars as e}from"./collect.js";function t(e){let t=e.default;return Array.isArray(t)?t.join(`,`):typeof t==`boolean`?t?`true`:`false`:typeof t==`number`?String(t):typeof t==`object`&&t?JSON.stringify(t):t===void 0?``:String(t)}function n(n,r={}){let i=r.envPrefix??`APP_`,a=r.scopeSeparator??`----`,o=e(n,i,{envPathOf:r.envPathOf}),s=r.scopes??Object.keys(n),c=o.filter(e=>s.includes(e.scope)&&(!r.include||r.include.includes(e.name))&&!r.exclude?.includes(e.name)),l=[];r.header&&l.push(r.header,``);let u;for(let e of c){if(e.scope!==u&&(u!==void 0&&l.push(``),l.push(`# ${a} ${e.scope.toUpperCase()} ${a}`),u=e.scope),!r.bare&&e.description)for(let t of e.description.split(`
2
- `))l.push(`# ${t}`);let n=r.values?.[e.name];e.secret&&n===void 0?l.push(`# ${e.name}=`):l.push(`${e.name}=${n??t(e)}`)}if(r.extra){let e=Object.entries(r.extra).filter(([e])=>!c.some(t=>t.name===e)).map(([e,t])=>`${e}=${t}`);e.length&&l.push(``,`# ${a} EXTRA ${a}`,...e)}return`${l.join(`
1
+ import"node:path";import"node:url";import.meta.url;import{collectVars as e}from"./collect.js";function t(e){let t=e.default;return Array.isArray(t)?t.join(`,`):typeof t==`boolean`?t?`true`:`false`:typeof t==`number`?String(t):typeof t==`object`&&t?JSON.stringify(t):t===void 0?``:String(t)}function n(n,r={}){let i=r.envPrefix??`APP_`,a=r.scopeSeparator??`----`,o=e(n,i,{envPathOf:r.envPathOf}).filter(e=>e.name!==void 0),s=r.scopes??[...new Set(o.map(e=>e.scope))],c=o.filter(e=>s.includes(e.scope)&&(!r.include||r.include.includes(e.name))&&!r.exclude?.includes(e.name)),l=[];r.header&&l.push(r.header,``);let u;for(let e of c){let n=e.name;if(e.scope!==u&&(u!==void 0&&l.push(``),l.push(`# ${a} ${e.scope.toUpperCase()} ${a}`),u=e.scope),!r.bare&&e.description)for(let t of e.description.split(`
2
+ `))l.push(`# ${t}`);let i=r.values?.[n];e.secret&&i===void 0?l.push(`# ${n}=`):l.push(`${n}=${i??t(e)}`)}if(r.extra){let e=Object.entries(r.extra).filter(([e])=>!c.some(t=>t.name===e)).map(([e,t])=>`${e}=${t}`);e.length&&l.push(``,`# ${a} EXTRA ${a}`,...e)}return`${l.join(`
3
3
  `)}\n`}export{n as generateEnvFile};
@@ -3,8 +3,8 @@ import __tsdown_shims_url from 'node:url';
3
3
  //#region packages/config/src/env.d.ts
4
4
  /**
5
5
  * Low-level configuration helpers: env-tree parsing, typed accessors and
6
- * override merging. Free of Node builtins so browser consumers can import the
7
- * frontend resolver without pulling `node:path` / `node:url` into a bundle.
6
+ * dotted-path derivation. Free of Node builtins so browser consumers can import
7
+ * the frontend resolver without pulling `node:path` / `node:url` into a bundle.
8
8
  */
9
9
  /** A flat env source (process.env, import.meta.env or a plain object). */
10
10
  export type EnvSource = Record<string, string | undefined>;
@@ -24,8 +24,6 @@ export declare function envBool(tree: EnvTree, path: string, fallback: boolean):
24
24
  export declare function envList(tree: EnvTree, path: string, fallback?: string[]): string[];
25
25
  /** Read `Header=value,...` into a lowercase-keyed record. */
26
26
  export declare function envMap(tree: EnvTree, path: string): Record<string, string>;
27
- /** Recursively merge typed overrides over a base object (shallow per level). */
28
- export declare function applyOverrides<T extends object>(base: T, overrides?: Partial<T>): T;
29
- /** Trim trailing slashes from a URL-ish string. */
30
- export declare function trimTrailingSlashes(value: string): string;
27
+ /** Derive the dotted config path from an env var name + prefix. */
28
+ export declare function envPathOf(env: string, prefix?: string): string;
31
29
  //#endregion
@@ -1 +1 @@
1
- import"node:path";import"node:url";import.meta.url;function e(e={},t=`APP_`){let n={};for(let[r,i]of Object.entries(e)){if(!r.startsWith(t)||i===void 0)continue;let e=r.slice(t.length).toLowerCase().split(`_`),a=n;for(let t=0;t<e.length-1;t+=1){let n=e[t]??``;(typeof a[n]!=`object`||a[n]===null)&&(a[n]={}),a=a[n]}a[e[e.length-1]??``]=i}return n}function t(e,t){let n=e;for(let e of t.split(`.`)){if(typeof n!=`object`||!n)return;n=n[e]}return n}function n(e,n,r=``){let i=t(e,n);return typeof i==`string`&&i.trim()!==``?i:r}function r(e,n,r){let i=t(e,n);if(typeof i!=`string`||i.trim()===``)return r;let a=Number.parseInt(i,10);return Number.isFinite(a)?a:r}function i(e,n,r){let i=t(e,n);if(typeof i!=`string`||i.trim()===``)return r;let a=i.trim().toLowerCase();return[`true`,`1`,`yes`,`on`].includes(a)?!0:![`false`,`0`,`no`,`off`].includes(a)&&r}function a(e,n,r=[]){let i=t(e,n);return typeof i!=`string`||i.trim()===``?r:i.split(`,`).map(e=>e.trim()).filter(Boolean)}function o(e,t){let n={};for(let r of a(e,t,[])){let e=r.indexOf(`=`);e!==-1&&(n[r.slice(0,e).trim().toLowerCase()]=r.slice(e+1).trim())}return n}function s(e,t){if(!t)return e;let n={...e};for(let[r,i]of Object.entries(t)){if(i===void 0)continue;let t=e[r];n[r]=t&&typeof t==`object`&&!Array.isArray(t)&&i&&typeof i==`object`&&!Array.isArray(i)?s(t,i):i}return n}function c(e){return e.replace(/\/+$/,``)}export{s as applyOverrides,i as envBool,r as envInt,a as envList,o as envMap,n as envString,e as parseEnvTree,t as readEnvPath,c as trimTrailingSlashes};
1
+ import"node:path";import"node:url";import.meta.url;function e(e={},t=`APP_`){let n={};for(let[r,i]of Object.entries(e)){if(!r.startsWith(t)||i===void 0)continue;let e=r.slice(t.length).toLowerCase().split(`_`),a=n;for(let t=0;t<e.length-1;t+=1){let n=e[t]??``;(typeof a[n]!=`object`||a[n]===null)&&(a[n]={}),a=a[n]}a[e[e.length-1]??``]=i}return n}function t(e,t){let n=e;for(let e of t.split(`.`)){if(typeof n!=`object`||!n)return;n=n[e]}return n}function n(e,n,r=``){let i=t(e,n);return typeof i==`string`&&i.trim()!==``?i:r}function r(e,n,r){let i=t(e,n);if(typeof i!=`string`||i.trim()===``)return r;let a=Number.parseInt(i,10);return Number.isFinite(a)?a:r}function i(e,n,r){let i=t(e,n);if(typeof i!=`string`||i.trim()===``)return r;let a=i.trim().toLowerCase();return[`true`,`1`,`yes`,`on`].includes(a)?!0:![`false`,`0`,`no`,`off`].includes(a)&&r}function a(e,n,r=[]){let i=t(e,n);return typeof i!=`string`||i.trim()===``?r:i.split(`,`).map(e=>e.trim()).filter(Boolean)}function o(e,t){let n={};for(let r of a(e,t,[])){let e=r.indexOf(`=`);e!==-1&&(n[r.slice(0,e).trim().toLowerCase()]=r.slice(e+1).trim())}return n}function s(e,t=`APP_`){return e.slice(e.startsWith(t)?t.length:0).toLowerCase().replace(/_/g,`.`)}export{i as envBool,r as envInt,a as envList,o as envMap,s as envPathOf,n as envString,e as parseEnvTree,t as readEnvPath};
@@ -1,7 +1,7 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { ConfigScopes } from "../types.js";
4
- import { CollectEnvVarsOptions } from "../collect.js";
3
+ import { ConfigSchema } from "../types.js";
4
+ import { CollectVarsOptions } from "../collect.js";
5
5
  import { ParseArgsOptionsConfig } from "node:util";
6
6
  //#region packages/config/src/generators/cli.d.ts
7
7
  /** Flag-shaping options shared by every CLI helper. */
@@ -11,9 +11,9 @@ export interface CliFlagOptions {
11
11
  /** Shorthand flags keyed by env var name (eg. `{ APP_TOKEN: 't' }`). */
12
12
  shortFlags?: Record<string, string>;
13
13
  /** Custom env-name -> dotted-path derivation. */
14
- envPathOf?: CollectEnvVarsOptions['envPathOf'];
14
+ envPathOf?: CollectVarsOptions['envPathOf'];
15
15
  }
16
- /** A generated CLI option definition for one env var. */
16
+ /** A generated CLI option definition. */
17
17
  export interface CliOptionDef {
18
18
  /** CLI flag, e.g. `--base-url`. */
19
19
  flag: string;
@@ -42,10 +42,10 @@ export interface GenerateCliOptionsOptions extends CliFlagOptions {
42
42
  /** The scope whose env vars become flags (default `cli`). */
43
43
  scope?: string;
44
44
  /** Output file path to write the options as JSON. */
45
- output?: string;
45
+ output?: string | false;
46
46
  }
47
47
  /** Generate the CLI option definitions for a scope's env vars. */
48
- export declare function generateCliOptions(scopes: ConfigScopes, options?: GenerateCliOptionsOptions): CliOptionDef[];
48
+ export declare function generateCliOptions(schema: ConfigSchema, options?: GenerateCliOptionsOptions): CliOptionDef[];
49
49
  /** The typed `values` of a parsed CLI args result. */
50
50
  export type CliArgsValues = Record<string, string | undefined>;
51
51
  /** A parsed CLI args result (node `parseArgs` output). */
@@ -1 +1 @@
1
- import"node:path";import"node:url";import.meta.url;import{formatCliFlag as e}from"../../../shared/src/string-utils.js";import"../../../shared/src/index.js";import{collectEnvVars as t}from"../collect.js";import n from"node:fs";import{parseArgs as r}from"node:util";function i(t,n={}){return e(t,n.envPrefix??`APP_`)}function a(e,t={}){return`--${i(e,t)}`}function o(e,t={}){let n=t.shortFlags?.[e];return n?`-${n}`:void 0}function s(e,t={}){let n=a(e,t),r=o(e,t);return r?`${r}, ${n}`:n}function c(e,r={}){let i=r.scope??`cli`,s=[];for(let n of t(e,r.envPrefix,{envPathOf:r.envPathOf}).filter(e=>e.scope===i)){let e=o(n.name,r);s.push({flag:a(n.name,r),env:n.name,type:n.envType??`string`,...e?{short:e}:{},...n.description?{description:n.description}:{},...n.secret?{secret:!0}:{},...n.default!==void 0&&!n.secret?{default:String(n.default)}:{}})}return r.output&&n.writeFileSync(r.output,`${JSON.stringify(s,null,4)}\n`,`utf-8`),s}function l(e){return Object.fromEntries(e.map(e=>[e.flag.replace(/^--/,``),{type:`string`,...e.short?{short:e.short.replace(/^-/,``)}:{},...e.default?{default:e.default}:{}}]))}function u(e,t){let n=l(e);return{options:n,parse:(e=process.argv.slice(2))=>r({args:e,options:n,strict:t?.strict??!0}),toConfig:e=>{let t=e?.values??{},n={};for(let[e,r]of Object.entries(t))r!==void 0&&(n[e]=r);return n}}}export{s as cliFlagLabel,a as cliFlagOf,o as cliShortOf,u as createCliArgsParser,i as flagOf,l as generateCliArgsOptions,c as generateCliOptions};
1
+ import"node:path";import"node:url";import.meta.url;import{formatCliFlag as e}from"../../../shared/src/string-utils.js";import"../../../shared/src/index.js";import{collectVars as t}from"../collect.js";import n from"node:fs";import{parseArgs as r}from"node:util";function i(t,n={}){return e(t,n.envPrefix??`APP_`)}function a(e,t={}){return`--${i(e,t)}`}function o(e,t={}){let n=t.shortFlags?.[e];return n?`-${n}`:void 0}function s(e,t={}){let n=a(e,t),r=o(e,t);return r?`${r}, ${n}`:n}function c(e,r={}){let i=r.scope??`cli`,s=[];for(let n of t(e,r.envPrefix,{envPathOf:r.envPathOf}).filter(e=>e.scope===i&&(e.name||e.cliFlag))){let e=n.meta?.cliFlagShort?`-${n.meta.cliFlagShort.replace(/^-/,``)}`:o(n.name??``,r);s.push({flag:n.cliFlag??a(n.name??``,r),env:n.name??``,type:n.type??`string`,...e?{short:e}:{},...n.description?{description:n.description}:{},...n.secret?{secret:!0}:{},...n.default!==void 0&&!n.secret?{default:String(n.default)}:{}})}return typeof r.output==`string`&&n.writeFileSync(r.output,`${JSON.stringify(s,null,4)}\n`,`utf-8`),s}function l(e){return Object.fromEntries(e.map(e=>[e.flag.replace(/^--/,``),{type:`string`,...e.short?{short:e.short.replace(/^-/,``)}:{},...e.default?{default:e.default}:{}}]))}function u(e,t){let n=l(e);return{options:n,parse:(e=process.argv.slice(2))=>r({args:e,options:n,strict:t?.strict??!0}),toConfig:e=>{let t=e?.values??{},n={};for(let[e,r]of Object.entries(t))r!==void 0&&(n[e]=r);return n}}}export{s as cliFlagLabel,a as cliFlagOf,o as cliShortOf,u as createCliArgsParser,i as flagOf,l as generateCliArgsOptions,c as generateCliOptions};
@@ -1,11 +1,11 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { ConfigScopes } from "../types.js";
4
- import { CollectEnvVarsOptions } from "../collect.js";
3
+ import { ConfigSchema } from "../types.js";
4
+ import { CollectVarsOptions } from "../collect.js";
5
5
  //#region packages/config/src/generators/env.d.ts
6
6
  export interface GenerateEnvTypesOptions {
7
7
  /** Output directory. When omitted, nothing is written. */
8
- outputDir?: string;
8
+ outputDir?: string | false;
9
9
  /** The env-var prefix (default `APP_`). */
10
10
  envPrefix?: string;
11
11
  /** The `process.env` interface name (default `AppEnv`). */
@@ -29,14 +29,14 @@ export interface GenerateEnvTypesOptions {
29
29
  /** Add a `declare module 'vite'` augmentation to the `.d.ts`. */
30
30
  augmentVite?: boolean;
31
31
  /** Custom env-name -> dotted-path derivation. */
32
- envPathOf?: CollectEnvVarsOptions['envPathOf'];
32
+ envPathOf?: CollectVarsOptions['envPathOf'];
33
33
  }
34
34
  /** Render the `env.ts` content (the env + vite-env interfaces). */
35
- export declare function generateEnv(scopes: ConfigScopes, options?: GenerateEnvTypesOptions): string;
35
+ export declare function generateEnv(schema: ConfigSchema, options?: GenerateEnvTypesOptions): string;
36
36
  /** Render the ambient `.d.ts` content. */
37
37
  export declare function generateEnvDts(options?: GenerateEnvTypesOptions): string;
38
- /** Generate `env.ts` + the ambient `.d.ts` into `outputDir`. Returns the paths. */
39
- export declare function generateEnvTypes(scopes: ConfigScopes, options: GenerateEnvTypesOptions & {
40
- outputDir: string;
41
- }): string[];
38
+ /** Generate env type file contents (and optionally write them). */
39
+ export declare function generateConfigEnv(schema: ConfigSchema, options?: GenerateEnvTypesOptions): Record<string, string>;
40
+ /** @deprecated Use {@link generateConfigEnv}. */
41
+ export declare const generateEnvTypes: typeof generateConfigEnv;
42
42
  //#endregion
@@ -1,4 +1,4 @@
1
- import{default as e}from"node:path";import"node:url";import.meta.url;import{collectEnvVars as t}from"../collect.js";import n from"node:fs";function r(e){return e??`Generated env typing — DO NOT EDIT.`}function i(e,n={}){let i=n.envPrefix??`APP_`,a=n.envInterfaceName??`AppEnv`,o=n.viteEnvInterfaceName??`AppViteEnv`,s=t(e,i,{envPathOf:n.envPathOf}),c=s.filter(e=>e.scope!==`frontend`),l=s.filter(e=>e.public),u=n.envHeader?[n.envHeader,``]:[`/**`,` * ${r(n.header)}`,` */`,``];u.push(`/** ${n.envComment??"Environment variables typed on `process.env`."} */`,`export interface ${a} {`);for(let e of c)u.push(` /** ${(e.description??``).replace(/\n/g,` `)} */`),u.push(` ${e.name}?: string;`);u.push(`}`),u.push(``),u.push("/** Public frontend environment variables typed on `import.meta.env`. */"),u.push(`export interface ${o} {`);for(let e of l)u.push(` /** ${(e.description??``).replace(/\n/g,` `)} */`),u.push(` ${e.name}?: string;`);return u.push(`}`),`${u.join(`
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{collectVars as t}from"../collect.js";import n from"node:fs";function r(e){return e??`Generated env typing — DO NOT EDIT.`}function i(e,n={}){let i=n.envPrefix??`APP_`,a=n.envInterfaceName??`AppEnv`,o=n.viteEnvInterfaceName??`AppViteEnv`,s=t(e,i,{envPathOf:n.envPathOf}).filter(e=>e.name),c=s.filter(e=>e.scope!==`frontend`),l=s.filter(e=>e.public),u=n.envHeader?[n.envHeader,``]:[`/**`,` * ${r(n.header)}`,` */`,``];u.push(`/** ${n.envComment??"Environment variables typed on `process.env`."} */`,`export interface ${a} {`);for(let e of c)u.push(` /** ${(e.description??``).replace(/\n/g,` `)} */`),u.push(` ${e.name}?: string;`);u.push(`}`),u.push(``),u.push("/** Public frontend environment variables typed on `import.meta.env`. */"),u.push(`export interface ${o} {`);for(let e of l)u.push(` /** ${(e.description??``).replace(/\n/g,` `)} */`),u.push(` ${e.name}?: string;`);return u.push(`}`),`${u.join(`
2
2
  `).trimEnd()}\n`}function a(e={}){let t=e.envInterfaceName??`AppEnv`,n=e.viteEnvInterfaceName??`AppViteEnv`,i=e.importPath??`./env.js`;return`${e.dtsHeader?`${e.dtsHeader}\n`:`/**
3
3
  * ${r(e.header)}
4
4
  *
@@ -20,4 +20,4 @@ declare module 'vite' {
20
20
  }`:``}
21
21
 
22
22
  export {};
23
- `}function o(t,r){let o=e.join(r.outputDir,r.envFile??`env.ts`),s=e.join(r.outputDir,r.dtsFile??`env.d.ts`);return n.mkdirSync(r.outputDir,{recursive:!0}),n.writeFileSync(o,i(t,r),`utf-8`),n.writeFileSync(s,a(r),`utf-8`),[o,s]}export{i as generateEnv,a as generateEnvDts,o as generateEnvTypes};
23
+ `}function o(t,r={}){let o=r.envFile??`env.ts`,s=r.dtsFile??`env.d.ts`,c={[o]:i(t,r),[s]:a(r)};if(typeof r.outputDir==`string`){n.mkdirSync(r.outputDir,{recursive:!0});for(let[t,i]of Object.entries(c))n.writeFileSync(e.join(r.outputDir,t),i,`utf-8`)}return c}const s=o;export{o as generateConfigEnv,i as generateEnv,a as generateEnvDts,s as generateEnvTypes};
@@ -1,8 +1,8 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
3
  import { CliArgsOptionConfig, CliArgsParser, CliArgsResult, CliArgsValues, CliFlagOptions, CliOptionDef, GenerateCliOptionsOptions, cliFlagLabel, cliFlagOf, cliShortOf, createCliArgsParser, flagOf, generateCliArgsOptions, generateCliOptions } from "./cli.js";
4
- import { GenerateEnvTypesOptions, generateEnv, generateEnvDts, generateEnvTypes } from "./env.js";
4
+ import { GenerateEnvTypesOptions, generateConfigEnv, generateEnv, generateEnvDts, generateEnvTypes } from "./env.js";
5
5
  import { GenerateJsonSchemaOptions, generateConfigJsonSchema, generateJsonSchemaFile } from "./json.js";
6
- import { ConfigFileSection, GenerateMarkdownOptions, RenderConfigFileOptions, RenderMarkdownOptions, generateConfigMarkdown, renderConfigFileMarkdown, renderConfigIndex, renderScopeMarkdown } from "./markdown.js";
7
- import { GenerateTypesOptions, generateConfigTypes, renderAllConfigTypes, renderConfigImports, renderConfigTypes, resolveScopeSchema } from "./types.js";
8
- export { CliArgsOptionConfig, CliArgsParser, CliArgsResult, CliArgsValues, CliFlagOptions, CliOptionDef, ConfigFileSection, GenerateCliOptionsOptions, GenerateEnvTypesOptions, GenerateJsonSchemaOptions, GenerateMarkdownOptions, GenerateTypesOptions, RenderConfigFileOptions, RenderMarkdownOptions, cliFlagLabel, cliFlagOf, cliShortOf, createCliArgsParser, flagOf, generateCliArgsOptions, generateCliOptions, generateConfigJsonSchema, generateConfigMarkdown, generateConfigTypes, generateEnv, generateEnvDts, generateEnvTypes, generateJsonSchemaFile, renderAllConfigTypes, renderConfigFileMarkdown, renderConfigImports, renderConfigIndex, renderConfigTypes, renderScopeMarkdown, resolveScopeSchema };
6
+ import { GenerateMarkdownOptions, RenderConfigFileOptions, RenderMarkdownFrontmatter, RenderMarkdownOptions, generateConfigMarkdown } from "./markdown.js";
7
+ import { GenerateTypesOptions, generateConfigTypes } from "./types.js";
8
+ export { CliArgsOptionConfig, CliArgsParser, CliArgsResult, CliArgsValues, CliFlagOptions, CliOptionDef, GenerateCliOptionsOptions, GenerateEnvTypesOptions, GenerateJsonSchemaOptions, GenerateMarkdownOptions, GenerateTypesOptions, RenderConfigFileOptions, RenderMarkdownFrontmatter, RenderMarkdownOptions, cliFlagLabel, cliFlagOf, cliShortOf, createCliArgsParser, flagOf, generateCliArgsOptions, generateCliOptions, generateConfigEnv, generateConfigJsonSchema, generateConfigMarkdown, generateConfigTypes, generateEnv, generateEnvDts, generateEnvTypes, generateJsonSchemaFile };
@@ -1 +1 @@
1
- import"node:path";import"node:url";import.meta.url;import{cliFlagLabel as e,cliFlagOf as t,cliShortOf as n,createCliArgsParser as r,flagOf as i,generateCliArgsOptions as a,generateCliOptions as o}from"./cli.js";import{generateEnv as s,generateEnvDts as c,generateEnvTypes as l}from"./env.js";import{generateConfigJsonSchema as u,generateJsonSchemaFile as d}from"./json.js";import{generateConfigMarkdown as f,renderConfigFileMarkdown as p,renderConfigIndex as m,renderScopeMarkdown as h}from"./markdown.js";import{generateConfigTypes as g,renderAllConfigTypes as _,renderConfigImports as v,renderConfigTypes as y,resolveScopeSchema as b}from"./types.js";export{e as cliFlagLabel,t as cliFlagOf,n as cliShortOf,r as createCliArgsParser,i as flagOf,a as generateCliArgsOptions,o as generateCliOptions,u as generateConfigJsonSchema,f as generateConfigMarkdown,g as generateConfigTypes,s as generateEnv,c as generateEnvDts,l as generateEnvTypes,d as generateJsonSchemaFile,_ as renderAllConfigTypes,p as renderConfigFileMarkdown,v as renderConfigImports,m as renderConfigIndex,y as renderConfigTypes,h as renderScopeMarkdown,b as resolveScopeSchema};
1
+ import"node:path";import"node:url";import.meta.url;import{cliFlagLabel as e,cliFlagOf as t,cliShortOf as n,createCliArgsParser as r,flagOf as i,generateCliArgsOptions as a,generateCliOptions as o}from"./cli.js";import{generateConfigEnv as s,generateEnv as c,generateEnvDts as l,generateEnvTypes as u}from"./env.js";import{generateConfigJsonSchema as d,generateJsonSchemaFile as f}from"./json.js";import{generateConfigMarkdown as p}from"./markdown.js";import{generateConfigTypes as m}from"./types.js";export{e as cliFlagLabel,t as cliFlagOf,n as cliShortOf,r as createCliArgsParser,i as flagOf,a as generateCliArgsOptions,o as generateCliOptions,s as generateConfigEnv,d as generateConfigJsonSchema,p as generateConfigMarkdown,m as generateConfigTypes,c as generateEnv,l as generateEnvDts,u as generateEnvTypes,f as generateJsonSchemaFile};
@@ -1,12 +1,10 @@
1
1
  import __tsdown_shims_path from 'node:path';
2
2
  import __tsdown_shims_url from 'node:url';
3
- import { ConfigScopes } from "../types.js";
3
+ import { ConfigEngineOptions, ConfigSchema } from "../types.js";
4
4
  //#region packages/config/src/generators/json.d.ts
5
- export interface GenerateJsonSchemaOptions {
5
+ export interface GenerateJsonSchemaOptions extends Pick<ConfigEngineOptions, 'baseGroup'> {
6
6
  /** Output file path. When omitted, nothing is written. */
7
- output?: string;
8
- /** The base group hoisted to the top level (default `base`). */
9
- baseGroup?: string;
7
+ output?: string | false;
10
8
  /** Document metadata overrides. */
11
9
  id?: string;
12
10
  title?: string;
@@ -16,9 +14,9 @@ export interface GenerateJsonSchemaOptions {
16
14
  * Build the combined untyped JSON Schema document covering every scope, using
17
15
  * untyped's `resolveSchema` on the definitions lowered from the Zod schemas.
18
16
  */
19
- export declare function generateConfigJsonSchema(scopes: ConfigScopes, options?: GenerateJsonSchemaOptions): Promise<Record<string, unknown>>;
17
+ export declare function generateConfigJsonSchema(schema: ConfigSchema, options?: GenerateJsonSchemaOptions): Promise<Record<string, unknown>>;
20
18
  /** Generate the JSON Schema document into `output`. Returns the path written. */
21
- export declare function generateJsonSchemaFile(scopes: ConfigScopes, options: GenerateJsonSchemaOptions & {
19
+ export declare function generateJsonSchemaFile(schema: ConfigSchema, options: GenerateJsonSchemaOptions & {
22
20
  output: string;
23
21
  }): Promise<string>;
24
22
  //#endregion
@@ -1 +1 @@
1
- import{default as e}from"node:path";import"node:url";import.meta.url;import{flattenBaseSchema as t,zodToUntypedDefinition as n}from"../schema.js";import r from"node:fs";import{resolveSchema as i}from"untyped";async function a(a,o={}){let s={};for(let[e,r]of Object.entries(a))s[e]=t(await i(n(r.zodSchema)),o.baseGroup);let c={$schema:`https://json-schema.org/draft/2020-12/schema`,$id:o.id??`https://example.com/schemas/config.json`,title:o.title??`Configuration`,description:o.description??`Every env-var-backed configuration value across all scopes.`,type:`object`,properties:s,required:Object.keys(a)};return o.output&&(r.mkdirSync(e.dirname(o.output),{recursive:!0}),r.writeFileSync(o.output,`${JSON.stringify(c,null,4)}\n`,`utf-8`)),c}async function o(e,t){return await a(e,t),t.output}export{a as generateConfigJsonSchema,o as generateJsonSchemaFile};
1
+ import{default as e}from"node:path";import"node:url";import.meta.url;import{flattenBaseSchema as t,normalizeConfigSchema as n}from"../schema.js";import r from"node:fs";async function i(i,a={}){let o=n(i),s={};for(let[e]of Object.entries(o))s[e]=t(o[e],Array.isArray(a.baseGroup)?String(a.baseGroup[0]??`base`):String(a.baseGroup??`base`));let c={$schema:`https://json-schema.org/draft/2020-12/schema`,$id:a.id??`https://example.com/schemas/config.json`,title:a.title??`Configuration`,description:a.description??`Every env-var-backed configuration value across all scopes.`,type:`object`,properties:s,required:Object.keys(o)};return typeof a.output==`string`&&(r.mkdirSync(e.dirname(a.output),{recursive:!0}),r.writeFileSync(a.output,`${JSON.stringify(c,null,4)}\n`,`utf-8`)),c}async function a(e,t){return await i(e,t),t.output}export{i as generateConfigJsonSchema,a as generateJsonSchemaFile};