@sidebase/base-config 0.1.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
 
@@ -134,9 +134,10 @@ The payload is validated and dogfooded against the CLI, so `@sidebase/streamctl`
134
134
  `validate:presets` imports the CLI's exported manifest schema and the e2e dry-run drives the
135
135
  real CLI binary, so both resolve `@sidebase/streamctl` from the registry.
136
136
 
137
- The root `streamctl.config.ts` this payload documents needs **streamctl >= 0.2.0**, so the
138
- pin and the `pnpm-workspace.yaml` c12 override both move when that release lands. See
139
- "Config location" below.
137
+ This payload needs **streamctl >= 0.3.0**: its manifest declares `schemaVersion` 3 (the
138
+ `fromDependency` placeholder behind the derived Prisma ARG), which a 0.2.x CLI rejects with
139
+ `SCHEMA_UNSUPPORTED`. The root `streamctl.config.ts` location it documents arrived in
140
+ 0.2.0. See "Config location" below.
140
141
 
141
142
  ## Typed config
142
143
 
@@ -174,7 +175,7 @@ covers both.
174
175
 
175
176
  `defineNuxtBaseConfig` returns the config unchanged. Its job is typed editor inference
176
177
  for this payload's knobs: completion and type checking on `ci`, `versions`, `docker`,
177
- `automation`, `security`, `pnpm`, and the whole `eslint` option surface, plus `profile`
178
+ `automation`, `security`, `pnpm`, `editor`, and the whole `eslint` option surface, plus `profile`
178
179
  narrowed to the profile names that actually exist. Without it the object is an untyped
179
180
  literal, so a typo such as `ci: { unitTest: true }` stays silent in your editor.
180
181
 
@@ -274,7 +275,7 @@ The custom bans map to these ESLint rule IDs. Use the exact ID in an
274
275
  "Re-export" is not a figure of speech: a barrel file doing `export * from "node:process"`
275
276
  reports, as do `export { env } from "node:process"` and `export { default as p } from
276
277
  "node:process"`. The one shape that does **not** report is a bare side-effect import with
277
- 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.
278
279
 
279
280
  The `process.env` ban is enforced by **two** rules, and which one reports depends on the
280
281
  shape, so suppressing the wrong one fails twice over: the directive does not suppress
@@ -302,14 +303,15 @@ entirely, as does running on Deno or Bun, which import TypeScript directly.
302
303
  #### Type-aware linting prerequisite
303
304
 
304
305
  Type-aware linting is gated behind `LINT_TYPEAWARE=true` (off by default), so this only
305
- matters on the opt-in / CI path. When type-aware lint is on, the Prisma client and Nuxt types must be
306
- generated **before** `lint` runs, otherwise type-aware rules fail on missing generated types. This is
307
- 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:
308
309
 
309
310
  - the managed `ci.yml` runs `prisma generate` (and `nuxi prepare`) before `pnpm lint`, and
310
311
  - `scripts.postinstall: "nuxt prepare"` regenerates Nuxt types on install.
311
312
 
312
- 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.
313
315
 
314
316
  ## Prisma factory
315
317
 
@@ -441,13 +443,47 @@ existing `onlyBuiltDependencies` allowlist and `ignoredBuiltDependencies` are bo
441
443
  by the baked-in baseline, and **nothing warns about it**. Most affected packages ship a
442
444
  prebuilt native binary and keep working either way, so the practical breakage is limited to
443
445
  architectures with no prebuild and to postinstalls doing essential non-native work. Capture
