@weave-kit/engine 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +79 -0
- package/README.md +7 -0
- package/dist/adapters/graphql/http.d.ts +24 -0
- package/dist/adapters/graphql/http.d.ts.map +1 -0
- package/dist/adapters/graphql/http.js +147 -0
- package/dist/adapters/graphql/http.js.map +1 -0
- package/dist/adapters/graphql/index.d.ts +33 -0
- package/dist/adapters/graphql/index.d.ts.map +1 -0
- package/dist/adapters/graphql/index.js +24 -0
- package/dist/adapters/graphql/index.js.map +1 -0
- package/dist/adapters/graphql/loader.d.ts +4 -0
- package/dist/adapters/graphql/loader.d.ts.map +1 -0
- package/dist/adapters/graphql/loader.js +135 -0
- package/dist/adapters/graphql/loader.js.map +1 -0
- package/dist/adapters/graphql/resolvers.d.ts +52 -0
- package/dist/adapters/graphql/resolvers.d.ts.map +1 -0
- package/dist/adapters/graphql/resolvers.js +110 -0
- package/dist/adapters/graphql/resolvers.js.map +1 -0
- package/dist/adapters/graphql/scalars.d.ts +8 -0
- package/dist/adapters/graphql/scalars.d.ts.map +1 -0
- package/dist/adapters/graphql/scalars.js +14 -0
- package/dist/adapters/graphql/scalars.js.map +1 -0
- package/dist/adapters/graphql/schema.d.ts +9 -0
- package/dist/adapters/graphql/schema.d.ts.map +1 -0
- package/dist/adapters/graphql/schema.js +297 -0
- package/dist/adapters/graphql/schema.js.map +1 -0
- package/dist/adapters/graphql/security.d.ts +29 -0
- package/dist/adapters/graphql/security.d.ts.map +1 -0
- package/dist/adapters/graphql/security.js +81 -0
- package/dist/adapters/graphql/security.js.map +1 -0
- package/dist/adapters/graphql/types.d.ts +69 -0
- package/dist/adapters/graphql/types.d.ts.map +1 -0
- package/dist/adapters/graphql/types.js +2 -0
- package/dist/adapters/graphql/types.js.map +1 -0
- package/dist/adapters/mcp/generate.d.ts.map +1 -1
- package/dist/adapters/mcp/generate.js +4 -3
- package/dist/adapters/mcp/generate.js.map +1 -1
- package/dist/adapters/mcp/guardrails.d.ts +1 -1
- package/dist/adapters/mcp/http.d.ts +2 -0
- package/dist/adapters/mcp/http.d.ts.map +1 -1
- package/dist/adapters/mcp/http.js +34 -16
- package/dist/adapters/mcp/http.js.map +1 -1
- package/dist/adapters/mcp/index.d.ts +2 -0
- package/dist/adapters/mcp/index.d.ts.map +1 -1
- package/dist/adapters/mcp/index.js +2 -1
- package/dist/adapters/mcp/index.js.map +1 -1
- package/dist/adapters/mcp/session.d.ts +11 -3
- package/dist/adapters/mcp/session.d.ts.map +1 -1
- package/dist/adapters/mcp/session.js +12 -0
- package/dist/adapters/mcp/session.js.map +1 -1
- package/dist/adapters/mcp/tools.d.ts.map +1 -1
- package/dist/adapters/mcp/tools.js +16 -7
- package/dist/adapters/mcp/tools.js.map +1 -1
- package/dist/adapters/openapi/document.d.ts.map +1 -1
- package/dist/adapters/openapi/document.js +9 -2
- package/dist/adapters/openapi/document.js.map +1 -1
- package/dist/adapters/openapi/schema.d.ts +8 -6
- package/dist/adapters/openapi/schema.d.ts.map +1 -1
- package/dist/adapters/openapi/schema.js +41 -9
- package/dist/adapters/openapi/schema.js.map +1 -1
- package/dist/adapters/openapi/types.d.ts +2 -0
- package/dist/adapters/openapi/types.d.ts.map +1 -1
- package/dist/adapters/rest/plugin.d.ts.map +1 -1
- package/dist/adapters/rest/plugin.js +11 -8
- package/dist/adapters/rest/plugin.js.map +1 -1
- package/dist/adapters/rest/workflow.js +8 -8
- package/dist/adapters/rest/workflow.js.map +1 -1
- package/dist/cli/commands/deploy.d.ts +6 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -0
- package/dist/cli/commands/deploy.js +88 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/enums.d.ts +14 -0
- package/dist/cli/commands/enums.d.ts.map +1 -0
- package/dist/cli/commands/enums.js +83 -0
- package/dist/cli/commands/enums.js.map +1 -0
- package/dist/cli/commands/field-add.d.ts.map +1 -1
- package/dist/cli/commands/field-add.js +12 -4
- package/dist/cli/commands/field-add.js.map +1 -1
- package/dist/cli/commands/graphql-schema.d.ts +9 -0
- package/dist/cli/commands/graphql-schema.d.ts.map +1 -0
- package/dist/cli/commands/graphql-schema.js +35 -0
- package/dist/cli/commands/graphql-schema.js.map +1 -0
- package/dist/cli/commands/openapi.d.ts.map +1 -1
- package/dist/cli/commands/openapi.js +4 -1
- package/dist/cli/commands/openapi.js.map +1 -1
- package/dist/cli/index.js +36 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/types/commands.d.ts +24 -0
- package/dist/cli/types/commands.d.ts.map +1 -1
- package/dist/cli/types/index.d.ts +1 -1
- package/dist/cli/types/index.d.ts.map +1 -1
- package/dist/cli/types/values.d.ts +5 -0
- package/dist/cli/types/values.d.ts.map +1 -1
- package/dist/cli/types/values.js +5 -0
- package/dist/cli/types/values.js.map +1 -1
- package/dist/core/api/error.d.ts +3 -2
- package/dist/core/api/error.d.ts.map +1 -1
- package/dist/core/api/error.js +20 -16
- package/dist/core/api/error.js.map +1 -1
- package/dist/core/audit/index.d.ts +2 -2
- package/dist/core/audit/index.d.ts.map +1 -1
- package/dist/core/audit/index.js +1 -1
- package/dist/core/audit/index.js.map +1 -1
- package/dist/core/audit/types.d.ts +25 -2
- package/dist/core/audit/types.d.ts.map +1 -1
- package/dist/core/audit/types.js +11 -0
- package/dist/core/audit/types.js.map +1 -1
- package/dist/core/i18n/ar.d.ts.map +1 -1
- package/dist/core/i18n/ar.js +8 -0
- package/dist/core/i18n/ar.js.map +1 -1
- package/dist/core/i18n/de.d.ts.map +1 -1
- package/dist/core/i18n/de.js +8 -0
- package/dist/core/i18n/de.js.map +1 -1
- package/dist/core/i18n/en.d.ts +8 -0
- package/dist/core/i18n/en.d.ts.map +1 -1
- package/dist/core/i18n/en.js +8 -0
- package/dist/core/i18n/en.js.map +1 -1
- package/dist/core/i18n/es.d.ts.map +1 -1
- package/dist/core/i18n/es.js +8 -0
- package/dist/core/i18n/es.js.map +1 -1
- package/dist/core/i18n/fr.d.ts.map +1 -1
- package/dist/core/i18n/fr.js +8 -0
- package/dist/core/i18n/fr.js.map +1 -1
- package/dist/core/i18n/hi.d.ts.map +1 -1
- package/dist/core/i18n/hi.js +8 -0
- package/dist/core/i18n/hi.js.map +1 -1
- package/dist/core/i18n/id.d.ts.map +1 -1
- package/dist/core/i18n/id.js +8 -0
- package/dist/core/i18n/id.js.map +1 -1
- package/dist/core/i18n/ja.d.ts.map +1 -1
- package/dist/core/i18n/ja.js +8 -0
- package/dist/core/i18n/ja.js.map +1 -1
- package/dist/core/i18n/ko.d.ts.map +1 -1
- package/dist/core/i18n/ko.js +8 -0
- package/dist/core/i18n/ko.js.map +1 -1
- package/dist/core/i18n/pt.d.ts.map +1 -1
- package/dist/core/i18n/pt.js +8 -0
- package/dist/core/i18n/pt.js.map +1 -1
- package/dist/core/i18n/ru.d.ts.map +1 -1
- package/dist/core/i18n/ru.js +8 -0
- package/dist/core/i18n/ru.js.map +1 -1
- package/dist/core/i18n/vi.d.ts.map +1 -1
- package/dist/core/i18n/vi.js +8 -0
- package/dist/core/i18n/vi.js.map +1 -1
- package/dist/core/i18n/zh-hant.d.ts.map +1 -1
- package/dist/core/i18n/zh-hant.js +8 -0
- package/dist/core/i18n/zh-hant.js.map +1 -1
- package/dist/core/i18n/zh.d.ts.map +1 -1
- package/dist/core/i18n/zh.js +8 -0
- package/dist/core/i18n/zh.js.map +1 -1
- package/dist/core/object/describe.d.ts +11 -0
- package/dist/core/object/describe.d.ts.map +1 -1
- package/dist/core/object/describe.js +8 -0
- package/dist/core/object/describe.js.map +1 -1
- package/dist/core/object/enums.d.ts +5 -0
- package/dist/core/object/enums.d.ts.map +1 -0
- package/dist/core/object/enums.js +67 -0
- package/dist/core/object/enums.js.map +1 -0
- package/dist/core/object/gen-types.d.ts +2 -2
- package/dist/core/object/gen-types.d.ts.map +1 -1
- package/dist/core/object/gen-types.js +39 -2
- package/dist/core/object/gen-types.js.map +1 -1
- package/dist/core/object/index.d.ts +1 -0
- package/dist/core/object/index.d.ts.map +1 -1
- package/dist/core/object/index.js +1 -0
- package/dist/core/object/index.js.map +1 -1
- package/dist/core/object/migrations.d.ts.map +1 -1
- package/dist/core/object/migrations.js +11 -0
- package/dist/core/object/migrations.js.map +1 -1
- package/dist/core/object/registry.d.ts +4 -1
- package/dist/core/object/registry.d.ts.map +1 -1
- package/dist/core/object/registry.js +5 -2
- package/dist/core/object/registry.js.map +1 -1
- package/dist/core/object/schema-version.d.ts +1 -1
- package/dist/core/object/schema-version.js +1 -1
- package/dist/core/object/validate/field.d.ts +3 -1
- package/dist/core/object/validate/field.d.ts.map +1 -1
- package/dist/core/object/validate/field.js +63 -29
- package/dist/core/object/validate/field.js.map +1 -1
- package/dist/core/object/validate/object.d.ts +6 -1
- package/dist/core/object/validate/object.d.ts.map +1 -1
- package/dist/core/object/validate/object.js +5 -1
- package/dist/core/object/validate/object.js.map +1 -1
- package/dist/core/storage/apply.d.ts +3 -1
- package/dist/core/storage/apply.d.ts.map +1 -1
- package/dist/core/storage/apply.js +6 -2
- package/dist/core/storage/apply.js.map +1 -1
- package/dist/core/storage/index.d.ts +1 -0
- package/dist/core/storage/index.d.ts.map +1 -1
- package/dist/core/storage/index.js.map +1 -1
- package/dist/core/storage/meta.d.ts +4 -3
- package/dist/core/storage/meta.d.ts.map +1 -1
- package/dist/core/storage/meta.js +5 -4
- package/dist/core/storage/meta.js.map +1 -1
- package/dist/core/storage/migrate.d.ts +8 -0
- package/dist/core/storage/migrate.d.ts.map +1 -1
- package/dist/core/storage/migrate.js +33 -12
- package/dist/core/storage/migrate.js.map +1 -1
- package/dist/core/storage/queryable.d.ts +14 -0
- package/dist/core/storage/queryable.d.ts.map +1 -0
- package/dist/core/storage/queryable.js +2 -0
- package/dist/core/storage/queryable.js.map +1 -0
- package/dist/core/storage/system-tables.d.ts +2 -0
- package/dist/core/storage/system-tables.d.ts.map +1 -1
- package/dist/core/storage/system-tables.js +39 -0
- package/dist/core/storage/system-tables.js.map +1 -1
- package/dist/core/tools/types.d.ts +1 -1
- package/dist/core/tools/types.d.ts.map +1 -1
- package/dist/core/types/enum-registry.d.ts +33 -0
- package/dist/core/types/enum-registry.d.ts.map +1 -0
- package/dist/core/types/enum-registry.js +21 -0
- package/dist/core/types/enum-registry.js.map +1 -0
- package/dist/core/types/index.d.ts +3 -0
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/index.js +2 -0
- package/dist/core/types/index.js.map +1 -1
- package/dist/core/types/principal.d.ts +34 -0
- package/dist/core/types/principal.d.ts.map +1 -0
- package/dist/core/types/principal.js +32 -0
- package/dist/core/types/principal.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/runtime/data-access/cursor.d.ts +9 -0
- package/dist/runtime/data-access/cursor.d.ts.map +1 -0
- package/dist/runtime/data-access/cursor.js +26 -0
- package/dist/runtime/data-access/cursor.js.map +1 -0
- package/dist/runtime/data-access/index.d.ts +2 -0
- package/dist/runtime/data-access/index.d.ts.map +1 -1
- package/dist/runtime/data-access/index.js +2 -0
- package/dist/runtime/data-access/index.js.map +1 -1
- package/dist/runtime/data-access/query.d.ts +1 -1
- package/dist/runtime/data-access/query.d.ts.map +1 -1
- package/dist/runtime/data-access/query.js +109 -36
- package/dist/runtime/data-access/query.js.map +1 -1
- package/dist/runtime/data-access/rbac.d.ts +2 -2
- package/dist/runtime/data-access/rbac.d.ts.map +1 -1
- package/dist/runtime/data-access/rbac.js +86 -47
- package/dist/runtime/data-access/rbac.js.map +1 -1
- package/dist/runtime/data-access/types.d.ts +24 -9
- package/dist/runtime/data-access/types.d.ts.map +1 -1
- package/dist/runtime/data-access/types.js +9 -1
- package/dist/runtime/data-access/types.js.map +1 -1
- package/dist/runtime/engine.d.ts +13 -2
- package/dist/runtime/engine.d.ts.map +1 -1
- package/dist/runtime/engine.js +57 -14
- package/dist/runtime/engine.js.map +1 -1
- package/dist/runtime/enums/index.d.ts +3 -0
- package/dist/runtime/enums/index.d.ts.map +1 -0
- package/dist/runtime/enums/index.js +2 -0
- package/dist/runtime/enums/index.js.map +1 -0
- package/dist/runtime/enums/loader.d.ts +27 -0
- package/dist/runtime/enums/loader.d.ts.map +1 -0
- package/dist/runtime/enums/loader.js +61 -0
- package/dist/runtime/enums/loader.js.map +1 -0
- package/dist/runtime/git/autoCommit.d.ts +1 -1
- package/dist/runtime/git/autoCommit.d.ts.map +1 -1
- package/dist/runtime/git/autoCommit.js +20 -1
- package/dist/runtime/git/autoCommit.js.map +1 -1
- package/dist/runtime/git/loader.d.ts +5 -1
- package/dist/runtime/git/loader.d.ts.map +1 -1
- package/dist/runtime/git/loader.js +6 -1
- package/dist/runtime/git/loader.js.map +1 -1
- package/dist/runtime/git/sync.d.ts +18 -3
- package/dist/runtime/git/sync.d.ts.map +1 -1
- package/dist/runtime/git/sync.js +25 -25
- package/dist/runtime/git/sync.js.map +1 -1
- package/dist/runtime/metadata/cache.d.ts +17 -5
- package/dist/runtime/metadata/cache.d.ts.map +1 -1
- package/dist/runtime/metadata/cache.js +46 -19
- package/dist/runtime/metadata/cache.js.map +1 -1
- package/dist/runtime/metadata/index.d.ts +3 -1
- package/dist/runtime/metadata/index.d.ts.map +1 -1
- package/dist/runtime/metadata/index.js +2 -1
- package/dist/runtime/metadata/index.js.map +1 -1
- package/dist/runtime/metadata/revision.d.ts +41 -0
- package/dist/runtime/metadata/revision.d.ts.map +1 -0
- package/dist/runtime/metadata/revision.js +53 -0
- package/dist/runtime/metadata/revision.js.map +1 -0
- package/dist/runtime/tools/executor.d.ts +1 -1
- package/dist/runtime/tools/executor.d.ts.map +1 -1
- package/dist/runtime/tools/executor.js +2 -1
- package/dist/runtime/tools/executor.js.map +1 -1
- package/dist/subsystems/audit/index.d.ts +10 -2
- package/dist/subsystems/audit/index.d.ts.map +1 -1
- package/dist/subsystems/audit/index.js +14 -1
- package/dist/subsystems/audit/index.js.map +1 -1
- package/dist/subsystems/audit/outbox.d.ts +33 -0
- package/dist/subsystems/audit/outbox.d.ts.map +1 -0
- package/dist/subsystems/audit/outbox.js +111 -0
- package/dist/subsystems/audit/outbox.js.map +1 -0
- package/dist/subsystems/audit/store.d.ts +3 -2
- package/dist/subsystems/audit/store.d.ts.map +1 -1
- package/dist/subsystems/audit/store.js +9 -7
- package/dist/subsystems/audit/store.js.map +1 -1
- package/dist/subsystems/script/bridge.d.ts.map +1 -1
- package/dist/subsystems/script/bridge.js +2 -1
- package/dist/subsystems/script/bridge.js.map +1 -1
- package/dist/subsystems/workflow/scheduler.d.ts.map +1 -1
- package/dist/subsystems/workflow/scheduler.js +2 -1
- package/dist/subsystems/workflow/scheduler.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,85 @@
|
|
|
3
3
|
All notable changes to `@weave-kit/engine`. Format follows [Keep a Changelog](https://keepachangelog.com/);
|
|
4
4
|
the project uses [Semantic Versioning](https://semver.org/).
|
|
5
5
|
|
|
6
|
+
## [0.9.0]
|
|
7
|
+
|
|
8
|
+
A **breaking** consistency/authorization release. Read the **Breaking** section before upgrading.
|
|
9
|
+
|
|
10
|
+
### Breaking
|
|
11
|
+
|
|
12
|
+
- **`DataAccessContext.principal` is now required; the implicit `subject` field is removed.** The old
|
|
13
|
+
convention — omit `subject` and get unrestricted access — is gone, so a forgotten actor is now a
|
|
14
|
+
**compile error** instead of a silent RBAC bypass. Migrate:
|
|
15
|
+
- a user call → `principal: userPrincipal(subject)` (or a literal `{ kind: 'user', subject }`);
|
|
16
|
+
- an internal/seed/system call → `principal: systemPrincipal(SYSTEM_CAPABILITIES.INTERNAL_ADMIN)`
|
|
17
|
+
(or `{ kind: 'system', capability: 'internal.admin' }`).
|
|
18
|
+
`AccessPrincipal`, `userPrincipal`, `systemPrincipal` and `SYSTEM_CAPABILITIES` are exported from
|
|
19
|
+
the package root. `withRbac` passes through only for an explicit **system** principal.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- **Global schema revisions + atomic deploys.** New `weavekit_schema_revision` (append-only, anchored
|
|
24
|
+
on a deterministic aggregate `computeSchemaHash(files)`). `weave migrate` / `weave deploy apply` now
|
|
25
|
+
commit the DDL, the metadata cache and the schema revision in **one transaction** (serialized by an
|
|
26
|
+
advisory lock) — a failure rolls the whole deploy back. New CLI: `weave deploy plan` (read-only
|
|
27
|
+
preview + risk) and `weave deploy apply`.
|
|
28
|
+
- **Audit durability modes.** `subsystems.audit.mode`: `best-effort` (default, unchanged),
|
|
29
|
+
`transactional` (audit row written in the business transaction) and `durable` (transactional outbox
|
|
30
|
+
`weavekit_audit_outbox` + a crash-safe, at-least-once relay). New `AuditSink.recordInTx(event,
|
|
31
|
+
client)` seam; audit events gain `requestId` / `traceId` (new indexed columns).
|
|
32
|
+
- **Cursor pagination.** `FindOptions.cursor` + `FindResult.nextCursor` / `hasMore` (opaque keyset on
|
|
33
|
+
the single primary key). MCP `search_records` accepts `cursor` and returns `hasMore`/`nextCursor`;
|
|
34
|
+
offset remains supported.
|
|
35
|
+
- **Access principal types** (`core/types/principal.ts`): `AccessPrincipal`, `SYSTEM_CAPABILITIES`,
|
|
36
|
+
`userPrincipal`, `systemPrincipal`, `principalSubject`, `principalActorId`.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- **MCP compiled-surface cache** key now includes a schema signature (registry-derived) and the
|
|
41
|
+
custom-tool set, and the cache is bounded — a schema/tool change no longer serves stale tools.
|
|
42
|
+
- **Workflow privileged operations** (`releaseWorkflowLock` / `workflowTodos` / `overrideWorkflow`)
|
|
43
|
+
are now guarded in the RBAC decorator (fail-closed read/update checks) instead of passing through.
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- **Implicit-unrestricted holes** in the custom-tool base context and the transition guardrail
|
|
48
|
+
context: both now carry a user principal, so a tool/policy cannot read unrestricted by omission.
|
|
49
|
+
|
|
50
|
+
## [0.8.0]
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
|
|
54
|
+
- **GraphQL adapter (opt-in).** `adapters.graphql` compiles the same `schema.json` into a read/write
|
|
55
|
+
GraphQL endpoint (`/graphql`, POST + GET) that reuses the engine's RBAC / RLS / audit unchanged:
|
|
56
|
+
queries (`<object>` pages + `<object>_by_id`, with nested relations batched per request),
|
|
57
|
+
mutations (`create`/`update`/`delete` plus workflow `transition`), query hardening
|
|
58
|
+
(depth / complexity / alias limits), an operation allow list, and an introspection toggle.
|
|
59
|
+
Its only runtime dependency is `graphql@16` — the engine speaks GraphQL-over-HTTP itself
|
|
60
|
+
(`graphql-http` is not required). New CLI: `weave graphql:schema` emits the SDL offline. **Off by
|
|
61
|
+
default** (`adapters.graphql.enabled`).
|
|
62
|
+
- **Named enums (schema v6).** Declare an enum once in `enums/<name>.json` and reference it from any
|
|
63
|
+
field with `{ "type": "enum", "enumType": "<name>" }`. Values validate centrally, generate named
|
|
64
|
+
TypeScript unions (`weave types`), surface as shared OpenAPI `components.schemas` (with
|
|
65
|
+
`x-enumLabels`), and are listed with `weave enum:list` / `weave enum:check`; `weave field:add
|
|
66
|
+
--enum` wires a new field to an existing enum. The on-disk format is bumped to **v6**
|
|
67
|
+
(`SCHEMA_FORMAT_VERSION`); existing v5 files migrate on read (additive — run `weave schema:upgrade`
|
|
68
|
+
to stamp them).
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
|
|
72
|
+
- **Uncategorized `SchemaError`s now map to HTTP 400** instead of falling through to 500. The error
|
|
73
|
+
space is dominated by request conditions (bad params/fields, RBAC, not-found); genuine server
|
|
74
|
+
faults keep 500 via an explicit set (`http.internal`, `data.schemaDrift`, and script runtime
|
|
75
|
+
failures `script.timeout` / `script.busy` / `script.compile` / `script.sandbox.unavailable`).
|
|
76
|
+
|
|
77
|
+
### Fixed
|
|
78
|
+
|
|
79
|
+
- **MCP session ↔ agent binding.** A follow-up request on an existing session now re-verifies that
|
|
80
|
+
the presented Bearer key is the one that established the session (compared by a non-secret SHA-256
|
|
81
|
+
fingerprint); a different key reusing a session id is rejected with `mcp.session.agentMismatch`.
|
|
82
|
+
The raw API key is no longer stored on the session or written to the audit log — audit `actorId`
|
|
83
|
+
is the credential fingerprint and the agent principal id stays in `meta`.
|
|
84
|
+
|
|
6
85
|
## [0.7.0]
|
|
7
86
|
|
|
8
87
|
### Added
|
package/README.md
CHANGED
|
@@ -50,10 +50,14 @@ write.
|
|
|
50
50
|
- **Custom field types** — register business-semantic types (`money`, `address`, …) as thin, namespaced
|
|
51
51
|
layers over a built-in primitive; they inherit storage, REST/MCP/OpenAPI schemas and generated
|
|
52
52
|
types. Declared in a project-local, Git-committed `field-types/` directory.
|
|
53
|
+
- **Named enums** — declare a shared enum once in `enums/` and reference it from any object by
|
|
54
|
+
`enumType`; every field shares one native PostgreSQL type and one set of per-value labels.
|
|
53
55
|
- **Governed REST API** — object CRUD with row-level (`all`/`own`/`team`) and field-level RBAC and a
|
|
54
56
|
uniform error contract.
|
|
55
57
|
- **MCP tool surface** — a streamable HTTP endpoint at `/mcp` with a per-identity tool surface and
|
|
56
58
|
guardrails.
|
|
59
|
+
- **GraphQL API** — an opt-in read/write GraphQL endpoint compiled from the same `schema.json`, with
|
|
60
|
+
nested relations, the same RBAC/audit, per-request batching and query hardening.
|
|
57
61
|
- **Audit log** — an immutable event log for data mutations.
|
|
58
62
|
- **Sandboxed hooks** — `*.server.js` lifecycle hooks running in isolated workers.
|
|
59
63
|
- **Type generation** — object-level TypeScript types derived from the schema.
|
|
@@ -139,12 +143,15 @@ await engine.app.listen({ port: 3000 });
|
|
|
139
143
|
| `weave schema:map [object] [--drift]` | Report the schema field ↔ PostgreSQL column mapping |
|
|
140
144
|
| `weave schema:upgrade [--dry-run]` | Upgrade `objects/*/schema.json` to the current format version |
|
|
141
145
|
| `weave openapi [--out] [--generic] [--server]` | Emit an OpenAPI 3.1 document for the REST API |
|
|
146
|
+
| `weave graphql:schema [--out]` | Emit the GraphQL SDL for this project |
|
|
142
147
|
| `weave mcp:config [--host]` | Print MCP client config for this project's `/mcp` endpoint |
|
|
143
148
|
| `weave connect` | Connect a self-hosted engine out to a governance tunnel endpoint |
|
|
144
149
|
| `weave object:create <name>` | Scaffold `objects/<name>/schema.json` + `server.js` hooks |
|
|
145
150
|
| `weave field:add <object>` | Add a validated field to a schema |
|
|
146
151
|
| `weave field-type:list` | List built-in + registered field types |
|
|
147
152
|
| `weave field-type:check` | Validate registrations + schemas against the registry |
|
|
153
|
+
| `weave enum:list` | List declared named enums (`enums/<name>.json`) |
|
|
154
|
+
| `weave enum:check` | Validate enum declarations + schema references |
|
|
148
155
|
| `weave module:add` / `module:remove <name>` | Enable/disable an optional subsystem (audit/script) |
|
|
149
156
|
|
|
150
157
|
## Object-level types
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
import { type GraphQLSchema } from 'graphql';
|
|
3
|
+
import { type Locale } from '../../core/index.js';
|
|
4
|
+
import { type Authenticator } from '../auth/index.js';
|
|
5
|
+
import type { EngineGraphQLConfig, GraphQLEngine } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Fastify adapter for the GraphQL endpoint (`/graphql`, POST + GET).
|
|
8
|
+
*
|
|
9
|
+
* A thin, dependency-light HTTP handler (per the plan's decision 1B): the engine
|
|
10
|
+
* ships `graphql` as its only new runtime dependency and speaks GraphQL-over-HTTP
|
|
11
|
+
* itself. Request order: authenticate (plain `401`) → rate limit → parse →
|
|
12
|
+
* validate → query hardening (depth/complexity/alias) → execute. GraphQL-level
|
|
13
|
+
* problems (parse/validate/execute) return `200 { errors }`; a rejected security
|
|
14
|
+
* limit carries its stable code in `errors[].extensions.code`.
|
|
15
|
+
*/
|
|
16
|
+
export interface GraphQLRouteDeps {
|
|
17
|
+
engine: GraphQLEngine;
|
|
18
|
+
authenticator: Authenticator;
|
|
19
|
+
schema: GraphQLSchema;
|
|
20
|
+
graphql: EngineGraphQLConfig | undefined;
|
|
21
|
+
locale: Locale;
|
|
22
|
+
}
|
|
23
|
+
export declare function registerGraphQLRoutes(app: FastifyInstance, deps: GraphQLRouteDeps): void;
|
|
24
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/adapters/graphql/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgC,MAAM,SAAS,CAAC;AAC7E,OAAO,EAA0C,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAA0D,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE1G,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;;;;GASG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;IAC7B,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;CAChB;AAyED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAgFxF"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { execute, GraphQLError, parse, validate } from 'graphql';
|
|
2
|
+
import { createSlidingWindow, SchemaError } from '../../core/index.js';
|
|
3
|
+
import { mapSchemaError } from '../../core/api/index.js';
|
|
4
|
+
import { authenticate } from '../auth/index.js';
|
|
5
|
+
import { createRecordLoader } from './loader.js';
|
|
6
|
+
import { resolveSecurity, validateQuery, validationRules } from './security.js';
|
|
7
|
+
/** uniform error body (matches the REST/MCP contract) */
|
|
8
|
+
function errorBody(code, message, params) {
|
|
9
|
+
return { error: { code, message, ...(params === undefined ? {} : { params }) } };
|
|
10
|
+
}
|
|
11
|
+
function formatError(error) {
|
|
12
|
+
return {
|
|
13
|
+
message: error.message,
|
|
14
|
+
...(error.locations === undefined ? {} : { locations: error.locations }),
|
|
15
|
+
...(error.path === undefined ? {} : { path: error.path }),
|
|
16
|
+
...(error.extensions === undefined || Object.keys(error.extensions).length === 0
|
|
17
|
+
? {}
|
|
18
|
+
: { extensions: error.extensions }),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function badRequest(detail, param) {
|
|
22
|
+
return errorBody('http.param.invalid', detail, { param });
|
|
23
|
+
}
|
|
24
|
+
/** parse a POST (JSON body) or GET (query string) request into a GraphQL operation */
|
|
25
|
+
function parseOperation(request) {
|
|
26
|
+
if (request.method === 'GET') {
|
|
27
|
+
const q = request.query;
|
|
28
|
+
if (typeof q.query !== 'string' || q.query.length === 0)
|
|
29
|
+
return badRequest('query is required', 'query');
|
|
30
|
+
let variables;
|
|
31
|
+
if (typeof q.variables === 'string' && q.variables.length > 0) {
|
|
32
|
+
try {
|
|
33
|
+
variables = JSON.parse(q.variables);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return badRequest('variables must be valid JSON', 'variables');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const operationName = typeof q.operationName === 'string' && q.operationName.length > 0 ? q.operationName : undefined;
|
|
40
|
+
return {
|
|
41
|
+
query: q.query,
|
|
42
|
+
...(variables === undefined ? {} : { variables }),
|
|
43
|
+
...(operationName === undefined ? {} : { operationName }),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const body = request.body;
|
|
47
|
+
if (body === undefined || typeof body !== 'object' || body === null) {
|
|
48
|
+
return badRequest('request body must be a JSON object', 'body');
|
|
49
|
+
}
|
|
50
|
+
if (typeof body.query !== 'string' || body.query.length === 0)
|
|
51
|
+
return badRequest('query is required', 'query');
|
|
52
|
+
let variables;
|
|
53
|
+
if (body.variables !== undefined) {
|
|
54
|
+
if (typeof body.variables !== 'object' || body.variables === null || Array.isArray(body.variables)) {
|
|
55
|
+
return badRequest('variables must be an object', 'variables');
|
|
56
|
+
}
|
|
57
|
+
variables = body.variables;
|
|
58
|
+
}
|
|
59
|
+
const operationName = typeof body.operationName === 'string' && body.operationName.length > 0 ? body.operationName : undefined;
|
|
60
|
+
return {
|
|
61
|
+
query: body.query,
|
|
62
|
+
...(variables === undefined ? {} : { variables }),
|
|
63
|
+
...(operationName === undefined ? {} : { operationName }),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function isParsed(value) {
|
|
67
|
+
return typeof value.query === 'string';
|
|
68
|
+
}
|
|
69
|
+
export function registerGraphQLRoutes(app, deps) {
|
|
70
|
+
const path = deps.graphql?.prefix ?? '/graphql';
|
|
71
|
+
const limiter = deps.graphql?.rateLimit === undefined ? undefined : createSlidingWindow(deps.graphql.rateLimit);
|
|
72
|
+
const security = resolveSecurity(deps.graphql?.security);
|
|
73
|
+
app.route({
|
|
74
|
+
method: ['POST', 'GET'],
|
|
75
|
+
url: path,
|
|
76
|
+
handler: async (request, reply) => {
|
|
77
|
+
// authenticate before executing (401 stays a plain HTTP error)
|
|
78
|
+
let subject;
|
|
79
|
+
try {
|
|
80
|
+
subject = await authenticate(deps.authenticator, request.headers.authorization, deps.locale);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const spec = mapSchemaError(error, deps.locale);
|
|
84
|
+
reply.status(spec.status).send(spec.body);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (limiter !== undefined) {
|
|
88
|
+
const auth = request.headers.authorization;
|
|
89
|
+
const key = typeof auth === 'string' ? auth.replace(/^Bearer\s+/i, '') : subject.id;
|
|
90
|
+
if (!limiter.check(key)) {
|
|
91
|
+
reply.status(429).send(errorBody('http.rateLimited', 'rate limit exceeded'));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const parsed = parseOperation(request);
|
|
96
|
+
if (!isParsed(parsed)) {
|
|
97
|
+
reply.status(400).send(parsed);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// parse → validate → harden → execute (all GraphQL-level failures are 200)
|
|
101
|
+
let document;
|
|
102
|
+
try {
|
|
103
|
+
document = parse(parsed.query);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
reply.status(200).send({ errors: [formatError(error)] });
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const validationErrors = validate(deps.schema, document, validationRules(security));
|
|
110
|
+
if (validationErrors.length > 0) {
|
|
111
|
+
reply.status(200).send({ errors: validationErrors.map(formatError) });
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
validateQuery(document, security, deps.locale);
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
if (error instanceof SchemaError) {
|
|
119
|
+
reply.status(200).send({
|
|
120
|
+
errors: [
|
|
121
|
+
{
|
|
122
|
+
message: error.localize(deps.locale),
|
|
123
|
+
extensions: { code: error.code, ...(Object.keys(error.params).length === 0 ? {} : { params: error.params }) },
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
});
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
131
|
+
const result = await execute({
|
|
132
|
+
schema: deps.schema,
|
|
133
|
+
document,
|
|
134
|
+
...(parsed.variables === undefined ? {} : { variableValues: parsed.variables }),
|
|
135
|
+
...(parsed.operationName === undefined ? {} : { operationName: parsed.operationName }),
|
|
136
|
+
contextValue: { subject, engine: deps.engine, loader: createRecordLoader(deps.engine, subject), requestId: request.id },
|
|
137
|
+
});
|
|
138
|
+
const body = {};
|
|
139
|
+
if (result.data !== undefined)
|
|
140
|
+
body.data = result.data;
|
|
141
|
+
if (result.errors !== undefined)
|
|
142
|
+
body.errors = result.errors.map(formatError);
|
|
143
|
+
reply.status(200).send(body);
|
|
144
|
+
},
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/adapters/graphql/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
import type { GraphQLSchema } from 'graphql';
|
|
3
|
+
import type { Locale } from '../../core/index.js';
|
|
4
|
+
import type { Authenticator } from '../auth/index.js';
|
|
5
|
+
import type { EngineGraphQLConfig, GraphQLEngine } from './types.js';
|
|
6
|
+
/**
|
|
7
|
+
* GraphQL adapter assembly. `registerGraphQL` compiles the object registry into
|
|
8
|
+
* a GraphQL schema and mounts the `/graphql` endpoint on the fastify app. The
|
|
9
|
+
* adapter reuses the engine's data-access/RBAC/audit layer — the assembly layer
|
|
10
|
+
* (createEngine) injects the same `dataAccess` + `authenticator` as REST/MCP.
|
|
11
|
+
*
|
|
12
|
+
* Disabled unless `adapters.graphql.enabled` is true (decision 7): the engine
|
|
13
|
+
* only mounts the endpoint when a project opts in.
|
|
14
|
+
*/
|
|
15
|
+
export interface GraphQLDeps {
|
|
16
|
+
engine: GraphQLEngine;
|
|
17
|
+
authenticator: Authenticator;
|
|
18
|
+
graphql: EngineGraphQLConfig | undefined;
|
|
19
|
+
locale: Locale;
|
|
20
|
+
}
|
|
21
|
+
export interface GraphQLServerHandle {
|
|
22
|
+
/** the compiled schema (read-only; exposed for tooling / SDL export) */
|
|
23
|
+
readonly schema: GraphQLSchema;
|
|
24
|
+
close(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
/** Register the GraphQL endpoint on an existing fastify app. */
|
|
27
|
+
export declare function registerGraphQL(app: FastifyInstance, deps: GraphQLDeps): GraphQLServerHandle;
|
|
28
|
+
export { buildGraphQLSchema, printGraphQLSchema } from './schema.js';
|
|
29
|
+
export { registerGraphQLRoutes } from './http.js';
|
|
30
|
+
export { GRAPHQL_DEFAULT_MAX_DEPTH, operationHash, validationRules } from './security.js';
|
|
31
|
+
export type { GraphQLRouteDeps } from './http.js';
|
|
32
|
+
export type { GraphQLEngine, EngineGraphQLConfig, GraphQLSecurityConfig, RecordLoader } from './types.js';
|
|
33
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/graphql/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;;;GAQG;AAEH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,wEAAwE;IACxE,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,WAAW,GAAG,mBAAmB,CAgB5F;AAED,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,yBAAyB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC1F,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { buildGraphQLSchema } from './schema.js';
|
|
2
|
+
import { registerGraphQLRoutes } from './http.js';
|
|
3
|
+
/** Register the GraphQL endpoint on an existing fastify app. */
|
|
4
|
+
export function registerGraphQL(app, deps) {
|
|
5
|
+
const schema = buildGraphQLSchema(deps.engine);
|
|
6
|
+
registerGraphQLRoutes(app, {
|
|
7
|
+
engine: deps.engine,
|
|
8
|
+
authenticator: deps.authenticator,
|
|
9
|
+
schema,
|
|
10
|
+
graphql: deps.graphql,
|
|
11
|
+
locale: deps.locale,
|
|
12
|
+
});
|
|
13
|
+
return {
|
|
14
|
+
schema,
|
|
15
|
+
async close() {
|
|
16
|
+
// per-request execution holds no persistent resources yet; reserved for
|
|
17
|
+
// loaders/schedulers added in later phases.
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export { buildGraphQLSchema, printGraphQLSchema } from './schema.js';
|
|
22
|
+
export { registerGraphQLRoutes } from './http.js';
|
|
23
|
+
export { GRAPHQL_DEFAULT_MAX_DEPTH, operationHash, validationRules } from './security.js';
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/graphql/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AA0BlD,gEAAgE;AAChE,MAAM,UAAU,eAAe,CAAC,GAAoB,EAAE,IAAiB;IACrE,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/C,qBAAqB,CAAC,GAAG,EAAE;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,MAAM;QACN,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CAAC;IACH,OAAO;QACL,MAAM;QACN,KAAK,CAAC,KAAK;YACT,wEAAwE;YACxE,4CAA4C;QAC9C,CAAC;KACF,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,yBAAyB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/adapters/graphql/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,eAAe,EAErB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAsB9D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,eAAe,GAAG,YAAY,CAqJhG"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { DETAILS_COLUMNS, decodeRecordKey, FIELD_TYPES, primaryFieldsOf, RECORD_META_ID_FIELD, userPrincipal, } from '../../core/index.js';
|
|
2
|
+
export function createRecordLoader(engine, subject) {
|
|
3
|
+
const recordPending = new Map();
|
|
4
|
+
const childPending = new Map();
|
|
5
|
+
let scheduled = false;
|
|
6
|
+
const context = () => ({
|
|
7
|
+
pool: engine.pool,
|
|
8
|
+
registry: engine.registry,
|
|
9
|
+
principal: userPrincipal(subject),
|
|
10
|
+
locale: engine.locale,
|
|
11
|
+
});
|
|
12
|
+
const projection = (def, extra = []) => [
|
|
13
|
+
...def.fields.filter((f) => f.type !== FIELD_TYPES.DETAILS).map((f) => f.name),
|
|
14
|
+
...extra,
|
|
15
|
+
RECORD_META_ID_FIELD,
|
|
16
|
+
];
|
|
17
|
+
const schedule = () => {
|
|
18
|
+
if (scheduled)
|
|
19
|
+
return;
|
|
20
|
+
scheduled = true;
|
|
21
|
+
queueMicrotask(() => {
|
|
22
|
+
void flush();
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
async function flush() {
|
|
26
|
+
scheduled = false;
|
|
27
|
+
const records = new Map(recordPending);
|
|
28
|
+
const children = new Map(childPending);
|
|
29
|
+
recordPending.clear();
|
|
30
|
+
childPending.clear();
|
|
31
|
+
await Promise.all([
|
|
32
|
+
...[...records].map(([object, byKey]) => flushRecords(object, byKey)),
|
|
33
|
+
...[...children].map(([object, byKey]) => flushChildren(object, byKey)),
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
36
|
+
async function flushRecords(objectName, byKey) {
|
|
37
|
+
try {
|
|
38
|
+
const rows = await loadRecords(objectName, [...byKey.keys()]);
|
|
39
|
+
const byId = new Map(rows.map((row) => [String(row[RECORD_META_ID_FIELD]), row]));
|
|
40
|
+
for (const [key, entries] of byKey) {
|
|
41
|
+
const value = byId.get(key) ?? null;
|
|
42
|
+
for (const entry of entries)
|
|
43
|
+
entry.resolve(value);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
for (const entries of byKey.values())
|
|
48
|
+
for (const entry of entries)
|
|
49
|
+
entry.reject(error);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async function loadRecords(objectName, keys) {
|
|
53
|
+
const def = engine.registry.get(objectName);
|
|
54
|
+
if (def === undefined)
|
|
55
|
+
return [];
|
|
56
|
+
const pks = primaryFieldsOf(def);
|
|
57
|
+
if (pks.length === 1) {
|
|
58
|
+
const values = keys.map((key) => {
|
|
59
|
+
try {
|
|
60
|
+
return decodeRecordKey(key)[0];
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return key;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
const result = await engine.dataAccess.find(objectName, { filter: { [pks[0].name]: { in: values } }, fields: projection(def) }, context());
|
|
67
|
+
return result.rows;
|
|
68
|
+
}
|
|
69
|
+
const rows = [];
|
|
70
|
+
for (const key of keys) {
|
|
71
|
+
const row = await engine.dataAccess.findOne(objectName, key, context());
|
|
72
|
+
if (row !== null)
|
|
73
|
+
rows.push(row);
|
|
74
|
+
}
|
|
75
|
+
return rows;
|
|
76
|
+
}
|
|
77
|
+
async function flushChildren(childObject, byKey) {
|
|
78
|
+
try {
|
|
79
|
+
const rows = await loadChildrenRows(childObject, [...byKey.keys()]);
|
|
80
|
+
const grouped = new Map();
|
|
81
|
+
for (const row of rows) {
|
|
82
|
+
const parentId = String(row[DETAILS_COLUMNS.PARENT_ID] ?? '');
|
|
83
|
+
const list = grouped.get(parentId);
|
|
84
|
+
if (list === undefined)
|
|
85
|
+
grouped.set(parentId, [row]);
|
|
86
|
+
else
|
|
87
|
+
list.push(row);
|
|
88
|
+
}
|
|
89
|
+
for (const list of grouped.values()) {
|
|
90
|
+
list.sort((a, b) => Number(a[DETAILS_COLUMNS.PARENT_IDX] ?? 0) - Number(b[DETAILS_COLUMNS.PARENT_IDX] ?? 0));
|
|
91
|
+
}
|
|
92
|
+
for (const [key, entries] of byKey) {
|
|
93
|
+
const list = grouped.get(key) ?? [];
|
|
94
|
+
for (const entry of entries)
|
|
95
|
+
entry.resolve(list);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
for (const entries of byKey.values())
|
|
100
|
+
for (const entry of entries)
|
|
101
|
+
entry.reject(error);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function loadChildrenRows(childObject, parentKeys) {
|
|
105
|
+
const def = engine.registry.get(childObject);
|
|
106
|
+
if (def === undefined)
|
|
107
|
+
return [];
|
|
108
|
+
const result = await engine.dataAccess.find(childObject, {
|
|
109
|
+
filter: { [DETAILS_COLUMNS.PARENT_ID]: { in: parentKeys } },
|
|
110
|
+
fields: projection(def, [DETAILS_COLUMNS.PARENT_ID, DETAILS_COLUMNS.PARENT_IDX]),
|
|
111
|
+
}, context());
|
|
112
|
+
return result.rows;
|
|
113
|
+
}
|
|
114
|
+
function enqueue(store, objectName, key, entry) {
|
|
115
|
+
const byKey = store.get(objectName) ?? new Map();
|
|
116
|
+
store.set(objectName, byKey);
|
|
117
|
+
const list = byKey.get(key) ?? [];
|
|
118
|
+
list.push(entry);
|
|
119
|
+
byKey.set(key, list);
|
|
120
|
+
schedule();
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
load(objectName, recordKey) {
|
|
124
|
+
return new Promise((resolve, reject) => {
|
|
125
|
+
enqueue(recordPending, objectName, recordKey, { resolve, reject });
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
loadChildren(childObject, parentKey) {
|
|
129
|
+
return new Promise((resolve, reject) => {
|
|
130
|
+
enqueue(childPending, childObject, parentKey, { resolve, reject });
|
|
131
|
+
});
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/adapters/graphql/loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type ObjectDefinition } from '../../core/index.js';
|
|
2
|
+
import type { Sort } from '../../runtime/data-access/index.js';
|
|
3
|
+
import type { GraphQLContext } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Root Query resolvers. Each one builds a {@link DataAccessContext} from the
|
|
6
|
+
* request context and calls the RBAC-decorated data-access layer — so row scope
|
|
7
|
+
* (`own`/`department`), field exclusion and (for writes) auditing come from the
|
|
8
|
+
* existing layer, exactly as REST/MCP. A thrown {@link SchemaError} is mapped to
|
|
9
|
+
* a GraphQLError carrying its stable `extensions.code`.
|
|
10
|
+
*/
|
|
11
|
+
interface ListArgs {
|
|
12
|
+
filter?: unknown;
|
|
13
|
+
sort?: Sort[];
|
|
14
|
+
limit?: number;
|
|
15
|
+
offset?: number;
|
|
16
|
+
}
|
|
17
|
+
/** `<object>` — a page of records, row-scoped by the identity's read RBAC */
|
|
18
|
+
export declare function listResolver(objectName: string): (_parent: unknown, args: ListArgs, context: GraphQLContext) => Promise<{
|
|
19
|
+
rows: unknown[];
|
|
20
|
+
total: number;
|
|
21
|
+
}>;
|
|
22
|
+
/** `<object>_by_id` — one record by its `weave_id` (record_key), or null */
|
|
23
|
+
export declare function singleResolver(objectName: string): (_parent: unknown, args: {
|
|
24
|
+
id: string;
|
|
25
|
+
}, context: GraphQLContext) => Promise<unknown>;
|
|
26
|
+
/** `create<Object>(data:)` — create one record (RBAC-checked + audited by data-access) */
|
|
27
|
+
export declare function createResolver(objectName: string): (_parent: unknown, args: {
|
|
28
|
+
data: Record<string, unknown>;
|
|
29
|
+
}, context: GraphQLContext) => Promise<unknown>;
|
|
30
|
+
/** `update<Object>(id:, changes:)` — update one record by its `weave_id` */
|
|
31
|
+
export declare function updateResolver(objectName: string): (_parent: unknown, args: {
|
|
32
|
+
id: string;
|
|
33
|
+
changes: Record<string, unknown>;
|
|
34
|
+
}, context: GraphQLContext) => Promise<unknown>;
|
|
35
|
+
/** `delete<Object>(id:)` — delete one record; returns true (throws when absent/denied) */
|
|
36
|
+
export declare function deleteResolver(objectName: string): (_parent: unknown, args: {
|
|
37
|
+
id: string;
|
|
38
|
+
}, context: GraphQLContext) => Promise<boolean>;
|
|
39
|
+
/** `transition<Object>(id:, action:, payload:)` — run a workflow action */
|
|
40
|
+
export declare function transitionResolver(objectName: string): (_parent: unknown, args: {
|
|
41
|
+
id: string;
|
|
42
|
+
action: string;
|
|
43
|
+
payload?: Record<string, unknown>;
|
|
44
|
+
}, context: GraphQLContext) => Promise<unknown>;
|
|
45
|
+
/** a `relation`/`user`/`department` output field → the target object (batched) */
|
|
46
|
+
export declare function relationResolver(target: string, fieldName: string): (parent: unknown, _args: unknown, context: GraphQLContext) => Promise<Record<string, unknown> | null>;
|
|
47
|
+
/** a `multiRelation` output field → the target objects (batched) */
|
|
48
|
+
export declare function multiRelationResolver(target: string, targetDef: ObjectDefinition, fieldName: string): (parent: unknown, _args: unknown, context: GraphQLContext) => Promise<Record<string, unknown>[]>;
|
|
49
|
+
/** a `details` output field → the parent's children (batched, ordered by `parent_idx`) */
|
|
50
|
+
export declare function detailsResolver(childObject: string): (parent: unknown, _args: unknown, context: GraphQLContext) => Promise<Record<string, unknown>[]>;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=resolvers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolvers.d.ts","sourceRoot":"","sources":["../../../src/adapters/graphql/resolvers.ts"],"names":[],"mappings":"AACA,OAAO,EAQL,KAAK,gBAAgB,EACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAA6B,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;GAMG;AAEH,UAAU,QAAQ;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAkCD,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,IAE3C,SAAS,OAAO,EAChB,MAAM,QAAQ,EACd,SAAS,cAAc,KACtB,OAAO,CAAC;IAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAqB/C;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,IACjC,SAAS,OAAO,EAAE,MAAM;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,SAAS,cAAc,KAAG,OAAO,CAAC,OAAO,CAAC,CAOjG;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,IACjC,SAAS,OAAO,EAAE,MAAM;IAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EAAE,SAAS,cAAc,KAAG,OAAO,CAAC,OAAO,CAAC,CAMpH;AAED,4EAA4E;AAC5E,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,IAE7C,SAAS,OAAO,EAChB,MAAM;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EACtD,SAAS,cAAc,KACtB,OAAO,CAAC,OAAO,CAAC,CAMpB;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,IACjC,SAAS,OAAO,EAAE,MAAM;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,SAAS,cAAc,KAAG,OAAO,CAAC,OAAO,CAAC,CAIjG;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,IAEjD,SAAS,OAAO,EAChB,MAAM;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EACvE,SAAS,cAAc,KACtB,OAAO,CAAC,OAAO,CAAC,CAapB;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,IAE9D,QAAQ,OAAO,EACf,OAAO,OAAO,EACd,SAAS,cAAc,KACtB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAK3C;AAED,oEAAoE;AACpE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,IACpF,QAAQ,OAAO,EAAE,OAAO,OAAO,EAAE,SAAS,cAAc,KAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAS5G;AAED,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,IACnC,QAAQ,OAAO,EAAE,OAAO,OAAO,EAAE,SAAS,cAAc,KAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAK5G"}
|