@shivaedev/create-app 0.23.0 → 0.25.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/CHANGELOG.md CHANGED
@@ -1,5 +1,71 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.25.0 - 2026-10-30
4
+
5
+ ### Added
6
+
7
+ - Export generator modules through `@shivaedev/create-app/*.ts` so tooling can reuse scaffolding, template packing and starter updates. Importing `pack.ts` leaves template generation to its direct command invocation.
8
+ - Expose the native submission `cause` on `useEditor`, `useCreate` and `SaveState` so applications can render failures that include defects.
9
+ - Identity's `trustedOrigins` accepts an optional `sameOrigin: { trustedProxy }` policy using the transport guard's loopback and trusted-proxy authority checks. Session resolution supplies the transport peer address; RPC message headers cannot establish proxy trust.
10
+
11
+ ### Changed
12
+
13
+ - Generated applications import React test helpers from their existing `@shivaedev/test-story` development dependency.
14
+ - Generated notes apps derive live list and detail invalidations from repository writes, including word-count jobs, with the owner bucket declared on the stored model.
15
+ - Generated applications keep jobs connection strings redacted and provide one app pg-boss Layer to feature registrations, producers and workers, replacing per-feature connection arguments and Symbol cache keys.
16
+
17
+ ### Fixed
18
+
19
+ - A failed initial commit names the Git command as `git commit -m 'Initialize a generated app'`, without the fallback identity flags.
20
+ - Ignore repeated sign-out dispatch while sign-out is pending.
21
+ - Generated apps send an explicitly signed-out visitor to sign-in when the replacement session receives `Unauthorized` from the notes route.
22
+ - Generated apps retain database failure causes, report constraint violations as conflicts, validate trimmed titles in their Schema, and show the session error screen for malformed session payloads.
23
+ - Keep template preparation and rendering failures as non-enumerable causes, name the failed step and file, and include the cause in CLI error logs.
24
+ - Generated apps accept their own forwarded HTTPS RPC requests without `PUBLIC_URL`, while refusing foreign origins. A configured `PUBLIC_URL` remains the explicit RPC origin allowlist.
25
+
26
+ ### Breaking
27
+
28
+ - `useSignOut` stops follow-up navigation on component unmount or registry disposal. Keep the component mounted until the request completes, or let the replacement session's route policy navigate to sign-in when a session refresh unmounts it first.
29
+ - Move the React test helpers to `@shivaedev/test-story/client/react.ts`. Replace imports from `@shivaedev/react/client/testing.ts` with this path for `render`, `eventually`, `captureReactWarnings`, `expectNoReactWarnings` and their types. Add `@shivaedev/test-story` as a development dependency and install its React helpers' optional peers `react`, `react-dom` and `@effect/atom-react` when using them. React no longer brings `@shivaedev/test` into applications as a runtime dependency.
30
+ - Generated notes apps remove the test-only `notes.whoami` RPC. Read the viewer through identity's session API instead.
31
+ - Notes RPC callers decode raw titles with `NoteFields` or `NoteEditFields` before submitting; title validation now happens in the Schema. Handle database constraint rejections as `Conflict` and unexpected failures as `InternalServerError`.
32
+ - `appFile` validates `package.json` with the starter's concrete manifest schema. Use manifests from `packTemplate`, or supply the complete starter manifest shape with string-valued dependency, script, import and engine maps instead of arbitrary JSON objects.
33
+
34
+ ## 0.24.0 - 2026-10-30
35
+
36
+ ### Added
37
+
38
+ - Inspect running apps locally with browser-check screenshots, test-user sign-in and smoke checks, installing Chromium only when the command runs.
39
+ - Give generated apps an opt-in browser-check script and ignored screenshot folder, outside app CI and ready checks.
40
+ - Generated apps report coverage and JUnit from one stable `CI` job, uploading a `coverage-tests` artifact with commit and job metadata. CI skips draft pull requests, cancels superseded pull-request runs and preserves default-branch measurements. Existing apps receive the workflow through `create-app update`.
41
+ - Quality accepts app migrations referencing the auth user id with `ON DELETE CASCADE` or `ON DELETE SET NULL`, while keeping auth reads and writes behind identity.
42
+ - Identity exports `userReference` from `server/better-auth/userReference.ts` so app migrations share the user table and id column names.
43
+ - Starter notes use a `user_id` foreign key with cascading deletion. A numbered migration renames the existing ownership column and adds the constraint for existing apps.
44
+
45
+ ### Changed
46
+
47
+ - Require Effect 4.0.6 and align the Effect companion package peers and generated starter catalog to the same exact release. Install the 4.0.6 Effect stack together.
48
+ - `@shivaedev/create-app` omits unused chart and tooltip components and Recharts from generated apps, and removes the notes table dependency from minimal apps and their starter updates. Generated guidance explains Quality's test naming, the dev server forwards `/health`, and Railway workers use the default restart policy. Existing apps receive the removals through `create-app update`.
49
+ - The starter's Railway deployment supplies `TRUSTED_PROXY=100.64.0.0/10` and `AUTH_CLIENT_IP_HEADER=x-real-ip` through its shared proxy configuration. Generated deployment docs explain the automatic Railway settings and when a host refuses to boot.
50
+ - New apps include an outbound HTTP adapter example in the notes module, with stories covering success, error statuses and malformed bodies against a fake API.
51
+ - The `story-testing` skill covers how a story reads: one name per actor, actions that name their change, a proven before state, domain outcomes, a separated action, a true title, `outcomes` for several checks, explained setup, one behaviour per story, stories only for plausible regressions, and settling on events. It now applies to package stories as well as app stories.
52
+ - Generated apps record the starter's existing findings for the new story rules in their baseline.
53
+ - Quality applies Biome’s test-title check only to `*.test.*`, `*.spec.*` and `test-support/` files, so ordinary helpers named `describe`, `it` or `test` do not receive test-title findings.
54
+ - Quality and starter guidance explain that a `CreateSpace` component in `spaces/client/` is named `Create.tsx`, keeping the full export name without repeating a folder in the file name.
55
+
56
+ ### Fixed
57
+
58
+ - Register hosted RPC cache-control handling through Effect 4.0.6's request-scoped pre-response API so responses keep `private, no-store`.
59
+ - Accept native RPC's `application/x-ndjson` media type while preserving `application/ndjson` callers at the transport guard.
60
+ - Keep subscriptions open after their HTTP request body completes; closing the socket still cancels them.
61
+
62
+ ### Breaking
63
+
64
+ - `@shivaedev/admin`: Move page declarations and `registerAdmin` handler maps into their owning modules. Combine their registries with `mergeAdminRegistries` in browser composition and their registrations with `mergeAdminRegistrations` in the application host. Registration now exposes its pages; duplicate page ids are rejected by TypeScript as well as at runtime. Keep each module's handler Layer with its page registration.
65
+ - `@shivaedev/create-app`: The starter foundation owns Users and Jobs, and notes registers only its statistics page. Move application pages and handlers into their owning module registrations and combine them at the host; client modules contribute navigation through their own registry. Run `create-app update` to merge the starter side, preserving application customizations through its normal merge flow. Minimal apps retain Users and Jobs when notes is removed.
66
+ - `@shivaedev/server` refuses to start a session host bound to a non-loopback address without proxy trust, with a typed `TrustedProxyRequired` error naming the missing setting. Set `TRUSTED_PROXY` to your proxy's peer IP addresses or CIDR ranges, set `config.trustedProxy`, or deploy with the starter's Railway configuration. Local loopback hosts keep working without it.
67
+ - Specs get new findings from three story rules. `tests/domain-outcomes` reports Effect `Exit`, `Cause` and `Result` uses, `_tag` reads and `"Success"` or `"Failure"` tagged literals: return the outcome in the domain's words from a kit verb or readout. `tests/grouped-outcomes` reports consecutive `expect(yield* …)` checks: write them as rows of one `outcomes` call from `@shivaedev/test-story/server/outcomes.ts`. `tests/wait-on-events` reports sleeps, timers, `eventually`, Vitest fake timers and `TestClock` adjustments: settle on the engine's own signal, and advance the clock in a kit verb named for the time that passes. Record existing findings with `quality baseline write --rule tests/domain-outcomes --rule tests/grouped-outcomes --rule tests/wait-on-events`.
68
+
3
69
  ## 0.23.0 - 2026-10-29