444
- the old list before you adopt and re-add it via `pnpm.onlyBuiltDependencies` above. A repo that genuinely needs its own `packages:` list
445
- (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:
446
449
 
447
450
  ```ts
448
451
  files: { "pnpm-workspace.yaml": "off" },
449
452
  ```
450
453
 
454
+ ## CI knobs
455
+
456
+ The `nuxt-app` preset ships a managed `.github/workflows/ci.yml`. Its `lint-typecheck` and
457
+ `build` jobs always run; the rest is knobs:
458
+
459
+ | Knob | Default | Effect |
460
+ | ---- | ------- | ------ |
461
+ | `ci.unitTests` | `false` | Add the `test` job (`pnpm test`) |
462
+ | `ci.e2e` | `false` | Add the `e2e` job, with a health-checked postgres service |
463
+ | `ci.aptPackages` | `[]` | System packages `apt-get`-installed in the `test` and `e2e` jobs |
464
+
465
+ `ci.aptPackages` is the CI counterpart to `docker.aptPackages` below: extra system packages
466
+ on top of what the runner image already carries, for a binary the suite needs and
467
+ `ubuntu-latest` does not ship. The motivating case is `libxml2-utils`, for `xmllint`.
468
+
469
+ It applies to the `test` and `e2e` jobs only, never `lint-typecheck` or `build`. The step
470
+ installs directly after `checkout`, before `pnpm install`, so a package needed by an install
471
+ lifecycle script is covered as well as one needed by the tests. Leave it unset and the step
472
+ is skipped entirely: it renders with a guard on the value being non-empty, so the default
473
+ costs a no-op step rather than an `apt-get` call.
474
+
475
+ ```ts
476
+ export default {
477
+ // ...
478
+ ci: { unitTests: true, e2e: true, aptPackages: ["libxml2-utils"] },
479
+ };
480
+ ```
481
+
482
+ Package names only. Every element is rejected if it contains a shell metacharacter, and the
483
+ joined string is then re-validated against the Debian package-name character set (lowercase,
484
+ digits, `+`, `-`, `.`). Both checks exist because the rendered command deliberately leaves
485
+ the value unquoted, which is how several packages word-split into one `apt-get` call.
486
+
451
487
  ## Dockerfile knobs
452
488
 
453
489
  The `nuxt-app` preset ships a managed `Dockerfile`. Beyond `docker.aptPackages`
@@ -464,6 +500,16 @@ out:
464
500
  | `docker.prismaRuntime` | final stage | copy the schema + install the `migrate deploy` CLI |
465
501
  | `docker.startCommand` | inside `CMD` | `prisma migrate deploy` then the node server |
466
502
 
503
+ A seventh knob is different in kind: a validated version, not raw text.
504
+
505
+ | Knob | Position | Default |
506
+ | ---- | -------- | ------- |
507
+ | `docker.prismaVersion` | the `ARG PRISMA_VERSION=` default inside `docker.prismaRuntime` | derived from the repo's `prisma` pin (its range floor); the baseline only when no full `x.y.z` pin exists |
508
+
509
+ It is pattern-checked (`x.y.z`, optional prerelease), so unlike the six raw-text
510
+ knobs it cannot inject arbitrary Dockerfile content. `--build-arg PRISMA_VERSION=`
511
+ still overrides at build time.
512
+
467
513
  ```ts
468
514
  export default {
469
515
  // ...
@@ -481,8 +527,10 @@ export default {
481
527
  > shell-metacharacter check runs on them. The trust level is exactly that of
482
528
  > `files: { "Dockerfile": "off" }`, which any consumer can already set: whoever
483
529
  > can edit `streamctl.config.ts` can already replace the whole file. The
484
- > `USER node` switch and the `.output` ownership stay FIXED outside every knob,
485
- > 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"`.
486
534
 
487
535
  Setting a knob replaces its default outright, it does not append. So a `docker.buildSteps`
488
536
  override must restate every build command you still want, and `docker.prismaRuntime: ""`
@@ -490,8 +538,8 @@ removes the Prisma runtime block entirely. The three knobs that default to real
490
538
  (`buildSteps`, `prismaRuntime`, `startCommand`) are the ones where this matters; the other
491
539
  three default to `""`.
492
540
 
493
- **`prismaRuntime` and `startCommand` are coupled -- override one and you must override the
494
- 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
495
543
  DEFAULT `startCommand` is `npm exec prisma migrate deploy && node ...`. Setting only
496
544
  `prismaRuntime: ""` therefore produces an image whose `CMD` invokes a CLI that is no longer
497
545
  installed, and the container fails to start. The example above overrides both, which is why
@@ -502,6 +550,42 @@ Global installs in `docker.preInstall` must use `npm i -g <tool>`, not
502
550
  `pnpm add -g`: the image sets no `PNPM_HOME`, so pnpm's global bin dir is
503
551
  undefined.
504
552
 
553
+ ## Editor settings (`.vscode/settings.json`)
554
+
555
+ The base preset owns its own keys in `.vscode/settings.json` and leaves the rest of the file
556
+ to the project. Among them is i18n-ally, configured for the fleet's standard setup:
557
+ `@nuxtjs/i18n` with flat dotted keys under `i18n/locales`.
558
+
559
+ Everything the payload does not write is yours and survives a sync untouched: your
560
+ `editor.fontSize`, your `files.exclude`, any unrelated key at all. Six of those are named in
561
+ the manifest as project-owned on top of that (`editor.fontSize`, `editor.rulers`,
562
+ `editor.formatOnSave`, `files.exclude`, `search.exclude`, `files.watcherExclude`), which
563
+ keeps them yours even if a later payload version starts setting them. Only the keys the
564
+ payload writes are reverted, and they are the ones below.
565
+
566
+ | Knob | Default | Effect |
567
+ | ---- | ------- | ------ |
568
+ | `editor.i18nSourceLanguage` | `"de"` | The locale i18n-ally translates FROM (`i18n-ally.sourceLanguage`). Payload-enforced; see below |
569
+
570
+ ```ts
571
+ export default {
572
+ // ...
573
+ editor: { i18nSourceLanguage: "en" },
574
+ };
575
+ ```
576
+
577
+ **If your repo authors its source strings in English, set this.** The source language is
578
+ payload-owned, so leaving it unset does not mean "keep what I have". Every sync writes
579
+ `"de"` into the file, over the top of an `"en"` you put there by hand. Nothing warns, and
580
+ `streamctl check` stays green afterwards, because the value it finds is the value the payload
581
+ intends. Setting the knob is the only thing that makes `"en"` survive a sync.
582
+
583
+ `i18n-ally.localesPaths` and `i18n-ally.keystyle` are deliberately NOT configurable: the
584
+ locales path and the flat key style are fleet-wide conventions, so they are enforced rather
585
+ than offered. Editing either one in your own `.vscode/settings.json` is reverted on the next
586
+ sync. A repo that genuinely needs a different layout should opt the file out
587
+ (`files: { ".vscode/settings.json": "off" }`) rather than fight the merge.
588
+
505
589
  ## Upgrade-PR workflow
506
590
 
507
591
  The base preset ships `.github/workflows/streamctl-upgrade.yml`, a scheduled workflow
@@ -543,9 +627,9 @@ plan-only PR labelled `needs-interactive-upgrade` for a human to finish with
543
627
 
544
628
  ### Action pinning policy
545
629
 
546
- Every action in every managed workflow and CI job fragment is pinned by full commit
547
- SHA (with the version tag in a trailing comment), since moving tags can be re-pointed, so
548
- 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
549
633
  templates and fails on any `uses:` that is not a 40-hex SHA.
550
634
 
551
635
  The shipped pins track `actions/checkout` v6, `actions/setup-node` v6, and
package/dist/config.d.mts CHANGED
@@ -1,32 +1,36 @@
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. */
20
17
  unitTests?: boolean;
21
18
  /** Include the e2e job + postgres service. */
22
19
  e2e?: boolean;
20
+ /**
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.
26
+ */
27
+ aptPackages?: string[];
23
28
  }
