@cogenta/import 0.1.4 → 0.2.1

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 (53) hide show
  1. package/dist/csv-import.d.ts +11 -0
  2. package/dist/csv-import.d.ts.map +1 -0
  3. package/dist/csv-import.js +14 -0
  4. package/dist/csv-import.js.map +1 -0
  5. package/dist/csv.d.ts +15 -0
  6. package/dist/csv.d.ts.map +1 -0
  7. package/dist/csv.js +100 -0
  8. package/dist/csv.js.map +1 -0
  9. package/dist/feed.d.ts +4 -0
  10. package/dist/feed.d.ts.map +1 -0
  11. package/dist/feed.js +50 -0
  12. package/dist/feed.js.map +1 -0
  13. package/dist/generic-import.d.ts +56 -0
  14. package/dist/generic-import.d.ts.map +1 -0
  15. package/dist/generic-import.js +64 -0
  16. package/dist/generic-import.js.map +1 -0
  17. package/dist/index.d.ts +17 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +10 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/json-import.d.ts +52 -0
  22. package/dist/json-import.d.ts.map +1 -0
  23. package/dist/json-import.js +110 -0
  24. package/dist/json-import.js.map +1 -0
  25. package/dist/mapping.d.ts +23 -0
  26. package/dist/mapping.d.ts.map +1 -0
  27. package/dist/mapping.js +41 -0
  28. package/dist/mapping.js.map +1 -0
  29. package/dist/ssrf.d.ts +12 -0
  30. package/dist/ssrf.d.ts.map +1 -0
  31. package/dist/ssrf.js +106 -0
  32. package/dist/ssrf.js.map +1 -0
  33. package/dist/tracking.d.ts +82 -0
  34. package/dist/tracking.d.ts.map +1 -0
  35. package/dist/tracking.js +200 -0
  36. package/dist/tracking.js.map +1 -0
  37. package/dist/undo.d.ts +27 -0
  38. package/dist/undo.d.ts.map +1 -0
  39. package/dist/undo.js +47 -0
  40. package/dist/undo.js.map +1 -0
  41. package/dist/wordpress/analyze.d.ts +40 -0
  42. package/dist/wordpress/analyze.d.ts.map +1 -0
  43. package/dist/wordpress/analyze.js +111 -0
  44. package/dist/wordpress/analyze.js.map +1 -0
  45. package/dist/wordpress/import.d.ts +31 -0
  46. package/dist/wordpress/import.d.ts.map +1 -1
  47. package/dist/wordpress/import.js +199 -6
  48. package/dist/wordpress/import.js.map +1 -1
  49. package/dist/wordpress/media.d.ts +3 -0
  50. package/dist/wordpress/media.d.ts.map +1 -1
  51. package/dist/wordpress/media.js +39 -2
  52. package/dist/wordpress/media.js.map +1 -1
  53. package/package.json +6 -5
