@cosmicdrift/kumiko-dev-server 0.369.0 → 0.371.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/build.d.ts +1 -1
  2. package/dist/cli.d.ts +3 -3
  3. package/dist/compose-stacks.d.ts +63 -3
  4. package/dist/compose-stacks.js +94 -12
  5. package/dist/host-dispatch-adapter.d.ts +7 -0
  6. package/dist/host-dispatch-adapter.js +31 -0
  7. package/dist/index.d.ts +21 -20
  8. package/dist/index.js +2 -1
  9. package/dist/init-deploy-cli.js +6 -0
  10. package/dist/managed-files/app-scripts.d.ts +13 -0
  11. package/dist/managed-files/app-scripts.js +40 -0
  12. package/dist/managed-files/check.d.ts +34 -0
  13. package/dist/managed-files/check.js +109 -0
  14. package/dist/managed-files/index.d.ts +8 -0
  15. package/dist/managed-files/index.js +8 -0
  16. package/dist/managed-files/jsonc.d.ts +1 -0
  17. package/dist/managed-files/jsonc.js +12 -0
  18. package/dist/managed-files/line-diff.d.ts +2 -0
  19. package/dist/managed-files/line-diff.js +60 -0
  20. package/dist/managed-files/marker.d.ts +17 -0
  21. package/dist/managed-files/marker.js +49 -0
  22. package/dist/managed-files/port-registry.d.ts +17 -0
  23. package/dist/managed-files/port-registry.js +31 -0
  24. package/dist/managed-files/registry.d.ts +51 -0
  25. package/dist/managed-files/registry.js +115 -0
  26. package/dist/managed-files/static-app-config.d.ts +16 -0
  27. package/dist/managed-files/static-app-config.js +99 -0
  28. package/dist/managed-files/sync.d.ts +19 -0
  29. package/dist/managed-files/sync.js +101 -0
  30. package/dist/run-dev-app.d.ts +1 -1
  31. package/dist/run-dev-app.js +7 -1
  32. package/dist/scaffold-app.d.ts +3 -3
  33. package/dist/scaffold-app.js +125 -199
  34. package/dist/scaffold-deploy.d.ts +9 -0
  35. package/dist/scaffold-deploy.js +34 -6
  36. package/dist/scaffold-feature.js +1 -0
  37. package/package.json +18 -9
  38. package/src/changes.json +25 -0
  39. package/templates/deploy/migrate-step.sh.template +11 -6
  40. package/templates/managed/cache-cleanup.yml.template +30 -0
  41. package/templates/managed/ci.yml.template +65 -0
  42. package/templates/managed/husky-pre-push.template +40 -0
  43. package/templates/managed/kumiko-schema.ts.template +12 -0
  44. package/templates/managed/release.yml.template +55 -0
@@ -127,6 +127,7 @@ function renderTsconfig() {
127
127
  target: "ESNext",
128
128
  module: "ESNext",
129
129
  moduleResolution: "bundler",
130
+ allowImportingTsExtensions: true,
130
131
  esModuleInterop: true,
131
132
  skipLibCheck: true,
132
133
  lib: ["ESNext"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-dev-server",
3
- "version": "0.369.0",
3
+ "version": "0.371.0",
4
4
  "description": "Dev-tooling for Kumiko apps: local dev-server bootstrap (runDevApp), scaffolding. Its compose-stacks/env-schema subpaths are consumed at prod boot too — see @cosmicdrift/kumiko-server-runtime for the prod runner itself.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -18,6 +18,7 @@
18
18
  "runtime": "dev",
19
19
  "bunOnlyExports": [
20
20
  ".",
21
+ "./managed-files",
21
22
  "./setup-test-stack-from-features"
22
23
  ]
23
24
  },
@@ -38,6 +39,10 @@
38
39
  "types": "./dist/env-schema.d.ts",
39
40
  "default": "./dist/env-schema.js"
40
41
  },
42
+ "./managed-files": {
43
+ "types": "./dist/managed-files/index.d.ts",
44
+ "default": "./dist/managed-files/index.js"
45
+ },
41
46
  "./setup-test-stack-from-features": {
42
47
  "types": "./dist/setup-test-stack-from-features.d.ts",
43
48
  "default": "./dist/setup-test-stack-from-features.js"
@@ -67,14 +72,14 @@
67
72
  "kumiko-upgrade": "./bin/kumiko-upgrade.ts"
68
73
  },
