@sidebase/base-config 0.2.0 → 0.2.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
@@ -19,10 +19,10 @@ pnpm add -D @sidebase/base-config eslint jiti
19
19
  required because the config file is TypeScript. `prisma` and `@prisma/client` (`^6.19`)
20
20
  are optional peers, install them only if you use `/prisma`.
21
21
 
22
- **`jiti` is not a declared peer** -- `peerDependencies` is `eslint`, `prisma` and
23
- `@prisma/client`. It is in the command above because `/eslint` genuinely needs it, but
24
- since nothing declares it, **pnpm emits no missing-peer warning if you leave it out**.
25
- This README is the only thing that will tell you. See Requirements below.
22
+ **`jiti` is not a declared peer.** `peerDependencies` is `eslint`, `prisma` and
23
+ `@prisma/client`. It is in the command above because `/eslint` genuinely needs it. Since
24
+ nothing declares it, pnpm emits no missing-peer warning if you leave it out. This README is
25
+ the only thing that will tell you. See Requirements below.
26
26
 
27
27
  For the file-sync channel, see Adopting below. The CLI wires the dependency itself.
28
28
 
@@ -137,7 +137,7 @@ real CLI binary, so both resolve `@sidebase/streamctl` from the registry.
137
137
  This payload needs **streamctl >= 0.3.0**: its manifest declares `schemaVersion` 3 (the
138
138
  `fromDependency` placeholder behind the derived Prisma ARG), which a 0.2.x CLI rejects with
139
139
  `SCHEMA_UNSUPPORTED`. The root `streamctl.config.ts` location it documents arrived in
140
- 0.2.0 — see "Config location" below.
140
+ 0.2.0. See "Config location" below.
141
141
 
142
142
  ## Typed config
143
143
 
@@ -275,7 +275,7 @@ The custom bans map to these ESLint rule IDs. Use the exact ID in an
275
275
  "Re-export" is not a figure of speech: a barrel file doing `export * from "node:process"`
276
276
  reports, as do `export { env } from "node:process"` and `export { default as p } from
277
277
  "node:process"`. The one shape that does **not** report is a bare side-effect import with
278
- no bindings, `import "node:process"` -- it cannot reach `env`, so there is nothing to ban.
278
+ no bindings, `import "node:process"`. It cannot reach `env`, so there is nothing to ban.
279
279
 
280
280
  The `process.env` ban is enforced by **two** rules, and which one reports depends on the
281
281
  shape, so suppressing the wrong one fails twice over: the directive does not suppress
@@ -303,14 +303,15 @@ entirely, as does running on Deno or Bun, which import TypeScript directly.
303
303
  #### Type-aware linting prerequisite
304
304
 
305
305
  Type-aware linting is gated behind `LINT_TYPEAWARE=true` (off by default), so this only
306
- matters on the opt-in / CI path. When type-aware lint is on, the Prisma client and Nuxt types must be
307
- generated **before** `lint` runs, otherwise type-aware rules fail on missing generated types. This is
308
- satisfied by ordering, not a preflight check:
306
+ matters on the opt-in and CI path. When type-aware lint is on, the Prisma client and Nuxt
307
+ types must be generated **before** `lint` runs, otherwise type-aware rules fail on missing
308
+ generated types. Ordering satisfies this, not a preflight check:
309
309
 
310
310
  - the managed `ci.yml` runs `prisma generate` (and `nuxi prepare`) before `pnpm lint`, and
311
311
  - `scripts.postinstall: "nuxt prepare"` regenerates Nuxt types on install.
312
312
 
313
- So a standard `pnpm install` + the managed CI ordering covers the prerequisite; no separate check is run.
313
+ A standard `pnpm install` plus the managed CI ordering covers the prerequisite. No separate
314
+ check runs.
314
315
 
315
316
  ## Prisma factory
316
317
 
@@ -442,8 +443,9 @@ existing `onlyBuiltDependencies` allowlist and `ignoredBuiltDependencies` are bo
442
443
  by the baked-in baseline, and **nothing warns about it**. Most affected packages ship a
443
444
  prebuilt native binary and keep working either way, so the practical breakage is limited to
444
445
  architectures with no prebuild and to postinstalls doing essential non-native work. Capture
445
- the old list before you adopt and re-add it via `pnpm.onlyBuiltDependencies` above. A repo that genuinely needs its own `packages:` list
446
- (a real monorepo) or its own exclude list should opt the file out entirely instead:
446
+ the old list before you adopt and re-add it via `pnpm.onlyBuiltDependencies` above. A repo
447
+ that genuinely needs its own `packages:` list (a real monorepo) or its own exclude list
448
+ should opt the file out entirely instead:
447
449
 
448
450
  ```ts
449
451
  files: { "pnpm-workspace.yaml": "off" },
@@ -464,7 +466,7 @@ The `nuxt-app` preset ships a managed `.github/workflows/ci.yml`. Its `lint-type
464
466
  on top of what the runner image already carries, for a binary the suite needs and
