@jini-ai/cms 0.1.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/LICENSE +201 -0
- package/README.md +84 -0
- package/dist/content-types/agent-tools.d.ts +65 -0
- package/dist/content-types/agent-tools.d.ts.map +1 -0
- package/dist/content-types/agent-tools.js +172 -0
- package/dist/content-types/agent-tools.js.map +1 -0
- package/dist/content-types/cleanup.d.ts +118 -0
- package/dist/content-types/cleanup.d.ts.map +1 -0
- package/dist/content-types/cleanup.js +65 -0
- package/dist/content-types/cleanup.js.map +1 -0
- package/dist/content-types/errors.d.ts +90 -0
- package/dist/content-types/errors.d.ts.map +1 -0
- package/dist/content-types/errors.js +119 -0
- package/dist/content-types/errors.js.map +1 -0
- package/dist/content-types/field-defs.d.ts +25 -0
- package/dist/content-types/field-defs.d.ts.map +1 -0
- package/dist/content-types/field-defs.js +155 -0
- package/dist/content-types/field-defs.js.map +1 -0
- package/dist/content-types/index-provisioning.d.ts +94 -0
- package/dist/content-types/index-provisioning.d.ts.map +1 -0
- package/dist/content-types/index-provisioning.js +133 -0
- package/dist/content-types/index-provisioning.js.map +1 -0
- package/dist/content-types/index.d.ts +63 -0
- package/dist/content-types/index.d.ts.map +1 -0
- package/dist/content-types/index.js +36 -0
- package/dist/content-types/index.js.map +1 -0
- package/dist/content-types/lifecycle-dispatch.d.ts +38 -0
- package/dist/content-types/lifecycle-dispatch.d.ts.map +1 -0
- package/dist/content-types/lifecycle-dispatch.js +28 -0
- package/dist/content-types/lifecycle-dispatch.js.map +1 -0
- package/dist/content-types/lifecycle.d.ts +104 -0
- package/dist/content-types/lifecycle.d.ts.map +1 -0
- package/dist/content-types/lifecycle.js +143 -0
- package/dist/content-types/lifecycle.js.map +1 -0
- package/dist/content-types/list.d.ts +44 -0
- package/dist/content-types/list.d.ts.map +1 -0
- package/dist/content-types/list.js +13 -0
- package/dist/content-types/list.js.map +1 -0
- package/dist/content-types/repo.memory.d.ts +72 -0
- package/dist/content-types/repo.memory.d.ts.map +1 -0
- package/dist/content-types/repo.memory.js +71 -0
- package/dist/content-types/repo.memory.js.map +1 -0
- package/dist/content-types/tool-registrations.d.ts +65 -0
- package/dist/content-types/tool-registrations.d.ts.map +1 -0
- package/dist/content-types/tool-registrations.js +180 -0
- package/dist/content-types/tool-registrations.js.map +1 -0
- package/dist/content-types/types.d.ts +78 -0
- package/dist/content-types/types.d.ts.map +1 -0
- package/dist/content-types/types.js +32 -0
- package/dist/content-types/types.js.map +1 -0
- package/dist/content-types/write-service.d.ts +141 -0
- package/dist/content-types/write-service.d.ts.map +1 -0
- package/dist/content-types/write-service.js +180 -0
- package/dist/content-types/write-service.js.map +1 -0
- package/dist/core/commands/change-set.d.ts +98 -0
- package/dist/core/commands/change-set.d.ts.map +1 -0
- package/dist/core/commands/change-set.js +2 -0
- package/dist/core/commands/change-set.js.map +1 -0
- package/dist/core/commands/command.d.ts +168 -0
- package/dist/core/commands/command.d.ts.map +1 -0
- package/dist/core/commands/command.js +173 -0
- package/dist/core/commands/command.js.map +1 -0
- package/dist/core/index.d.ts +45 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +43 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/ports.d.ts +139 -0
- package/dist/core/ports.d.ts.map +1 -0
- package/dist/core/ports.js +2 -0
- package/dist/core/ports.js.map +1 -0
- package/dist/core/tools/registration-kit.d.ts +308 -0
- package/dist/core/tools/registration-kit.d.ts.map +1 -0
- package/dist/core/tools/registration-kit.js +381 -0
- package/dist/core/tools/registration-kit.js.map +1 -0
- package/dist/entries/agent-tools.d.ts +78 -0
- package/dist/entries/agent-tools.d.ts.map +1 -0
- package/dist/entries/agent-tools.js +158 -0
- package/dist/entries/agent-tools.js.map +1 -0
- package/dist/entries/errors.d.ts +43 -0
- package/dist/entries/errors.d.ts.map +1 -0
- package/dist/entries/errors.js +59 -0
- package/dist/entries/errors.js.map +1 -0
- package/dist/entries/field-validation.d.ts +70 -0
- package/dist/entries/field-validation.d.ts.map +1 -0
- package/dist/entries/field-validation.js +87 -0
- package/dist/entries/field-validation.js.map +1 -0
- package/dist/entries/index.d.ts +55 -0
- package/dist/entries/index.d.ts.map +1 -0
- package/dist/entries/index.js +38 -0
- package/dist/entries/index.js.map +1 -0
- package/dist/entries/lifecycle-dispatch.d.ts +15 -0
- package/dist/entries/lifecycle-dispatch.d.ts.map +1 -0
- package/dist/entries/lifecycle-dispatch.js +16 -0
- package/dist/entries/lifecycle-dispatch.js.map +1 -0
- package/dist/entries/list.d.ts +47 -0
- package/dist/entries/list.d.ts.map +1 -0
- package/dist/entries/list.js +12 -0
- package/dist/entries/list.js.map +1 -0
- package/dist/entries/repo.memory.d.ts +64 -0
- package/dist/entries/repo.memory.d.ts.map +1 -0
- package/dist/entries/repo.memory.js +73 -0
- package/dist/entries/repo.memory.js.map +1 -0
- package/dist/entries/tool-registrations.d.ts +52 -0
- package/dist/entries/tool-registrations.d.ts.map +1 -0
- package/dist/entries/tool-registrations.js +141 -0
- package/dist/entries/tool-registrations.js.map +1 -0
- package/dist/entries/types.d.ts +55 -0
- package/dist/entries/types.d.ts.map +1 -0
- package/dist/entries/types.js +2 -0
- package/dist/entries/types.js.map +1 -0
- package/dist/entries/write-service.d.ts +202 -0
- package/dist/entries/write-service.d.ts.map +1 -0
- package/dist/entries/write-service.js +204 -0
- package/dist/entries/write-service.js.map +1 -0
- package/dist/identity/admin-crud-service.d.ts +252 -0
- package/dist/identity/admin-crud-service.d.ts.map +1 -0
- package/dist/identity/admin-crud-service.js +437 -0
- package/dist/identity/admin-crud-service.js.map +1 -0
- package/dist/identity/agent-tool-input.d.ts +58 -0
- package/dist/identity/agent-tool-input.d.ts.map +1 -0
- package/dist/identity/agent-tool-input.js +126 -0
- package/dist/identity/agent-tool-input.js.map +1 -0
- package/dist/identity/agent-tools.d.ts +101 -0
- package/dist/identity/agent-tools.d.ts.map +1 -0
- package/dist/identity/agent-tools.js +290 -0
- package/dist/identity/agent-tools.js.map +1 -0
- package/dist/identity/auth-service.d.ts +87 -0
- package/dist/identity/auth-service.d.ts.map +1 -0
- package/dist/identity/auth-service.js +141 -0
- package/dist/identity/auth-service.js.map +1 -0
- package/dist/identity/authorize.d.ts +90 -0
- package/dist/identity/authorize.d.ts.map +1 -0
- package/dist/identity/authorize.js +94 -0
- package/dist/identity/authorize.js.map +1 -0
- package/dist/identity/grant-service.d.ts +198 -0
- package/dist/identity/grant-service.d.ts.map +1 -0
- package/dist/identity/grant-service.js +361 -0
- package/dist/identity/grant-service.js.map +1 -0
- package/dist/identity/hasher.d.ts +39 -0
- package/dist/identity/hasher.d.ts.map +1 -0
- package/dist/identity/hasher.js +39 -0
- package/dist/identity/hasher.js.map +1 -0
- package/dist/identity/index.d.ts +59 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +51 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/identity/password-policy.d.ts +58 -0
- package/dist/identity/password-policy.d.ts.map +1 -0
- package/dist/identity/password-policy.js +67 -0
- package/dist/identity/password-policy.js.map +1 -0
- package/dist/identity/permission-migrations.d.ts +86 -0
- package/dist/identity/permission-migrations.d.ts.map +1 -0
- package/dist/identity/permission-migrations.js +67 -0
- package/dist/identity/permission-migrations.js.map +1 -0
- package/dist/identity/permissions.d.ts +35 -0
- package/dist/identity/permissions.d.ts.map +1 -0
- package/dist/identity/permissions.js +603 -0
- package/dist/identity/permissions.js.map +1 -0
- package/dist/identity/ports.d.ts +201 -0
- package/dist/identity/ports.d.ts.map +1 -0
- package/dist/identity/ports.js +2 -0
- package/dist/identity/ports.js.map +1 -0
- package/dist/identity/repo.memory.d.ts +164 -0
- package/dist/identity/repo.memory.d.ts.map +1 -0
- package/dist/identity/repo.memory.js +224 -0
- package/dist/identity/repo.memory.js.map +1 -0
- package/dist/identity/seed.d.ts +42 -0
- package/dist/identity/seed.d.ts.map +1 -0
- package/dist/identity/seed.js +277 -0
- package/dist/identity/seed.js.map +1 -0
- package/dist/identity/tool-registrations.d.ts +50 -0
- package/dist/identity/tool-registrations.d.ts.map +1 -0
- package/dist/identity/tool-registrations.js +419 -0
- package/dist/identity/tool-registrations.js.map +1 -0
- package/dist/identity/types.d.ts +185 -0
- package/dist/identity/types.d.ts.map +1 -0
- package/dist/identity/types.js +64 -0
- package/dist/identity/types.js.map +1 -0
- package/dist/identity/username.d.ts +12 -0
- package/dist/identity/username.d.ts.map +1 -0
- package/dist/identity/username.js +14 -0
- package/dist/identity/username.js.map +1 -0
- package/dist/media/agent-tools.d.ts +66 -0
- package/dist/media/agent-tools.d.ts.map +1 -0
- package/dist/media/agent-tools.js +131 -0
- package/dist/media/agent-tools.js.map +1 -0
- package/dist/media/blob-gc-lock.d.ts +37 -0
- package/dist/media/blob-gc-lock.d.ts.map +1 -0
- package/dist/media/blob-gc-lock.js +55 -0
- package/dist/media/blob-gc-lock.js.map +1 -0
- package/dist/media/blob-gc.d.ts +246 -0
- package/dist/media/blob-gc.d.ts.map +1 -0
- package/dist/media/blob-gc.js +254 -0
- package/dist/media/blob-gc.js.map +1 -0
- package/dist/media/blob-key.d.ts +28 -0
- package/dist/media/blob-key.d.ts.map +1 -0
- package/dist/media/blob-key.js +11 -0
- package/dist/media/blob-key.js.map +1 -0
- package/dist/media/blob-store.fs.d.ts +23 -0
- package/dist/media/blob-store.fs.d.ts.map +1 -0
- package/dist/media/blob-store.fs.js +48 -0
- package/dist/media/blob-store.fs.js.map +1 -0
- package/dist/media/blob-store.memory.d.ts +22 -0
- package/dist/media/blob-store.memory.d.ts.map +1 -0
- package/dist/media/blob-store.memory.js +23 -0
- package/dist/media/blob-store.memory.js.map +1 -0
- package/dist/media/content-type-sniffer.d.ts +49 -0
- package/dist/media/content-type-sniffer.d.ts.map +1 -0
- package/dist/media/content-type-sniffer.js +141 -0
- package/dist/media/content-type-sniffer.js.map +1 -0
- package/dist/media/image-transformer.d.ts +45 -0
- package/dist/media/image-transformer.d.ts.map +1 -0
- package/dist/media/image-transformer.js +23 -0
- package/dist/media/image-transformer.js.map +1 -0
- package/dist/media/image-transformer.sharp.d.ts +26 -0
- package/dist/media/image-transformer.sharp.d.ts.map +1 -0
- package/dist/media/image-transformer.sharp.js +91 -0
- package/dist/media/image-transformer.sharp.js.map +1 -0
- package/dist/media/index.d.ts +43 -0
- package/dist/media/index.d.ts.map +1 -0
- package/dist/media/index.js +31 -0
- package/dist/media/index.js.map +1 -0
- package/dist/media/media-service.d.ts +244 -0
- package/dist/media/media-service.d.ts.map +1 -0
- package/dist/media/media-service.js +345 -0
- package/dist/media/media-service.js.map +1 -0
- package/dist/media/ports.d.ts +142 -0
- package/dist/media/ports.d.ts.map +1 -0
- package/dist/media/ports.js +2 -0
- package/dist/media/ports.js.map +1 -0
- package/dist/media/rendition-service.d.ts +66 -0
- package/dist/media/rendition-service.d.ts.map +1 -0
- package/dist/media/rendition-service.js +135 -0
- package/dist/media/rendition-service.js.map +1 -0
- package/dist/media/repo.memory.d.ts +107 -0
- package/dist/media/repo.memory.d.ts.map +1 -0
- package/dist/media/repo.memory.js +131 -0
- package/dist/media/repo.memory.js.map +1 -0
- package/dist/media/tool-registrations.d.ts +42 -0
- package/dist/media/tool-registrations.d.ts.map +1 -0
- package/dist/media/tool-registrations.js +121 -0
- package/dist/media/tool-registrations.js.map +1 -0
- package/dist/media/transform-lock.d.ts +36 -0
- package/dist/media/transform-lock.d.ts.map +1 -0
- package/dist/media/transform-lock.js +50 -0
- package/dist/media/transform-lock.js.map +1 -0
- package/dist/media/transform-registry.d.ts +103 -0
- package/dist/media/transform-registry.d.ts.map +1 -0
- package/dist/media/transform-registry.js +87 -0
- package/dist/media/transform-registry.js.map +1 -0
- package/dist/media/transform-types.d.ts +82 -0
- package/dist/media/transform-types.d.ts.map +1 -0
- package/dist/media/transform-types.js +47 -0
- package/dist/media/transform-types.js.map +1 -0
- package/dist/media/types.d.ts +150 -0
- package/dist/media/types.d.ts.map +1 -0
- package/dist/media/types.js +26 -0
- package/dist/media/types.js.map +1 -0
- package/dist/navigation/agent-tools.d.ts +90 -0
- package/dist/navigation/agent-tools.d.ts.map +1 -0
- package/dist/navigation/agent-tools.js +225 -0
- package/dist/navigation/agent-tools.js.map +1 -0
- package/dist/navigation/contracts.d.ts +98 -0
- package/dist/navigation/contracts.d.ts.map +1 -0
- package/dist/navigation/contracts.js +70 -0
- package/dist/navigation/contracts.js.map +1 -0
- package/dist/navigation/index.d.ts +39 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/index.js +30 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/navigation/menu-service.d.ts +256 -0
- package/dist/navigation/menu-service.d.ts.map +1 -0
- package/dist/navigation/menu-service.js +382 -0
- package/dist/navigation/menu-service.js.map +1 -0
- package/dist/navigation/ports.d.ts +147 -0
- package/dist/navigation/ports.d.ts.map +1 -0
- package/dist/navigation/ports.js +2 -0
- package/dist/navigation/ports.js.map +1 -0
- package/dist/navigation/read-model.d.ts +11 -0
- package/dist/navigation/read-model.d.ts.map +1 -0
- package/dist/navigation/read-model.js +27 -0
- package/dist/navigation/read-model.js.map +1 -0
- package/dist/navigation/reconcile.d.ts +57 -0
- package/dist/navigation/reconcile.d.ts.map +1 -0
- package/dist/navigation/reconcile.js +33 -0
- package/dist/navigation/reconcile.js.map +1 -0
- package/dist/navigation/repo.memory.d.ts +137 -0
- package/dist/navigation/repo.memory.d.ts.map +1 -0
- package/dist/navigation/repo.memory.js +95 -0
- package/dist/navigation/repo.memory.js.map +1 -0
- package/dist/navigation/resolver.d.ts +110 -0
- package/dist/navigation/resolver.d.ts.map +1 -0
- package/dist/navigation/resolver.js +131 -0
- package/dist/navigation/resolver.js.map +1 -0
- package/dist/navigation/tool-registrations.d.ts +43 -0
- package/dist/navigation/tool-registrations.d.ts.map +1 -0
- package/dist/navigation/tool-registrations.js +126 -0
- package/dist/navigation/tool-registrations.js.map +1 -0
- package/dist/navigation/types.d.ts +207 -0
- package/dist/navigation/types.d.ts.map +1 -0
- package/dist/navigation/types.js +14 -0
- package/dist/navigation/types.js.map +1 -0
- package/dist/presentation/index.d.ts +15 -0
- package/dist/presentation/index.d.ts.map +1 -0
- package/dist/presentation/index.js +15 -0
- package/dist/presentation/index.js.map +1 -0
- package/dist/presentation/presentation.d.ts +72 -0
- package/dist/presentation/presentation.d.ts.map +1 -0
- package/dist/presentation/presentation.js +51 -0
- package/dist/presentation/presentation.js.map +1 -0
- package/dist/presentation/repo.memory.d.ts +9 -0
- package/dist/presentation/repo.memory.d.ts.map +1 -0
- package/dist/presentation/repo.memory.js +21 -0
- package/dist/presentation/repo.memory.js.map +1 -0
- package/dist/server/index.d.ts +28 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +28 -0
- package/dist/server/index.js.map +1 -0
- package/dist/settings/agent-tools.d.ts +83 -0
- package/dist/settings/agent-tools.d.ts.map +1 -0
- package/dist/settings/agent-tools.js +200 -0
- package/dist/settings/agent-tools.js.map +1 -0
- package/dist/settings/agent-writable-preferences.d.ts +67 -0
- package/dist/settings/agent-writable-preferences.d.ts.map +1 -0
- package/dist/settings/agent-writable-preferences.js +144 -0
- package/dist/settings/agent-writable-preferences.js.map +1 -0
- package/dist/settings/change-feed.d.ts +74 -0
- package/dist/settings/change-feed.d.ts.map +1 -0
- package/dist/settings/change-feed.js +61 -0
- package/dist/settings/change-feed.js.map +1 -0
- package/dist/settings/definitions-dispatch.d.ts +51 -0
- package/dist/settings/definitions-dispatch.d.ts.map +1 -0
- package/dist/settings/definitions-dispatch.js +86 -0
- package/dist/settings/definitions-dispatch.js.map +1 -0
- package/dist/settings/dictionaries/index.d.ts +45 -0
- package/dist/settings/dictionaries/index.d.ts.map +1 -0
- package/dist/settings/dictionaries/index.js +69 -0
- package/dist/settings/dictionaries/index.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ar.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.ar.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ar.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.ar.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.bn.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.bn.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.bn.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.bn.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.de.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.de.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.de.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.de.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.es.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.es.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.es.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.es.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.fa.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.fa.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.fa.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.fa.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.fr.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.fr.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.fr.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.fr.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.hi.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.hi.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.hi.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.hi.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.hu.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.hu.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.hu.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.hu.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.id.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.id.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.id.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.id.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.it.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.it.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.it.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.it.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ja.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.ja.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ja.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.ja.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ko.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.ko.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ko.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.ko.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.pl.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.pl.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.pl.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.pl.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.pt-BR.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.pt-BR.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.pt-BR.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.pt-BR.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ru.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.ru.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ru.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.ru.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.th.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.th.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.th.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.th.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.tr.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.tr.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.tr.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.tr.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.uk.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.uk.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.uk.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.uk.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ur.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.ur.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.ur.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.ur.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.zh-CN.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.zh-CN.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.zh-CN.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.zh-CN.js.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.zh-TW.d.ts +3 -0
- package/dist/settings/dictionaries/settings-dialog.zh-TW.d.ts.map +1 -0
- package/dist/settings/dictionaries/settings-dialog.zh-TW.js +28 -0
- package/dist/settings/dictionaries/settings-dialog.zh-TW.js.map +1 -0
- package/dist/settings/ensure-definitions.d.ts +88 -0
- package/dist/settings/ensure-definitions.d.ts.map +1 -0
- package/dist/settings/ensure-definitions.js +91 -0
- package/dist/settings/ensure-definitions.js.map +1 -0
- package/dist/settings/errors.d.ts +36 -0
- package/dist/settings/errors.d.ts.map +1 -0
- package/dist/settings/errors.js +40 -0
- package/dist/settings/errors.js.map +1 -0
- package/dist/settings/index.d.ts +37 -0
- package/dist/settings/index.d.ts.map +1 -0
- package/dist/settings/index.js +36 -0
- package/dist/settings/index.js.map +1 -0
- package/dist/settings/ports.d.ts +117 -0
- package/dist/settings/ports.d.ts.map +1 -0
- package/dist/settings/ports.js +2 -0
- package/dist/settings/ports.js.map +1 -0
- package/dist/settings/purge-service.d.ts +53 -0
- package/dist/settings/purge-service.d.ts.map +1 -0
- package/dist/settings/purge-service.js +105 -0
- package/dist/settings/purge-service.js.map +1 -0
- package/dist/settings/repo.memory.d.ts +119 -0
- package/dist/settings/repo.memory.d.ts.map +1 -0
- package/dist/settings/repo.memory.js +199 -0
- package/dist/settings/repo.memory.js.map +1 -0
- package/dist/settings/settings.d.ts +124 -0
- package/dist/settings/settings.d.ts.map +1 -0
- package/dist/settings/settings.js +238 -0
- package/dist/settings/settings.js.map +1 -0
- package/dist/settings/tool-registrations.d.ts +56 -0
- package/dist/settings/tool-registrations.d.ts.map +1 -0
- package/dist/settings/tool-registrations.js +240 -0
- package/dist/settings/tool-registrations.js.map +1 -0
- package/dist/settings/types.d.ts +125 -0
- package/dist/settings/types.d.ts.map +1 -0
- package/dist/settings/types.js +3 -0
- package/dist/settings/types.js.map +1 -0
- package/dist/settings/ui-tab-definitions.d.ts +41 -0
- package/dist/settings/ui-tab-definitions.d.ts.map +1 -0
- package/dist/settings/ui-tab-definitions.js +148 -0
- package/dist/settings/ui-tab-definitions.js.map +1 -0
- package/dist/settings/write-service.d.ts +314 -0
- package/dist/settings/write-service.d.ts.map +1 -0
- package/dist/settings/write-service.js +677 -0
- package/dist/settings/write-service.js.map +1 -0
- package/dist/taxonomy/agent-tools.d.ts +76 -0
- package/dist/taxonomy/agent-tools.d.ts.map +1 -0
- package/dist/taxonomy/agent-tools.js +178 -0
- package/dist/taxonomy/agent-tools.js.map +1 -0
- package/dist/taxonomy/content-lookup.d.ts +45 -0
- package/dist/taxonomy/content-lookup.d.ts.map +1 -0
- package/dist/taxonomy/content-lookup.js +9 -0
- package/dist/taxonomy/content-lookup.js.map +1 -0
- package/dist/taxonomy/index.d.ts +38 -0
- package/dist/taxonomy/index.d.ts.map +1 -0
- package/dist/taxonomy/index.js +38 -0
- package/dist/taxonomy/index.js.map +1 -0
- package/dist/taxonomy/list.d.ts +39 -0
- package/dist/taxonomy/list.d.ts.map +1 -0
- package/dist/taxonomy/list.js +19 -0
- package/dist/taxonomy/list.js.map +1 -0
- package/dist/taxonomy/merge-term.d.ts +94 -0
- package/dist/taxonomy/merge-term.d.ts.map +1 -0
- package/dist/taxonomy/merge-term.js +65 -0
- package/dist/taxonomy/merge-term.js.map +1 -0
- package/dist/taxonomy/repo.memory.d.ts +160 -0
- package/dist/taxonomy/repo.memory.d.ts.map +1 -0
- package/dist/taxonomy/repo.memory.js +171 -0
- package/dist/taxonomy/repo.memory.js.map +1 -0
- package/dist/taxonomy/validation-chain.d.ts +114 -0
- package/dist/taxonomy/validation-chain.d.ts.map +1 -0
- package/dist/taxonomy/validation-chain.js +152 -0
- package/dist/taxonomy/validation-chain.js.map +1 -0
- package/dist/taxonomy/write-service.d.ts +387 -0
- package/dist/taxonomy/write-service.d.ts.map +1 -0
- package/dist/taxonomy/write-service.js +350 -0
- package/dist/taxonomy/write-service.js.map +1 -0
- package/dist/workspace/agent-tools.d.ts +67 -0
- package/dist/workspace/agent-tools.d.ts.map +1 -0
- package/dist/workspace/agent-tools.js +103 -0
- package/dist/workspace/agent-tools.js.map +1 -0
- package/dist/workspace/create.d.ts +116 -0
- package/dist/workspace/create.d.ts.map +1 -0
- package/dist/workspace/create.js +69 -0
- package/dist/workspace/create.js.map +1 -0
- package/dist/workspace/delete.d.ts +50 -0
- package/dist/workspace/delete.d.ts.map +1 -0
- package/dist/workspace/delete.js +24 -0
- package/dist/workspace/delete.js.map +1 -0
- package/dist/workspace/index.d.ts +27 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +27 -0
- package/dist/workspace/index.js.map +1 -0
- package/dist/workspace/repo.memory.d.ts +34 -0
- package/dist/workspace/repo.memory.d.ts.map +1 -0
- package/dist/workspace/repo.memory.js +50 -0
- package/dist/workspace/repo.memory.js.map +1 -0
- package/dist/workspace/tool-registrations.d.ts +38 -0
- package/dist/workspace/tool-registrations.d.ts.map +1 -0
- package/dist/workspace/tool-registrations.js +71 -0
- package/dist/workspace/tool-registrations.js.map +1 -0
- package/dist/workspace/update.d.ts +52 -0
- package/dist/workspace/update.d.ts.map +1 -0
- package/dist/workspace/update.js +41 -0
- package/dist/workspace/update.js.map +1 -0
- package/package.json +149 -0
|
@@ -0,0 +1,677 @@
|
|
|
1
|
+
import { AliasDepthExceededError, DefinitionInvalidError, DefinitionNotFoundError, DefinitionTombstonedError, ForbiddenError, PrincipalNotFoundError, RenameRetypeConflictError, ScopeNotAllowedError, ValueValidationFailedError, } from "./errors.js";
|
|
2
|
+
import { invalidateDefinitionNamespaceCache, resolveDefinitionRaw, validateDefinitionInput, validateValueAgainstSchema, } from "./settings.js";
|
|
3
|
+
import { SCOPE_BIT } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* behavior.spec.md §1.3 / REQ-06 `[internal-invariant]` — the self-vs-other
|
|
6
|
+
* permission derivation. `targetPrincipalId` omitted or equal to the caller
|
|
7
|
+
* -> `settings.user.self.write`; any other principal -> `settings.user.write`.
|
|
8
|
+
* A divergence between this function and any other implementation of the
|
|
9
|
+
* rule is a fail-open authorization bug (Red-Team RT-003) — this is the only
|
|
10
|
+
* place the rule may be encoded.
|
|
11
|
+
*
|
|
12
|
+
* @complexity O(1), pure.
|
|
13
|
+
* @overallScore 100
|
|
14
|
+
*/
|
|
15
|
+
export function deriveRequiredPermission(input) {
|
|
16
|
+
if (input.scope === "global")
|
|
17
|
+
return "settings.global.write";
|
|
18
|
+
if (input.scope === "workspace")
|
|
19
|
+
return "settings.workspace.write";
|
|
20
|
+
const isSelf = input.targetPrincipalId == null || input.targetPrincipalId === input.callerPrincipalId;
|
|
21
|
+
return isSelf ? "settings.user.self.write" : "settings.user.write";
|
|
22
|
+
}
|
|
23
|
+
/** REQ-02/REQ-09 chokepoint write: authorize `settings.definitions.manage` -> validate -> write + revision, one per definition, each its own tx. */
|
|
24
|
+
export async function registerDefinitions(required) {
|
|
25
|
+
const { deps, input } = required;
|
|
26
|
+
const authResult = await deps.authorize({
|
|
27
|
+
principalId: input.callerPrincipalId,
|
|
28
|
+
permission: "settings.definitions.manage",
|
|
29
|
+
workspaceId: input.authWorkspaceId,
|
|
30
|
+
entityType: "setting-definition",
|
|
31
|
+
});
|
|
32
|
+
if (!authResult.allowed) {
|
|
33
|
+
throw new ForbiddenError(`principal '${input.callerPrincipalId}' is not authorized for 'settings.definitions.manage' (${authResult.reason})`);
|
|
34
|
+
}
|
|
35
|
+
const registered = [];
|
|
36
|
+
for (const definitionInput of input.definitions) {
|
|
37
|
+
const validation = validateDefinitionInput(definitionInput);
|
|
38
|
+
if (!validation.valid)
|
|
39
|
+
throw validation.error;
|
|
40
|
+
await deps.repo.transaction(async () => {
|
|
41
|
+
const now = deps.clock.nowIso();
|
|
42
|
+
const settingId = deps.ids.newId();
|
|
43
|
+
await deps.repo.saveDefinition({
|
|
44
|
+
settingId,
|
|
45
|
+
version: 1,
|
|
46
|
+
workspaceId: definitionInput.workspaceId,
|
|
47
|
+
namespace: definitionInput.namespace,
|
|
48
|
+
key: definitionInput.key,
|
|
49
|
+
ownerKind: definitionInput.ownerKind,
|
|
50
|
+
ownerId: definitionInput.ownerId ?? null,
|
|
51
|
+
schema: definitionInput.schema,
|
|
52
|
+
defaultValue: definitionInput.defaultValue,
|
|
53
|
+
scopes: definitionInput.scopes,
|
|
54
|
+
secret: false,
|
|
55
|
+
status: "active",
|
|
56
|
+
aliasOfNamespace: null,
|
|
57
|
+
aliasOfKey: null,
|
|
58
|
+
coercionTag: null,
|
|
59
|
+
createdAt: now,
|
|
60
|
+
updatedAt: now,
|
|
61
|
+
});
|
|
62
|
+
await deps.repo.appendRevision({
|
|
63
|
+
entityKind: "definition",
|
|
64
|
+
settingId,
|
|
65
|
+
scope: null,
|
|
66
|
+
workspaceId: definitionInput.workspaceId,
|
|
67
|
+
principalId: null,
|
|
68
|
+
op: "register",
|
|
69
|
+
beforeJson: null,
|
|
70
|
+
afterJson: null,
|
|
71
|
+
defVersion: 1,
|
|
72
|
+
actor: input.callerPrincipalId,
|
|
73
|
+
originPluginId: null,
|
|
74
|
+
changeSetId: null,
|
|
75
|
+
createdAt: now,
|
|
76
|
+
});
|
|
77
|
+
registered.push(settingId);
|
|
78
|
+
});
|
|
79
|
+
invalidateDefinitionNamespaceCache(deps.repo, definitionInput.namespace);
|
|
80
|
+
}
|
|
81
|
+
return { registered };
|
|
82
|
+
}
|
|
83
|
+
async function resolveScopedDefinitionOrThrow(deps, input) {
|
|
84
|
+
const definitionWorkspaceId = input.scope === "global" ? null : (input.workspaceId ?? null);
|
|
85
|
+
const definition = await resolveDefinitionRaw(deps, {
|
|
86
|
+
namespace: input.namespace,
|
|
87
|
+
key: input.key,
|
|
88
|
+
workspaceId: definitionWorkspaceId,
|
|
89
|
+
});
|
|
90
|
+
if (!definition) {
|
|
91
|
+
throw new DefinitionNotFoundError(`setting '${input.namespace}.${input.key}' was not found`);
|
|
92
|
+
}
|
|
93
|
+
if (definition.status === "tombstone") {
|
|
94
|
+
throw new DefinitionTombstonedError(`setting '${input.namespace}.${input.key}' has been tombstoned`);
|
|
95
|
+
}
|
|
96
|
+
if ((definition.scopes & SCOPE_BIT[input.scope]) === 0) {
|
|
97
|
+
throw new ScopeNotAllowedError(`setting '${input.namespace}.${input.key}' does not allow scope '${input.scope}'`);
|
|
98
|
+
}
|
|
99
|
+
return definition;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Every non-global write must land in the workspace it was AUTHORIZED against.
|
|
103
|
+
*
|
|
104
|
+
* `authorize()` is called with `authWorkspaceId` while the value row and revision are written with
|
|
105
|
+
* `input.workspaceId`. Nothing forces the two to match unless this guard runs — a caller that
|
|
106
|
+
* constructs the input directly (rather than through a route that validates the body against the
|
|
107
|
+
* ambient workspace) could otherwise pass a mismatched target and have the write land in a
|
|
108
|
+
* workspace neither `authorize()` call was actually evaluated against.
|
|
109
|
+
*
|
|
110
|
+
* A host's HTTP routes should reject a mismatched body id at the route layer (the real fix, closer
|
|
111
|
+
* to the request). This is the backstop: it holds for every internal caller that constructs the
|
|
112
|
+
* input directly, and makes a future caller incapable of reintroducing the gap.
|
|
113
|
+
*
|
|
114
|
+
* `ForbiddenError` rather than a validation error because the condition is exactly "you are not
|
|
115
|
+
* authorized to write to that workspace".
|
|
116
|
+
*
|
|
117
|
+
* `scope: "global"` is exempt: the platform partition has no workspace, and `set`/`clear` already
|
|
118
|
+
* force `workspaceId: null` on that path.
|
|
119
|
+
*/
|
|
120
|
+
function assertTargetWorkspaceMatchesAuth(input) {
|
|
121
|
+
if (input.scope === "global")
|
|
122
|
+
return;
|
|
123
|
+
if (input.workspaceId === undefined)
|
|
124
|
+
return;
|
|
125
|
+
if (input.workspaceId === input.authWorkspaceId)
|
|
126
|
+
return;
|
|
127
|
+
throw new ForbiddenError(`principal '${input.callerPrincipalId}' authorized against workspace '${input.authWorkspaceId}' ` +
|
|
128
|
+
`but the write targets workspace '${input.workspaceId}'`);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* REQ-13/INV-09 — for scope=user writes targeting another principal, verify
|
|
132
|
+
* that principal resolves to an active user whose own `workspace_id` equals
|
|
133
|
+
* the request's `workspaceId` (structural scoping — a principal
|
|
134
|
+
* belongs to exactly one workspace, not a membership join).
|
|
135
|
+
*/
|
|
136
|
+
async function assertTargetPrincipalInWorkspace(deps, input) {
|
|
137
|
+
if (input.scope !== "user")
|
|
138
|
+
return;
|
|
139
|
+
if (!input.principalId || input.principalId === input.callerPrincipalId)
|
|
140
|
+
return;
|
|
141
|
+
if (!input.workspaceId)
|
|
142
|
+
return;
|
|
143
|
+
const principal = await deps.principals.findById({ workspaceId: input.workspaceId, id: input.principalId });
|
|
144
|
+
if (!principal || principal.status === "disabled") {
|
|
145
|
+
throw new PrincipalNotFoundError(`principal '${input.principalId}' was not found in workspace '${input.workspaceId}'`, input.principalId, input.workspaceId);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/** REQ-04/REQ-13 chokepoint write: authorize -> validate -> value + revision, same tx. */
|
|
149
|
+
export async function set(required) {
|
|
150
|
+
const { deps, input } = required;
|
|
151
|
+
const permission = input.requiredPermissionOverride ??
|
|
152
|
+
deriveRequiredPermission({
|
|
153
|
+
scope: input.scope,
|
|
154
|
+
targetPrincipalId: input.principalId,
|
|
155
|
+
callerPrincipalId: input.callerPrincipalId,
|
|
156
|
+
});
|
|
157
|
+
const authWorkspaceId = input.authWorkspaceId ?? input.workspaceId ?? input.callerPrincipalId;
|
|
158
|
+
assertTargetWorkspaceMatchesAuth({ ...input, authWorkspaceId });
|
|
159
|
+
const authResult = await deps.authorize({
|
|
160
|
+
principalId: input.callerPrincipalId,
|
|
161
|
+
permission,
|
|
162
|
+
workspaceId: authWorkspaceId,
|
|
163
|
+
entityType: "setting-value",
|
|
164
|
+
});
|
|
165
|
+
if (!authResult.allowed) {
|
|
166
|
+
throw new ForbiddenError(`principal '${input.callerPrincipalId}' is not authorized for '${permission}' (${authResult.reason})`);
|
|
167
|
+
}
|
|
168
|
+
const definition = await resolveScopedDefinitionOrThrow(deps, input);
|
|
169
|
+
if (!validateValueAgainstSchema(definition.schema, input.value)) {
|
|
170
|
+
throw new ValueValidationFailedError(`value for '${input.namespace}.${input.key}' does not match the definition schema`);
|
|
171
|
+
}
|
|
172
|
+
await assertTargetPrincipalInWorkspace(deps, input);
|
|
173
|
+
const result = await deps.repo.transaction(async () => {
|
|
174
|
+
const now = deps.clock.nowIso();
|
|
175
|
+
const revisionSeq = await deps.repo.appendRevision({
|
|
176
|
+
entityKind: "value",
|
|
177
|
+
settingId: definition.settingId,
|
|
178
|
+
scope: input.scope,
|
|
179
|
+
workspaceId: input.scope === "global" ? null : (input.workspaceId ?? null),
|
|
180
|
+
principalId: input.scope === "user" ? (input.principalId ?? input.callerPrincipalId) : null,
|
|
181
|
+
op: "set",
|
|
182
|
+
beforeJson: null,
|
|
183
|
+
afterJson: input.value,
|
|
184
|
+
defVersion: definition.version,
|
|
185
|
+
actor: input.callerPrincipalId,
|
|
186
|
+
originPluginId: null,
|
|
187
|
+
changeSetId: null,
|
|
188
|
+
createdAt: now,
|
|
189
|
+
});
|
|
190
|
+
const base = {
|
|
191
|
+
settingId: definition.settingId,
|
|
192
|
+
scope: input.scope,
|
|
193
|
+
valueJson: input.value,
|
|
194
|
+
state: "set",
|
|
195
|
+
defVersion: definition.version,
|
|
196
|
+
seq: revisionSeq,
|
|
197
|
+
updatedBy: input.callerPrincipalId,
|
|
198
|
+
updatedAt: now,
|
|
199
|
+
originPluginId: null,
|
|
200
|
+
};
|
|
201
|
+
if (input.scope === "global") {
|
|
202
|
+
await deps.repo.saveGlobalValue({ ...base, workspaceId: null, principalId: null });
|
|
203
|
+
}
|
|
204
|
+
else if (input.scope === "workspace") {
|
|
205
|
+
await deps.repo.saveWorkspaceValue({
|
|
206
|
+
...base,
|
|
207
|
+
workspaceId: input.workspaceId ?? null,
|
|
208
|
+
principalId: null,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
await deps.repo.saveUserValue({
|
|
213
|
+
...base,
|
|
214
|
+
workspaceId: input.workspaceId ?? null,
|
|
215
|
+
principalId: input.principalId ?? input.callerPrincipalId,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return { value: input.value, revisionSeq };
|
|
219
|
+
});
|
|
220
|
+
return result;
|
|
221
|
+
}
|
|
222
|
+
/** REQ-04/REQ-13 chokepoint write: authorize -> value + revision (state='cleared'), same tx. */
|
|
223
|
+
export async function clear(required) {
|
|
224
|
+
const { deps, input } = required;
|
|
225
|
+
if (!input.skipAuthorize) {
|
|
226
|
+
const permission = deriveRequiredPermission({
|
|
227
|
+
scope: input.scope,
|
|
228
|
+
targetPrincipalId: input.principalId,
|
|
229
|
+
callerPrincipalId: input.callerPrincipalId,
|
|
230
|
+
});
|
|
231
|
+
const authWorkspaceId = input.authWorkspaceId ?? input.workspaceId ?? input.callerPrincipalId;
|
|
232
|
+
assertTargetWorkspaceMatchesAuth({ ...input, authWorkspaceId });
|
|
233
|
+
const authResult = await deps.authorize({
|
|
234
|
+
principalId: input.callerPrincipalId,
|
|
235
|
+
permission,
|
|
236
|
+
workspaceId: authWorkspaceId,
|
|
237
|
+
entityType: "setting-value",
|
|
238
|
+
});
|
|
239
|
+
if (!authResult.allowed) {
|
|
240
|
+
throw new ForbiddenError(`principal '${input.callerPrincipalId}' is not authorized for '${permission}' (${authResult.reason})`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
const definition = await resolveScopedDefinitionOrThrow(deps, input);
|
|
244
|
+
await assertTargetPrincipalInWorkspace(deps, input);
|
|
245
|
+
const runClear = async () => {
|
|
246
|
+
const now = deps.clock.nowIso();
|
|
247
|
+
const revisionSeq = await deps.repo.appendRevision({
|
|
248
|
+
entityKind: "value",
|
|
249
|
+
settingId: definition.settingId,
|
|
250
|
+
scope: input.scope,
|
|
251
|
+
workspaceId: input.scope === "global" ? null : (input.workspaceId ?? null),
|
|
252
|
+
principalId: input.scope === "user" ? (input.principalId ?? input.callerPrincipalId) : null,
|
|
253
|
+
op: "clear",
|
|
254
|
+
beforeJson: null,
|
|
255
|
+
afterJson: null,
|
|
256
|
+
defVersion: definition.version,
|
|
257
|
+
actor: input.callerPrincipalId,
|
|
258
|
+
originPluginId: null,
|
|
259
|
+
changeSetId: null,
|
|
260
|
+
createdAt: now,
|
|
261
|
+
});
|
|
262
|
+
const base = {
|
|
263
|
+
settingId: definition.settingId,
|
|
264
|
+
scope: input.scope,
|
|
265
|
+
valueJson: null,
|
|
266
|
+
state: "cleared",
|
|
267
|
+
defVersion: definition.version,
|
|
268
|
+
seq: revisionSeq,
|
|
269
|
+
updatedBy: input.callerPrincipalId,
|
|
270
|
+
updatedAt: now,
|
|
271
|
+
originPluginId: null,
|
|
272
|
+
};
|
|
273
|
+
if (input.scope === "global") {
|
|
274
|
+
await deps.repo.saveGlobalValue({ ...base, workspaceId: null, principalId: null });
|
|
275
|
+
}
|
|
276
|
+
else if (input.scope === "workspace") {
|
|
277
|
+
await deps.repo.saveWorkspaceValue({
|
|
278
|
+
...base,
|
|
279
|
+
workspaceId: input.workspaceId ?? null,
|
|
280
|
+
principalId: null,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
await deps.repo.saveUserValue({
|
|
285
|
+
...base,
|
|
286
|
+
workspaceId: input.workspaceId ?? null,
|
|
287
|
+
principalId: input.principalId ?? input.callerPrincipalId,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
return { revisionSeq };
|
|
291
|
+
};
|
|
292
|
+
// `skipTransaction` means an enclosing caller already owns the boundary, so
|
|
293
|
+
// this write joins it and a later failure rolls this one back too.
|
|
294
|
+
const result = input.skipTransaction ? await runClear() : await deps.repo.transaction(runClear);
|
|
295
|
+
return result;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* EC-09/R3-01 — an explicit, human-invoked orchestrator: authorize
|
|
299
|
+
* the matching `settings.reset.*` permission once, then loop `clear()` for
|
|
300
|
+
* every setting in the namespace in the reset-authorized internal context
|
|
301
|
+
* (`skipAuthorize: true`) — the outer reset permission is sufficient on its
|
|
302
|
+
* own; each inner clear still emits its own `op='clear'` revision.
|
|
303
|
+
*
|
|
304
|
+
* `revisionSeqs` collects each inner `clear()` call's own `revisionSeq` so a
|
|
305
|
+
* host's admin HTTP route can surface the full contract without a second
|
|
306
|
+
* read. Existing callers that only read `.clearedCount` are unaffected.
|
|
307
|
+
*/
|
|
308
|
+
export async function resetNamespace(required, keysInNamespace) {
|
|
309
|
+
const { deps, input } = required;
|
|
310
|
+
const resetPermission = `settings.reset.${input.scope}`;
|
|
311
|
+
const authWorkspaceId = input.authWorkspaceId ?? input.workspaceId ?? input.callerPrincipalId;
|
|
312
|
+
// Asserted once here rather than per inner `clear()`: those run with `skipAuthorize: true`, which
|
|
313
|
+
// short-circuits the same check inside `clear()`. This is the only gate for the whole loop.
|
|
314
|
+
assertTargetWorkspaceMatchesAuth({ ...input, authWorkspaceId });
|
|
315
|
+
const authResult = await deps.authorize({
|
|
316
|
+
principalId: input.callerPrincipalId,
|
|
317
|
+
permission: resetPermission,
|
|
318
|
+
workspaceId: authWorkspaceId,
|
|
319
|
+
entityType: "setting-namespace",
|
|
320
|
+
});
|
|
321
|
+
if (!authResult.allowed) {
|
|
322
|
+
throw new ForbiddenError(`principal '${input.callerPrincipalId}' is not authorized for '${resetPermission}' (${authResult.reason})`);
|
|
323
|
+
}
|
|
324
|
+
// One transaction around the whole loop, so a reset is all-or-nothing.
|
|
325
|
+
//
|
|
326
|
+
// Each `clear()` opens its own transaction and commits on its own, so a
|
|
327
|
+
// failure partway through used to leave the namespace HALF reset — some keys
|
|
328
|
+
// durably cleared, the rest untouched — while the caller received an error and
|
|
329
|
+
// could reasonably assume nothing had happened. "Reset this namespace" is not
|
|
330
|
+
// a meaningful operation if it can apply to an arbitrary prefix of the keys.
|
|
331
|
+
//
|
|
332
|
+
// This works because each inner `clear()` is passed `skipTransaction: true`
|
|
333
|
+
// and so writes into THIS frame instead of opening its own. That is explicit
|
|
334
|
+
// at the call site by design: an earlier version made `transaction` reentrant
|
|
335
|
+
// via an instance-level depth counter, which could not tell a genuine nested
|
|
336
|
+
// call from an unrelated concurrent one and silently merged the two.
|
|
337
|
+
//
|
|
338
|
+
// Both adapters honour the rollback: a SQLite adapter via ROLLBACK, and
|
|
339
|
+
// `repo.memory.ts` via a snapshot/restore journal.
|
|
340
|
+
return deps.repo.transaction(async () => {
|
|
341
|
+
let clearedCount = 0;
|
|
342
|
+
const revisionSeqs = [];
|
|
343
|
+
for (const key of keysInNamespace) {
|
|
344
|
+
const result = await clear({
|
|
345
|
+
deps,
|
|
346
|
+
input: {
|
|
347
|
+
namespace: input.namespace,
|
|
348
|
+
key,
|
|
349
|
+
scope: input.scope,
|
|
350
|
+
workspaceId: input.workspaceId,
|
|
351
|
+
principalId: input.principalId,
|
|
352
|
+
callerPrincipalId: input.callerPrincipalId,
|
|
353
|
+
skipAuthorize: true,
|
|
354
|
+
skipTransaction: true,
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
revisionSeqs.push(result.revisionSeq);
|
|
358
|
+
clearedCount++;
|
|
359
|
+
}
|
|
360
|
+
return { clearedCount, revisionSeqs };
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* The single authorization gate shared by every definition-
|
|
365
|
+
* lifecycle op (rename/retype/deprecate/tombstone), matching
|
|
366
|
+
* `registerDefinitions`'s own `settings.definitions.manage` check (same
|
|
367
|
+
* permission also gates `purge`/`coerce` per §7 — high privilege, human-only).
|
|
368
|
+
*/
|
|
369
|
+
async function authorizeDefinitionsManage(deps, callerPrincipalId, authWorkspaceId) {
|
|
370
|
+
const authResult = await deps.authorize({
|
|
371
|
+
principalId: callerPrincipalId,
|
|
372
|
+
permission: "settings.definitions.manage",
|
|
373
|
+
workspaceId: authWorkspaceId,
|
|
374
|
+
entityType: "setting-definition",
|
|
375
|
+
});
|
|
376
|
+
if (!authResult.allowed) {
|
|
377
|
+
throw new ForbiddenError(`principal '${callerPrincipalId}' is not authorized for 'settings.definitions.manage' (${authResult.reason})`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
/** Resolves the canonical active definition at (namespace,key,workspaceId), rejecting anything but `status='active'`. */
|
|
381
|
+
async function resolveActiveDefinitionOrThrow(deps, input, verb) {
|
|
382
|
+
const current = await deps.repo.findActiveDefinition(input);
|
|
383
|
+
if (!current) {
|
|
384
|
+
throw new DefinitionNotFoundError(`setting '${input.namespace}.${input.key}' was not found`);
|
|
385
|
+
}
|
|
386
|
+
if (current.status === "tombstone") {
|
|
387
|
+
throw new DefinitionTombstonedError(`setting '${input.namespace}.${input.key}' has been tombstoned`);
|
|
388
|
+
}
|
|
389
|
+
if (current.status === "alias") {
|
|
390
|
+
throw new DefinitionInvalidError(`cannot ${verb} '${input.namespace}.${input.key}': it is an alias marker, not the canonical active definition`);
|
|
391
|
+
}
|
|
392
|
+
return current;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* The rename mechanism (AC-09, EC-06): a same-tx pair —
|
|
396
|
+
* (1) UPDATE the active definition row's `(namespace,key)` to the new name,
|
|
397
|
+
* same `setting_id`/`version` (ledgered `op='alias'`); (2) INSERT a fresh v1
|
|
398
|
+
* alias marker at the OLD name pointing at the new name. Because identity
|
|
399
|
+
* never moves, value rows (keyed on `setting_id` only) stay attached.
|
|
400
|
+
*
|
|
401
|
+
* Sequential rename (A->B then B->C) retargets every prior marker pointing
|
|
402
|
+
* at the OLD name to the NEW name in the same tx. A rename target that
|
|
403
|
+
* itself resolves to an existing alias is rejected `ALIAS_DEPTH_EXCEEDED`
|
|
404
|
+
* (behavior.spec.md §7: "the rename target resolves to an alias").
|
|
405
|
+
*
|
|
406
|
+
* Never touches `schema`/`defaultValue`/`scopes` -- a pure rename can never
|
|
407
|
+
* trigger `RENAME_RETYPE_CONFLICT` by construction; that guard lives in
|
|
408
|
+
* `retypeDefinition` ("no rename+retype in one op").
|
|
409
|
+
*/
|
|
410
|
+
export async function renameDefinition(required) {
|
|
411
|
+
const { deps, input } = required;
|
|
412
|
+
await authorizeDefinitionsManage(deps, input.callerPrincipalId, input.authWorkspaceId);
|
|
413
|
+
const current = await resolveActiveDefinitionOrThrow(deps, input, "rename");
|
|
414
|
+
if (input.namespace === input.newNamespace && input.key === input.newKey) {
|
|
415
|
+
throw new DefinitionInvalidError("rename requires newNamespace/newKey to differ from the current name");
|
|
416
|
+
}
|
|
417
|
+
const destination = await deps.repo.findActiveDefinition({
|
|
418
|
+
namespace: input.newNamespace,
|
|
419
|
+
key: input.newKey,
|
|
420
|
+
workspaceId: input.workspaceId,
|
|
421
|
+
});
|
|
422
|
+
if (destination) {
|
|
423
|
+
if (destination.status === "alias") {
|
|
424
|
+
throw new AliasDepthExceededError(`rename target '${input.newNamespace}.${input.newKey}' resolves to an existing alias marker; a marker's alias_of must point to an active definition (depth <=1)`);
|
|
425
|
+
}
|
|
426
|
+
throw new DefinitionInvalidError(`rename target '${input.newNamespace}.${input.newKey}' is already in use`);
|
|
427
|
+
}
|
|
428
|
+
const result = await deps.repo.transaction(async () => {
|
|
429
|
+
const now = deps.clock.nowIso();
|
|
430
|
+
// Step 1: move the active row to the new name -- same setting_id, same version.
|
|
431
|
+
await deps.repo.saveDefinition({ ...current, namespace: input.newNamespace, key: input.newKey, updatedAt: now });
|
|
432
|
+
// Sequential rename: retarget every prior marker pointing at the OLD name to the NEW name.
|
|
433
|
+
const siblings = await deps.repo.listActiveDefinitions({ workspaceId: input.workspaceId });
|
|
434
|
+
for (const sibling of siblings) {
|
|
435
|
+
if (sibling.status === "alias" &&
|
|
436
|
+
sibling.aliasOfNamespace === input.namespace &&
|
|
437
|
+
sibling.aliasOfKey === input.key) {
|
|
438
|
+
await deps.repo.saveDefinition({
|
|
439
|
+
...sibling,
|
|
440
|
+
aliasOfNamespace: input.newNamespace,
|
|
441
|
+
aliasOfKey: input.newKey,
|
|
442
|
+
updatedAt: now,
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
// Step 2: insert a fresh v1 alias marker at the OLD name pointing at the NEW name.
|
|
447
|
+
const markerSettingId = deps.ids.newId();
|
|
448
|
+
await deps.repo.saveDefinition({
|
|
449
|
+
settingId: markerSettingId,
|
|
450
|
+
version: 1,
|
|
451
|
+
workspaceId: input.workspaceId,
|
|
452
|
+
namespace: input.namespace,
|
|
453
|
+
key: input.key,
|
|
454
|
+
ownerKind: current.ownerKind,
|
|
455
|
+
ownerId: current.ownerId,
|
|
456
|
+
schema: current.schema,
|
|
457
|
+
defaultValue: current.defaultValue,
|
|
458
|
+
scopes: current.scopes,
|
|
459
|
+
secret: current.secret,
|
|
460
|
+
status: "alias",
|
|
461
|
+
aliasOfNamespace: input.newNamespace,
|
|
462
|
+
aliasOfKey: input.newKey,
|
|
463
|
+
coercionTag: null,
|
|
464
|
+
createdAt: now,
|
|
465
|
+
updatedAt: now,
|
|
466
|
+
});
|
|
467
|
+
await deps.repo.appendRevision({
|
|
468
|
+
entityKind: "definition",
|
|
469
|
+
settingId: current.settingId,
|
|
470
|
+
scope: null,
|
|
471
|
+
workspaceId: input.workspaceId,
|
|
472
|
+
principalId: null,
|
|
473
|
+
op: "alias",
|
|
474
|
+
beforeJson: null,
|
|
475
|
+
afterJson: null,
|
|
476
|
+
defVersion: current.version,
|
|
477
|
+
actor: input.callerPrincipalId,
|
|
478
|
+
originPluginId: null,
|
|
479
|
+
changeSetId: null,
|
|
480
|
+
createdAt: now,
|
|
481
|
+
});
|
|
482
|
+
return { settingId: current.settingId, markerSettingId };
|
|
483
|
+
});
|
|
484
|
+
// Both the old (alias-marker) namespace and the new (active-row) namespace
|
|
485
|
+
// need a fresh definition-cache read after a rename.
|
|
486
|
+
invalidateDefinitionNamespaceCache(deps.repo, input.namespace);
|
|
487
|
+
invalidateDefinitionNamespaceCache(deps.repo, input.newNamespace);
|
|
488
|
+
return result;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* The retype mechanism (AC-10, EC-05): a same-tx pair --
|
|
492
|
+
* (1) UPDATE the prior active version's `status` to `deprecated` FIRST (else
|
|
493
|
+
* the insert in step 2 collides with the one-active-row-per-slot
|
|
494
|
+
* invariant); (2) INSERT the new `version+1` row as `active`, same
|
|
495
|
+
* `setting_id`/`namespace`/`key`. Rejected unless every prior version
|
|
496
|
+
* (2..N) already carries a total coercer -- `coercionTag` is `null` only for
|
|
497
|
+
* version 1 by construction (`types.ts`), so this walks 2..N and requires
|
|
498
|
+
* each to be non-null.
|
|
499
|
+
*/
|
|
500
|
+
export async function retypeDefinition(required) {
|
|
501
|
+
const { deps, input } = required;
|
|
502
|
+
await authorizeDefinitionsManage(deps, input.callerPrincipalId, input.authWorkspaceId);
|
|
503
|
+
const current = await resolveActiveDefinitionOrThrow(deps, input, "retype");
|
|
504
|
+
const namespaceOrKeyChanged = (input.newNamespace !== undefined && input.newNamespace !== current.namespace) ||
|
|
505
|
+
(input.newKey !== undefined && input.newKey !== current.key);
|
|
506
|
+
const schemaChanged = JSON.stringify(input.schema) !== JSON.stringify(current.schema);
|
|
507
|
+
if (namespaceOrKeyChanged && schemaChanged) {
|
|
508
|
+
throw new RenameRetypeConflictError(`cannot rename and retype '${input.namespace}.${input.key}' in the same operation; submit the rename and the retype as two separate chokepoint calls`);
|
|
509
|
+
}
|
|
510
|
+
for (let version = 2; version <= current.version; version++) {
|
|
511
|
+
const priorVersion = await deps.repo.findDefinitionBySettingId({ settingId: current.settingId, version });
|
|
512
|
+
if (!priorVersion || priorVersion.coercionTag == null) {
|
|
513
|
+
throw new DefinitionInvalidError(`retype of '${input.namespace}.${input.key}' rejected: version ${version} does not carry a total coercer`);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
const result = await deps.repo.transaction(async () => {
|
|
517
|
+
const now = deps.clock.nowIso();
|
|
518
|
+
const newVersion = current.version + 1;
|
|
519
|
+
// Step 1: deprecate the prior active version first.
|
|
520
|
+
await deps.repo.saveDefinition({ ...current, status: "deprecated", updatedAt: now });
|
|
521
|
+
// Step 2: insert the new version as active -- same setting_id/namespace/key.
|
|
522
|
+
await deps.repo.saveDefinition({
|
|
523
|
+
settingId: current.settingId,
|
|
524
|
+
version: newVersion,
|
|
525
|
+
workspaceId: current.workspaceId,
|
|
526
|
+
namespace: current.namespace,
|
|
527
|
+
key: current.key,
|
|
528
|
+
ownerKind: current.ownerKind,
|
|
529
|
+
ownerId: current.ownerId,
|
|
530
|
+
schema: input.schema,
|
|
531
|
+
defaultValue: input.defaultValue,
|
|
532
|
+
scopes: current.scopes,
|
|
533
|
+
secret: current.secret,
|
|
534
|
+
status: "active",
|
|
535
|
+
aliasOfNamespace: null,
|
|
536
|
+
aliasOfKey: null,
|
|
537
|
+
coercionTag: input.coercionTag,
|
|
538
|
+
createdAt: now,
|
|
539
|
+
updatedAt: now,
|
|
540
|
+
});
|
|
541
|
+
await deps.repo.appendRevision({
|
|
542
|
+
entityKind: "definition",
|
|
543
|
+
settingId: current.settingId,
|
|
544
|
+
scope: null,
|
|
545
|
+
workspaceId: current.workspaceId,
|
|
546
|
+
principalId: null,
|
|
547
|
+
op: "retype",
|
|
548
|
+
beforeJson: null,
|
|
549
|
+
afterJson: null,
|
|
550
|
+
defVersion: newVersion,
|
|
551
|
+
actor: input.callerPrincipalId,
|
|
552
|
+
originPluginId: null,
|
|
553
|
+
changeSetId: null,
|
|
554
|
+
createdAt: now,
|
|
555
|
+
});
|
|
556
|
+
return { settingId: current.settingId, version: newVersion };
|
|
557
|
+
});
|
|
558
|
+
invalidateDefinitionNamespaceCache(deps.repo, input.namespace);
|
|
559
|
+
return result;
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Reconciles a stored `default_json` that has drifted from the default its
|
|
563
|
+
* source declares. Idempotent and a no-op when they already agree.
|
|
564
|
+
*
|
|
565
|
+
* Why this exists — the bug it closes:
|
|
566
|
+
* `ensure-definitions.ts` registers each definition once and then skips it
|
|
567
|
+
* forever (`if (existing) continue;`). That makes a changed `defaultValue` in
|
|
568
|
+
* SOURCE unreachable in any install that has already booted, for every
|
|
569
|
+
* settings-dialog tab a host registers this way. It can surface as a stored
|
|
570
|
+
* default staying "system" in the database while source says "light",
|
|
571
|
+
* rendering a settings panel with the wrong initial state — a visibly wrong
|
|
572
|
+
* value produced by entirely correct-looking source. The next occurrence
|
|
573
|
+
* could be a silently wrong default with no visual tell at all.
|
|
574
|
+
*
|
|
575
|
+
* Why `core`-only:
|
|
576
|
+
* `ownerKind` already encodes who owns a definition. `core` definitions
|
|
577
|
+
* configure a platform capability and are code-owned, so code is the authority
|
|
578
|
+
* on their default and may overwrite a drifted stored one. `site` and `theme`
|
|
579
|
+
* definitions are operator-owned — silently overwriting those would destroy a
|
|
580
|
+
* deliberate choice, so they are rejected rather than reconciled.
|
|
581
|
+
*
|
|
582
|
+
* Why this is NOT a `retype`:
|
|
583
|
+
* `retype` deprecates the active row and inserts `version+1` because a changed
|
|
584
|
+
* SCHEMA means every stored value needs a total coercer. A changed DEFAULT
|
|
585
|
+
* needs none — the schema is untouched, so every stored value stays valid and
|
|
586
|
+
* only the resolution of UNSET values moves. The row is therefore updated in
|
|
587
|
+
* place at the same version, and the paired revision carries the old and new
|
|
588
|
+
* default in `beforeJson`/`afterJson` so the change is auditable.
|
|
589
|
+
*
|
|
590
|
+
* @complexity O(1) — one definition lookup plus at most one row update and one
|
|
591
|
+
* revision append, in a single transaction.
|
|
592
|
+
*/
|
|
593
|
+
export async function reconcileDefinitionDefault(required) {
|
|
594
|
+
const { deps, input } = required;
|
|
595
|
+
await authorizeDefinitionsManage(deps, input.callerPrincipalId, input.authWorkspaceId);
|
|
596
|
+
const current = await resolveActiveDefinitionOrThrow(deps, input, "reconcile the default of");
|
|
597
|
+
if (current.ownerKind !== "core") {
|
|
598
|
+
throw new DefinitionInvalidError(`cannot reconcile the default of '${input.namespace}.${input.key}': only 'core' definitions are code-owned, and this one is '${current.ownerKind}' (operator-owned)`);
|
|
599
|
+
}
|
|
600
|
+
// Structural compare — `defaultValue` is a `JsonValue`, so `===` would miss a
|
|
601
|
+
// changed object/array default.
|
|
602
|
+
if (JSON.stringify(current.defaultValue) === JSON.stringify(input.defaultValue)) {
|
|
603
|
+
return { settingId: current.settingId, changed: false };
|
|
604
|
+
}
|
|
605
|
+
if (!validateValueAgainstSchema(current.schema, input.defaultValue)) {
|
|
606
|
+
throw new ValueValidationFailedError(`cannot reconcile the default of '${input.namespace}.${input.key}': the source default does not satisfy the definition's own schema (type '${current.schema.type}')`);
|
|
607
|
+
}
|
|
608
|
+
await deps.repo.transaction(async () => {
|
|
609
|
+
const now = deps.clock.nowIso();
|
|
610
|
+
await deps.repo.saveDefinition({ ...current, defaultValue: input.defaultValue, updatedAt: now });
|
|
611
|
+
await deps.repo.appendRevision({
|
|
612
|
+
entityKind: "definition",
|
|
613
|
+
settingId: current.settingId,
|
|
614
|
+
scope: null,
|
|
615
|
+
workspaceId: current.workspaceId,
|
|
616
|
+
principalId: null,
|
|
617
|
+
op: "redefault",
|
|
618
|
+
beforeJson: current.defaultValue,
|
|
619
|
+
afterJson: input.defaultValue,
|
|
620
|
+
// Unchanged, deliberately — see the retype contrast above.
|
|
621
|
+
defVersion: current.version,
|
|
622
|
+
actor: input.callerPrincipalId,
|
|
623
|
+
originPluginId: null,
|
|
624
|
+
changeSetId: null,
|
|
625
|
+
createdAt: now,
|
|
626
|
+
});
|
|
627
|
+
});
|
|
628
|
+
invalidateDefinitionNamespaceCache(deps.repo, input.namespace);
|
|
629
|
+
return { settingId: current.settingId, changed: true };
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* `deprecateDefinition`/`tombstoneDefinition` were a jaccard-1.0
|
|
633
|
+
* duplicate pair (same authorize -> resolve -> same-tx status flip + revision
|
|
634
|
+
* shape, differing only in the target status string). This is that shape,
|
|
635
|
+
* written once; both thin exports below just name their target status.
|
|
636
|
+
*/
|
|
637
|
+
async function transitionDefinitionStatus(deps, input, target) {
|
|
638
|
+
await authorizeDefinitionsManage(deps, input.callerPrincipalId, input.authWorkspaceId);
|
|
639
|
+
const current = await resolveActiveDefinitionOrThrow(deps, input, target.revisionOp);
|
|
640
|
+
const result = await deps.repo.transaction(async () => {
|
|
641
|
+
const now = deps.clock.nowIso();
|
|
642
|
+
await deps.repo.saveDefinition({ ...current, status: target.status, updatedAt: now });
|
|
643
|
+
await deps.repo.appendRevision({
|
|
644
|
+
entityKind: "definition",
|
|
645
|
+
settingId: current.settingId,
|
|
646
|
+
scope: null,
|
|
647
|
+
workspaceId: current.workspaceId,
|
|
648
|
+
principalId: null,
|
|
649
|
+
op: target.revisionOp,
|
|
650
|
+
beforeJson: null,
|
|
651
|
+
afterJson: null,
|
|
652
|
+
defVersion: current.version,
|
|
653
|
+
actor: input.callerPrincipalId,
|
|
654
|
+
originPluginId: null,
|
|
655
|
+
changeSetId: null,
|
|
656
|
+
createdAt: now,
|
|
657
|
+
});
|
|
658
|
+
return { settingId: current.settingId, version: current.version };
|
|
659
|
+
});
|
|
660
|
+
invalidateDefinitionNamespaceCache(deps.repo, input.namespace);
|
|
661
|
+
return result;
|
|
662
|
+
}
|
|
663
|
+
/** Flips the active definition's status to `deprecated`, ledgered `op='deprecate'` -- same-tx, chokepoint-gated. */
|
|
664
|
+
export async function deprecateDefinition(required) {
|
|
665
|
+
return transitionDefinitionStatus(required.deps, required.input, {
|
|
666
|
+
status: "deprecated",
|
|
667
|
+
revisionOp: "deprecate",
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
/** Flips the active definition's status to `tombstone` (kills a core key), ledgered `op='tombstone'` -- same-tx, chokepoint-gated. */
|
|
671
|
+
export async function tombstoneDefinition(required) {
|
|
672
|
+
return transitionDefinitionStatus(required.deps, required.input, {
|
|
673
|
+
status: "tombstone",
|
|
674
|
+
revisionOp: "tombstone",
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
//# sourceMappingURL=write-service.js.map
|