@@ -0,0 +1,11 @@
1
+ import type { GenericSourceRecord } from './generic-import.js';
2
+ /**
3
+ * CSV as an import source (fiche 25 task 5).
4
+ *
5
+ * `sourceId` is the row number (1-based, header excluded): stable across a
6
+ * re-analysis of the exact same file, which is what resume and undo rely on.
7
+ * A CSV re-exported with rows reordered gets a fresh run rather than a false
8
+ * resume — the same honest limit `parseCsv` itself does not try to solve.
9
+ */
10
+ export declare function csvToRecords(text: string): readonly GenericSourceRecord[];
11
+ //# sourceMappingURL=csv-import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv-import.d.ts","sourceRoot":"","sources":["../src/csv-import.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAE9D;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,mBAAmB,EAAE,CAGzE"}
@@ -0,0 +1,14 @@
1
+ import { parseCsv } from './csv.js';
2
+ /**
3
+ * CSV as an import source (fiche 25 task 5).
4
+ *
5
+ * `sourceId` is the row number (1-based, header excluded): stable across a
6
+ * re-analysis of the exact same file, which is what resume and undo rely on.
7
+ * A CSV re-exported with rows reordered gets a fresh run rather than a false
8
+ * resume — the same honest limit `parseCsv` itself does not try to solve.
9
+ */
10
+ export function csvToRecords(text) {
11
+ const { rows } = parseCsv(text);
12
+ return rows.map((values, index) => ({ sourceId: String(index + 1), values }));
13
+ }
14
+ //# sourceMappingURL=csv-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv-import.js","sourceRoot":"","sources":["../src/csv-import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAGnC;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC/B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;AAC/E,CAAC"}
package/dist/csv.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * A hand-rolled CSV parser (RFC 4180), fiche 25 task 5.
3
+ *
4
+ * R9: a correct parser — quoted fields, an embedded comma, an embedded
5
+ * newline inside a quoted field, a doubled `""` escaping a literal quote,
6
+ * a UTF-8 BOM, and both CRLF and bare LF line endings — is a hundred lines.
7
+ * No dependency earns its place over that.
8
+ */
9
+ export interface ParsedCsv {
10
+ readonly headers: readonly string[];
11
+ /** One object per data row, keyed by header. A short row pads with `''`; a long row's extra cells are dropped. */
12
+ readonly rows: readonly Readonly<Record<string, string>>[];
13
+ }
14
+ export declare function parseCsv(text: string): ParsedCsv;
15
+ //# sourceMappingURL=csv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv.d.ts","sourceRoot":"","sources":["../src/csv.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;IACnC,kHAAkH;IAClH,QAAQ,CAAC,IAAI,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAA;CAC3D;AA0ED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAqChD"}
package/dist/csv.js ADDED
@@ -0,0 +1,100 @@
1
+ import { CogentaError } from '@cogenta/core';
2
+ function stripBom(text) {
3
+ return text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
4
+ }
5
+ /** Splits CSV text into rows of raw cells, respecting quoted fields. */
6
+ function tokenize(text) {
7
+ const rows = [];
8
+ let row = [];
9
+ let cell = '';
10
+ let inQuotes = false;
11
+ let i = 0;
12
+ const length = text.length;
13
+ while (i < length) {
14
+ const char = text[i];
15
+ if (inQuotes) {
16
+ if (char === '"') {
17
+ if (text[i + 1] === '"') {
18
+ cell += '"';
19
+ i += 2;
20
+ continue;
21
+ }
22
+ inQuotes = false;
23
+ i += 1;
24
+ continue;
25
+ }
26
+ cell += char;
27
+ i += 1;
28
+ continue;
29
+ }
30
+ if (char === '"') {
31
+ inQuotes = true;
32
+ i += 1;
33
+ continue;
34
+ }
35
+ if (char === ',') {
36
+ row.push(cell);
37
+ cell = '';
38
+ i += 1;
39
+ continue;
40
+ }
41
+ if (char === '\r') {
42
+ // Peek past a possible \n — either way this ends the row.
43
+ row.push(cell);
44
+ cell = '';
45
+ rows.push(row);
46
+ row = [];
47
+ i += text[i + 1] === '\n' ? 2 : 1;
48
+ continue;
49
+ }
50
+ if (char === '\n') {
51
+ row.push(cell);
52
+ cell = '';
53
+ rows.push(row);
54
+ row = [];
55
+ i += 1;
56
+ continue;
57
+ }
58
+ cell += char;
59
+ i += 1;
60
+ }
61
+ if (cell.length > 0 || row.length > 0) {
62
+ row.push(cell);
63
+ rows.push(row);
64
+ }
65
+ return rows;
66
+ }
67
+ export function parseCsv(text) {
68
+ const rows = tokenize(stripBom(text)).filter((row) => !(row.length === 1 && row[0] === ''));
69
+ const [headerRow, ...dataRows] = rows;
70
+ if (headerRow === undefined) {
71
+ throw new CogentaError({
72
+ code: 'IMPORT_CSV_INVALID',
73
+ message: 'This CSV file has no header row.',
74
+ hint: 'The first line must name each column.',
75
+ });
76
+ }
77
+ const headers = headerRow.map((header) => header.trim());
78
+ const seen = new Set();
79
+ for (const header of headers) {
80
+ if (header.length === 0) {
81
+ throw new CogentaError({
82
+ code: 'IMPORT_CSV_INVALID',
83
+ message: 'A column header is empty.',
84
+ hint: 'Every column needs a non-empty name.',
85
+ });
86
+ }
87
+ if (seen.has(header)) {
88
+ throw new CogentaError({
89
+ code: 'IMPORT_CSV_INVALID',
90
+ message: `Column "${header}" appears more than once.`,
91
+ hint: 'Rename one of the duplicate columns.',
92
+ details: { header },
93
+ });
94
+ }
95
+ seen.add(header);
96
+ }
97
+ const parsedRows = dataRows.map((cells) => Object.fromEntries(headers.map((header, index) => [header, cells[index] ?? ''])));
98
+ return { headers, rows: parsedRows };
99
+ }
100
+ //# sourceMappingURL=csv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csv.js","sourceRoot":"","sources":["../src/csv.ts"],"names":[],"mappings":"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"}
package/dist/feed.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { GenericSourceRecord } from './generic-import.js';
2
+ /** `title`, `link`, `description`/`summary`/`content`, `pubDate`/`published`, `guid`/`id`. */
3
+ export declare function feedToRecords(xml: string): readonly GenericSourceRecord[];
4
+ //# sourceMappingURL=feed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feed.d.ts","sourceRoot":"","sources":["../src/feed.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAqB9D,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,mBAAmB,EAAE,CAkCzE"}
package/dist/feed.js ADDED
@@ -0,0 +1,50 @@
1
+ import { CogentaError } from '@cogenta/core';
2
+ import { children, firstChild, parseXmlDocument, textOfChild } from './wordpress/xml.js';
3
+ /**
4
+ * RSS 2.0 and Atom feed reading (fiche 25 task 5).
5
+ *
6
+ * Reuses the WXR reader's own XML parser rather than a new dependency (R9) —
7
+ * both formats are well-known, narrow dialects `parseXmlDocument` already
8
+ * reads safely (no DTD entity expansion, R8's own concern for content of
9
+ * unknown provenance).
10
+ */
11
+ function atomLink(item) {
12
+ for (const link of children(item, 'link')) {
13
+ if (link.attrs['rel'] === undefined || link.attrs['rel'] === 'alternate') {
14
+ return link.attrs['href'] ?? '';
15
+ }
16
+ }
17
+ return '';
18
+ }
19
+ /** `title`, `link`, `description`/`summary`/`content`, `pubDate`/`published`, `guid`/`id`. */
20
+ export function feedToRecords(xml) {
21
+ const root = parseXmlDocument(xml);
22
+ const isAtom = root.name === 'feed';
23
+ const container = isAtom ? root : (firstChild(root, 'channel') ?? root);
24
+ const itemName = isAtom ? 'entry' : 'item';
25
+ const items = children(container, itemName);
26
+ if (items.length === 0 && root.name !== 'rss' && !isAtom) {
27
+ throw new CogentaError({
28
+ code: 'IMPORT_FEED_INVALID',
29
+ message: 'This document is neither an RSS <rss> feed nor an Atom <feed>.',
30
+ hint: 'Point the importer at a real RSS 2.0 or Atom XML export.',
31
+ });
32
+ }
33
+ return items.map((item, index) => {
34
+ const title = textOfChild(item, 'title');
35
+ const link = isAtom ? atomLink(item) : textOfChild(item, 'link');
36
+ const description = isAtom
37
+ ? textOfChild(item, 'summary') || textOfChild(item, 'content')
38
+ : textOfChild(item, 'description');
39
+ const published = isAtom
40
+ ? textOfChild(item, 'published') || textOfChild(item, 'updated')
41
+ : textOfChild(item, 'pubDate');
42
+ const guid = isAtom ? textOfChild(item, 'id') : textOfChild(item, 'guid') || link;
43
+ const sourceId = guid.length > 0 ? guid : `${index + 1}`;
44
+ return {
45
+ sourceId,
46
+ values: { title, link, description, publishedAt: published },
47
+ };
48
+ });
49
+ }
50
+ //# sourceMappingURL=feed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feed.js","sourceRoot":"","sources":["../src/feed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAExF;;;;;;;GAOG;AAEH,SAAS,QAAQ,CAAC,IAA6C;IAC7D,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QAC1C,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,WAAW,EAAE,CAAC;YACzE,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAA;QACjC,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;IAElC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,CAAA;IACnC,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,CAAA;IACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAA;IAC1C,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;IAE3C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QACzD,MAAM,IAAI,YAAY,CAAC;YACrB,IAAI,EAAE,qBAAqB;YAC3B,OAAO,EAAE,gEAAgE;YACzE,IAAI,EAAE,0DAA0D;SACjE,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACxC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAChE,MAAM,WAAW,GAAG,MAAM;YACxB,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC;YAC9D,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;QACpC,MAAM,SAAS,GAAG,MAAM;YACtB,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC;YAChE,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAA;QAEjF,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,CAAA;QAExD,OAAO;YACL,QAAQ;YACR,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE;SAC7D,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,56 @@
1
+ import type { CollectionDefinition, ContentStore } from '@cogenta/schema';
2
+ import { type FieldMapping } from './mapping.js';
3
+ import type { ImportTrackingStore } from './tracking.js';
4
+ /**
5
+ * The shared engine behind CSV and RSS/Atom import (fiche 25 task 5).
6
+ *
7
+ * Both sources reduce to the same shape once parsed — a list of records, each
8
+ * with a stable `sourceId` and a bag of string values — so the mapping,
9
+ * preview, apply, resume and undo machinery is written once here rather than
10
+ * twice. WordPress keeps its own pipeline (`wordpress/import.ts`): its source
11
+ * shape is not tabular, and forcing it through this engine would lose the
12
+ * category/tag/media/author handling that is specific to it.
13
+ */
14
+ export interface GenericSourceRecord {
15
+ /** Stable across re-analysis of the same file — a CSV row number, an RSS item's guid/link. */
16
+ readonly sourceId: string;
17
+ readonly values: Readonly<Record<string, string>>;
18
+ }
19
+ export interface GenericPreviewReport {
20
+ readonly totalRecords: number;
21
+ readonly sourceFields: readonly string[];
22
+ readonly proposedMapping: FieldMapping;
23
+ /** The first few records, for the mapping/preview screen. */
24
+ readonly sample: readonly Readonly<Record<string, string>>[];
25
+ readonly warnings: readonly string[];
26
+ }
27
+ export declare function analyzeGeneric(records: readonly GenericSourceRecord[], targetCollection: CollectionDefinition): GenericPreviewReport;
28
+ export interface ApplyGenericOptions {
29
+ readonly records: readonly GenericSourceRecord[];
30
+ readonly mapping: FieldMapping;
31
+ readonly collections: readonly CollectionDefinition[];
32
+ readonly storeFor: (collection: CollectionDefinition) => ContentStore;
33
+ readonly tracking: ImportTrackingStore;
34
+ readonly runId: string;
35
+ readonly createdBy: string | null;
36
+ readonly status?: 'draft' | 'published';
37
+ }
38
+ export interface GenericApplyReport {
39
+ readonly imported: number;
40
+ /** Already recorded for this run — a resume, not a fresh write. */
41
+ readonly resumedSkips: number;
42
+ readonly errors: readonly {
43
+ readonly sourceId: string;
44
+ readonly message: string;
45
+ }[];
46
+ }
47
+ /**
48
+ * Writes every record not already recorded for this run.
49
+ *
50
+ * Resumable by construction: `tracking.doneSourceIds` is read once up front,
51
+ * and every successful write is recorded before moving to the next record —
52
+ * a process killed mid-run leaves a run whose next `applyGeneric` call picks
53
+ * up exactly where it stopped, with no duplicate entries.
54
+ */
55
+ export declare function applyGeneric(options: ApplyGenericOptions): Promise<GenericApplyReport>;
56
+ //# sourceMappingURL=generic-import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic-import.d.ts","sourceRoot":"","sources":["../src/generic-import.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACzE,OAAO,EAAE,KAAK,YAAY,EAAuC,MAAM,cAAc,CAAA;AACrF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAExD;;;;;;;;;GASG;AAEH,MAAM,WAAW,mBAAmB;IAClC,8FAA8F;IAC9F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;CAClD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;IACxC,QAAQ,CAAC,eAAe,EAAE,YAAY,CAAA;IACtC,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAAA;IAC5D,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CACrC;AAID,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,mBAAmB,EAAE,EACvC,gBAAgB,EAAE,oBAAoB,GACrC,oBAAoB,CActB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAA;IAChD,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAC9B,QAAQ,CAAC,WAAW,EAAE,SAAS,oBAAoB,EAAE,CAAA;IACrD,QAAQ,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,oBAAoB,KAAK,YAAY,CAAA;IACrE,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAA;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,CAAA;CACxC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,mEAAmE;IACnE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CACpF;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0C5F"}
@@ -0,0 +1,64 @@
1
+ import { proposeFieldMapping, resolveMapping } from './mapping.js';
2
+ const SAMPLE_SIZE = 5;
3
+ export function analyzeGeneric(records, targetCollection) {
4
+ const sourceFields = records[0] === undefined ? [] : Object.keys(records[0].values);
5
+ const warnings = [];
6
+ if (records.length === 0) {
7
+ warnings.push('The source carries no importable record.');
8
+ }
9
+ return {
10
+ totalRecords: records.length,
11
+ sourceFields,
12
+ proposedMapping: proposeFieldMapping(sourceFields, targetCollection),
13
+ sample: records.slice(0, SAMPLE_SIZE).map((record) => record.values),
14
+ warnings,
15
+ };
16
+ }
17
+ /**
18
+ * Writes every record not already recorded for this run.
19
+ *
20
+ * Resumable by construction: `tracking.doneSourceIds` is read once up front,
21
+ * and every successful write is recorded before moving to the next record —
22
+ * a process killed mid-run leaves a run whose next `applyGeneric` call picks
23
+ * up exactly where it stopped, with no duplicate entries.
24
+ */
25
+ export async function applyGeneric(options) {
26
+ const resolved = resolveMapping(options.mapping, options.collections);
27
+ const store = options.storeFor(resolved.collection);
28
+ const done = await options.tracking.doneSourceIds(options.runId);
29
+ let imported = 0;
30
+ let resumedSkips = 0;
31
+ const errors = [];
32
+ for (const record of options.records) {
33
+ if (done.has(record.sourceId)) {
34
+ resumedSkips += 1;
35
+ continue;
36
+ }
37
+ const values = {};
38
+ for (const [source, target] of resolved.fields) {
39
+ values[target] = record.values[source] ?? '';
40
+ }
41
+ try {
42
+ const entry = await store.create({
43
+ status: options.status ?? 'draft',
44
+ createdBy: options.createdBy,
45
+ values,
46
+ });
47
+ await options.tracking.recordItem({
48
+ runId: options.runId,
49
+ sourceId: record.sourceId,
50
+ collection: resolved.collection.name,
51
+ entryId: entry.id,
52
+ });
53
+ imported += 1;
54
+ }
55
+ catch (error) {
56
+ errors.push({
57
+ sourceId: record.sourceId,
58
+ message: error instanceof Error ? error.message : String(error),
59
+ });
60
+ }
61
+ }
62
+ return { imported, resumedSkips, errors };
63
+ }
64
+ //# sourceMappingURL=generic-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generic-import.js","sourceRoot":"","sources":["../src/generic-import.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,20 @@
1
+ export type { ParsedCsv } from './csv.js';
2
+ export { parseCsv } from './csv.js';
3
+ export { csvToRecords } from './csv-import.js';
4
+ export { feedToRecords } from './feed.js';
5
+ export type { ApplyGenericOptions, GenericApplyReport, GenericPreviewReport, GenericSourceRecord, } from './generic-import.js';
6
+ export { analyzeGeneric, applyGeneric } from './generic-import.js';
7
+ export type { ApplyJsonOptions, JsonApplyReport, JsonImportRecord, JsonPreviewReport, } from './json-import.js';
8
+ export { analyzeJson, applyJson, parseJsonImport } from './json-import.js';
9
+ export type { FieldMapping, ResolvedMapping } from './mapping.js';
10
+ export { proposeFieldMapping, resolveMapping } from './mapping.js';
11
+ export { assertPublicUrl, isPrivateAddress } from './ssrf.js';
12
+ export type { CreateImportRunInput, CreateImportTrackingStoreOptions, ImportItem, ImportRun, ImportRunStatus, ImportSource, ImportTrackingStore, } from './tracking.js';
13
+ export { createImportTrackingStore, IMPORT_ITEMS_TABLE, IMPORT_RUN_STATUSES, IMPORT_RUNS_TABLE, IMPORT_SOURCES, } from './tracking.js';
14
+ export type { UndoImportOptions, UndoImportReport } from './undo.js';
15
+ export { undoImport } from './undo.js';
16
+ export type { WordPressPreviewReport, WordPressSlugConflict } from './wordpress/analyze.js';
17
+ export { analyzeWordPress } from './wordpress/analyze.js';
1
18
  export { WORDPRESS_IMPORT_COLLECTIONS, wpCategory, wpComment, wpPage, wpPost, wpTag, } from './wordpress/collections.js';