465
467
  `ubuntu-latest` does not ship. The motivating case is `libxml2-utils`, for `xmllint`.
466
468
 
467
- It applies to the `test` and `e2e` jobs **only** -- never `lint-typecheck` or `build` -- and
469
+ It applies to the `test` and `e2e` jobs only, never `lint-typecheck` or `build`. The step
468
470
  installs directly after `checkout`, before `pnpm install`, so a package needed by an install
469
471
  lifecycle script is covered as well as one needed by the tests. Leave it unset and the step
470
472
  is skipped entirely: it renders with a guard on the value being non-empty, so the default
@@ -498,7 +500,7 @@ out:
498
500
  | `docker.prismaRuntime` | final stage | copy the schema + install the `migrate deploy` CLI |
499
501
  | `docker.startCommand` | inside `CMD` | `prisma migrate deploy` then the node server |
500
502
 
501
- A seventh knob is different in kind — a validated version, not raw text:
503
+ A seventh knob is different in kind: a validated version, not raw text.
502
504
 
503
505
  | Knob | Position | Default |
504
506
  | ---- | -------- | ------- |
@@ -525,8 +527,10 @@ export default {
525
527
  > shell-metacharacter check runs on them. The trust level is exactly that of
526
528
  > `files: { "Dockerfile": "off" }`, which any consumer can already set: whoever
527
529
  > can edit `streamctl.config.ts` can already replace the whole file. The
528
- > `USER node` switch and the `.output` ownership stay FIXED outside every knob,
529
- > so an override cannot re-root the container or drop the runtime user.
530
+ > `.output` ownership stays FIXED outside every knob. The container itself runs
531
+ > as **root**: a fixed `USER node` broke every deployment that overrides the image
532
+ > CMD with a root-requiring command, so a repo that wants an unprivileged runtime
533
+ > opts in with `docker.finalStage: "USER node"`.
530
534
 
531
535
  Setting a knob replaces its default outright, it does not append. So a `docker.buildSteps`
532
536
  override must restate every build command you still want, and `docker.prismaRuntime: ""`
@@ -534,8 +538,8 @@ removes the Prisma runtime block entirely. The three knobs that default to real
534
538
  (`buildSteps`, `prismaRuntime`, `startCommand`) are the ones where this matters; the other
535
539
  three default to `""`.
536
540
 
537
- **`prismaRuntime` and `startCommand` are coupled -- override one and you must override the
538
- other.** `prismaRuntime` is what installs the Prisma CLI into the final stage, and the
541
+ **`prismaRuntime` and `startCommand` are coupled.** Override one and you must override the
542
+ other. `prismaRuntime` is what installs the Prisma CLI into the final stage, and the
539
543
  DEFAULT `startCommand` is `npm exec prisma migrate deploy && node ...`. Setting only
540
544
  `prismaRuntime: ""` therefore produces an image whose `CMD` invokes a CLI that is no longer
541
545
  installed, and the container fails to start. The example above overrides both, which is why
@@ -552,7 +556,7 @@ The base preset owns its own keys in `.vscode/settings.json` and leaves the rest
552
556
  to the project. Among them is i18n-ally, configured for the fleet's standard setup:
553
557
  `@nuxtjs/i18n` with flat dotted keys under `i18n/locales`.
554
558
 
555
- Everything the payload does not write is yours and survives a sync untouched -- your
559
+ Everything the payload does not write is yours and survives a sync untouched: your
556
560
  `editor.fontSize`, your `files.exclude`, any unrelated key at all. Six of those are named in
557
561
  the manifest as project-owned on top of that (`editor.fontSize`, `editor.rulers`,
558
562
  `editor.formatOnSave`, `files.exclude`, `search.exclude`, `files.watcherExclude`), which
@@ -561,7 +565,7 @@ payload writes are reverted, and they are the ones below.
561
565
 
562
566
  | Knob | Default | Effect |
563
567
  | ---- | ------- | ------ |
564
- | `editor.i18nSourceLanguage` | `"de"` | The locale i18n-ally translates FROM (`i18n-ally.sourceLanguage`). Payload-enforced -- see below |
568
+ | `editor.i18nSourceLanguage` | `"de"` | The locale i18n-ally translates FROM (`i18n-ally.sourceLanguage`). Payload-enforced; see below |
565
569
 
566
570
  ```ts
567
571
  export default {
@@ -571,7 +575,7 @@ export default {
571
575
  ```
572
576
 
573
577
  **If your repo authors its source strings in English, set this.** The source language is
574
- payload-owned, so leaving it unset does not mean "keep what I have" -- every sync writes
578
+ payload-owned, so leaving it unset does not mean "keep what I have". Every sync writes
575
579
  `"de"` into the file, over the top of an `"en"` you put there by hand. Nothing warns, and
576
580
  `streamctl check` stays green afterwards, because the value it finds is the value the payload
577
581
  intends. Setting the knob is the only thing that makes `"en"` survive a sync.
@@ -623,9 +627,9 @@ plan-only PR labelled `needs-interactive-upgrade` for a human to finish with
623
627
 
624
628
  ### Action pinning policy
625
629
 
626
- Every action in every managed workflow and CI job fragment is pinned by full commit
627
- SHA (with the version tag in a trailing comment), since moving tags can be re-pointed, so
628
- tags are never trusted, secrets or not. `test/workflow-pins.test.ts` sweeps all preset
630
+ Every action in every managed workflow and CI job fragment is pinned by full commit SHA,
631
+ with the version tag in a trailing comment. Moving tags can be re-pointed, so tags are
632
+ never trusted, secrets or not. `test/workflow-pins.test.ts` sweeps all preset
629
633
  templates and fails on any `uses:` that is not a 40-hex SHA.
630
634
 
631
635
  The shipped pins track `actions/checkout` v6, `actions/setup-node` v6, and
package/dist/config.d.mts CHANGED
@@ -1,19 +1,16 @@
1
- import { C as CreateSidebaseEslintOptions } from './shared/base-config.CuUhyvQo.mjs';
1
+ import { C as CreateSidebaseEslintOptions } from './shared/base-config.BoberVUk.mjs';
2
2
 
3
3
  /**
4
- * Version-baseline profile, named for the framework AND its major so two majors can
5
- * coexist during a migration: the manifest declares one profile per major with its own
6
- * `detect.majorIs`, and each repo detects the one matching its own Nuxt version.
4
+ * Version-baseline profile, named for the framework and its major so two majors can
5
+ * coexist during a migration.
7
6
  *
8
- * The name MUST match a `versionProfiles` key in the preset chain. The CLI resolves the
9
- * baseline with `versionProfiles?.[profile] ?? {}`, so a name nothing declares reconciles
10
- * NOTHING, silently. `scripts/validate-presets.mjs` fails the build on that mismatch.
7
+ * An unknown name reconciles nothing, silently. `scripts/validate-presets.mjs` fails
8
+ * the build on that mismatch.
11
9
  */
12
10
  type Profile = "nuxt-4";
13
11
  /**
14
- * Optional CI knobs (`config.ci.*`) the nuxt-app preset understands: the job
15
- * toggles. Keys mirror the manifest's `ci.*` `configKeys`; the consistency test
16
- * in `test/config.test.ts` proves they stay in lockstep.
12
+ * CI job knobs (`config.ci.*`). Keys mirror the manifest's `ci.*` `configKeys`, and
13
+ * `test/config.test.ts` proves the two stay in lockstep.
17
14
  */
18
15
  interface NuxtBaseCiConfig {
19
16
  /** Include the `pnpm test` job. */
@@ -21,22 +18,19 @@ interface NuxtBaseCiConfig {
21
18
  /** Include the e2e job + postgres service. */
22
19
  e2e?: boolean;
23
20
  /**
24
- * System packages apt-installed in the `test` and `e2e` jobs before
25
- * `pnpm install`, for a binary the suite needs that `ubuntu-latest` does not
26
- * ship (the motivating case: `libxml2-utils` for `xmllint`). Empty by default,
27
- * which renders the install step inert rather than absent. Package names only:
28
- * each element is metacharacter-checked, then the joined string is re-validated
29
- * by the manifest pattern, because the rendered `run:` line is deliberately
30
- * unquoted so word splitting reaches apt-get.
21
+ * Packages apt-installed in the `test` and `e2e` jobs, for a binary the suite needs
22
+ * that `ubuntu-latest` lacks. Empty renders the install step inert, not absent.
23
+ *
24
+ * Package names only: the rendered `run:` line is unquoted so word splitting reaches
25
+ * apt-get, so every element is metacharacter-checked.
31
26
  */
32
27
  aptPackages?: string[];
33
28
  }
34
29
  /**
35
- * Optional runtime version pins (`config.versions.*`). `node` feeds every
36
- * render (`ci.yml`, the Dockerfile, the upgrade-PR workflow); `pnpm` feeds the
37
- * Dockerfile only. CI takes its pnpm from `package.json#packageManager`, the
38
- * single reconciled source, so it is never passed to `pnpm/action-setup`.
39
- * Defaults come from the version baseline (node 24.13.0, pnpm 10.28.1).
30
+ * Runtime version pins (`config.versions.*`). `node` feeds every render (`ci.yml`,
31
+ * the Dockerfile, the upgrade workflow); `pnpm` feeds the Dockerfile only, because CI
32
+ * takes pnpm from `package.json#packageManager`. Defaults come from the version
33
+ * baseline (node 24.13.0, pnpm 10.28.1).
40
34
  */
41
35
  interface NuxtBaseVersionsConfig {
42
36
  /** Node version for CI jobs, the Docker base image, and the upgrade workflow. */
@@ -52,16 +46,15 @@ interface NuxtBaseVersionsConfig {
52
46
  */
53
47
  interface NuxtBaseDockerConfig {
54
48
  /**
55
- * Project-owned apt packages for the production stage, ON TOP of the baked-in
56
- * baseline (`openssl`: the Prisma query engine generated in the build stage
57
- * dynamically links libssl3, which slim images do not ship).
49
+ * Apt packages for the production stage, on top of the baked-in `openssl`, which is
50
+ * always installed because the Prisma query engine links libssl3 and slim images do
51
+ * not ship it.
58
52
  */
59
53
  aptPackages?: string[];
60
54
  /**
61
- * Raw Dockerfile text injected in the build stage BEFORE `pnpm install`, e.g.
62
- * a `COPY ./vendor ./vendor` a repo needs present at install time. Lands
63
- * verbatim; see the trust note below. Global installs must use `npm i -g`
64
- * (`PNPM_HOME` is not set, so `pnpm add -g` fails to find its bin dir).
55
+ * Raw Dockerfile text injected in the build stage before `pnpm install`, e.g. a
56
+ * `COPY ./vendor ./vendor` needed at install time. Lands verbatim. Global installs
57
+ * must use `npm i -g`: `PNPM_HOME` is unset, so `pnpm add -g` cannot find its bin dir.
65
58
  */
66
59
  preInstall?: string;
67
60
  /**
@@ -77,15 +70,14 @@ interface NuxtBaseDockerConfig {
77
70
  buildSteps?: string;
78
71
  /**
79
72
  * Raw Dockerfile text injected in the final stage BEFORE `CMD`, e.g. extra
80
- * `ENV`, `COPY --from`, or `RUN`. Lands verbatim. Cannot drop the fixed
81
- * `USER node` switch, which sits below it.
73
+ * `ENV`, `COPY --from`, or `RUN`. Lands verbatim. The container runs as root,
74
+ * so a repo that wants an unprivileged runtime appends its own `USER` here.
82
75
  */
83
76
  finalStage?: string;
84
77
  /**
85
78
  * The final-stage Prisma runtime block (copy the schema, install the CLI for
86
79
  * `migrate deploy`). Defaults to that block; set `""` for a repo with no
87
- * Prisma. The `USER node` switch and the `.output` ownership are FIXED outside
88
- * this knob, so an override cannot re-root the container. Lands verbatim.
80
+ * Prisma. The `.output` ownership is FIXED outside this knob. Lands verbatim.
89
81
  */
90
82
  prismaRuntime?: string;
91
83
  /**
@@ -101,25 +93,22 @@ interface NuxtBaseDockerConfig {
101
93
  startCommand?: string;
102
94
  }
103
95
  /**
104
- * Optional automation knobs (`config.automation.*`) the base preset understands:
105
- * the opt-in upgrade-PR workflow and its runtime version pins. Keys mirror the
106
- * manifest's `automation.*` `configKeys`; the consistency test in
107
- * `test/config.test.ts` proves they stay in lockstep.
96
+ * Automation knobs (`config.automation.*`) for the opt-in upgrade-PR workflow. Keys
97
+ * mirror the manifest's `automation.*` `configKeys`, checked by `test/config.test.ts`.
108
98
  */
109
99
  interface NuxtBaseAutomationConfig {
110
100
  /** Sync the weekly streamctl upgrade-PR workflow (default: off, no workflow lands). */
111
101
  upgradePr?: boolean;
112
102
  }
113
103
  /**
114
- * Optional supply-chain knobs (`config.security.*`) the base preset understands:
115
- * the pnpm install cooldown rendered into the managed `pnpm-workspace.yaml`.
104
+ * Supply-chain knobs (`config.security.*`): the pnpm install cooldown rendered into
105
+ * the managed `pnpm-workspace.yaml`.
116
106
  */
117
107
  interface NuxtBaseSecurityConfig {
118
108
  /**
119
- * Minutes a version must have been published before pnpm resolves it
120
- * (`minimumReleaseAge`). Default `"10080"` (7 days); `"0"` disables the cooldown.
121
- * A STRING because the manifest's `configKeys` has no number type, same as the
122
- * `versions.*` pins.
109
+ * Minutes a version must have been published before pnpm resolves it. Default
110
+ * `"10080"` (7 days), `"0"` disables it. A string because the manifest's
111
+ * `configKeys` has no number type, same as the `versions.*` pins.
123
112
  */
124
113
  minimumReleaseAge?: string;
125
114
  }
@@ -129,33 +118,29 @@ interface NuxtBaseSecurityConfig {
129
118
  */
130
119
  interface NuxtBasePnpmConfig {
131
120
  /**
132
- * Packages allowed to run install lifecycle scripts, ON TOP of the baked-in
133
- * baseline (`@prisma/client`, `esbuild`, `prisma`). Use this instead of
134
- * `pnpm approve-builds`, which writes to the managed file and is reverted on
135
- * the next sync.
121
+ * Packages allowed to run install lifecycle scripts, on top of the baseline
122
+ * (`@prisma/client`, `esbuild`, `prisma`). Use this instead of `pnpm approve-builds`,
123
+ * which writes to the managed file and is reverted on the next sync.
136
124
  */
137
125
  onlyBuiltDependencies?: string[];
138
126
  }
139
127
  /**
140
- * Optional editor knobs (`config.editor.*`) rendered into the managed
141
- * `.vscode/settings.json`. Only the i18n-ally source language varies across the
142
- * fleet; the locales path and key style are payload-enforced.
128
+ * Editor knobs (`config.editor.*`) rendered into the managed `.vscode/settings.json`.
129
+ * Only the i18n-ally source language varies across the fleet.
143
130
  */
144
131
  interface NuxtBaseEditorConfig {
145
132
  /**
146
- * Source locale i18n-ally translates FROM (`i18n-ally.sourceLanguage`).
147
- * Default `"de"`, the fleet majority; repos authoring in English set `"en"`.
148
- * A BCP-47-ish tag (`de`, `pt-BR`, `zh-Hans-CN`); the manifest's `pattern`
149
- * rejects anything that could break the rendered JSON string.
133
+ * Source locale i18n-ally translates from. Default `"de"`; repos authoring in
134
+ * English set `"en"`. A BCP-47-ish tag (`de`, `pt-BR`, `zh-Hans-CN`); the manifest
135
+ * pattern rejects anything that could break the rendered JSON string.
150
136
  */
151
137
  i18nSourceLanguage?: string;
152
138
  }
153
139
  /**
154
- * The typed `streamctl.config.ts` shape for the `@sidebase/base-config` payload:
155
- * the CLI-universal fields plus this payload's declared knobs (`ci`, `versions`,
156
- * `docker`, `automation`, `eslint`) with their real option types. The generic CLI only
157
- * shape-checks these against the manifest's `configKeys`, so the precise types live
158
- * here, next to the payload that owns them, and consumers keep a fully typed config.
140
+ * The typed `streamctl.config.ts` shape for this payload: the CLI-universal fields plus
141
+ * the declared knobs with their real option types. The CLI only shape-checks knobs
142
+ * against the manifest's `configKeys`, so the precise types live here, next to the
143
+ * payload that owns them, and consumers keep a fully typed config.
159
144
  */
160
145
  interface NuxtBaseConfig {
161
146
  /** The payload package this repo syncs from. */
@@ -190,9 +175,8 @@ interface NuxtBaseConfig {
190
175
  eslint?: CreateSidebaseEslintOptions;
191
176
  }
192
177
  /**
193
- * Identity helper for a typed `streamctl.config.ts`, the payload analog of the
194
- * CLI's `defineStreamctlConfig`, adding editor inference for this payload's knobs.
195
- * Returns the config unchanged; the CLI validates it at load.
178
+ * Identity helper giving editor inference for this payload's knobs, the analog of the
179
+ * CLI's `defineStreamctlConfig`. Returns the config unchanged; the CLI validates it.
196
180
  */
197
181
  declare function defineNuxtBaseConfig(config: NuxtBaseConfig): NuxtBaseConfig;
198
182
  /** Runtime list of every {@link NuxtBaseCiConfig} key. */
@@ -210,11 +194,9 @@ declare const NUXT_BASE_PNPM_KEYS: string[];
210
194
  /** Runtime list of every {@link NuxtBaseEditorConfig} key. */
211
195
  declare const NUXT_BASE_EDITOR_KEYS: string[];
212
196
  /**
213
- * Every payload KNOB dot-path {@link NuxtBaseConfig} declares (the `ci.*` and
214
- * `automation.*` leaves plus the top-level knobs); excludes the CLI-universal
215
- * fields. The consistency test asserts this set equals the RESOLVED preset chain's
216
- * declared `configKeys` (base + nuxt-app), catching drift between the type and the
217
- * manifest in either direction.
197
+ * Every knob dot-path {@link NuxtBaseConfig} declares, excluding the CLI-universal
198
+ * fields. The consistency test asserts this set equals the resolved preset chain's
199
+ * `configKeys`, catching drift between the type and the manifest in either direction.
218
200
  */
219
201
  declare const NUXT_BASE_CONFIG_KEYS: string[];
220
202
 
package/dist/config.d.ts CHANGED
@@ -1,19 +1,16 @@
1
- import { C as CreateSidebaseEslintOptions } from './shared/base-config.CuUhyvQo.js';
1
+ import { C as CreateSidebaseEslintOptions } from './shared/base-config.BoberVUk.js';
2
2
 
3
3
  /**
4
- * Version-baseline profile, named for the framework AND its major so two majors can
5
- * coexist during a migration: the manifest declares one profile per major with its own
6
- * `detect.majorIs`, and each repo detects the one matching its own Nuxt version.
4
+ * Version-baseline profile, named for the framework and its major so two majors can
5
+ * coexist during a migration.
7
6
  *
8
- * The name MUST match a `versionProfiles` key in the preset chain. The CLI resolves the
9
- * baseline with `versionProfiles?.[profile] ?? {}`, so a name nothing declares reconciles
10
- * NOTHING, silently. `scripts/validate-presets.mjs` fails the build on that mismatch.
7
+ * An unknown name reconciles nothing, silently. `scripts/validate-presets.mjs` fails
8
+ * the build on that mismatch.
11
9
  */
12
10
  type Profile = "nuxt-4";
13
11
  /**
14
- * Optional CI knobs (`config.ci.*`) the nuxt-app preset understands: the job
15
- * toggles. Keys mirror the manifest's `ci.*` `configKeys`; the consistency test
16
- * in `test/config.test.ts` proves they stay in lockstep.
12
+ * CI job knobs (`config.ci.*`). Keys mirror the manifest's `ci.*` `configKeys`, and
13
+ * `test/config.test.ts` proves the two stay in lockstep.
17
14
  */
18
15
  interface NuxtBaseCiConfig {
19
16
  /** Include the `pnpm test` job. */
@@ -21,22 +18,19 @@ interface NuxtBaseCiConfig {
21
18
  /** Include the e2e job + postgres service. */
22
19
  e2e?: boolean;
23
20
  /**
24
- * System packages apt-installed in the `test` and `e2e` jobs before
25
- * `pnpm install`, for a binary the suite needs that `ubuntu-latest` does not
26
- * ship (the motivating case: `libxml2-utils` for `xmllint`). Empty by default,
27
- * which renders the install step inert rather than absent. Package names only:
28
- * each element is metacharacter-checked, then the joined string is re-validated
29
- * by the manifest pattern, because the rendered `run:` line is deliberately
30
- * unquoted so word splitting reaches apt-get.
21
+ * Packages apt-installed in the `test` and `e2e` jobs, for a binary the suite needs
22
+ * that `ubuntu-latest` lacks. Empty renders the install step inert, not absent.
23
+ *
24
+ * Package names only: the rendered `run:` line is unquoted so word splitting reaches
25
+ * apt-get, so every element is metacharacter-checked.
31
26
  */
32
27
  aptPackages?: string[];
33
28
  }
34
29
  /**
35
- * Optional runtime version pins (`config.versions.*`). `node` feeds every
36
- * render (`ci.yml`, the Dockerfile, the upgrade-PR workflow); `pnpm` feeds the
37
- * Dockerfile only. CI takes its pnpm from `package.json#packageManager`, the
38
- * single reconciled source, so it is never passed to `pnpm/action-setup`.
39
- * Defaults come from the version baseline (node 24.13.0, pnpm 10.28.1).
30
+ * Runtime version pins (`config.versions.*`). `node` feeds every render (`ci.yml`,
31
+ * the Dockerfile, the upgrade workflow); `pnpm` feeds the Dockerfile only, because CI
32
+ * takes pnpm from `package.json#packageManager`. Defaults come from the version
33
+ * baseline (node 24.13.0, pnpm 10.28.1).
40
34
  */
41
35
  interface NuxtBaseVersionsConfig {
42
36
  /** Node version for CI jobs, the Docker base image, and the upgrade workflow. */
@@ -52,16 +46,15 @@ interface NuxtBaseVersionsConfig {
52
46
  */
53
47
  interface NuxtBaseDockerConfig {
54
48
  /**
55
- * Project-owned apt packages for the production stage, ON TOP of the baked-in
56
- * baseline (`openssl`: the Prisma query engine generated in the build stage
57
- * dynamically links libssl3, which slim images do not ship).
49
+ * Apt packages for the production stage, on top of the baked-in `openssl`, which is
50
+ * always installed because the Prisma query engine links libssl3 and slim images do
51
+ * not ship it.
58
52
  */
59
53
  aptPackages?: string[];
60
54
  /**
61
- * Raw Dockerfile text injected in the build stage BEFORE `pnpm install`, e.g.
62
- * a `COPY ./vendor ./vendor` a repo needs present at install time. Lands
63
- * verbatim; see the trust note below. Global installs must use `npm i -g`
64
- * (`PNPM_HOME` is not set, so `pnpm add -g` fails to find its bin dir).
55
+ * Raw Dockerfile text injected in the build stage before `pnpm install`, e.g. a
56
+ * `COPY ./vendor ./vendor` needed at install time. Lands verbatim. Global installs
57
+ * must use `npm i -g`: `PNPM_HOME` is unset, so `pnpm add -g` cannot find its bin dir.
65
58
  */
66
59
  preInstall?: string;
67
60
  /**
@@ -77,15 +70,14 @@ interface NuxtBaseDockerConfig {
77
70
  buildSteps?: string;
78
71
  /**
79
72
  * Raw Dockerfile text injected in the final stage BEFORE `CMD`, e.g. extra
80
- * `ENV`, `COPY --from`, or `RUN`. Lands verbatim. Cannot drop the fixed
81
- * `USER node` switch, which sits below it.
73
+ * `ENV`, `COPY --from`, or `RUN`. Lands verbatim. The container runs as root,
74
+ * so a repo that wants an unprivileged runtime appends its own `USER` here.
82
75
  */
83
76
  finalStage?: string;
84
77
  /**
85
78
  * The final-stage Prisma runtime block (copy the schema, install the CLI for
86
79
  * `migrate deploy`). Defaults to that block; set `""` for a repo with no
87
- * Prisma. The `USER node` switch and the `.output` ownership are FIXED outside
88
- * this knob, so an override cannot re-root the container. Lands verbatim.
80
+ * Prisma. The `.output` ownership is FIXED outside this knob. Lands verbatim.
89
81
  */
90
82
  prismaRuntime?: string;
91
83
  /**
@@ -101,25 +93,22 @@ interface NuxtBaseDockerConfig {
101
93
  startCommand?: string;
102
94
  }
103
95
  /**
104
- * Optional automation knobs (`config.automation.*`) the base preset understands:
105
- * the opt-in upgrade-PR workflow and its runtime version pins. Keys mirror the
106
- * manifest's `automation.*` `configKeys`; the consistency test in
107
- * `test/config.test.ts` proves they stay in lockstep.
96
+ * Automation knobs (`config.automation.*`) for the opt-in upgrade-PR workflow. Keys
97
+ * mirror the manifest's `automation.*` `configKeys`, checked by `test/config.test.ts`.
108
98
  */
109
99
  interface NuxtBaseAutomationConfig {
110
100
  /** Sync the weekly streamctl upgrade-PR workflow (default: off, no workflow lands). */
111
101
  upgradePr?: boolean;
112
102
  }
113
103
  /**
114
- * Optional supply-chain knobs (`config.security.*`) the base preset understands:
115
- * the pnpm install cooldown rendered into the managed `pnpm-workspace.yaml`.
104
+ * Supply-chain knobs (`config.security.*`): the pnpm install cooldown rendered into
105
+ * the managed `pnpm-workspace.yaml`.
116
106
  */
117
107
  interface NuxtBaseSecurityConfig {
118
108
  /**
119
- * Minutes a version must have been published before pnpm resolves it
120
- * (`minimumReleaseAge`). Default `"10080"` (7 days); `"0"` disables the cooldown.
121
- * A STRING because the manifest's `configKeys` has no number type, same as the
122
- * `versions.*` pins.
109
+ * Minutes a version must have been published before pnpm resolves it. Default
110
+ * `"10080"` (7 days), `"0"` disables it. A string because the manifest's
111
+ * `configKeys` has no number type, same as the `versions.*` pins.
123
112
  */
124
113
  minimumReleaseAge?: string;
125
114
  }
@@ -129,33 +118,29 @@ interface NuxtBaseSecurityConfig {
129
118
  */
130
119
  interface NuxtBasePnpmConfig {
131
120
  /**
132
- * Packages allowed to run install lifecycle scripts, ON TOP of the baked-in
133
- * baseline (`@prisma/client`, `esbuild`, `prisma`). Use this instead of
134
- * `pnpm approve-builds`, which writes to the managed file and is reverted on
135
- * the next sync.
121
+ * Packages allowed to run install lifecycle scripts, on top of the baseline
122
+ * (`@prisma/client`, `esbuild`, `prisma`). Use this instead of `pnpm approve-builds`,
123
+ * which writes to the managed file and is reverted on the next sync.
136
124
  */
137
125
  onlyBuiltDependencies?: string[];
138
126
  }
139
127
  /**
140
- * Optional editor knobs (`config.editor.*`) rendered into the managed
141
- * `.vscode/settings.json`. Only the i18n-ally source language varies across the
142
- * fleet; the locales path and key style are payload-enforced.
128
+ * Editor knobs (`config.editor.*`) rendered into the managed `.vscode/settings.json`.
129
+ * Only the i18n-ally source language varies across the fleet.
143
130
  */
144
131
  interface NuxtBaseEditorConfig {
145
132
  /**
146
- * Source locale i18n-ally translates FROM (`i18n-ally.sourceLanguage`).
147
- * Default `"de"`, the fleet majority; repos authoring in English set `"en"`.
148
- * A BCP-47-ish tag (`de`, `pt-BR`, `zh-Hans-CN`); the manifest's `pattern`
149
- * rejects anything that could break the rendered JSON string.
133
+ * Source locale i18n-ally translates from. Default `"de"`; repos authoring in
134
+ * English set `"en"`. A BCP-47-ish tag (`de`, `pt-BR`, `zh-Hans-CN`); the manifest
135
+ * pattern rejects anything that could break the rendered JSON string.
150
136
  */
151
137
  i18nSourceLanguage?: string;
152
138
  }
153
139
  /**
154
- * The typed `streamctl.config.ts` shape for the `@sidebase/base-config` payload:
155
- * the CLI-universal fields plus this payload's declared knobs (`ci`, `versions`,
156
- * `docker`, `automation`, `eslint`) with their real option types. The generic CLI only
157
- * shape-checks these against the manifest's `configKeys`, so the precise types live
158
- * here, next to the payload that owns them, and consumers keep a fully typed config.
140
+ * The typed `streamctl.config.ts` shape for this payload: the CLI-universal fields plus
141
+ * the declared knobs with their real option types. The CLI only shape-checks knobs
142
+ * against the manifest's `configKeys`, so the precise types live here, next to the
143
+ * payload that owns them, and consumers keep a fully typed config.
159
144
  */
160
145
  interface NuxtBaseConfig {
161
146
  /** The payload package this repo syncs from. */
@@ -190,9 +175,8 @@ interface NuxtBaseConfig {
190
175
  eslint?: CreateSidebaseEslintOptions;
191
176
  }
192
177
  /**
193
- * Identity helper for a typed `streamctl.config.ts`, the payload analog of the
194
- * CLI's `defineStreamctlConfig`, adding editor inference for this payload's knobs.
195
- * Returns the config unchanged; the CLI validates it at load.
178
+ * Identity helper giving editor inference for this payload's knobs, the analog of the
179
+ * CLI's `defineStreamctlConfig`. Returns the config unchanged; the CLI validates it.
196
180
  */
197
181
  declare function defineNuxtBaseConfig(config: NuxtBaseConfig): NuxtBaseConfig;
198
182
  /** Runtime list of every {@link NuxtBaseCiConfig} key. */
@@ -210,11 +194,9 @@ declare const NUXT_BASE_PNPM_KEYS: string[];
210
194
  /** Runtime list of every {@link NuxtBaseEditorConfig} key. */
211
195
  declare const NUXT_BASE_EDITOR_KEYS: string[];
212
196
  /**
213
- * Every payload KNOB dot-path {@link NuxtBaseConfig} declares (the `ci.*` and
214
- * `automation.*` leaves plus the top-level knobs); excludes the CLI-universal
215
- * fields. The consistency test asserts this set equals the RESOLVED preset chain's
216
- * declared `configKeys` (base + nuxt-app), catching drift between the type and the
217
- * manifest in either direction.
197
+ * Every knob dot-path {@link NuxtBaseConfig} declares, excluding the CLI-universal
198
+ * fields. The consistency test asserts this set equals the resolved preset chain's
199
+ * `configKeys`, catching drift between the type and the manifest in either direction.
218
200
  */
219
201
  declare const NUXT_BASE_CONFIG_KEYS: string[];
220
202
 
@@ -1,5 +1,5 @@
1
- import { C as CreateSidebaseEslintOptions } from '../shared/base-config.CuUhyvQo.mjs';
2
- export { E as ESLINT_OPTION_KEYS } from '../shared/base-config.CuUhyvQo.mjs';
1
+ import { C as CreateSidebaseEslintOptions } from '../shared/base-config.BoberVUk.mjs';
2
+ export { E as ESLINT_OPTION_KEYS } from '../shared/base-config.BoberVUk.mjs';
3
3
  import antfu, { TypedFlatConfigItem } from '@antfu/eslint-config';
4
4
 
5
5
  /** {@link CreateSidebaseEslintOptions} with all defaults applied + the computed type-aware gate. */
@@ -20,10 +20,7 @@ interface ResolvedEslintOptions {
20
20
  testFilePattern: string[];
21
21
  typeAware: boolean;
22
22
  }
23
- /**
24
- * Whether type-aware linting is on: gated behind `LINT_TYPEAWARE=true` so the
25
- * slower type-aware pass stays opt-in (CI/local override).
26
- */
23
+ /** Type-aware linting is gated behind `LINT_TYPEAWARE=true` because it is slow. */
27
24
  declare function isTypeAware(): boolean;
28
25
  /** Apply the documented option defaults and resolve the type-aware gate. */
29
26
  declare function resolveEslintOptions(options?: CreateSidebaseEslintOptions): ResolvedEslintOptions;
@@ -1,5 +1,5 @@
1
- import { C as CreateSidebaseEslintOptions } from '../shared/base-config.CuUhyvQo.js';
2
- export { E as ESLINT_OPTION_KEYS } from '../shared/base-config.CuUhyvQo.js';
1
+ import { C as CreateSidebaseEslintOptions } from '../shared/base-config.BoberVUk.js';
2
+ export { E as ESLINT_OPTION_KEYS } from '../shared/base-config.BoberVUk.js';
3
3
  import antfu, { TypedFlatConfigItem } from '@antfu/eslint-config';
4
4
 
5
5
  /** {@link CreateSidebaseEslintOptions} with all defaults applied + the computed type-aware gate. */
@@ -20,10 +20,7 @@ interface ResolvedEslintOptions {
20
20
  testFilePattern: string[];
21
21
  typeAware: boolean;
22
22
  }
23
- /**
24
- * Whether type-aware linting is on: gated behind `LINT_TYPEAWARE=true` so the
25
- * slower type-aware pass stays opt-in (CI/local override).
26
- */
23
+ /** Type-aware linting is gated behind `LINT_TYPEAWARE=true` because it is slow. */
27
24
  declare function isTypeAware(): boolean;
28
25
  /** Apply the documented option defaults and resolve the type-aware gate. */
29
26
  declare function resolveEslintOptions(options?: CreateSidebaseEslintOptions): ResolvedEslintOptions;