@sidebase/base-config 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +554 -0
- package/dist/config.d.mts +189 -0
- package/dist/config.d.ts +189 -0
- package/dist/config.mjs +46 -0
- package/dist/eslint/index.d.mts +55 -0
- package/dist/eslint/index.d.ts +55 -0
- package/dist/eslint/index.mjs +278 -0
- package/dist/prisma/index.d.mts +74 -0
- package/dist/prisma/index.d.ts +74 -0
- package/dist/prisma/index.mjs +61 -0
- package/dist/shared/base-config.CuUhyvQo.d.mts +47 -0
- package/dist/shared/base-config.CuUhyvQo.d.ts +47 -0
- package/docs/migration.md +764 -0
- package/package.json +94 -0
- package/presets/base/AGENTS.md +31 -0
- package/presets/base/CLAUDE.md +3 -0
- package/presets/base/dockerignore +18 -0
- package/presets/base/editorconfig +12 -0
- package/presets/base/github/workflows/streamctl-upgrade.yml +130 -0
- package/presets/base/gitignore +19 -0
- package/presets/base/oxlintrc.json +31 -0
- package/presets/base/pnpm-workspace.yaml +27 -0
- package/presets/base/preset.json +38 -0
- package/presets/base/templates/pnpm/only-built-dependency.yml +1 -0
- package/presets/base/tsconfig.json +3 -0
- package/presets/base/vscode/extensions.json +8 -0
- package/presets/base/vscode/settings.json +43 -0
- package/presets/config.template.ts +18 -0
- package/presets/manifest.json +17 -0
- package/presets/nuxt-app/Dockerfile +63 -0
- package/presets/nuxt-app/eslint.config.ts +5 -0
- package/presets/nuxt-app/github/workflows/ci.yml +66 -0
- package/presets/nuxt-app/github/workflows/pr-preview-cleanup.yml +41 -0
- package/presets/nuxt-app/preset.json +67 -0
- package/presets/nuxt-app/prisma.config.ts +6 -0
- package/presets/nuxt-app/templates/ci/e2e-job.yml +39 -0
- package/presets/nuxt-app/templates/ci/test-job.yml +13 -0
- package/presets/nuxt-app/tsconfig.json +6 -0
- package/tsconfig.base.json +19 -0
package/package.json
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sidebase/base-config",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Shared @sidebase base configuration for Nuxt repos: ESLint / Prisma / tsconfig factories on npm, plus the streamctl file-sync preset payload",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"sidebase",
|
|
7
|
+
"config-sync",
|
|
8
|
+
"nuxt",
|
|
9
|
+
"eslint",
|
|
10
|
+
"prisma",
|
|
11
|
+
"streamctl"
|
|
12
|
+
],
|
|
13
|
+
"type": "module",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"homepage": "https://github.com/sidebase/base-config#readme",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/sidebase/base-config.git"
|
|
20
|
+
},
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/sidebase/base-config/issues"
|
|
23
|
+
},
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"docs/migration.md",
|
|
30
|
+
"presets",
|
|
31
|
+
"tsconfig.base.json"
|
|
32
|
+
],
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./dist/config.d.ts",
|
|
36
|
+
"import": "./dist/config.mjs"
|
|
37
|
+
},
|
|
38
|
+
"./tsconfig.base": "./tsconfig.base.json",
|
|
39
|
+
"./config": {
|
|
40
|
+
"types": "./dist/config.d.ts",
|
|
41
|
+
"import": "./dist/config.mjs"
|
|
42
|
+
},
|
|
43
|
+
"./eslint": {
|
|
44
|
+
"types": "./dist/eslint/index.d.ts",
|
|
45
|
+
"import": "./dist/eslint/index.mjs"
|
|
46
|
+
},
|
|
47
|
+
"./prisma": {
|
|
48
|
+
"types": "./dist/prisma/index.d.ts",
|
|
49
|
+
"import": "./dist/prisma/index.mjs"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=22"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@antfu/eslint-config": "^7.4",
|
|
57
|
+
"ufo": "^1.6.4"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"@prisma/client": "^6.19",
|
|
61
|
+
"eslint": "^10.5.0",
|
|
62
|
+
"prisma": "^6.19"
|
|
63
|
+
},
|
|
64
|
+
"peerDependenciesMeta": {
|
|
65
|
+
"@prisma/client": {
|
|
66
|
+
"optional": true
|
|
67
|
+
},
|
|
68
|
+
"prisma": {
|
|
69
|
+
"optional": true
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
74
|
+
"@prisma/client": "^6.19.3",
|
|
75
|
+
"@sidebase/streamctl": "^0.2.0",
|
|
76
|
+
"@types/node": "^24.0.0",
|
|
77
|
+
"eslint": "^10.5.0",
|
|
78
|
+
"jiti": "^2.7.0",
|
|
79
|
+
"prisma": "^6.19.3",
|
|
80
|
+
"publint": "^0.3.21",
|
|
81
|
+
"typescript": "^6.0.0",
|
|
82
|
+
"unbuild": "^3.5.0",
|
|
83
|
+
"vitest": "^3.0.0",
|
|
84
|
+
"yaml": "^2.9.0"
|
|
85
|
+
},
|
|
86
|
+
"scripts": {
|
|
87
|
+
"build": "unbuild",
|
|
88
|
+
"typecheck": "tsc --noEmit -p tsconfig.json && tsc -p tsconfig.test.json",
|
|
89
|
+
"test": "vitest run",
|
|
90
|
+
"lint": "eslint .",
|
|
91
|
+
"validate:presets": "node scripts/validate-presets.mjs",
|
|
92
|
+
"e2e:dry-run": "pnpm build && node scripts/e2e-dry-run.mjs"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Agent instructions
|
|
2
|
+
|
|
3
|
+
These are the shared conventions every coding agent working in this repository must
|
|
4
|
+
follow. They are the same across every repo in the fleet.
|
|
5
|
+
|
|
6
|
+
## Golden rules
|
|
7
|
+
|
|
8
|
+
- Prefer small, reviewable changes; explain the intent, not just the diff.
|
|
9
|
+
- Match the surrounding code and existing patterns before introducing new ones.
|
|
10
|
+
- Never commit secrets, credentials, or generated build artifacts.
|
|
11
|
+
- Keep all code, comments and identifiers in English.
|
|
12
|
+
|
|
13
|
+
## Types & correctness
|
|
14
|
+
|
|
15
|
+
- Use precise types; avoid `any` and unchecked casts. Parse and validate external input at the boundary instead of trusting it downstream.
|
|
16
|
+
- Handle the error and empty-result paths, not just the happy path.
|
|
17
|
+
|
|
18
|
+
## Tests & verification
|
|
19
|
+
|
|
20
|
+
- Run the project's typecheck, lint, and test scripts before proposing a change.
|
|
21
|
+
- Add or update tests for the behavior you change; don't weaken existing assertions to make a change pass.
|
|
22
|
+
|
|
23
|
+
## Commits & pull requests
|
|
24
|
+
|
|
25
|
+
- Use Conventional Commits (`feat:`, `fix:`, `refactor:`, `test:`, `docs:`).
|
|
26
|
+
- Keep one logical change per commit and describe the WHAT and WHY.
|
|
27
|
+
|
|
28
|
+
## Dependencies
|
|
29
|
+
|
|
30
|
+
- Use the repository's pinned package manager; do not switch tools ad hoc.
|
|
31
|
+
- Justify every new dependency; prefer existing utilities or the standard library.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.git
|
|
2
|
+
.github
|
|
3
|
+
node_modules
|
|
4
|
+
npm-debug*
|
|
5
|
+
.nuxt
|
|
6
|
+
.output
|
|
7
|
+
.data
|
|
8
|
+
dist
|
|
9
|
+
tests
|
|
10
|
+
*.log
|
|
11
|
+
.env
|
|
12
|
+
.env.*
|
|
13
|
+
!.env.example
|
|
14
|
+
# The build-stage COPY globs `.npmrc*`; keep token-bearing backups
|
|
15
|
+
# (`.npmrc.local`, `.npmrc.bak`, ...) out of the build context. `.npmrc` itself
|
|
16
|
+
# is intentionally allowed through.
|
|
17
|
+
.npmrc.*
|
|
18
|
+
.DS_Store
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Managed by streamctl (full-own, render: automation-upgrade). OFF BY DEFAULT: this
|
|
2
|
+
# file only lands when a repo sets `automation: { upgradePr: true }` in
|
|
3
|
+
# streamctl.config.ts. See the payload README "Upgrade-PR workflow" for enabling.
|
|
4
|
+
#
|
|
5
|
+
# TOKEN: the PR is opened with `secrets.STREAMCTL_PR_TOKEN` (a GitHub App
|
|
6
|
+
# installation token or a machine-account PAT), NOT the default `GITHUB_TOKEN`.
|
|
7
|
+
# A PR created with `GITHUB_TOKEN` does NOT trigger `pull_request` workflows, so
|
|
8
|
+
# this repo's own `check` gate would never run on the bot's PR. The bot identity
|
|
9
|
+
# for the fleet is still being decided; treat this file as inert and provide the
|
|
10
|
+
# secret before enabling. No registry token is needed: the payload is public npm.
|
|
11
|
+
# A repo with OTHER private dependencies must opt this file out
|
|
12
|
+
# (`files: { ".github/workflows/streamctl-upgrade.yml": "off" }`) and wire its own auth.
|
|
13
|
+
#
|
|
14
|
+
# Actions are pinned by full commit SHA (this workflow handles a token); the version
|
|
15
|
+
# tag is in the trailing comment.
|
|
16
|
+
name: streamctl upgrade
|
|
17
|
+
|
|
18
|
+
on:
|
|
19
|
+
schedule:
|
|
20
|
+
- cron: "0 6 * * 1" # Mondays 06:00 UTC
|
|
21
|
+
workflow_dispatch:
|
|
22
|
+
|
|
23
|
+
# Least privilege: every PR/issue write below uses STREAMCTL_PR_TOKEN, so the
|
|
24
|
+
# default token only needs to read the repo for checkout.
|
|
25
|
+
permissions:
|
|
26
|
+
contents: read
|
|
27
|
+
|
|
28
|
+
env:
|
|
29
|
+
NODE_VERSION: "${NODE_VERSION}"
|
|
30
|
+
|
|
31
|
+
jobs:
|
|
32
|
+
upgrade:
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
steps:
|
|
35
|
+
# A bot identity is REQUIRED for the PR (see the header). To mint an App token
|
|
36
|
+
# in-workflow instead of storing a PAT, uncomment and wire the App credentials,
|
|
37
|
+
# then use `${{ steps.bot.outputs.token }}` in place of STREAMCTL_PR_TOKEN below:
|
|
38
|
+
#
|
|
39
|
+
# - id: bot
|
|
40
|
+
# uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0
|
|
41
|
+
# with:
|
|
42
|
+
# app-id: ${{ secrets.STREAMCTL_APP_ID }}
|
|
43
|
+
# private-key: ${{ secrets.STREAMCTL_APP_PRIVATE_KEY }}
|
|
44
|
+
|
|
45
|
+
- name: Checkout
|
|
46
|
+
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
47
|
+
|
|
48
|
+
- name: Set up pnpm
|
|
49
|
+
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
|
|
50
|
+
with:
|
|
51
|
+
run_install: false
|
|
52
|
+
|
|
53
|
+
- name: Set up Node.js
|
|
54
|
+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
55
|
+
with:
|
|
56
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
57
|
+
cache: pnpm
|
|
58
|
+
|
|
59
|
+
- name: Install dependencies
|
|
60
|
+
run: pnpm install --frozen-lockfile
|
|
61
|
+
|
|
62
|
+
# Exit codes drive the branch: 4 = an update is available (proceed); 0 = up to
|
|
63
|
+
# date (stop, no PR); 3 = the repo already has drift (open an issue, not a PR).
|
|
64
|
+
- id: check
|
|
65
|
+
name: Check for a payload update
|
|
66
|
+
run: |
|
|
67
|
+
set +e
|
|
68
|
+
pnpm streamctl check --fail-on outdated --json > streamctl-check.json
|
|
69
|
+
echo "code=$?" >> "$GITHUB_OUTPUT"
|
|
70
|
+
set -e
|
|
71
|
+
cat streamctl-check.json
|
|
72
|
+
|
|
73
|
+
- name: Open a drift issue (repo already diverged)
|
|
74
|
+
if: ${{ steps.check.outputs.code == '3' }}
|
|
75
|
+
env:
|
|
76
|
+
GH_TOKEN: ${{ secrets.STREAMCTL_PR_TOKEN }}
|
|
77
|
+
run: |
|
|
78
|
+
gh issue create \
|
|
79
|
+
--title "streamctl: managed files have drifted" \
|
|
80
|
+
--label streamctl \
|
|
81
|
+
--body "\`streamctl check\` reports pre-existing drift, so the automated upgrade was skipped. Run \`pnpm streamctl sync\` locally, commit the result, then re-run this workflow."
|
|
82
|
+
|
|
83
|
+
# Only upgrade when an update is actually available (check exit 4).
|
|
84
|
+
- id: upgrade
|
|
85
|
+
name: Upgrade the payload
|
|
86
|
+
if: ${{ steps.check.outputs.code == '4' }}
|
|
87
|
+
run: |
|
|
88
|
+
set +e
|
|
89
|
+
pnpm streamctl upgrade --json > streamctl-upgrade.json
|
|
90
|
+
echo "code=$?" >> "$GITHUB_OUTPUT"
|
|
91
|
+
set -e
|
|
92
|
+
cat streamctl-upgrade.json
|
|
93
|
+
|
|
94
|
+
# exit 2 = the chained sync hit conflicts and ROLLED BACK. Re-run bumping only the
|
|
95
|
+
# pin + devDependency (no sync) so the PR carries a reviewable diff a human then
|
|
96
|
+
# reconciles with `streamctl sync --interactive`.
|
|
97
|
+
- name: Prepare a plan-only bump (interactive sync required)
|
|
98
|
+
if: ${{ steps.upgrade.outputs.code == '2' }}
|
|
99
|
+
run: pnpm streamctl upgrade --no-install --json > streamctl-upgrade.json
|
|
100
|
+
|
|
101
|
+
- name: Open the upgrade PR (clean reconcile)
|
|
102
|
+
if: ${{ steps.upgrade.outputs.code == '0' }}
|
|
103
|
+
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
|
104
|
+
with:
|
|
105
|
+
token: ${{ secrets.STREAMCTL_PR_TOKEN }}
|
|
106
|
+
branch: chore/streamctl-upgrade
|
|
107
|
+
commit-message: "chore: upgrade the streamctl payload"
|
|
108
|
+
title: "chore: upgrade the streamctl payload"
|
|
109
|
+
body: |
|
|
110
|
+
Automated payload upgrade: the managed files were reconciled cleanly by
|
|
111
|
+
`streamctl upgrade`. Review the diff; `streamctl-upgrade.json` (in the run
|
|
112
|
+
logs) has the full sync summary and dependency bumps.
|
|
113
|
+
labels: streamctl
|
|
114
|
+
|
|
115
|
+
- name: Open a plan-only PR (conflicts need interactive sync)
|
|
116
|
+
if: ${{ steps.upgrade.outputs.code == '2' }}
|
|
117
|
+
uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8
|
|
118
|
+
with:
|
|
119
|
+
token: ${{ secrets.STREAMCTL_PR_TOKEN }}
|
|
120
|
+
branch: chore/streamctl-upgrade
|
|
121
|
+
commit-message: "chore: bump the streamctl payload pin (interactive sync required)"
|
|
122
|
+
title: "chore: streamctl payload upgrade needs interactive sync"
|
|
123
|
+
body: |
|
|
124
|
+
The automated `streamctl upgrade` hit conflicts and rolled the sync back, so
|
|
125
|
+
only the payload pin + devDependency were bumped here. Finish the upgrade by
|
|
126
|
+
hand: check out this branch, run `pnpm streamctl sync --interactive`, resolve
|
|
127
|
+
each conflict, and push.
|
|
128
|
+
labels: |
|
|
129
|
+
streamctl
|
|
130
|
+
needs-interactive-upgrade
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
node_modules
|
|
2
|
+
.output
|
|
3
|
+
.nuxt
|
|
4
|
+
.data
|
|
5
|
+
dist
|
|
6
|
+
.env
|
|
7
|
+
.env.*
|
|
8
|
+
!.env.example
|
|
9
|
+
*.log
|
|
10
|
+
pglite-debug.log
|
|
11
|
+
prisma/*.db
|
|
12
|
+
prisma/migrations/dev
|
|
13
|
+
.DS_Store
|
|
14
|
+
# streamctl local scratch dirs/files (e.g. local.concept) stay untracked.
|
|
15
|
+
local.*
|
|
16
|
+
local.*/
|
|
17
|
+
# CLAUDE.md is managed by streamctl; a user-global gitignore that ignores the
|
|
18
|
+
# filename everywhere would silently untrack it. Force-allow it here.
|
|
19
|
+
!CLAUDE.md
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"env": {
|
|
3
|
+
"browser": true
|
|
4
|
+
},
|
|
5
|
+
"ignorePatterns": [
|
|
6
|
+
"local.*",
|
|
7
|
+
"local.*/"
|
|
8
|
+
],
|
|
9
|
+
"plugins": [
|
|
10
|
+
"unicorn",
|
|
11
|
+
"typescript",
|
|
12
|
+
"oxc"
|
|
13
|
+
],
|
|
14
|
+
"categories": {
|
|
15
|
+
"correctness": "deny",
|
|
16
|
+
"perf": "deny",
|
|
17
|
+
"suspicious": "deny",
|
|
18
|
+
"pedantic": "deny"
|
|
19
|
+
},
|
|
20
|
+
"rules": {
|
|
21
|
+
"unicorn/no-useless-undefined": "off",
|
|
22
|
+
"eslint/no-console": "error",
|
|
23
|
+
"max-lines-per-function": "off",
|
|
24
|
+
"max-depth": "off",
|
|
25
|
+
"max-nested-callbacks": "off",
|
|
26
|
+
"max-lines": "off",
|
|
27
|
+
"no-warning-comments": "off",
|
|
28
|
+
"no-inline-comments": "off",
|
|
29
|
+
"no-map-spread": "off"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Managed by streamctl (full-own, render: security). pnpm's own settings file.
|
|
2
|
+
#
|
|
3
|
+
# SUPPLY-CHAIN COOLDOWN: a version must have been published for ${MIN_RELEASE_AGE}
|
|
4
|
+
# minutes before pnpm will resolve it, so a compromised release has time to be caught
|
|
5
|
+
# and yanked before the fleet installs it. Requires pnpm >= 10.16 (baseline: 10.28.1);
|
|
6
|
+
# it gates fresh resolution only, so `--frozen-lockfile` installs are unaffected.
|
|
7
|
+
# `@sidebase/*` is exempt: the first-party scope (this payload + the streamctl CLI),
|
|
8
|
+
# published by the org itself, so a payload release reaches the fleet the same day.
|
|
9
|
+
#
|
|
10
|
+
# `packages: []` is REQUIRED, not decorative: pnpm defaults it to `**` whenever a
|
|
11
|
+
# pnpm-workspace.yaml exists, which would silently promote every nested package.json
|
|
12
|
+
# (test fixtures, examples) to a workspace project and break `--frozen-lockfile`.
|
|
13
|
+
# A real monorepo owns this key itself, so opt the file out with
|
|
14
|
+
# `files: { "pnpm-workspace.yaml": "off" }` in .streamctl/config.ts.
|
|
15
|
+
#
|
|
16
|
+
# `onlyBuiltDependencies` is the postinstall-script allowlist: everything else installs
|
|
17
|
+
# with its lifecycle scripts blocked. The baseline covers what the fleet universally
|
|
18
|
+
# needs; add extras via `pnpm: { onlyBuiltDependencies: [...] }` rather than running
|
|
19
|
+
# `pnpm approve-builds` (which writes here and would be reverted on the next sync).
|
|
20
|
+
packages: []
|
|
21
|
+
minimumReleaseAge: ${MIN_RELEASE_AGE}
|
|
22
|
+
minimumReleaseAgeExclude:
|
|
23
|
+
- "@sidebase/*"
|
|
24
|
+
onlyBuiltDependencies:
|
|
25
|
+
- "@prisma/client"
|
|
26
|
+
- "esbuild"
|
|
27
|
+
- "prisma"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "base",
|
|
3
|
+
"files": [
|
|
4
|
+
{ "path": ".editorconfig", "strategy": "block", "source": "base/editorconfig", "blockMark": "editorconfig" },
|
|
5
|
+
{ "path": "tsconfig.json", "strategy": "full", "source": "base/tsconfig.json", "adoption": "expected" },
|
|
6
|
+
{ "path": ".dockerignore", "strategy": "full", "source": "base/dockerignore", "adoption": "expected" },
|
|
7
|
+
{ "path": "pnpm-workspace.yaml", "strategy": "full", "source": "base/pnpm-workspace.yaml", "render": "security", "adoption": "expected" },
|
|
8
|
+
{ "path": ".gitignore", "strategy": "block", "source": "base/gitignore", "blockMark": "core" },
|
|
9
|
+
{ "path": ".oxlintrc.json", "strategy": "full", "source": "base/oxlintrc.json", "adoption": "expected" },
|
|
10
|
+
{ "path": ".vscode/settings.json", "strategy": "merge", "source": "base/vscode/settings.json", "projectFields": ["editor.fontSize", "editor.rulers", "editor.formatOnSave", "files.exclude", "search.exclude", "files.watcherExclude"] },
|
|
11
|
+
{ "path": ".vscode/extensions.json", "strategy": "merge", "source": "base/vscode/extensions.json", "projectFields": ["unwantedRecommendations"] },
|
|
12
|
+
{ "path": "AGENTS.md", "strategy": "full", "source": "base/AGENTS.md", "adoption": "expected" },
|
|
13
|
+
{ "path": "CLAUDE.md", "strategy": "scaffold", "source": "base/CLAUDE.md", "adoption": "expected" },
|
|
14
|
+
{ "path": ".github/workflows/streamctl-upgrade.yml", "strategy": "full", "source": "base/github/workflows/streamctl-upgrade.yml", "render": "automation-upgrade", "enabledBy": "automation.upgradePr", "adoption": "unexpected" }
|
|
15
|
+
],
|
|
16
|
+
"renders": {
|
|
17
|
+
"automation-upgrade": {
|
|
18
|
+
"placeholders": {
|
|
19
|
+
"NODE_VERSION": { "configPath": "versions.node", "default": "24.13.0", "pattern": "^[\\w.+-]+$" }
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"security": {
|
|
23
|
+
"placeholders": {
|
|
24
|
+
"MIN_RELEASE_AGE": { "configPath": "security.minimumReleaseAge", "default": "10080", "pattern": "^\\d+$" }
|
|
25
|
+
},
|
|
26
|
+
"fragments": [
|
|
27
|
+
{ "forEach": "pnpm.onlyBuiltDependencies", "source": "base/templates/pnpm/only-built-dependency.yml" }
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"configKeys": {
|
|
32
|
+
"automation.upgradePr": "boolean",
|
|
33
|
+
"security.minimumReleaseAge": "string",
|
|
34
|
+
"pnpm.onlyBuiltDependencies": "string[]",
|
|
35
|
+
"versions.node": "string",
|
|
36
|
+
"versions.pnpm": "string"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
- "${ITEM}"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Disable the default formatter, use eslint instead
|
|
3
|
+
"prettier.enable": false,
|
|
4
|
+
"eslint.useFlatConfig": true,
|
|
5
|
+
"typescript.tsdk": "node_modules/typescript/lib",
|
|
6
|
+
|
|
7
|
+
// Auto fix
|
|
8
|
+
"editor.codeActionsOnSave": {
|
|
9
|
+
"source.fixAll.eslint": "explicit",
|
|
10
|
+
"source.organizeImports": "never"
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
// Silence the stylistic rules in the IDE, but still auto fix them
|
|
14
|
+
"eslint.rules.customizations": [
|
|
15
|
+
{ "rule": "style/*", "severity": "off" },
|
|
16
|
+
{ "rule": "format/*", "severity": "off" },
|
|
17
|
+
{ "rule": "*-indent", "severity": "off" },
|
|
18
|
+
{ "rule": "*-spacing", "severity": "off" },
|
|
19
|
+
{ "rule": "*-spaces", "severity": "off" },
|
|
20
|
+
{ "rule": "*-order", "severity": "off" },
|
|
21
|
+
{ "rule": "*-dangle", "severity": "off" },
|
|
22
|
+
{ "rule": "*-newline", "severity": "off" },
|
|
23
|
+
{ "rule": "*quotes", "severity": "off" },
|
|
24
|
+
{ "rule": "*semi", "severity": "off" }
|
|
25
|
+
],
|
|
26
|
+
|
|
27
|
+
// Enable eslint for all supported languages
|
|
28
|
+
"eslint.validate": [
|
|
29
|
+
"javascript",
|
|
30
|
+
"javascriptreact",
|
|
31
|
+
"typescript",
|
|
32
|
+
"typescriptreact",
|
|
33
|
+
"vue",
|
|
34
|
+
"html",
|
|
35
|
+
"markdown",
|
|
36
|
+
"json",
|
|
37
|
+
"jsonc",
|
|
38
|
+
"yaml",
|
|
39
|
+
"toml",
|
|
40
|
+
"gql",
|
|
41
|
+
"graphql"
|
|
42
|
+
]
|
|
43
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { defineNuxtBaseConfig } from '@sidebase/base-config'
|
|
2
|
+
|
|
3
|
+
// Scaffolded by `streamctl init`. `defineNuxtBaseConfig` gives typed editor
|
|
4
|
+
// inference for this payload's knobs; the CLI validates the file on every sync.
|
|
5
|
+
export default defineNuxtBaseConfig({
|
|
6
|
+
package: '__PACKAGE__',
|
|
7
|
+
base: '__BASE__',
|
|
8
|
+
version: '__VERSION__',
|
|
9
|
+
profile: '__PROFILE__',
|
|
10
|
+
|
|
11
|
+
// Optional knobs, uncomment to enable:
|
|
12
|
+
// ci: { unitTests: true, e2e: true },
|
|
13
|
+
// versions: { node: '24.13.0', pnpm: '10.28.1' },
|
|
14
|
+
// docker: { aptPackages: ['ffmpeg'] }, // extras; openssl is always installed
|
|
15
|
+
// security: { minimumReleaseAge: '10080' }, // minutes before pnpm installs a release; '0' disables
|
|
16
|
+
// pnpm: { onlyBuiltDependencies: ['sharp'] }, // extras on top of prisma + esbuild
|
|
17
|
+
// eslint: { trpcGuard: true },
|
|
18
|
+
})
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# see https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
|
|
2
|
+
ARG NODE_VERSION=node:${NODE_VERSION}
|
|
3
|
+
ARG PNPM_VERSION=${PNPM_VERSION}
|
|
4
|
+
|
|
5
|
+
# --- BUILD STAGE ---
|
|
6
|
+
FROM $NODE_VERSION AS production-base
|
|
7
|
+
|
|
8
|
+
# A pre-`FROM` ARG is visible only to `FROM`. Re-declare it bare to inherit the
|
|
9
|
+
# global value inside this stage, or $PNPM_VERSION expands to empty below.
|
|
10
|
+
ARG PNPM_VERSION
|
|
11
|
+
|
|
12
|
+
WORKDIR /app
|
|
13
|
+
|
|
14
|
+
# Installed directly rather than through corepack: Node 25 no longer bundles
|
|
15
|
+
# corepack, and `versions.node` declares no ceiling. npm's global bin is already
|
|
16
|
+
# on PATH, so no PNPM_HOME wiring is needed.
|
|
17
|
+
RUN npm i -g pnpm@$PNPM_VERSION
|
|
18
|
+
|
|
19
|
+
# Copy pnpm files
|
|
20
|
+
COPY package.json pnpm-lock.yaml .npmrc* ./
|
|
21
|
+
${DOCKER_PRE_INSTALL}
|
|
22
|
+
# load packages into the virtual store using only information from a lockfile.
|
|
23
|
+
# --ignore-scripts: only package files exist at this layer, so lifecycle scripts
|
|
24
|
+
# (e.g. `postinstall: nuxt prepare`) would run against no sources; the explicit
|
|
25
|
+
# build steps below (docker.buildSteps) cover them against the full tree.
|
|
26
|
+
RUN pnpm install --ignore-scripts --frozen-lockfile --prefer-offline
|
|
27
|
+
|
|
28
|
+
ARG ARG_NUXT_BUILD_CLIENT_SOURCE_MAPS=false
|
|
29
|
+
ENV NUXT_BUILD_CLIENT_SOURCE_MAPS=$ARG_NUXT_BUILD_CLIENT_SOURCE_MAPS
|
|
30
|
+
${DOCKER_BUILD_ARGS}
|
|
31
|
+
# copy the app, note .dockerignore
|
|
32
|
+
COPY . .
|
|
33
|
+
|
|
34
|
+
# split commands into seperate RUN to not invalidate entire cache layers
|
|
35
|
+
${DOCKER_BUILD_STEPS}
|
|
36
|
+
|
|
37
|
+
# --- FINAL PRODUCTION STAGE ---
|
|
38
|
+
FROM $NODE_VERSION-slim AS production
|
|
39
|
+
|
|
40
|
+
# openssl is always installed: the Prisma query engine generated in the build
|
|
41
|
+
# stage (debian-openssl-3.0.x) dynamically links libssl3, which slim images do
|
|
42
|
+
# not ship. Without it the app crashes on its first query. APT_PACKAGES adds
|
|
43
|
+
# project-owned extras on top (docker.aptPackages knob, e.g. "ffmpeg").
|
|
44
|
+
ARG APT_PACKAGES="${APT_PACKAGES}"
|
|
45
|
+
RUN apt-get update && apt-get install -y --no-install-recommends openssl $APT_PACKAGES \
|
|
46
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
47
|
+
|
|
48
|
+
# copy necessary directories from the production-base stage to the final production
|
|
49
|
+
# stage, owned by the runtime uid 1000 rather than root (see the USER switch below)
|
|
50
|
+
COPY --chown=node:node --from=production-base /app/.output /app/.output
|
|
51
|
+
|
|
52
|
+
WORKDIR /app
|
|
53
|
+
|
|
54
|
+
${DOCKER_PRISMA_RUNTIME}
|
|
55
|
+
${DOCKER_FINAL_STAGE}
|
|
56
|
+
# Drop to the unprivileged `node` user (uid 1000) the base image already ships.
|
|
57
|
+
# FIXED and outside every knob, so an override cannot re-root the container.
|
|
58
|
+
# Everything the runtime reads or executes is node-owned, and `npm exec` writes
|
|
59
|
+
# its npx cache under /home/node/.npm, which the official image creates writable.
|
|
60
|
+
USER node
|
|
61
|
+
|
|
62
|
+
# start the app
|
|
63
|
+
CMD [ "sh", "-c", "${DOCKER_START_COMMAND}" ]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Managed by streamctl (full-own, render: ci). NODE_VERSION is a render knob
|
|
2
|
+
# sourced from the version baseline. pnpm is not pinned here: action-setup reads
|
|
3
|
+
# `packageManager` from package.json, the single reconciled source.
|
|
4
|
+
# The build-and-deploy-* preview/staging/production suite is deferred to 0.2.0.
|
|
5
|
+
name: CI
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
pull_request:
|
|
9
|
+
branches: [main]
|
|
10
|
+
|
|
11
|
+
# Least privilege: the jobs only read the repo. Install/build steps run
|
|
12
|
+
# third-party code, so a read-only default token limits a malicious script.
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
18
|
+
cancel-in-progress: true
|
|
19
|
+
|
|
20
|
+
env:
|
|
21
|
+
NODE_VERSION: "${NODE_VERSION}"
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
lint-typecheck:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
28
|
+
|
|
29
|
+
- name: Set up pnpm
|
|
30
|
+
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
|
|
31
|
+
with:
|
|
32
|
+
run_install: false
|
|
33
|
+
|
|
34
|
+
- name: Use Node.js ${{ env.NODE_VERSION }}
|
|
35
|
+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
36
|
+
with:
|
|
37
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
38
|
+
cache: pnpm
|
|
39
|
+
|
|
40
|
+
- run: pnpm install --frozen-lockfile
|
|
41
|
+
- run: pnpm streamctl check
|
|
42
|
+
- run: pnpm prisma format && git diff --exit-code prisma/schema.prisma
|
|
43
|
+
- run: pnpm prisma generate
|
|
44
|
+
- run: pnpm lint
|
|
45
|
+
- run: pnpm jsonsort -c i18n/locales/{**/*,*}.json
|
|
46
|
+
- run: pnpm typecheck
|
|
47
|
+
|
|
48
|
+
build:
|
|
49
|
+
needs: lint-typecheck
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
|
53
|
+
|
|
54
|
+
- name: Set up pnpm
|
|
55
|
+
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
|
|
56
|
+
with:
|
|
57
|
+
run_install: false
|
|
58
|
+
|
|
59
|
+
- name: Use Node.js ${{ env.NODE_VERSION }}
|
|
60
|
+
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
61
|
+
with:
|
|
62
|
+
node-version: ${{ env.NODE_VERSION }}
|
|
63
|
+
cache: pnpm
|
|
64
|
+
|
|
65
|
+
- run: pnpm install --frozen-lockfile
|
|
66
|
+
- run: pnpm nuxi prepare && pnpm prisma generate && pnpm build
|