2
19
  export type { ContentConversionNote, ContentConversionResult, DraftBlock, } from './wordpress/content-convert.js';
3
20
  export { convertContent, mediaUrlsOf, resolveMediaReferences } from './wordpress/content-convert.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,UAAU,EACV,SAAS,EACT,MAAM,EACN,MAAM,EACN,KAAK,GACN,MAAM,4BAA4B,CAAA;AACnC,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,UAAU,GACX,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACpG,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,YAAY,EACV,4BAA4B,EAC5B,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,YAAY,EACV,SAAS,EACT,SAAS,EACT,WAAW,EACX,UAAU,EACV,OAAO,EACP,WAAW,EACX,MAAM,EACN,UAAU,GACX,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClE,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAC1E,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC7D,YAAY,EACV,oBAAoB,EACpB,gCAAgC,EAChC,UAAU,EACV,SAAS,EACT,eAAe,EACf,YAAY,EACZ,mBAAmB,GACpB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,GACf,MAAM,eAAe,CAAA;AACtB,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAC3F,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EACL,4BAA4B,EAC5B,UAAU,EACV,SAAS,EACT,MAAM,EACN,MAAM,EACN,KAAK,GACN,MAAM,4BAA4B,CAAA;AACnC,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,UAAU,GACX,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AACpG,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,YAAY,EACV,4BAA4B,EAC5B,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,YAAY,EACV,SAAS,EACT,SAAS,EACT,WAAW,EACX,UAAU,EACV,OAAO,EACP,WAAW,EACX,MAAM,EACN,UAAU,GACX,MAAM,sBAAsB,CAAA;AAC7B,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA"}