69
74
  "dependencies": {
70
- "@cosmicdrift/kumiko-bundled-features": "0.369.0",
71
- "@cosmicdrift/kumiko-framework": "0.369.0",
72
- "@cosmicdrift/kumiko-headless": "0.369.0",
73
- "@cosmicdrift/kumiko-renderer-mail-html": "0.369.0",
74
- "@cosmicdrift/kumiko-renderer-web": "0.369.0",
75
- "@cosmicdrift/kumiko-server-runtime": "0.369.0",
76
- "@cosmicdrift/kumiko-testing": "0.369.0",
77
- "@cosmicdrift/kumiko-types": "0.369.0",
75
+ "@cosmicdrift/kumiko-bundled-features": "0.371.0",
76
+ "@cosmicdrift/kumiko-framework": "0.371.0",
77
+ "@cosmicdrift/kumiko-headless": "0.371.0",
78
+ "@cosmicdrift/kumiko-renderer-mail-html": "0.371.0",
79
+ "@cosmicdrift/kumiko-renderer-web": "0.371.0",
80
+ "@cosmicdrift/kumiko-server-runtime": "0.371.0",
81
+ "@cosmicdrift/kumiko-testing": "0.371.0",
82
+ "@cosmicdrift/kumiko-types": "0.371.0",
78
83
  "bun-types": "^1.3.13",
79
84
  "ts-morph": "^28.0.0",
80
85
  "zod": "^4.4.3"
@@ -99,6 +104,10 @@
99
104
  "types": "./dist/env-schema.d.ts",
100
105
  "default": "./dist/env-schema.js"
101
106
  },