4
70
 
5
71
  ### Changed
package/README.md CHANGED
@@ -52,6 +52,18 @@ Run `pnpm run setup` after cloning the generated repository to install dependenc
52
52
 
53
53
  Run `pnpm dlx @shivaedev/create-app@latest update` in a generated app with a clean Git working tree to take later starter changes. The command reads `.create-app.json`, downloads the recorded generator’s starter and uses Git’s three-way merge to replay its changes against the current starter; app edits survive, deleted files stay deleted, and conflicts are listed and left for you to resolve. A successful merge records the current generator version; review the changes, run `pnpm install` and commit them yourself. An update adds the admin Users registration and route to an app that lacks them, and lists conflicts where the app customized those parts.
54
54
 
55
+ ### Reuse the generator
56
+
57
+ Generator modules are available through `@shivaedev/create-app/*.ts`. Compose their Effects with your application’s services when you need scaffolding outside the CLI:
58
+
59
+ ```ts
60
+ import { packTemplate } from "@shivaedev/create-app/packTemplate.ts";
61
+
62
+ const template = packTemplate("/path/to/starter", "/path/to/template.json");
63
+ ```
64
+
65
+ `packTemplate` reads its filesystem service from the Effect environment. Node integrations need `@effect/platform-node` and `@effect/platform-node-shared`; the CLI bundles them. Test-support files stay outside the published archive.
66
+
55
67
  ### Requirements
56
68
 