24
29
  /**
25
- * Optional runtime version pins (`config.versions.*`). `node` feeds every
26
- * render (`ci.yml`, the Dockerfile, the upgrade-PR workflow); `pnpm` feeds the
27
- * Dockerfile only. CI takes its pnpm from `package.json#packageManager`, the
28
- * single reconciled source, so it is never passed to `pnpm/action-setup`.
29
- * 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).
30
34
  */
31
35
  interface NuxtBaseVersionsConfig {
32
36
  /** Node version for CI jobs, the Docker base image, and the upgrade workflow. */
@@ -42,16 +46,15 @@ interface NuxtBaseVersionsConfig {
42
46
  */
43
47
  interface NuxtBaseDockerConfig {
44
48
  /**
45
- * Project-owned apt packages for the production stage, ON TOP of the baked-in
46
- * baseline (`openssl`: the Prisma query engine generated in the build stage
47
- * 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.
48
52
  */
49
53
  aptPackages?: string[];
50
54
  /**
51
- * Raw Dockerfile text injected in the build stage BEFORE `pnpm install`, e.g.
52
- * a `COPY ./vendor ./vendor` a repo needs present at install time. Lands
53
- * verbatim; see the trust note below. Global installs must use `npm i -g`
54
- * (`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.
55
58
  */
56
59
  preInstall?: string;
57
60
  /**
@@ -67,17 +70,21 @@ interface NuxtBaseDockerConfig {
67
70
  buildSteps?: string;
68
71
  /**
69
72
  * Raw Dockerfile text injected in the final stage BEFORE `CMD`, e.g. extra
70
- * `ENV`, `COPY --from`, or `RUN`. Lands verbatim. Cannot drop the fixed
71
- * `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.
72
75
  */
73
76
  finalStage?: string;
74
77
  /**
75
78
  * The final-stage Prisma runtime block (copy the schema, install the CLI for
76
79
  * `migrate deploy`). Defaults to that block; set `""` for a repo with no
77
- * Prisma. The `USER node` switch and the `.output` ownership are FIXED outside
78
- * this knob, so an override cannot re-root the container. Lands verbatim.
80
+ * Prisma. The `.output` ownership is FIXED outside this knob. Lands verbatim.
79
81
  */
80
82
  prismaRuntime?: string;
83
+ /**
84
+ * Override for the runtime Prisma CLI `ARG PRISMA_VERSION` default. Derived
85
+ * from the repo's `prisma` pin when unset.
86
+ */
87
+ prismaVersion?: string;
81
88
  /**
82
89
  * The `sh -c` argument of the final `CMD`. Defaults to
83
90
  * `prisma migrate deploy` then the node server; override e.g. for `db push`
@@ -86,25 +93,22 @@ interface NuxtBaseDockerConfig {
86
93
  startCommand?: string;
87
94
  }
88
95
  /**
89
- * Optional automation knobs (`config.automation.*`) the base preset understands:
90
- * the opt-in upgrade-PR workflow and its runtime version pins. Keys mirror the
91
- * manifest's `automation.*` `configKeys`; the consistency test in
92
- * `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`.
93
98
  */
94
99
  interface NuxtBaseAutomationConfig {
95
100
  /** Sync the weekly streamctl upgrade-PR workflow (default: off, no workflow lands). */
96
101
  upgradePr?: boolean;
97
102
  }
98
103
  /**
99
- * Optional supply-chain knobs (`config.security.*`) the base preset understands:
100
- * 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`.
101
106
  */
102
107
  interface NuxtBaseSecurityConfig {
103
108
  /**
104
- * Minutes a version must have been published before pnpm resolves it
105
- * (`minimumReleaseAge`). Default `"10080"` (7 days); `"0"` disables the cooldown.
106
- * A STRING because the manifest's `configKeys` has no number type, same as the
107
- * `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.
108
112
  */
109
113
  minimumReleaseAge?: string;
110
114
  }
@@ -114,19 +118,29 @@ interface NuxtBaseSecurityConfig {
114
118
  */
115
119
  interface NuxtBasePnpmConfig {
116
120
  /**
117
- * Packages allowed to run install lifecycle scripts, ON TOP of the baked-in
118
- * baseline (`@prisma/client`, `esbuild`, `prisma`). Use this instead of
119
- * `pnpm approve-builds`, which writes to the managed file and is reverted on
120
- * 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.
121
124
  */
122
125
  onlyBuiltDependencies?: string[];
123
126
  }
124
127
  /**
125
- * The typed `streamctl.config.ts` shape for the `@sidebase/base-config` payload:
126
- * the CLI-universal fields plus this payload's declared knobs (`ci`, `versions`,
127
- * `docker`, `automation`, `eslint`) with their real option types. The generic CLI only
128
- * shape-checks these against the manifest's `configKeys`, so the precise types live
129
- * here, next to the payload that owns them, and consumers keep a fully typed config.
128
+ * Editor knobs (`config.editor.*`) rendered into the managed `.vscode/settings.json`.
129
+ * Only the i18n-ally source language varies across the fleet.
130
+ */
131
+ interface NuxtBaseEditorConfig {
132
+ /**
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.
136
+ */
137
+ i18nSourceLanguage?: string;
138
+ }
139
+ /**
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.
130
144
  */
131
145
  interface NuxtBaseConfig {
132
146
  /** The payload package this repo syncs from. */
@@ -155,13 +169,14 @@ interface NuxtBaseConfig {
155
169
  security?: NuxtBaseSecurityConfig;
156
170
  /** Optional pnpm knobs (extra build-script allowances). */
157
171
  pnpm?: NuxtBasePnpmConfig;
172
+ /** Optional editor knobs (the i18n-ally source language). */
173
+ editor?: NuxtBaseEditorConfig;
158
174
  /** ESLint factory options, typed with the payload's own option surface. */
159
175
  eslint?: CreateSidebaseEslintOptions;
160
176
  }
161
177
  /**
162
- * Identity helper for a typed `streamctl.config.ts`, the payload analog of the
163
- * CLI's `defineStreamctlConfig`, adding editor inference for this payload's knobs.
164
- * 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.
165
180
  */
166
181
  declare function defineNuxtBaseConfig(config: NuxtBaseConfig): NuxtBaseConfig;
167
182
  /** Runtime list of every {@link NuxtBaseCiConfig} key. */
@@ -176,14 +191,14 @@ declare const NUXT_BASE_AUTOMATION_KEYS: string[];
176
191
  declare const NUXT_BASE_SECURITY_KEYS: string[];
177
192
  /** Runtime list of every {@link NuxtBasePnpmConfig} key. */
178
193
  declare const NUXT_BASE_PNPM_KEYS: string[];
194
+ /** Runtime list of every {@link NuxtBaseEditorConfig} key. */
195
+ declare const NUXT_BASE_EDITOR_KEYS: string[];
179
196
  /**
180
- * Every payload KNOB dot-path {@link NuxtBaseConfig} declares (the `ci.*` and
181
- * `automation.*` leaves plus the top-level knobs); excludes the CLI-universal
182
- * fields. The consistency test asserts this set equals the RESOLVED preset chain's
183
- * declared `configKeys` (base + nuxt-app), catching drift between the type and the
184
- * 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.
185
200
  */
186
201
  declare const NUXT_BASE_CONFIG_KEYS: string[];
187
202
 
188
- export { NUXT_BASE_AUTOMATION_KEYS, NUXT_BASE_CI_KEYS, NUXT_BASE_CONFIG_KEYS, NUXT_BASE_DOCKER_KEYS, NUXT_BASE_PNPM_KEYS, NUXT_BASE_SECURITY_KEYS, NUXT_BASE_VERSIONS_KEYS, defineNuxtBaseConfig };
189
- export type { NuxtBaseAutomationConfig, NuxtBaseCiConfig, NuxtBaseConfig, NuxtBaseDockerConfig, NuxtBasePnpmConfig, NuxtBaseSecurityConfig, NuxtBaseVersionsConfig, Profile };
203
+ export { NUXT_BASE_AUTOMATION_KEYS, NUXT_BASE_CI_KEYS, NUXT_BASE_CONFIG_KEYS, NUXT_BASE_DOCKER_KEYS, NUXT_BASE_EDITOR_KEYS, NUXT_BASE_PNPM_KEYS, NUXT_BASE_SECURITY_KEYS, NUXT_BASE_VERSIONS_KEYS, defineNuxtBaseConfig };
204
+ export type { NuxtBaseAutomationConfig, NuxtBaseCiConfig, NuxtBaseConfig, NuxtBaseDockerConfig, NuxtBaseEditorConfig, NuxtBasePnpmConfig, NuxtBaseSecurityConfig, NuxtBaseVersionsConfig, Profile };
package/dist/config.d.ts CHANGED
@@ -1,32 +1,36 @@
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. */
20
17
  unitTests?: boolean;
21
18
  /** Include the e2e job + postgres service. */
22
19
  e2e?: boolean;
20
+ /**
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.
26
+ */
27
+ aptPackages?: string[];
23
28
  }
24
29
  /**
25
- * Optional runtime version pins (`config.versions.*`). `node` feeds every
26
- * render (`ci.yml`, the Dockerfile, the upgrade-PR workflow); `pnpm` feeds the
27
- * Dockerfile only. CI takes its pnpm from `package.json#packageManager`, the
28
- * single reconciled source, so it is never passed to `pnpm/action-setup`.
29
- * 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).
30
34
  */
31
35
  interface NuxtBaseVersionsConfig {
32
36
  /** Node version for CI jobs, the Docker base image, and the upgrade workflow. */
@@ -42,16 +46,15 @@ interface NuxtBaseVersionsConfig {
42
46
  */
43
47
  interface NuxtBaseDockerConfig {
44
48
  /**
45
- * Project-owned apt packages for the production stage, ON TOP of the baked-in
46
- * baseline (`openssl`: the Prisma query engine generated in the build stage
47
- * 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.
48
52
  */
49
53
  aptPackages?: string[];
50
54
  /**
51
- * Raw Dockerfile text injected in the build stage BEFORE `pnpm install`, e.g.
52
- * a `COPY ./vendor ./vendor` a repo needs present at install time. Lands
53
- * verbatim; see the trust note below. Global installs must use `npm i -g`
54
- * (`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.
55
58
  */
56
59
  preInstall?: string;
57
60
  /**
@@ -67,17 +70,21 @@ interface NuxtBaseDockerConfig {
67
70
  buildSteps?: string;
68
71
  /**
69
72
  * Raw Dockerfile text injected in the final stage BEFORE `CMD`, e.g. extra
70
- * `ENV`, `COPY --from`, or `RUN`. Lands verbatim. Cannot drop the fixed
71
- * `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.
72
75
  */
73
76
  finalStage?: string;
74
77
  /**
75
78
  * The final-stage Prisma runtime block (copy the schema, install the CLI for
76
79
  * `migrate deploy`). Defaults to that block; set `""` for a repo with no
77
- * Prisma. The `USER node` switch and the `.output` ownership are FIXED outside
78
- * this knob, so an override cannot re-root the container. Lands verbatim.
80
+ * Prisma. The `.output` ownership is FIXED outside this knob. Lands verbatim.
79
81
  */
80
82
  prismaRuntime?: string;
83
+ /**
84
+ * Override for the runtime Prisma CLI `ARG PRISMA_VERSION` default. Derived
85
+ * from the repo's `prisma` pin when unset.
86
+ */
87
+ prismaVersion?: string;
81
88
  /**
82
89
  * The `sh -c` argument of the final `CMD`. Defaults to
83
90
  * `prisma migrate deploy` then the node server; override e.g. for `db push`
@@ -86,25 +93,22 @@ interface NuxtBaseDockerConfig {
86
93
  startCommand?: string;
87
94
  }
88
95
  /**
89
- * Optional automation knobs (`config.automation.*`) the base preset understands:
90
- * the opt-in upgrade-PR workflow and its runtime version pins. Keys mirror the
91
- * manifest's `automation.*` `configKeys`; the consistency test in
92
- * `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`.
93
98
  */
94
99
  interface NuxtBaseAutomationConfig {
95
100
  /** Sync the weekly streamctl upgrade-PR workflow (default: off, no workflow lands). */
96
101
  upgradePr?: boolean;
97
102
  }
98
103
  /**
99
- * Optional supply-chain knobs (`config.security.*`) the base preset understands:
100
- * 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`.
101
106
  */
102
107
  interface NuxtBaseSecurityConfig {
103
108
  /**
104
- * Minutes a version must have been published before pnpm resolves it
105
- * (`minimumReleaseAge`). Default `"10080"` (7 days); `"0"` disables the cooldown.
106
- * A STRING because the manifest's `configKeys` has no number type, same as the
107
- * `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.
108
112
  */
109
113
  minimumReleaseAge?: string;
110
114
  }
@@ -114,19 +118,29 @@ interface NuxtBaseSecurityConfig {
114
118
  */
115
119
  interface NuxtBasePnpmConfig {
116
120
  /**
117
- * Packages allowed to run install lifecycle scripts, ON TOP of the baked-in
118
- * baseline (`@prisma/client`, `esbuild`, `prisma`). Use this instead of
119
- * `pnpm approve-builds`, which writes to the managed file and is reverted on
120
- * 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.
121
124
  */
122
125
  onlyBuiltDependencies?: string[];
123
126
  }
124
127
  /**
125
- * The typed `streamctl.config.ts` shape for the `@sidebase/base-config` payload:
126
- * the CLI-universal fields plus this payload's declared knobs (`ci`, `versions`,
127
- * `docker`, `automation`, `eslint`) with their real option types. The generic CLI only
128
- * shape-checks these against the manifest's `configKeys`, so the precise types live
129
- * here, next to the payload that owns them, and consumers keep a fully typed config.
128
+ * Editor knobs (`config.editor.*`) rendered into the managed `.vscode/settings.json`.
129
+ * Only the i18n-ally source language varies across the fleet.
130
+ */
131
+ interface NuxtBaseEditorConfig {
132
+ /**
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.
136
+ */
137
+ i18nSourceLanguage?: string;
138
+ }
139
+ /**
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.
130
144
  */
131
145
  interface NuxtBaseConfig {
132
146
  /** The payload package this repo syncs from. */
@@ -155,13 +169,14 @@ interface NuxtBaseConfig {
155
169
  security?: NuxtBaseSecurityConfig;
156
170
  /** Optional pnpm knobs (extra build-script allowances). */
157
171
  pnpm?: NuxtBasePnpmConfig;
172
+ /** Optional editor knobs (the i18n-ally source language). */
173
+ editor?: NuxtBaseEditorConfig;
158
174
  /** ESLint factory options, typed with the payload's own option surface. */
159
175
  eslint?: CreateSidebaseEslintOptions;
160
176
  }
161
177
  /**
162
- * Identity helper for a typed `streamctl.config.ts`, the payload analog of the
163
- * CLI's `defineStreamctlConfig`, adding editor inference for this payload's knobs.
164
- * 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.
165
180
  */
166
181
  declare function defineNuxtBaseConfig(config: NuxtBaseConfig): NuxtBaseConfig;
167
182
  /** Runtime list of every {@link NuxtBaseCiConfig} key. */
@@ -176,14 +191,14 @@ declare const NUXT_BASE_AUTOMATION_KEYS: string[];
176
191
  declare const NUXT_BASE_SECURITY_KEYS: string[];
177
192
  /** Runtime list of every {@link NuxtBasePnpmConfig} key. */
178
193
  declare const NUXT_BASE_PNPM_KEYS: string[];
194
+ /** Runtime list of every {@link NuxtBaseEditorConfig} key. */
195
+ declare const NUXT_BASE_EDITOR_KEYS: string[];
179
196
  /**
180
- * Every payload KNOB dot-path {@link NuxtBaseConfig} declares (the `ci.*` and
181
- * `automation.*` leaves plus the top-level knobs); excludes the CLI-universal
182
- * fields. The consistency test asserts this set equals the RESOLVED preset chain's
183
- * declared `configKeys` (base + nuxt-app), catching drift between the type and the
184
- * 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.
185
200
  */
186
201
  declare const NUXT_BASE_CONFIG_KEYS: string[];
187
202
 
188
- export { NUXT_BASE_AUTOMATION_KEYS, NUXT_BASE_CI_KEYS, NUXT_BASE_CONFIG_KEYS, NUXT_BASE_DOCKER_KEYS, NUXT_BASE_PNPM_KEYS, NUXT_BASE_SECURITY_KEYS, NUXT_BASE_VERSIONS_KEYS, defineNuxtBaseConfig };
189
- export type { NuxtBaseAutomationConfig, NuxtBaseCiConfig, NuxtBaseConfig, NuxtBaseDockerConfig, NuxtBasePnpmConfig, NuxtBaseSecurityConfig, NuxtBaseVersionsConfig, Profile };
203
+ export { NUXT_BASE_AUTOMATION_KEYS, NUXT_BASE_CI_KEYS, NUXT_BASE_CONFIG_KEYS, NUXT_BASE_DOCKER_KEYS, NUXT_BASE_EDITOR_KEYS, NUXT_BASE_PNPM_KEYS, NUXT_BASE_SECURITY_KEYS, NUXT_BASE_VERSIONS_KEYS, defineNuxtBaseConfig };
204
+ export type { NuxtBaseAutomationConfig, NuxtBaseCiConfig, NuxtBaseConfig, NuxtBaseDockerConfig, NuxtBaseEditorConfig, NuxtBasePnpmConfig, NuxtBaseSecurityConfig, NuxtBaseVersionsConfig, Profile };