107
+ "./managed-files": {
108
+ "types": "./dist/managed-files/index.d.ts",
109
+ "default": "./dist/managed-files/index.js"
110
+ },
102
111
  "./setup-test-stack-from-features": {
103
112
  "types": "./dist/setup-test-stack-from-features.d.ts",
104
113
  "default": "./dist/setup-test-stack-from-features.js"
package/src/changes.json CHANGED
@@ -1,4 +1,29 @@
1
1
  [
2
+ {
3
+ "version": "0.371.0",
4
+ "type": "improvement",
5
+ "title": "composeGdprStack access, composePagesStack terms, migrate-step project name",
6
+ "detail": "composeGdprStack({ access }) is passed to compliance-profiles and composeOpsStack({ access }) to delivery as their handler roles. composePagesStack({ terms }) is passed to legal-pages. DevHostDispatch and DevHostDispatchResult are exported. The migrate-step.sh template and the managed pre-push template follow the show-pony version, with the compose project name taken from docker compose config."
7
+ },
8
+ {
9
+ "version": "0.370.0",
10
+ "type": "improvement",
11
+ "title": "runDevApp binds the MFA token secrets",
12
+ "detail": "When auth-mfa is mounted and JWT_SECRET is set, runDevApp binds the MFA token secrets the same way runProdApp does."
13
+ },
14
+ {
15
+ "version": "0.370.0",
16
+ "type": "improvement",
17
+ "title": "composeAuthStack, composeSaasStack and composeSecurityStack",
18
+ "detail": "composeAuthStack({ sessions?, mfa?, accountSecurity? }) mounts auth-foundation and sessions, with mfa also auth-mfa and account-security; the password login still comes from the auth option or composeFeatures. composeSaasStack({ billing: \"stripe\" | \"mollie\", tiers, caps?, waitlist?, billingFoundation? }) mounts billing-foundation and tier-engine, cap-counter plus cap-overview with caps, waitlist with waitlist. With \"stripe\" the runProdApp billing option mounts subscription-stripe and the tier-sync webhook route; with \"mollie\" the stack mounts subscription-mollie from the mollie options and the app adds the webhook route. composeSecurityStack({ includeSessions? }) mounts sessions, crypto-shredding, rate-limiting and audit. composeGdprStack({ selfService: { userDataRights? } }) adds sessions, user-data-rights and user-profile in the order dsgvoSelfServiceFeatures used. billing-foundation requires tenant-lifecycle and compliance-profiles, which composeGdprStack({ tenantLifecycle: true }) mounts. user-profile in selfService requires user-data-rights-defaults and auth-email-password; composeUserDataRightsStack mounts the defaults, and the login comes from the auth option. Recipe: samples/recipes/compose-stacks."
19
+ },
20
+ {
21
+ "version": "0.370.0",
22
+ "type": "improvement",
23
+ "title": "Managed files: one template source for the scaffold, kumiko check managed and kumiko sync-managed",
24
+ "detail": "deploy/Dockerfile, deploy/Dockerfile.dockerignore, deploy/migrate-step.sh, .husky/pre-push, .github/workflows/{ci,release,cache-cleanup}.yml, the bunfigs and kumiko/schema.ts carry a kumiko-managed marker on line 1 (line 2 after a shebang or # syntax= line). kumiko new app writes them, plus kumiko.config.ts, bin/server.ts (was bin/dev.ts), bin/env-schema.ts, e2e/_helpers and src/__tests__/_setup.ts; bunfig.ci.toml is gone. kumiko/schema.ts is generated from kumiko.config.ts. kumiko-init-deploy prints a deprecation notice and goes away in the next release. Release targets come from package.json#kumiko.deploy.namespace and .deployment (default: the app name).",
25
+ "migration": "Existing apps: add kumiko.config.ts with defineAppConfig, then run kumiko sync-managed (dry run), kumiko sync-managed --write --adopt for files that are identical or should follow the template, and mark deliberate deviations with \"# kumiko-managed: local <reason>\" on line 2. Until kumiko.config.ts calls defineAppConfig, kumiko check only warns about drift and missing scripts."
26
+ },
2
27
  {
3
28
  "version": "0.368.0",
4
29
  "type": "breaking",
@@ -10,8 +10,9 @@
10
10
  # changes BEFORE the app container starts — runProdApp's boot gate would
11
11
  # otherwise abort with SchemaDriftError.
12
12
  #
13
- # Network: the exact `<dirname>_stack` name of the compose project this
14
- # script runs in — never another project's network on a shared host.
13
+ # Network: the exact `<project>_stack` name of the compose project this
14
+ # script runs in (project name as reported by `docker compose config`) —
15
+ # never another project's network on a shared host.
15
16
 
16
17
  set -euo pipefail
17
18
 
@@ -22,12 +23,16 @@ set -a
22
23
  . ./.env
23
24
  set +a
24
25
 
25
- # After the .env import, so a COMPOSE_PROJECT_NAME set there picks the network.
26
- # Compose lowercases the project name and drops characters outside [a-z0-9_-].
27
- COMPOSE_PROJECT="$(printf '%s' "${COMPOSE_PROJECT_NAME:-$(basename "$PWD")}" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9_-')"
26
+ # After the .env import, so COMPOSE_PROJECT_NAME from there is honored. Ask
27
+ # compose first: it also takes the name from a top-level `name:` key. The
28
+ # fallback mirrors compose's normalization (lowercase, drop [^a-z0-9_-]).
29
+ COMPOSE_PROJECT="$(docker compose config 2>/dev/null | sed -n 's/^name: //p' | head -n1 || true)"
30
+ if [ -z "$COMPOSE_PROJECT" ]; then
31
+ COMPOSE_PROJECT="$(printf '%s' "${COMPOSE_PROJECT_NAME:-$(basename "$PWD")}" | tr '[:upper:]' '[:lower:]' | tr -cd 'a-z0-9_-')"
32
+ fi
28
33
  STACK_NETWORK="${COMPOSE_PROJECT}_stack"
29
34
  if ! docker network inspect "$STACK_NETWORK" >/dev/null 2>&1; then
30
- echo "Stack network '$STACK_NETWORK' not found (derived from COMPOSE_PROJECT_NAME or the directory name '$(basename "$PWD")') — compose project not running?" >&2
35
+ echo "Stack network '$STACK_NETWORK' not found (project name from 'docker compose config', fallback COMPOSE_PROJECT_NAME or directory name '$(basename "$PWD")'; 'docker compose -p <name>' is not detected, set COMPOSE_PROJECT_NAME in .env then) — compose project not running?" >&2
31
36
  exit 1
32
37
  fi
33
38
 
@@ -0,0 +1,30 @@
1
+ name: cache-cleanup
2
+
3
+ on:
4
+ schedule:
5
+ - cron: "0 3 * * 1"
6
+ workflow_dispatch: {}
7
+
8
+ jobs:
9
+ cleanup:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ actions: write
13
+ steps:
14
+ - name: Delete caches unused for 3+ days
15
+ # Actions cache is branch-scoped: every PR branch writes its own copy
16
+ # even with an identical key, and GitHub only auto-evicts on the
17
+ # per-repo 10GB cap or 7-day-unused rule. This keeps repos well under
18
+ # that cap instead of relying on eviction churn.
19
+ env:
20
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21
+ REPO: ${{ github.repository }}
22
+ run: |
23
+ cutoff=$(date -u -d '3 days ago' +%s)
24
+ gh api --paginate "repos/$REPO/actions/caches?per_page=100" --jq '.actions_caches[] | "\(.id) \(.last_accessed_at)"' |
25
+ while read -r id ts; do
26
+ age=$(date -u -d "$ts" +%s)
27
+ if [ "$age" -lt "$cutoff" ]; then
28
+ gh api -X DELETE "repos/$REPO/actions/caches/$id" && echo "deleted $id"
29
+ fi
30
+ done
@@ -0,0 +1,65 @@
1
+ # CI for {{appName}}: a thin orchestrator over the reusable workflows in
2
+ # cosmicdriftgamestudio/infra. Jobs only this app needs go into an unmanaged
3
+ # workflow next to this one (e.g. ci-extra.yml).
4
+
5
+ name: CI
6
+
7
+ on:
8
+ push:
9
+ branches: [main]
10
+ pull_request:
11
+ branches: [main]
12
+
13
+ concurrency:
14
+ group: ci-${{ github.ref }}
15
+ cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
16
+
17
+ env:
18
+ HUSKY: "0"
19
+
20
+ jobs:
21
+ test:
22
+ uses: cosmicdriftgamestudio/infra/.github/workflows/_app-test.yml@main
23
+ with:
24
+ ui-guards: {{uiGuards}}
25
+ # The boot gate in kumiko-schema validate demands a provider for file
26
+ # fields; CI only checks that one is configured.
27
+ file-storage-provider: "inmemory"
28
+ secrets: inherit
29
+
30
+ integration:
31
+ uses: cosmicdriftgamestudio/infra/.github/workflows/_app-integration.yml@main
32
+ {{#minio}}
33
+ with:
34
+ minio: true
35
+ {{/minio}}
36
+ secrets: inherit
37
+
38
+ # merge_group included: as a required check in a merge queue, e2e would
39
+ # otherwise never report and block the merge.
40
+ e2e:
41
+ if: contains(fromJSON('["pull_request","merge_group"]'), github.event_name)
42
+ uses: cosmicdriftgamestudio/infra/.github/workflows/_app-e2e.yml@main
43
+ {{#e2eInputs}}
44
+ with:
45
+ {{/e2eInputs}}
46
+ {{#meilisearch}}
47
+ meilisearch: true
48
+ {{/meilisearch}}
49
+ {{#minio}}
50
+ minio: true
51
+ {{/minio}}
52
+ secrets: inherit
53
+
54
+ # Build on main only; the rollout runs through the manual release workflow.
55
+ build:
56
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
57
+ needs: [test, integration]
58
+ permissions:
59
+ contents: read
60
+ packages: write
61
+ uses: cosmicdriftgamestudio/infra/.github/workflows/_docker-build-push.yml@main
62
+ with:
63
+ image-name: {{appName}}
64
+ dockerfile: deploy/Dockerfile
65
+ secrets: inherit
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env sh
2
+ # PRE_PUSH_SKIP is checked here too so the bypass works even without node_modules.
3
+ if [ "${PRE_PUSH_SKIP:-0}" = "1" ]; then
4
+ echo "[pre-push] PRE_PUSH_SKIP=1 — hook skipped"
5
+ exit 0
6
+ fi
7
+
8
+ REPO_ROOT="$(git rev-parse --show-toplevel)"
9
+ if [ -z "$REPO_ROOT" ]; then
10
+ echo "[pre-push] FATAL: git rev-parse --show-toplevel failed — refusing push" >&2
11
+ exit 1
12
+ fi
13
+
14
+ # Walk up so a worktree without its own node_modules resolves via the parent
15
+ # install, but not past an enclosing repository: a bin above that boundary
16
+ # belongs to another project. `[ -x ]` also skips a broken (uninstalled) symlink.
17
+ BIN=""
18
+ DIR="$REPO_ROOT"
19
+ while true; do
20
+ CANDIDATE="$DIR/node_modules/.bin/kumiko-pre-push"
21
+ if [ -x "$CANDIDATE" ]; then
22
+ BIN="$CANDIDATE"
23
+ break
24
+ fi
25
+ if [ "$DIR" = "/" ]; then
26
+ break
27
+ fi
28
+ if [ "$DIR" != "$REPO_ROOT" ] && [ -e "$DIR/.git" ]; then
29
+ break
30
+ fi
31
+ DIR="$(dirname "$DIR")"
32
+ done
33
+
34
+ if [ -z "$BIN" ]; then
35
+ echo "[pre-push] kumiko-pre-push not found in any node_modules/.bin above $REPO_ROOT." >&2
36
+ echo "Run \`bun install\`, or set PRE_PUSH_SKIP=1 to bypass this hook." >&2
37
+ exit 1
38
+ fi
39
+
40
+ cd "$REPO_ROOT" && exec "$BIN" "$@"
@@ -0,0 +1,12 @@
1
+ // Input of the schema tooling (kumiko-schema generate|apply|validate and the
2
+ // boot step of kumiko check), derived from kumiko.config.ts. Edit the feature
3
+ // lists there.
4
+
5
+ import { allAppFeatures } from "@cosmicdrift/kumiko-framework/config";
6
+ import { collectTableMetas, type EntityTableMeta } from "@cosmicdrift/kumiko-framework/db";
7
+ import type { FeatureDefinition } from "@cosmicdrift/kumiko-framework/engine";
8
+ import appConfig from "../kumiko.config";
9
+
10
+ export const FEATURES: readonly FeatureDefinition[] = allAppFeatures(appConfig);
11
+
12
+ export const ENTITY_METAS: readonly EntityTableMeta[] = collectTableMetas(FEATURES);
@@ -0,0 +1,55 @@
1
+ name: release
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ sha:
7
+ description: "Full 40-char main SHA; image sha-<7> must exist"
8
+ required: true
9
+ type: string
10
+
11
+ concurrency:
12
+ group: release-{{appName}}
13
+ cancel-in-progress: false
14
+
15
+ permissions:
16
+ contents: read
17
+ actions: read
18
+
19
+ jobs:
20
+ verify:
21
+ runs-on: ubuntu-latest
22
+ timeout-minutes: 5
23
+ steps:
24
+ - uses: actions/checkout@v7
25
+ with:
26
+ fetch-depth: 0
27
+ - name: Verify SHA
28
+ env:
29
+ SHA: ${{ inputs.sha }}
30
+ GH_TOKEN: ${{ github.token }}
31
+ run: |
32
+ set -euo pipefail
33
+ if ! [[ "$SHA" =~ ^[0-9a-f]{40}$ ]]; then
34
+ echo "::error::sha must be a full 40-char lowercase hex SHA."
35
+ exit 1
36
+ fi
37
+ if ! git merge-base --is-ancestor "$SHA" origin/main; then
38
+ echo "::error::$SHA is not an ancestor of origin/main."
39
+ exit 1
40
+ fi
41
+ count=$(gh api "repos/$GITHUB_REPOSITORY/actions/workflows/ci.yml/runs?head_sha=$SHA&event=push&status=success" --jq '.total_count')
42
+ if [ "${count:-0}" -le 0 ]; then
43
+ echo "::error::No successful CI push run found for $SHA."
44
+ exit 1
45
+ fi
46
+
47
+ deploy:
48
+ needs: verify
49
+ uses: cosmicdriftgamestudio/infra/.github/workflows/_app-deploy.yml@main
50
+ with:
51
+ namespace: {{namespace}}
52
+ deployment: {{deployment}}
53
+ image-name: {{appName}}
54
+ git_sha: ${{ inputs.sha }}
55
+ secrets: inherit