@graphty/graph-io 0.3.18 → 0.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -2
- package/dist/chunks/{escape-D-gZWO26.js → escape-CWExcecC.js} +3 -3
- package/dist/chunks/{escape-D-gZWO26.js.map → escape-CWExcecC.js.map} +1 -1
- package/dist/chunks/exporter-CbMZyVt-.js +735 -0
- package/dist/chunks/exporter-CbMZyVt-.js.map +1 -0
- package/dist/chunks/importer-BAP4PrxR.js +2194 -0
- package/dist/chunks/importer-BAP4PrxR.js.map +1 -0
- package/dist/chunks/{importer-Br_QeAeE.js → importer-BNFuV1-K.js} +5 -4
- package/dist/chunks/{importer-Br_QeAeE.js.map → importer-BNFuV1-K.js.map} +1 -1
- package/dist/chunks/{importer-d0uQxFp6.js → importer-BVGtU1NA.js} +5 -4
- package/dist/chunks/{importer-d0uQxFp6.js.map → importer-BVGtU1NA.js.map} +1 -1
- package/dist/chunks/{importer-DHagxvDD.js → importer-BW-Ft2ps.js} +5 -4
- package/dist/chunks/{importer-DHagxvDD.js.map → importer-BW-Ft2ps.js.map} +1 -1
- package/dist/chunks/{importer-Du5crN9l.js → importer-Bm1_5vPS.js} +275 -82
- package/dist/chunks/importer-Bm1_5vPS.js.map +1 -0
- package/dist/chunks/{importer-aNJfe0qu.js → importer-ByPGO-09.js} +2 -2
- package/dist/chunks/{importer-aNJfe0qu.js.map → importer-ByPGO-09.js.map} +1 -1
- package/dist/chunks/importer-DOepkgnG.js +1713 -0
- package/dist/chunks/importer-DOepkgnG.js.map +1 -0
- package/dist/chunks/json-elements-CZY1wiZh.js +779 -0
- package/dist/chunks/json-elements-CZY1wiZh.js.map +1 -0
- package/dist/chunks/{records-Bk9jgodz.js → records-BzNicMsf.js} +2 -2
- package/dist/chunks/{records-Bk9jgodz.js.map → records-BzNicMsf.js.map} +1 -1
- package/dist/chunks/{report-BOk0p5y8.js → report-BcWboivV.js} +95 -95
- package/dist/chunks/{report-BOk0p5y8.js.map → report-BcWboivV.js.map} +1 -1
- package/dist/chunks/weights-CwISIpCP.js +176 -0
- package/dist/chunks/weights-CwISIpCP.js.map +1 -0
- package/dist/chunks/{writer-GAdltGmC.js → writer-DQiKgQJc.js} +8 -179
- package/dist/chunks/writer-DQiKgQJc.js.map +1 -0
- package/dist/csv.js +5 -4
- package/dist/csv.js.map +1 -1
- package/dist/cx.d.ts +1 -0
- package/dist/cx.js +6 -0
- package/dist/cx.js.map +1 -0
- package/dist/cx2.d.ts +1 -0
- package/dist/cx2.js +10 -0
- package/dist/cx2.js.map +1 -0
- package/dist/dot.js +1 -1
- package/dist/gexf.js +15 -4
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +5 -4
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +145 -389
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +1 -1
- package/dist/json.js +1 -1
- package/dist/neo4j.js +5 -4
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +1 -1
- package/dist/pajek.js +1 -1
- package/dist/src/common/json-elements.d.ts +286 -0
- package/dist/src/common/json-elements.d.ts.map +1 -0
- package/dist/src/common/json-elements.js +926 -0
- package/dist/src/common/json-elements.js.map +1 -0
- package/dist/src/formats/cx/importer.d.ts +133 -0
- package/dist/src/formats/cx/importer.d.ts.map +1 -0
- package/dist/src/formats/cx/importer.js +2220 -0
- package/dist/src/formats/cx/importer.js.map +1 -0
- package/dist/src/formats/cx/index.d.ts +7 -0
- package/dist/src/formats/cx/index.d.ts.map +1 -0
- package/dist/src/formats/cx/index.js +7 -0
- package/dist/src/formats/cx/index.js.map +1 -0
- package/dist/src/formats/cx2/exporter.d.ts +59 -0
- package/dist/src/formats/cx2/exporter.d.ts.map +1 -0
- package/dist/src/formats/cx2/exporter.js +864 -0
- package/dist/src/formats/cx2/exporter.js.map +1 -0
- package/dist/src/formats/cx2/importer.d.ts +169 -0
- package/dist/src/formats/cx2/importer.d.ts.map +1 -0
- package/dist/src/formats/cx2/importer.js +1652 -0
- package/dist/src/formats/cx2/importer.js.map +1 -0
- package/dist/src/formats/cx2/index.d.ts +7 -0
- package/dist/src/formats/cx2/index.d.ts.map +1 -0
- package/dist/src/formats/cx2/index.js +7 -0
- package/dist/src/formats/cx2/index.js.map +1 -0
- package/dist/src/formats/gexf/exporter.d.ts +2 -0
- package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
- package/dist/src/formats/gexf/exporter.js +6 -0
- package/dist/src/formats/gexf/exporter.js.map +1 -1
- package/dist/src/formats/gexf/importer.d.ts +2 -4
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +2 -4
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gexf/index.d.ts +1 -1
- package/dist/src/formats/gexf/index.js +2 -2
- package/dist/src/formats/gexf/index.js.map +1 -1
- package/dist/src/formats/gml/exporter.js +1 -1
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +6 -104
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +5 -0
- package/dist/src/registry.js.map +1 -1
- package/dist/src/sniff.d.ts +1 -1
- package/dist/src/sniff.d.ts.map +1 -1
- package/dist/src/sniff.js +2 -0
- package/dist/src/sniff.js.map +1 -1
- package/package.json +11 -1
- package/src/common/json-elements.ts +1147 -0
- package/src/formats/cx/importer.ts +2733 -0
- package/src/formats/cx/index.ts +7 -0
- package/src/formats/cx2/exporter.ts +1036 -0
- package/src/formats/cx2/importer.ts +2187 -0
- package/src/formats/cx2/index.ts +7 -0
- package/src/formats/gexf/exporter.ts +11 -0
- package/src/formats/gexf/importer.ts +2 -2
- package/src/formats/gexf/index.ts +1 -1
- package/src/formats/gml/exporter.ts +1 -1
- package/src/formats/json/importer.ts +6 -105
- package/src/index.ts +10 -0
- package/src/registry.ts +5 -0
- package/src/sniff.ts +14 -1
- package/dist/chunks/importer-Du5crN9l.js.map +0 -1
- package/dist/chunks/writer-GAdltGmC.js.map +0 -1
package/dist/neo4j.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"neo4j.js","sources":["../src/formats/neo4j/header.ts","../src/formats/neo4j/importer.ts","../src/formats/neo4j/exporter.ts","../src/formats/neo4j/index.ts"],"sourcesContent":["/**\n * The neo4j-admin import header grammar (research note 07 section 2.6): every header cell is\n * `<name>:<field type>(<id space>){<options>}` where the name and every later part are optional.\n * The field types `ID`, `LABEL`, `START_ID`, `END_ID`, `TYPE` and `IGNORE` are structural; any\n * other field type is a property type of design section 5.1 (`int`, `long`, `float`, `double`,\n * `boolean`, `byte`, `short`, `char`, `string`, `point`, `date`, `localtime`, `time`,\n * `localdatetime`, `datetime`, `duration`, each with an optional `[]` suffix); a cell without a\n * colon is a string property. An id space may follow `ID`, `START_ID` and `END_ID`; brace options\n * (`label`, `id-type`) may follow any structural type.\n */\n\nimport { GraphFormatError } from \"@graphty/graph-format\";\n\n/** The structural field types and the marker for a property column. */\nexport type FieldKind = \"ID\" | \"LABEL\" | \"START_ID\" | \"END_ID\" | \"TYPE\" | \"IGNORE\" | \"PROPERTY\";\n\n/** One parsed header cell. */\nexport interface HeaderField {\n /** The cell text as written. */\n readonly text: string;\n /** The property name (the id property name for `name:ID`); empty when none. */\n readonly name: string;\n /** The field kind. */\n readonly kind: FieldKind;\n /** The property type text for a PROPERTY field (null when the cell declares none); null otherwise. */\n readonly type: string | null;\n /** The id space of an ID / START_ID / END_ID field, or null. */\n readonly space: string | null;\n /** The brace options, keys lower-cased. */\n readonly options: ReadonlyMap<string, string>;\n}\n\nconst STRUCTURAL: ReadonlySet<string> = new Set([\"ID\", \"LABEL\", \"START_ID\", \"END_ID\", \"TYPE\", \"IGNORE\"]);\nconst SPACE_KINDS: ReadonlySet<string> = new Set([\"ID\", \"START_ID\", \"END_ID\"]);\nconst HEADER_MARKER = /^[^:{}()]*:\\s*(ID|START_ID|END_ID)\\s*(\\(|\\{|$)/i;\nconst CELL = /^([^:(){}]*)(?::([^:(){}]*))?(?:\\(([^)]*)\\))?(?:\\{([^}]*)\\})?$/;\n\n/**\n * Whether a record looks like a section header: some cell declares an `ID`, `START_ID` or `END_ID`\n * field. The neo4j-admin convention allows several files, each with its own header; graphty's\n * single-file convention (the CSVDataSource of graphty-element) concatenates sections, so a header\n * may appear anywhere.\n * @param cells - the record's cells\n * @param count - how many cells are valid\n * @returns true when the record is a header\n */\nexport function isHeaderRecord(cells: readonly string[], count: number): boolean {\n for (let i = 0; i < count; i++) {\n const cell = cells[i];\n // every header marker holds a colon; the indexOf keeps the regex off the data rows\n if (cell.indexOf(\":\") >= 0 && HEADER_MARKER.test(cell.trim())) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Parse one header cell.\n * @param text - the cell text\n * @returns the field; E_UNSUPPORTED (reason \"header\") for a cell outside the grammar\n */\nexport function parseHeaderField(text: string): HeaderField {\n const trimmed = text.trim();\n const m = CELL.exec(trimmed);\n if (m === null) {\n throw headerError(text, \"not a neo4j header cell\");\n }\n const name = m[1].trim();\n const rawType = m[2] === undefined ? null : m[2].trim();\n const space = m[3] === undefined ? null : m[3].trim();\n const options = parseOptions(text, m[4]);\n if (rawType === null) {\n // `name` alone: a string property\n if (name.length === 0) {\n throw headerError(text, \"an empty header cell\");\n }\n if (space !== null || options.size > 0) {\n throw headerError(text, \"an id space or options need a field type\");\n }\n return { text, name, kind: \"PROPERTY\", type: null, space: null, options };\n }\n if (rawType.length === 0) {\n throw headerError(text, \"an empty field type\");\n }\n const upper = rawType.toUpperCase();\n if (STRUCTURAL.has(upper)) {\n const kind = upper as Exclude<FieldKind, \"PROPERTY\">;\n if (space !== null && !SPACE_KINDS.has(kind)) {\n throw headerError(text, `an id space is only allowed on ID, START_ID and END_ID, not ${kind}`);\n }\n if (name.length > 0 && kind !== \"ID\" && kind !== \"IGNORE\") {\n throw headerError(text, `a ${kind} field cannot be stored as a property`);\n }\n return { text, name, kind, type: null, space: space === \"\" ? null : space, options };\n }\n if (name.length === 0) {\n throw headerError(text, \"a property column needs a name\");\n }\n if (space !== null) {\n throw headerError(text, \"an id space is only allowed on ID, START_ID and END_ID\");\n }\n return { text, name, kind: \"PROPERTY\", type: rawType, space: null, options };\n}\n\n/**\n * Parse the `{key:value, key:value}` options of a header cell.\n * @param text - the whole cell, for errors\n * @param body - the text between the braces, or undefined when absent\n * @returns the options with lower-cased keys\n */\nfunction parseOptions(text: string, body: string | undefined): ReadonlyMap<string, string> {\n const options = new Map<string, string>();\n if (body === undefined || body.trim().length === 0) {\n return options;\n }\n for (const part of body.split(\",\")) {\n const colon = part.indexOf(\":\");\n if (colon < 0) {\n throw headerError(text, `option \"${part.trim()}\" is not key:value`);\n }\n const key = part.slice(0, colon).trim().toLowerCase();\n const value = part.slice(colon + 1).trim();\n if (key.length === 0) {\n throw headerError(text, \"an option needs a key\");\n }\n options.set(key, value);\n }\n return options;\n}\n\n/**\n * The error of a malformed header cell.\n * @param text - the cell\n * @param reason - why\n * @returns the error\n */\nfunction headerError(text: string, reason: string): GraphFormatError {\n return new GraphFormatError(\"E_UNSUPPORTED\", `header cell \"${text}\": ${reason}`, {\n reason: \"header\",\n cell: text,\n detail: reason,\n });\n}\n\n/**\n * Write a header cell from its parts, the inverse of parseHeaderField.\n * @param name - the property name, or empty\n * @param type - the field type or property type\n * @param space - the id space, or null\n * @returns the cell text\n */\nexport function formatHeaderField(name: string, type: string, space: string | null): string {\n const base = `${name}:${type}`;\n return space === null ? base : `${base}(${space})`;\n}\n","/**\n * The Neo4j importer (design sections 8.4 and 5.1, research note 07 sections 2.6 and 2.10): reads\n * neo4j-admin import CSV -- node tables with `:ID`, `:LABEL` and typed property columns,\n * relationship tables with `:START_ID`, `:END_ID`, `:TYPE` and typed property columns -- and pushes\n * scalars into the sink one record at a time. Input is one or more files: the primary input plus the\n * `nodes` and `relationships` option inputs, each read in order; every input holds one or more\n * sections, each starting with its own header row (the single-file convention of graphty-element's\n * CSVDataSource, where a node table and a relationship table follow each other in one file).\n *\n * Mapping (design section 5.1 and decision Q27):\n * - Property columns are declared up front from the header types (`int` -> i32, `long` -> f64\n * with a precision issue beyond 2^53, `float` -> f32, `double` -> f64, `boolean` -> bool,\n * `string` / `char` / `duration` -> string, temporal types -> f64 milliseconds with a `.text`\n * companion when the source text is not canonical, `point` -> json, `type[]` -> list); an\n * untyped column is a string property. An unquoted empty cell is \"property not set\"; a quoted\n * empty cell is an empty string (or an empty list), as neo4j-admin stores it by default.\n * - `:LABEL` becomes the node list-of-dict column `labels` (role `labels`); `:TYPE` the edge dict\n * column `type` (role `kind`); an id space `:ID(Space)` the node dict column `idSpace` (role\n * `idSpace`), and a stored id `name:ID(Space)` also a string node column `name` whose\n * `origin.namespace` is the space. A property whose name collides with one of those is renamed\n * `<name>#<name>` (design section 5.6).\n * - Id spaces: neo4j-admin keeps one id space per `:ID(Space)` name, so `1` in `:ID(Product)` and\n * `1` in `:ID(Category)` are two nodes. The core has one id space, so a node of a spaced section\n * is stored under the string id `Space:id` (every row of the section, collision or not, so an id\n * never depends on file order), its id text goes into the node string column `originalId` and\n * its space into `idSpace`. The column has no role: the `originalId` role means an id rewritten by\n * `sanitizeIds: \"mangle\"`, which other importers restore as the node id. `:START_ID(Space)` /\n * `:END_ID(Space)` endpoints are qualified the same way before the lookup; an endpoint without a\n * space is looked up as written.\n * - Ids are text cells coerced by the `ids` option (\"canonical\" by default, so `1` is the number 1\n * and `007` stays a string; integers beyond 2^53 stay strings). Relationships are always directed\n * (\"In Neo4j, all relationships have a direction\"), so the sink is set directed before the first\n * edge and `onMixedDirection: \"undirected\"` is the way to read a file as undirected.\n * - `:IGNORE` columns are skipped and counted in a loss note.\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n GraphFormatError,\n type GraphSink,\n INVALID_INDEX,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport {\n type AttributeDeclarationInput,\n declareAttribute,\n declareCompanion,\n type DeclaredAttribute,\n declareOn,\n losesPrecision,\n parseDeclaredTemporal,\n parseDeclaredValue,\n PRECISION_CODE,\n RENAMED_CODE,\n takenIn,\n uniqueColumnName,\n} from \"../../common/attributes.js\";\nimport {\n DUPLICATE_NODE_CODE as SHARED_DUPLICATE_NODE_CODE,\n MISSING_ENDPOINT_CODE as SHARED_MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE as SHARED_MISSING_ID_CODE,\n ROLE_TAKEN_CODE as SHARED_ROLE_TAKEN_CODE,\n} from \"../../common/codes.js\";\nimport { type DeclaredTypeSpec } from \"../../common/declared-types.js\";\nimport { DirectionResolver } from \"../../common/direction.js\";\nimport { ID_MERGED_CODE as SHARED_ID_MERGED_CODE, IdCoercer } from \"../../common/ids.js\";\nimport { inputLength, isImportInput, type ReadOptions, throwIfAborted } from \"../../common/input.js\";\nimport { type ListSyntax, splitListText } from \"../../common/lists.js\";\nimport {\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { parseWeightText } from \"../../common/weights.js\";\nimport {\n type CommonImportOptions,\n type GraphImporter,\n ImportError,\n type ImportInput,\n type ImportReport,\n} from \"../../types.js\";\nimport { checkRecordSyntax, RecordReader, type RecordSyntax } from \"../csv/records.js\";\nimport { type FieldKind, type HeaderField, isHeaderRecord, parseHeaderField } from \"./header.js\";\n\n/** The format-specific options of the Neo4j importer. */\nexport interface Neo4jImportOptions {\n /** Further node files, each with its own header row(s); read after the primary input. */\n nodes?: ImportInput | readonly ImportInput[] | undefined;\n /** Relationship files, each with its own header row(s); read after the node files. */\n relationships?: ImportInput | readonly ImportInput[] | undefined;\n /**\n * The field delimiter (neo4j-admin `--delimiter`); one character. When absent it is sniffed\n * from the first rows between \",\" and a tab, so a `.tsv` file needs no option.\n */\n delimiter?: string | undefined;\n /** The array delimiter of list values and `:LABEL` cells (neo4j-admin `--array-delimiter`); \";\" by default. */\n arrayDelimiter?: \";\" | \",\" | \"|\" | undefined;\n /** The quote character (neo4j-admin `--quote`); one character; a double quote by default. */\n quote?: string | undefined;\n}\n\n/** The name of the node list column holding `:LABEL` values. */\nexport const LABELS_COLUMN = \"labels\";\n\n/** The name of the edge dict column holding `:TYPE` values. */\nexport const TYPE_COLUMN = \"type\";\n\n/** The name of the node dict column holding the id space of `:ID(Space)`. */\nexport const ID_SPACE_COLUMN = \"idSpace\";\n\n/** The name of the node string column holding the id text of a node of an id space (its id is `Space:id`). */\nexport const ORIGINAL_ID_COLUMN = \"originalId\";\n\n/** Issue code: a header row (or a whole section) is malformed; the import aborts. */\nexport const HEADER_CODE = \"E_NEO4J_HEADER\";\n\n/** Issue code: a row has a different number of cells than its header. */\nexport const COLUMN_COUNT_CODE = \"E_NEO4J_COLUMN_COUNT\";\n\n/** Issue code: a node row has an unquoted empty `:ID` cell (a quoted empty cell is the id \"\"). */\nexport const MISSING_ID_CODE = SHARED_MISSING_ID_CODE;\n\n/** Issue code: a relationship row has an unquoted empty `:START_ID` or `:END_ID` cell. */\nexport const MISSING_ENDPOINT_CODE = SHARED_MISSING_ENDPOINT_CODE;\n\n/** Issue code: a node id was declared twice (same id space); the later row's properties win. */\nexport const DUPLICATE_NODE_CODE = SHARED_DUPLICATE_NODE_CODE;\n\n/**\n * Issue code: a node id was declared in two id spaces -- a spaced id `Space:id` equals the text of an\n * id declared without a space; the later row is skipped.\n */\nexport const ID_SPACE_COLLISION_CODE = \"E_NEO4J_ID_SPACE_COLLISION\";\n\n/**\n * Issue code: a `:START_ID(Space)` / `:END_ID(Space)` endpoint's qualified id `Space:id` names a node a\n * node row declared in another id space (without a space); the row is skipped.\n */\nexport const ENDPOINT_SPACE_CODE = \"E_NEO4J_ENDPOINT_SPACE\";\n\n/** Issue code: two different id cells became one id under `ids: \"number\"`. */\nexport const ID_MERGED_CODE = SHARED_ID_MERGED_CODE;\n\n/** Issue code: a header brace option the importer does not act on. */\nexport const HEADER_OPTION_CODE = \"W_NEO4J_HEADER_OPTION_IGNORED\";\n\n/** Issue code: a reserved column (labels / type / idSpace) lost its role because the sink already holds it. */\nexport const ROLE_TAKEN_CODE = SHARED_ROLE_TAKEN_CODE;\n\n/** Loss code: `:IGNORE` columns were skipped. */\nexport const IGNORED_COLUMNS_LOSS = \"W_NEO4J_IGNORED_COLUMNS\";\n\n/** The common options the Neo4j importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"weightFrom\",\n \"weightDtype\",\n \"long\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\nconst NEO4J = \"neo4j\";\n\n/** Rows between two checks of the cancellation signal (a whole string input is one chunk). */\nconst ABORT_CHECK_INTERVAL = 64;\n\nconst LABELS_DECL: ColumnDecl = {\n name: LABELS_COLUMN,\n dtype: \"list\",\n itemDtype: \"dict\",\n nullable: true,\n role: \"labels\",\n origin: { format: NEO4J, id: \":LABEL\", title: null, type: \"LABEL\", namespace: null },\n};\n\nconst TYPE_DECL: ColumnDecl = {\n name: TYPE_COLUMN,\n dtype: \"dict\",\n nullable: true,\n role: \"kind\",\n origin: { format: NEO4J, id: \":TYPE\", title: null, type: \"TYPE\", namespace: null },\n};\n\nconst ID_SPACE_DECL: ColumnDecl = {\n name: ID_SPACE_COLUMN,\n dtype: \"dict\",\n nullable: true,\n role: \"idSpace\",\n origin: { format: NEO4J, id: \":ID\", title: null, type: \"ID\", namespace: null },\n};\n\nconst ORIGINAL_ID_DECL: ColumnDecl = {\n name: ORIGINAL_ID_COLUMN,\n dtype: \"string\",\n nullable: true,\n // origin.type stays null so the column is never mistaken for a stored id (`name:ID`)\n origin: { format: NEO4J, id: \":ID\", title: null, type: null, namespace: null },\n};\n\nconst ARRAY_DELIMITERS: Readonly<Record<string, ListSyntax>> = { \";\": \"semicolon\", \",\": \"comma\", \"|\": \"pipe\" };\n\n/** The resolved format-specific options. */\ninterface ResolvedNeo4jOptions {\n readonly nodes: readonly ImportInput[];\n readonly relationships: readonly ImportInput[];\n readonly syntax: RecordSyntax;\n readonly listSyntax: ListSyntax;\n}\n\n/** One property column of a section. */\ninterface PropertySlot {\n /** The cell index. */\n readonly cell: number;\n /** The column name (after any rename). */\n readonly name: string;\n /** The column handle. */\n readonly handle: ColumnHandle;\n /** How the cell text is parsed. */\n readonly spec: DeclaredTypeSpec;\n /** The declaration of the companion text column of a temporal property, or null. */\n readonly companionDecl: ColumnDecl | null;\n /** The companion's handle once a value needed it (design section 5.1); INVALID_INDEX before. */\n companion: ColumnHandle;\n}\n\n/** A node section: the header interpreted. */\ninterface NodeSection {\n readonly kind: \"node\";\n readonly width: number;\n readonly idCell: number;\n /** The column holding the id as a property (`name:ID`), or INVALID_INDEX. */\n readonly idHandle: ColumnHandle;\n readonly space: string | null;\n readonly spaceCode: number;\n readonly labelCells: readonly number[];\n readonly extraLabels: readonly string[];\n readonly properties: readonly PropertySlot[];\n}\n\n/** A relationship section: the header interpreted. */\ninterface RelationshipSection {\n readonly kind: \"relationship\";\n readonly width: number;\n readonly startCell: number;\n readonly endCell: number;\n /** The id space of `:START_ID` / `:END_ID`, or null when the header declares none. */\n readonly startSpace: string | null;\n readonly endSpace: string | null;\n /** The id space of `:START_ID` / `:END_ID` as a registry code, or 0 when the header declares none. */\n readonly startSpaceCode: number;\n readonly endSpaceCode: number;\n /** The `:TYPE` cell, or -1. */\n readonly typeCell: number;\n /** The cell of the property named by `weightFrom`, or -1. */\n readonly weightCell: number;\n readonly properties: readonly PropertySlot[];\n}\n\ntype Section = NodeSection | RelationshipSection;\n\n/** The delimiters sniffed between when none is given: neo4j-admin's default and the TSV tab. */\nconst NEO4J_DELIMITER_CANDIDATES: readonly string[] = Object.freeze([\",\", \"\\t\"]);\n\n/**\n * Resolve the format-specific options.\n * @param options - the caller's options\n * @returns the resolved options; E_UNSUPPORTED for an invalid value\n */\nfunction resolveNeo4jOptions(options: Neo4jImportOptions | undefined): ResolvedNeo4jOptions {\n const o: Neo4jImportOptions = options ?? {};\n const arrayDelimiter = o.arrayDelimiter ?? \";\";\n const listSyntax = ARRAY_DELIMITERS[arrayDelimiter];\n if (typeof arrayDelimiter !== \"string\" || listSyntax === undefined) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option arrayDelimiter: ${JSON.stringify(arrayDelimiter)} is not one of \";\", \",\", \"|\"`,\n { option: \"arrayDelimiter\", found: arrayDelimiter },\n );\n }\n const syntax = checkRecordSyntax({\n delimiter: o.delimiter ?? null,\n quote: o.quote ?? '\"',\n candidates: NEO4J_DELIMITER_CANDIDATES.filter((d) => d !== arrayDelimiter),\n });\n if (syntax.delimiter === arrayDelimiter) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"options delimiter and arrayDelimiter must differ\", {\n option: \"arrayDelimiter\",\n found: arrayDelimiter,\n });\n }\n return {\n nodes: inputList(\"nodes\", o.nodes),\n relationships: inputList(\"relationships\", o.relationships),\n syntax,\n listSyntax,\n };\n}\n\n/**\n * Normalise an input-list option.\n * @param name - the option name\n * @param value - one input, a list of inputs, or undefined\n * @returns the inputs; E_UNSUPPORTED for anything else\n */\nfunction inputList(name: string, value: unknown): readonly ImportInput[] {\n if (value === undefined || value === null) {\n return [];\n }\n const list: unknown[] = Array.isArray(value) ? (value as unknown[]) : [value];\n for (const item of list) {\n if (!isImportInput(item)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option ${name}: an entry is not an ImportInput`, {\n option: name,\n found: typeof item,\n });\n }\n }\n return list as ImportInput[];\n}\n\n/**\n * Which nodes were declared by a node row and in which id space, by node index, so a repeated id\n * is reported (a duplicate in one space, a collision across spaces).\n */\nclass NodeRegistry {\n private codes = new Uint32Array(1024);\n\n private readonly spaces = new Map<string | null, number>();\n\n /**\n * The code of an id space (1 for \"no space\").\n * @param space - the space name or null\n * @returns a code >= 1\n */\n codeOf(space: string | null): number {\n let code = this.spaces.get(space);\n if (code === undefined) {\n code = this.spaces.size + 1;\n this.spaces.set(space, code);\n }\n return code;\n }\n\n /**\n * Record that a node row declared a node.\n * @param index - the node index\n * @param code - the space code\n * @returns \"new\" for a first declaration, \"duplicate\" for a repeat in the same space, \"collision\" across spaces\n */\n declare(index: number, code: number): \"new\" | \"duplicate\" | \"collision\" {\n if (index >= this.codes.length) {\n let size = this.codes.length * 2;\n while (size <= index) {\n size *= 2;\n }\n const grown = new Uint32Array(size);\n grown.set(this.codes);\n this.codes = grown;\n }\n const previous = this.codes[index];\n if (previous === 0) {\n this.codes[index] = code;\n return \"new\";\n }\n return previous === code ? \"duplicate\" : \"collision\";\n }\n\n /**\n * The space code a node row declared a node in.\n * @param index - the node index\n * @returns the code, or 0 when no node row declared the node\n */\n codeAt(index: number): number {\n return index < this.codes.length ? this.codes[index] : 0;\n }\n}\n\n/**\n * Byte progress over several inputs as one sequence: each input's progress is offset by the bytes\n * of the inputs before it, and the total is known only when every input is in memory.\n */\nclass ProgressTracker {\n private readonly callback: ((bytesDone: number, bytesTotal?: number) => void) | null;\n\n private readonly total: number | undefined;\n\n private offset = 0;\n\n private lastDone = 0;\n\n /**\n * Create a tracker.\n * @param callback - the caller's onProgress, or null\n * @param inputs - every input in reading order\n */\n constructor(callback: ((bytesDone: number, bytesTotal?: number) => void) | null, inputs: readonly ImportInput[]) {\n this.callback = callback;\n let total: number | undefined = 0;\n for (const input of inputs) {\n const length = inputLength(input);\n if (length === null) {\n total = undefined;\n break;\n }\n total += length;\n }\n this.total = total;\n }\n\n /**\n * The read options for one input.\n * @param signal - the cancellation signal\n * @returns options whose onProgress reports cumulative bytes\n */\n optionsFor(signal: AbortSignal | null): ReadOptions {\n const { callback } = this;\n if (callback === null) {\n return { signal };\n }\n return {\n signal,\n onProgress: (done: number): void => {\n this.lastDone = done;\n callback(this.offset + done, this.total);\n },\n };\n }\n\n /** Move the offset past the input just finished. */\n finishInput(): void {\n this.offset += this.lastDone;\n this.lastDone = 0;\n }\n}\n\n/**\n * The state of one import call: the sink, the report, the resolved options, the reserved column\n * handles and the per-section row handlers.\n */\nclass Neo4jImportSession {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly common: ResolvedImportOptions;\n\n private readonly options: ResolvedNeo4jOptions;\n\n private readonly coercer: IdCoercer;\n\n private readonly direction: DirectionResolver;\n\n private readonly registry = new NodeRegistry();\n\n private labelsHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private typeHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private idSpaceHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private originalIdHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private ignoredColumns = 0;\n\n /** Whether the sink's direction was set (before the first relationship, design section 8.4 rule 1). */\n private headerSet = false;\n\n /** Scratch: the parsed value of every cell of the current row. */\n private values: unknown[] = [];\n\n /** Scratch: the companion text of every cell of the current row. */\n private texts: (string | null)[] = [];\n\n /** Scratch: the property slots of the current row that lost precision. */\n private readonly precisionSlots: PropertySlot[] = [];\n\n /**\n * Create a session.\n * @param sink - the sink\n * @param report - the report\n * @param common - the resolved common options\n * @param options - the resolved format options\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n options: ResolvedNeo4jOptions,\n ) {\n this.sink = sink;\n this.report = report;\n this.common = common;\n this.options = options;\n this.coercer = new IdCoercer(common.ids);\n this.direction = new DirectionResolver(sink, report, common.onMixedDirection);\n }\n\n /**\n * Read every input.\n * @param inputs - the inputs in reading order\n */\n async run(inputs: readonly ImportInput[]): Promise<void> {\n const progress = new ProgressTracker(this.common.onProgress, inputs);\n for (const input of inputs) {\n await this.readInput(input, { ...progress.optionsFor(this.common.signal), encoding: this.common.encoding });\n progress.finishInput();\n }\n if (this.ignoredColumns > 0) {\n this.report.loss(\n IGNORED_COLUMNS_LOSS,\n `${this.ignoredColumns} :IGNORE column(s) were skipped as the header instructs`,\n null,\n this.ignoredColumns,\n );\n }\n }\n\n /**\n * Read one input: a header row, then data rows until the next header row.\n * @param input - the input\n * @param readOptions - cancellation and progress\n */\n private async readInput(input: ImportInput, readOptions: ReadOptions): Promise<void> {\n const reader = new RecordReader(input, this.report, this.options.syntax, readOptions);\n let section: Section | null = null;\n let sinceCheck = 0;\n for await (const count of reader) {\n if (section === null || isHeaderRecord(reader.cells, count)) {\n section = this.declareSection(reader, count);\n continue;\n }\n if (section.kind === \"node\") {\n this.nodeRow(section, reader, count);\n } else {\n this.relationshipRow(section, reader, count);\n }\n if (++sinceCheck >= ABORT_CHECK_INTERVAL) {\n sinceCheck = 0;\n throwIfAborted(readOptions.signal);\n }\n }\n if (section === null) {\n this.report.fail(HEADER_CODE, \"the input has no header row\", { line: 1 });\n }\n }\n\n /**\n * Interpret a header row: parse every cell, check the section shape, declare its columns.\n * @param reader - the reader positioned on the header\n * @param count - the number of header cells\n * @returns the section\n */\n private declareSection(reader: RecordReader, count: number): Section {\n const { line } = reader;\n const fields: HeaderField[] = [];\n try {\n for (let i = 0; i < count; i++) {\n fields.push(parseHeaderField(reader.cells[i]));\n }\n const kinds = new Map<FieldKind, number[]>();\n fields.forEach((field, i) => {\n const list = kinds.get(field.kind);\n if (list === undefined) {\n kinds.set(field.kind, [i]);\n } else {\n list.push(i);\n }\n });\n const ids = kinds.get(\"ID\") ?? [];\n const starts = kinds.get(\"START_ID\") ?? [];\n const ends = kinds.get(\"END_ID\") ?? [];\n const isNode = ids.length > 0;\n const isRelationship = starts.length > 0 || ends.length > 0;\n if (isNode && isRelationship) {\n throw headerError(\"a header mixes :ID with :START_ID / :END_ID\");\n }\n if (!isNode && !isRelationship) {\n throw headerError(\n \"a header needs an :ID column (nodes) or :START_ID and :END_ID columns (relationships)\",\n );\n }\n checkPropertyNames(fields);\n this.ignoredColumns += (kinds.get(\"IGNORE\") ?? []).length;\n if (isNode) {\n if (ids.length > 1) {\n throw headerError(\"a node header has more than one :ID column\");\n }\n if (kinds.has(\"TYPE\")) {\n throw headerError(\"a node header cannot have a :TYPE column\");\n }\n return this.declareNodeSection(fields, ids[0], kinds.get(\"LABEL\") ?? [], line);\n }\n if (starts.length !== 1 || ends.length !== 1) {\n throw headerError(\"a relationship header needs exactly one :START_ID and one :END_ID column\");\n }\n if (kinds.has(\"LABEL\")) {\n throw headerError(\"a relationship header cannot have a :LABEL column\");\n }\n const types = kinds.get(\"TYPE\") ?? [];\n if (types.length > 1) {\n throw headerError(\"a relationship header has more than one :TYPE column\");\n }\n return this.declareRelationshipSection(\n fields,\n starts[0],\n ends[0],\n types.length === 1 ? types[0] : -1,\n line,\n );\n } catch (err) {\n if (err instanceof GraphFormatError && !(err instanceof ImportError)) {\n this.report.fail(HEADER_CODE, `line ${line}: ${err.message}`, { line }, { cause: err.code });\n }\n throw err;\n }\n }\n\n /**\n * Declare the columns of a node section.\n * @param fields - the parsed header\n * @param idCell - the `:ID` cell\n * @param labelCells - the `:LABEL` cells\n * @param line - the header line\n * @returns the section\n */\n private declareNodeSection(\n fields: readonly HeaderField[],\n idCell: number,\n labelCells: readonly number[],\n line: number,\n ): NodeSection {\n const idField = fields[idCell];\n const extraLabels: string[] = [];\n for (const field of fields) {\n for (const [key, value] of field.options) {\n if (key === \"label\" && field.kind === \"ID\") {\n extraLabels.push(value);\n } else {\n this.report.warning(\n \"unsupported\",\n HEADER_OPTION_CODE,\n `header option ${key}:${value} of \"${field.text}\" is ignored`,\n { line, element: field.text },\n );\n }\n }\n }\n if (labelCells.length > 0 || extraLabels.length > 0) {\n this.ensureLabels();\n }\n if (idField.space !== null) {\n this.ensureIdSpace();\n }\n let idHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n if (idField.name.length > 0) {\n idHandle = this.declareProperty(\n \"node\",\n { ...idField, type: null },\n idCell,\n { origin: { format: NEO4J, id: idField.name, title: null, type: \"ID\", namespace: idField.space } },\n line,\n ).handle;\n }\n const properties = this.declareProperties(\"node\", fields, line, null);\n return {\n kind: \"node\",\n width: fields.length,\n idCell,\n idHandle,\n space: idField.space,\n spaceCode: this.registry.codeOf(idField.space),\n labelCells,\n extraLabels,\n properties,\n };\n }\n\n /**\n * Declare the columns of a relationship section.\n * @param fields - the parsed header\n * @param startCell - the `:START_ID` cell\n * @param endCell - the `:END_ID` cell\n * @param typeCell - the `:TYPE` cell, or -1\n * @param line - the header line\n * @returns the section\n */\n private declareRelationshipSection(\n fields: readonly HeaderField[],\n startCell: number,\n endCell: number,\n typeCell: number,\n line: number,\n ): RelationshipSection {\n for (const field of fields) {\n for (const [key, value] of field.options) {\n this.report.warning(\n \"unsupported\",\n HEADER_OPTION_CODE,\n `header option ${key}:${value} of \"${field.text}\" is ignored`,\n { line, element: field.text },\n );\n }\n }\n if (typeCell >= 0) {\n this.ensureType();\n }\n const { weightFrom } = this.common;\n let weightCell = -1;\n if (weightFrom !== null) {\n weightCell = fields.findIndex((field) => field.kind === \"PROPERTY\" && field.name === weightFrom);\n }\n const properties = this.declareProperties(\"edge\", fields, line, weightCell);\n const { space: startSpace } = fields[startCell];\n const { space: endSpace } = fields[endCell];\n return {\n kind: \"relationship\",\n width: fields.length,\n startCell,\n endCell,\n startSpace,\n endSpace,\n startSpaceCode: startSpace === null ? 0 : this.registry.codeOf(startSpace),\n endSpaceCode: endSpace === null ? 0 : this.registry.codeOf(endSpace),\n typeCell,\n weightCell,\n properties,\n };\n }\n\n /**\n * Declare every PROPERTY field of a header.\n * @param domain - node or edge\n * @param fields - the parsed header\n * @param line - the header line\n * @param skipCell - a cell to leave undeclared (the weight), or null\n * @returns the property slots\n */\n private declareProperties(\n domain: \"node\" | \"edge\",\n fields: readonly HeaderField[],\n line: number,\n skipCell: number | null,\n ): PropertySlot[] {\n const slots: PropertySlot[] = [];\n fields.forEach((field, cell) => {\n if (field.kind !== \"PROPERTY\" || cell === skipCell) {\n return;\n }\n slots.push(this.declareProperty(domain, field, cell, {}, line));\n });\n const width = fields.length;\n if (this.values.length < width) {\n this.values = new Array<unknown>(width);\n this.texts = new Array<string | null>(width);\n }\n return slots;\n }\n\n /**\n * Declare one property column on the sink: the same name and shape again shares the column;\n * a different shape under the same name is renamed `<name>#<name>` (design section 5.6).\n * @param domain - node or edge\n * @param field - the header field\n * @param cell - the field's cell index\n * @param patch - declaration fields to override (the id property's origin)\n * @param line - the header line\n * @returns the slot\n */\n private declareProperty(\n domain: \"node\" | \"edge\",\n field: HeaderField,\n cell: number,\n patch: Partial<ColumnDecl>,\n line: number,\n ): PropertySlot {\n const { sink, report } = this;\n const { listSyntax } = this.options;\n const input: AttributeDeclarationInput = {\n format: NEO4J,\n id: field.name,\n title: null,\n type: field.type,\n namespace: null,\n listSyntax,\n long: this.common.long,\n };\n let declared: DeclaredAttribute = declareAttribute(input);\n let decl: ColumnDecl = { ...declared.decl, ...patch };\n let handle: ColumnHandle;\n try {\n handle = declareOn(sink, domain, decl);\n } catch (err) {\n if (!(err instanceof GraphFormatError) || err.code !== \"E_COLUMN_EXISTS\") {\n throw err;\n }\n declared = declareAttribute({ ...input, taken: takenIn(sink, domain) });\n decl = { ...declared.decl, ...patch, name: declared.decl.name };\n handle = declareOn(sink, domain, decl);\n }\n for (const issue of declared.issues) {\n report.warning(issue.category, issue.code, issue.message, { line, element: field.text });\n }\n return {\n cell,\n name: decl.name,\n handle,\n spec: declared.spec,\n companionDecl: declared.companion,\n companion: INVALID_INDEX as ColumnHandle,\n };\n }\n\n /** Declare (or adopt) the labels column. */\n private ensureLabels(): void {\n if (this.labelsHandle === INVALID_INDEX) {\n this.labelsHandle = this.declareReserved(\"node\", LABELS_DECL);\n }\n }\n\n /** Declare (or adopt) the relationship type column. */\n private ensureType(): void {\n if (this.typeHandle === INVALID_INDEX) {\n this.typeHandle = this.declareReserved(\"edge\", TYPE_DECL);\n }\n }\n\n /** Declare (or adopt) the id space column. */\n private ensureIdSpace(): void {\n if (this.idSpaceHandle === INVALID_INDEX) {\n this.idSpaceHandle = this.declareReserved(\"node\", ID_SPACE_DECL);\n this.originalIdHandle = this.declareReserved(\"node\", ORIGINAL_ID_DECL);\n }\n }\n\n /**\n * Declare a reserved column: the same shape again shares it; a name taken by another shape is\n * renamed `<name>#<origin.id>` and reported; a role the sink already holds elsewhere is dropped\n * and reported.\n * @param domain - node or edge\n * @param decl - the reserved declaration\n * @returns the handle\n */\n private declareReserved(domain: \"node\" | \"edge\", decl: ColumnDecl): ColumnHandle {\n const { sink, report } = this;\n let current = decl;\n for (;;) {\n try {\n return declareOn(sink, domain, current);\n } catch (err) {\n if (!(err instanceof GraphFormatError)) {\n throw err;\n }\n if (err.code === \"E_COLUMN_EXISTS\") {\n const name = uniqueColumnName(current.name, current.origin?.id ?? null, takenIn(sink, domain));\n report.warning(\n \"coercion\",\n RENAMED_CODE,\n `column \"${current.name}\" renamed to \"${name}\": the name was taken`,\n { element: current.name },\n );\n current = { ...current, name };\n } else if (err.code === \"E_DUPLICATE_ROLE\") {\n report.warning(\n \"coercion\",\n ROLE_TAKEN_CODE,\n `column \"${current.name}\" declared without role \"${String(current.role)}\": the sink already holds that role`,\n { element: current.name },\n );\n const { role: _role, ...withoutRole } = current;\n current = withoutRole;\n } else {\n throw err;\n }\n }\n }\n }\n\n /**\n * Push one node row.\n * @param section - the section\n * @param reader - the reader positioned on the row\n * @param count - the row's cell count\n */\n private nodeRow(section: NodeSection, reader: RecordReader, count: number): void {\n const { sink, report } = this;\n const { cells, quoted, line } = reader;\n if (count !== section.width) {\n report.error(\n \"validation-error\",\n COLUMN_COUNT_CODE,\n `row has ${count} cell(s) but the header has ${section.width}`,\n { line },\n );\n report.counts.skippedNodes++;\n return;\n }\n const idText = cells[section.idCell];\n if (idText.length === 0 && !quoted[section.idCell]) {\n // a quoted empty cell is the id \"\" (neo4j-admin: an empty quoted field is an empty string)\n report.error(\"missing-value\", MISSING_ID_CODE, \"empty :ID cell\", { line });\n report.counts.skippedNodes++;\n return;\n }\n const coerced = this.coerceId(idText, line);\n if (coerced === null || !this.parseProperties(section.properties, cells, quoted, line, idText)) {\n report.counts.skippedNodes++;\n return;\n }\n const id = qualify(coerced, section.space);\n let labels: string[] | undefined;\n if (section.labelCells.length > 0 || section.extraLabels.length > 0) {\n labels = this.labelsOf(section, cells, quoted);\n }\n const index = sink.addNode(id);\n const status = this.registry.declare(index, section.spaceCode);\n if (status === \"collision\") {\n report.error(\n \"validation-error\",\n ID_SPACE_COLLISION_CODE,\n `node ${idText} is declared in id space ${section.space ?? \"(none)\"} and in another id space; the core has one id space and this row is skipped`,\n { line, element: idText },\n );\n report.counts.skippedNodes++;\n return;\n }\n if (status === \"duplicate\") {\n report.warning(\n \"merged\",\n DUPLICATE_NODE_CODE,\n `node ${idText} is declared twice; the later properties win`,\n {\n line,\n element: idText,\n },\n );\n }\n if (section.idHandle !== INVALID_INDEX) {\n sink.setNodeValue(section.idHandle, index, idText);\n }\n if (section.space !== null) {\n sink.setNodeValue(this.idSpaceHandle, index, section.space);\n sink.setNodeValue(this.originalIdHandle, index, idText);\n }\n if (labels !== undefined) {\n sink.setNodeValue(this.labelsHandle, index, labels);\n }\n this.writeProperties(\"node\", section.properties, index);\n this.reportPrecision(line, idText);\n report.counts.nodes++;\n }\n\n /**\n * Push one relationship row.\n * @param section - the section\n * @param reader - the reader positioned on the row\n * @param count - the row's cell count\n */\n private relationshipRow(section: RelationshipSection, reader: RecordReader, count: number): void {\n const { sink, report } = this;\n const { cells, quoted, line } = reader;\n if (!this.headerSet) {\n // a Neo4j file is directed by definition (\"all relationships have a direction\"); the sink's\n // direction is set once, before the first relationship, so a node-only file leaves it alone\n this.headerSet = true;\n this.direction.setHeader(true, { line });\n }\n if (count !== section.width) {\n report.error(\n \"validation-error\",\n COLUMN_COUNT_CODE,\n `row has ${count} cell(s) but the header has ${section.width}`,\n { line },\n );\n report.counts.skippedEdges++;\n return;\n }\n const startText = cells[section.startCell];\n const endText = cells[section.endCell];\n const startMissing = startText.length === 0 && !quoted[section.startCell];\n if (startMissing || (endText.length === 0 && !quoted[section.endCell])) {\n report.error(\n \"missing-value\",\n MISSING_ENDPOINT_CODE,\n `empty ${startMissing ? \":START_ID\" : \":END_ID\"} cell`,\n {\n line,\n },\n );\n report.counts.skippedEdges++;\n return;\n }\n const element = `${startText}->${endText}`;\n const start = this.coerceId(startText, line);\n const end = start === null ? null : this.coerceId(endText, line);\n if (start === null || end === null) {\n report.counts.skippedEdges++;\n return;\n }\n const source = qualify(start, section.startSpace);\n const target = qualify(end, section.endSpace);\n let wrongSpace: string | null = null;\n if (this.wrongSpace(source, section.startSpaceCode)) {\n wrongSpace = startText;\n } else if (this.wrongSpace(target, section.endSpaceCode)) {\n wrongSpace = endText;\n }\n if (wrongSpace !== null) {\n report.error(\n \"missing-value\",\n ENDPOINT_SPACE_CODE,\n `endpoint ${wrongSpace} is not a node of its declared id space (a node of another id space has that id); the row is skipped`,\n { line, element },\n );\n report.counts.skippedEdges++;\n return;\n }\n let weight: number | undefined;\n if (section.weightCell >= 0) {\n try {\n weight = parseWeightText(cells[section.weightCell]);\n } catch (err) {\n report.recordError(err, { line, element });\n report.counts.skippedEdges++;\n return;\n }\n }\n if (!this.parseProperties(section.properties, cells, quoted, line, element)) {\n report.counts.skippedEdges++;\n return;\n }\n let edge: number;\n try {\n edge = this.direction.addEdge(source, target, \"directed\", weight, { line, element });\n } catch (err) {\n report.recordError(err, { line, element });\n report.counts.skippedEdges++;\n return;\n }\n if (section.typeCell >= 0) {\n const type = cells[section.typeCell];\n if (type.length > 0) {\n sink.setEdgeValue(this.typeHandle, edge, type);\n }\n }\n this.writeProperties(\"edge\", section.properties, edge);\n this.reportPrecision(line, element);\n report.counts.edges++;\n }\n\n /**\n * Whether a qualified endpoint id belongs to a node a node row declared in another id space than\n * the endpoint's header declares (an unspaced node whose id text is `Space:id`). An endpoint\n * without a declared space, or a node no row declared yet, is looked up by id alone.\n * @param id - the endpoint id\n * @param spaceCode - the endpoint's space code, 0 for none\n * @returns true when the endpoint resolves to a node of another space\n */\n private wrongSpace(id: NodeId, spaceCode: number): boolean {\n if (spaceCode === 0) {\n return false;\n }\n const index = this.sink.indexOf(id);\n if (index < 0) {\n return false;\n }\n const declared = this.registry.codeAt(index);\n return declared !== 0 && declared !== spaceCode;\n }\n\n /**\n * Coerce an id cell, reporting a merge under `ids: \"number\"` and an invalid id as an error.\n * @param text - the cell\n * @param line - the row's line\n * @returns the id, or null when the cell was rejected (the error is recorded)\n */\n private coerceId(text: string, line: number): NodeId | null {\n const { coercer, report } = this;\n let id: NodeId;\n try {\n id = coercer.text(text);\n } catch (err) {\n report.recordError(err, { line, element: text });\n return null;\n }\n const merge = coercer.lastMerge;\n if (merge !== null) {\n report.warning(\n \"coercion\",\n ID_MERGED_CODE,\n `id \"${merge.text}\" merged with \"${merge.previousText}\" as ${merge.id} under ids: \"number\"`,\n { line, element: text },\n );\n }\n return id;\n }\n\n /**\n * Parse the property cells of a row into the scratch arrays.\n * @param slots - the section's property slots\n * @param cells - the row's cells\n * @param quoted - whether each cell was quoted\n * @param line - the row's line\n * @param element - the row's element name for issues\n * @returns true when every cell parsed; false after recording the first error\n */\n private parseProperties(\n slots: readonly PropertySlot[],\n cells: readonly string[],\n quoted: readonly boolean[],\n line: number,\n element: string,\n ): boolean {\n const { values, texts, precisionSlots } = this;\n precisionSlots.length = 0;\n for (const slot of slots) {\n const text = cells[slot.cell];\n texts[slot.cell] = null;\n if (text.length === 0) {\n values[slot.cell] = quoted[slot.cell] ? emptyValue(slot.spec) : undefined;\n continue;\n }\n const { spec } = slot;\n try {\n if (spec.temporal !== null && !spec.list) {\n const parsed = parseDeclaredTemporal(text, spec);\n values[slot.cell] = parsed.value;\n texts[slot.cell] = parsed.text;\n } else {\n values[slot.cell] = parseDeclaredValue(text, spec, this.options.listSyntax);\n }\n } catch (err) {\n this.report.recordError(err, { line, element: `${element} ${slot.name}` });\n return false;\n }\n if (spec.precision && losesPrecision(spec, text)) {\n precisionSlots.push(slot);\n }\n }\n return true;\n }\n\n /**\n * Write the parsed property values of a row.\n * @param domain - node or edge\n * @param slots - the section's property slots\n * @param row - the node or edge index\n */\n private writeProperties(domain: \"node\" | \"edge\", slots: readonly PropertySlot[], row: number): void {\n const { sink, values, texts } = this;\n for (const slot of slots) {\n const value = values[slot.cell];\n if (value === undefined) {\n continue;\n }\n const text = texts[slot.cell];\n if (text !== null && slot.companion === INVALID_INDEX && slot.companionDecl !== null) {\n slot.companion = declareCompanion(sink, domain, slot.companionDecl);\n }\n if (domain === \"node\") {\n sink.setNodeValue(slot.handle, row, value);\n if (text !== null) {\n sink.setNodeValue(slot.companion, row, text);\n }\n } else {\n sink.setEdgeValue(slot.handle, row, value);\n if (text !== null) {\n sink.setEdgeValue(slot.companion, row, text);\n }\n }\n }\n }\n\n /**\n * Report the precision losses of the row just accepted.\n * @param line - the row's line\n * @param element - the row's element name\n */\n private reportPrecision(line: number, element: string): void {\n for (const slot of this.precisionSlots) {\n this.report.warning(\n \"precision\",\n PRECISION_CODE,\n `long value of \"${slot.name}\" is beyond 2^53 and was stored as the nearest f64`,\n { line, element },\n );\n }\n this.precisionSlots.length = 0;\n }\n\n /**\n * The labels of a node row: every `:LABEL` cell split by the array delimiter (empty items\n * dropped), plus the header's `{label:...}` options.\n * @param section - the section\n * @param cells - the row's cells\n * @param quoted - whether each cell was quoted\n * @returns the labels, or undefined when every label cell is unset and no extra label exists\n */\n private labelsOf(section: NodeSection, cells: readonly string[], quoted: readonly boolean[]): string[] | undefined {\n let labels: string[] | undefined;\n for (const cell of section.labelCells) {\n const text = cells[cell];\n if (text.length === 0 && !quoted[cell]) {\n continue;\n }\n if (labels === undefined) {\n labels = [];\n }\n for (const item of splitListText(text, this.options.listSyntax)) {\n if (item.length > 0) {\n labels.push(item);\n }\n }\n }\n if (section.extraLabels.length > 0) {\n if (labels === undefined) {\n labels = [];\n }\n labels.push(...section.extraLabels);\n }\n return labels;\n }\n}\n\n/**\n * The id a node of an id space is stored under: `Space:id`, so the same id in two spaces stays two\n * nodes (the core has one id space).\n * @param id - the coerced id cell\n * @param space - the id space, or null\n * @returns the id unchanged without a space, else the string `Space:id`\n */\nfunction qualify(id: NodeId, space: string | null): NodeId {\n return space === null ? id : `${space}:${String(id)}`;\n}\n\n/**\n * The value of a quoted empty cell: an empty string for a string-kind property, an empty list for\n * a list property, unset for anything else (neo4j-admin's default `--ignore-empty-strings=false`).\n * @param spec - the property's declared type\n * @returns the value, or undefined for unset\n */\nfunction emptyValue(spec: DeclaredTypeSpec): unknown {\n if (spec.list) {\n return [];\n }\n if (spec.kind === \"string\" || spec.kind === \"duration\") {\n return \"\";\n }\n return undefined;\n}\n\n/**\n * Check that no two PROPERTY (or stored-id) fields of one header share a name.\n * @param fields - the parsed header\n */\nfunction checkPropertyNames(fields: readonly HeaderField[]): void {\n const seen = new Set<string>();\n for (const field of fields) {\n if (field.name.length === 0 || field.kind === \"IGNORE\") {\n continue;\n }\n if (seen.has(field.name)) {\n throw headerError(`property \"${field.name}\" is declared twice`);\n }\n seen.add(field.name);\n }\n}\n\n/**\n * The error of a malformed section header.\n * @param reason - why\n * @returns the error\n */\nfunction headerError(reason: string): GraphFormatError {\n return new GraphFormatError(\"E_UNSUPPORTED\", reason, { reason: \"header\" });\n}\n\n/**\n * Confidence that a head of bytes is a neo4j-admin CSV: the first line holds an `:ID`,\n * `:START_ID` or `:END_ID` header cell.\n * @param head - the first bytes of the input\n * @returns 0.95 for a Neo4j header, 0 otherwise\n */\nfunction sniffNeo4j(head: Uint8Array): number {\n const text = new TextDecoder(\"utf-8\", { fatal: false, ignoreBOM: false }).decode(head);\n const end = text.search(/[\\r\\n]/);\n const first = end < 0 ? text : text.slice(0, end);\n const cells = first.split(/[,;|\\t]/);\n return isHeaderRecord(cells, cells.length) ? 0.95 : 0;\n}\n\n/** The Neo4j importer. */\nexport const neo4jImporter: GraphImporter<Neo4jImportOptions> = Object.freeze({\n format: NEO4J,\n extensions: Object.freeze([\".csv\", \".tsv\"]),\n mimeTypes: Object.freeze([\"text/csv\", \"text/tab-separated-values\"]),\n sniff: sniffNeo4j,\n /**\n * Read one or more neo4j-admin CSV inputs into the sink.\n * @param input - the primary input (a node table, a relationship table, or sections of both)\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report; ImportError beyond the error limit or on a malformed header\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: Neo4jImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n const common = resolveImportOptions(options, { ids: \"canonical\", defaultDirected: true, weightFrom: \"weight\" });\n const format = resolveNeo4jOptions(options);\n const report = new ImportReportBuilder(NEO4J, common.errorLimit);\n reportSinkOptions(sink, options, report);\n // nodeIdFrom and defaultDirected are among the reported options: Neo4j ids are the :ID\n // column and every relationship is directed\n reportUnusedOptions(options, report, USED_OPTIONS);\n const session = new Neo4jImportSession(sink, report, common, format);\n await session.run([input, ...format.nodes, ...format.relationships]);\n throwIfAborted(common.signal);\n return report.finish();\n },\n});\n","/**\n * The Neo4j exporter (design section 8.5, research note 07 section 9): writes a snapshot as\n * neo4j-admin import CSV -- node sections with `:ID`, `:LABEL` and typed property columns,\n * relationship sections with `:START_ID`, `:END_ID`, `:TYPE`, the weight and typed property\n * columns -- as one document (node sections first) or as the node or relationship part alone.\n *\n * What a property graph cannot carry is reported by check() before anything is written: an\n * undirected snapshot (every edge becomes a directed relationship), expanded mixed direction (per\n * `onMixedDirection`), edge ids, hierarchy, element lifetimes, graph attributes, nested json (points\n * excepted), multi-component columns (flattened to arrays), u32 / u8 columns (written as `long` /\n * `int`), ids whose text would re-import as another type or collide, and list items that contain\n * the array delimiter.\n *\n * Column headers restore the declared Neo4j type from `origin.type` when it is compatible with the\n * column's dtype (`int`, `byte`, `short`, `long`, `char`, `duration`, the temporal types, `point`,\n * `type[]`), and derive it from the dtype otherwise. Temporal columns write their `.text`\n * companion when set and the canonical ISO form otherwise. Nodes are grouped into sections by\n * (id space, stored-id column) in index order, so a re-import restores the same node order;\n * relationships likewise by (start space, end space). A node of an id space is written under its\n * `originalId` value (the id text the importer stored it under as `Space:id`), so a round trip\n * reproduces the source file.\n */\n\nimport {\n type Column,\n type ColumnMeta,\n type Dtype,\n GraphFormatError,\n type GraphSnapshot,\n type NodeId,\n type ScalarDtype,\n} from \"@graphty/graph-format\";\n\nimport { ID_TEXT_COLLISION_CODE, ID_TEXT_TYPE_CODE } from \"../../common/codes.js\";\nimport { type DeclaredTypeSpec, mapDeclaredType } from \"../../common/declared-types.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { quoteCsvCell } from \"../../common/escape.js\";\nimport { capabilities, checkCapabilities, LOSS } from \"../../common/export.js\";\nimport { formatF32, formatF64, formatInteger } from \"../../common/format.js\";\nimport { isCanonicalIntegerText } from \"../../common/ids.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { formatTemporal, type TemporalKind } from \"../../common/temporal.js\";\nimport { type ExplicitWeights, explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, joinText } from \"../../common/writer.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport { checkRecordSyntax, type RecordSyntax } from \"../csv/records.js\";\nimport { formatHeaderField } from \"./header.js\";\nimport { ID_SPACE_COLUMN, LABELS_COLUMN, TYPE_COLUMN } from \"./importer.js\";\n\n/** The format-specific options of the Neo4j exporter. */\nexport interface Neo4jExportOptions {\n /** Which tables to write: both (node sections first; default), the node sections or the relationship sections. */\n part?: \"all\" | \"nodes\" | \"relationships\" | undefined;\n /** The field delimiter; one character; \",\" by default. */\n delimiter?: string | undefined;\n /** The array delimiter of list values and `:LABEL` cells; \";\" by default. */\n arrayDelimiter?: \";\" | \",\" | \"|\" | undefined;\n /** The quote character; one character; a double quote by default. */\n quote?: string | undefined;\n /**\n * The property that receives explicit edge weights (`<name>:double`); \"weight\" by default (the\n * importer's `weightFrom` default); null writes no weights.\n */\n weightColumn?: string | null | undefined;\n /**\n * The property name of the `:ID` column for nodes that have no stored-id column of their own\n * (`<name>:ID`); null (default) writes a bare `:ID`.\n */\n idColumn?: string | null | undefined;\n}\n\n/** Loss code: undirected edges (an undirected snapshot, or the folded pairs of a mixed one) written as directed relationships. */\nexport const UNDIRECTED_LOSS = \"W_NEO4J_UNDIRECTED_AS_DIRECTED\";\n\n/** Loss code: node ids whose text re-imports as another type under the canonical id rule. */\nexport const ID_TEXT_TYPE_LOSS = ID_TEXT_TYPE_CODE;\n\n/** Loss code: two node ids share one text; export() throws E_INVALID_ID. */\nexport const ID_TEXT_COLLISION_LOSS = ID_TEXT_COLLISION_CODE;\n\n/** Loss code: an edge property column already uses the weight column name; export() throws E_COLUMN_EXISTS. */\nexport const WEIGHT_COLUMN_TAKEN_LOSS = \"E_NEO4J_WEIGHT_COLUMN_TAKEN\";\n\n/** Loss code: a node property column already uses the idColumn name; export() throws E_COLUMN_EXISTS. */\nexport const ID_COLUMN_TAKEN_LOSS = \"E_NEO4J_ID_COLUMN_TAKEN\";\n\n/** Loss code: a node has more than one stored-id column set; only the first is written. */\nexport const MULTIPLE_ID_PROPERTIES_LOSS = \"W_NEO4J_MULTIPLE_ID_PROPERTIES\";\n\n/** Loss code: a declared integer type holds non-integral values and is written as double. */\nexport const DECLARED_TYPE_CHANGED_LOSS = \"W_NEO4J_DECLARED_TYPE_CHANGED\";\n\n/** Loss code: a list item contains the array delimiter, which Neo4j cannot escape. */\nexport const ARRAY_DELIMITER_LOSS = \"W_NEO4J_ARRAY_DELIMITER\";\n\n/** The roles Neo4j has a slot for: `:TYPE`, `:LABEL` and the id space of `:ID(Space)`. */\nconst SLOT_ROLES: ReadonlySet<string> = new Set([\"kind\", \"labels\", \"idSpace\"]);\n\nconst NEO4J = \"neo4j\";\nconst ID_TYPE = \"ID\";\n\n/** The weight property the importer reads by default (its weightFrom default). */\nconst DEFAULT_WEIGHT_COLUMN = \"weight\";\n\n/** The names the importer gives the slot columns, for the name-change notes. */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n kind: TYPE_COLUMN,\n labels: LABELS_COLUMN,\n idSpace: ID_SPACE_COLUMN,\n});\n\n/**\n * The capabilities of neo4j-admin CSV (research note 07 section 9): declared scalar types and\n * arrays; a dict column reads back as string (the header has no enumeration type); a position or\n * visual column is written as a plain property (a point for a 2- or 3-component position) and\n * reads back without its role.\n */\nexport const NEO4J_CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: false,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"none\",\n idCharset: \"any\",\n dtypes: [\"f32\", \"f64\", \"i32\", \"bool\", \"string\"],\n components: false,\n lists: true,\n json: false,\n defaults: false,\n options: false,\n hierarchy: false,\n temporal: \"none\",\n graphAttributes: false,\n positions: false,\n viz: false,\n});\n\n/** Roles whose columns are never written as properties. */\nconst SKIPPED_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n \"parent\",\n \"parents\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n]);\n\n/** Notes about relationships only, dropped when only nodes are written. */\nconst EDGE_NOTE_CODES: ReadonlySet<string> = new Set([\n LOSS.MIXED_DIRECTION,\n LOSS.MIXED_DIRECTION_ERROR,\n LOSS.MULTI_EDGES,\n LOSS.SELF_LOOPS,\n LOSS.EDGE_IDS_GENERATED,\n LOSS.EDGE_IDS_DROPPED,\n UNDIRECTED_LOSS,\n WEIGHT_COLUMN_TAKEN_LOSS,\n]);\n\n/** Notes about nodes only, dropped when only relationships are written. */\nconst NODE_NOTE_CODES: ReadonlySet<string> = new Set([\n LOSS.ID_MANGLED,\n LOSS.ID_CHARSET,\n LOSS.ID_RENUMBERED,\n ID_TEXT_TYPE_LOSS,\n ID_COLUMN_TAKEN_LOSS,\n MULTIPLE_ID_PROPERTIES_LOSS,\n]);\n\nconst ARRAY_SYNTAXES: ReadonlySet<string> = new Set([\";\", \",\", \"|\"]);\nconst PARTS: ReadonlySet<string> = new Set([\"all\", \"nodes\", \"relationships\"]);\n\n/** The resolved format options. */\ninterface ResolvedNeo4jExportOptions {\n readonly part: \"all\" | \"nodes\" | \"relationships\";\n readonly syntax: RecordSyntax & { readonly delimiter: string };\n readonly arrayDelimiter: string;\n readonly weightColumn: string | null;\n readonly idColumn: string | null;\n}\n\n/** How one cell's value is written. */\ntype CellKind = \"integer\" | \"float\" | \"double\" | \"boolean\" | \"string\" | \"temporal\" | \"point\" | \"json\";\n\n/** The Neo4j type and cell kind of one scalar (a column or a list item). */\ninterface ScalarPlan {\n readonly type: string;\n readonly kind: CellKind;\n readonly temporal: TemporalKind | null;\n}\n\n/** One property column as it will be written. */\ninterface ColumnPlan {\n readonly column: Column;\n readonly header: string;\n readonly scalar: ScalarPlan;\n /** A list (or flattened vector) column: items are joined by the array delimiter. */\n readonly list: boolean;\n /** The companion text column of a temporal column, or null. */\n readonly companion: Column | null;\n}\n\n/**\n * Resolve the format options.\n * @param options - the caller's options\n * @returns the resolved options; E_UNSUPPORTED for an invalid value\n */\nfunction resolveNeo4jExportOptions(options: Neo4jExportOptions | undefined): ResolvedNeo4jExportOptions {\n const o: Neo4jExportOptions = options ?? {};\n const part = o.part ?? \"all\";\n if (!PARTS.has(part)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option part: ${JSON.stringify(part)} is not \"all\", \"nodes\" or \"relationships\"`,\n {\n option: \"part\",\n found: part,\n },\n );\n }\n const arrayDelimiter = o.arrayDelimiter ?? \";\";\n if (!ARRAY_SYNTAXES.has(arrayDelimiter)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option arrayDelimiter: ${JSON.stringify(arrayDelimiter)} is not one of \";\", \",\", \"|\"`,\n { option: \"arrayDelimiter\", found: arrayDelimiter },\n );\n }\n const delimiter = o.delimiter ?? \",\";\n const syntax = { ...checkRecordSyntax({ delimiter, quote: o.quote ?? '\"' }), delimiter };\n if (syntax.delimiter === arrayDelimiter) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"options delimiter and arrayDelimiter must differ\", {\n option: \"arrayDelimiter\",\n found: arrayDelimiter,\n });\n }\n const weightColumn = o.weightColumn === undefined ? \"weight\" : o.weightColumn;\n if (weightColumn !== null && (typeof weightColumn !== \"string\" || weightColumn.length === 0)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"option weightColumn: expected a non-empty name or null\", {\n option: \"weightColumn\",\n found: weightColumn,\n });\n }\n const idColumn = o.idColumn ?? null;\n if (idColumn !== null && (typeof idColumn !== \"string\" || idColumn.length === 0)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"option idColumn: expected a non-empty name or null\", {\n option: \"idColumn\",\n found: idColumn,\n });\n }\n return { part, syntax, arrayDelimiter, weightColumn, idColumn };\n}\n\n/**\n * Everything check() and export() share: the column plans, the section keys, the notes and the\n * error export() throws (if any), computed once from the snapshot and the options.\n */\nclass ExportPlan {\n readonly snapshot: GraphSnapshot;\n\n readonly options: ResolvedNeo4jExportOptions;\n\n readonly common: ResolvedExportOptions;\n\n /** The notes: the generic capability notes first, then the format's own, in that order. */\n readonly notes: LossNote[] = [];\n\n /** The format's own notes, appended after the generic ones. */\n private readonly ownNotes: LossNote[] = [];\n\n /** The error export() throws because of the node sections, or null. */\n private fatalNodes: GraphFormatError | null = null;\n\n /** The error export() throws because of the relationship sections, or null. */\n private fatalEdges: GraphFormatError | null = null;\n\n /** The error export() throws whatever the part (an id text collision), or null. */\n private fatalAll: GraphFormatError | null = null;\n\n readonly nodeColumns: ColumnPlan[] = [];\n\n readonly edgeColumns: ColumnPlan[] = [];\n\n /** Stored-id node columns (`name:ID`), in declaration order. */\n readonly idColumns: Column[] = [];\n\n readonly idSpace: Column | null;\n\n /** The id text of the nodes of an id space (the importer's `originalId` column), or null. */\n readonly originalId: Column | null;\n\n readonly labels: Column | null;\n\n readonly kind: Column | null;\n\n readonly weights: ExplicitWeights | null;\n\n /** The pair folding (design section 3.6): the mirror halves of undirected pairs are not written. */\n readonly folding: PairFolding;\n\n /**\n * Build the plan.\n * @param snapshot - the snapshot\n * @param options - the resolved format options\n * @param common - the resolved common options\n */\n constructor(snapshot: GraphSnapshot, options: ResolvedNeo4jExportOptions, common: ResolvedExportOptions) {\n this.snapshot = snapshot;\n this.options = options;\n this.common = common;\n this.idSpace = snapshot.nodes.byRole(\"idSpace\");\n this.originalId = [...snapshot.nodes].find((column) => isIdText(column.meta)) ?? null;\n this.labels = snapshot.nodes.byRole(\"labels\");\n this.kind = snapshot.edges.byRole(\"kind\");\n for (const column of snapshot.nodes) {\n if (isStoredId(column.meta)) {\n this.idColumns.push(column);\n }\n }\n const generic = checkCapabilities(snapshot, NEO4J_CAPABILITIES, common, {\n roles: SLOT_ROLES,\n roleNames: ROLE_NAMES,\n temporalText: true,\n });\n this.planColumns(\"node\", snapshot.nodes, this.nodeColumns);\n this.planColumns(\"edge\", snapshot.edges, this.edgeColumns);\n this.weights = this.planWeightSource();\n this.folding = pairFolding(snapshot);\n this.checkIds();\n this.checkIdColumn();\n this.checkStoredIds();\n this.directionNotes();\n const slots = new Set([this.kind, this.labels, this.idSpace].flatMap((c) => (c === null ? [] : [c.meta.name])));\n for (const gen of generic) {\n if (gen.code === LOSS.JSON && gen.column !== null && this.writtenAsPoint(gen.column)) {\n continue;\n }\n if (gen.code === LOSS.DTYPE && gen.column !== null && slots.has(gen.column)) {\n // :TYPE, :LABEL and :ID(Space) read back as the dict / list-of-dict columns they were\n continue;\n }\n if (gen.code === LOSS.MIXED_DIRECTION_ERROR && this.fatalEdges === null) {\n this.fatalEdges = new GraphFormatError(\"E_DIRECTED\", gen.message, { reason: \"mixed direction\" });\n }\n if ((gen.code === LOSS.POSITIONS || gen.code === LOSS.VIZ) && gen.column !== null) {\n // written as a plain property (a point for a position); the role is what is lost\n this.notes.push(\n Object.freeze({\n code: gen.code,\n message: `node column \"${gen.column}\" is written as a plain property; its role is lost on re-import`,\n column: gen.column,\n count: gen.count,\n }),\n );\n continue;\n }\n this.notes.push(gen);\n }\n this.notes.push(...this.ownNotes);\n this.filterNotesByPart();\n }\n\n /**\n * The direction notes: an undirected snapshot writes every edge as a directed relationship;\n * a mixed snapshot folds its undirected pairs to one directed relationship each under\n * \"directed\" or \"undirected\" (Neo4j has no undirected relationship, so both policies write\n * the same file and the generic W_MIXED_DIRECTION note names the policy); a mutual pair is\n * written as two relationships without its mark.\n */\n private directionNotes(): void {\n const { snapshot, folding } = this;\n if (!snapshot.directed) {\n this.note(\n UNDIRECTED_LOSS,\n `the snapshot is undirected; every edge is written as a directed relationship (${snapshot.edgeCount} edge(s))`,\n null,\n snapshot.edgeCount,\n );\n } else if (this.common.onMixedDirection !== \"error\") {\n let undirected = 0;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (!folding.folded(e) && !folding.sourceDirected(e)) {\n undirected++;\n }\n }\n if (undirected > 0) {\n this.note(\n UNDIRECTED_LOSS,\n `${undirected} undirected edge(s) are written as one directed relationship each (source to target, a pair folded to its primary); Neo4j has no undirected relationship`,\n null,\n undirected,\n );\n }\n }\n if (folding.mutualCount > 0) {\n this.note(\n LOSS.MUTUAL_EXPANDED,\n `${folding.mutualCount} mutual pair(s) are written as two directed relationships; the mutual mark is lost`,\n null,\n folding.mutualCount,\n );\n }\n }\n\n /**\n * Record a note.\n * @param code - the code\n * @param message - the message\n * @param column - the column, or null\n * @param count - the count, or null\n */\n private note(code: string, message: string, column: string | null = null, count: number | null = null): void {\n this.ownNotes.push(Object.freeze({ code, message, column, count }));\n }\n\n /**\n * Plan the property columns of one table.\n * @param domain - node or edge\n * @param table - the table\n * @param out - receives the plans in declaration order\n */\n private planColumns(domain: \"node\" | \"edge\", table: Iterable<Column>, out: ColumnPlan[]): void {\n const all = [...table];\n const names = new Set(all.map((column) => column.meta.name));\n const companionFor = new Map<string, Column>();\n const companions = new Set<Column>();\n for (const column of all) {\n const target = column.meta.extra.for;\n if (column.dtype === \"string\" && typeof target === \"string\" && names.has(target)) {\n companionFor.set(target, column);\n companions.add(column);\n }\n }\n for (const column of all) {\n const { meta } = column;\n const { role } = meta;\n if (companions.has(column) || (role !== null && SKIPPED_ROLES.has(role))) {\n continue;\n }\n if (\n domain === \"node\" &&\n (isStoredId(meta) || column === this.idSpace || column === this.labels || column === this.originalId)\n ) {\n continue;\n }\n if (domain === \"edge\" && (role === \"id\" || column === this.kind)) {\n continue;\n }\n out.push(this.planColumn(column, companionFor.get(meta.name) ?? null));\n }\n }\n\n /**\n * Plan one property column: its header type, cell kind and notes.\n * @param column - the column\n * @param companion - its text companion, or null\n * @returns the plan\n */\n private planColumn(column: Column, companion: Column | null): ColumnPlan {\n const { meta } = column;\n const declared = meta.origin?.type ?? null;\n const mapped = declared === null ? null : mapDeclaredType(NEO4J, declared, \"f64\");\n const label = `${meta.domain} column \"${meta.name}\"`;\n if (meta.dtype === \"list\") {\n const itemDtype = meta.itemDtype ?? \"string\";\n const compatible =\n mapped !== null && mapped.list && mapped.itemDtype === itemDtype && mapped.kind !== \"long\";\n let scalar = compatible\n ? { type: declaredScalar(declared as string), kind: kindOf(mapped), temporal: mapped.temporal }\n : defaultScalar(itemDtype);\n if (mapped !== null && mapped.list && mapped.kind === \"long\" && itemDtype === \"f64\") {\n scalar = this.integralOrDouble(column, declaredScalar(declared as string), label);\n }\n const itemComponents = meta.itemComponents ?? 1;\n if (itemComponents > 1) {\n this.note(\n LOSS.COMPONENTS,\n `${label} holds items of ${itemComponents} components; they are flattened into one array`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n this.checkArrayItems(column, scalar, label);\n return {\n column,\n header: formatHeaderField(meta.name, `${scalar.type}[]`, null),\n scalar,\n list: true,\n companion,\n };\n }\n let scalar: ScalarPlan;\n const compatible = mapped !== null && !mapped.list && mapped.dtype === meta.dtype;\n if (compatible && mapped.kind === \"long\") {\n scalar = this.integralOrDouble(column, declared as string, label);\n } else if (compatible) {\n scalar = { type: declared as string, kind: kindOf(mapped), temporal: mapped.temporal };\n } else {\n scalar = defaultScalar(meta.dtype);\n }\n // the generic check treats position and visual columns by role only; their dtype and\n // stride are checked here so the notes match those of any other column\n const visual = meta.role === \"position\" || (meta.role !== null && isVizRole(meta.role));\n if (visual && meta.dtype === \"json\" && scalar.kind !== \"point\") {\n this.note(\n LOSS.JSON,\n `${label} holds nested values; the format has no nested values`,\n meta.name,\n column.length - column.nullCount,\n );\n } else if (visual && meta.dtype !== \"json\" && !NEO4J_CAPABILITIES.dtypes.includes(meta.dtype)) {\n this.note(\n LOSS.DTYPE,\n `${label} is ${meta.dtype}; the format cannot keep that dtype`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n if (meta.components > 1) {\n if (visual) {\n this.note(\n LOSS.COMPONENTS,\n `${label} has ${meta.components} components; the format has no strides`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n return {\n column,\n header: formatHeaderField(meta.name, `${scalar.type}[]`, null),\n scalar,\n list: true,\n companion,\n };\n }\n // an untyped Neo4j header (`name` alone) is a string property; restore it as written\n const untyped = declared === null && meta.origin?.format === NEO4J && meta.dtype === \"string\";\n const header = untyped ? meta.name : formatHeaderField(meta.name, scalar.type, null);\n return { column, header, scalar, list: false, companion };\n }\n\n /**\n * The plan of an f64 column declared with an integer type: kept when every set value is\n * integral, written as double (with a note) otherwise.\n * @param column - the column\n * @param declared - the declared type text\n * @param label - the column label for messages\n * @returns the scalar plan\n */\n private integralOrDouble(column: Column, declared: string, label: string): ScalarPlan {\n let integral = true;\n if (column.dtype === \"f64\") {\n for (let r = 0; r < column.length && integral; r++) {\n if (column.isSet(r) && !Number.isInteger(column.data[r])) {\n integral = false;\n }\n }\n } else if (column.dtype === \"list\" && column.child.dtype === \"f64\") {\n const { data } = column.child;\n for (let i = 0; i < data.length && integral; i++) {\n if (!Number.isInteger(data[i])) {\n integral = false;\n }\n }\n }\n if (integral) {\n return { type: declared, kind: \"integer\", temporal: null };\n }\n this.note(\n DECLARED_TYPE_CHANGED_LOSS,\n `${label} is declared ${declared} but holds non-integral values; written as double`,\n column.meta.name,\n null,\n );\n return { type: \"double\", kind: \"double\", temporal: null };\n }\n\n /**\n * Count the rows of a list column with an item containing the array delimiter.\n * @param column - the list column\n * @param scalar - the item plan\n * @param label - the column label\n */\n private checkArrayItems(column: Column, scalar: ScalarPlan, label: string): void {\n if (\n column.dtype !== \"list\" ||\n (scalar.kind !== \"string\" && scalar.kind !== \"json\" && scalar.kind !== \"point\")\n ) {\n return;\n }\n const { arrayDelimiter } = this.options;\n let rows = 0;\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n for (const item of column.sliceOf(r)) {\n if (formatScalar(item, scalar, null).includes(arrayDelimiter)) {\n rows++;\n break;\n }\n }\n }\n if (rows > 0) {\n this.note(\n ARRAY_DELIMITER_LOSS,\n `${label}: ${rows} row(s) hold an item containing the array delimiter \"${arrayDelimiter}\", which Neo4j cannot escape`,\n column.meta.name,\n rows,\n );\n }\n }\n\n /**\n * The explicit weights (design section 3.7), and the weight-column name check.\n * @returns the weights, or null when no weights are written\n */\n private planWeightSource(): ExplicitWeights | null {\n const { snapshot } = this;\n const name = this.options.weightColumn;\n if (name === null) {\n return null;\n }\n const weights = explicitWeights(snapshot);\n const taken = this.edgeColumns.find((plan) => plan.column.meta.name === name);\n if (taken !== undefined && weights.weighted) {\n this.note(\n WEIGHT_COLUMN_TAKEN_LOSS,\n `edge column \"${name}\" already exists; explicit weights cannot be written under weightColumn \"${name}\"`,\n name,\n null,\n );\n if (this.fatalEdges === null) {\n this.fatalEdges = new GraphFormatError(\n \"E_COLUMN_EXISTS\",\n `edge column \"${name}\" already exists; choose another weightColumn`,\n { column: name, domain: \"edge\" },\n );\n }\n } else if (taken !== undefined && name === DEFAULT_WEIGHT_COLUMN) {\n this.note(\n LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${name}\" is written under the property the importer reads THE weight from (weightFrom \"${name}\"); it reads back as the weight, not as a column`,\n name,\n taken.column.length - taken.column.nullCount,\n );\n }\n return weights.weighted ? weights : null;\n }\n\n /** Check the node ids' text forms: type changes under the canonical rule and collisions. */\n private checkIds(): void {\n const { ids } = this.snapshot;\n let typeChanges = 0;\n let collisions = 0;\n switch (ids.kind) {\n case \"identity\":\n case \"dense\":\n break;\n case \"numeric\":\n for (let i = 0; i < ids.size; i++) {\n if (!Number.isSafeInteger(ids.idOf(i))) {\n typeChanges++;\n }\n }\n break;\n case \"string\":\n for (let i = 0; i < ids.size; i++) {\n if (isCanonicalIntegerText(String(ids.idOf(i)))) {\n typeChanges++;\n }\n }\n break;\n case \"mixed\": {\n const seen = new Set<string>();\n for (let i = 0; i < ids.size; i++) {\n const id = ids.idOf(i);\n const text = String(id);\n if (typeof id === \"number\" ? !Number.isSafeInteger(id) : isCanonicalIntegerText(text)) {\n typeChanges++;\n }\n if (seen.has(text)) {\n collisions++;\n } else {\n seen.add(text);\n }\n }\n break;\n }\n default: {\n const name: string = ids.kind;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown id map kind ${name}`, { kind: name });\n }\n }\n if (typeChanges > 0) {\n this.note(\n ID_TEXT_TYPE_LOSS,\n `${typeChanges} node id(s) re-import as another type under the canonical id rule (a string of canonical integer text, or a non-integer number)`,\n null,\n typeChanges,\n );\n }\n if (collisions > 0) {\n this.note(\n ID_TEXT_COLLISION_LOSS,\n `${collisions} node id(s) share their text with another id (a number and a string); export() will throw`,\n null,\n collisions,\n );\n this.fatalAll = new GraphFormatError(\n \"E_INVALID_ID\",\n `${collisions} node id(s) share their text with another id; Neo4j ids are text`,\n { reason: \"text collision\", count: collisions },\n );\n }\n }\n\n /** Check that the idColumn option does not name an existing node property. */\n private checkIdColumn(): void {\n const name = this.options.idColumn;\n if (name === null) {\n return;\n }\n const taken =\n this.nodeColumns.some((plan) => plan.column.meta.name === name) ||\n this.idColumns.some((column) => column.meta.name === name);\n if (!taken) {\n return;\n }\n this.note(\n ID_COLUMN_TAKEN_LOSS,\n `node column \"${name}\" already exists; the :ID column cannot be named idColumn \"${name}\"`,\n name,\n null,\n );\n if (this.fatalNodes === null) {\n this.fatalNodes = new GraphFormatError(\n \"E_COLUMN_EXISTS\",\n `node column \"${name}\" already exists; choose another idColumn`,\n { column: name, domain: \"node\" },\n );\n }\n }\n\n /** Count the nodes with more than one stored-id column set. */\n private checkStoredIds(): void {\n if (this.idColumns.length < 2) {\n return;\n }\n let count = 0;\n for (let i = 0; i < this.snapshot.nodeCount; i++) {\n let set = 0;\n for (const column of this.idColumns) {\n if (column.isSet(i)) {\n set++;\n }\n }\n if (set > 1) {\n count++;\n }\n }\n if (count > 0) {\n this.note(\n MULTIPLE_ID_PROPERTIES_LOSS,\n `${count} node(s) have more than one stored-id column set; only the first in declaration order is written`,\n null,\n count,\n );\n }\n }\n\n /**\n * Whether a json column is written as Neo4j points (so the generic nested-value note does not apply).\n * @param name - the column name\n * @returns true when its plan writes point literals\n */\n private writtenAsPoint(name: string): boolean {\n for (const plan of [...this.nodeColumns, ...this.edgeColumns]) {\n if (plan.column.meta.name === name && plan.scalar.kind === \"point\") {\n return true;\n }\n }\n return false;\n }\n\n /** Drop the notes about the part that is not written. */\n private filterNotesByPart(): void {\n const { part } = this.options;\n if (part === \"all\") {\n return;\n }\n const { snapshot } = this;\n const keep = this.notes.filter((n) => {\n if (part === \"nodes\") {\n if (EDGE_NOTE_CODES.has(n.code)) {\n return false;\n }\n return n.column === null || !snapshot.edges.has(n.column) || snapshot.nodes.has(n.column);\n }\n if (NODE_NOTE_CODES.has(n.code)) {\n return false;\n }\n return n.column === null || !snapshot.nodes.has(n.column) || snapshot.edges.has(n.column);\n });\n this.notes.length = 0;\n this.notes.push(...keep);\n }\n\n /**\n * The error export() throws for the requested part, or null when the export can proceed.\n * @returns the error\n */\n get fatal(): GraphFormatError | null {\n if (this.fatalAll !== null) {\n return this.fatalAll;\n }\n const { part } = this.options;\n if (part !== \"relationships\" && this.fatalNodes !== null) {\n return this.fatalNodes;\n }\n return part === \"nodes\" ? null : this.fatalEdges;\n }\n\n /**\n * The id space of a node.\n * @param index - the node index\n * @returns the space name, or null\n */\n spaceOf(index: number): string | null {\n const { idSpace } = this;\n if (idSpace === null || !idSpace.isSet(index)) {\n return null;\n }\n const value = idSpace.value(index);\n return typeof value === \"string\" ? value : String(value);\n }\n\n /**\n * The `:ID` / `:START_ID` / `:END_ID` text of a node: its originalId value when it has an id\n * space (the importer stored it as `Space:id`), its id otherwise.\n * @param index - the node index\n * @returns the id text\n */\n idTextOf(index: number): string {\n const { originalId } = this;\n if (originalId !== null && originalId.isSet(index) && this.spaceOf(index) !== null) {\n return textOf(originalId, index);\n }\n return idText(this.snapshot.ids.idOf(index));\n }\n\n /**\n * The stored-id column of a node: the first one set in declaration order.\n * @param index - the node index\n * @returns the column, or null\n */\n storedIdOf(index: number): Column | null {\n for (const column of this.idColumns) {\n if (column.isSet(index)) {\n return column;\n }\n }\n return null;\n }\n\n /**\n * The node sections, then the relationship sections, as CSV lines.\n * @yields one line at a time (with its line break)\n * @returns nothing\n */\n *lines(): Generator<string, void, undefined> {\n if (this.fatal !== null) {\n throw this.fatal;\n }\n const { part } = this.options;\n if (part !== \"relationships\") {\n yield* this.nodeLines();\n }\n if (part !== \"nodes\") {\n yield* this.relationshipLines();\n }\n }\n\n /**\n * The node sections.\n * @yields one line at a time\n * @returns nothing\n */\n private *nodeLines(): Generator<string, void, undefined> {\n const { snapshot, labels, nodeColumns } = this;\n const { delimiter } = this.options.syntax;\n const propertyHeaders = nodeColumns.map((plan) => plan.header).join(delimiter);\n let sections = 0;\n let sectionSpace: string | null = null;\n let sectionIdName: string | null = null;\n const cells: string[] = [];\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const space = this.spaceOf(i);\n const stored = this.storedIdOf(i);\n const idName = stored === null ? (this.options.idColumn ?? \"\") : stored.meta.name;\n if (sections === 0 || space !== sectionSpace || idName !== sectionIdName) {\n sections++;\n sectionSpace = space;\n sectionIdName = idName;\n const header = [formatHeaderField(idName, ID_TYPE, space)];\n if (labels !== null) {\n header.push(\":LABEL\");\n }\n if (propertyHeaders.length > 0) {\n header.push(propertyHeaders);\n }\n yield `${header.join(delimiter)}\\n`;\n }\n cells.length = 0;\n cells.push(this.cell(this.idTextOf(i)));\n if (labels !== null) {\n cells.push(this.cell(this.labelsText(i)));\n }\n for (const plan of nodeColumns) {\n cells.push(this.cell(this.valueText(plan, i)));\n }\n yield `${cells.join(delimiter)}\\n`;\n }\n if (sections === 0) {\n // no nodes: one header so the section (and its columns) still exists\n const header = [formatHeaderField(this.options.idColumn ?? \"\", ID_TYPE, null)];\n if (labels !== null) {\n header.push(\":LABEL\");\n }\n if (propertyHeaders.length > 0) {\n header.push(propertyHeaders);\n }\n yield `${header.join(delimiter)}\\n`;\n }\n }\n\n /**\n * The relationship sections.\n * @yields one line at a time\n * @returns nothing\n */\n private *relationshipLines(): Generator<string, void, undefined> {\n const { snapshot, kind, weights, edgeColumns, folding } = this;\n const { delimiter } = this.options.syntax;\n const list = snapshot.edgeList();\n const propertyHeaders = edgeColumns.map((plan) => plan.header).join(delimiter);\n const weightHeader =\n weights === null ? null : formatHeaderField(this.options.weightColumn ?? \"weight\", \"double\", null);\n let sections = 0;\n let sectionStart: string | null = null;\n let sectionEnd: string | null = null;\n const cells: string[] = [];\n const headerOf = (startSpace: string | null, endSpace: string | null): string => {\n const header = [formatHeaderField(\"\", \"START_ID\", startSpace), formatHeaderField(\"\", \"END_ID\", endSpace)];\n if (kind !== null) {\n header.push(\":TYPE\");\n }\n if (weightHeader !== null) {\n header.push(weightHeader);\n }\n if (propertyHeaders.length > 0) {\n header.push(propertyHeaders);\n }\n return `${header.join(delimiter)}\\n`;\n };\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (folding.folded(e)) {\n continue;\n }\n const u = list.src[e];\n const v = list.dst[e];\n const startSpace = this.spaceOf(u);\n const endSpace = this.spaceOf(v);\n if (sections === 0 || startSpace !== sectionStart || endSpace !== sectionEnd) {\n sections++;\n sectionStart = startSpace;\n sectionEnd = endSpace;\n yield headerOf(startSpace, endSpace);\n }\n cells.length = 0;\n cells.push(this.cell(this.idTextOf(u)), this.cell(this.idTextOf(v)));\n if (kind !== null) {\n cells.push(this.cell(kind.isSet(e) ? textOf(kind, e) : null));\n }\n if (weights !== null) {\n cells.push(this.cell(weights.text(e)));\n }\n for (const plan of edgeColumns) {\n cells.push(this.cell(this.valueText(plan, e)));\n }\n yield `${cells.join(delimiter)}\\n`;\n }\n if (sections === 0) {\n yield headerOf(null, null);\n }\n }\n\n /**\n * A CSV cell: empty for an unset value, a quoted empty string for a set empty string, the\n * quoted text otherwise.\n * @param text - the value text, or null for unset\n * @returns the cell as written\n */\n private cell(text: string | null): string {\n if (text === null) {\n return \"\";\n }\n const { quote } = this.options.syntax;\n if (text.length === 0) {\n return quote + quote;\n }\n return quoteCsvCell(text, this.options.syntax.delimiter);\n }\n\n /**\n * The `:LABEL` cell of a node.\n * @param index - the node index\n * @returns the labels joined by the array delimiter, or null when unset\n */\n private labelsText(index: number): string | null {\n const { labels } = this;\n if (labels === null || !labels.isSet(index)) {\n return null;\n }\n if (labels.dtype === \"list\") {\n return labels\n .sliceOf(index)\n .map((item) => String(item))\n .join(this.options.arrayDelimiter);\n }\n return textOf(labels, index);\n }\n\n /**\n * The text of one property cell.\n * @param plan - the column plan\n * @param row - the row\n * @returns the text, or null when unset\n */\n private valueText(plan: ColumnPlan, row: number): string | null {\n const { column, scalar, companion } = plan;\n if (!column.isSet(row)) {\n return null;\n }\n if (plan.list) {\n const items = column.dtype === \"list\" ? column.sliceOf(row) : (column.value(row) as ArrayLike<unknown>);\n const texts: string[] = [];\n for (const item of Array.from(items)) {\n // an item of several components (itemComponents > 1) is flattened into the array\n if (Array.isArray(item) || ArrayBuffer.isView(item)) {\n for (const component of Array.from(item as ArrayLike<unknown>)) {\n texts.push(formatScalar(component, scalar, null));\n }\n } else {\n texts.push(formatScalar(item, scalar, null));\n }\n }\n return texts.join(this.options.arrayDelimiter);\n }\n const text = companion !== null && companion.isSet(row) ? textOf(companion, row) : null;\n return formatScalar(column.dtype === \"json\" ? column.values[row] : column.value(row), scalar, text);\n }\n}\n\n/**\n * Whether a node column is the importer's id text of the nodes of an id space (`originalId`).\n * @param meta - the column metadata\n * @returns true for the role-less string column the Neo4j importer declares with origin id `:ID` and no type\n */\nfunction isIdText(meta: ColumnMeta): boolean {\n return (\n meta.role === null &&\n meta.dtype === \"string\" &&\n meta.origin !== null &&\n meta.origin.format === NEO4J &&\n meta.origin.id === \":ID\" &&\n meta.origin.type === null\n );\n}\n\n/**\n * Whether a node column is a stored id (`name:ID` on import).\n * @param meta - the column metadata\n * @returns true for a string column declared by the Neo4j importer as the id property\n */\nfunction isStoredId(meta: ColumnMeta): boolean {\n return (\n meta.role === null &&\n meta.dtype === \"string\" &&\n meta.origin !== null &&\n meta.origin.format === NEO4J &&\n meta.origin.type === ID_TYPE\n );\n}\n\n/**\n * Whether a role is one of the visual roles.\n * @param role - the role\n * @returns true for color, size, shape and thickness\n */\nfunction isVizRole(role: string): boolean {\n return role === \"color\" || role === \"size\" || role === \"shape\" || role === \"thickness\";\n}\n\n/**\n * The declared scalar type text of a list declaration (`string[]` -> `string`).\n * @param declared - the declared type text\n * @returns the text without its `[]` suffix\n */\nfunction declaredScalar(declared: string): string {\n const trimmed = declared.trim();\n return trimmed.endsWith(\"[]\") ? trimmed.slice(0, -2) : trimmed;\n}\n\n/**\n * The cell kind of a mapped declared type.\n * @param spec - the mapped type\n * @returns the kind\n */\nfunction kindOf(spec: DeclaredTypeSpec): CellKind {\n switch (spec.kind) {\n case \"boolean\":\n return \"boolean\";\n case \"integer\":\n case \"long\":\n return \"integer\";\n case \"float\":\n return \"float\";\n case \"double\":\n return \"double\";\n case \"string\":\n case \"duration\":\n return \"string\";\n case \"temporal\":\n return \"temporal\";\n case \"point\":\n return \"point\";\n case \"json\":\n return \"json\";\n default: {\n const name: string = spec.kind;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown value kind ${name}`, { kind: name });\n }\n }\n}\n\n/**\n * The Neo4j type of a dtype without a compatible declaration.\n * @param dtype - the column or item dtype\n * @returns the type and cell kind\n */\nfunction defaultScalar(dtype: Dtype | ScalarDtype): ScalarPlan {\n switch (dtype) {\n case \"f32\":\n return { type: \"float\", kind: \"float\", temporal: null };\n case \"f64\":\n return { type: \"double\", kind: \"double\", temporal: null };\n case \"i32\":\n case \"u8\":\n return { type: \"int\", kind: \"integer\", temporal: null };\n case \"u32\":\n return { type: \"long\", kind: \"integer\", temporal: null };\n case \"bool\":\n return { type: \"boolean\", kind: \"boolean\", temporal: null };\n case \"dict\":\n case \"string\":\n return { type: \"string\", kind: \"string\", temporal: null };\n case \"json\":\n return { type: \"string\", kind: \"json\", temporal: null };\n case \"list\":\n return { type: \"string\", kind: \"json\", temporal: null };\n default: {\n const name: string = dtype;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown dtype ${name}`, { dtype: name });\n }\n }\n}\n\n/**\n * Format one scalar value for a cell.\n * @param value - the value\n * @param scalar - the plan\n * @param text - the companion text of a temporal value, or null\n * @returns the text\n */\nfunction formatScalar(value: unknown, scalar: ScalarPlan, text: string | null): string {\n switch (scalar.kind) {\n case \"integer\":\n return typeof value === \"number\" ? formatInteger(value) : String(value);\n case \"float\":\n return typeof value === \"number\" ? formatF32(value) : String(value);\n case \"double\":\n return typeof value === \"number\" ? formatF64(value) : String(value);\n case \"boolean\":\n return value === true ? \"true\" : \"false\";\n case \"string\":\n return typeof value === \"string\" ? value : String(value);\n case \"temporal\":\n if (text !== null) {\n return text;\n }\n return typeof value === \"number\" && scalar.temporal !== null\n ? formatTemporal(value, scalar.temporal)\n : String(value);\n case \"point\":\n return formatPoint(value);\n case \"json\":\n return JSON.stringify(value) ?? \"\";\n default: {\n const name: string = scalar.kind;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown cell kind ${name}`, { kind: name });\n }\n }\n}\n\n/**\n * A Neo4j point literal `{x:1.5, y:2, crs:'cartesian'}` from a point object; any other value is\n * written as JSON text.\n * @param value - the json value\n * @returns the literal\n */\nfunction formatPoint(value: unknown): string {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return JSON.stringify(value) ?? \"\";\n }\n const parts: string[] = [];\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (typeof item === \"number\") {\n parts.push(`${key}:${formatF64(item)}`);\n } else if (typeof item === \"string\") {\n parts.push(`${key}:'${item.replace(/'/g, \"\")}'`);\n } else {\n return JSON.stringify(value) ?? \"\";\n }\n }\n return `{${parts.join(\", \")}}`;\n}\n\n/**\n * The text of a node id.\n * @param id - the id\n * @returns String(id)\n */\nfunction idText(id: NodeId): string {\n if (typeof id === \"string\") {\n return id;\n }\n return Number.isInteger(id) ? formatInteger(id) : String(id);\n}\n\n/**\n * The text of a set cell of a dict / string (or any scalar) column.\n * @param column - the column\n * @param row - the row\n * @returns the value as text\n */\nfunction textOf(column: Column, row: number): string {\n switch (column.dtype) {\n case \"string\":\n return column.valueAt(row);\n case \"dict\":\n return String(column.value(row));\n case \"list\":\n return column.sliceOf(row).map(String).join(\",\");\n case \"json\":\n return JSON.stringify(column.values[row]) ?? \"\";\n case \"bool\":\n return column.value(row) === true ? \"true\" : \"false\";\n default: {\n const value = column.value(row);\n return typeof value === \"number\" ? String(value) : Array.from(value as ArrayLike<number>).join(\",\");\n }\n }\n}\n\n/** The Neo4j exporter. */\nexport const neo4jExporter: GraphExporter<Neo4jExportOptions> = Object.freeze({\n format: NEO4J,\n capabilities: NEO4J_CAPABILITIES,\n /**\n * Pre-flight: what export() would lose.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the notes\n */\n check(snapshot: GraphSnapshot, options?: Neo4jExportOptions & CommonExportOptions): readonly LossNote[] {\n return Object.freeze([...plan(snapshot, options).notes]);\n },\n /**\n * Write the snapshot as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: Neo4jExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(plan(snapshot, options).lines());\n },\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: Neo4jExportOptions & CommonExportOptions): Promise<string> {\n return joinText(plan(snapshot, options).lines());\n },\n});\n\n/**\n * Build the export plan of a snapshot.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @returns the plan\n */\nfunction plan(snapshot: GraphSnapshot, options: (Neo4jExportOptions & CommonExportOptions) | undefined): ExportPlan {\n return new ExportPlan(snapshot, resolveNeo4jExportOptions(options), resolveExportOptions(options));\n}\n","/**\n * The `@graphty/graph-io/neo4j` subpath: the Neo4j importer and exporter with their option types\n * (design section 8.2), the names of the reserved columns and the issue and loss-note codes\n * grouped in two tables.\n */\n\nimport {\n COLUMN_RENAMED_CODE,\n ENCODING_FALLBACK_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MUTUAL_EXPANDED_CODE,\n OPTION_IGNORED_CODE,\n PRECISION_CODE,\n ROLE_DROPPED_CODE,\n SINK_OPTION_CODE,\n UNKNOWN_ATTR_TYPE_CODE,\n UNKNOWN_ENCODING_CODE,\n WEIGHT_KEY_CLASH_CODE,\n} from \"../../common/codes.js\";\nimport { BAD_QUOTE_CODE, UNCLOSED_QUOTE_CODE } from \"../csv/records.js\";\nimport {\n ARRAY_DELIMITER_LOSS,\n DECLARED_TYPE_CHANGED_LOSS,\n ID_COLUMN_TAKEN_LOSS,\n ID_TEXT_COLLISION_LOSS,\n ID_TEXT_TYPE_LOSS,\n MULTIPLE_ID_PROPERTIES_LOSS,\n UNDIRECTED_LOSS,\n WEIGHT_COLUMN_TAKEN_LOSS,\n} from \"./exporter.js\";\nimport {\n COLUMN_COUNT_CODE,\n DUPLICATE_NODE_CODE,\n ENDPOINT_SPACE_CODE,\n HEADER_CODE,\n HEADER_OPTION_CODE,\n ID_MERGED_CODE,\n ID_SPACE_COLLISION_CODE,\n IGNORED_COLUMNS_LOSS,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n ROLE_TAKEN_CODE,\n} from \"./importer.js\";\n\nexport { NEO4J_CAPABILITIES, neo4jExporter, type Neo4jExportOptions } from \"./exporter.js\";\nexport {\n ID_SPACE_COLUMN,\n LABELS_COLUMN,\n neo4jImporter,\n type Neo4jImportOptions,\n ORIGINAL_ID_COLUMN,\n TYPE_COLUMN,\n} from \"./importer.js\";\n\n/**\n * The issue codes the Neo4j importer records (design section 8.6), by name: the codes shared with\n * the other importers (src/common/codes.ts, the CSV record reader) and the Neo4j-specific ones.\n * A key is the code without its severity and format prefixes.\n */\nexport const NEO4J_ISSUE = Object.freeze({\n /** The input holds invalid UTF-8 (fatal). */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /** Invalid bytes in the encoding a BOM, a declaration or the encoding option chose (fatal). */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** An unterminated quoted field (fatal). */\n CSV_UNCLOSED_QUOTE: UNCLOSED_QUOTE_CODE,\n /** Text after a closing quote (fatal). */\n CSV_QUOTE: BAD_QUOTE_CODE,\n /** No header or a malformed header (fatal). */\n HEADER: HEADER_CODE,\n /** A row with a different field count than the header. */\n COLUMN_COUNT: COLUMN_COUNT_CODE,\n /** A node row without an id. */\n MISSING_ID: MISSING_ID_CODE,\n /** A relationship row without a start or end id. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** A node id repeated in one id space (last write wins). */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** A spaced node id `Space:id` that equals the text of an id declared without a space. */\n ID_SPACE_COLLISION: ID_SPACE_COLLISION_CODE,\n /** A spaced relationship endpoint `Space:id` that names a node declared without a space; the row is skipped. */\n ENDPOINT_SPACE: ENDPOINT_SPACE_CODE,\n /** Two id texts merged into one number under ids \"number\". */\n ID_MERGED: ID_MERGED_CODE,\n /** A header brace option the importer does not apply. */\n HEADER_OPTION_IGNORED: HEADER_OPTION_CODE,\n /** A declared type the format does not define (kept as string). */\n UNKNOWN_ATTR_TYPE: UNKNOWN_ATTR_TYPE_CODE,\n /** A long value beyond 2^53 rounded. */\n PRECISION: PRECISION_CODE,\n /** A column renamed `<name>#<id>` because the name was taken (design section 5.6). */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /** A role the caller's sink already holds. */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** A common option the importer has no use for (nodeIdFrom, defaultDirected, ...). */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** A builder-policy option the sink does not honour. */\n SINK_OPTION: SINK_OPTION_CODE,\n});\n\n/**\n * The loss-note codes of the Neo4j importer (report.lossy) and exporter (check()), by name: the\n * Neo4j ones and, aliased, the shared ones it records (`LOSS` holds the generic pre-flight's).\n */\nexport const NEO4J_LOSS = Object.freeze({\n /** `:IGNORE` columns skipped on import. */\n IGNORED_COLUMNS: IGNORED_COLUMNS_LOSS,\n /** Undirected edges (an undirected snapshot, the folded pairs of a mixed one) written as directed relationships. */\n UNDIRECTED_AS_DIRECTED: UNDIRECTED_LOSS,\n /** A mutual pair written as two directed relationships without its mark. */\n MUTUAL_EXPANDED: MUTUAL_EXPANDED_CODE,\n /** A role column Neo4j has no slot for (label, ...) written as a plain property. */\n ROLE_DROPPED: ROLE_DROPPED_CODE,\n /** A plain `weight` edge column reads back as THE weight (the importer's weightFrom default). */\n WEIGHT_KEY_CLASH: WEIGHT_KEY_CLASH_CODE,\n /** A node id whose text re-imports as another type under the canonical rule. */\n ID_TEXT_TYPE: ID_TEXT_TYPE_LOSS,\n /** A number and a string id with the same text; export() throws. */\n ID_TEXT_COLLISION: ID_TEXT_COLLISION_LOSS,\n /** The weight column name is taken by an edge column; export() throws. */\n WEIGHT_COLUMN_TAKEN: WEIGHT_COLUMN_TAKEN_LOSS,\n /** The id column name is taken by a node column; export() throws. */\n ID_COLUMN_TAKEN: ID_COLUMN_TAKEN_LOSS,\n /** Several stored-id properties; one becomes the `:ID` column. */\n MULTIPLE_ID_PROPERTIES: MULTIPLE_ID_PROPERTIES_LOSS,\n /** An integer-typed column with non-integral values written as double. */\n DECLARED_TYPE_CHANGED: DECLARED_TYPE_CHANGED_LOSS,\n /** A list item containing the array delimiter, which Neo4j cannot escape. */\n ARRAY_DELIMITER: ARRAY_DELIMITER_LOSS,\n});\n"],"names":["headerError","SHARED_MISSING_ID_CODE","SHARED_MISSING_ENDPOINT_CODE","SHARED_DUPLICATE_NODE_CODE","SHARED_ID_MERGED_CODE","SHARED_ROLE_TAKEN_CODE","NEO4J","idText","compatible","scalar","plan"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"neo4j.js","sources":["../src/formats/neo4j/header.ts","../src/formats/neo4j/importer.ts","../src/formats/neo4j/exporter.ts","../src/formats/neo4j/index.ts"],"sourcesContent":["/**\n * The neo4j-admin import header grammar (research note 07 section 2.6): every header cell is\n * `<name>:<field type>(<id space>){<options>}` where the name and every later part are optional.\n * The field types `ID`, `LABEL`, `START_ID`, `END_ID`, `TYPE` and `IGNORE` are structural; any\n * other field type is a property type of design section 5.1 (`int`, `long`, `float`, `double`,\n * `boolean`, `byte`, `short`, `char`, `string`, `point`, `date`, `localtime`, `time`,\n * `localdatetime`, `datetime`, `duration`, each with an optional `[]` suffix); a cell without a\n * colon is a string property. An id space may follow `ID`, `START_ID` and `END_ID`; brace options\n * (`label`, `id-type`) may follow any structural type.\n */\n\nimport { GraphFormatError } from \"@graphty/graph-format\";\n\n/** The structural field types and the marker for a property column. */\nexport type FieldKind = \"ID\" | \"LABEL\" | \"START_ID\" | \"END_ID\" | \"TYPE\" | \"IGNORE\" | \"PROPERTY\";\n\n/** One parsed header cell. */\nexport interface HeaderField {\n /** The cell text as written. */\n readonly text: string;\n /** The property name (the id property name for `name:ID`); empty when none. */\n readonly name: string;\n /** The field kind. */\n readonly kind: FieldKind;\n /** The property type text for a PROPERTY field (null when the cell declares none); null otherwise. */\n readonly type: string | null;\n /** The id space of an ID / START_ID / END_ID field, or null. */\n readonly space: string | null;\n /** The brace options, keys lower-cased. */\n readonly options: ReadonlyMap<string, string>;\n}\n\nconst STRUCTURAL: ReadonlySet<string> = new Set([\"ID\", \"LABEL\", \"START_ID\", \"END_ID\", \"TYPE\", \"IGNORE\"]);\nconst SPACE_KINDS: ReadonlySet<string> = new Set([\"ID\", \"START_ID\", \"END_ID\"]);\nconst HEADER_MARKER = /^[^:{}()]*:\\s*(ID|START_ID|END_ID)\\s*(\\(|\\{|$)/i;\nconst CELL = /^([^:(){}]*)(?::([^:(){}]*))?(?:\\(([^)]*)\\))?(?:\\{([^}]*)\\})?$/;\n\n/**\n * Whether a record looks like a section header: some cell declares an `ID`, `START_ID` or `END_ID`\n * field. The neo4j-admin convention allows several files, each with its own header; graphty's\n * single-file convention (the CSVDataSource of graphty-element) concatenates sections, so a header\n * may appear anywhere.\n * @param cells - the record's cells\n * @param count - how many cells are valid\n * @returns true when the record is a header\n */\nexport function isHeaderRecord(cells: readonly string[], count: number): boolean {\n for (let i = 0; i < count; i++) {\n const cell = cells[i];\n // every header marker holds a colon; the indexOf keeps the regex off the data rows\n if (cell.indexOf(\":\") >= 0 && HEADER_MARKER.test(cell.trim())) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Parse one header cell.\n * @param text - the cell text\n * @returns the field; E_UNSUPPORTED (reason \"header\") for a cell outside the grammar\n */\nexport function parseHeaderField(text: string): HeaderField {\n const trimmed = text.trim();\n const m = CELL.exec(trimmed);\n if (m === null) {\n throw headerError(text, \"not a neo4j header cell\");\n }\n const name = m[1].trim();\n const rawType = m[2] === undefined ? null : m[2].trim();\n const space = m[3] === undefined ? null : m[3].trim();\n const options = parseOptions(text, m[4]);\n if (rawType === null) {\n // `name` alone: a string property\n if (name.length === 0) {\n throw headerError(text, \"an empty header cell\");\n }\n if (space !== null || options.size > 0) {\n throw headerError(text, \"an id space or options need a field type\");\n }\n return { text, name, kind: \"PROPERTY\", type: null, space: null, options };\n }\n if (rawType.length === 0) {\n throw headerError(text, \"an empty field type\");\n }\n const upper = rawType.toUpperCase();\n if (STRUCTURAL.has(upper)) {\n const kind = upper as Exclude<FieldKind, \"PROPERTY\">;\n if (space !== null && !SPACE_KINDS.has(kind)) {\n throw headerError(text, `an id space is only allowed on ID, START_ID and END_ID, not ${kind}`);\n }\n if (name.length > 0 && kind !== \"ID\" && kind !== \"IGNORE\") {\n throw headerError(text, `a ${kind} field cannot be stored as a property`);\n }\n return { text, name, kind, type: null, space: space === \"\" ? null : space, options };\n }\n if (name.length === 0) {\n throw headerError(text, \"a property column needs a name\");\n }\n if (space !== null) {\n throw headerError(text, \"an id space is only allowed on ID, START_ID and END_ID\");\n }\n return { text, name, kind: \"PROPERTY\", type: rawType, space: null, options };\n}\n\n/**\n * Parse the `{key:value, key:value}` options of a header cell.\n * @param text - the whole cell, for errors\n * @param body - the text between the braces, or undefined when absent\n * @returns the options with lower-cased keys\n */\nfunction parseOptions(text: string, body: string | undefined): ReadonlyMap<string, string> {\n const options = new Map<string, string>();\n if (body === undefined || body.trim().length === 0) {\n return options;\n }\n for (const part of body.split(\",\")) {\n const colon = part.indexOf(\":\");\n if (colon < 0) {\n throw headerError(text, `option \"${part.trim()}\" is not key:value`);\n }\n const key = part.slice(0, colon).trim().toLowerCase();\n const value = part.slice(colon + 1).trim();\n if (key.length === 0) {\n throw headerError(text, \"an option needs a key\");\n }\n options.set(key, value);\n }\n return options;\n}\n\n/**\n * The error of a malformed header cell.\n * @param text - the cell\n * @param reason - why\n * @returns the error\n */\nfunction headerError(text: string, reason: string): GraphFormatError {\n return new GraphFormatError(\"E_UNSUPPORTED\", `header cell \"${text}\": ${reason}`, {\n reason: \"header\",\n cell: text,\n detail: reason,\n });\n}\n\n/**\n * Write a header cell from its parts, the inverse of parseHeaderField.\n * @param name - the property name, or empty\n * @param type - the field type or property type\n * @param space - the id space, or null\n * @returns the cell text\n */\nexport function formatHeaderField(name: string, type: string, space: string | null): string {\n const base = `${name}:${type}`;\n return space === null ? base : `${base}(${space})`;\n}\n","/**\n * The Neo4j importer (design sections 8.4 and 5.1, research note 07 sections 2.6 and 2.10): reads\n * neo4j-admin import CSV -- node tables with `:ID`, `:LABEL` and typed property columns,\n * relationship tables with `:START_ID`, `:END_ID`, `:TYPE` and typed property columns -- and pushes\n * scalars into the sink one record at a time. Input is one or more files: the primary input plus the\n * `nodes` and `relationships` option inputs, each read in order; every input holds one or more\n * sections, each starting with its own header row (the single-file convention of graphty-element's\n * CSVDataSource, where a node table and a relationship table follow each other in one file).\n *\n * Mapping (design section 5.1 and decision Q27):\n * - Property columns are declared up front from the header types (`int` -> i32, `long` -> f64\n * with a precision issue beyond 2^53, `float` -> f32, `double` -> f64, `boolean` -> bool,\n * `string` / `char` / `duration` -> string, temporal types -> f64 milliseconds with a `.text`\n * companion when the source text is not canonical, `point` -> json, `type[]` -> list); an\n * untyped column is a string property. An unquoted empty cell is \"property not set\"; a quoted\n * empty cell is an empty string (or an empty list), as neo4j-admin stores it by default.\n * - `:LABEL` becomes the node list-of-dict column `labels` (role `labels`); `:TYPE` the edge dict\n * column `type` (role `kind`); an id space `:ID(Space)` the node dict column `idSpace` (role\n * `idSpace`), and a stored id `name:ID(Space)` also a string node column `name` whose\n * `origin.namespace` is the space. A property whose name collides with one of those is renamed\n * `<name>#<name>` (design section 5.6).\n * - Id spaces: neo4j-admin keeps one id space per `:ID(Space)` name, so `1` in `:ID(Product)` and\n * `1` in `:ID(Category)` are two nodes. The core has one id space, so a node of a spaced section\n * is stored under the string id `Space:id` (every row of the section, collision or not, so an id\n * never depends on file order), its id text goes into the node string column `originalId` and\n * its space into `idSpace`. The column has no role: the `originalId` role means an id rewritten by\n * `sanitizeIds: \"mangle\"`, which other importers restore as the node id. `:START_ID(Space)` /\n * `:END_ID(Space)` endpoints are qualified the same way before the lookup; an endpoint without a\n * space is looked up as written.\n * - Ids are text cells coerced by the `ids` option (\"canonical\" by default, so `1` is the number 1\n * and `007` stays a string; integers beyond 2^53 stay strings). Relationships are always directed\n * (\"In Neo4j, all relationships have a direction\"), so the sink is set directed before the first\n * edge and `onMixedDirection: \"undirected\"` is the way to read a file as undirected.\n * - `:IGNORE` columns are skipped and counted in a loss note.\n */\n\nimport {\n type ColumnDecl,\n type ColumnHandle,\n GraphFormatError,\n type GraphSink,\n INVALID_INDEX,\n type NodeId,\n} from \"@graphty/graph-format\";\n\nimport {\n type AttributeDeclarationInput,\n declareAttribute,\n declareCompanion,\n type DeclaredAttribute,\n declareOn,\n losesPrecision,\n parseDeclaredTemporal,\n parseDeclaredValue,\n PRECISION_CODE,\n RENAMED_CODE,\n takenIn,\n uniqueColumnName,\n} from \"../../common/attributes.js\";\nimport {\n DUPLICATE_NODE_CODE as SHARED_DUPLICATE_NODE_CODE,\n MISSING_ENDPOINT_CODE as SHARED_MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE as SHARED_MISSING_ID_CODE,\n ROLE_TAKEN_CODE as SHARED_ROLE_TAKEN_CODE,\n} from \"../../common/codes.js\";\nimport { type DeclaredTypeSpec } from \"../../common/declared-types.js\";\nimport { DirectionResolver } from \"../../common/direction.js\";\nimport { ID_MERGED_CODE as SHARED_ID_MERGED_CODE, IdCoercer } from \"../../common/ids.js\";\nimport { inputLength, isImportInput, type ReadOptions, throwIfAborted } from \"../../common/input.js\";\nimport { type ListSyntax, splitListText } from \"../../common/lists.js\";\nimport {\n reportSinkOptions,\n reportUnusedOptions,\n type ResolvedImportOptions,\n resolveImportOptions,\n} from \"../../common/options.js\";\nimport { ImportReportBuilder } from \"../../common/report.js\";\nimport { parseWeightText } from \"../../common/weights.js\";\nimport {\n type CommonImportOptions,\n type GraphImporter,\n ImportError,\n type ImportInput,\n type ImportReport,\n} from \"../../types.js\";\nimport { checkRecordSyntax, RecordReader, type RecordSyntax } from \"../csv/records.js\";\nimport { type FieldKind, type HeaderField, isHeaderRecord, parseHeaderField } from \"./header.js\";\n\n/** The format-specific options of the Neo4j importer. */\nexport interface Neo4jImportOptions {\n /** Further node files, each with its own header row(s); read after the primary input. */\n nodes?: ImportInput | readonly ImportInput[] | undefined;\n /** Relationship files, each with its own header row(s); read after the node files. */\n relationships?: ImportInput | readonly ImportInput[] | undefined;\n /**\n * The field delimiter (neo4j-admin `--delimiter`); one character. When absent it is sniffed\n * from the first rows between \",\" and a tab, so a `.tsv` file needs no option.\n */\n delimiter?: string | undefined;\n /** The array delimiter of list values and `:LABEL` cells (neo4j-admin `--array-delimiter`); \";\" by default. */\n arrayDelimiter?: \";\" | \",\" | \"|\" | undefined;\n /** The quote character (neo4j-admin `--quote`); one character; a double quote by default. */\n quote?: string | undefined;\n}\n\n/** The name of the node list column holding `:LABEL` values. */\nexport const LABELS_COLUMN = \"labels\";\n\n/** The name of the edge dict column holding `:TYPE` values. */\nexport const TYPE_COLUMN = \"type\";\n\n/** The name of the node dict column holding the id space of `:ID(Space)`. */\nexport const ID_SPACE_COLUMN = \"idSpace\";\n\n/** The name of the node string column holding the id text of a node of an id space (its id is `Space:id`). */\nexport const ORIGINAL_ID_COLUMN = \"originalId\";\n\n/** Issue code: a header row (or a whole section) is malformed; the import aborts. */\nexport const HEADER_CODE = \"E_NEO4J_HEADER\";\n\n/** Issue code: a row has a different number of cells than its header. */\nexport const COLUMN_COUNT_CODE = \"E_NEO4J_COLUMN_COUNT\";\n\n/** Issue code: a node row has an unquoted empty `:ID` cell (a quoted empty cell is the id \"\"). */\nexport const MISSING_ID_CODE = SHARED_MISSING_ID_CODE;\n\n/** Issue code: a relationship row has an unquoted empty `:START_ID` or `:END_ID` cell. */\nexport const MISSING_ENDPOINT_CODE = SHARED_MISSING_ENDPOINT_CODE;\n\n/** Issue code: a node id was declared twice (same id space); the later row's properties win. */\nexport const DUPLICATE_NODE_CODE = SHARED_DUPLICATE_NODE_CODE;\n\n/**\n * Issue code: a node id was declared in two id spaces -- a spaced id `Space:id` equals the text of an\n * id declared without a space; the later row is skipped.\n */\nexport const ID_SPACE_COLLISION_CODE = \"E_NEO4J_ID_SPACE_COLLISION\";\n\n/**\n * Issue code: a `:START_ID(Space)` / `:END_ID(Space)` endpoint's qualified id `Space:id` names a node a\n * node row declared in another id space (without a space); the row is skipped.\n */\nexport const ENDPOINT_SPACE_CODE = \"E_NEO4J_ENDPOINT_SPACE\";\n\n/** Issue code: two different id cells became one id under `ids: \"number\"`. */\nexport const ID_MERGED_CODE = SHARED_ID_MERGED_CODE;\n\n/** Issue code: a header brace option the importer does not act on. */\nexport const HEADER_OPTION_CODE = \"W_NEO4J_HEADER_OPTION_IGNORED\";\n\n/** Issue code: a reserved column (labels / type / idSpace) lost its role because the sink already holds it. */\nexport const ROLE_TAKEN_CODE = SHARED_ROLE_TAKEN_CODE;\n\n/** Loss code: `:IGNORE` columns were skipped. */\nexport const IGNORED_COLUMNS_LOSS = \"W_NEO4J_IGNORED_COLUMNS\";\n\n/** The common options the Neo4j importer reads (the rest is reported by reportUnusedOptions). */\nconst USED_OPTIONS: ReadonlySet<keyof CommonImportOptions> = new Set<keyof CommonImportOptions>([\n \"ids\",\n \"addMissingNodes\",\n \"duplicateEdges\",\n \"selfLoops\",\n \"onMixedDirection\",\n \"weightFrom\",\n \"weightDtype\",\n \"long\",\n \"errorLimit\",\n \"signal\",\n \"onProgress\",\n]);\n\nconst NEO4J = \"neo4j\";\n\n/** Rows between two checks of the cancellation signal (a whole string input is one chunk). */\nconst ABORT_CHECK_INTERVAL = 64;\n\nconst LABELS_DECL: ColumnDecl = {\n name: LABELS_COLUMN,\n dtype: \"list\",\n itemDtype: \"dict\",\n nullable: true,\n role: \"labels\",\n origin: { format: NEO4J, id: \":LABEL\", title: null, type: \"LABEL\", namespace: null },\n};\n\nconst TYPE_DECL: ColumnDecl = {\n name: TYPE_COLUMN,\n dtype: \"dict\",\n nullable: true,\n role: \"kind\",\n origin: { format: NEO4J, id: \":TYPE\", title: null, type: \"TYPE\", namespace: null },\n};\n\nconst ID_SPACE_DECL: ColumnDecl = {\n name: ID_SPACE_COLUMN,\n dtype: \"dict\",\n nullable: true,\n role: \"idSpace\",\n origin: { format: NEO4J, id: \":ID\", title: null, type: \"ID\", namespace: null },\n};\n\nconst ORIGINAL_ID_DECL: ColumnDecl = {\n name: ORIGINAL_ID_COLUMN,\n dtype: \"string\",\n nullable: true,\n // origin.type stays null so the column is never mistaken for a stored id (`name:ID`)\n origin: { format: NEO4J, id: \":ID\", title: null, type: null, namespace: null },\n};\n\nconst ARRAY_DELIMITERS: Readonly<Record<string, ListSyntax>> = { \";\": \"semicolon\", \",\": \"comma\", \"|\": \"pipe\" };\n\n/** The resolved format-specific options. */\ninterface ResolvedNeo4jOptions {\n readonly nodes: readonly ImportInput[];\n readonly relationships: readonly ImportInput[];\n readonly syntax: RecordSyntax;\n readonly listSyntax: ListSyntax;\n}\n\n/** One property column of a section. */\ninterface PropertySlot {\n /** The cell index. */\n readonly cell: number;\n /** The column name (after any rename). */\n readonly name: string;\n /** The column handle. */\n readonly handle: ColumnHandle;\n /** How the cell text is parsed. */\n readonly spec: DeclaredTypeSpec;\n /** The declaration of the companion text column of a temporal property, or null. */\n readonly companionDecl: ColumnDecl | null;\n /** The companion's handle once a value needed it (design section 5.1); INVALID_INDEX before. */\n companion: ColumnHandle;\n}\n\n/** A node section: the header interpreted. */\ninterface NodeSection {\n readonly kind: \"node\";\n readonly width: number;\n readonly idCell: number;\n /** The column holding the id as a property (`name:ID`), or INVALID_INDEX. */\n readonly idHandle: ColumnHandle;\n readonly space: string | null;\n readonly spaceCode: number;\n readonly labelCells: readonly number[];\n readonly extraLabels: readonly string[];\n readonly properties: readonly PropertySlot[];\n}\n\n/** A relationship section: the header interpreted. */\ninterface RelationshipSection {\n readonly kind: \"relationship\";\n readonly width: number;\n readonly startCell: number;\n readonly endCell: number;\n /** The id space of `:START_ID` / `:END_ID`, or null when the header declares none. */\n readonly startSpace: string | null;\n readonly endSpace: string | null;\n /** The id space of `:START_ID` / `:END_ID` as a registry code, or 0 when the header declares none. */\n readonly startSpaceCode: number;\n readonly endSpaceCode: number;\n /** The `:TYPE` cell, or -1. */\n readonly typeCell: number;\n /** The cell of the property named by `weightFrom`, or -1. */\n readonly weightCell: number;\n readonly properties: readonly PropertySlot[];\n}\n\ntype Section = NodeSection | RelationshipSection;\n\n/** The delimiters sniffed between when none is given: neo4j-admin's default and the TSV tab. */\nconst NEO4J_DELIMITER_CANDIDATES: readonly string[] = Object.freeze([\",\", \"\\t\"]);\n\n/**\n * Resolve the format-specific options.\n * @param options - the caller's options\n * @returns the resolved options; E_UNSUPPORTED for an invalid value\n */\nfunction resolveNeo4jOptions(options: Neo4jImportOptions | undefined): ResolvedNeo4jOptions {\n const o: Neo4jImportOptions = options ?? {};\n const arrayDelimiter = o.arrayDelimiter ?? \";\";\n const listSyntax = ARRAY_DELIMITERS[arrayDelimiter];\n if (typeof arrayDelimiter !== \"string\" || listSyntax === undefined) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option arrayDelimiter: ${JSON.stringify(arrayDelimiter)} is not one of \";\", \",\", \"|\"`,\n { option: \"arrayDelimiter\", found: arrayDelimiter },\n );\n }\n const syntax = checkRecordSyntax({\n delimiter: o.delimiter ?? null,\n quote: o.quote ?? '\"',\n candidates: NEO4J_DELIMITER_CANDIDATES.filter((d) => d !== arrayDelimiter),\n });\n if (syntax.delimiter === arrayDelimiter) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"options delimiter and arrayDelimiter must differ\", {\n option: \"arrayDelimiter\",\n found: arrayDelimiter,\n });\n }\n return {\n nodes: inputList(\"nodes\", o.nodes),\n relationships: inputList(\"relationships\", o.relationships),\n syntax,\n listSyntax,\n };\n}\n\n/**\n * Normalise an input-list option.\n * @param name - the option name\n * @param value - one input, a list of inputs, or undefined\n * @returns the inputs; E_UNSUPPORTED for anything else\n */\nfunction inputList(name: string, value: unknown): readonly ImportInput[] {\n if (value === undefined || value === null) {\n return [];\n }\n const list: unknown[] = Array.isArray(value) ? (value as unknown[]) : [value];\n for (const item of list) {\n if (!isImportInput(item)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", `option ${name}: an entry is not an ImportInput`, {\n option: name,\n found: typeof item,\n });\n }\n }\n return list as ImportInput[];\n}\n\n/**\n * Which nodes were declared by a node row and in which id space, by node index, so a repeated id\n * is reported (a duplicate in one space, a collision across spaces).\n */\nclass NodeRegistry {\n private codes = new Uint32Array(1024);\n\n private readonly spaces = new Map<string | null, number>();\n\n /**\n * The code of an id space (1 for \"no space\").\n * @param space - the space name or null\n * @returns a code >= 1\n */\n codeOf(space: string | null): number {\n let code = this.spaces.get(space);\n if (code === undefined) {\n code = this.spaces.size + 1;\n this.spaces.set(space, code);\n }\n return code;\n }\n\n /**\n * Record that a node row declared a node.\n * @param index - the node index\n * @param code - the space code\n * @returns \"new\" for a first declaration, \"duplicate\" for a repeat in the same space, \"collision\" across spaces\n */\n declare(index: number, code: number): \"new\" | \"duplicate\" | \"collision\" {\n if (index >= this.codes.length) {\n let size = this.codes.length * 2;\n while (size <= index) {\n size *= 2;\n }\n const grown = new Uint32Array(size);\n grown.set(this.codes);\n this.codes = grown;\n }\n const previous = this.codes[index];\n if (previous === 0) {\n this.codes[index] = code;\n return \"new\";\n }\n return previous === code ? \"duplicate\" : \"collision\";\n }\n\n /**\n * The space code a node row declared a node in.\n * @param index - the node index\n * @returns the code, or 0 when no node row declared the node\n */\n codeAt(index: number): number {\n return index < this.codes.length ? this.codes[index] : 0;\n }\n}\n\n/**\n * Byte progress over several inputs as one sequence: each input's progress is offset by the bytes\n * of the inputs before it, and the total is known only when every input is in memory.\n */\nclass ProgressTracker {\n private readonly callback: ((bytesDone: number, bytesTotal?: number) => void) | null;\n\n private readonly total: number | undefined;\n\n private offset = 0;\n\n private lastDone = 0;\n\n /**\n * Create a tracker.\n * @param callback - the caller's onProgress, or null\n * @param inputs - every input in reading order\n */\n constructor(callback: ((bytesDone: number, bytesTotal?: number) => void) | null, inputs: readonly ImportInput[]) {\n this.callback = callback;\n let total: number | undefined = 0;\n for (const input of inputs) {\n const length = inputLength(input);\n if (length === null) {\n total = undefined;\n break;\n }\n total += length;\n }\n this.total = total;\n }\n\n /**\n * The read options for one input.\n * @param signal - the cancellation signal\n * @returns options whose onProgress reports cumulative bytes\n */\n optionsFor(signal: AbortSignal | null): ReadOptions {\n const { callback } = this;\n if (callback === null) {\n return { signal };\n }\n return {\n signal,\n onProgress: (done: number): void => {\n this.lastDone = done;\n callback(this.offset + done, this.total);\n },\n };\n }\n\n /** Move the offset past the input just finished. */\n finishInput(): void {\n this.offset += this.lastDone;\n this.lastDone = 0;\n }\n}\n\n/**\n * The state of one import call: the sink, the report, the resolved options, the reserved column\n * handles and the per-section row handlers.\n */\nclass Neo4jImportSession {\n private readonly sink: GraphSink;\n\n private readonly report: ImportReportBuilder;\n\n private readonly common: ResolvedImportOptions;\n\n private readonly options: ResolvedNeo4jOptions;\n\n private readonly coercer: IdCoercer;\n\n private readonly direction: DirectionResolver;\n\n private readonly registry = new NodeRegistry();\n\n private labelsHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private typeHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private idSpaceHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private originalIdHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n\n private ignoredColumns = 0;\n\n /** Whether the sink's direction was set (before the first relationship, design section 8.4 rule 1). */\n private headerSet = false;\n\n /** Scratch: the parsed value of every cell of the current row. */\n private values: unknown[] = [];\n\n /** Scratch: the companion text of every cell of the current row. */\n private texts: (string | null)[] = [];\n\n /** Scratch: the property slots of the current row that lost precision. */\n private readonly precisionSlots: PropertySlot[] = [];\n\n /**\n * Create a session.\n * @param sink - the sink\n * @param report - the report\n * @param common - the resolved common options\n * @param options - the resolved format options\n */\n constructor(\n sink: GraphSink,\n report: ImportReportBuilder,\n common: ResolvedImportOptions,\n options: ResolvedNeo4jOptions,\n ) {\n this.sink = sink;\n this.report = report;\n this.common = common;\n this.options = options;\n this.coercer = new IdCoercer(common.ids);\n this.direction = new DirectionResolver(sink, report, common.onMixedDirection);\n }\n\n /**\n * Read every input.\n * @param inputs - the inputs in reading order\n */\n async run(inputs: readonly ImportInput[]): Promise<void> {\n const progress = new ProgressTracker(this.common.onProgress, inputs);\n for (const input of inputs) {\n await this.readInput(input, { ...progress.optionsFor(this.common.signal), encoding: this.common.encoding });\n progress.finishInput();\n }\n if (this.ignoredColumns > 0) {\n this.report.loss(\n IGNORED_COLUMNS_LOSS,\n `${this.ignoredColumns} :IGNORE column(s) were skipped as the header instructs`,\n null,\n this.ignoredColumns,\n );\n }\n }\n\n /**\n * Read one input: a header row, then data rows until the next header row.\n * @param input - the input\n * @param readOptions - cancellation and progress\n */\n private async readInput(input: ImportInput, readOptions: ReadOptions): Promise<void> {\n const reader = new RecordReader(input, this.report, this.options.syntax, readOptions);\n let section: Section | null = null;\n let sinceCheck = 0;\n for await (const count of reader) {\n if (section === null || isHeaderRecord(reader.cells, count)) {\n section = this.declareSection(reader, count);\n continue;\n }\n if (section.kind === \"node\") {\n this.nodeRow(section, reader, count);\n } else {\n this.relationshipRow(section, reader, count);\n }\n if (++sinceCheck >= ABORT_CHECK_INTERVAL) {\n sinceCheck = 0;\n throwIfAborted(readOptions.signal);\n }\n }\n if (section === null) {\n this.report.fail(HEADER_CODE, \"the input has no header row\", { line: 1 });\n }\n }\n\n /**\n * Interpret a header row: parse every cell, check the section shape, declare its columns.\n * @param reader - the reader positioned on the header\n * @param count - the number of header cells\n * @returns the section\n */\n private declareSection(reader: RecordReader, count: number): Section {\n const { line } = reader;\n const fields: HeaderField[] = [];\n try {\n for (let i = 0; i < count; i++) {\n fields.push(parseHeaderField(reader.cells[i]));\n }\n const kinds = new Map<FieldKind, number[]>();\n fields.forEach((field, i) => {\n const list = kinds.get(field.kind);\n if (list === undefined) {\n kinds.set(field.kind, [i]);\n } else {\n list.push(i);\n }\n });\n const ids = kinds.get(\"ID\") ?? [];\n const starts = kinds.get(\"START_ID\") ?? [];\n const ends = kinds.get(\"END_ID\") ?? [];\n const isNode = ids.length > 0;\n const isRelationship = starts.length > 0 || ends.length > 0;\n if (isNode && isRelationship) {\n throw headerError(\"a header mixes :ID with :START_ID / :END_ID\");\n }\n if (!isNode && !isRelationship) {\n throw headerError(\n \"a header needs an :ID column (nodes) or :START_ID and :END_ID columns (relationships)\",\n );\n }\n checkPropertyNames(fields);\n this.ignoredColumns += (kinds.get(\"IGNORE\") ?? []).length;\n if (isNode) {\n if (ids.length > 1) {\n throw headerError(\"a node header has more than one :ID column\");\n }\n if (kinds.has(\"TYPE\")) {\n throw headerError(\"a node header cannot have a :TYPE column\");\n }\n return this.declareNodeSection(fields, ids[0], kinds.get(\"LABEL\") ?? [], line);\n }\n if (starts.length !== 1 || ends.length !== 1) {\n throw headerError(\"a relationship header needs exactly one :START_ID and one :END_ID column\");\n }\n if (kinds.has(\"LABEL\")) {\n throw headerError(\"a relationship header cannot have a :LABEL column\");\n }\n const types = kinds.get(\"TYPE\") ?? [];\n if (types.length > 1) {\n throw headerError(\"a relationship header has more than one :TYPE column\");\n }\n return this.declareRelationshipSection(\n fields,\n starts[0],\n ends[0],\n types.length === 1 ? types[0] : -1,\n line,\n );\n } catch (err) {\n if (err instanceof GraphFormatError && !(err instanceof ImportError)) {\n this.report.fail(HEADER_CODE, `line ${line}: ${err.message}`, { line }, { cause: err.code });\n }\n throw err;\n }\n }\n\n /**\n * Declare the columns of a node section.\n * @param fields - the parsed header\n * @param idCell - the `:ID` cell\n * @param labelCells - the `:LABEL` cells\n * @param line - the header line\n * @returns the section\n */\n private declareNodeSection(\n fields: readonly HeaderField[],\n idCell: number,\n labelCells: readonly number[],\n line: number,\n ): NodeSection {\n const idField = fields[idCell];\n const extraLabels: string[] = [];\n for (const field of fields) {\n for (const [key, value] of field.options) {\n if (key === \"label\" && field.kind === \"ID\") {\n extraLabels.push(value);\n } else {\n this.report.warning(\n \"unsupported\",\n HEADER_OPTION_CODE,\n `header option ${key}:${value} of \"${field.text}\" is ignored`,\n { line, element: field.text },\n );\n }\n }\n }\n if (labelCells.length > 0 || extraLabels.length > 0) {\n this.ensureLabels();\n }\n if (idField.space !== null) {\n this.ensureIdSpace();\n }\n let idHandle: ColumnHandle = INVALID_INDEX as ColumnHandle;\n if (idField.name.length > 0) {\n idHandle = this.declareProperty(\n \"node\",\n { ...idField, type: null },\n idCell,\n { origin: { format: NEO4J, id: idField.name, title: null, type: \"ID\", namespace: idField.space } },\n line,\n ).handle;\n }\n const properties = this.declareProperties(\"node\", fields, line, null);\n return {\n kind: \"node\",\n width: fields.length,\n idCell,\n idHandle,\n space: idField.space,\n spaceCode: this.registry.codeOf(idField.space),\n labelCells,\n extraLabels,\n properties,\n };\n }\n\n /**\n * Declare the columns of a relationship section.\n * @param fields - the parsed header\n * @param startCell - the `:START_ID` cell\n * @param endCell - the `:END_ID` cell\n * @param typeCell - the `:TYPE` cell, or -1\n * @param line - the header line\n * @returns the section\n */\n private declareRelationshipSection(\n fields: readonly HeaderField[],\n startCell: number,\n endCell: number,\n typeCell: number,\n line: number,\n ): RelationshipSection {\n for (const field of fields) {\n for (const [key, value] of field.options) {\n this.report.warning(\n \"unsupported\",\n HEADER_OPTION_CODE,\n `header option ${key}:${value} of \"${field.text}\" is ignored`,\n { line, element: field.text },\n );\n }\n }\n if (typeCell >= 0) {\n this.ensureType();\n }\n const { weightFrom } = this.common;\n let weightCell = -1;\n if (weightFrom !== null) {\n weightCell = fields.findIndex((field) => field.kind === \"PROPERTY\" && field.name === weightFrom);\n }\n const properties = this.declareProperties(\"edge\", fields, line, weightCell);\n const { space: startSpace } = fields[startCell];\n const { space: endSpace } = fields[endCell];\n return {\n kind: \"relationship\",\n width: fields.length,\n startCell,\n endCell,\n startSpace,\n endSpace,\n startSpaceCode: startSpace === null ? 0 : this.registry.codeOf(startSpace),\n endSpaceCode: endSpace === null ? 0 : this.registry.codeOf(endSpace),\n typeCell,\n weightCell,\n properties,\n };\n }\n\n /**\n * Declare every PROPERTY field of a header.\n * @param domain - node or edge\n * @param fields - the parsed header\n * @param line - the header line\n * @param skipCell - a cell to leave undeclared (the weight), or null\n * @returns the property slots\n */\n private declareProperties(\n domain: \"node\" | \"edge\",\n fields: readonly HeaderField[],\n line: number,\n skipCell: number | null,\n ): PropertySlot[] {\n const slots: PropertySlot[] = [];\n fields.forEach((field, cell) => {\n if (field.kind !== \"PROPERTY\" || cell === skipCell) {\n return;\n }\n slots.push(this.declareProperty(domain, field, cell, {}, line));\n });\n const width = fields.length;\n if (this.values.length < width) {\n this.values = new Array<unknown>(width);\n this.texts = new Array<string | null>(width);\n }\n return slots;\n }\n\n /**\n * Declare one property column on the sink: the same name and shape again shares the column;\n * a different shape under the same name is renamed `<name>#<name>` (design section 5.6).\n * @param domain - node or edge\n * @param field - the header field\n * @param cell - the field's cell index\n * @param patch - declaration fields to override (the id property's origin)\n * @param line - the header line\n * @returns the slot\n */\n private declareProperty(\n domain: \"node\" | \"edge\",\n field: HeaderField,\n cell: number,\n patch: Partial<ColumnDecl>,\n line: number,\n ): PropertySlot {\n const { sink, report } = this;\n const { listSyntax } = this.options;\n const input: AttributeDeclarationInput = {\n format: NEO4J,\n id: field.name,\n title: null,\n type: field.type,\n namespace: null,\n listSyntax,\n long: this.common.long,\n };\n let declared: DeclaredAttribute = declareAttribute(input);\n let decl: ColumnDecl = { ...declared.decl, ...patch };\n let handle: ColumnHandle;\n try {\n handle = declareOn(sink, domain, decl);\n } catch (err) {\n if (!(err instanceof GraphFormatError) || err.code !== \"E_COLUMN_EXISTS\") {\n throw err;\n }\n declared = declareAttribute({ ...input, taken: takenIn(sink, domain) });\n decl = { ...declared.decl, ...patch, name: declared.decl.name };\n handle = declareOn(sink, domain, decl);\n }\n for (const issue of declared.issues) {\n report.warning(issue.category, issue.code, issue.message, { line, element: field.text });\n }\n return {\n cell,\n name: decl.name,\n handle,\n spec: declared.spec,\n companionDecl: declared.companion,\n companion: INVALID_INDEX as ColumnHandle,\n };\n }\n\n /** Declare (or adopt) the labels column. */\n private ensureLabels(): void {\n if (this.labelsHandle === INVALID_INDEX) {\n this.labelsHandle = this.declareReserved(\"node\", LABELS_DECL);\n }\n }\n\n /** Declare (or adopt) the relationship type column. */\n private ensureType(): void {\n if (this.typeHandle === INVALID_INDEX) {\n this.typeHandle = this.declareReserved(\"edge\", TYPE_DECL);\n }\n }\n\n /** Declare (or adopt) the id space column. */\n private ensureIdSpace(): void {\n if (this.idSpaceHandle === INVALID_INDEX) {\n this.idSpaceHandle = this.declareReserved(\"node\", ID_SPACE_DECL);\n this.originalIdHandle = this.declareReserved(\"node\", ORIGINAL_ID_DECL);\n }\n }\n\n /**\n * Declare a reserved column: the same shape again shares it; a name taken by another shape is\n * renamed `<name>#<origin.id>` and reported; a role the sink already holds elsewhere is dropped\n * and reported.\n * @param domain - node or edge\n * @param decl - the reserved declaration\n * @returns the handle\n */\n private declareReserved(domain: \"node\" | \"edge\", decl: ColumnDecl): ColumnHandle {\n const { sink, report } = this;\n let current = decl;\n for (;;) {\n try {\n return declareOn(sink, domain, current);\n } catch (err) {\n if (!(err instanceof GraphFormatError)) {\n throw err;\n }\n if (err.code === \"E_COLUMN_EXISTS\") {\n const name = uniqueColumnName(current.name, current.origin?.id ?? null, takenIn(sink, domain));\n report.warning(\n \"coercion\",\n RENAMED_CODE,\n `column \"${current.name}\" renamed to \"${name}\": the name was taken`,\n { element: current.name },\n );\n current = { ...current, name };\n } else if (err.code === \"E_DUPLICATE_ROLE\") {\n report.warning(\n \"coercion\",\n ROLE_TAKEN_CODE,\n `column \"${current.name}\" declared without role \"${String(current.role)}\": the sink already holds that role`,\n { element: current.name },\n );\n const { role: _role, ...withoutRole } = current;\n current = withoutRole;\n } else {\n throw err;\n }\n }\n }\n }\n\n /**\n * Push one node row.\n * @param section - the section\n * @param reader - the reader positioned on the row\n * @param count - the row's cell count\n */\n private nodeRow(section: NodeSection, reader: RecordReader, count: number): void {\n const { sink, report } = this;\n const { cells, quoted, line } = reader;\n if (count !== section.width) {\n report.error(\n \"validation-error\",\n COLUMN_COUNT_CODE,\n `row has ${count} cell(s) but the header has ${section.width}`,\n { line },\n );\n report.counts.skippedNodes++;\n return;\n }\n const idText = cells[section.idCell];\n if (idText.length === 0 && !quoted[section.idCell]) {\n // a quoted empty cell is the id \"\" (neo4j-admin: an empty quoted field is an empty string)\n report.error(\"missing-value\", MISSING_ID_CODE, \"empty :ID cell\", { line });\n report.counts.skippedNodes++;\n return;\n }\n const coerced = this.coerceId(idText, line);\n if (coerced === null || !this.parseProperties(section.properties, cells, quoted, line, idText)) {\n report.counts.skippedNodes++;\n return;\n }\n const id = qualify(coerced, section.space);\n let labels: string[] | undefined;\n if (section.labelCells.length > 0 || section.extraLabels.length > 0) {\n labels = this.labelsOf(section, cells, quoted);\n }\n const index = sink.addNode(id);\n const status = this.registry.declare(index, section.spaceCode);\n if (status === \"collision\") {\n report.error(\n \"validation-error\",\n ID_SPACE_COLLISION_CODE,\n `node ${idText} is declared in id space ${section.space ?? \"(none)\"} and in another id space; the core has one id space and this row is skipped`,\n { line, element: idText },\n );\n report.counts.skippedNodes++;\n return;\n }\n if (status === \"duplicate\") {\n report.warning(\n \"merged\",\n DUPLICATE_NODE_CODE,\n `node ${idText} is declared twice; the later properties win`,\n {\n line,\n element: idText,\n },\n );\n }\n if (section.idHandle !== INVALID_INDEX) {\n sink.setNodeValue(section.idHandle, index, idText);\n }\n if (section.space !== null) {\n sink.setNodeValue(this.idSpaceHandle, index, section.space);\n sink.setNodeValue(this.originalIdHandle, index, idText);\n }\n if (labels !== undefined) {\n sink.setNodeValue(this.labelsHandle, index, labels);\n }\n this.writeProperties(\"node\", section.properties, index);\n this.reportPrecision(line, idText);\n report.counts.nodes++;\n }\n\n /**\n * Push one relationship row.\n * @param section - the section\n * @param reader - the reader positioned on the row\n * @param count - the row's cell count\n */\n private relationshipRow(section: RelationshipSection, reader: RecordReader, count: number): void {\n const { sink, report } = this;\n const { cells, quoted, line } = reader;\n if (!this.headerSet) {\n // a Neo4j file is directed by definition (\"all relationships have a direction\"); the sink's\n // direction is set once, before the first relationship, so a node-only file leaves it alone\n this.headerSet = true;\n this.direction.setHeader(true, { line });\n }\n if (count !== section.width) {\n report.error(\n \"validation-error\",\n COLUMN_COUNT_CODE,\n `row has ${count} cell(s) but the header has ${section.width}`,\n { line },\n );\n report.counts.skippedEdges++;\n return;\n }\n const startText = cells[section.startCell];\n const endText = cells[section.endCell];\n const startMissing = startText.length === 0 && !quoted[section.startCell];\n if (startMissing || (endText.length === 0 && !quoted[section.endCell])) {\n report.error(\n \"missing-value\",\n MISSING_ENDPOINT_CODE,\n `empty ${startMissing ? \":START_ID\" : \":END_ID\"} cell`,\n {\n line,\n },\n );\n report.counts.skippedEdges++;\n return;\n }\n const element = `${startText}->${endText}`;\n const start = this.coerceId(startText, line);\n const end = start === null ? null : this.coerceId(endText, line);\n if (start === null || end === null) {\n report.counts.skippedEdges++;\n return;\n }\n const source = qualify(start, section.startSpace);\n const target = qualify(end, section.endSpace);\n let wrongSpace: string | null = null;\n if (this.wrongSpace(source, section.startSpaceCode)) {\n wrongSpace = startText;\n } else if (this.wrongSpace(target, section.endSpaceCode)) {\n wrongSpace = endText;\n }\n if (wrongSpace !== null) {\n report.error(\n \"missing-value\",\n ENDPOINT_SPACE_CODE,\n `endpoint ${wrongSpace} is not a node of its declared id space (a node of another id space has that id); the row is skipped`,\n { line, element },\n );\n report.counts.skippedEdges++;\n return;\n }\n let weight: number | undefined;\n if (section.weightCell >= 0) {\n try {\n weight = parseWeightText(cells[section.weightCell]);\n } catch (err) {\n report.recordError(err, { line, element });\n report.counts.skippedEdges++;\n return;\n }\n }\n if (!this.parseProperties(section.properties, cells, quoted, line, element)) {\n report.counts.skippedEdges++;\n return;\n }\n let edge: number;\n try {\n edge = this.direction.addEdge(source, target, \"directed\", weight, { line, element });\n } catch (err) {\n report.recordError(err, { line, element });\n report.counts.skippedEdges++;\n return;\n }\n if (section.typeCell >= 0) {\n const type = cells[section.typeCell];\n if (type.length > 0) {\n sink.setEdgeValue(this.typeHandle, edge, type);\n }\n }\n this.writeProperties(\"edge\", section.properties, edge);\n this.reportPrecision(line, element);\n report.counts.edges++;\n }\n\n /**\n * Whether a qualified endpoint id belongs to a node a node row declared in another id space than\n * the endpoint's header declares (an unspaced node whose id text is `Space:id`). An endpoint\n * without a declared space, or a node no row declared yet, is looked up by id alone.\n * @param id - the endpoint id\n * @param spaceCode - the endpoint's space code, 0 for none\n * @returns true when the endpoint resolves to a node of another space\n */\n private wrongSpace(id: NodeId, spaceCode: number): boolean {\n if (spaceCode === 0) {\n return false;\n }\n const index = this.sink.indexOf(id);\n if (index < 0) {\n return false;\n }\n const declared = this.registry.codeAt(index);\n return declared !== 0 && declared !== spaceCode;\n }\n\n /**\n * Coerce an id cell, reporting a merge under `ids: \"number\"` and an invalid id as an error.\n * @param text - the cell\n * @param line - the row's line\n * @returns the id, or null when the cell was rejected (the error is recorded)\n */\n private coerceId(text: string, line: number): NodeId | null {\n const { coercer, report } = this;\n let id: NodeId;\n try {\n id = coercer.text(text);\n } catch (err) {\n report.recordError(err, { line, element: text });\n return null;\n }\n const merge = coercer.lastMerge;\n if (merge !== null) {\n report.warning(\n \"coercion\",\n ID_MERGED_CODE,\n `id \"${merge.text}\" merged with \"${merge.previousText}\" as ${merge.id} under ids: \"number\"`,\n { line, element: text },\n );\n }\n return id;\n }\n\n /**\n * Parse the property cells of a row into the scratch arrays.\n * @param slots - the section's property slots\n * @param cells - the row's cells\n * @param quoted - whether each cell was quoted\n * @param line - the row's line\n * @param element - the row's element name for issues\n * @returns true when every cell parsed; false after recording the first error\n */\n private parseProperties(\n slots: readonly PropertySlot[],\n cells: readonly string[],\n quoted: readonly boolean[],\n line: number,\n element: string,\n ): boolean {\n const { values, texts, precisionSlots } = this;\n precisionSlots.length = 0;\n for (const slot of slots) {\n const text = cells[slot.cell];\n texts[slot.cell] = null;\n if (text.length === 0) {\n values[slot.cell] = quoted[slot.cell] ? emptyValue(slot.spec) : undefined;\n continue;\n }\n const { spec } = slot;\n try {\n if (spec.temporal !== null && !spec.list) {\n const parsed = parseDeclaredTemporal(text, spec);\n values[slot.cell] = parsed.value;\n texts[slot.cell] = parsed.text;\n } else {\n values[slot.cell] = parseDeclaredValue(text, spec, this.options.listSyntax);\n }\n } catch (err) {\n this.report.recordError(err, { line, element: `${element} ${slot.name}` });\n return false;\n }\n if (spec.precision && losesPrecision(spec, text)) {\n precisionSlots.push(slot);\n }\n }\n return true;\n }\n\n /**\n * Write the parsed property values of a row.\n * @param domain - node or edge\n * @param slots - the section's property slots\n * @param row - the node or edge index\n */\n private writeProperties(domain: \"node\" | \"edge\", slots: readonly PropertySlot[], row: number): void {\n const { sink, values, texts } = this;\n for (const slot of slots) {\n const value = values[slot.cell];\n if (value === undefined) {\n continue;\n }\n const text = texts[slot.cell];\n if (text !== null && slot.companion === INVALID_INDEX && slot.companionDecl !== null) {\n slot.companion = declareCompanion(sink, domain, slot.companionDecl);\n }\n if (domain === \"node\") {\n sink.setNodeValue(slot.handle, row, value);\n if (text !== null) {\n sink.setNodeValue(slot.companion, row, text);\n }\n } else {\n sink.setEdgeValue(slot.handle, row, value);\n if (text !== null) {\n sink.setEdgeValue(slot.companion, row, text);\n }\n }\n }\n }\n\n /**\n * Report the precision losses of the row just accepted.\n * @param line - the row's line\n * @param element - the row's element name\n */\n private reportPrecision(line: number, element: string): void {\n for (const slot of this.precisionSlots) {\n this.report.warning(\n \"precision\",\n PRECISION_CODE,\n `long value of \"${slot.name}\" is beyond 2^53 and was stored as the nearest f64`,\n { line, element },\n );\n }\n this.precisionSlots.length = 0;\n }\n\n /**\n * The labels of a node row: every `:LABEL` cell split by the array delimiter (empty items\n * dropped), plus the header's `{label:...}` options.\n * @param section - the section\n * @param cells - the row's cells\n * @param quoted - whether each cell was quoted\n * @returns the labels, or undefined when every label cell is unset and no extra label exists\n */\n private labelsOf(section: NodeSection, cells: readonly string[], quoted: readonly boolean[]): string[] | undefined {\n let labels: string[] | undefined;\n for (const cell of section.labelCells) {\n const text = cells[cell];\n if (text.length === 0 && !quoted[cell]) {\n continue;\n }\n if (labels === undefined) {\n labels = [];\n }\n for (const item of splitListText(text, this.options.listSyntax)) {\n if (item.length > 0) {\n labels.push(item);\n }\n }\n }\n if (section.extraLabels.length > 0) {\n if (labels === undefined) {\n labels = [];\n }\n labels.push(...section.extraLabels);\n }\n return labels;\n }\n}\n\n/**\n * The id a node of an id space is stored under: `Space:id`, so the same id in two spaces stays two\n * nodes (the core has one id space).\n * @param id - the coerced id cell\n * @param space - the id space, or null\n * @returns the id unchanged without a space, else the string `Space:id`\n */\nfunction qualify(id: NodeId, space: string | null): NodeId {\n return space === null ? id : `${space}:${String(id)}`;\n}\n\n/**\n * The value of a quoted empty cell: an empty string for a string-kind property, an empty list for\n * a list property, unset for anything else (neo4j-admin's default `--ignore-empty-strings=false`).\n * @param spec - the property's declared type\n * @returns the value, or undefined for unset\n */\nfunction emptyValue(spec: DeclaredTypeSpec): unknown {\n if (spec.list) {\n return [];\n }\n if (spec.kind === \"string\" || spec.kind === \"duration\") {\n return \"\";\n }\n return undefined;\n}\n\n/**\n * Check that no two PROPERTY (or stored-id) fields of one header share a name.\n * @param fields - the parsed header\n */\nfunction checkPropertyNames(fields: readonly HeaderField[]): void {\n const seen = new Set<string>();\n for (const field of fields) {\n if (field.name.length === 0 || field.kind === \"IGNORE\") {\n continue;\n }\n if (seen.has(field.name)) {\n throw headerError(`property \"${field.name}\" is declared twice`);\n }\n seen.add(field.name);\n }\n}\n\n/**\n * The error of a malformed section header.\n * @param reason - why\n * @returns the error\n */\nfunction headerError(reason: string): GraphFormatError {\n return new GraphFormatError(\"E_UNSUPPORTED\", reason, { reason: \"header\" });\n}\n\n/**\n * Confidence that a head of bytes is a neo4j-admin CSV: the first line holds an `:ID`,\n * `:START_ID` or `:END_ID` header cell.\n * @param head - the first bytes of the input\n * @returns 0.95 for a Neo4j header, 0 otherwise\n */\nfunction sniffNeo4j(head: Uint8Array): number {\n const text = new TextDecoder(\"utf-8\", { fatal: false, ignoreBOM: false }).decode(head);\n const end = text.search(/[\\r\\n]/);\n const first = end < 0 ? text : text.slice(0, end);\n const cells = first.split(/[,;|\\t]/);\n return isHeaderRecord(cells, cells.length) ? 0.95 : 0;\n}\n\n/** The Neo4j importer. */\nexport const neo4jImporter: GraphImporter<Neo4jImportOptions> = Object.freeze({\n format: NEO4J,\n extensions: Object.freeze([\".csv\", \".tsv\"]),\n mimeTypes: Object.freeze([\"text/csv\", \"text/tab-separated-values\"]),\n sniff: sniffNeo4j,\n /**\n * Read one or more neo4j-admin CSV inputs into the sink.\n * @param input - the primary input (a node table, a relationship table, or sections of both)\n * @param sink - the sink\n * @param options - format-specific and common options\n * @returns the report; ImportError beyond the error limit or on a malformed header\n */\n async import(\n input: ImportInput,\n sink: GraphSink,\n options?: Neo4jImportOptions & CommonImportOptions,\n ): Promise<ImportReport> {\n const common = resolveImportOptions(options, { ids: \"canonical\", defaultDirected: true, weightFrom: \"weight\" });\n const format = resolveNeo4jOptions(options);\n const report = new ImportReportBuilder(NEO4J, common.errorLimit);\n reportSinkOptions(sink, options, report);\n // nodeIdFrom and defaultDirected are among the reported options: Neo4j ids are the :ID\n // column and every relationship is directed\n reportUnusedOptions(options, report, USED_OPTIONS);\n const session = new Neo4jImportSession(sink, report, common, format);\n await session.run([input, ...format.nodes, ...format.relationships]);\n throwIfAborted(common.signal);\n return report.finish();\n },\n});\n","/**\n * The Neo4j exporter (design section 8.5, research note 07 section 9): writes a snapshot as\n * neo4j-admin import CSV -- node sections with `:ID`, `:LABEL` and typed property columns,\n * relationship sections with `:START_ID`, `:END_ID`, `:TYPE`, the weight and typed property\n * columns -- as one document (node sections first) or as the node or relationship part alone.\n *\n * What a property graph cannot carry is reported by check() before anything is written: an\n * undirected snapshot (every edge becomes a directed relationship), expanded mixed direction (per\n * `onMixedDirection`), edge ids, hierarchy, element lifetimes, graph attributes, nested json (points\n * excepted), multi-component columns (flattened to arrays), u32 / u8 columns (written as `long` /\n * `int`), ids whose text would re-import as another type or collide, and list items that contain\n * the array delimiter.\n *\n * Column headers restore the declared Neo4j type from `origin.type` when it is compatible with the\n * column's dtype (`int`, `byte`, `short`, `long`, `char`, `duration`, the temporal types, `point`,\n * `type[]`), and derive it from the dtype otherwise. Temporal columns write their `.text`\n * companion when set and the canonical ISO form otherwise. Nodes are grouped into sections by\n * (id space, stored-id column) in index order, so a re-import restores the same node order;\n * relationships likewise by (start space, end space). A node of an id space is written under its\n * `originalId` value (the id text the importer stored it under as `Space:id`), so a round trip\n * reproduces the source file.\n */\n\nimport {\n type Column,\n type ColumnMeta,\n type Dtype,\n GraphFormatError,\n type GraphSnapshot,\n type NodeId,\n type ScalarDtype,\n} from \"@graphty/graph-format\";\n\nimport { ID_TEXT_COLLISION_CODE, ID_TEXT_TYPE_CODE } from \"../../common/codes.js\";\nimport { type DeclaredTypeSpec, mapDeclaredType } from \"../../common/declared-types.js\";\nimport { type PairFolding, pairFolding } from \"../../common/direction.js\";\nimport { quoteCsvCell } from \"../../common/escape.js\";\nimport { capabilities, checkCapabilities, LOSS } from \"../../common/export.js\";\nimport { formatF32, formatF64, formatInteger } from \"../../common/format.js\";\nimport { isCanonicalIntegerText } from \"../../common/ids.js\";\nimport { type ResolvedExportOptions, resolveExportOptions } from \"../../common/options.js\";\nimport { formatTemporal, type TemporalKind } from \"../../common/temporal.js\";\nimport { type ExplicitWeights, explicitWeights } from \"../../common/weights.js\";\nimport { encodeChunks, joinText } from \"../../common/writer.js\";\nimport { type CommonExportOptions, type ExportCapabilities, type GraphExporter, type LossNote } from \"../../types.js\";\nimport { checkRecordSyntax, type RecordSyntax } from \"../csv/records.js\";\nimport { formatHeaderField } from \"./header.js\";\nimport { ID_SPACE_COLUMN, LABELS_COLUMN, TYPE_COLUMN } from \"./importer.js\";\n\n/** The format-specific options of the Neo4j exporter. */\nexport interface Neo4jExportOptions {\n /** Which tables to write: both (node sections first; default), the node sections or the relationship sections. */\n part?: \"all\" | \"nodes\" | \"relationships\" | undefined;\n /** The field delimiter; one character; \",\" by default. */\n delimiter?: string | undefined;\n /** The array delimiter of list values and `:LABEL` cells; \";\" by default. */\n arrayDelimiter?: \";\" | \",\" | \"|\" | undefined;\n /** The quote character; one character; a double quote by default. */\n quote?: string | undefined;\n /**\n * The property that receives explicit edge weights (`<name>:double`); \"weight\" by default (the\n * importer's `weightFrom` default); null writes no weights.\n */\n weightColumn?: string | null | undefined;\n /**\n * The property name of the `:ID` column for nodes that have no stored-id column of their own\n * (`<name>:ID`); null (default) writes a bare `:ID`.\n */\n idColumn?: string | null | undefined;\n}\n\n/** Loss code: undirected edges (an undirected snapshot, or the folded pairs of a mixed one) written as directed relationships. */\nexport const UNDIRECTED_LOSS = \"W_NEO4J_UNDIRECTED_AS_DIRECTED\";\n\n/** Loss code: node ids whose text re-imports as another type under the canonical id rule. */\nexport const ID_TEXT_TYPE_LOSS = ID_TEXT_TYPE_CODE;\n\n/** Loss code: two node ids share one text; export() throws E_INVALID_ID. */\nexport const ID_TEXT_COLLISION_LOSS = ID_TEXT_COLLISION_CODE;\n\n/** Loss code: an edge property column already uses the weight column name; export() throws E_COLUMN_EXISTS. */\nexport const WEIGHT_COLUMN_TAKEN_LOSS = \"E_NEO4J_WEIGHT_COLUMN_TAKEN\";\n\n/** Loss code: a node property column already uses the idColumn name; export() throws E_COLUMN_EXISTS. */\nexport const ID_COLUMN_TAKEN_LOSS = \"E_NEO4J_ID_COLUMN_TAKEN\";\n\n/** Loss code: a node has more than one stored-id column set; only the first is written. */\nexport const MULTIPLE_ID_PROPERTIES_LOSS = \"W_NEO4J_MULTIPLE_ID_PROPERTIES\";\n\n/** Loss code: a declared integer type holds non-integral values and is written as double. */\nexport const DECLARED_TYPE_CHANGED_LOSS = \"W_NEO4J_DECLARED_TYPE_CHANGED\";\n\n/** Loss code: a list item contains the array delimiter, which Neo4j cannot escape. */\nexport const ARRAY_DELIMITER_LOSS = \"W_NEO4J_ARRAY_DELIMITER\";\n\n/** The roles Neo4j has a slot for: `:TYPE`, `:LABEL` and the id space of `:ID(Space)`. */\nconst SLOT_ROLES: ReadonlySet<string> = new Set([\"kind\", \"labels\", \"idSpace\"]);\n\nconst NEO4J = \"neo4j\";\nconst ID_TYPE = \"ID\";\n\n/** The weight property the importer reads by default (its weightFrom default). */\nconst DEFAULT_WEIGHT_COLUMN = \"weight\";\n\n/** The names the importer gives the slot columns, for the name-change notes. */\nconst ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({\n kind: TYPE_COLUMN,\n labels: LABELS_COLUMN,\n idSpace: ID_SPACE_COLUMN,\n});\n\n/**\n * The capabilities of neo4j-admin CSV (research note 07 section 9): declared scalar types and\n * arrays; a dict column reads back as string (the header has no enumeration type); a position or\n * visual column is written as a plain property (a point for a 2- or 3-component position) and\n * reads back without its role.\n */\nexport const NEO4J_CAPABILITIES: ExportCapabilities = capabilities({\n mixedDirection: false,\n multiEdges: true,\n selfLoops: true,\n edgeIds: \"none\",\n idCharset: \"any\",\n dtypes: [\"f32\", \"f64\", \"i32\", \"bool\", \"string\"],\n components: false,\n lists: true,\n json: false,\n defaults: false,\n options: false,\n hierarchy: false,\n temporal: \"none\",\n graphAttributes: false,\n positions: false,\n viz: false,\n});\n\n/** Roles whose columns are never written as properties. */\nconst SKIPPED_ROLES: ReadonlySet<string> = new Set([\n \"directed\",\n \"pair\",\n \"mutual\",\n \"weight\",\n \"timeText\",\n \"originalId\",\n \"parent\",\n \"parents\",\n \"start\",\n \"end\",\n \"timestamp\",\n \"timestamps\",\n \"spells\",\n \"open\",\n \"spellsOpen\",\n]);\n\n/** Notes about relationships only, dropped when only nodes are written. */\nconst EDGE_NOTE_CODES: ReadonlySet<string> = new Set([\n LOSS.MIXED_DIRECTION,\n LOSS.MIXED_DIRECTION_ERROR,\n LOSS.MULTI_EDGES,\n LOSS.SELF_LOOPS,\n LOSS.EDGE_IDS_GENERATED,\n LOSS.EDGE_IDS_DROPPED,\n UNDIRECTED_LOSS,\n WEIGHT_COLUMN_TAKEN_LOSS,\n]);\n\n/** Notes about nodes only, dropped when only relationships are written. */\nconst NODE_NOTE_CODES: ReadonlySet<string> = new Set([\n LOSS.ID_MANGLED,\n LOSS.ID_CHARSET,\n LOSS.ID_RENUMBERED,\n ID_TEXT_TYPE_LOSS,\n ID_COLUMN_TAKEN_LOSS,\n MULTIPLE_ID_PROPERTIES_LOSS,\n]);\n\nconst ARRAY_SYNTAXES: ReadonlySet<string> = new Set([\";\", \",\", \"|\"]);\nconst PARTS: ReadonlySet<string> = new Set([\"all\", \"nodes\", \"relationships\"]);\n\n/** The resolved format options. */\ninterface ResolvedNeo4jExportOptions {\n readonly part: \"all\" | \"nodes\" | \"relationships\";\n readonly syntax: RecordSyntax & { readonly delimiter: string };\n readonly arrayDelimiter: string;\n readonly weightColumn: string | null;\n readonly idColumn: string | null;\n}\n\n/** How one cell's value is written. */\ntype CellKind = \"integer\" | \"float\" | \"double\" | \"boolean\" | \"string\" | \"temporal\" | \"point\" | \"json\";\n\n/** The Neo4j type and cell kind of one scalar (a column or a list item). */\ninterface ScalarPlan {\n readonly type: string;\n readonly kind: CellKind;\n readonly temporal: TemporalKind | null;\n}\n\n/** One property column as it will be written. */\ninterface ColumnPlan {\n readonly column: Column;\n readonly header: string;\n readonly scalar: ScalarPlan;\n /** A list (or flattened vector) column: items are joined by the array delimiter. */\n readonly list: boolean;\n /** The companion text column of a temporal column, or null. */\n readonly companion: Column | null;\n}\n\n/**\n * Resolve the format options.\n * @param options - the caller's options\n * @returns the resolved options; E_UNSUPPORTED for an invalid value\n */\nfunction resolveNeo4jExportOptions(options: Neo4jExportOptions | undefined): ResolvedNeo4jExportOptions {\n const o: Neo4jExportOptions = options ?? {};\n const part = o.part ?? \"all\";\n if (!PARTS.has(part)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option part: ${JSON.stringify(part)} is not \"all\", \"nodes\" or \"relationships\"`,\n {\n option: \"part\",\n found: part,\n },\n );\n }\n const arrayDelimiter = o.arrayDelimiter ?? \";\";\n if (!ARRAY_SYNTAXES.has(arrayDelimiter)) {\n throw new GraphFormatError(\n \"E_UNSUPPORTED\",\n `option arrayDelimiter: ${JSON.stringify(arrayDelimiter)} is not one of \";\", \",\", \"|\"`,\n { option: \"arrayDelimiter\", found: arrayDelimiter },\n );\n }\n const delimiter = o.delimiter ?? \",\";\n const syntax = { ...checkRecordSyntax({ delimiter, quote: o.quote ?? '\"' }), delimiter };\n if (syntax.delimiter === arrayDelimiter) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"options delimiter and arrayDelimiter must differ\", {\n option: \"arrayDelimiter\",\n found: arrayDelimiter,\n });\n }\n const weightColumn = o.weightColumn === undefined ? \"weight\" : o.weightColumn;\n if (weightColumn !== null && (typeof weightColumn !== \"string\" || weightColumn.length === 0)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"option weightColumn: expected a non-empty name or null\", {\n option: \"weightColumn\",\n found: weightColumn,\n });\n }\n const idColumn = o.idColumn ?? null;\n if (idColumn !== null && (typeof idColumn !== \"string\" || idColumn.length === 0)) {\n throw new GraphFormatError(\"E_UNSUPPORTED\", \"option idColumn: expected a non-empty name or null\", {\n option: \"idColumn\",\n found: idColumn,\n });\n }\n return { part, syntax, arrayDelimiter, weightColumn, idColumn };\n}\n\n/**\n * Everything check() and export() share: the column plans, the section keys, the notes and the\n * error export() throws (if any), computed once from the snapshot and the options.\n */\nclass ExportPlan {\n readonly snapshot: GraphSnapshot;\n\n readonly options: ResolvedNeo4jExportOptions;\n\n readonly common: ResolvedExportOptions;\n\n /** The notes: the generic capability notes first, then the format's own, in that order. */\n readonly notes: LossNote[] = [];\n\n /** The format's own notes, appended after the generic ones. */\n private readonly ownNotes: LossNote[] = [];\n\n /** The error export() throws because of the node sections, or null. */\n private fatalNodes: GraphFormatError | null = null;\n\n /** The error export() throws because of the relationship sections, or null. */\n private fatalEdges: GraphFormatError | null = null;\n\n /** The error export() throws whatever the part (an id text collision), or null. */\n private fatalAll: GraphFormatError | null = null;\n\n readonly nodeColumns: ColumnPlan[] = [];\n\n readonly edgeColumns: ColumnPlan[] = [];\n\n /** Stored-id node columns (`name:ID`), in declaration order. */\n readonly idColumns: Column[] = [];\n\n readonly idSpace: Column | null;\n\n /** The id text of the nodes of an id space (the importer's `originalId` column), or null. */\n readonly originalId: Column | null;\n\n readonly labels: Column | null;\n\n readonly kind: Column | null;\n\n readonly weights: ExplicitWeights | null;\n\n /** The pair folding (design section 3.6): the mirror halves of undirected pairs are not written. */\n readonly folding: PairFolding;\n\n /**\n * Build the plan.\n * @param snapshot - the snapshot\n * @param options - the resolved format options\n * @param common - the resolved common options\n */\n constructor(snapshot: GraphSnapshot, options: ResolvedNeo4jExportOptions, common: ResolvedExportOptions) {\n this.snapshot = snapshot;\n this.options = options;\n this.common = common;\n this.idSpace = snapshot.nodes.byRole(\"idSpace\");\n this.originalId = [...snapshot.nodes].find((column) => isIdText(column.meta)) ?? null;\n this.labels = snapshot.nodes.byRole(\"labels\");\n this.kind = snapshot.edges.byRole(\"kind\");\n for (const column of snapshot.nodes) {\n if (isStoredId(column.meta)) {\n this.idColumns.push(column);\n }\n }\n const generic = checkCapabilities(snapshot, NEO4J_CAPABILITIES, common, {\n roles: SLOT_ROLES,\n roleNames: ROLE_NAMES,\n temporalText: true,\n });\n this.planColumns(\"node\", snapshot.nodes, this.nodeColumns);\n this.planColumns(\"edge\", snapshot.edges, this.edgeColumns);\n this.weights = this.planWeightSource();\n this.folding = pairFolding(snapshot);\n this.checkIds();\n this.checkIdColumn();\n this.checkStoredIds();\n this.directionNotes();\n const slots = new Set([this.kind, this.labels, this.idSpace].flatMap((c) => (c === null ? [] : [c.meta.name])));\n for (const gen of generic) {\n if (gen.code === LOSS.JSON && gen.column !== null && this.writtenAsPoint(gen.column)) {\n continue;\n }\n if (gen.code === LOSS.DTYPE && gen.column !== null && slots.has(gen.column)) {\n // :TYPE, :LABEL and :ID(Space) read back as the dict / list-of-dict columns they were\n continue;\n }\n if (gen.code === LOSS.MIXED_DIRECTION_ERROR && this.fatalEdges === null) {\n this.fatalEdges = new GraphFormatError(\"E_DIRECTED\", gen.message, { reason: \"mixed direction\" });\n }\n if ((gen.code === LOSS.POSITIONS || gen.code === LOSS.VIZ) && gen.column !== null) {\n // written as a plain property (a point for a position); the role is what is lost\n this.notes.push(\n Object.freeze({\n code: gen.code,\n message: `node column \"${gen.column}\" is written as a plain property; its role is lost on re-import`,\n column: gen.column,\n count: gen.count,\n }),\n );\n continue;\n }\n this.notes.push(gen);\n }\n this.notes.push(...this.ownNotes);\n this.filterNotesByPart();\n }\n\n /**\n * The direction notes: an undirected snapshot writes every edge as a directed relationship;\n * a mixed snapshot folds its undirected pairs to one directed relationship each under\n * \"directed\" or \"undirected\" (Neo4j has no undirected relationship, so both policies write\n * the same file and the generic W_MIXED_DIRECTION note names the policy); a mutual pair is\n * written as two relationships without its mark.\n */\n private directionNotes(): void {\n const { snapshot, folding } = this;\n if (!snapshot.directed) {\n this.note(\n UNDIRECTED_LOSS,\n `the snapshot is undirected; every edge is written as a directed relationship (${snapshot.edgeCount} edge(s))`,\n null,\n snapshot.edgeCount,\n );\n } else if (this.common.onMixedDirection !== \"error\") {\n let undirected = 0;\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (!folding.folded(e) && !folding.sourceDirected(e)) {\n undirected++;\n }\n }\n if (undirected > 0) {\n this.note(\n UNDIRECTED_LOSS,\n `${undirected} undirected edge(s) are written as one directed relationship each (source to target, a pair folded to its primary); Neo4j has no undirected relationship`,\n null,\n undirected,\n );\n }\n }\n if (folding.mutualCount > 0) {\n this.note(\n LOSS.MUTUAL_EXPANDED,\n `${folding.mutualCount} mutual pair(s) are written as two directed relationships; the mutual mark is lost`,\n null,\n folding.mutualCount,\n );\n }\n }\n\n /**\n * Record a note.\n * @param code - the code\n * @param message - the message\n * @param column - the column, or null\n * @param count - the count, or null\n */\n private note(code: string, message: string, column: string | null = null, count: number | null = null): void {\n this.ownNotes.push(Object.freeze({ code, message, column, count }));\n }\n\n /**\n * Plan the property columns of one table.\n * @param domain - node or edge\n * @param table - the table\n * @param out - receives the plans in declaration order\n */\n private planColumns(domain: \"node\" | \"edge\", table: Iterable<Column>, out: ColumnPlan[]): void {\n const all = [...table];\n const names = new Set(all.map((column) => column.meta.name));\n const companionFor = new Map<string, Column>();\n const companions = new Set<Column>();\n for (const column of all) {\n const target = column.meta.extra.for;\n if (column.dtype === \"string\" && typeof target === \"string\" && names.has(target)) {\n companionFor.set(target, column);\n companions.add(column);\n }\n }\n for (const column of all) {\n const { meta } = column;\n const { role } = meta;\n if (companions.has(column) || (role !== null && SKIPPED_ROLES.has(role))) {\n continue;\n }\n if (\n domain === \"node\" &&\n (isStoredId(meta) || column === this.idSpace || column === this.labels || column === this.originalId)\n ) {\n continue;\n }\n if (domain === \"edge\" && (role === \"id\" || column === this.kind)) {\n continue;\n }\n out.push(this.planColumn(column, companionFor.get(meta.name) ?? null));\n }\n }\n\n /**\n * Plan one property column: its header type, cell kind and notes.\n * @param column - the column\n * @param companion - its text companion, or null\n * @returns the plan\n */\n private planColumn(column: Column, companion: Column | null): ColumnPlan {\n const { meta } = column;\n const declared = meta.origin?.type ?? null;\n const mapped = declared === null ? null : mapDeclaredType(NEO4J, declared, \"f64\");\n const label = `${meta.domain} column \"${meta.name}\"`;\n if (meta.dtype === \"list\") {\n const itemDtype = meta.itemDtype ?? \"string\";\n const compatible =\n mapped !== null && mapped.list && mapped.itemDtype === itemDtype && mapped.kind !== \"long\";\n let scalar = compatible\n ? { type: declaredScalar(declared as string), kind: kindOf(mapped), temporal: mapped.temporal }\n : defaultScalar(itemDtype);\n if (mapped !== null && mapped.list && mapped.kind === \"long\" && itemDtype === \"f64\") {\n scalar = this.integralOrDouble(column, declaredScalar(declared as string), label);\n }\n const itemComponents = meta.itemComponents ?? 1;\n if (itemComponents > 1) {\n this.note(\n LOSS.COMPONENTS,\n `${label} holds items of ${itemComponents} components; they are flattened into one array`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n this.checkArrayItems(column, scalar, label);\n return {\n column,\n header: formatHeaderField(meta.name, `${scalar.type}[]`, null),\n scalar,\n list: true,\n companion,\n };\n }\n let scalar: ScalarPlan;\n const compatible = mapped !== null && !mapped.list && mapped.dtype === meta.dtype;\n if (compatible && mapped.kind === \"long\") {\n scalar = this.integralOrDouble(column, declared as string, label);\n } else if (compatible) {\n scalar = { type: declared as string, kind: kindOf(mapped), temporal: mapped.temporal };\n } else {\n scalar = defaultScalar(meta.dtype);\n }\n // the generic check treats position and visual columns by role only; their dtype and\n // stride are checked here so the notes match those of any other column\n const visual = meta.role === \"position\" || (meta.role !== null && isVizRole(meta.role));\n if (visual && meta.dtype === \"json\" && scalar.kind !== \"point\") {\n this.note(\n LOSS.JSON,\n `${label} holds nested values; the format has no nested values`,\n meta.name,\n column.length - column.nullCount,\n );\n } else if (visual && meta.dtype !== \"json\" && !NEO4J_CAPABILITIES.dtypes.includes(meta.dtype)) {\n this.note(\n LOSS.DTYPE,\n `${label} is ${meta.dtype}; the format cannot keep that dtype`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n if (meta.components > 1) {\n if (visual) {\n this.note(\n LOSS.COMPONENTS,\n `${label} has ${meta.components} components; the format has no strides`,\n meta.name,\n column.length - column.nullCount,\n );\n }\n return {\n column,\n header: formatHeaderField(meta.name, `${scalar.type}[]`, null),\n scalar,\n list: true,\n companion,\n };\n }\n // an untyped Neo4j header (`name` alone) is a string property; restore it as written\n const untyped = declared === null && meta.origin?.format === NEO4J && meta.dtype === \"string\";\n const header = untyped ? meta.name : formatHeaderField(meta.name, scalar.type, null);\n return { column, header, scalar, list: false, companion };\n }\n\n /**\n * The plan of an f64 column declared with an integer type: kept when every set value is\n * integral, written as double (with a note) otherwise.\n * @param column - the column\n * @param declared - the declared type text\n * @param label - the column label for messages\n * @returns the scalar plan\n */\n private integralOrDouble(column: Column, declared: string, label: string): ScalarPlan {\n let integral = true;\n if (column.dtype === \"f64\") {\n for (let r = 0; r < column.length && integral; r++) {\n if (column.isSet(r) && !Number.isInteger(column.data[r])) {\n integral = false;\n }\n }\n } else if (column.dtype === \"list\" && column.child.dtype === \"f64\") {\n const { data } = column.child;\n for (let i = 0; i < data.length && integral; i++) {\n if (!Number.isInteger(data[i])) {\n integral = false;\n }\n }\n }\n if (integral) {\n return { type: declared, kind: \"integer\", temporal: null };\n }\n this.note(\n DECLARED_TYPE_CHANGED_LOSS,\n `${label} is declared ${declared} but holds non-integral values; written as double`,\n column.meta.name,\n null,\n );\n return { type: \"double\", kind: \"double\", temporal: null };\n }\n\n /**\n * Count the rows of a list column with an item containing the array delimiter.\n * @param column - the list column\n * @param scalar - the item plan\n * @param label - the column label\n */\n private checkArrayItems(column: Column, scalar: ScalarPlan, label: string): void {\n if (\n column.dtype !== \"list\" ||\n (scalar.kind !== \"string\" && scalar.kind !== \"json\" && scalar.kind !== \"point\")\n ) {\n return;\n }\n const { arrayDelimiter } = this.options;\n let rows = 0;\n for (let r = 0; r < column.length; r++) {\n if (!column.isSet(r)) {\n continue;\n }\n for (const item of column.sliceOf(r)) {\n if (formatScalar(item, scalar, null).includes(arrayDelimiter)) {\n rows++;\n break;\n }\n }\n }\n if (rows > 0) {\n this.note(\n ARRAY_DELIMITER_LOSS,\n `${label}: ${rows} row(s) hold an item containing the array delimiter \"${arrayDelimiter}\", which Neo4j cannot escape`,\n column.meta.name,\n rows,\n );\n }\n }\n\n /**\n * The explicit weights (design section 3.7), and the weight-column name check.\n * @returns the weights, or null when no weights are written\n */\n private planWeightSource(): ExplicitWeights | null {\n const { snapshot } = this;\n const name = this.options.weightColumn;\n if (name === null) {\n return null;\n }\n const weights = explicitWeights(snapshot);\n const taken = this.edgeColumns.find((plan) => plan.column.meta.name === name);\n if (taken !== undefined && weights.weighted) {\n this.note(\n WEIGHT_COLUMN_TAKEN_LOSS,\n `edge column \"${name}\" already exists; explicit weights cannot be written under weightColumn \"${name}\"`,\n name,\n null,\n );\n if (this.fatalEdges === null) {\n this.fatalEdges = new GraphFormatError(\n \"E_COLUMN_EXISTS\",\n `edge column \"${name}\" already exists; choose another weightColumn`,\n { column: name, domain: \"edge\" },\n );\n }\n } else if (taken !== undefined && name === DEFAULT_WEIGHT_COLUMN) {\n this.note(\n LOSS.WEIGHT_KEY_CLASH,\n `edge column \"${name}\" is written under the property the importer reads THE weight from (weightFrom \"${name}\"); it reads back as the weight, not as a column`,\n name,\n taken.column.length - taken.column.nullCount,\n );\n }\n return weights.weighted ? weights : null;\n }\n\n /** Check the node ids' text forms: type changes under the canonical rule and collisions. */\n private checkIds(): void {\n const { ids } = this.snapshot;\n let typeChanges = 0;\n let collisions = 0;\n switch (ids.kind) {\n case \"identity\":\n case \"dense\":\n break;\n case \"numeric\":\n for (let i = 0; i < ids.size; i++) {\n if (!Number.isSafeInteger(ids.idOf(i))) {\n typeChanges++;\n }\n }\n break;\n case \"string\":\n for (let i = 0; i < ids.size; i++) {\n if (isCanonicalIntegerText(String(ids.idOf(i)))) {\n typeChanges++;\n }\n }\n break;\n case \"mixed\": {\n const seen = new Set<string>();\n for (let i = 0; i < ids.size; i++) {\n const id = ids.idOf(i);\n const text = String(id);\n if (typeof id === \"number\" ? !Number.isSafeInteger(id) : isCanonicalIntegerText(text)) {\n typeChanges++;\n }\n if (seen.has(text)) {\n collisions++;\n } else {\n seen.add(text);\n }\n }\n break;\n }\n default: {\n const name: string = ids.kind;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown id map kind ${name}`, { kind: name });\n }\n }\n if (typeChanges > 0) {\n this.note(\n ID_TEXT_TYPE_LOSS,\n `${typeChanges} node id(s) re-import as another type under the canonical id rule (a string of canonical integer text, or a non-integer number)`,\n null,\n typeChanges,\n );\n }\n if (collisions > 0) {\n this.note(\n ID_TEXT_COLLISION_LOSS,\n `${collisions} node id(s) share their text with another id (a number and a string); export() will throw`,\n null,\n collisions,\n );\n this.fatalAll = new GraphFormatError(\n \"E_INVALID_ID\",\n `${collisions} node id(s) share their text with another id; Neo4j ids are text`,\n { reason: \"text collision\", count: collisions },\n );\n }\n }\n\n /** Check that the idColumn option does not name an existing node property. */\n private checkIdColumn(): void {\n const name = this.options.idColumn;\n if (name === null) {\n return;\n }\n const taken =\n this.nodeColumns.some((plan) => plan.column.meta.name === name) ||\n this.idColumns.some((column) => column.meta.name === name);\n if (!taken) {\n return;\n }\n this.note(\n ID_COLUMN_TAKEN_LOSS,\n `node column \"${name}\" already exists; the :ID column cannot be named idColumn \"${name}\"`,\n name,\n null,\n );\n if (this.fatalNodes === null) {\n this.fatalNodes = new GraphFormatError(\n \"E_COLUMN_EXISTS\",\n `node column \"${name}\" already exists; choose another idColumn`,\n { column: name, domain: \"node\" },\n );\n }\n }\n\n /** Count the nodes with more than one stored-id column set. */\n private checkStoredIds(): void {\n if (this.idColumns.length < 2) {\n return;\n }\n let count = 0;\n for (let i = 0; i < this.snapshot.nodeCount; i++) {\n let set = 0;\n for (const column of this.idColumns) {\n if (column.isSet(i)) {\n set++;\n }\n }\n if (set > 1) {\n count++;\n }\n }\n if (count > 0) {\n this.note(\n MULTIPLE_ID_PROPERTIES_LOSS,\n `${count} node(s) have more than one stored-id column set; only the first in declaration order is written`,\n null,\n count,\n );\n }\n }\n\n /**\n * Whether a json column is written as Neo4j points (so the generic nested-value note does not apply).\n * @param name - the column name\n * @returns true when its plan writes point literals\n */\n private writtenAsPoint(name: string): boolean {\n for (const plan of [...this.nodeColumns, ...this.edgeColumns]) {\n if (plan.column.meta.name === name && plan.scalar.kind === \"point\") {\n return true;\n }\n }\n return false;\n }\n\n /** Drop the notes about the part that is not written. */\n private filterNotesByPart(): void {\n const { part } = this.options;\n if (part === \"all\") {\n return;\n }\n const { snapshot } = this;\n const keep = this.notes.filter((n) => {\n if (part === \"nodes\") {\n if (EDGE_NOTE_CODES.has(n.code)) {\n return false;\n }\n return n.column === null || !snapshot.edges.has(n.column) || snapshot.nodes.has(n.column);\n }\n if (NODE_NOTE_CODES.has(n.code)) {\n return false;\n }\n return n.column === null || !snapshot.nodes.has(n.column) || snapshot.edges.has(n.column);\n });\n this.notes.length = 0;\n this.notes.push(...keep);\n }\n\n /**\n * The error export() throws for the requested part, or null when the export can proceed.\n * @returns the error\n */\n get fatal(): GraphFormatError | null {\n if (this.fatalAll !== null) {\n return this.fatalAll;\n }\n const { part } = this.options;\n if (part !== \"relationships\" && this.fatalNodes !== null) {\n return this.fatalNodes;\n }\n return part === \"nodes\" ? null : this.fatalEdges;\n }\n\n /**\n * The id space of a node.\n * @param index - the node index\n * @returns the space name, or null\n */\n spaceOf(index: number): string | null {\n const { idSpace } = this;\n if (idSpace === null || !idSpace.isSet(index)) {\n return null;\n }\n const value = idSpace.value(index);\n return typeof value === \"string\" ? value : String(value);\n }\n\n /**\n * The `:ID` / `:START_ID` / `:END_ID` text of a node: its originalId value when it has an id\n * space (the importer stored it as `Space:id`), its id otherwise.\n * @param index - the node index\n * @returns the id text\n */\n idTextOf(index: number): string {\n const { originalId } = this;\n if (originalId !== null && originalId.isSet(index) && this.spaceOf(index) !== null) {\n return textOf(originalId, index);\n }\n return idText(this.snapshot.ids.idOf(index));\n }\n\n /**\n * The stored-id column of a node: the first one set in declaration order.\n * @param index - the node index\n * @returns the column, or null\n */\n storedIdOf(index: number): Column | null {\n for (const column of this.idColumns) {\n if (column.isSet(index)) {\n return column;\n }\n }\n return null;\n }\n\n /**\n * The node sections, then the relationship sections, as CSV lines.\n * @yields one line at a time (with its line break)\n * @returns nothing\n */\n *lines(): Generator<string, void, undefined> {\n if (this.fatal !== null) {\n throw this.fatal;\n }\n const { part } = this.options;\n if (part !== \"relationships\") {\n yield* this.nodeLines();\n }\n if (part !== \"nodes\") {\n yield* this.relationshipLines();\n }\n }\n\n /**\n * The node sections.\n * @yields one line at a time\n * @returns nothing\n */\n private *nodeLines(): Generator<string, void, undefined> {\n const { snapshot, labels, nodeColumns } = this;\n const { delimiter } = this.options.syntax;\n const propertyHeaders = nodeColumns.map((plan) => plan.header).join(delimiter);\n let sections = 0;\n let sectionSpace: string | null = null;\n let sectionIdName: string | null = null;\n const cells: string[] = [];\n for (let i = 0; i < snapshot.nodeCount; i++) {\n const space = this.spaceOf(i);\n const stored = this.storedIdOf(i);\n const idName = stored === null ? (this.options.idColumn ?? \"\") : stored.meta.name;\n if (sections === 0 || space !== sectionSpace || idName !== sectionIdName) {\n sections++;\n sectionSpace = space;\n sectionIdName = idName;\n const header = [formatHeaderField(idName, ID_TYPE, space)];\n if (labels !== null) {\n header.push(\":LABEL\");\n }\n if (propertyHeaders.length > 0) {\n header.push(propertyHeaders);\n }\n yield `${header.join(delimiter)}\\n`;\n }\n cells.length = 0;\n cells.push(this.cell(this.idTextOf(i)));\n if (labels !== null) {\n cells.push(this.cell(this.labelsText(i)));\n }\n for (const plan of nodeColumns) {\n cells.push(this.cell(this.valueText(plan, i)));\n }\n yield `${cells.join(delimiter)}\\n`;\n }\n if (sections === 0) {\n // no nodes: one header so the section (and its columns) still exists\n const header = [formatHeaderField(this.options.idColumn ?? \"\", ID_TYPE, null)];\n if (labels !== null) {\n header.push(\":LABEL\");\n }\n if (propertyHeaders.length > 0) {\n header.push(propertyHeaders);\n }\n yield `${header.join(delimiter)}\\n`;\n }\n }\n\n /**\n * The relationship sections.\n * @yields one line at a time\n * @returns nothing\n */\n private *relationshipLines(): Generator<string, void, undefined> {\n const { snapshot, kind, weights, edgeColumns, folding } = this;\n const { delimiter } = this.options.syntax;\n const list = snapshot.edgeList();\n const propertyHeaders = edgeColumns.map((plan) => plan.header).join(delimiter);\n const weightHeader =\n weights === null ? null : formatHeaderField(this.options.weightColumn ?? \"weight\", \"double\", null);\n let sections = 0;\n let sectionStart: string | null = null;\n let sectionEnd: string | null = null;\n const cells: string[] = [];\n const headerOf = (startSpace: string | null, endSpace: string | null): string => {\n const header = [formatHeaderField(\"\", \"START_ID\", startSpace), formatHeaderField(\"\", \"END_ID\", endSpace)];\n if (kind !== null) {\n header.push(\":TYPE\");\n }\n if (weightHeader !== null) {\n header.push(weightHeader);\n }\n if (propertyHeaders.length > 0) {\n header.push(propertyHeaders);\n }\n return `${header.join(delimiter)}\\n`;\n };\n for (let e = 0; e < snapshot.edgeCount; e++) {\n if (folding.folded(e)) {\n continue;\n }\n const u = list.src[e];\n const v = list.dst[e];\n const startSpace = this.spaceOf(u);\n const endSpace = this.spaceOf(v);\n if (sections === 0 || startSpace !== sectionStart || endSpace !== sectionEnd) {\n sections++;\n sectionStart = startSpace;\n sectionEnd = endSpace;\n yield headerOf(startSpace, endSpace);\n }\n cells.length = 0;\n cells.push(this.cell(this.idTextOf(u)), this.cell(this.idTextOf(v)));\n if (kind !== null) {\n cells.push(this.cell(kind.isSet(e) ? textOf(kind, e) : null));\n }\n if (weights !== null) {\n cells.push(this.cell(weights.text(e)));\n }\n for (const plan of edgeColumns) {\n cells.push(this.cell(this.valueText(plan, e)));\n }\n yield `${cells.join(delimiter)}\\n`;\n }\n if (sections === 0) {\n yield headerOf(null, null);\n }\n }\n\n /**\n * A CSV cell: empty for an unset value, a quoted empty string for a set empty string, the\n * quoted text otherwise.\n * @param text - the value text, or null for unset\n * @returns the cell as written\n */\n private cell(text: string | null): string {\n if (text === null) {\n return \"\";\n }\n const { quote } = this.options.syntax;\n if (text.length === 0) {\n return quote + quote;\n }\n return quoteCsvCell(text, this.options.syntax.delimiter);\n }\n\n /**\n * The `:LABEL` cell of a node.\n * @param index - the node index\n * @returns the labels joined by the array delimiter, or null when unset\n */\n private labelsText(index: number): string | null {\n const { labels } = this;\n if (labels === null || !labels.isSet(index)) {\n return null;\n }\n if (labels.dtype === \"list\") {\n return labels\n .sliceOf(index)\n .map((item) => String(item))\n .join(this.options.arrayDelimiter);\n }\n return textOf(labels, index);\n }\n\n /**\n * The text of one property cell.\n * @param plan - the column plan\n * @param row - the row\n * @returns the text, or null when unset\n */\n private valueText(plan: ColumnPlan, row: number): string | null {\n const { column, scalar, companion } = plan;\n if (!column.isSet(row)) {\n return null;\n }\n if (plan.list) {\n const items = column.dtype === \"list\" ? column.sliceOf(row) : (column.value(row) as ArrayLike<unknown>);\n const texts: string[] = [];\n for (const item of Array.from(items)) {\n // an item of several components (itemComponents > 1) is flattened into the array\n if (Array.isArray(item) || ArrayBuffer.isView(item)) {\n for (const component of Array.from(item as ArrayLike<unknown>)) {\n texts.push(formatScalar(component, scalar, null));\n }\n } else {\n texts.push(formatScalar(item, scalar, null));\n }\n }\n return texts.join(this.options.arrayDelimiter);\n }\n const text = companion !== null && companion.isSet(row) ? textOf(companion, row) : null;\n return formatScalar(column.dtype === \"json\" ? column.values[row] : column.value(row), scalar, text);\n }\n}\n\n/**\n * Whether a node column is the importer's id text of the nodes of an id space (`originalId`).\n * @param meta - the column metadata\n * @returns true for the role-less string column the Neo4j importer declares with origin id `:ID` and no type\n */\nfunction isIdText(meta: ColumnMeta): boolean {\n return (\n meta.role === null &&\n meta.dtype === \"string\" &&\n meta.origin !== null &&\n meta.origin.format === NEO4J &&\n meta.origin.id === \":ID\" &&\n meta.origin.type === null\n );\n}\n\n/**\n * Whether a node column is a stored id (`name:ID` on import).\n * @param meta - the column metadata\n * @returns true for a string column declared by the Neo4j importer as the id property\n */\nfunction isStoredId(meta: ColumnMeta): boolean {\n return (\n meta.role === null &&\n meta.dtype === \"string\" &&\n meta.origin !== null &&\n meta.origin.format === NEO4J &&\n meta.origin.type === ID_TYPE\n );\n}\n\n/**\n * Whether a role is one of the visual roles.\n * @param role - the role\n * @returns true for color, size, shape and thickness\n */\nfunction isVizRole(role: string): boolean {\n return role === \"color\" || role === \"size\" || role === \"shape\" || role === \"thickness\";\n}\n\n/**\n * The declared scalar type text of a list declaration (`string[]` -> `string`).\n * @param declared - the declared type text\n * @returns the text without its `[]` suffix\n */\nfunction declaredScalar(declared: string): string {\n const trimmed = declared.trim();\n return trimmed.endsWith(\"[]\") ? trimmed.slice(0, -2) : trimmed;\n}\n\n/**\n * The cell kind of a mapped declared type.\n * @param spec - the mapped type\n * @returns the kind\n */\nfunction kindOf(spec: DeclaredTypeSpec): CellKind {\n switch (spec.kind) {\n case \"boolean\":\n return \"boolean\";\n case \"integer\":\n case \"long\":\n return \"integer\";\n case \"float\":\n return \"float\";\n case \"double\":\n return \"double\";\n case \"string\":\n case \"duration\":\n return \"string\";\n case \"temporal\":\n return \"temporal\";\n case \"point\":\n return \"point\";\n case \"json\":\n return \"json\";\n default: {\n const name: string = spec.kind;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown value kind ${name}`, { kind: name });\n }\n }\n}\n\n/**\n * The Neo4j type of a dtype without a compatible declaration.\n * @param dtype - the column or item dtype\n * @returns the type and cell kind\n */\nfunction defaultScalar(dtype: Dtype | ScalarDtype): ScalarPlan {\n switch (dtype) {\n case \"f32\":\n return { type: \"float\", kind: \"float\", temporal: null };\n case \"f64\":\n return { type: \"double\", kind: \"double\", temporal: null };\n case \"i32\":\n case \"u8\":\n return { type: \"int\", kind: \"integer\", temporal: null };\n case \"u32\":\n return { type: \"long\", kind: \"integer\", temporal: null };\n case \"bool\":\n return { type: \"boolean\", kind: \"boolean\", temporal: null };\n case \"dict\":\n case \"string\":\n return { type: \"string\", kind: \"string\", temporal: null };\n case \"json\":\n return { type: \"string\", kind: \"json\", temporal: null };\n case \"list\":\n return { type: \"string\", kind: \"json\", temporal: null };\n default: {\n const name: string = dtype;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown dtype ${name}`, { dtype: name });\n }\n }\n}\n\n/**\n * Format one scalar value for a cell.\n * @param value - the value\n * @param scalar - the plan\n * @param text - the companion text of a temporal value, or null\n * @returns the text\n */\nfunction formatScalar(value: unknown, scalar: ScalarPlan, text: string | null): string {\n switch (scalar.kind) {\n case \"integer\":\n return typeof value === \"number\" ? formatInteger(value) : String(value);\n case \"float\":\n return typeof value === \"number\" ? formatF32(value) : String(value);\n case \"double\":\n return typeof value === \"number\" ? formatF64(value) : String(value);\n case \"boolean\":\n return value === true ? \"true\" : \"false\";\n case \"string\":\n return typeof value === \"string\" ? value : String(value);\n case \"temporal\":\n if (text !== null) {\n return text;\n }\n return typeof value === \"number\" && scalar.temporal !== null\n ? formatTemporal(value, scalar.temporal)\n : String(value);\n case \"point\":\n return formatPoint(value);\n case \"json\":\n return JSON.stringify(value) ?? \"\";\n default: {\n const name: string = scalar.kind;\n throw new GraphFormatError(\"E_UNSUPPORTED\", `unknown cell kind ${name}`, { kind: name });\n }\n }\n}\n\n/**\n * A Neo4j point literal `{x:1.5, y:2, crs:'cartesian'}` from a point object; any other value is\n * written as JSON text.\n * @param value - the json value\n * @returns the literal\n */\nfunction formatPoint(value: unknown): string {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return JSON.stringify(value) ?? \"\";\n }\n const parts: string[] = [];\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (typeof item === \"number\") {\n parts.push(`${key}:${formatF64(item)}`);\n } else if (typeof item === \"string\") {\n parts.push(`${key}:'${item.replace(/'/g, \"\")}'`);\n } else {\n return JSON.stringify(value) ?? \"\";\n }\n }\n return `{${parts.join(\", \")}}`;\n}\n\n/**\n * The text of a node id.\n * @param id - the id\n * @returns String(id)\n */\nfunction idText(id: NodeId): string {\n if (typeof id === \"string\") {\n return id;\n }\n return Number.isInteger(id) ? formatInteger(id) : String(id);\n}\n\n/**\n * The text of a set cell of a dict / string (or any scalar) column.\n * @param column - the column\n * @param row - the row\n * @returns the value as text\n */\nfunction textOf(column: Column, row: number): string {\n switch (column.dtype) {\n case \"string\":\n return column.valueAt(row);\n case \"dict\":\n return String(column.value(row));\n case \"list\":\n return column.sliceOf(row).map(String).join(\",\");\n case \"json\":\n return JSON.stringify(column.values[row]) ?? \"\";\n case \"bool\":\n return column.value(row) === true ? \"true\" : \"false\";\n default: {\n const value = column.value(row);\n return typeof value === \"number\" ? String(value) : Array.from(value as ArrayLike<number>).join(\",\");\n }\n }\n}\n\n/** The Neo4j exporter. */\nexport const neo4jExporter: GraphExporter<Neo4jExportOptions> = Object.freeze({\n format: NEO4J,\n capabilities: NEO4J_CAPABILITIES,\n /**\n * Pre-flight: what export() would lose.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the notes\n */\n check(snapshot: GraphSnapshot, options?: Neo4jExportOptions & CommonExportOptions): readonly LossNote[] {\n return Object.freeze([...plan(snapshot, options).notes]);\n },\n /**\n * Write the snapshot as UTF-8 chunks.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the chunks\n */\n export(snapshot: GraphSnapshot, options?: Neo4jExportOptions & CommonExportOptions): AsyncIterable<Uint8Array> {\n return encodeChunks(plan(snapshot, options).lines());\n },\n /**\n * Write the snapshot as one string.\n * @param snapshot - the snapshot\n * @param options - format-specific and common options\n * @returns the document\n */\n exportToString(snapshot: GraphSnapshot, options?: Neo4jExportOptions & CommonExportOptions): Promise<string> {\n return joinText(plan(snapshot, options).lines());\n },\n});\n\n/**\n * Build the export plan of a snapshot.\n * @param snapshot - the snapshot\n * @param options - the caller's options\n * @returns the plan\n */\nfunction plan(snapshot: GraphSnapshot, options: (Neo4jExportOptions & CommonExportOptions) | undefined): ExportPlan {\n return new ExportPlan(snapshot, resolveNeo4jExportOptions(options), resolveExportOptions(options));\n}\n","/**\n * The `@graphty/graph-io/neo4j` subpath: the Neo4j importer and exporter with their option types\n * (design section 8.2), the names of the reserved columns and the issue and loss-note codes\n * grouped in two tables.\n */\n\nimport {\n COLUMN_RENAMED_CODE,\n ENCODING_FALLBACK_CODE,\n INVALID_ENCODING_CODE,\n INVALID_UTF8_CODE,\n MUTUAL_EXPANDED_CODE,\n OPTION_IGNORED_CODE,\n PRECISION_CODE,\n ROLE_DROPPED_CODE,\n SINK_OPTION_CODE,\n UNKNOWN_ATTR_TYPE_CODE,\n UNKNOWN_ENCODING_CODE,\n WEIGHT_KEY_CLASH_CODE,\n} from \"../../common/codes.js\";\nimport { BAD_QUOTE_CODE, UNCLOSED_QUOTE_CODE } from \"../csv/records.js\";\nimport {\n ARRAY_DELIMITER_LOSS,\n DECLARED_TYPE_CHANGED_LOSS,\n ID_COLUMN_TAKEN_LOSS,\n ID_TEXT_COLLISION_LOSS,\n ID_TEXT_TYPE_LOSS,\n MULTIPLE_ID_PROPERTIES_LOSS,\n UNDIRECTED_LOSS,\n WEIGHT_COLUMN_TAKEN_LOSS,\n} from \"./exporter.js\";\nimport {\n COLUMN_COUNT_CODE,\n DUPLICATE_NODE_CODE,\n ENDPOINT_SPACE_CODE,\n HEADER_CODE,\n HEADER_OPTION_CODE,\n ID_MERGED_CODE,\n ID_SPACE_COLLISION_CODE,\n IGNORED_COLUMNS_LOSS,\n MISSING_ENDPOINT_CODE,\n MISSING_ID_CODE,\n ROLE_TAKEN_CODE,\n} from \"./importer.js\";\n\nexport { NEO4J_CAPABILITIES, neo4jExporter, type Neo4jExportOptions } from \"./exporter.js\";\nexport {\n ID_SPACE_COLUMN,\n LABELS_COLUMN,\n neo4jImporter,\n type Neo4jImportOptions,\n ORIGINAL_ID_COLUMN,\n TYPE_COLUMN,\n} from \"./importer.js\";\n\n/**\n * The issue codes the Neo4j importer records (design section 8.6), by name: the codes shared with\n * the other importers (src/common/codes.ts, the CSV record reader) and the Neo4j-specific ones.\n * A key is the code without its severity and format prefixes.\n */\nexport const NEO4J_ISSUE = Object.freeze({\n /** The input holds invalid UTF-8 (fatal). */\n INVALID_UTF8: INVALID_UTF8_CODE,\n /** Invalid bytes in the encoding a BOM, a declaration or the encoding option chose (fatal). */\n INVALID_ENCODING: INVALID_ENCODING_CODE,\n /** Bytes that are not UTF-8 and declare no encoding were read as windows-1252. */\n ENCODING_FALLBACK: ENCODING_FALLBACK_CODE,\n /** A declared encoding the platform cannot decode was ignored. */\n UNKNOWN_ENCODING: UNKNOWN_ENCODING_CODE,\n /** An unterminated quoted field (fatal). */\n CSV_UNCLOSED_QUOTE: UNCLOSED_QUOTE_CODE,\n /** Text after a closing quote (fatal). */\n CSV_QUOTE: BAD_QUOTE_CODE,\n /** No header or a malformed header (fatal). */\n HEADER: HEADER_CODE,\n /** A row with a different field count than the header. */\n COLUMN_COUNT: COLUMN_COUNT_CODE,\n /** A node row without an id. */\n MISSING_ID: MISSING_ID_CODE,\n /** A relationship row without a start or end id. */\n MISSING_ENDPOINT: MISSING_ENDPOINT_CODE,\n /** A node id repeated in one id space (last write wins). */\n DUPLICATE_NODE: DUPLICATE_NODE_CODE,\n /** A spaced node id `Space:id` that equals the text of an id declared without a space. */\n ID_SPACE_COLLISION: ID_SPACE_COLLISION_CODE,\n /** A spaced relationship endpoint `Space:id` that names a node declared without a space; the row is skipped. */\n ENDPOINT_SPACE: ENDPOINT_SPACE_CODE,\n /** Two id texts merged into one number under ids \"number\". */\n ID_MERGED: ID_MERGED_CODE,\n /** A header brace option the importer does not apply. */\n HEADER_OPTION_IGNORED: HEADER_OPTION_CODE,\n /** A declared type the format does not define (kept as string). */\n UNKNOWN_ATTR_TYPE: UNKNOWN_ATTR_TYPE_CODE,\n /** A long value beyond 2^53 rounded. */\n PRECISION: PRECISION_CODE,\n /** A column renamed `<name>#<id>` because the name was taken (design section 5.6). */\n COLUMN_RENAMED: COLUMN_RENAMED_CODE,\n /** A role the caller's sink already holds. */\n ROLE_TAKEN: ROLE_TAKEN_CODE,\n /** A common option the importer has no use for (nodeIdFrom, defaultDirected, ...). */\n OPTION_IGNORED: OPTION_IGNORED_CODE,\n /** A builder-policy option the sink does not honour. */\n SINK_OPTION: SINK_OPTION_CODE,\n});\n\n/**\n * The loss-note codes of the Neo4j importer (report.lossy) and exporter (check()), by name: the\n * Neo4j ones and, aliased, the shared ones it records (`LOSS` holds the generic pre-flight's).\n */\nexport const NEO4J_LOSS = Object.freeze({\n /** `:IGNORE` columns skipped on import. */\n IGNORED_COLUMNS: IGNORED_COLUMNS_LOSS,\n /** Undirected edges (an undirected snapshot, the folded pairs of a mixed one) written as directed relationships. */\n UNDIRECTED_AS_DIRECTED: UNDIRECTED_LOSS,\n /** A mutual pair written as two directed relationships without its mark. */\n MUTUAL_EXPANDED: MUTUAL_EXPANDED_CODE,\n /** A role column Neo4j has no slot for (label, ...) written as a plain property. */\n ROLE_DROPPED: ROLE_DROPPED_CODE,\n /** A plain `weight` edge column reads back as THE weight (the importer's weightFrom default). */\n WEIGHT_KEY_CLASH: WEIGHT_KEY_CLASH_CODE,\n /** A node id whose text re-imports as another type under the canonical rule. */\n ID_TEXT_TYPE: ID_TEXT_TYPE_LOSS,\n /** A number and a string id with the same text; export() throws. */\n ID_TEXT_COLLISION: ID_TEXT_COLLISION_LOSS,\n /** The weight column name is taken by an edge column; export() throws. */\n WEIGHT_COLUMN_TAKEN: WEIGHT_COLUMN_TAKEN_LOSS,\n /** The id column name is taken by a node column; export() throws. */\n ID_COLUMN_TAKEN: ID_COLUMN_TAKEN_LOSS,\n /** Several stored-id properties; one becomes the `:ID` column. */\n MULTIPLE_ID_PROPERTIES: MULTIPLE_ID_PROPERTIES_LOSS,\n /** An integer-typed column with non-integral values written as double. */\n DECLARED_TYPE_CHANGED: DECLARED_TYPE_CHANGED_LOSS,\n /** A list item containing the array delimiter, which Neo4j cannot escape. */\n ARRAY_DELIMITER: ARRAY_DELIMITER_LOSS,\n});\n"],"names":["headerError","SHARED_MISSING_ID_CODE","SHARED_MISSING_ENDPOINT_CODE","SHARED_DUPLICATE_NODE_CODE","SHARED_ID_MERGED_CODE","SHARED_ROLE_TAKEN_CODE","NEO4J","idText","compatible","scalar","plan"],"mappings":"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"}
|