@contentrail/editor 0.0.0-stage → 0.1.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.
Files changed (44) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +121 -2
  3. package/dist/api/client.d.ts +52 -0
  4. package/dist/api/client.d.ts.map +1 -0
  5. package/dist/api/client.js +92 -0
  6. package/dist/api/client.js.map +1 -0
  7. package/dist/api/types.d.ts +72 -0
  8. package/dist/api/types.d.ts.map +1 -0
  9. package/dist/api/types.js +2 -0
  10. package/dist/api/types.js.map +1 -0
  11. package/dist/fields/defaults.d.ts +11 -0
  12. package/dist/fields/defaults.d.ts.map +1 -0
  13. package/dist/fields/defaults.js +93 -0
  14. package/dist/fields/defaults.js.map +1 -0
  15. package/dist/fields/types.d.ts +62 -0
  16. package/dist/fields/types.d.ts.map +1 -0
  17. package/dist/fields/types.js +6 -0
  18. package/dist/fields/types.js.map +1 -0
  19. package/dist/form/FieldControl.d.ts +11 -0
  20. package/dist/form/FieldControl.d.ts.map +1 -0
  21. package/dist/form/FieldControl.js +72 -0
  22. package/dist/form/FieldControl.js.map +1 -0
  23. package/dist/form/SchemaForm.d.ts +14 -0
  24. package/dist/form/SchemaForm.d.ts.map +1 -0
  25. package/dist/form/SchemaForm.js +33 -0
  26. package/dist/form/SchemaForm.js.map +1 -0
  27. package/dist/import/tabular.d.ts +35 -0
  28. package/dist/import/tabular.d.ts.map +1 -0
  29. package/dist/import/tabular.js +191 -0
  30. package/dist/import/tabular.js.map +1 -0
  31. package/dist/index.d.ts +14 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +12 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/state/draft.d.ts +12 -0
  36. package/dist/state/draft.d.ts.map +1 -0
  37. package/dist/state/draft.js +32 -0
  38. package/dist/state/draft.js.map +1 -0
  39. package/dist/styles.css +322 -0
  40. package/dist/ui/EditorApp.d.ts +10 -0
  41. package/dist/ui/EditorApp.d.ts.map +1 -0
  42. package/dist/ui/EditorApp.js +352 -0
  43. package/dist/ui/EditorApp.js.map +1 -0
  44. package/package.json +60 -3
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
2
+ import { emptyValueForField, sortFields } from "../fields/defaults.js";
3
+ export function FieldControl(props) {
4
+ const { field, value, path, error, onChange, disabled } = props;
5
+ const id = `cr-field-${path.replaceAll(".", "-")}`;
6
+ const describedBy = error
7
+ ? `${id}-error`
8
+ : field.helpText
9
+ ? `${id}-help`
10
+ : undefined;
11
+ const readOnly = Boolean(field.readOnly || disabled);
12
+ if (field.widget === "unsupported") {
13
+ return (_jsxs("div", { class: "cr-field cr-field--unsupported", role: "group", children: [_jsx("div", { class: "cr-label", children: field.label }), _jsxs("p", { class: "cr-unsupported", id: id, children: ["This field cannot be edited in the ContentRail editor (", field.reason, "). Contact your developer to change it."] })] }));
14
+ }
15
+ if (field.widget === "object") {
16
+ const record = value !== null && typeof value === "object" && !Array.isArray(value)
17
+ ? value
18
+ : {};
19
+ return (_jsxs("fieldset", { class: "cr-fieldset", children: [_jsx("legend", { children: field.label }), field.helpText ? _jsx("p", { class: "cr-help", children: field.helpText }) : null, sortFields(field.fields).map((child) => (_jsx(FieldControl, { field: child, value: record[child.name], path: `${path}.${child.name}`, onChange: onChange, disabled: readOnly }, child.name)))] }));
20
+ }
21
+ if (field.widget === "array") {
22
+ const items = Array.isArray(value) ? value : [];
23
+ return (_jsxs("fieldset", { class: "cr-fieldset", children: [_jsxs("legend", { children: [field.label, field.required ? (_jsxs("span", { class: "cr-required", "aria-hidden": "true", children: [" ", "*"] })) : null] }), field.helpText ? _jsx("p", { class: "cr-help", children: field.helpText }) : null, _jsx("ul", { class: "cr-array", children: items.map((item, index) => (_jsxs("li", { class: "cr-array-item", children: [_jsx(FieldControl, { field: {
24
+ ...field.item,
25
+ name: String(index),
26
+ label: `Item ${index + 1}`,
27
+ }, value: item, path: `${path}.${index}`, onChange: onChange, disabled: readOnly }), !readOnly ? (_jsx("button", { type: "button", class: "cr-button cr-button--ghost", onClick: () => onChange(path, items.filter((_, i) => i !== index)), children: "Remove" })) : null] }, `${path}-${index}`))) }), !readOnly ? (_jsx("button", { type: "button", class: "cr-button cr-button--secondary", onClick: () => onChange(path, [...items, emptyValueForField(field.item)]), children: "Add item" })) : null, error ? (_jsx("p", { class: "cr-error", id: `${id}-error`, role: "alert", children: error })) : null] }));
28
+ }
29
+ return (_jsxs("div", { class: `cr-field${error ? " cr-field--invalid" : ""}`, children: [_jsxs("label", { class: "cr-label", for: id, children: [field.label, field.required ? (_jsxs("span", { class: "cr-required", title: "Required", children: [" ", "*"] })) : null] }), field.helpText ? (_jsx("p", { class: "cr-help", id: `${id}-help`, children: field.helpText })) : null, renderInput(field, id, value, path, onChange, readOnly, describedBy), error ? (_jsx("p", { class: "cr-error", id: `${id}-error`, role: "alert", children: error })) : null] }));
30
+ }
31
+ function renderInput(field, id, value, path, onChange, readOnly, describedBy) {
32
+ if (field.widget === "textarea") {
33
+ return (_jsx("textarea", { id: id, class: "cr-input", value: typeof value === "string" ? value : "", ...(field.placeholder !== undefined
34
+ ? { placeholder: field.placeholder }
35
+ : {}), readOnly: readOnly, required: Boolean(field.required), ...(describedBy?.endsWith("-error")
36
+ ? { "aria-invalid": true }
37
+ : {}), ...(describedBy !== undefined
38
+ ? { "aria-describedby": describedBy }
39
+ : {}), onInput: (event) => onChange(path, event.currentTarget.value) }));
40
+ }
41
+ if (field.widget === "number") {
42
+ return (_jsx("input", { id: id, class: "cr-input", type: "number", value: typeof value === "number" ? String(value) : "", ...(field.min !== undefined ? { min: field.min } : {}), ...(field.max !== undefined ? { max: field.max } : {}), ...(field.step !== undefined ? { step: field.step } : {}), readOnly: readOnly, required: Boolean(field.required), ...(describedBy?.endsWith("-error")
43
+ ? { "aria-invalid": true }
44
+ : {}), ...(describedBy !== undefined
45
+ ? { "aria-describedby": describedBy }
46
+ : {}), onInput: (event) => {
47
+ const raw = event.currentTarget.value;
48
+ onChange(path, raw === "" ? null : Number(raw));
49
+ } }));
50
+ }
51
+ if (field.widget === "boolean") {
52
+ return (_jsxs("label", { class: "cr-checkbox", children: [_jsx("input", { id: id, type: "checkbox", checked: Boolean(value), disabled: readOnly, ...(describedBy !== undefined
53
+ ? { "aria-describedby": describedBy }
54
+ : {}), onChange: (event) => onChange(path, event.currentTarget.checked) }), _jsx("span", { children: field.label })] }));
55
+ }
56
+ if (field.widget === "enum") {
57
+ return (_jsx("select", { id: id, class: "cr-input", value: typeof value === "string" ? value : "", disabled: readOnly, required: Boolean(field.required), ...(describedBy?.endsWith("-error")
58
+ ? { "aria-invalid": true }
59
+ : {}), ...(describedBy !== undefined
60
+ ? { "aria-describedby": describedBy }
61
+ : {}), onChange: (event) => onChange(path, event.currentTarget.value), children: field.options.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value))) }));
62
+ }
63
+ // text
64
+ return (_jsx("input", { id: id, class: "cr-input", type: "text", value: typeof value === "string" ? value : "", ...(field.widget === "text" && field.placeholder !== undefined
65
+ ? { placeholder: field.placeholder }
66
+ : {}), readOnly: readOnly, required: Boolean(field.required), ...(describedBy?.endsWith("-error")
67
+ ? { "aria-invalid": true }
68
+ : {}), ...(describedBy !== undefined
69
+ ? { "aria-describedby": describedBy }
70
+ : {}), onInput: (event) => onChange(path, event.currentTarget.value) }));
71
+ }
72
+ //# sourceMappingURL=FieldControl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FieldControl.js","sourceRoot":"","sources":["../../src/form/FieldControl.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { EditorCollectionConfig } from "../fields/types.js";
2
+ export interface SchemaFormProps {
3
+ readonly collection: EditorCollectionConfig;
4
+ readonly entryId: string;
5
+ readonly data: Record<string, unknown>;
6
+ readonly errors?: Readonly<Record<string, string>>;
7
+ readonly onEntryIdChange: (id: string) => void;
8
+ readonly onChange: (path: string, value: unknown) => void;
9
+ readonly entryIdReadOnly?: boolean;
10
+ readonly disabled?: boolean;
11
+ }
12
+ export declare function applyFieldChange(data: Record<string, unknown>, path: string, value: unknown): Record<string, unknown>;
13
+ export declare function SchemaForm(props: SchemaFormProps): import("preact").JSX.Element;
14
+ //# sourceMappingURL=SchemaForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaForm.d.ts","sourceRoot":"","sources":["../../src/form/SchemaForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAIjE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC1D,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AA2BD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACb,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,gCAiEhD"}
@@ -0,0 +1,33 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "preact/jsx-runtime";
2
+ import { sortFields } from "../fields/defaults.js";
3
+ import { FieldControl } from "./FieldControl.js";
4
+ function setAtPath(data, path, value) {
5
+ const parts = path.split(".");
6
+ const root = structuredClone(data);
7
+ let cursor = root;
8
+ for (let i = 0; i < parts.length - 1; i += 1) {
9
+ const key = parts[i];
10
+ if (cursor === null || typeof cursor !== "object") {
11
+ return root;
12
+ }
13
+ const container = cursor;
14
+ if (container[key] === undefined) {
15
+ container[key] = /^\d+$/.test(parts[i + 1]) ? [] : {};
16
+ }
17
+ cursor = container[key];
18
+ }
19
+ if (cursor !== null && typeof cursor === "object") {
20
+ cursor[parts[parts.length - 1]] = value;
21
+ }
22
+ return root;
23
+ }
24
+ export function applyFieldChange(data, path, value) {
25
+ return setAtPath(data, path, value);
26
+ }
27
+ export function SchemaForm(props) {
28
+ const { collection, entryId, data, errors = {}, onEntryIdChange, onChange, entryIdReadOnly, disabled, } = props;
29
+ return (_jsxs("form", { class: "cr-form", onSubmit: (event) => event.preventDefault(), noValidate: true, children: [_jsxs("div", { class: "cr-field", children: [_jsxs("label", { class: "cr-label", for: "cr-entry-id", children: ["Entry ID", _jsxs("span", { class: "cr-required", title: "Required", children: [" ", "*"] })] }), _jsx("p", { class: "cr-help", id: "cr-entry-id-help", children: "Stable identifier used in URLs and storage. Use lowercase letters, numbers, hyphens or underscores." }), _jsx("input", { id: "cr-entry-id", class: "cr-input", type: "text", value: entryId, readOnly: Boolean(entryIdReadOnly || disabled), required: true, pattern: "[a-z0-9][a-z0-9_-]*", "aria-describedby": "cr-entry-id-help", onInput: (event) => onEntryIdChange(event.currentTarget.value) }), errors["(id)"] ? (_jsx("p", { class: "cr-error", role: "alert", children: errors["(id)"] })) : null] }), sortFields(collection.fields).map((field) => (_jsx(FieldControl, { field: field, value: data[field.name], path: field.name, ...(errors[field.name] !== undefined
30
+ ? { error: errors[field.name] }
31
+ : {}), onChange: onChange, ...(disabled !== undefined ? { disabled } : {}) }, field.name)))] }));
32
+ }
33
+ //# sourceMappingURL=SchemaForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaForm.js","sourceRoot":"","sources":["../../src/form/SchemaForm.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export interface TabularParseLimits {
2
+ readonly maxBytes?: number;
3
+ readonly maxRows?: number;
4
+ }
5
+ export interface TabularParseSuccess {
6
+ readonly ok: true;
7
+ readonly headers: readonly string[];
8
+ readonly rows: ReadonlyArray<Record<string, string>>;
9
+ readonly sourceName: string;
10
+ }
11
+ export interface TabularParseFailure {
12
+ readonly ok: false;
13
+ readonly code: "EMPTY" | "TOO_LARGE" | "TOO_MANY_ROWS" | "UNSUPPORTED_TYPE" | "PARSE_ERROR";
14
+ readonly message: string;
15
+ }
16
+ export type TabularParseResult = TabularParseSuccess | TabularParseFailure;
17
+ /**
18
+ * Parse a CSV or Excel (`.xlsx`) file **in the browser**.
19
+ * Returns string cells only — callers must validate against ContentRail schemas
20
+ * before publishing. Never send the raw workbook to the Worker.
21
+ *
22
+ * Excel notes (`read-excel-file`):
23
+ * - Legacy binary `.xls` is not supported; re-save as `.xlsx` or use CSV.
24
+ * - Formula cells become their computed values when present in the file.
25
+ * - Spreadsheet error tokens (e.g. `#REF!`) become ordinary strings and must
26
+ * still fail independent schema/domain validation.
27
+ * - Unexpected columns are preserved in the row map; callers decide mapping.
28
+ */
29
+ export declare function parseTabularFile(file: File, limits?: TabularParseLimits): Promise<TabularParseResult>;
30
+ /**
31
+ * Map tabular rows to objects using a column → field map.
32
+ * Unmapped columns are ignored. Missing mapped columns become "".
33
+ */
34
+ export declare function mapTabularRows(rows: ReadonlyArray<Record<string, string>>, columnMap: Readonly<Record<string, string>>): Array<Record<string, string>>;
35
+ //# sourceMappingURL=tabular.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabular.d.ts","sourceRoot":"","sources":["../../src/import/tabular.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,IAAI,EACT,OAAO,GACP,WAAW,GACX,eAAe,GACf,kBAAkB,GAClB,aAAa,CAAC;IAClB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,GAAG,mBAAmB,CAAC;AAK3E;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,IAAI,EACV,MAAM,GAAE,kBAAuB,GAC9B,OAAO,CAAC,kBAAkB,CAAC,CAmD7B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAC3C,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAC1C,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAQ/B"}
@@ -0,0 +1,191 @@
1
+ import { readSheet } from "read-excel-file/universal";
2
+ const DEFAULT_MAX_BYTES = 512_000;
3
+ const DEFAULT_MAX_ROWS = 500;
4
+ /**
5
+ * Parse a CSV or Excel (`.xlsx`) file **in the browser**.
6
+ * Returns string cells only — callers must validate against ContentRail schemas
7
+ * before publishing. Never send the raw workbook to the Worker.
8
+ *
9
+ * Excel notes (`read-excel-file`):
10
+ * - Legacy binary `.xls` is not supported; re-save as `.xlsx` or use CSV.
11
+ * - Formula cells become their computed values when present in the file.
12
+ * - Spreadsheet error tokens (e.g. `#REF!`) become ordinary strings and must
13
+ * still fail independent schema/domain validation.
14
+ * - Unexpected columns are preserved in the row map; callers decide mapping.
15
+ */
16
+ export async function parseTabularFile(file, limits = {}) {
17
+ const maxBytes = limits.maxBytes ?? DEFAULT_MAX_BYTES;
18
+ const maxRows = limits.maxRows ?? DEFAULT_MAX_ROWS;
19
+ if (file.size > maxBytes) {
20
+ return {
21
+ ok: false,
22
+ code: "TOO_LARGE",
23
+ message: `File exceeds ${maxBytes} bytes.`,
24
+ };
25
+ }
26
+ const name = file.name.toLowerCase();
27
+ const isCsv = name.endsWith(".csv") || file.type === "text/csv";
28
+ const isLegacyXls = name.endsWith(".xls") && !name.endsWith(".xlsx");
29
+ const isXlsx = name.endsWith(".xlsx") ||
30
+ file.type.includes("spreadsheetml") ||
31
+ file.type ===
32
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
33
+ if (isLegacyXls) {
34
+ return {
35
+ ok: false,
36
+ code: "UNSUPPORTED_TYPE",
37
+ message: "Legacy .xls is not supported. Re-save as .xlsx or export CSV.",
38
+ };
39
+ }
40
+ if (!isCsv && !isXlsx) {
41
+ return {
42
+ ok: false,
43
+ code: "UNSUPPORTED_TYPE",
44
+ message: "Supported formats: .csv, .xlsx",
45
+ };
46
+ }
47
+ try {
48
+ const matrix = isCsv
49
+ ? parseCsvMatrix(await file.text())
50
+ : await readXlsxMatrix(file);
51
+ return matrixToTabular(matrix, file.name, maxRows);
52
+ }
53
+ catch (error) {
54
+ return {
55
+ ok: false,
56
+ code: "PARSE_ERROR",
57
+ message: error instanceof Error ? error.message : "Unable to parse spreadsheet.",
58
+ };
59
+ }
60
+ }
61
+ /**
62
+ * Map tabular rows to objects using a column → field map.
63
+ * Unmapped columns are ignored. Missing mapped columns become "".
64
+ */
65
+ export function mapTabularRows(rows, columnMap) {
66
+ return rows.map((row) => {
67
+ const mapped = {};
68
+ for (const [column, field] of Object.entries(columnMap)) {
69
+ mapped[field] = row[column] ?? "";
70
+ }
71
+ return mapped;
72
+ });
73
+ }
74
+ async function readXlsxMatrix(file) {
75
+ const buffer = await file.arrayBuffer();
76
+ const sheet = await readSheet(buffer);
77
+ return sheet.map((row) => row.map((cell) => {
78
+ if (cell === null || cell === undefined) {
79
+ return "";
80
+ }
81
+ if (cell instanceof Date) {
82
+ return cell.toISOString();
83
+ }
84
+ return String(cell);
85
+ }));
86
+ }
87
+ function matrixToTabular(matrix, sourceName, maxRows) {
88
+ if (matrix.length === 0) {
89
+ return { ok: false, code: "EMPTY", message: "Sheet is empty." };
90
+ }
91
+ const headerRow = matrix[0] ?? [];
92
+ const headers = headerRow.map((cell, index) => {
93
+ const label = String(cell ?? "").trim();
94
+ return label === "" ? `column_${index + 1}` : label;
95
+ });
96
+ if (headers.every((header) => header.startsWith("column_"))) {
97
+ const allBlank = matrix.every((row) => row.every((cell) => String(cell ?? "").trim() === ""));
98
+ if (allBlank) {
99
+ return { ok: false, code: "EMPTY", message: "Sheet is empty." };
100
+ }
101
+ }
102
+ const body = matrix.slice(1);
103
+ if (body.length > maxRows) {
104
+ return {
105
+ ok: false,
106
+ code: "TOO_MANY_ROWS",
107
+ message: `Row limit is ${maxRows} (found ${body.length}).`,
108
+ };
109
+ }
110
+ const rows = body
111
+ .map((row) => {
112
+ const record = {};
113
+ headers.forEach((header, index) => {
114
+ record[header] = String(row[index] ?? "").trim();
115
+ });
116
+ return record;
117
+ })
118
+ .filter((row) => Object.values(row).some((value) => value !== ""));
119
+ if (rows.length === 0) {
120
+ return { ok: false, code: "EMPTY", message: "No data rows found." };
121
+ }
122
+ return {
123
+ ok: true,
124
+ headers,
125
+ rows,
126
+ sourceName,
127
+ };
128
+ }
129
+ /**
130
+ * Minimal RFC 4180-oriented CSV parser for browser import.
131
+ * Supports quoted fields, escaped quotes, and CR/LF line endings.
132
+ */
133
+ function parseCsvMatrix(text) {
134
+ const rows = [];
135
+ let row = [];
136
+ let field = "";
137
+ let inQuotes = false;
138
+ for (let i = 0; i < text.length; i += 1) {
139
+ const char = text[i];
140
+ const next = text[i + 1];
141
+ if (inQuotes) {
142
+ if (char === '"' && next === '"') {
143
+ field += '"';
144
+ i += 1;
145
+ continue;
146
+ }
147
+ if (char === '"') {
148
+ inQuotes = false;
149
+ continue;
150
+ }
151
+ field += char;
152
+ continue;
153
+ }
154
+ if (char === '"') {
155
+ inQuotes = true;
156
+ continue;
157
+ }
158
+ if (char === ",") {
159
+ row.push(field);
160
+ field = "";
161
+ continue;
162
+ }
163
+ if (char === "\n") {
164
+ row.push(field);
165
+ rows.push(row);
166
+ row = [];
167
+ field = "";
168
+ continue;
169
+ }
170
+ if (char === "\r") {
171
+ if (next === "\n") {
172
+ continue;
173
+ }
174
+ row.push(field);
175
+ rows.push(row);
176
+ row = [];
177
+ field = "";
178
+ continue;
179
+ }
180
+ field += char;
181
+ }
182
+ if (inQuotes) {
183
+ throw new Error("Unterminated quoted CSV field.");
184
+ }
185
+ if (field.length > 0 || row.length > 0) {
186
+ row.push(field);
187
+ rows.push(row);
188
+ }
189
+ return rows;
190
+ }
191
+ //# sourceMappingURL=tabular.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tabular.js","sourceRoot":"","sources":["../../src/import/tabular.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @contentrail/editor — browser-safe schema-driven content editor.
3
+ * Talks only to authenticated ContentRail APIs. Never embed Git/R2 secrets.
4
+ */
5
+ export { createContentRailApiClient, type ContentRailApiClient, type ContentRailApiClientOptions, } from "./api/client.js";
6
+ export type { ApiErrorBody, ContentSnapshotResponse, EditorApiResult, PublishResponse, SiteSummary, StatusResponse, } from "./api/types.js";
7
+ export { clientValidateFields, emptyValueForField, emptyValueForFields, sortFields, } from "./fields/defaults.js";
8
+ export type { ArrayFieldSpec, BooleanFieldSpec, EditorCollectionConfig, EditorFieldBase, EditorFieldSpec, EditorSiteConfig, EditorWidget, EnumFieldSpec, NumberFieldSpec, ObjectFieldSpec, TextFieldSpec, UnsupportedFieldSpec, } from "./fields/types.js";
9
+ export { applyFieldChange, SchemaForm, type SchemaFormProps, } from "./form/SchemaForm.js";
10
+ export { FieldControl, type FieldControlProps } from "./form/FieldControl.js";
11
+ export { clearSessionDraft, loadSessionDraft, saveSessionDraft, type EntryDraft, } from "./state/draft.js";
12
+ export { EditorApp, type EditorAppProps } from "./ui/EditorApp.js";
13
+ export { mapTabularRows, parseTabularFile, type TabularParseFailure, type TabularParseLimits, type TabularParseResult, type TabularParseSuccess, } from "./import/tabular.js";
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,0BAA0B,EAC1B,KAAK,oBAAoB,EACzB,KAAK,2BAA2B,GACjC,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,YAAY,EACZ,uBAAuB,EACvB,eAAe,EACf,eAAe,EACf,WAAW,EACX,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,eAAe,EACf,aAAa,EACb,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,UAAU,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @contentrail/editor — browser-safe schema-driven content editor.
3
+ * Talks only to authenticated ContentRail APIs. Never embed Git/R2 secrets.
4
+ */
5
+ export { createContentRailApiClient, } from "./api/client.js";
6
+ export { clientValidateFields, emptyValueForField, emptyValueForFields, sortFields, } from "./fields/defaults.js";
7
+ export { applyFieldChange, SchemaForm, } from "./form/SchemaForm.js";
8
+ export { FieldControl } from "./form/FieldControl.js";
9
+ export { clearSessionDraft, loadSessionDraft, saveSessionDraft, } from "./state/draft.js";
10
+ export { EditorApp } from "./ui/EditorApp.js";
11
+ export { mapTabularRows, parseTabularFile, } from "./import/tabular.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,0BAA0B,GAG3B,MAAM,iBAAiB,CAAC;AASzB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,GACX,MAAM,sBAAsB,CAAC;AAe9B,OAAO,EACL,gBAAgB,EAChB,UAAU,GAEX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,YAAY,EAA0B,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,GAEjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAuB,MAAM,mBAAmB,CAAC;AACnE,OAAO,EACL,cAAc,EACd,gBAAgB,GAKjB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface EntryDraft {
2
+ readonly siteId: string;
3
+ readonly collection: string;
4
+ readonly entryId: string;
5
+ readonly data: unknown;
6
+ readonly baseVersion: string | null;
7
+ readonly updatedAt: string;
8
+ }
9
+ export declare function saveSessionDraft(draft: EntryDraft): void;
10
+ export declare function loadSessionDraft(siteId: string, collection: string, entryId: string): EntryDraft | null;
11
+ export declare function clearSessionDraft(siteId: string, collection: string, entryId: string): void;
12
+ //# sourceMappingURL=draft.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft.d.ts","sourceRoot":"","sources":["../../src/state/draft.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAQD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAQxD;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,UAAU,GAAG,IAAI,CAanB;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,IAAI,CAKN"}
@@ -0,0 +1,32 @@
1
+ const PREFIX = "contentrail-editor-draft:";
2
+ function keyFor(siteId, collection, entryId) {
3
+ return `${PREFIX}${siteId}:${collection}:${entryId}`;
4
+ }
5
+ export function saveSessionDraft(draft) {
6
+ if (typeof sessionStorage === "undefined") {
7
+ return;
8
+ }
9
+ sessionStorage.setItem(keyFor(draft.siteId, draft.collection, draft.entryId), JSON.stringify(draft));
10
+ }
11
+ export function loadSessionDraft(siteId, collection, entryId) {
12
+ if (typeof sessionStorage === "undefined") {
13
+ return null;
14
+ }
15
+ const raw = sessionStorage.getItem(keyFor(siteId, collection, entryId));
16
+ if (raw === null) {
17
+ return null;
18
+ }
19
+ try {
20
+ return JSON.parse(raw);
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ export function clearSessionDraft(siteId, collection, entryId) {
27
+ if (typeof sessionStorage === "undefined") {
28
+ return;
29
+ }
30
+ sessionStorage.removeItem(keyFor(siteId, collection, entryId));
31
+ }
32
+ //# sourceMappingURL=draft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"draft.js","sourceRoot":"","sources":["../../src/state/draft.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,GAAG,2BAA2B,CAAC;AAE3C,SAAS,MAAM,CAAC,MAAc,EAAE,UAAkB,EAAE,OAAe;IACjE,OAAO,GAAG,MAAM,GAAG,MAAM,IAAI,UAAU,IAAI,OAAO,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAiB;IAChD,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,cAAc,CAAC,OAAO,CACpB,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,EACrD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CACtB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,MAAc,EACd,UAAkB,EAClB,OAAe;IAEf,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IACxE,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,MAAc,EACd,UAAkB,EAClB,OAAe;IAEf,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE,CAAC;QAC1C,OAAO;IACT,CAAC;IACD,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;AACjE,CAAC"}