@phtngyn/cms 0.2.0-beta.4 → 0.2.0-beta.6
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/README.md +31 -13
- package/package.json +7 -7
- package/src/ApplicationTypes.d.ts +3 -3
- package/src/Authoring.d.ts +11 -3
- package/src/{Configuration-BU-UyGoH.js → Configuration-JQ1qyaU0.js} +347 -189
- package/src/Configuration-JQ1qyaU0.js.map +1 -0
- package/src/Configuration.d.ts +1 -1
- package/src/Content.d.ts +7 -6
- package/src/Content.js +106 -47
- package/src/Content.js.map +1 -1
- package/src/ContentTransfer-BxwswWn3.js +86 -0
- package/src/ContentTransfer-BxwswWn3.js.map +1 -0
- package/src/{ContentTransfer-CRQet3QJ.d.ts → ContentTransfer-Z9FHyLez.d.ts} +33 -9
- package/src/{DocumentEngine-ClhFXW9M.js → DocumentEngine-j6Vi7nQo.js} +279 -178
- package/src/DocumentEngine-j6Vi7nQo.js.map +1 -0
- package/src/DocumentModel.d.ts +9 -2
- package/src/DocumentModel.js +17 -4
- package/src/DocumentModel.js.map +1 -1
- package/src/{Forms-DoB56hfe.js → Forms-CX-hwmJF.js} +18 -11
- package/src/Forms-CX-hwmJF.js.map +1 -0
- package/src/{Forms-BbkE7QfC.js → Forms-CfNPTiCr.js} +2 -2
- package/src/{Forms-BbkE7QfC.js.map → Forms-CfNPTiCr.js.map} +1 -1
- package/src/Media-j1bTritO.js +112 -0
- package/src/Media-j1bTritO.js.map +1 -0
- package/src/Module.js +0 -4
- package/src/Module.js.map +1 -1
- package/src/References-CCPDAPve.js +45 -0
- package/src/References-CCPDAPve.js.map +1 -0
- package/src/{S3MediaObjects-CR3p1WTg.js → S3MediaObjects-BRuPQbxl.js} +454 -516
- package/src/S3MediaObjects-BRuPQbxl.js.map +1 -0
- package/src/cli/content.js +6 -5
- package/src/cli/content.js.map +1 -1
- package/src/cli.js +16 -3
- package/src/cli.js.map +1 -1
- package/src/{connection-D5S9Iph-.js → connection-BP80q4d-.js} +2 -2
- package/src/{connection-D5S9Iph-.js.map → connection-BP80q4d-.js.map} +1 -1
- package/src/{dev-lifecycle-D3f9-upa.js → dev-lifecycle-CExksm2R.js} +27 -7
- package/src/dev-lifecycle-CExksm2R.js.map +1 -0
- package/src/{installation-fZtNxtoW.js → installation-BoG8E3nJ.js} +7982 -7155
- package/src/installation-BoG8E3nJ.js.map +1 -0
- package/src/internal/authoring-catalog.js +2 -2
- package/src/internal/authoring-compiler.js +35 -9
- package/src/internal/authoring-compiler.js.map +1 -1
- package/src/internal/authoring-metadata.js +14 -5
- package/src/internal/authoring-metadata.js.map +1 -1
- package/src/internal/configuration.js +27 -3
- package/src/internal/configuration.js.map +1 -1
- package/src/internal/dev-lifecycle.js +2 -2
- package/src/internal/document-model.js +134 -43
- package/src/internal/document-model.js.map +1 -1
- package/src/internal/field-metadata.js +2 -1
- package/src/internal/field-metadata.js.map +1 -1
- package/src/internal/form-capabilities.js +1 -1
- package/src/{location-CPX7oj0o.js → location-CMNGO3lU.js} +2 -2
- package/src/{location-CPX7oj0o.js.map → location-CMNGO3lU.js.map} +1 -1
- package/src/{metadata-BEZPWh-3.js → metadata-UzZmjwxM.js} +2 -2
- package/src/{metadata-BEZPWh-3.js.map → metadata-UzZmjwxM.js.map} +1 -1
- package/src/{models-C9kF9JlQ.js → models-5j67LMqW.js} +4 -4
- package/src/{models-C9kF9JlQ.js.map → models-5j67LMqW.js.map} +1 -1
- package/src/{models-ChRxBChy.js → models-VmGmG19-.js} +42 -130
- package/src/models-VmGmG19-.js.map +1 -0
- package/src/runtime/delivery/DocumentRenderer.js +5 -1
- package/src/runtime/delivery/DocumentRenderer.js.map +1 -1
- package/src/runtime/delivery/context.js +1 -1
- package/src/runtime/delivery/plugin.js +2 -2
- package/src/runtime/delivery/preview.d.ts +1 -1
- package/src/runtime/delivery/types.d.ts +1 -1
- package/src/runtime/delivery/useCmsDocumentSeo.d.ts +1 -1
- package/src/runtime/forms/document.js +2 -2
- package/src/runtime/forms/useCmsForm.js +2 -2
- package/src/runtime/installation.js +1 -1
- package/src/runtime/plugin.js +1 -1
- package/src/runtime/preview/CmsStudioPreviewMarker.js +18 -4
- package/src/runtime/preview/CmsStudioPreviewMarker.js.map +1 -1
- package/src/runtime/preview/connection.js +1 -1
- package/src/runtime/preview/controller.js +65 -74
- package/src/runtime/preview/controller.js.map +1 -1
- package/src/runtime/preview/overlay.js +85 -28
- package/src/runtime/preview/overlay.js.map +1 -1
- package/src/runtime/preview/plugin.client.js +4 -4
- package/src/runtime/preview/preview.css +50 -36
- package/src/runtime/preview/protocol.d.ts +11 -5
- package/src/runtime/preview/protocol.js +17 -5
- package/src/runtime/preview/protocol.js.map +1 -1
- package/src/runtime/preview/regions.js +142 -0
- package/src/runtime/preview/regions.js.map +1 -0
- package/src/runtime/preview/store.js +1 -1
- package/src/runtime/sitemap.js +9 -10
- package/src/runtime/sitemap.js.map +1 -1
- package/src/{scalars-B2lgGUnj.js → scalars-CVZqT3L0.js} +2 -6
- package/src/scalars-CVZqT3L0.js.map +1 -0
- package/src/{store-CCsjHaZm.js → store-PKKB8xa2.js} +49 -66
- package/src/store-PKKB8xa2.js.map +1 -0
- package/src/{types-DutFRtaG.d.ts → types-DZ0IV-Ow.d.ts} +14 -3
- package/studio/CreateDocumentDialog-DqvusuGU.js +335 -0
- package/studio/{documentPlanning-CDb31mnl.js → SelectMenu-BgikeouH.js} +16292 -12303
- package/studio/{editor-Bzlh3zXt.js → editor-P2rB7Csp.js} +11228 -11927
- package/studio/host.css +1 -1
- package/studio/host.js +28987 -34295
- package/studio/rolldown-runtime-Dy4uBu1J.js +11 -0
- package/src/Configuration-BU-UyGoH.js.map +0 -1
- package/src/ContentTransfer-BhF9G56s.js +0 -57
- package/src/ContentTransfer-BhF9G56s.js.map +0 -1
- package/src/DocumentEngine-ClhFXW9M.js.map +0 -1
- package/src/Forms-DoB56hfe.js.map +0 -1
- package/src/S3MediaObjects-CR3p1WTg.js.map +0 -1
- package/src/dev-lifecycle-D3f9-upa.js.map +0 -1
- package/src/installation-fZtNxtoW.js.map +0 -1
- package/src/models-ChRxBChy.js.map +0 -1
- package/src/runtime/preview/targets.js +0 -101
- package/src/runtime/preview/targets.js.map +0 -1
- package/src/scalars-B2lgGUnj.js.map +0 -1
- package/src/store-CCsjHaZm.js.map +0 -1
- package/studio/CreateDocumentDialog-DJ8c0WZb.js +0 -256
- package/studio/dom-to-image-more.min-D6jGGdrW.js +0 -877
- package/studio/rolldown-runtime-B0aSnxlc.js +0 -20
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { $ as
|
|
3
|
-
import { i as
|
|
1
|
+
import { i as DocumentVersion, l as Slug, n as DocumentHistoryCursor, o as PublicPath, r as DocumentId, s as RevisionId, t as DocumentGeneration, u as nonNegativeInt } from "./scalars-CVZqT3L0.js";
|
|
2
|
+
import { $ as MEDIA_ACTIONS, A as RestoreDocumentInput, B as SeoConfiguration, C as MoveDocumentInput, D as PublishedDocumentQuery, E as PublishedDocumentPage, F as GlobalSeoSettings, G as SeoSnapshot, H as SeoMediaUnavailable, I as PublishSeoInput, J as SeoVersionConflict, K as SeoState, L as SaveSeoInput, N as UpdateDocumentInput, O as PublishedDocumentSurroundQuery, Q as DOCUMENT_ACTIONS, R as SeoCanonicalOrigin, T as PublishedDocumentLookup, U as SeoMutationResult, V as SeoConfirmationRequired, X as AccessDenied, Y as SitemapEntry, Z as AuthenticationRequired, b as DocumentValidationResult, d as DocumentNavigationItem, et as Role, f as DocumentNavigationQuery, g as DocumentSource, h as DocumentRevisionAction, i as CreateDocumentInput, j as UndeleteDocumentInput, k as RemoveDocumentInput, l as DocumentIssue, m as DocumentQueryScalar, n as CmsMarkdownDocument, nt as StudioEntryDenied, o as DeletedDocument, p as DocumentPlacement, q as SeoUrl, r as CompiledDocument, s as DocumentBrowseQuery, st as RequestId, tt as StudioActor, u as DocumentMutationResult, v as DocumentSummary, w as PublishDocumentInput, x as DuplicateDocumentInput, y as DocumentSurround, z as SeoCapabilities } from "./models-VmGmG19-.js";
|
|
3
|
+
import { _ as MediaReferenced, a as MediaConflict, b as MediaUpload, c as MediaId, f as MediaNotFound, g as MediaReference, h as MediaQuery, i as MediaCleanupReport, l as MediaIntegrityReport, m as MediaPage, n as MediaAsset, p as MediaObjectKey, r as MediaByteSize, s as MediaFolder, t as ImageMimeType, u as MediaInvalid, y as MediaTooLarge } from "./Media-j1bTritO.js";
|
|
4
|
+
import { a as ContentSnapshot, c as ContentTransferConflict, d as DocumentNotFound, f as DocumentRouteConflict, h as PublishedDocumentNotFound, i as ContentPlan, l as ContentTransferInput, m as DocumentVersionConflict, n as ContentApplyResult, p as DocumentValidationFailed, t as ContentApplyInput, u as DocumentMediaUnavailable } from "./ContentTransfer-BxwswWn3.js";
|
|
4
5
|
import { u as STUDIO_API_PATH } from "./HttpPaths-c9nLZ9H2.js";
|
|
5
|
-
import { c as FormSubmission, o as FormResult } from "./Forms-
|
|
6
|
-
import {
|
|
7
|
-
import { i as withoutEditorMetadata } from "./metadata-
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
6
|
+
import { c as FormSubmission, o as FormResult } from "./Forms-CfNPTiCr.js";
|
|
7
|
+
import { m as toComarkDocument } from "./Forms-CX-hwmJF.js";
|
|
8
|
+
import { i as withoutEditorMetadata } from "./metadata-UzZmjwxM.js";
|
|
9
|
+
import { f as EditorRenderFailed, i as MediaConfiguration, r as DocumentConfiguration } from "./Configuration-JQ1qyaU0.js";
|
|
10
|
+
import { n as DocumentCompilationFailed, t as createDocumentEngine } from "./DocumentEngine-j6Vi7nQo.js";
|
|
10
11
|
import { Context, Crypto, Data, DateTime, Effect, Encoding, Layer, Option, Predicate, PubSub, Redacted, Ref, Result, Schedule, Schema, Semaphore, Stream, flow } from "effect";
|
|
11
12
|
import { NodeStream } from "@effect/platform-node-shared";
|
|
12
13
|
import { Multipart } from "effect/unstable/http";
|
|
@@ -15,25 +16,6 @@ import { renderMarkdown } from "comark/render";
|
|
|
15
16
|
import { diffArrays } from "diff";
|
|
16
17
|
import { CopyObjectCommand, CreateBucketCommand, DeleteObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectsV2Command, PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
|
17
18
|
|
|
18
|
-
//#region ../protocol/src/internal/documents/errors.ts
|
|
19
|
-
var DocumentNotFound = class extends Schema.TaggedError()("Document.NotFound", {
|
|
20
|
-
documentId: DocumentId,
|
|
21
|
-
revisionId: Schema.optionalKey(RevisionId)
|
|
22
|
-
}) {};
|
|
23
|
-
var DocumentPathConflict = class extends Schema.TaggedError()("Document.PathConflict", { sourcePath: SourcePath }) {};
|
|
24
|
-
var DocumentVersionConflict = class extends Schema.TaggedError()("Document.VersionConflict", {
|
|
25
|
-
documentId: DocumentId,
|
|
26
|
-
expectedVersion: DocumentVersion,
|
|
27
|
-
actualVersion: DocumentVersion
|
|
28
|
-
}) {};
|
|
29
|
-
var DocumentMediaUnavailable = class extends Schema.TaggedError()("Document.MediaUnavailable", {
|
|
30
|
-
documentId: DocumentId,
|
|
31
|
-
mediaKeys: Schema.Array(MediaObjectKey).check(Schema.isMinLength(1))
|
|
32
|
-
}) {};
|
|
33
|
-
var DocumentValidationFailed = class extends Schema.TaggedError()("Document.ValidationFailed", { issues: Schema.Array(DocumentIssue) }) {};
|
|
34
|
-
var PublishedDocumentNotFound = class extends Schema.TaggedError()("PublishedDocument.NotFound", { lookup: PublishedDocumentLookup }) {};
|
|
35
|
-
|
|
36
|
-
//#endregion
|
|
37
19
|
//#region ../protocol/src/Activity.ts
|
|
38
20
|
/**
|
|
39
21
|
* Immutable completed Activity facts. Pages are ordered newest-first; cursors are opaque,
|
|
@@ -139,8 +121,8 @@ const DocumentRevisionSummary = Schema.Struct({
|
|
|
139
121
|
activity: ActivityEntry,
|
|
140
122
|
createdAt: Schema.DateTimeUtcFromString,
|
|
141
123
|
documentId: DocumentId,
|
|
124
|
+
placement: DocumentPlacement,
|
|
142
125
|
revisionId: RevisionId,
|
|
143
|
-
sourcePath: SourcePath,
|
|
144
126
|
version: DocumentVersion
|
|
145
127
|
}).annotate({ identifier: "DocumentRevisionSummary" });
|
|
146
128
|
const DocumentRevision = Schema.Struct({
|
|
@@ -451,7 +433,7 @@ const ValidateDocumentPayload = Schema.Struct({
|
|
|
451
433
|
const UpdateDocumentPayload = ValidateDocumentPayload.pipe(Schema.fieldsAssign({ reason: UpdateDocumentInput.fields.reason }));
|
|
452
434
|
const MoveDocumentPayload = Schema.Struct({
|
|
453
435
|
expectedVersion: MoveDocumentInput.fields.expectedVersion,
|
|
454
|
-
|
|
436
|
+
placement: MoveDocumentInput.fields.placement,
|
|
455
437
|
reason: MoveDocumentInput.fields.reason
|
|
456
438
|
});
|
|
457
439
|
const PublishDocumentPayload = Schema.Struct({
|
|
@@ -481,7 +463,7 @@ const NotFound = DocumentNotFound.pipe(HttpApiSchema.status(404));
|
|
|
481
463
|
const VersionConflict = DocumentVersionConflict.pipe(HttpApiSchema.status(409));
|
|
482
464
|
const Conflict = Schema.Union([
|
|
483
465
|
DocumentMediaUnavailable,
|
|
484
|
-
|
|
466
|
+
DocumentRouteConflict,
|
|
485
467
|
DocumentVersionConflict
|
|
486
468
|
]).pipe(HttpApiSchema.status(409));
|
|
487
469
|
const ValidationFailed = DocumentValidationFailed.pipe(HttpApiSchema.status(422));
|
|
@@ -795,6 +777,14 @@ const StudioCollaborationApi = HttpApiGroup.make("collaboration").add(HttpApiEnd
|
|
|
795
777
|
Forbidden,
|
|
796
778
|
InternalError
|
|
797
779
|
]
|
|
780
|
+
}), HttpApiEndpoint.post("discard", "/:documentId/discard", {
|
|
781
|
+
params: { documentId: DocumentId },
|
|
782
|
+
success: CollaborationTicket,
|
|
783
|
+
error: [
|
|
784
|
+
NotFound,
|
|
785
|
+
Forbidden,
|
|
786
|
+
InternalError
|
|
787
|
+
]
|
|
798
788
|
})).middleware(StudioAuthentication).prefix("/collaboration");
|
|
799
789
|
const FormsApi = HttpApiGroup.make("forms").add(HttpApiEndpoint.post("submit", "/submit", {
|
|
800
790
|
payload: FormSubmission,
|
|
@@ -873,80 +863,18 @@ const renderEditorMarkdown = Effect.fn("EditorDocument.renderMarkdown")((documen
|
|
|
873
863
|
});
|
|
874
864
|
});
|
|
875
865
|
|
|
876
|
-
//#endregion
|
|
877
|
-
//#region ../document/src/internal/document-engine/relocate-links.ts
|
|
878
|
-
/** Rewrites only semantic page links, preserving bindings and unrelated content. */
|
|
879
|
-
function rewriteDocumentRoutes(document, destinations, components = []) {
|
|
880
|
-
let changed = false;
|
|
881
|
-
function link(value) {
|
|
882
|
-
const target = referenceTarget("a", /* @__PURE__ */ new Map([["href", value]]), document.path, void 0);
|
|
883
|
-
if (target?.kind !== "document" || !Predicate.isString(value)) return value;
|
|
884
|
-
const destination = destinations.get(target.path);
|
|
885
|
-
const sourceMoved = destinations.has(document.path);
|
|
886
|
-
if (!destination && (!sourceMoved || value.startsWith("/"))) return value;
|
|
887
|
-
const suffix = value.match(/[?#].*$/u)?.[0] ?? "";
|
|
888
|
-
const next = `${destination ?? target.path}${suffix}`;
|
|
889
|
-
if (next !== value) changed = true;
|
|
890
|
-
return next;
|
|
891
|
-
}
|
|
892
|
-
function properties(fields, values) {
|
|
893
|
-
const result = mutableJsonObject(values);
|
|
894
|
-
for (const field of fields) {
|
|
895
|
-
const value = values[field.name] === void 0 ? field.defaultValue : values[field.name];
|
|
896
|
-
if (field.input === "link") {
|
|
897
|
-
const next = link(value);
|
|
898
|
-
if (next !== void 0 && next !== value) result[field.name] = next;
|
|
899
|
-
} else if (field.fields) {
|
|
900
|
-
const next = Array.isArray(value) ? value.map((item) => Schema.is(Schema.JsonObject)(item) ? properties(field.fields ?? [], item) : item) : Schema.is(Schema.JsonObject)(value) ? properties(field.fields, value) : value;
|
|
901
|
-
if (next !== void 0 && JSON.stringify(next) !== JSON.stringify(value)) result[field.name] = next;
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
return result;
|
|
905
|
-
}
|
|
906
|
-
function visit(node, renderData) {
|
|
907
|
-
if (Predicate.isString(node) || node[0] === null) return node;
|
|
908
|
-
const [tag, attributes, ...children] = node;
|
|
909
|
-
const projection = projectCmsEditorComponentAttributes(attributes, renderData);
|
|
910
|
-
let props = properties(components.find((component) => component.name.toLowerCase() === tag.toLowerCase())?.authoring.props ?? [], projection.props);
|
|
911
|
-
if (tag === "a") {
|
|
912
|
-
const href = link(projection.props.href);
|
|
913
|
-
if (href !== void 0) props = Object.assign({}, props, { href });
|
|
914
|
-
}
|
|
915
|
-
return [
|
|
916
|
-
tag,
|
|
917
|
-
JSON.stringify(props) === JSON.stringify(projection.props) ? attributes : encodeCmsEditorComponentAttributes(props, projection.bindings),
|
|
918
|
-
...children.map((child) => visit(child, projection.renderData))
|
|
919
|
-
];
|
|
920
|
-
}
|
|
921
|
-
const nodes = document.body.nodes.map((node) => visit(node, createCmsComarkRenderData(document.body)));
|
|
922
|
-
return changed ? Object.assign({}, document.body, { nodes }) : void 0;
|
|
923
|
-
}
|
|
924
|
-
|
|
925
866
|
//#endregion
|
|
926
867
|
//#region ../document/src/DocumentPlanning.ts
|
|
927
868
|
function planDocumentCreation(configuration, input) {
|
|
928
869
|
return Result.gen(function* () {
|
|
929
870
|
const collection = configuration.types.find((candidate) => candidate.collection === input.collection);
|
|
930
|
-
if (!collection) return yield* invalid
|
|
871
|
+
if (!collection) return yield* invalid(`Document collection "${input.collection}" does not exist.`, "collection");
|
|
931
872
|
const title = input.title.trim();
|
|
932
|
-
if (!title) return yield* invalid
|
|
873
|
+
if (!title) return yield* invalid("A document title is required.", "title");
|
|
933
874
|
const locale = yield* resolveLocale(configuration, input.locale);
|
|
934
|
-
const address = yield* parseDocumentAddress(collection.addressPattern).pipe(Result.mapError(addressInvalid));
|
|
935
|
-
const relativePath = yield* resolveRelativePath(collection, input.location);
|
|
936
|
-
const data = Object.fromEntries(address.tokens.flatMap((token) => {
|
|
937
|
-
if (token.name === "slug" && relativePath) return [[token.name, relativePath.split("/").at(-1) ?? relativePath]];
|
|
938
|
-
return [];
|
|
939
|
-
}));
|
|
940
|
-
const relativeKey = yield* normalizePublicPath(relativePath).pipe(Result.mapError(addressInvalid));
|
|
941
|
-
const key = yield* resolveDocumentAddress(address, relativeKey, data).pipe(Result.mapError(addressInvalid));
|
|
942
|
-
const sourcePath = documentSourcePath(collection, relativePath, locale);
|
|
943
|
-
const path = localizeDocumentPath(key, locale, configuration.locales);
|
|
944
875
|
return Object.assign({
|
|
945
876
|
collection,
|
|
946
|
-
|
|
947
|
-
key,
|
|
948
|
-
path,
|
|
949
|
-
sourcePath,
|
|
877
|
+
placement: input.placement,
|
|
950
878
|
title
|
|
951
879
|
}, locale === void 0 ? void 0 : { locale });
|
|
952
880
|
});
|
|
@@ -966,69 +894,25 @@ const createInitialDocumentSource = Effect.fn("DocumentPlanning.createInitialSou
|
|
|
966
894
|
markdown: yield* renderEditorMarkdown(body)
|
|
967
895
|
};
|
|
968
896
|
});
|
|
969
|
-
function planDocumentMove(configuration, document, location) {
|
|
970
|
-
return Result.gen(function* () {
|
|
971
|
-
const collection = configuration.types.find((candidate) => candidate.collection === document.collection);
|
|
972
|
-
if (!collection) return yield* invalid$1(`Document collection "${document.collection}" does not exist.`, "documentId");
|
|
973
|
-
return documentSourcePath(collection, yield* resolveRelativePath(collection, location), document.locale);
|
|
974
|
-
});
|
|
975
|
-
}
|
|
976
|
-
function documentRelativePath(collection, entry) {
|
|
977
|
-
let sourcePath = entry.sourcePath;
|
|
978
|
-
if (entry.document.locale && sourcePath.startsWith(`${entry.document.locale}/`)) sourcePath = sourcePath.slice(entry.document.locale.length + 1);
|
|
979
|
-
if (collection.directory !== "." && sourcePath.startsWith(`${collection.directory}/`)) sourcePath = sourcePath.slice(collection.directory.length + 1);
|
|
980
|
-
sourcePath = sourcePath.replace(/\.(?:md|mdc)$/iu, "");
|
|
981
|
-
return sourcePath.toLocaleLowerCase() === "index" ? void 0 : sourcePath.replace(/\/index$/iu, "");
|
|
982
|
-
}
|
|
983
|
-
function documentSourcePath(collection, relativePath, locale) {
|
|
984
|
-
const sourceName = relativePath ? `${relativePath}.md` : "index.md";
|
|
985
|
-
return SourcePath.make([
|
|
986
|
-
locale,
|
|
987
|
-
collection.directory === "." ? void 0 : collection.directory,
|
|
988
|
-
sourceName
|
|
989
|
-
].filter((value) => value !== void 0).join("/"));
|
|
990
|
-
}
|
|
991
897
|
function initialFrontmatter(plan) {
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
}
|
|
1002
|
-
function setNestedValue(target, path, value) {
|
|
1003
|
-
const [segment, ...rest] = path;
|
|
1004
|
-
if (!segment) return target;
|
|
1005
|
-
if (rest.length === 0) return Object.assign({}, target, { [segment]: value });
|
|
1006
|
-
const current = target[segment];
|
|
1007
|
-
return Object.assign({}, target, { [segment]: setNestedValue(isJsonObject(current) ? current : {}, rest, value) });
|
|
898
|
+
return Object.assign(structuredDefaults(plan.collection.authoringFields), { title: plan.title });
|
|
899
|
+
}
|
|
900
|
+
function structuredDefaults(fields) {
|
|
901
|
+
return Object.fromEntries(fields.flatMap((field) => {
|
|
902
|
+
if (field.defaultValue !== void 0) return [[field.name, structuredClone(field.defaultValue)]];
|
|
903
|
+
if (field.type !== "object") return [];
|
|
904
|
+
const nested = structuredDefaults(field.fields ?? []);
|
|
905
|
+
return Object.keys(nested).length === 0 ? [] : [[field.name, nested]];
|
|
906
|
+
}));
|
|
1008
907
|
}
|
|
1009
|
-
const isJsonObject = Schema.is(Schema.JsonObject);
|
|
1010
908
|
function resolveLocale(configuration, requested) {
|
|
1011
909
|
const locales = configuration.locales;
|
|
1012
|
-
if (!locales) return requested === void 0 ? Result.succeed(void 0) : invalid
|
|
910
|
+
if (!locales) return requested === void 0 ? Result.succeed(void 0) : invalid(`Document locale "${requested}" is not configured.`, "locale");
|
|
1013
911
|
const locale = requested ?? locales.defaultLocale;
|
|
1014
|
-
return locales.locales.includes(locale) ? Result.succeed(locale) : invalid
|
|
1015
|
-
}
|
|
1016
|
-
function resolveRelativePath(collection, location) {
|
|
1017
|
-
if (location.kind === "home") return collection.addressPattern === "/:path*" ? Result.succeed("") : invalid$1("Only a root catch-all collection can use the home location.", "location");
|
|
1018
|
-
if (location.parent !== void 0 && !collection.hierarchy) return invalid$1(`Document collection "${collection.collection}" does not allow hierarchy.`, "location.parent");
|
|
1019
|
-
return normalizeDocumentRelativePath([location.parent, location.slug].filter((value) => value !== void 0).join("/")).pipe(Result.mapError((error) => addressInvalid({
|
|
1020
|
-
...error,
|
|
1021
|
-
field: "location"
|
|
1022
|
-
})));
|
|
1023
|
-
}
|
|
1024
|
-
function addressInvalid(error) {
|
|
1025
|
-
return new DocumentValidationFailed({ issues: [validationIssue(error.message, error.field)] });
|
|
912
|
+
return locales.locales.includes(locale) ? Result.succeed(locale) : invalid(`Document locale "${locale}" does not exist.`, "locale");
|
|
1026
913
|
}
|
|
1027
|
-
function invalid
|
|
1028
|
-
return Result.fail(new DocumentValidationFailed({ issues: [
|
|
1029
|
-
}
|
|
1030
|
-
function validationIssue(message, field) {
|
|
1031
|
-
return field === void 0 ? {
|
|
914
|
+
function invalid(message, field) {
|
|
915
|
+
return Result.fail(new DocumentValidationFailed({ issues: [field === void 0 ? {
|
|
1032
916
|
code: "document.invalid",
|
|
1033
917
|
message,
|
|
1034
918
|
severity: "error"
|
|
@@ -1037,20 +921,8 @@ function validationIssue(message, field) {
|
|
|
1037
921
|
field,
|
|
1038
922
|
message,
|
|
1039
923
|
severity: "error"
|
|
1040
|
-
};
|
|
924
|
+
}] }));
|
|
1041
925
|
}
|
|
1042
|
-
/** Updates route-owned frontmatter when relocating a page in a slug-addressed collection. */
|
|
1043
|
-
const relocateDocumentMarkdown = Effect.fn("DocumentPlanning.relocateMarkdown")(function* (configuration, document, location, markdown) {
|
|
1044
|
-
const collection = configuration.types.find((type) => type.collection === document.collection);
|
|
1045
|
-
if (!collection || !collection.addressPattern.includes(":slug") || location.kind === "home") return markdown;
|
|
1046
|
-
return yield* renderEditorMarkdown({
|
|
1047
|
-
...document.body,
|
|
1048
|
-
frontmatter: {
|
|
1049
|
-
...document.body.frontmatter,
|
|
1050
|
-
slug: location.slug
|
|
1051
|
-
}
|
|
1052
|
-
});
|
|
1053
|
-
});
|
|
1054
926
|
|
|
1055
927
|
//#endregion
|
|
1056
928
|
//#region ../server/src/internal/documents/document-state.ts
|
|
@@ -1093,19 +965,19 @@ const compileDocumentState = Effect.fn("DocumentState.compile")(function* (engin
|
|
|
1093
965
|
});
|
|
1094
966
|
function authoredSources(snapshot) {
|
|
1095
967
|
return snapshot.active.map((source) => ({
|
|
1096
|
-
documentId: source.documentId,
|
|
1097
968
|
draft: source.publishedVersion !== source.version,
|
|
969
|
+
identity: source.identity,
|
|
1098
970
|
markdown: source.markdown,
|
|
1099
|
-
|
|
971
|
+
placement: source.placement
|
|
1100
972
|
}));
|
|
1101
973
|
}
|
|
1102
974
|
function publishedSources(snapshot) {
|
|
1103
975
|
return snapshot.published.map((source) => ({
|
|
1104
|
-
documentId: source.documentId,
|
|
1105
976
|
draft: false,
|
|
977
|
+
identity: source.identity,
|
|
1106
978
|
markdown: source.markdown,
|
|
1107
|
-
|
|
1108
|
-
|
|
979
|
+
placement: source.placement,
|
|
980
|
+
publishedAt: source.editedAt
|
|
1109
981
|
}));
|
|
1110
982
|
}
|
|
1111
983
|
const compileValidCatalog = Effect.fn("DocumentState.compileValid")(function* (engine, sources, previous) {
|
|
@@ -1118,7 +990,7 @@ const compileValidCatalog = Effect.fn("DocumentState.compileValid")(function* (e
|
|
|
1118
990
|
if (errors.length > 0) return yield* new DocumentValidationFailed({ issues: errors });
|
|
1119
991
|
return result.success;
|
|
1120
992
|
});
|
|
1121
|
-
const validateDocumentSources = Effect.fn("DocumentState.validate")(function* (engine, sources,
|
|
993
|
+
const validateDocumentSources = Effect.fn("DocumentState.validate")(function* (engine, sources, documentId, previous) {
|
|
1122
994
|
const result = yield* Effect.result(engine.compileAll({
|
|
1123
995
|
previous,
|
|
1124
996
|
sources
|
|
@@ -1128,7 +1000,7 @@ const validateDocumentSources = Effect.fn("DocumentState.validate")(function* (e
|
|
|
1128
1000
|
valid: false
|
|
1129
1001
|
});
|
|
1130
1002
|
const catalog = result.success;
|
|
1131
|
-
const document = catalog.documents.find((candidate) => candidate.
|
|
1003
|
+
const document = catalog.documents.find((candidate) => candidate.id === documentId);
|
|
1132
1004
|
const issues = catalog.issues;
|
|
1133
1005
|
const validation = {
|
|
1134
1006
|
issues,
|
|
@@ -1144,8 +1016,7 @@ function authoringEntries(state, query) {
|
|
|
1144
1016
|
if (query.locale !== void 0 && document.locale !== query.locale) return [];
|
|
1145
1017
|
return [DocumentSummary.make({
|
|
1146
1018
|
...browseMetadata(state, source),
|
|
1147
|
-
document,
|
|
1148
|
-
sourcePath: source.sourcePath,
|
|
1019
|
+
document: summaryDocument(document),
|
|
1149
1020
|
version: source.version
|
|
1150
1021
|
})];
|
|
1151
1022
|
});
|
|
@@ -1156,8 +1027,9 @@ function deletedEntries(state) {
|
|
|
1156
1027
|
...source.path ? { path: source.path } : void 0,
|
|
1157
1028
|
...source.trashBatchId ? { trashBatchId: source.trashBatchId } : void 0,
|
|
1158
1029
|
documentId: source.documentId,
|
|
1030
|
+
identity: source.identity,
|
|
1031
|
+
placement: source.placement,
|
|
1159
1032
|
deletedAt: source.deletedAt,
|
|
1160
|
-
sourcePath: source.sourcePath,
|
|
1161
1033
|
version: source.version
|
|
1162
1034
|
}));
|
|
1163
1035
|
}
|
|
@@ -1166,18 +1038,32 @@ function entryById(state, documentId) {
|
|
|
1166
1038
|
const document = state.authoredById.get(documentId);
|
|
1167
1039
|
return source && document ? DocumentSummary.make({
|
|
1168
1040
|
...browseMetadata(state, source),
|
|
1169
|
-
document,
|
|
1170
|
-
sourcePath: source.sourcePath,
|
|
1041
|
+
document: summaryDocument(document),
|
|
1171
1042
|
version: source.version
|
|
1172
1043
|
}) : void 0;
|
|
1173
1044
|
}
|
|
1045
|
+
function summaryDocument(document) {
|
|
1046
|
+
return {
|
|
1047
|
+
collection: document.collection,
|
|
1048
|
+
draft: document.draft,
|
|
1049
|
+
id: document.id,
|
|
1050
|
+
identity: document.identity,
|
|
1051
|
+
issues: document.issues,
|
|
1052
|
+
key: document.key,
|
|
1053
|
+
...document.locale ? { locale: document.locale } : void 0,
|
|
1054
|
+
path: document.path,
|
|
1055
|
+
placement: document.placement,
|
|
1056
|
+
searchText: document.analysis.searchText,
|
|
1057
|
+
title: document.title
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1174
1060
|
function compilationIssues(error) {
|
|
1175
1061
|
if (isDocumentCompilationFailed(error)) return error.issues;
|
|
1176
1062
|
return [{
|
|
1177
1063
|
code: "markdown.parse",
|
|
1178
1064
|
message: errorMessage(error.cause),
|
|
1179
1065
|
severity: "error",
|
|
1180
|
-
|
|
1066
|
+
documentId: error.documentId
|
|
1181
1067
|
}];
|
|
1182
1068
|
}
|
|
1183
1069
|
function errorMessage(cause) {
|
|
@@ -1196,14 +1082,27 @@ function browseMetadata(state, source) {
|
|
|
1196
1082
|
|
|
1197
1083
|
//#endregion
|
|
1198
1084
|
//#region ../server/src/internal/documents/document-tree-mutation.ts
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
const
|
|
1202
|
-
|
|
1203
|
-
|
|
1085
|
+
function subtreeIds(state, documentId, catalog = "authored") {
|
|
1086
|
+
const documents = catalog === "authored" ? state.authored.documents : state.published.documents;
|
|
1087
|
+
const children = /* @__PURE__ */ new Map();
|
|
1088
|
+
for (const document of documents) {
|
|
1089
|
+
if (document.placement.kind === "home") continue;
|
|
1090
|
+
const existing = children.get(document.placement.parentDocumentId) ?? [];
|
|
1091
|
+
existing.push(document.id);
|
|
1092
|
+
children.set(document.placement.parentDocumentId, existing);
|
|
1093
|
+
}
|
|
1094
|
+
const result = [];
|
|
1095
|
+
const pending = [documentId];
|
|
1096
|
+
while (pending.length > 0) {
|
|
1097
|
+
const current = pending.shift();
|
|
1098
|
+
if (!current || result.includes(current)) continue;
|
|
1099
|
+
result.push(current);
|
|
1100
|
+
pending.push(...children.get(current) ?? []);
|
|
1101
|
+
}
|
|
1102
|
+
return result;
|
|
1204
1103
|
}
|
|
1205
1104
|
const prepareTreeMutation = Effect.fn("Documents.prepareTreeMutation")(function* (dependencies, state, command) {
|
|
1206
|
-
const {
|
|
1105
|
+
const { engine } = dependencies;
|
|
1207
1106
|
const input = command.input;
|
|
1208
1107
|
const root = command.action === "document.undelete" ? state.snapshot.deleted.find((source) => source.documentId === input.documentId) : state.activeById.get(input.documentId);
|
|
1209
1108
|
if (!root) return yield* new DocumentNotFound({ documentId: input.documentId });
|
|
@@ -1212,152 +1111,121 @@ const prepareTreeMutation = Effect.fn("Documents.prepareTreeMutation")(function*
|
|
|
1212
1111
|
actualVersion: root.version,
|
|
1213
1112
|
expectedVersion: input.expectedVersion
|
|
1214
1113
|
});
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
sources = state.snapshot.deleted.filter((source) => source.documentId === root.documentId || deleted && deleted.trashBatchId && source.trashBatchId === deleted.trashBatchId && deleted.path !== void 0 && source.path?.startsWith(`${deleted.path}/`));
|
|
1219
|
-
} else {
|
|
1220
|
-
const ids = new Set(command.action === "document.duplicate" && !command.input.includeChildren ? [root.documentId] : subtreeIds(state, root.documentId));
|
|
1221
|
-
sources = state.snapshot.active.filter((source) => ids.has(source.documentId));
|
|
1222
|
-
}
|
|
1223
|
-
sources = [root, ...sources.filter((source) => source.documentId !== root.documentId)];
|
|
1114
|
+
const sources = affectedSources(state, root, command);
|
|
1115
|
+
const authored = authoredSources(state.snapshot);
|
|
1116
|
+
const published = publishedSources(state.snapshot);
|
|
1224
1117
|
const plans = [];
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1118
|
+
let nextAuthored = [...authored];
|
|
1119
|
+
let nextPublished = [...published];
|
|
1120
|
+
switch (command.action) {
|
|
1121
|
+
case "document.move": {
|
|
1122
|
+
const next = compilationSource$2(root, command.input.placement);
|
|
1123
|
+
nextAuthored = replaceSource$1(nextAuthored, next);
|
|
1229
1124
|
plans.push({
|
|
1230
|
-
...command.action === "document.remove" ? {
|
|
1231
|
-
trashBatchId: root.version,
|
|
1232
|
-
title: page?.title,
|
|
1233
|
-
path: page?.path
|
|
1234
|
-
} : void 0,
|
|
1235
1125
|
action: command.action,
|
|
1236
|
-
documentId:
|
|
1237
|
-
expectedVersion:
|
|
1238
|
-
markdown:
|
|
1239
|
-
|
|
1126
|
+
documentId: root.documentId,
|
|
1127
|
+
expectedVersion: root.version,
|
|
1128
|
+
markdown: root.markdown,
|
|
1129
|
+
placement: command.input.placement,
|
|
1130
|
+
publishedVersion: root.publishedVersion
|
|
1240
1131
|
});
|
|
1241
|
-
|
|
1132
|
+
break;
|
|
1242
1133
|
}
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
plans.push({
|
|
1271
|
-
action: "document.create",
|
|
1272
|
-
documentId,
|
|
1273
|
-
markdown,
|
|
1274
|
-
sourcePath
|
|
1275
|
-
});
|
|
1276
|
-
} else plans.push({
|
|
1277
|
-
action: "document.move",
|
|
1278
|
-
documentId: source.documentId,
|
|
1279
|
-
expectedVersion: source.version,
|
|
1280
|
-
markdown,
|
|
1281
|
-
sourcePath,
|
|
1282
|
-
publishedVersion: source.publishedVersion
|
|
1283
|
-
});
|
|
1284
|
-
}
|
|
1285
|
-
const changed = new Set(plans.map((plan) => plan.documentId));
|
|
1286
|
-
const nextSources = authoredSources(state.snapshot).filter((source) => !changed.has(source.documentId));
|
|
1287
|
-
if (command.action !== "document.remove") for (const plan of plans) {
|
|
1288
|
-
if (nextSources.some((source) => source.sourcePath === plan.sourcePath)) return yield* new DocumentPathConflict({ sourcePath: plan.sourcePath });
|
|
1289
|
-
nextSources.push({
|
|
1290
|
-
documentId: plan.documentId,
|
|
1291
|
-
draft: true,
|
|
1292
|
-
markdown: plan.markdown,
|
|
1293
|
-
sourcePath: plan.sourcePath
|
|
1294
|
-
});
|
|
1295
|
-
}
|
|
1296
|
-
if (command.action === "document.move" || command.action === "document.duplicate") {
|
|
1297
|
-
const preliminary = yield* engine.compileAll({
|
|
1298
|
-
sources: nextSources,
|
|
1299
|
-
previous: state.authored
|
|
1300
|
-
});
|
|
1301
|
-
const destinations = /* @__PURE__ */ new Map();
|
|
1302
|
-
for (let index = 0; index < sources.length; index++) {
|
|
1303
|
-
const original = sources[index];
|
|
1304
|
-
const plan = plans[index];
|
|
1305
|
-
const oldPage = original && state.authoredById.get(original.documentId);
|
|
1306
|
-
const newPage = plan && preliminary.documents.find((document) => document.id === plan.documentId);
|
|
1307
|
-
if (oldPage && newPage) destinations.set(oldPage.path, newPage.path);
|
|
1134
|
+
case "document.duplicate": {
|
|
1135
|
+
const ids = /* @__PURE__ */ new Map();
|
|
1136
|
+
for (const source of sources) ids.set(source.documentId, yield* command.nextDocumentId);
|
|
1137
|
+
for (const source of sources) {
|
|
1138
|
+
const documentId = ids.get(source.documentId);
|
|
1139
|
+
if (!documentId) return yield* Effect.die(/* @__PURE__ */ new Error("Duplicate document identity was not allocated."));
|
|
1140
|
+
const placement = duplicatePlacement(source, root, command.input.placement, ids);
|
|
1141
|
+
const identity = {
|
|
1142
|
+
...source.identity,
|
|
1143
|
+
documentId,
|
|
1144
|
+
...command.input.locale === void 0 ? void 0 : { locale: command.input.locale }
|
|
1145
|
+
};
|
|
1146
|
+
const next = {
|
|
1147
|
+
draft: true,
|
|
1148
|
+
identity,
|
|
1149
|
+
markdown: source.markdown,
|
|
1150
|
+
placement
|
|
1151
|
+
};
|
|
1152
|
+
nextAuthored.push(next);
|
|
1153
|
+
plans.push({
|
|
1154
|
+
action: "document.create",
|
|
1155
|
+
identity,
|
|
1156
|
+
markdown: source.markdown,
|
|
1157
|
+
placement
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
break;
|
|
1308
1161
|
}
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
const
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1162
|
+
case "document.remove": {
|
|
1163
|
+
const ids = new Set(sources.map((source) => source.documentId));
|
|
1164
|
+
nextAuthored = nextAuthored.filter((source) => !ids.has(source.identity.documentId));
|
|
1165
|
+
nextPublished = nextPublished.filter((source) => !ids.has(source.identity.documentId));
|
|
1166
|
+
for (const source of sources) {
|
|
1167
|
+
const page = state.authoredById.get(source.documentId);
|
|
1168
|
+
plans.push({
|
|
1169
|
+
action: command.action,
|
|
1170
|
+
trashBatchId: root.version,
|
|
1171
|
+
title: page?.title,
|
|
1172
|
+
path: page?.path,
|
|
1173
|
+
documentId: source.documentId,
|
|
1174
|
+
expectedVersion: source.version,
|
|
1175
|
+
markdown: source.markdown,
|
|
1176
|
+
placement: source.placement
|
|
1177
|
+
});
|
|
1178
|
+
}
|
|
1179
|
+
break;
|
|
1180
|
+
}
|
|
1181
|
+
case "document.undelete": for (const source of sources) {
|
|
1182
|
+
const next = compilationSource$2(source, source.placement);
|
|
1183
|
+
nextAuthored.push(next);
|
|
1184
|
+
plans.push({
|
|
1185
|
+
action: command.action,
|
|
1325
1186
|
documentId: source.documentId,
|
|
1326
1187
|
expectedVersion: source.version,
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
publishedVersion: source.publishedVersion
|
|
1188
|
+
markdown: source.markdown,
|
|
1189
|
+
placement: source.placement
|
|
1330
1190
|
});
|
|
1331
1191
|
}
|
|
1332
|
-
for (const plan of plans) {
|
|
1333
|
-
const index = nextSources.findIndex((source) => source.documentId === plan.documentId);
|
|
1334
|
-
const updated = {
|
|
1335
|
-
documentId: plan.documentId,
|
|
1336
|
-
sourcePath: plan.sourcePath,
|
|
1337
|
-
markdown: plan.markdown,
|
|
1338
|
-
draft: true
|
|
1339
|
-
};
|
|
1340
|
-
if (index >= 0) nextSources[index] = updated;
|
|
1341
|
-
else nextSources.push(updated);
|
|
1342
|
-
}
|
|
1343
1192
|
}
|
|
1344
1193
|
const first = plans[0];
|
|
1345
1194
|
if (!first) return yield* Effect.die(/* @__PURE__ */ new Error("Empty subtree mutation."));
|
|
1346
1195
|
return {
|
|
1347
|
-
authored: yield* compileValidCatalog(engine,
|
|
1348
|
-
published:
|
|
1196
|
+
authored: yield* compileValidCatalog(engine, nextAuthored, state.authored),
|
|
1197
|
+
published: yield* compileValidCatalog(engine, nextPublished, state.published),
|
|
1349
1198
|
commitPlan: first,
|
|
1350
1199
|
additionalPlans: plans.slice(1)
|
|
1351
1200
|
};
|
|
1352
1201
|
});
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1202
|
+
function affectedSources(state, root, command) {
|
|
1203
|
+
if (command.action === "document.undelete") {
|
|
1204
|
+
if (!("deletedAt" in root)) return [];
|
|
1205
|
+
return state.snapshot.deleted.filter((source) => source.documentId === root.documentId || root.trashBatchId !== void 0 && source.trashBatchId === root.trashBatchId);
|
|
1206
|
+
}
|
|
1207
|
+
const ids = new Set(command.action === "document.duplicate" && !command.input.includeChildren ? [root.documentId] : subtreeIds(state, root.documentId));
|
|
1208
|
+
return [root, ...state.snapshot.active.filter((source) => source.documentId !== root.documentId && ids.has(source.documentId))];
|
|
1209
|
+
}
|
|
1210
|
+
function compilationSource$2(source, placement) {
|
|
1211
|
+
return {
|
|
1212
|
+
draft: true,
|
|
1213
|
+
identity: source.identity,
|
|
1214
|
+
markdown: source.markdown,
|
|
1215
|
+
placement
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
function duplicatePlacement(source, root, rootPlacement, ids) {
|
|
1219
|
+
if (source.documentId === root.documentId) return rootPlacement;
|
|
1220
|
+
if (source.placement.kind === "home") return source.placement;
|
|
1221
|
+
const parentDocumentId = ids.get(source.placement.parentDocumentId);
|
|
1222
|
+
return parentDocumentId === void 0 ? source.placement : {
|
|
1223
|
+
...source.placement,
|
|
1224
|
+
parentDocumentId
|
|
1225
|
+
};
|
|
1226
|
+
}
|
|
1227
|
+
function replaceSource$1(sources, source) {
|
|
1228
|
+
return [...sources.filter((candidate) => candidate.identity.documentId !== source.identity.documentId), source];
|
|
1361
1229
|
}
|
|
1362
1230
|
|
|
1363
1231
|
//#endregion
|
|
@@ -1370,43 +1238,32 @@ const prepareDocumentMutation = Effect.fn("DocumentLifecycle.prepare")(function*
|
|
|
1370
1238
|
const published = publishedSources(state.snapshot);
|
|
1371
1239
|
switch (command.action) {
|
|
1372
1240
|
case "document.create": {
|
|
1373
|
-
|
|
1374
|
-
const nextAuthored = [...authored, {
|
|
1375
|
-
documentId: command.documentId,
|
|
1376
|
-
draft: true,
|
|
1377
|
-
markdown: command.markdown,
|
|
1378
|
-
sourcePath: command.sourcePath
|
|
1379
|
-
}];
|
|
1241
|
+
const source = compilationSource$1(command.identity, command.placement, command.markdown, true);
|
|
1380
1242
|
return PreparedDocumentMutation.Commit({
|
|
1381
|
-
authored: yield* compileValidCatalog(engine,
|
|
1243
|
+
authored: yield* compileValidCatalog(engine, [...authored, source], state.authored),
|
|
1382
1244
|
published: state.published,
|
|
1383
1245
|
commitPlan: {
|
|
1384
1246
|
action: command.action,
|
|
1385
|
-
|
|
1247
|
+
identity: command.identity,
|
|
1386
1248
|
markdown: command.markdown,
|
|
1387
|
-
|
|
1249
|
+
placement: command.placement
|
|
1388
1250
|
}
|
|
1389
1251
|
});
|
|
1390
1252
|
}
|
|
1391
1253
|
case "document.update": {
|
|
1392
1254
|
const current = yield* requireActive(state, command.input.documentId);
|
|
1393
1255
|
yield* requireVersion(current, command.input.expectedVersion);
|
|
1394
|
-
const
|
|
1395
|
-
documentId: current.documentId,
|
|
1396
|
-
draft: true,
|
|
1397
|
-
markdown: command.input.markdown,
|
|
1398
|
-
sourcePath: current.sourcePath
|
|
1399
|
-
});
|
|
1256
|
+
const source = compilationSource$1(current.identity, current.placement, command.input.markdown, true);
|
|
1400
1257
|
return PreparedDocumentMutation.Commit({
|
|
1401
|
-
authored: yield* compileValidCatalog(engine,
|
|
1258
|
+
authored: yield* compileValidCatalog(engine, replaceSource(authored, source), state.authored),
|
|
1402
1259
|
published: state.published,
|
|
1403
1260
|
commitPlan: {
|
|
1404
1261
|
action: command.action,
|
|
1405
1262
|
documentId: current.documentId,
|
|
1406
1263
|
expectedVersion: command.input.expectedVersion,
|
|
1407
1264
|
markdown: command.input.markdown,
|
|
1408
|
-
|
|
1409
|
-
|
|
1265
|
+
placement: current.placement,
|
|
1266
|
+
publishedVersion: current.publishedVersion
|
|
1410
1267
|
}
|
|
1411
1268
|
});
|
|
1412
1269
|
}
|
|
@@ -1414,69 +1271,47 @@ const prepareDocumentMutation = Effect.fn("DocumentLifecycle.prepare")(function*
|
|
|
1414
1271
|
const current = yield* requireActive(state, command.input.documentId);
|
|
1415
1272
|
yield* requireVersion(current, command.input.expectedVersion);
|
|
1416
1273
|
const historical = yield* repository.revision(current.documentId, command.input.revisionId);
|
|
1417
|
-
const
|
|
1418
|
-
documentId: current.documentId,
|
|
1419
|
-
draft: true,
|
|
1420
|
-
markdown: historical.markdown,
|
|
1421
|
-
sourcePath: current.sourcePath
|
|
1422
|
-
});
|
|
1274
|
+
const source = compilationSource$1(current.identity, historical.placement, historical.markdown, true);
|
|
1423
1275
|
return PreparedDocumentMutation.Commit({
|
|
1424
|
-
authored: yield* compileValidCatalog(engine,
|
|
1276
|
+
authored: yield* compileValidCatalog(engine, replaceSource(authored, source), state.authored),
|
|
1425
1277
|
published: state.published,
|
|
1426
1278
|
commitPlan: {
|
|
1427
1279
|
action: command.action,
|
|
1428
1280
|
documentId: current.documentId,
|
|
1429
1281
|
expectedVersion: command.input.expectedVersion,
|
|
1430
1282
|
markdown: historical.markdown,
|
|
1283
|
+
placement: historical.placement,
|
|
1431
1284
|
publishedVersion: current.publishedVersion,
|
|
1432
|
-
revisionId: command.input.revisionId
|
|
1433
|
-
sourcePath: current.sourcePath
|
|
1285
|
+
revisionId: command.input.revisionId
|
|
1434
1286
|
}
|
|
1435
1287
|
});
|
|
1436
1288
|
}
|
|
1437
1289
|
case "document.unpublish": {
|
|
1438
1290
|
const current = yield* requireActive(state, command.input.documentId);
|
|
1439
1291
|
yield* requireVersion(current, command.input.expectedVersion);
|
|
1292
|
+
const ids = new Set(subtreeIds(state, current.documentId, "published"));
|
|
1293
|
+
const plans = state.snapshot.active.filter((source) => ids.has(source.documentId) && source.publishedVersion !== void 0).map((source) => ({
|
|
1294
|
+
action: "document.unpublish",
|
|
1295
|
+
documentId: source.documentId,
|
|
1296
|
+
expectedVersion: source.version,
|
|
1297
|
+
markdown: source.markdown,
|
|
1298
|
+
placement: source.placement,
|
|
1299
|
+
revisionId: source.revisionId
|
|
1300
|
+
}));
|
|
1301
|
+
const first = plans[0];
|
|
1302
|
+
if (!first) return unchanged(state, current, "document.unpublish");
|
|
1440
1303
|
return PreparedDocumentMutation.Commit({
|
|
1441
|
-
authored: yield* compileValidCatalog(engine,
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
sourcePath: current.sourcePath
|
|
1446
|
-
}), state.authored),
|
|
1447
|
-
published: yield* compileValidCatalog(engine, withoutDocument(published, current.documentId), state.published),
|
|
1448
|
-
commitPlan: {
|
|
1449
|
-
action: command.action,
|
|
1450
|
-
documentId: current.documentId,
|
|
1451
|
-
expectedVersion: current.version,
|
|
1452
|
-
markdown: current.markdown,
|
|
1453
|
-
sourcePath: current.sourcePath,
|
|
1454
|
-
revisionId: current.revisionId
|
|
1455
|
-
}
|
|
1304
|
+
authored: yield* compileValidCatalog(engine, authored.map((source) => ids.has(source.identity.documentId) ? Object.assign({}, source, { draft: true }) : source), state.authored),
|
|
1305
|
+
published: yield* compileValidCatalog(engine, published.filter((source) => !ids.has(source.identity.documentId)), state.published),
|
|
1306
|
+
commitPlan: first,
|
|
1307
|
+
additionalPlans: plans.slice(1)
|
|
1456
1308
|
});
|
|
1457
1309
|
}
|
|
1458
1310
|
case "document.publish": {
|
|
1459
1311
|
const current = yield* requireActive(state, command.input.documentId);
|
|
1460
1312
|
yield* requireVersion(current, command.input.expectedVersion);
|
|
1461
|
-
if (current.publishedVersion === current.version)
|
|
1462
|
-
|
|
1463
|
-
const result = {
|
|
1464
|
-
action: "document.publish",
|
|
1465
|
-
affectedDocumentIds: [current.documentId],
|
|
1466
|
-
documentId: current.documentId,
|
|
1467
|
-
generation: state.snapshot.generation,
|
|
1468
|
-
revisionId: current.revisionId,
|
|
1469
|
-
sourcePath: current.sourcePath,
|
|
1470
|
-
version: current.version
|
|
1471
|
-
};
|
|
1472
|
-
return PreparedDocumentMutation.Unchanged({ result: DocumentMutationResult.make(Object.assign(result, entry === void 0 ? void 0 : { entry })) });
|
|
1473
|
-
}
|
|
1474
|
-
const source = {
|
|
1475
|
-
documentId: current.documentId,
|
|
1476
|
-
draft: false,
|
|
1477
|
-
markdown: current.markdown,
|
|
1478
|
-
sourcePath: current.sourcePath
|
|
1479
|
-
};
|
|
1313
|
+
if (current.publishedVersion === current.version) return unchanged(state, current, "document.publish");
|
|
1314
|
+
const source = compilationSource$1(current.identity, current.placement, current.markdown, false);
|
|
1480
1315
|
return PreparedDocumentMutation.Commit({
|
|
1481
1316
|
authored: yield* compileValidCatalog(engine, replaceSource(authored, source), state.authored),
|
|
1482
1317
|
published: yield* compileValidCatalog(engine, replaceSource(published, source), state.published),
|
|
@@ -1485,8 +1320,8 @@ const prepareDocumentMutation = Effect.fn("DocumentLifecycle.prepare")(function*
|
|
|
1485
1320
|
documentId: current.documentId,
|
|
1486
1321
|
expectedVersion: command.input.expectedVersion,
|
|
1487
1322
|
markdown: current.markdown,
|
|
1488
|
-
|
|
1489
|
-
|
|
1323
|
+
placement: current.placement,
|
|
1324
|
+
revisionId: current.revisionId
|
|
1490
1325
|
}
|
|
1491
1326
|
});
|
|
1492
1327
|
}
|
|
@@ -1495,14 +1330,30 @@ const prepareDocumentMutation = Effect.fn("DocumentLifecycle.prepare")(function*
|
|
|
1495
1330
|
const validateDocumentUpdate = Effect.fn("DocumentLifecycle.validateUpdate")(function* (engine, state, input) {
|
|
1496
1331
|
const current = yield* requireActive(state, input.documentId);
|
|
1497
1332
|
yield* requireVersion(current, input.expectedVersion);
|
|
1498
|
-
const source =
|
|
1499
|
-
|
|
1500
|
-
draft: true,
|
|
1501
|
-
markdown: input.markdown,
|
|
1502
|
-
sourcePath: current.sourcePath
|
|
1503
|
-
};
|
|
1504
|
-
return yield* validateDocumentSources(engine, replaceSource(authoredSources(state.snapshot), source), current.sourcePath, state.authored);
|
|
1333
|
+
const source = compilationSource$1(current.identity, current.placement, input.markdown, true);
|
|
1334
|
+
return yield* validateDocumentSources(engine, replaceSource(authoredSources(state.snapshot), source), current.documentId, state.authored);
|
|
1505
1335
|
});
|
|
1336
|
+
function compilationSource$1(identity, placement, markdown, draft) {
|
|
1337
|
+
return {
|
|
1338
|
+
draft,
|
|
1339
|
+
identity,
|
|
1340
|
+
markdown,
|
|
1341
|
+
placement
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
function unchanged(state, current, action) {
|
|
1345
|
+
const entry = entryById(state, current.documentId);
|
|
1346
|
+
const result = DocumentMutationResult.make({
|
|
1347
|
+
action,
|
|
1348
|
+
affectedDocumentIds: [current.documentId],
|
|
1349
|
+
documentId: current.documentId,
|
|
1350
|
+
generation: state.snapshot.generation,
|
|
1351
|
+
revisionId: current.revisionId,
|
|
1352
|
+
version: current.version,
|
|
1353
|
+
...entry === void 0 ? void 0 : { entry }
|
|
1354
|
+
});
|
|
1355
|
+
return PreparedDocumentMutation.Unchanged({ result });
|
|
1356
|
+
}
|
|
1506
1357
|
function requireActive(state, documentId) {
|
|
1507
1358
|
const source = state.activeById.get(documentId);
|
|
1508
1359
|
return source ? Effect.succeed(source) : Effect.fail(new DocumentNotFound({ documentId }));
|
|
@@ -1514,14 +1365,8 @@ function requireVersion(source, expectedVersion) {
|
|
|
1514
1365
|
expectedVersion
|
|
1515
1366
|
}));
|
|
1516
1367
|
}
|
|
1517
|
-
function ensurePathAvailable(state, sourcePath, exceptDocumentId) {
|
|
1518
|
-
return state.snapshot.active.some((source) => source.sourcePath === sourcePath && source.documentId !== exceptDocumentId) ? Effect.fail(new DocumentPathConflict({ sourcePath })) : Effect.void;
|
|
1519
|
-
}
|
|
1520
1368
|
function replaceSource(sources, source) {
|
|
1521
|
-
return [...sources.filter((candidate) => candidate.documentId !== source.documentId), source];
|
|
1522
|
-
}
|
|
1523
|
-
function withoutDocument(sources, documentId) {
|
|
1524
|
-
return sources.filter((source) => source.documentId !== documentId);
|
|
1369
|
+
return [...sources.filter((candidate) => candidate.identity.documentId !== source.identity.documentId), source];
|
|
1525
1370
|
}
|
|
1526
1371
|
|
|
1527
1372
|
//#endregion
|
|
@@ -1540,108 +1385,109 @@ function toMediaReference(reference) {
|
|
|
1540
1385
|
...reference.target.mediaId ? { mediaId: reference.target.mediaId } : void 0,
|
|
1541
1386
|
nodePath: reference.nodePath,
|
|
1542
1387
|
objectKey: MediaObjectKey.make(reference.target.key),
|
|
1543
|
-
|
|
1544
|
-
sourcePath: reference.source.sourcePath
|
|
1388
|
+
route: reference.source.route
|
|
1545
1389
|
});
|
|
1546
1390
|
}
|
|
1547
1391
|
function referenceIdentity(reference) {
|
|
1548
|
-
return `${reference.documentId}:${reference.
|
|
1392
|
+
return `${reference.documentId}:${reference.nodePath.join(".")}:${reference.objectKey}`;
|
|
1549
1393
|
}
|
|
1550
1394
|
|
|
1551
1395
|
//#endregion
|
|
1552
1396
|
//#region ../server/src/internal/documents/content-transfer.ts
|
|
1553
|
-
/**
|
|
1554
|
-
const planContentTransfer = Effect.fn("ContentTransfer.plan")(function* (engine, state, input, crypto) {
|
|
1555
|
-
const
|
|
1397
|
+
/** Import/export adapter planning. File paths are consumed here and never enter document state. */
|
|
1398
|
+
const planContentTransfer = Effect.fn("ContentTransfer.plan")(function* (engine, configuration, state, input, crypto) {
|
|
1399
|
+
const incoming = yield* resolveSources(configuration, state, input.sources, crypto);
|
|
1400
|
+
const currentById = new Map(state.snapshot.active.map((source) => [source.documentId, source]));
|
|
1556
1401
|
const seen = /* @__PURE__ */ new Set();
|
|
1557
1402
|
const commitPlans = [];
|
|
1558
1403
|
const entries = [];
|
|
1559
|
-
const authored = new Map(authoredSources(state.snapshot).map((source) => [source.
|
|
1560
|
-
const published = new Map(publishedSources(state.snapshot).map((source) => [source.
|
|
1404
|
+
const authored = new Map(authoredSources(state.snapshot).map((source) => [source.identity.documentId, source]));
|
|
1405
|
+
const published = new Map(publishedSources(state.snapshot).map((source) => [source.identity.documentId, source]));
|
|
1561
1406
|
const now = yield* DateTime.now;
|
|
1562
1407
|
let created = 0;
|
|
1563
1408
|
let updated = 0;
|
|
1564
1409
|
let publishedCount = 0;
|
|
1565
1410
|
let unchanged = 0;
|
|
1566
|
-
for (const source of
|
|
1567
|
-
if (seen.has(source.
|
|
1568
|
-
seen.add(source.
|
|
1569
|
-
const current =
|
|
1411
|
+
for (const source of incoming) {
|
|
1412
|
+
if (seen.has(source.filePath)) return yield* new ContentTransferConflict({ message: `Duplicate content file path: ${source.filePath}` });
|
|
1413
|
+
seen.add(source.filePath);
|
|
1414
|
+
const current = currentById.get(source.identity.documentId);
|
|
1570
1415
|
const shouldPublish = input.publish && source.published;
|
|
1571
|
-
const
|
|
1416
|
+
const shouldUnpublish = input.publish && !source.published && current?.publishedVersion !== void 0;
|
|
1417
|
+
const identityConflict = current !== void 0 && !sameIdentity(current.identity, source.identity);
|
|
1418
|
+
const changed = current !== void 0 && (current.markdown !== source.markdown || !samePlacement(current.placement, source.placement) || source.revisionId !== void 0 && current.revisionId !== source.revisionId);
|
|
1419
|
+
const action = identityConflict ? "conflict" : !current ? "create" : changed ? input.overwrite ? "update" : "conflict" : shouldPublish && current.publishedVersion !== current.version ? "publish" : shouldUnpublish ? "unpublish" : "unchanged";
|
|
1572
1420
|
entries.push({
|
|
1573
|
-
|
|
1421
|
+
filePath: source.filePath,
|
|
1574
1422
|
action,
|
|
1575
1423
|
currentRevisionId: current?.revisionId ?? null
|
|
1576
1424
|
});
|
|
1577
1425
|
if (action === "create" || action === "update") {
|
|
1578
|
-
const documentId = current?.documentId ?? DocumentId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie));
|
|
1579
1426
|
if (current) {
|
|
1580
1427
|
commitPlans.push({
|
|
1581
1428
|
action: "document.update",
|
|
1582
|
-
documentId,
|
|
1429
|
+
documentId: current.documentId,
|
|
1583
1430
|
expectedVersion: current.version,
|
|
1584
1431
|
markdown: source.markdown,
|
|
1432
|
+
placement: source.placement,
|
|
1585
1433
|
publish: shouldPublish,
|
|
1586
1434
|
publishedVersion: current.publishedVersion,
|
|
1587
|
-
|
|
1435
|
+
...source.revisionId === void 0 ? void 0 : { newRevisionId: source.revisionId },
|
|
1436
|
+
...shouldUnpublish ? { unpublish: true } : void 0
|
|
1588
1437
|
});
|
|
1589
1438
|
updated++;
|
|
1590
1439
|
} else {
|
|
1591
1440
|
commitPlans.push({
|
|
1592
1441
|
action: "document.create",
|
|
1593
|
-
|
|
1442
|
+
identity: source.identity,
|
|
1594
1443
|
markdown: source.markdown,
|
|
1444
|
+
placement: source.placement,
|
|
1595
1445
|
publish: shouldPublish,
|
|
1596
|
-
|
|
1446
|
+
...source.revisionId === void 0 ? void 0 : { newRevisionId: source.revisionId }
|
|
1597
1447
|
});
|
|
1598
1448
|
created++;
|
|
1599
1449
|
}
|
|
1600
1450
|
if (shouldPublish) publishedCount++;
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
markdown: source.markdown,
|
|
1605
|
-
sourcePath: source.sourcePath
|
|
1606
|
-
});
|
|
1607
|
-
if (shouldPublish) published.set(source.sourcePath, {
|
|
1608
|
-
documentId,
|
|
1451
|
+
const compiled = compilationSource(source, !shouldPublish);
|
|
1452
|
+
authored.set(source.identity.documentId, compiled);
|
|
1453
|
+
if (shouldPublish) published.set(source.identity.documentId, Object.assign({}, compiled, {
|
|
1609
1454
|
draft: false,
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
});
|
|
1455
|
+
publishedAt: now
|
|
1456
|
+
}));
|
|
1457
|
+
else if (shouldUnpublish) published.delete(source.identity.documentId);
|
|
1614
1458
|
} else if (action === "publish" && current) {
|
|
1615
1459
|
commitPlans.push({
|
|
1616
1460
|
action: "document.publish",
|
|
1617
1461
|
documentId: current.documentId,
|
|
1618
1462
|
expectedVersion: current.version,
|
|
1619
1463
|
markdown: current.markdown,
|
|
1620
|
-
|
|
1621
|
-
|
|
1464
|
+
placement: current.placement,
|
|
1465
|
+
revisionId: current.revisionId
|
|
1622
1466
|
});
|
|
1623
1467
|
publishedCount++;
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
published.set(source.sourcePath, {
|
|
1468
|
+
const compiled = compilationSource(source, false);
|
|
1469
|
+
authored.set(source.identity.documentId, compiled);
|
|
1470
|
+
published.set(source.identity.documentId, Object.assign({}, compiled, { publishedAt: now }));
|
|
1471
|
+
} else if (action === "unpublish" && current) {
|
|
1472
|
+
commitPlans.push({
|
|
1473
|
+
action: "document.unpublish",
|
|
1631
1474
|
documentId: current.documentId,
|
|
1632
|
-
|
|
1475
|
+
expectedVersion: current.version,
|
|
1633
1476
|
markdown: current.markdown,
|
|
1634
|
-
|
|
1635
|
-
|
|
1477
|
+
placement: current.placement,
|
|
1478
|
+
revisionId: current.revisionId
|
|
1636
1479
|
});
|
|
1480
|
+
published.delete(source.identity.documentId);
|
|
1637
1481
|
} else if (action === "unchanged") unchanged++;
|
|
1638
1482
|
}
|
|
1639
|
-
const
|
|
1640
|
-
const
|
|
1483
|
+
const firstDocumentId = incoming[0]?.identity.documentId;
|
|
1484
|
+
const publishedValues = [...published.values()];
|
|
1485
|
+
const publishedDocumentId = publishedValues[0]?.identity.documentId;
|
|
1486
|
+
const authoredValidation = firstDocumentId ? yield* validateDocumentSources(engine, [...authored.values()], firstDocumentId, state.authored) : DocumentValidationResult.make({
|
|
1641
1487
|
issues: [],
|
|
1642
1488
|
valid: true
|
|
1643
1489
|
});
|
|
1644
|
-
const publishedValidation = input.publish &&
|
|
1490
|
+
const publishedValidation = input.publish && publishedDocumentId ? yield* validateDocumentSources(engine, publishedValues, publishedDocumentId, state.published) : DocumentValidationResult.make({
|
|
1645
1491
|
issues: [],
|
|
1646
1492
|
valid: true
|
|
1647
1493
|
});
|
|
@@ -1654,7 +1500,7 @@ const planContentTransfer = Effect.fn("ContentTransfer.plan")(function* (engine,
|
|
|
1654
1500
|
valid: authoredValidation.valid && !entries.some((entry) => entry.action === "conflict") && !issues.some((issue) => issue.severity === "error")
|
|
1655
1501
|
}),
|
|
1656
1502
|
authoredSources: [...authored.values()],
|
|
1657
|
-
publishedSources:
|
|
1503
|
+
publishedSources: publishedValues,
|
|
1658
1504
|
commitPlans,
|
|
1659
1505
|
counts: {
|
|
1660
1506
|
created,
|
|
@@ -1664,6 +1510,116 @@ const planContentTransfer = Effect.fn("ContentTransfer.plan")(function* (engine,
|
|
|
1664
1510
|
}
|
|
1665
1511
|
};
|
|
1666
1512
|
});
|
|
1513
|
+
function resolveSources(configuration, state, sources, crypto) {
|
|
1514
|
+
return Effect.gen(function* () {
|
|
1515
|
+
const resolved = [];
|
|
1516
|
+
const indexed = [];
|
|
1517
|
+
const unindexed = [];
|
|
1518
|
+
for (const source of sources) {
|
|
1519
|
+
if (source.identity && source.placement) {
|
|
1520
|
+
indexed.push(Object.assign({}, source, {
|
|
1521
|
+
identity: source.identity,
|
|
1522
|
+
placement: source.placement
|
|
1523
|
+
}));
|
|
1524
|
+
continue;
|
|
1525
|
+
}
|
|
1526
|
+
if (source.identity || source.placement) return yield* new ContentTransferConflict({ message: `${source.filePath}: indexed content must include both identity and placement.` });
|
|
1527
|
+
unindexed.push(source);
|
|
1528
|
+
}
|
|
1529
|
+
resolved.push(...indexed);
|
|
1530
|
+
const byPlacement = placementIndex([...state.snapshot.active, ...indexed]);
|
|
1531
|
+
const pending = unindexed.map((source) => ({
|
|
1532
|
+
inferred: inferFilePlacement(configuration, source.filePath),
|
|
1533
|
+
source
|
|
1534
|
+
})).toSorted((left, right) => Number(right.inferred.home) - Number(left.inferred.home) || left.inferred.segments.length - right.inferred.segments.length || left.source.filePath.localeCompare(right.source.filePath));
|
|
1535
|
+
for (const { inferred, source } of pending) {
|
|
1536
|
+
const scope = `${inferred.collection}:${inferred.locale ?? ""}`;
|
|
1537
|
+
const key = `${scope}:${inferred.segments.join("/")}`;
|
|
1538
|
+
let identity = byPlacement.get(key);
|
|
1539
|
+
if (!identity) identity = {
|
|
1540
|
+
collection: inferred.collection,
|
|
1541
|
+
documentId: DocumentId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie)),
|
|
1542
|
+
...inferred.locale === void 0 ? void 0 : { locale: inferred.locale }
|
|
1543
|
+
};
|
|
1544
|
+
const placement = inferred.home ? { kind: "home" } : {
|
|
1545
|
+
kind: "entry",
|
|
1546
|
+
parentDocumentId: byPlacement.get(`${scope}:${inferred.segments.slice(0, -1).join("/")}`)?.documentId ?? (yield* new ContentTransferConflict({ message: `${source.filePath}: parent document is missing from the import and target catalog.` })),
|
|
1547
|
+
slug: Slug.make(inferred.segments.at(-1) ?? "")
|
|
1548
|
+
};
|
|
1549
|
+
const value = Object.assign({}, source, {
|
|
1550
|
+
identity,
|
|
1551
|
+
placement
|
|
1552
|
+
});
|
|
1553
|
+
resolved.push(value);
|
|
1554
|
+
byPlacement.set(key, identity);
|
|
1555
|
+
}
|
|
1556
|
+
return resolved;
|
|
1557
|
+
});
|
|
1558
|
+
}
|
|
1559
|
+
function inferFilePlacement(configuration, filePath) {
|
|
1560
|
+
const segments = filePath.replace(/\.(?:md|mdc)$/iu, "").split("/");
|
|
1561
|
+
let locale = configuration.locales?.locales.find((candidate) => candidate === segments[0]);
|
|
1562
|
+
if (locale) segments.shift();
|
|
1563
|
+
else locale = configuration.locales?.defaultLocale;
|
|
1564
|
+
let collection = configuration.types[0]?.collection;
|
|
1565
|
+
const configured = configuration.types.find((candidate) => candidate.collection === segments[0]);
|
|
1566
|
+
if (configured) {
|
|
1567
|
+
collection = configured.collection;
|
|
1568
|
+
segments.shift();
|
|
1569
|
+
}
|
|
1570
|
+
if (!collection) throw new Error("Content import needs at least one configured collection.");
|
|
1571
|
+
const home = segments.length === 1 && segments[0]?.toLocaleLowerCase() === "index";
|
|
1572
|
+
const normalized = home ? [] : segments.at(-1)?.toLocaleLowerCase() === "index" ? segments.slice(0, -1) : segments;
|
|
1573
|
+
return {
|
|
1574
|
+
collection,
|
|
1575
|
+
home,
|
|
1576
|
+
locale,
|
|
1577
|
+
segments: normalized
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
function placementIndex(sources) {
|
|
1581
|
+
const index = /* @__PURE__ */ new Map();
|
|
1582
|
+
const byId = new Map(sources.map((source) => [source.identity.documentId, source]));
|
|
1583
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
1584
|
+
const segmentsFor = (documentId, ancestors) => {
|
|
1585
|
+
const cached = resolved.get(documentId);
|
|
1586
|
+
if (cached) return cached;
|
|
1587
|
+
if (ancestors.has(documentId)) return void 0;
|
|
1588
|
+
const source = byId.get(documentId);
|
|
1589
|
+
if (!source) return void 0;
|
|
1590
|
+
if (source.placement.kind === "home") {
|
|
1591
|
+
resolved.set(documentId, []);
|
|
1592
|
+
return [];
|
|
1593
|
+
}
|
|
1594
|
+
const parent = segmentsFor(source.placement.parentDocumentId, /* @__PURE__ */ new Set([...ancestors, documentId]));
|
|
1595
|
+
if (!parent) return void 0;
|
|
1596
|
+
const segments = [...parent, source.placement.slug];
|
|
1597
|
+
resolved.set(documentId, segments);
|
|
1598
|
+
return segments;
|
|
1599
|
+
};
|
|
1600
|
+
for (const source of sources) {
|
|
1601
|
+
const segments = segmentsFor(source.identity.documentId, /* @__PURE__ */ new Set());
|
|
1602
|
+
if (segments) index.set(placementIndexKey(source.identity, segments), source.identity);
|
|
1603
|
+
}
|
|
1604
|
+
return index;
|
|
1605
|
+
}
|
|
1606
|
+
function placementIndexKey(identity, segments) {
|
|
1607
|
+
return `${identity.collection}:${identity.locale ?? ""}:${segments.join("/")}`;
|
|
1608
|
+
}
|
|
1609
|
+
function compilationSource(source, draft) {
|
|
1610
|
+
return {
|
|
1611
|
+
draft,
|
|
1612
|
+
identity: source.identity,
|
|
1613
|
+
markdown: source.markdown,
|
|
1614
|
+
placement: source.placement
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
function samePlacement(left, right) {
|
|
1618
|
+
return left.kind === right.kind && (left.kind === "home" || right.kind === "entry" && left.parentDocumentId === right.parentDocumentId && left.slug === right.slug);
|
|
1619
|
+
}
|
|
1620
|
+
function sameIdentity(left, right) {
|
|
1621
|
+
return left.documentId === right.documentId && left.collection === right.collection && left.locale === right.locale;
|
|
1622
|
+
}
|
|
1667
1623
|
|
|
1668
1624
|
//#endregion
|
|
1669
1625
|
//#region ../server/src/internal/documents/document-mutation.ts
|
|
@@ -1675,7 +1631,8 @@ const commitApprovedDocumentPlans = Effect.fn("Documents.commitApprovedPlans")(f
|
|
|
1675
1631
|
plan,
|
|
1676
1632
|
additionalPlans,
|
|
1677
1633
|
expectedGeneration: input.current.snapshot.generation,
|
|
1678
|
-
|
|
1634
|
+
...input.configurationRevision === void 0 ? void 0 : { expectedConfigurationRevision: input.configurationRevision },
|
|
1635
|
+
mediaReferences: input.plans.flatMap((candidate) => projectMediaReferences(input.authored, input.published, planDocumentId(candidate)))
|
|
1679
1636
|
});
|
|
1680
1637
|
});
|
|
1681
1638
|
/** Authorize every affected document before the adapter commits the approved plan atomically. */
|
|
@@ -1708,18 +1665,6 @@ const commitDocumentMutation = Effect.fn("Documents.commitMutation")(function* (
|
|
|
1708
1665
|
}
|
|
1709
1666
|
}
|
|
1710
1667
|
const prepared = yield* prepareDocumentMutation(dependencies, current, command);
|
|
1711
|
-
if (command.action === "document.move" && Predicate.isTagged("Commit")(prepared)) {
|
|
1712
|
-
for (const plan of prepared.additionalPlans ?? []) if (plan.action === "document.update") yield* accessControl.require({
|
|
1713
|
-
actor: activity.actor,
|
|
1714
|
-
requestId: activity.requestId
|
|
1715
|
-
}, {
|
|
1716
|
-
action: "document.update",
|
|
1717
|
-
resource: {
|
|
1718
|
-
kind: "document",
|
|
1719
|
-
documentId: plan.documentId
|
|
1720
|
-
}
|
|
1721
|
-
});
|
|
1722
|
-
}
|
|
1723
1668
|
if (command.action === "document.undelete" && Predicate.isTagged("Commit")(prepared)) for (const plan of [prepared.commitPlan, ...prepared.additionalPlans ?? []]) yield* accessControl.require({
|
|
1724
1669
|
actor: activity.actor,
|
|
1725
1670
|
requestId: activity.requestId
|
|
@@ -1727,7 +1672,7 @@ const commitDocumentMutation = Effect.fn("Documents.commitMutation")(function* (
|
|
|
1727
1672
|
action: "document.undelete",
|
|
1728
1673
|
resource: {
|
|
1729
1674
|
kind: "document",
|
|
1730
|
-
documentId: plan
|
|
1675
|
+
documentId: planDocumentId(plan)
|
|
1731
1676
|
}
|
|
1732
1677
|
});
|
|
1733
1678
|
if (Predicate.isTagged("Unchanged")(prepared)) return {
|
|
@@ -1740,7 +1685,8 @@ const commitDocumentMutation = Effect.fn("Documents.commitMutation")(function* (
|
|
|
1740
1685
|
plans: [prepared.commitPlan, ...prepared.additionalPlans ?? []],
|
|
1741
1686
|
authored: prepared.authored,
|
|
1742
1687
|
published: prepared.published,
|
|
1743
|
-
activity
|
|
1688
|
+
activity,
|
|
1689
|
+
...dependencies.configurationRevision === void 0 ? void 0 : { configurationRevision: dependencies.configurationRevision }
|
|
1744
1690
|
});
|
|
1745
1691
|
const next = makeDocumentState(prepared.authored, prepared.published, committed.snapshot);
|
|
1746
1692
|
const entry = entryById(next, committed.mutation.documentId);
|
|
@@ -1750,6 +1696,9 @@ const commitDocumentMutation = Effect.fn("Documents.commitMutation")(function* (
|
|
|
1750
1696
|
result: DocumentMutationResult.make(Object.assign({}, committed.mutation, entry === void 0 ? void 0 : { entry }))
|
|
1751
1697
|
};
|
|
1752
1698
|
});
|
|
1699
|
+
function planDocumentId(plan) {
|
|
1700
|
+
return plan.action === "document.create" ? plan.identity.documentId : plan.documentId;
|
|
1701
|
+
}
|
|
1753
1702
|
|
|
1754
1703
|
//#endregion
|
|
1755
1704
|
//#region ../server/src/internal/documents/document-store.ts
|
|
@@ -1765,6 +1714,10 @@ var DocumentGenerationConflict = class extends Schema.TaggedError()("Documents.G
|
|
|
1765
1714
|
expectedGeneration: DocumentGeneration,
|
|
1766
1715
|
actualGeneration: DocumentGeneration
|
|
1767
1716
|
}) {};
|
|
1717
|
+
var DocumentConfigurationConflict = class extends Schema.TaggedError()("Documents.ConfigurationConflict", {
|
|
1718
|
+
expectedRevision: Schema.NonEmptyString,
|
|
1719
|
+
actualRevision: Schema.NullOr(Schema.NonEmptyString)
|
|
1720
|
+
}) {};
|
|
1768
1721
|
|
|
1769
1722
|
//#endregion
|
|
1770
1723
|
//#region ../server/src/internal/cursor.ts
|
|
@@ -1940,41 +1893,17 @@ function createNavigation(documents, query, configuration) {
|
|
|
1940
1893
|
const locale = query.locale ?? configuration.locales?.defaultLocale;
|
|
1941
1894
|
const candidates = documents.filter((document) => (query.collection === void 0 || document.collection === query.collection) && (locale === void 0 || document.locale === locale) && document.data.navigation !== false);
|
|
1942
1895
|
const roots = [];
|
|
1943
|
-
const
|
|
1896
|
+
const itemsById = new Map(candidates.map((document) => [document.id, navigationItem(document)]));
|
|
1944
1897
|
const orderByItem = /* @__PURE__ */ new Map();
|
|
1945
1898
|
for (const document of candidates) {
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
for (let index = 0; index < segments.length; index += 1) {
|
|
1955
|
-
const key = PublicPath.make(`/${segments.slice(0, index + 1).join("/")}`);
|
|
1956
|
-
let item = itemsByKey.get(key);
|
|
1957
|
-
if (!item) {
|
|
1958
|
-
item = {
|
|
1959
|
-
children: [],
|
|
1960
|
-
key,
|
|
1961
|
-
title: titleFromSegment(segments[index] ?? "")
|
|
1962
|
-
};
|
|
1963
|
-
itemsByKey.set(key, item);
|
|
1964
|
-
if (parent) parent.children.push(item);
|
|
1965
|
-
else roots.push(item);
|
|
1966
|
-
}
|
|
1967
|
-
if (index === segments.length - 1) {
|
|
1968
|
-
const resolved = navigationItem(document);
|
|
1969
|
-
item.title = resolved.title;
|
|
1970
|
-
item.path = resolved.path;
|
|
1971
|
-
if (resolved.locale !== void 0) item.locale = resolved.locale;
|
|
1972
|
-
else delete item.locale;
|
|
1973
|
-
item.documentId = resolved.documentId;
|
|
1974
|
-
orderByItem.set(item, navigationOrder(document));
|
|
1975
|
-
}
|
|
1976
|
-
parent = item;
|
|
1977
|
-
}
|
|
1899
|
+
const item = itemsById.get(document.id);
|
|
1900
|
+
if (!item) continue;
|
|
1901
|
+
orderByItem.set(item, document.placement.kind === "home" ? Number.NEGATIVE_INFINITY : navigationOrder(document));
|
|
1902
|
+
if (document.placement.kind === "entry") {
|
|
1903
|
+
const parent = itemsById.get(document.placement.parentDocumentId);
|
|
1904
|
+
if (parent) parent.children.push(item);
|
|
1905
|
+
else roots.push(item);
|
|
1906
|
+
} else roots.push(item);
|
|
1978
1907
|
}
|
|
1979
1908
|
sortNavigation(roots, orderByItem);
|
|
1980
1909
|
return roots.map((item) => DocumentNavigationItem.make(item));
|
|
@@ -2009,7 +1938,6 @@ function documentField(document, field) {
|
|
|
2009
1938
|
case "key": return document.key;
|
|
2010
1939
|
case "locale": return document.locale;
|
|
2011
1940
|
case "path": return document.path;
|
|
2012
|
-
case "source.path": return document.source.path;
|
|
2013
1941
|
case "title": return document.title;
|
|
2014
1942
|
default: return nestedValue(document.data, field.startsWith("data.") ? field.slice(5) : field);
|
|
2015
1943
|
}
|
|
@@ -2042,9 +1970,6 @@ function compareValues(left, right) {
|
|
|
2042
1970
|
const rightText = Schema.is(Schema.String)(right) ? right : JSON.stringify(right) ?? "";
|
|
2043
1971
|
return leftText.localeCompare(rightText);
|
|
2044
1972
|
}
|
|
2045
|
-
function titleFromSegment(segment) {
|
|
2046
|
-
return segment.replace(/[-_]+/gu, " ").replace(/^./u, (character) => character.toUpperCase());
|
|
2047
|
-
}
|
|
2048
1973
|
|
|
2049
1974
|
//#endregion
|
|
2050
1975
|
//#region ../server/src/internal/documents/documents.ts
|
|
@@ -2066,8 +1991,8 @@ const makeDocuments = Effect.fn("Documents.make")(function* (configuration, opti
|
|
|
2066
1991
|
const dependencies = {
|
|
2067
1992
|
engine,
|
|
2068
1993
|
configuration,
|
|
2069
|
-
|
|
2070
|
-
|
|
1994
|
+
...options.configurationRevision === void 0 ? void 0 : { configurationRevision: options.configurationRevision },
|
|
1995
|
+
repository
|
|
2071
1996
|
};
|
|
2072
1997
|
const refreshUnlocked = Effect.fn("Documents.refreshUnlocked")(function* (force = false) {
|
|
2073
1998
|
const current = yield* Ref.get(state);
|
|
@@ -2114,11 +2039,15 @@ const makeDocuments = Effect.fn("Documents.make")(function* (configuration, opti
|
|
|
2114
2039
|
const plan = yield* Effect.fromResult(planDocumentCreation(configuration, input));
|
|
2115
2040
|
const source = yield* createInitialDocumentSource(plan);
|
|
2116
2041
|
const documentId = DocumentId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie));
|
|
2042
|
+
const identity = Object.assign({
|
|
2043
|
+
collection: plan.collection.collection,
|
|
2044
|
+
documentId
|
|
2045
|
+
}, plan.locale === void 0 ? void 0 : { locale: plan.locale });
|
|
2117
2046
|
return yield* runMutation({
|
|
2118
2047
|
action: "document.create",
|
|
2119
|
-
|
|
2048
|
+
identity,
|
|
2120
2049
|
markdown: source.markdown,
|
|
2121
|
-
|
|
2050
|
+
placement: plan.placement
|
|
2122
2051
|
}, activity, input.reason);
|
|
2123
2052
|
});
|
|
2124
2053
|
const duplicate = Effect.fn("Documents.duplicate")((input, activity) => runMutation({
|
|
@@ -2197,24 +2126,25 @@ const makeDocuments = Effect.fn("Documents.make")(function* (configuration, opti
|
|
|
2197
2126
|
yield* refreshUnlocked();
|
|
2198
2127
|
const current = yield* Ref.get(state);
|
|
2199
2128
|
return ContentSnapshot.make({
|
|
2200
|
-
version:
|
|
2129
|
+
version: 2,
|
|
2201
2130
|
sources: current.snapshot.active.map((source) => ({
|
|
2202
|
-
|
|
2203
|
-
|
|
2131
|
+
identity: source.identity,
|
|
2132
|
+
placement: source.placement,
|
|
2204
2133
|
markdown: source.markdown,
|
|
2205
|
-
published: source.publishedVersion === source.version
|
|
2206
|
-
|
|
2134
|
+
published: source.publishedVersion === source.version,
|
|
2135
|
+
revisionId: source.revisionId
|
|
2136
|
+
})).sort((left, right) => left.identity.documentId.localeCompare(right.identity.documentId))
|
|
2207
2137
|
});
|
|
2208
2138
|
}))));
|
|
2209
2139
|
const contentPlan = (context, input) => requireContentTransfer(context).pipe(Effect.andThen(semaphore.withPermits(1)(Effect.gen(function* () {
|
|
2210
2140
|
yield* refreshUnlocked();
|
|
2211
|
-
return (yield* planContentTransfer(engine, yield* Ref.get(state), input, crypto)).plan;
|
|
2141
|
+
return (yield* planContentTransfer(engine, configuration, yield* Ref.get(state), input, crypto)).plan;
|
|
2212
2142
|
}))));
|
|
2213
2143
|
const contentApply = (context, input) => requireContentTransfer(context).pipe(Effect.andThen(semaphore.withPermits(1)(Effect.gen(function* () {
|
|
2214
2144
|
yield* refreshUnlocked();
|
|
2215
2145
|
const current = yield* Ref.get(state);
|
|
2216
2146
|
if (current.snapshot.generation !== input.expectedGeneration) return yield* new ContentTransferConflict({ message: "Content changed since the plan. Run content plan again." });
|
|
2217
|
-
const planned = yield* planContentTransfer(engine, current, input, crypto);
|
|
2147
|
+
const planned = yield* planContentTransfer(engine, configuration, current, input, crypto);
|
|
2218
2148
|
if (planned.plan.entries.some((entry) => entry.action === "conflict")) return yield* new ContentTransferConflict({ message: "Destination content differs. Use --overwrite after reviewing the plan." });
|
|
2219
2149
|
if (!planned.plan.valid) return yield* new DocumentValidationFailed({ issues: planned.plan.issues });
|
|
2220
2150
|
if (planned.commitPlans.length === 0) return ContentApplyResult.make({
|
|
@@ -2231,7 +2161,8 @@ const makeDocuments = Effect.fn("Documents.make")(function* (configuration, opti
|
|
|
2231
2161
|
plans: [first, ...additionalPlans],
|
|
2232
2162
|
authored,
|
|
2233
2163
|
published: publishedCatalog,
|
|
2234
|
-
activity: requestActivity$1(context, "CMS content import")
|
|
2164
|
+
activity: requestActivity$1(context, "CMS content import"),
|
|
2165
|
+
...options.configurationRevision === void 0 ? void 0 : { configurationRevision: options.configurationRevision }
|
|
2235
2166
|
}).pipe(Effect.mapError((error) => isDocumentGenerationConflict(error) ? new ContentTransferConflict({ message: "Content changed since the plan. Run content plan again." }) : error));
|
|
2236
2167
|
yield* Ref.set(state, yield* compileDocumentState(engine, committed.snapshot, current));
|
|
2237
2168
|
yield* PubSub.publish(mutationEvents, committed.mutation);
|
|
@@ -2290,6 +2221,12 @@ const makeDocuments = Effect.fn("Documents.make")(function* (configuration, opti
|
|
|
2290
2221
|
return {
|
|
2291
2222
|
documents,
|
|
2292
2223
|
maintenance: DocumentMaintenance.of({
|
|
2224
|
+
compile: (source) => engine.compile({
|
|
2225
|
+
draft: source.publishedVersion !== source.version,
|
|
2226
|
+
identity: source.identity,
|
|
2227
|
+
markdown: source.markdown,
|
|
2228
|
+
placement: source.placement
|
|
2229
|
+
}),
|
|
2293
2230
|
mediaReferences: (documentId) => semaphore.withPermits(1)(Effect.gen(function* () {
|
|
2294
2231
|
yield* refreshUnlocked();
|
|
2295
2232
|
const current = yield* Ref.get(state);
|
|
@@ -2680,26 +2617,27 @@ function statObject(bucket, prefix, objectKey, client) {
|
|
|
2680
2617
|
}));
|
|
2681
2618
|
}
|
|
2682
2619
|
function listObjects(bucket, prefix, client) {
|
|
2683
|
-
return Stream.
|
|
2684
|
-
|
|
2685
|
-
continuationToken
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2620
|
+
return Stream.suspend(() => {
|
|
2621
|
+
const seenTokens = /* @__PURE__ */ new Set();
|
|
2622
|
+
return Stream.paginate(void 0, (continuationToken) => providerRequest("MediaObjectStore.S3.list", client.listObjects({
|
|
2623
|
+
bucket,
|
|
2624
|
+
continuationToken,
|
|
2625
|
+
prefix: `${prefix}${mediaObjectPrefix}`
|
|
2626
|
+
})).pipe(Effect.flatMap((page) => Effect.gen(function* () {
|
|
2627
|
+
return [yield* Effect.forEach(page.objects, (object) => decodeListedObject(object, prefix)), yield* validateNextContinuationToken(continuationToken, seenTokens, page)];
|
|
2628
|
+
}))));
|
|
2629
|
+
});
|
|
2690
2630
|
}
|
|
2691
2631
|
function decodeListedObject(object, prefix) {
|
|
2692
2632
|
if (object.key === void 0) return Effect.fail(storageError("MediaObjectStore.S3.list", "The provider returned object metadata without a key."));
|
|
2693
2633
|
return decodeStoredObject("MediaObjectStore.S3.list", object.key.slice(prefix.length), object.size);
|
|
2694
2634
|
}
|
|
2695
|
-
function
|
|
2635
|
+
function validateNextContinuationToken(continuationToken, seenTokens, page) {
|
|
2696
2636
|
if (!page.isTruncated) return Effect.succeedNone;
|
|
2697
2637
|
const token = page.nextContinuationToken;
|
|
2698
|
-
if (!token || token ===
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
seenTokens: /* @__PURE__ */ new Set([...state.seenTokens, token])
|
|
2702
|
-
});
|
|
2638
|
+
if (!token || token === continuationToken || seenTokens.has(token)) return Effect.fail(storageError("MediaObjectStore.S3.list", "The provider returned an invalid continuation token."));
|
|
2639
|
+
seenTokens.add(token);
|
|
2640
|
+
return Effect.succeedSome(token);
|
|
2703
2641
|
}
|
|
2704
2642
|
function decodeStoredObject(operation, objectKey, byteSize, contentType) {
|
|
2705
2643
|
const decodedObjectKey = Schema.decodeOption(MediaObjectKey)(objectKey);
|
|
@@ -2800,5 +2738,5 @@ function storageError(operation, message) {
|
|
|
2800
2738
|
const maxS3SingleCopyBytes = 5e9;
|
|
2801
2739
|
|
|
2802
2740
|
//#endregion
|
|
2803
|
-
export {
|
|
2804
|
-
//# sourceMappingURL=S3MediaObjects-
|
|
2741
|
+
export { DocumentHistoryInvalidCursor as $, StudioAuthentication as A, CreateUserInput as B, DocumentPersistenceError as C, defaultAccessControlLayer as D, AccessControl as E, StudioInternalError as F, UserPage as G, UserAdministrationDenied as H, studioInternalError as I, CollaborationClientMessage as J, UserSelfRemovalDenied as K, InitializationAlreadyCompleted as L, StudioBootstrap as M, StudioRequestConflict as N, CurrentStudioRequest as O, StudioSchemaError as P, DocumentHistoryComparisonTooLarge as Q, InitializationProofInvalid as R, DocumentGenerationConflict as S, renderEditorMarkdown as T, UserAlreadyExists as U, User as V, UserNotFound as W, CollaborationTicket as X, CollaborationServerMessage as Y, StateVector as Z, Documents as _, mediaObjectPrefix as a, ActivityCursorInvalid as at, cursorCodec as b, Seo as c, ActivityId as ct, seoDeliveryLayer as d, ActivityTargetKind as dt, DocumentRevision as et, seoLayer as f, DocumentPreviews as g, DocumentMaintenance as h, MediaObjectStore as i, ActivityCursor as it, StudioBadRequest as j, StudioApi as k, SeoDelivery as l, ActivityPage as lt, SeoStore as m, s3MediaObjectStoreLayer as n, ActivityAction as nt, PreviewSeo as o, ActivityEntry as ot, SeoPersistenceError as p, UserSelfRoleChangeDenied as q, MediaPersistenceError as r, ActivityContext as rt, PublishedSeo as s, ActivityEntryDraft as st, maxS3SingleCopyBytes as t, ACTIVITY_ACTIONS as tt, makeDefaultSeoOptions as u, ActivityTarget as ut, PublishedDocuments as v, DocumentStore as w, DocumentConfigurationConflict as x, documentsLayer as y, InitializationState as z };
|
|
2742
|
+
//# sourceMappingURL=S3MediaObjects-BRuPQbxl.js.map
|