@adamhl8/configs 2.3.2 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -119,6 +119,15 @@ import { commitlintConfig } from "@adamhl8/configs"
119
119
  export default commitlintConfig({ ... })
120
120
  ```
121
121
 
122
+ #### Notes
123
+
124
+ `@commitlint/config-conventional` is both a dependency and a peer dependency:
125
+
126
+ - Dependency: `commitlint.base.ts` imports it to read the conventional commit types.
127
+ - Peer dependency: `commitlint.base.ts` also sets `extends: ["@commitlint/config-conventional"]`. commitlint resolves that string from the consumer's project root, not from `@adamhl8/configs`.
128
+
129
+ With bun's `isolated` linker, our copy lives only in `@adamhl8/configs`'s own `node_modules` and is never hoisted to the consumer's root. So commitlint can't find it unless the consumer installs it directly, which the peer dependency asks them to do.
130
+
122
131
  ### release-it
123
132
 
124
133
  ```ts
@@ -141,7 +150,7 @@ adamhl8-cliff --bumped-version
141
150
 
142
151
  ### lefthook
143
152
 
144
- `lefthook.base.yaml` runs `just lint` on pre-commit and `commitlint` on commit-msg. Extend it from your `lefthook.yaml`:
153
+ `lefthook.base.yaml` runs `just build` on pre-commit and `commitlint` on commit-msg. Extend it from your `lefthook.yaml`:
145
154
 
146
155
  ```yaml
147
156
  # lefthook.yaml
@@ -149,7 +158,7 @@ extends:
149
158
  - node_modules/@adamhl8/configs/dist/configs/lefthook.base.yaml
150
159
  ```
151
160
 
