@owlmeans/viable-common 0.0.5 → 0.0.7
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/README.md +1 -68
- package/build/areas/consts.d.ts +1 -1
- package/build/areas/consts.js +1 -1
- package/build/connect/consts.d.ts +6 -94
- package/build/connect/consts.d.ts.map +1 -1
- package/build/connect/consts.js +2 -91
- package/build/connect/consts.js.map +1 -1
- package/build/connect/entrypoints.d.ts +3 -3
- package/build/connect/entrypoints.d.ts.map +1 -1
- package/build/connect/entrypoints.js +54 -95
- package/build/connect/entrypoints.js.map +1 -1
- package/build/connect/ops.d.ts +2 -46
- package/build/connect/ops.d.ts.map +1 -1
- package/build/connect/references.d.ts +63 -117
- package/build/connect/references.d.ts.map +1 -1
- package/build/connect/references.js +0 -16
- package/build/connect/references.js.map +1 -1
- package/build/connect/schemas.d.ts +2 -17
- package/build/connect/schemas.d.ts.map +1 -1
- package/build/connect/schemas.js +7 -91
- package/build/connect/schemas.js.map +1 -1
- package/build/connect/types.d.ts +1 -125
- package/build/connect/types.d.ts.map +1 -1
- package/build/dev/types.d.ts +3 -2
- package/build/dev/types.d.ts.map +1 -1
- package/build/index.d.ts +0 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +0 -1
- package/build/index.js.map +1 -1
- package/build/skills/catalogue.d.ts.map +1 -1
- package/build/skills/catalogue.js +109 -103
- package/build/skills/catalogue.js.map +1 -1
- package/build/slot/consts.d.ts +2 -73
- package/build/slot/consts.d.ts.map +1 -1
- package/build/slot/consts.js +5 -105
- package/build/slot/consts.js.map +1 -1
- package/build/slot/schemas.d.ts +1 -9
- package/build/slot/schemas.d.ts.map +1 -1
- package/build/slot/schemas.js +0 -18
- package/build/slot/schemas.js.map +1 -1
- package/build/slot/types.d.ts +0 -71
- package/build/slot/types.d.ts.map +1 -1
- package/package.json +7 -15
- package/src/areas/consts.ts +1 -1
- package/src/connect/consts.ts +2 -94
- package/src/connect/entrypoints.ts +69 -139
- package/src/connect/ops.ts +2 -50
- package/src/connect/references.ts +56 -32
- package/src/connect/schemas.ts +13 -102
- package/src/connect/types.ts +2 -130
- package/src/dev/types.ts +3 -2
- package/src/index.ts +0 -1
- package/src/skills/catalogue.ts +109 -103
- package/src/slot/consts.ts +6 -112
- package/src/slot/schemas.ts +1 -20
- package/src/slot/types.ts +0 -80
- package/agent-meta/manifest.json +0 -16
- package/agent-meta/skills/viable-common/SKILL.md +0 -179
- package/build/convert/consts.d.ts +0 -539
- package/build/convert/consts.d.ts.map +0 -1
- package/build/convert/consts.js +0 -630
- package/build/convert/consts.js.map +0 -1
- package/build/convert/helpers.d.ts +0 -91
- package/build/convert/helpers.d.ts.map +0 -1
- package/build/convert/helpers.js +0 -301
- package/build/convert/helpers.js.map +0 -1
- package/build/convert/index.d.ts +0 -11
- package/build/convert/index.d.ts.map +0 -1
- package/build/convert/index.js +0 -4
- package/build/convert/index.js.map +0 -1
- package/build/convert/schemas.d.ts +0 -62
- package/build/convert/schemas.d.ts.map +0 -1
- package/build/convert/schemas.js +0 -626
- package/build/convert/schemas.js.map +0 -1
- package/build/convert/types.d.ts +0 -683
- package/build/convert/types.d.ts.map +0 -1
- package/build/convert/types.js +0 -2
- package/build/convert/types.js.map +0 -1
- package/src/convert/consts.ts +0 -672
- package/src/convert/helpers.ts +0 -340
- package/src/convert/index.ts +0 -10
- package/src/convert/schemas.ts +0 -663
- package/src/convert/types.ts +0 -741
- package/tests/connect-convert.spec.ts +0 -161
- package/tests/convert.spec.ts +0 -318
- /package/tests/{design.spec.ts → design.test.ts} +0 -0
|
@@ -94,10 +94,10 @@ These files are the CONTRACT between the packages. Every screen, endpoint and jo
|
|
|
94
94
|
them, and each has a sentinel comment marking where a new line goes:
|
|
95
95
|
|
|
96
96
|
- \`sources/common/src/consts.ts\` — the \`app\` alias tree.
|
|
97
|
-
- \`sources/common/src/entrypoints.ts\` — the shared \`
|
|
98
|
-
- \`sources/api/src/entrypoints.ts\` — server
|
|
99
|
-
- \`sources/web/src/entrypoints.ts\` — client
|
|
100
|
-
- \`sources/worker/src/entrypoints.ts\` — job
|
|
97
|
+
- \`sources/common/src/entrypoints.ts\` — the shared immutable protocol tree (\`appEntrypoints\`).
|
|
98
|
+
- \`sources/api/src/entrypoints.ts\` — server bindings (\`bind\` + \`handlers<Context>()\`).
|
|
99
|
+
- \`sources/web/src/entrypoints.ts\` — client bindings (\`bindAll\` + \`bindScreen\`).
|
|
100
|
+
- \`sources/worker/src/entrypoints.ts\` — job bindings (\`bind\`).
|
|
101
101
|
- \`sources/web/src/nav.ts\` — the navigation registry: one line per screen, which
|
|
102
102
|
is the only thing that puts it in the menus.
|
|
103
103
|
|
|
@@ -249,13 +249,13 @@ in its own language, with no TypeScript syntax and no import statements it does
|
|
|
249
249
|
skill(ViableSkill.OwlMeansEntrypoints, 'Entrypoints — screens and endpoints', `
|
|
250
250
|
Everything this app addresses — a screen the browser renders, an endpoint the server answers
|
|
251
251
|
— is an OwlMeans **entrypoint**: declared with \`@owlmeans/entrypoint\` and \`@owlmeans/route\`
|
|
252
|
-
in the shared package,
|
|
253
|
-
\`@owlmeans/server-
|
|
252
|
+
in the shared package, bound with \`@owlmeans/client-entrypoint\` in the browser and
|
|
253
|
+
\`@owlmeans/server-entrypoint\` on the backend. \`@owlmeans/web-client\` builds the route table from the
|
|
254
254
|
entrypoints and renders it over the History API, so there is no router file, no \`<Routes>\` and
|
|
255
255
|
no \`app.get(...)\`. No third-party routing or HTTP-server package is installed — importing one
|
|
256
256
|
fails to resolve.
|
|
257
257
|
|
|
258
|
-
An entrypoint is DECLARED once in the shared package, then
|
|
258
|
+
An entrypoint protocol is DECLARED once in the shared package, then BOUND on each side that uses it.
|
|
259
259
|
|
|
260
260
|
**1. The alias.** Aliases live in ONE place, the \`app\` tree in
|
|
261
261
|
\`sources/common/src/consts.ts\`. NEVER write an alias string inline — always reference
|
|
@@ -263,27 +263,30 @@ An entrypoint is DECLARED once in the shared package, then ELEVATED on each side
|
|
|
263
263
|
|
|
264
264
|
${ALIAS_CONVENTION}
|
|
265
265
|
|
|
266
|
-
**2. The declaration** — \`sources/common/src/entrypoints.ts\`, one
|
|
267
|
-
|
|
266
|
+
**2. The declaration** — \`sources/common/src/entrypoints.ts\`, one property in the immutable
|
|
267
|
+
\`appEntrypoints\` protocol tree:
|
|
268
268
|
|
|
269
|
-
import {
|
|
269
|
+
import { openProtocol, protocol, contract, typed } from '@owlmeans/entrypoint'
|
|
270
270
|
import { route, frontend, RouteMethod } from '@owlmeans/route'
|
|
271
271
|
|
|
272
|
-
|
|
272
|
+
task: {
|
|
273
|
+
list: protocol(route(app.api.task.list, '/list', { parent: app.api.task }),
|
|
274
|
+
contract(typed<Task[]>()), { guards: DEFAULT_GUARD }),
|
|
275
|
+
}
|
|
273
276
|
|
|
274
277
|
- \`route(alias, path)\` is a BACKEND route by default. \`route(alias, path, frontend())\` makes
|
|
275
278
|
it a screen; \`frontend({ default: true, parent: app.web.base })\` makes it the index screen.
|
|
276
279
|
- Nest with \`{ parent: <group alias> }\` — the child path is APPENDED to the parent's, so the
|
|
277
280
|
child path is the tail only (\`'/list'\`, not \`'/tasks/list'\`).
|
|
278
281
|
- \`{ method: RouteMethod.POST }\` (from \`@owlmeans/route\`) for anything that is not a GET.
|
|
279
|
-
- \`
|
|
282
|
+
- \`contract.request({ body: typed<T>(TSchema) }, typed<Response>())\` whenever the body's type has a schema beside it in the shared
|
|
280
283
|
package — every generated type exports one, named after the type with a \`Schema\` suffix
|
|
281
284
|
(\`Task\` → \`TaskSchema\`). Import both from the shared package and use them; that is what makes
|
|
282
285
|
the framework reject a malformed request before your handler runs, so the handler never has to
|
|
283
286
|
check whether a field arrived. Still never INVENT a schema inline: if the type has none, leave
|
|
284
287
|
the endpoint unfiltered rather than writing a literal here that nothing else agrees with.
|
|
285
|
-
- Access is declarative: no \`
|
|
286
|
-
\`
|
|
288
|
+
- Access is declarative: no \`guards\` option = public, \`{ guards: DEFAULT_GUARD }\` = any signed-in user,
|
|
289
|
+
\`{ guards: DEFAULT_GUARD, gate: { alias: OIDC_GATE, params: ['<permission>'] } }\` = a permission is required.
|
|
287
290
|
\`<permission>\` is a SHAPE, never a value: build the real name from the domain being
|
|
288
291
|
implemented — the resource, TWO hyphens, the action, lowercase kebab-case, singular resource.
|
|
289
292
|
Do not write a bracketed word into an application, and do not copy a name out of this
|
|
@@ -293,30 +296,29 @@ array:
|
|
|
293
296
|
nothing and the gate then refuses every request. Guards and gates are INHERITED by children and
|
|
294
297
|
enforced by the framework — a handler or a screen never re-checks them.
|
|
295
298
|
|
|
296
|
-
**3. The
|
|
299
|
+
**3. The binding.** The protocol declaration alone renders and answers nothing.
|
|
297
300
|
|
|
298
301
|
- Server, \`sources/api/src/entrypoints.ts\`:
|
|
299
|
-
\`
|
|
302
|
+
\`bind(protocols.api.task.list, api.request(protocols.api.task.list, handleTaskList))\`
|
|
300
303
|
- Client screen, \`sources/web/src/entrypoints.ts\`:
|
|
301
|
-
\`
|
|
302
|
-
- Client CALL, same file:
|
|
303
|
-
|
|
304
|
-
browser. Passing a component to a backend alias is a hard error, not a warning.
|
|
304
|
+
\`bindScreen(protocols.web.taskList, handler(TaskListScreen))\`
|
|
305
|
+
- Client CALL, same file: \`bindAll(protocols.api.task)\`. This is what makes the protocol callable
|
|
306
|
+
from the browser. Passing a component to a backend protocol is a hard error, not a warning.
|
|
305
307
|
|
|
306
|
-
**A missing client
|
|
307
|
-
registered on the browser context, so \`ctx.entrypoint(
|
|
308
|
-
and returns it; the call site
|
|
309
|
-
|
|
308
|
+
**A missing client binding is invisible until the app runs.** The whole shared tree is
|
|
309
|
+
registered on the browser context, so \`ctx.entrypoint(protocol)\` finds the unbound declaration
|
|
310
|
+
and returns it; the call site assumes the protocol is bound, so the build can still be clean. The
|
|
311
|
+
only symptom is in the browser:
|
|
310
312
|
|
|
311
313
|
TypeError: entrypoint.call is not a function
|
|
312
314
|
|
|
313
|
-
That message means EXACTLY one thing — the
|
|
314
|
-
\`
|
|
315
|
-
|
|
315
|
+
That message means EXACTLY one thing — the protocol in that \`ctx.entrypoint(...)\` has no
|
|
316
|
+
\`bindAll(protocols.api)\` or specific \`bind(protocols.api.<name>)\` line in
|
|
317
|
+
\`sources/web/src/entrypoints.ts\`. Add the binding above the API binding sentinel. It is
|
|
316
318
|
never a broken component, never a bad import, and never a reason to rewrite the view model or to
|
|
317
319
|
replace the call with \`fetch\`. If the alias is not declared in
|
|
318
|
-
\`sources/common/src/entrypoints.ts\` either, declare it there FIRST:
|
|
319
|
-
shared
|
|
320
|
+
\`sources/common/src/entrypoints.ts\` either, declare it there FIRST: binding a protocol the
|
|
321
|
+
shared tree does not carry throws while the module is
|
|
320
322
|
still loading, which blanks the whole app instead of failing one call.
|
|
321
323
|
|
|
322
324
|
**4. An AREA is the PARENT entrypoint.** The chrome of the app — header, navigation, footer —
|
|
@@ -329,16 +331,16 @@ project, and an area contributes chrome AND a URL prefix:
|
|
|
329
331
|
- \`app.web.area.admin\` at \`/admin\` — the owner of the application.
|
|
330
332
|
- \`app.web.area.operator\` at \`/backoffice\` — staff running the business process; the back office.
|
|
331
333
|
|
|
332
|
-
Those four declarations and their
|
|
333
|
-
path, NEVER touch its \`
|
|
334
|
+
Those four declarations and their bindings are FIXED. NEVER add an area, NEVER change one's
|
|
335
|
+
path, NEVER touch its \`guards\`/\`gate\` options, NEVER re-declare one — put the screen in the area
|
|
334
336
|
whose access and audience it needs instead. A product's own roles are not areas: they are users
|
|
335
337
|
or operators holding different permissions.
|
|
336
338
|
|
|
337
339
|
// sources/common/src/entrypoints.ts — a screen: TAIL path, area as parent, no access
|
|
338
|
-
|
|
340
|
+
taskList: openProtocol(route(app.web.taskList, '/tasks', frontend({ parent: app.web.area.user }))),
|
|
339
341
|
|
|
340
342
|
// sources/web/src/entrypoints.ts
|
|
341
|
-
|
|
343
|
+
bindScreen(protocols.web.taskList, handler(TaskListScreen))
|
|
342
344
|
|
|
343
345
|
That screen answers at \`/frontoffice/tasks\`. The path you write is the TAIL ONLY — repeating the
|
|
344
346
|
area prefix (\`'/frontoffice/tasks'\`) publishes it at \`/frontoffice/frontoffice/tasks\`, which
|
|
@@ -349,7 +351,7 @@ The framework passes the matched child to the area as \`children\`, so an area l
|
|
|
349
351
|
renders ONLY its own content: importing a layout inside a screen renders the header, the menu
|
|
350
352
|
and the footer a second time, nested inside the first.
|
|
351
353
|
|
|
352
|
-
- \`app.web.base\` stays
|
|
354
|
+
- \`app.web.base\` stays BOUND with \`stab\` — \`bindScreen(protocols.web.base, stab)\`, no \`handler()\`. It is the
|
|
353
355
|
pass-through shell that hosts the four areas and contributes no chrome.
|
|
354
356
|
- Every area needs a child declared \`frontend({ default: true, parent: app.web.area.<area> })\`.
|
|
355
357
|
An entrypoint with children but no default child matches nothing and renders a BLANK PAGE.
|
|
@@ -358,20 +360,20 @@ and the footer a second time, nested inside the first.
|
|
|
358
360
|
**Access is INHERITED from the area.** Guards and gates cascade to children, so choosing the area
|
|
359
361
|
IS the access decision and a screen declares none of its own:
|
|
360
362
|
|
|
361
|
-
- guest area — no
|
|
362
|
-
- user area — \`
|
|
363
|
-
- admin area — \`
|
|
363
|
+
- guest area — no guards option; its screens add nothing.
|
|
364
|
+
- user area — \`{ guards: DEFAULT_GUARD }\`; its screens add nothing.
|
|
365
|
+
- admin area — \`{ guards: DEFAULT_GUARD, gate: { alias: OIDC_GATE, params: ['project--admin'] } }\`; its screens add
|
|
364
366
|
nothing, the marker is the whole rule.
|
|
365
|
-
- operator area — \`
|
|
366
|
-
\`gate
|
|
367
|
+
- operator area — \`{ guards: DEFAULT_GUARD, gate: { alias: OIDC_GATE, params: ['project--operator'] } }\`, and EVERY screen under it additionally declares
|
|
368
|
+
a \`gate\` option naming the permission THAT screen needs, built from the
|
|
367
369
|
screen's own resource and action (add \`@<routeParam>\` when the screen shows one specific
|
|
368
370
|
record). This is the ONLY screen that declares access.
|
|
369
371
|
|
|
370
|
-
An ENDPOINT has no area to inherit from, so it states its level itself: no \`
|
|
371
|
-
\`
|
|
372
|
-
\`
|
|
372
|
+
An ENDPOINT has no area to inherit from, so it states its level itself: no \`guards\` option for guest,
|
|
373
|
+
\`{ guards: DEFAULT_GUARD }\` for any signed-in user,
|
|
374
|
+
\`{ guards: DEFAULT_GUARD, gate: { alias: OIDC_GATE, params: ['<permission>'] } }\` when a permission is required — built
|
|
373
375
|
from ITS OWN resource and action — and
|
|
374
|
-
\`
|
|
376
|
+
\`{ guards: DEFAULT_GUARD, gate: { alias: OIDC_GATE, params: ['project--admin'] } }\` for owner-only.
|
|
375
377
|
|
|
376
378
|
\`project--admin\` is the OWNER's marker — holding it passes EVERY gate, so the owner is not a
|
|
377
379
|
role inside the app. It is never one of the permissions this app declares for itself, and it is
|
|
@@ -380,17 +382,18 @@ existing guard to make something reachable, and never model a "limited admin" wi
|
|
|
380
382
|
that is an ordinary user holding some of the app's own permissions.
|
|
381
383
|
|
|
382
384
|
Insert every new line ABOVE the matching \`// owlmeans: add new ... above this line\` sentinel,
|
|
383
|
-
one declaration or
|
|
384
|
-
|
|
385
|
-
|
|
385
|
+
one declaration or binding per line. Adding an endpoint touches five files (alias,
|
|
386
|
+
protocol, handler, server binding, client binding); a screen touches five too (alias,
|
|
387
|
+
protocol, screen component, client binding, navigation entry). Skipping one leaves it
|
|
386
388
|
unreachable.
|
|
387
389
|
|
|
388
|
-
**Calling an endpoint** from the frontend — \`call()\` resolves to the VALUE, and a non-2xx THROWS
|
|
390
|
+
**Calling an endpoint** from the frontend — \`call()\` resolves to the VALUE, and a non-2xx THROWS.
|
|
391
|
+
Use the shared protocol reference; request and response types come from its contract:
|
|
389
392
|
|
|
390
|
-
const tasks = await owlCtx.entrypoint
|
|
391
|
-
const task = await owlCtx.entrypoint
|
|
393
|
+
const tasks = await owlCtx.entrypoint(protocols.api.task.list).call()
|
|
394
|
+
const task = await owlCtx.entrypoint(protocols.api.task.create)
|
|
392
395
|
.call({ body: input })
|
|
393
|
-
const task = await owlCtx.entrypoint
|
|
396
|
+
const task = await owlCtx.entrypoint(protocols.api.task.get)
|
|
394
397
|
.call({ params: { taskId } })
|
|
395
398
|
|
|
396
399
|
An entrypoint carries three verbs and each answers a different question:
|
|
@@ -403,15 +406,9 @@ An entrypoint carries three verbs and each answers a different question:
|
|
|
403
406
|
for a fully qualified one. A SCREEN entrypoint answers only this verb — calling \`call()\` or
|
|
404
407
|
\`invoke()\` on one THROWS.
|
|
405
408
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
\`@owlmeans/client\` does NOT export it — importing it from there fails the build with
|
|
411
|
-
\`error TS2305: Module '"@owlmeans/client"' has no exported member 'ClientEntrypoint'\`.
|
|
412
|
-
And the type argument goes on \`ClientEntrypoint\`, never on \`entrypoint\` itself:
|
|
413
|
-
\`owlCtx.entrypoint<Task>(alias)\` fails with \`error TS2739: Type 'Task' is missing the
|
|
414
|
-
following properties from type 'BasicEntrypoint'\`.
|
|
409
|
+
Do not import or cast a legacy client-entrypoint type, and do not put a value type argument on
|
|
410
|
+
\`entrypoint\`. The protocol reference is the only source of request and response types; a call
|
|
411
|
+
site that needs a different shape must fix the shared contract instead of overriding it locally.
|
|
415
412
|
|
|
416
413
|
Inside a component or a hook — which is where nearly every call belongs — read the context with
|
|
417
414
|
\`useContext()\` from \`@owlmeans/web-client\`. \`owlCtx\` is for module-level code that has no
|
|
@@ -467,7 +464,7 @@ resolve.
|
|
|
467
464
|
a layout. The chrome comes from \`NavLayout\` (\`@owlmeans/web-panel\`), which the four area
|
|
468
465
|
layouts already render off this registry.
|
|
469
466
|
|
|
470
|
-
A screen with no line here compiles,
|
|
467
|
+
A screen with no line here compiles, binds and renders — it is simply reachable by direct URL
|
|
471
468
|
only, and nothing reports it.
|
|
472
469
|
`),
|
|
473
470
|
skill(ViableSkill.PermissionModel, 'Permissions — the name, the gate and the grant', `
|
|
@@ -477,7 +474,7 @@ copied out of this document is a gate nobody can ever pass.
|
|
|
477
474
|
|
|
478
475
|
A permission is ONE string that has to line up in three places:
|
|
479
476
|
|
|
480
|
-
1. the GATE on the
|
|
477
|
+
1. the GATE on the protocol — \`gate: { alias: OIDC_GATE, params: ['enquiry--view@enquiryId'] }\`
|
|
481
478
|
2. the permission DEFINITION registered for the project — name \`enquiry--view\`,
|
|
482
479
|
resource \`enquiry\`, action \`view\`, resource-scoped \`true\`
|
|
483
480
|
3. the GRANT an administrator makes, which addresses that definition by name.
|
|
@@ -485,9 +482,10 @@ A permission is ONE string that has to line up in three places:
|
|
|
485
482
|
**The \`@\` suffix belongs to the GATE ONLY. It is never part of a permission's name.**
|
|
486
483
|
|
|
487
484
|
// right — the gate scopes the check; the definition and the grant use the bare name
|
|
488
|
-
|
|
485
|
+
protocol(
|
|
489
486
|
route(app.api.enquiry.get, '/:enquiryId', { parent: app.api.enquiry }),
|
|
490
|
-
|
|
487
|
+
contract(typed<Enquiry>()),
|
|
488
|
+
{ guards: DEFAULT_GUARD, gate: { alias: OIDC_GATE, params: ['enquiry--view@enquiryId'] } },
|
|
491
489
|
)
|
|
492
490
|
// definition: enquiry--view grant: enquiry--view
|
|
493
491
|
|
|
@@ -531,16 +529,16 @@ examples; yours is not, so read the right-hand column as a shape and build the n
|
|
|
531
529
|
domain.
|
|
532
530
|
|
|
533
531
|
// WRONG — a bracketed word from an instruction, written as if it were a name
|
|
534
|
-
gate
|
|
535
|
-
gate
|
|
532
|
+
gate: { alias: OIDC_GATE, params: ['<permission>'] }
|
|
533
|
+
gate: { alias: OIDC_GATE, params: ['<resource>--<action>'] }
|
|
536
534
|
// RIGHT — this application's own resource and action
|
|
537
|
-
gate
|
|
535
|
+
gate: { alias: OIDC_GATE, params: ['appointment--modify'] }
|
|
538
536
|
// Costs: nothing registers a bracketed name, so the gate refuses every request forever.
|
|
539
537
|
|
|
540
538
|
// WRONG — a name copied out of a skill, a comment or another app's example
|
|
541
|
-
gate
|
|
539
|
+
gate: { alias: OIDC_GATE, params: ['article--modify'] } // in an application that has no articles
|
|
542
540
|
// RIGHT — a name that exists in THIS domain
|
|
543
|
-
gate
|
|
541
|
+
gate: { alias: OIDC_GATE, params: ['appointment--modify'] }
|
|
544
542
|
// Costs: the permission is asserted but never declared, so no administrator can grant it.
|
|
545
543
|
|
|
546
544
|
// WRONG — the selector carried into the stored name
|
|
@@ -551,15 +549,15 @@ domain.
|
|
|
551
549
|
|
|
552
550
|
// WRONG — a selector naming a param this route does not declare
|
|
553
551
|
route(app.api.appointment.get, '/:appointmentId')
|
|
554
|
-
gate
|
|
552
|
+
gate: { alias: OIDC_GATE, params: ['appointment--view@id'] }
|
|
555
553
|
// RIGHT — the name after @ is a ":" segment of this very route
|
|
556
|
-
gate
|
|
554
|
+
gate: { alias: OIDC_GATE, params: ['appointment--view@appointmentId'] }
|
|
557
555
|
// Costs: the id resolves to nothing, so the endpoint refuses every request with nothing logged.
|
|
558
556
|
|
|
559
557
|
// WRONG — one hyphen
|
|
560
|
-
gate
|
|
558
|
+
gate: { alias: OIDC_GATE, params: ['appointment-modify'] }
|
|
561
559
|
// RIGHT — two
|
|
562
|
-
gate
|
|
560
|
+
gate: { alias: OIDC_GATE, params: ['appointment--modify'] }
|
|
563
561
|
// Costs: it registers as a resource with no action, and never lines up with the real one.
|
|
564
562
|
|
|
565
563
|
**Never spell one permission two ways.** Reuse the exact string an existing declaration already
|
|
@@ -980,7 +978,7 @@ So a null check around it is dead code that never runs:
|
|
|
980
978
|
const svc = ctx.service(ALIAS)
|
|
981
979
|
if (!svc) { throw { status: 503 } }
|
|
982
980
|
|
|
983
|
-
\`ctx.resource(alias)\` and \`ctx.entrypoint(
|
|
981
|
+
\`ctx.resource(alias)\` and \`ctx.entrypoint(protocol)\` throw the same way
|
|
984
982
|
(\`Resource X not found\`, \`Entrypoint X not found\`).
|
|
985
983
|
|
|
986
984
|
**Only when a real lifecycle-owning singleton is needed** — a client holding a connection, a
|
|
@@ -1067,28 +1065,37 @@ There is NO express here. \`express\`, \`cors\` and \`@types/express\` are not i
|
|
|
1067
1065
|
no \`app.get(...)\`, no \`req\`/\`res\` of a web server, no \`next\`, and no middleware. Anything
|
|
1068
1066
|
written for express fails to resolve.
|
|
1069
1067
|
|
|
1070
|
-
A handler is a plain async function that RETURNS its result,
|
|
1071
|
-
from \`@owlmeans/server-
|
|
1068
|
+
A handler is a plain async function that RETURNS its result, created from the protocol with a
|
|
1069
|
+
typed helper from \`@owlmeans/server-api\`. Pick by what the handler reads:
|
|
1072
1070
|
|
|
1073
|
-
import {
|
|
1071
|
+
import { handlers } from '@owlmeans/server-api'
|
|
1072
|
+
import { bind } from '@owlmeans/server-entrypoint'
|
|
1073
|
+
import { protocols } from 'project-common/entrypoints'
|
|
1074
|
+
const api = handlers<Context>()
|
|
1074
1075
|
|
|
1075
|
-
// the request BODY — the payload type
|
|
1076
|
-
|
|
1076
|
+
// the request BODY — the payload type comes from the protocol contract
|
|
1077
|
+
const createTask = api.body(protocols.api.task.create, async (payload, ctx) => {
|
|
1077
1078
|
const tasks = getTaskResource(ctx)
|
|
1078
1079
|
return await tasks.create(payload)
|
|
1079
1080
|
})
|
|
1080
1081
|
|
|
1081
1082
|
// the route PARAMS — names match the ':' segments of the declared path
|
|
1082
|
-
|
|
1083
|
+
const getTask = api.params(protocols.api.task.get, async ({ taskId }, ctx) => {
|
|
1083
1084
|
return await tasks(ctx).load(taskId)
|
|
1084
1085
|
})
|
|
1085
1086
|
|
|
1086
1087
|
// anything else (query, headers, nothing at all) — the whole request
|
|
1087
|
-
|
|
1088
|
+
const listTasks = api.request(protocols.api.task.list, async (req, ctx) => {
|
|
1088
1089
|
const query = req.query as { search?: string }
|
|
1089
1090
|
return await tasks(ctx).list(query.search != null ? { search: query.search } : {})
|
|
1090
1091
|
})
|
|
1091
1092
|
|
|
1093
|
+
export const entrypoints = [
|
|
1094
|
+
bind(protocols.api.task.create, createTask),
|
|
1095
|
+
bind(protocols.api.task.get, getTask),
|
|
1096
|
+
bind(protocols.api.task.list, listTasks),
|
|
1097
|
+
]
|
|
1098
|
+
|
|
1092
1099
|
- The SECOND argument is the OwlMeans context. Reach every resource through it — never
|
|
1093
1100
|
import a database connection and never write raw SQL in a handler.
|
|
1094
1101
|
- RETURN the value. \`res.json(...)\`, \`res.status(...)\`, \`res.send(...)\` do not exist; a
|
|
@@ -1097,9 +1104,9 @@ from \`@owlmeans/server-app\`. Pick by what the handler reads:
|
|
|
1097
1104
|
\`ResilientError\` subclass is mapped to its status by the framework; catching it produces a
|
|
1098
1105
|
200 carrying an error object instead.
|
|
1099
1106
|
- Never read a token, never check a role, never look at an \`Authorization\` header. Access is
|
|
1100
|
-
declared on the
|
|
1101
|
-
- A handler is inert until
|
|
1102
|
-
\`sources/api/src/entrypoints.ts\` binds it to its
|
|
1107
|
+
declared on the protocol (\`guards\` / \`gate\` options) and enforced before the handler runs.
|
|
1108
|
+
- A handler is inert until a \`bind(protocols.api.<name>, handler)\` line in
|
|
1109
|
+
\`sources/api/src/entrypoints.ts\` binds it to its protocol. Without that line the endpoint
|
|
1103
1110
|
answers 404 and nothing reports an error.
|
|
1104
1111
|
- Handlers are ENTITY-SCOPED: \`sources/api/src/app/<entity>/<action>.ts\`, named exports only.
|
|
1105
1112
|
The directory is what keeps two entities' \`list\` apart — the file name carries no marker.
|
|
@@ -1159,15 +1166,15 @@ says before rewriting anything.
|
|
|
1159
1166
|
\`@reduxjs/toolkit\`, \`react-redux\`, \`@/state/store\` or \`@/lib/fetch\` means the file was
|
|
1160
1167
|
written against the REMOVED stack. None of those packages are installed and none will be.
|
|
1161
1168
|
Rewrite the file against entrypoints: \`useNavigate\` from \`@owlmeans/client\` for navigation,
|
|
1162
|
-
\`ctx.entrypoint(
|
|
1163
|
-
\`
|
|
1169
|
+
\`ctx.entrypoint(protocol).call(...)\` for a backend call, a typed
|
|
1170
|
+
\`handlers<Context>()\` callback bound to its protocol for an endpoint, and the state hooks
|
|
1164
1171
|
(\`useStoreModel\`/\`useStoreList\` over a state resource) for client state. Do NOT install the
|
|
1165
1172
|
package and do NOT create the missing module.
|
|
1166
1173
|
- A missing export from a \`*.ts\` module — a selector, an action creator, a thunk, a
|
|
1167
1174
|
reducer — is the same removed stack in a different disguise. That module exports an ALIAS
|
|
1168
1175
|
constant and read hooks only. Replace a selector with the matching hook, a dispatched action
|
|
1169
1176
|
with \`resource.save(record)\` / \`model.update({ ... })\`, and a thunk with an
|
|
1170
|
-
\`entrypoint(
|
|
1177
|
+
\`entrypoint(protocol).call(...)\` in the VIEW MODEL followed by a \`save\`. Do not add the missing
|
|
1171
1178
|
export to the state module.
|
|
1172
1179
|
- A runtime \`Resource <alias> not found\` for a state alias means the state module is written but
|
|
1173
1180
|
nothing registered it. Add the import and ONE
|
|
@@ -1185,21 +1192,20 @@ says before rewriting anything.
|
|
|
1185
1192
|
that changes which records match, so the \`useValue(() => resource.list())\` that fed it a list
|
|
1186
1193
|
of ids goes away entirely rather than being repaired.
|
|
1187
1194
|
- A runtime \`TypeError: entrypoint.call is not a function\` (or \`<name>.call is not a function\`
|
|
1188
|
-
on the result of \`ctx.entrypoint(...)\`) is a MISSING CLIENT
|
|
1189
|
-
|
|
1190
|
-
one has \`call\`. Add
|
|
1191
|
-
|
|
1195
|
+
on the result of \`ctx.entrypoint(...)\`) is a MISSING CLIENT BINDING and nothing else. The
|
|
1196
|
+
protocol resolves — the browser context carries every shared declaration — but only a bound
|
|
1197
|
+
one has \`call\`. Add \`bindAll(protocols.api)\` (or a specific \`bind(protocols.api.<name>)\`) above the
|
|
1198
|
+
API binding sentinel in
|
|
1192
1199
|
\`sources/web/src/entrypoints.ts\`. Do NOT rewrite the view model, do NOT replace the
|
|
1193
|
-
call with \`fetch\`, and do NOT add a component to a backend alias. The
|
|
1194
|
-
|
|
1195
|
-
the elevation line is the fix.
|
|
1200
|
+
call with \`fetch\`, and do NOT add a component to a backend alias. The binding line is the fix;
|
|
1201
|
+
the declaration itself cannot provide \`call\` until a client binding materializes it.
|
|
1196
1202
|
- A screen that renders blank is the same class of fault on the other side: the screen alias has
|
|
1197
|
-
no \`
|
|
1203
|
+
no \`bindScreen(protocols.web.<name>, handler(Screen))\` line. Adding a protocol without its binding
|
|
1198
1204
|
is the usual cause of both.
|
|
1199
1205
|
- A header, menu or footer rendered TWICE is a screen importing its own layout. The AREA is the
|
|
1200
1206
|
screen's parent entrypoint and the framework already wraps it — delete the import and the
|
|
1201
1207
|
wrapper element from the screen, never the area from the entrypoint tree.
|
|
1202
|
-
- An error naming an AREA — \`app.web.area.<area>\`, its \`route(...)\`, its \`
|
|
1208
|
+
- An error naming an AREA — \`app.web.area.<area>\`, its \`route(...)\`, its \`guards\`/\`gate\` options,
|
|
1203
1209
|
or one of the four layouts in \`sources/web/src/layout/area.tsx\` — means generated code
|
|
1204
1210
|
EDITED something that ships with the project. RESTORE the shipped form: four areas under
|
|
1205
1211
|
\`app.web.base\` at \`/\`, \`/frontoffice\`, \`/admin\` and \`/backoffice\`, each with its own guard
|
|
@@ -1208,14 +1214,14 @@ says before rewriting anything.
|
|
|
1208
1214
|
access belongs in a different area.
|
|
1209
1215
|
- A user who WAS granted a permission and still gets 403 is almost always an \`@\` in the stored
|
|
1210
1216
|
permission NAME. The gate splits its parameter at the first \`@\`: \`'enquiry--view@enquiryId'\`
|
|
1211
|
-
in \`gate
|
|
1217
|
+
in a protocol's \`gate: { alias: OIDC_GATE, params: [...] }\` is CORRECT and means "look up \`enquiry--view\`, read the resource
|
|
1212
1218
|
id from the \`:enquiryId\` route param". The same string registered or granted as a permission
|
|
1213
1219
|
NAME is a key nothing ever looks up, so every grant against it is a silent no-op. Fix the
|
|
1214
1220
|
registration and the grant, never the gate line — and never delete the \`@\` from the gate to
|
|
1215
1221
|
"make the names match". A gate whose \`@name\` is not a \`:\` segment of that entrypoint's own
|
|
1216
1222
|
declared path is the other half of the same fault: it refuses every request.
|
|
1217
1223
|
- A PERMISSION that no definition backs is a gate nobody can pass, and there are two ways generated
|
|
1218
|
-
code gets one. A bracketed word — \`gate
|
|
1224
|
+
code gets one. A bracketed word — \`gate: { alias: OIDC_GATE, params: ['<permission>'] }\` — is an instruction's
|
|
1219
1225
|
placeholder written out as if it were a name. A foreign name — \`article--modify\` in an
|
|
1220
1226
|
application that has no articles — is an example copied from a comment or a skill. Both look
|
|
1221
1227
|
perfectly valid to the compiler and to the boot check, so nothing reports them; the app simply
|
|
@@ -1339,12 +1345,12 @@ export const queues: QueueDeclaration[] = [
|
|
|
1339
1345
|
|
|
1340
1346
|
## 2. The alias and the entrypoint — \`sources/common/src\`
|
|
1341
1347
|
The job's name IS its entrypoint alias. Declare \`app.job.<name>\` in \`consts.ts\` above the
|
|
1342
|
-
sentinel, and the
|
|
1348
|
+
sentinel, and the protocol in \`entrypoints.ts\` with \`job()\` from \`@owlmeans/route\`.
|
|
1343
1349
|
|
|
1344
1350
|
## 3. The processor — \`sources/worker/src/jobs/<name>.ts\`
|
|
1345
|
-
A plain async function
|
|
1346
|
-
|
|
1347
|
-
|
|
1351
|
+
A plain async function created with \`handlers<Context>()\` and bound to the job protocol, exactly
|
|
1352
|
+
like an endpoint handler. It RETURNS its result; throwing a \`ResilientError\` subclass is how a
|
|
1353
|
+
refusal is reported, and the class survives the broker.
|
|
1348
1354
|
|
|
1349
1355
|
Two rules with no equivalent on the HTTP side:
|
|
1350
1356
|
- **Call \`job.touch()\` inside every long loop.** The broker judges liveness by the lock, and
|
|
@@ -1353,8 +1359,8 @@ Two rules with no equivalent on the HTTP side:
|
|
|
1353
1359
|
- **A processor must be safe to run twice.** Skip what a previous attempt recorded, or delete
|
|
1354
1360
|
what it created, and say in a comment which of the two this one does.
|
|
1355
1361
|
|
|
1356
|
-
|
|
1357
|
-
with \`context.
|
|
1362
|
+
Bind it in \`sources/worker/src/entrypoints.ts\` above the sentinel. Enqueue from an endpoint
|
|
1363
|
+
with the same typed call used for HTTP: \`context.entrypoint(appEntrypoints.job.<name>).call({ body: data })\`.
|
|
1358
1364
|
`),
|
|
1359
1365
|
skill(ViableSkill.TargetAgents, 'LLM agents inside the application', `
|
|
1360
1366
|
An agent generated into the application is an \`@owlmeans/agent\` model, built in the shared
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalogue.js","sourceRoot":"","sources":["../../src/skills/catalogue.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"catalogue.js","sourceRoot":"","sources":["../../src/skills/catalogue.ts"],"names":[],"mappings":"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"}
|
package/build/slot/consts.d.ts
CHANGED
|
@@ -38,14 +38,6 @@ export declare enum SlotCommandType {
|
|
|
38
38
|
}
|
|
39
39
|
export declare enum SlotGitCommand {
|
|
40
40
|
Ensure = "ensure",
|
|
41
|
-
/**
|
|
42
|
-
* Bring a remote repository's tree onto a volume that already exists.
|
|
43
|
-
*
|
|
44
|
-
* NOT `git clone`: a slot's directory is never empty — provisioning leaves its own metadata
|
|
45
|
-
* there — and `git clone` refuses a non-empty destination. The executor therefore initializes,
|
|
46
|
-
* adds the remote, fetches at a bounded depth and checks the branch out over the tree.
|
|
47
|
-
*/
|
|
48
|
-
Clone = "clone",
|
|
49
41
|
Status = "status",
|
|
50
42
|
Commit = "commit",
|
|
51
43
|
Log = "log",
|
|
@@ -69,35 +61,7 @@ export declare enum SlotFileCommand {
|
|
|
69
61
|
WriteSource = "writeSource",
|
|
70
62
|
DeleteFile = "deleteFile",
|
|
71
63
|
FindFilesWithEnvVars = "findFilesWithEnvVars",
|
|
72
|
-
GetRootPath = "getRootPath"
|
|
73
|
-
/**
|
|
74
|
-
* List a tree with a size and a binary flag per entry, bounded by a caller-given limit.
|
|
75
|
-
*
|
|
76
|
-
* The reason it exists rather than being composed out of {@link SlotFileCommand.GetSourceList}
|
|
77
|
-
* plus a read per file: a foreign repository can hold a hundred thousand files, and one round
|
|
78
|
-
* trip each — over a signed HTTP call to a pod, or over a connector on somebody's laptop — is
|
|
79
|
-
* not a slower version of the same thing, it is a walk that never finishes.
|
|
80
|
-
*/
|
|
81
|
-
StatTree = "statTree",
|
|
82
|
-
/**
|
|
83
|
-
* Read the first N bytes of one file.
|
|
84
|
-
*
|
|
85
|
-
* A census classifies a file from its head; reading whole files to do it would hold a 1 MB
|
|
86
|
-
* export in memory to look at its first line. The answer is text, so a binary head comes back
|
|
87
|
-
* as whatever decoding produced — which is exactly the signal the entropy classification wants.
|
|
88
|
-
*/
|
|
89
|
-
ReadHead = "readHead",
|
|
90
|
-
/**
|
|
91
|
-
* Move everything in the project root into a subdirectory, keeping a named few in place.
|
|
92
|
-
*
|
|
93
|
-
* One command rather than a listing plus a move per file, because it must be ATOMIC from the
|
|
94
|
-
* caller's point of view: a relocation interrupted half way leaves a tree that is neither the
|
|
95
|
-
* origin nor a target, and nothing downstream can tell which files already moved. Binary-safe —
|
|
96
|
-
* it moves paths and never reads contents.
|
|
97
|
-
*/
|
|
98
|
-
Relocate = "relocate",
|
|
99
|
-
/** Delete a directory and everything under it. The purge of a relocated origin. */
|
|
100
|
-
RemoveTree = "removeTree"
|
|
64
|
+
GetRootPath = "getRootPath"
|
|
101
65
|
}
|
|
102
66
|
export declare enum SlotShellCommand {
|
|
103
67
|
Bun = "bun",
|
|
@@ -237,26 +201,6 @@ export declare const LOCAL_SLOT_HOST = "localhost:5173";
|
|
|
237
201
|
*/
|
|
238
202
|
export declare const COMMAND_DEADLINES: Record<string, number>;
|
|
239
203
|
export declare const DEFAULT_COMMAND_DEADLINE = 60000;
|
|
240
|
-
/**
|
|
241
|
-
* EXECUTOR-side ceilings for the git commands whose real duration is not a git command's.
|
|
242
|
-
*
|
|
243
|
-
* Everything git does inside a slot is local and takes seconds — except a clone, which is a
|
|
244
|
-
* network fetch of somebody else's repository and is measured in minutes. Bounding it by the
|
|
245
|
-
* generic git deadline made a conversion's very first step fail on any repository large enough
|
|
246
|
-
* to be worth converting.
|
|
247
|
-
*/
|
|
248
|
-
export declare const GIT_COMMAND_DEADLINES: Partial<Record<SlotGitCommand, number>>;
|
|
249
|
-
/** What every other git command gets. The value the type-level branch used to hard-code. */
|
|
250
|
-
export declare const DEFAULT_GIT_COMMAND_DEADLINE = 60000;
|
|
251
|
-
/**
|
|
252
|
-
* EXECUTOR-side ceilings for the file commands that walk or move a whole tree.
|
|
253
|
-
*
|
|
254
|
-
* The other file commands are one path each and finish in milliseconds; these three are bounded
|
|
255
|
-
* by how big the tree is, which for an origin project is set by whoever wrote it.
|
|
256
|
-
*/
|
|
257
|
-
export declare const FILE_COMMAND_DEADLINES: Partial<Record<SlotFileCommand, number>>;
|
|
258
|
-
/** What every other file command gets. The value the type-level branch used to hard-code. */
|
|
259
|
-
export declare const DEFAULT_FILE_COMMAND_DEADLINE = 30000;
|
|
260
204
|
/**
|
|
261
205
|
* CALLER-side ceilings per command type: how long the asker waits for an answer.
|
|
262
206
|
*
|
|
@@ -277,15 +221,6 @@ export declare const DEFAULT_COMMAND_TIMEOUT = 60000;
|
|
|
277
221
|
* install still needs.
|
|
278
222
|
*/
|
|
279
223
|
export declare const SHELL_COMMAND_TIMEOUTS: Record<string, number>;
|
|
280
|
-
/**
|
|
281
|
-
* Per-COMMAND caller ceilings for git and for files.
|
|
282
|
-
*
|
|
283
|
-
* Each is its executor deadline plus the same 40 s margin: the caller's bound must outlast the
|
|
284
|
-
* executor's, or a command that failed cleanly inside its own deadline reaches the caller as a
|
|
285
|
-
* timeout and the real reason — the one the executor took the trouble to produce — is lost.
|
|
286
|
-
*/
|
|
287
|
-
export declare const GIT_COMMAND_TIMEOUTS: Partial<Record<SlotGitCommand, number>>;
|
|
288
|
-
export declare const FILE_COMMAND_TIMEOUTS: Partial<Record<SlotFileCommand, number>>;
|
|
289
224
|
/**
|
|
290
225
|
* Resolve the caller-side bound for one command.
|
|
291
226
|
*
|
|
@@ -294,12 +229,6 @@ export declare const FILE_COMMAND_TIMEOUTS: Partial<Record<SlotFileCommand, numb
|
|
|
294
229
|
* added to stop.
|
|
295
230
|
*/
|
|
296
231
|
export declare const commandTimeout: (type: SlotCommandType, command: string, override?: number) => number;
|
|
297
|
-
/**
|
|
298
|
-
* Resolve the executor-side deadline for one command.
|
|
299
|
-
*
|
|
300
|
-
* Per-command first, per-type second. It was per-type only, which is how a clone inherited the
|
|
301
|
-
* bound of a `git status` — the same shape as the shell table above, and added for the same
|
|
302
|
-
* reason.
|
|
303
|
-
*/
|
|
232
|
+
/** Resolve the executor-side deadline for one command. */
|
|
304
233
|
export declare const commandDeadline: (type: SlotCommandType, command: string) => number;
|
|
305
234
|
//# sourceMappingURL=consts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../../src/slot/consts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;;GAQG;AACH,oBAAY,YAAY;IACtB,SAAS,cAAc;IACvB,UAAU,eAAe;IACzB;;;;;;;OAOG;IACH,KAAK,UAAU;CAChB;AAED,oBAAY,eAAe;IACzB,KAAK,UAAU;IACf,KAAK,UAAU;IACf,GAAG,QAAQ;CACZ;AAED,oBAAY,cAAc;IACxB,MAAM,WAAW;IACjB
|
|
1
|
+
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../../src/slot/consts.ts"],"names":[],"mappings":"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"}
|