@replohq/sdk 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,43 +1,3 @@
1
+ export { jsonStringifyOrNull, omitJsonObjectFieldsOrNull, parseJsonOrNull } from '../../../chunk-VKO7P3ED.mjs';
2
+ import '../../../chunk-GV5FY7ZZ.mjs';
1
3
  import '../../../chunk-UJCSKKID.mjs';
2
-
3
- // ../replo-utils/lib/object.ts
4
- function omit(obj, keysToOmit) {
5
- const result = { ...obj };
6
- for (const key of keysToOmit) {
7
- delete result[key];
8
- }
9
- return result;
10
- }
11
-
12
- // ../replo-utils/lib/json.ts
13
- function parseJsonOrNull(json) {
14
- try {
15
- return JSON.parse(json);
16
- } catch {
17
- return null;
18
- }
19
- }
20
- function omitJsonObjectFieldsOrNull({
21
- json,
22
- fields
23
- }) {
24
- const parsedJson = parseJsonOrNull(json);
25
- if (typeof parsedJson !== "object" || parsedJson === null || Array.isArray(parsedJson)) {
26
- return null;
27
- }
28
- return jsonStringifyOrNull(
29
- omit(Object.fromEntries(Object.entries(parsedJson)), fields)
30
- );
31
- }
32
- function jsonStringifyOrNull(value) {
33
- if (value === null || value === void 0) {
34
- return null;
35
- }
36
- try {
37
- return JSON.stringify(value);
38
- } catch {
39
- return null;
40
- }
41
- }
42
-
43
- export { jsonStringifyOrNull, omitJsonObjectFieldsOrNull, parseJsonOrNull };
@@ -0,0 +1,3 @@
1
+ export { coerceNumberToString, deepCloneAndMergeReplacingArrays, errorMessage, exhaustiveSwitch, formatFileSize, getFromRecordOrNull, hasOwnProperty, invariant, isEmpty, isFunction_default as isFunction, isNotNullish, isNullish, isPrimitive, mergeReplacingArrays, mergeReplacingObjects, noop, preventDefault, sleep, warning } from '../../../chunk-AL3F36PH.mjs';
2
+ export { isNumber_default as isNumber, isString_default as isString } from '../../../chunk-GV5FY7ZZ.mjs';
3
+ import '../../../chunk-UJCSKKID.mjs';
@@ -0,0 +1,231 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * The shared app-root manifest that bundles `content/**` for production
4
+ * builds (published Workers have no filesystem). Scaffolded as a placeholder
5
+ * by the coordinator, imported by the generated templates, and populated by
6
+ * the harness publish tool before `next build` — one constant so those three
7
+ * can never drift.
8
+ */
9
+ export declare const CONTENT_MANIFEST_FILENAME = "content-manifest.generated.json";
10
+ /** Site-relative directory that holds all content. */
11
+ export declare const CONTENT_DIRNAME = "content";
12
+ /** Per-collection schema file inside `content/<collection>/`. */
13
+ export declare const CONTENT_COLLECTION_SCHEMA_FILENAME = "_collection.json";
14
+ /** Extension of entry files inside `content/<collection>/`. */
15
+ export declare const CONTENT_ENTRY_FILE_EXTENSION = ".mdx";
16
+ /**
17
+ * Frontmatter key that stores the `relatedContent` field's value (an array of
18
+ * `<collection>/<entry>` paths). The storage key predates the field id; both
19
+ * the editor's serializer and the SDK renderer map between them through this
20
+ * constant.
21
+ */
22
+ export declare const CONTENT_RELATED_VALUE_STORAGE_KEY = "related";
23
+ /**
24
+ * One slug contract for collection and entry slugs: they become directory
25
+ * names, file names, and public URL segments in every consumer. The pattern
26
+ * is ASCII-only, so the length cap counts bytes and characters identically.
27
+ */
28
+ export declare const CONTENT_SLUG_PATTERN: RegExp;
29
+ export declare const CONTENT_MAX_SLUG_LENGTH = 100;
30
+ export declare const contentSlugSchema: z.ZodString;
31
+ export declare function isValidContentSlug(slug: string): boolean;
32
+ export declare const CONTENT_ENTRY_STATUSES: readonly ["draft", "published", "archived"];
33
+ export type ContentEntryStatus = (typeof CONTENT_ENTRY_STATUSES)[number];
34
+ export declare const contentEntryStatusSchema: z.ZodEnum<{
35
+ draft: "draft";
36
+ published: "published";
37
+ archived: "archived";
38
+ }>;
39
+ /**
40
+ * The one public-visibility rule: only published, non-archived entries render
41
+ * on the published site. The sandbox preview (`next dev`) and the website
42
+ * builder pass `allowDrafts: true` so drafts are previewable before publish.
43
+ */
44
+ export declare function isContentEntryPubliclyVisible({ status, archivedAt, allowDrafts, }: {
45
+ status: ContentEntryStatus;
46
+ archivedAt: unknown;
47
+ allowDrafts: boolean;
48
+ }): boolean;
49
+ export declare const contentCollectionFieldTypeSchema: z.ZodEnum<{
50
+ boolean: "boolean";
51
+ status: "status";
52
+ image: "image";
53
+ url: "url";
54
+ date: "date";
55
+ tags: "tags";
56
+ related: "related";
57
+ "short-text": "short-text";
58
+ "long-text": "long-text";
59
+ "rich-text": "rich-text";
60
+ }>;
61
+ export type ContentCollectionFieldType = z.infer<typeof contentCollectionFieldTypeSchema>;
62
+ export declare const contentCollectionColorSchema: z.ZodEnum<{
63
+ seashell: "seashell";
64
+ yellow: "yellow";
65
+ lightGreen: "lightGreen";
66
+ darkGreen: "darkGreen";
67
+ lightPink: "lightPink";
68
+ magenta: "magenta";
69
+ purple: "purple";
70
+ blue: "blue";
71
+ }>;
72
+ export declare const contentCollectionFieldSchema: z.ZodObject<{
73
+ id: z.ZodString;
74
+ label: z.ZodString;
75
+ type: z.ZodEnum<{
76
+ boolean: "boolean";
77
+ status: "status";
78
+ image: "image";
79
+ url: "url";
80
+ date: "date";
81
+ tags: "tags";
82
+ related: "related";
83
+ "short-text": "short-text";
84
+ "long-text": "long-text";
85
+ "rich-text": "rich-text";
86
+ }>;
87
+ required: z.ZodBoolean;
88
+ enabled: z.ZodBoolean;
89
+ helpText: z.ZodOptional<z.ZodString>;
90
+ builtin: z.ZodBoolean;
91
+ }, z.core.$strip>;
92
+ export type ContentCollectionField = z.infer<typeof contentCollectionFieldSchema>;
93
+ /**
94
+ * The `_collection.json` file contract. `passthrough` keeps unknown keys so
95
+ * editor round-trips never drop data another writer added.
96
+ */
97
+ export declare const contentCollectionFileSchema: z.ZodObject<{
98
+ name: z.ZodString;
99
+ description: z.ZodString;
100
+ icon: z.ZodString;
101
+ color: z.ZodEnum<{
102
+ seashell: "seashell";
103
+ yellow: "yellow";
104
+ lightGreen: "lightGreen";
105
+ darkGreen: "darkGreen";
106
+ lightPink: "lightPink";
107
+ magenta: "magenta";
108
+ purple: "purple";
109
+ blue: "blue";
110
+ }>;
111
+ tags: z.ZodArray<z.ZodString>;
112
+ fields: z.ZodArray<z.ZodObject<{
113
+ id: z.ZodString;
114
+ label: z.ZodString;
115
+ type: z.ZodEnum<{
116
+ boolean: "boolean";
117
+ status: "status";
118
+ image: "image";
119
+ url: "url";
120
+ date: "date";
121
+ tags: "tags";
122
+ related: "related";
123
+ "short-text": "short-text";
124
+ "long-text": "long-text";
125
+ "rich-text": "rich-text";
126
+ }>;
127
+ required: z.ZodBoolean;
128
+ enabled: z.ZodBoolean;
129
+ helpText: z.ZodOptional<z.ZodString>;
130
+ builtin: z.ZodBoolean;
131
+ }, z.core.$strip>>;
132
+ archivedAt: z.ZodOptional<z.ZodNullable<z.ZodISODateTime>>;
133
+ hasListingPage: z.ZodOptional<z.ZodBoolean>;
134
+ }, z.core.$loose>;
135
+ /**
136
+ * Whether a URL is renderable on a published page. Relative URLs resolve
137
+ * against a dummy base so path-only values pass; only http(s) may be an
138
+ * image source, while links additionally allow mailto/tel.
139
+ */
140
+ export declare function isSafeContentUrl(value: string, { image }: {
141
+ image: boolean;
142
+ }): boolean;
143
+ /**
144
+ * Validity of a present (non-empty) value for a field type. This decides both
145
+ * editor-side validation errors and whether the SDK renders the entry at all,
146
+ * so the two can never disagree about what a valid value is.
147
+ */
148
+ export declare function getContentFieldValueSchema(fieldType: ContentCollectionFieldType): z.ZodType;
149
+ /**
150
+ * Slugs a collection may never claim even when the segment doesn't exist yet:
151
+ * conventional Next.js route namespaces every site is expected to grow into.
152
+ * Segments the site already owns are rejected separately at scaffold time.
153
+ */
154
+ export declare const CONTENT_RESERVED_COLLECTION_SLUGS: readonly ["api", "new"];
155
+ export declare const CONTENT_RESERVED_ENTRY_SLUGS: readonly ["new"];
156
+ export declare function isContentReservedEntrySlug(slug: string): boolean;
157
+ /**
158
+ * - `content`: rendered on the published page and ordered by collection
159
+ * settings (all custom fields are content).
160
+ * - `publishing`: publish controls (never rendered as page content).
161
+ * - `seo`: head metadata, not body content.
162
+ * - `private`: never leaves the editor.
163
+ */
164
+ export type ContentFieldRole = "content" | "publishing" | "seo" | "private";
165
+ /**
166
+ * Role of every builtin collection field. `satisfies` makes adding a builtin
167
+ * without classifying it a compile error wherever field ids are typed as
168
+ * `ContentBuiltinFieldId`.
169
+ */
170
+ export declare const CONTENT_BUILTIN_FIELD_ROLES: {
171
+ readonly title: "content";
172
+ readonly author: "content";
173
+ readonly excerpt: "content";
174
+ readonly coverImage: "content";
175
+ readonly body: "content";
176
+ readonly tags: "content";
177
+ readonly relatedContent: "content";
178
+ readonly slug: "publishing";
179
+ readonly status: "publishing";
180
+ readonly publishedAt: "publishing";
181
+ };
182
+ export type ContentBuiltinFieldId = keyof typeof CONTENT_BUILTIN_FIELD_ROLES;
183
+ /** Entry-level frontmatter keys that are head metadata, not collection fields. */
184
+ export declare const CONTENT_SEO_VALUE_KEYS: readonly ["seoTitle", "seoDescription"];
185
+ /** Entry-level frontmatter keys that must never be publicly rendered. */
186
+ export declare const CONTENT_PRIVATE_VALUE_KEYS: readonly ["scratchpad", "backlinks"];
187
+ /**
188
+ * Values that render and edit with a parent content field instead of owning
189
+ * an ordered slot of their own.
190
+ */
191
+ export declare const CONTENT_COUPLED_VALUE_PARENTS: {
192
+ readonly coverImageAlt: "coverImage";
193
+ readonly authorInitials: "author";
194
+ };
195
+ /**
196
+ * A related-content reference as stored in `related` frontmatter:
197
+ * `<collectionSlug>/<entrySlug>`. Producer and consumer share this pair so
198
+ * the written form and the published renderer can't drift apart.
199
+ */
200
+ export declare function formatContentEntryRef({ collectionSlug, entrySlug, }: {
201
+ collectionSlug: string;
202
+ entrySlug: string;
203
+ }): string;
204
+ /** Null when the ref isn't a `<collectionSlug>/<entrySlug>` pair. */
205
+ export declare function parseContentEntryRef(ref: string): {
206
+ collectionSlug: string;
207
+ entrySlug: string;
208
+ } | null;
209
+ export declare function isContentPrivateValueKey(key: string): boolean;
210
+ export declare function isContentSeoValueKey(key: string): boolean;
211
+ export declare function isContentReservedCollectionSlug(slug: string): boolean;
212
+ /** Custom (non-builtin) collection fields are always content. */
213
+ export declare function getContentFieldRole(fieldId: string): ContentFieldRole;
214
+ /**
215
+ * Enabled fields in collection-settings order, for the published page. The
216
+ * "Visible" toggle is authoritative here — including lifecycle fields like
217
+ * status and the slug, which the entry editor renders as dedicated controls
218
+ * rather than ordered fields. Private keys never publish.
219
+ */
220
+ export declare function getPublishedContentFields<Field extends {
221
+ id: string;
222
+ enabled: boolean;
223
+ }>(fields: Field[]): Field[];
224
+ /**
225
+ * Enabled content-role fields in collection-settings order — what the entry
226
+ * editor renders as the ordered field list.
227
+ */
228
+ export declare function getOrderedContentFields<Field extends {
229
+ id: string;
230
+ enabled: boolean;
231
+ }>(fields: Field[]): Field[];
@@ -0,0 +1,2 @@
1
+ export { CONTENT_BUILTIN_FIELD_ROLES, CONTENT_COLLECTION_SCHEMA_FILENAME, CONTENT_COUPLED_VALUE_PARENTS, CONTENT_DIRNAME, CONTENT_ENTRY_FILE_EXTENSION, CONTENT_ENTRY_STATUSES, CONTENT_MANIFEST_FILENAME, CONTENT_MAX_SLUG_LENGTH, CONTENT_PRIVATE_VALUE_KEYS, CONTENT_RELATED_VALUE_STORAGE_KEY, CONTENT_RESERVED_COLLECTION_SLUGS, CONTENT_RESERVED_ENTRY_SLUGS, CONTENT_SEO_VALUE_KEYS, CONTENT_SLUG_PATTERN, contentCollectionColorSchema, contentCollectionFieldSchema, contentCollectionFieldTypeSchema, contentCollectionFileSchema, contentEntryStatusSchema, contentSlugSchema, formatContentEntryRef, getContentFieldRole, getContentFieldValueSchema, getOrderedContentFields, getPublishedContentFields, isContentEntryPubliclyVisible, isContentPrivateValueKey, isContentReservedCollectionSlug, isContentReservedEntrySlug, isContentSeoValueKey, isSafeContentUrl, isValidContentSlug, parseContentEntryRef } from '../../chunk-IQ5GRTXO.mjs';
2
+ import '../../chunk-UJCSKKID.mjs';
@@ -0,0 +1,53 @@
1
+ import { contentCollectionFieldSchema } from "./contentCollection";
2
+ import { z } from "zod";
3
+ export declare const CONTENT_MANAGED_ENTRY_VALUE_KEYS: readonly ["slug", "title", "status", "author", "authorInitials", "excerpt", "coverImage", "coverImageAlt", "tags", "updatedAt", "publishedAt", "archivedAt", "seoTitle", "seoDescription", "related", "scratchpad", "backlinks"];
4
+ export declare const contentEntryFrontmatterSchema: z.ZodObject<{
5
+ slug: z.ZodOptional<z.ZodUnknown>;
6
+ title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
7
+ status: z.ZodEnum<{
8
+ draft: "draft";
9
+ published: "published";
10
+ archived: "archived";
11
+ }>;
12
+ author: z.ZodOptional<z.ZodNullable<z.ZodString>>;
13
+ authorInitials: z.ZodOptional<z.ZodNullable<z.ZodString>>;
14
+ excerpt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
15
+ coverImage: z.ZodOptional<z.ZodNullable<z.ZodString>>;
16
+ coverImageAlt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
17
+ tags: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
18
+ updatedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
19
+ publishedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
20
+ archivedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
21
+ seoTitle: z.ZodOptional<z.ZodNullable<z.ZodString>>;
22
+ seoDescription: z.ZodOptional<z.ZodNullable<z.ZodString>>;
23
+ related: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
24
+ scratchpad: z.ZodOptional<z.ZodUnknown>;
25
+ backlinks: z.ZodOptional<z.ZodUnknown>;
26
+ }, z.core.$loose>;
27
+ export type ContentEntryFrontmatter = z.infer<typeof contentEntryFrontmatterSchema>;
28
+ export interface ContentEntryDocument {
29
+ values: ContentEntryFrontmatter;
30
+ body: string;
31
+ }
32
+ export type ParsedContentEntryDocument = {
33
+ status: "ready";
34
+ document: ContentEntryDocument;
35
+ } | {
36
+ status: "invalid";
37
+ message: string;
38
+ };
39
+ export declare function parseContentEntryDocument(raw: string): ParsedContentEntryDocument;
40
+ export declare function serializeContentEntryDocument({ values, body, }: ContentEntryDocument): string;
41
+ export declare function getContentRenderableEntryValues({ document, slug, }: {
42
+ document: ContentEntryDocument;
43
+ slug: string;
44
+ }): Record<string, unknown>;
45
+ export interface ContentEntryFieldValidationIssue {
46
+ fieldId: string;
47
+ message: string;
48
+ }
49
+ export declare function getContentEntryFieldValidationIssues({ fields, values, requireRequiredFields, }: {
50
+ fields: z.infer<typeof contentCollectionFieldSchema>[];
51
+ values: Record<string, unknown>;
52
+ requireRequiredFields: boolean;
53
+ }): ContentEntryFieldValidationIssue[];
@@ -0,0 +1,3 @@
1
+ export { CONTENT_MANAGED_ENTRY_VALUE_KEYS, contentEntryFrontmatterSchema, getContentEntryFieldValidationIssues, getContentRenderableEntryValues, parseContentEntryDocument, serializeContentEntryDocument } from '../../chunk-I23U2PUI.mjs';
2
+ import '../../chunk-IQ5GRTXO.mjs';
3
+ import '../../chunk-UJCSKKID.mjs';
@@ -0,0 +1,18 @@
1
+ /** Matches a leading `---` frontmatter block, tolerating CRLF and EOF. */
2
+ export declare const CONTENT_FRONTMATTER_PATTERN: RegExp;
3
+ /**
4
+ * Strictly parse a frontmatter YAML block into a plain object, or null when
5
+ * it isn't valid. Strictness (unique keys, no merge, bounded aliases) is part
6
+ * of the format contract: a file the published runtime would reject must be
7
+ * rejected by every editor surface too.
8
+ */
9
+ export declare function parseContentFrontmatterYaml(yamlText: string): Record<string, unknown> | null;
10
+ /**
11
+ * Parse a full entry file that must start with a frontmatter block. Returns
12
+ * null when the block is missing or invalid; the remainder of the file is the
13
+ * markdown body.
14
+ */
15
+ export declare function parseContentFrontmatter(raw: string): {
16
+ values: Record<string, unknown>;
17
+ body: string;
18
+ } | null;
@@ -0,0 +1,44 @@
1
+ import { z } from "zod";
2
+ export declare const contentManifestSchema: z.ZodObject<{
3
+ files: z.ZodRecord<z.ZodString, z.ZodString>;
4
+ }, z.core.$strip>;
5
+ export type ContentManifest = z.infer<typeof contentManifestSchema>;
6
+ export type ContentFilePath = {
7
+ type: "collection";
8
+ collection: string;
9
+ } | {
10
+ type: "entry";
11
+ collection: string;
12
+ entry: string;
13
+ };
14
+ export interface ContentValidationIssue {
15
+ path: string;
16
+ message: string;
17
+ }
18
+ export interface ContentIndexEntry {
19
+ slug: string;
20
+ title: string;
21
+ status: "draft" | "published";
22
+ }
23
+ export interface ContentIndexCollection {
24
+ slug: string;
25
+ name: string;
26
+ entries: ContentIndexEntry[];
27
+ }
28
+ export declare function createContentManifest({ files, }: {
29
+ files: {
30
+ path: string;
31
+ content: string;
32
+ }[];
33
+ }): ContentManifest;
34
+ export declare function getContentFilePath(filePath: string): ContentFilePath | null;
35
+ export declare function getContentManifestCollectionSlugs(contentManifest: ContentManifest): string[];
36
+ export declare function getContentManifestEntrySlugs({ collection, contentManifest, }: {
37
+ collection: string;
38
+ contentManifest: ContentManifest;
39
+ }): string[];
40
+ export declare function getContentIndex({ files, allowDrafts, }: {
41
+ files: Record<string, string | null>;
42
+ allowDrafts: boolean;
43
+ }): ContentIndexCollection[];
44
+ export declare function validateContentManifest(contentManifest: ContentManifest): ContentValidationIssue[];
@@ -0,0 +1,197 @@
1
+ import { parseContentEntryDocument, getContentRenderableEntryValues, getContentEntryFieldValidationIssues } from '../../chunk-I23U2PUI.mjs';
2
+ import { isValidContentSlug, CONTENT_COLLECTION_SCHEMA_FILENAME, CONTENT_ENTRY_FILE_EXTENSION, contentCollectionFileSchema, isContentEntryPubliclyVisible } from '../../chunk-IQ5GRTXO.mjs';
3
+ import { parseJsonOrNull } from '../../chunk-VKO7P3ED.mjs';
4
+ import '../../chunk-GV5FY7ZZ.mjs';
5
+ import '../../chunk-UJCSKKID.mjs';
6
+ import { z } from 'zod';
7
+
8
+ var contentManifestSchema = z.object({
9
+ files: z.record(z.string(), z.string())
10
+ });
11
+ function createContentManifest({
12
+ files
13
+ }) {
14
+ const sortedFiles = [...files].sort((left, right) => {
15
+ return left.path.localeCompare(right.path);
16
+ });
17
+ return {
18
+ files: Object.fromEntries(
19
+ sortedFiles.map((file) => [file.path, file.content])
20
+ )
21
+ };
22
+ }
23
+ function getContentFilePath(filePath) {
24
+ const segments = filePath.split("/").filter(Boolean);
25
+ const filename = segments.at(-1);
26
+ const collection = segments.at(-2);
27
+ if (!filename || !collection || !isValidContentSlug(collection)) {
28
+ return null;
29
+ }
30
+ if (filename === CONTENT_COLLECTION_SCHEMA_FILENAME) {
31
+ return { type: "collection", collection };
32
+ }
33
+ if (!filename.endsWith(CONTENT_ENTRY_FILE_EXTENSION)) {
34
+ return null;
35
+ }
36
+ const entry = filename.slice(0, -CONTENT_ENTRY_FILE_EXTENSION.length);
37
+ return isValidContentSlug(entry) ? { type: "entry", collection, entry } : null;
38
+ }
39
+ function getContentManifestCollectionSlugs(contentManifest) {
40
+ return Object.keys(contentManifest.files).flatMap((relativePath) => {
41
+ const parsedPath = getContentManifestFilePath(relativePath);
42
+ return parsedPath?.type === "collection" ? [parsedPath.collection] : [];
43
+ });
44
+ }
45
+ function getContentManifestEntrySlugs({
46
+ collection,
47
+ contentManifest
48
+ }) {
49
+ return Object.keys(contentManifest.files).flatMap((relativePath) => {
50
+ const parsedPath = getContentManifestFilePath(relativePath);
51
+ return parsedPath?.type === "entry" && parsedPath.collection === collection ? [parsedPath.entry] : [];
52
+ });
53
+ }
54
+ function getContentIndex({
55
+ files,
56
+ allowDrafts
57
+ }) {
58
+ const collectionsBySlug = /* @__PURE__ */ new Map();
59
+ for (const [filePath, content] of Object.entries(files)) {
60
+ const parsedPath = getContentFilePath(filePath);
61
+ if (parsedPath?.type !== "collection" || content === null) {
62
+ continue;
63
+ }
64
+ const parsedCollection = contentCollectionFileSchema.safeParse(
65
+ parseJsonOrNull(content)
66
+ );
67
+ if (!parsedCollection.success || parsedCollection.data.archivedAt) {
68
+ continue;
69
+ }
70
+ collectionsBySlug.set(parsedPath.collection, {
71
+ schema: parsedCollection.data,
72
+ collection: {
73
+ slug: parsedPath.collection,
74
+ name: parsedCollection.data.name,
75
+ entries: []
76
+ }
77
+ });
78
+ }
79
+ for (const [filePath, content] of Object.entries(files)) {
80
+ const parsedPath = getContentFilePath(filePath);
81
+ if (parsedPath?.type !== "entry" || content === null) {
82
+ continue;
83
+ }
84
+ const collection = collectionsBySlug.get(parsedPath.collection);
85
+ if (!collection) {
86
+ continue;
87
+ }
88
+ const parsedDocument = parseContentEntryDocument(content);
89
+ if (parsedDocument.status === "invalid") {
90
+ continue;
91
+ }
92
+ const document = parsedDocument.document;
93
+ const status = document.values.status;
94
+ if (status === "archived" || !isContentEntryPubliclyVisible({
95
+ status,
96
+ archivedAt: document.values.archivedAt,
97
+ allowDrafts
98
+ })) {
99
+ continue;
100
+ }
101
+ const values = getContentRenderableEntryValues({
102
+ document,
103
+ slug: parsedPath.entry
104
+ });
105
+ const validationIssues = getContentEntryFieldValidationIssues({
106
+ fields: collection.schema.fields,
107
+ values,
108
+ requireRequiredFields: document.values.status === "published"
109
+ });
110
+ if (validationIssues.length > 0) {
111
+ continue;
112
+ }
113
+ const trimmedTitle = document.values.title?.trim();
114
+ collection.collection.entries.push({
115
+ slug: parsedPath.entry,
116
+ title: trimmedTitle && trimmedTitle.length > 0 ? trimmedTitle : parsedPath.entry,
117
+ status
118
+ });
119
+ }
120
+ const collections = [...collectionsBySlug.values()].map(({ collection }) => {
121
+ collection.entries.sort((left, right) => {
122
+ return left.title.localeCompare(right.title);
123
+ });
124
+ return collection;
125
+ });
126
+ return collections.sort((left, right) => {
127
+ return left.name.localeCompare(right.name);
128
+ });
129
+ }
130
+ function validateContentManifest(contentManifest) {
131
+ const collectionSchemas = /* @__PURE__ */ new Map();
132
+ const issues = [];
133
+ for (const [relativePath, content] of Object.entries(contentManifest.files)) {
134
+ const parsedPath = getContentManifestFilePath(relativePath);
135
+ if (!parsedPath) {
136
+ issues.push({
137
+ path: relativePath,
138
+ message: "The collection or entry slug is not valid."
139
+ });
140
+ continue;
141
+ }
142
+ if (parsedPath.type !== "collection") {
143
+ continue;
144
+ }
145
+ const parsedCollection = contentCollectionFileSchema.safeParse(
146
+ parseJsonOrNull(content)
147
+ );
148
+ if (!parsedCollection.success) {
149
+ issues.push({
150
+ path: relativePath,
151
+ message: parsedCollection.error.issues[0]?.message ?? "The collection settings are invalid."
152
+ });
153
+ continue;
154
+ }
155
+ collectionSchemas.set(parsedPath.collection, parsedCollection.data);
156
+ }
157
+ for (const [relativePath, content] of Object.entries(contentManifest.files)) {
158
+ const parsedPath = getContentManifestFilePath(relativePath);
159
+ if (parsedPath?.type !== "entry") {
160
+ continue;
161
+ }
162
+ const collectionSchema = collectionSchemas.get(parsedPath.collection);
163
+ if (!collectionSchema) {
164
+ issues.push({
165
+ path: relativePath,
166
+ message: `Collection "${parsedPath.collection}" has no valid ${CONTENT_COLLECTION_SCHEMA_FILENAME}.`
167
+ });
168
+ continue;
169
+ }
170
+ const parsedDocument = parseContentEntryDocument(content);
171
+ if (parsedDocument.status === "invalid") {
172
+ issues.push({ path: relativePath, message: parsedDocument.message });
173
+ continue;
174
+ }
175
+ const document = parsedDocument.document;
176
+ const fieldIssues = getContentEntryFieldValidationIssues({
177
+ fields: collectionSchema.fields,
178
+ values: getContentRenderableEntryValues({
179
+ document,
180
+ slug: parsedPath.entry
181
+ }),
182
+ requireRequiredFields: document.values.status === "published"
183
+ });
184
+ issues.push(
185
+ ...fieldIssues.map((issue) => ({
186
+ path: relativePath,
187
+ message: `${issue.fieldId}: ${issue.message}`
188
+ }))
189
+ );
190
+ }
191
+ return issues;
192
+ }
193
+ function getContentManifestFilePath(relativePath) {
194
+ return relativePath.split("/").length === 2 ? getContentFilePath(relativePath) : null;
195
+ }
196
+
197
+ export { contentManifestSchema, createContentManifest, getContentFilePath, getContentIndex, getContentManifestCollectionSlugs, getContentManifestEntrySlugs, validateContentManifest };
@@ -1,4 +1,6 @@
1
1
  import { ReploError } from '../../chunk-5M7VU32I.mjs';
