@growth-labs/cms 0.5.29 → 0.5.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/engine/index.d.ts +5 -0
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +5 -0
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/publication-continuity.d.ts +77 -0
- package/dist/engine/publication-continuity.d.ts.map +1 -0
- package/dist/engine/publication-continuity.js +94 -0
- package/dist/engine/publication-continuity.js.map +1 -0
- package/dist/engine/publication-receipt/canonical-json.d.ts +34 -0
- package/dist/engine/publication-receipt/canonical-json.d.ts.map +1 -0
- package/dist/engine/publication-receipt/canonical-json.js +100 -0
- package/dist/engine/publication-receipt/canonical-json.js.map +1 -0
- package/dist/engine/publication-receipt/receipt.d.ts +316 -0
- package/dist/engine/publication-receipt/receipt.d.ts.map +1 -0
- package/dist/engine/publication-receipt/receipt.js +131 -0
- package/dist/engine/publication-receipt/receipt.js.map +1 -0
- package/dist/engine/publication-receipt/signature.d.ts +36 -0
- package/dist/engine/publication-receipt/signature.d.ts.map +1 -0
- package/dist/engine/publication-receipt/signature.js +79 -0
- package/dist/engine/publication-receipt/signature.js.map +1 -0
- package/dist/engine/publication.d.ts.map +1 -1
- package/dist/engine/publication.js +2 -0
- package/dist/engine/publication.js.map +1 -1
- package/dist/engine/publisher.d.ts.map +1 -1
- package/dist/engine/publisher.js +2 -0
- package/dist/engine/publisher.js.map +1 -1
- package/dist/engine/source-sections.d.ts +20 -0
- package/dist/engine/source-sections.d.ts.map +1 -0
- package/dist/engine/source-sections.js +130 -0
- package/dist/engine/source-sections.js.map +1 -0
- package/dist/engine/validator/checks/source-section-diagnostics.d.ts +7 -0
- package/dist/engine/validator/checks/source-section-diagnostics.d.ts.map +1 -0
- package/dist/engine/validator/checks/source-section-diagnostics.js +120 -0
- package/dist/engine/validator/checks/source-section-diagnostics.js.map +1 -0
- package/dist/engine/validator/index.d.ts +10 -0
- package/dist/engine/validator/index.d.ts.map +1 -1
- package/dist/engine/validator/index.js +4 -0
- package/dist/engine/validator/index.js.map +1 -1
- package/dist/engine/validator/types.d.ts +1 -1
- package/dist/engine/validator/types.d.ts.map +1 -1
- package/dist/engine/validator/types.js +10 -0
- package/dist/engine/validator/types.js.map +1 -1
- package/dist/providers/types.d.ts +1 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/routes/content.d.ts.map +1 -1
- package/dist/routes/content.js +22 -2
- package/dist/routes/content.js.map +1 -1
- package/dist/routes/surveys.d.ts.map +1 -1
- package/dist/routes/surveys.js +13 -1
- package/dist/routes/surveys.js.map +1 -1
- package/dist/schema/insights-ingest.d.ts +28 -28
- package/dist/surveys/access.d.ts +2 -0
- package/dist/surveys/access.d.ts.map +1 -1
- package/dist/surveys/access.js +7 -0
- package/dist/surveys/access.js.map +1 -1
- package/dist/surveys/errors.d.ts +8 -0
- package/dist/surveys/errors.d.ts.map +1 -1
- package/dist/surveys/errors.js +12 -0
- package/dist/surveys/errors.js.map +1 -1
- package/dist/surveys/schema.d.ts +75 -0
- package/dist/surveys/schema.d.ts.map +1 -1
- package/dist/surveys/schema.js +45 -0
- package/dist/surveys/schema.js.map +1 -1
- package/dist/ui/editor/ContentForm.d.ts.map +1 -1
- package/dist/ui/editor/ContentForm.js +52 -1
- package/dist/ui/editor/ContentForm.js.map +1 -1
- package/dist/ui/editor/body-warnings.d.ts +27 -0
- package/dist/ui/editor/body-warnings.d.ts.map +1 -0
- package/dist/ui/editor/body-warnings.js +58 -0
- package/dist/ui/editor/body-warnings.js.map +1 -0
- package/dist/ui/screens/SurveyResponsesScreen.d.ts +7 -1
- package/dist/ui/screens/SurveyResponsesScreen.d.ts.map +1 -1
- package/dist/ui/screens/SurveyResponsesScreen.js +141 -32
- package/dist/ui/screens/SurveyResponsesScreen.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/index.ts +33 -0
- package/src/engine/publication-continuity.ts +140 -0
- package/src/engine/publication-receipt/canonical-json.ts +123 -0
- package/src/engine/publication-receipt/receipt.ts +160 -0
- package/src/engine/publication-receipt/signature.ts +112 -0
- package/src/engine/publication.ts +2 -0
- package/src/engine/publisher.ts +2 -0
- package/src/engine/source-sections.ts +153 -0
- package/src/engine/validator/checks/source-section-diagnostics.ts +187 -0
- package/src/engine/validator/index.ts +12 -0
- package/src/engine/validator/types.ts +19 -0
- package/src/providers/types.ts +1 -1
- package/src/routes/content.ts +23 -2
- package/src/routes/surveys.ts +12 -1
- package/src/surveys/access.ts +9 -0
- package/src/surveys/errors.ts +12 -0
- package/src/surveys/schema.ts +47 -0
- package/src/ui/editor/ContentForm.tsx +93 -0
- package/src/ui/editor/body-warnings.ts +78 -0
- package/src/ui/screens/SurveyResponsesScreen.tsx +369 -121
package/dist/engine/index.d.ts
CHANGED
|
@@ -15,6 +15,10 @@ export { listMembers, loadMembership, type MemberListEntry, type MembershipRecor
|
|
|
15
15
|
export { canChangeMemberRole, canRemoveMember, type MemberActionDecision, type MembershipSummary, ownerCount, } from './membership-rules.js';
|
|
16
16
|
export { buildOgCardSpec, type OgCardSpec, type OgCardSpecOpts, type OgImageRenderer, } from './og-render.js';
|
|
17
17
|
export { ContentArchiveImportLimitError, type ContentArchiveInput, type ContentArchiveItem, DEFAULT_PENDING_PUBLICATION_ATTEMPT_LIMIT, DEFAULT_PUBLICATION_SURFACE_HOOK_TIMEOUT_MS, type ImportContentArchiveOptions, type ImportContentArchiveResult, type ImportedArchiveItem, importContentArchive, type ListPendingPublicationAttemptsOptions, listPendingPublicationAttempts, MAX_PENDING_PUBLICATION_ATTEMPT_LIMIT, MAX_PUBLICATION_SURFACE_HOOK_TIMEOUT_MS, type PublicationAttempt, type PublicationAttemptState, PublicationInputError, PublicationNotFoundError, type PublicationOperation, PublicationPointerMoveError, type PublicationReconciler, PublicationReconciliationError, type PublicationReconciliationInput, type PublicationSurfaceCommitStatus, type PublicationSurfacePhase, type PublicationSurfaceReceipt, PublicationSurfaceRequirementError, type PublicationSurfaceStatus, type PublishOneInput, type PublishOneReceipt, publishOne, type RetryPublicationSurfacesInput, type RetryPublicationSurfacesReceipt, type RollbackPublicationInput, type RollbackPublicationReceipt, retryPublicationSurfaces, rollbackPublication, type SkippedArchiveItem, } from './publication.js';
|
|
18
|
+
export { acceptsProbeStatus, type ContinuityArchiveItem, type ContinuityDrift, type ContinuityDriftField, type ContinuityPublishedRow, isRetiredItem, payloadDrift, } from './publication-continuity.js';
|
|
19
|
+
export { CanonicalJsonError, canonicalJson, canonicalJsonBytes, canonicalJsonSha256, type JsonValue, } from './publication-receipt/canonical-json.js';
|
|
20
|
+
export { canonicalizeReceiptBody, PublicationReceiptError, SITE_PUBLICATION_RECEIPT_AUDIENCE, SITE_PUBLICATION_RECEIPT_SCHEMA, type SitePublicationReceiptBody, sitePublicationReceiptBodySchema, } from './publication-receipt/receipt.js';
|
|
21
|
+
export { type SignedPublicationReceipt, signPublicationReceipt, verifyPublicationReceipt, } from './publication-receipt/signature.js';
|
|
18
22
|
export { evaluateArticleBody, type PublishGuardOptions, type PublishGuardOutcome, publishGuardResponseOrNull, } from './publish-guard.js';
|
|
19
23
|
export { getPublishedContentById, getPublishedContentBySlug, type ListPublishedContentOptions, listPublishedContent, MAX_PUBLISHED_CONTENT_PAGE_BYTES, MAX_PUBLISHED_CONTENT_PAGE_SIZE, MAX_PUBLISHED_CONTENT_PAYLOAD_BYTES, type PublishedContent, type PublishedContentCursor, type PublishedContentPage, PublishedContentReadError, type PublishedContentReadErrorCode, } from './published-content.js';
|
|
20
24
|
export { type ArticleInput, assertContentBodyValidForPublish, type BaseContentInput, type ContentItemRecord, type CreateContentInput, claimScheduledForPublish, countWords, createContent, createRevision, duplicateContentItem, ensureUniqueSlug, estimateReadTime, evaluateContentBodyForPublish, getContentItem, getContentRelations, getContentSnapshot, getContentTagPairs, MAX_ITEM_TAG_COUNT, MAX_ITEM_TAGS_TOTAL_BYTES, MAX_TAG_LABEL_BYTES, type NewsletterInput, type PodcastInput, PublishContentValidationError, publishContent, scheduleContent, setContentRelations, setContentTags, TagInputError, type UpdateContentInput, unpublishContent, updateContentItem, VerifiedMediaDurationConflictError, type VideoInput, } from './publisher.js';
|
|
@@ -27,6 +31,7 @@ export { type SeoCheck, type SeoScoreInput, type SeoScoreResult, scoreDraft, } f
|
|
|
27
31
|
export { buildContentPath, ensureTrailingSlash, normalizeSlug, slugify, stripTrailingSlash, } from './slug.js';
|
|
28
32
|
export { applySlugRenameRedirects, clearSlugRedirect, recordSlugRedirect, } from './slug-redirects.js';
|
|
29
33
|
export { listActiveIds, purgeContent, restoreContent, softDeleteContent, } from './soft-delete.js';
|
|
34
|
+
export { normalizeSourceSections, type SourceSectionNormalization, } from './source-sections.js';
|
|
30
35
|
export { createTag, deleteTag, listTags, renameTag, searchTags, type TagSummary, } from './tags.js';
|
|
31
36
|
export { type TaxonomyTag, utf8ByteLength, validateDeclaredTagList, validateRevisionTaxonomy, validateSingleDeclaredTag, validateStoredTaxonomyRows, } from './taxonomy.js';
|
|
32
37
|
export { type UrlGuardResult, validateWebhookUrl } from './url-guard.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEnE,OAAO,EACN,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,kBAAkB,EAClB,wBAAwB,GACxB,MAAM,aAAa,CAAA;AACpB,OAAO,EACN,6BAA6B,EAC7B,KAAK,2BAA2B,GAChC,MAAM,2BAA2B,CAAA;AAElC,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,SAAS,EACT,KAAK,oBAAoB,EACzB,kBAAkB,EAClB,eAAe,EACf,KAAK,0BAA0B,EAC/B,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,eAAe,EACf,KAAK,oBAAoB,EACzB,eAAe,GACf,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,YAAY,EACZ,aAAa,EACb,iBAAiB,GACjB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACN,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,YAAY,EACZ,SAAS,EACT,KAAK,kBAAkB,EACvB,eAAe,GACf,MAAM,eAAe,CAAA;AAEtB,OAAO,EACN,KAAK,eAAe,EACpB,oBAAoB,EACpB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,0BAA0B,EAC1B,oBAAoB,EACpB,wBAAwB,GACxB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,eAAe,GACf,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,mBAAmB,EAAE,KAAK,sBAAsB,EAAE,MAAM,WAAW,CAAA;AAE5E,YAAY,EAAE,UAAU,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAE3F,OAAO,EACN,oBAAoB,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,iBAAiB,EACjB,KAAK,eAAe,EACpB,UAAU,GACV,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EACN,cAAc,EACd,KAAK,gBAAgB,EACrB,UAAU,EACV,aAAa,EACb,gBAAgB,GAChB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EACN,KAAK,iBAAiB,EACtB,YAAY,EACZ,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,YAAY,EACZ,eAAe,EACf,KAAK,YAAY,EACjB,iBAAiB,GACjB,MAAM,cAAc,CAAA;AAErB,OAAO,EACN,WAAW,EACX,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,YAAY,EACZ,OAAO,EACP,KAAK,uBAAuB,EAC5B,kBAAkB,GAClB,MAAM,cAAc,CAAA;AAErB,OAAO,EACN,mBAAmB,EACnB,eAAe,EACf,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,UAAU,GACV,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EACN,eAAe,EACf,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,KAAK,eAAe,GACpB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACN,8BAA8B,EAC9B,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,yCAAyC,EACzC,2CAA2C,EAC3C,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,oBAAoB,EACpB,KAAK,qCAAqC,EAC1C,8BAA8B,EAC9B,qCAAqC,EACrC,uCAAuC,EACvC,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,qBAAqB,EACrB,wBAAwB,EACxB,KAAK,oBAAoB,EACzB,2BAA2B,EAC3B,KAAK,qBAAqB,EAC1B,8BAA8B,EAC9B,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,EACnC,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,kCAAkC,EAClC,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,UAAU,EACV,KAAK,6BAA6B,EAClC,KAAK,+BAA+B,EACpC,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,wBAAwB,EACxB,mBAAmB,EACnB,KAAK,kBAAkB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,kBAAkB,EAClB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,aAAa,EACb,YAAY,GACZ,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACN,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,SAAS,GACd,MAAM,yCAAyC,CAAA;AAChD,OAAO,EACN,uBAAuB,EACvB,uBAAuB,EACvB,iCAAiC,EACjC,+BAA+B,EAC/B,KAAK,0BAA0B,EAC/B,gCAAgC,GAChC,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACN,KAAK,wBAAwB,EAC7B,sBAAsB,EACtB,wBAAwB,GACxB,MAAM,oCAAoC,CAAA;AAE3C,OAAO,EACN,mBAAmB,EACnB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,0BAA0B,GAC1B,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EACN,uBAAuB,EACvB,yBAAyB,EACzB,KAAK,2BAA2B,EAChC,oBAAoB,EACpB,gCAAgC,EAChC,+BAA+B,EAC/B,mCAAmC,EACnC,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,yBAAyB,EACzB,KAAK,6BAA6B,GAClC,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EACN,KAAK,YAAY,EACjB,gCAAgC,EAChC,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,wBAAwB,EACxB,UAAU,EACV,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,6BAA6B,EAC7B,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,mBAAmB,EACnB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,6BAA6B,EAC7B,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,KAAK,kBAAkB,EACvB,gBAAgB,EAChB,iBAAiB,EACjB,kCAAkC,EAClC,KAAK,UAAU,GACf,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAEnD,OAAO,EACN,KAAK,2BAA2B,EAChC,KAAK,eAAe,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,+BAA+B,EAC/B,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,2BAA2B,EAC3B,+BAA+B,EAC/B,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,wBAAwB,EACxB,4BAA4B,EAC5B,KAAK,qBAAqB,EAC1B,qBAAqB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,yBAAyB,EAC9B,KAAK,2BAA2B,EAChC,KAAK,oBAAoB,EACzB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,GACb,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACN,KAAK,sBAAsB,EAC3B,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,KAAK,eAAe,EACpB,eAAe,GACf,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACN,qBAAqB,EACrB,KAAK,eAAe,EACpB,QAAQ,EACR,YAAY,EACZ,gBAAgB,GAChB,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,KAAK,mBAAmB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE/E,OAAO,EACN,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,UAAU,GACV,MAAM,UAAU,CAAA;AAEjB,OAAO,EACN,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,OAAO,EACP,kBAAkB,GAClB,MAAM,WAAW,CAAA;AAElB,OAAO,EACN,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EACN,aAAa,EACb,YAAY,EACZ,cAAc,EACd,iBAAiB,GACjB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,uBAAuB,EACvB,KAAK,0BAA0B,GAC/B,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACN,SAAS,EACT,SAAS,EACT,QAAQ,EACR,SAAS,EACT,UAAU,EACV,KAAK,UAAU,GACf,MAAM,WAAW,CAAA;AAClB,OAAO,EACN,KAAK,WAAW,EAChB,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,GAC1B,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,KAAK,cAAc,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAExE,OAAO,EACN,KAAK,gBAAgB,EACrB,WAAW,EACX,sBAAsB,EACtB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,UAAU,GACV,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EACN,2BAA2B,EAC3B,eAAe,EACf,oBAAoB,GACpB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EACN,KAAK,yBAAyB,EAC9B,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,aAAa,EACb,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,aAAa,GAClB,MAAM,eAAe,CAAA"}
|
package/dist/engine/index.js
CHANGED
|
@@ -33,6 +33,10 @@ export { canChangeMemberRole, canRemoveMember, ownerCount, } from './membership-
|
|
|
33
33
|
export { buildOgCardSpec, } from './og-render.js';
|
|
34
34
|
// Bounded one-item publication kernel.
|
|
35
35
|
export { ContentArchiveImportLimitError, DEFAULT_PENDING_PUBLICATION_ATTEMPT_LIMIT, DEFAULT_PUBLICATION_SURFACE_HOOK_TIMEOUT_MS, importContentArchive, listPendingPublicationAttempts, MAX_PENDING_PUBLICATION_ATTEMPT_LIMIT, MAX_PUBLICATION_SURFACE_HOOK_TIMEOUT_MS, PublicationInputError, PublicationNotFoundError, PublicationPointerMoveError, PublicationReconciliationError, PublicationSurfaceRequirementError, publishOne, retryPublicationSurfaces, rollbackPublication, } from './publication.js';
|
|
36
|
+
export { acceptsProbeStatus, isRetiredItem, payloadDrift, } from './publication-continuity.js';
|
|
37
|
+
export { CanonicalJsonError, canonicalJson, canonicalJsonBytes, canonicalJsonSha256, } from './publication-receipt/canonical-json.js';
|
|
38
|
+
export { canonicalizeReceiptBody, PublicationReceiptError, SITE_PUBLICATION_RECEIPT_AUDIENCE, SITE_PUBLICATION_RECEIPT_SCHEMA, sitePublicationReceiptBodySchema, } from './publication-receipt/receipt.js';
|
|
39
|
+
export { signPublicationReceipt, verifyPublicationReceipt, } from './publication-receipt/signature.js';
|
|
36
40
|
// Pre-publish body validation guard.
|
|
37
41
|
export { evaluateArticleBody, publishGuardResponseOrNull, } from './publish-guard.js';
|
|
38
42
|
// Bounded, pointer-selected public content read model.
|
|
@@ -56,6 +60,7 @@ export { buildContentPath, ensureTrailingSlash, normalizeSlug, slugify, stripTra
|
|
|
56
60
|
export { applySlugRenameRedirects, clearSlugRedirect, recordSlugRedirect, } from './slug-redirects.js';
|
|
57
61
|
// Soft-delete engine — softDeleteContent / restoreContent / purgeContent / listActiveIds.
|
|
58
62
|
export { listActiveIds, purgeContent, restoreContent, softDeleteContent, } from './soft-delete.js';
|
|
63
|
+
export { normalizeSourceSections, } from './source-sections.js';
|
|
59
64
|
// Tag CRUD engine — listTags / searchTags / renameTag / deleteTag.
|
|
60
65
|
export { createTag, deleteTag, listTags, renameTag, searchTags, } from './tags.js';
|
|
61
66
|
export { utf8ByteLength, validateDeclaredTagList, validateRevisionTaxonomy, validateSingleDeclaredTag, validateStoredTaxonomyRows, } from './taxonomy.js';
|
package/dist/engine/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/engine/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,0EAA0E;AAC1E,2EAA2E;AAC3E,uCAAuC;AAEvC,4EAA4E;AAC5E,OAAO,EAAsB,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACnE,oEAAoE;AACpE,OAAO,EACN,kBAAkB,EAGlB,kBAAkB,EAClB,wBAAwB,GACxB,MAAM,aAAa,CAAA;AACpB,OAAO,EACN,6BAA6B,GAE7B,MAAM,2BAA2B,CAAA;AAClC,+DAA+D;AAC/D,OAAO,EAGN,SAAS,EAET,kBAAkB,EAClB,eAAe,EAEf,qBAAqB,EAErB,eAAe,EAEf,eAAe,GACf,MAAM,iBAAiB,CAAA;AACxB,gDAAgD;AAChD,OAAO,EAGN,YAAY,EACZ,aAAa,EACb,iBAAiB,GACjB,MAAM,mBAAmB,CAAA;AAC1B,0DAA0D;AAC1D,OAAO,EAIN,YAAY,EACZ,cAAc,EACd,WAAW,EACX,YAAY,EACZ,SAAS,EAET,eAAe,GACf,MAAM,eAAe,CAAA;AACtB,0EAA0E;AAC1E,OAAO,EAEN,oBAAoB,EAGpB,0BAA0B,EAC1B,oBAAoB,EACpB,wBAAwB,GACxB,MAAM,uBAAuB,CAAA;AAC9B,qEAAqE;AACrE,OAAO,EAGN,gBAAgB,EAChB,eAAe,GACf,MAAM,mBAAmB,CAAA;AAC1B,2BAA2B;AAC3B,OAAO,EAAE,mBAAmB,EAA+B,MAAM,WAAW,CAAA;AAG5E,iEAAiE;AACjE,OAAO,EACN,oBAAoB,EAGpB,iBAAiB,EAEjB,UAAU,GACV,MAAM,uBAAuB,CAAA;AAC9B,8EAA8E;AAC9E,OAAO,EACN,cAAc,EAEd,UAAU,EACV,aAAa,EACb,gBAAgB,GAChB,MAAM,qBAAqB,CAAA;AAC5B,iDAAiD;AACjD,OAAO,EAEN,YAAY,EAGZ,YAAY,EACZ,eAAe,EAEf,iBAAiB,GACjB,MAAM,cAAc,CAAA;AACrB,0EAA0E;AAC1E,OAAO,EACN,WAAW,EACX,cAAc,EAGd,YAAY,EACZ,OAAO,EAEP,kBAAkB,GAClB,MAAM,cAAc,CAAA;AACrB,uEAAuE;AACvE,OAAO,EACN,mBAAmB,EACnB,eAAe,EAGf,UAAU,GACV,MAAM,uBAAuB,CAAA;AAC9B,oEAAoE;AACpE,OAAO,EACN,eAAe,GAIf,MAAM,gBAAgB,CAAA;AACvB,uCAAuC;AACvC,OAAO,EACN,8BAA8B,EAG9B,yCAAyC,EACzC,2CAA2C,EAI3C,oBAAoB,EAEpB,8BAA8B,EAC9B,qCAAqC,EACrC,uCAAuC,EAGvC,qBAAqB,EACrB,wBAAwB,EAExB,2BAA2B,EAE3B,8BAA8B,EAK9B,kCAAkC,EAIlC,UAAU,EAKV,wBAAwB,EACxB,mBAAmB,GAEnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,kBAAkB,EAKlB,aAAa,EACb,YAAY,GACZ,MAAM,6BAA6B,CAAA;AACpC,OAAO,EACN,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,mBAAmB,GAEnB,MAAM,yCAAyC,CAAA;AAChD,OAAO,EACN,uBAAuB,EACvB,uBAAuB,EACvB,iCAAiC,EACjC,+BAA+B,EAE/B,gCAAgC,GAChC,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAEN,sBAAsB,EACtB,wBAAwB,GACxB,MAAM,oCAAoC,CAAA;AAC3C,qCAAqC;AACrC,OAAO,EACN,mBAAmB,EAGnB,0BAA0B,GAC1B,MAAM,oBAAoB,CAAA;AAC3B,uDAAuD;AACvD,OAAO,EACN,uBAAuB,EACvB,yBAAyB,EAEzB,oBAAoB,EACpB,gCAAgC,EAChC,+BAA+B,EAC/B,mCAAmC,EAInC,yBAAyB,GAEzB,MAAM,wBAAwB,CAAA;AAC/B,oDAAoD;AACpD,OAAO,EAEN,gCAAgC,EAIhC,wBAAwB,EACxB,UAAU,EACV,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,6BAA6B,EAC7B,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,mBAAmB,EAGnB,6BAA6B,EAC7B,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,aAAa,EAEb,gBAAgB,EAChB,iBAAiB,EACjB,kCAAkC,GAElC,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,+EAA+E;AAC/E,OAAO,EAGN,oBAAoB,EACpB,kBAAkB,EAClB,+BAA+B,EAC/B,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,2BAA2B,EAC3B,+BAA+B,EAI/B,wBAAwB,EACxB,4BAA4B,EAE5B,qBAAqB,EAQrB,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAIlB,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,GACb,MAAM,mBAAmB,CAAA;AAC1B,6DAA6D;AAC7D,OAAO,EAEN,uBAAuB,EACvB,WAAW,EACX,aAAa,EAEb,eAAe,GACf,MAAM,gBAAgB,CAAA;AACvB,sEAAsE;AACtE,OAAO,EACN,qBAAqB,EAErB,QAAQ,EACR,YAAY,EACZ,gBAAgB,GAChB,MAAM,eAAe,CAAA;AACtB,yEAAyE;AACzE,OAAO,EAA4B,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC/E,gEAAgE;AAChE,OAAO,EAIN,UAAU,GACV,MAAM,UAAU,CAAA;AACjB,gBAAgB;AAChB,OAAO,EACN,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,OAAO,EACP,kBAAkB,GAClB,MAAM,WAAW,CAAA;AAClB,oCAAoC;AACpC,OAAO,EACN,wBAAwB,EACxB,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,qBAAqB,CAAA;AAC5B,0FAA0F;AAC1F,OAAO,EACN,aAAa,EACb,YAAY,EACZ,cAAc,EACd,iBAAiB,GACjB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACN,uBAAuB,GAEvB,MAAM,sBAAsB,CAAA;AAC7B,mEAAmE;AACnE,OAAO,EACN,SAAS,EACT,SAAS,EACT,QAAQ,EACR,SAAS,EACT,UAAU,GAEV,MAAM,WAAW,CAAA;AAClB,OAAO,EAEN,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,GAC1B,MAAM,eAAe,CAAA;AACtB,wFAAwF;AACxF,OAAO,EAAuB,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACxE,4EAA4E;AAC5E,OAAO,EAEN,WAAW,EACX,sBAAsB,EAOtB,mBAAmB,EACnB,UAAU,GACV,MAAM,sBAAsB,CAAA;AAC7B,mFAAmF;AACnF,OAAO,EACN,2BAA2B,EAC3B,eAAe,EACf,oBAAoB,GACpB,MAAM,qBAAqB,CAAA;AAC5B,oFAAoF;AACpF,OAAO,EAEN,oBAAoB,EAEpB,aAAa,EACb,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,cAAc,GAId,MAAM,eAAe,CAAA"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/** The archive-side fields a continuity run compares. */
|
|
2
|
+
export interface ContinuityArchiveItem {
|
|
3
|
+
title?: string | null;
|
|
4
|
+
description?: string | null;
|
|
5
|
+
featured?: boolean | null;
|
|
6
|
+
heroImageId?: string | null;
|
|
7
|
+
visibility?: string | null;
|
|
8
|
+
/** The archive's name for what the engine stores as `channel`. */
|
|
9
|
+
primaryCategory?: string | null;
|
|
10
|
+
bodyMarkdown?: string | null;
|
|
11
|
+
metadata?: {
|
|
12
|
+
originalStatus?: string | null;
|
|
13
|
+
} | null;
|
|
14
|
+
}
|
|
15
|
+
/** The joined `content_items` + published-revision row, as the engine stores it. */
|
|
16
|
+
export interface ContinuityPublishedRow {
|
|
17
|
+
rev_title?: string | null;
|
|
18
|
+
rev_description?: string | null;
|
|
19
|
+
rev_featured?: number | null;
|
|
20
|
+
rev_hero_image_id?: string | null;
|
|
21
|
+
rev_visibility?: string | null;
|
|
22
|
+
rev_channel?: string | null;
|
|
23
|
+
rev_body_markdown?: string | null;
|
|
24
|
+
}
|
|
25
|
+
export type ContinuityDriftField = 'title' | 'description' | 'featured' | 'heroImage' | 'visibility' | 'channel' | 'body';
|
|
26
|
+
export interface ContinuityDrift {
|
|
27
|
+
drifted: boolean;
|
|
28
|
+
fields: ContinuityDriftField[];
|
|
29
|
+
title: string;
|
|
30
|
+
description: string | null;
|
|
31
|
+
/** `content_items.featured` is INTEGER; the archive item carries a boolean. */
|
|
32
|
+
featured: 0 | 1;
|
|
33
|
+
heroImageId: string | null;
|
|
34
|
+
visibility: 'free' | 'premium';
|
|
35
|
+
channel: string | null;
|
|
36
|
+
body: string;
|
|
37
|
+
bodyDrifted: boolean;
|
|
38
|
+
}
|
|
39
|
+
/** An item the archive has taken down rather than published. */
|
|
40
|
+
export declare function isRetiredItem(item: ContinuityArchiveItem | null | undefined): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Compare the fields a reader actually sees against the published revision.
|
|
43
|
+
*
|
|
44
|
+
* The site renders from the published revision payload, so an edit to any field
|
|
45
|
+
* this does not examine is classified "already in sync", skipped, and never
|
|
46
|
+
* reaches a reader — while the run reports success. That has stranded real work
|
|
47
|
+
* twice: fourteen restored article bodies, and a `featured` flag flip, both
|
|
48
|
+
* merged, both reporting `failed=0`, neither ever visible.
|
|
49
|
+
*
|
|
50
|
+
* Comparison is exact rather than a length or prefix heuristic. The entire class
|
|
51
|
+
* of bug being prevented is a cheap test that silently misses a real edit: a
|
|
52
|
+
* false "stale" costs one idempotent republish, a false "in sync" loses the edit.
|
|
53
|
+
*
|
|
54
|
+
* NOT COMPARED: tags. The revision stores them canonicalized and sorted while
|
|
55
|
+
* the archive carries raw frontmatter strings, and the engine exports no
|
|
56
|
+
* canonicalizer to reuse. Detecting a field this cannot also REPAIR would be
|
|
57
|
+
* worse than not detecting it — tag writes go through the engine, so a tag-only
|
|
58
|
+
* drift would republish unchanged and stay stale on every run, forever.
|
|
59
|
+
*/
|
|
60
|
+
export declare function payloadDrift(item: ContinuityArchiveItem, row: ContinuityPublishedRow): ContinuityDrift;
|
|
61
|
+
/**
|
|
62
|
+
* Whether a live probe response means the publication succeeded.
|
|
63
|
+
*
|
|
64
|
+
* LIVE → 200 only.
|
|
65
|
+
* RETIRED → 301/308 (redirected to a surviving twin) or 404 (gone, with no
|
|
66
|
+
* honest target to redirect to).
|
|
67
|
+
*
|
|
68
|
+
* The invariant: **a retired article must never answer 200.** That is the
|
|
69
|
+
* stale-row symptom a teardown exists to remove, and it is the only status this
|
|
70
|
+
* rejects for a retirement. Demanding 200 for retirements instead would fail the
|
|
71
|
+
* run forever on exactly the articles the archive deliberately took down.
|
|
72
|
+
*
|
|
73
|
+
* 301 and 308 are both permanent; a server may answer GET with one and other
|
|
74
|
+
* methods with the other, so both are accepted.
|
|
75
|
+
*/
|
|
76
|
+
export declare function acceptsProbeStatus(status: number, retired: boolean): boolean;
|
|
77
|
+
//# sourceMappingURL=publication-continuity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publication-continuity.d.ts","sourceRoot":"","sources":["../../src/engine/publication-continuity.ts"],"names":[],"mappings":"AAUA,yDAAyD;AACzD,MAAM,WAAW,qBAAqB;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,kEAAkE;IAClE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,QAAQ,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAA;CACpD;AAED,oFAAoF;AACpF,MAAM,WAAW,sBAAsB;IACtC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAED,MAAM,MAAM,oBAAoB,GAC7B,OAAO,GACP,aAAa,GACb,UAAU,GACV,WAAW,GACX,YAAY,GACZ,SAAS,GACT,MAAM,CAAA;AAET,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,oBAAoB,EAAE,CAAA;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,+EAA+E;IAC/E,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAA;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,OAAO,CAAA;CACpB;AAED,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,IAAI,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAErF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAC3B,IAAI,EAAE,qBAAqB,EAC3B,GAAG,EAAE,sBAAsB,GACzB,eAAe,CAmCjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAG5E"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// Publication continuity decisions (#342).
|
|
2
|
+
//
|
|
3
|
+
// Extracted from the Warfronts publish bridge so every site shares one rule set
|
|
4
|
+
// instead of each re-deriving it. These are the decisions a continuity run makes
|
|
5
|
+
// before it touches the database: is this item retired, did the published
|
|
6
|
+
// revision drift from the archive, and does a live probe response mean success.
|
|
7
|
+
//
|
|
8
|
+
// All pure. The bridge's DB, network and filesystem work stays site-owned; only
|
|
9
|
+
// the judgement moves here.
|
|
10
|
+
/** An item the archive has taken down rather than published. */
|
|
11
|
+
export function isRetiredItem(item) {
|
|
12
|
+
return item?.metadata?.originalStatus === 'archived';
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Compare the fields a reader actually sees against the published revision.
|
|
16
|
+
*
|
|
17
|
+
* The site renders from the published revision payload, so an edit to any field
|
|
18
|
+
* this does not examine is classified "already in sync", skipped, and never
|
|
19
|
+
* reaches a reader — while the run reports success. That has stranded real work
|
|
20
|
+
* twice: fourteen restored article bodies, and a `featured` flag flip, both
|
|
21
|
+
* merged, both reporting `failed=0`, neither ever visible.
|
|
22
|
+
*
|
|
23
|
+
* Comparison is exact rather than a length or prefix heuristic. The entire class
|
|
24
|
+
* of bug being prevented is a cheap test that silently misses a real edit: a
|
|
25
|
+
* false "stale" costs one idempotent republish, a false "in sync" loses the edit.
|
|
26
|
+
*
|
|
27
|
+
* NOT COMPARED: tags. The revision stores them canonicalized and sorted while
|
|
28
|
+
* the archive carries raw frontmatter strings, and the engine exports no
|
|
29
|
+
* canonicalizer to reuse. Detecting a field this cannot also REPAIR would be
|
|
30
|
+
* worse than not detecting it — tag writes go through the engine, so a tag-only
|
|
31
|
+
* drift would republish unchanged and stay stale on every run, forever.
|
|
32
|
+
*/
|
|
33
|
+
export function payloadDrift(item, row) {
|
|
34
|
+
// The engine stores an absent body as a single space, so normalize the same
|
|
35
|
+
// way before comparing or the first resync of a body-less article would
|
|
36
|
+
// churn forever.
|
|
37
|
+
const body = item.bodyMarkdown ?? ' ';
|
|
38
|
+
const title = String(item.title ?? '');
|
|
39
|
+
const description = item.description ?? null;
|
|
40
|
+
const featured = item.featured ? 1 : 0;
|
|
41
|
+
const heroImageId = item.heroImageId ?? null;
|
|
42
|
+
const visibility = item.visibility === 'premium' ? 'premium' : 'free';
|
|
43
|
+
const channel = item.primaryCategory ?? null;
|
|
44
|
+
const fields = [];
|
|
45
|
+
if (row.rev_title !== title)
|
|
46
|
+
fields.push('title');
|
|
47
|
+
if ((row.rev_description ?? null) !== description)
|
|
48
|
+
fields.push('description');
|
|
49
|
+
if (Number(row.rev_featured ?? 0) !== featured)
|
|
50
|
+
fields.push('featured');
|
|
51
|
+
if ((row.rev_hero_image_id ?? null) !== heroImageId)
|
|
52
|
+
fields.push('heroImage');
|
|
53
|
+
if ((row.rev_visibility ?? 'free') !== visibility)
|
|
54
|
+
fields.push('visibility');
|
|
55
|
+
if ((row.rev_channel ?? null) !== channel)
|
|
56
|
+
fields.push('channel');
|
|
57
|
+
// A revision predating this check can lack the key entirely; treat an absent
|
|
58
|
+
// body as drift rather than silently matching.
|
|
59
|
+
if ((row.rev_body_markdown ?? null) !== body)
|
|
60
|
+
fields.push('body');
|
|
61
|
+
return {
|
|
62
|
+
drifted: fields.length > 0,
|
|
63
|
+
fields,
|
|
64
|
+
title,
|
|
65
|
+
description,
|
|
66
|
+
featured,
|
|
67
|
+
heroImageId,
|
|
68
|
+
visibility,
|
|
69
|
+
channel,
|
|
70
|
+
body,
|
|
71
|
+
bodyDrifted: fields.includes('body'),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Whether a live probe response means the publication succeeded.
|
|
76
|
+
*
|
|
77
|
+
* LIVE → 200 only.
|
|
78
|
+
* RETIRED → 301/308 (redirected to a surviving twin) or 404 (gone, with no
|
|
79
|
+
* honest target to redirect to).
|
|
80
|
+
*
|
|
81
|
+
* The invariant: **a retired article must never answer 200.** That is the
|
|
82
|
+
* stale-row symptom a teardown exists to remove, and it is the only status this
|
|
83
|
+
* rejects for a retirement. Demanding 200 for retirements instead would fail the
|
|
84
|
+
* run forever on exactly the articles the archive deliberately took down.
|
|
85
|
+
*
|
|
86
|
+
* 301 and 308 are both permanent; a server may answer GET with one and other
|
|
87
|
+
* methods with the other, so both are accepted.
|
|
88
|
+
*/
|
|
89
|
+
export function acceptsProbeStatus(status, retired) {
|
|
90
|
+
if (!retired)
|
|
91
|
+
return status === 200;
|
|
92
|
+
return status === 301 || status === 308 || status === 404;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=publication-continuity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publication-continuity.js","sourceRoot":"","sources":["../../src/engine/publication-continuity.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,gFAAgF;AAChF,iFAAiF;AACjF,0EAA0E;AAC1E,gFAAgF;AAChF,EAAE;AACF,gFAAgF;AAChF,4BAA4B;AAiD5B,gEAAgE;AAChE,MAAM,UAAU,aAAa,CAAC,IAA8C;IAC3E,OAAO,IAAI,EAAE,QAAQ,EAAE,cAAc,KAAK,UAAU,CAAA;AACrD,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAC3B,IAA2B,EAC3B,GAA2B;IAE3B,4EAA4E;IAC5E,wEAAwE;IACxE,iBAAiB;IACjB,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,IAAI,GAAG,CAAA;IACrC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;IACtC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAA;IAC5C,MAAM,QAAQ,GAAU,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,IAAI,CAAA;IAC5C,MAAM,UAAU,GAAuB,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAA;IACzF,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,IAAI,IAAI,CAAA;IAE5C,MAAM,MAAM,GAA2B,EAAE,CAAA;IACzC,IAAI,GAAG,CAAC,SAAS,KAAK,KAAK;QAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACjD,IAAI,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,KAAK,WAAW;QAAE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IAC7E,IAAI,MAAM,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,CAAC,KAAK,QAAQ;QAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACvE,IAAI,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,KAAK,WAAW;QAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAC7E,IAAI,CAAC,GAAG,CAAC,cAAc,IAAI,MAAM,CAAC,KAAK,UAAU;QAAE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IAC5E,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,OAAO;QAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IACjE,6EAA6E;IAC7E,+CAA+C;IAC/C,IAAI,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,KAAK,IAAI;QAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAEjE,OAAO;QACN,OAAO,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC;QAC1B,MAAM;QACN,KAAK;QACL,WAAW;QACX,QAAQ;QACR,WAAW;QACX,UAAU;QACV,OAAO;QACP,IAAI;QACJ,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;KACpC,CAAA;AACF,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,OAAgB;IAClE,IAAI,CAAC,OAAO;QAAE,OAAO,MAAM,KAAK,GAAG,CAAA;IACnC,OAAO,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,CAAA;AAC1D,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export declare class CanonicalJsonError extends Error {
|
|
2
|
+
readonly code: 'non_finite_number' | 'unsupported_type' | 'circular_reference';
|
|
3
|
+
constructor(code: CanonicalJsonError['code'], message: string);
|
|
4
|
+
}
|
|
5
|
+
type JsonPrimitive = string | number | boolean | null;
|
|
6
|
+
export type JsonValue = JsonPrimitive | JsonValue[] | {
|
|
7
|
+
[key: string]: JsonValue;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Serialize `value` per RFC 8785.
|
|
11
|
+
*
|
|
12
|
+
* Three things do the work, and each is load-bearing:
|
|
13
|
+
*
|
|
14
|
+
* 1. Object keys sort by UTF-16 code unit. JavaScript's default string sort is
|
|
15
|
+
* already a UTF-16 code-unit comparison, which is exactly what §3.2.3
|
|
16
|
+
* requires — so `.sort()` here is the specified behaviour, not a shortcut.
|
|
17
|
+
* 2. Numbers use ECMAScript `Number::toString`, which `JSON.stringify` applies.
|
|
18
|
+
* §3.2.2.3 defers to that same algorithm, so the platform is authoritative
|
|
19
|
+
* and reimplementing it would only introduce drift.
|
|
20
|
+
* 3. Strings use `JSON.stringify`'s escaping, which since ES2019 emits
|
|
21
|
+
* well-formed output (lone surrogates escaped rather than passed through) —
|
|
22
|
+
* §3.2.2.2's requirement.
|
|
23
|
+
*
|
|
24
|
+
* Non-finite numbers throw rather than becoming `null` as `JSON.stringify`
|
|
25
|
+
* would. A receipt containing `NaN` is a bug, and silently signing `null` in
|
|
26
|
+
* its place would make that bug undetectable downstream.
|
|
27
|
+
*/
|
|
28
|
+
export declare function canonicalJson(value: JsonValue): string;
|
|
29
|
+
/** Canonical UTF-8 bytes, which are what gets hashed and signed. */
|
|
30
|
+
export declare function canonicalJsonBytes(value: JsonValue): Uint8Array;
|
|
31
|
+
/** Lowercase hex SHA-256 of the canonical bytes. */
|
|
32
|
+
export declare function canonicalJsonSha256(value: JsonValue): Promise<string>;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=canonical-json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-json.d.ts","sourceRoot":"","sources":["../../../src/engine/publication-receipt/canonical-json.ts"],"names":[],"mappings":"AAYA,qBAAa,kBAAmB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,IAAI,EAAE,mBAAmB,GAAG,kBAAkB,GAAG,oBAAoB,CAAA;gBAElE,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM;CAK7D;AAED,KAAK,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAA;AACrD,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,SAAS,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAElF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,CAEtD;AA4DD,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,UAAU,CAE/D;AAED,oDAAoD;AACpD,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAU3E"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// RFC 8785 JSON Canonicalization Scheme (#342).
|
|
2
|
+
//
|
|
3
|
+
// A publication receipt is hashed and signed, and the same bytes must be
|
|
4
|
+
// reproducible by Foundry from the same object. Canonicalization is what makes
|
|
5
|
+
// that true: `JSON.stringify` alone is not stable, because object key order
|
|
6
|
+
// follows insertion order rather than a defined sort.
|
|
7
|
+
//
|
|
8
|
+
// Deliberately implemented rather than pulled from a dependency. The whole
|
|
9
|
+
// value here is that both sides agree byte-for-byte, so the algorithm should be
|
|
10
|
+
// readable, pinned, and covered by the RFC's own vectors rather than tracking
|
|
11
|
+
// someone else's semver.
|
|
12
|
+
export class CanonicalJsonError extends Error {
|
|
13
|
+
code;
|
|
14
|
+
constructor(code, message) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = 'CanonicalJsonError';
|
|
17
|
+
this.code = code;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Serialize `value` per RFC 8785.
|
|
22
|
+
*
|
|
23
|
+
* Three things do the work, and each is load-bearing:
|
|
24
|
+
*
|
|
25
|
+
* 1. Object keys sort by UTF-16 code unit. JavaScript's default string sort is
|
|
26
|
+
* already a UTF-16 code-unit comparison, which is exactly what §3.2.3
|
|
27
|
+
* requires — so `.sort()` here is the specified behaviour, not a shortcut.
|
|
28
|
+
* 2. Numbers use ECMAScript `Number::toString`, which `JSON.stringify` applies.
|
|
29
|
+
* §3.2.2.3 defers to that same algorithm, so the platform is authoritative
|
|
30
|
+
* and reimplementing it would only introduce drift.
|
|
31
|
+
* 3. Strings use `JSON.stringify`'s escaping, which since ES2019 emits
|
|
32
|
+
* well-formed output (lone surrogates escaped rather than passed through) —
|
|
33
|
+
* §3.2.2.2's requirement.
|
|
34
|
+
*
|
|
35
|
+
* Non-finite numbers throw rather than becoming `null` as `JSON.stringify`
|
|
36
|
+
* would. A receipt containing `NaN` is a bug, and silently signing `null` in
|
|
37
|
+
* its place would make that bug undetectable downstream.
|
|
38
|
+
*/
|
|
39
|
+
export function canonicalJson(value) {
|
|
40
|
+
return write(value, new Set());
|
|
41
|
+
}
|
|
42
|
+
function write(value, seen) {
|
|
43
|
+
if (value === null)
|
|
44
|
+
return 'null';
|
|
45
|
+
switch (typeof value) {
|
|
46
|
+
case 'boolean':
|
|
47
|
+
return value ? 'true' : 'false';
|
|
48
|
+
case 'number': {
|
|
49
|
+
if (!Number.isFinite(value)) {
|
|
50
|
+
throw new CanonicalJsonError('non_finite_number', `Cannot canonicalize non-finite number: ${String(value)}`);
|
|
51
|
+
}
|
|
52
|
+
// -0 serializes as "0" per RFC 8785 §3.2.2.3; JSON.stringify agrees.
|
|
53
|
+
return JSON.stringify(value);
|
|
54
|
+
}
|
|
55
|
+
case 'string':
|
|
56
|
+
return JSON.stringify(value);
|
|
57
|
+
case 'object':
|
|
58
|
+
break;
|
|
59
|
+
default:
|
|
60
|
+
throw new CanonicalJsonError('unsupported_type', `Cannot canonicalize value of type ${typeof value}`);
|
|
61
|
+
}
|
|
62
|
+
const object = value;
|
|
63
|
+
if (seen.has(object)) {
|
|
64
|
+
throw new CanonicalJsonError('circular_reference', 'Cannot canonicalize a circular structure');
|
|
65
|
+
}
|
|
66
|
+
seen.add(object);
|
|
67
|
+
try {
|
|
68
|
+
if (Array.isArray(value)) {
|
|
69
|
+
return `[${value.map((entry) => write(entry, seen)).join(',')}]`;
|
|
70
|
+
}
|
|
71
|
+
const record = value;
|
|
72
|
+
// Undefined-valued keys are omitted, matching JSON.stringify. RFC 8785
|
|
73
|
+
// has no representation for them.
|
|
74
|
+
const keys = Object.keys(record)
|
|
75
|
+
.filter((key) => record[key] !== undefined)
|
|
76
|
+
.sort();
|
|
77
|
+
const members = keys.map((key) => `${JSON.stringify(key)}:${write(record[key], seen)}`);
|
|
78
|
+
return `{${members.join(',')}}`;
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
seen.delete(object);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** Canonical UTF-8 bytes, which are what gets hashed and signed. */
|
|
85
|
+
export function canonicalJsonBytes(value) {
|
|
86
|
+
return new TextEncoder().encode(canonicalJson(value));
|
|
87
|
+
}
|
|
88
|
+
/** Lowercase hex SHA-256 of the canonical bytes. */
|
|
89
|
+
export async function canonicalJsonSha256(value) {
|
|
90
|
+
// `Uint8Array.from` yields an ArrayBuffer-backed copy. TextEncoder returns
|
|
91
|
+
// `Uint8Array<ArrayBufferLike>`, which may be SharedArrayBuffer-backed and
|
|
92
|
+
// so is not a `BufferSource`. Same idiom as sha256Hex in
|
|
93
|
+
// @growth-labs/monitoring's site-agent signature helper.
|
|
94
|
+
const copy = Uint8Array.from(canonicalJsonBytes(value));
|
|
95
|
+
const digest = await globalThis.crypto.subtle.digest('SHA-256', copy);
|
|
96
|
+
return Array.from(new Uint8Array(digest))
|
|
97
|
+
.map((byte) => byte.toString(16).padStart(2, '0'))
|
|
98
|
+
.join('');
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=canonical-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-json.js","sourceRoot":"","sources":["../../../src/engine/publication-receipt/canonical-json.ts"],"names":[],"mappings":"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"}
|