package/dist/index.js CHANGED
@@ -1,3 +1,13 @@
1
+ export { parseCsv } from './csv.js';
2
+ export { csvToRecords } from './csv-import.js';
3
+ export { feedToRecords } from './feed.js';
4
+ export { analyzeGeneric, applyGeneric } from './generic-import.js';
5
+ export { analyzeJson, applyJson, parseJsonImport } from './json-import.js';
6
+ export { proposeFieldMapping, resolveMapping } from './mapping.js';
7
+ export { assertPublicUrl, isPrivateAddress } from './ssrf.js';
8
+ export { createImportTrackingStore, IMPORT_ITEMS_TABLE, IMPORT_RUN_STATUSES, IMPORT_RUNS_TABLE, IMPORT_SOURCES, } from './tracking.js';
9
+ export { undoImport } from './undo.js';
10
+ export { analyzeWordPress } from './wordpress/analyze.js';
1
11
  export { WORDPRESS_IMPORT_COLLECTIONS, wpCategory, wpComment, wpPage, wpPost, wpTag, } from './wordpress/collections.js';
2
12
  export { convertContent, mediaUrlsOf, resolveMediaReferences } from './wordpress/content-convert.js';
3
13
  export { importWordPress } from './wordpress/import.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,EAC5B,UAAU,EACV,SAAS,EACT,MAAM,EACN,MAAM,EACN,KAAK,GACN,MAAM,4BAA4B,CAAA;AAMnC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AAEpG,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAMvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAY9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAOzC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAOlE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAE1E,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAU7D,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,GACf,MAAM,eAAe,CAAA;AAEtB,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAEtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EACL,4BAA4B,EAC5B,UAAU,EACV,SAAS,EACT,MAAM,EACN,MAAM,EACN,KAAK,GACN,MAAM,4BAA4B,CAAA;AAMnC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AAEpG,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAMvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAE/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAY9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,52 @@