2
+ import '../../chunk-AL3F36PH.mjs';
3
+ import '../../chunk-GV5FY7ZZ.mjs';
2
4
  import { __commonJS, __toESM } from '../../chunk-UJCSKKID.mjs';
3
5
  import { z } from 'zod';
4
6
 
@@ -1,4 +1,6 @@
1
1
  import { ReploError } from '../../../chunk-5M7VU32I.mjs';
2
+ import '../../../chunk-AL3F36PH.mjs';
3
+ import '../../../chunk-GV5FY7ZZ.mjs';
2
4
  import '../../../chunk-UJCSKKID.mjs';
3
5
  import { z } from 'zod';
4
6
 
@@ -1,5 +1,7 @@
1
1
  import { getParamSegment, getRouteParams, hasRouteParam, matchSource } from '../../../chunk-VPEVERWE.mjs';
2
2
  import { ReploError } from '../../../chunk-5M7VU32I.mjs';
3
+ import '../../../chunk-AL3F36PH.mjs';
4
+ import '../../../chunk-GV5FY7ZZ.mjs';
3
5
  import '../../../chunk-UJCSKKID.mjs';
4
6
  import { z } from 'zod';
5
7
 
@@ -53,8 +53,7 @@ export interface CartContextType {
53
53
  }
54
54
  /**
55
55
  * Provider component that manages global cart state and operations. Handles both
56
- * server-side cart synchronization and client-side optimistic updates. Supports
57
- * editor mode for preview environments.
56
+ * server-side cart synchronization and client-side optimistic updates.
58
57
  *
59
58
  * @returns A context provider wrapping the children with cart functionality
60
59
  */
@@ -17,12 +17,6 @@ import { recalculateCartCost } from "./utils/cart-utils";
17
17
  import { createOptimisticSellingPlanAllocation } from "./utils/variant-to-cart-line";
18
18
  class CartContextError extends CanopyError {
19
19
  }
20
- const isEditorMode = () => {
21
- if (typeof window === "undefined") {
22
- return false;
23
- }
24
- return window.parent !== window;
25
- };
26
20
  let cartCreationPromise = null;
27
21
  function addLineToCart(cart, line) {
28
22
  const existingLineIndex = cart.lines.findIndex((existingLine) => {
@@ -312,12 +306,7 @@ function CartProvider({
312
306
  return null;
313
307
  }
314
308
  };
315
- const checkoutUrl = (() => {
316
- if (isEditorMode()) {
317
- return "/";
318
- }
319
- return cartData?.checkoutUrl ?? "/";
320
- })();
309
+ const checkoutUrl = cartData?.checkoutUrl ?? "/";
321
310
  return /* @__PURE__ */ jsx(
322
311
  CartContext.Provider,
323
312
  {