@jskit-ai/agent-docs 0.1.257 → 0.1.258
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/guide/agent/app-extras/assistant-conversation.md +88 -35
- package/guide/agent/app-extras/assistant.md +28 -28
- package/guide/agent/app-setup/authentication.md +36 -17
- package/guide/agent/app-setup/database-layer.md +116 -17
- package/guide/agent/app-setup/existing-application-migration.md +29 -25
- package/guide/agent/app-setup/multi-homing.md +94 -48
- package/guide/agent/app-setup/run-an-accounts-hub.md +6 -4
- package/guide/agent/framework/client-features.md +496 -0
- package/guide/agent/framework/crud-operations.md +5 -5
- package/guide/agent/framework/translation.md +4 -3
- package/guide/agent/framework/typed-features.md +1104 -0
- package/guide/agent/framework/ui-operations.md +2 -2
- package/guide/agent/index.md +6 -1
- package/package.json +1 -1
- package/patterns/feature-package/PATTERN.md +104 -10
- package/patterns/feature-package/example/booking-engine/package.json +9 -4
- package/patterns/feature-package/example/booking-engine/src/server/BookingEngineFeature.js +24 -0
- package/patterns/feature-package/example/booking-engine/src/server/bookingAvailability.js +10 -0
- package/patterns/feature-package/example/booking-engine/src/server/bookingEngine.js +29 -0
- package/patterns/feature-package/example/booking-engine/src/server/bookingEngineActions.js +26 -0
- package/patterns/feature-package/example/booking-engine/src/server/inputSchemas.js +1 -2
- package/patterns/feature-package/example/booking-engine/src/server/types.js +12 -0
- package/patterns/feature-package/example/variations/AvailabilityEngineFeature.js +19 -0
- package/patterns/feature-package/example/variations/InvoiceRollupFeature.js +23 -0
- package/patterns/feature-package/example/variations/availabilityEngineActions.js +26 -0
- package/patterns/feature-package/example/variations/customKnexRepository.js +32 -26
- package/patterns/feature-package/example/variations/invoiceRollupActions.js +26 -0
- package/patterns/feature-package/example/variations/orchestratorService.js +24 -19
- package/patterns/feature-package/example/variations/types.js +7 -0
- package/patterns/minimal-foundation/PATTERN.md +30 -1
- package/patterns/minimal-foundation/example/AGENTS.md +14 -0
- package/patterns/minimal-foundation/example/bin/develop.js +10 -5
- package/patterns/minimal-foundation/example/eslint.config.mjs +21 -2
- package/patterns/minimal-foundation/example/package.json +5 -4
- package/patterns/minimal-foundation/example/playwright.config.mjs +1 -1
- package/patterns/minimal-foundation/example/server/lib/envFile.js +19 -0
- package/patterns/minimal-foundation/example/server/lib/loggerOptions.js +15 -0
- package/patterns/minimal-foundation/example/server/lib/runtimeEnv.js +17 -17
- package/patterns/minimal-foundation/example/server.js +32 -29
- package/patterns/minimal-foundation/example/tests/server/smoke.test.js +2 -1
- package/patterns/shell-foundation/PATTERN.md +29 -0
- package/patterns/shell-foundation/example/AGENTS.md +14 -0
- package/patterns/shell-foundation/example/bin/develop.js +10 -5
- package/patterns/shell-foundation/example/eslint.config.mjs +21 -2
- package/patterns/shell-foundation/example/package.json +6 -5
- package/patterns/shell-foundation/example/packages/main/package.json +1 -1
- package/patterns/shell-foundation/example/packages/main/src/client/providers/MainClientProvider.js +1 -0
- package/patterns/shell-foundation/example/playwright.config.mjs +1 -1
- package/patterns/shell-foundation/example/server/lib/envFile.js +19 -0
- package/patterns/shell-foundation/example/server/lib/loggerOptions.js +15 -0
- package/patterns/shell-foundation/example/server/lib/runtimeEnv.js +17 -17
- package/patterns/shell-foundation/example/server.js +32 -29
- package/patterns/shell-foundation/example/tests/server/smoke.test.js +2 -1
- package/reference/autogen/KERNEL_MAP.md +14 -8
- package/reference/autogen/PATTERN_INDEX.md +37 -37
- package/reference/autogen/README.md +2 -0
- package/reference/autogen/packages/agent-docs.md +70 -26
- package/reference/autogen/packages/agent-runtime.md +129 -0
- package/reference/autogen/packages/agent.md +149 -0
- package/reference/autogen/packages/architecture-inspector.md +97 -44
- package/reference/autogen/packages/assistant-core.md +786 -292
- package/reference/autogen/packages/assistant-runtime.md +182 -57
- package/reference/autogen/packages/assistant-voice-sherpa.md +4 -0
- package/reference/autogen/packages/assistant-voice.md +54 -8
- package/reference/autogen/packages/auth-core.md +44 -13
- package/reference/autogen/packages/auth-provider-local-core.md +86 -34
- package/reference/autogen/packages/auth-provider-local-db-core.md +1 -2
- package/reference/autogen/packages/auth-provider-oidc-core.md +10 -4
- package/reference/autogen/packages/auth-provider-supabase-core.md +52 -66
- package/reference/autogen/packages/auth-web.md +19 -11
- package/reference/autogen/packages/connectors-catalog.md +71 -43
- package/reference/autogen/packages/connectors-core.md +42 -4
- package/reference/autogen/packages/console-core.md +27 -14
- package/reference/autogen/packages/crud-core.md +178 -170
- package/reference/autogen/packages/database-runtime-mysql.md +0 -2
- package/reference/autogen/packages/database-runtime-postgres.md +0 -2
- package/reference/autogen/packages/database-runtime.md +39 -10
- package/reference/autogen/packages/http-runtime.md +79 -57
- package/reference/autogen/packages/json-rest-api-core.md +11 -8
- package/reference/autogen/packages/kernel.md +144 -83
- package/reference/autogen/packages/oidc-issuer-core.md +49 -20
- package/reference/autogen/packages/payments-core.md +20 -3
- package/reference/autogen/packages/realtime.md +47 -22
- package/reference/autogen/packages/resource-core.md +1 -1
- package/reference/autogen/packages/resource-crud-core.md +64 -26
- package/reference/autogen/packages/rewarded-core.md +47 -36
- package/reference/autogen/packages/shell-web.md +7 -10
- package/reference/autogen/packages/storage-runtime.md +6 -2
- package/reference/autogen/packages/uploads-runtime.md +10 -2
- package/reference/autogen/packages/users-core.md +73 -71
- package/reference/autogen/packages/workspaces-core.md +121 -106
- package/reference/autogen/packages/workspaces-web.md +1 -2
- package/reference/autogen/tooling/config-eslint.md +302 -0
- package/reference/autogen/tooling/jskit-catalog.md +28 -18
- package/reference/autogen/tooling/jskit-release.md +35 -20
- package/reference/autogen/tooling/testUtils.md +3 -1
- package/skills/jskit/SKILL.md +3 -2
- package/skills/jskit/references/app-operations.md +1 -1
- package/skills/jskit/references/client-features.md +491 -0
- package/skills/jskit/references/crud-form-actions.md +1 -1
- package/skills/jskit/references/crud-operations.md +7 -7
- package/skills/jskit/references/existing-application-migration.md +31 -27
- package/skills/jskit/references/heuristics/INDEX.md +5 -1
- package/skills/jskit/references/heuristics/child-cruds.md +1 -1
- package/skills/jskit/references/heuristics/client-features.md +66 -0
- package/skills/jskit/references/heuristics/client-requests.md +1 -1
- package/skills/jskit/references/heuristics/crud-authoring.md +12 -2
- package/skills/jskit/references/heuristics/crud-links.md +1 -1
- package/skills/jskit/references/heuristics/crud-repository-mapping.md +3 -3
- package/skills/jskit/references/heuristics/filters.md +1 -1
- package/skills/jskit/references/heuristics/live-actions.md +1 -1
- package/skills/jskit/references/heuristics/page-redirects.md +1 -1
- package/skills/jskit/references/heuristics/page-scaffolding.md +1 -1
- package/skills/jskit/references/heuristics/placements.md +1 -1
- package/skills/jskit/references/heuristics/row-policies.md +1 -1
- package/skills/jskit/references/heuristics/server-search.md +1 -1
- package/skills/jskit/references/heuristics/surfaces.md +1 -1
- package/skills/jskit/references/heuristics/typed-features.md +100 -0
- package/skills/jskit/references/heuristics/ui-contract.md +1 -1
- package/skills/jskit/references/heuristics/ui-testing.md +4 -4
- package/skills/jskit/references/material-3.md +2 -2
- package/skills/jskit/references/multi-homing.md +96 -50
- package/skills/jskit/references/pattern-index.md +37 -37
- package/skills/jskit/references/patterns/app/minimal-foundation/PATTERN.md +30 -1
- package/skills/jskit/references/patterns/app/minimal-foundation/example/AGENTS.md +14 -0
- package/skills/jskit/references/patterns/app/minimal-foundation/example/bin/develop.js +10 -5
- package/skills/jskit/references/patterns/app/minimal-foundation/example/eslint.config.mjs +21 -2
- package/skills/jskit/references/patterns/app/minimal-foundation/example/package.json +5 -4
- package/skills/jskit/references/patterns/app/minimal-foundation/example/playwright.config.mjs +1 -1
- package/skills/jskit/references/patterns/app/minimal-foundation/example/server/lib/envFile.js +19 -0
- package/skills/jskit/references/patterns/app/minimal-foundation/example/server/lib/loggerOptions.js +15 -0
- package/skills/jskit/references/patterns/app/minimal-foundation/example/server/lib/runtimeEnv.js +17 -17
- package/skills/jskit/references/patterns/app/minimal-foundation/example/server.js +32 -29
- package/skills/jskit/references/patterns/app/minimal-foundation/example/tests/server/smoke.test.js +2 -1
- package/skills/jskit/references/patterns/app/shell-foundation/PATTERN.md +29 -0
- package/skills/jskit/references/patterns/app/shell-foundation/example/AGENTS.md +14 -0
- package/skills/jskit/references/patterns/app/shell-foundation/example/bin/develop.js +10 -5
- package/skills/jskit/references/patterns/app/shell-foundation/example/eslint.config.mjs +21 -2
- package/skills/jskit/references/patterns/app/shell-foundation/example/package.json +6 -5
- package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/package.json +1 -1
- package/skills/jskit/references/patterns/app/shell-foundation/example/packages/main/src/client/providers/MainClientProvider.js +1 -0
- package/skills/jskit/references/patterns/app/shell-foundation/example/playwright.config.mjs +1 -1
- package/skills/jskit/references/patterns/app/shell-foundation/example/server/lib/envFile.js +19 -0
- package/skills/jskit/references/patterns/app/shell-foundation/example/server/lib/loggerOptions.js +15 -0
- package/skills/jskit/references/patterns/app/shell-foundation/example/server/lib/runtimeEnv.js +17 -17
- package/skills/jskit/references/patterns/app/shell-foundation/example/server.js +32 -29
- package/skills/jskit/references/patterns/app/shell-foundation/example/tests/server/smoke.test.js +2 -1
- package/skills/jskit/references/patterns/assistant/assistant-surface/example/src/ApplicationAiFeature.js +4 -2
- package/skills/jskit/references/patterns/auth/accounts-hub/PATTERN.md +2 -1
- package/skills/jskit/references/patterns/auth/accounts-hub/example/package.json +2 -2
- package/skills/jskit/references/patterns/auth/accounts-hub/example/server/hubPaths.js +9 -3
- package/skills/jskit/references/patterns/auth/auth-surface/PATTERN.md +25 -12
- package/skills/jskit/references/patterns/auth/auth-surface/example/tools/preview-identity +7 -1
- package/skills/jskit/references/patterns/auth/oidc-sign-in/example/package.json +2 -2
- package/skills/jskit/references/patterns/auth/supabase-auth/example/package.json +1 -1
- package/skills/jskit/references/patterns/connectors/ai-connections/PATTERN.md +16 -1
- package/skills/jskit/references/patterns/connectors/ai-connections/example/ai-model.js +12 -3
- package/skills/jskit/references/patterns/connectors/ai-connections/example/perplexity-answer.js +15 -4
- package/skills/jskit/references/patterns/connectors/api-key-connection/PATTERN.md +9 -1
- package/skills/jskit/references/patterns/connectors/api-key-connection/example/connections.js +5 -2
- package/skills/jskit/references/patterns/connectors/aws-storage-queries/PATTERN.md +13 -3
- package/skills/jskit/references/patterns/connectors/aws-storage-queries/example/s3-transfer.js +14 -3
- package/skills/jskit/references/patterns/connectors/calendar-cli/PATTERN.md +8 -0
- package/skills/jskit/references/patterns/connectors/calendar-cli/example/knexfile.js +1 -1
- package/skills/jskit/references/patterns/connectors/calendar-cli/example/package.json +4 -4
- package/skills/jskit/references/patterns/connectors/calendar-cli/example/scripts/calendar.js +8 -4
- package/skills/jskit/references/patterns/connectors/event-delivery/PATTERN.md +1 -1
- package/skills/jskit/references/patterns/connectors/firebase-messaging/PATTERN.md +10 -0
- package/skills/jskit/references/patterns/connectors/firebase-messaging/example/server/notifications.js +8 -0
- package/skills/jskit/references/patterns/connectors/google-ads-search/PATTERN.md +18 -7
- package/skills/jskit/references/patterns/connectors/google-ads-search/example/ads-setup.js +13 -5
- package/skills/jskit/references/patterns/connectors/oauth-connection/PATTERN.md +1 -1
- package/skills/jskit/references/patterns/connectors/paddle-catalogue/PATTERN.md +11 -2
- package/skills/jskit/references/patterns/connectors/paddle-catalogue/example/create-products.js +5 -2
- package/skills/jskit/references/patterns/connectors/public-image/PATTERN.md +10 -1
- package/skills/jskit/references/patterns/connectors/public-image/example/logo-url.js +4 -1
- package/skills/jskit/references/patterns/connectors/redshift-queries/PATTERN.md +1 -1
- package/skills/jskit/references/patterns/connectors/source-scanning/PATTERN.md +13 -2
- package/skills/jskit/references/patterns/connectors/source-scanning/example/source-scanner.js +9 -0
- package/skills/jskit/references/patterns/crud/json-api-resource-package/PATTERN.md +102 -23
- package/skills/jskit/references/patterns/crud/json-api-resource-package/example/packages/books/package.json +3 -2
- package/skills/jskit/references/patterns/crud/json-api-resource-package/example/packages/books/src/server/types.js +5 -0
- package/skills/jskit/references/patterns/crud/resource-contract/PATTERN.md +54 -1
- package/skills/jskit/references/patterns/database/mysql-application/PATTERN.md +16 -5
- package/skills/jskit/references/patterns/database/mysql-application/example/knexfile.js +2 -2
- package/skills/jskit/references/patterns/database/mysql-application/example/package.json +1 -1
- package/skills/jskit/references/patterns/database/mysql-application/example/scripts/prepare-database.js +1 -1
- package/skills/jskit/references/patterns/database/postgres-application/PATTERN.md +16 -5
- package/skills/jskit/references/patterns/database/postgres-application/example/knexfile.js +2 -2
- package/skills/jskit/references/patterns/database/postgres-application/example/package.json +1 -1
- package/skills/jskit/references/patterns/database/postgres-application/example/scripts/prepare-database.js +1 -1
- package/skills/jskit/references/patterns/realtime/realtime-application/example/package.json +2 -2
- package/skills/jskit/references/patterns/rewards/google-rewarded/example/GoogleRewardedDeliveryProvider.js +1 -1
- package/skills/jskit/references/patterns/rewards/google-rewarded/example/googlePublisherTag.js +5 -11
- package/skills/jskit/references/patterns/server/feature-package/PATTERN.md +104 -10
- package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/package.json +9 -4
- package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/BookingEngineFeature.js +24 -0
- package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/bookingAvailability.js +10 -0
- package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/bookingEngine.js +29 -0
- package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/bookingEngineActions.js +26 -0
- package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/inputSchemas.js +1 -2
- package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/types.js +12 -0
- package/skills/jskit/references/patterns/server/feature-package/example/variations/AvailabilityEngineFeature.js +19 -0
- package/skills/jskit/references/patterns/server/feature-package/example/variations/InvoiceRollupFeature.js +23 -0
- package/skills/jskit/references/patterns/server/feature-package/example/variations/availabilityEngineActions.js +26 -0
- package/skills/jskit/references/patterns/server/feature-package/example/variations/customKnexRepository.js +32 -26
- package/skills/jskit/references/patterns/server/feature-package/example/variations/invoiceRollupActions.js +26 -0
- package/skills/jskit/references/patterns/server/feature-package/example/variations/orchestratorService.js +24 -19
- package/skills/jskit/references/patterns/server/feature-package/example/variations/types.js +7 -0
- package/skills/jskit/references/patterns/users/user-administration-server/PATTERN.md +16 -1
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/package.json +3 -2
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users/src/server/types.js +5 -0
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/package.json +4 -3
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/src/server/UsersWorkspaceFeature.js +2 -9
- package/skills/jskit/references/patterns/users/user-administration-server/example/packages/users-workspace/src/server/types.js +5 -0
- package/skills/jskit/references/patterns/workspaces/workspace-server/PATTERN.md +42 -17
- package/skills/jskit/references/patterns/workspaces/workspace-server/example/packages/main/src/server/WorkspaceInvitationsFeature.js +27 -0
- package/skills/jskit/references/patterns/workspaces/workspace-server/example/packages/main/src/server/email/workspaceInviteEmail.js +11 -10
- package/skills/jskit/references/patterns/workspaces/workspace-server/example/packages/main/src/server/email/workspaceInviteMailer.js +27 -0
- package/skills/jskit/references/translation.md +5 -4
- package/skills/jskit/references/typed-features.md +1099 -0
- package/skills/jskit/references/ui-operations.md +3 -3
- package/patterns/feature-package/example/booking-engine/src/server/BookingEngineProvider.js +0 -33
- package/patterns/feature-package/example/booking-engine/src/server/actions.js +0 -24
- package/patterns/feature-package/example/variations/AvailabilityEngineProvider.js +0 -31
- package/patterns/feature-package/example/variations/InvoiceRollupProvider.js +0 -36
- package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/BookingEngineProvider.js +0 -33
- package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/src/server/actions.js +0 -24
- package/skills/jskit/references/patterns/server/feature-package/example/variations/AvailabilityEngineProvider.js +0 -31
- package/skills/jskit/references/patterns/server/feature-package/example/variations/InvoiceRollupProvider.js +0 -36
|
@@ -42,8 +42,43 @@ questionnaire.
|
|
|
42
42
|
the feature package.
|
|
43
43
|
- `defineFeature()` receives only declared capabilities and returns only
|
|
44
44
|
declared feature APIs.
|
|
45
|
-
-
|
|
46
|
-
|
|
45
|
+
- Each provided capability exports its type. A named `create<Name>` factory in
|
|
46
|
+
its own module builds the value `setup()` returns, and `types.js` declares
|
|
47
|
+
one `@typedef` per provided token, named after the token in PascalCase
|
|
48
|
+
(`feature.booking-engine` -> `BookingEngine`). A package exports it as
|
|
49
|
+
`./server/types`.
|
|
50
|
+
- Every factory, action creator and hook that receives a collaborator names its
|
|
51
|
+
type in a JSDoc `@param`: `import("./types.js").<Name>` or
|
|
52
|
+
`ReturnType<typeof createX>` inside the package, the owner's `./server/types`
|
|
53
|
+
across packages; a Knex client is database-runtime's `RuntimeKnex`.
|
|
54
|
+
- Collaborators are required. There is no `= null`, `= {}` or no-op default,
|
|
55
|
+
no `typeof` probe, no optional call and no "requires x" guard: the capability
|
|
56
|
+
runtime refuses to start without a required token.
|
|
57
|
+
- An extension point is an `optional` token whose default the package names
|
|
58
|
+
in a module of its own and `setup()` resolves once with `??`, never a setter
|
|
59
|
+
that fills a slot later or a module-level registry. The token is typed
|
|
60
|
+
`X | null` only in `setup()`; what `setup()` builds receives it as required.
|
|
61
|
+
- One `create<Name>Actions({ <api> })` per feature, destructured, in
|
|
62
|
+
`<name>Actions.js`, creates its actions and closes over the feature APIs they
|
|
63
|
+
need. Every definition and the list are frozen. Each definition spreads one
|
|
64
|
+
frozen constant of the fields its kind shares (`version`, `kind`,
|
|
65
|
+
`channels`, `surfaces`) first. Each id is a string literal or a module-level
|
|
66
|
+
constant, and `execute: (input, context) => api.method(input, { context })`
|
|
67
|
+
is one call, without `async`, a body, an envelope or a helper that builds or
|
|
68
|
+
strips it. Actions never resolve arbitrary dependencies at execution time.
|
|
69
|
+
- Methods take the validated input as it is: no `input = {}` default, no
|
|
70
|
+
`input?.x` and no second normalization of fields the input schema already
|
|
71
|
+
checked. An options bag whose fields are optional by contract
|
|
72
|
+
(`options = {}` with `trx`) keeps its default.
|
|
73
|
+
- The package reads the actor from an action context one way, with the
|
|
74
|
+
kernel's `resolveActorId(context)` or `resolveActor(context)`
|
|
75
|
+
(`@jskit-ai/kernel/server/actions/actionContributorHelpers`), and its actions
|
|
76
|
+
pass the context one way.
|
|
77
|
+
- Every `create*` returns `Object.freeze({ … })` of named inner functions, and
|
|
78
|
+
exposes another factory's functions by name, never by spreading it.
|
|
79
|
+
- A description sits inside its `/** */` block, never in a `//` line above it.
|
|
80
|
+
- One copy of each pure helper per package, imported directly. Files stay under
|
|
81
|
+
750 lines and functions under 600, one concern per factory.
|
|
47
82
|
- The service orchestrates the feature and does not issue SQL directly.
|
|
48
83
|
- A repository owns persistence and accepts transaction/context options.
|
|
49
84
|
- The normal persistence lane uses a public or documented high-level resource
|
|
@@ -68,20 +103,65 @@ The custom persistence variation uses `createWithTransaction()` from
|
|
|
68
103
|
## Example files
|
|
69
104
|
|
|
70
105
|
`example/booking-engine/` is a concrete app-local package showing the preferred
|
|
71
|
-
small-feature boundary
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
`
|
|
106
|
+
small-feature boundary:
|
|
107
|
+
|
|
108
|
+
- `src/server/BookingEngineFeature.js` declares the feature, its optional
|
|
109
|
+
`feature.booking-engine.availability` slot and the engine it provides;
|
|
110
|
+
- `src/server/bookingEngine.js` builds the engine with `createBookingEngine()`,
|
|
111
|
+
a frozen object of named functions, and reads who asked with the kernel's
|
|
112
|
+
`resolveActorId(context)`;
|
|
113
|
+
- `src/server/bookingAvailability.js` names the slot's default,
|
|
114
|
+
`everyScopeOpen`;
|
|
115
|
+
- `src/server/bookingEngineActions.js` creates its one-line, frozen actions
|
|
116
|
+
with `createBookingEngineActions({ bookingEngine })`, each spreading the
|
|
117
|
+
shared `BOOKING_QUERY` fields first;
|
|
118
|
+
- `src/server/types.js` declares `BookingEngine` and
|
|
119
|
+
`BookingEngineAvailability`, exported as `./server/types`.
|
|
120
|
+
|
|
121
|
+
Its status query is deliberately small: product logic can grow inside the
|
|
122
|
+
returned feature API without creating ceremonial layers. The feature resolves
|
|
123
|
+
the slot once:
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
optional: {
|
|
127
|
+
availability: "feature.booking-engine.availability"
|
|
128
|
+
},
|
|
129
|
+
/** @param {{ availability: import("./types.js").BookingEngineAvailability | null }} capabilities */
|
|
130
|
+
setup({ availability }) {
|
|
131
|
+
return { bookingEngine: createBookingEngine({ availability: availability ?? everyScopeOpen }) };
|
|
132
|
+
},
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Another package fills the slot by providing the token, never by calling a
|
|
136
|
+
setter:
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
const SeasonalAvailabilityFeature = defineFeature({
|
|
140
|
+
id: "feature.seasonal-availability",
|
|
141
|
+
provides: { availability: "feature.booking-engine.availability" },
|
|
142
|
+
setup: () => ({ availability: isInSeason })
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`example/variations/AvailabilityEngineFeature.js`,
|
|
147
|
+
`example/variations/availabilityEngineActions.js` and
|
|
75
148
|
`example/variations/orchestratorService.js` show the repository-free lane.
|
|
76
|
-
`example/variations/
|
|
149
|
+
`example/variations/InvoiceRollupFeature.js`,
|
|
150
|
+
`example/variations/invoiceRollupActions.js` and
|
|
77
151
|
`example/variations/customKnexRepository.js` show the explicit custom
|
|
78
|
-
persistence lane.
|
|
152
|
+
persistence lane. `example/variations/types.js` declares the
|
|
153
|
+
`AvailabilityEngine` and `InvoiceRollup` types.
|
|
154
|
+
|
|
155
|
+
The [typed features guide](https://mobily-enterprises.github.io/jskit-ai/guide/framework/typed-features)
|
|
156
|
+
explains each rule this example follows, with a good and a bad example, and
|
|
157
|
+
`npm run lint` checks the ones a machine can see.
|
|
79
158
|
|
|
80
159
|
## Variation points
|
|
81
160
|
|
|
82
161
|
Rename the package, capability id, actions, validators, and domain methods.
|
|
83
|
-
Select the
|
|
84
|
-
|
|
162
|
+
Select the channels and surfaces in the shared-field constant each definition
|
|
163
|
+
spreads first; a kind of action whose values differ gets a constant of its
|
|
164
|
+
own. Add a service when orchestration is shared or
|
|
85
165
|
stateful. Add a repository only when the feature owns persistence. Replace the
|
|
86
166
|
illustrative status query with narrow product language before shipping.
|
|
87
167
|
|
|
@@ -104,5 +184,19 @@ illustrative status query with narrow product language before shipping.
|
|
|
104
184
|
- a repository for an orchestration-only feature
|
|
105
185
|
- generic `execute(anything)` operations in finished product code
|
|
106
186
|
- `app.make()`, `scope.make()`, container tokens, or service-location helpers
|
|
187
|
+
- probing a collaborator (`typeof x.method === "function"`, `x?.method?.()`)
|
|
188
|
+
before calling it
|
|
189
|
+
- absent defaults on a collaborator or on the dependencies object (`= null`,
|
|
190
|
+
`= {}`, a no-op)
|
|
191
|
+
- setters that fill a slot after construction, and module-level registries
|
|
192
|
+
- a collaborator accepted in two shapes (`capability.service || capability`)
|
|
193
|
+
- an `async` `execute`, an `execute` with a body, or a helper that builds an
|
|
194
|
+
action or strips its input
|
|
195
|
+
- a hand-written `(...args: any[]) => Promise<any>` type instead of the
|
|
196
|
+
owner's type, and the same `ReturnType<…>` or indexed type spelled out in
|
|
197
|
+
several files
|
|
198
|
+
- spreading an in-package factory's result into a provided value
|
|
199
|
+
- unfrozen `create*` results and inline methods
|
|
200
|
+
- a guard, default or comment that exists for a test double
|
|
107
201
|
- metadata claiming which authoring tool or pattern created the package
|
|
108
202
|
- field questionnaires, overwrite switches, or durable operation records
|
package/skills/jskit/references/patterns/server/feature-package/example/booking-engine/package.json
CHANGED
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
"private": true,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@jskit-ai/kernel": "0.2.
|
|
8
|
+
"@jskit-ai/kernel": "0.2.4",
|
|
9
9
|
"json-rest-schema": "^1.0.17"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
|
-
"./server/actions": "./src/server/
|
|
12
|
+
"./server/actions": "./src/server/bookingEngineActions.js",
|
|
13
|
+
"./server/types": "./src/server/types.js"
|
|
13
14
|
},
|
|
14
15
|
"jskit": {
|
|
15
16
|
"kind": "runtime",
|
|
@@ -25,8 +26,8 @@
|
|
|
25
26
|
"server": {
|
|
26
27
|
"providers": [
|
|
27
28
|
{
|
|
28
|
-
"entrypoint": "src/server/
|
|
29
|
-
"export": "
|
|
29
|
+
"entrypoint": "src/server/BookingEngineFeature.js",
|
|
30
|
+
"export": "BookingEngineFeature"
|
|
30
31
|
}
|
|
31
32
|
]
|
|
32
33
|
},
|
|
@@ -40,6 +41,10 @@
|
|
|
40
41
|
{
|
|
41
42
|
"subpath": "./server/actions",
|
|
42
43
|
"summary": "Exports booking-engine action definitions."
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"subpath": "./server/types",
|
|
47
|
+
"summary": "Types of the feature.booking-engine capability and its optional feature.booking-engine.availability slot."
|
|
43
48
|
}
|
|
44
49
|
]
|
|
45
50
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { defineFeature } from "@jskit-ai/kernel/server/features";
|
|
2
|
+
import { everyScopeOpen } from "./bookingAvailability.js";
|
|
3
|
+
import { createBookingEngine } from "./bookingEngine.js";
|
|
4
|
+
import { createBookingEngineActions } from "./bookingEngineActions.js";
|
|
5
|
+
|
|
6
|
+
const BookingEngineFeature = defineFeature({
|
|
7
|
+
id: "feature.booking-engine",
|
|
8
|
+
domain: "booking",
|
|
9
|
+
optional: {
|
|
10
|
+
availability: "feature.booking-engine.availability"
|
|
11
|
+
},
|
|
12
|
+
provides: {
|
|
13
|
+
bookingEngine: "feature.booking-engine"
|
|
14
|
+
},
|
|
15
|
+
/** @param {{ availability: import("./types.js").BookingEngineAvailability | null }} capabilities */
|
|
16
|
+
setup({ availability }) {
|
|
17
|
+
return { bookingEngine: createBookingEngine({ availability: availability ?? everyScopeOpen }) };
|
|
18
|
+
},
|
|
19
|
+
actions({ bookingEngine }) {
|
|
20
|
+
return createBookingEngineActions({ bookingEngine });
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export { BookingEngineFeature };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `feature.booking-engine.availability` default when no package provides
|
|
3
|
+
* one: every scope takes bookings.
|
|
4
|
+
* @type {import("./types.js").BookingEngineAvailability}
|
|
5
|
+
*/
|
|
6
|
+
async function everyScopeOpen() {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { everyScopeOpen };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { resolveActorId } from "@jskit-ai/kernel/server/actions/actionContributorHelpers";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The booking engine the feature provides as `feature.booking-engine`.
|
|
5
|
+
* @param {object} dependencies
|
|
6
|
+
* @param {import("./types.js").BookingEngineAvailability} dependencies.availability
|
|
7
|
+
*/
|
|
8
|
+
function createBookingEngine({ availability }) {
|
|
9
|
+
/**
|
|
10
|
+
* Reports, for the validated query, whether its scope takes bookings and who
|
|
11
|
+
* asked.
|
|
12
|
+
* @param {{ scope?: string, verbose?: boolean }} query
|
|
13
|
+
* @param {{ context: object }} options
|
|
14
|
+
*/
|
|
15
|
+
async function readStatus({ scope = "default", verbose = false }, { context }) {
|
|
16
|
+
return {
|
|
17
|
+
ok: true,
|
|
18
|
+
feature: "booking-engine",
|
|
19
|
+
scope,
|
|
20
|
+
verbose,
|
|
21
|
+
open: await availability(scope),
|
|
22
|
+
requestedBy: resolveActorId(context)
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return Object.freeze({ readStatus });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { createBookingEngine };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { statusQueryInputValidator } from "./inputSchemas.js";
|
|
2
|
+
|
|
3
|
+
const ACTION_GET_STATUS = "feature.booking-engine.status.read";
|
|
4
|
+
|
|
5
|
+
/** The fields every booking query shares, spread first into each definition. */
|
|
6
|
+
const BOOKING_QUERY = Object.freeze({
|
|
7
|
+
version: 1,
|
|
8
|
+
kind: "query",
|
|
9
|
+
channels: ["api", "assistant", "internal"],
|
|
10
|
+
surfaces: ["app"]
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
/** @param {{ bookingEngine: import("./types.js").BookingEngine }} dependencies */
|
|
14
|
+
function createBookingEngineActions({ bookingEngine }) {
|
|
15
|
+
return Object.freeze([
|
|
16
|
+
Object.freeze({
|
|
17
|
+
...BOOKING_QUERY,
|
|
18
|
+
id: ACTION_GET_STATUS,
|
|
19
|
+
input: statusQueryInputValidator,
|
|
20
|
+
output: null,
|
|
21
|
+
execute: (input, context) => bookingEngine.readStatus(input, { context })
|
|
22
|
+
})
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { ACTION_GET_STATUS, createBookingEngineActions };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// The types of the `feature.booking-engine` capability and of its optional
|
|
2
|
+
// `feature.booking-engine.availability` slot.
|
|
3
|
+
|
|
4
|
+
/** @typedef {ReturnType<typeof import("./bookingEngine.js").createBookingEngine>} BookingEngine */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The `feature.booking-engine.availability` slot: answers whether a scope takes
|
|
8
|
+
* bookings. A package supplies it by providing that token.
|
|
9
|
+
* @typedef {(scope: string) => Promise<boolean>} BookingEngineAvailability
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineFeature } from "@jskit-ai/kernel/server/features";
|
|
2
|
+
import { createAvailabilityEngineActions } from "./availabilityEngineActions.js";
|
|
3
|
+
import { createAvailabilityEngine } from "./orchestratorService.js";
|
|
4
|
+
|
|
5
|
+
const AvailabilityEngineFeature = defineFeature({
|
|
6
|
+
id: "feature.availability-engine",
|
|
7
|
+
domain: "availability",
|
|
8
|
+
provides: {
|
|
9
|
+
availabilityEngine: "feature.availability-engine"
|
|
10
|
+
},
|
|
11
|
+
setup() {
|
|
12
|
+
return { availabilityEngine: createAvailabilityEngine() };
|
|
13
|
+
},
|
|
14
|
+
actions({ availabilityEngine }) {
|
|
15
|
+
return createAvailabilityEngineActions({ availabilityEngine });
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export { AvailabilityEngineFeature };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defineFeature } from "@jskit-ai/kernel/server/features";
|
|
2
|
+
import { createInvoiceRollup } from "./customKnexRepository.js";
|
|
3
|
+
import { createInvoiceRollupActions } from "./invoiceRollupActions.js";
|
|
4
|
+
|
|
5
|
+
const InvoiceRollupFeature = defineFeature({
|
|
6
|
+
id: "feature.invoice-rollup",
|
|
7
|
+
domain: "invoices",
|
|
8
|
+
requires: {
|
|
9
|
+
database: "runtime.database"
|
|
10
|
+
},
|
|
11
|
+
provides: {
|
|
12
|
+
invoiceRollup: "feature.invoice-rollup"
|
|
13
|
+
},
|
|
14
|
+
/** @param {{ database: import("@jskit-ai/database-runtime/server/types").RuntimeDatabase }} capabilities */
|
|
15
|
+
setup({ database }) {
|
|
16
|
+
return { invoiceRollup: createInvoiceRollup({ knex: database.knex }) };
|
|
17
|
+
},
|
|
18
|
+
actions({ invoiceRollup }) {
|
|
19
|
+
return createInvoiceRollupActions({ invoiceRollup });
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export { InvoiceRollupFeature };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { emptyInputValidator } from "@jskit-ai/kernel/server/actions/actionContributorHelpers";
|
|
2
|
+
|
|
3
|
+
const ACTION_GET_AVAILABILITY_STATUS = "availability.status.read";
|
|
4
|
+
|
|
5
|
+
/** The fields every availability query shares, spread first into each definition. */
|
|
6
|
+
const AVAILABILITY_QUERY = Object.freeze({
|
|
7
|
+
version: 1,
|
|
8
|
+
kind: "query",
|
|
9
|
+
channels: ["api", "assistant", "internal"],
|
|
10
|
+
surfaces: ["app"]
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
/** @param {{ availabilityEngine: import("./types.js").AvailabilityEngine }} dependencies */
|
|
14
|
+
function createAvailabilityEngineActions({ availabilityEngine }) {
|
|
15
|
+
return Object.freeze([
|
|
16
|
+
Object.freeze({
|
|
17
|
+
...AVAILABILITY_QUERY,
|
|
18
|
+
id: ACTION_GET_AVAILABILITY_STATUS,
|
|
19
|
+
input: emptyInputValidator,
|
|
20
|
+
output: null,
|
|
21
|
+
execute: (input) => availabilityEngine.getStatus(input)
|
|
22
|
+
})
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { ACTION_GET_AVAILABILITY_STATUS, createAvailabilityEngineActions };
|
|
@@ -1,34 +1,40 @@
|
|
|
1
1
|
import { createWithTransaction } from "@jskit-ai/database-runtime/shared";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The invoice rollup's persistence: a reviewed custom Knex repository.
|
|
5
|
+
* @param {{ knex: import("@jskit-ai/database-runtime/server/types").RuntimeKnex }} dependencies
|
|
6
|
+
*/
|
|
7
|
+
function createInvoiceRollup({ knex }) {
|
|
8
|
+
const withTransaction = createWithTransaction(knex);
|
|
9
|
+
|
|
10
|
+
async function getStatus(input, options = {}) {
|
|
11
|
+
return {
|
|
12
|
+
ok: true,
|
|
13
|
+
feature: "invoice-rollup",
|
|
14
|
+
persistence: "custom-knex",
|
|
15
|
+
tableName: "invoice_rollups",
|
|
16
|
+
hasTransaction: Boolean(options.trx),
|
|
17
|
+
input
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function execute(input, options = {}) {
|
|
22
|
+
return {
|
|
23
|
+
accepted: false,
|
|
24
|
+
feature: "invoice-rollup",
|
|
25
|
+
persistence: "custom-knex",
|
|
26
|
+
tableName: "invoice_rollups",
|
|
27
|
+
hasTransaction: Boolean(options.trx),
|
|
28
|
+
input,
|
|
29
|
+
message: "Replace this example with the reviewed domain-specific query."
|
|
30
|
+
};
|
|
6
31
|
}
|
|
7
32
|
|
|
8
33
|
return Object.freeze({
|
|
9
|
-
withTransaction
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
ok: true,
|
|
13
|
-
feature: "invoice-rollup",
|
|
14
|
-
persistence: "custom-knex",
|
|
15
|
-
tableName: "invoice_rollups",
|
|
16
|
-
hasTransaction: Boolean(options.trx),
|
|
17
|
-
input
|
|
18
|
-
};
|
|
19
|
-
},
|
|
20
|
-
async execute(input = {}, options = {}) {
|
|
21
|
-
return {
|
|
22
|
-
accepted: false,
|
|
23
|
-
feature: "invoice-rollup",
|
|
24
|
-
persistence: "custom-knex",
|
|
25
|
-
tableName: "invoice_rollups",
|
|
26
|
-
hasTransaction: Boolean(options.trx),
|
|
27
|
-
input,
|
|
28
|
-
message: "Replace this example with the reviewed domain-specific query."
|
|
29
|
-
};
|
|
30
|
-
}
|
|
34
|
+
withTransaction,
|
|
35
|
+
getStatus,
|
|
36
|
+
execute
|
|
31
37
|
});
|
|
32
38
|
}
|
|
33
39
|
|
|
34
|
-
export {
|
|
40
|
+
export { createInvoiceRollup };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { emptyInputValidator } from "@jskit-ai/kernel/server/actions/actionContributorHelpers";
|
|
2
|
+
|
|
3
|
+
const ACTION_GET_ROLLUP_STATUS = "invoices.rollup.status.read";
|
|
4
|
+
|
|
5
|
+
/** The fields every invoice rollup query shares, spread first into each definition: they run on the admin surface. */
|
|
6
|
+
const ROLLUP_QUERY = Object.freeze({
|
|
7
|
+
version: 1,
|
|
8
|
+
kind: "query",
|
|
9
|
+
channels: ["api", "assistant", "internal"],
|
|
10
|
+
surfaces: ["admin"]
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
/** @param {{ invoiceRollup: import("./types.js").InvoiceRollup }} dependencies */
|
|
14
|
+
function createInvoiceRollupActions({ invoiceRollup }) {
|
|
15
|
+
return Object.freeze([
|
|
16
|
+
Object.freeze({
|
|
17
|
+
...ROLLUP_QUERY,
|
|
18
|
+
id: ACTION_GET_ROLLUP_STATUS,
|
|
19
|
+
input: emptyInputValidator,
|
|
20
|
+
output: null,
|
|
21
|
+
execute: (input, context) => invoiceRollup.getStatus(input, { context })
|
|
22
|
+
})
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { ACTION_GET_ROLLUP_STATUS, createInvoiceRollupActions };
|
|
@@ -1,23 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
/** The availability engine: orchestration with no persistence of its own. */
|
|
2
|
+
function createAvailabilityEngine() {
|
|
3
|
+
async function getStatus(input) {
|
|
4
|
+
return {
|
|
5
|
+
ok: true,
|
|
6
|
+
feature: "availability-engine",
|
|
7
|
+
mode: "orchestrator",
|
|
8
|
+
input
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async function execute(input) {
|
|
13
|
+
return {
|
|
14
|
+
accepted: false,
|
|
15
|
+
feature: "availability-engine",
|
|
16
|
+
mode: "orchestrator",
|
|
17
|
+
input,
|
|
18
|
+
message: "Replace this example with calls to the feature's injected collaborators."
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
2
22
|
return Object.freeze({
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
ok: true,
|
|
6
|
-
feature: "availability-engine",
|
|
7
|
-
mode: "orchestrator",
|
|
8
|
-
input
|
|
9
|
-
};
|
|
10
|
-
},
|
|
11
|
-
async execute(input = {}) {
|
|
12
|
-
return {
|
|
13
|
-
accepted: false,
|
|
14
|
-
feature: "availability-engine",
|
|
15
|
-
mode: "orchestrator",
|
|
16
|
-
input,
|
|
17
|
-
message: "Replace this example with calls to the feature's injected collaborators."
|
|
18
|
-
};
|
|
19
|
-
}
|
|
23
|
+
getStatus,
|
|
24
|
+
execute
|
|
20
25
|
});
|
|
21
26
|
}
|
|
22
27
|
|
|
23
|
-
export {
|
|
28
|
+
export { createAvailabilityEngine };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// The types of the `feature.availability-engine` and `feature.invoice-rollup`
|
|
2
|
+
// capabilities, for features that require them.
|
|
3
|
+
|
|
4
|
+
/** @typedef {ReturnType<typeof import("./orchestratorService.js").createAvailabilityEngine>} AvailabilityEngine */
|
|
5
|
+
/** @typedef {ReturnType<typeof import("./customKnexRepository.js").createInvoiceRollup>} InvoiceRollup */
|
|
6
|
+
|
|
7
|
+
export {};
|
|
@@ -38,12 +38,25 @@ and the resource contracts from `@jskit-ai/resource-crud-core`.
|
|
|
38
38
|
- Shared profile persistence remains owned by `@jskit-ai/users-core`.
|
|
39
39
|
- The resource is the field contract; the feature projects its repository,
|
|
40
40
|
service, actions, and routes without app-local ceremony.
|
|
41
|
+
- Each package exports the type of the capability it provides:
|
|
42
|
+
`src/server/types.js` declares `AppUsers` (for `app.users`) or
|
|
43
|
+
`AppUsersWorkspace` (for `app.users-workspace`) as crud-core's
|
|
44
|
+
`CrudResourceApi`, exported as `./server/types`. A feature that requires the
|
|
45
|
+
capability names that type in a JSDoc `@param`.
|
|
46
|
+
- Code added to a declaration follows [typed features](https://github.com/mobily-enterprises/jskit-ai/blob/main/packages/agent-docs/site/guide/framework/typed-features.md):
|
|
47
|
+
decorators, lifecycle hooks and named actions call the collaborators they
|
|
48
|
+
receive directly, with no `typeof` probe, optional call, absent default,
|
|
49
|
+
slot setter or module-level registry, and each action's `execute` is one
|
|
50
|
+
call to one service method with the validated input. Keep one copy of each
|
|
51
|
+
helper per package, files under 750 lines and functions under 600.
|
|
41
52
|
|
|
42
53
|
## Example files
|
|
43
54
|
|
|
44
55
|
`example/packages/users/` is a global administration package.
|
|
45
56
|
`example/packages/users-workspace/` demonstrates the workspace route/action
|
|
46
|
-
boundary while reusing the same
|
|
57
|
+
boundary, with workspaces-core's `WORKSPACE_CRUD_SCOPE`, while reusing the same
|
|
58
|
+
service contract. Each package's
|
|
59
|
+
`src/server/types.js` declares the type of the capability it provides. Copy only the composition
|
|
47
60
|
that matches the product and adapt it as ordinary application source.
|
|
48
61
|
|
|
49
62
|
## Variation points
|
|
@@ -62,3 +75,5 @@ isolation, missing records, null/cleared fields, filtering, and pagination.
|
|
|
62
75
|
- trusting route scope without repository scope
|
|
63
76
|
- adding app-local mechanics already provided by `defineCrudJsonApiFeature()`
|
|
64
77
|
- generator metadata or field questionnaires
|
|
78
|
+
- probing a collaborator, defaulting one to `null`, `{}` or a no-op, setters
|
|
79
|
+
that fill a slot after construction, and module-level registries
|
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
8
8
|
"./server/UsersFeature": "./src/server/UsersFeature.js",
|
|
9
|
+
"./server/types": "./src/server/types.js",
|
|
9
10
|
"./shared": "./src/shared/index.js"
|
|
10
11
|
},
|
|
11
12
|
"dependencies": {
|
|
12
|
-
"@jskit-ai/crud-core": "0.2.
|
|
13
|
-
"@jskit-ai/resource-crud-core": "0.1.
|
|
13
|
+
"@jskit-ai/crud-core": "0.2.4",
|
|
14
|
+
"@jskit-ai/resource-crud-core": "0.1.195"
|
|
14
15
|
},
|
|
15
16
|
"jskit": {
|
|
16
17
|
"kind": "runtime",
|
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|
|
8
8
|
"./server/UsersWorkspaceFeature": "./src/server/UsersWorkspaceFeature.js",
|
|
9
|
+
"./server/types": "./src/server/types.js",
|
|
9
10
|
"./shared": "./src/shared/index.js"
|
|
10
11
|
},
|
|
11
12
|
"dependencies": {
|
|
12
|
-
"@jskit-ai/crud-core": "0.2.
|
|
13
|
-
"@jskit-ai/resource-crud-core": "0.1.
|
|
14
|
-
"@jskit-ai/workspaces-core": "0.2.
|
|
13
|
+
"@jskit-ai/crud-core": "0.2.4",
|
|
14
|
+
"@jskit-ai/resource-crud-core": "0.1.195",
|
|
15
|
+
"@jskit-ai/workspaces-core": "0.2.5"
|
|
15
16
|
},
|
|
16
17
|
"jskit": {
|
|
17
18
|
"kind": "runtime",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { defineCrudJsonApiFeature } from "@jskit-ai/crud-core/server/defineCrudJsonApiFeature";
|
|
2
|
-
import {
|
|
3
|
-
import { workspaceSlugParamsValidator } from "@jskit-ai/workspaces-core/server/validators/routeParamsValidator";
|
|
2
|
+
import { WORKSPACE_CRUD_SCOPE } from "@jskit-ai/workspaces-core/server/support/workspaceCrud";
|
|
4
3
|
import { resource } from "../shared/userResource.js";
|
|
5
4
|
|
|
6
5
|
const UsersWorkspaceFeature = defineCrudJsonApiFeature({
|
|
@@ -10,13 +9,7 @@ const UsersWorkspaceFeature = defineCrudJsonApiFeature({
|
|
|
10
9
|
surface: "admin",
|
|
11
10
|
ownershipFilter: "workspace",
|
|
12
11
|
relativePath: "/users",
|
|
13
|
-
scope:
|
|
14
|
-
routeBase: "/w/:workspaceSlug",
|
|
15
|
-
actionInputValidator: workspaceSlugParamsValidator,
|
|
16
|
-
routeParamsValidator: workspaceSlugParamsValidator,
|
|
17
|
-
inputKeys: ["workspaceSlug"],
|
|
18
|
-
input: (request) => buildWorkspaceInputFromRouteParams(request.input.params)
|
|
19
|
-
}
|
|
12
|
+
scope: WORKSPACE_CRUD_SCOPE
|
|
20
13
|
});
|
|
21
14
|
|
|
22
15
|
export { UsersWorkspaceFeature };
|