@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,32 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { Reflector } from '@nestjs/core';
|
|
3
|
+
import { AccessPolicy, ApiTokenService } from '@orthacms/identity-server';
|
|
4
|
+
/**
|
|
5
|
+
* Authenticates a public content-API request from its `Authorization: Bearer`
|
|
6
|
+
* token and authorizes it against the token's scope.
|
|
7
|
+
*
|
|
8
|
+
* These routes are `@Public()`, so the app-wide session `AuthGuard` passes them
|
|
9
|
+
* through untouched — this guard is the whole authentication story for them. It
|
|
10
|
+
* hashes the presented bearer, resolves it via `ApiTokenService.verify` (which
|
|
11
|
+
* rejects unknown, revoked, and expired tokens identically), and attaches the
|
|
12
|
+
* verified token as `request.apiToken`.
|
|
13
|
+
*
|
|
14
|
+
* Authorization then reuses the **same** machinery as the session routes:
|
|
15
|
+
* `scopePermissions` turns the token's scope into a permission set, and the
|
|
16
|
+
* route's `@RequirePermissions(...)` metadata is evaluated against it by the
|
|
17
|
+
* pure {@link AccessPolicy} — so a route's requirement means exactly the same
|
|
18
|
+
* thing whether the caller is a logged-in user or a token, and adding a write
|
|
19
|
+
* route later needs no change here.
|
|
20
|
+
*
|
|
21
|
+
* Every authentication failure — no header, wrong scheme, unknown/revoked/
|
|
22
|
+
* expired token — is one bare 401, so the endpoint can't be used to probe which
|
|
23
|
+
* tokens exist.
|
|
24
|
+
*/
|
|
25
|
+
export declare class ApiTokenGuard implements CanActivate {
|
|
26
|
+
private readonly reflector;
|
|
27
|
+
private readonly tokens;
|
|
28
|
+
private readonly accessPolicy;
|
|
29
|
+
constructor(reflector: Reflector, tokens: ApiTokenService, accessPolicy: AccessPolicy);
|
|
30
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=api-token.guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-token.guard.d.ts","sourceRoot":"","sources":["../../../../../src/lib/public-api/http/guards/api-token.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,WAAW,EACX,gBAAgB,EAInB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACH,YAAY,EACZ,eAAe,EAKlB,MAAM,2BAA2B,CAAC;AAMnC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBACa,aAAc,YAAW,WAAW;IAEzC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAFZ,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,eAAe,EACvB,YAAY,EAAE,YAAY;IAGzC,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CA4CjE"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ApiTokenGuard = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const core_1 = require("@nestjs/core");
|
|
7
|
+
const identity_server_1 = require("@orthacms/identity-server");
|
|
8
|
+
/** The scheme the `Authorization` header must use, case-insensitively. */
|
|
9
|
+
const BEARER = 'bearer';
|
|
10
|
+
/**
|
|
11
|
+
* Authenticates a public content-API request from its `Authorization: Bearer`
|
|
12
|
+
* token and authorizes it against the token's scope.
|
|
13
|
+
*
|
|
14
|
+
* These routes are `@Public()`, so the app-wide session `AuthGuard` passes them
|
|
15
|
+
* through untouched — this guard is the whole authentication story for them. It
|
|
16
|
+
* hashes the presented bearer, resolves it via `ApiTokenService.verify` (which
|
|
17
|
+
* rejects unknown, revoked, and expired tokens identically), and attaches the
|
|
18
|
+
* verified token as `request.apiToken`.
|
|
19
|
+
*
|
|
20
|
+
* Authorization then reuses the **same** machinery as the session routes:
|
|
21
|
+
* `scopePermissions` turns the token's scope into a permission set, and the
|
|
22
|
+
* route's `@RequirePermissions(...)` metadata is evaluated against it by the
|
|
23
|
+
* pure {@link AccessPolicy} — so a route's requirement means exactly the same
|
|
24
|
+
* thing whether the caller is a logged-in user or a token, and adding a write
|
|
25
|
+
* route later needs no change here.
|
|
26
|
+
*
|
|
27
|
+
* Every authentication failure — no header, wrong scheme, unknown/revoked/
|
|
28
|
+
* expired token — is one bare 401, so the endpoint can't be used to probe which
|
|
29
|
+
* tokens exist.
|
|
30
|
+
*/
|
|
31
|
+
let ApiTokenGuard = class ApiTokenGuard {
|
|
32
|
+
reflector;
|
|
33
|
+
tokens;
|
|
34
|
+
accessPolicy;
|
|
35
|
+
constructor(reflector, tokens, accessPolicy) {
|
|
36
|
+
this.reflector = reflector;
|
|
37
|
+
this.tokens = tokens;
|
|
38
|
+
this.accessPolicy = accessPolicy;
|
|
39
|
+
}
|
|
40
|
+
async canActivate(context) {
|
|
41
|
+
const request = context.switchToHttp().getRequest();
|
|
42
|
+
const secret = bearerFrom(request.headers.authorization);
|
|
43
|
+
if (!secret) {
|
|
44
|
+
throw new common_1.UnauthorizedException('Missing `Authorization: Bearer <token>` header.');
|
|
45
|
+
}
|
|
46
|
+
const token = await this.tokens.verify(secret);
|
|
47
|
+
if (!token) {
|
|
48
|
+
// Unknown, revoked, and expired are one flat 401 — no enumeration
|
|
49
|
+
// signal, and no hint about which of the three it was.
|
|
50
|
+
throw new common_1.UnauthorizedException('Invalid API token.');
|
|
51
|
+
}
|
|
52
|
+
request.apiToken = {
|
|
53
|
+
id: token.id,
|
|
54
|
+
name: token.name,
|
|
55
|
+
scope: token.scope,
|
|
56
|
+
workspaceIds: token.workspaceIds,
|
|
57
|
+
createdBy: token.createdBy ?? null
|
|
58
|
+
};
|
|
59
|
+
const required = this.reflector.getAllAndOverride(identity_server_1.PERMISSIONS_KEY, [context.getHandler(), context.getClass()]);
|
|
60
|
+
if (required && required.length > 0) {
|
|
61
|
+
// A token acts on its own behalf, not a user's — see `tokenActor`
|
|
62
|
+
// for why the minting user's role grants are never consulted.
|
|
63
|
+
const allowed = this.accessPolicy.canAll((0, identity_server_1.tokenActor)(token), required.map((key) => identity_server_1.Permission.create(key)));
|
|
64
|
+
if (!allowed) {
|
|
65
|
+
throw new common_1.ForbiddenException('This token’s scope does not allow that operation.');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
exports.ApiTokenGuard = ApiTokenGuard;
|
|
72
|
+
exports.ApiTokenGuard = ApiTokenGuard = tslib_1.__decorate([
|
|
73
|
+
(0, common_1.Injectable)(),
|
|
74
|
+
tslib_1.__metadata("design:paramtypes", [core_1.Reflector,
|
|
75
|
+
identity_server_1.ApiTokenService,
|
|
76
|
+
identity_server_1.AccessPolicy])
|
|
77
|
+
], ApiTokenGuard);
|
|
78
|
+
/**
|
|
79
|
+
* The raw token out of an `Authorization` header, or `undefined` when the
|
|
80
|
+
* header is absent, uses another scheme, or carries no value.
|
|
81
|
+
*/
|
|
82
|
+
function bearerFrom(header) {
|
|
83
|
+
if (!header) {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
const [scheme, ...rest] = header.trim().split(/\s+/);
|
|
87
|
+
if (scheme.toLowerCase() !== BEARER) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
const value = rest.join(' ');
|
|
91
|
+
return value.length > 0 ? value : undefined;
|
|
92
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from '@nestjs/common';
|
|
2
|
+
import { AccessPolicy } from '@orthacms/identity-server';
|
|
3
|
+
/**
|
|
4
|
+
* Gates `?status=draft|any` on **write** scope.
|
|
5
|
+
*
|
|
6
|
+
* Every public read defaults to published-only, which is the API's headline
|
|
7
|
+
* rule. A write-scoped token needs to widen it — otherwise creating a draft
|
|
8
|
+
* returns a record that is then invisible forever, and the creator cannot poll
|
|
9
|
+
* its own work. Widening is safe for exactly that caller and no other: a token
|
|
10
|
+
* that may read drafts is one that could have published them anyway.
|
|
11
|
+
*
|
|
12
|
+
* A **guard** rather than a check inside the query service, so the rule has one
|
|
13
|
+
* home and applies to every route the moment it is added to the controller —
|
|
14
|
+
* including ones that reach the drafts indirectly (a translations preview, a
|
|
15
|
+
* relation expansion) and would otherwise each need to remember.
|
|
16
|
+
*
|
|
17
|
+
* `content:update` is the probe rather than `content:read`, because read is
|
|
18
|
+
* exactly what both scopes hold; update is what separates them.
|
|
19
|
+
*/
|
|
20
|
+
export declare class DraftVisibilityGuard implements CanActivate {
|
|
21
|
+
private readonly policy;
|
|
22
|
+
constructor(policy: AccessPolicy);
|
|
23
|
+
canActivate(context: ExecutionContext): boolean;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=draft-visibility.guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft-visibility.guard.d.ts","sourceRoot":"","sources":["../../../../../src/lib/public-api/http/guards/draft-visibility.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,WAAW,EACX,gBAAgB,EAGnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACH,YAAY,EAIf,MAAM,2BAA2B,CAAC;AAOnC;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,oBAAqB,YAAW,WAAW;IACxC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,YAAY;IAEjD,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;CA4BlD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DraftVisibilityGuard = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const common_1 = require("@nestjs/common");
|
|
6
|
+
const identity_server_1 = require("@orthacms/identity-server");
|
|
7
|
+
const public_list_entries_query_dto_1 = require("../dto/public-list-entries-query.dto");
|
|
8
|
+
/** The default — and the only visibility a read-only token may ask for. */
|
|
9
|
+
const PUBLISHED = 'published';
|
|
10
|
+
/**
|
|
11
|
+
* Gates `?status=draft|any` on **write** scope.
|
|
12
|
+
*
|
|
13
|
+
* Every public read defaults to published-only, which is the API's headline
|
|
14
|
+
* rule. A write-scoped token needs to widen it — otherwise creating a draft
|
|
15
|
+
* returns a record that is then invisible forever, and the creator cannot poll
|
|
16
|
+
* its own work. Widening is safe for exactly that caller and no other: a token
|
|
17
|
+
* that may read drafts is one that could have published them anyway.
|
|
18
|
+
*
|
|
19
|
+
* A **guard** rather than a check inside the query service, so the rule has one
|
|
20
|
+
* home and applies to every route the moment it is added to the controller —
|
|
21
|
+
* including ones that reach the drafts indirectly (a translations preview, a
|
|
22
|
+
* relation expansion) and would otherwise each need to remember.
|
|
23
|
+
*
|
|
24
|
+
* `content:update` is the probe rather than `content:read`, because read is
|
|
25
|
+
* exactly what both scopes hold; update is what separates them.
|
|
26
|
+
*/
|
|
27
|
+
let DraftVisibilityGuard = class DraftVisibilityGuard {
|
|
28
|
+
policy;
|
|
29
|
+
constructor(policy) {
|
|
30
|
+
this.policy = policy;
|
|
31
|
+
}
|
|
32
|
+
canActivate(context) {
|
|
33
|
+
const request = context.switchToHttp().getRequest();
|
|
34
|
+
const requested = request.query?.['status'];
|
|
35
|
+
// Absent, or the default: nothing to authorize. An unrecognised value
|
|
36
|
+
// is left alone deliberately — the DTO's `@IsIn` turns it into a 400,
|
|
37
|
+
// and a guard that 403'd first would report the wrong problem.
|
|
38
|
+
if (typeof requested !== 'string' ||
|
|
39
|
+
requested === PUBLISHED ||
|
|
40
|
+
!public_list_entries_query_dto_1.ENTRY_VISIBILITY.includes(requested)) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
const token = request.apiToken;
|
|
44
|
+
const allowed = !!token &&
|
|
45
|
+
this.policy.can((0, identity_server_1.tokenActor)(token), identity_server_1.Permission.create(identity_server_1.PERMISSIONS.CONTENT_UPDATE));
|
|
46
|
+
if (!allowed) {
|
|
47
|
+
throw new common_1.ForbiddenException(`status=${requested} requires a token with write scope.`);
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
exports.DraftVisibilityGuard = DraftVisibilityGuard;
|
|
53
|
+
exports.DraftVisibilityGuard = DraftVisibilityGuard = tslib_1.__decorate([
|
|
54
|
+
(0, common_1.Injectable)(),
|
|
55
|
+
tslib_1.__metadata("design:paramtypes", [identity_server_1.AccessPolicy])
|
|
56
|
+
], DraftVisibilityGuard);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { BULK_SAVE_OP, type BulkSaveOp } from '../types/public-bulk';
|
|
2
|
+
import type { EntryLocator } from './public-entries.query';
|
|
3
|
+
/**
|
|
4
|
+
* What one bulk-save item was addressed as — a **discriminated union**, so a
|
|
5
|
+
* caller that has checked `op` gets the locator without a fallback for a case
|
|
6
|
+
* the resolver never produces.
|
|
7
|
+
*/
|
|
8
|
+
export type ResolvedBulkSaveOp = {
|
|
9
|
+
op: typeof BULK_SAVE_OP.Create;
|
|
10
|
+
} | {
|
|
11
|
+
op: typeof BULK_SAVE_OP.Update;
|
|
12
|
+
/** Which row the update targets. */
|
|
13
|
+
locator: EntryLocator;
|
|
14
|
+
/**
|
|
15
|
+
* The addressing locale of a group-addressed update — the query
|
|
16
|
+
* string's `?locale=` on the single-entry route.
|
|
17
|
+
*
|
|
18
|
+
* Only ever set for an update, and deliberately so: on a **create**
|
|
19
|
+
* the item's `locale` stamps the new row, and passing it as an
|
|
20
|
+
* addressing locale is the exact confusion that let a group-addressed
|
|
21
|
+
* German update rewrite the English row (see
|
|
22
|
+
* `PublicEntryWritesService.update`).
|
|
23
|
+
*/
|
|
24
|
+
locale?: string;
|
|
25
|
+
};
|
|
26
|
+
/** The addressing fields a bulk-save item may carry. */
|
|
27
|
+
interface BulkSaveItemAddress {
|
|
28
|
+
id?: string;
|
|
29
|
+
localeGroupId?: string;
|
|
30
|
+
locale?: string;
|
|
31
|
+
op?: BulkSaveOp;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Decide what one bulk-save item does, from how it is addressed.
|
|
35
|
+
*
|
|
36
|
+
* A single-entry write says this in its **URL** — `POST /:typeName` creates,
|
|
37
|
+
* `PATCH /:typeName/:id` updates, `PATCH /:typeName/group/:gid?locale=` updates
|
|
38
|
+
* a translation. A batch has one URL for every item, so the addressing moves
|
|
39
|
+
* into the item and this function is the one place that reads it. The rules:
|
|
40
|
+
*
|
|
41
|
+
* - `id` → **update** that row. An entry id already names one row, including
|
|
42
|
+
* its locale, so no addressing locale is involved.
|
|
43
|
+
* - neither `id` nor `localeGroupId` → **create**.
|
|
44
|
+
* - `localeGroupId` alone → genuinely ambiguous, so `op` is **required**:
|
|
45
|
+
* `create` adds that record's row in `locale` (joining the group), `update`
|
|
46
|
+
* changes the row the group already has there.
|
|
47
|
+
*
|
|
48
|
+
* `op` may always be stated explicitly, and disagreeing with the addressing is
|
|
49
|
+
* an error rather than a silent preference — `{ op: 'create', id }` is a caller
|
|
50
|
+
* who believes one thing while the request says another, and picking a winner
|
|
51
|
+
* would make whichever they did not mean happen quietly.
|
|
52
|
+
*/
|
|
53
|
+
export declare function resolveBulkSaveOp(item: BulkSaveItemAddress): ResolvedBulkSaveOp;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=bulk-save-op.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bulk-save-op.d.ts","sourceRoot":"","sources":["../../../../src/lib/public-api/infrastructure/bulk-save-op.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GACxB;IAAE,EAAE,EAAE,OAAO,YAAY,CAAC,MAAM,CAAA;CAAE,GAClC;IACI,EAAE,EAAE,OAAO,YAAY,CAAC,MAAM,CAAC;IAC/B,oCAAoC;IACpC,OAAO,EAAE,YAAY,CAAC;IACtB;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAER,wDAAwD;AACxD,UAAU,mBAAmB;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,EAAE,CAAC,EAAE,UAAU,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAC7B,IAAI,EAAE,mBAAmB,GAC1B,kBAAkB,CA2CpB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveBulkSaveOp = resolveBulkSaveOp;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const public_bulk_1 = require("../types/public-bulk");
|
|
6
|
+
/**
|
|
7
|
+
* Decide what one bulk-save item does, from how it is addressed.
|
|
8
|
+
*
|
|
9
|
+
* A single-entry write says this in its **URL** — `POST /:typeName` creates,
|
|
10
|
+
* `PATCH /:typeName/:id` updates, `PATCH /:typeName/group/:gid?locale=` updates
|
|
11
|
+
* a translation. A batch has one URL for every item, so the addressing moves
|
|
12
|
+
* into the item and this function is the one place that reads it. The rules:
|
|
13
|
+
*
|
|
14
|
+
* - `id` → **update** that row. An entry id already names one row, including
|
|
15
|
+
* its locale, so no addressing locale is involved.
|
|
16
|
+
* - neither `id` nor `localeGroupId` → **create**.
|
|
17
|
+
* - `localeGroupId` alone → genuinely ambiguous, so `op` is **required**:
|
|
18
|
+
* `create` adds that record's row in `locale` (joining the group), `update`
|
|
19
|
+
* changes the row the group already has there.
|
|
20
|
+
*
|
|
21
|
+
* `op` may always be stated explicitly, and disagreeing with the addressing is
|
|
22
|
+
* an error rather than a silent preference — `{ op: 'create', id }` is a caller
|
|
23
|
+
* who believes one thing while the request says another, and picking a winner
|
|
24
|
+
* would make whichever they did not mean happen quietly.
|
|
25
|
+
*/
|
|
26
|
+
function resolveBulkSaveOp(item) {
|
|
27
|
+
const id = nonEmpty(item.id);
|
|
28
|
+
const localeGroupId = nonEmpty(item.localeGroupId);
|
|
29
|
+
if (id && localeGroupId) {
|
|
30
|
+
throw new common_1.BadRequestException('Pass either `id` or `localeGroupId`, not both — they are two ways of naming the same row.');
|
|
31
|
+
}
|
|
32
|
+
if (id) {
|
|
33
|
+
if (item.op === public_bulk_1.BULK_SAVE_OP.Create) {
|
|
34
|
+
throw new common_1.BadRequestException('`op: "create"` cannot carry an `id` — an id names an entry that already exists. Drop the id to create, or drop `op` to update it.');
|
|
35
|
+
}
|
|
36
|
+
return { op: public_bulk_1.BULK_SAVE_OP.Update, locator: { id } };
|
|
37
|
+
}
|
|
38
|
+
if (!localeGroupId) {
|
|
39
|
+
if (item.op === public_bulk_1.BULK_SAVE_OP.Update) {
|
|
40
|
+
throw new common_1.BadRequestException('`op: "update"` needs an `id`, or a `localeGroupId` with the `locale` to change.');
|
|
41
|
+
}
|
|
42
|
+
return { op: public_bulk_1.BULK_SAVE_OP.Create };
|
|
43
|
+
}
|
|
44
|
+
// A group id and nothing else. Both readings are things a caller really
|
|
45
|
+
// wants, and neither is the obvious default, so ask rather than guess.
|
|
46
|
+
if (!item.op) {
|
|
47
|
+
throw new common_1.BadRequestException('This item names a `localeGroupId` but no `id`, so it could either create that record’s row in `locale` or update the row it already has there. Say which with `op: "create"` or `op: "update"`.');
|
|
48
|
+
}
|
|
49
|
+
if (item.op === public_bulk_1.BULK_SAVE_OP.Create) {
|
|
50
|
+
return { op: public_bulk_1.BULK_SAVE_OP.Create };
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
op: public_bulk_1.BULK_SAVE_OP.Update,
|
|
54
|
+
locator: { localeGroupId },
|
|
55
|
+
...(nonEmpty(item.locale) ? { locale: item.locale } : {})
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/** A present, non-empty string, or `undefined`. */
|
|
59
|
+
function nonEmpty(value) {
|
|
60
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
61
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AnyContentType } from '../../types/content-type';
|
|
2
|
+
/**
|
|
3
|
+
* Parse a `?fields=` selection into the set of value fields to return, or
|
|
4
|
+
* `undefined` for "everything" (the parameter absent, or present but empty).
|
|
5
|
+
*
|
|
6
|
+
* Selection covers the **`values` bag only** — the envelope (`id`, timestamps,
|
|
7
|
+
* `publishedAt`, `locale`, `localeGroupId`) is always returned. `id` in
|
|
8
|
+
* particular is what a consumer needs to fetch the entry again, so letting a
|
|
9
|
+
* selection drop it would be a foot-gun for no payload saving; the envelope is
|
|
10
|
+
* a handful of small columns either way, while the weight a caller actually
|
|
11
|
+
* wants to avoid is in the fields (a richtext body).
|
|
12
|
+
*
|
|
13
|
+
* An unrecognised name is a **400**, not a silent drop. A sparse fieldset is an
|
|
14
|
+
* explicit request, so a typo should say so rather than quietly returning an
|
|
15
|
+
* entry missing the field the caller asked for. Reference fields (relation and
|
|
16
|
+
* media) get their own message, because "not selectable *yet*" is a different
|
|
17
|
+
* fact from "no such field" and points at the API's current limit rather than
|
|
18
|
+
* at the caller's spelling.
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseFieldSelection(type: AnyContentType, raw: string | undefined): ReadonlySet<string> | undefined;
|
|
21
|
+
//# sourceMappingURL=field-selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-selection.d.ts","sourceRoot":"","sources":["../../../../src/lib/public-api/infrastructure/field-selection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAU/D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAC/B,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,MAAM,GAAG,SAAS,GACxB,WAAW,CAAC,MAAM,CAAC,GAAG,SAAS,CAmDjC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseFieldSelection = parseFieldSelection;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
const public_entry_row_1 = require("./public-entry-row");
|
|
6
|
+
/**
|
|
7
|
+
* Upper bound on how many names a `?fields=` list may carry. Generous — no real
|
|
8
|
+
* content type has this many — but it bounds the parse and the projection a
|
|
9
|
+
* single request can provoke.
|
|
10
|
+
*/
|
|
11
|
+
const MAX_SELECTED_FIELDS = 100;
|
|
12
|
+
/**
|
|
13
|
+
* Parse a `?fields=` selection into the set of value fields to return, or
|
|
14
|
+
* `undefined` for "everything" (the parameter absent, or present but empty).
|
|
15
|
+
*
|
|
16
|
+
* Selection covers the **`values` bag only** — the envelope (`id`, timestamps,
|
|
17
|
+
* `publishedAt`, `locale`, `localeGroupId`) is always returned. `id` in
|
|
18
|
+
* particular is what a consumer needs to fetch the entry again, so letting a
|
|
19
|
+
* selection drop it would be a foot-gun for no payload saving; the envelope is
|
|
20
|
+
* a handful of small columns either way, while the weight a caller actually
|
|
21
|
+
* wants to avoid is in the fields (a richtext body).
|
|
22
|
+
*
|
|
23
|
+
* An unrecognised name is a **400**, not a silent drop. A sparse fieldset is an
|
|
24
|
+
* explicit request, so a typo should say so rather than quietly returning an
|
|
25
|
+
* entry missing the field the caller asked for. Reference fields (relation and
|
|
26
|
+
* media) get their own message, because "not selectable *yet*" is a different
|
|
27
|
+
* fact from "no such field" and points at the API's current limit rather than
|
|
28
|
+
* at the caller's spelling.
|
|
29
|
+
*/
|
|
30
|
+
function parseFieldSelection(type, raw) {
|
|
31
|
+
if (raw === undefined) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
const names = [
|
|
35
|
+
...new Set(raw
|
|
36
|
+
.split(',')
|
|
37
|
+
.map((name) => name.trim())
|
|
38
|
+
.filter(Boolean))
|
|
39
|
+
];
|
|
40
|
+
if (names.length === 0) {
|
|
41
|
+
// `?fields=` with nothing in it reads as "no preference", not "no
|
|
42
|
+
// fields" — an empty `values` bag is never what a caller meant.
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
if (names.length > MAX_SELECTED_FIELDS) {
|
|
46
|
+
throw new common_1.BadRequestException(`fields: at most ${MAX_SELECTED_FIELDS} names may be selected.`);
|
|
47
|
+
}
|
|
48
|
+
for (const name of names) {
|
|
49
|
+
// `Object.hasOwn`, not `type.fields[name]`: the field map is the host's
|
|
50
|
+
// plain object literal, passed through untouched, so a bare lookup also
|
|
51
|
+
// resolves everything it INHERITS. `?fields=constructor` read back
|
|
52
|
+
// `Object` — a function, so `!spec` was false and the "unknown field"
|
|
53
|
+
// 400 never fired — and `isPureValueField` then asked for
|
|
54
|
+
// `Object.type`, `undefined`, which is not a reference type, so the
|
|
55
|
+
// second 400 never fired either. `constructor` landed in the selected
|
|
56
|
+
// set and reached the projection builder, which put a class function
|
|
57
|
+
// into the `.select()` list instead of a column: a 500 out of drizzle
|
|
58
|
+
// on a public, token-authenticated endpoint. `toString`, `valueOf`,
|
|
59
|
+
// `hasOwnProperty`, `isPrototypeOf`, `propertyIsEnumerable` and
|
|
60
|
+
// `toLocaleString` all worked the same way.
|
|
61
|
+
const spec = Object.hasOwn(type.fields, name)
|
|
62
|
+
? type.fields[name]
|
|
63
|
+
: undefined;
|
|
64
|
+
if (!spec) {
|
|
65
|
+
throw new common_1.BadRequestException(`fields: unknown field "${name}" on "${type.name}".`);
|
|
66
|
+
}
|
|
67
|
+
if (!(0, public_entry_row_1.isPureValueField)(spec)) {
|
|
68
|
+
throw new common_1.BadRequestException(`fields: "${name}" is a ${spec.type} field and cannot be selected — this API does not return relation or media values yet.`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return new Set(names);
|
|
72
|
+
}
|