1
+ import type { CollectionDefinition, ContentStore } from '@cogenta/schema';
2
+ import type { ImportTrackingStore } from './tracking.js';
3
+ /**
4
+ * JSON import (fiche 25 task 5): one Cogenta site's content, moved into
5
+ * another.
6
+ *
7
+ * The format is intentionally minimal and self-contained — newline-delimited
8
+ * JSON, one entry per line, `{ collection, id?, status?, locale?, values }` —
9
+ * rather than a reuse of `@cogenta/export`'s own NDJSON format: that package
10
+ * is not present in this branch (no `packages/export`), so there is no
11
+ * `export@1.0` writer to round-trip against yet. This reader is written to
12
+ * the shape that format's manifest already documents (collection, id,
13
+ * status, locale, values are exactly its `entry` record's own fields), so
14
+ * once `@cogenta/export` lands, wiring this import to consume its real
15
+ * stream is a matter of mapping its `ExportEntryRecord` onto
16
+ * `JsonImportRecord`, not a rewrite.
17
+ */
18
+ export interface JsonImportRecord {
19
+ readonly collection: string;
20
+ /** Present on a real Cogenta export; absent on a hand-written JSON import, where the store assigns one. */
21
+ readonly id?: string;
22
+ readonly status?: 'draft' | 'published' | 'archived';
23
+ readonly locale?: string;
24
+ readonly values: Readonly<Record<string, unknown>>;
25
+ }
26
+ export declare function parseJsonImport(text: string): readonly JsonImportRecord[];
27
+ export interface JsonPreviewReport {
28
+ readonly totalRecords: number;
29
+ readonly byCollection: Readonly<Record<string, number>>;
30
+ /** A collection this site does not declare — the record will be skipped and named at apply time, never dropped silently. */
31
+ readonly unknownCollections: readonly string[];
32
+ readonly warnings: readonly string[];
33
+ }
34
+ export declare function analyzeJson(records: readonly JsonImportRecord[], collections: readonly CollectionDefinition[]): JsonPreviewReport;
35
+ export interface ApplyJsonOptions {
36
+ readonly records: readonly JsonImportRecord[];
37
+ readonly collections: readonly CollectionDefinition[];
38
+ readonly storeFor: (collection: CollectionDefinition) => ContentStore;
39
+ readonly tracking: ImportTrackingStore;
40
+ readonly runId: string;
41
+ readonly createdBy: string | null;
42
+ }
43
+ export interface JsonApplyReport {
44
+ readonly imported: number;
45
+ readonly resumedSkips: number;
46
+ readonly errors: readonly {
47
+ readonly sourceId: string;
48
+ readonly message: string;
49
+ }[];
50
+ }
51
+ export declare function applyJson(options: ApplyJsonOptions): Promise<JsonApplyReport>;
52
+ //# sourceMappingURL=json-import.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-import.d.ts","sourceRoot":"","sources":["../src/json-import.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AAExD;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,2GAA2G;IAC3G,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,UAAU,CAAA;IACpD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACnD;AAWD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,gBAAgB,EAAE,CAuCzE;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACvD,4HAA4H;IAC5H,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9C,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CACrC;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,WAAW,EAAE,SAAS,oBAAoB,EAAE,GAC3C,iBAAiB,CAuBnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAC7C,QAAQ,CAAC,WAAW,EAAE,SAAS,oBAAoB,EAAE,CAAA;IACrD,QAAQ,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,oBAAoB,KAAK,YAAY,CAAA;IACrE,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAA;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS;QAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CACpF;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CA8CnF"}
@@ -0,0 +1,110 @@
1
+ import { CogentaError } from '@cogenta/core';
2
+ function invalidLine(lineNumber, reason) {
3
+ return new CogentaError({
4
+ code: 'IMPORT_SOURCE_INVALID',
5
+ message: `Line ${lineNumber} of the JSON import is not usable: ${reason}.`,
6
+ hint: 'Each line must be a JSON object shaped { "collection": "...", "values": { ... } }.',
7
+ details: { line: lineNumber },
8
+ });
9
+ }
10
+ export function parseJsonImport(text) {
11
+ const records = [];
12
+ const lines = text.split(/\r\n|\n/);
13
+ lines.forEach((line, index) => {
14
+ if (line.trim().length === 0)
15
+ return;
16
+ const lineNumber = index + 1;
17
+ let parsed;
18
+ try {
19
+ parsed = JSON.parse(line);
20
+ }
21
+ catch {
22
+ throw invalidLine(lineNumber, 'not valid JSON');
23
+ }
24
+ if (typeof parsed !== 'object' || parsed === null)
25
+ throw invalidLine(lineNumber, 'not a JSON object');
26
+ const record = parsed;
27
+ if (typeof record['collection'] !== 'string' || record['collection'].length === 0) {
28
+ throw invalidLine(lineNumber, 'missing a "collection" name');
29
+ }
30
+ if (typeof record['values'] !== 'object' || record['values'] === null) {
31
+ throw invalidLine(lineNumber, 'missing a "values" object');
32
+ }
33
+ records.push({
34
+ collection: record['collection'],
35
+ ...(typeof record['id'] === 'string' ? { id: record['id'] } : {}),
36
+ ...(record['status'] === 'draft' ||
37
+ record['status'] === 'published' ||
38
+ record['status'] === 'archived'
39
+ ? { status: record['status'] }
40
+ : {}),
41
+ ...(typeof record['locale'] === 'string' ? { locale: record['locale'] } : {}),
42
+ values: record['values'],
43
+ });
44
+ });
45
+ return records;
46
+ }
47
+ export function analyzeJson(records, collections) {
48
+ const known = new Set(collections.map((c) => c.name));
49
+ const byCollection = {};
50
+ const unknown = new Set();
51
+ for (const record of records) {
52
+ byCollection[record.collection] = (byCollection[record.collection] ?? 0) + 1;
53
+ if (!known.has(record.collection))
54
+ unknown.add(record.collection);
55
+ }
56
+ const warnings = [];
57
+ if (unknown.size > 0) {
58
+ warnings.push(`${[...unknown].join(', ')} — not declared on this site; those records will be skipped.`);
59
+ }
60
+ return {
61
+ totalRecords: records.length,
62
+ byCollection,
63
+ unknownCollections: [...unknown],
64
+ warnings,
65
+ };
66
+ }
67
+ export async function applyJson(options) {
68
+ const collectionByName = new Map(options.collections.map((c) => [c.name, c]));
69
+ const done = await options.tracking.doneSourceIds(options.runId);
70
+ let imported = 0;
71
+ let resumedSkips = 0;
72
+ const errors = [];
73
+ for (const [index, record] of options.records.entries()) {
74
+ const sourceId = record.id ?? `line:${index + 1}`;
75
+ if (done.has(sourceId)) {
76
+ resumedSkips += 1;
77
+ continue;
78
+ }
79
+ const collection = collectionByName.get(record.collection);
80
+ if (collection === undefined) {
81
+ errors.push({
82
+ sourceId,
83
+ message: `Collection "${record.collection}" does not exist on this site.`,
84
+ });
85
+ continue;
86
+ }
87
+ try {
88
+ const store = options.storeFor(collection);
89
+ const entry = await store.create({
90
+ ...(record.id === undefined ? {} : { id: record.id }),
91
+ ...(record.status === undefined ? {} : { status: record.status }),
92
+ ...(record.locale === undefined ? {} : { locale: record.locale }),
93
+ createdBy: options.createdBy,
94
+ values: record.values,
95
+ });
96
+ await options.tracking.recordItem({
97
+ runId: options.runId,
98
+ sourceId,
99
+ collection: collection.name,
100
+ entryId: entry.id,
101
+ });
102
+ imported += 1;
103
+ }
104
+ catch (error) {
105
+ errors.push({ sourceId, message: error instanceof Error ? error.message : String(error) });
106
+ }
107
+ }
108
+ return { imported, resumedSkips, errors };
109
+ }
110
+ //# sourceMappingURL=json-import.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-import.js","sourceRoot":"","sources":["../src/json-import.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AA6B5C,SAAS,WAAW,CAAC,UAAkB,EAAE,MAAc;IACrD,OAAO,IAAI,YAAY,CAAC;QACtB,IAAI,EAAE,uBAAuB;QAC7B,OAAO,EAAE,QAAQ,UAAU,sCAAsC,MAAM,GAAG;QAC1E,IAAI,EAAE,oFAAoF;QAC1F,OAAO,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE;KAC9B,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,OAAO,GAAuB,EAAE,CAAA;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IAEnC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;QAC5B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QACpC,MAAM,UAAU,GAAG,KAAK,GAAG,CAAC,CAAA;QAE5B,IAAI,MAAe,CAAA;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,WAAW,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAA;QACjD,CAAC;QAED,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;YAC/C,MAAM,WAAW,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAA;QACpD,MAAM,MAAM,GAAG,MAAiC,CAAA;QAChD,IAAI,OAAO,MAAM,CAAC,YAAY,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClF,MAAM,WAAW,CAAC,UAAU,EAAE,6BAA6B,CAAC,CAAA;QAC9D,CAAC;QACD,IAAI,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC;YACtE,MAAM,WAAW,CAAC,UAAU,EAAE,2BAA2B,CAAC,CAAA;QAC5D,CAAC;QAED,OAAO,CAAC,IAAI,CAAC;YACX,UAAU,EAAE,MAAM,CAAC,YAAY,CAAC;YAChC,GAAG,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,OAAO;gBAChC,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW;gBAChC,MAAM,CAAC,QAAQ,CAAC,KAAK,UAAU;gBAC7B,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;gBAC9B,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,MAAM,EAAE,MAAM,CAAC,QAAQ,CAA4B;SACpD,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,OAAO,OAAO,CAAA;AAChB,CAAC;AAUD,MAAM,UAAU,WAAW,CACzB,OAAoC,EACpC,WAA4C;IAE5C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IACrD,MAAM,YAAY,GAA2B,EAAE,CAAA;IAC/C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAA;IAEjC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QAC5E,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACnE,CAAC;IAED,MAAM,QAAQ,GAAa,EAAE,CAAA;IAC7B,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACrB,QAAQ,CAAC,IAAI,CACX,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,8DAA8D,CACzF,CAAA;IACH,CAAC;IAED,OAAO;QACL,YAAY,EAAE,OAAO,CAAC,MAAM;QAC5B,YAAY;QACZ,kBAAkB,EAAE,CAAC,GAAG,OAAO,CAAC;QAChC,QAAQ;KACT,CAAA;AACH,CAAC;AAiBD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAyB;IACvD,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAU,CAAC,CAAC,CAAA;IACtF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAEhE,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,IAAI,YAAY,GAAG,CAAC,CAAA;IACpB,MAAM,MAAM,GAA4C,EAAE,CAAA;IAE1D,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QACxD,MAAM,QAAQ,GAAG,MAAM,CAAC,EAAE,IAAI,QAAQ,KAAK,GAAG,CAAC,EAAE,CAAA;QACjD,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvB,YAAY,IAAI,CAAC,CAAA;YACjB,SAAQ;QACV,CAAC;QAED,MAAM,UAAU,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;QAC1D,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC;gBACV,QAAQ;gBACR,OAAO,EAAE,eAAe,MAAM,CAAC,UAAU,gCAAgC;aAC1E,CAAC,CAAA;YACF,SAAQ;QACV,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;YAC1C,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC;gBAC/B,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;gBACrD,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;gBACjE,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;gBACjE,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,MAAM,EAAE,MAAM,CAAC,MAAM;aACtB,CAAC,CAAA;YACF,MAAM,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;gBAChC,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,QAAQ;gBACR,UAAU,EAAE,UAAU,CAAC,IAAI;gBAC3B,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC,CAAA;YACF,QAAQ,IAAI,CAAC,CAAA;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC5F,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,EAAE,CAAA;AAC3C,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { CollectionDefinition } from '@cogenta/schema';
2
+ /**
3
+ * Field correspondence, fiche 25 task 2.
4
+ *
5
+ * `null` on a source field means "ignore" — the preview names it, the
6
+ * mapping screen offers it, and the report counts it under
7
+ * `fieldsWithoutTarget` so an import never drops data silently.
8
+ */
9
+ export interface FieldMapping {
10
+ readonly targetCollection: string;
11
+ /** Source field name → target field name, or `null` to ignore it. */
12
+ readonly fields: Readonly<Record<string, string | null>>;
13
+ }
14
+ export interface ResolvedMapping {
15
+ readonly collection: CollectionDefinition;
16
+ /** Source field → target field, `null` entries already removed. */
17
+ readonly fields: ReadonlyMap<string, string>;
18
+ readonly ignored: readonly string[];
19
+ }
20
+ /** Proposes target field names by matching source header names case-insensitively (task 2's "correspondances proposées automatiquement"). */
21
+ export declare function proposeFieldMapping(sourceFields: readonly string[], collection: CollectionDefinition): FieldMapping;
22
+ export declare function resolveMapping(mapping: FieldMapping, collections: readonly CollectionDefinition[]): ResolvedMapping;
23
+ //# sourceMappingURL=mapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../src/mapping.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AAE3D;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAA;CACzD;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAA;IACzC,mEAAmE;IACnE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5C,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAA;CACpC;AAED,6IAA6I;AAC7I,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,UAAU,EAAE,oBAAoB,GAC/B,YAAY,CASd;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,YAAY,EACrB,WAAW,EAAE,SAAS,oBAAoB,EAAE,GAC3C,eAAe,CAgCjB"}