@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,384 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PublicExpansionQuery = exports.MAX_EXPANDED_FIELDS = 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_domain_1 = require("@orthacms/content-domain");
|
|
9
|
+
const content_type_1 = require("../../types/content-type");
|
|
10
|
+
const fields_1 = require("../../types/fields");
|
|
11
|
+
const media_asset_resolver_1 = require("../../extension/media-asset-resolver");
|
|
12
|
+
const relation_link_service_1 = require("../../entries/infrastructure/persistence/relation-link.service");
|
|
13
|
+
const public_list_entries_query_dto_1 = require("../http/dto/public-list-entries-query.dto");
|
|
14
|
+
const public_entry_row_1 = require("./public-entry-row");
|
|
15
|
+
/**
|
|
16
|
+
* Upper bound on how many fields one request may expand, per kind. The cost of
|
|
17
|
+
* a preview scales with the number of **fields**, not rows (each relation field
|
|
18
|
+
* is one or two queries spanning the whole page), so this is the knob that
|
|
19
|
+
* actually bounds a request — the admin caps only the raw string length, which
|
|
20
|
+
* on a public endpoint would leave a type with a dozen relations open to a
|
|
21
|
+
* request asking for all of them.
|
|
22
|
+
*/
|
|
23
|
+
exports.MAX_EXPANDED_FIELDS = 10;
|
|
24
|
+
/**
|
|
25
|
+
* Route prefix the public API reports for an asset's bytes.
|
|
26
|
+
*
|
|
27
|
+
* The `MEDIA_ASSET_RESOLVER` hands back the **admin's** URLs, which derive their
|
|
28
|
+
* scope from the caller's workspace *membership* — something a token does not
|
|
29
|
+
* have, so a bearer got a 404 on every one of them. Media-server's
|
|
30
|
+
* `/api/v1/media` sibling derives the same scope from the token's resolved
|
|
31
|
+
* workspace instead, so these are the URLs a public consumer can actually fetch,
|
|
32
|
+
* with the very token it already holds.
|
|
33
|
+
*
|
|
34
|
+
* A literal rather than an import: content-server does not depend on
|
|
35
|
+
* media-server (the dependency runs the other way — media binds content's
|
|
36
|
+
* resolver port), so this package cannot ask for the route. It mirrors the
|
|
37
|
+
* default `publicBasePath` the media config already hardcodes.
|
|
38
|
+
*/
|
|
39
|
+
const PUBLIC_MEDIA_BASE_PATH = '/api/v1/media/assets';
|
|
40
|
+
/**
|
|
41
|
+
* Rewrites a track's admin URL to the public one.
|
|
42
|
+
*
|
|
43
|
+
* The resolver builds `/api/media/assets/<id>/raw`, whose scope comes from the
|
|
44
|
+
* caller's workspace **membership** — which a bearer token does not have. The
|
|
45
|
+
* id is the only part worth keeping, so it is lifted out and re-addressed
|
|
46
|
+
* against the public base, same as {@link publicAssetUrl} does for the asset
|
|
47
|
+
* itself. A src that does not match is passed through: an unexpected shape is
|
|
48
|
+
* better published as-is than silently rewritten to a 404.
|
|
49
|
+
*/
|
|
50
|
+
function publicTrackUrl(src) {
|
|
51
|
+
const id = /\/assets\/([^/]+)\/raw/.exec(src)?.[1];
|
|
52
|
+
return id ? publicAssetUrl(id) : src;
|
|
53
|
+
}
|
|
54
|
+
/** The public download URL for one asset, optionally a generated derivative. */
|
|
55
|
+
function publicAssetUrl(id, variant) {
|
|
56
|
+
const base = `${PUBLIC_MEDIA_BASE_PATH}/${id}/raw`;
|
|
57
|
+
return variant ? `${base}?variant=${variant}` : base;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Resolves the public API's opt-in **relation** and **media** expansions for a
|
|
61
|
+
* page of entries.
|
|
62
|
+
*
|
|
63
|
+
* Both are batched across the whole page — one bounded set of queries per
|
|
64
|
+
* *field*, never one per row. Relations delegate to
|
|
65
|
+
* `RelationLinkService.previewForEntries` (windowed `row_number()` for the cap,
|
|
66
|
+
* `count(*) over` for the total, batched title resolution). Media deliberately
|
|
67
|
+
* does **not** reuse `MediaRefsQuery.forValues`: that method takes one entry's
|
|
68
|
+
* values, so calling it per row would be exactly the N+1 the relation preview
|
|
69
|
+
* was built to avoid. Instead every media id on the page is collected and
|
|
70
|
+
* resolved in a single batched lookup.
|
|
71
|
+
*/
|
|
72
|
+
let PublicExpansionQuery = class PublicExpansionQuery {
|
|
73
|
+
db;
|
|
74
|
+
relationLinks;
|
|
75
|
+
media;
|
|
76
|
+
constructor(db, relationLinks, media) {
|
|
77
|
+
this.db = db;
|
|
78
|
+
this.relationLinks = relationLinks;
|
|
79
|
+
this.media = media;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Validate a `?relationFields=` list: every name must be a relation field
|
|
83
|
+
* on the type, and its target must be a content type the workspace was
|
|
84
|
+
* granted. An ungranted target is a **400**, matching how `?filter=` treats
|
|
85
|
+
* a traversal into one — a public caller should not be able to expand into
|
|
86
|
+
* content the workspace does not expose, and saying so beats silently
|
|
87
|
+
* returning an empty field.
|
|
88
|
+
*/
|
|
89
|
+
parseRelationFields(type, raw, granted) {
|
|
90
|
+
if (!raw?.trim()) {
|
|
91
|
+
// No list given: expand everything expandable. An ungranted target
|
|
92
|
+
// is skipped rather than refused — the caller didn't name it, so
|
|
93
|
+
// there is nothing to correct them about, and this matches what the
|
|
94
|
+
// `/relations` sibling route returns.
|
|
95
|
+
return this.allFieldsOfKind(type, 'relationFields', (spec) => spec.type === fields_1.CONTENT_FIELD_TYPE.Relation &&
|
|
96
|
+
!!spec.relation &&
|
|
97
|
+
granted.has(spec.relation.to().name));
|
|
98
|
+
}
|
|
99
|
+
return this.parseFields(type, raw, 'relationFields', (name, spec) => {
|
|
100
|
+
if (spec.type !== fields_1.CONTENT_FIELD_TYPE.Relation || !spec.relation) {
|
|
101
|
+
throw new common_1.BadRequestException(`relationFields: "${name}" is not a relation field on "${type.name}".`);
|
|
102
|
+
}
|
|
103
|
+
const target = spec.relation.to();
|
|
104
|
+
if (!granted.has(target.name)) {
|
|
105
|
+
throw new common_1.BadRequestException(`relationFields: "${name}" cannot be expanded — this workspace has no access to "${target.name}".`);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/** Validate a `?mediaFields=` list: every name must be a media field. */
|
|
110
|
+
parseMediaFields(type, raw) {
|
|
111
|
+
if (!raw?.trim()) {
|
|
112
|
+
return this.allFieldsOfKind(type, 'mediaFields', (spec) => spec.type === fields_1.CONTENT_FIELD_TYPE.Media);
|
|
113
|
+
}
|
|
114
|
+
return this.parseFields(type, raw, 'mediaFields', (name, spec) => {
|
|
115
|
+
if (spec.type !== fields_1.CONTENT_FIELD_TYPE.Media) {
|
|
116
|
+
throw new common_1.BadRequestException(`mediaFields: "${name}" is not a media field on "${type.name}".`);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* One capped page of links per requested relation field, for every row on
|
|
122
|
+
* the page, keyed by entry id.
|
|
123
|
+
*
|
|
124
|
+
* `publishedOnly` is the public difference: a draft target is neither shown
|
|
125
|
+
* nor counted, so `total` is the number of links a caller can actually
|
|
126
|
+
* reach.
|
|
127
|
+
*/
|
|
128
|
+
async relationsForRows(type, fields, rows, workspaceId, limit = public_list_entries_query_dto_1.DEFAULT_EXPANSION_LIMIT) {
|
|
129
|
+
const out = new Map();
|
|
130
|
+
if (!fields.length || !rows.length) {
|
|
131
|
+
return out;
|
|
132
|
+
}
|
|
133
|
+
const previews = await this.relationLinks.previewForEntries(type, fields, rows, workspaceId, limit, { publishedOnly: true });
|
|
134
|
+
// The preview yields ordered link ids; hydrate them into full entries
|
|
135
|
+
// with one batched read per distinct TARGET TYPE, so a page costs a
|
|
136
|
+
// query per type rather than per link.
|
|
137
|
+
const entriesById = await this.linkedEntriesById(type, fields, previews, workspaceId);
|
|
138
|
+
for (const [entryId, byField] of previews) {
|
|
139
|
+
const view = {};
|
|
140
|
+
for (const [field, value] of Object.entries(byField)) {
|
|
141
|
+
const linked = entriesById.get(field);
|
|
142
|
+
view[field] = {
|
|
143
|
+
// Preserve the preview's link order, and drop any id the
|
|
144
|
+
// hydration didn't return (it named a target the caller
|
|
145
|
+
// can't see — already excluded from `total` upstream).
|
|
146
|
+
items: value.items
|
|
147
|
+
.map((ref) => linked?.get(ref.id))
|
|
148
|
+
.filter((entry) => !!entry),
|
|
149
|
+
total: value.total
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
out.set(entryId, view);
|
|
153
|
+
}
|
|
154
|
+
return out;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Hydrate already-read link views (the `/relations` sibling routes' output
|
|
158
|
+
* from `readAll` / `readField`) into the same full-entry shape the list
|
|
159
|
+
* preview returns, so both surfaces speak one contract.
|
|
160
|
+
*/
|
|
161
|
+
async hydrateRelationViews(type, views, workspaceId) {
|
|
162
|
+
const fields = Object.keys(views);
|
|
163
|
+
const linked = await this.linkedEntriesById(type, fields, new Map([['one', views]]), workspaceId);
|
|
164
|
+
const out = {};
|
|
165
|
+
for (const [field, view] of Object.entries(views)) {
|
|
166
|
+
const byId = linked.get(field);
|
|
167
|
+
out[field] = {
|
|
168
|
+
items: view.items
|
|
169
|
+
.map((ref) => byId?.get(ref.id))
|
|
170
|
+
.filter((entry) => !!entry),
|
|
171
|
+
total: view.total
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return out;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Load every linked entry named by a preview, keyed by field and then by
|
|
178
|
+
* id. One `IN (…)` read per relation field's target type, projected through
|
|
179
|
+
* the same {@link toPublicEntry} the entry routes use — so a linked record
|
|
180
|
+
* has exactly the shape a consumer already handles.
|
|
181
|
+
*
|
|
182
|
+
* Linked entries are returned **unexpanded**: nothing here recurses, which
|
|
183
|
+
* is what bounds a request to one level of the graph.
|
|
184
|
+
*/
|
|
185
|
+
async linkedEntriesById(type, fields, previews, workspaceId) {
|
|
186
|
+
const idsByField = new Map();
|
|
187
|
+
for (const byField of previews.values()) {
|
|
188
|
+
for (const [field, value] of Object.entries(byField)) {
|
|
189
|
+
let ids = idsByField.get(field);
|
|
190
|
+
if (!ids) {
|
|
191
|
+
ids = new Set();
|
|
192
|
+
idsByField.set(field, ids);
|
|
193
|
+
}
|
|
194
|
+
for (const ref of value.items)
|
|
195
|
+
ids.add(ref.id);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const out = new Map();
|
|
199
|
+
await Promise.all(fields.map(async (field) => {
|
|
200
|
+
const ids = idsByField.get(field);
|
|
201
|
+
const target = type.fields[field]?.relation?.to();
|
|
202
|
+
if (!target || !ids?.size)
|
|
203
|
+
return;
|
|
204
|
+
const cols = target.table;
|
|
205
|
+
const rows = (await this.db
|
|
206
|
+
.select()
|
|
207
|
+
.from(target.table)
|
|
208
|
+
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.inArray)(cols['id'], [...ids]), (0, drizzle_orm_1.eq)(cols['workspaceId'], workspaceId), target.publishable
|
|
209
|
+
? (0, drizzle_orm_1.eq)(cols['status'], content_type_1.ENTRY_STATUS.Published)
|
|
210
|
+
: undefined, target.paranoid
|
|
211
|
+
? (0, drizzle_orm_1.isNull)(cols['deletedAt'])
|
|
212
|
+
: undefined)));
|
|
213
|
+
out.set(field, new Map(rows.map((row) => [
|
|
214
|
+
row['id'],
|
|
215
|
+
(0, public_entry_row_1.toPublicEntry)(target, row)
|
|
216
|
+
])));
|
|
217
|
+
}));
|
|
218
|
+
return out;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* The assets of each requested media field, for every row on the page,
|
|
222
|
+
* keyed by entry id. One batched resolver lookup for the whole page.
|
|
223
|
+
*
|
|
224
|
+
* A no-op when no media plugin is registered (nothing binds the resolver),
|
|
225
|
+
* exactly like the admin's media read — content boots without media.
|
|
226
|
+
*/
|
|
227
|
+
async mediaForRows(type, fields, rows, workspaceId, limit = public_list_entries_query_dto_1.DEFAULT_EXPANSION_LIMIT) {
|
|
228
|
+
const out = new Map();
|
|
229
|
+
if (!this.media || !fields.length || !rows.length) {
|
|
230
|
+
return out;
|
|
231
|
+
}
|
|
232
|
+
// Collect every id on the page first, so the resolver is hit once.
|
|
233
|
+
// Refs rather than ids: a media value carries a per-usage `alt` and a
|
|
234
|
+
// `decorative` flag since `ORT-83`, and those are what a public consumer
|
|
235
|
+
// needs to emit a correct `<img alt>` — the asset row's own description
|
|
236
|
+
// is only the fallback.
|
|
237
|
+
const idsByRowField = new Map();
|
|
238
|
+
const all = new Set();
|
|
239
|
+
for (const row of rows) {
|
|
240
|
+
const entryId = row['id'];
|
|
241
|
+
if (typeof entryId !== 'string')
|
|
242
|
+
continue;
|
|
243
|
+
const byField = new Map();
|
|
244
|
+
for (const field of fields) {
|
|
245
|
+
const refs = mediaRefsOf(row[field]);
|
|
246
|
+
if (!refs.length)
|
|
247
|
+
continue;
|
|
248
|
+
byField.set(field, refs);
|
|
249
|
+
for (const ref of refs)
|
|
250
|
+
all.add(ref.id);
|
|
251
|
+
}
|
|
252
|
+
idsByRowField.set(entryId, byField);
|
|
253
|
+
}
|
|
254
|
+
if (!all.size) {
|
|
255
|
+
return out;
|
|
256
|
+
}
|
|
257
|
+
const resolved = await this.media.resolve([...all], workspaceId);
|
|
258
|
+
for (const [entryId, byField] of idsByRowField) {
|
|
259
|
+
const view = {};
|
|
260
|
+
for (const [field, refs] of byField) {
|
|
261
|
+
// An id the resolver didn't return names an asset that is gone
|
|
262
|
+
// or lives in another workspace. The admin keeps it as a
|
|
263
|
+
// `missing` placeholder to preserve ordering in an editor; a
|
|
264
|
+
// public read has no such need and simply omits it, so every
|
|
265
|
+
// ref it returns is a real asset.
|
|
266
|
+
const present = refs
|
|
267
|
+
.map((ref) => {
|
|
268
|
+
const asset = resolved.get(ref.id);
|
|
269
|
+
return asset ? { ref, asset } : null;
|
|
270
|
+
})
|
|
271
|
+
.filter((pair) => pair !== null);
|
|
272
|
+
// `total` counts every asset actually attached, before the
|
|
273
|
+
// limit — so a lowered limit is visible as `items.length <
|
|
274
|
+
// total` rather than silently passing off a slice as the whole.
|
|
275
|
+
const items = present.slice(0, limit).map(({ ref, asset }) => ({
|
|
276
|
+
id: asset.id,
|
|
277
|
+
name: asset.name,
|
|
278
|
+
// The resolver's own URLs are the admin's; rewrite to
|
|
279
|
+
// the token-fetchable route. Presence of a derivative is
|
|
280
|
+
// still read from the resolver — it is what knows
|
|
281
|
+
// whether one was generated — but the address is ours.
|
|
282
|
+
url: publicAssetUrl(asset.id),
|
|
283
|
+
...(asset.thumbUrl
|
|
284
|
+
? { thumbUrl: publicAssetUrl(asset.id, 'thumb') }
|
|
285
|
+
: {}),
|
|
286
|
+
...(asset.previewUrl
|
|
287
|
+
? {
|
|
288
|
+
previewUrl: publicAssetUrl(asset.id, 'preview')
|
|
289
|
+
}
|
|
290
|
+
: {}),
|
|
291
|
+
kind: asset.kind,
|
|
292
|
+
mimeType: asset.mimeType,
|
|
293
|
+
alt: publicAlt(ref, asset.alt),
|
|
294
|
+
// Rewritten to the token-fetchable route, exactly like
|
|
295
|
+
// `url` above: the resolver hands back the admin's
|
|
296
|
+
// addresses, which a bearer cannot reach (`ORT-92`).
|
|
297
|
+
tracks: asset.tracks.map((track) => ({
|
|
298
|
+
kind: track.kind,
|
|
299
|
+
srclang: track.srclang,
|
|
300
|
+
label: track.label,
|
|
301
|
+
src: publicTrackUrl(track.src),
|
|
302
|
+
...(track.default ? { default: true } : {})
|
|
303
|
+
})),
|
|
304
|
+
...(ref.decorative === true
|
|
305
|
+
? { decorative: true }
|
|
306
|
+
: {})
|
|
307
|
+
}));
|
|
308
|
+
view[field] = { items, total: present.length };
|
|
309
|
+
}
|
|
310
|
+
out.set(entryId, view);
|
|
311
|
+
}
|
|
312
|
+
return out;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Every field of one kind — what `?relations=preview` / `?media=preview`
|
|
316
|
+
* expand when the caller names no fields.
|
|
317
|
+
*
|
|
318
|
+
* A type with more expandable fields than the cap is a **400** telling the
|
|
319
|
+
* caller to name the ones they want, rather than a silently truncated
|
|
320
|
+
* response: quietly dropping fields would read as "this entry has no
|
|
321
|
+
* links" and be near-impossible to notice.
|
|
322
|
+
*/
|
|
323
|
+
allFieldsOfKind(type, param, matches) {
|
|
324
|
+
const names = Object.entries(type.fields)
|
|
325
|
+
.filter(([, spec]) => matches(spec))
|
|
326
|
+
.map(([name]) => name);
|
|
327
|
+
if (names.length > exports.MAX_EXPANDED_FIELDS) {
|
|
328
|
+
throw new common_1.BadRequestException(`${param}: "${type.name}" has ${names.length} expandable fields, more than the ${exports.MAX_EXPANDED_FIELDS} a single request may expand — name the ones you need with \`${param}\`.`);
|
|
329
|
+
}
|
|
330
|
+
return names;
|
|
331
|
+
}
|
|
332
|
+
/** Shared parse: split, trim, de-duplicate, bound, then per-kind checks. */
|
|
333
|
+
parseFields(type, raw, param, check) {
|
|
334
|
+
if (!raw)
|
|
335
|
+
return [];
|
|
336
|
+
const names = [
|
|
337
|
+
...new Set(raw
|
|
338
|
+
.split(',')
|
|
339
|
+
.map((name) => name.trim())
|
|
340
|
+
.filter(Boolean))
|
|
341
|
+
];
|
|
342
|
+
if (names.length > exports.MAX_EXPANDED_FIELDS) {
|
|
343
|
+
throw new common_1.BadRequestException(`${param}: at most ${exports.MAX_EXPANDED_FIELDS} fields may be expanded per request.`);
|
|
344
|
+
}
|
|
345
|
+
for (const name of names) {
|
|
346
|
+
const spec = type.fields[name];
|
|
347
|
+
if (!spec) {
|
|
348
|
+
throw new common_1.BadRequestException(`${param}: unknown field "${name}" on "${type.name}".`);
|
|
349
|
+
}
|
|
350
|
+
check(name, spec);
|
|
351
|
+
}
|
|
352
|
+
return names;
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
exports.PublicExpansionQuery = PublicExpansionQuery;
|
|
356
|
+
exports.PublicExpansionQuery = PublicExpansionQuery = tslib_1.__decorate([
|
|
357
|
+
(0, common_1.Injectable)(),
|
|
358
|
+
tslib_1.__param(0, (0, database_1.InjectDatabase)()),
|
|
359
|
+
tslib_1.__param(2, (0, common_1.Optional)()),
|
|
360
|
+
tslib_1.__param(2, (0, media_asset_resolver_1.InjectMediaAssetResolver)()),
|
|
361
|
+
tslib_1.__metadata("design:paramtypes", [Object, relation_link_service_1.RelationLinkService, Object])
|
|
362
|
+
], PublicExpansionQuery);
|
|
363
|
+
/** The asset ids stored in a media field — one id, or an ordered list. */
|
|
364
|
+
function mediaRefsOf(value) {
|
|
365
|
+
return (Array.isArray(value) ? value : [value])
|
|
366
|
+
.map(content_domain_1.toMediaValueRef)
|
|
367
|
+
.filter((ref) => ref !== null && !!ref.id);
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* The alt text a public consumer should render for one usage.
|
|
371
|
+
*
|
|
372
|
+
* `decorative` resolves to `''` — the value an `<img alt="">` needs to be
|
|
373
|
+
* skipped by a screen reader, which is a different claim from omitting the
|
|
374
|
+
* attribute. A per-usage `alt` otherwise overrides the asset row's default,
|
|
375
|
+
* because alt text is per usage: the same logo is "Acme logo" in a header and
|
|
376
|
+
* decorative in a footer strip (`ORT-83`).
|
|
377
|
+
*/
|
|
378
|
+
function publicAlt(ref, assetAlt) {
|
|
379
|
+
if (ref.decorative === true)
|
|
380
|
+
return '';
|
|
381
|
+
if (typeof ref.alt === 'string' && ref.alt.trim() !== '')
|
|
382
|
+
return ref.alt;
|
|
383
|
+
return assetAlt;
|
|
384
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { PublicEntry } from './public-entry';
|
|
2
|
+
/**
|
|
3
|
+
* Wire contracts for the public API's **batch** writes — one request that saves,
|
|
4
|
+
* publishes, unpublishes or deletes many entries of one content type.
|
|
5
|
+
*
|
|
6
|
+
* Shared by every surface that offers them: the public REST routes and the MCP
|
|
7
|
+
* `content_bulk_*` tools. Defined once here so a client that learned a shape
|
|
8
|
+
* from the OpenAPI document reads the tool's output without a second mapping.
|
|
9
|
+
*
|
|
10
|
+
* Only the **save** contract is new. Bulk publish / unpublish / delete answer in
|
|
11
|
+
* the shapes the admin's own bulk routes already publish (`BulkPublishResult`,
|
|
12
|
+
* `BulkActionResult`), because they run the very same use-cases — see
|
|
13
|
+
* `PublicEntryWritesService`.
|
|
14
|
+
*/
|
|
15
|
+
/** What a bulk-save item does to the store. */
|
|
16
|
+
export declare const BULK_SAVE_OP: {
|
|
17
|
+
/** Insert a new entry — a draft on a publishable type. */
|
|
18
|
+
readonly Create: "create";
|
|
19
|
+
/** Merge values onto an entry that already exists. */
|
|
20
|
+
readonly Update: "update";
|
|
21
|
+
};
|
|
22
|
+
/** One item's operation. */
|
|
23
|
+
export type BulkSaveOp = (typeof BULK_SAVE_OP)[keyof typeof BULK_SAVE_OP];
|
|
24
|
+
/**
|
|
25
|
+
* Why one item of a batch did not go through.
|
|
26
|
+
*
|
|
27
|
+
* Carries the **status the equivalent single-entry call would have returned**
|
|
28
|
+
* (404 for an entry that isn't there, 422 for values that don't validate, 400
|
|
29
|
+
* for a malformed item) rather than a bulk-specific error vocabulary, so a
|
|
30
|
+
* client already handling the single-entry API needs no new branch — and so a
|
|
31
|
+
* per-item failure stays diagnosable at all, which a flattened boolean would
|
|
32
|
+
* not be.
|
|
33
|
+
*/
|
|
34
|
+
export interface PublicBulkError {
|
|
35
|
+
/** The HTTP status the same write would have failed with on its own. */
|
|
36
|
+
status: number;
|
|
37
|
+
/** The message, as the single-entry route would have phrased it. */
|
|
38
|
+
message: string;
|
|
39
|
+
/** The per-field issues of a 422, when there are any. */
|
|
40
|
+
issues?: unknown;
|
|
41
|
+
}
|
|
42
|
+
/** What became of one submitted item, positionally matched to the request. */
|
|
43
|
+
export interface PublicBulkSaveItemResult {
|
|
44
|
+
/** The item's 0-based position in the submitted `items` array. */
|
|
45
|
+
index: number;
|
|
46
|
+
/** Which operation the item resolved to. @see BULK_SAVE_OP */
|
|
47
|
+
op: BulkSaveOp;
|
|
48
|
+
/** Whether the write landed. */
|
|
49
|
+
ok: boolean;
|
|
50
|
+
/** The saved entry, in the same shape a single-entry write returns. */
|
|
51
|
+
entry?: PublicEntry;
|
|
52
|
+
/** Why it did not, when `ok` is false. */
|
|
53
|
+
error?: PublicBulkError;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The response of a bulk save: one result per submitted item, **in request
|
|
57
|
+
* order**, plus the tallies.
|
|
58
|
+
*
|
|
59
|
+
* **Partial success is the contract**, not a degraded mode. The items are
|
|
60
|
+
* written one transaction at a time (see `PublicEntryWritesService.bulkSave`),
|
|
61
|
+
* so a batch cannot be rolled back as a unit — and rejecting 49 good entries
|
|
62
|
+
* because the fiftieth names a missing relation would make the endpoint useless
|
|
63
|
+
* for the imports it exists to serve. The response is therefore always a 200
|
|
64
|
+
* with the per-item verdicts, exactly as the bulk-publish commit reports its
|
|
65
|
+
* `skipped` ids, and a caller retries the failures it can fix.
|
|
66
|
+
*/
|
|
67
|
+
export interface PublicBulkSaveResult {
|
|
68
|
+
/** One entry per submitted item, in request order. */
|
|
69
|
+
items: PublicBulkSaveItemResult[];
|
|
70
|
+
/** How many items were inserted. */
|
|
71
|
+
created: number;
|
|
72
|
+
/** How many existing entries were changed. */
|
|
73
|
+
updated: number;
|
|
74
|
+
/** How many items did not save. */
|
|
75
|
+
failed: number;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=public-bulk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-bulk.d.ts","sourceRoot":"","sources":["../../../../src/lib/public-api/types/public-bulk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;;;;;;;;;;GAYG;AAEH,+CAA+C;AAC/C,eAAO,MAAM,YAAY;IACrB,0DAA0D;;IAE1D,sDAAsD;;CAEhD,CAAC;AAEX,4BAA4B;AAC5B,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE1E;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC5B,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,8EAA8E;AAC9E,MAAM,WAAW,wBAAwB;IACrC,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,EAAE,EAAE,UAAU,CAAC;IACf,gCAAgC;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,uEAAuE;IACvE,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,oBAAoB;IACjC,sDAAsD;IACtD,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAClC,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;CAClB"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BULK_SAVE_OP = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Wire contracts for the public API's **batch** writes — one request that saves,
|
|
6
|
+
* publishes, unpublishes or deletes many entries of one content type.
|
|
7
|
+
*
|
|
8
|
+
* Shared by every surface that offers them: the public REST routes and the MCP
|
|
9
|
+
* `content_bulk_*` tools. Defined once here so a client that learned a shape
|
|
10
|
+
* from the OpenAPI document reads the tool's output without a second mapping.
|
|
11
|
+
*
|
|
12
|
+
* Only the **save** contract is new. Bulk publish / unpublish / delete answer in
|
|
13
|
+
* the shapes the admin's own bulk routes already publish (`BulkPublishResult`,
|
|
14
|
+
* `BulkActionResult`), because they run the very same use-cases — see
|
|
15
|
+
* `PublicEntryWritesService`.
|
|
16
|
+
*/
|
|
17
|
+
/** What a bulk-save item does to the store. */
|
|
18
|
+
exports.BULK_SAVE_OP = {
|
|
19
|
+
/** Insert a new entry — a draft on a publishable type. */
|
|
20
|
+
Create: 'create',
|
|
21
|
+
/** Merge values onto an entry that already exists. */
|
|
22
|
+
Update: 'update'
|
|
23
|
+
};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire contracts for the public content API (`/api/v1/...`). Kept separate from
|
|
3
|
+
* the admin's `EntryRecord` on purpose: this is a **published contract** an
|
|
4
|
+
* external site or app builds against, so it must be free to stay still while
|
|
5
|
+
* the admin's internal shape evolves.
|
|
6
|
+
*/
|
|
7
|
+
import type { PublicMediaFieldView, PublicRelationFieldView } from './public-expansion';
|
|
8
|
+
/**
|
|
9
|
+
* One entry as the public API serves it: the storage envelope plus a flat
|
|
10
|
+
* `values` bag keyed by field name.
|
|
11
|
+
*
|
|
12
|
+
* `values` carries the entry's **own** data only — text, richtext, number,
|
|
13
|
+
* money, boolean, date, datetime, select, multiselect, and json. Every
|
|
14
|
+
* **reference** field is omitted: `relation` in all four cardinalities and
|
|
15
|
+
* `media`. Neither is resolvable through this API yet, so returning a bare
|
|
16
|
+
* uuid would hand a consumer an identifier it has no route to follow.
|
|
17
|
+
*
|
|
18
|
+
* That omission is **provisional**, not the intended end state. The schema
|
|
19
|
+
* endpoint still describes the omitted fields, because they are part of the
|
|
20
|
+
* real content model; when relation and media reads land they begin appearing
|
|
21
|
+
* in `values`, which only ever adds keys.
|
|
22
|
+
*
|
|
23
|
+
* `status` is carried on publishable types. It used to be omitted as a
|
|
24
|
+
* constant — this API only ever served published rows — but a write-scoped
|
|
25
|
+
* token can now create drafts and read them back with `?status=`, so it is real
|
|
26
|
+
* information again. Adding it is additive: a consumer that ignored the key
|
|
27
|
+
* before still sees `published` on every entry a read-only token can reach.
|
|
28
|
+
*/
|
|
29
|
+
export interface PublicEntry {
|
|
30
|
+
/** Entry id — the `:id` segment of the single-entry route. */
|
|
31
|
+
id: string;
|
|
32
|
+
/**
|
|
33
|
+
* `draft` or `published` — only on `publishable` types. A read-only token
|
|
34
|
+
* only ever sees `published`.
|
|
35
|
+
*
|
|
36
|
+
* `draft` with a non-null {@link publishedAt} is the admin's **Modified**
|
|
37
|
+
* state: live content with unpublished edits on top. Saving a published
|
|
38
|
+
* entry moves it back to `draft` while its published *version* stays live,
|
|
39
|
+
* so the pair is what tells those apart — neither field alone does.
|
|
40
|
+
*/
|
|
41
|
+
status?: string;
|
|
42
|
+
/** ISO creation timestamp. */
|
|
43
|
+
createdAt: string;
|
|
44
|
+
/** ISO last-updated timestamp. */
|
|
45
|
+
updatedAt: string;
|
|
46
|
+
/**
|
|
47
|
+
* ISO timestamp of when this entry last went live — only on `publishable`
|
|
48
|
+
* types. Never null in a public response: an entry with no published
|
|
49
|
+
* version is not served at all.
|
|
50
|
+
*/
|
|
51
|
+
publishedAt?: string | null;
|
|
52
|
+
/** Locale slug of this row — only on `i18n` types. */
|
|
53
|
+
locale?: string;
|
|
54
|
+
/** Shared translation-group id — only on `i18n` types, so a consumer can
|
|
55
|
+
* correlate an entry with its other translations. */
|
|
56
|
+
localeGroupId?: string;
|
|
57
|
+
/** The entry's own field values, keyed by field name (see the note above
|
|
58
|
+
* on which kinds are omitted). */
|
|
59
|
+
values: Record<string, unknown>;
|
|
60
|
+
/**
|
|
61
|
+
* Relation links, keyed by field name — present only when the caller opts
|
|
62
|
+
* in with `?relations=preview&relationFields=…`. Each field carries at most
|
|
63
|
+
* one page of refs plus the true count of *visible* links.
|
|
64
|
+
*/
|
|
65
|
+
relations?: Record<string, PublicRelationFieldView>;
|
|
66
|
+
/**
|
|
67
|
+
* Media assets, keyed by field name — present only when the caller opts in
|
|
68
|
+
* with `?media=preview&mediaFields=…`. Read the URL caveat on
|
|
69
|
+
* {@link PublicMediaRef} before pointing a browser at one.
|
|
70
|
+
*/
|
|
71
|
+
media?: Record<string, PublicMediaFieldView>;
|
|
72
|
+
/**
|
|
73
|
+
* The entry's **other** locale rows — the rest of its translation group —
|
|
74
|
+
* present only when the caller opts in with `?translations=preview` on a
|
|
75
|
+
* localized type. Ordered by locale slug, and each is a full
|
|
76
|
+
* {@link PublicEntry} honouring the same `?fields=` selection as the root,
|
|
77
|
+
* so a language switcher reads `[entry, ...entry.translations]`.
|
|
78
|
+
*
|
|
79
|
+
* The entry itself is **not** repeated here: it is the row you asked for,
|
|
80
|
+
* in the locale you asked for. Only published, non-deleted siblings appear,
|
|
81
|
+
* so a locale that exists but is still a draft is absent — the same
|
|
82
|
+
* visibility rule as every other public read. Siblings are not themselves
|
|
83
|
+
* expanded: their `relations`, `media`, and `translations` are absent.
|
|
84
|
+
*/
|
|
85
|
+
translations?: PublicEntry[];
|
|
86
|
+
}
|
|
87
|
+
/** One page of public entries. */
|
|
88
|
+
export interface PublicEntryListView {
|
|
89
|
+
items: PublicEntry[];
|
|
90
|
+
/** Total matching entries, ignoring pagination. */
|
|
91
|
+
total: number;
|
|
92
|
+
/** 1-based page number this page represents. */
|
|
93
|
+
page: number;
|
|
94
|
+
/** Rows per page actually applied. */
|
|
95
|
+
pageSize: number;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=public-entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-entry.d.ts","sourceRoot":"","sources":["../../../../src/lib/public-api/types/public-entry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACR,oBAAoB,EACpB,uBAAuB,EAC1B,MAAM,oBAAoB,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,WAAW;IACxB,8DAA8D;IAC9D,EAAE,EAAE,MAAM,CAAC;IACX;;;;;;;;OAQG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;yDACqD;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;sCACkC;IAClC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IACpD;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAC7C;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;CAChC;AAED,kCAAkC;AAClC,MAAM,WAAW,mBAAmB;IAChC,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Wire contracts for the public content API (`/api/v1/...`). Kept separate from
|
|
4
|
+
* the admin's `EntryRecord` on purpose: this is a **published contract** an
|
|
5
|
+
* external site or app builds against, so it must be free to stay still while
|
|
6
|
+
* the admin's internal shape evolves.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|