@orthacms/content-server 0.0.0-reserve.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +7 -0
- package/dist/define.d.ts +17 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +28 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +109 -0
- package/dist/lib/collection/define.d.ts +35 -0
- package/dist/lib/collection/define.d.ts.map +1 -0
- package/dist/lib/collection/define.js +217 -0
- package/dist/lib/collection/table-builder.d.ts +28 -0
- package/dist/lib/collection/table-builder.d.ts.map +1 -0
- package/dist/lib/collection/table-builder.js +306 -0
- package/dist/lib/content-types/controllers/get-content-schema.controller.d.ts +24 -0
- package/dist/lib/content-types/controllers/get-content-schema.controller.d.ts.map +1 -0
- package/dist/lib/content-types/controllers/get-content-schema.controller.js +58 -0
- package/dist/lib/content-types/controllers/get-filter-fields.controller.d.ts +35 -0
- package/dist/lib/content-types/controllers/get-filter-fields.controller.d.ts.map +1 -0
- package/dist/lib/content-types/controllers/get-filter-fields.controller.js +74 -0
- package/dist/lib/content-types/controllers/list-content-schema.controller.d.ts +15 -0
- package/dist/lib/content-types/controllers/list-content-schema.controller.d.ts.map +1 -0
- package/dist/lib/content-types/controllers/list-content-schema.controller.js +38 -0
- package/dist/lib/content-types/queries/workspace-grants.query.d.ts +25 -0
- package/dist/lib/content-types/queries/workspace-grants.query.d.ts.map +1 -0
- package/dist/lib/content-types/queries/workspace-grants.query.js +45 -0
- package/dist/lib/content.module.d.ts +21 -0
- package/dist/lib/content.module.d.ts.map +1 -0
- package/dist/lib/content.module.js +264 -0
- package/dist/lib/content.tokens.d.ts +5 -0
- package/dist/lib/content.tokens.d.ts.map +1 -0
- package/dist/lib/content.tokens.js +9 -0
- package/dist/lib/copilot/content-tool.provider.d.ts +64 -0
- package/dist/lib/copilot/content-tool.provider.d.ts.map +1 -0
- package/dist/lib/copilot/content-tool.provider.js +309 -0
- package/dist/lib/copilot/diff-snapshots.d.ts +42 -0
- package/dist/lib/copilot/diff-snapshots.d.ts.map +1 -0
- package/dist/lib/copilot/diff-snapshots.js +77 -0
- package/dist/lib/copilot/entry-proposal.applier.d.ts +89 -0
- package/dist/lib/copilot/entry-proposal.applier.d.ts.map +1 -0
- package/dist/lib/copilot/entry-proposal.applier.js +245 -0
- package/dist/lib/copilot/entry-proposal.provider.d.ts +157 -0
- package/dist/lib/copilot/entry-proposal.provider.d.ts.map +1 -0
- package/dist/lib/copilot/entry-proposal.provider.js +619 -0
- package/dist/lib/copilot/filter-schema.d.ts +61 -0
- package/dist/lib/copilot/filter-schema.d.ts.map +1 -0
- package/dist/lib/copilot/filter-schema.js +139 -0
- package/dist/lib/copilot/project-entry.d.ts +23 -0
- package/dist/lib/copilot/project-entry.d.ts.map +1 -0
- package/dist/lib/copilot/project-entry.js +36 -0
- package/dist/lib/copilot/proposal-kinds.d.ts +30 -0
- package/dist/lib/copilot/proposal-kinds.d.ts.map +1 -0
- package/dist/lib/copilot/proposal-kinds.js +32 -0
- package/dist/lib/copilot/revision-tool.provider.d.ts +56 -0
- package/dist/lib/copilot/revision-tool.provider.d.ts.map +1 -0
- package/dist/lib/copilot/revision-tool.provider.js +215 -0
- package/dist/lib/docs/content-schemas.d.ts +34 -0
- package/dist/lib/docs/content-schemas.d.ts.map +1 -0
- package/dist/lib/docs/content-schemas.js +617 -0
- package/dist/lib/docs/describe-content-api.d.ts +22 -0
- package/dist/lib/docs/describe-content-api.d.ts.map +1 -0
- package/dist/lib/docs/describe-content-api.js +173 -0
- package/dist/lib/docs/field-schema.d.ts +28 -0
- package/dist/lib/docs/field-schema.d.ts.map +1 -0
- package/dist/lib/docs/field-schema.js +214 -0
- package/dist/lib/entries/application/use-cases/bulk-publish-entries.use-case.d.ts +23 -0
- package/dist/lib/entries/application/use-cases/bulk-publish-entries.use-case.d.ts.map +1 -0
- package/dist/lib/entries/application/use-cases/bulk-publish-entries.use-case.js +77 -0
- package/dist/lib/entries/application/use-cases/bulk-unpublish-entries.use-case.d.ts +23 -0
- package/dist/lib/entries/application/use-cases/bulk-unpublish-entries.use-case.d.ts.map +1 -0
- package/dist/lib/entries/application/use-cases/bulk-unpublish-entries.use-case.js +66 -0
- package/dist/lib/entries/application/use-cases/publish-entry.use-case.d.ts +43 -0
- package/dist/lib/entries/application/use-cases/publish-entry.use-case.d.ts.map +1 -0
- package/dist/lib/entries/application/use-cases/publish-entry.use-case.js +106 -0
- package/dist/lib/entries/application/use-cases/unpublish-entry.use-case.d.ts +30 -0
- package/dist/lib/entries/application/use-cases/unpublish-entry.use-case.d.ts.map +1 -0
- package/dist/lib/entries/application/use-cases/unpublish-entry.use-case.js +70 -0
- package/dist/lib/entries/controllers/bulk-entries.controller.d.ts +26 -0
- package/dist/lib/entries/controllers/bulk-entries.controller.d.ts.map +1 -0
- package/dist/lib/entries/controllers/create-entry.controller.d.ts +20 -0
- package/dist/lib/entries/controllers/create-entry.controller.d.ts.map +1 -0
- package/dist/lib/entries/controllers/delete-entry.controller.d.ts +24 -0
- package/dist/lib/entries/controllers/delete-entry.controller.d.ts.map +1 -0
- package/dist/lib/entries/controllers/get-entry.controller.d.ts +34 -0
- package/dist/lib/entries/controllers/get-entry.controller.d.ts.map +1 -0
- package/dist/lib/entries/controllers/list-entries.controller.d.ts +20 -0
- package/dist/lib/entries/controllers/list-entries.controller.d.ts.map +1 -0
- package/dist/lib/entries/controllers/publish-entry.controller.d.ts +19 -0
- package/dist/lib/entries/controllers/publish-entry.controller.d.ts.map +1 -0
- package/dist/lib/entries/controllers/resolve-type.d.ts +9 -0
- package/dist/lib/entries/controllers/resolve-type.d.ts.map +1 -0
- package/dist/lib/entries/controllers/update-entry.controller.d.ts +18 -0
- package/dist/lib/entries/controllers/update-entry.controller.d.ts.map +1 -0
- package/dist/lib/entries/domain/entry-publish-blocked.error.d.ts +13 -0
- package/dist/lib/entries/domain/entry-publish-blocked.error.d.ts.map +1 -0
- package/dist/lib/entries/domain/entry-publish-blocked.error.js +19 -0
- package/dist/lib/entries/domain/entry.d.ts +71 -0
- package/dist/lib/entries/domain/entry.d.ts.map +1 -0
- package/dist/lib/entries/domain/entry.js +90 -0
- package/dist/lib/entries/domain/events/entry-events.d.ts +67 -0
- package/dist/lib/entries/domain/events/entry-events.d.ts.map +1 -0
- package/dist/lib/entries/domain/events/entry-events.js +100 -0
- package/dist/lib/entries/dto/bulk-ids.dto.d.ts +11 -0
- package/dist/lib/entries/dto/bulk-ids.dto.d.ts.map +1 -0
- package/dist/lib/entries/dto/list-entries-query.dto.d.ts +46 -0
- package/dist/lib/entries/dto/list-entries-query.dto.d.ts.map +1 -0
- package/dist/lib/entries/dto/relation-delta-map.validator.d.ts +19 -0
- package/dist/lib/entries/dto/relation-delta-map.validator.d.ts.map +1 -0
- package/dist/lib/entries/dto/save-entry.dto.d.ts +46 -0
- package/dist/lib/entries/dto/save-entry.dto.d.ts.map +1 -0
- package/dist/lib/entries/entries.constants.d.ts +19 -0
- package/dist/lib/entries/entries.constants.d.ts.map +1 -0
- package/dist/lib/entries/entries.constants.js +21 -0
- package/dist/lib/entries/http/controllers/bulk-entries.controller.d.ts +33 -0
- package/dist/lib/entries/http/controllers/bulk-entries.controller.d.ts.map +1 -0
- package/dist/lib/entries/http/controllers/bulk-entries.controller.js +143 -0
- package/dist/lib/entries/http/controllers/create-entry.controller.d.ts +21 -0
- package/dist/lib/entries/http/controllers/create-entry.controller.d.ts.map +1 -0
- package/dist/lib/entries/http/controllers/create-entry.controller.js +52 -0
- package/dist/lib/entries/http/controllers/delete-entry.controller.d.ts +25 -0
- package/dist/lib/entries/http/controllers/delete-entry.controller.d.ts.map +1 -0
- package/dist/lib/entries/http/controllers/delete-entry.controller.js +84 -0
- package/dist/lib/entries/http/controllers/get-entry.controller.d.ts +44 -0
- package/dist/lib/entries/http/controllers/get-entry.controller.d.ts.map +1 -0
- package/dist/lib/entries/http/controllers/get-entry.controller.js +124 -0
- package/dist/lib/entries/http/controllers/list-entries.controller.d.ts +20 -0
- package/dist/lib/entries/http/controllers/list-entries.controller.d.ts.map +1 -0
- package/dist/lib/entries/http/controllers/list-entries.controller.js +52 -0
- package/dist/lib/entries/http/controllers/publish-entry.controller.d.ts +22 -0
- package/dist/lib/entries/http/controllers/publish-entry.controller.d.ts.map +1 -0
- package/dist/lib/entries/http/controllers/publish-entry.controller.js +68 -0
- package/dist/lib/entries/http/controllers/resolve-type.d.ts +9 -0
- package/dist/lib/entries/http/controllers/resolve-type.d.ts.map +1 -0
- package/dist/lib/entries/http/controllers/resolve-type.js +16 -0
- package/dist/lib/entries/http/controllers/to-actor.d.ts +13 -0
- package/dist/lib/entries/http/controllers/to-actor.d.ts.map +1 -0
- package/dist/lib/entries/http/controllers/to-actor.js +15 -0
- package/dist/lib/entries/http/controllers/update-entry.controller.d.ts +19 -0
- package/dist/lib/entries/http/controllers/update-entry.controller.d.ts.map +1 -0
- package/dist/lib/entries/http/controllers/update-entry.controller.js +51 -0
- package/dist/lib/entries/http/dto/bulk-ids.dto.d.ts +11 -0
- package/dist/lib/entries/http/dto/bulk-ids.dto.d.ts.map +1 -0
- package/dist/lib/entries/http/dto/bulk-ids.dto.js +33 -0
- package/dist/lib/entries/http/dto/list-entries-query.dto.d.ts +66 -0
- package/dist/lib/entries/http/dto/list-entries-query.dto.d.ts.map +1 -0
- package/dist/lib/entries/http/dto/list-entries-query.dto.js +192 -0
- package/dist/lib/entries/http/dto/relation-delta-map.validator.d.ts +30 -0
- package/dist/lib/entries/http/dto/relation-delta-map.validator.d.ts.map +1 -0
- package/dist/lib/entries/http/dto/relation-delta-map.validator.js +102 -0
- package/dist/lib/entries/http/dto/save-entry.dto.d.ts +48 -0
- package/dist/lib/entries/http/dto/save-entry.dto.d.ts.map +1 -0
- package/dist/lib/entries/http/dto/save-entry.dto.js +120 -0
- package/dist/lib/entries/http/guards/content-grant.guard.d.ts +37 -0
- package/dist/lib/entries/http/guards/content-grant.guard.d.ts.map +1 -0
- package/dist/lib/entries/http/guards/content-grant.guard.js +67 -0
- package/dist/lib/entries/infrastructure/persistence/bulk-publish-verdicts.d.ts +22 -0
- package/dist/lib/entries/infrastructure/persistence/bulk-publish-verdicts.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/persistence/bulk-publish-verdicts.js +81 -0
- package/dist/lib/entries/infrastructure/persistence/entry-counter.service.d.ts +42 -0
- package/dist/lib/entries/infrastructure/persistence/entry-counter.service.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/persistence/entry-counter.service.js +73 -0
- package/dist/lib/entries/infrastructure/persistence/entry-row.d.ts +56 -0
- package/dist/lib/entries/infrastructure/persistence/entry-row.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/persistence/entry-row.js +185 -0
- package/dist/lib/entries/infrastructure/persistence/entry-writer.service.d.ts +392 -0
- package/dist/lib/entries/infrastructure/persistence/entry-writer.service.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/persistence/entry-writer.service.js +1223 -0
- package/dist/lib/entries/infrastructure/persistence/field-selection.d.ts +24 -0
- package/dist/lib/entries/infrastructure/persistence/field-selection.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/persistence/media-accept.d.ts +23 -0
- package/dist/lib/entries/infrastructure/persistence/media-accept.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/persistence/media-accept.js +55 -0
- package/dist/lib/entries/infrastructure/persistence/relation-link.service.d.ts +327 -0
- package/dist/lib/entries/infrastructure/persistence/relation-link.service.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/persistence/relation-link.service.js +1008 -0
- package/dist/lib/entries/infrastructure/queries/bulk-publish-preview.query.d.ts +19 -0
- package/dist/lib/entries/infrastructure/queries/bulk-publish-preview.query.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/queries/bulk-publish-preview.query.js +39 -0
- package/dist/lib/entries/infrastructure/queries/entries.service.d.ts +64 -0
- package/dist/lib/entries/infrastructure/queries/entries.service.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/queries/entries.service.js +202 -0
- package/dist/lib/entries/infrastructure/queries/entry-filter-schema.d.ts +40 -0
- package/dist/lib/entries/infrastructure/queries/entry-filter-schema.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/queries/entry-filter-surface.d.ts +38 -0
- package/dist/lib/entries/infrastructure/queries/entry-filter-surface.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/queries/entry-filter-surface.js +310 -0
- package/dist/lib/entries/infrastructure/queries/entry-scalar-fields.d.ts +25 -0
- package/dist/lib/entries/infrastructure/queries/entry-scalar-fields.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/queries/entry-scalar-fields.js +51 -0
- package/dist/lib/entries/infrastructure/queries/entry-search.d.ts +19 -0
- package/dist/lib/entries/infrastructure/queries/entry-search.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/queries/entry-search.js +52 -0
- package/dist/lib/entries/infrastructure/queries/media-refs.query.d.ts +21 -0
- package/dist/lib/entries/infrastructure/queries/media-refs.query.d.ts.map +1 -0
- package/dist/lib/entries/infrastructure/queries/media-refs.query.js +117 -0
- package/dist/lib/entries/services/entries.service.d.ts +59 -0
- package/dist/lib/entries/services/entries.service.d.ts.map +1 -0
- package/dist/lib/entries/services/entry-counter.service.d.ts +31 -0
- package/dist/lib/entries/services/entry-counter.service.d.ts.map +1 -0
- package/dist/lib/entries/services/entry-filter-schema.d.ts +32 -0
- package/dist/lib/entries/services/entry-filter-schema.d.ts.map +1 -0
- package/dist/lib/entries/services/entry-row.d.ts +56 -0
- package/dist/lib/entries/services/entry-row.d.ts.map +1 -0
- package/dist/lib/entries/services/entry-writer.service.d.ts +193 -0
- package/dist/lib/entries/services/entry-writer.service.d.ts.map +1 -0
- package/dist/lib/entries/services/relation-link.service.d.ts +115 -0
- package/dist/lib/entries/services/relation-link.service.d.ts.map +1 -0
- package/dist/lib/entries/types/bulk-publish.d.ts +75 -0
- package/dist/lib/entries/types/bulk-publish.d.ts.map +1 -0
- package/dist/lib/entries/types/bulk-publish.js +22 -0
- package/dist/lib/entries/types/entry-list-view.d.ts +205 -0
- package/dist/lib/entries/types/entry-list-view.d.ts.map +1 -0
- package/dist/lib/entries/types/entry-list-view.js +5 -0
- package/dist/lib/entries/types/filter-surface.d.ts +35 -0
- package/dist/lib/entries/types/filter-surface.d.ts.map +1 -0
- package/dist/lib/entries/types/filter-surface.js +2 -0
- package/dist/lib/extension/entry-extension-boot-check.d.ts +16 -0
- package/dist/lib/extension/entry-extension-boot-check.d.ts.map +1 -0
- package/dist/lib/extension/entry-extension-boot-check.js +42 -0
- package/dist/lib/extension/entry-extension.d.ts +225 -0
- package/dist/lib/extension/entry-extension.d.ts.map +1 -0
- package/dist/lib/extension/entry-extension.js +27 -0
- package/dist/lib/extension/media-asset-resolver.d.ts +85 -0
- package/dist/lib/extension/media-asset-resolver.d.ts.map +1 -0
- package/dist/lib/extension/media-asset-resolver.js +26 -0
- package/dist/lib/extension/per-locale-relation.d.ts +18 -0
- package/dist/lib/extension/per-locale-relation.d.ts.map +1 -0
- package/dist/lib/extension/relation-locale-sync.d.ts +62 -0
- package/dist/lib/extension/relation-locale-sync.d.ts.map +1 -0
- package/dist/lib/extension/relation-locale-sync.js +88 -0
- package/dist/lib/fields/index.d.ts +94 -0
- package/dist/lib/fields/index.d.ts.map +1 -0
- package/dist/lib/fields/index.js +203 -0
- package/dist/lib/insights/http/controllers/content-pipeline.controller.d.ts +16 -0
- package/dist/lib/insights/http/controllers/content-pipeline.controller.d.ts.map +1 -0
- package/dist/lib/insights/http/controllers/content-pipeline.controller.js +39 -0
- package/dist/lib/insights/http/controllers/content-punchcard.controller.d.ts +18 -0
- package/dist/lib/insights/http/controllers/content-punchcard.controller.d.ts.map +1 -0
- package/dist/lib/insights/http/controllers/content-punchcard.controller.js +42 -0
- package/dist/lib/insights/http/controllers/content-stale.controller.d.ts +17 -0
- package/dist/lib/insights/http/controllers/content-stale.controller.d.ts.map +1 -0
- package/dist/lib/insights/http/controllers/content-stale.controller.js +40 -0
- package/dist/lib/insights/http/controllers/content-totals.controller.d.ts +18 -0
- package/dist/lib/insights/http/controllers/content-totals.controller.d.ts.map +1 -0
- package/dist/lib/insights/http/controllers/content-totals.controller.js +42 -0
- package/dist/lib/insights/http/controllers/content-unshipped.controller.d.ts +17 -0
- package/dist/lib/insights/http/controllers/content-unshipped.controller.d.ts.map +1 -0
- package/dist/lib/insights/http/controllers/content-unshipped.controller.js +40 -0
- package/dist/lib/insights/http/controllers/content-velocity.controller.d.ts +17 -0
- package/dist/lib/insights/http/controllers/content-velocity.controller.d.ts.map +1 -0
- package/dist/lib/insights/http/controllers/content-velocity.controller.js +41 -0
- package/dist/lib/insights/http/dto/insights-range-query.dto.d.ts +15 -0
- package/dist/lib/insights/http/dto/insights-range-query.dto.d.ts.map +1 -0
- package/dist/lib/insights/http/dto/insights-range-query.dto.js +38 -0
- package/dist/lib/insights/infrastructure/queries/content-insights.query.d.ts +77 -0
- package/dist/lib/insights/infrastructure/queries/content-insights.query.d.ts.map +1 -0
- package/dist/lib/insights/infrastructure/queries/content-insights.query.js +380 -0
- package/dist/lib/insights/types/content-insights-view.d.ts +134 -0
- package/dist/lib/insights/types/content-insights-view.d.ts.map +1 -0
- package/dist/lib/insights/types/content-insights-view.js +10 -0
- package/dist/lib/mcp/content-tools.provider.d.ts +83 -0
- package/dist/lib/mcp/content-tools.provider.d.ts.map +1 -0
- package/dist/lib/mcp/content-tools.provider.js +441 -0
- package/dist/lib/mcp/tool-input.d.ts +43 -0
- package/dist/lib/mcp/tool-input.d.ts.map +1 -0
- package/dist/lib/mcp/tool-input.js +117 -0
- package/dist/lib/mcp/tool-schemas.d.ts +34 -0
- package/dist/lib/mcp/tool-schemas.d.ts.map +1 -0
- package/dist/lib/mcp/tool-schemas.js +282 -0
- package/dist/lib/public/controllers/get-public-entry.controller.d.ts +26 -0
- package/dist/lib/public/controllers/get-public-entry.controller.d.ts.map +1 -0
- package/dist/lib/public/controllers/list-public-entries.controller.d.ts +24 -0
- package/dist/lib/public/controllers/list-public-entries.controller.d.ts.map +1 -0
- package/dist/lib/public/controllers/public-schema.controller.d.ts +18 -0
- package/dist/lib/public/controllers/public-schema.controller.d.ts.map +1 -0
- package/dist/lib/public-api/http/api-token-request.d.ts +41 -0
- package/dist/lib/public-api/http/api-token-request.d.ts.map +1 -0
- package/dist/lib/public-api/http/api-token-request.js +2 -0
- package/dist/lib/public-api/http/controllers/public-content-types.controller.d.ts +31 -0
- package/dist/lib/public-api/http/controllers/public-content-types.controller.d.ts.map +1 -0
- package/dist/lib/public-api/http/controllers/public-content-types.controller.js +93 -0
- package/dist/lib/public-api/http/controllers/public-entries.controller.d.ts +101 -0
- package/dist/lib/public-api/http/controllers/public-entries.controller.d.ts.map +1 -0
- package/dist/lib/public-api/http/controllers/public-entries.controller.js +307 -0
- package/dist/lib/public-api/http/controllers/public-entry-writes.controller.d.ts +76 -0
- package/dist/lib/public-api/http/controllers/public-entry-writes.controller.d.ts.map +1 -0
- package/dist/lib/public-api/http/controllers/public-entry-writes.controller.js +353 -0
- package/dist/lib/public-api/http/controllers/resolve-granted-type.d.ts +42 -0
- package/dist/lib/public-api/http/controllers/resolve-granted-type.d.ts.map +1 -0
- package/dist/lib/public-api/http/controllers/resolve-granted-type.js +25 -0
- package/dist/lib/public-api/http/decorators/current-api-token.decorator.d.ts +8 -0
- package/dist/lib/public-api/http/decorators/current-api-token.decorator.d.ts.map +1 -0
- package/dist/lib/public-api/http/decorators/current-api-token.decorator.js +17 -0
- package/dist/lib/public-api/http/dto/public-bulk.dto.d.ts +58 -0
- package/dist/lib/public-api/http/dto/public-bulk.dto.d.ts.map +1 -0
- package/dist/lib/public-api/http/dto/public-bulk.dto.js +118 -0
- package/dist/lib/public-api/http/dto/public-list-entries-query.dto.d.ts +106 -0
- package/dist/lib/public-api/http/dto/public-list-entries-query.dto.d.ts.map +1 -0
- package/dist/lib/public-api/http/dto/public-list-entries-query.dto.js +297 -0
- package/dist/lib/public-api/http/dto/public-save-entry.dto.d.ts +39 -0
- package/dist/lib/public-api/http/dto/public-save-entry.dto.d.ts.map +1 -0
- package/dist/lib/public-api/http/dto/public-save-entry.dto.js +112 -0
- package/dist/lib/public-api/http/guards/api-token-workspace.guard.d.ts +25 -0
- package/dist/lib/public-api/http/guards/api-token-workspace.guard.d.ts.map +1 -0
- package/dist/lib/public-api/http/guards/api-token-workspace.guard.js +58 -0
- package/dist/lib/public-api/http/guards/api-token.guard.d.ts +32 -0
- package/dist/lib/public-api/http/guards/api-token.guard.d.ts.map +1 -0
- package/dist/lib/public-api/http/guards/api-token.guard.js +92 -0
- package/dist/lib/public-api/http/guards/draft-visibility.guard.d.ts +25 -0
- package/dist/lib/public-api/http/guards/draft-visibility.guard.d.ts.map +1 -0
- package/dist/lib/public-api/http/guards/draft-visibility.guard.js +56 -0
- package/dist/lib/public-api/infrastructure/bulk-save-op.d.ts +55 -0
- package/dist/lib/public-api/infrastructure/bulk-save-op.d.ts.map +1 -0
- package/dist/lib/public-api/infrastructure/bulk-save-op.js +61 -0
- package/dist/lib/public-api/infrastructure/field-selection.d.ts +21 -0
- package/dist/lib/public-api/infrastructure/field-selection.d.ts.map +1 -0
- package/dist/lib/public-api/infrastructure/field-selection.js +72 -0
- package/dist/lib/public-api/infrastructure/public-entries.query.d.ts +248 -0
- package/dist/lib/public-api/infrastructure/public-entries.query.d.ts.map +1 -0
- package/dist/lib/public-api/infrastructure/public-entries.query.js +557 -0
- package/dist/lib/public-api/infrastructure/public-entry-row.d.ts +31 -0
- package/dist/lib/public-api/infrastructure/public-entry-row.d.ts.map +1 -0
- package/dist/lib/public-api/infrastructure/public-entry-row.js +76 -0
- package/dist/lib/public-api/infrastructure/public-entry-writes.service.d.ts +188 -0
- package/dist/lib/public-api/infrastructure/public-entry-writes.service.d.ts.map +1 -0
- package/dist/lib/public-api/infrastructure/public-entry-writes.service.js +321 -0
- package/dist/lib/public-api/infrastructure/public-expansion.query.d.ts +98 -0
- package/dist/lib/public-api/infrastructure/public-expansion.query.d.ts.map +1 -0
- package/dist/lib/public-api/infrastructure/public-expansion.query.js +384 -0
- package/dist/lib/public-api/types/public-bulk.d.ts +77 -0
- package/dist/lib/public-api/types/public-bulk.d.ts.map +1 -0
- package/dist/lib/public-api/types/public-bulk.js +23 -0
- package/dist/lib/public-api/types/public-entry.d.ts +97 -0
- package/dist/lib/public-api/types/public-entry.d.ts.map +1 -0
- package/dist/lib/public-api/types/public-entry.js +8 -0
- package/dist/lib/public-api/types/public-expansion.d.ts +92 -0
- package/dist/lib/public-api/types/public-expansion.d.ts.map +1 -0
- package/dist/lib/public-api/types/public-expansion.js +2 -0
- package/dist/lib/registry/content-type-registry.d.ts +103 -0
- package/dist/lib/registry/content-type-registry.d.ts.map +1 -0
- package/dist/lib/registry/content-type-registry.js +155 -0
- package/dist/lib/revisions/application/ports/revision-store.d.ts +71 -0
- package/dist/lib/revisions/application/ports/revision-store.d.ts.map +1 -0
- package/dist/lib/revisions/application/ports/revision-store.js +9 -0
- package/dist/lib/revisions/application/use-cases/publish-revision.use-case.d.ts +40 -0
- package/dist/lib/revisions/application/use-cases/publish-revision.use-case.d.ts.map +1 -0
- package/dist/lib/revisions/application/use-cases/publish-revision.use-case.js +66 -0
- package/dist/lib/revisions/application/use-cases/restore-revision.use-case.d.ts +36 -0
- package/dist/lib/revisions/application/use-cases/restore-revision.use-case.d.ts.map +1 -0
- package/dist/lib/revisions/application/use-cases/restore-revision.use-case.js +57 -0
- package/dist/lib/revisions/domain/revision-status.d.ts +18 -0
- package/dist/lib/revisions/domain/revision-status.d.ts.map +1 -0
- package/dist/lib/revisions/domain/revision-status.js +18 -0
- package/dist/lib/revisions/domain/revision.d.ts +80 -0
- package/dist/lib/revisions/domain/revision.d.ts.map +1 -0
- package/dist/lib/revisions/domain/revision.js +84 -0
- package/dist/lib/revisions/http/controllers/publish-revision.controller.d.ts +19 -0
- package/dist/lib/revisions/http/controllers/publish-revision.controller.d.ts.map +1 -0
- package/dist/lib/revisions/http/controllers/publish-revision.controller.js +51 -0
- package/dist/lib/revisions/http/controllers/restore-revision.controller.d.ts +17 -0
- package/dist/lib/revisions/http/controllers/restore-revision.controller.d.ts.map +1 -0
- package/dist/lib/revisions/http/controllers/restore-revision.controller.js +49 -0
- package/dist/lib/revisions/http/controllers/revisions.controller.d.ts +20 -0
- package/dist/lib/revisions/http/controllers/revisions.controller.d.ts.map +1 -0
- package/dist/lib/revisions/http/controllers/revisions.controller.js +76 -0
- package/dist/lib/revisions/infrastructure/persistence/drizzle-revision.store.d.ts +33 -0
- package/dist/lib/revisions/infrastructure/persistence/drizzle-revision.store.d.ts.map +1 -0
- package/dist/lib/revisions/infrastructure/persistence/drizzle-revision.store.js +174 -0
- package/dist/lib/revisions/infrastructure/persistence/revision-snapshot.d.ts +17 -0
- package/dist/lib/revisions/infrastructure/persistence/revision-snapshot.d.ts.map +1 -0
- package/dist/lib/revisions/infrastructure/persistence/revision-snapshot.js +20 -0
- package/dist/lib/revisions/infrastructure/persistence/revision-table.d.ts +228 -0
- package/dist/lib/revisions/infrastructure/persistence/revision-table.d.ts.map +1 -0
- package/dist/lib/revisions/infrastructure/persistence/revision-table.js +57 -0
- package/dist/lib/revisions/infrastructure/queries/revision-refs.query.d.ts +22 -0
- package/dist/lib/revisions/infrastructure/queries/revision-refs.query.d.ts.map +1 -0
- package/dist/lib/revisions/infrastructure/queries/revision-refs.query.js +66 -0
- package/dist/lib/revisions/revisions.constants.d.ts +10 -0
- package/dist/lib/revisions/revisions.constants.d.ts.map +1 -0
- package/dist/lib/revisions/revisions.constants.js +12 -0
- package/dist/lib/revisions/types/revision-view.d.ts +74 -0
- package/dist/lib/revisions/types/revision-view.d.ts.map +1 -0
- package/dist/lib/revisions/types/revision-view.js +2 -0
- package/dist/lib/types/content-type.d.ts +131 -0
- package/dist/lib/types/content-type.d.ts.map +1 -0
- package/dist/lib/types/content-type.js +28 -0
- package/dist/lib/types/fields.d.ts +303 -0
- package/dist/lib/types/fields.d.ts.map +1 -0
- package/dist/lib/types/fields.js +52 -0
- package/dist/lib/utils/content-plugin.d.ts +35 -0
- package/dist/lib/utils/content-plugin.d.ts.map +1 -0
- package/dist/lib/utils/content-plugin.js +35 -0
- package/dist/lib/validation/services/entry-validation.service.d.ts +24 -0
- package/dist/lib/validation/services/entry-validation.service.d.ts.map +1 -0
- package/dist/lib/validation/services/entry-validation.service.js +35 -0
- package/package.json +54 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Turns a field map into physical Drizzle tables. One table per content
|
|
4
|
+
* type (`content_<name>`), plus one join table per many-relation
|
|
5
|
+
* (`content_<name>_<field>`). The HOST re-exports these from its
|
|
6
|
+
* drizzle-kit schema entry, so collection changes become ordinary
|
|
7
|
+
* committed migrations — exactly like any plugin-owned schema.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.snakeCase = snakeCase;
|
|
11
|
+
exports.buildTables = buildTables;
|
|
12
|
+
const drizzle_orm_1 = require("drizzle-orm");
|
|
13
|
+
const pg_core_1 = require("drizzle-orm/pg-core");
|
|
14
|
+
const fields_1 = require("../types/fields");
|
|
15
|
+
const content_type_1 = require("../types/content-type");
|
|
16
|
+
/** camelCase / kebab-case → snake_case column-safe identifier. */
|
|
17
|
+
function snakeCase(value) {
|
|
18
|
+
return value
|
|
19
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
20
|
+
.replace(/[^a-zA-Z0-9]+/g, '_')
|
|
21
|
+
.toLowerCase();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The `id` column of a generated table. Generated tables are built from a
|
|
25
|
+
* dynamic column record, so their columns aren't statically typed — but the
|
|
26
|
+
* envelope guarantees `id` exists on every one of them.
|
|
27
|
+
*/
|
|
28
|
+
function idColumnOf(table) {
|
|
29
|
+
return table.id;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Builds the column for one (non-many-relation) field.
|
|
33
|
+
*
|
|
34
|
+
* `enforceRequired` decides the NOT NULL constraint: a **non-publishable** type
|
|
35
|
+
* is always live, so a required field is `NOT NULL`. A **publishable** type has
|
|
36
|
+
* a draft stage where a required field may legitimately be empty — "required"
|
|
37
|
+
* means "required *to publish*", enforced by `EntryValidationService` at publish
|
|
38
|
+
* time, not the column. So a publishable type's columns stay nullable even when
|
|
39
|
+
* the field is required.
|
|
40
|
+
*/
|
|
41
|
+
function columnFor(fieldName, spec, enforceRequired, i18n) {
|
|
42
|
+
const col = snakeCase(fieldName);
|
|
43
|
+
let builder;
|
|
44
|
+
switch (spec.type) {
|
|
45
|
+
case fields_1.CONTENT_FIELD_TYPE.Text:
|
|
46
|
+
case fields_1.CONTENT_FIELD_TYPE.Select:
|
|
47
|
+
builder = (0, pg_core_1.text)(col);
|
|
48
|
+
break;
|
|
49
|
+
case fields_1.CONTENT_FIELD_TYPE.RichText:
|
|
50
|
+
// A structured document (the editor's node tree), not an HTML
|
|
51
|
+
// string — which is what makes a body's heading order, table
|
|
52
|
+
// headers and language markers checkable rather than opaque.
|
|
53
|
+
// A body written before that change is a JSON *string* in the same
|
|
54
|
+
// column, so nothing had to be rewritten to migrate: `jsonb` holds
|
|
55
|
+
// both, and both read back as a valid `richtext` value.
|
|
56
|
+
builder = (0, pg_core_1.jsonb)(col);
|
|
57
|
+
break;
|
|
58
|
+
case fields_1.CONTENT_FIELD_TYPE.Number:
|
|
59
|
+
builder = spec.validation.integer
|
|
60
|
+
? (0, pg_core_1.integer)(col)
|
|
61
|
+
: (0, pg_core_1.doublePrecision)(col);
|
|
62
|
+
break;
|
|
63
|
+
case fields_1.CONTENT_FIELD_TYPE.Money:
|
|
64
|
+
// integer minor units — exact arithmetic, no float drift
|
|
65
|
+
builder = (0, pg_core_1.integer)(col);
|
|
66
|
+
break;
|
|
67
|
+
case fields_1.CONTENT_FIELD_TYPE.Boolean:
|
|
68
|
+
// A required boolean defaults to false so an omitted value is a
|
|
69
|
+
// concrete `false` rather than a NOT NULL violation. The default is
|
|
70
|
+
// useful regardless of whether NOT NULL is ultimately enforced.
|
|
71
|
+
builder = spec.required
|
|
72
|
+
? (0, pg_core_1.boolean)(col).default(false)
|
|
73
|
+
: (0, pg_core_1.boolean)(col);
|
|
74
|
+
break;
|
|
75
|
+
case fields_1.CONTENT_FIELD_TYPE.Date:
|
|
76
|
+
builder = (0, pg_core_1.date)(col);
|
|
77
|
+
break;
|
|
78
|
+
case fields_1.CONTENT_FIELD_TYPE.Datetime:
|
|
79
|
+
builder = (0, pg_core_1.timestamp)(col, { withTimezone: true });
|
|
80
|
+
break;
|
|
81
|
+
case fields_1.CONTENT_FIELD_TYPE.Json:
|
|
82
|
+
case fields_1.CONTENT_FIELD_TYPE.Multiselect:
|
|
83
|
+
builder = (0, pg_core_1.jsonb)(col);
|
|
84
|
+
break;
|
|
85
|
+
case fields_1.CONTENT_FIELD_TYPE.Media:
|
|
86
|
+
// A media reference is an asset id (or an ordered list of them).
|
|
87
|
+
// No FK — the assets live in the media plugin's schema, which this
|
|
88
|
+
// package can't reference (same convention as `workspace_id`);
|
|
89
|
+
// existence + the `accept` restriction are enforced in the app layer.
|
|
90
|
+
builder = spec.multiple ? (0, pg_core_1.jsonb)(col) : (0, pg_core_1.uuid)(col);
|
|
91
|
+
break;
|
|
92
|
+
case fields_1.CONTENT_FIELD_TYPE.Relation: {
|
|
93
|
+
// An inverse (back-reference) owns no storage — it reuses the owning
|
|
94
|
+
// side's column/join table.
|
|
95
|
+
if (spec.relation?.inverse)
|
|
96
|
+
return null;
|
|
97
|
+
if (spec.relation?.many)
|
|
98
|
+
return null; // join table instead
|
|
99
|
+
// Lazy reference: the thunk resolves at query/diff time, so
|
|
100
|
+
// mutually-referencing collections can import each other.
|
|
101
|
+
builder = (0, pg_core_1.uuid)(`${col}_id`).references(() => idColumnOf(spec.relation.to().table), { onDelete: spec.relation.onDelete });
|
|
102
|
+
// One-to-one: at most one owner may point at a given target.
|
|
103
|
+
// Nullable-unique — Postgres allows many NULLs, so owners with no
|
|
104
|
+
// relation don't collide.
|
|
105
|
+
//
|
|
106
|
+
// On an **i18n** type the constraint is per-locale instead, and is
|
|
107
|
+
// emitted as a composite index below rather than here: a localized
|
|
108
|
+
// record is N rows, one per language, so a column-wide UNIQUE would
|
|
109
|
+
// read "one *row* may point at this target" when what the model
|
|
110
|
+
// means is "one *record* may". The English and German rows of one
|
|
111
|
+
// article legitimately share an SEO record; two different articles
|
|
112
|
+
// must not.
|
|
113
|
+
if (spec.relation.unique && !i18n)
|
|
114
|
+
builder = builder.unique();
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return enforceRequired && spec.required ? builder.notNull() : builder;
|
|
119
|
+
}
|
|
120
|
+
/** Builds the main table + join tables for a content type. */
|
|
121
|
+
function buildTables(typeName, fields, meta = {}) {
|
|
122
|
+
const tableName = `content_${snakeCase(typeName)}`;
|
|
123
|
+
const columns = {
|
|
124
|
+
/** Primary key. */
|
|
125
|
+
id: (0, pg_core_1.uuid)('id').primaryKey().defaultRandom(),
|
|
126
|
+
/**
|
|
127
|
+
* Owning workspace. Stamped on create and filtered on every read/write
|
|
128
|
+
* by the entries services (scoped via `WorkspaceGuard`'s `X-Workspace-Id`
|
|
129
|
+
* header), so entries never cross workspaces. Plain uuid, no FK — the
|
|
130
|
+
* `workspaces` table lives in the identity plugin's schema, which this
|
|
131
|
+
* package can't reference; isolation is enforced in the app layer.
|
|
132
|
+
*/
|
|
133
|
+
workspaceId: (0, pg_core_1.uuid)('workspace_id'),
|
|
134
|
+
/** Row creation timestamp. */
|
|
135
|
+
createdAt: (0, pg_core_1.timestamp)('created_at', { withTimezone: true })
|
|
136
|
+
.notNull()
|
|
137
|
+
.defaultNow(),
|
|
138
|
+
/** Last update timestamp (the service layer refreshes it). */
|
|
139
|
+
updatedAt: (0, pg_core_1.timestamp)('updated_at', { withTimezone: true })
|
|
140
|
+
.notNull()
|
|
141
|
+
.defaultNow()
|
|
142
|
+
};
|
|
143
|
+
// Publish workflow is opt-in: only a `publishable` type carries a
|
|
144
|
+
// draft/published `status` and the `published_at` stamp — two halves of
|
|
145
|
+
// the same concept. A non-publishable type has no publish state; every row
|
|
146
|
+
// is simply live. `published_at` is nullable with no default (null = "not
|
|
147
|
+
// yet published"; the service layer stamps it).
|
|
148
|
+
if (meta.publishable) {
|
|
149
|
+
columns['status'] = (0, pg_core_1.text)('status', {
|
|
150
|
+
enum: [content_type_1.ENTRY_STATUS.Draft, content_type_1.ENTRY_STATUS.Published]
|
|
151
|
+
})
|
|
152
|
+
.notNull()
|
|
153
|
+
.default(content_type_1.ENTRY_STATUS.Draft);
|
|
154
|
+
columns['publishedAt'] = (0, pg_core_1.timestamp)('published_at', {
|
|
155
|
+
withTimezone: true
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
// Soft delete: nullable `deleted_at` (null = "not deleted"; service stamps it).
|
|
159
|
+
if (meta.paranoid) {
|
|
160
|
+
columns['deletedAt'] = (0, pg_core_1.timestamp)('deleted_at', { withTimezone: true });
|
|
161
|
+
}
|
|
162
|
+
// Row-per-locale: each locale of an entry is a full row; siblings share a
|
|
163
|
+
// `locale_group_id`. The group id defaults to a fresh uuid so a plain
|
|
164
|
+
// create starts its own translation group — linking into an existing group
|
|
165
|
+
// (translation creation) sets it explicitly. The slug's meaning (allowed
|
|
166
|
+
// values, the default) is owned by the bound localization plugin.
|
|
167
|
+
if (meta.i18n) {
|
|
168
|
+
columns['locale'] = (0, pg_core_1.text)('locale').notNull();
|
|
169
|
+
columns['localeGroupId'] = (0, pg_core_1.uuid)('locale_group_id')
|
|
170
|
+
.notNull()
|
|
171
|
+
.defaultRandom();
|
|
172
|
+
}
|
|
173
|
+
// Publishable types keep required columns nullable (a draft may be
|
|
174
|
+
// incomplete; publish enforces requiredness). Non-publishable types are
|
|
175
|
+
// always live, so a required field is NOT NULL.
|
|
176
|
+
const enforceRequired = !meta.publishable;
|
|
177
|
+
for (const [fieldName, spec] of Object.entries(fields)) {
|
|
178
|
+
const column = columnFor(fieldName, spec, enforceRequired, !!meta.i18n);
|
|
179
|
+
if (column)
|
|
180
|
+
columns[fieldName] = column;
|
|
181
|
+
}
|
|
182
|
+
const table = (0, pg_core_1.pgTable)(tableName, columns, (t) => {
|
|
183
|
+
const cols = t;
|
|
184
|
+
// Every list view filters by workspace; i18n types also filter by
|
|
185
|
+
// locale, and publishable types by status — fold each into the list
|
|
186
|
+
// index only where the column exists.
|
|
187
|
+
const listColumns = [
|
|
188
|
+
cols['workspaceId'],
|
|
189
|
+
...(meta.i18n ? [cols['locale']] : []),
|
|
190
|
+
...(meta.publishable ? [cols['status']] : [])
|
|
191
|
+
];
|
|
192
|
+
const listIndexName = meta.i18n
|
|
193
|
+
? `${tableName}_workspace_locale_idx`
|
|
194
|
+
: meta.publishable
|
|
195
|
+
? `${tableName}_workspace_status_idx`
|
|
196
|
+
: `${tableName}_workspace_idx`;
|
|
197
|
+
const indexes = [
|
|
198
|
+
(0, pg_core_1.index)(listIndexName).on(listColumns[0], ...listColumns.slice(1))
|
|
199
|
+
];
|
|
200
|
+
// Each owning single relation's FK. The *inverse* of such a relation is
|
|
201
|
+
// read by filtering this column (`inArray(fk, sourceIds)` in
|
|
202
|
+
// `RelationLinkService.previewInverse`), which the records table now
|
|
203
|
+
// runs for a whole page on every render — unindexed that is a sequential
|
|
204
|
+
// scan of the collection per keystroke, sort click and page change.
|
|
205
|
+
// `unique: true` already implies an index, so skip those.
|
|
206
|
+
for (const [fieldName, spec] of Object.entries(fields)) {
|
|
207
|
+
if (spec.type !== fields_1.CONTENT_FIELD_TYPE.Relation)
|
|
208
|
+
continue;
|
|
209
|
+
if (spec.relation?.many ||
|
|
210
|
+
spec.relation?.inverse ||
|
|
211
|
+
spec.relation?.unique)
|
|
212
|
+
continue;
|
|
213
|
+
const fk = cols[fieldName];
|
|
214
|
+
if (!fk)
|
|
215
|
+
continue;
|
|
216
|
+
indexes.push((0, pg_core_1.index)(`${tableName}_${snakeCase(fieldName)}_id_idx`).on(fk));
|
|
217
|
+
}
|
|
218
|
+
if (meta.i18n) {
|
|
219
|
+
// One row per (group, locale). Partial on paranoid types so a
|
|
220
|
+
// soft-deleted sibling never blocks re-creating that locale —
|
|
221
|
+
// restoring into a conflict then fails (23505 → 409 upstream).
|
|
222
|
+
const groupLocale = (0, pg_core_1.uniqueIndex)(`${tableName}_group_locale_unique`).on(cols['localeGroupId'], cols['locale']);
|
|
223
|
+
indexes.push(meta.paranoid
|
|
224
|
+
? groupLocale.where((0, drizzle_orm_1.isNull)(cols['deletedAt']))
|
|
225
|
+
: groupLocale);
|
|
226
|
+
// One-to-one, **scoped to the locale** — the i18n counterpart of the
|
|
227
|
+
// column-level UNIQUE `columnFor` emits on a plain type.
|
|
228
|
+
//
|
|
229
|
+
// A localized record is one row per language, so "at most one owner
|
|
230
|
+
// points at this target" has to be counted in records, not rows.
|
|
231
|
+
// `(locale, <field>_id)` says exactly that: within any one language
|
|
232
|
+
// a target is claimed once, while the same target may be shared by
|
|
233
|
+
// the locale rows of the record that owns it — which is what a
|
|
234
|
+
// relation synced across the group *is*. Nullable-unique survives,
|
|
235
|
+
// since Postgres treats NULLs as distinct in a composite index too.
|
|
236
|
+
for (const [fieldName, spec] of Object.entries(fields)) {
|
|
237
|
+
if (spec.type !== fields_1.CONTENT_FIELD_TYPE.Relation ||
|
|
238
|
+
!spec.relation?.unique ||
|
|
239
|
+
spec.relation.many ||
|
|
240
|
+
spec.relation.inverse)
|
|
241
|
+
continue;
|
|
242
|
+
const fk = cols[fieldName];
|
|
243
|
+
if (!fk)
|
|
244
|
+
continue;
|
|
245
|
+
// The FK leads deliberately. Uniqueness of a pair is
|
|
246
|
+
// order-independent, but the leading column decides what the
|
|
247
|
+
// index can also *serve* — and the inverse side of this
|
|
248
|
+
// relation reads `inArray(<fk>, sourceIds)` for a whole page on
|
|
249
|
+
// every records-table render. Leading with `locale` would leave
|
|
250
|
+
// that a sequential scan, since the skipped plain FK index just
|
|
251
|
+
// below assumes `unique` already provides one.
|
|
252
|
+
const localeUnique = (0, pg_core_1.uniqueIndex)(`${tableName}_${snakeCase(fieldName)}_locale_unique`).on(fk, cols['locale']);
|
|
253
|
+
// Partial on paranoid types for the same reason as the pair
|
|
254
|
+
// above: a trashed row must not hold a target hostage.
|
|
255
|
+
indexes.push(meta.paranoid
|
|
256
|
+
? localeUnique.where((0, drizzle_orm_1.isNull)(cols['deletedAt']))
|
|
257
|
+
: localeUnique);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return indexes;
|
|
261
|
+
});
|
|
262
|
+
const joinTables = {};
|
|
263
|
+
for (const [fieldName, spec] of Object.entries(fields)) {
|
|
264
|
+
if (spec.type !== fields_1.CONTENT_FIELD_TYPE.Relation ||
|
|
265
|
+
!spec.relation?.many ||
|
|
266
|
+
spec.relation.inverse // inverse reuses the owning side's join table
|
|
267
|
+
)
|
|
268
|
+
continue;
|
|
269
|
+
const joinName = `${tableName}_${snakeCase(fieldName)}`;
|
|
270
|
+
joinTables[fieldName] = (0, pg_core_1.pgTable)(joinName, {
|
|
271
|
+
/** The owning entry. Join rows die with it. */
|
|
272
|
+
sourceId: (0, pg_core_1.uuid)('source_id')
|
|
273
|
+
.notNull()
|
|
274
|
+
.references(() => idColumnOf(table), {
|
|
275
|
+
onDelete: 'cascade'
|
|
276
|
+
}),
|
|
277
|
+
/** The referenced entry on the target type. */
|
|
278
|
+
targetId: (0, pg_core_1.uuid)('target_id')
|
|
279
|
+
.notNull()
|
|
280
|
+
.references(() => idColumnOf(spec.relation.to().table), {
|
|
281
|
+
onDelete: 'cascade'
|
|
282
|
+
}),
|
|
283
|
+
/**
|
|
284
|
+
* Ordinal of this target within its **source's** ordered list —
|
|
285
|
+
* the source's own ordering of its many-relation, so a
|
|
286
|
+
* drag-reorder survives a reload. Float, so a target can be moved
|
|
287
|
+
* between two neighbours without renumbering the whole list.
|
|
288
|
+
* Defaults to 0 (append picks `max(position)+1` for the source).
|
|
289
|
+
* The inverse side reads by it too (stable), but doesn't own the
|
|
290
|
+
* order — a two-way link has one order, the owning side's.
|
|
291
|
+
*/
|
|
292
|
+
position: (0, pg_core_1.doublePrecision)('position').notNull().default(0)
|
|
293
|
+
}, (t) => {
|
|
294
|
+
const cols = t;
|
|
295
|
+
return [
|
|
296
|
+
// one link per pair; leftmost prefix covers "links of an entry"
|
|
297
|
+
(0, pg_core_1.unique)(`${joinName}_pair_unique`).on(cols['sourceId'], cols['targetId']),
|
|
298
|
+
// reverse lookups: "which entries reference this target?"
|
|
299
|
+
(0, pg_core_1.index)(`${joinName}_target_idx`).on(cols['targetId']),
|
|
300
|
+
// ordered read of a source's links: `WHERE source_id ORDER BY position`
|
|
301
|
+
(0, pg_core_1.index)(`${joinName}_source_pos_idx`).on(cols['sourceId'], cols['position'])
|
|
302
|
+
];
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
return { table, joinTables };
|
|
306
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ContentTypeRegistry, SerializedContentType } from '../../registry/content-type-registry';
|
|
2
|
+
import { WorkspaceGrantsQuery } from '../queries/workspace-grants.query';
|
|
3
|
+
/**
|
|
4
|
+
* `GET /api/content-schema/:name` — the full field schema of one content
|
|
5
|
+
* type: types, validation rules, and admin presentation props. This is
|
|
6
|
+
* what the admin's dynamic tables/forms render from. Authentication is
|
|
7
|
+
* enforced by the app-wide AuthGuard; read access is gated on `content:read`.
|
|
8
|
+
*
|
|
9
|
+
* **Workspace-scoped**, like its `/filter-fields` sibling and unlike the
|
|
10
|
+
* `GET /api/content-schema` catalogue: the schema of a type is the shape of
|
|
11
|
+
* content this workspace may open, so a type the workspace was not granted
|
|
12
|
+
* (`workspace_content`) answers with exactly the `404` an unknown name gets —
|
|
13
|
+
* same status, same message, grants read before the registry decision — and
|
|
14
|
+
* the route therefore discloses nothing about the content model outside the
|
|
15
|
+
* caller's workspace. Serving it unconditionally was the read half of the
|
|
16
|
+
* hole `ContentGrantGuard` closes on the entry routes.
|
|
17
|
+
*/
|
|
18
|
+
export declare class GetContentSchemaController {
|
|
19
|
+
private readonly registry;
|
|
20
|
+
private readonly grants;
|
|
21
|
+
constructor(registry: ContentTypeRegistry, grants: WorkspaceGrantsQuery);
|
|
22
|
+
get(name: string, workspaceId: string): Promise<SerializedContentType>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=get-content-schema.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-content-schema.controller.d.ts","sourceRoot":"","sources":["../../../../src/lib/content-types/controllers/get-content-schema.controller.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACR,mBAAmB,EACnB,qBAAqB,EACxB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE;;;;;;;;;;;;;;GAcG;AACH,qBAGa,0BAA0B;IAG/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,QAAQ,EAAE,mBAAmB,EAC7B,MAAM,EAAE,oBAAoB;IAI3C,GAAG,CACU,IAAI,EAAE,MAAM,EACP,WAAW,EAAE,MAAM,GACxC,OAAO,CAAC,qBAAqB,CAAC;CAUpC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GetContentSchemaController = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const identity_server_1 = require("@orthacms/identity-server");
|
|
7
|
+
const workspaces_server_1 = require("@orthacms/workspaces-server");
|
|
8
|
+
const content_tokens_1 = require("../../content.tokens");
|
|
9
|
+
const workspace_grants_query_1 = require("../queries/workspace-grants.query");
|
|
10
|
+
/**
|
|
11
|
+
* `GET /api/content-schema/:name` — the full field schema of one content
|
|
12
|
+
* type: types, validation rules, and admin presentation props. This is
|
|
13
|
+
* what the admin's dynamic tables/forms render from. Authentication is
|
|
14
|
+
* enforced by the app-wide AuthGuard; read access is gated on `content:read`.
|
|
15
|
+
*
|
|
16
|
+
* **Workspace-scoped**, like its `/filter-fields` sibling and unlike the
|
|
17
|
+
* `GET /api/content-schema` catalogue: the schema of a type is the shape of
|
|
18
|
+
* content this workspace may open, so a type the workspace was not granted
|
|
19
|
+
* (`workspace_content`) answers with exactly the `404` an unknown name gets —
|
|
20
|
+
* same status, same message, grants read before the registry decision — and
|
|
21
|
+
* the route therefore discloses nothing about the content model outside the
|
|
22
|
+
* caller's workspace. Serving it unconditionally was the read half of the
|
|
23
|
+
* hole `ContentGrantGuard` closes on the entry routes.
|
|
24
|
+
*/
|
|
25
|
+
let GetContentSchemaController = class GetContentSchemaController {
|
|
26
|
+
registry;
|
|
27
|
+
grants;
|
|
28
|
+
constructor(registry, grants) {
|
|
29
|
+
this.registry = registry;
|
|
30
|
+
this.grants = grants;
|
|
31
|
+
}
|
|
32
|
+
async get(name, workspaceId) {
|
|
33
|
+
const serialized = this.registry.serialize(name);
|
|
34
|
+
// Read the grants before deciding, so an ungranted type and an unknown
|
|
35
|
+
// one are indistinguishable — same status, same body, same work done.
|
|
36
|
+
const granted = await this.grants.grantedSlugs(workspaceId);
|
|
37
|
+
if (!serialized || !granted.has(name)) {
|
|
38
|
+
throw new common_1.NotFoundException(`Unknown content type "${name}".`);
|
|
39
|
+
}
|
|
40
|
+
return serialized;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
exports.GetContentSchemaController = GetContentSchemaController;
|
|
44
|
+
tslib_1.__decorate([
|
|
45
|
+
(0, common_1.Get)(':name'),
|
|
46
|
+
tslib_1.__param(0, (0, common_1.Param)('name')),
|
|
47
|
+
tslib_1.__param(1, (0, workspaces_server_1.CurrentWorkspace)()),
|
|
48
|
+
tslib_1.__metadata("design:type", Function),
|
|
49
|
+
tslib_1.__metadata("design:paramtypes", [String, String]),
|
|
50
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
51
|
+
], GetContentSchemaController.prototype, "get", null);
|
|
52
|
+
exports.GetContentSchemaController = GetContentSchemaController = tslib_1.__decorate([
|
|
53
|
+
(0, common_1.UseGuards)(identity_server_1.PermissionsGuard, workspaces_server_1.WorkspaceGuard),
|
|
54
|
+
(0, identity_server_1.RequirePermissions)(identity_server_1.PERMISSIONS.CONTENT_READ),
|
|
55
|
+
(0, common_1.Controller)('content-schema'),
|
|
56
|
+
tslib_1.__param(0, (0, content_tokens_1.InjectContentRegistry)()),
|
|
57
|
+
tslib_1.__metadata("design:paramtypes", [Function, workspace_grants_query_1.WorkspaceGrantsQuery])
|
|
58
|
+
], GetContentSchemaController);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ContentTypeRegistry } from '../../registry/content-type-registry';
|
|
2
|
+
import type { FilterFieldsResponse } from '../../entries/types/filter-surface';
|
|
3
|
+
import { WorkspaceGrantsQuery } from '../queries/workspace-grants.query';
|
|
4
|
+
/**
|
|
5
|
+
* `GET /api/content-schema/:name/filter-fields` — every scalar path the
|
|
6
|
+
* records-table query builder may filter on: the type's own fields plus,
|
|
7
|
+
* recursively within the relation-hop budget, its relations' fields
|
|
8
|
+
* (`author.name`, `author.company.name`). This is the admin counterpart of
|
|
9
|
+
* the SQL `FilterSchema` the list endpoint enforces — both come from a
|
|
10
|
+
* single `buildEntryFilterSurface` traversal, so the picker can never offer
|
|
11
|
+
* a path the API would reject with a 400.
|
|
12
|
+
*
|
|
13
|
+
* **Workspace-scoped**, unlike the sibling `/content-schema` routes (which
|
|
14
|
+
* serve the global, code-defined type catalogue). The response describes
|
|
15
|
+
* what *this* workspace may traverse, so it is pruned to the workspace's
|
|
16
|
+
* `workspace_content` grants in two places:
|
|
17
|
+
*
|
|
18
|
+
* - the requested `:name` must itself be granted, else **404** — the same
|
|
19
|
+
* answer an unknown type gets, so the endpoint carries no signal about
|
|
20
|
+
* which types exist outside the caller's workspace;
|
|
21
|
+
* - `grantedTypes` prunes the offered relations, mirroring the entry
|
|
22
|
+
* editor's `availableTypeNames`, so the picker never offers a traversal
|
|
23
|
+
* into a collection the caller cannot open.
|
|
24
|
+
*
|
|
25
|
+
* The SQL the list endpoint runs is workspace-scoped regardless, so this is
|
|
26
|
+
* about not *disclosing* the shape of another workspace's content model,
|
|
27
|
+
* not about row access.
|
|
28
|
+
*/
|
|
29
|
+
export declare class GetFilterFieldsController {
|
|
30
|
+
private readonly registry;
|
|
31
|
+
private readonly grants;
|
|
32
|
+
constructor(registry: ContentTypeRegistry, grants: WorkspaceGrantsQuery);
|
|
33
|
+
filterFields(name: string, workspaceId: string): Promise<FilterFieldsResponse>;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=get-filter-fields.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-filter-fields.controller.d.ts","sourceRoot":"","sources":["../../../../src/lib/content-types/controllers/get-filter-fields.controller.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAEhF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAGa,yBAAyB;IAG9B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,QAAQ,EAAE,mBAAmB,EAC7B,MAAM,EAAE,oBAAoB;IAI3C,YAAY,CACC,IAAI,EAAE,MAAM,EACP,WAAW,EAAE,MAAM,GACxC,OAAO,CAAC,oBAAoB,CAAC;CAenC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GetFilterFieldsController = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const identity_server_1 = require("@orthacms/identity-server");
|
|
7
|
+
const workspaces_server_1 = require("@orthacms/workspaces-server");
|
|
8
|
+
const content_tokens_1 = require("../../content.tokens");
|
|
9
|
+
const entry_filter_surface_1 = require("../../entries/infrastructure/queries/entry-filter-surface");
|
|
10
|
+
const workspace_grants_query_1 = require("../queries/workspace-grants.query");
|
|
11
|
+
/**
|
|
12
|
+
* `GET /api/content-schema/:name/filter-fields` — every scalar path the
|
|
13
|
+
* records-table query builder may filter on: the type's own fields plus,
|
|
14
|
+
* recursively within the relation-hop budget, its relations' fields
|
|
15
|
+
* (`author.name`, `author.company.name`). This is the admin counterpart of
|
|
16
|
+
* the SQL `FilterSchema` the list endpoint enforces — both come from a
|
|
17
|
+
* single `buildEntryFilterSurface` traversal, so the picker can never offer
|
|
18
|
+
* a path the API would reject with a 400.
|
|
19
|
+
*
|
|
20
|
+
* **Workspace-scoped**, unlike the sibling `/content-schema` routes (which
|
|
21
|
+
* serve the global, code-defined type catalogue). The response describes
|
|
22
|
+
* what *this* workspace may traverse, so it is pruned to the workspace's
|
|
23
|
+
* `workspace_content` grants in two places:
|
|
24
|
+
*
|
|
25
|
+
* - the requested `:name` must itself be granted, else **404** — the same
|
|
26
|
+
* answer an unknown type gets, so the endpoint carries no signal about
|
|
27
|
+
* which types exist outside the caller's workspace;
|
|
28
|
+
* - `grantedTypes` prunes the offered relations, mirroring the entry
|
|
29
|
+
* editor's `availableTypeNames`, so the picker never offers a traversal
|
|
30
|
+
* into a collection the caller cannot open.
|
|
31
|
+
*
|
|
32
|
+
* The SQL the list endpoint runs is workspace-scoped regardless, so this is
|
|
33
|
+
* about not *disclosing* the shape of another workspace's content model,
|
|
34
|
+
* not about row access.
|
|
35
|
+
*/
|
|
36
|
+
let GetFilterFieldsController = class GetFilterFieldsController {
|
|
37
|
+
registry;
|
|
38
|
+
grants;
|
|
39
|
+
constructor(registry, grants) {
|
|
40
|
+
this.registry = registry;
|
|
41
|
+
this.grants = grants;
|
|
42
|
+
}
|
|
43
|
+
async filterFields(name, workspaceId) {
|
|
44
|
+
const type = this.registry.get(name);
|
|
45
|
+
// Resolve the grants before the registry check so an ungranted type
|
|
46
|
+
// and an unknown one are indistinguishable — same status, same body,
|
|
47
|
+
// same work done.
|
|
48
|
+
const grantedTypes = await this.grants.grantedSlugs(workspaceId);
|
|
49
|
+
if (!type || !grantedTypes.has(name)) {
|
|
50
|
+
throw new common_1.NotFoundException(`Unknown content type "${name}".`);
|
|
51
|
+
}
|
|
52
|
+
const { fields } = (0, entry_filter_surface_1.buildEntryFilterSurface)(type, {
|
|
53
|
+
workspaceId,
|
|
54
|
+
grantedTypes
|
|
55
|
+
});
|
|
56
|
+
return { fields };
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
exports.GetFilterFieldsController = GetFilterFieldsController;
|
|
60
|
+
tslib_1.__decorate([
|
|
61
|
+
(0, common_1.Get)(':name/filter-fields'),
|
|
62
|
+
tslib_1.__param(0, (0, common_1.Param)('name')),
|
|
63
|
+
tslib_1.__param(1, (0, workspaces_server_1.CurrentWorkspace)()),
|
|
64
|
+
tslib_1.__metadata("design:type", Function),
|
|
65
|
+
tslib_1.__metadata("design:paramtypes", [String, String]),
|
|
66
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
67
|
+
], GetFilterFieldsController.prototype, "filterFields", null);
|
|
68
|
+
exports.GetFilterFieldsController = GetFilterFieldsController = tslib_1.__decorate([
|
|
69
|
+
(0, common_1.UseGuards)(identity_server_1.PermissionsGuard, workspaces_server_1.WorkspaceGuard),
|
|
70
|
+
(0, identity_server_1.RequirePermissions)(identity_server_1.PERMISSIONS.CONTENT_READ),
|
|
71
|
+
(0, common_1.Controller)('content-schema'),
|
|
72
|
+
tslib_1.__param(0, (0, content_tokens_1.InjectContentRegistry)()),
|
|
73
|
+
tslib_1.__metadata("design:paramtypes", [Function, workspace_grants_query_1.WorkspaceGrantsQuery])
|
|
74
|
+
], GetFilterFieldsController);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ContentTypeRegistry, SerializedContentTypeSummary } from '../../registry/content-type-registry';
|
|
2
|
+
/**
|
|
3
|
+
* `GET /api/content-schema` — summaries of every code-defined content
|
|
4
|
+
* type (collections and singles). Shape-compatible with identity's
|
|
5
|
+
* `ContentTypeDescriptor`, so once identity's workspace grants consume
|
|
6
|
+
* this registry, its mock `/api/content-types` retires in favor of this
|
|
7
|
+
* source of truth. Authentication is enforced by the app-wide AuthGuard;
|
|
8
|
+
* read access is gated on `content:read`.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ListContentSchemaController {
|
|
11
|
+
private readonly registry;
|
|
12
|
+
constructor(registry: ContentTypeRegistry);
|
|
13
|
+
list(): SerializedContentTypeSummary[];
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=list-content-schema.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-content-schema.controller.d.ts","sourceRoot":"","sources":["../../../../src/lib/content-types/controllers/list-content-schema.controller.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACR,mBAAmB,EACnB,4BAA4B,EAC/B,MAAM,sCAAsC,CAAC;AAE9C;;;;;;;GAOG;AACH,qBAGa,2BAA2B;IAGhC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,mBAAmB;IAIlD,IAAI,IAAI,4BAA4B,EAAE;CAGzC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ListContentSchemaController = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const identity_server_1 = require("@orthacms/identity-server");
|
|
7
|
+
const content_tokens_1 = require("../../content.tokens");
|
|
8
|
+
/**
|
|
9
|
+
* `GET /api/content-schema` — summaries of every code-defined content
|
|
10
|
+
* type (collections and singles). Shape-compatible with identity's
|
|
11
|
+
* `ContentTypeDescriptor`, so once identity's workspace grants consume
|
|
12
|
+
* this registry, its mock `/api/content-types` retires in favor of this
|
|
13
|
+
* source of truth. Authentication is enforced by the app-wide AuthGuard;
|
|
14
|
+
* read access is gated on `content:read`.
|
|
15
|
+
*/
|
|
16
|
+
let ListContentSchemaController = class ListContentSchemaController {
|
|
17
|
+
registry;
|
|
18
|
+
constructor(registry) {
|
|
19
|
+
this.registry = registry;
|
|
20
|
+
}
|
|
21
|
+
list() {
|
|
22
|
+
return this.registry.summaries();
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
exports.ListContentSchemaController = ListContentSchemaController;
|
|
26
|
+
tslib_1.__decorate([
|
|
27
|
+
(0, common_1.Get)(),
|
|
28
|
+
tslib_1.__metadata("design:type", Function),
|
|
29
|
+
tslib_1.__metadata("design:paramtypes", []),
|
|
30
|
+
tslib_1.__metadata("design:returntype", Array)
|
|
31
|
+
], ListContentSchemaController.prototype, "list", null);
|
|
32
|
+
exports.ListContentSchemaController = ListContentSchemaController = tslib_1.__decorate([
|
|
33
|
+
(0, common_1.UseGuards)(identity_server_1.PermissionsGuard),
|
|
34
|
+
(0, identity_server_1.RequirePermissions)(identity_server_1.PERMISSIONS.CONTENT_READ),
|
|
35
|
+
(0, common_1.Controller)('content-schema'),
|
|
36
|
+
tslib_1.__param(0, (0, content_tokens_1.InjectContentRegistry)()),
|
|
37
|
+
tslib_1.__metadata("design:paramtypes", [Function])
|
|
38
|
+
], ListContentSchemaController);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type Database } from '@orthacms/database';
|
|
2
|
+
/**
|
|
3
|
+
* Reads a workspace's **content grants** — the `workspace_content` slugs the
|
|
4
|
+
* open workspace may access, written by the workspace create/edit wizard.
|
|
5
|
+
*
|
|
6
|
+
* The grants are workspaces-owned data, but the dependency only runs one way:
|
|
7
|
+
* content-server already depends on `@orthacms/workspaces-server` for
|
|
8
|
+
* `WorkspaceGuard`, and that package deliberately re-exports its Drizzle
|
|
9
|
+
* schema. Inverting this into a port would mean workspaces depending on
|
|
10
|
+
* content, which is the cycle `CONTENT_CATALOG` exists to avoid.
|
|
11
|
+
*
|
|
12
|
+
* A thin CQRS read — no aggregate, no write path.
|
|
13
|
+
*/
|
|
14
|
+
export declare class WorkspaceGrantsQuery {
|
|
15
|
+
private readonly db;
|
|
16
|
+
constructor(db: Database);
|
|
17
|
+
/**
|
|
18
|
+
* Every content slug granted to `workspaceId`. Returned as a `Set` so
|
|
19
|
+
* callers can test membership per relation hop without re-querying.
|
|
20
|
+
* An empty set means the workspace was granted nothing — callers must
|
|
21
|
+
* treat that as "no access", never as "no filtering".
|
|
22
|
+
*/
|
|
23
|
+
grantedSlugs(workspaceId: string): Promise<Set<string>>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=workspace-grants.query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-grants.query.d.ts","sourceRoot":"","sources":["../../../../src/lib/content-types/queries/workspace-grants.query.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnE;;;;;;;;;;;GAWG;AACH,qBACa,oBAAoB;IACC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAAF,EAAE,EAAE,QAAQ;IAE3D;;;;;OAKG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;CAOhE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WorkspaceGrantsQuery = 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
|
+
/**
|
|
10
|
+
* Reads a workspace's **content grants** — the `workspace_content` slugs the
|
|
11
|
+
* open workspace may access, written by the workspace create/edit wizard.
|
|
12
|
+
*
|
|
13
|
+
* The grants are workspaces-owned data, but the dependency only runs one way:
|
|
14
|
+
* content-server already depends on `@orthacms/workspaces-server` for
|
|
15
|
+
* `WorkspaceGuard`, and that package deliberately re-exports its Drizzle
|
|
16
|
+
* schema. Inverting this into a port would mean workspaces depending on
|
|
17
|
+
* content, which is the cycle `CONTENT_CATALOG` exists to avoid.
|
|
18
|
+
*
|
|
19
|
+
* A thin CQRS read — no aggregate, no write path.
|
|
20
|
+
*/
|
|
21
|
+
let WorkspaceGrantsQuery = class WorkspaceGrantsQuery {
|
|
22
|
+
db;
|
|
23
|
+
constructor(db) {
|
|
24
|
+
this.db = db;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Every content slug granted to `workspaceId`. Returned as a `Set` so
|
|
28
|
+
* callers can test membership per relation hop without re-querying.
|
|
29
|
+
* An empty set means the workspace was granted nothing — callers must
|
|
30
|
+
* treat that as "no access", never as "no filtering".
|
|
31
|
+
*/
|
|
32
|
+
async grantedSlugs(workspaceId) {
|
|
33
|
+
const rows = await this.db
|
|
34
|
+
.select({ slug: workspaces_server_1.workspaceContent.slug })
|
|
35
|
+
.from(workspaces_server_1.workspaceContent)
|
|
36
|
+
.where((0, drizzle_orm_1.eq)(workspaces_server_1.workspaceContent.workspaceId, workspaceId));
|
|
37
|
+
return new Set(rows.map((row) => row.slug));
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
exports.WorkspaceGrantsQuery = WorkspaceGrantsQuery;
|
|
41
|
+
exports.WorkspaceGrantsQuery = WorkspaceGrantsQuery = tslib_1.__decorate([
|
|
42
|
+
(0, common_1.Injectable)(),
|
|
43
|
+
tslib_1.__param(0, (0, database_1.InjectDatabase)()),
|
|
44
|
+
tslib_1.__metadata("design:paramtypes", [Object])
|
|
45
|
+
], WorkspaceGrantsQuery);
|