@voltro/cli 0.12.0 → 0.13.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 +93 -0
- package/dist/{apiBuild-GefjNI5d.js → apiBuild-B6_ehbem.js} +3 -3
- package/dist/apiBuild-Bzpb383i.js +2 -0
- package/dist/bin.js +3 -3
- package/dist/{commands-BmNi1RgZ.js → commands-DYOuGlEC.js} +1668 -1371
- package/dist/dbCommand-ADD4mrTI.js +2 -0
- package/dist/{dbCommand-DNrkb58g.js → dbCommand-DIOJQwsq.js} +71 -57
- package/dist/{dev-d0LjACxE.js → dev-Fb9BmavX.js} +1483 -1414
- package/dist/dev-xdijqojc.js +3 -0
- package/dist/{seedRunner-DZmhoqNt.js → frameworkTableAssembly-CYlrafoK.js} +110 -331
- package/dist/frameworkTableAssembly-XvKO7wQt.js +2 -0
- package/dist/index.js +1 -1
- package/dist/{inspectMetrics-uEfIS1vp.js → inspectMetrics-DOiiII34.js} +302 -293
- package/dist/seedRunner-D6eu-u5U.js +229 -0
- package/dist/{serveCommand-B2-YV9TU.js → serveCommand-CqYxzBZR.js} +368 -367
- package/dist/serveEntry.js +3 -3
- package/dist/{start-DKcQd52a.js → start-CjG_0xhR.js} +1 -1
- package/dist/startEntry.js +2 -2
- package/package.json +17 -17
- package/templates/AGENTS.md +1 -1
- package/templates/agent-docs/_index.md +1 -1
- package/templates/agent-docs/authentication.md +36 -0
- package/templates/agent-docs/cli.md +78 -4
- package/templates/agent-docs/configuration.md +48 -0
- package/templates/agent-docs/database/migrations.md +32 -0
- package/templates/agent-docs/database/transactions.md +31 -0
- package/templates/agent-docs/testing.md +24 -0
- package/templates/agent-docs/whats-new.md +41 -137
- package/templates/apps/api-ai/package.json +7 -7
- package/templates/apps/api-auth/package.json +8 -8
- package/templates/apps/api-backend/package.json +7 -7
- package/templates/apps/api-backend-deactivation/package.json +7 -7
- package/templates/apps/api-backend-deactivation/tests/users.deactivate.test.ts +1 -1
- package/templates/apps/api-backend-mail/package.json +8 -8
- package/templates/apps/api-backend-mariadb/package.json +9 -9
- package/templates/apps/api-backend-storage/package.json +8 -8
- package/templates/apps/api-data-advanced/package.json +8 -8
- package/templates/apps/api-data-advanced/tests/queries.test.ts +6 -1
- package/templates/apps/api-durable/package.json +8 -8
- package/templates/apps/api-feature-flags/package.json +9 -9
- package/templates/apps/api-governance/app.config.ts +0 -1
- package/templates/apps/api-governance/package.json +8 -8
- package/templates/apps/api-kv/package.json +8 -8
- package/templates/apps/api-kv/tests/sync.test.ts +2 -2
- package/templates/apps/api-moderation/package.json +8 -8
- package/templates/apps/api-observability/package.json +8 -8
- package/templates/apps/api-ratelimit/package.json +8 -8
- package/templates/apps/api-rbac/README.md +53 -14
- package/templates/apps/api-rbac/app.config.ts +24 -26
- package/templates/apps/api-rbac/authz.ts +76 -0
- package/templates/apps/api-rbac/database/schema.ts +23 -6
- package/templates/apps/api-rbac/mutations/notes.create.mutation.server.ts +7 -5
- package/templates/apps/api-rbac/mutations/notes.create.mutation.ts +15 -8
- package/templates/apps/api-rbac/mutations/notes.delete.mutation.server.ts +54 -0
- package/templates/apps/api-rbac/mutations/notes.delete.mutation.ts +43 -0
- package/templates/apps/api-rbac/mutations/teams.rename.mutation.server.ts +19 -0
- package/templates/apps/api-rbac/mutations/teams.rename.mutation.ts +37 -0
- package/templates/apps/api-rbac/package.json +8 -8
- package/templates/apps/api-rbac/queries/notes.list.query.server.ts +12 -0
- package/templates/apps/api-rbac/queries/notes.list.query.ts +26 -0
- package/templates/apps/api-rbac/template.json +2 -2
- package/templates/apps/api-rbac/tests/authz.test.ts +233 -0
- package/templates/apps/api-rest/package.json +7 -7
- package/templates/apps/api-saas/package.json +11 -11
- package/templates/apps/api-search/package.json +8 -8
- package/templates/apps/api-versioning/package.json +8 -8
- package/templates/apps/api-webhooks/package.json +9 -8
- package/templates/apps/changelog/package.json +6 -6
- package/templates/apps/edge-functions/package.json +2 -2
- package/templates/apps/frontend-admin/package.json +8 -8
- package/templates/apps/frontend-app/package.json +8 -8
- package/templates/apps/frontend-blank/package.json +7 -7
- package/templates/apps/frontend-contact/package.json +7 -7
- package/templates/apps/frontend-dashboard/package.json +7 -7
- package/templates/apps/frontend-docs/package.json +7 -7
- package/templates/apps/frontend-i18n/package.json +6 -6
- package/templates/apps/frontend-landing/package.json +7 -7
- package/templates/apps/frontend-spa/package.json +7 -7
- package/templates/apps/frontend-ssr/package.json +7 -7
- package/templates/apps/frontend-ssr-api/package.json +8 -8
- package/templates/apps/frontend-static-blog/package.json +6 -6
- package/dist/apiBuild-s7swuEU5.js +0 -2
- package/dist/dbCommand-Bt6BCG7g.js +0 -2
- package/dist/dev-YHbHmeXt.js +0 -3
- package/templates/apps/api-rbac/tests/notes.create.test.ts +0 -80
|
@@ -14,18 +14,18 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@effect/platform": "^0.96.1",
|
|
17
|
-
"@voltro/cli": "0.
|
|
18
|
-
"@voltro/client": "0.
|
|
19
|
-
"@voltro/env": "0.
|
|
20
|
-
"@voltro/i18n": "0.
|
|
21
|
-
"@voltro/serverless": "0.
|
|
22
|
-
"@voltro/web": "0.
|
|
17
|
+
"@voltro/cli": "0.13.0",
|
|
18
|
+
"@voltro/client": "0.13.0",
|
|
19
|
+
"@voltro/env": "0.13.0",
|
|
20
|
+
"@voltro/i18n": "0.13.0",
|
|
21
|
+
"@voltro/serverless": "0.13.0",
|
|
22
|
+
"@voltro/web": "0.13.0",
|
|
23
23
|
"effect": "^3.21.2",
|
|
24
24
|
"react": "^19.0.0",
|
|
25
25
|
"react-dom": "^19.0.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@voltro/devtools": "0.
|
|
28
|
+
"@voltro/devtools": "0.13.0",
|
|
29
29
|
"@types/react": "^19.0.0",
|
|
30
30
|
"@types/react-dom": "^19.0.0",
|
|
31
31
|
"typescript": "^5.7.0",
|
|
@@ -11,17 +11,17 @@
|
|
|
11
11
|
"test": "voltro test"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@voltro/cli": "0.
|
|
15
|
-
"@voltro/client": "0.
|
|
16
|
-
"@voltro/env": "0.
|
|
17
|
-
"@voltro/i18n": "0.
|
|
18
|
-
"@voltro/ui-shadcn": "0.
|
|
19
|
-
"@voltro/web": "0.
|
|
14
|
+
"@voltro/cli": "0.13.0",
|
|
15
|
+
"@voltro/client": "0.13.0",
|
|
16
|
+
"@voltro/env": "0.13.0",
|
|
17
|
+
"@voltro/i18n": "0.13.0",
|
|
18
|
+
"@voltro/ui-shadcn": "0.13.0",
|
|
19
|
+
"@voltro/web": "0.13.0",
|
|
20
20
|
"react": "^19.0.0",
|
|
21
21
|
"react-dom": "^19.0.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@voltro/devtools": "0.
|
|
24
|
+
"@voltro/devtools": "0.13.0",
|
|
25
25
|
"@types/react": "^19.0.0",
|
|
26
26
|
"@types/react-dom": "^19.0.0",
|
|
27
27
|
"typescript": "^5.7.0",
|
|
@@ -11,17 +11,17 @@
|
|
|
11
11
|
"test": "voltro test"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@voltro/cli": "0.
|
|
15
|
-
"@voltro/client": "0.
|
|
16
|
-
"@voltro/env": "0.
|
|
17
|
-
"@voltro/i18n": "0.
|
|
18
|
-
"@voltro/ui-shadcn": "0.
|
|
19
|
-
"@voltro/web": "0.
|
|
14
|
+
"@voltro/cli": "0.13.0",
|
|
15
|
+
"@voltro/client": "0.13.0",
|
|
16
|
+
"@voltro/env": "0.13.0",
|
|
17
|
+
"@voltro/i18n": "0.13.0",
|
|
18
|
+
"@voltro/ui-shadcn": "0.13.0",
|
|
19
|
+
"@voltro/web": "0.13.0",
|
|
20
20
|
"react": "^19.0.0",
|
|
21
21
|
"react-dom": "^19.0.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@voltro/devtools": "0.
|
|
24
|
+
"@voltro/devtools": "0.13.0",
|
|
25
25
|
"@types/react": "^19.0.0",
|
|
26
26
|
"@types/react-dom": "^19.0.0",
|
|
27
27
|
"typescript": "^5.7.0",
|
|
@@ -11,16 +11,16 @@
|
|
|
11
11
|
"test": "voltro test"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@voltro/cli": "0.
|
|
15
|
-
"@voltro/client": "0.
|
|
16
|
-
"@voltro/env": "0.
|
|
17
|
-
"@voltro/i18n": "0.
|
|
18
|
-
"@voltro/web": "0.
|
|
14
|
+
"@voltro/cli": "0.13.0",
|
|
15
|
+
"@voltro/client": "0.13.0",
|
|
16
|
+
"@voltro/env": "0.13.0",
|
|
17
|
+
"@voltro/i18n": "0.13.0",
|
|
18
|
+
"@voltro/web": "0.13.0",
|
|
19
19
|
"react": "^19.0.0",
|
|
20
20
|
"react-dom": "^19.0.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@voltro/devtools": "0.
|
|
23
|
+
"@voltro/devtools": "0.13.0",
|
|
24
24
|
"@types/react": "^19.0.0",
|
|
25
25
|
"@types/react-dom": "^19.0.0",
|
|
26
26
|
"typescript": "^5.7.0",
|
|
@@ -11,17 +11,17 @@
|
|
|
11
11
|
"typecheck": "tsc --noEmit"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@voltro/cli": "0.
|
|
15
|
-
"@voltro/client": "0.
|
|
16
|
-
"@voltro/env": "0.
|
|
17
|
-
"@voltro/i18n": "0.
|
|
18
|
-
"@voltro/ui-shadcn": "0.
|
|
19
|
-
"@voltro/web": "0.
|
|
14
|
+
"@voltro/cli": "0.13.0",
|
|
15
|
+
"@voltro/client": "0.13.0",
|
|
16
|
+
"@voltro/env": "0.13.0",
|
|
17
|
+
"@voltro/i18n": "0.13.0",
|
|
18
|
+
"@voltro/ui-shadcn": "0.13.0",
|
|
19
|
+
"@voltro/web": "0.13.0",
|
|
20
20
|
"react": "^19.0.0",
|
|
21
21
|
"react-dom": "^19.0.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@voltro/devtools": "0.
|
|
24
|
+
"@voltro/devtools": "0.13.0",
|
|
25
25
|
"@types/react": "^19.0.0",
|
|
26
26
|
"@types/react-dom": "^19.0.0",
|
|
27
27
|
"typescript": "^5.7.0",
|
|
@@ -11,17 +11,17 @@
|
|
|
11
11
|
"typecheck": "tsc --noEmit"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@voltro/cli": "0.
|
|
15
|
-
"@voltro/client": "0.
|
|
16
|
-
"@voltro/env": "0.
|
|
17
|
-
"@voltro/i18n": "0.
|
|
18
|
-
"@voltro/ui-shadcn": "0.
|
|
19
|
-
"@voltro/web": "0.
|
|
14
|
+
"@voltro/cli": "0.13.0",
|
|
15
|
+
"@voltro/client": "0.13.0",
|
|
16
|
+
"@voltro/env": "0.13.0",
|
|
17
|
+
"@voltro/i18n": "0.13.0",
|
|
18
|
+
"@voltro/ui-shadcn": "0.13.0",
|
|
19
|
+
"@voltro/web": "0.13.0",
|
|
20
20
|
"react": "^19.0.0",
|
|
21
21
|
"react-dom": "^19.0.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@voltro/devtools": "0.
|
|
24
|
+
"@voltro/devtools": "0.13.0",
|
|
25
25
|
"@types/react": "^19.0.0",
|
|
26
26
|
"@types/react-dom": "^19.0.0",
|
|
27
27
|
"typescript": "^5.7.0",
|
|
@@ -11,17 +11,17 @@
|
|
|
11
11
|
"test": "voltro test"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@voltro/cli": "0.
|
|
15
|
-
"@voltro/client": "0.
|
|
16
|
-
"@voltro/env": "0.
|
|
17
|
-
"@voltro/i18n": "0.
|
|
18
|
-
"@voltro/ui-shadcn": "0.
|
|
19
|
-
"@voltro/web": "0.
|
|
14
|
+
"@voltro/cli": "0.13.0",
|
|
15
|
+
"@voltro/client": "0.13.0",
|
|
16
|
+
"@voltro/env": "0.13.0",
|
|
17
|
+
"@voltro/i18n": "0.13.0",
|
|
18
|
+
"@voltro/ui-shadcn": "0.13.0",
|
|
19
|
+
"@voltro/web": "0.13.0",
|
|
20
20
|
"react": "^19.0.0",
|
|
21
21
|
"react-dom": "^19.0.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@voltro/devtools": "0.
|
|
24
|
+
"@voltro/devtools": "0.13.0",
|
|
25
25
|
"@types/react": "^19.0.0",
|
|
26
26
|
"@types/react-dom": "^19.0.0",
|
|
27
27
|
"typescript": "^5.7.0",
|
|
@@ -11,18 +11,18 @@
|
|
|
11
11
|
"test": "voltro test"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@{{projectName}}/api": "0.
|
|
15
|
-
"@voltro/cli": "0.
|
|
16
|
-
"@voltro/client": "0.
|
|
17
|
-
"@voltro/env": "0.
|
|
18
|
-
"@voltro/i18n": "0.
|
|
19
|
-
"@voltro/ui-shadcn": "0.
|
|
20
|
-
"@voltro/web": "0.
|
|
14
|
+
"@{{projectName}}/api": "0.13.0",
|
|
15
|
+
"@voltro/cli": "0.13.0",
|
|
16
|
+
"@voltro/client": "0.13.0",
|
|
17
|
+
"@voltro/env": "0.13.0",
|
|
18
|
+
"@voltro/i18n": "0.13.0",
|
|
19
|
+
"@voltro/ui-shadcn": "0.13.0",
|
|
20
|
+
"@voltro/web": "0.13.0",
|
|
21
21
|
"react": "^19.0.0",
|
|
22
22
|
"react-dom": "^19.0.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@voltro/devtools": "0.
|
|
25
|
+
"@voltro/devtools": "0.13.0",
|
|
26
26
|
"@types/react": "^19.0.0",
|
|
27
27
|
"@types/react-dom": "^19.0.0",
|
|
28
28
|
"typescript": "^5.7.0",
|
|
@@ -11,16 +11,16 @@
|
|
|
11
11
|
"test": "voltro test"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@voltro/cli": "0.
|
|
15
|
-
"@voltro/client": "0.
|
|
16
|
-
"@voltro/env": "0.
|
|
17
|
-
"@voltro/i18n": "0.
|
|
18
|
-
"@voltro/web": "0.
|
|
14
|
+
"@voltro/cli": "0.13.0",
|
|
15
|
+
"@voltro/client": "0.13.0",
|
|
16
|
+
"@voltro/env": "0.13.0",
|
|
17
|
+
"@voltro/i18n": "0.13.0",
|
|
18
|
+
"@voltro/web": "0.13.0",
|
|
19
19
|
"react": "^19.0.0",
|
|
20
20
|
"react-dom": "^19.0.0"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@voltro/devtools": "0.
|
|
23
|
+
"@voltro/devtools": "0.13.0",
|
|
24
24
|
"@types/react": "^19.0.0",
|
|
25
25
|
"@types/react-dom": "^19.0.0",
|
|
26
26
|
"typescript": "^5.7.0",
|
package/dist/dev-YHbHmeXt.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
// Unit test for `notes.create` — driven through `@voltro/testing`.
|
|
2
|
-
//
|
|
3
|
-
// This executor is Effect-native: it `yield*`s the RBAC guard
|
|
4
|
-
// `permission(ctx, 'notes:write')` (fails typed `ScopeError` for a caller
|
|
5
|
-
// lacking the scope) and then `yield* EffectStore` to insert. `makeTestContext`
|
|
6
|
-
// exposes the mixin-wrapped store as `ctx.store`; we provide it to the Effect as
|
|
7
|
-
// the `EffectStore` layer via `makeEffectStoreLayer` — the SAME wiring the CLI
|
|
8
|
-
// dev/serve dispatcher does — so the handler runs exactly as at runtime.
|
|
9
|
-
//
|
|
10
|
-
// In production the rbac INTERCEPTOR resolves the caller's roles → scopes and
|
|
11
|
-
// stashes them on the subject before the handler runs. That interceptor is a
|
|
12
|
-
// dispatch-time concern the unit harness doesn't run, so we drive the handler's
|
|
13
|
-
// OWN guard directly by putting the resolved scope on `subject.scopes` — exactly
|
|
14
|
-
// what the interceptor would have stashed. Run with `voltro test` (vitest).
|
|
15
|
-
|
|
16
|
-
import { describe, it, expect } from 'vitest'
|
|
17
|
-
import { Cause, Effect, Exit, Option, Schema } from 'effect'
|
|
18
|
-
import { makeTestContext, mockStore } from '@voltro/testing'
|
|
19
|
-
import { makeEffectStoreLayer } from '@voltro/runtime'
|
|
20
|
-
import { database } from '../database/schema' // registers actors / tenants / notes
|
|
21
|
-
import { createNote } from '../mutations/notes.create.mutation'
|
|
22
|
-
import createNoteHandler from '../mutations/notes.create.mutation.server'
|
|
23
|
-
import { ScopeError } from '@voltro/protocol'
|
|
24
|
-
|
|
25
|
-
// Run the Effect-native executor with the test store provided as EffectStore.
|
|
26
|
-
const runExec = (input: { title: string; body: string }, ctx: ReturnType<typeof makeTestContext>) =>
|
|
27
|
-
Effect.runPromise(createNoteHandler(input, ctx).pipe(Effect.provide(makeEffectStoreLayer(ctx.store))))
|
|
28
|
-
|
|
29
|
-
// Same, but returns the raw Exit so a typed failure can be inspected WITHOUT
|
|
30
|
-
// the `FiberFailure` wrapper `runPromise` throws (which would defeat a plain
|
|
31
|
-
// `instanceof ScopeError` assertion). Unwrap the Cause to get the real error.
|
|
32
|
-
const runExit = (input: { title: string; body: string }, ctx: ReturnType<typeof makeTestContext>) =>
|
|
33
|
-
Effect.runPromiseExit(createNoteHandler(input, ctx).pipe(Effect.provide(makeEffectStoreLayer(ctx.store))))
|
|
34
|
-
|
|
35
|
-
describe('notes.create', () => {
|
|
36
|
-
it('inserts for a caller holding notes:write — tenant-stamped, note_ TypeID', async () => {
|
|
37
|
-
const ctx = makeTestContext({
|
|
38
|
-
subject: { type: 'user', id: 'editor_1', tenantId: 'acme', scopes: ['notes:write'] },
|
|
39
|
-
store: mockStore({ notes: [] }),
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
const row = await runExec({ title: 'Ship it', body: 'World' }, ctx)
|
|
43
|
-
|
|
44
|
-
expect(row.title).toBe('Ship it')
|
|
45
|
-
expect(row.tenantId).toBe('acme') // tenant() auto-filled from the subject
|
|
46
|
-
expect(row.id).toMatch(/^note_/)
|
|
47
|
-
|
|
48
|
-
// The row is really in the store — the live tenant-scoped query sees it.
|
|
49
|
-
const rows = await ctx.store.query(database.notes.descriptor)
|
|
50
|
-
expect(rows).toHaveLength(1)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it('rejects a caller WITHOUT notes:write with typed ScopeError — nothing written', async () => {
|
|
54
|
-
const ctx = makeTestContext({
|
|
55
|
-
subject: { type: 'user', id: 'viewer_1', tenantId: 'acme', scopes: [] },
|
|
56
|
-
store: mockStore({ notes: [] }),
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
const exit = await runExit({ title: 'x', body: '' }, ctx)
|
|
60
|
-
|
|
61
|
-
expect(Exit.isFailure(exit)).toBe(true)
|
|
62
|
-
const failure = Exit.isFailure(exit) ? Cause.failureOption(exit.cause) : Option.none()
|
|
63
|
-
expect(Option.getOrThrow(failure)).toBeInstanceOf(ScopeError)
|
|
64
|
-
|
|
65
|
-
const rows = await ctx.store.query(database.notes.descriptor)
|
|
66
|
-
expect(rows).toHaveLength(0)
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
it('pins the descriptor: name, input decode + the declared ScopeError error', () => {
|
|
70
|
-
expect(createNote.name).toBe('notes.create')
|
|
71
|
-
|
|
72
|
-
const decoded = Schema.decodeUnknownSync(createNote.input)({ title: 'ok', body: 'b' })
|
|
73
|
-
expect(decoded).toEqual({ title: 'ok', body: 'b' })
|
|
74
|
-
// Empty title is rejected at the input Schema (NonEmptyString).
|
|
75
|
-
expect(() => Schema.decodeUnknownSync(createNote.input)({ title: '', body: '' })).toThrow()
|
|
76
|
-
|
|
77
|
-
const denied = new ScopeError({ required: 'notes:write', message: 'missing required permission' })
|
|
78
|
-
expect(Schema.is(ScopeError)(denied)).toBe(true)
|
|
79
|
-
})
|
|
80
|
-
})
|