@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,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Media's tool-registration wiring: maps `agent-tools.ts`'s four catalog entries onto
|
|
3
|
+
* `media-service.ts`'s list/upload/update/trash operations, as `ToolRegistration`s. The entire
|
|
4
|
+
* catalog is wired — `purgeMedia` is deliberately absent from the catalog rather than
|
|
5
|
+
* present-but-unwired; see `media/agent-tools.ts`'s own header.
|
|
6
|
+
*
|
|
7
|
+
* Authorization shape: unlike Forms/Identity/Widgets, `media-service.ts`'s functions perform NO
|
|
8
|
+
* internal `authorize()` call of their own — every admin HTTP route a host builds gates inline
|
|
9
|
+
* instead. Every handler here does the same via the kit's `requireToolPermission`, which is the
|
|
10
|
+
* single evaluation for these tools, located where a real route would locate it.
|
|
11
|
+
*/
|
|
12
|
+
import type { AuthorizeFn } from "../core/commands/command.js";
|
|
13
|
+
import { type DerivedRiskByToolId, type ToolRegistration } from "../core/tools/registration-kit.js";
|
|
14
|
+
import type { AssetBlobRepoPort, AssetRenditionRepoPort, BlobStorePort, MediaRepoPort } from "./ports.js";
|
|
15
|
+
/**
|
|
16
|
+
* The exact slice of a host's route-deps bag Media's tool handlers read. Declared structurally
|
|
17
|
+
* (rather than importing any host's own route-deps type) so this module carries no back-edge into
|
|
18
|
+
* a host's composition root. A host satisfies this structurally by passing its existing route deps
|
|
19
|
+
* object; nothing there needs to change shape.
|
|
20
|
+
*/
|
|
21
|
+
export interface MediaToolDeps {
|
|
22
|
+
authorize: AuthorizeFn;
|
|
23
|
+
workspaceId: string;
|
|
24
|
+
clock: {
|
|
25
|
+
nowIso(): string;
|
|
26
|
+
};
|
|
27
|
+
idGen: {
|
|
28
|
+
newId(): string;
|
|
29
|
+
};
|
|
30
|
+
mediaRepo: MediaRepoPort;
|
|
31
|
+
assetBlobRepo: AssetBlobRepoPort;
|
|
32
|
+
assetRenditionRepo: AssetRenditionRepoPort;
|
|
33
|
+
blobStore: BlobStorePort;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* This wiring layer's OWN risk classification, authored from what each handler below actually
|
|
37
|
+
* calls. See `DerivedRiskByToolId` in the kit for why it is independent of the catalog's own
|
|
38
|
+
* `sideEffects` declaration.
|
|
39
|
+
*/
|
|
40
|
+
export declare const mediaDerivedRisk: DerivedRiskByToolId;
|
|
41
|
+
export declare function buildMediaRegistrations(routeDeps: MediaToolDeps): ToolRegistration[];
|
|
42
|
+
//# sourceMappingURL=tool-registrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-registrations.d.ts","sourceRoot":"","sources":["../../src/media/tool-registrations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAQL,KAAK,mBAAmB,EAExB,KAAK,gBAAgB,EACtB,MAAM,mCAAmC,CAAC;AAG3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAK1G;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,WAAW,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE;QAAE,MAAM,IAAI,MAAM,CAAA;KAAE,CAAC;IAC5B,KAAK,EAAE;QAAE,KAAK,IAAI,MAAM,CAAA;KAAE,CAAC;IAC3B,SAAS,EAAE,aAAa,CAAC;IACzB,aAAa,EAAE,iBAAiB,CAAC;IACjC,kBAAkB,EAAE,sBAAsB,CAAC;IAC3C,SAAS,EAAE,aAAa,CAAC;CAC1B;AAED;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,mBAU7B,CAAC;AAqCH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,aAAa,GAAG,gBAAgB,EAAE,CAkFpF"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { buildDomainRegistrations, indexCatalogById, requireInputRecord, requireString, requireToolPermission, withSchemaOnRejection, } from "../core/tools/registration-kit.js";
|
|
2
|
+
import { mediaAgentToolCatalog } from "./agent-tools.js";
|
|
3
|
+
import { listMedia, MediaValidationError, trashMedia, updateMediaMetadata, uploadMedia } from "./media-service.js";
|
|
4
|
+
const CATALOG_BY_ID = indexCatalogById(mediaAgentToolCatalog);
|
|
5
|
+
/**
|
|
6
|
+
* This wiring layer's OWN risk classification, authored from what each handler below actually
|
|
7
|
+
* calls. See `DerivedRiskByToolId` in the kit for why it is independent of the catalog's own
|
|
8
|
+
* `sideEffects` declaration.
|
|
9
|
+
*/
|
|
10
|
+
export const mediaDerivedRisk = new Map([
|
|
11
|
+
// -> listMedia (media-service.ts): mediaRepo.list only, no write.
|
|
12
|
+
["media_list_assets", "none"],
|
|
13
|
+
// -> uploadMedia (media-service.ts): blobRepo.save (maybe) + mediaRepo.save + renditionRepo.save.
|
|
14
|
+
["media_upload_asset", "mutates-durable-state"],
|
|
15
|
+
// -> updateMediaMetadata (media-service.ts): mediaRepo.save, editorial fields only.
|
|
16
|
+
["media_update_metadata", "mutates-durable-state"],
|
|
17
|
+
// -> trashMedia (media-service.ts): mediaRepo.save, status flip. Never a purge: purgeMedia is
|
|
18
|
+
// deliberately not exposed at all (see media/agent-tools.ts's file header).
|
|
19
|
+
["media_trash_asset", "mutates-durable-state"],
|
|
20
|
+
]);
|
|
21
|
+
/** The only Media rejection worth decorating with the published schema — a shape problem a different input would fix. */
|
|
22
|
+
function isMediaShapeRejection(error) {
|
|
23
|
+
return error instanceof MediaValidationError;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Projects a `MediaRecord` into an explicit model-facing shape rather than returning the domain
|
|
27
|
+
* record verbatim — the same discipline Forms' `toFormDefinitionView` applies. `workspaceId`/
|
|
28
|
+
* `createdAt`/`updatedAt` are dropped for the identical reasons given there.
|
|
29
|
+
*/
|
|
30
|
+
function toMediaToolView(record) {
|
|
31
|
+
return {
|
|
32
|
+
id: record.id,
|
|
33
|
+
title: record.title,
|
|
34
|
+
alt: record.alt,
|
|
35
|
+
caption: record.caption,
|
|
36
|
+
credit: record.credit,
|
|
37
|
+
sha256: record.source.sha256,
|
|
38
|
+
status: record.status,
|
|
39
|
+
version: record.version,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export function buildMediaRegistrations(routeDeps) {
|
|
43
|
+
const mediaWriteDeps = () => ({
|
|
44
|
+
clock: routeDeps.clock,
|
|
45
|
+
idGen: routeDeps.idGen,
|
|
46
|
+
mediaRepo: routeDeps.mediaRepo,
|
|
47
|
+
blobRepo: routeDeps.assetBlobRepo,
|
|
48
|
+
renditionRepo: routeDeps.assetRenditionRepo,
|
|
49
|
+
blobStore: routeDeps.blobStore,
|
|
50
|
+
});
|
|
51
|
+
const handlers = {
|
|
52
|
+
media_list_assets: async (ctx) => {
|
|
53
|
+
await requireToolPermission(routeDeps, { principalId: ctx.principal.id, permission: "media.read", entityType: "media" });
|
|
54
|
+
const { media } = await listMedia({ deps: { mediaRepo: routeDeps.mediaRepo }, input: { workspaceId: routeDeps.workspaceId } });
|
|
55
|
+
return { media: media.map(toMediaToolView) };
|
|
56
|
+
},
|
|
57
|
+
media_upload_asset: async (ctx) => {
|
|
58
|
+
const input = requireInputRecord(ctx.input);
|
|
59
|
+
await requireToolPermission(routeDeps, { principalId: ctx.principal.id, permission: "media.upload", entityType: "media" });
|
|
60
|
+
return withSchemaOnRejection({ toolId: "media_upload_asset", catalog: CATALOG_BY_ID, isShapeRejection: isMediaShapeRejection }, async () => {
|
|
61
|
+
const dataBase64 = requireString(input, "dataBase64");
|
|
62
|
+
let bytes;
|
|
63
|
+
try {
|
|
64
|
+
bytes = new Uint8Array(Buffer.from(dataBase64, "base64"));
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
throw new Error("'dataBase64' is not valid base64");
|
|
68
|
+
}
|
|
69
|
+
const { media } = await uploadMedia({
|
|
70
|
+
deps: mediaWriteDeps(),
|
|
71
|
+
input: {
|
|
72
|
+
workspaceId: routeDeps.workspaceId,
|
|
73
|
+
bytes,
|
|
74
|
+
filename: requireString(input, "filename"),
|
|
75
|
+
contentType: requireString(input, "contentType"),
|
|
76
|
+
alt: typeof input.alt === "string" ? input.alt : undefined,
|
|
77
|
+
caption: typeof input.caption === "string" ? input.caption : undefined,
|
|
78
|
+
credit: typeof input.credit === "string" ? input.credit : undefined,
|
|
79
|
+
createdByPrincipal: ctx.principal.id,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
return { media: toMediaToolView(media) };
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
media_update_metadata: async (ctx) => {
|
|
86
|
+
const input = requireInputRecord(ctx.input);
|
|
87
|
+
const mediaId = requireString(input, "mediaId");
|
|
88
|
+
await requireToolPermission(routeDeps, { principalId: ctx.principal.id, permission: "media.update", entityType: "media", entityId: mediaId });
|
|
89
|
+
const { media } = await updateMediaMetadata({
|
|
90
|
+
deps: { clock: routeDeps.clock, mediaRepo: routeDeps.mediaRepo },
|
|
91
|
+
input: {
|
|
92
|
+
workspaceId: routeDeps.workspaceId,
|
|
93
|
+
id: mediaId,
|
|
94
|
+
title: typeof input.title === "string" ? input.title : undefined,
|
|
95
|
+
alt: typeof input.alt === "string" ? input.alt : undefined,
|
|
96
|
+
caption: typeof input.caption === "string" ? input.caption : undefined,
|
|
97
|
+
credit: typeof input.credit === "string" ? input.credit : undefined,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
return { media: toMediaToolView(media) };
|
|
101
|
+
},
|
|
102
|
+
media_trash_asset: async (ctx) => {
|
|
103
|
+
const mediaId = requireString(requireInputRecord(ctx.input), "mediaId");
|
|
104
|
+
await requireToolPermission(routeDeps, { principalId: ctx.principal.id, permission: "media.delete", entityType: "media", entityId: mediaId });
|
|
105
|
+
const { media } = await trashMedia({
|
|
106
|
+
deps: { clock: routeDeps.clock, mediaRepo: routeDeps.mediaRepo },
|
|
107
|
+
input: { workspaceId: routeDeps.workspaceId, id: mediaId },
|
|
108
|
+
});
|
|
109
|
+
return { media: toMediaToolView(media) };
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
// No `unwiredToolIds`: Media wires its ENTIRE catalog, same tripwire discipline as Forms.
|
|
113
|
+
return buildDomainRegistrations({
|
|
114
|
+
domain: "media",
|
|
115
|
+
catalogModule: "media/agent-tools.ts",
|
|
116
|
+
catalog: CATALOG_BY_ID,
|
|
117
|
+
handlers,
|
|
118
|
+
derivedRisk: mediaDerivedRisk,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=tool-registrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-registrations.js","sourceRoot":"","sources":["../../src/media/tool-registrations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Generic in-process keyed mutex factory, extracted from
|
|
3
|
+
* `blob-gc-lock.ts`'s `withSha256Lock` shape (INV-1's
|
|
4
|
+
* "Serialization" clause) so the same FIFO-per-key critical-section pattern
|
|
5
|
+
* can back two independent lock namespaces this domain needs:
|
|
6
|
+
*
|
|
7
|
+
* - `withTransformRegistryLock` — serializes `registerTransform`'s
|
|
8
|
+
* read-max-version-then-insert-next-version sequence per `(workspaceId,
|
|
9
|
+
* name)`, so two concurrent registrations of the same name can't both
|
|
10
|
+
* read the same "current max" and mint a colliding version.
|
|
11
|
+
* - `withRenditionLock` — serializes lazy rendition generation per
|
|
12
|
+
* `(sha256, transformName, version)` ("single-flight"), so two
|
|
13
|
+
* concurrent requests for the same not-yet-generated rendition never run
|
|
14
|
+
* the image transformer twice.
|
|
15
|
+
*
|
|
16
|
+
* `blob-gc-lock.ts` itself is untouched — this is a separate module, not a
|
|
17
|
+
* modification of that file's exports (its shape is deliberately mirrored
|
|
18
|
+
* here, not imported, so `blob-gc-lock.ts`'s own signature stays untouched).
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Creates one independent keyed-lock namespace: calls sharing the same `key`
|
|
22
|
+
* are strictly FIFO-ordered; calls for different keys run fully
|
|
23
|
+
* concurrently. A rejection in one critical section does not poison the lock
|
|
24
|
+
* for later callers on the same key (each waits for its predecessor to
|
|
25
|
+
* *settle*, not to succeed) — identical semantics to `withSha256Lock`.
|
|
26
|
+
*
|
|
27
|
+
* @complexity O(1) scheduling overhead per call; total wait time is bounded
|
|
28
|
+
* by the number of other calls currently queued for the same key.
|
|
29
|
+
* @overallScore 100
|
|
30
|
+
*/
|
|
31
|
+
export declare function createKeyedLock(): <T>(key: string, criticalSection: () => Promise<T>) => Promise<T>;
|
|
32
|
+
/** Keyed on `${workspaceId}:${name}` — see file header. */
|
|
33
|
+
export declare const withTransformRegistryLock: <T>(key: string, criticalSection: () => Promise<T>) => Promise<T>;
|
|
34
|
+
/** Keyed on `${sha256}:${transformName}:${version}` — see file header. */
|
|
35
|
+
export declare const withRenditionLock: <T>(key: string, criticalSection: () => Promise<T>) => Promise<T>;
|
|
36
|
+
//# sourceMappingURL=transform-lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform-lock.d.ts","sourceRoot":"","sources":["../../src/media/transform-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAkBnG;AAED,2DAA2D;AAC3D,eAAO,MAAM,yBAAyB,GArBF,CAAC,OAAO,MAAM,mBAAmB,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAqBzC,CAAC;AAE3D,0EAA0E;AAC1E,eAAO,MAAM,iBAAiB,GAxBM,CAAC,OAAO,MAAM,mBAAmB,MAAM,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAwBjD,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Generic in-process keyed mutex factory, extracted from
|
|
3
|
+
* `blob-gc-lock.ts`'s `withSha256Lock` shape (INV-1's
|
|
4
|
+
* "Serialization" clause) so the same FIFO-per-key critical-section pattern
|
|
5
|
+
* can back two independent lock namespaces this domain needs:
|
|
6
|
+
*
|
|
7
|
+
* - `withTransformRegistryLock` — serializes `registerTransform`'s
|
|
8
|
+
* read-max-version-then-insert-next-version sequence per `(workspaceId,
|
|
9
|
+
* name)`, so two concurrent registrations of the same name can't both
|
|
10
|
+
* read the same "current max" and mint a colliding version.
|
|
11
|
+
* - `withRenditionLock` — serializes lazy rendition generation per
|
|
12
|
+
* `(sha256, transformName, version)` ("single-flight"), so two
|
|
13
|
+
* concurrent requests for the same not-yet-generated rendition never run
|
|
14
|
+
* the image transformer twice.
|
|
15
|
+
*
|
|
16
|
+
* `blob-gc-lock.ts` itself is untouched — this is a separate module, not a
|
|
17
|
+
* modification of that file's exports (its shape is deliberately mirrored
|
|
18
|
+
* here, not imported, so `blob-gc-lock.ts`'s own signature stays untouched).
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Creates one independent keyed-lock namespace: calls sharing the same `key`
|
|
22
|
+
* are strictly FIFO-ordered; calls for different keys run fully
|
|
23
|
+
* concurrently. A rejection in one critical section does not poison the lock
|
|
24
|
+
* for later callers on the same key (each waits for its predecessor to
|
|
25
|
+
* *settle*, not to succeed) — identical semantics to `withSha256Lock`.
|
|
26
|
+
*
|
|
27
|
+
* @complexity O(1) scheduling overhead per call; total wait time is bounded
|
|
28
|
+
* by the number of other calls currently queued for the same key.
|
|
29
|
+
* @overallScore 100
|
|
30
|
+
*/
|
|
31
|
+
export function createKeyedLock() {
|
|
32
|
+
const lockTails = new Map();
|
|
33
|
+
return function withLock(key, criticalSection) {
|
|
34
|
+
const priorTail = lockTails.get(key) ?? Promise.resolve();
|
|
35
|
+
const run = priorTail.then(criticalSection, criticalSection);
|
|
36
|
+
const settledTail = run.then(() => undefined, () => undefined);
|
|
37
|
+
lockTails.set(key, settledTail);
|
|
38
|
+
void settledTail.then(() => {
|
|
39
|
+
if (lockTails.get(key) === settledTail) {
|
|
40
|
+
lockTails.delete(key);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return run;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/** Keyed on `${workspaceId}:${name}` — see file header. */
|
|
47
|
+
export const withTransformRegistryLock = createKeyedLock();
|
|
48
|
+
/** Keyed on `${sha256}:${transformName}:${version}` — see file header. */
|
|
49
|
+
export const withRenditionLock = createKeyedLock();
|
|
50
|
+
//# sourceMappingURL=transform-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform-lock.js","sourceRoot":"","sources":["../../src/media/transform-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEnD,OAAO,SAAS,QAAQ,CAAI,GAAW,EAAE,eAAiC;QACxE,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAC1D,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;QAC7D,MAAM,WAAW,GAAkB,GAAG,CAAC,IAAI,CACzC,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;QACF,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAChC,KAAK,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE;YACzB,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,WAAW,EAAE,CAAC;gBACvC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,CAAC,MAAM,yBAAyB,GAAG,eAAe,EAAE,CAAC;AAE3D,0EAA0E;AAC1E,MAAM,CAAC,MAAM,iBAAiB,GAAG,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Named transform registry service — the core-declared
|
|
3
|
+
* path only (no theme/plugin declaration API; see `transform-types.ts` file
|
|
4
|
+
* header for that disclosed scope boundary).
|
|
5
|
+
*
|
|
6
|
+
* Mirrors `media-service.ts`'s shape: plain async functions taking
|
|
7
|
+
* `{ deps, input }` (+ optional `options`), typed domain errors.
|
|
8
|
+
*/
|
|
9
|
+
import type { ClockPort, IdGeneratorPort, UUID } from "../core/ports.js";
|
|
10
|
+
import type { TransformDefinitionRepoPort } from "./ports.js";
|
|
11
|
+
import { TransformValidationError, type TransformDefinitionRecord, type TransformParams } from "./transform-types.js";
|
|
12
|
+
export { TransformValidationError };
|
|
13
|
+
export interface RegisterTransformInput {
|
|
14
|
+
workspaceId: UUID;
|
|
15
|
+
name: string;
|
|
16
|
+
params: TransformParams;
|
|
17
|
+
/** Registering module id, e.g. `"core"`. See `transform-types.ts` file header. */
|
|
18
|
+
owner: string;
|
|
19
|
+
}
|
|
20
|
+
export interface RegisterTransformDeps {
|
|
21
|
+
clock: ClockPort;
|
|
22
|
+
idGen: IdGeneratorPort;
|
|
23
|
+
transformRepo: TransformDefinitionRepoPort;
|
|
24
|
+
}
|
|
25
|
+
export interface RegisterTransformRequired {
|
|
26
|
+
deps: RegisterTransformDeps;
|
|
27
|
+
input: RegisterTransformInput;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Registers a named transform definition. Append-only:
|
|
31
|
+
* redefining an already-used `name` never mutates the prior version's row —
|
|
32
|
+
* it inserts a new row at `version = (current max version for name) + 1`
|
|
33
|
+
* (or `1` if `name` has never been registered). The read-max-then-insert
|
|
34
|
+
* sequence runs inside {@link withTransformRegistryLock} keyed on
|
|
35
|
+
* `(workspaceId, name)` so two concurrent `registerTransform` calls for the
|
|
36
|
+
* same name can't both observe the same "current max" and mint colliding
|
|
37
|
+
* versions (the version-numbering equivalent of the race
|
|
38
|
+
* `withSha256Lock`/`blob-gc-lock.ts` closes for blob dedup-vs-GC).
|
|
39
|
+
*
|
|
40
|
+
* @complexity O(v) in the number of existing versions of `name`, from the
|
|
41
|
+
* max-version scan (`listByName` + reduce) — acceptable at walking-skeleton
|
|
42
|
+
* scale, same tradeoff class as `isBlobUnreferenced`'s O(n) scan.
|
|
43
|
+
* @overallScore 100
|
|
44
|
+
*/
|
|
45
|
+
export declare function registerTransform(required: RegisterTransformRequired, _optional?: Record<string, never>): Promise<{
|
|
46
|
+
definition: TransformDefinitionRecord;
|
|
47
|
+
}>;
|
|
48
|
+
export interface GetLatestTransformDefinitionRequired {
|
|
49
|
+
deps: {
|
|
50
|
+
transformRepo: TransformDefinitionRepoPort;
|
|
51
|
+
};
|
|
52
|
+
input: {
|
|
53
|
+
workspaceId: UUID;
|
|
54
|
+
name: string;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Returns the highest-`version` row registered for `name`, or `null` if
|
|
59
|
+
* `name` has never been registered.
|
|
60
|
+
*
|
|
61
|
+
* @complexity O(v) in the number of versions of `name`.
|
|
62
|
+
* @overallScore 100
|
|
63
|
+
*/
|
|
64
|
+
export declare function getLatestTransformDefinition(required: GetLatestTransformDefinitionRequired): Promise<TransformDefinitionRecord | null>;
|
|
65
|
+
export interface IsLatestTransformVersionRequired {
|
|
66
|
+
deps: {
|
|
67
|
+
transformRepo: TransformDefinitionRepoPort;
|
|
68
|
+
};
|
|
69
|
+
input: {
|
|
70
|
+
workspaceId: UUID;
|
|
71
|
+
name: string;
|
|
72
|
+
version: number;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Answers "is `version` the current latest registered version of `name`?" —
|
|
77
|
+
* the cheap half of the anonymous-generation bound ("latest
|
|
78
|
+
* registry version of that name"). Used by `rendition-service.ts` to decide
|
|
79
|
+
* whether an unauthenticated request may trigger lazy generation for an
|
|
80
|
+
* as-yet-ungenerated rendition.
|
|
81
|
+
*
|
|
82
|
+
* @complexity O(v), inherited from {@link getLatestTransformDefinition}.
|
|
83
|
+
* @overallScore 100
|
|
84
|
+
*/
|
|
85
|
+
export declare function isLatestTransformVersion(required: IsLatestTransformVersionRequired): Promise<boolean>;
|
|
86
|
+
/**
|
|
87
|
+
* STUB (disclosed) — the other half of the anonymous-generation
|
|
88
|
+
* bound: "referenced by published content". The real check depends on
|
|
89
|
+
* the `entry_refs` where-used index, which is not implemented as
|
|
90
|
+
* running code yet (same disclosed gap `blob-gc.ts`'s `hasLiveEntryRefs`
|
|
91
|
+
* names for the same reason — see that file's header). Always reports "not
|
|
92
|
+
* referenced", which is what makes {@link isLatestTransformVersion} alone
|
|
93
|
+
* the effective bound in this build.
|
|
94
|
+
*
|
|
95
|
+
* @complexity O(1) (stub).
|
|
96
|
+
* @overallScore 100
|
|
97
|
+
*/
|
|
98
|
+
export declare function isReferencedByPublishedContent(_input: {
|
|
99
|
+
workspaceId: UUID;
|
|
100
|
+
name: string;
|
|
101
|
+
version: number;
|
|
102
|
+
}): boolean;
|
|
103
|
+
//# sourceMappingURL=transform-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform-registry.d.ts","sourceRoot":"","sources":["../../src/media/transform-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAA8B,wBAAwB,EAAE,KAAK,yBAAyB,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGlJ,OAAO,EAAE,wBAAwB,EAAE,CAAC;AAMpC,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,eAAe,CAAC;IACvB,aAAa,EAAE,2BAA2B,CAAC;CAC5C;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,qBAAqB,CAAC;IAC5B,KAAK,EAAE,sBAAsB,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,yBAAyB,EACnC,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAM,GACpC,OAAO,CAAC;IAAE,UAAU,EAAE,yBAAyB,CAAA;CAAE,CAAC,CAyBpD;AAMD,MAAM,WAAW,oCAAoC;IACnD,IAAI,EAAE;QAAE,aAAa,EAAE,2BAA2B,CAAA;KAAE,CAAC;IACrD,KAAK,EAAE;QAAE,WAAW,EAAE,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5C;AAED;;;;;;GAMG;AACH,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,oCAAoC,GAC7C,OAAO,CAAC,yBAAyB,GAAG,IAAI,CAAC,CAI3C;AAED,MAAM,WAAW,gCAAgC;IAC/C,IAAI,EAAE;QAAE,aAAa,EAAE,2BAA2B,CAAA;KAAE,CAAC;IACrD,KAAK,EAAE;QAAE,WAAW,EAAE,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7D;AAED;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAAC,QAAQ,EAAE,gCAAgC,GAAG,OAAO,CAAC,OAAO,CAAC,CAG3G;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAAC,MAAM,EAAE;IACrD,WAAW,EAAE,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAEV"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { assertValidTransformParams, TransformValidationError } from "./transform-types.js";
|
|
2
|
+
import { withTransformRegistryLock } from "./transform-lock.js";
|
|
3
|
+
export { TransformValidationError };
|
|
4
|
+
/**
|
|
5
|
+
* Registers a named transform definition. Append-only:
|
|
6
|
+
* redefining an already-used `name` never mutates the prior version's row —
|
|
7
|
+
* it inserts a new row at `version = (current max version for name) + 1`
|
|
8
|
+
* (or `1` if `name` has never been registered). The read-max-then-insert
|
|
9
|
+
* sequence runs inside {@link withTransformRegistryLock} keyed on
|
|
10
|
+
* `(workspaceId, name)` so two concurrent `registerTransform` calls for the
|
|
11
|
+
* same name can't both observe the same "current max" and mint colliding
|
|
12
|
+
* versions (the version-numbering equivalent of the race
|
|
13
|
+
* `withSha256Lock`/`blob-gc-lock.ts` closes for blob dedup-vs-GC).
|
|
14
|
+
*
|
|
15
|
+
* @complexity O(v) in the number of existing versions of `name`, from the
|
|
16
|
+
* max-version scan (`listByName` + reduce) — acceptable at walking-skeleton
|
|
17
|
+
* scale, same tradeoff class as `isBlobUnreferenced`'s O(n) scan.
|
|
18
|
+
* @overallScore 100
|
|
19
|
+
*/
|
|
20
|
+
export async function registerTransform(required, _optional = {}) {
|
|
21
|
+
const { deps, input } = required;
|
|
22
|
+
const name = input.name.trim();
|
|
23
|
+
if (!name)
|
|
24
|
+
throw new TransformValidationError("transform name is required");
|
|
25
|
+
const owner = input.owner.trim();
|
|
26
|
+
if (!owner)
|
|
27
|
+
throw new TransformValidationError("owner is required");
|
|
28
|
+
assertValidTransformParams(input.params);
|
|
29
|
+
return withTransformRegistryLock(`${input.workspaceId}:${name}`, async () => {
|
|
30
|
+
const existingVersions = await deps.transformRepo.listByName({ workspaceId: input.workspaceId, name });
|
|
31
|
+
const currentMaxVersion = existingVersions.reduce((max, row) => Math.max(max, row.version), 0);
|
|
32
|
+
const definition = {
|
|
33
|
+
id: deps.idGen.newId(),
|
|
34
|
+
workspaceId: input.workspaceId,
|
|
35
|
+
name,
|
|
36
|
+
version: currentMaxVersion + 1,
|
|
37
|
+
params: input.params,
|
|
38
|
+
owner,
|
|
39
|
+
createdAt: deps.clock.nowIso(),
|
|
40
|
+
};
|
|
41
|
+
await deps.transformRepo.insert(definition);
|
|
42
|
+
return { definition };
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Returns the highest-`version` row registered for `name`, or `null` if
|
|
47
|
+
* `name` has never been registered.
|
|
48
|
+
*
|
|
49
|
+
* @complexity O(v) in the number of versions of `name`.
|
|
50
|
+
* @overallScore 100
|
|
51
|
+
*/
|
|
52
|
+
export async function getLatestTransformDefinition(required) {
|
|
53
|
+
const rows = await required.deps.transformRepo.listByName(required.input);
|
|
54
|
+
if (rows.length === 0)
|
|
55
|
+
return null;
|
|
56
|
+
return rows.reduce((latest, row) => (row.version > latest.version ? row : latest));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Answers "is `version` the current latest registered version of `name`?" —
|
|
60
|
+
* the cheap half of the anonymous-generation bound ("latest
|
|
61
|
+
* registry version of that name"). Used by `rendition-service.ts` to decide
|
|
62
|
+
* whether an unauthenticated request may trigger lazy generation for an
|
|
63
|
+
* as-yet-ungenerated rendition.
|
|
64
|
+
*
|
|
65
|
+
* @complexity O(v), inherited from {@link getLatestTransformDefinition}.
|
|
66
|
+
* @overallScore 100
|
|
67
|
+
*/
|
|
68
|
+
export async function isLatestTransformVersion(required) {
|
|
69
|
+
const latest = await getLatestTransformDefinition({ deps: required.deps, input: required.input });
|
|
70
|
+
return latest !== null && latest.version === required.input.version;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* STUB (disclosed) — the other half of the anonymous-generation
|
|
74
|
+
* bound: "referenced by published content". The real check depends on
|
|
75
|
+
* the `entry_refs` where-used index, which is not implemented as
|
|
76
|
+
* running code yet (same disclosed gap `blob-gc.ts`'s `hasLiveEntryRefs`
|
|
77
|
+
* names for the same reason — see that file's header). Always reports "not
|
|
78
|
+
* referenced", which is what makes {@link isLatestTransformVersion} alone
|
|
79
|
+
* the effective bound in this build.
|
|
80
|
+
*
|
|
81
|
+
* @complexity O(1) (stub).
|
|
82
|
+
* @overallScore 100
|
|
83
|
+
*/
|
|
84
|
+
export function isReferencedByPublishedContent(_input) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=transform-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform-registry.js","sourceRoot":"","sources":["../../src/media/transform-registry.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAwD,MAAM,sBAAsB,CAAC;AAClJ,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,OAAO,EAAE,wBAAwB,EAAE,CAAC;AAyBpC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,QAAmC,EACnC,YAAmC,EAAE;IAErC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;IAEjC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC/B,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,wBAAwB,CAAC,4BAA4B,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACjC,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,wBAAwB,CAAC,mBAAmB,CAAC,CAAC;IACpE,0BAA0B,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAEzC,OAAO,yBAAyB,CAAC,GAAG,KAAK,CAAC,WAAW,IAAI,IAAI,EAAE,EAAE,KAAK,IAAI,EAAE;QAC1E,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;QACvG,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QAE/F,MAAM,UAAU,GAA8B;YAC5C,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE;YACtB,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,IAAI;YACJ,OAAO,EAAE,iBAAiB,GAAG,CAAC;YAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;SAC/B,CAAC;QACF,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5C,OAAO,EAAE,UAAU,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC;AAWD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,QAA8C;IAE9C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AACrF,CAAC;AAOD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,QAA0C;IACvF,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAClG,OAAO,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;AACtE,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,8BAA8B,CAAC,MAI9C;IACC,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Domain types + typed errors for the named transform registry and
|
|
3
|
+
* rendition generation ("Transforms and the immutable URL
|
|
4
|
+
* contract").
|
|
5
|
+
*
|
|
6
|
+
* Purpose:
|
|
7
|
+
* `TransformDefinitionRecord` is the `transform_registry` sidecar row: a
|
|
8
|
+
* declarative, immutable, append-only named transform definition keyed
|
|
9
|
+
* `(workspaceId, name, version)`. `TransformParams` is the small closed set
|
|
10
|
+
* of resize/format parameters this build supports — deliberately NOT an
|
|
11
|
+
* arbitrary `?w=&h=` query grammar (an explicit amplification /
|
|
12
|
+
* URL-grammar-freeze decision).
|
|
13
|
+
*
|
|
14
|
+
* SCOPE NOTE (disclosed): the original design describes transforms as declarable by
|
|
15
|
+
* "core + theme/plugin". This build only implements the core-declared path —
|
|
16
|
+
* there is no theme/plugin declaration API here (out of scope for this task).
|
|
17
|
+
* `owner` is kept as a plain string (not a hardcoded `"core"` literal type)
|
|
18
|
+
* specifically so a future theme/plugin declarer can pass its own id through
|
|
19
|
+
* the same field without a schema change — mirrors
|
|
20
|
+
* `identity/permissions.ts`'s `PermissionDescriptor.owner` pattern, which
|
|
21
|
+
* solves the identical "who registered this, extensibly" problem for the
|
|
22
|
+
* permission catalog.
|
|
23
|
+
*/
|
|
24
|
+
import type { ISODateTime, UUID } from "../core/ports.js";
|
|
25
|
+
/** Resize behavior, mirrors `sharp`'s `fit` vocabulary (a deliberately small subset). */
|
|
26
|
+
export type TransformFit = "cover" | "contain" | "fill" | "inside" | "outside";
|
|
27
|
+
/**
|
|
28
|
+
* Output re-encode format. Matches `media-service.ts`'s
|
|
29
|
+
* `DEFAULT_ALLOWED_MIME_TYPES` image set minus SVG (never a transform output —
|
|
30
|
+
* SVG has no raster pixels to resize).
|
|
31
|
+
*/
|
|
32
|
+
export type TransformFormat = "jpeg" | "png" | "webp" | "gif";
|
|
33
|
+
/**
|
|
34
|
+
* Declarative transform parameters (named definitions only, never
|
|
35
|
+
* caller-supplied dimensions). `width`/`height` are optional so a
|
|
36
|
+
* format-only re-encode (no resize) is a valid definition; `fit` only
|
|
37
|
+
* matters when both `width` and `height` are given.
|
|
38
|
+
*/
|
|
39
|
+
export interface TransformParams {
|
|
40
|
+
width?: number | undefined;
|
|
41
|
+
height?: number | undefined;
|
|
42
|
+
fit?: TransformFit | undefined;
|
|
43
|
+
format: TransformFormat;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* `transform_registry` sidecar row. Identity is
|
|
47
|
+
* `(workspaceId, name, version)`; a row, once inserted, is never updated or
|
|
48
|
+
* removed — see `TransformDefinitionRepoPort.insert`'s append-only contract
|
|
49
|
+
* in `ports.ts`. Redefining `name` mints a new row with `version` one higher
|
|
50
|
+
* than the previous max, never a mutation of the old row.
|
|
51
|
+
*/
|
|
52
|
+
export interface TransformDefinitionRecord {
|
|
53
|
+
id: UUID;
|
|
54
|
+
workspaceId: UUID;
|
|
55
|
+
name: string;
|
|
56
|
+
version: number;
|
|
57
|
+
params: TransformParams;
|
|
58
|
+
/** Registering module — `"core"` for every definition this task creates. See file header. */
|
|
59
|
+
owner: string;
|
|
60
|
+
createdAt: ISODateTime;
|
|
61
|
+
}
|
|
62
|
+
export declare class TransformValidationError extends Error {
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* @complexity O(1).
|
|
66
|
+
* @overallScore 100
|
|
67
|
+
*/
|
|
68
|
+
export declare function mimeForTransformFormat(format: TransformFormat): string;
|
|
69
|
+
/** Upper bound on a requested resize dimension — an output-side resource-use guard (not the
|
|
70
|
+
* full pixel-bomb ingest cap, which polices upload input; this polices the transform
|
|
71
|
+
* definition itself so a registered definition can't ask the image transformer to allocate an
|
|
72
|
+
* absurd target canvas). */
|
|
73
|
+
export declare const MAX_TRANSFORM_DIMENSION_PX = 8000;
|
|
74
|
+
/**
|
|
75
|
+
* Validates a {@link TransformParams} value at registration time. Throws
|
|
76
|
+
* {@link TransformValidationError} on the first violation found.
|
|
77
|
+
*
|
|
78
|
+
* @complexity O(1).
|
|
79
|
+
* @overallScore 100
|
|
80
|
+
*/
|
|
81
|
+
export declare function assertValidTransformParams(params: TransformParams): void;
|
|
82
|
+
//# sourceMappingURL=transform-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform-types.d.ts","sourceRoot":"","sources":["../../src/media/transform-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE1D,yFAAyF;AACzF,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE/E;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,GAAG,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,eAAe,CAAC;CACzB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,IAAI,CAAC;IACT,WAAW,EAAE,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,eAAe,CAAC;IACxB,6FAA6F;IAC7F,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,WAAW,CAAC;CACxB;AAED,qBAAa,wBAAyB,SAAQ,KAAK;CAAG;AAUtD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAEtE;AAED;;;4BAG4B;AAC5B,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAoBxE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export class TransformValidationError extends Error {
|
|
2
|
+
}
|
|
3
|
+
/** Maps a {@link TransformFormat} to the MIME type served on the rendition response. */
|
|
4
|
+
const MIME_BY_TRANSFORM_FORMAT = {
|
|
5
|
+
jpeg: "image/jpeg",
|
|
6
|
+
png: "image/png",
|
|
7
|
+
webp: "image/webp",
|
|
8
|
+
gif: "image/gif",
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* @complexity O(1).
|
|
12
|
+
* @overallScore 100
|
|
13
|
+
*/
|
|
14
|
+
export function mimeForTransformFormat(format) {
|
|
15
|
+
return MIME_BY_TRANSFORM_FORMAT[format];
|
|
16
|
+
}
|
|
17
|
+
/** Upper bound on a requested resize dimension — an output-side resource-use guard (not the
|
|
18
|
+
* full pixel-bomb ingest cap, which polices upload input; this polices the transform
|
|
19
|
+
* definition itself so a registered definition can't ask the image transformer to allocate an
|
|
20
|
+
* absurd target canvas). */
|
|
21
|
+
export const MAX_TRANSFORM_DIMENSION_PX = 8000;
|
|
22
|
+
/**
|
|
23
|
+
* Validates a {@link TransformParams} value at registration time. Throws
|
|
24
|
+
* {@link TransformValidationError} on the first violation found.
|
|
25
|
+
*
|
|
26
|
+
* @complexity O(1).
|
|
27
|
+
* @overallScore 100
|
|
28
|
+
*/
|
|
29
|
+
export function assertValidTransformParams(params) {
|
|
30
|
+
if (!params.format || !(params.format in MIME_BY_TRANSFORM_FORMAT)) {
|
|
31
|
+
throw new TransformValidationError(`transform params.format must be one of ${Object.keys(MIME_BY_TRANSFORM_FORMAT).join(", ")}`);
|
|
32
|
+
}
|
|
33
|
+
for (const [key, value] of [
|
|
34
|
+
["width", params.width],
|
|
35
|
+
["height", params.height],
|
|
36
|
+
]) {
|
|
37
|
+
if (value === undefined)
|
|
38
|
+
continue;
|
|
39
|
+
if (!Number.isInteger(value) || value < 1 || value > MAX_TRANSFORM_DIMENSION_PX) {
|
|
40
|
+
throw new TransformValidationError(`transform params.${key} must be an integer between 1 and ${MAX_TRANSFORM_DIMENSION_PX}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (params.fit !== undefined && !(params.width && params.height)) {
|
|
44
|
+
throw new TransformValidationError("transform params.fit requires both width and height");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=transform-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transform-types.js","sourceRoot":"","sources":["../../src/media/transform-types.ts"],"names":[],"mappings":"AAkEA,MAAM,OAAO,wBAAyB,SAAQ,KAAK;CAAG;AAEtD,wFAAwF;AACxF,MAAM,wBAAwB,GAAoC;IAChE,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;CACjB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAuB;IAC5D,OAAO,wBAAwB,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED;;;4BAG4B;AAC5B,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,CAAC;AAE/C;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAuB;IAChE,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,wBAAwB,CAAC,EAAE,CAAC;QACnE,MAAM,IAAI,wBAAwB,CAChC,0CAA0C,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7F,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI;QACzB,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC;QACvB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC;KACjB,EAAE,CAAC;QACX,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,0BAA0B,EAAE,CAAC;YAChF,MAAM,IAAI,wBAAwB,CAChC,oBAAoB,GAAG,qCAAqC,0BAA0B,EAAE,CACzF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,wBAAwB,CAAC,qDAAqD,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC"}
|