@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,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SaveEntryDto = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
6
|
+
const class_validator_1 = require("class-validator");
|
|
7
|
+
const relation_delta_map_validator_1 = require("./relation-delta-map.validator");
|
|
8
|
+
/** Longest accepted locale slug (BCP-47's practical bound). */
|
|
9
|
+
const LOCALE_MAX_LENGTH = 35;
|
|
10
|
+
/** OpenAPI schema of one uuid-array leg of a relation delta. */
|
|
11
|
+
const UUID_ARRAY_SCHEMA = {
|
|
12
|
+
type: 'array',
|
|
13
|
+
maxItems: relation_delta_map_validator_1.MAX_DELTA_IDS,
|
|
14
|
+
items: { type: 'string', format: 'uuid' }
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Body for `POST /api/content/:typeName` (create) and
|
|
18
|
+
* `PATCH /api/content/:typeName/:id` (update). The field `values` bag crosses the
|
|
19
|
+
* wire, plus optional per-field relation **deltas** (`relations`) — the editor
|
|
20
|
+
* stages its many-to-many / inverse link changes locally and sends them here
|
|
21
|
+
* with the rest of the document, so a save persists everything in **one
|
|
22
|
+
* transaction** without ever transmitting a huge relation whole.
|
|
23
|
+
*
|
|
24
|
+
* Reserved envelope columns (`status`/`published_at`/`deleted_at`) are owned by
|
|
25
|
+
* the service and can't be set from here: `coerceValues`/`toColumns` project
|
|
26
|
+
* only keys declared on the type, so a reserved (or otherwise unknown) key in
|
|
27
|
+
* the bag is **silently dropped** — including before validation, which runs on
|
|
28
|
+
* the coerced bag, so an unknown key is never a 422 on either kind of type.
|
|
29
|
+
* (That is what keeps an old revision snapshot restorable after its field was
|
|
30
|
+
* removed from the type.) The bag's
|
|
31
|
+
* *contents* are validated against the type's field specs by that same service
|
|
32
|
+
* (a dynamic, per-type contract class-validator can't express); the relation
|
|
33
|
+
* deltas' ids are validated as existing workspace entries by
|
|
34
|
+
* `RelationLinkService`. `values` is structurally only "an object" (its contents
|
|
35
|
+
* are the per-type contract); the `relations` bag's *shape* — each value a
|
|
36
|
+
* `{ link?, unlink?, order? }` of uuid arrays — is enforced here so a malformed
|
|
37
|
+
* delta is a clean 400, not a 500 from a bad id hitting the query.
|
|
38
|
+
*/
|
|
39
|
+
class SaveEntryDto {
|
|
40
|
+
/** Field values keyed by field name. */
|
|
41
|
+
values;
|
|
42
|
+
/**
|
|
43
|
+
* Per-field relation deltas (`{ <field>: { link?, unlink?, order? } }`) —
|
|
44
|
+
* many/inverse relations only; a single relation is set through `values`.
|
|
45
|
+
*/
|
|
46
|
+
relations;
|
|
47
|
+
/**
|
|
48
|
+
* Locale slug the entry is created in — an **extension-owned** param this
|
|
49
|
+
* package declares but never interprets (forwarded to the bound
|
|
50
|
+
* `CONTENT_ENTRY_EXTENSION`, which validates it and stamps the envelope
|
|
51
|
+
* column). Read on create only; an update never re-homes a row's locale.
|
|
52
|
+
*/
|
|
53
|
+
locale;
|
|
54
|
+
/**
|
|
55
|
+
* The existing translation group a created row joins (making it a sibling)
|
|
56
|
+
* — an **extension-owned**, opaque param, like {@link locale}. Absent → the
|
|
57
|
+
* row starts its own fresh group. The bound extension validates it against
|
|
58
|
+
* the workspace. Read on create only.
|
|
59
|
+
*/
|
|
60
|
+
localeGroupId;
|
|
61
|
+
}
|
|
62
|
+
exports.SaveEntryDto = SaveEntryDto;
|
|
63
|
+
tslib_1.__decorate([
|
|
64
|
+
(0, swagger_1.ApiProperty)({
|
|
65
|
+
type: 'object',
|
|
66
|
+
additionalProperties: true,
|
|
67
|
+
example: { title: 'Hello world', author: null },
|
|
68
|
+
description: "Field values keyed by field name — the per-type contract, so this is structurally just an object. Contents are validated against the content type's field specs (a failure is a 422 carrying per-field issues). Reserved envelope keys (`status`, `publishedAt`, `deletedAt`, `locale`, `localeGroupId`) are not settable here."
|
|
69
|
+
}),
|
|
70
|
+
(0, class_validator_1.IsObject)(),
|
|
71
|
+
tslib_1.__metadata("design:type", Object)
|
|
72
|
+
], SaveEntryDto.prototype, "values", void 0);
|
|
73
|
+
tslib_1.__decorate([
|
|
74
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
75
|
+
type: 'object',
|
|
76
|
+
maxProperties: relation_delta_map_validator_1.MAX_DELTA_FIELDS,
|
|
77
|
+
additionalProperties: {
|
|
78
|
+
type: 'object',
|
|
79
|
+
properties: {
|
|
80
|
+
link: UUID_ARRAY_SCHEMA,
|
|
81
|
+
unlink: UUID_ARRAY_SCHEMA,
|
|
82
|
+
order: UUID_ARRAY_SCHEMA
|
|
83
|
+
},
|
|
84
|
+
additionalProperties: false
|
|
85
|
+
},
|
|
86
|
+
example: {
|
|
87
|
+
tags: {
|
|
88
|
+
link: ['9c4b1e77-2f0a-4d3b-8e6c-1a5f7b2d9e04'],
|
|
89
|
+
unlink: []
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
description: `Per-field relation deltas, keyed by relation field. Many-to-many and inverse relations only — a single relation is set through \`values\`, and naming one here is a 400. At most ${relation_delta_map_validator_1.MAX_DELTA_FIELDS} fields per save and ${relation_delta_map_validator_1.MAX_DELTA_IDS} ids per array; \`order\` is accepted on the owning side only.`
|
|
93
|
+
}),
|
|
94
|
+
(0, class_validator_1.IsOptional)(),
|
|
95
|
+
(0, class_validator_1.IsObject)(),
|
|
96
|
+
(0, relation_delta_map_validator_1.IsRelationDeltaMap)(),
|
|
97
|
+
tslib_1.__metadata("design:type", Object)
|
|
98
|
+
], SaveEntryDto.prototype, "relations", void 0);
|
|
99
|
+
tslib_1.__decorate([
|
|
100
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
101
|
+
type: String,
|
|
102
|
+
maxLength: LOCALE_MAX_LENGTH,
|
|
103
|
+
example: 'de',
|
|
104
|
+
description: 'Locale slug the entry is created in. Extension-owned: forwarded to the bound `CONTENT_ENTRY_EXTENSION`, which validates it and stamps the envelope column. Read on create only — an update never re-homes a row’s locale.'
|
|
105
|
+
}),
|
|
106
|
+
(0, class_validator_1.IsOptional)(),
|
|
107
|
+
(0, class_validator_1.IsString)(),
|
|
108
|
+
(0, class_validator_1.MaxLength)(LOCALE_MAX_LENGTH),
|
|
109
|
+
tslib_1.__metadata("design:type", String)
|
|
110
|
+
], SaveEntryDto.prototype, "locale", void 0);
|
|
111
|
+
tslib_1.__decorate([
|
|
112
|
+
(0, swagger_1.ApiPropertyOptional)({
|
|
113
|
+
type: String,
|
|
114
|
+
format: 'uuid',
|
|
115
|
+
description: 'The existing translation group a created row joins, making it a sibling. Absent → the row starts its own fresh group. Validated against the workspace by the bound extension (unknown group → 404; duplicate locale in the group → 409). Read on create only.'
|
|
116
|
+
}),
|
|
117
|
+
(0, class_validator_1.IsOptional)(),
|
|
118
|
+
(0, class_validator_1.IsUUID)(),
|
|
119
|
+
tslib_1.__metadata("design:type", String)
|
|
120
|
+
], SaveEntryDto.prototype, "localeGroupId", void 0);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { WorkspaceGrantsQuery } from '../../../content-types/queries/workspace-grants.query';
|
|
3
|
+
/**
|
|
4
|
+
* Refuses a content route whose `:typeName` the **open workspace** was never
|
|
5
|
+
* granted (`workspace_content`), with the same `404` an unknown type gets.
|
|
6
|
+
*
|
|
7
|
+
* The grant set is the workspace's declared content surface: the nav renders
|
|
8
|
+
* from it, the workspace wizard writes it, and revoking a grant is refused
|
|
9
|
+
* while entries of that type still exist. Every other surface over this same
|
|
10
|
+
* content already honours it — the public REST API
|
|
11
|
+
* (`resolveGrantedType`), the GraphQL adapter, the MCP tools and the copilot's
|
|
12
|
+
* read/propose tools all resolve a type through the grants. The session-side
|
|
13
|
+
* admin API was the one exception, so a member of a workspace granted only
|
|
14
|
+
* `article` could still list, read, create, edit, publish and delete `tag`
|
|
15
|
+
* entries in it by naming the type in the URL — rows the admin then never
|
|
16
|
+
* shows (its nav is grant-driven) yet which count toward the workspace-delete
|
|
17
|
+
* guard, and which re-break the "a revoked grant never orphans records"
|
|
18
|
+
* invariant from the other side.
|
|
19
|
+
*
|
|
20
|
+
* **Unknown and ungranted are deliberately indistinguishable** — same status,
|
|
21
|
+
* same message, and the grant read happens before any registry decision — so
|
|
22
|
+
* the route carries no signal about which types exist outside the caller's
|
|
23
|
+
* workspace. That is also why this is a guard rather than a check inside each
|
|
24
|
+
* handler: it runs before the controller can leak a type-shaped error.
|
|
25
|
+
*
|
|
26
|
+
* Must be listed **after** `WorkspaceGuard`, which validates the header and
|
|
27
|
+
* attaches `request.workspaceId`. Applies only to routes carrying a
|
|
28
|
+
* `:typeName` param; a route without one is left alone (there is nothing to
|
|
29
|
+
* scope), which is why the global `/api/content-schema` catalogue keeps its own
|
|
30
|
+
* rules.
|
|
31
|
+
*/
|
|
32
|
+
export declare class ContentGrantGuard implements CanActivate {
|
|
33
|
+
private readonly grants;
|
|
34
|
+
constructor(grants: WorkspaceGrantsQuery);
|
|
35
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=content-grant.guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-grant.guard.d.ts","sourceRoot":"","sources":["../../../../../src/lib/entries/http/guards/content-grant.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,WAAW,EACX,gBAAgB,EAGnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,MAAM,uDAAuD,CAAC;AAK7F;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBACa,iBAAkB,YAAW,WAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,oBAAoB;IAEnD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CAkBjE"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContentGrantGuard = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const workspace_grants_query_1 = require("../../../content-types/queries/workspace-grants.query");
|
|
7
|
+
/** The route param every registry-driven content route names its type with. */
|
|
8
|
+
const TYPE_PARAM = 'typeName';
|
|
9
|
+
/**
|
|
10
|
+
* Refuses a content route whose `:typeName` the **open workspace** was never
|
|
11
|
+
* granted (`workspace_content`), with the same `404` an unknown type gets.
|
|
12
|
+
*
|
|
13
|
+
* The grant set is the workspace's declared content surface: the nav renders
|
|
14
|
+
* from it, the workspace wizard writes it, and revoking a grant is refused
|
|
15
|
+
* while entries of that type still exist. Every other surface over this same
|
|
16
|
+
* content already honours it — the public REST API
|
|
17
|
+
* (`resolveGrantedType`), the GraphQL adapter, the MCP tools and the copilot's
|
|
18
|
+
* read/propose tools all resolve a type through the grants. The session-side
|
|
19
|
+
* admin API was the one exception, so a member of a workspace granted only
|
|
20
|
+
* `article` could still list, read, create, edit, publish and delete `tag`
|
|
21
|
+
* entries in it by naming the type in the URL — rows the admin then never
|
|
22
|
+
* shows (its nav is grant-driven) yet which count toward the workspace-delete
|
|
23
|
+
* guard, and which re-break the "a revoked grant never orphans records"
|
|
24
|
+
* invariant from the other side.
|
|
25
|
+
*
|
|
26
|
+
* **Unknown and ungranted are deliberately indistinguishable** — same status,
|
|
27
|
+
* same message, and the grant read happens before any registry decision — so
|
|
28
|
+
* the route carries no signal about which types exist outside the caller's
|
|
29
|
+
* workspace. That is also why this is a guard rather than a check inside each
|
|
30
|
+
* handler: it runs before the controller can leak a type-shaped error.
|
|
31
|
+
*
|
|
32
|
+
* Must be listed **after** `WorkspaceGuard`, which validates the header and
|
|
33
|
+
* attaches `request.workspaceId`. Applies only to routes carrying a
|
|
34
|
+
* `:typeName` param; a route without one is left alone (there is nothing to
|
|
35
|
+
* scope), which is why the global `/api/content-schema` catalogue keeps its own
|
|
36
|
+
* rules.
|
|
37
|
+
*/
|
|
38
|
+
let ContentGrantGuard = class ContentGrantGuard {
|
|
39
|
+
grants;
|
|
40
|
+
constructor(grants) {
|
|
41
|
+
this.grants = grants;
|
|
42
|
+
}
|
|
43
|
+
async canActivate(context) {
|
|
44
|
+
const request = context
|
|
45
|
+
.switchToHttp()
|
|
46
|
+
.getRequest();
|
|
47
|
+
const typeName = request.params?.[TYPE_PARAM];
|
|
48
|
+
if (!typeName)
|
|
49
|
+
return true;
|
|
50
|
+
const workspaceId = request.workspaceId;
|
|
51
|
+
if (!workspaceId) {
|
|
52
|
+
// Only reachable if the guard is wired without `WorkspaceGuard`
|
|
53
|
+
// ahead of it — refuse rather than fall open.
|
|
54
|
+
throw new common_1.NotFoundException(`Unknown content type "${typeName}".`);
|
|
55
|
+
}
|
|
56
|
+
const granted = await this.grants.grantedSlugs(workspaceId);
|
|
57
|
+
if (!granted.has(typeName)) {
|
|
58
|
+
throw new common_1.NotFoundException(`Unknown content type "${typeName}".`);
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
exports.ContentGrantGuard = ContentGrantGuard;
|
|
64
|
+
exports.ContentGrantGuard = ContentGrantGuard = tslib_1.__decorate([
|
|
65
|
+
(0, common_1.Injectable)(),
|
|
66
|
+
tslib_1.__metadata("design:paramtypes", [workspace_grants_query_1.WorkspaceGrantsQuery])
|
|
67
|
+
], ContentGrantGuard);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pure per-entry publish-verdict logic — shared by the bulk-publish **dry
|
|
3
|
+
* run** (the preview query) and the committed bulk-publish use-case so they can
|
|
4
|
+
* never disagree on what is publishable. Extracted verbatim from the original
|
|
5
|
+
* writer's `verdictsFor`/`buildChecks`; takes the validation as a function so it
|
|
6
|
+
* stays free of DI.
|
|
7
|
+
*/
|
|
8
|
+
import type { AnyContentType } from '../../../types/content-type';
|
|
9
|
+
import type { ValidationResult } from '../../../validation/services/entry-validation.service';
|
|
10
|
+
import { type BulkPublishVerdict } from '../../types/bulk-publish';
|
|
11
|
+
/** A generated content row seen as a bag of values by property name. */
|
|
12
|
+
type Row = Record<string, unknown>;
|
|
13
|
+
/** How the caller runs value validation (the injectable service's `validate`). */
|
|
14
|
+
export type ValidateEntry = (type: AnyContentType, values: Record<string, unknown>) => ValidationResult;
|
|
15
|
+
/**
|
|
16
|
+
* Compute the per-entry publish verdict (will-publish / already-published /
|
|
17
|
+
* blocked / not-found) for `ids` in request order, given the live rows keyed by
|
|
18
|
+
* id and a value-validation function.
|
|
19
|
+
*/
|
|
20
|
+
export declare function computeBulkPublishVerdicts(type: AnyContentType, ids: string[], byId: Map<string, Row>, validate: ValidateEntry): BulkPublishVerdict[];
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=bulk-publish-verdicts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bulk-publish-verdicts.d.ts","sourceRoot":"","sources":["../../../../../src/lib/entries/infrastructure/persistence/bulk-publish-verdicts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,6BAA6B,CAAC;AAE/E,OAAO,KAAK,EAER,gBAAgB,EACnB,MAAM,uDAAuD,CAAC;AAC/D,OAAO,EAGH,KAAK,kBAAkB,EAC1B,MAAM,0BAA0B,CAAC;AAGlC,wEAAwE;AACxE,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnC,kFAAkF;AAClF,MAAM,MAAM,aAAa,GAAG,CACxB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC9B,gBAAgB,CAAC;AAEtB;;;;GAIG;AACH,wBAAgB,0BAA0B,CACtC,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,MAAM,EAAE,EACb,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,EACtB,QAAQ,EAAE,aAAa,GACxB,kBAAkB,EAAE,CA0CtB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The pure per-entry publish-verdict logic — shared by the bulk-publish **dry
|
|
4
|
+
* run** (the preview query) and the committed bulk-publish use-case so they can
|
|
5
|
+
* never disagree on what is publishable. Extracted verbatim from the original
|
|
6
|
+
* writer's `verdictsFor`/`buildChecks`; takes the validation as a function so it
|
|
7
|
+
* stays free of DI.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.computeBulkPublishVerdicts = computeBulkPublishVerdicts;
|
|
11
|
+
const content_type_1 = require("../../../types/content-type");
|
|
12
|
+
const bulk_publish_1 = require("../../types/bulk-publish");
|
|
13
|
+
const entry_row_1 = require("./entry-row");
|
|
14
|
+
/**
|
|
15
|
+
* Compute the per-entry publish verdict (will-publish / already-published /
|
|
16
|
+
* blocked / not-found) for `ids` in request order, given the live rows keyed by
|
|
17
|
+
* id and a value-validation function.
|
|
18
|
+
*/
|
|
19
|
+
function computeBulkPublishVerdicts(type, ids, byId, validate) {
|
|
20
|
+
return ids.map((id) => {
|
|
21
|
+
const row = byId.get(id);
|
|
22
|
+
if (!row) {
|
|
23
|
+
return {
|
|
24
|
+
id,
|
|
25
|
+
title: id,
|
|
26
|
+
status: null,
|
|
27
|
+
verdict: bulk_publish_1.BULK_VERDICT.NotFound,
|
|
28
|
+
issues: [],
|
|
29
|
+
checks: []
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const title = (0, entry_row_1.entryTitle)(type, row);
|
|
33
|
+
const status = row['status'];
|
|
34
|
+
if (status === content_type_1.ENTRY_STATUS.Published) {
|
|
35
|
+
// Already published, so nothing will change — but still surface its
|
|
36
|
+
// per-field gate (an already-published row is valid, so the checks
|
|
37
|
+
// all pass) so the dialog can expand it like every other row instead
|
|
38
|
+
// of leaving it a dead, non-collapsible entry.
|
|
39
|
+
const result = validate(type, (0, entry_row_1.toRecord)(type, row).values);
|
|
40
|
+
return {
|
|
41
|
+
id,
|
|
42
|
+
title,
|
|
43
|
+
status,
|
|
44
|
+
verdict: bulk_publish_1.BULK_VERDICT.AlreadyPublished,
|
|
45
|
+
issues: [],
|
|
46
|
+
checks: buildChecks(type, result.issues)
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const result = validate(type, (0, entry_row_1.toRecord)(type, row).values);
|
|
50
|
+
return {
|
|
51
|
+
id,
|
|
52
|
+
title,
|
|
53
|
+
status,
|
|
54
|
+
verdict: result.valid
|
|
55
|
+
? bulk_publish_1.BULK_VERDICT.Publishable
|
|
56
|
+
: bulk_publish_1.BULK_VERDICT.Blocked,
|
|
57
|
+
issues: result.issues,
|
|
58
|
+
checks: buildChecks(type, result.issues)
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* The per-field publish-gate checklist for one record: every required field plus
|
|
64
|
+
* any field that has an issue, each marked pass/fail. Mirrors the editor's
|
|
65
|
+
* Publish Gate so a row can show its passed fields, not just the failures.
|
|
66
|
+
*/
|
|
67
|
+
function buildChecks(type, issues) {
|
|
68
|
+
const byField = new Map();
|
|
69
|
+
for (const issue of issues) {
|
|
70
|
+
if (!byField.has(issue.field))
|
|
71
|
+
byField.set(issue.field, issue.message);
|
|
72
|
+
}
|
|
73
|
+
return Object.entries(type.fields)
|
|
74
|
+
.filter(([name, spec]) => spec.required || byField.has(name))
|
|
75
|
+
.map(([name, spec]) => ({
|
|
76
|
+
field: name,
|
|
77
|
+
label: spec.admin.label ?? name,
|
|
78
|
+
ok: !byField.has(name),
|
|
79
|
+
message: byField.get(name)
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type Database } from '@orthacms/database';
|
|
2
|
+
import type { ContentEntryCounter } from '@orthacms/workspaces-server';
|
|
3
|
+
import type { ContentTypeRegistry } from '../../../registry/content-type-registry';
|
|
4
|
+
/**
|
|
5
|
+
* Implements identity's {@link ContentEntryCounter} port over the generated
|
|
6
|
+
* `content_<name>` tables: counts how many entries of a content type a
|
|
7
|
+
* workspace holds. Bound to `CONTENT_ENTRY_COUNTER` in {@link ContentModule},
|
|
8
|
+
* so identity's "revoke a content-type grant only when empty" rule resolves
|
|
9
|
+
* against the real stored entries.
|
|
10
|
+
*/
|
|
11
|
+
export declare class EntryCounterService implements ContentEntryCounter {
|
|
12
|
+
private readonly db;
|
|
13
|
+
private readonly registry;
|
|
14
|
+
constructor(db: Database, registry: ContentTypeRegistry);
|
|
15
|
+
/**
|
|
16
|
+
* Every stored row of content type `slug` in `workspaceId`. Counts the
|
|
17
|
+
* whole workspace slice of the type's table — including soft-deleted rows
|
|
18
|
+
* for paranoid types (data that still exists must keep the grant). An
|
|
19
|
+
* unknown slug (no such content type) counts as `0`.
|
|
20
|
+
*/
|
|
21
|
+
countEntries(workspaceId: string, slug: string): Promise<number>;
|
|
22
|
+
/**
|
|
23
|
+
* Every stored row the workspace holds across **all** content types —
|
|
24
|
+
* summed over each type's table. Backs the workspace-delete guard (delete is
|
|
25
|
+
* refused until this is zero). The per-type counts run concurrently.
|
|
26
|
+
*
|
|
27
|
+
* Deliberately **not** narrowed to the workspace's `workspace_content`
|
|
28
|
+
* grants, even though every read/write surface now is
|
|
29
|
+
* (`ContentGrantGuard`). This is a data-safety guard, not an access-control
|
|
30
|
+
* surface, and the two want opposite defaults: counting only granted types
|
|
31
|
+
* would let a workspace be deleted while rows of an ungranted type still
|
|
32
|
+
* sat in its slice — exactly the orphaned records the guard exists to
|
|
33
|
+
* prevent. Such rows are no longer *creatable* through the API, but a grant
|
|
34
|
+
* revoked between two deployments, or data written before the grant check
|
|
35
|
+
* landed, still has to hold the delete. Counting everything can only ever
|
|
36
|
+
* refuse a delete too often, which is the safe direction to be wrong in.
|
|
37
|
+
*/
|
|
38
|
+
countWorkspaceEntries(workspaceId: string): Promise<number>;
|
|
39
|
+
/** Counts a single content type's rows in a workspace. */
|
|
40
|
+
private countTable;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=entry-counter.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-counter.service.d.ts","sourceRoot":"","sources":["../../../../../src/lib/entries/infrastructure/persistence/entry-counter.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAMnF;;;;;;GAMG;AACH,qBACa,mBAAoB,YAAW,mBAAmB;IAErC,OAAO,CAAC,QAAQ,CAAC,EAAE;IACZ,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBADf,EAAE,EAAE,QAAQ,EACL,QAAQ,EAAE,mBAAmB;IAG3E;;;;;OAKG;IACG,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMtE;;;;;;;;;;;;;;;OAeG;IACG,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IASjE,0DAA0D;YAC5C,UAAU;CAW3B"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EntryCounterService = 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 content_tokens_1 = require("../../../content.tokens");
|
|
9
|
+
/**
|
|
10
|
+
* Implements identity's {@link ContentEntryCounter} port over the generated
|
|
11
|
+
* `content_<name>` tables: counts how many entries of a content type a
|
|
12
|
+
* workspace holds. Bound to `CONTENT_ENTRY_COUNTER` in {@link ContentModule},
|
|
13
|
+
* so identity's "revoke a content-type grant only when empty" rule resolves
|
|
14
|
+
* against the real stored entries.
|
|
15
|
+
*/
|
|
16
|
+
let EntryCounterService = class EntryCounterService {
|
|
17
|
+
db;
|
|
18
|
+
registry;
|
|
19
|
+
constructor(db, registry) {
|
|
20
|
+
this.db = db;
|
|
21
|
+
this.registry = registry;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Every stored row of content type `slug` in `workspaceId`. Counts the
|
|
25
|
+
* whole workspace slice of the type's table — including soft-deleted rows
|
|
26
|
+
* for paranoid types (data that still exists must keep the grant). An
|
|
27
|
+
* unknown slug (no such content type) counts as `0`.
|
|
28
|
+
*/
|
|
29
|
+
async countEntries(workspaceId, slug) {
|
|
30
|
+
const type = this.registry.get(slug);
|
|
31
|
+
if (!type)
|
|
32
|
+
return 0;
|
|
33
|
+
return this.countTable(type, workspaceId);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Every stored row the workspace holds across **all** content types —
|
|
37
|
+
* summed over each type's table. Backs the workspace-delete guard (delete is
|
|
38
|
+
* refused until this is zero). The per-type counts run concurrently.
|
|
39
|
+
*
|
|
40
|
+
* Deliberately **not** narrowed to the workspace's `workspace_content`
|
|
41
|
+
* grants, even though every read/write surface now is
|
|
42
|
+
* (`ContentGrantGuard`). This is a data-safety guard, not an access-control
|
|
43
|
+
* surface, and the two want opposite defaults: counting only granted types
|
|
44
|
+
* would let a workspace be deleted while rows of an ungranted type still
|
|
45
|
+
* sat in its slice — exactly the orphaned records the guard exists to
|
|
46
|
+
* prevent. Such rows are no longer *creatable* through the API, but a grant
|
|
47
|
+
* revoked between two deployments, or data written before the grant check
|
|
48
|
+
* landed, still has to hold the delete. Counting everything can only ever
|
|
49
|
+
* refuse a delete too often, which is the safe direction to be wrong in.
|
|
50
|
+
*/
|
|
51
|
+
async countWorkspaceEntries(workspaceId) {
|
|
52
|
+
const counts = await Promise.all(this.registry
|
|
53
|
+
.all()
|
|
54
|
+
.map((type) => this.countTable(type, workspaceId)));
|
|
55
|
+
return counts.reduce((sum, n) => sum + n, 0);
|
|
56
|
+
}
|
|
57
|
+
/** Counts a single content type's rows in a workspace. */
|
|
58
|
+
async countTable(type, workspaceId) {
|
|
59
|
+
const table = type.table;
|
|
60
|
+
const [{ total }] = await this.db
|
|
61
|
+
.select({ total: (0, drizzle_orm_1.count)() })
|
|
62
|
+
.from(type.table)
|
|
63
|
+
.where((0, drizzle_orm_1.eq)(table['workspaceId'], workspaceId));
|
|
64
|
+
return total;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
exports.EntryCounterService = EntryCounterService;
|
|
68
|
+
exports.EntryCounterService = EntryCounterService = tslib_1.__decorate([
|
|
69
|
+
(0, common_1.Injectable)(),
|
|
70
|
+
tslib_1.__param(0, (0, database_1.InjectDatabase)()),
|
|
71
|
+
tslib_1.__param(1, (0, content_tokens_1.InjectContentRegistry)()),
|
|
72
|
+
tslib_1.__metadata("design:paramtypes", [Object, Function])
|
|
73
|
+
], EntryCounterService);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure row ↔ entry mappers shared by the read ({@link EntriesService}) and write
|
|
3
|
+
* ({@link EntryWriterService}) paths, so the wire shape and the column projection
|
|
4
|
+
* have one definition each. No DB access, no NestJS — just shape translation.
|
|
5
|
+
*/
|
|
6
|
+
import type { AnyContentType } from '../../../types/content-type';
|
|
7
|
+
import type { EntryRecord } from '../../types/entry-list-view';
|
|
8
|
+
/** A generated content table row seen as a bag of values by property name. */
|
|
9
|
+
type Row = Record<string, unknown>;
|
|
10
|
+
/**
|
|
11
|
+
* Map a raw DB row to the admin {@link EntryRecord}: envelope fields plus a
|
|
12
|
+
* `values` bag keyed by field name. `status`/`publishedAt` are emitted only for
|
|
13
|
+
* publishable types. Relations that own no column — many-relations (their links live in join
|
|
14
|
+
* tables) and inverse/back-references (they reuse the owning side's storage) —
|
|
15
|
+
* aren't selected here; an owning single relation passes through as its FK uuid.
|
|
16
|
+
*/
|
|
17
|
+
export declare function toRecord(type: AnyContentType, row: Row): EntryRecord;
|
|
18
|
+
/**
|
|
19
|
+
* Normalize the admin's (string-shaped) `values` bag to the proper JS types the
|
|
20
|
+
* validator and storage expect — numbers parsed, JSON text parsed, empties
|
|
21
|
+
* collapsed to null — keeping every field (so a many-relation array still
|
|
22
|
+
* validates). The single coercion point: both {@link toColumns} (storage) and
|
|
23
|
+
* the writer's validation run against the result, so they can't disagree on a
|
|
24
|
+
* value's type. Datetime/date stay ISO strings (the validator accepts them;
|
|
25
|
+
* {@link toColumns} converts datetime to `Date` for `timestamptz`).
|
|
26
|
+
*/
|
|
27
|
+
export declare function coerceValues(type: AnyContentType, values: Record<string, unknown>): Record<string, unknown>;
|
|
28
|
+
/**
|
|
29
|
+
* Project a (coerced) `values` bag onto the columns of a generated table for an
|
|
30
|
+
* insert/update. Includes only keys declared on the type (reserved envelope
|
|
31
|
+
* columns — `status`/`published_at`/`deleted_at`/timestamps — are owned by the
|
|
32
|
+
* service, never the client), skips relations that own no column (many-relations,
|
|
33
|
+
* whose links live in join tables, and inverse/back-references, which reuse the
|
|
34
|
+
* owning side's storage), collapses empties to `null`, converts a `datetime` to a `Date` for
|
|
35
|
+
* the `timestamptz` column (guarding an invalid date to `null` rather than
|
|
36
|
+
* letting `pg` throw), and drops a `NaN` number to `null`. A field absent from
|
|
37
|
+
* `values` is written as `null` — the editor submits the full bag, so a write
|
|
38
|
+
* replaces the whole document.
|
|
39
|
+
*/
|
|
40
|
+
export declare function toColumns(type: AnyContentType, values: Record<string, unknown>): Record<string, unknown>;
|
|
41
|
+
/**
|
|
42
|
+
* A human display label for an entry — the first non-empty title-eligible field's
|
|
43
|
+
* value (see {@link TITLE_FIELD_TYPES}), falling back to the id. Used to label
|
|
44
|
+
* rows in the bulk-publish preview.
|
|
45
|
+
*/
|
|
46
|
+
export declare function entryTitle(type: AnyContentType, row: Row): string;
|
|
47
|
+
/**
|
|
48
|
+
* The slug handle for an entry — the value of its **slug field**: the first
|
|
49
|
+
* field flagged `admin.widget === 'slug'`, else a field literally named `slug`.
|
|
50
|
+
* Returns the trimmed value when present and non-empty, otherwise `undefined`
|
|
51
|
+
* (the type has no slug field, or the row's slug is blank). Used to give a
|
|
52
|
+
* linked relation record a stable `/handle` in the admin.
|
|
53
|
+
*/
|
|
54
|
+
export declare function entrySlug(type: AnyContentType, row: Row): string | undefined;
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=entry-row.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-row.d.ts","sourceRoot":"","sources":["../../../../../src/lib/entries/infrastructure/persistence/entry-row.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE/D,8EAA8E;AAC9E,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEnC;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,GAAG,WAAW,CA6BpE;AAiBD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CACxB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgCzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CACrB,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA2BzB;AAWD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,GAAG,MAAM,CAOjE;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,CAS5E"}
|