152
- `lefthook install` (the base justfile's `prepare` recipe runs it) sets up the hooks.
161
+ `lefthook install` (the base justfile's `prepare` recipe runs it) sets up the hooks. `prepare` skips it in CI (when `CI` is set), so commits made by the workflows don't run the hooks.
153
162
 
154
163
  ### bunfig
155
164
 
@@ -194,7 +203,7 @@ export const env = parseEnv({
194
203
 
195
204
  ## GitHub Actions
196
205
 
197
- This repo hosts three reusable workflows you can call from other projects instead of copy/pasting them. The calling project must use `bun`, have a `justfile` that imports the base justfile (see [just](#just)), and have a commitlint config (e.g. via these configs). The workflows set up bun and install just and lefthook themselves.
206
+ This repo hosts three reusable workflows you can call from other projects instead of copy/pasting them. The calling project must use `bun`, have a `justfile` that imports the base justfile (see [just](#just)), and have a commitlint config (e.g. via these configs). The workflows set up bun and install just themselves.
198
207
 
199
208
  - `ci.yml`: runs `build` (build + lint) on pushes/PRs and lints commit messages with commitlint
200
209
  - `update-deps.yml`: weekly `bump-deps` run that opens a dependency-update PR
@@ -301,6 +310,6 @@ Configure these on each repo that uses the workflows (Settings -> Secrets and va
301
310
 
302
311
  ## Notes
303
312
 
304
- The `prepare` script is `"prepare": "just prepare"`, which runs the base justfile's `prepare` recipe (`lefthook install`, the `.gitignore` sync, and the `bunfig.toml` sync).
313
+ The `prepare` script is `"prepare": "just prepare"`, which runs the base justfile's `prepare` recipe (`lefthook install` outside CI, the `.gitignore` sync, and the `bunfig.toml` sync).
305
314
 
306
315
  bun links a dependency's `package.json` bin executables into the local `node_modules/.bin`, but not the bins of the package being developed itself. This repo depends on itself (`"@adamhl8/configs": "file:."`) so that its own bins can be run directly, e.g. `adamhl8-cliff` instead of `src/adamhl8-cliff/index.ts`. That's also why this repo overrides the `prepare` recipe to first run `tsdown`: the bins point at `dist/`, so those builds need to be available.
@@ -2,7 +2,6 @@
2
2
  import path from "node:path";
3
3
  import bun from "bun";
4
4
  import { isPlainObject, merge } from "es-toolkit";
5
- import { stringify } from "smol-toml";
6
5
  import { objectHasOwn } from "ts-extras";
7
6
  const BUNFIG_BASE_PATH = path.resolve(import.meta.dir, "../configs/bunfig.base.toml");
8
7
  const BUNFIG_PROJECT_PATH = path.resolve("./bunfig.toml");
@@ -12,6 +11,6 @@ const isTomlImport = (tomlImport) => typeof tomlImport === "object" && objectHas
12
11
  const baseBunfig = isTomlImport(baseBunfigImport) ? baseBunfigImport.default : {};
13
12
  const projectBunfig = isTomlImport(projectBunfigImport) ? projectBunfigImport.default : {};
14
13
  const mergedConfig = merge(baseBunfig, projectBunfig);
15
- const mergedConfigToml = stringify(mergedConfig);
14
+ const mergedConfigToml = bun.TOML.stringify(mergedConfig) ?? "";
16
15
  await bun.write(BUNFIG_PROJECT_PATH, mergedConfigToml);
17
16
  export {};
@@ -1,12 +1,11 @@
1
1
  import { OptionalMergeConfigFn } from "../merge-config/merge-config.js";
2
2
  import { UserConfig } from "@commitlint/types";
3
3
  //#region src/configs/commitlint.base.d.ts
4
- declare const commitlintConfig: OptionalMergeConfigFn<UserConfig, {
4
+ export declare const commitlintConfig: OptionalMergeConfigFn<UserConfig, {
5
5
  readonly extends: ["@commitlint/config-conventional"];
6
6
  readonly rules: {
7
7
  readonly "type-enum": readonly [2, "always", string[]];
8
8
  };
9
9
  }>;
10
10
  //#endregion
11
- export { commitlintConfig };
12
11
  //# sourceMappingURL=commitlint.base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commitlint.base.d.ts","names":[],"sources":["../../src/configs/commitlint.base.ts"],"mappings":";;;cAkBa,kBAAgB,sBAAA;;;aAJzB"}
1
+ {"version":3,"file":"commitlint.base.d.ts","names":[],"sources":["../../src/configs/commitlint.base.ts"],"mappings":";;;qBAkBa,kBAAgB,sBAAA;;;aAJzB"}
@@ -4,7 +4,7 @@ set default-list
4
4
  set allow-duplicate-recipes
5
5
 
6
6
  # runs cmd if the condition command succeeds, echoing cmd only when it runs
7
- run-when(cmd, condition) := f"if {{condition}}; then echo {{style("command", cmd)}}; {{cmd}}; fi"
7
+ run-when(cmd, condition) := f"if {{ condition }}; then echo {{ style("command", cmd) }}; {{ cmd }}; fi"
8
8
 
9
9
  # run if not in CI, the repo has a root module, and the aws profile exists on this machine
10
10
  tofu-run-condition := '[ -z "${CI:-}" ] && ls *.tofu >/dev/null 2>&1 && aws configure list-profiles 2>/dev/null | grep -qx adamhl8'
@@ -14,7 +14,7 @@ tofu-run-condition := '[ -z "${CI:-}" ] && ls *.tofu >/dev/null 2>&1 && aws conf
14
14
 
15
15
  prepare: _prepare
16
16
  _prepare:
17
- lefthook install
17
+ @{{ run-when("lefthook install", '[ -z "${CI:-}" ]') }}
18
18
  bun adamhl8-gitignore
19
19
  bun adamhl8-bunfig
20
20
  bun oxfmt bunfig.toml
@@ -25,7 +25,7 @@ _bump-deps:
25
25
  bunx npm-check-updates --upgrade --format group
26
26
  rm -f bun.lock
27
27
  rm -rf node_modules/
28
- bun install --no-summary
28
+ bun install --no-summary --no-cache
29
29
 
30
30
  tofu-check: _tofu-check
31
31
  _tofu-check:
@@ -1,7 +1,7 @@
1
1
  import { OptionalMergeConfigFn } from "../merge-config/merge-config.js";
2
2
  import { KnipConfig } from "knip";
3
3
  //#region src/configs/knip.base.d.ts
4
- declare const knipConfig: OptionalMergeConfigFn<KnipConfig, {
4
+ export declare const knipConfig: OptionalMergeConfigFn<KnipConfig, {
5
5
  readonly project: ["**/*"];
6
6
  readonly ignoreBinaries: ["just"];
7
7
  readonly ignoreDependencies: ["@adamhl8/eslint-plugin-clean-modules"];
@@ -10,5 +10,4 @@ declare const knipConfig: OptionalMergeConfigFn<KnipConfig, {
10
10
  };
11
11
  }>;
12
12
  //#endregion
13
- export { knipConfig };
14
13
  //# sourceMappingURL=knip.base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"knip.base.d.ts","names":[],"sources":["../../src/configs/knip.base.ts"],"mappings":";;;cAsBa,YAAU,sBAAA;;;;;aAJnB"}
1
+ {"version":3,"file":"knip.base.d.ts","names":[],"sources":["../../src/configs/knip.base.ts"],"mappings":";;;qBAsBa,YAAU,sBAAA;;;;;aAJnB"}
@@ -1,7 +1,7 @@
1
1
  import { OptionalMergeConfigFn } from "../merge-config/merge-config.js";
2
2
  import { OxfmtConfig } from "oxfmt";
3
3
  //#region src/configs/oxfmt.base.d.ts
4
- declare const oxfmtConfig: OptionalMergeConfigFn<OxfmtConfig, {
4
+ export declare const oxfmtConfig: OptionalMergeConfigFn<OxfmtConfig, {
5
5
  readonly printWidth: 120;
6
6
  readonly semi: false;
7
7
  readonly jsdoc: true;
@@ -11,5 +11,4 @@ declare const oxfmtConfig: OptionalMergeConfigFn<OxfmtConfig, {
11
11
  readonly sortTailwindcss: true;
12
12
  }>;
13
13
  //#endregion
14
- export { oxfmtConfig };
15
14
  //# sourceMappingURL=oxfmt.base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oxfmt.base.d.ts","names":[],"sources":["../../src/configs/oxfmt.base.ts"],"mappings":";;;cAqBa,aAAW,sBAAA;WAhBV;;;;aAIV"}
1
+ {"version":3,"file":"oxfmt.base.d.ts","names":[],"sources":["../../src/configs/oxfmt.base.ts"],"mappings":";;;qBAqBa,aAAW,sBAAA;WAhBV;;;;aAIV"}
@@ -1,7 +1,7 @@
1
1
  import { OptionalMergeConfigFn } from "../merge-config/merge-config.js";
2
2
  import { OxlintConfig } from "oxlint";
3
3
  //#region src/configs/oxlint.base.d.ts
4
- declare const oxlintConfig: OptionalMergeConfigFn<OxlintConfig, {
4
+ export declare const oxlintConfig: OptionalMergeConfigFn<OxlintConfig, {
5
5
  readonly options: {
6
6
  readonly reportUnusedDisableDirectives: "error";
7
7
  readonly typeAware: true;
@@ -127,5 +127,4 @@ declare const oxlintConfig: OptionalMergeConfigFn<OxlintConfig, {
127
127
  };
128
128
  }>;
129
129
  //#endregion
130
- export { oxlintConfig };
131
130
  //# sourceMappingURL=oxlint.base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oxlint.base.d.ts","names":[],"sources":["../../src/configs/oxlint.base.ts"],"mappings":";;;cA0Ja,cAAY,sBAAA;;aAlJrB;aACA;aACA;;;aAIA;aACA;aACA;aACA;aACA;aACA;aACA;;;;;;;eAkCI;;;;;eAMA;;;;;;;mBAMqD;;;;;;aAMjB;aACG;aACF;;;;eAIe;eAA4B;eAAiB;;;eAClD;;;;iBAItC;iBAAiB;;;;;;aAKN;aACX;aACU;aACC;aACG;aACD;aACE;aACG;aACC;aACX;aACE;aACE;aACD;aACX;aACa;aACR;aACJ;aACC;aACS;aACF;aACF;aACL;aACD;aACF;aACI;aACK;aACV;aACa;aACR;aACW;aAChB;aACW;aACM;aACK;aACD;aACA;aACT;aACE;aACG;aACX;aACD;aACH;aACmB;aACY;aACC;aACC;aACL;aACF;aACE;aACH;aACX;aACI;aACD;aACX;aACmB;aACG;aACN;aACO;aACT;aACJ;aACC;aACP;aACQ"}
1
+ {"version":3,"file":"oxlint.base.d.ts","names":[],"sources":["../../src/configs/oxlint.base.ts"],"mappings":";;;qBA0Ja,cAAY,sBAAA;;aAlJrB;aACA;aACA;;;aAIA;aACA;aACA;aACA;aACA;aACA;aACA;;;;;;;eAkCI;;;;;eAMA;;;;;;;mBAMqD;;;;;;aAMjB;aACG;aACF;;;;eAIe;eAA4B;eAAiB;;;eAClD;;;;iBAItC;iBAAiB;;;;;;aAKN;aACX;aACU;aACC;aACG;aACD;aACE;aACG;aACC;aACX;aACE;aACE;aACD;aACX;aACa;aACR;aACJ;aACC;aACS;aACF;aACF;aACL;aACD;aACF;aACI;aACK;aACV;aACa;aACR;aACW;aAChB;aACW;aACM;aACK;aACD;aACA;aACT;aACE;aACG;aACX;aACD;aACH;aACmB;aACY;aACC;aACC;aACL;aACF;aACE;aACH;aACX;aACI;aACD;aACX;aACmB;aACG;aACN;aACO;aACT;aACJ;aACC;aACP;aACQ"}
@@ -1,7 +1,7 @@
1
1
  import { OptionalMergeConfigFn } from "../merge-config/merge-config.js";
2
2
  import { Config } from "release-it";
3
3
  //#region src/configs/release-it.base.d.ts
4
- declare const releaseItConfig: OptionalMergeConfigFn<Config, {
4
+ export declare const releaseItConfig: OptionalMergeConfigFn<Config, {
5
5
  readonly hooks: {
6
6
  readonly "before:init": "just build";
7
7
  readonly "after:bump": ["bun adamhl8-cliff --tag ${version} -o", "bun oxfmt CHANGELOG.md"];
@@ -24,5 +24,4 @@ declare const releaseItConfig: OptionalMergeConfigFn<Config, {
24
24
  };
25
25
  }>;
26
26
  //#endregion
27
- export { releaseItConfig };
28
27
  //# sourceMappingURL=release-it.base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"release-it.base.d.ts","names":[],"sources":["../../src/configs/release-it.base.ts"],"mappings":";;;cA4Ba,iBAAe,sBAAA;;aArBxB;aACA;;;aAGA;aACA;aACA;aACA;;;aAGA;aACA;aACA;;;aAGA;aACA;aACA"}
1
+ {"version":3,"file":"release-it.base.d.ts","names":[],"sources":["../../src/configs/release-it.base.ts"],"mappings":";;;qBA4Ba,iBAAe,sBAAA;;aArBxB;aACA;;;aAGA;aACA;aACA;aACA;;;aAGA;aACA;aACA;;;aAGA;aACA;aACA"}
@@ -13,8 +13,8 @@ declare const baseConfig: {
13
13
  readonly fixedExtension: false;
14
14
  readonly hash: false;
15
15
  readonly dts: {
16
+ readonly generator: "tsgo";
16
17
  readonly newContext: true;
17
- readonly tsgo: true;
18
18
  readonly sourcemap: true;
19
19
  };
20
20
  readonly deps: {
@@ -79,9 +79,8 @@ declare const binConfig: {
79
79
  readonly js: "";
80
80
  };
81
81
  };
82
- declare const tsdownConfig: MergeConfigFn<StrictConfig, typeof baseConfig>;
83
- declare const tsdownBundleConfig: MergeConfigFn<StrictBundleConfig, typeof bundleConfig>;
84
- declare const tsdownBinConfig: MergeConfigFn<StrictBinConfig, typeof binConfig>;
82
+ export declare const tsdownConfig: MergeConfigFn<StrictConfig, typeof baseConfig>;
83
+ export declare const tsdownBundleConfig: MergeConfigFn<StrictBundleConfig, typeof bundleConfig>;
84
+ export declare const tsdownBinConfig: MergeConfigFn<StrictBinConfig, typeof binConfig>;
85
85
  //#endregion
86
- export { tsdownBinConfig, tsdownBundleConfig, tsdownConfig };
87
86
  //# sourceMappingURL=tsdown.base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tsdown.base.d.ts","names":[],"sources":["../../src/configs/tsdown.base.ts"],"mappings":";;;;KAOK,eAAe,YAAY;cAE1B;;WAEM;;;;WAIF;;;;aAIN;aACA;aACA;;;aAGA;;;aAGA;aACA;;;;;;KAQC,qBAAqB,YAAY;cAGhC;WA5BM;;WAIF;;;;aASN;;;;;;;;;;;aAwBA;eACE;;;;KAMD,kBAAkB,YAAY;cAG7B;;WA3CI;;;;aASN;;;;;;;;;;;aAwBA;eACE;;;WAWM;;aACkB;;;cAKjB,cAAc,cAAc,qBAAqB;cAKjD,oBAAoB,cAAc,2BAA2B;cAK7D,iBAAiB,cAAc,wBAAwB"}
1
+ {"version":3,"file":"tsdown.base.d.ts","names":[],"sources":["../../src/configs/tsdown.base.ts"],"mappings":";;;;KAOK,eAAe,YAAY;cAE1B;;WAEM;;;;WAIF;;;;aAIN;aACA;aACA;;;aAGA;;;aAGA;aACA;;;;;;KAQC,qBAAqB,YAAY;cAGhC;WA5BM;;WAIF;;;;aASN;;;;;;;;;;;aAwBA;eACE;;;;KAMD,kBAAkB,YAAY;cAG7B;;WA3CI;;;;aASN;;;;;;;;;;;aAwBA;eACE;;;WAWM;;aACkB;;;qBAKjB,cAAc,cAAc,qBAAqB;qBAKjD,oBAAoB,cAAc,2BAA2B;qBAK7D,iBAAiB,cAAc,wBAAwB"}
@@ -10,8 +10,8 @@ const baseConfig = {
10
10
  fixedExtension: false,
11
11
  hash: false,
12
12
  dts: {
13
+ generator: "tsgo",
13
14
  newContext: true,
14
- tsgo: true,
15
15
  sourcemap: true
16
16
  },
17
17
  deps: { neverBundle: ["bun"] },
@@ -1 +1 @@
1
- {"version":3,"file":"tsdown.base.js","names":[],"sources":["../../src/configs/tsdown.base.ts"],"sourcesContent":["import type { UserConfig } from \"tsdown\"\nimport type { SetRequired } from \"type-fest\"\n\nimport type { MergeConfigFn } from \"#merge-config/merge-config.ts\"\nimport { createMergeConfigFn } from \"#merge-config/merge-config.ts\"\n\n// Force projects to specify platform\ntype StrictConfig = SetRequired<UserConfig, \"platform\">\n\nconst baseConfig = {\n entry: [\"./src/index.ts\"],\n platform: \"neutral\",\n target: false,\n unbundle: true,\n sourcemap: true,\n minify: \"dce-only\",\n fixedExtension: false,\n hash: false,\n dts: {\n newContext: true,\n tsgo: true,\n sourcemap: true,\n },\n deps: {\n neverBundle: [\"bun\"],\n },\n attw: {\n level: \"error\",\n profile: \"esm-only\",\n },\n publint: true,\n failOnWarn: true,\n suppressWarnings: [\"does not yet have a stable API\"],\n} as const satisfies StrictConfig\n\n// Force projects to specify platform and entry\ntype StrictBundleConfig = SetRequired<UserConfig, \"platform\" | \"entry\">\n\n// Single-file bundle (not a published library): bundle everything, drop types/lint/sourcemap.\nconst bundleConfig = {\n ...baseConfig,\n entry: [],\n unbundle: false,\n sourcemap: false,\n dts: false,\n attw: false,\n publint: false,\n inputOptions: {\n experimental: {\n attachDebugInfo: \"none\", // remove region comments from bundled output\n },\n },\n} as const satisfies StrictBundleConfig\n\n// Force projects to specify platform and entry\ntype StrictBinConfig = SetRequired<UserConfig, \"entry\">\n\n// A bin is a node bundle with no output file extension.\nconst binConfig = {\n ...bundleConfig,\n platform: \"node\",\n outExtensions: () => ({ js: \"\" }) as const,\n} as const satisfies StrictBinConfig\n\n// The export annotations forbid the no-arg call (platform/entry must be provided) and are load-bearing for\n// declaration emit: without one, tsgo synthesizes the type and fails with TS2883 on tsdown's non-exported internals.\nexport const tsdownConfig: MergeConfigFn<StrictConfig, typeof baseConfig> = createMergeConfigFn<\n StrictConfig,\n typeof baseConfig\n>(baseConfig)\n\nexport const tsdownBundleConfig: MergeConfigFn<StrictBundleConfig, typeof bundleConfig> = createMergeConfigFn<\n StrictBundleConfig,\n typeof bundleConfig\n>(bundleConfig)\n\nexport const tsdownBinConfig: MergeConfigFn<StrictBinConfig, typeof binConfig> = createMergeConfigFn<\n StrictBinConfig,\n typeof binConfig\n>(binConfig)\n"],"mappings":";;AASA,MAAM,aAAa;CACjB,OAAO,CAAC,gBAAgB;CACxB,UAAU;CACV,QAAQ;CACR,UAAU;CACV,WAAW;CACX,QAAQ;CACR,gBAAgB;CAChB,MAAM;CACN,KAAK;EACH,YAAY;EACZ,MAAM;EACN,WAAW;CACb;CACA,MAAM,EACJ,aAAa,CAAC,KAAK,EACrB;CACA,MAAM;EACJ,OAAO;EACP,SAAS;CACX;CACA,SAAS;CACT,YAAY;CACZ,kBAAkB,CAAC,gCAAgC;AACrD;AAMA,MAAM,eAAe;CACnB,GAAG;CACH,OAAO,CAAC;CACR,UAAU;CACV,WAAW;CACX,KAAK;CACL,MAAM;CACN,SAAS;CACT,cAAc,EACZ,cAAc,EACZ,iBAAiB,OACnB,EACF;AACF;AAMA,MAAM,YAAY;CAChB,GAAG;CACH,UAAU;CACV,sBAAsB,EAAE,IAAI,GAAG;AACjC;AAIA,MAAa,eAA+D,oBAG1E,UAAU;AAEZ,MAAa,qBAA6E,oBAGxF,YAAY;AAEd,MAAa,kBAAoE,oBAG/E,SAAS"}
1
+ {"version":3,"file":"tsdown.base.js","names":[],"sources":["../../src/configs/tsdown.base.ts"],"sourcesContent":["import type { UserConfig } from \"tsdown\"\nimport type { SetRequired } from \"type-fest\"\n\nimport type { MergeConfigFn } from \"#merge-config/merge-config.ts\"\nimport { createMergeConfigFn } from \"#merge-config/merge-config.ts\"\n\n// Force projects to specify platform\ntype StrictConfig = SetRequired<UserConfig, \"platform\">\n\nconst baseConfig = {\n entry: [\"./src/index.ts\"],\n platform: \"neutral\",\n target: false,\n unbundle: true,\n sourcemap: true,\n minify: \"dce-only\",\n fixedExtension: false,\n hash: false,\n dts: {\n generator: \"tsgo\",\n newContext: true,\n sourcemap: true,\n },\n deps: {\n neverBundle: [\"bun\"],\n },\n attw: {\n level: \"error\",\n profile: \"esm-only\",\n },\n publint: true,\n failOnWarn: true,\n suppressWarnings: [\"does not yet have a stable API\"],\n} as const satisfies StrictConfig\n\n// Force projects to specify platform and entry\ntype StrictBundleConfig = SetRequired<UserConfig, \"platform\" | \"entry\">\n\n// Single-file bundle (not a published library): bundle everything, drop types/lint/sourcemap.\nconst bundleConfig = {\n ...baseConfig,\n entry: [],\n unbundle: false,\n sourcemap: false,\n dts: false,\n attw: false,\n publint: false,\n inputOptions: {\n experimental: {\n attachDebugInfo: \"none\", // remove region comments from bundled output\n },\n },\n} as const satisfies StrictBundleConfig\n\n// Force projects to specify platform and entry\ntype StrictBinConfig = SetRequired<UserConfig, \"entry\">\n\n// A bin is a node bundle with no output file extension.\nconst binConfig = {\n ...bundleConfig,\n platform: \"node\",\n outExtensions: () => ({ js: \"\" }) as const,\n} as const satisfies StrictBinConfig\n\n// The export annotations forbid the no-arg call (platform/entry must be provided) and are load-bearing for\n// declaration emit: without one, tsgo synthesizes the type and fails with TS2883 on tsdown's non-exported internals.\nexport const tsdownConfig: MergeConfigFn<StrictConfig, typeof baseConfig> = createMergeConfigFn<\n StrictConfig,\n typeof baseConfig\n>(baseConfig)\n\nexport const tsdownBundleConfig: MergeConfigFn<StrictBundleConfig, typeof bundleConfig> = createMergeConfigFn<\n StrictBundleConfig,\n typeof bundleConfig\n>(bundleConfig)\n\nexport const tsdownBinConfig: MergeConfigFn<StrictBinConfig, typeof binConfig> = createMergeConfigFn<\n StrictBinConfig,\n typeof binConfig\n>(binConfig)\n"],"mappings":";;AASA,MAAM,aAAa;CACjB,OAAO,CAAC,gBAAgB;CACxB,UAAU;CACV,QAAQ;CACR,UAAU;CACV,WAAW;CACX,QAAQ;CACR,gBAAgB;CAChB,MAAM;CACN,KAAK;EACH,WAAW;EACX,YAAY;EACZ,WAAW;CACb;CACA,MAAM,EACJ,aAAa,CAAC,KAAK,EACrB;CACA,MAAM;EACJ,OAAO;EACP,SAAS;CACX;CACA,SAAS;CACT,YAAY;CACZ,kBAAkB,CAAC,gCAAgC;AACrD;AAMA,MAAM,eAAe;CACnB,GAAG;CACH,OAAO,CAAC;CACR,UAAU;CACV,WAAW;CACX,KAAK;CACL,MAAM;CACN,SAAS;CACT,cAAc,EACZ,cAAc,EACZ,iBAAiB,OACnB,EACF;AACF;AAMA,MAAM,YAAY;CAChB,GAAG;CACH,UAAU;CACV,sBAAsB,EAAE,IAAI,GAAG;AACjC;AAIA,MAAa,eAA+D,oBAG1E,UAAU;AAEZ,MAAa,qBAA6E,oBAGxF,YAAY;AAEd,MAAa,kBAAoE,oBAG/E,SAAS"}
@@ -2,7 +2,7 @@ import { requireWhen } from "./utils.js";
2
2
  import arkenv from "arkenv";
3
3
  //#region src/env/index.d.ts
4
4
  type ArkEnv = typeof arkenv;
5
- declare const parseEnv: ArkEnv;
5
+ export declare const parseEnv: ArkEnv;
6
6
  //#endregion
7
- export { parseEnv, requireWhen };
7
+ export { requireWhen };
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/env/index.ts"],"mappings":";;;KAKK,gBAAgB;cAER,UAOP"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/env/index.ts"],"mappings":";;;KAKK,gBAAgB;qBAER,UAOP"}
@@ -6,8 +6,7 @@ import { type } from "arktype";
6
6
  * A set value must always satisfy `def`. An unset var takes `fallback` (exempt from `def` validation), or the key is
7
7
  * omitted entirely if no fallback is given.
8
8
  */
9
- declare function requireWhen<const type$1>(when: boolean, type: type.validate<type$1>): ReturnType<type.instantiate<type$1>["optional"]>;
10
- declare function requireWhen<const type$2>(when: boolean, type: type.validate<type$2>, fallback: type.infer<type$2>): type.instantiate<type$2>;
9
+ export declare function requireWhen<const def>(when: boolean, type: type.validate<def>): ReturnType<type.instantiate<def>["optional"]>;
10
+ export declare function requireWhen<const def>(when: boolean, type: type.validate<def>, fallback: type.infer<def>): type.instantiate<def>;
11
11
  //#endregion
12
- export { requireWhen };
13
12
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","names":[],"sources":["../../src/env/utils.ts"],"mappings":";;;;;;;;iBASgB,kBAAkB,QAChC,eACA,MAAM,KAAQ,SAAS,UACtB,WAAW,KAAQ,YAAY;iBAClB,kBAAkB,QAChC,eACA,MAAM,KAAQ,SAAS,SACvB,UAAU,KAAQ,MAAM,UACvB,KAAQ,YAAY"}
1
+ {"version":3,"file":"utils.d.ts","names":[],"sources":["../../src/env/utils.ts"],"mappings":";;;;;;;;wBASgB,kBAAkB,KAChC,eACA,MAAM,KAAQ,SAAS,OACtB,WAAW,KAAQ,YAAY;wBAClB,kBAAkB,KAChC,eACA,MAAM,KAAQ,SAAS,MACvB,UAAU,KAAQ,MAAM,OACvB,KAAQ,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","names":["arkenvType","type"],"sources":["../../src/env/utils.ts"],"sourcesContent":["import { type as arkenvType } from \"arkenv\"\nimport type { type as arktype } from \"arktype\"\n\n/**\n * Makes an env var required while `when` is true, otherwise optional.\n *\n * A set value must always satisfy `def`. An unset var takes `fallback` (exempt from `def` validation), or the key is\n * omitted entirely if no fallback is given.\n */\nexport function requireWhen<const type>(\n when: boolean,\n type: arktype.validate<type>,\n): ReturnType<arktype.instantiate<type>[\"optional\"]>\nexport function requireWhen<const type>(\n when: boolean,\n type: arktype.validate<type>,\n fallback: arktype.infer<type>,\n): arktype.instantiate<type>\n/* oxlint-disable typescript/no-unsafe-type-assertion */\nexport function requireWhen(when: boolean, type: unknown, ...rest: [unknown?]): never {\n const t = arkenvType.raw(type)\n if (when) return t as never\n if (rest.length === 0) return t.optional() as never\n const [fallback] = rest\n // defaulting to a sentinel keeps the fallback exempt from def validation without\n // letting an explicitly set value bypass it (env values can never be a symbol)\n const unset = Symbol(\"unset\")\n return t\n .or(arkenvType.unit(unset))\n .pipe((v: unknown) => (v === unset ? fallback : v))\n .default(unset as never) as never\n}\n"],"mappings":";;AAmBA,SAAgB,YAAY,MAAe,QAAe,GAAG,MAAyB;CACpF,MAAM,IAAIA,KAAW,IAAIC,MAAI;CAC7B,IAAI,MAAM,OAAO;CACjB,IAAI,KAAK,WAAW,GAAG,OAAO,EAAE,SAAS;CACzC,MAAM,CAAC,YAAY;CAGnB,MAAM,QAAQ,OAAO,OAAO;CAC5B,OAAO,EACJ,GAAGD,KAAW,KAAK,KAAK,CAAC,CAAC,CAC1B,MAAM,MAAgB,MAAM,QAAQ,WAAW,CAAE,CAAC,CAClD,QAAQ,KAAc;AAC3B"}
1
+ {"version":3,"file":"utils.js","names":["arkenvType","type"],"sources":["../../src/env/utils.ts"],"sourcesContent":["import { type as arkenvType } from \"arkenv\"\nimport type { type as arktype } from \"arktype\"\n\n/**\n * Makes an env var required while `when` is true, otherwise optional.\n *\n * A set value must always satisfy `def`. An unset var takes `fallback` (exempt from `def` validation), or the key is\n * omitted entirely if no fallback is given.\n */\nexport function requireWhen<const def>(\n when: boolean,\n type: arktype.validate<def>,\n): ReturnType<arktype.instantiate<def>[\"optional\"]>\nexport function requireWhen<const def>(\n when: boolean,\n type: arktype.validate<def>,\n fallback: arktype.infer<def>,\n): arktype.instantiate<def>\n/* oxlint-disable typescript/no-unsafe-type-assertion */\nexport function requireWhen(when: boolean, type: unknown, ...rest: [unknown?]): never {\n const t = arkenvType.raw(type)\n if (when) return t as never\n if (rest.length === 0) return t.optional() as never\n const [fallback] = rest\n // defaulting to a sentinel keeps the fallback exempt from def validation without\n // letting an explicitly set value bypass it (env values can never be a symbol)\n const unset = Symbol(\"unset\")\n return t\n .or(arkenvType.unit(unset))\n .pipe((v: unknown) => (v === unset ? fallback : v))\n .default(unset as never) as never\n}\n"],"mappings":";;AAmBA,SAAgB,YAAY,MAAe,QAAe,GAAG,MAAyB;CACpF,MAAM,IAAIA,KAAW,IAAIC,MAAI;CAC7B,IAAI,MAAM,OAAO;CACjB,IAAI,KAAK,WAAW,GAAG,OAAO,EAAE,SAAS;CACzC,MAAM,CAAC,YAAY;CAGnB,MAAM,QAAQ,OAAO,OAAO;CAC5B,OAAO,EACJ,GAAGD,KAAW,KAAK,KAAK,CAAC,CAAC,CAC1B,MAAM,MAAgB,MAAM,QAAQ,WAAW,CAAE,CAAC,CAClD,QAAQ,KAAc;AAC3B"}
@@ -11,9 +11,8 @@ import { ReadonlyDeep } from "type-fest";
11
11
  * readonly arrays/objects (e.g. from `as const`), and the result is writable so it stays assignable to the tools' own
12
12
  * (mutable) config types.
13
13
  */
14
- type MergeConfigFn<UserConfig, BaseConfig> = (<const UserConfigToMerge extends ReadonlyDeep<UserConfig>>(userConfig: UserConfigToMerge) => MergedConfig<BaseConfig, UserConfigToMerge>) & (<const UserConfigToMerge extends ReadonlyDeep<UserConfig>, const ReplaceConfigToMerge extends ReadonlyDeep<Partial<UserConfig>>>(userConfig: UserConfigToMerge, replaceConfig: ReplaceConfigToMerge) => MergedConfig<MergedConfig<BaseConfig, UserConfigToMerge>, ReplaceConfigToMerge, "replace">);
14
+ export type MergeConfigFn<UserConfig, BaseConfig> = (<const UserConfigToMerge extends ReadonlyDeep<UserConfig>>(userConfig: UserConfigToMerge) => MergedConfig<BaseConfig, UserConfigToMerge>) & (<const UserConfigToMerge extends ReadonlyDeep<UserConfig>, const ReplaceConfigToMerge extends ReadonlyDeep<Partial<UserConfig>>>(userConfig: UserConfigToMerge, replaceConfig: ReplaceConfigToMerge) => MergedConfig<MergedConfig<BaseConfig, UserConfigToMerge>, ReplaceConfigToMerge, "replace">);
15
15
  /** A MergeConfigFn that can also be called with no arguments, returning a writable clone of the base config. */
16
- type OptionalMergeConfigFn<UserConfig, BaseConfig> = MergeConfigFn<UserConfig, BaseConfig> & (() => Clean<BaseConfig>);
16
+ export type OptionalMergeConfigFn<UserConfig, BaseConfig> = MergeConfigFn<UserConfig, BaseConfig> & (() => Clean<BaseConfig>);
17
17
  //#endregion
18
- export { MergeConfigFn, OptionalMergeConfigFn };
19
18
  //# sourceMappingURL=merge-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"merge-config.d.ts","names":[],"sources":["../../src/merge-config/merge-config.ts"],"mappings":";;;;;;;;;;;;;KAgCY,cAAc,YAAY,sBAAsB,0BAA0B,aAAa,aACjG,YAAY,sBACT,aAAa,YAAY,8BAEpB,0BAA0B,aAAa,mBACvC,6BAA6B,aAAa,QAAQ,cAExD,YAAY,mBACZ,eAAe,yBACZ,aAAa,aAAa,YAAY,oBAAoB;;KAGrD,sBAAsB,YAAY,cAAc,cAAc,YAAY,qBAC7E,MAAM"}
1
+ {"version":3,"file":"merge-config.d.ts","names":[],"sources":["../../src/merge-config/merge-config.ts"],"mappings":";;;;;;;;;;;;;YAgCY,cAAc,YAAY,sBAAsB,0BAA0B,aAAa,aACjG,YAAY,sBACT,aAAa,YAAY,8BAEpB,0BAA0B,aAAa,mBACvC,6BAA6B,aAAa,QAAQ,cAExD,YAAY,mBACZ,eAAe,yBACZ,aAAa,aAAa,YAAY,oBAAoB;;YAGrD,sBAAsB,YAAY,cAAc,cAAc,YAAY,qBAC7E,MAAM"}
@@ -1,7 +1,7 @@
1
1
  //#region src/merge-config/merge.types.d.ts
2
2
  type AnyFunction = (...args: never[]) => unknown;
3
3
  /** How user arrays combine with base arrays: appended in spread mode, used as-is in replace mode. */
4
- type Mode = "spread" | "replace";
4
+ export type Mode = "spread" | "replace";
5
5
  /**
6
6
  * Recursion budget for the merge walk, threaded through every recursive type below. When a call fails the generic
7
7
  * constraint, these types run over the full constraint (the whole tool config type, with circular types like Console in
@@ -22,7 +22,7 @@ type NonRecursive = AnyFunction | Date | RegExp | Error | {
22
22
  * interface-shaped values with symbol-keyed members, e.g. anything iterable). The `T extends object` gate comes first
23
23
  * so primitive leaves (most nodes of a config type) cost one relation, and only recursion spends the depth budget.
24
24
  */
25
- type Clean<T, Depth extends readonly unknown[] = MaxDepth> = T extends object ? Depth extends readonly [unknown, ...infer RemainingDepth] ? T extends NonRecursive ? T : { -readonly [K in keyof T]: Clean<T[K], RemainingDepth>; } : T : T;
25
+ export type Clean<T, Depth extends readonly unknown[] = MaxDepth> = T extends object ? Depth extends readonly [unknown, ...infer RemainingDepth] ? T extends NonRecursive ? T : { -readonly [K in keyof T]: Clean<T[K], RemainingDepth>; } : T : T;
26
26
  /**
27
27
  * In spread mode, base and user arrays concatenate to an element-union array. In replace mode, or over a non-array
28
28
  * base, the user array is used as-is.
@@ -45,7 +45,6 @@ type MergeObjects<BaseConfig, UserConfig, Depth extends readonly unknown[], M ex
45
45
  * The merged result type, exact per key: spread-mode arrays show the element-union of base and user, replace-mode
46
46
  * arrays show only the user's elements.
47
47
  */
48
- type MergedConfig<BaseConfig, UserConfig, M extends Mode = "spread"> = MergeObjects<BaseConfig, UserConfig, MaxDepth, M>;
48
+ export type MergedConfig<BaseConfig, UserConfig, M extends Mode = "spread"> = MergeObjects<BaseConfig, UserConfig, MaxDepth, M>;
49
49
  //#endregion
50
- export { Clean, MergedConfig, Mode };
51
50
  //# sourceMappingURL=merge.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"merge.types.d.ts","names":[],"sources":["../../src/merge-config/merge.types.ts"],"mappings":";KAWK,kBAAkB;;KAGX;;;;;;KAOP;;;;;;KAOA,eAAe,cAAc,OAAO,SAAS;YAAoB,OAAO;;;;;;;;KAQjE,MAAM,GAAG,mCAAmC,YAAY,mBAChE,0CAA0C,kBACxC,UAAU,eACR,iBACa,WAAW,IAAI,MAAM,EAAE,IAAI,qBAC1C,IACF;;;;;KAMC,YACH,WACA,sCACA,kCACA,UAAU,QACR,qBACA,wCACG,MAAM,mBAAmB,SAAS,MAAM,mBAAmB,YAC5D,MAAM,WAAW,SACnB,MAAM,WAAW;;;;;KAMhB,YAAY,WAAW,WAAW,kCAAkC,UAAU,QAAQ,2BACvF,uCACE,YAAY,WAAW,WAAW,OAAO,KACzC,kBAAkB,eAChB,YACA,uCAAuC,eACrC,MAAM,WAAW,SACjB,2BACE,aAAa,WAAW,WAAW,OAAO,KAC1C,MAAM,WAAW,SACzB;;;;;;;;KASC,aAAa,YAAY,YAAY,kCAAkC,UAAU,QAAQ,0CAEnF,+BAGM,WAAW,aAAa,gBAAgB,+BAC7B,WAAW,KAEvB,YAAY,WAAW,IAAI,QAAQ,WAAW,gBAAgB,gBAAgB,KAC9E,MAAM,WAAW,IAAI,kBACzB,YAAY,WAAW,IAAI,WAAW,IAAI,gBAAgB,KAC5D,MAAM,WAAW,IAAI,kCAEd,WAAW,cAAc,gBAAgB,8BAA8B,IAAI,MACpF,WAAW,IACX,kCAEY,aACX,WAAW,SAAS,OAAO,gBAEhC;;;;;KAMQ,aAAa,YAAY,YAAY,UAAU,mBAAmB,aAC5E,YACA,YACA,UACA"}
1
+ {"version":3,"file":"merge.types.d.ts","names":[],"sources":["../../src/merge-config/merge.types.ts"],"mappings":";KAWK,kBAAkB;;YAGX;;;;;;KAOP;;;;;;KAOA,eAAe,cAAc,OAAO,SAAS;YAAoB,OAAO;;;;;;;;YAQjE,MAAM,GAAG,mCAAmC,YAAY,mBAChE,0CAA0C,kBACxC,UAAU,eACR,iBACa,WAAW,IAAI,MAAM,EAAE,IAAI,qBAC1C,IACF;;;;;KAMC,YACH,WACA,sCACA,kCACA,UAAU,QACR,qBACA,wCACG,MAAM,mBAAmB,SAAS,MAAM,mBAAmB,YAC5D,MAAM,WAAW,SACnB,MAAM,WAAW;;;;;KAMhB,YAAY,WAAW,WAAW,kCAAkC,UAAU,QAAQ,2BACvF,uCACE,YAAY,WAAW,WAAW,OAAO,KACzC,kBAAkB,eAChB,YACA,uCAAuC,eACrC,MAAM,WAAW,SACjB,2BACE,aAAa,WAAW,WAAW,OAAO,KAC1C,MAAM,WAAW,SACzB;;;;;;;;KASC,aAAa,YAAY,YAAY,kCAAkC,UAAU,QAAQ,0CAEnF,+BAGM,WAAW,aAAa,gBAAgB,+BAC7B,WAAW,KAEvB,YAAY,WAAW,IAAI,QAAQ,WAAW,gBAAgB,gBAAgB,KAC9E,MAAM,WAAW,IAAI,kBACzB,YAAY,WAAW,IAAI,WAAW,IAAI,gBAAgB,KAC5D,MAAM,WAAW,IAAI,kCAEd,WAAW,cAAc,gBAAgB,8BAA8B,IAAI,MACpF,WAAW,IACX,kCAEY,aACX,WAAW,SAAS,OAAO,gBAEhC;;;;;YAMQ,aAAa,YAAY,YAAY,UAAU,mBAAmB,aAC5E,YACA,YACA,UACA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adamhl8/configs",
3
- "version": "2.3.2",
3
+ "version": "2.4.1",
4
4
  "description": "My shared configs for TS projects",
5
5
  "homepage": "https://github.com/adamhl8/configs",
6
6
  "bugs": {
@@ -47,29 +47,28 @@
47
47
  },
48
48
  "dependencies": {
49
49
  "@adamhl8/eslint-plugin-clean-modules": "^0.1.5",
50
- "@commitlint/config-conventional": "^21.2.2",
51
- "@commitlint/types": "^21.2.0",
50
+ "@commitlint/config-conventional": "^21.2.3",
51
+ "@commitlint/types": "^21.2.3",
52
52
  "arkenv": "^0.12.3",
53
53
  "arktype": "^2.2.3",
54
- "es-toolkit": "^1.51.0",
55
- "smol-toml": "^1.8.0",
54
+ "es-toolkit": "^1.52.0",
56
55
  "ts-explicit-errors": "^4.1.3",
57
56
  "ts-extras": "^1.3.0",
58
- "type-fest": "^5.8.0"
57
+ "type-fest": "^5.10.0"
59
58
  },
60
59
  "devDependencies": {
61
60
  "@adamhl8/configs": "file:.",
62
61
  "@arethetypeswrong/core": "^0.18.5",
63
- "@commitlint/cli": "^21.2.2",
64
- "@types/bun": "^1.3.14",
65
- "knip": "^6.32.2",
62
+ "@commitlint/cli": "^21.2.3",
63
+ "@types/bun": "^1.4.2",
64
+ "knip": "^6.37.0",
66
65
  "markdown-toc": "^1.2.0",
67
- "oxfmt": "^0.63.0",
68
- "oxlint": "^1.78.0",
69
- "oxlint-tsgolint": "^7.0.2001",
70
- "publint": "^0.3.23",
71
- "release-it": "^21.0.2",
72
- "tsdown": "^0.22.14",
66
+ "oxfmt": "^0.70.0",
67
+ "oxlint": "^1.85.0",
68
+ "oxlint-tsgolint": "^7.0.2002",
69
+ "publint": "^0.3.24",
70
+ "release-it": "^21.1.0",
71
+ "tsdown": "^0.23.0",
73
72
  "typescript": "^7.0.2"
74
73
  },
75
74
  "peerDependencies": {
@@ -87,30 +86,6 @@
87
86
  "typescript": "^7.0.0"
88
87
  },
89
88
  "peerDependenciesMeta": {
90
- "@arethetypeswrong/core": {
91
- "optional": true
92
- },
93
- "@commitlint/cli": {
94
- "optional": true
95
- },
96
- "@commitlint/config-conventional": {
97
- "optional": true
98
- },
99
- "knip": {
100
- "optional": true
101
- },
102
- "markdown-toc": {
103
- "optional": true
104
- },
105
- "oxfmt": {
106
- "optional": true
107
- },
108
- "oxlint-tsgolint": {
109
- "optional": true
110
- },
111
- "oxlint": {
112
- "optional": true
113
- },
114
89
  "publint": {
115
90
  "optional": true
116
91
  },