create-substrat 0.9.6 → 0.9.8
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/index.js
CHANGED
|
@@ -36,11 +36,11 @@ const TEMPLATE = join(HERE, 'template');
|
|
|
36
36
|
// The runtime packages release together off one version line (the changesets `fixed`
|
|
37
37
|
// group), so one constant is right for all of them. Engines do NOT share a line —
|
|
38
38
|
// each versions on its own, so one pin per engine, deliberately.
|
|
39
|
-
const SUBSTRAT = '^0.
|
|
40
|
-
const ENGINE_WORKORDER = '^0.11.
|
|
41
|
-
const ENGINE_INVOICING = '^0.10.
|
|
39
|
+
const SUBSTRAT = '^0.114.0';
|
|
40
|
+
const ENGINE_WORKORDER = '^0.11.13';
|
|
41
|
+
const ENGINE_INVOICING = '^0.10.4';
|
|
42
42
|
const BOUNDARY_LINT = '^0.4.2';
|
|
43
|
-
const DEV_ISSUER = '^0.1.
|
|
43
|
+
const DEV_ISSUER = '^0.1.29';
|
|
44
44
|
|
|
45
45
|
const DOCS = 'https://substrat.net';
|
|
46
46
|
|
package/package.json
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* not in `.claude/`. `.claude/settings.json` is a three-line adapter that runs it,
|
|
21
21
|
* and any other client that grows a session hook binds the same way. It also
|
|
22
22
|
* means the plugin distribution (#753) ships this script unchanged rather than
|
|
23
|
-
* forking it: `plugin/substrat/scripts/session-start.mjs` is emitted from this
|
|
23
|
+
* forking it: `plugin/substrat/scripts/session-start.generated.mjs` is emitted from this
|
|
24
24
|
* file byte-for-byte, and `pnpm lint:plugin --check` fails if the two diverge.
|
|
25
25
|
*
|
|
26
26
|
* The plugin copy is what reaches a project scaffolded before this hook existed.
|
package/template/AGENTS.md
CHANGED
|
@@ -46,11 +46,13 @@ src/migrations.ts the SqlMigration[] ← module cod
|
|
|
46
46
|
src/module.ts the handlers, bound to the declaration ← module code
|
|
47
47
|
src/provision.ts MODULES, ROLES, grant shapes — node-free ← module code
|
|
48
48
|
src/seed.ts host, tenants, demo cast, seed world ← harness
|
|
49
|
+
src/personas.ts the dev cast, read by the issuer and the seed ← harness
|
|
49
50
|
src/routes.ts the routes, DERIVED from the operations ← harness
|
|
50
51
|
src/server.ts the dev entrypoint (node + persona picker) ← harness
|
|
51
52
|
src/worker.ts the deployable Cloudflare worker ← harness
|
|
52
53
|
src/config-do.ts per-instance config store (Cloudflare only) ← harness
|
|
53
54
|
test/scenario.test.ts the scenario — including the denials
|
|
55
|
+
test/entities.test.ts the registry, held to the tables it migrates
|
|
54
56
|
```
|
|
55
57
|
|
|
56
58
|
**A new route is an `http` declaration on its operation, never a handler in an
|
|
@@ -156,6 +158,12 @@ same object feeds `operationInputs: operationInputsOf(bikeShopOperations)`, so t
|
|
|
156
158
|
schemas the host parses with are the ones the declaration states — they cannot drift,
|
|
157
159
|
because there is only one of them.
|
|
158
160
|
|
|
161
|
+
The permission list works the same way. `SHOP_PERMISSIONS`, the array handed to
|
|
162
|
+
`defineOperations`, is also the `keys` that `src/provision.ts` hands
|
|
163
|
+
`definePermissions({ modules, roles, entityGrants, keys })` — and `definePermissions`
|
|
164
|
+
throws at module load if those keys and `MODULES` disagree in either direction. Hand
|
|
165
|
+
both readers the same array; a second copy is a list that drifts.
|
|
166
|
+
|
|
159
167
|
**A list read must declare `paged`.** `defineOperations` refuses a bare-array `output`
|
|
160
168
|
that does not, and it refuses it at module load — so it fires in every build, every
|
|
161
169
|
test and every dev server rather than in a lint tool that has to find you. A list
|
package/template/src/worker.ts
CHANGED
|
@@ -47,7 +47,13 @@ import {
|
|
|
47
47
|
SCOPE_SWEEPER_NAME,
|
|
48
48
|
type ScopeSweeperDo,
|
|
49
49
|
} from '@substrat-run/adapter-cloudflare';
|
|
50
|
-
import {
|
|
50
|
+
import {
|
|
51
|
+
PLATFORM_REQUEST_HEADER,
|
|
52
|
+
readRoutedNode,
|
|
53
|
+
RouterAssertionError,
|
|
54
|
+
type ScopeStub,
|
|
55
|
+
invocationLog,
|
|
56
|
+
} from '@substrat-run/kernel';
|
|
51
57
|
import { mountPlatformSurface } from '@substrat-run/vertical-host';
|
|
52
58
|
import { MODULES, OWNER_ROLE_KEY, ROLES } from './provision.js';
|
|
53
59
|
import { SHOP_ENV } from './manifest.js';
|
|
@@ -213,7 +219,14 @@ async function stub(c: Context<{ Bindings: Env }>): Promise<ScopeStub> {
|
|
|
213
219
|
const node = nodeFor(c.req.raw, c.env);
|
|
214
220
|
const principal = await authenticatedPrincipal(c.req.raw, c.env);
|
|
215
221
|
if (!principal) throw new HTTPException(401, { message: await unauthorizedReason(c.env, node) });
|
|
216
|
-
return hostFor(c.env).getScope(principal, node.tenantId, node.scopeId
|
|
222
|
+
return hostFor(c.env).getScope(principal, node.tenantId, node.scopeId, {
|
|
223
|
+
// An operation that called `ctx.requestPlatform` flags its response, and the router
|
|
224
|
+
// drains this scope within seconds instead of at the next sweep. Leave it wired even
|
|
225
|
+
// if nothing requests anything yet: the host calls this only when a committed invoke
|
|
226
|
+
// enqueued at least one intent, so it costs nothing until then, and without it every
|
|
227
|
+
// platform intent waits up to a quarter of an hour.
|
|
228
|
+
onPlatformRequests: () => c.header(PLATFORM_REQUEST_HEADER, '1'),
|
|
229
|
+
});
|
|
217
230
|
}
|
|
218
231
|
|
|
219
232
|
/**
|