57
69
  Use Node 24 or newer and pnpm. See the [framework quickstart](https://github.com/ShivaeDev/platform/blob/main/docs/framework/quickstart.md) for the starter's application and deployment workflow.
@@ -1,11 +1,12 @@
1
- import { Runtime } from "effect";
2
1
  declare const CreateAppError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
3
2
  readonly _tag: "CreateAppError";
4
3
  } & Readonly<A>;
5
4
  export declare class CreateAppError extends CreateAppError_base<{
6
5
  readonly message: string;
7
6
  }> {
8
- readonly [Runtime.errorReported] = false;
7
+ constructor(fields: {
8
+ readonly message: string;
9
+ }, options?: ErrorOptions);
9
10
  }
10
11
  export {};
11
12
  //# sourceMappingURL=CreateAppError.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CreateAppError.d.ts","sourceRoot":"","sources":["../src/CreateAppError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,OAAO,EAAE,MAAM,QAAQ,CAAC;;;;AAEvC,qBAAa,cAAe,SAAQ,oBAAmC;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;IACnG,SAAkB,CAAC,OAAO,CAAC,aAAa,CAAC,SAAS;CAClD"}
1
+ {"version":3,"file":"CreateAppError.d.ts","sourceRoot":"","sources":["../src/CreateAppError.ts"],"names":[],"mappings":";;;AAEA,qBAAa,cAAe,SAAQ,oBAAmC;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;IACnG,YAAY,MAAM,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,OAAO,CAAC,EAAE,YAAY,EAGvE;CACD"}
@@ -1,5 +1,8 @@
1
- import { Data, Runtime } from "effect";
1
+ import { Data } from "effect";
2
2
  export class CreateAppError extends Data.TaggedError("CreateAppError") {
3
- [Runtime.errorReported] = false;
3
+ constructor(fields, options) {
4
+ super(fields);
5
+ Object.defineProperty(this, "cause", { value: options?.cause });
6
+ }
4
7
  }
5
8
  //# sourceMappingURL=CreateAppError.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CreateAppError.js","sourceRoot":"","sources":["../src/CreateAppError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEvC,MAAM,OAAO,cAAe,SAAQ,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAA+B;IACjF,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC;CAClD"}
1
+ {"version":3,"file":"CreateAppError.js","sourceRoot":"","sources":["../src/CreateAppError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAE9B,MAAM,OAAO,cAAe,SAAQ,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAA+B;IACnG,YAAY,MAAoC,EAAE,OAAsB;QACvE,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACjE,CAAC;CACD"}
@@ -1 +1 @@
1
- {"version":3,"file":"appFiles.d.ts","sourceRoot":"","sources":["../src/appFiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAKrC,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,UAKxC;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,2BAgBlE"}
1
+ {"version":3,"file":"appFiles.d.ts","sourceRoot":"","sources":["../src/appFiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,UAKxC;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,2BAgBlE"}
package/dist/appFiles.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Buffer } from "node:buffer";
2
- import { Schema } from "effect";
3
- const decodeManifest = Schema.decodeUnknownSync(Schema.fromJsonString(Schema.Record(Schema.String, Schema.Unknown)));
2
+ import { decodeManifest, manifestJson } from "#template.ts";
4
3
  export function databaseName(name) {
5
4
  return name
6
5
  .replaceAll(/[.-]/gu, "_")
@@ -9,7 +8,7 @@ export function databaseName(name) {
9
8
  }
10
9
  export function appFile(path, content, name) {
11
10
  if (path === "package.json") {
12
- return Buffer.from(`${JSON.stringify({ ...decodeManifest(content.toString()), name }, null, "\t")}\n`);
11
+ return Buffer.from(manifestJson({ ...decodeManifest(content.toString()), name }));
13
12
  }
14
13
  if (path === ".env.example") {
15
14
  return Buffer.from(content
@@ -1 +1 @@
1
- {"version":3,"file":"appFiles.js","sourceRoot":"","sources":["../src/appFiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,MAAM,cAAc,GAAG,MAAM,CAAC,iBAAiB,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAErH,MAAM,UAAU,YAAY,CAAC,IAAY;IACxC,OAAO,IAAI;SACT,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC;SACzB,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC;SAC7B,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,OAAe,EAAE,IAAY;IAClE,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACxG,CAAC;IACD,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC,IAAI,CACjB,OAAO;aACL,QAAQ,EAAE;aACV,UAAU,CAAC,aAAa,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;aACtD,UAAU,CAAC,cAAc,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAC1D,CAAC;IACH,CAAC;IACD,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"appFiles.js","sourceRoot":"","sources":["../src/appFiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5D,MAAM,UAAU,YAAY,CAAC,IAAY;IACxC,OAAO,IAAI;SACT,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC;SACzB,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC;SAC7B,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY,EAAE,OAAe,EAAE,IAAY;IAClE,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC,IAAI,CACjB,OAAO;aACL,QAAQ,EAAE;aACV,UAAU,CAAC,aAAa,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC;aACtD,UAAU,CAAC,cAAc,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAC1D,CAAC;IACH,CAAC;IACD,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC"}