@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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Database } from '@orthacms/database';
|
|
2
2
|
import { type AnyContentType } from '../../types/content-type';
|
|
3
3
|
import { type MediaAssetResolver } from '../../extension/media-asset-resolver';
|
|
4
|
+
import { ContentReadScopeRegistry } from '../../extension/read-scope';
|
|
4
5
|
import { RelationLinkService } from '../../entries/infrastructure/persistence/relation-link.service';
|
|
5
6
|
import type { PublicMediaFieldView, PublicRelationFieldView } from '../types/public-expansion';
|
|
6
7
|
/** A generated content row seen as a bag of values by property name. */
|
|
@@ -31,7 +32,16 @@ export declare class PublicExpansionQuery {
|
|
|
31
32
|
private readonly db;
|
|
32
33
|
private readonly relationLinks;
|
|
33
34
|
private readonly media?;
|
|
34
|
-
|
|
35
|
+
private readonly readScopes?;
|
|
36
|
+
constructor(db: Database, relationLinks: RelationLinkService, media?: MediaAssetResolver | undefined, readScopes?: ContentReadScopeRegistry | undefined);
|
|
37
|
+
/**
|
|
38
|
+
* The read-scope fragments for one hop's target type.
|
|
39
|
+
*
|
|
40
|
+
* The target is a different content type from the one the request named, so
|
|
41
|
+
* the scope is asked about **it** — a scope keyed to the requested type
|
|
42
|
+
* would leave every relation target unguarded.
|
|
43
|
+
*/
|
|
44
|
+
private readScopeWhere;
|
|
35
45
|
/**
|
|
36
46
|
* Validate a `?relationFields=` list: every name must be a relation field
|
|
37
47
|
* on the type, and its target must be a content type the workspace was
|
|
@@ -47,9 +57,11 @@ export declare class PublicExpansionQuery {
|
|
|
47
57
|
* One capped page of links per requested relation field, for every row on
|
|
48
58
|
* the page, keyed by entry id.
|
|
49
59
|
*
|
|
50
|
-
* `publishedOnly` is the public difference: a draft target
|
|
51
|
-
*
|
|
52
|
-
* reach.
|
|
60
|
+
* `publishedOnly` is the public difference: a draft target — or one a bound
|
|
61
|
+
* read scope hides from this reader — is neither shown **nor counted**, so
|
|
62
|
+
* `total` is the number of links this caller can actually reach. Counting
|
|
63
|
+
* them would leak the cardinality of what is hidden: "5 links, 2 visible"
|
|
64
|
+
* says three restricted records exist here.
|
|
53
65
|
*/
|
|
54
66
|
relationsForRows(type: AnyContentType, fields: string[], rows: Row[], workspaceId: string, limit?: number): Promise<Map<string, Record<string, PublicRelationFieldView>>>;
|
|
55
67
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-expansion.query.d.ts","sourceRoot":"","sources":["../../../../src/lib/public-api/infrastructure/public-expansion.query.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"public-expansion.query.d.ts","sourceRoot":"","sources":["../../../../src/lib/public-api/infrastructure/public-expansion.query.ts"],"names":[],"mappings":"AASA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnE,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE7E,OAAO,EAEH,KAAK,kBAAkB,EAC1B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gEAAgE,CAAC;AAErG,OAAO,KAAK,EACR,oBAAoB,EAEpB,uBAAuB,EAC1B,MAAM,2BAA2B,CAAC;AAInC,wEAAwE;AACxE,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAKnC;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAwCtC;;;;;;;;;;;;GAYG;AACH,qBACa,oBAAoB;IAEP,OAAO,CAAC,QAAQ,CAAC,EAAE;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAG9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IAKvB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;gBATO,EAAE,EAAE,QAAQ,EAC9B,aAAa,EAAE,mBAAmB,EAGlC,KAAK,CAAC,EAAE,kBAAkB,YAAA,EAK1B,UAAU,CAAC,EAAE,wBAAwB,YAAA;IAG1D;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAOtB;;;;;;;OAOG;IACH,mBAAmB,CACf,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAC7B,MAAM,EAAE;IA8BX,yEAAyE;IACzE,gBAAgB,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE;IAiBzE;;;;;;;;;OASG;IACG,gBAAgB,CAClB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,GAAG,EAAE,EACX,WAAW,EAAE,MAAM,EACnB,KAAK,SAA0B,GAChC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC,CAAC;IA6ChE;;;;OAIG;IACG,oBAAoB,CACtB,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,EACjE,WAAW,EAAE,MAAM,GACpB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IAqBnD;;;;;;;;OAQG;YACW,iBAAiB;IAuD/B;;;;;;OAMG;IACG,YAAY,CACd,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,EAAE,EAChB,IAAI,EAAE,GAAG,EAAE,EACX,WAAW,EAAE,MAAM,EACnB,KAAK,SAA0B,GAChC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;IA+F7D;;;;;;;;OAQG;IACH,OAAO,CAAC,eAAe;IAgBvB,4EAA4E;IAC5E,OAAO,CAAC,WAAW;CA+BtB"}
|
|
@@ -9,6 +9,7 @@ const content_domain_1 = require("@orthacms/content-domain");
|
|
|
9
9
|
const content_type_1 = require("../../types/content-type");
|
|
10
10
|
const fields_1 = require("../../types/fields");
|
|
11
11
|
const media_asset_resolver_1 = require("../../extension/media-asset-resolver");
|
|
12
|
+
const read_scope_1 = require("../../extension/read-scope");
|
|
12
13
|
const relation_link_service_1 = require("../../entries/infrastructure/persistence/relation-link.service");
|
|
13
14
|
const public_list_entries_query_dto_1 = require("../http/dto/public-list-entries-query.dto");
|
|
14
15
|
const public_entry_row_1 = require("./public-entry-row");
|
|
@@ -73,10 +74,22 @@ let PublicExpansionQuery = class PublicExpansionQuery {
|
|
|
73
74
|
db;
|
|
74
75
|
relationLinks;
|
|
75
76
|
media;
|
|
76
|
-
|
|
77
|
+
readScopes;
|
|
78
|
+
constructor(db, relationLinks, media, readScopes) {
|
|
77
79
|
this.db = db;
|
|
78
80
|
this.relationLinks = relationLinks;
|
|
79
81
|
this.media = media;
|
|
82
|
+
this.readScopes = readScopes;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The read-scope fragments for one hop's target type.
|
|
86
|
+
*
|
|
87
|
+
* The target is a different content type from the one the request named, so
|
|
88
|
+
* the scope is asked about **it** — a scope keyed to the requested type
|
|
89
|
+
* would leave every relation target unguarded.
|
|
90
|
+
*/
|
|
91
|
+
readScopeWhere(type, workspaceId) {
|
|
92
|
+
return this.readScopes?.fragments({ type, workspaceId }) ?? [];
|
|
80
93
|
}
|
|
81
94
|
/**
|
|
82
95
|
* Validate a `?relationFields=` list: every name must be a relation field
|
|
@@ -121,9 +134,11 @@ let PublicExpansionQuery = class PublicExpansionQuery {
|
|
|
121
134
|
* One capped page of links per requested relation field, for every row on
|
|
122
135
|
* the page, keyed by entry id.
|
|
123
136
|
*
|
|
124
|
-
* `publishedOnly` is the public difference: a draft target
|
|
125
|
-
*
|
|
126
|
-
* reach.
|
|
137
|
+
* `publishedOnly` is the public difference: a draft target — or one a bound
|
|
138
|
+
* read scope hides from this reader — is neither shown **nor counted**, so
|
|
139
|
+
* `total` is the number of links this caller can actually reach. Counting
|
|
140
|
+
* them would leak the cardinality of what is hidden: "5 links, 2 visible"
|
|
141
|
+
* says three restricted records exist here.
|
|
127
142
|
*/
|
|
128
143
|
async relationsForRows(type, fields, rows, workspaceId, limit = public_list_entries_query_dto_1.DEFAULT_EXPANSION_LIMIT) {
|
|
129
144
|
const out = new Map();
|
|
@@ -140,9 +155,13 @@ let PublicExpansionQuery = class PublicExpansionQuery {
|
|
|
140
155
|
for (const [field, value] of Object.entries(byField)) {
|
|
141
156
|
const linked = entriesById.get(field);
|
|
142
157
|
view[field] = {
|
|
143
|
-
// Preserve the preview's link order
|
|
144
|
-
//
|
|
145
|
-
//
|
|
158
|
+
// Preserve the preview's link order. Nothing should drop
|
|
159
|
+
// here any more — `previewForEntries` applies the same
|
|
160
|
+
// visibility (published-only **and** the bound read scopes)
|
|
161
|
+
// inside its window, so an unreachable target is already
|
|
162
|
+
// out of both `items` and `total`. The filter stays as a
|
|
163
|
+
// belt: a hydration miss must never leave a hole in the
|
|
164
|
+
// array, and it is cheap to keep honest.
|
|
146
165
|
items: value.items
|
|
147
166
|
.map((ref) => linked?.get(ref.id))
|
|
148
167
|
.filter((entry) => !!entry),
|
|
@@ -209,7 +228,7 @@ let PublicExpansionQuery = class PublicExpansionQuery {
|
|
|
209
228
|
? (0, drizzle_orm_1.eq)(cols['status'], content_type_1.ENTRY_STATUS.Published)
|
|
210
229
|
: undefined, target.paranoid
|
|
211
230
|
? (0, drizzle_orm_1.isNull)(cols['deletedAt'])
|
|
212
|
-
: undefined)));
|
|
231
|
+
: undefined, ...this.readScopeWhere(target, workspaceId))));
|
|
213
232
|
out.set(field, new Map(rows.map((row) => [
|
|
214
233
|
row['id'],
|
|
215
234
|
(0, public_entry_row_1.toPublicEntry)(target, row)
|
|
@@ -358,7 +377,8 @@ exports.PublicExpansionQuery = PublicExpansionQuery = tslib_1.__decorate([
|
|
|
358
377
|
tslib_1.__param(0, (0, database_1.InjectDatabase)()),
|
|
359
378
|
tslib_1.__param(2, (0, common_1.Optional)()),
|
|
360
379
|
tslib_1.__param(2, (0, media_asset_resolver_1.InjectMediaAssetResolver)()),
|
|
361
|
-
tslib_1.
|
|
380
|
+
tslib_1.__param(3, (0, common_1.Optional)()),
|
|
381
|
+
tslib_1.__metadata("design:paramtypes", [Object, relation_link_service_1.RelationLinkService, Object, read_scope_1.ContentReadScopeRegistry])
|
|
362
382
|
], PublicExpansionQuery);
|
|
363
383
|
/** The asset ids stored in a media field — one id, or an ordered list. */
|
|
364
384
|
function mediaRefsOf(value) {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type EventActor } from '@orthacms/database';
|
|
2
|
+
import type { ToolActor } from '@orthacms/tools-server';
|
|
3
|
+
import type { PublicApiToken } from '../http/api-token-request';
|
|
4
|
+
/**
|
|
5
|
+
* The API token as the {@link EventActor} a public-API write stamps onto its
|
|
6
|
+
* domain events.
|
|
7
|
+
*
|
|
8
|
+
* Every write over the public REST API, GraphQL and MCP used to reach the audit
|
|
9
|
+
* log with no actor at all and render as "System" — not an oversight but the
|
|
10
|
+
* only honest option at the time, since `actor_id` meant "a `users` row" and a
|
|
11
|
+
* token is not one. `activity_events.actor_type` is what makes naming the
|
|
12
|
+
* credential possible, so this is the seam that fills it.
|
|
13
|
+
*
|
|
14
|
+
* `email` carries the token's **label**, because that is the readable name a
|
|
15
|
+
* row needs and a token has no address; `actor_type` is what tells a client not
|
|
16
|
+
* to read it as one. The token id goes in `id` — the same handle the API Tokens
|
|
17
|
+
* page lists and the revoke button acts on, so a row leads straight to the
|
|
18
|
+
* credential it names.
|
|
19
|
+
*
|
|
20
|
+
* A revision's `created_by` still gets `null` for a token: that column really is
|
|
21
|
+
* a `users` FK. The split lives in `EntryWriterService`'s `revisionActorId`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function toTokenActor(token: PublicApiToken): EventActor;
|
|
24
|
+
/**
|
|
25
|
+
* The {@link EventActor} for a write made through the shared **tool registry** —
|
|
26
|
+
* an MCP client, or the copilot's own run loop.
|
|
27
|
+
*
|
|
28
|
+
* `ToolActor` already carries the distinction this needs (`kind`, `id`,
|
|
29
|
+
* `displayName`), which is the point of it being transport-neutral: one
|
|
30
|
+
* conversion covers both surfaces, and neither had any actor on its writes
|
|
31
|
+
* before. A token acts as itself here exactly as it does over REST — the
|
|
32
|
+
* minting user in `actor.userId` is attribution for a revision's `created_by`,
|
|
33
|
+
* not the principal that performed the call, and conflating them would name a
|
|
34
|
+
* person for every request an integration makes.
|
|
35
|
+
*/
|
|
36
|
+
export declare function toToolEventActor(actor: ToolActor): EventActor;
|
|
37
|
+
//# sourceMappingURL=token-actor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-actor.d.ts","sourceRoot":"","sources":["../../../../src/lib/public-api/infrastructure/token-actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAEhE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CAO9D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,CAa7D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toTokenActor = toTokenActor;
|
|
4
|
+
exports.toToolEventActor = toToolEventActor;
|
|
5
|
+
const database_1 = require("@orthacms/database");
|
|
6
|
+
/**
|
|
7
|
+
* The API token as the {@link EventActor} a public-API write stamps onto its
|
|
8
|
+
* domain events.
|
|
9
|
+
*
|
|
10
|
+
* Every write over the public REST API, GraphQL and MCP used to reach the audit
|
|
11
|
+
* log with no actor at all and render as "System" — not an oversight but the
|
|
12
|
+
* only honest option at the time, since `actor_id` meant "a `users` row" and a
|
|
13
|
+
* token is not one. `activity_events.actor_type` is what makes naming the
|
|
14
|
+
* credential possible, so this is the seam that fills it.
|
|
15
|
+
*
|
|
16
|
+
* `email` carries the token's **label**, because that is the readable name a
|
|
17
|
+
* row needs and a token has no address; `actor_type` is what tells a client not
|
|
18
|
+
* to read it as one. The token id goes in `id` — the same handle the API Tokens
|
|
19
|
+
* page lists and the revoke button acts on, so a row leads straight to the
|
|
20
|
+
* credential it names.
|
|
21
|
+
*
|
|
22
|
+
* A revision's `created_by` still gets `null` for a token: that column really is
|
|
23
|
+
* a `users` FK. The split lives in `EntryWriterService`'s `revisionActorId`.
|
|
24
|
+
*/
|
|
25
|
+
function toTokenActor(token) {
|
|
26
|
+
return {
|
|
27
|
+
id: token.id,
|
|
28
|
+
email: token.name,
|
|
29
|
+
type: database_1.EVENT_ACTOR_TYPE.ApiToken,
|
|
30
|
+
label: token.name
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The {@link EventActor} for a write made through the shared **tool registry** —
|
|
35
|
+
* an MCP client, or the copilot's own run loop.
|
|
36
|
+
*
|
|
37
|
+
* `ToolActor` already carries the distinction this needs (`kind`, `id`,
|
|
38
|
+
* `displayName`), which is the point of it being transport-neutral: one
|
|
39
|
+
* conversion covers both surfaces, and neither had any actor on its writes
|
|
40
|
+
* before. A token acts as itself here exactly as it does over REST — the
|
|
41
|
+
* minting user in `actor.userId` is attribution for a revision's `created_by`,
|
|
42
|
+
* not the principal that performed the call, and conflating them would name a
|
|
43
|
+
* person for every request an integration makes.
|
|
44
|
+
*/
|
|
45
|
+
function toToolEventActor(actor) {
|
|
46
|
+
return actor.kind === 'token'
|
|
47
|
+
? {
|
|
48
|
+
id: actor.id,
|
|
49
|
+
email: actor.displayName,
|
|
50
|
+
type: database_1.EVENT_ACTOR_TYPE.ApiToken,
|
|
51
|
+
label: actor.displayName
|
|
52
|
+
}
|
|
53
|
+
: {
|
|
54
|
+
id: actor.id,
|
|
55
|
+
email: actor.displayName,
|
|
56
|
+
type: database_1.EVENT_ACTOR_TYPE.User
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restore-revision.use-case.d.ts","sourceRoot":"","sources":["../../../../../src/lib/revisions/application/use-cases/restore-revision.use-case.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kEAAkE,CAAC;AACtG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAEH,KAAK,aAAa,EACrB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;GASG;AACH,qBACa,sBAAsB;IAE3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACA,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAD5B,MAAM,EAAE,kBAAkB,EACH,KAAK,EAAE,aAAa;IAG1D,OAAO,CACT,IAAI,EAAE,cAAc,EACpB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM;IACnB;;;;OAIG;IACH,KAAK,EAAE,UAAU,GAAG,IAAI,EACxB,OAAO,CAAC,EAAE;QACN;;;;;WAKG;QACH,cAAc,CAAC,EAAE,OAAO,CAAC;KAC5B,GACF,OAAO,CAAC,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"restore-revision.use-case.d.ts","sourceRoot":"","sources":["../../../../../src/lib/revisions/application/use-cases/restore-revision.use-case.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kEAAkE,CAAC;AACtG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAC1E,OAAO,EAEH,KAAK,aAAa,EACrB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;GASG;AACH,qBACa,sBAAsB;IAE3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACA,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAD5B,MAAM,EAAE,kBAAkB,EACH,KAAK,EAAE,aAAa;IAG1D,OAAO,CACT,IAAI,EAAE,cAAc,EACpB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM;IACnB;;;;OAIG;IACH,KAAK,EAAE,UAAU,GAAG,IAAI,EACxB,OAAO,CAAC,EAAE;QACN;;;;;WAKG;QACH,cAAc,CAAC,EAAE,OAAO,CAAC;KAC5B,GACF,OAAO,CAAC,WAAW,CAAC;CAoD1B"}
|
|
@@ -46,7 +46,29 @@ let RestoreRevisionUseCase = class RestoreRevisionUseCase {
|
|
|
46
46
|
values[field] = ids;
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
return this.writer.update(type, id, values, workspaceId, undefined,
|
|
49
|
+
return this.writer.update(type, id, values, workspaceId, undefined,
|
|
50
|
+
// Restoring reaches the log as the `entry.updated` its save raises,
|
|
51
|
+
// naming the fields it put back — which is right, and used to be
|
|
52
|
+
// the whole story: nothing said the edit *was* a restore, or of
|
|
53
|
+
// which version. `via` carries that without inventing a kind, the
|
|
54
|
+
// same seam a copilot-applied change uses.
|
|
55
|
+
actor
|
|
56
|
+
? {
|
|
57
|
+
...actor,
|
|
58
|
+
via: { kind: 'revision_restore', revisionNumber: number }
|
|
59
|
+
}
|
|
60
|
+
: actor, {
|
|
61
|
+
...options,
|
|
62
|
+
// Put back whatever the bound extensions held when this version was
|
|
63
|
+
// captured — segments' audiences, today. Without it "go back to
|
|
64
|
+
// Tuesday" would restore Tuesday's words in front of today's
|
|
65
|
+
// readers, which is the half of a restore nobody would think to
|
|
66
|
+
// check. A version captured before any extension existed carries no
|
|
67
|
+
// bag, and an absent bag changes nothing (an omitted key is left
|
|
68
|
+
// alone) — which is the right reading: that version knows nothing
|
|
69
|
+
// about audiences, it does not assert the entry had none.
|
|
70
|
+
extensions: detail.snapshot.extra
|
|
71
|
+
});
|
|
50
72
|
}
|
|
51
73
|
};
|
|
52
74
|
exports.RestoreRevisionUseCase = RestoreRevisionUseCase;
|
|
@@ -11,7 +11,13 @@ type Row = Record<string, unknown>;
|
|
|
11
11
|
* `relations` is read separately from the join tables — those links never travel
|
|
12
12
|
* in the `values` bag — inside the save transaction, so the snapshot reflects
|
|
13
13
|
* exactly what committed.
|
|
14
|
+
*
|
|
15
|
+
* `extra` is the same idea one plugin further out: state a **bound entry-write
|
|
16
|
+
* extension** owns in a table this package knows nothing about (segments'
|
|
17
|
+
* audiences), read back on the same transaction. It is omitted when there is
|
|
18
|
+
* none, so a snapshot on an installation with no extensions is byte-for-byte
|
|
19
|
+
* what it was before the port existed.
|
|
14
20
|
*/
|
|
15
|
-
export declare function buildSnapshot(type: AnyContentType, row: Row, relations: Record<string, string[]>): RevisionSnapshot;
|
|
21
|
+
export declare function buildSnapshot(type: AnyContentType, row: Row, relations: Record<string, string[]>, extra?: Record<string, unknown>): RevisionSnapshot;
|
|
16
22
|
export {};
|
|
17
23
|
//# sourceMappingURL=revision-snapshot.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revision-snapshot.d.ts","sourceRoot":"","sources":["../../../../../src/lib/revisions/infrastructure/persistence/revision-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE,wEAAwE;AACxE,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnC
|
|
1
|
+
{"version":3,"file":"revision-snapshot.d.ts","sourceRoot":"","sources":["../../../../../src/lib/revisions/infrastructure/persistence/revision-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE,wEAAwE;AACxE,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CACzB,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACnC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,gBAAgB,CAMlB"}
|
|
@@ -11,10 +11,17 @@ const entry_row_1 = require("../../../entries/infrastructure/persistence/entry-r
|
|
|
11
11
|
* `relations` is read separately from the join tables — those links never travel
|
|
12
12
|
* in the `values` bag — inside the save transaction, so the snapshot reflects
|
|
13
13
|
* exactly what committed.
|
|
14
|
+
*
|
|
15
|
+
* `extra` is the same idea one plugin further out: state a **bound entry-write
|
|
16
|
+
* extension** owns in a table this package knows nothing about (segments'
|
|
17
|
+
* audiences), read back on the same transaction. It is omitted when there is
|
|
18
|
+
* none, so a snapshot on an installation with no extensions is byte-for-byte
|
|
19
|
+
* what it was before the port existed.
|
|
14
20
|
*/
|
|
15
|
-
function buildSnapshot(type, row, relations) {
|
|
21
|
+
function buildSnapshot(type, row, relations, extra) {
|
|
16
22
|
return {
|
|
17
23
|
values: (0, entry_row_1.toRecord)(type, row).values,
|
|
18
|
-
relations
|
|
24
|
+
relations,
|
|
25
|
+
...(extra ? { extra } : {})
|
|
19
26
|
};
|
|
20
27
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { OnModuleInit } from '@nestjs/common';
|
|
2
|
+
import { UnitOfWork } from '@orthacms/database';
|
|
3
|
+
import { WorkspacePurgeRegistry, type WorkspacePurger, type WorkspacePurgeOutcome } from '@orthacms/workspaces-server';
|
|
4
|
+
/**
|
|
5
|
+
* Removes a deleted workspace's entry revisions.
|
|
6
|
+
*
|
|
7
|
+
* Content is otherwise the plugin that does **not** purge: a workspace holding
|
|
8
|
+
* entries is refused (409), because entries are authored records someone must
|
|
9
|
+
* delete deliberately. Revisions fall outside that protection in both
|
|
10
|
+
* directions. They carry a plain `workspace_id` with no foreign key, and
|
|
11
|
+
* `countWorkspaceEntries` sums the live `content_<name>` tables only — so a
|
|
12
|
+
* workspace whose entries have all been deleted counts as empty, deletes
|
|
13
|
+
* cleanly, and leaves its whole revision history behind pointing at nothing.
|
|
14
|
+
*
|
|
15
|
+
* That history is not an authored record in its own right: it is the version
|
|
16
|
+
* timeline of rows that are already gone, unreachable once the workspace it was
|
|
17
|
+
* scoped to no longer opens. Purging it is the same call the folder tree and the
|
|
18
|
+
* token bucket get — scoping rows with no independent meaning left.
|
|
19
|
+
*/
|
|
20
|
+
export declare class RevisionsWorkspacePurger implements WorkspacePurger, OnModuleInit {
|
|
21
|
+
private readonly uow;
|
|
22
|
+
private readonly registry?;
|
|
23
|
+
readonly purgeName = "content:entry-revisions";
|
|
24
|
+
constructor(uow: UnitOfWork, registry?: WorkspacePurgeRegistry | undefined);
|
|
25
|
+
onModuleInit(): void;
|
|
26
|
+
purge(workspaceId: string): Promise<WorkspacePurgeOutcome>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=revisions-workspace.purger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revisions-workspace.purger.d.ts","sourceRoot":"","sources":["../../../../../src/lib/revisions/infrastructure/purge/revisions-workspace.purger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAAY,MAAM,gBAAgB,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EACH,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC7B,MAAM,6BAA6B,CAAC;AAGrC;;;;;;;;;;;;;;;GAeG;AACH,qBACa,wBAAyB,YAAW,eAAe,EAAE,YAAY;IAItE,OAAO,CAAC,QAAQ,CAAC,GAAG;IACR,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAJ1C,QAAQ,CAAC,SAAS,6BAA6B;gBAG1B,GAAG,EAAE,UAAU,EACH,QAAQ,CAAC,EAAE,sBAAsB,YAAA;IAGlE,YAAY,IAAI,IAAI;IAId,KAAK,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;CASnE"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RevisionsWorkspacePurger = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const drizzle_orm_1 = require("drizzle-orm");
|
|
7
|
+
const database_1 = require("@orthacms/database");
|
|
8
|
+
const workspaces_server_1 = require("@orthacms/workspaces-server");
|
|
9
|
+
const revision_table_1 = require("../persistence/revision-table");
|
|
10
|
+
/**
|
|
11
|
+
* Removes a deleted workspace's entry revisions.
|
|
12
|
+
*
|
|
13
|
+
* Content is otherwise the plugin that does **not** purge: a workspace holding
|
|
14
|
+
* entries is refused (409), because entries are authored records someone must
|
|
15
|
+
* delete deliberately. Revisions fall outside that protection in both
|
|
16
|
+
* directions. They carry a plain `workspace_id` with no foreign key, and
|
|
17
|
+
* `countWorkspaceEntries` sums the live `content_<name>` tables only — so a
|
|
18
|
+
* workspace whose entries have all been deleted counts as empty, deletes
|
|
19
|
+
* cleanly, and leaves its whole revision history behind pointing at nothing.
|
|
20
|
+
*
|
|
21
|
+
* That history is not an authored record in its own right: it is the version
|
|
22
|
+
* timeline of rows that are already gone, unreachable once the workspace it was
|
|
23
|
+
* scoped to no longer opens. Purging it is the same call the folder tree and the
|
|
24
|
+
* token bucket get — scoping rows with no independent meaning left.
|
|
25
|
+
*/
|
|
26
|
+
let RevisionsWorkspacePurger = class RevisionsWorkspacePurger {
|
|
27
|
+
uow;
|
|
28
|
+
registry;
|
|
29
|
+
purgeName = 'content:entry-revisions';
|
|
30
|
+
constructor(uow, registry) {
|
|
31
|
+
this.uow = uow;
|
|
32
|
+
this.registry = registry;
|
|
33
|
+
}
|
|
34
|
+
onModuleInit() {
|
|
35
|
+
this.registry?.register(this);
|
|
36
|
+
}
|
|
37
|
+
async purge(workspaceId) {
|
|
38
|
+
const removed = await this.uow
|
|
39
|
+
.current()
|
|
40
|
+
.delete(revision_table_1.contentEntryRevisions)
|
|
41
|
+
.where((0, drizzle_orm_1.eq)(revision_table_1.contentEntryRevisions.workspaceId, workspaceId))
|
|
42
|
+
.returning({ id: revision_table_1.contentEntryRevisions.id });
|
|
43
|
+
return { rows: removed.length };
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
exports.RevisionsWorkspacePurger = RevisionsWorkspacePurger;
|
|
47
|
+
exports.RevisionsWorkspacePurger = RevisionsWorkspacePurger = tslib_1.__decorate([
|
|
48
|
+
(0, common_1.Injectable)(),
|
|
49
|
+
tslib_1.__param(1, (0, common_1.Optional)()),
|
|
50
|
+
tslib_1.__metadata("design:paramtypes", [database_1.UnitOfWork,
|
|
51
|
+
workspaces_server_1.WorkspacePurgeRegistry])
|
|
52
|
+
], RevisionsWorkspacePurger);
|
|
@@ -17,6 +17,17 @@ export interface RevisionSnapshot {
|
|
|
17
17
|
* never travel in {@link values}.
|
|
18
18
|
*/
|
|
19
19
|
relations: Record<string, string[]>;
|
|
20
|
+
/**
|
|
21
|
+
* What each bound **entry-write extension** held for the entry at capture
|
|
22
|
+
* time, keyed by its `key` — state a different plugin owns in a table this
|
|
23
|
+
* package knows nothing about (`segments` records who could read the entry).
|
|
24
|
+
*
|
|
25
|
+
* Opaque here: content-server stores it, hands it back on a restore, and
|
|
26
|
+
* never looks inside. Absent on an installation with no extensions, and on
|
|
27
|
+
* every version captured before one was installed — so a reader must treat
|
|
28
|
+
* a missing bag as "nothing is known", never as "the entry had none".
|
|
29
|
+
*/
|
|
30
|
+
extra?: Record<string, unknown>;
|
|
20
31
|
}
|
|
21
32
|
/**
|
|
22
33
|
* One revision as served to the admin timeline — the metadata, without the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"revision-view.d.ts","sourceRoot":"","sources":["../../../../src/lib/revisions/types/revision-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EACR,QAAQ,EACR,WAAW,EACd,MAAM,qCAAqC,CAAC;AAE7C;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"revision-view.d.ts","sourceRoot":"","sources":["../../../../src/lib/revisions/types/revision-view.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EACR,QAAQ,EACR,WAAW,EACd,MAAM,qCAAqC,CAAC;AAE7C;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC7B;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACpC;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC5B,mBAAmB;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,MAAM,EAAE,cAAc,CAAC;IACvB,wDAAwD;IACxD,WAAW,EAAE,OAAO,CAAC;IACrB,sEAAsE;IACtE,QAAQ,EAAE,OAAO,CAAC;IAClB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wEAAwE;AACxE,MAAM,WAAW,cAAe,SAAQ,eAAe;IACnD,6BAA6B;IAC7B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IAC7C,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;CAC1C;AAED,0EAA0E;AAC1E,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/content-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"content-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/content-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAI/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACjC,iEAAiE;IACjE,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IACjC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,YAAY,CAAC,YAAY,CAAC,CAAC;CAC3C;AAED,kEAAkE;AAClE,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACrD,QAAQ,EAAE,mBAAmB,CAAC;CACjC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CACzB,OAAO,EAAE,oBAAoB,GAC9B,mBAAmB,CAsBrB"}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ContentPlugin = ContentPlugin;
|
|
4
4
|
const content_module_1 = require("../content.module");
|
|
5
5
|
const describe_content_api_1 = require("../docs/describe-content-api");
|
|
6
|
+
const describe_content_insights_api_1 = require("../insights/docs/describe-content-insights-api");
|
|
6
7
|
const content_type_registry_1 = require("../registry/content-type-registry");
|
|
7
8
|
/**
|
|
8
9
|
* Content plugin factory. Builds the registry eagerly — duplicate names
|
|
@@ -29,7 +30,15 @@ function ContentPlugin(options) {
|
|
|
29
30
|
// can see; the registry is what knows `article` from `home_page`. This
|
|
30
31
|
// hook is where the code-defined types become OpenAPI schemas.
|
|
31
32
|
docs: {
|
|
32
|
-
decorate: (document) =>
|
|
33
|
+
decorate: (document) => {
|
|
34
|
+
(0, describe_content_api_1.describeContentApi)(document, registry.serializeAll());
|
|
35
|
+
// The Insights widgets are a second surface with a fixed
|
|
36
|
+
// contract — six unlike payloads whose views are `interface`s,
|
|
37
|
+
// so the scanner emits an empty 200 for each. Described from
|
|
38
|
+
// their own module rather than folded into the pass above:
|
|
39
|
+
// they are grouped under the `insights` tag, not `content`.
|
|
40
|
+
(0, describe_content_insights_api_1.describeContentInsightsApi)(document);
|
|
41
|
+
}
|
|
33
42
|
}
|
|
34
43
|
};
|
|
35
44
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ServerPlugin } from '@orthacms/bootstrap-server';
|
|
2
|
+
import type { ContentServerPlugin } from './content-plugin';
|
|
3
|
+
/** Options for {@link ContentViewsPlugin}. */
|
|
4
|
+
export interface ContentViewsPluginOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The content plugin this rides on — its registry is what turns a view's
|
|
7
|
+
* `content:<typeName>` scope back into a known content type. Taking the
|
|
8
|
+
* whole plugin (rather than a bare registry) makes the dependency visible
|
|
9
|
+
* at the composition root: the entry has to be listed *after* the content
|
|
10
|
+
* one, which is also the migration order its foreign keys need.
|
|
11
|
+
*/
|
|
12
|
+
content: ContentServerPlugin;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Saved list views — the named filter/sort/column slices an editor returns to.
|
|
16
|
+
*
|
|
17
|
+
* A **separate `ServerPlugin` entry from the same package** as `ContentPlugin`,
|
|
18
|
+
* and deliberately so. `ServerPlugin.migrations` is one descriptor, and
|
|
19
|
+
* content's is already carrying the HOST's generated collection tables; a
|
|
20
|
+
* second entry is how this package ships its own fixed tables without touching
|
|
21
|
+
* that contract. The host applies both under their own tracking tables.
|
|
22
|
+
*
|
|
23
|
+
* Order matters at the composition root: `saved_views` has foreign keys into
|
|
24
|
+
* identity's `users` and workspaces' `workspaces`, and nothing declares that
|
|
25
|
+
* dependency — list this after both, and after `ContentPlugin` itself.
|
|
26
|
+
*/
|
|
27
|
+
export declare function ContentViewsPlugin(options: ContentViewsPluginOptions): ServerPlugin;
|
|
28
|
+
//# sourceMappingURL=content-views-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-views-plugin.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/content-views-plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG/D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,8CAA8C;AAC9C,MAAM,WAAW,yBAAyB;IACtC;;;;;;OAMG;IACH,OAAO,EAAE,mBAAmB,CAAC;CAChC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAC9B,OAAO,EAAE,yBAAyB,GACnC,YAAY,CAqBd"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContentViewsPlugin = ContentViewsPlugin;
|
|
4
|
+
const node_path_1 = require("node:path");
|
|
5
|
+
const content_views_module_1 = require("../views/content-views.module");
|
|
6
|
+
const describe_views_api_1 = require("../docs/describe-views-api");
|
|
7
|
+
/**
|
|
8
|
+
* Saved list views — the named filter/sort/column slices an editor returns to.
|
|
9
|
+
*
|
|
10
|
+
* A **separate `ServerPlugin` entry from the same package** as `ContentPlugin`,
|
|
11
|
+
* and deliberately so. `ServerPlugin.migrations` is one descriptor, and
|
|
12
|
+
* content's is already carrying the HOST's generated collection tables; a
|
|
13
|
+
* second entry is how this package ships its own fixed tables without touching
|
|
14
|
+
* that contract. The host applies both under their own tracking tables.
|
|
15
|
+
*
|
|
16
|
+
* Order matters at the composition root: `saved_views` has foreign keys into
|
|
17
|
+
* identity's `users` and workspaces' `workspaces`, and nothing declares that
|
|
18
|
+
* dependency — list this after both, and after `ContentPlugin` itself.
|
|
19
|
+
*/
|
|
20
|
+
function ContentViewsPlugin(options) {
|
|
21
|
+
return {
|
|
22
|
+
name: 'content-views',
|
|
23
|
+
module: content_views_module_1.ContentViewsModule.forRoot(options.content.registry),
|
|
24
|
+
// src/lib/utils → ../../../migrations = <pkg>/migrations.
|
|
25
|
+
migrations: {
|
|
26
|
+
dir: () => (0, node_path_1.join)(__dirname, '../../../migrations'),
|
|
27
|
+
table: '__drizzle_migrations_content_views'
|
|
28
|
+
},
|
|
29
|
+
// `SavedView` is a framework-free `interface` (ADR-0003 forbids
|
|
30
|
+
// decorating it) and its `scope` is `content:<typeName>`, which only
|
|
31
|
+
// the registry knows — so the swagger scanner sees neither the shape
|
|
32
|
+
// nor the values, and this hook is where both become visible.
|
|
33
|
+
docs: {
|
|
34
|
+
decorate: (document) => (0, describe_views_api_1.describeViewsApi)(document, options.content.registry.serializeAll())
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SavedView } from '../../domain/saved-view';
|
|
2
|
+
import { type SavedViewRecord, type SavedViewRepository } from '../../domain/saved-view.repository';
|
|
3
|
+
/**
|
|
4
|
+
* The read side: every view a caller may see for one list, with the two
|
|
5
|
+
* per-caller flags the switcher renders from (`isOwn` gates Save and Delete,
|
|
6
|
+
* `isDefault` marks the row and drives the landing view).
|
|
7
|
+
*/
|
|
8
|
+
export declare class SavedViewsQuery {
|
|
9
|
+
private readonly repository;
|
|
10
|
+
constructor(repository: SavedViewRepository);
|
|
11
|
+
/** Views visible to `readerId` in this workspace + scope. */
|
|
12
|
+
list(workspaceId: string, scope: string, readerId: string): Promise<SavedView[]>;
|
|
13
|
+
}
|
|
14
|
+
/** Projects a stored row into the API shape for one reader. */
|
|
15
|
+
export declare function toSavedView(record: SavedViewRecord, readerId: string, defaultId: string | null): SavedView;
|
|
16
|
+
//# sourceMappingURL=saved-views.query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saved-views.query.d.ts","sourceRoot":"","sources":["../../../../../src/lib/views/application/queries/saved-views.query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAEH,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAC3B,MAAM,oCAAoC,CAAC;AAE5C;;;;GAIG;AACH,qBACa,eAAe;IAGpB,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,mBAAmB;IAGpD,6DAA6D;IACvD,IAAI,CACN,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,EAAE,CAAC;CAS1B;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CACvB,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAAG,IAAI,GACzB,SAAS,CAYX"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SavedViewsQuery = void 0;
|
|
4
|
+
exports.toSavedView = toSavedView;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const common_1 = require("@nestjs/common");
|
|
7
|
+
const saved_view_repository_1 = require("../../domain/saved-view.repository");
|
|
8
|
+
/**
|
|
9
|
+
* The read side: every view a caller may see for one list, with the two
|
|
10
|
+
* per-caller flags the switcher renders from (`isOwn` gates Save and Delete,
|
|
11
|
+
* `isDefault` marks the row and drives the landing view).
|
|
12
|
+
*/
|
|
13
|
+
let SavedViewsQuery = class SavedViewsQuery {
|
|
14
|
+
repository;
|
|
15
|
+
constructor(repository) {
|
|
16
|
+
this.repository = repository;
|
|
17
|
+
}
|
|
18
|
+
/** Views visible to `readerId` in this workspace + scope. */
|
|
19
|
+
async list(workspaceId, scope, readerId) {
|
|
20
|
+
const [records, defaultId] = await Promise.all([
|
|
21
|
+
this.repository.listVisible(workspaceId, scope, readerId),
|
|
22
|
+
this.repository.findDefaultId(readerId, scope)
|
|
23
|
+
]);
|
|
24
|
+
return records.map((record) => toSavedView(record, readerId, defaultId));
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
exports.SavedViewsQuery = SavedViewsQuery;
|
|
28
|
+
exports.SavedViewsQuery = SavedViewsQuery = tslib_1.__decorate([
|
|
29
|
+
(0, common_1.Injectable)(),
|
|
30
|
+
tslib_1.__param(0, (0, common_1.Inject)(saved_view_repository_1.SAVED_VIEW_REPOSITORY)),
|
|
31
|
+
tslib_1.__metadata("design:paramtypes", [Object])
|
|
32
|
+
], SavedViewsQuery);
|
|
33
|
+
/** Projects a stored row into the API shape for one reader. */
|
|
34
|
+
function toSavedView(record, readerId, defaultId) {
|
|
35
|
+
return {
|
|
36
|
+
id: record.id,
|
|
37
|
+
scope: record.scope,
|
|
38
|
+
name: record.name,
|
|
39
|
+
visibility: record.visibility,
|
|
40
|
+
ownerId: record.ownerId,
|
|
41
|
+
isOwn: record.ownerId === readerId,
|
|
42
|
+
isDefault: record.id === defaultId,
|
|
43
|
+
payload: record.payload,
|
|
44
|
+
updatedAt: record.updatedAt.toISOString()
|
|
45
|
+
};
|
|
46
|
+
}
|