@beignet/cli 0.0.51 → 0.0.53
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 +46 -0
- package/README.md +182 -19
- package/dist/analysis/layers.d.ts +2 -0
- package/dist/analysis/layers.d.ts.map +1 -1
- package/dist/analysis/layers.js +9 -2
- package/dist/analysis/layers.js.map +1 -1
- package/dist/analysis/port-wiring.d.ts +4 -2
- package/dist/analysis/port-wiring.d.ts.map +1 -1
- package/dist/analysis/port-wiring.js +41 -11
- package/dist/analysis/port-wiring.js.map +1 -1
- package/dist/analysis/source-files.d.ts +15 -0
- package/dist/analysis/source-files.d.ts.map +1 -0
- package/dist/analysis/source-files.js +52 -0
- package/dist/analysis/source-files.js.map +1 -0
- package/dist/analysis/source-index.d.ts +2 -1
- package/dist/analysis/source-index.d.ts.map +1 -1
- package/dist/analysis/source-index.js +34 -5
- package/dist/analysis/source-index.js.map +1 -1
- package/dist/analysis/workspace-routes.d.ts +8 -0
- package/dist/analysis/workspace-routes.d.ts.map +1 -0
- package/dist/analysis/workspace-routes.js +291 -0
- package/dist/analysis/workspace-routes.js.map +1 -0
- package/dist/analysis/workspace.d.ts +24 -3
- package/dist/analysis/workspace.d.ts.map +1 -1
- package/dist/analysis/workspace.js +184 -43
- package/dist/analysis/workspace.js.map +1 -1
- package/dist/app-map-changes.d.ts.map +1 -1
- package/dist/app-map-changes.js +24 -14
- package/dist/app-map-changes.js.map +1 -1
- package/dist/app-map.d.ts.map +1 -1
- package/dist/app-map.js +87 -81
- package/dist/app-map.js.map +1 -1
- package/dist/check.d.ts +12 -0
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +92 -25
- package/dist/check.js.map +1 -1
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -0
- package/dist/config.js.map +1 -1
- package/dist/git-changes.d.ts +17 -1
- package/dist/git-changes.d.ts.map +1 -1
- package/dist/git-changes.js +118 -84
- package/dist/git-changes.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -3
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts.map +1 -1
- package/dist/inspect.js +424 -129
- package/dist/inspect.js.map +1 -1
- package/dist/lint.d.ts.map +1 -1
- package/dist/lint.js +108 -43
- package/dist/lint.js.map +1 -1
- package/dist/make/shared.js +1 -1
- package/dist/make.js +18 -1
- package/dist/make.js.map +1 -1
- package/dist/mcp.js +1 -1
- package/dist/mcp.js.map +1 -1
- package/dist/provider-add.js +2 -2
- package/dist/provider-add.js.map +1 -1
- package/dist/provider-audit.d.ts.map +1 -1
- package/dist/provider-audit.js +22 -6
- package/dist/provider-audit.js.map +1 -1
- package/dist/templates/agents.d.ts.map +1 -1
- package/dist/templates/agents.js +36 -13
- package/dist/templates/agents.js.map +1 -1
- package/dist/templates/base.js +5 -5
- package/dist/templates/db/mysql.d.ts.map +1 -1
- package/dist/templates/db/mysql.js +51 -22
- package/dist/templates/db/mysql.js.map +1 -1
- package/dist/templates/db/postgres.d.ts.map +1 -1
- package/dist/templates/db/postgres.js +60 -20
- package/dist/templates/db/postgres.js.map +1 -1
- package/dist/templates/db/sqlite.d.ts.map +1 -1
- package/dist/templates/db/sqlite.js +51 -23
- package/dist/templates/db/sqlite.js.map +1 -1
- package/dist/templates/shadcn.js +1 -1
- package/dist/templates/shadcn.js.map +1 -1
- package/dist/templates/shared.js +6 -6
- package/dist/templates/shared.js.map +1 -1
- package/dist/templates/testing.d.ts.map +1 -1
- package/dist/templates/testing.js +7 -19
- package/dist/templates/testing.js.map +1 -1
- package/dist/test-discovery.d.ts +9 -0
- package/dist/test-discovery.d.ts.map +1 -0
- package/dist/test-discovery.js +40 -0
- package/dist/test-discovery.js.map +1 -0
- package/package.json +8 -5
- package/skills/app-structure/SKILL.md +74 -7
- package/src/analysis/layers.ts +13 -2
- package/src/analysis/port-wiring.ts +68 -11
- package/src/analysis/source-files.ts +61 -0
- package/src/analysis/source-index.ts +56 -4
- package/src/analysis/workspace-routes.ts +385 -0
- package/src/analysis/workspace.ts +302 -59
- package/src/app-map-changes.ts +41 -13
- package/src/app-map.ts +114 -103
- package/src/check.ts +115 -25
- package/src/config.ts +33 -0
- package/src/git-changes.ts +218 -86
- package/src/index.ts +33 -5
- package/src/inspect.ts +608 -156
- package/src/lint.ts +152 -48
- package/src/make/shared.ts +1 -1
- package/src/make.ts +31 -1
- package/src/mcp.ts +1 -1
- package/src/provider-add.ts +2 -2
- package/src/provider-audit.ts +30 -10
- package/src/templates/agents.ts +36 -13
- package/src/templates/base.ts +5 -5
- package/src/templates/db/mysql.ts +51 -22
- package/src/templates/db/postgres.ts +60 -20
- package/src/templates/db/sqlite.ts +51 -23
- package/src/templates/shadcn.ts +1 -1
- package/src/templates/shared.ts +6 -6
- package/src/templates/testing.ts +12 -19
- package/src/test-discovery.ts +53 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# @beignet/cli
|
|
2
2
|
|
|
3
|
+
## 0.0.53
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6ef881c: Reject incompatible default route-binder inputs at compile time and classify
|
|
8
|
+
type-erased runtime mismatches as framework-owned validation errors. Generated
|
|
9
|
+
resource cursors now remain optional at the request boundary and normalize to
|
|
10
|
+
nullable repository pagination state inside the use case.
|
|
11
|
+
- 71f1de1: Generate StoragePort imports from the public ports subpath for S3 and Vercel Blob setup, including apps that already declare local storage.
|
|
12
|
+
- e1a559d: Add authenticated string encryption through EncryptionPort and createEncryption, with optional context binding, decryption through previous keys, and non-sensitive failure errors. Add beignet encryption key for key generation, server import checks, and guidance for rotation and recovery.
|
|
13
|
+
- ce6a5f6: Require patched Next.js and Nodemailer releases, and use them in generated apps and SMTP provider setup.
|
|
14
|
+
- faf58ad: Clarify form adapter installation and migration, document TanStack Form UI
|
|
15
|
+
generator restrictions, and correct React Form reference examples.
|
|
16
|
+
- edebbea: Add `@beignet/react-form`, a TanStack Form adapter that installs a contract body schema as a Standard Schema validator, types the `onServer` error slot, and maps client errors with `serverErrorMap`. `beignet lint` keeps the form packages out of domain and use-case code, `beignet doctor` expects `client/forms.ts` for either form adapter, and `beignet make feature --with ui` refuses to add React Hook Form components to an app that depends on `@beignet/react-form`.
|
|
17
|
+
- 4df0522: Add typed `cacheEntries` and `updateCachedQueries` helpers with partial parameter matching, and declarative, awaited mutation invalidation. Preserve native query metadata and snapshot success defaults for each executing mutation. Prevent recursive execution of composed mutation defaults. Append an `infinite` segment to generated infinite-query keys so manually seeded and hydrated infinite data stays separate from standard responses; discard persisted infinite caches from the old key format when upgrading. Reserve the `beignet` key prefix for contract data. Require TanStack React Query 5.102 or newer and align generated dependency ranges.
|
|
18
|
+
- 8f98e8b: Add opt-in workspace source analysis for shared application and infrastructure packages. Follow package exports in architecture lint, route inspection, port wiring, and app maps while keeping generators and repairs app-local.
|
|
19
|
+
|
|
20
|
+
Preserve per-file Next.js handlers, trace route registration from the exported server, reject imports into omitted source packages, and follow wiring aliases when inferring application ports.
|
|
21
|
+
|
|
22
|
+
Resolve package import aliases, import-then-export barrels, and contract aliases by source declaration so repeated export names and loader-local variables do not produce incorrect route matches.
|
|
23
|
+
|
|
24
|
+
- Updated dependencies [6ef881c]
|
|
25
|
+
- Updated dependencies [e1a559d]
|
|
26
|
+
- Updated dependencies [edebbea]
|
|
27
|
+
- @beignet/core@0.0.53
|
|
28
|
+
|
|
29
|
+
## 0.0.52
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- b39bb6e: Clarify that Beignet applications require Node.js 22.12 or newer and can use
|
|
34
|
+
npm, pnpm, Yarn, or Bun for package management and framework commands.
|
|
35
|
+
- 1ec2ed2: Record Git source state around `beignet check` and mark the run unsuccessful when source changes during validation.
|
|
36
|
+
- d4bb9fb: Map tests across canonical and configured app roots so app maps, explanations, and changed-impact reports include adjacent application, infrastructure, and server tests.
|
|
37
|
+
- a0b0e53: Analyze JavaScript, JSX, and mixed JavaScript/TypeScript application architecture in lint, map, changed-impact, and explain workflows.
|
|
38
|
+
- 06eb712: Support Better Auth 1.7, scaffold its issuer-scoped account identity schema, and warn when upgraded Drizzle apps still need the account migration.
|
|
39
|
+
- ac76ab9: Reject event payloads with `EventTransportError` when they are not canonical JSON or change when validated again after transport, before publishing or recording them durably. Direct memory and recording-bus publication must be awaited while validation completes.
|
|
40
|
+
- 9d52cb7: Generate apps with patched integration dependencies and require maintained
|
|
41
|
+
Next.js, Inngest, and Vercel Blob peer versions.
|
|
42
|
+
- Updated dependencies [b39bb6e]
|
|
43
|
+
- Updated dependencies [33bd8a2]
|
|
44
|
+
- Updated dependencies [ac76ab9]
|
|
45
|
+
- Updated dependencies [64dca8d]
|
|
46
|
+
- Updated dependencies [a50ef66]
|
|
47
|
+
- @beignet/core@0.0.52
|
|
48
|
+
|
|
3
49
|
## 0.0.51
|
|
4
50
|
|
|
5
51
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
Command-line tools for creating and maintaining Beignet apps.
|
|
8
8
|
|
|
9
|
-
Beignet requires Node.js 22.12 or newer. Bun
|
|
10
|
-
CLI commands.
|
|
9
|
+
Beignet requires Node.js 22.12 or newer. Bun is optional; npm, pnpm, Yarn, and
|
|
10
|
+
Bun can run CLI commands.
|
|
11
11
|
|
|
12
12
|
The package ships a single `beignet` bin. Generated apps install
|
|
13
13
|
`@beignet/cli` as a dev dependency and add a `beignet` package script, so the
|
|
@@ -49,7 +49,7 @@ add. Passing any selection flag (`--api`, `--db`, `--providers`, or
|
|
|
49
49
|
non-interactive defaults (the full-stack SQLite starter with `bun`) even on a
|
|
50
50
|
terminal. Non-interactive runs in scripts and CI behave exactly as before.
|
|
51
51
|
|
|
52
|
-
By default the CLI creates
|
|
52
|
+
By default the CLI creates an app using Next.js 16.3.3 or newer within v16, with:
|
|
53
53
|
|
|
54
54
|
- Contract-first todos API routes
|
|
55
55
|
- Better Auth routes and Beignet auth provider wiring
|
|
@@ -231,7 +231,7 @@ beignet db seed [--dry-run] [--json] [--cwd <dir>]
|
|
|
231
231
|
beignet db reset [--dry-run] [--json] [--cwd <dir>]
|
|
232
232
|
beignet db schema sync [--dialect sqlite|postgres|mysql] [--tables audit,idempotency,outbox] [--output <path>] [--dry-run] [--json] [--cwd <dir>]
|
|
233
233
|
beignet routes [--json] [--cwd <dir>]
|
|
234
|
-
beignet map [--json] [--feature <name>] [--kind <kinds>] [--cwd <dir>]
|
|
234
|
+
beignet map [--json] [--feature <name>] [--kind <kinds>] [--changed] [--base <ref>] [--cwd <dir>]
|
|
235
235
|
beignet explain <kind> <target> [--json] [--cwd <dir>]
|
|
236
236
|
beignet check [--json] [--fix] [--preflight] [--preflight-connect] [--connect-timeout-ms <ms>] [--cwd <dir>]
|
|
237
237
|
beignet preflight [--connect] [--connect-timeout-ms <ms>] [--json] [--cwd <dir>]
|
|
@@ -506,6 +506,110 @@ export default defineConfig({
|
|
|
506
506
|
This affects CLI provider auditing only. It does not skip `createEnv(...)` or
|
|
507
507
|
provider runtime configuration validation.
|
|
508
508
|
|
|
509
|
+
## Workspace source packages
|
|
510
|
+
|
|
511
|
+
A web app and a worker can share Beignet application code and infrastructure
|
|
512
|
+
through ordinary workspace packages. Each runtime owns startup and shutdown;
|
|
513
|
+
shared packages export contracts, use cases, port types, and adapter factories.
|
|
514
|
+
Sharing an adapter implementation does not share an in-memory instance across
|
|
515
|
+
processes. Use the same persistent database or service when runtimes need shared
|
|
516
|
+
state.
|
|
517
|
+
|
|
518
|
+
Opt into source analysis from the app's `beignet.config.ts`:
|
|
519
|
+
|
|
520
|
+
```ts
|
|
521
|
+
import { defineConfig } from "@beignet/cli/config";
|
|
522
|
+
|
|
523
|
+
export default defineConfig({
|
|
524
|
+
framework: "web",
|
|
525
|
+
workspace: {
|
|
526
|
+
packages: ["../../packages/application", "../../packages/infra"],
|
|
527
|
+
},
|
|
528
|
+
});
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
List every source package to inspect, including transitive dependencies. Paths
|
|
532
|
+
are relative to the app and may point to sibling packages. Each package needs a
|
|
533
|
+
unique `package.json` name and must be reachable through declared dependencies
|
|
534
|
+
from the app. Package roots cannot overlap. Beignet does not discover or inspect
|
|
535
|
+
all of `node_modules`; install workspace dependencies using your package manager.
|
|
536
|
+
Turborepo can schedule the package scripts but is not required by Beignet.
|
|
537
|
+
|
|
538
|
+
Each package uses its own `beignet.config.*` paths and `tsconfig.json` (or
|
|
539
|
+
`jsconfig.json`). An application package can keep the usual `features/`, `ports/`,
|
|
540
|
+
and `lib/` layout. An infra package containing adapters under `src/` can declare:
|
|
541
|
+
|
|
542
|
+
```ts
|
|
543
|
+
// packages/infra/beignet.config.ts
|
|
544
|
+
import { defineConfig } from "@beignet/cli/config";
|
|
545
|
+
|
|
546
|
+
export default defineConfig({
|
|
547
|
+
paths: { portWiring: "src/port-wiring.ts" },
|
|
548
|
+
});
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
This identifies `src/` as the package's infrastructure layer. A package that
|
|
552
|
+
only exports adapter factories does not need a port-wiring file. The consuming
|
|
553
|
+
app can compose those factories in its own `infra/port-wiring.ts`.
|
|
554
|
+
|
|
555
|
+
Expose source entrypoints through package exports, for example:
|
|
556
|
+
|
|
557
|
+
```json
|
|
558
|
+
{
|
|
559
|
+
"name": "@example/infra",
|
|
560
|
+
"private": true,
|
|
561
|
+
"type": "module",
|
|
562
|
+
"exports": { "./notes": "./src/notes.ts" },
|
|
563
|
+
"dependencies": { "@example/application": "workspace:*" }
|
|
564
|
+
}
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
The normal TypeScript resolver handles exports, subpaths, conditions, package
|
|
568
|
+
imports, and configured aliases. Configure the consuming build and runtime to
|
|
569
|
+
resolve the same source. Beignet does not rewrite imports or redirect built
|
|
570
|
+
exports to guessed source files. Missing exports and entries that resolve only
|
|
571
|
+
to excluded build output produce `BEIGNET_WORKSPACE_IMPORT` diagnostics.
|
|
572
|
+
|
|
573
|
+
`beignet lint` follows imports and reexports across included packages and applies
|
|
574
|
+
each owner's architecture rules. Moving an adapter to a package does not make
|
|
575
|
+
it accessible to use cases or browser code. Cross-package imports require a
|
|
576
|
+
dependency declaration in the importing package, including type-only imports.
|
|
577
|
+
Relative imports, TypeScript aliases, and `package.json#imports` aliases that
|
|
578
|
+
resolve outside the configured source roots also produce a workspace diagnostic;
|
|
579
|
+
include the owning source package in `workspace.packages`. Aliases to installed
|
|
580
|
+
external dependencies remain external imports.
|
|
581
|
+
|
|
582
|
+
App-owned provider checks recognize reexported `AppPorts` declarations and
|
|
583
|
+
provider metadata in hoisted `node_modules` installations. Inferred declarations
|
|
584
|
+
such as `AppPorts = typeof initialPorts` follow the underlying wiring declaration
|
|
585
|
+
through reexport aliases. Barrels may import a symbol and then export it, including
|
|
586
|
+
type-only exports of shared port interfaces.
|
|
587
|
+
|
|
588
|
+
`beignet routes` and `doctor` inspect shared contracts and explicit
|
|
589
|
+
`defineRoutes(...)` / `defineRouteGroup(...)` composition from the selected
|
|
590
|
+
server. Inspection follows the exported `server` or the server returned by an
|
|
591
|
+
exported `getServer = createNextServerLoader(...)`. Unrelated server factories
|
|
592
|
+
do not register routes, and verified per-file Next.js handlers remain valid
|
|
593
|
+
without central registration. Contract matching follows imports and local aliases
|
|
594
|
+
to the declaration, so shared export names and loader-local variables remain
|
|
595
|
+
distinct. Computed or ambiguous workspace route registration produces
|
|
596
|
+
`BEIGNET_WORKSPACE_ROUTES_UNRESOLVED`. `map` and `explain` include shared source
|
|
597
|
+
and qualify shared feature names, for example `@example/application:notes`.
|
|
598
|
+
Evidence paths remain relative to the selected app and can contain `../`.
|
|
599
|
+
`map --changed` includes changes to configured source packages.
|
|
600
|
+
|
|
601
|
+
Keep lifecycle provider registration, environment configuration, database
|
|
602
|
+
commands, and operational workflow registries app-owned. Provider and
|
|
603
|
+
operational doctor checks still use those app conventions; this source analysis
|
|
604
|
+
does not make arbitrary imported runtime factories statically verifiable.
|
|
605
|
+
Worker-only packages can use `lint` to check their dependencies; the HTTP-focused
|
|
606
|
+
`routes` and `doctor` commands run against the web app.
|
|
607
|
+
|
|
608
|
+
Generators and doctor repairs remain scoped to the selected app. `paths.*`
|
|
609
|
+
values must still stay inside that app; `workspace.packages` grants read-only
|
|
610
|
+
analysis, not permission to generate or repair files in another package. The
|
|
611
|
+
standard single-app examples remain the default architecture.
|
|
612
|
+
|
|
509
613
|
## Generate a contract
|
|
510
614
|
|
|
511
615
|
Use `make contract` when you want to start with the HTTP contract only:
|
|
@@ -582,6 +686,12 @@ invalidates the generated list query. If the app does not have one yet, the
|
|
|
582
686
|
generator also creates the canonical `client/forms.ts` adapter and installs the
|
|
583
687
|
React Hook Form dependencies.
|
|
584
688
|
|
|
689
|
+
The addon targets React Hook Form. In an app that depends on
|
|
690
|
+
`@beignet/react-form`, both `--with ui` and `--recipe full-slice` stop with
|
|
691
|
+
guidance. Generate the feature without those options, then write its component
|
|
692
|
+
using the [TanStack Form guide](https://beignetjs.com/react-form). You can still
|
|
693
|
+
select other addons with `--with`.
|
|
694
|
+
|
|
585
695
|
Use the named full-slice recipe when you want a richer reference slice:
|
|
586
696
|
|
|
587
697
|
```bash
|
|
@@ -951,6 +1061,21 @@ Run `make event <feature.event>` first, then generate listeners for that event.
|
|
|
951
1061
|
repeated runs skip identical files and avoid duplicate wiring. If a generated
|
|
952
1062
|
file exists with different content, the command stops unless you pass `--force`.
|
|
953
1063
|
|
|
1064
|
+
## Generate an encryption key
|
|
1065
|
+
|
|
1066
|
+
```bash
|
|
1067
|
+
beignet encryption key
|
|
1068
|
+
beignet encryption key --json
|
|
1069
|
+
```
|
|
1070
|
+
|
|
1071
|
+
Prints a new `base64:`-prefixed 256-bit key for
|
|
1072
|
+
`createEncryption(...)` from `@beignet/core/encryption`. JSON output contains
|
|
1073
|
+
`schemaVersion: 1` and `key`. The command works outside an app and does not
|
|
1074
|
+
read or update environment files. Put the key into your server secret store;
|
|
1075
|
+
keep command output out of shared logs and never replace a key without retaining
|
|
1076
|
+
the keys needed to read existing data. See [Encryption](https://beignetjs.com/encryption)
|
|
1077
|
+
for wiring, rolling rotation, and backup recovery.
|
|
1078
|
+
|
|
954
1079
|
## Database lifecycle
|
|
955
1080
|
|
|
956
1081
|
Use `beignet db` from an app root to run database workflow scripts through one
|
|
@@ -1070,6 +1195,22 @@ tables, OpenAPI exposure, tests, cross-feature dependencies, doctor/lint
|
|
|
1070
1195
|
findings, and unresolved references. Every node has a stable ID and source;
|
|
1071
1196
|
every edge carries source evidence and confidence.
|
|
1072
1197
|
|
|
1198
|
+
Source analysis covers TypeScript (`.ts`, `.tsx`, `.mts`, and `.cts`) and
|
|
1199
|
+
JavaScript (`.js`, `.jsx`, `.mjs`, and `.cjs`). Statically recognizable
|
|
1200
|
+
Beignet declarations using ES module exports become the same stable concept
|
|
1201
|
+
nodes as their TypeScript equivalents, while imports, re-exports, literal
|
|
1202
|
+
dynamic imports, and CommonJS `require()` calls contribute dependency evidence
|
|
1203
|
+
across mixed-language graphs.
|
|
1204
|
+
|
|
1205
|
+
Test nodes include JavaScript and TypeScript files named with `.test` or `.spec`
|
|
1206
|
+
under Beignet's canonical app test roots and any relevant roots configured
|
|
1207
|
+
through `beignet.config.*`.
|
|
1208
|
+
Tests inside a feature retain feature ownership and a `contains-test` edge;
|
|
1209
|
+
adjacent app, infra, server, and top-level tests remain app-level nodes. When
|
|
1210
|
+
one of those tests imports changed source, `map --changed` can report it as an
|
|
1211
|
+
exact reverse-import consumer. That is impact evidence, not proof that the test
|
|
1212
|
+
covers every behavior affected by the change.
|
|
1213
|
+
|
|
1073
1214
|
The JSON app map retains failed local module references as explicit
|
|
1074
1215
|
`local_import_unresolved` entries instead of silently omitting their edges. It
|
|
1075
1216
|
also reports `contract_declaration_unresolved` when an exported direct or
|
|
@@ -1168,14 +1309,24 @@ and `server/index.ts` is accepted when `app-context.ts` is missing so doctor
|
|
|
1168
1309
|
can report the drift. Other package roots stop before lint, doctor, or app
|
|
1169
1310
|
scripts run.
|
|
1170
1311
|
|
|
1312
|
+
When the app is inside a Git worktree, `check` captures the repository HEAD,
|
|
1313
|
+
index, worktree, and non-ignored untracked files before and after validation.
|
|
1314
|
+
If the ending source-state hash differs from the baseline, the result is
|
|
1315
|
+
stale, `ok` is false, and the command exits non-zero even when every validation
|
|
1316
|
+
step passed. Rerun `check` against the resulting source. Untracked build and
|
|
1317
|
+
coverage output excluded by Git ignore rules does not affect the hash. Outside
|
|
1318
|
+
Git, validation continues and reports source provenance as unavailable;
|
|
1319
|
+
corrupt or unreadable Git state still fails loudly.
|
|
1320
|
+
|
|
1171
1321
|
Use `beignet check --fix` to apply doctor's eligible low-risk fixes
|
|
1172
|
-
before
|
|
1173
|
-
(`schemaVersion: 1`) with the step list, statuses,
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
check alone or its
|
|
1322
|
+
before the provenance baseline and validation steps. `beignet check --json`
|
|
1323
|
+
returns a versioned payload (`schemaVersion: 1`) with the step list, statuses,
|
|
1324
|
+
captured failure output, applied fixes, and starting and ending provenance.
|
|
1325
|
+
Add `--preflight` to run the disconnected runtime environment gate after
|
|
1326
|
+
strict doctor. Use `--preflight-connect` when the same check should also
|
|
1327
|
+
inspect migration status and dependency health; it implies `--preflight`.
|
|
1328
|
+
The individual commands below still work when you need one check alone or its
|
|
1329
|
+
`--format github` output.
|
|
1179
1330
|
|
|
1180
1331
|
## Gate the deploy environment
|
|
1181
1332
|
|
|
@@ -1225,7 +1376,8 @@ Run `lint` when you want the CLI to enforce Beignet dependency direction:
|
|
|
1225
1376
|
beignet lint
|
|
1226
1377
|
```
|
|
1227
1378
|
|
|
1228
|
-
The command
|
|
1379
|
+
The command analyzes `.ts`, `.tsx`, `.mts`, `.cts`, `.js`, `.jsx`, `.mjs`, and
|
|
1380
|
+
`.cjs` files. It recognizes imports and re-exports, `require()`, import
|
|
1229
1381
|
assignments, and literal dynamic imports. It fails when app layers reach into
|
|
1230
1382
|
runtime or framework layers, including domain, use case, workflow, policy,
|
|
1231
1383
|
port, contract, route, schema, seed, agent capability, feature helper, infra,
|
|
@@ -1250,11 +1402,13 @@ application layers cannot depend back on those adapters. Seeds may compose
|
|
|
1250
1402
|
factories and app ports, but not concrete infra, providers, UI, or runtime
|
|
1251
1403
|
composition.
|
|
1252
1404
|
|
|
1253
|
-
Local imports are resolved with the app's complete `tsconfig.json
|
|
1254
|
-
|
|
1255
|
-
`baseUrl`, every `paths` alias such as `@/*`,
|
|
1256
|
-
with multiple targets. The CLI uses
|
|
1257
|
-
|
|
1405
|
+
Local imports are resolved with the app's complete `tsconfig.json`, or its
|
|
1406
|
+
`jsconfig.json` when no TypeScript config exists, before dependency direction
|
|
1407
|
+
is classified. That includes `baseUrl`, every `paths` alias such as `@/*`,
|
|
1408
|
+
`~/*`, or `#app/*`, and aliases with multiple targets. The CLI uses
|
|
1409
|
+
TypeScript's config parser and resolver, so JSON comments and extended configs
|
|
1410
|
+
follow the same rules as the compiler. Beignet enables JavaScript resolution
|
|
1411
|
+
for this read-only analysis without changing the app's compiler configuration.
|
|
1258
1412
|
|
|
1259
1413
|
Import diagnostics include 1-based `line` and `column` positions and preserve
|
|
1260
1414
|
separate occurrences of the same module specifier. Human output prints
|
|
@@ -1351,7 +1505,9 @@ Today it detects:
|
|
|
1351
1505
|
- Devtools routes without authorization or an explicit local-only development opt-in
|
|
1352
1506
|
- Cron routes that do not use `CRON_SECRET`
|
|
1353
1507
|
- Installed provider packages without expected environment configuration
|
|
1354
|
-
- Better Auth providers without an auth route or trusted-origin configuration
|
|
1508
|
+
- Better Auth providers without an auth route or trusted-origin configuration,
|
|
1509
|
+
and Better Auth 1.7 Drizzle apps missing `account.issuer` or the required
|
|
1510
|
+
compound identity index
|
|
1355
1511
|
- Central servers that omit `createSecurityHeadersHooks(...)`
|
|
1356
1512
|
- Credentialed wildcard CORS configuration
|
|
1357
1513
|
- Notification dispatchers that bypass `ctx.ports.notifications`
|
|
@@ -1379,6 +1535,11 @@ Supported presets are `flags-openfeature`, `jobs-bullmq`, `jobs-inngest`,
|
|
|
1379
1535
|
the exact file changes. The same presets can be selected at create time with
|
|
1380
1536
|
`--providers`.
|
|
1381
1537
|
|
|
1538
|
+
The storage presets declare `StoragePort` from `@beignet/core/ports` and reuse
|
|
1539
|
+
that declaration if your app already has local storage. Before switching storage
|
|
1540
|
+
providers, remove the previous provider entry, import, and unused provider
|
|
1541
|
+
package; keep the app's `storage` port and deferred binding.
|
|
1542
|
+
|
|
1382
1543
|
Use `beignet provider audit` when you want a report-only inventory of the
|
|
1383
1544
|
provider packages installed in an app. The human audit prints provider
|
|
1384
1545
|
metadata validity, registration status, required env, required tables, and
|
|
@@ -1474,7 +1635,9 @@ Tools:
|
|
|
1474
1635
|
`{ kind, target }`, returning relationships, conventions, findings,
|
|
1475
1636
|
suggested files, and follow-up commands (read-only)
|
|
1476
1637
|
- `check` - run the complete validation loop and return versioned step
|
|
1477
|
-
results, bounded failure output, durations, and
|
|
1638
|
+
results, bounded failure output, durations, starting and ending source
|
|
1639
|
+
provenance, and overall `ok`. An ending fingerprint that differs from the
|
|
1640
|
+
baseline makes the result stale and unsuccessful. The tool accepts
|
|
1478
1641
|
`{ preflight?: boolean, preflightConnect?: boolean, connectTimeoutMs?: number, timeoutMs?: number }`,
|
|
1479
1642
|
cancels the active script with the MCP request, and does not apply Beignet
|
|
1480
1643
|
fixes. `preflightConnect` implies preflight and adds migration and dependency
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { type ResolvedBeignetConfig } from "../config.js";
|
|
2
|
+
import { type AnalysisWorkspace } from "./workspace.js";
|
|
3
|
+
export declare function classifyWorkspaceSourcePath(file: string, workspace: AnalysisWorkspace): SourceLayer;
|
|
2
4
|
export type SourceLayer = "app" | "app-context" | "agent-capability" | "client" | "component" | "contract" | "domain" | "feature-helper" | "feature-port" | "infra" | "lib" | "policy" | "port" | "route" | "schema" | "seed" | "server" | "test" | "use-case" | "workflow" | "unknown";
|
|
3
5
|
export declare function classifySourcePath(filePath: string, config: ResolvedBeignetConfig): SourceLayer;
|
|
4
6
|
export declare function canonicalFeatureLayerPath(filePath: string, config: ResolvedBeignetConfig): string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../src/analysis/layers.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../src/analysis/layers.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,KAAK,iBAAiB,EAAiB,MAAM,gBAAgB,CAAC;AAEvE,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,iBAAiB,GAC3B,WAAW,CAGb;AAED,MAAM,MAAM,WAAW,GACnB,KAAK,GACL,aAAa,GACb,kBAAkB,GAClB,QAAQ,GACR,WAAW,GACX,UAAU,GACV,QAAQ,GACR,gBAAgB,GAChB,cAAc,GACd,OAAO,GACP,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,MAAM,GACN,UAAU,GACV,UAAU,GACV,SAAS,CAAC;AA6Cd,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,qBAAqB,GAC5B,WAAW,CAuEb;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,qBAAqB,GAC5B,MAAM,GAAG,SAAS,CAmCpB"}
|
package/dist/analysis/layers.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { clientDirPath, directoryPath, normalizePath, } from "../config.js";
|
|
3
|
+
import { isAppTestFile } from "../test-discovery.js";
|
|
4
|
+
import { stripSourceFileExtension } from "./source-files.js";
|
|
5
|
+
import { projectSource } from "./workspace.js";
|
|
6
|
+
export function classifyWorkspaceSourcePath(file, workspace) {
|
|
7
|
+
const source = projectSource(workspace, file);
|
|
8
|
+
return classifySourcePath(source.file, source.project.config);
|
|
9
|
+
}
|
|
3
10
|
const canonicalFeatureDirectories = {
|
|
4
11
|
client: "client",
|
|
5
12
|
components: "component",
|
|
@@ -120,7 +127,7 @@ export function canonicalFeatureLayerPath(filePath, config) {
|
|
|
120
127
|
}
|
|
121
128
|
function isTestSourceFile(segment, rest) {
|
|
122
129
|
const fileName = rest.at(-1) ?? segment;
|
|
123
|
-
return
|
|
130
|
+
return isAppTestFile(fileName);
|
|
124
131
|
}
|
|
125
132
|
function featureDirectoryConvention(segment) {
|
|
126
133
|
const canonical = Object.entries(canonicalFeatureDirectories).find(([candidate]) => normalizeLayerSegment(candidate) === normalizeLayerSegment(segment));
|
|
@@ -144,7 +151,7 @@ function normalizeLayerSegment(segment) {
|
|
|
144
151
|
return segment.replaceAll("-", "").replaceAll("_", "").toLowerCase();
|
|
145
152
|
}
|
|
146
153
|
function stripKnownExtension(filePath) {
|
|
147
|
-
return filePath
|
|
154
|
+
return stripSourceFileExtension(filePath);
|
|
148
155
|
}
|
|
149
156
|
function isTestPath(filePath) {
|
|
150
157
|
return (filePath.includes("/tests/") ||
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layers.js","sourceRoot":"","sources":["../../src/analysis/layers.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,GAEd,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"layers.js","sourceRoot":"","sources":["../../src/analysis/layers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
2
|
import type { ResolvedBeignetConfig } from "../config.js";
|
|
3
|
-
import type
|
|
3
|
+
import { type SourceIndex } from "./source-index.js";
|
|
4
|
+
import { type AnalysisWorkspace } from "./workspace.js";
|
|
4
5
|
type PortAnalysisWorkspace = Pick<AnalysisWorkspace, "config" | "fileSet" | "readSourceFile">;
|
|
5
6
|
export type PortWiringAnalysis = {
|
|
6
7
|
portsFileExists: boolean;
|
|
7
8
|
portWiringFileExists: boolean;
|
|
8
9
|
properties: Map<string, ts.PropertySignature>;
|
|
10
|
+
propertyFiles: Map<string, string>;
|
|
9
11
|
declared: Set<string>;
|
|
10
12
|
bound: Set<string>;
|
|
11
13
|
deferred: Set<string>;
|
|
@@ -13,7 +15,7 @@ export type PortWiringAnalysis = {
|
|
|
13
15
|
declarationIndeterminate: boolean;
|
|
14
16
|
indeterminate: boolean;
|
|
15
17
|
};
|
|
16
|
-
export declare function analyzePortWiring(workspace: PortAnalysisWorkspace): Promise<PortWiringAnalysis>;
|
|
18
|
+
export declare function analyzePortWiring(workspace: PortAnalysisWorkspace, sourceIndex?: SourceIndex): Promise<PortWiringAnalysis>;
|
|
17
19
|
export declare function analyzePortWiringFiles(options: {
|
|
18
20
|
targetDir: string;
|
|
19
21
|
files: readonly string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port-wiring.d.ts","sourceRoot":"","sources":["../../src/analysis/port-wiring.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"port-wiring.d.ts","sourceRoot":"","sources":["../../src/analysis/port-wiring.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,iBAAiB,EAEvB,MAAM,gBAAgB,CAAC;AAExB,KAAK,qBAAqB,GAAG,IAAI,CAC/B,iBAAiB,EACjB,QAAQ,GAAG,SAAS,GAAG,gBAAgB,CACxC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,eAAe,EAAE,OAAO,CAAC;IACzB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC;IAC9C,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnB,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,0BAA0B,EAAE,OAAO,CAAC;IACpC,wBAAwB,EAAE,OAAO,CAAC;IAClC,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC;AAEF,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,qBAAqB,EAChC,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,kBAAkB,CAAC,CAgJ7B;AAiGD,wBAAsB,sBAAsB,CAAC,OAAO,EAAE;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,qBAAqB,CAAC;CAC/B,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAyB9B"}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import ts from "typescript";
|
|
4
|
-
|
|
4
|
+
import { sourceFileScriptKind } from "./source-files.js";
|
|
5
|
+
import { createSourceIndex, } from "./source-index.js";
|
|
6
|
+
import { createAnalysisWorkspace, } from "./workspace.js";
|
|
7
|
+
export async function analyzePortWiring(workspace, sourceIndex) {
|
|
5
8
|
const result = {
|
|
6
9
|
portsFileExists: workspace.fileSet.has(workspace.config.paths.ports),
|
|
7
10
|
portWiringFileExists: workspace.fileSet.has(workspace.config.paths.portWiring),
|
|
8
11
|
properties: new Map(),
|
|
12
|
+
propertyFiles: new Map(),
|
|
9
13
|
declared: new Set(),
|
|
10
14
|
bound: new Set(),
|
|
11
15
|
deferred: new Set(),
|
|
@@ -14,18 +18,25 @@ export async function analyzePortWiring(workspace) {
|
|
|
14
18
|
indeterminate: false,
|
|
15
19
|
};
|
|
16
20
|
let inferredAppPortsName;
|
|
21
|
+
let inferredAppPortsReference;
|
|
17
22
|
if (result.portsFileExists) {
|
|
18
|
-
const
|
|
23
|
+
const reference = await sourceIndex?.resolveExport(workspace.config.paths.ports, "AppPorts");
|
|
24
|
+
const portsFile = reference?.file ?? workspace.config.paths.ports;
|
|
25
|
+
const portsName = reference?.exportName ?? "AppPorts";
|
|
26
|
+
const sourceFile = await workspace.readSourceFile(portsFile);
|
|
19
27
|
const declarations = collectTypeDeclarations(sourceFile);
|
|
20
|
-
inferredAppPortsName = inferredTypeQueryName(
|
|
28
|
+
inferredAppPortsName = inferredTypeQueryName(portsName, declarations);
|
|
29
|
+
if (inferredAppPortsName)
|
|
30
|
+
inferredAppPortsReference = await sourceIndex?.resolveName(portsFile, inferredAppPortsName);
|
|
21
31
|
const collection = inferredAppPortsName
|
|
22
32
|
? { properties: [], indeterminate: false }
|
|
23
|
-
: collectNamedTypeProperties(
|
|
33
|
+
: collectNamedTypeProperties(portsName, declarations, !sourceIndex);
|
|
24
34
|
result.declarationIndeterminate = collection.indeterminate;
|
|
25
35
|
for (const property of collection.properties) {
|
|
26
36
|
const name = propertyName(property.name);
|
|
27
37
|
if (name && !result.properties.has(name)) {
|
|
28
38
|
result.properties.set(name, property);
|
|
39
|
+
result.propertyFiles.set(name, portsFile);
|
|
29
40
|
result.declared.add(name);
|
|
30
41
|
}
|
|
31
42
|
}
|
|
@@ -35,10 +46,16 @@ export async function analyzePortWiring(workspace) {
|
|
|
35
46
|
result.declarationIndeterminate = true;
|
|
36
47
|
return result;
|
|
37
48
|
}
|
|
38
|
-
const
|
|
49
|
+
const wiringReference = await sourceIndex?.resolveExport(workspace.config.paths.portWiring, "initialPorts");
|
|
50
|
+
const sourceFile = await workspace.readSourceFile(wiringReference?.file ?? workspace.config.paths.portWiring);
|
|
39
51
|
const values = collectVariableInitializers(sourceFile);
|
|
40
|
-
const definitions = portDefinitionCalls(sourceFile
|
|
41
|
-
|
|
52
|
+
const definitions = portDefinitionCalls(sourceFile, wiringReference?.declaration &&
|
|
53
|
+
ts.isVariableDeclaration(wiringReference.declaration) &&
|
|
54
|
+
ts.isIdentifier(wiringReference.declaration.name)
|
|
55
|
+
? wiringReference.declaration.name.text
|
|
56
|
+
: wiringReference?.exportName);
|
|
57
|
+
if (definitions.indeterminate ||
|
|
58
|
+
(sourceIndex && definitions.calls.length === 0))
|
|
42
59
|
result.indeterminate = true;
|
|
43
60
|
for (const call of definitions.calls) {
|
|
44
61
|
const objectArgument = call.arguments
|
|
@@ -92,7 +109,11 @@ export async function analyzePortWiring(workspace) {
|
|
|
92
109
|
}
|
|
93
110
|
if (inferredAppPortsName) {
|
|
94
111
|
if (!definitions.indeterminate &&
|
|
95
|
-
|
|
112
|
+
(sourceIndex
|
|
113
|
+
? Boolean(inferredAppPortsReference?.declaration &&
|
|
114
|
+
inferredAppPortsReference.declaration ===
|
|
115
|
+
wiringReference?.declaration)
|
|
116
|
+
: definitions.name === inferredAppPortsName)) {
|
|
96
117
|
result.appPortsInferredFromWiring = true;
|
|
97
118
|
for (const name of result.bound)
|
|
98
119
|
result.declared.add(name);
|
|
@@ -105,7 +126,7 @@ export async function analyzePortWiring(workspace) {
|
|
|
105
126
|
}
|
|
106
127
|
return result;
|
|
107
128
|
}
|
|
108
|
-
function portDefinitionCalls(sourceFile) {
|
|
129
|
+
function portDefinitionCalls(sourceFile, preferredName) {
|
|
109
130
|
const exportedNames = locallyExportedNames(sourceFile);
|
|
110
131
|
const candidates = [];
|
|
111
132
|
for (const statement of sourceFile.statements) {
|
|
@@ -128,7 +149,10 @@ function portDefinitionCalls(sourceFile) {
|
|
|
128
149
|
});
|
|
129
150
|
}
|
|
130
151
|
}
|
|
131
|
-
const canonical = candidates.filter((candidate) => candidate.name === "initialPorts" &&
|
|
152
|
+
const canonical = candidates.filter((candidate) => candidate.name === (preferredName ?? "initialPorts") &&
|
|
153
|
+
candidate.exported);
|
|
154
|
+
if (preferredName && canonical.length === 0)
|
|
155
|
+
return { calls: [], indeterminate: true };
|
|
132
156
|
const exported = candidates.filter((candidate) => candidate.exported);
|
|
133
157
|
const selected = canonical.length > 0
|
|
134
158
|
? canonical
|
|
@@ -174,6 +198,12 @@ function definePortsCalls(node) {
|
|
|
174
198
|
return calls;
|
|
175
199
|
}
|
|
176
200
|
export async function analyzePortWiringFiles(options) {
|
|
201
|
+
if (options.config.workspace.packages.length > 0) {
|
|
202
|
+
const workspace = await createAnalysisWorkspace(options.targetDir, {
|
|
203
|
+
config: options.config,
|
|
204
|
+
});
|
|
205
|
+
return analyzePortWiring(workspace, createSourceIndex(workspace));
|
|
206
|
+
}
|
|
177
207
|
const sourceFiles = new Map();
|
|
178
208
|
return analyzePortWiring({
|
|
179
209
|
config: options.config,
|
|
@@ -182,7 +212,7 @@ export async function analyzePortWiringFiles(options) {
|
|
|
182
212
|
const cached = sourceFiles.get(file);
|
|
183
213
|
if (cached)
|
|
184
214
|
return cached;
|
|
185
|
-
const sourceFile = ts.createSourceFile(file, await readFile(path.join(options.targetDir, file), "utf8"), ts.ScriptTarget.Latest, true, file
|
|
215
|
+
const sourceFile = ts.createSourceFile(file, await readFile(path.join(options.targetDir, file), "utf8"), ts.ScriptTarget.Latest, true, sourceFileScriptKind(file));
|
|
186
216
|
sourceFiles.set(file, sourceFile);
|
|
187
217
|
return sourceFile;
|
|
188
218
|
},
|