@orthacms/content-server 0.4.2 → 0.5.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/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +41 -1
- package/dist/lib/content.module.d.ts.map +1 -1
- package/dist/lib/content.module.js +31 -1
- package/dist/lib/copilot/entry-proposal.applier.d.ts.map +1 -1
- package/dist/lib/copilot/entry-proposal.applier.js +5 -4
- package/dist/lib/docs/describe-content-api.d.ts +7 -0
- package/dist/lib/docs/describe-content-api.d.ts.map +1 -1
- package/dist/lib/docs/describe-content-api.js +177 -53
- package/dist/lib/docs/describe-views-api.d.ts +19 -0
- package/dist/lib/docs/describe-views-api.d.ts.map +1 -0
- package/dist/lib/docs/describe-views-api.js +76 -0
- package/dist/lib/docs/field-schema.d.ts.map +1 -1
- package/dist/lib/docs/field-schema.js +36 -2
- package/dist/lib/docs/openapi-writer.d.ts +49 -0
- package/dist/lib/docs/openapi-writer.d.ts.map +1 -0
- package/dist/lib/docs/openapi-writer.js +76 -0
- package/dist/lib/docs/public-api-schemas.d.ts +45 -0
- package/dist/lib/docs/public-api-schemas.d.ts.map +1 -0
- package/dist/lib/docs/public-api-schemas.js +377 -0
- package/dist/lib/docs/views-schemas.d.ts +22 -0
- package/dist/lib/docs/views-schemas.d.ts.map +1 -0
- package/dist/lib/docs/views-schemas.js +156 -0
- package/dist/lib/entries/application/use-cases/bulk-publish-entries.use-case.d.ts +8 -2
- package/dist/lib/entries/application/use-cases/bulk-publish-entries.use-case.d.ts.map +1 -1
- package/dist/lib/entries/application/use-cases/bulk-publish-entries.use-case.js +19 -4
- package/dist/lib/entries/application/use-cases/bulk-unpublish-entries.use-case.d.ts +2 -2
- package/dist/lib/entries/application/use-cases/bulk-unpublish-entries.use-case.d.ts.map +1 -1
- package/dist/lib/entries/application/use-cases/bulk-unpublish-entries.use-case.js +14 -4
- package/dist/lib/entries/application/use-cases/publish-entry.use-case.d.ts +6 -8
- package/dist/lib/entries/application/use-cases/publish-entry.use-case.d.ts.map +1 -1
- package/dist/lib/entries/application/use-cases/publish-entry.use-case.js +10 -4
- package/dist/lib/entries/application/use-cases/unpublish-entry.use-case.d.ts +2 -5
- package/dist/lib/entries/application/use-cases/unpublish-entry.use-case.d.ts.map +1 -1
- package/dist/lib/entries/application/use-cases/unpublish-entry.use-case.js +6 -1
- package/dist/lib/entries/domain/entry.d.ts +8 -1
- package/dist/lib/entries/domain/entry.d.ts.map +1 -1
- package/dist/lib/entries/domain/entry.js +12 -12
- package/dist/lib/entries/domain/events/entry-events.d.ts +47 -5
- package/dist/lib/entries/domain/events/entry-events.d.ts.map +1 -1
- package/dist/lib/entries/domain/events/entry-events.js +26 -10
- package/dist/lib/entries/entries.constants.d.ts +10 -2
- package/dist/lib/entries/entries.constants.d.ts.map +1 -1
- package/dist/lib/entries/entries.constants.js +11 -2
- package/dist/lib/entries/http/controllers/bulk-entries.controller.d.ts +2 -2
- package/dist/lib/entries/http/controllers/bulk-entries.controller.d.ts.map +1 -1
- package/dist/lib/entries/http/controllers/bulk-entries.controller.js +8 -6
- package/dist/lib/entries/http/controllers/create-entry.controller.d.ts.map +1 -1
- package/dist/lib/entries/http/controllers/create-entry.controller.js +1 -1
- package/dist/lib/entries/http/controllers/update-entry.controller.d.ts.map +1 -1
- package/dist/lib/entries/http/controllers/update-entry.controller.js +1 -1
- package/dist/lib/entries/http/dto/extension-bag.validator.d.ts +14 -0
- package/dist/lib/entries/http/dto/extension-bag.validator.d.ts.map +1 -0
- package/dist/lib/entries/http/dto/extension-bag.validator.js +42 -0
- package/dist/lib/entries/http/dto/save-entry.dto.d.ts +16 -0
- package/dist/lib/entries/http/dto/save-entry.dto.d.ts.map +1 -1
- package/dist/lib/entries/http/dto/save-entry.dto.js +30 -0
- package/dist/lib/entries/infrastructure/persistence/entry-writer.service.d.ts +50 -8
- package/dist/lib/entries/infrastructure/persistence/entry-writer.service.d.ts.map +1 -1
- package/dist/lib/entries/infrastructure/persistence/entry-writer.service.js +183 -32
- package/dist/lib/entries/infrastructure/persistence/relation-link.service.d.ts +38 -5
- package/dist/lib/entries/infrastructure/persistence/relation-link.service.d.ts.map +1 -1
- package/dist/lib/entries/infrastructure/persistence/relation-link.service.js +38 -6
- package/dist/lib/entries/infrastructure/queries/entries.service.d.ts +3 -1
- package/dist/lib/entries/infrastructure/queries/entries.service.d.ts.map +1 -1
- package/dist/lib/entries/infrastructure/queries/entries.service.js +17 -5
- package/dist/lib/entries/infrastructure/queries/entry-match.query.d.ts +82 -0
- package/dist/lib/entries/infrastructure/queries/entry-match.query.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/queries/entry-match.query.js +152 -0
- package/dist/lib/extension/entry-filter-provider.d.ts +79 -0
- package/dist/lib/extension/entry-filter-provider.d.ts.map +1 -0
- package/dist/lib/extension/entry-filter-provider.js +149 -0
- package/dist/lib/extension/entry-write-extension.d.ts +185 -0
- package/dist/lib/extension/entry-write-extension.d.ts.map +1 -0
- package/dist/lib/extension/entry-write-extension.js +182 -0
- package/dist/lib/extension/read-scope.d.ts +107 -0
- package/dist/lib/extension/read-scope.d.ts.map +1 -0
- package/dist/lib/extension/read-scope.js +131 -0
- package/dist/lib/insights/docs/describe-content-insights-api.d.ts +23 -0
- package/dist/lib/insights/docs/describe-content-insights-api.d.ts.map +1 -0
- package/dist/lib/insights/docs/describe-content-insights-api.js +329 -0
- package/dist/lib/mcp/content-tools.provider.d.ts.map +1 -1
- package/dist/lib/mcp/content-tools.provider.js +10 -9
- package/dist/lib/public-api/http/controllers/public-entry-writes.controller.d.ts +14 -13
- package/dist/lib/public-api/http/controllers/public-entry-writes.controller.d.ts.map +1 -1
- package/dist/lib/public-api/http/controllers/public-entry-writes.controller.js +62 -46
- package/dist/lib/public-api/http/guards/api-token-workspace.guard.d.ts.map +1 -1
- package/dist/lib/public-api/http/guards/api-token-workspace.guard.js +8 -0
- package/dist/lib/public-api/infrastructure/public-entries.query.d.ts +14 -1
- package/dist/lib/public-api/infrastructure/public-entries.query.d.ts.map +1 -1
- package/dist/lib/public-api/infrastructure/public-entries.query.js +20 -3
- package/dist/lib/public-api/infrastructure/public-entry-writes.service.d.ts +10 -9
- package/dist/lib/public-api/infrastructure/public-entry-writes.service.d.ts.map +1 -1
- package/dist/lib/public-api/infrastructure/public-entry-writes.service.js +23 -24
- package/dist/lib/public-api/infrastructure/public-expansion.query.d.ts +16 -4
- package/dist/lib/public-api/infrastructure/public-expansion.query.d.ts.map +1 -1
- package/dist/lib/public-api/infrastructure/public-expansion.query.js +29 -9
- package/dist/lib/public-api/infrastructure/token-actor.d.ts +37 -0
- package/dist/lib/public-api/infrastructure/token-actor.d.ts.map +1 -0
- package/dist/lib/public-api/infrastructure/token-actor.js +58 -0
- package/dist/lib/revisions/application/use-cases/restore-revision.use-case.d.ts.map +1 -1
- package/dist/lib/revisions/application/use-cases/restore-revision.use-case.js +23 -1
- package/dist/lib/revisions/infrastructure/persistence/revision-snapshot.d.ts +7 -1
- package/dist/lib/revisions/infrastructure/persistence/revision-snapshot.d.ts.map +1 -1
- package/dist/lib/revisions/infrastructure/persistence/revision-snapshot.js +9 -2
- package/dist/lib/revisions/infrastructure/purge/revisions-workspace.purger.d.ts +28 -0
- package/dist/lib/revisions/infrastructure/purge/revisions-workspace.purger.d.ts.map +1 -0
- package/dist/lib/revisions/infrastructure/purge/revisions-workspace.purger.js +52 -0
- package/dist/lib/revisions/types/revision-view.d.ts +11 -0
- package/dist/lib/revisions/types/revision-view.d.ts.map +1 -1
- package/dist/lib/utils/content-plugin.d.ts.map +1 -1
- package/dist/lib/utils/content-plugin.js +10 -1
- package/dist/lib/utils/content-views-plugin.d.ts +28 -0
- package/dist/lib/utils/content-views-plugin.d.ts.map +1 -0
- package/dist/lib/utils/content-views-plugin.js +37 -0
- package/dist/lib/views/application/queries/saved-views.query.d.ts +16 -0
- package/dist/lib/views/application/queries/saved-views.query.d.ts.map +1 -0
- package/dist/lib/views/application/queries/saved-views.query.js +46 -0
- package/dist/lib/views/application/saved-view-access.service.d.ts +30 -0
- package/dist/lib/views/application/saved-view-access.service.d.ts.map +1 -0
- package/dist/lib/views/application/saved-view-access.service.js +55 -0
- package/dist/lib/views/application/use-cases/create-saved-view.use-case.d.ts +30 -0
- package/dist/lib/views/application/use-cases/create-saved-view.use-case.d.ts.map +1 -0
- package/dist/lib/views/application/use-cases/create-saved-view.use-case.js +81 -0
- package/dist/lib/views/application/use-cases/delete-saved-view.use-case.d.ts +18 -0
- package/dist/lib/views/application/use-cases/delete-saved-view.use-case.d.ts.map +1 -0
- package/dist/lib/views/application/use-cases/delete-saved-view.use-case.js +56 -0
- package/dist/lib/views/application/use-cases/set-default-view.use-case.d.ts +23 -0
- package/dist/lib/views/application/use-cases/set-default-view.use-case.d.ts.map +1 -0
- package/dist/lib/views/application/use-cases/set-default-view.use-case.js +51 -0
- package/dist/lib/views/application/use-cases/update-saved-view.use-case.d.ts +24 -0
- package/dist/lib/views/application/use-cases/update-saved-view.use-case.d.ts.map +1 -0
- package/dist/lib/views/application/use-cases/update-saved-view.use-case.js +90 -0
- package/dist/lib/views/application/view-scope.service.d.ts +25 -0
- package/dist/lib/views/application/view-scope.service.d.ts.map +1 -0
- package/dist/lib/views/application/view-scope.service.js +45 -0
- package/dist/lib/views/content-views.module.d.ts +22 -0
- package/dist/lib/views/content-views.module.d.ts.map +1 -0
- package/dist/lib/views/content-views.module.js +63 -0
- package/dist/lib/views/domain/errors/index.d.ts +6 -0
- package/dist/lib/views/domain/errors/index.d.ts.map +1 -0
- package/dist/lib/views/domain/errors/index.js +12 -0
- package/dist/lib/views/domain/errors/saved-view-forbidden.error.d.ts +10 -0
- package/dist/lib/views/domain/errors/saved-view-forbidden.error.d.ts.map +1 -0
- package/dist/lib/views/domain/errors/saved-view-forbidden.error.js +16 -0
- package/dist/lib/views/domain/errors/saved-view-limit-error.d.ts +9 -0
- package/dist/lib/views/domain/errors/saved-view-limit-error.d.ts.map +1 -0
- package/dist/lib/views/domain/errors/saved-view-limit-error.js +16 -0
- package/dist/lib/views/domain/errors/saved-view-name-taken.error.d.ts +5 -0
- package/dist/lib/views/domain/errors/saved-view-name-taken.error.d.ts.map +1 -0
- package/dist/lib/views/domain/errors/saved-view-name-taken.error.js +11 -0
- package/dist/lib/views/domain/errors/saved-view-not-found.error.d.ts +9 -0
- package/dist/lib/views/domain/errors/saved-view-not-found.error.d.ts.map +1 -0
- package/dist/lib/views/domain/errors/saved-view-not-found.error.js +15 -0
- package/dist/lib/views/domain/events/saved-view-events.d.ts +28 -0
- package/dist/lib/views/domain/events/saved-view-events.d.ts.map +1 -0
- package/dist/lib/views/domain/events/saved-view-events.js +38 -0
- package/dist/lib/views/domain/saved-view.d.ts +66 -0
- package/dist/lib/views/domain/saved-view.d.ts.map +1 -0
- package/dist/lib/views/domain/saved-view.js +18 -0
- package/dist/lib/views/domain/saved-view.repository.d.ts +77 -0
- package/dist/lib/views/domain/saved-view.repository.d.ts.map +1 -0
- package/dist/lib/views/domain/saved-view.repository.js +5 -0
- package/dist/lib/views/http/controllers/saved-views.controller.d.ts +45 -0
- package/dist/lib/views/http/controllers/saved-views.controller.d.ts.map +1 -0
- package/dist/lib/views/http/controllers/saved-views.controller.js +216 -0
- package/dist/lib/views/http/controllers/to-http-error.d.ts +10 -0
- package/dist/lib/views/http/controllers/to-http-error.d.ts.map +1 -0
- package/dist/lib/views/http/controllers/to-http-error.js +26 -0
- package/dist/lib/views/http/dto/save-view.dto.d.ts +54 -0
- package/dist/lib/views/http/dto/save-view.dto.d.ts.map +1 -0
- package/dist/lib/views/http/dto/save-view.dto.js +230 -0
- package/dist/lib/views/http/dto/view-payload.validator.d.ts +20 -0
- package/dist/lib/views/http/dto/view-payload.validator.d.ts.map +1 -0
- package/dist/lib/views/http/dto/view-payload.validator.js +52 -0
- package/dist/lib/views/infrastructure/persistence/drizzle-saved-view.repository.d.ts +26 -0
- package/dist/lib/views/infrastructure/persistence/drizzle-saved-view.repository.d.ts.map +1 -0
- package/dist/lib/views/infrastructure/persistence/drizzle-saved-view.repository.js +135 -0
- package/dist/lib/views/infrastructure/schema/external-refs.d.ts +68 -0
- package/dist/lib/views/infrastructure/schema/external-refs.d.ts.map +1 -0
- package/dist/lib/views/infrastructure/schema/external-refs.js +29 -0
- package/dist/lib/views/infrastructure/schema/index.d.ts +8 -0
- package/dist/lib/views/infrastructure/schema/index.d.ts.map +1 -0
- package/dist/lib/views/infrastructure/schema/index.js +13 -0
- package/dist/lib/views/infrastructure/schema/saved-views.d.ts +275 -0
- package/dist/lib/views/infrastructure/schema/saved-views.d.ts.map +1 -0
- package/dist/lib/views/infrastructure/schema/saved-views.js +87 -0
- package/dist/lib/views/views.constants.d.ts +26 -0
- package/dist/lib/views/views.constants.d.ts.map +1 -0
- package/dist/lib/views/views.constants.js +28 -0
- package/dist/lib/views/views.tokens.d.ts +17 -0
- package/dist/lib/views/views.tokens.d.ts.map +1 -0
- package/dist/lib/views/views.tokens.js +21 -0
- package/migrations/0000_saved_views.sql +29 -0
- package/migrations/meta/0000_snapshot.json +256 -0
- package/migrations/meta/_journal.json +13 -0
- package/package.json +13 -12
- package/dist/lib/entries/controllers/bulk-entries.controller.d.ts +0 -26
- package/dist/lib/entries/controllers/bulk-entries.controller.d.ts.map +0 -1
- package/dist/lib/entries/controllers/create-entry.controller.d.ts +0 -20
- package/dist/lib/entries/controllers/create-entry.controller.d.ts.map +0 -1
- package/dist/lib/entries/controllers/delete-entry.controller.d.ts +0 -24
- package/dist/lib/entries/controllers/delete-entry.controller.d.ts.map +0 -1
- package/dist/lib/entries/controllers/get-entry.controller.d.ts +0 -34
- package/dist/lib/entries/controllers/get-entry.controller.d.ts.map +0 -1
- package/dist/lib/entries/controllers/list-entries.controller.d.ts +0 -20
- package/dist/lib/entries/controllers/list-entries.controller.d.ts.map +0 -1
- package/dist/lib/entries/controllers/publish-entry.controller.d.ts +0 -19
- package/dist/lib/entries/controllers/publish-entry.controller.d.ts.map +0 -1
- package/dist/lib/entries/controllers/resolve-type.d.ts +0 -9
- package/dist/lib/entries/controllers/resolve-type.d.ts.map +0 -1
- package/dist/lib/entries/controllers/update-entry.controller.d.ts +0 -18
- package/dist/lib/entries/controllers/update-entry.controller.d.ts.map +0 -1
- package/dist/lib/entries/dto/bulk-ids.dto.d.ts +0 -11
- package/dist/lib/entries/dto/bulk-ids.dto.d.ts.map +0 -1
- package/dist/lib/entries/dto/list-entries-query.dto.d.ts +0 -46
- package/dist/lib/entries/dto/list-entries-query.dto.d.ts.map +0 -1
- package/dist/lib/entries/dto/relation-delta-map.validator.d.ts +0 -19
- package/dist/lib/entries/dto/relation-delta-map.validator.d.ts.map +0 -1
- package/dist/lib/entries/dto/save-entry.dto.d.ts +0 -46
- package/dist/lib/entries/dto/save-entry.dto.d.ts.map +0 -1
- package/dist/lib/entries/infrastructure/persistence/field-selection.d.ts +0 -24
- package/dist/lib/entries/infrastructure/persistence/field-selection.d.ts.map +0 -1
- package/dist/lib/entries/infrastructure/queries/entry-filter-schema.d.ts +0 -40
- package/dist/lib/entries/infrastructure/queries/entry-filter-schema.d.ts.map +0 -1
- package/dist/lib/entries/services/entries.service.d.ts +0 -59
- package/dist/lib/entries/services/entries.service.d.ts.map +0 -1
- package/dist/lib/entries/services/entry-counter.service.d.ts +0 -31
- package/dist/lib/entries/services/entry-counter.service.d.ts.map +0 -1
- package/dist/lib/entries/services/entry-filter-schema.d.ts +0 -32
- package/dist/lib/entries/services/entry-filter-schema.d.ts.map +0 -1
- package/dist/lib/entries/services/entry-row.d.ts +0 -56
- package/dist/lib/entries/services/entry-row.d.ts.map +0 -1
- package/dist/lib/entries/services/entry-writer.service.d.ts +0 -193
- package/dist/lib/entries/services/entry-writer.service.d.ts.map +0 -1
- package/dist/lib/entries/services/relation-link.service.d.ts +0 -115
- package/dist/lib/entries/services/relation-link.service.d.ts.map +0 -1
- package/dist/lib/extension/per-locale-relation.d.ts +0 -18
- package/dist/lib/extension/per-locale-relation.d.ts.map +0 -1
- package/dist/lib/public/controllers/get-public-entry.controller.d.ts +0 -26
- package/dist/lib/public/controllers/get-public-entry.controller.d.ts.map +0 -1
- package/dist/lib/public/controllers/list-public-entries.controller.d.ts +0 -24
- package/dist/lib/public/controllers/list-public-entries.controller.d.ts.map +0 -1
- package/dist/lib/public/controllers/public-schema.controller.d.ts +0 -18
- package/dist/lib/public/controllers/public-schema.controller.d.ts.map +0 -1
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The **read scope port** — the seam a downstream plugin uses to narrow what
|
|
4
|
+
* the public content API returns, without this package knowing why.
|
|
5
|
+
*
|
|
6
|
+
* Content-server declares the port and consults it from `PublicEntriesQuery`
|
|
7
|
+
* and `PublicExpansionQuery`; an implementing plugin
|
|
8
|
+
* (`@orthacms/segments-server`, for reader entitlements) registers a scope
|
|
9
|
+
* through {@link contentReadScopeRegistrar}. Every fragment returned is AND-ed
|
|
10
|
+
* onto the visibility predicate the public read already states, so a scope can
|
|
11
|
+
* only ever *subtract* rows — there is no shape of return value that widens a
|
|
12
|
+
* read.
|
|
13
|
+
*
|
|
14
|
+
* ## Why a registry rather than a DI token
|
|
15
|
+
*
|
|
16
|
+
* The port takes any number of independent narrowings, and Nest has **no
|
|
17
|
+
* multi-provider**: two dynamic modules binding the same token do not merge,
|
|
18
|
+
* the second silently replaces the first. A second scoping plugin would
|
|
19
|
+
* therefore switch the first one off, with nothing to notice it — which for a
|
|
20
|
+
* visibility rule means content quietly becoming visible. So registration is a
|
|
21
|
+
* runtime `register(...)` call against a registry this module owns, the same
|
|
22
|
+
* shape and the same reason as `copilotToolsRegistrar`.
|
|
23
|
+
*
|
|
24
|
+
* ## Why not `CONTENT_ENTRY_EXTENSION`
|
|
25
|
+
*
|
|
26
|
+
* That port is documented as a **single binding**: one provider per app, and
|
|
27
|
+
* i18n already holds it. Its own note suggests binding a composite when a
|
|
28
|
+
* second extension appears, and for a write-pipeline extension that composes
|
|
29
|
+
* cleanly — but "narrow a read" and "extend a write" are different
|
|
30
|
+
* responsibilities with different failure modes. A composite would fuse i18n
|
|
31
|
+
* and entitlements into one provider, where a fault in either silently drops
|
|
32
|
+
* the other's clause.
|
|
33
|
+
*
|
|
34
|
+
* ## Two constraints on an implementation
|
|
35
|
+
*
|
|
36
|
+
* **Synchronous.** The predicate is assembled inside the query builder, and
|
|
37
|
+
* making that path async would ripple through every public read for the benefit
|
|
38
|
+
* of one provider. A scope that needs I/O — resolving who the caller is, say —
|
|
39
|
+
* must do it earlier in the request (a guard, an interceptor, middleware) and
|
|
40
|
+
* read the result from its own request-scoped state here.
|
|
41
|
+
*
|
|
42
|
+
* **Public reads only.** These fragments are not applied to the admin's own
|
|
43
|
+
* entries list. An admin caller is a member of the workspace looking at their
|
|
44
|
+
* own CMS, while a reader entitlement is about who may *consume* published
|
|
45
|
+
* content, and scoping the editor's list by it would hide from an author the
|
|
46
|
+
* very rows they are responsible for. The same split content grants already
|
|
47
|
+
* make.
|
|
48
|
+
*/
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.ContentReadScopeRegistry = void 0;
|
|
51
|
+
exports.contentReadScopeRegistrar = contentReadScopeRegistrar;
|
|
52
|
+
const tslib_1 = require("tslib");
|
|
53
|
+
const common_1 = require("@nestjs/common");
|
|
54
|
+
/**
|
|
55
|
+
* Every registered narrowing, in registration order.
|
|
56
|
+
*
|
|
57
|
+
* Order does not affect the result — the fragments are AND-ed — but it is kept
|
|
58
|
+
* stable so a query log reads the same way twice.
|
|
59
|
+
*/
|
|
60
|
+
let ContentReadScopeRegistry = class ContentReadScopeRegistry {
|
|
61
|
+
scopes = [];
|
|
62
|
+
/** Adds a scope. Registering the same instance twice is a no-op. */
|
|
63
|
+
register(scope) {
|
|
64
|
+
if (!this.scopes.includes(scope)) {
|
|
65
|
+
this.scopes.push(scope);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/** Every registered scope. Empty on an installation with none. */
|
|
69
|
+
all() {
|
|
70
|
+
return this.scopes;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The fragments for one read, ready to be spread into `and(...)`.
|
|
74
|
+
*
|
|
75
|
+
* Returns an empty array — not a fragment matching everything — when
|
|
76
|
+
* nothing is registered, which is the state every installation without a
|
|
77
|
+
* scoping plugin stays in.
|
|
78
|
+
*/
|
|
79
|
+
fragments(context) {
|
|
80
|
+
if (!this.scopes.length) {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
return this.scopes.map((scope) => scope.scope(context));
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
exports.ContentReadScopeRegistry = ContentReadScopeRegistry;
|
|
87
|
+
exports.ContentReadScopeRegistry = ContentReadScopeRegistry = tslib_1.__decorate([
|
|
88
|
+
(0, common_1.Injectable)()
|
|
89
|
+
], ContentReadScopeRegistry);
|
|
90
|
+
/** Registers a plugin's read scopes with content at bootstrap. */
|
|
91
|
+
class ReadScopeBootstrapper {
|
|
92
|
+
label;
|
|
93
|
+
registry;
|
|
94
|
+
scopes;
|
|
95
|
+
logger = new common_1.Logger(ReadScopeBootstrapper.name);
|
|
96
|
+
constructor(label, registry, scopes) {
|
|
97
|
+
this.label = label;
|
|
98
|
+
this.registry = registry;
|
|
99
|
+
this.scopes = scopes;
|
|
100
|
+
}
|
|
101
|
+
onApplicationBootstrap() {
|
|
102
|
+
// A deployment that does not register `ContentPlugin` is not a real
|
|
103
|
+
// configuration, but a binding plugin should still boot rather than
|
|
104
|
+
// fail on an injection it cannot influence.
|
|
105
|
+
if (!this.registry) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
for (const scope of this.scopes) {
|
|
109
|
+
this.registry.register(scope);
|
|
110
|
+
}
|
|
111
|
+
this.logger.log(`Registered the ${this.label} read scope with the content API.`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Builds the DI provider that registers `scopes` with content's read-scope
|
|
116
|
+
* registry at bootstrap.
|
|
117
|
+
*
|
|
118
|
+
* A factory with an explicit `inject` list rather than a class with reflected
|
|
119
|
+
* parameters, for the reason `copilotToolsRegistrar` documents: an optional
|
|
120
|
+
* dependency typed as `Foo | null` emits `Object` for `design:paramtypes`, Nest
|
|
121
|
+
* injects `undefined` with no error, and the plugin ends up registering
|
|
122
|
+
* nothing. Here that failure would mean a visibility rule that silently stopped
|
|
123
|
+
* being applied.
|
|
124
|
+
*/
|
|
125
|
+
function contentReadScopeRegistrar(label, ...scopes) {
|
|
126
|
+
return {
|
|
127
|
+
provide: `CONTENT_READ_SCOPE_REGISTRAR_${label.toUpperCase()}`,
|
|
128
|
+
useFactory: (registry, ...resolved) => new ReadScopeBootstrapper(label, registry, resolved),
|
|
129
|
+
inject: [{ token: ContentReadScopeRegistry, optional: true }, ...scopes]
|
|
130
|
+
};
|
|
131
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The content-insights pass over the host's OpenAPI document.
|
|
3
|
+
*
|
|
4
|
+
* Six widgets, six **unlike** payloads. They share a prefix and nothing else:
|
|
5
|
+
* one is a stat tile with two sparklines, one a sparse 7×24 grid, one a fixed
|
|
6
|
+
* set of age buckets, one a time series with a self-describing bucket width.
|
|
7
|
+
* Reading a family resemblance into them and describing them from one schema is
|
|
8
|
+
* how a document ends up confidently wrong, so each is written out.
|
|
9
|
+
*
|
|
10
|
+
* Separate from `docs/describe-content-api.ts` because it describes a separate
|
|
11
|
+
* surface: `/insights/*` is grouped under its own `insights` tag in the
|
|
12
|
+
* reference (the host tags by first route segment), and the widgets are read by
|
|
13
|
+
* the Insights page rather than by anything reading content.
|
|
14
|
+
*
|
|
15
|
+
* Pure: it takes the document and mutates only these six operations.
|
|
16
|
+
*/
|
|
17
|
+
import type { OpenApiDocument } from '@orthacms/bootstrap-server';
|
|
18
|
+
import type { OpenApiSchema } from '../../docs/field-schema';
|
|
19
|
+
/** The schemas this pass adds, keyed by component name. */
|
|
20
|
+
export declare function buildContentInsightsSchemas(): Record<string, OpenApiSchema>;
|
|
21
|
+
/** Adds the content-insights schemas and describes the six widget routes. */
|
|
22
|
+
export declare function describeContentInsightsApi(document: OpenApiDocument): void;
|
|
23
|
+
//# sourceMappingURL=describe-content-insights-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe-content-insights-api.d.ts","sourceRoot":"","sources":["../../../../src/lib/insights/docs/describe-content-insights-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAyP7D,2DAA2D;AAC3D,wBAAgB,2BAA2B,IAAI,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAS3E;AA6DD,6EAA6E;AAC7E,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CA2B1E"}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The content-insights pass over the host's OpenAPI document.
|
|
4
|
+
*
|
|
5
|
+
* Six widgets, six **unlike** payloads. They share a prefix and nothing else:
|
|
6
|
+
* one is a stat tile with two sparklines, one a sparse 7×24 grid, one a fixed
|
|
7
|
+
* set of age buckets, one a time series with a self-describing bucket width.
|
|
8
|
+
* Reading a family resemblance into them and describing them from one schema is
|
|
9
|
+
* how a document ends up confidently wrong, so each is written out.
|
|
10
|
+
*
|
|
11
|
+
* Separate from `docs/describe-content-api.ts` because it describes a separate
|
|
12
|
+
* surface: `/insights/*` is grouped under its own `insights` tag in the
|
|
13
|
+
* reference (the host tags by first route segment), and the widgets are read by
|
|
14
|
+
* the Insights page rather than by anything reading content.
|
|
15
|
+
*
|
|
16
|
+
* Pure: it takes the document and mutates only these six operations.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.buildContentInsightsSchemas = buildContentInsightsSchemas;
|
|
20
|
+
exports.describeContentInsightsApi = describeContentInsightsApi;
|
|
21
|
+
const content_schemas_1 = require("../../docs/content-schemas");
|
|
22
|
+
/** The bucket widths a series picks from, by window length. */
|
|
23
|
+
const GRANULARITY = {
|
|
24
|
+
type: 'string',
|
|
25
|
+
enum: ['day', 'week', 'month'],
|
|
26
|
+
description: 'Chosen from the window, not requested: up to 31 days is `day`, up to 120 is `week`, longer is `month`. A year grouped by day would be 365 points for a sparkline 64 pixels wide.'
|
|
27
|
+
};
|
|
28
|
+
/** One point on a time series. */
|
|
29
|
+
const SERIES_POINT = {
|
|
30
|
+
type: 'object',
|
|
31
|
+
required: ['bucket', 'value'],
|
|
32
|
+
properties: {
|
|
33
|
+
bucket: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: 'Bucket start, `YYYY-MM-DD`. The client formats it.',
|
|
36
|
+
example: '2026-09-04'
|
|
37
|
+
},
|
|
38
|
+
value: { type: 'integer' }
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* The headline counts.
|
|
43
|
+
*
|
|
44
|
+
* There is deliberately no `draftsDelta` beside the other two: a draft's count
|
|
45
|
+
* changes when a row is *published*, and a row that moved back to draft leaves
|
|
46
|
+
* no trace on the collection table. Reporting one would mean inventing it.
|
|
47
|
+
*/
|
|
48
|
+
const TOTALS = {
|
|
49
|
+
type: 'object',
|
|
50
|
+
required: [
|
|
51
|
+
'entries',
|
|
52
|
+
'published',
|
|
53
|
+
'drafts',
|
|
54
|
+
'entriesDelta',
|
|
55
|
+
'publishedDelta',
|
|
56
|
+
'entriesHistory',
|
|
57
|
+
'publishedHistory'
|
|
58
|
+
],
|
|
59
|
+
properties: {
|
|
60
|
+
entries: {
|
|
61
|
+
type: 'integer',
|
|
62
|
+
description: 'Every non-deleted entry in the workspace.'
|
|
63
|
+
},
|
|
64
|
+
published: { type: 'integer', description: 'Entries currently live.' },
|
|
65
|
+
drafts: { type: 'integer', description: 'Entries currently in draft.' },
|
|
66
|
+
entriesDelta: {
|
|
67
|
+
type: 'integer',
|
|
68
|
+
description: 'Entries created within the window.'
|
|
69
|
+
},
|
|
70
|
+
publishedDelta: {
|
|
71
|
+
type: 'integer',
|
|
72
|
+
description: 'Entries first published within the window.'
|
|
73
|
+
},
|
|
74
|
+
entriesHistory: {
|
|
75
|
+
type: 'array',
|
|
76
|
+
items: { type: 'integer' },
|
|
77
|
+
description: 'Cumulative entry count across the window, oldest bucket first — the sparkline.'
|
|
78
|
+
},
|
|
79
|
+
publishedHistory: {
|
|
80
|
+
type: 'array',
|
|
81
|
+
items: { type: 'integer' },
|
|
82
|
+
description: 'Cumulative published count, oldest bucket first.'
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
/** Draft/published split per content type. */
|
|
87
|
+
const PIPELINE = {
|
|
88
|
+
type: 'object',
|
|
89
|
+
required: ['types'],
|
|
90
|
+
properties: {
|
|
91
|
+
types: {
|
|
92
|
+
type: 'array',
|
|
93
|
+
description: 'One row per type that has at least one entry, biggest first. A type the workspace has never used is omitted, not listed at zero.',
|
|
94
|
+
items: {
|
|
95
|
+
type: 'object',
|
|
96
|
+
required: ['name', 'label', 'published', 'drafts'],
|
|
97
|
+
properties: {
|
|
98
|
+
name: { type: 'string' },
|
|
99
|
+
label: { type: 'string' },
|
|
100
|
+
published: { type: 'integer' },
|
|
101
|
+
drafts: { type: 'integer' }
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
/** Entries published per bucket. */
|
|
108
|
+
const VELOCITY = {
|
|
109
|
+
type: 'object',
|
|
110
|
+
required: ['points', 'granularity'],
|
|
111
|
+
properties: {
|
|
112
|
+
points: {
|
|
113
|
+
type: 'array',
|
|
114
|
+
items: SERIES_POINT,
|
|
115
|
+
description: 'Oldest bucket first.'
|
|
116
|
+
},
|
|
117
|
+
granularity: GRANULARITY
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Editing activity by weekday and hour.
|
|
122
|
+
*
|
|
123
|
+
* Only non-empty cells come back — a full grid is 168 of them and most are
|
|
124
|
+
* zero — so `max` travels with them: recomputing the busiest value from a
|
|
125
|
+
* sparse list gives the wrong denominator whenever the grid is empty.
|
|
126
|
+
*/
|
|
127
|
+
const PUNCHCARD = {
|
|
128
|
+
type: 'object',
|
|
129
|
+
required: ['cells', 'max', 'total'],
|
|
130
|
+
properties: {
|
|
131
|
+
cells: {
|
|
132
|
+
type: 'array',
|
|
133
|
+
description: 'The non-empty slots only; the client fills the gaps.',
|
|
134
|
+
items: {
|
|
135
|
+
type: 'object',
|
|
136
|
+
required: ['weekday', 'hour', 'count'],
|
|
137
|
+
properties: {
|
|
138
|
+
weekday: {
|
|
139
|
+
type: 'integer',
|
|
140
|
+
minimum: 1,
|
|
141
|
+
maximum: 7,
|
|
142
|
+
description: 'ISO weekday: 1 = Monday … 7 = Sunday.'
|
|
143
|
+
},
|
|
144
|
+
hour: {
|
|
145
|
+
type: 'integer',
|
|
146
|
+
minimum: 0,
|
|
147
|
+
maximum: 23,
|
|
148
|
+
description: 'Hour of day in the database session’s timezone (UTC).'
|
|
149
|
+
},
|
|
150
|
+
count: {
|
|
151
|
+
type: 'integer',
|
|
152
|
+
description: 'Revisions written in that slot.'
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
max: {
|
|
158
|
+
type: 'integer',
|
|
159
|
+
description: 'The busiest cell’s count, or 0 when there is no activity.'
|
|
160
|
+
},
|
|
161
|
+
total: { type: 'integer', description: 'Revisions across the window.' }
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Published entries by how long ago they were last edited.
|
|
166
|
+
*
|
|
167
|
+
* The five buckets are fixed and always all present, in this order, zeros
|
|
168
|
+
* included — the query builds them from a constant table rather than from what
|
|
169
|
+
* it found — so they are an enum rather than a free string.
|
|
170
|
+
*/
|
|
171
|
+
const STALE = {
|
|
172
|
+
type: 'object',
|
|
173
|
+
required: ['buckets', 'total'],
|
|
174
|
+
properties: {
|
|
175
|
+
buckets: {
|
|
176
|
+
type: 'array',
|
|
177
|
+
description: 'Always these five, freshest first, whether or not they hold anything. Only live content is counted: an untouched draft is a draft, not a neglected page.',
|
|
178
|
+
items: {
|
|
179
|
+
type: 'object',
|
|
180
|
+
required: ['id', 'count'],
|
|
181
|
+
properties: {
|
|
182
|
+
id: {
|
|
183
|
+
type: 'string',
|
|
184
|
+
enum: ['d30', 'd90', 'd180', 'd365', 'older'],
|
|
185
|
+
description: 'Age band of the last edit, in days: up to 30, up to 90, up to 180, up to 365, then everything older.'
|
|
186
|
+
},
|
|
187
|
+
count: { type: 'integer' }
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
total: {
|
|
192
|
+
type: 'integer',
|
|
193
|
+
description: 'Across all buckets, so the client needn’t re-add them.'
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Live content with unpublished edits on top.
|
|
199
|
+
*
|
|
200
|
+
* `status` alone cannot separate "never published" from "published, then
|
|
201
|
+
* edited" — `publishedAt` is stamped on the first publish and cleared only by
|
|
202
|
+
* an unpublish, so draft + a timestamp is the admin's **Modified** badge and
|
|
203
|
+
* draft + no timestamp is a draft nobody ever shipped. That is the whole reason
|
|
204
|
+
* this endpoint exists, and why the three totals are not derivable from the
|
|
205
|
+
* pipeline's.
|
|
206
|
+
*/
|
|
207
|
+
const UNSHIPPED = {
|
|
208
|
+
type: 'object',
|
|
209
|
+
required: ['types', 'modified', 'live', 'neverPublished'],
|
|
210
|
+
properties: {
|
|
211
|
+
types: {
|
|
212
|
+
type: 'array',
|
|
213
|
+
description: 'One row per publishable type holding at least one modified entry. A type with nothing pending is omitted.',
|
|
214
|
+
items: {
|
|
215
|
+
type: 'object',
|
|
216
|
+
required: ['name', 'label', 'modified', 'published'],
|
|
217
|
+
properties: {
|
|
218
|
+
name: { type: 'string' },
|
|
219
|
+
label: { type: 'string' },
|
|
220
|
+
modified: {
|
|
221
|
+
type: 'integer',
|
|
222
|
+
description: 'Live entries with unpublished edits.'
|
|
223
|
+
},
|
|
224
|
+
published: {
|
|
225
|
+
type: 'integer',
|
|
226
|
+
description: 'Live entries with nothing pending.'
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
modified: {
|
|
232
|
+
type: 'integer',
|
|
233
|
+
description: 'Modified entries across the workspace.'
|
|
234
|
+
},
|
|
235
|
+
live: {
|
|
236
|
+
type: 'integer',
|
|
237
|
+
description: 'Entries with a live version at all (`modified` + fully published).'
|
|
238
|
+
},
|
|
239
|
+
neverPublished: {
|
|
240
|
+
type: 'integer',
|
|
241
|
+
description: 'Drafts that have never gone live.'
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
/** The schemas this pass adds, keyed by component name. */
|
|
246
|
+
function buildContentInsightsSchemas() {
|
|
247
|
+
return {
|
|
248
|
+
InsightsContentTotals: TOTALS,
|
|
249
|
+
InsightsContentPipeline: PIPELINE,
|
|
250
|
+
InsightsContentVelocity: VELOCITY,
|
|
251
|
+
InsightsContentPunchcard: PUNCHCARD,
|
|
252
|
+
InsightsContentStale: STALE,
|
|
253
|
+
InsightsContentUnshipped: UNSHIPPED
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
/** The routes, keyed by what follows `/insights/content`. */
|
|
257
|
+
const ROUTES = {
|
|
258
|
+
'/totals': {
|
|
259
|
+
schema: 'InsightsContentTotals',
|
|
260
|
+
description: 'Headline counts, their deltas over the window, and the sparklines.'
|
|
261
|
+
},
|
|
262
|
+
'/pipeline': {
|
|
263
|
+
schema: 'InsightsContentPipeline',
|
|
264
|
+
description: 'Draft/published split per content type.'
|
|
265
|
+
},
|
|
266
|
+
'/velocity': {
|
|
267
|
+
schema: 'InsightsContentVelocity',
|
|
268
|
+
description: 'Entries published per bucket, oldest first.'
|
|
269
|
+
},
|
|
270
|
+
'/punchcard': {
|
|
271
|
+
schema: 'InsightsContentPunchcard',
|
|
272
|
+
description: 'Editing activity by weekday and hour.'
|
|
273
|
+
},
|
|
274
|
+
'/stale': {
|
|
275
|
+
schema: 'InsightsContentStale',
|
|
276
|
+
description: 'Published entries by how long ago they were last edited.'
|
|
277
|
+
},
|
|
278
|
+
'/unshipped': {
|
|
279
|
+
schema: 'InsightsContentUnshipped',
|
|
280
|
+
description: 'Live entries with unpublished edits, and what has never shipped.'
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
/**
|
|
284
|
+
* Matches `<prefix>/insights/content<rest>`.
|
|
285
|
+
*
|
|
286
|
+
* The prefix is matched as segments carrying no `{`, so a nested route that
|
|
287
|
+
* merely ends the same way is not described with these shapes.
|
|
288
|
+
*/
|
|
289
|
+
const ROUTE_RE = /^(?:\/[^/{}]+)*\/insights\/content(\/.*)?$/;
|
|
290
|
+
/**
|
|
291
|
+
* Writes the schema onto whichever 2xx key the scanner emitted, never inventing
|
|
292
|
+
* one. These are all `@Get`s, so it is a 200 in practice.
|
|
293
|
+
*/
|
|
294
|
+
function setSuccessResponse(operation, schema, description) {
|
|
295
|
+
const responses = operation.responses ?? {};
|
|
296
|
+
const key = Object.keys(responses).find((code) => /^2\d\d$/.test(code));
|
|
297
|
+
if (!key || key === '204') {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
responses[key] = {
|
|
301
|
+
description,
|
|
302
|
+
content: { 'application/json': { schema } }
|
|
303
|
+
};
|
|
304
|
+
operation.responses = responses;
|
|
305
|
+
}
|
|
306
|
+
/** Adds the content-insights schemas and describes the six widget routes. */
|
|
307
|
+
function describeContentInsightsApi(document) {
|
|
308
|
+
document.components ??= {};
|
|
309
|
+
document.components.schemas ??= {};
|
|
310
|
+
Object.assign(document.components.schemas, buildContentInsightsSchemas());
|
|
311
|
+
for (const [route, item] of Object.entries(document.paths)) {
|
|
312
|
+
const match = ROUTE_RE.exec(route);
|
|
313
|
+
if (!match) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
const spec = ROUTES[match[1] ?? ''];
|
|
317
|
+
if (!spec) {
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
for (const [method, operation] of Object.entries(item)) {
|
|
321
|
+
if (method !== 'get' ||
|
|
322
|
+
!operation ||
|
|
323
|
+
typeof operation !== 'object') {
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
setSuccessResponse(operation, (0, content_schemas_1.ref)(spec.schema), spec.description);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-tools.provider.d.ts","sourceRoot":"","sources":["../../../src/lib/mcp/content-tools.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,YAAY,EAEf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACH,YAAY,EACZ,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EACpB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"content-tools.provider.d.ts","sourceRoot":"","sources":["../../../src/lib/mcp/content-tools.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,YAAY,EAEf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACH,YAAY,EACZ,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EACpB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,KAAK,EACR,mBAAmB,EAEtB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAC;AAEvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,mDAAmD,CAAC;AACvF,OAAO,EAAE,wBAAwB,EAAE,MAAM,0DAA0D,CAAC;AAoCpG;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBACa,mBAAoB,YAAW,YAAY,EAAE,YAAY;IAG9D,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACX,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;gBAJzB,QAAQ,EAAE,mBAAmB,EAC7B,MAAM,EAAE,oBAAoB,EAC5B,OAAO,EAAE,kBAAkB,EAC3B,MAAM,EAAE,wBAAwB,EACpB,YAAY,CAAC,EAAE,YAAY,YAAA;IAG5D;;;;OAIG;IACH,YAAY,IAAI,IAAI;IAIpB;;;;;;;;;OASG;IACH,KAAK,IAAI,SAAS,cAAc,EAAE;IAOlC,iEAAiE;IACjE,OAAO,CAAC,QAAQ;IAsahB;;;;OAIG;IACG,SAAS,CACX,OAAO,EAAE,WAAW,GACrB,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC;IAUzC,qCAAqC;IAC/B,YAAY,CACd,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,WAAW,GACrB,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAgBxC,8CAA8C;YAChC,gBAAgB;IAO9B,+DAA+D;IAC/D,OAAO,CAAC,OAAO;IASf;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY;CA6BvB"}
|
|
@@ -6,6 +6,7 @@ const common_1 = require("@nestjs/common");
|
|
|
6
6
|
const identity_server_1 = require("@orthacms/identity-server");
|
|
7
7
|
const tools_server_1 = require("@orthacms/tools-server");
|
|
8
8
|
const content_tokens_1 = require("../content.tokens");
|
|
9
|
+
const token_actor_1 = require("../public-api/infrastructure/token-actor");
|
|
9
10
|
const workspace_grants_query_1 = require("../content-types/queries/workspace-grants.query");
|
|
10
11
|
const resolve_granted_type_1 = require("../public-api/http/controllers/resolve-granted-type");
|
|
11
12
|
const public_entries_query_1 = require("../public-api/infrastructure/public-entries.query");
|
|
@@ -201,7 +202,7 @@ let ContentToolProvider = class ContentToolProvider {
|
|
|
201
202
|
handler: async (input, context) => {
|
|
202
203
|
const { type, granted } = await this.resolve((0, tool_input_1.requireTypeName)(input), context);
|
|
203
204
|
const body = await (0, tool_input_1.validateToolInput)(public_save_entry_dto_1.PublicSaveEntryDto, input);
|
|
204
|
-
return this.writes.create(type, body, context.workspaceId, granted);
|
|
205
|
+
return this.writes.create(type, body, context.workspaceId, granted, (0, token_actor_1.toToolEventActor)(context.actor));
|
|
205
206
|
}
|
|
206
207
|
},
|
|
207
208
|
{
|
|
@@ -224,7 +225,7 @@ let ContentToolProvider = class ContentToolProvider {
|
|
|
224
225
|
? {}
|
|
225
226
|
: { relations: input['relations'] })
|
|
226
227
|
});
|
|
227
|
-
return this.writes.update(type, (0, tool_input_1.requireLocator)(input), body, context.workspaceId, granted, localeArg(input));
|
|
228
|
+
return this.writes.update(type, (0, tool_input_1.requireLocator)(input), body, context.workspaceId, granted, localeArg(input), (0, token_actor_1.toToolEventActor)(context.actor));
|
|
228
229
|
}
|
|
229
230
|
},
|
|
230
231
|
{
|
|
@@ -236,7 +237,7 @@ let ContentToolProvider = class ContentToolProvider {
|
|
|
236
237
|
readOnly: false,
|
|
237
238
|
handler: async (input, context) => {
|
|
238
239
|
const { type, granted } = await this.resolve((0, tool_input_1.requireTypeName)(input), context);
|
|
239
|
-
return this.writes.publish(type, (0, tool_input_1.requireLocator)(input), context.workspaceId, granted, localeArg(input));
|
|
240
|
+
return this.writes.publish(type, (0, tool_input_1.requireLocator)(input), context.workspaceId, granted, localeArg(input), (0, token_actor_1.toToolEventActor)(context.actor));
|
|
240
241
|
}
|
|
241
242
|
},
|
|
242
243
|
{
|
|
@@ -248,7 +249,7 @@ let ContentToolProvider = class ContentToolProvider {
|
|
|
248
249
|
readOnly: false,
|
|
249
250
|
handler: async (input, context) => {
|
|
250
251
|
const { type, granted } = await this.resolve((0, tool_input_1.requireTypeName)(input), context);
|
|
251
|
-
return this.writes.unpublish(type, (0, tool_input_1.requireLocator)(input), context.workspaceId, granted, localeArg(input));
|
|
252
|
+
return this.writes.unpublish(type, (0, tool_input_1.requireLocator)(input), context.workspaceId, granted, localeArg(input), (0, token_actor_1.toToolEventActor)(context.actor));
|
|
252
253
|
}
|
|
253
254
|
},
|
|
254
255
|
{
|
|
@@ -261,7 +262,7 @@ let ContentToolProvider = class ContentToolProvider {
|
|
|
261
262
|
destructive: true,
|
|
262
263
|
handler: async (input, context) => {
|
|
263
264
|
const { type } = await this.resolve((0, tool_input_1.requireTypeName)(input), context);
|
|
264
|
-
await this.writes.remove(type, (0, tool_input_1.requireLocator)(input), context.workspaceId, localeArg(input));
|
|
265
|
+
await this.writes.remove(type, (0, tool_input_1.requireLocator)(input), context.workspaceId, localeArg(input), (0, token_actor_1.toToolEventActor)(context.actor));
|
|
265
266
|
return { deleted: true };
|
|
266
267
|
}
|
|
267
268
|
},
|
|
@@ -288,7 +289,7 @@ let ContentToolProvider = class ContentToolProvider {
|
|
|
288
289
|
const body = await (0, tool_input_1.validateToolInput)(public_bulk_dto_1.PublicBulkSaveDto, {
|
|
289
290
|
items: input['items']
|
|
290
291
|
});
|
|
291
|
-
return this.writes.bulkSave(type, body.items, context.workspaceId, granted);
|
|
292
|
+
return this.writes.bulkSave(type, body.items, context.workspaceId, granted, (0, token_actor_1.toToolEventActor)(context.actor));
|
|
292
293
|
}
|
|
293
294
|
},
|
|
294
295
|
{
|
|
@@ -303,7 +304,7 @@ let ContentToolProvider = class ContentToolProvider {
|
|
|
303
304
|
const body = await (0, tool_input_1.validateToolInput)(public_bulk_dto_1.PublicBulkIdsDto, {
|
|
304
305
|
ids: input['ids']
|
|
305
306
|
});
|
|
306
|
-
return this.writes.bulkPublish(type, body.ids, context.workspaceId);
|
|
307
|
+
return this.writes.bulkPublish(type, body.ids, context.workspaceId, (0, token_actor_1.toToolEventActor)(context.actor));
|
|
307
308
|
}
|
|
308
309
|
},
|
|
309
310
|
{
|
|
@@ -318,7 +319,7 @@ let ContentToolProvider = class ContentToolProvider {
|
|
|
318
319
|
const body = await (0, tool_input_1.validateToolInput)(public_bulk_dto_1.PublicBulkIdsDto, {
|
|
319
320
|
ids: input['ids']
|
|
320
321
|
});
|
|
321
|
-
return this.writes.bulkUnpublish(type, body.ids, context.workspaceId);
|
|
322
|
+
return this.writes.bulkUnpublish(type, body.ids, context.workspaceId, (0, token_actor_1.toToolEventActor)(context.actor));
|
|
322
323
|
}
|
|
323
324
|
},
|
|
324
325
|
{
|
|
@@ -334,7 +335,7 @@ let ContentToolProvider = class ContentToolProvider {
|
|
|
334
335
|
const body = await (0, tool_input_1.validateToolInput)(public_bulk_dto_1.PublicBulkIdsDto, {
|
|
335
336
|
ids: input['ids']
|
|
336
337
|
});
|
|
337
|
-
return this.writes.bulkRemove(type, body.ids, context.workspaceId);
|
|
338
|
+
return this.writes.bulkRemove(type, body.ids, context.workspaceId, (0, token_actor_1.toToolEventActor)(context.actor));
|
|
338
339
|
}
|
|
339
340
|
}
|
|
340
341
|
];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ContentTypeRegistry } from '../../../registry/content-type-registry';
|
|
2
2
|
import { WorkspaceGrantsQuery } from '../../../content-types/queries/workspace-grants.query';
|
|
3
3
|
import { PublicEntryWritesService } from '../../infrastructure/public-entry-writes.service';
|
|
4
|
+
import type { PublicApiToken } from '../api-token-request';
|
|
4
5
|
import type { PublicEntry } from '../../types/public-entry';
|
|
5
6
|
import { PublicSaveEntryDto } from '../dto/public-save-entry.dto';
|
|
6
7
|
import { PublicBulkIdsDto, PublicBulkSaveDto } from '../dto/public-bulk.dto';
|
|
@@ -41,31 +42,31 @@ export declare class PublicEntryWritesController {
|
|
|
41
42
|
private readonly writes;
|
|
42
43
|
constructor(registry: ContentTypeRegistry, grants: WorkspaceGrantsQuery, writes: PublicEntryWritesService);
|
|
43
44
|
/** `POST /api/v1/content/:typeName` — create a draft entry. */
|
|
44
|
-
create(typeName: string, body: PublicSaveEntryDto, workspaceId: string): Promise<PublicEntry>;
|
|
45
|
+
create(typeName: string, body: PublicSaveEntryDto, workspaceId: string, token: PublicApiToken): Promise<PublicEntry>;
|
|
45
46
|
/** `POST /api/v1/content/:typeName/bulk` — create and/or update many entries. */
|
|
46
|
-
bulkSave(typeName: string, body: PublicBulkSaveDto, workspaceId: string): Promise<PublicBulkSaveResult>;
|
|
47
|
+
bulkSave(typeName: string, body: PublicBulkSaveDto, workspaceId: string, token: PublicApiToken): Promise<PublicBulkSaveResult>;
|
|
47
48
|
/** `POST /api/v1/content/:typeName/bulk/publish` — take many entries live. */
|
|
48
|
-
bulkPublish(typeName: string, body: PublicBulkIdsDto, workspaceId: string): Promise<BulkPublishResult>;
|
|
49
|
+
bulkPublish(typeName: string, body: PublicBulkIdsDto, workspaceId: string, token: PublicApiToken): Promise<BulkPublishResult>;
|
|
49
50
|
/** `POST /api/v1/content/:typeName/bulk/unpublish` — take many off the air. */
|
|
50
|
-
bulkUnpublish(typeName: string, body: PublicBulkIdsDto, workspaceId: string): Promise<BulkActionResult>;
|
|
51
|
+
bulkUnpublish(typeName: string, body: PublicBulkIdsDto, workspaceId: string, token: PublicApiToken): Promise<BulkActionResult>;
|
|
51
52
|
/** `POST /api/v1/content/:typeName/bulk/delete` — remove many entries. */
|
|
52
|
-
bulkRemove(typeName: string, body: PublicBulkIdsDto, workspaceId: string): Promise<BulkActionResult>;
|
|
53
|
+
bulkRemove(typeName: string, body: PublicBulkIdsDto, workspaceId: string, token: PublicApiToken): Promise<BulkActionResult>;
|
|
53
54
|
/** `PATCH /api/v1/content/:typeName/group/:localeGroupId` */
|
|
54
|
-
updateByGroup(typeName: string, localeGroupId: string, body: PublicSaveEntryDto, query: PublicEntryQueryDto, workspaceId: string): Promise<PublicEntry>;
|
|
55
|
+
updateByGroup(typeName: string, localeGroupId: string, body: PublicSaveEntryDto, query: PublicEntryQueryDto, workspaceId: string, token: PublicApiToken): Promise<PublicEntry>;
|
|
55
56
|
/** `POST /api/v1/content/:typeName/group/:localeGroupId/publish` */
|
|
56
|
-
publishByGroup(typeName: string, localeGroupId: string, query: PublicEntryQueryDto, workspaceId: string): Promise<PublicEntry>;
|
|
57
|
+
publishByGroup(typeName: string, localeGroupId: string, query: PublicEntryQueryDto, workspaceId: string, token: PublicApiToken): Promise<PublicEntry>;
|
|
57
58
|
/** `POST /api/v1/content/:typeName/group/:localeGroupId/unpublish` */
|
|
58
|
-
unpublishByGroup(typeName: string, localeGroupId: string, query: PublicEntryQueryDto, workspaceId: string): Promise<PublicEntry>;
|
|
59
|
+
unpublishByGroup(typeName: string, localeGroupId: string, query: PublicEntryQueryDto, workspaceId: string, token: PublicApiToken): Promise<PublicEntry>;
|
|
59
60
|
/** `DELETE /api/v1/content/:typeName/group/:localeGroupId` */
|
|
60
|
-
removeByGroup(typeName: string, localeGroupId: string, query: PublicEntryQueryDto, workspaceId: string): Promise<void>;
|
|
61
|
+
removeByGroup(typeName: string, localeGroupId: string, query: PublicEntryQueryDto, workspaceId: string, token: PublicApiToken): Promise<void>;
|
|
61
62
|
/** `PATCH /api/v1/content/:typeName/:id` — replace an entry's values. */
|
|
62
|
-
update(typeName: string, id: string, body: PublicSaveEntryDto, workspaceId: string): Promise<PublicEntry>;
|
|
63
|
+
update(typeName: string, id: string, body: PublicSaveEntryDto, workspaceId: string, token: PublicApiToken): Promise<PublicEntry>;
|
|
63
64
|
/** `POST /api/v1/content/:typeName/:id/publish` — take an entry live. */
|
|
64
|
-
publish(typeName: string, id: string, workspaceId: string): Promise<PublicEntry>;
|
|
65
|
+
publish(typeName: string, id: string, workspaceId: string, token: PublicApiToken): Promise<PublicEntry>;
|
|
65
66
|
/** `POST /api/v1/content/:typeName/:id/unpublish` — take it off the air. */
|
|
66
|
-
unpublish(typeName: string, id: string, workspaceId: string): Promise<PublicEntry>;
|
|
67
|
+
unpublish(typeName: string, id: string, workspaceId: string, token: PublicApiToken): Promise<PublicEntry>;
|
|
67
68
|
/** `DELETE /api/v1/content/:typeName/:id` — remove an entry. */
|
|
68
|
-
remove(typeName: string, id: string, workspaceId: string): Promise<void>;
|
|
69
|
+
remove(typeName: string, id: string, workspaceId: string, token: PublicApiToken): Promise<void>;
|
|
69
70
|
/** @see update */
|
|
70
71
|
private applyUpdate;
|
|
71
72
|
/** @see publish */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-entry-writes.controller.d.ts","sourceRoot":"","sources":["../../../../../src/lib/public-api/http/controllers/public-entry-writes.controller.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uDAAuD,CAAC;AAC7F,OAAO,EAAE,wBAAwB,EAAE,MAAM,kDAAkD,CAAC;
|
|
1
|
+
{"version":3,"file":"public-entry-writes.controller.d.ts","sourceRoot":"","sources":["../../../../../src/lib/public-api/http/controllers/public-entry-writes.controller.ts"],"names":[],"mappings":"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"}
|