@graphty/graph-io 0.3.24 → 0.3.26
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 +49 -414
- package/dist/chunks/children-CL3Cy0ez.js.map +1 -1
- package/dist/chunks/choose-BbJI55dx.js +56 -0
- package/dist/chunks/choose-BbJI55dx.js.map +1 -0
- package/dist/chunks/constants-BCsFsMj4.js +231 -0
- package/dist/chunks/constants-BCsFsMj4.js.map +1 -0
- package/dist/chunks/{escape-B-tkk_Cl.js → escape-D0g6NNUy.js} +382 -92
- package/dist/chunks/escape-D0g6NNUy.js.map +1 -0
- package/dist/chunks/export-BTI4yQgy.js +4333 -0
- package/dist/chunks/export-BTI4yQgy.js.map +1 -0
- package/dist/chunks/exporter-BMqk5oxW.js +3465 -0
- package/dist/chunks/exporter-BMqk5oxW.js.map +1 -0
- package/dist/chunks/{importer-eUREhBGj.js → exporter-Cra2GYcN.js} +4969 -3201
- package/dist/chunks/exporter-Cra2GYcN.js.map +1 -0
- package/dist/chunks/{exporter-BGrsWamJ.js → exporter-Dxh231ZF.js} +38 -229
- package/dist/chunks/exporter-Dxh231ZF.js.map +1 -0
- package/dist/chunks/{exporter-DIeGJXAZ.js → exporter-tne475KK.js} +22 -20
- package/dist/chunks/exporter-tne475KK.js.map +1 -0
- package/dist/chunks/importer-90YWhJoF.js +2811 -0
- package/dist/chunks/importer-90YWhJoF.js.map +1 -0
- package/dist/chunks/{importer-D_e7e7LX.js → importer-Bcl1d4xH.js} +398 -145
- package/dist/chunks/importer-Bcl1d4xH.js.map +1 -0
- package/dist/chunks/{importer-BWY2FFc5.js → importer-BfIsp1f9.js} +255 -77
- package/dist/chunks/importer-BfIsp1f9.js.map +1 -0
- package/dist/chunks/{importer-zGLo8Dg_.js → importer-C_TEA1zJ.js} +484 -157
- package/dist/chunks/importer-C_TEA1zJ.js.map +1 -0
- package/dist/chunks/{importer-DET1tg6s.js → importer-DCjOvO7U.js} +1687 -310
- package/dist/chunks/importer-DCjOvO7U.js.map +1 -0
- package/dist/chunks/{importer-vi3bSdtw.js → importer-DfVu6j59.js} +509 -76
- package/dist/chunks/importer-DfVu6j59.js.map +1 -0
- package/dist/chunks/{importer-DIrbbnAf.js → importer-Dku_VAIY.js} +585 -226
- package/dist/chunks/importer-Dku_VAIY.js.map +1 -0
- package/dist/chunks/json-elements-3tnyt5uZ.js +1225 -0
- package/dist/chunks/json-elements-3tnyt5uZ.js.map +1 -0
- package/dist/chunks/ontology-export-B9Tcf37D.js +357 -0
- package/dist/chunks/ontology-export-B9Tcf37D.js.map +1 -0
- package/dist/chunks/{records-dbRkxwaq.js → records-CQXT__mY.js} +298 -114
- package/dist/chunks/records-CQXT__mY.js.map +1 -0
- package/dist/chunks/{text-Dr0Ifpag.js → text-DmcUs5_Q.js} +29 -11
- package/dist/chunks/text-DmcUs5_Q.js.map +1 -0
- package/dist/chunks/{writer-C7flM-Ih.js → writer-DxjgHwSe.js} +19 -1
- package/dist/chunks/writer-DxjgHwSe.js.map +1 -0
- package/dist/csv.js +951 -261
- package/dist/csv.js.map +1 -1
- package/dist/cx.js +6 -3
- package/dist/cx2.js +2 -2
- package/dist/cys.js +6 -3
- package/dist/dot.js +1 -1
- package/dist/gexf.js +554 -122
- package/dist/gexf.js.map +1 -1
- package/dist/gml.js +342 -85
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +1105 -213
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +3 -2
- package/dist/graphml.js.map +1 -1
- package/dist/json.js +3 -2
- package/dist/neo4j.js +564 -157
- package/dist/neo4j.js.map +1 -1
- package/dist/obo.js +6 -3
- package/dist/pajek.js +1 -1
- package/dist/src/children.d.ts +18 -6
- package/dist/src/children.d.ts.map +1 -1
- package/dist/src/children.js +6 -3
- package/dist/src/children.js.map +1 -1
- package/dist/src/common/attributes.d.ts +29 -11
- package/dist/src/common/attributes.d.ts.map +1 -1
- package/dist/src/common/attributes.js +25 -7
- package/dist/src/common/attributes.js.map +1 -1
- package/dist/src/common/cell-budget.d.ts +9 -2
- package/dist/src/common/cell-budget.d.ts.map +1 -1
- package/dist/src/common/cell-budget.js +11 -3
- package/dist/src/common/cell-budget.js.map +1 -1
- package/dist/src/common/choose.d.ts +19 -0
- package/dist/src/common/choose.d.ts.map +1 -0
- package/dist/src/common/choose.js +72 -0
- package/dist/src/common/choose.js.map +1 -0
- package/dist/src/common/codes.d.ts +456 -66
- package/dist/src/common/codes.d.ts.map +1 -1
- package/dist/src/common/codes.js +458 -66
- package/dist/src/common/codes.js.map +1 -1
- package/dist/src/common/compare.d.ts +81 -0
- package/dist/src/common/compare.d.ts.map +1 -0
- package/dist/src/common/compare.js +394 -0
- package/dist/src/common/compare.js.map +1 -0
- package/dist/src/common/cx-export.d.ts +123 -0
- package/dist/src/common/cx-export.d.ts.map +1 -0
- package/dist/src/common/cx-export.js +334 -0
- package/dist/src/common/cx-export.js.map +1 -0
- package/dist/src/common/declared-types.d.ts +22 -2
- package/dist/src/common/declared-types.d.ts.map +1 -1
- package/dist/src/common/declared-types.js +19 -1
- package/dist/src/common/declared-types.js.map +1 -1
- package/dist/src/common/direction.d.ts +74 -50
- package/dist/src/common/direction.d.ts.map +1 -1
- package/dist/src/common/direction.js +47 -27
- package/dist/src/common/direction.js.map +1 -1
- package/dist/src/common/escape.d.ts +21 -9
- package/dist/src/common/escape.d.ts.map +1 -1
- package/dist/src/common/escape.js +33 -17
- package/dist/src/common/escape.js.map +1 -1
- package/dist/src/common/export.d.ts +144 -32
- package/dist/src/common/export.d.ts.map +1 -1
- package/dist/src/common/export.js +216 -42
- package/dist/src/common/export.js.map +1 -1
- package/dist/src/common/format.d.ts +23 -1
- package/dist/src/common/format.d.ts.map +1 -1
- package/dist/src/common/format.js +26 -1
- package/dist/src/common/format.js.map +1 -1
- package/dist/src/common/ids.d.ts +9 -2
- package/dist/src/common/ids.d.ts.map +1 -1
- package/dist/src/common/ids.js +6 -2
- package/dist/src/common/ids.js.map +1 -1
- package/dist/src/common/input.d.ts +122 -28
- package/dist/src/common/input.d.ts.map +1 -1
- package/dist/src/common/input.js +890 -124
- package/dist/src/common/input.js.map +1 -1
- package/dist/src/common/json-elements.d.ts +144 -20
- package/dist/src/common/json-elements.d.ts.map +1 -1
- package/dist/src/common/json-elements.js +868 -188
- package/dist/src/common/json-elements.js.map +1 -1
- package/dist/src/common/line-format.d.ts +90 -0
- package/dist/src/common/line-format.d.ts.map +1 -0
- package/dist/src/common/line-format.js +185 -0
- package/dist/src/common/line-format.js.map +1 -0
- package/dist/src/common/lists.d.ts +6 -1
- package/dist/src/common/lists.d.ts.map +1 -1
- package/dist/src/common/lists.js +2 -0
- package/dist/src/common/lists.js.map +1 -1
- package/dist/src/common/ontology-export.d.ts +167 -0
- package/dist/src/common/ontology-export.d.ts.map +1 -0
- package/dist/src/common/ontology-export.js +359 -0
- package/dist/src/common/ontology-export.js.map +1 -0
- package/dist/src/common/ontology.d.ts +25 -3
- package/dist/src/common/ontology.d.ts.map +1 -1
- package/dist/src/common/ontology.js +30 -9
- package/dist/src/common/ontology.js.map +1 -1
- package/dist/src/common/options.d.ts +62 -12
- package/dist/src/common/options.d.ts.map +1 -1
- package/dist/src/common/options.js +89 -11
- package/dist/src/common/options.js.map +1 -1
- package/dist/src/common/plural.d.ts +31 -0
- package/dist/src/common/plural.d.ts.map +1 -0
- package/dist/src/common/plural.js +46 -0
- package/dist/src/common/plural.js.map +1 -0
- package/dist/src/common/report.d.ts +72 -14
- package/dist/src/common/report.d.ts.map +1 -1
- package/dist/src/common/report.js +146 -22
- package/dist/src/common/report.js.map +1 -1
- package/dist/src/common/temporal.d.ts +22 -5
- package/dist/src/common/temporal.d.ts.map +1 -1
- package/dist/src/common/temporal.js +13 -2
- package/dist/src/common/temporal.js.map +1 -1
- package/dist/src/common/text.d.ts +39 -23
- package/dist/src/common/text.d.ts.map +1 -1
- package/dist/src/common/text.js +51 -21
- package/dist/src/common/text.js.map +1 -1
- package/dist/src/common/weights.d.ts +37 -4
- package/dist/src/common/weights.d.ts.map +1 -1
- package/dist/src/common/weights.js +61 -2
- package/dist/src/common/weights.js.map +1 -1
- package/dist/src/common/writer.d.ts +19 -3
- package/dist/src/common/writer.d.ts.map +1 -1
- package/dist/src/common/writer.js +30 -2
- package/dist/src/common/writer.js.map +1 -1
- package/dist/src/common/xml.d.ts +125 -9
- package/dist/src/common/xml.d.ts.map +1 -1
- package/dist/src/common/xml.js +400 -83
- package/dist/src/common/xml.js.map +1 -1
- package/dist/src/common/zip.d.ts +44 -4
- package/dist/src/common/zip.d.ts.map +1 -1
- package/dist/src/common/zip.js +134 -5
- package/dist/src/common/zip.js.map +1 -1
- package/dist/src/formats/csv/exporter.d.ts +80 -24
- package/dist/src/formats/csv/exporter.d.ts.map +1 -1
- package/dist/src/formats/csv/exporter.js +145 -32
- package/dist/src/formats/csv/exporter.js.map +1 -1
- package/dist/src/formats/csv/header.d.ts +38 -9
- package/dist/src/formats/csv/header.d.ts.map +1 -1
- package/dist/src/formats/csv/header.js +46 -10
- package/dist/src/formats/csv/header.js.map +1 -1
- package/dist/src/formats/csv/importer.d.ts +187 -37
- package/dist/src/formats/csv/importer.d.ts.map +1 -1
- package/dist/src/formats/csv/importer.js +835 -204
- package/dist/src/formats/csv/importer.js.map +1 -1
- package/dist/src/formats/csv/index.d.ts +100 -19
- package/dist/src/formats/csv/index.d.ts.map +1 -1
- package/dist/src/formats/csv/index.js +94 -21
- package/dist/src/formats/csv/index.js.map +1 -1
- package/dist/src/formats/csv/records.d.ts +95 -10
- package/dist/src/formats/csv/records.d.ts.map +1 -1
- package/dist/src/formats/csv/records.js +333 -122
- package/dist/src/formats/csv/records.js.map +1 -1
- package/dist/src/formats/csv/values.d.ts +1 -0
- package/dist/src/formats/csv/values.d.ts.map +1 -1
- package/dist/src/formats/csv/values.js +1 -0
- package/dist/src/formats/csv/values.js.map +1 -1
- package/dist/src/formats/cx/exporter.d.ts +102 -0
- package/dist/src/formats/cx/exporter.d.ts.map +1 -0
- package/dist/src/formats/cx/exporter.js +1217 -0
- package/dist/src/formats/cx/exporter.js.map +1 -0
- package/dist/src/formats/cx/importer.d.ts +79 -32
- package/dist/src/formats/cx/importer.d.ts.map +1 -1
- package/dist/src/formats/cx/importer.js +680 -285
- package/dist/src/formats/cx/importer.js.map +1 -1
- package/dist/src/formats/cx/index.d.ts +4 -3
- package/dist/src/formats/cx/index.d.ts.map +1 -1
- package/dist/src/formats/cx/index.js +4 -3
- package/dist/src/formats/cx/index.js.map +1 -1
- package/dist/src/formats/cx2/exporter.d.ts +29 -11
- package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx2/exporter.js +39 -268
- package/dist/src/formats/cx2/exporter.js.map +1 -1
- package/dist/src/formats/cx2/importer.d.ts +78 -28
- package/dist/src/formats/cx2/importer.d.ts.map +1 -1
- package/dist/src/formats/cx2/importer.js +226 -79
- package/dist/src/formats/cx2/importer.js.map +1 -1
- package/dist/src/formats/cx2/index.d.ts +2 -1
- package/dist/src/formats/cx2/index.d.ts.map +1 -1
- package/dist/src/formats/cx2/index.js +2 -1
- package/dist/src/formats/cx2/index.js.map +1 -1
- package/dist/src/formats/cys/constants.d.ts +66 -17
- package/dist/src/formats/cys/constants.d.ts.map +1 -1
- package/dist/src/formats/cys/constants.js +59 -18
- package/dist/src/formats/cys/constants.js.map +1 -1
- package/dist/src/formats/cys/exporter.d.ts +118 -0
- package/dist/src/formats/cys/exporter.d.ts.map +1 -0
- package/dist/src/formats/cys/exporter.js +1072 -0
- package/dist/src/formats/cys/exporter.js.map +1 -0
- package/dist/src/formats/cys/importer.d.ts +22 -8
- package/dist/src/formats/cys/importer.d.ts.map +1 -1
- package/dist/src/formats/cys/importer.js +510 -149
- package/dist/src/formats/cys/importer.js.map +1 -1
- package/dist/src/formats/cys/index.d.ts +4 -2
- package/dist/src/formats/cys/index.d.ts.map +1 -1
- package/dist/src/formats/cys/index.js +4 -2
- package/dist/src/formats/cys/index.js.map +1 -1
- package/dist/src/formats/cys/session.d.ts +46 -7
- package/dist/src/formats/cys/session.d.ts.map +1 -1
- package/dist/src/formats/cys/session.js +98 -24
- package/dist/src/formats/cys/session.js.map +1 -1
- package/dist/src/formats/cys/tables.d.ts +9 -2
- package/dist/src/formats/cys/tables.d.ts.map +1 -1
- package/dist/src/formats/cys/tables.js +29 -7
- package/dist/src/formats/cys/tables.js.map +1 -1
- package/dist/src/formats/dot/exporter.d.ts +42 -14
- package/dist/src/formats/dot/exporter.d.ts.map +1 -1
- package/dist/src/formats/dot/exporter.js +56 -29
- package/dist/src/formats/dot/exporter.js.map +1 -1
- package/dist/src/formats/dot/importer.d.ts +91 -29
- package/dist/src/formats/dot/importer.d.ts.map +1 -1
- package/dist/src/formats/dot/importer.js +190 -39
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/dot/index.d.ts +2 -1
- package/dist/src/formats/dot/index.d.ts.map +1 -1
- package/dist/src/formats/dot/index.js +2 -1
- package/dist/src/formats/dot/index.js.map +1 -1
- package/dist/src/formats/dot/names.d.ts +44 -11
- package/dist/src/formats/dot/names.d.ts.map +1 -1
- package/dist/src/formats/dot/names.js +44 -11
- package/dist/src/formats/dot/names.js.map +1 -1
- package/dist/src/formats/dot/tokenizer.d.ts +9 -2
- package/dist/src/formats/dot/tokenizer.d.ts.map +1 -1
- package/dist/src/formats/dot/tokenizer.js +20 -5
- package/dist/src/formats/dot/tokenizer.js.map +1 -1
- package/dist/src/formats/gexf/exporter.d.ts +46 -15
- package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
- package/dist/src/formats/gexf/exporter.js +45 -15
- package/dist/src/formats/gexf/exporter.js.map +1 -1
- package/dist/src/formats/gexf/importer.d.ts +87 -23
- package/dist/src/formats/gexf/importer.d.ts.map +1 -1
- package/dist/src/formats/gexf/importer.js +471 -90
- package/dist/src/formats/gexf/importer.js.map +1 -1
- package/dist/src/formats/gexf/index.d.ts +84 -21
- package/dist/src/formats/gexf/index.d.ts.map +1 -1
- package/dist/src/formats/gexf/index.js +80 -23
- package/dist/src/formats/gexf/index.js.map +1 -1
- package/dist/src/formats/gexf/schema.d.ts +67 -15
- package/dist/src/formats/gexf/schema.d.ts.map +1 -1
- package/dist/src/formats/gexf/schema.js +59 -13
- package/dist/src/formats/gexf/schema.js.map +1 -1
- package/dist/src/formats/gml/exporter.d.ts +69 -21
- package/dist/src/formats/gml/exporter.d.ts.map +1 -1
- package/dist/src/formats/gml/exporter.js +74 -29
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/gml/importer.d.ts +116 -25
- package/dist/src/formats/gml/importer.d.ts.map +1 -1
- package/dist/src/formats/gml/importer.js +290 -61
- package/dist/src/formats/gml/importer.js.map +1 -1
- package/dist/src/formats/gml/index.d.ts +87 -24
- package/dist/src/formats/gml/index.d.ts.map +1 -1
- package/dist/src/formats/gml/index.js +79 -26
- package/dist/src/formats/gml/index.js.map +1 -1
- package/dist/src/formats/gml/syntax.d.ts +67 -18
- package/dist/src/formats/gml/syntax.d.ts.map +1 -1
- package/dist/src/formats/gml/syntax.js +108 -26
- package/dist/src/formats/gml/syntax.js.map +1 -1
- package/dist/src/formats/graphml/constants.d.ts +174 -44
- package/dist/src/formats/graphml/constants.d.ts.map +1 -1
- package/dist/src/formats/graphml/constants.js +165 -44
- package/dist/src/formats/graphml/constants.js.map +1 -1
- package/dist/src/formats/graphml/exporter.d.ts +17 -9
- package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
- package/dist/src/formats/graphml/exporter.js +33 -12
- package/dist/src/formats/graphml/exporter.js.map +1 -1
- package/dist/src/formats/graphml/importer.d.ts +19 -7
- package/dist/src/formats/graphml/importer.d.ts.map +1 -1
- package/dist/src/formats/graphml/importer.js +466 -39
- package/dist/src/formats/graphml/importer.js.map +1 -1
- package/dist/src/formats/graphml/index.d.ts +2 -1
- package/dist/src/formats/graphml/index.d.ts.map +1 -1
- package/dist/src/formats/graphml/index.js +2 -1
- package/dist/src/formats/graphml/index.js.map +1 -1
- package/dist/src/formats/graphml/tree.d.ts +6 -2
- package/dist/src/formats/graphml/tree.d.ts.map +1 -1
- package/dist/src/formats/graphml/tree.js +6 -2
- package/dist/src/formats/graphml/tree.js.map +1 -1
- package/dist/src/formats/graphml/yfiles.d.ts +8 -3
- package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
- package/dist/src/formats/graphml/yfiles.js +36 -15
- package/dist/src/formats/graphml/yfiles.js.map +1 -1
- package/dist/src/formats/json/dialect.d.ts +88 -24
- package/dist/src/formats/json/dialect.d.ts.map +1 -1
- package/dist/src/formats/json/dialect.js +109 -19
- package/dist/src/formats/json/dialect.js.map +1 -1
- package/dist/src/formats/json/exporter.d.ts +134 -22
- package/dist/src/formats/json/exporter.d.ts.map +1 -1
- package/dist/src/formats/json/exporter.js +135 -54
- package/dist/src/formats/json/exporter.js.map +1 -1
- package/dist/src/formats/json/importer.d.ts +173 -52
- package/dist/src/formats/json/importer.d.ts.map +1 -1
- package/dist/src/formats/json/importer.js +899 -220
- package/dist/src/formats/json/importer.js.map +1 -1
- package/dist/src/formats/json/index.d.ts +3 -2
- package/dist/src/formats/json/index.d.ts.map +1 -1
- package/dist/src/formats/json/index.js +3 -2
- package/dist/src/formats/json/index.js.map +1 -1
- package/dist/src/formats/json/obographs-export.d.ts +68 -0
- package/dist/src/formats/json/obographs-export.d.ts.map +1 -0
- package/dist/src/formats/json/obographs-export.js +941 -0
- package/dist/src/formats/json/obographs-export.js.map +1 -0
- package/dist/src/formats/json/obographs.d.ts +26 -0
- package/dist/src/formats/json/obographs.d.ts.map +1 -1
- package/dist/src/formats/json/obographs.js +297 -80
- package/dist/src/formats/json/obographs.js.map +1 -1
- package/dist/src/formats/neo4j/exporter.d.ts +109 -21
- package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
- package/dist/src/formats/neo4j/exporter.js +238 -85
- package/dist/src/formats/neo4j/exporter.js.map +1 -1
- package/dist/src/formats/neo4j/header.d.ts +17 -4
- package/dist/src/formats/neo4j/header.d.ts.map +1 -1
- package/dist/src/formats/neo4j/header.js +36 -4
- package/dist/src/formats/neo4j/header.js.map +1 -1
- package/dist/src/formats/neo4j/importer.d.ts +107 -27
- package/dist/src/formats/neo4j/importer.d.ts.map +1 -1
- package/dist/src/formats/neo4j/importer.js +415 -63
- package/dist/src/formats/neo4j/importer.js.map +1 -1
- package/dist/src/formats/neo4j/index.d.ts +73 -23
- package/dist/src/formats/neo4j/index.d.ts.map +1 -1
- package/dist/src/formats/neo4j/index.js +65 -25
- package/dist/src/formats/neo4j/index.js.map +1 -1
- package/dist/src/formats/obo/exporter.d.ts +150 -0
- package/dist/src/formats/obo/exporter.d.ts.map +1 -0
- package/dist/src/formats/obo/exporter.js +1736 -0
- package/dist/src/formats/obo/exporter.js.map +1 -0
- package/dist/src/formats/obo/importer.d.ts +95 -19
- package/dist/src/formats/obo/importer.d.ts.map +1 -1
- package/dist/src/formats/obo/importer.js +475 -104
- package/dist/src/formats/obo/importer.js.map +1 -1
- package/dist/src/formats/obo/index.d.ts +6 -3
- package/dist/src/formats/obo/index.d.ts.map +1 -1
- package/dist/src/formats/obo/index.js +6 -3
- package/dist/src/formats/obo/index.js.map +1 -1
- package/dist/src/formats/obo/syntax.d.ts +108 -4
- package/dist/src/formats/obo/syntax.d.ts.map +1 -1
- package/dist/src/formats/obo/syntax.js +211 -34
- package/dist/src/formats/obo/syntax.js.map +1 -1
- package/dist/src/formats/pajek/exporter.d.ts +54 -16
- package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
- package/dist/src/formats/pajek/exporter.js +66 -34
- package/dist/src/formats/pajek/exporter.js.map +1 -1
- package/dist/src/formats/pajek/importer.d.ts +84 -22
- package/dist/src/formats/pajek/importer.d.ts.map +1 -1
- package/dist/src/formats/pajek/importer.js +303 -83
- package/dist/src/formats/pajek/importer.js.map +1 -1
- package/dist/src/formats/pajek/index.d.ts +2 -1
- package/dist/src/formats/pajek/index.d.ts.map +1 -1
- package/dist/src/formats/pajek/index.js +2 -1
- package/dist/src/formats/pajek/index.js.map +1 -1
- package/dist/src/formats/pajek/syntax.d.ts +77 -14
- package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
- package/dist/src/formats/pajek/syntax.js +183 -51
- package/dist/src/formats/pajek/syntax.js.map +1 -1
- package/dist/src/formats/xgmml/columns.d.ts +1 -0
- package/dist/src/formats/xgmml/columns.d.ts.map +1 -1
- package/dist/src/formats/xgmml/columns.js +4 -0
- package/dist/src/formats/xgmml/columns.js.map +1 -1
- package/dist/src/formats/xgmml/constants.d.ts +186 -56
- package/dist/src/formats/xgmml/constants.d.ts.map +1 -1
- package/dist/src/formats/xgmml/constants.js +181 -57
- package/dist/src/formats/xgmml/constants.js.map +1 -1
- package/dist/src/formats/xgmml/document.d.ts +65 -11
- package/dist/src/formats/xgmml/document.d.ts.map +1 -1
- package/dist/src/formats/xgmml/document.js +157 -28
- package/dist/src/formats/xgmml/document.js.map +1 -1
- package/dist/src/formats/xgmml/emit.d.ts +61 -3
- package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
- package/dist/src/formats/xgmml/emit.js +129 -26
- package/dist/src/formats/xgmml/emit.js.map +1 -1
- package/dist/src/formats/xgmml/exporter.d.ts +13 -6
- package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
- package/dist/src/formats/xgmml/exporter.js +20 -21
- package/dist/src/formats/xgmml/exporter.js.map +1 -1
- package/dist/src/formats/xgmml/importer.d.ts +33 -12
- package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
- package/dist/src/formats/xgmml/importer.js +35 -72
- package/dist/src/formats/xgmml/importer.js.map +1 -1
- package/dist/src/formats/xgmml/index.d.ts +1 -0
- package/dist/src/formats/xgmml/index.d.ts.map +1 -1
- package/dist/src/formats/xgmml/index.js +1 -0
- package/dist/src/formats/xgmml/index.js.map +1 -1
- package/dist/src/formats/xgmml/values.d.ts +8 -1
- package/dist/src/formats/xgmml/values.d.ts.map +1 -1
- package/dist/src/formats/xgmml/values.js +7 -2
- package/dist/src/formats/xgmml/values.js.map +1 -1
- package/dist/src/index.d.ts +23 -18
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +28 -16
- package/dist/src/index.js.map +1 -1
- package/dist/src/registry.d.ts +478 -92
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +807 -88
- package/dist/src/registry.js.map +1 -1
- package/dist/src/sniff.d.ts +61 -19
- package/dist/src/sniff.d.ts.map +1 -1
- package/dist/src/sniff.js +121 -29
- package/dist/src/sniff.js.map +1 -1
- package/dist/src/types.d.ts +362 -112
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +28 -7
- package/dist/src/types.js.map +1 -1
- package/dist/xgmml.js +2 -2
- package/docs/samples/README.md +25 -0
- package/docs/samples/got-edges.csv +353 -0
- package/docs/samples/got-network.graphml +1384 -0
- package/docs/samples/got-nodes.csv +108 -0
- package/docs/samples/got.cx +930 -0
- package/docs/samples/got.cx2 +465 -0
- package/docs/samples/got.gexf +471 -0
- package/docs/samples/got.gml +2650 -0
- package/docs/samples/got.json +2546 -0
- package/docs/samples/got.net +461 -0
- package/docs/samples/movies-nodes.csv +9 -0
- package/docs/samples/movies-rels.csv +8 -0
- package/docs/samples/networks.cys +0 -0
- package/docs/samples/proteins.xgmml +9 -0
- package/docs/samples/teams.gv +24 -0
- package/docs/samples/vehicles.obo +25 -0
- package/package.json +9 -4
- package/src/children.ts +18 -6
- package/src/common/attributes.ts +29 -11
- package/src/common/cell-budget.ts +11 -3
- package/src/common/choose.ts +89 -0
- package/src/common/codes.ts +490 -66
- package/src/common/compare.ts +472 -0
- package/src/common/cx-export.ts +432 -0
- package/src/common/declared-types.ts +38 -4
- package/src/common/direction.ts +78 -51
- package/src/common/escape.ts +33 -17
- package/src/common/export.ts +284 -47
- package/src/common/format.ts +30 -1
- package/src/common/ids.ts +14 -3
- package/src/common/input.ts +1057 -134
- package/src/common/json-elements.ts +1034 -198
- package/src/common/line-format.ts +249 -0
- package/src/common/lists.ts +6 -1
- package/src/common/ontology-export.ts +461 -0
- package/src/common/ontology.ts +31 -9
- package/src/common/options.ts +110 -15
- package/src/common/plural.ts +49 -0
- package/src/common/report.ts +168 -25
- package/src/common/temporal.ts +22 -5
- package/src/common/text.ts +62 -23
- package/src/common/weights.ts +74 -4
- package/src/common/writer.ts +37 -3
- package/src/common/xml.ts +477 -88
- package/src/common/zip.ts +169 -7
- package/src/formats/csv/exporter.ts +201 -46
- package/src/formats/csv/header.ts +50 -11
- package/src/formats/csv/importer.ts +1133 -245
- package/src/formats/csv/index.ts +106 -19
- package/src/formats/csv/records.ts +396 -122
- package/src/formats/csv/values.ts +1 -0
- package/src/formats/cx/exporter.ts +1483 -0
- package/src/formats/cx/importer.ts +888 -300
- package/src/formats/cx/index.ts +4 -3
- package/src/formats/cx2/exporter.ts +61 -338
- package/src/formats/cx2/importer.ts +317 -86
- package/src/formats/cx2/index.ts +2 -1
- package/src/formats/cys/constants.ts +62 -17
- package/src/formats/cys/exporter.ts +1368 -0
- package/src/formats/cys/importer.ts +659 -157
- package/src/formats/cys/index.ts +4 -2
- package/src/formats/cys/session.ts +139 -31
- package/src/formats/cys/tables.ts +47 -9
- package/src/formats/dot/exporter.ts +83 -37
- package/src/formats/dot/importer.ts +248 -54
- package/src/formats/dot/index.ts +2 -1
- package/src/formats/dot/names.ts +44 -11
- package/src/formats/dot/tokenizer.ts +25 -6
- package/src/formats/gexf/exporter.ts +57 -18
- package/src/formats/gexf/importer.ts +636 -105
- package/src/formats/gexf/index.ts +90 -21
- package/src/formats/gexf/schema.ts +67 -15
- package/src/formats/gml/exporter.ts +90 -36
- package/src/formats/gml/importer.ts +388 -67
- package/src/formats/gml/index.ts +85 -24
- package/src/formats/gml/syntax.ts +111 -26
- package/src/formats/graphml/constants.ts +178 -44
- package/src/formats/graphml/exporter.ts +52 -18
- package/src/formats/graphml/importer.ts +640 -60
- package/src/formats/graphml/index.ts +2 -1
- package/src/formats/graphml/tree.ts +6 -2
- package/src/formats/graphml/yfiles.ts +37 -15
- package/src/formats/json/dialect.ts +128 -29
- package/src/formats/json/exporter.ts +205 -68
- package/src/formats/json/importer.ts +1163 -253
- package/src/formats/json/index.ts +3 -1
- package/src/formats/json/obographs-export.ts +1197 -0
- package/src/formats/json/obographs.ts +353 -92
- package/src/formats/neo4j/exporter.ts +320 -101
- package/src/formats/neo4j/header.ts +44 -6
- package/src/formats/neo4j/importer.ts +512 -73
- package/src/formats/neo4j/index.ts +75 -23
- package/src/formats/obo/exporter.ts +2210 -0
- package/src/formats/obo/importer.ts +622 -109
- package/src/formats/obo/index.ts +6 -3
- package/src/formats/obo/syntax.ts +232 -37
- package/src/formats/pajek/exporter.ts +89 -41
- package/src/formats/pajek/importer.ts +407 -93
- package/src/formats/pajek/index.ts +2 -1
- package/src/formats/pajek/syntax.ts +213 -52
- package/src/formats/xgmml/columns.ts +10 -0
- package/src/formats/xgmml/constants.ts +183 -56
- package/src/formats/xgmml/document.ts +212 -34
- package/src/formats/xgmml/emit.ts +175 -34
- package/src/formats/xgmml/exporter.ts +35 -27
- package/src/formats/xgmml/importer.ts +64 -86
- package/src/formats/xgmml/index.ts +1 -0
- package/src/formats/xgmml/values.ts +11 -3
- package/src/index.ts +81 -11
- package/src/registry.ts +1121 -135
- package/src/sniff.ts +163 -32
- package/src/types.ts +385 -114
- package/dist/chunks/escape-B-tkk_Cl.js.map +0 -1
- package/dist/chunks/export-Bh60Dv-n.js +0 -582
- package/dist/chunks/export-Bh60Dv-n.js.map +0 -1
- package/dist/chunks/exporter-BGrsWamJ.js.map +0 -1
- package/dist/chunks/exporter-DIeGJXAZ.js.map +0 -1
- package/dist/chunks/importer-BWY2FFc5.js.map +0 -1
- package/dist/chunks/importer-DD-xv9_Y.js +0 -1471
- package/dist/chunks/importer-DD-xv9_Y.js.map +0 -1
- package/dist/chunks/importer-DET1tg6s.js.map +0 -1
- package/dist/chunks/importer-DEcKhsmQ.js +0 -1614
- package/dist/chunks/importer-DEcKhsmQ.js.map +0 -1
- package/dist/chunks/importer-DIrbbnAf.js.map +0 -1
- package/dist/chunks/importer-D_e7e7LX.js.map +0 -1
- package/dist/chunks/importer-eUREhBGj.js.map +0 -1
- package/dist/chunks/importer-vi3bSdtw.js.map +0 -1
- package/dist/chunks/importer-zGLo8Dg_.js.map +0 -1
- package/dist/chunks/json-elements-DDS8N2Dd.js +0 -779
- package/dist/chunks/json-elements-DDS8N2Dd.js.map +0 -1
- package/dist/chunks/ontology-BnrJ4I98.js +0 -113
- package/dist/chunks/ontology-BnrJ4I98.js.map +0 -1
- package/dist/chunks/records-dbRkxwaq.js.map +0 -1
- package/dist/chunks/report-B1z4WT9e.js +0 -2372
- package/dist/chunks/report-B1z4WT9e.js.map +0 -1
- package/dist/chunks/text-Dr0Ifpag.js.map +0 -1
- package/dist/chunks/weights-Dzba96G3.js +0 -176
- package/dist/chunks/weights-Dzba96G3.js.map +0 -1
- package/dist/chunks/writer-C7flM-Ih.js.map +0 -1
|
@@ -39,6 +39,7 @@ import { capabilities, checkCapabilities, LOSS } from "../../common/export.js";
|
|
|
39
39
|
import { formatF32, formatF64, formatInteger } from "../../common/format.js";
|
|
40
40
|
import { isCanonicalIntegerText } from "../../common/ids.js";
|
|
41
41
|
import { type ResolvedExportOptions, resolveExportOptions } from "../../common/options.js";
|
|
42
|
+
import { agree, plural } from "../../common/plural.js";
|
|
42
43
|
import { formatTemporal, type TemporalKind } from "../../common/temporal.js";
|
|
43
44
|
import { type ExplicitWeights, explicitWeights } from "../../common/weights.js";
|
|
44
45
|
import { encodeChunks, joinText } from "../../common/writer.js";
|
|
@@ -47,50 +48,100 @@ import { checkRecordSyntax, type RecordSyntax } from "../csv/records.js";
|
|
|
47
48
|
import { formatHeaderField } from "./header.js";
|
|
48
49
|
import { ID_SPACE_COLUMN, LABELS_COLUMN, TYPE_COLUMN } from "./importer.js";
|
|
49
50
|
|
|
50
|
-
/**
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
/**
|
|
52
|
+
* The format-specific options of the Neo4j exporter.
|
|
53
|
+
* @category Built-in formats
|
|
54
|
+
*/
|
|
55
|
+
export interface Neo4jExportOptions extends CommonExportOptions {
|
|
56
|
+
/**
|
|
57
|
+
* Which tables to write: "all" (the node sections, then the relationship sections), "nodes" or
|
|
58
|
+
* "relationships".
|
|
59
|
+
* @defaultValue "all"
|
|
60
|
+
*/
|
|
53
61
|
part?: "all" | "nodes" | "relationships" | undefined;
|
|
54
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* The field delimiter, one character. It must differ from `arrayDelimiter`: with
|
|
64
|
+
* `delimiter: ";"`, also pass `arrayDelimiter: ","` or `"|"`.
|
|
65
|
+
* @defaultValue ","
|
|
66
|
+
*/
|
|
55
67
|
delimiter?: string | undefined;
|
|
56
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* The delimiter inside list values and `:LABEL` cells. It must differ from `delimiter`.
|
|
70
|
+
* @defaultValue ";"
|
|
71
|
+
*/
|
|
57
72
|
arrayDelimiter?: ";" | "," | "|" | undefined;
|
|
58
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* The quote character, one character. Cells that hold the delimiter, the quote character or a
|
|
75
|
+
* line break are quoted with it. Pass the same value as the `quote` import option to read the
|
|
76
|
+
* file back.
|
|
77
|
+
* @defaultValue '"'
|
|
78
|
+
*/
|
|
59
79
|
quote?: string | undefined;
|
|
60
80
|
/**
|
|
61
|
-
* The property that
|
|
62
|
-
*
|
|
81
|
+
* The relationship property that holds the edge weights, written as `<name>:double`; null
|
|
82
|
+
* writes no weights (checkExport() then returns W_WEIGHTS_DROPPED). graph-io reads the
|
|
83
|
+
* "weight" property back as the weight; for any other name, pass the same name as the
|
|
84
|
+
* `weightFrom` import option to read the weights back (`weightColumn: "strength"` with
|
|
85
|
+
* `weightFrom: "strength"`), or they come back as a plain edge attribute. A graph read from Neo4j
|
|
86
|
+
* CSV with `weightFrom` writes its weights back under the property they were read from.
|
|
87
|
+
* @defaultValue "weight", or the property a Neo4j import read the weights from
|
|
63
88
|
*/
|
|
64
89
|
weightColumn?: string | null | undefined;
|
|
65
90
|
/**
|
|
66
|
-
* The property name of the `:ID` column for nodes that have no
|
|
67
|
-
*
|
|
91
|
+
* The property name of the `:ID` column (`<name>:ID`) for nodes that have no id property of
|
|
92
|
+
* their own; null writes a bare `:ID`.
|
|
93
|
+
* @defaultValue null
|
|
68
94
|
*/
|
|
69
95
|
idColumn?: string | null | undefined;
|
|
70
96
|
}
|
|
71
97
|
|
|
72
|
-
/**
|
|
98
|
+
/**
|
|
99
|
+
* Neo4j relationships are always directed, so the edges of an undirected graph, and the undirected edges of a mixed
|
|
100
|
+
* graph, read back as directed.
|
|
101
|
+
* @category Built-in formats
|
|
102
|
+
*/
|
|
73
103
|
export const UNDIRECTED_LOSS = "W_NEO4J_UNDIRECTED_AS_DIRECTED";
|
|
74
104
|
|
|
75
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Node ids that read back as a different type, such as the text "7" as the number 7.
|
|
107
|
+
* @category Built-in formats
|
|
108
|
+
*/
|
|
76
109
|
export const ID_TEXT_TYPE_LOSS = ID_TEXT_TYPE_CODE;
|
|
77
110
|
|
|
78
|
-
/**
|
|
111
|
+
/**
|
|
112
|
+
* Two node ids share one text; export() throws E_INVALID_ID.
|
|
113
|
+
* @category Built-in formats
|
|
114
|
+
*/
|
|
79
115
|
export const ID_TEXT_COLLISION_LOSS = ID_TEXT_COLLISION_CODE;
|
|
80
116
|
|
|
81
|
-
/**
|
|
117
|
+
/**
|
|
118
|
+
* The `weightColumn` name is already an edge attribute; the save fails.
|
|
119
|
+
* @category Built-in formats
|
|
120
|
+
*/
|
|
82
121
|
export const WEIGHT_COLUMN_TAKEN_LOSS = "E_NEO4J_WEIGHT_COLUMN_TAKEN";
|
|
83
122
|
|
|
84
|
-
/**
|
|
123
|
+
/**
|
|
124
|
+
* The `idColumn` name is already a node attribute; the save fails.
|
|
125
|
+
* @category Built-in formats
|
|
126
|
+
*/
|
|
85
127
|
export const ID_COLUMN_TAKEN_LOSS = "E_NEO4J_ID_COLUMN_TAKEN";
|
|
86
128
|
|
|
87
|
-
/**
|
|
129
|
+
/**
|
|
130
|
+
* A node has more than one stored-id column set; only the first is written.
|
|
131
|
+
* @category Built-in formats
|
|
132
|
+
*/
|
|
88
133
|
export const MULTIPLE_ID_PROPERTIES_LOSS = "W_NEO4J_MULTIPLE_ID_PROPERTIES";
|
|
89
134
|
|
|
90
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* A declared integer type holds non-integral values and is written as double.
|
|
137
|
+
* @category Built-in formats
|
|
138
|
+
*/
|
|
91
139
|
export const DECLARED_TYPE_CHANGED_LOSS = "W_NEO4J_DECLARED_TYPE_CHANGED";
|
|
92
140
|
|
|
93
|
-
/**
|
|
141
|
+
/**
|
|
142
|
+
* A list item contains the array delimiter, which Neo4j cannot escape.
|
|
143
|
+
* @category Built-in formats
|
|
144
|
+
*/
|
|
94
145
|
export const ARRAY_DELIMITER_LOSS = "W_NEO4J_ARRAY_DELIMITER";
|
|
95
146
|
|
|
96
147
|
/** The roles Neo4j has a slot for: `:TYPE`, `:LABEL` and the id space of `:ID(Space)`. */
|
|
@@ -110,10 +161,11 @@ const ROLE_NAMES: Readonly<Record<string, string>> = Object.freeze({
|
|
|
110
161
|
});
|
|
111
162
|
|
|
112
163
|
/**
|
|
113
|
-
* The capabilities of neo4j-admin CSV
|
|
164
|
+
* The capabilities of neo4j-admin CSV: declared scalar types and
|
|
114
165
|
* arrays; a dict column reads back as string (the header has no enumeration type); a position or
|
|
115
166
|
* visual column is written as a plain property (a point for a 2- or 3-component position) and
|
|
116
167
|
* reads back without its role.
|
|
168
|
+
* @category Built-in formats
|
|
117
169
|
*/
|
|
118
170
|
export const NEO4J_CAPABILITIES: ExportCapabilities = capabilities({
|
|
119
171
|
mixedDirection: false,
|
|
@@ -211,9 +263,13 @@ interface ColumnPlan {
|
|
|
211
263
|
/**
|
|
212
264
|
* Resolve the format options.
|
|
213
265
|
* @param options - the caller's options
|
|
266
|
+
* @param readFrom - the property a Neo4j import read the weights from, the default weightColumn
|
|
214
267
|
* @returns the resolved options; E_UNSUPPORTED for an invalid value
|
|
215
268
|
*/
|
|
216
|
-
function resolveNeo4jExportOptions(
|
|
269
|
+
function resolveNeo4jExportOptions(
|
|
270
|
+
options: Neo4jExportOptions | undefined,
|
|
271
|
+
readFrom: string | null,
|
|
272
|
+
): ResolvedNeo4jExportOptions {
|
|
217
273
|
const o: Neo4jExportOptions = options ?? {};
|
|
218
274
|
const part = o.part ?? "all";
|
|
219
275
|
if (!PARTS.has(part)) {
|
|
@@ -237,12 +293,16 @@ function resolveNeo4jExportOptions(options: Neo4jExportOptions | undefined): Res
|
|
|
237
293
|
const delimiter = o.delimiter ?? ",";
|
|
238
294
|
const syntax = { ...checkRecordSyntax({ delimiter, quote: o.quote ?? '"' }), delimiter };
|
|
239
295
|
if (syntax.delimiter === arrayDelimiter) {
|
|
240
|
-
throw new GraphFormatError(
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
296
|
+
throw new GraphFormatError(
|
|
297
|
+
"E_UNSUPPORTED",
|
|
298
|
+
`options delimiter and arrayDelimiter must differ: both are ${JSON.stringify(arrayDelimiter)}; pass another arrayDelimiter (";", "," or "|")`,
|
|
299
|
+
{
|
|
300
|
+
option: "arrayDelimiter",
|
|
301
|
+
found: arrayDelimiter,
|
|
302
|
+
},
|
|
303
|
+
);
|
|
244
304
|
}
|
|
245
|
-
const weightColumn = o.weightColumn === undefined ? "weight" : o.weightColumn;
|
|
305
|
+
const weightColumn = o.weightColumn === undefined ? (readFrom ?? "weight") : o.weightColumn;
|
|
246
306
|
if (weightColumn !== null && (typeof weightColumn !== "string" || weightColumn.length === 0)) {
|
|
247
307
|
throw new GraphFormatError("E_UNSUPPORTED", "option weightColumn: expected a non-empty name or null", {
|
|
248
308
|
option: "weightColumn",
|
|
@@ -329,6 +389,7 @@ class ExportPlan {
|
|
|
329
389
|
roles: SLOT_ROLES,
|
|
330
390
|
roleNames: ROLE_NAMES,
|
|
331
391
|
temporalText: true,
|
|
392
|
+
weights: options.weightColumn !== null,
|
|
332
393
|
});
|
|
333
394
|
this.planColumns("node", snapshot.nodes, this.nodeColumns);
|
|
334
395
|
this.planColumns("edge", snapshot.edges, this.edgeColumns);
|
|
@@ -380,7 +441,7 @@ class ExportPlan {
|
|
|
380
441
|
if (!snapshot.directed) {
|
|
381
442
|
this.note(
|
|
382
443
|
UNDIRECTED_LOSS,
|
|
383
|
-
`the snapshot is undirected; every edge is written as a directed relationship (${snapshot.edgeCount} edge(
|
|
444
|
+
`the snapshot is undirected; every edge is written as a directed relationship (${snapshot.edgeCount} edge${plural(snapshot.edgeCount)})`,
|
|
384
445
|
null,
|
|
385
446
|
snapshot.edgeCount,
|
|
386
447
|
);
|
|
@@ -394,7 +455,7 @@ class ExportPlan {
|
|
|
394
455
|
if (undirected > 0) {
|
|
395
456
|
this.note(
|
|
396
457
|
UNDIRECTED_LOSS,
|
|
397
|
-
`${undirected} undirected edge(
|
|
458
|
+
`${undirected} undirected edge${plural(undirected)} ${agree(undirected, "is", "are")} written as one directed relationship each (source to target, a pair folded to its primary); Neo4j has no undirected relationship`,
|
|
398
459
|
null,
|
|
399
460
|
undirected,
|
|
400
461
|
);
|
|
@@ -403,7 +464,7 @@ class ExportPlan {
|
|
|
403
464
|
if (folding.mutualCount > 0) {
|
|
404
465
|
this.note(
|
|
405
466
|
LOSS.MUTUAL_EXPANDED,
|
|
406
|
-
`${folding.mutualCount} mutual pair(
|
|
467
|
+
`${folding.mutualCount} mutual pair${plural(folding.mutualCount)} ${agree(folding.mutualCount, "is", "are")} written as two directed relationships; the mutual mark is lost`,
|
|
407
468
|
null,
|
|
408
469
|
folding.mutualCount,
|
|
409
470
|
);
|
|
@@ -612,7 +673,7 @@ class ExportPlan {
|
|
|
612
673
|
if (rows > 0) {
|
|
613
674
|
this.note(
|
|
614
675
|
ARRAY_DELIMITER_LOSS,
|
|
615
|
-
`${label}: ${rows} row(
|
|
676
|
+
`${label}: ${rows} row${plural(rows)} ${agree(rows, "holds", "hold")} an item containing the array delimiter "${arrayDelimiter}", which Neo4j cannot escape`,
|
|
616
677
|
column.meta.name,
|
|
617
678
|
rows,
|
|
618
679
|
);
|
|
@@ -648,7 +709,7 @@ class ExportPlan {
|
|
|
648
709
|
} else if (taken !== undefined && name === DEFAULT_WEIGHT_COLUMN) {
|
|
649
710
|
this.note(
|
|
650
711
|
LOSS.WEIGHT_KEY_CLASH,
|
|
651
|
-
`edge column "${name}" is written under the property the importer reads
|
|
712
|
+
`edge column "${name}" is written under the property the importer reads edge weights from (weightFrom "${name}"); it reads back as the weight, not as a column`,
|
|
652
713
|
name,
|
|
653
714
|
taken.column.length - taken.column.nullCount,
|
|
654
715
|
);
|
|
@@ -703,7 +764,7 @@ class ExportPlan {
|
|
|
703
764
|
if (typeChanges > 0) {
|
|
704
765
|
this.note(
|
|
705
766
|
ID_TEXT_TYPE_LOSS,
|
|
706
|
-
`${typeChanges} node id(
|
|
767
|
+
`${typeChanges} node id${plural(typeChanges)} re-import as another type under the canonical id rule (a string of canonical integer text, or a non-integer number)`,
|
|
707
768
|
null,
|
|
708
769
|
typeChanges,
|
|
709
770
|
);
|
|
@@ -711,13 +772,13 @@ class ExportPlan {
|
|
|
711
772
|
if (collisions > 0) {
|
|
712
773
|
this.note(
|
|
713
774
|
ID_TEXT_COLLISION_LOSS,
|
|
714
|
-
`${collisions} node id(
|
|
775
|
+
`${collisions} node id${plural(collisions)} ${agree(collisions, "shares", "share")} their text with another id (a number and a string); the save fails`,
|
|
715
776
|
null,
|
|
716
777
|
collisions,
|
|
717
778
|
);
|
|
718
779
|
this.fatalAll = new GraphFormatError(
|
|
719
780
|
"E_INVALID_ID",
|
|
720
|
-
`${collisions} node id(
|
|
781
|
+
`${collisions} node id${plural(collisions)} ${agree(collisions, "shares", "share")} their text with another id; Neo4j ids are text`,
|
|
721
782
|
{ reason: "text collision", count: collisions },
|
|
722
783
|
);
|
|
723
784
|
}
|
|
@@ -770,7 +831,7 @@ class ExportPlan {
|
|
|
770
831
|
if (count > 0) {
|
|
771
832
|
this.note(
|
|
772
833
|
MULTIPLE_ID_PROPERTIES_LOSS,
|
|
773
|
-
`${count} node(
|
|
834
|
+
`${count} node${plural(count)} ${agree(count, "has", "have")} more than one stored-id column set; only the first in declaration order is written`,
|
|
774
835
|
null,
|
|
775
836
|
count,
|
|
776
837
|
);
|
|
@@ -877,6 +938,17 @@ class ExportPlan {
|
|
|
877
938
|
* @returns nothing
|
|
878
939
|
*/
|
|
879
940
|
*lines(): Generator<string, void, undefined> {
|
|
941
|
+
for (const row of this.rows()) {
|
|
942
|
+
yield row.line;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
/**
|
|
947
|
+
* The lines of the requested part, each header line tagged with the file it starts.
|
|
948
|
+
* @yields one line at a time, with the file name on a header line
|
|
949
|
+
* @returns nothing
|
|
950
|
+
*/
|
|
951
|
+
*rows(): Generator<SectionLine, void, undefined> {
|
|
880
952
|
if (this.fatal !== null) {
|
|
881
953
|
throw this.fatal;
|
|
882
954
|
}
|
|
@@ -889,19 +961,53 @@ class ExportPlan {
|
|
|
889
961
|
}
|
|
890
962
|
}
|
|
891
963
|
|
|
964
|
+
/**
|
|
965
|
+
* The requested part as one file per section kind: a node file per id space (and stored-id
|
|
966
|
+
* property), a relationship file per pair of endpoint id spaces, rows of one kind gathered
|
|
967
|
+
* under one header.
|
|
968
|
+
* @returns the files, node files first
|
|
969
|
+
*/
|
|
970
|
+
files(): Neo4jFile[] {
|
|
971
|
+
// keyed by the header row: sections with the same header are one file
|
|
972
|
+
const files = new Map<string, { name: string; kind: "nodes" | "relationships"; rows: string[] }>();
|
|
973
|
+
const names = new Set<string>();
|
|
974
|
+
let current: { rows: string[] } | null = null;
|
|
975
|
+
for (const row of this.rows()) {
|
|
976
|
+
if (row.file !== null) {
|
|
977
|
+
let file = files.get(row.line);
|
|
978
|
+
if (file === undefined) {
|
|
979
|
+
let name = `${row.file.name}.csv`;
|
|
980
|
+
let k = 2;
|
|
981
|
+
while (names.has(name)) {
|
|
982
|
+
name = `${row.file.name}-${k}.csv`;
|
|
983
|
+
k++;
|
|
984
|
+
}
|
|
985
|
+
names.add(name);
|
|
986
|
+
file = { name, kind: row.file.kind, rows: [] };
|
|
987
|
+
files.set(row.line, file);
|
|
988
|
+
}
|
|
989
|
+
current = file;
|
|
990
|
+
} else if (current !== null) {
|
|
991
|
+
current.rows.push(row.line);
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
// a part with no rows (a graph without edges) is a header alone, which neo4j-admin does not need
|
|
995
|
+
const written = [...files].filter(([, f], i) => f.rows.length > 0 || (i === 0 && files.size === 1));
|
|
996
|
+
return written.map(([header, f]) =>
|
|
997
|
+
Object.freeze({ name: f.name, kind: f.kind, text: header + f.rows.join("") }),
|
|
998
|
+
);
|
|
999
|
+
}
|
|
1000
|
+
|
|
892
1001
|
/**
|
|
893
1002
|
* The node sections.
|
|
894
1003
|
* @yields one line at a time
|
|
895
1004
|
* @returns nothing
|
|
896
1005
|
*/
|
|
897
|
-
private *nodeLines(): Generator<
|
|
898
|
-
const { snapshot
|
|
899
|
-
const { delimiter } = this.options.syntax;
|
|
900
|
-
const propertyHeaders = nodeColumns.map((plan) => plan.header).join(delimiter);
|
|
1006
|
+
private *nodeLines(): Generator<SectionLine, void, undefined> {
|
|
1007
|
+
const { snapshot } = this;
|
|
901
1008
|
let sections = 0;
|
|
902
1009
|
let sectionSpace: string | null = null;
|
|
903
1010
|
let sectionIdName: string | null = null;
|
|
904
|
-
const cells: string[] = [];
|
|
905
1011
|
for (let i = 0; i < snapshot.nodeCount; i++) {
|
|
906
1012
|
const space = this.spaceOf(i);
|
|
907
1013
|
const stored = this.storedIdOf(i);
|
|
@@ -910,36 +1016,50 @@ class ExportPlan {
|
|
|
910
1016
|
sections++;
|
|
911
1017
|
sectionSpace = space;
|
|
912
1018
|
sectionIdName = idName;
|
|
913
|
-
|
|
914
|
-
if (labels !== null) {
|
|
915
|
-
header.push(":LABEL");
|
|
916
|
-
}
|
|
917
|
-
if (propertyHeaders.length > 0) {
|
|
918
|
-
header.push(propertyHeaders);
|
|
919
|
-
}
|
|
920
|
-
yield `${header.join(delimiter)}\n`;
|
|
1019
|
+
yield this.nodeHeader(idName, space, space ?? idName);
|
|
921
1020
|
}
|
|
922
|
-
|
|
923
|
-
cells.push(this.cell(this.idTextOf(i)));
|
|
924
|
-
if (labels !== null) {
|
|
925
|
-
cells.push(this.cell(this.labelsText(i)));
|
|
926
|
-
}
|
|
927
|
-
for (const plan of nodeColumns) {
|
|
928
|
-
cells.push(this.cell(this.valueText(plan, i)));
|
|
929
|
-
}
|
|
930
|
-
yield `${cells.join(delimiter)}\n`;
|
|
1021
|
+
yield { line: this.nodeRow(i), file: null };
|
|
931
1022
|
}
|
|
932
1023
|
if (sections === 0) {
|
|
933
1024
|
// no nodes: one header so the section (and its columns) still exists
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
1025
|
+
yield this.nodeHeader(this.options.idColumn ?? "", null, null);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
/**
|
|
1030
|
+
* The header line of a node section, which starts its file.
|
|
1031
|
+
* @param idName - the id column's name
|
|
1032
|
+
* @param space - the id space, or null
|
|
1033
|
+
* @param fileKey - what names the file, or null for the default name
|
|
1034
|
+
* @returns the line
|
|
1035
|
+
*/
|
|
1036
|
+
private nodeHeader(idName: string, space: string | null, fileKey: string | null): SectionLine {
|
|
1037
|
+
const { delimiter } = this.options.syntax;
|
|
1038
|
+
const header = [formatHeaderField(idName, ID_TYPE, space)];
|
|
1039
|
+
if (this.labels !== null) {
|
|
1040
|
+
header.push(":LABEL");
|
|
1041
|
+
}
|
|
1042
|
+
const properties = this.nodeColumns.map((plan) => plan.header).join(delimiter);
|
|
1043
|
+
if (properties.length > 0) {
|
|
1044
|
+
header.push(properties);
|
|
942
1045
|
}
|
|
1046
|
+
return { line: `${header.join(delimiter)}\n`, file: { kind: "nodes", name: fileName("nodes", fileKey, null) } };
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
/**
|
|
1050
|
+
* One node's line: the id, the labels, the properties.
|
|
1051
|
+
* @param i - the node
|
|
1052
|
+
* @returns the line
|
|
1053
|
+
*/
|
|
1054
|
+
private nodeRow(i: number): string {
|
|
1055
|
+
const cells = [this.cell(this.idTextOf(i))];
|
|
1056
|
+
if (this.labels !== null) {
|
|
1057
|
+
cells.push(this.cell(this.labelsText(i)));
|
|
1058
|
+
}
|
|
1059
|
+
for (const plan of this.nodeColumns) {
|
|
1060
|
+
cells.push(this.cell(this.valueText(plan, i)));
|
|
1061
|
+
}
|
|
1062
|
+
return `${cells.join(this.options.syntax.delimiter)}\n`;
|
|
943
1063
|
}
|
|
944
1064
|
|
|
945
1065
|
/**
|
|
@@ -947,30 +1067,12 @@ class ExportPlan {
|
|
|
947
1067
|
* @yields one line at a time
|
|
948
1068
|
* @returns nothing
|
|
949
1069
|
*/
|
|
950
|
-
private *relationshipLines(): Generator<
|
|
951
|
-
const { snapshot,
|
|
952
|
-
const { delimiter } = this.options.syntax;
|
|
1070
|
+
private *relationshipLines(): Generator<SectionLine, void, undefined> {
|
|
1071
|
+
const { snapshot, folding } = this;
|
|
953
1072
|
const list = snapshot.edgeList();
|
|
954
|
-
const propertyHeaders = edgeColumns.map((plan) => plan.header).join(delimiter);
|
|
955
|
-
const weightHeader =
|
|
956
|
-
weights === null ? null : formatHeaderField(this.options.weightColumn ?? "weight", "double", null);
|
|
957
1073
|
let sections = 0;
|
|
958
1074
|
let sectionStart: string | null = null;
|
|
959
1075
|
let sectionEnd: string | null = null;
|
|
960
|
-
const cells: string[] = [];
|
|
961
|
-
const headerOf = (startSpace: string | null, endSpace: string | null): string => {
|
|
962
|
-
const header = [formatHeaderField("", "START_ID", startSpace), formatHeaderField("", "END_ID", endSpace)];
|
|
963
|
-
if (kind !== null) {
|
|
964
|
-
header.push(":TYPE");
|
|
965
|
-
}
|
|
966
|
-
if (weightHeader !== null) {
|
|
967
|
-
header.push(weightHeader);
|
|
968
|
-
}
|
|
969
|
-
if (propertyHeaders.length > 0) {
|
|
970
|
-
header.push(propertyHeaders);
|
|
971
|
-
}
|
|
972
|
-
return `${header.join(delimiter)}\n`;
|
|
973
|
-
};
|
|
974
1076
|
for (let e = 0; e < snapshot.edgeCount; e++) {
|
|
975
1077
|
if (folding.folded(e)) {
|
|
976
1078
|
continue;
|
|
@@ -983,24 +1085,60 @@ class ExportPlan {
|
|
|
983
1085
|
sections++;
|
|
984
1086
|
sectionStart = startSpace;
|
|
985
1087
|
sectionEnd = endSpace;
|
|
986
|
-
yield
|
|
987
|
-
}
|
|
988
|
-
cells.length = 0;
|
|
989
|
-
cells.push(this.cell(this.idTextOf(u)), this.cell(this.idTextOf(v)));
|
|
990
|
-
if (kind !== null) {
|
|
991
|
-
cells.push(this.cell(kind.isSet(e) ? textOf(kind, e) : null));
|
|
992
|
-
}
|
|
993
|
-
if (weights !== null) {
|
|
994
|
-
cells.push(this.cell(weights.text(e)));
|
|
995
|
-
}
|
|
996
|
-
for (const plan of edgeColumns) {
|
|
997
|
-
cells.push(this.cell(this.valueText(plan, e)));
|
|
1088
|
+
yield this.relationshipHeader(startSpace, endSpace);
|
|
998
1089
|
}
|
|
999
|
-
yield
|
|
1090
|
+
yield { line: this.relationshipRow(e, u, v), file: null };
|
|
1000
1091
|
}
|
|
1001
1092
|
if (sections === 0) {
|
|
1002
|
-
yield
|
|
1093
|
+
yield this.relationshipHeader(null, null);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
/**
|
|
1098
|
+
* The header line of a relationship section, which starts its file.
|
|
1099
|
+
* @param startSpace - the id space of the start nodes, or null
|
|
1100
|
+
* @param endSpace - the id space of the end nodes, or null
|
|
1101
|
+
* @returns the line
|
|
1102
|
+
*/
|
|
1103
|
+
private relationshipHeader(startSpace: string | null, endSpace: string | null): SectionLine {
|
|
1104
|
+
const { delimiter } = this.options.syntax;
|
|
1105
|
+
const header = [formatHeaderField("", "START_ID", startSpace), formatHeaderField("", "END_ID", endSpace)];
|
|
1106
|
+
if (this.kind !== null) {
|
|
1107
|
+
header.push(":TYPE");
|
|
1108
|
+
}
|
|
1109
|
+
if (this.weights !== null) {
|
|
1110
|
+
header.push(formatHeaderField(this.options.weightColumn ?? "weight", "double", null));
|
|
1111
|
+
}
|
|
1112
|
+
const properties = this.edgeColumns.map((plan) => plan.header).join(delimiter);
|
|
1113
|
+
if (properties.length > 0) {
|
|
1114
|
+
header.push(properties);
|
|
1115
|
+
}
|
|
1116
|
+
return {
|
|
1117
|
+
line: `${header.join(delimiter)}\n`,
|
|
1118
|
+
file: { kind: "relationships", name: fileName("relationships", startSpace, endSpace) },
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
/**
|
|
1123
|
+
* One relationship's line: the ends, the type, the weight, the properties.
|
|
1124
|
+
* @param e - the edge
|
|
1125
|
+
* @param u - its source
|
|
1126
|
+
* @param v - its target
|
|
1127
|
+
* @returns the line
|
|
1128
|
+
*/
|
|
1129
|
+
private relationshipRow(e: number, u: number, v: number): string {
|
|
1130
|
+
const { kind, weights } = this;
|
|
1131
|
+
const cells = [this.cell(this.idTextOf(u)), this.cell(this.idTextOf(v))];
|
|
1132
|
+
if (kind !== null) {
|
|
1133
|
+
cells.push(this.cell(kind.isSet(e) ? textOf(kind, e) : null));
|
|
1003
1134
|
}
|
|
1135
|
+
if (weights !== null) {
|
|
1136
|
+
cells.push(this.cell(weights.text(e)));
|
|
1137
|
+
}
|
|
1138
|
+
for (const plan of this.edgeColumns) {
|
|
1139
|
+
cells.push(this.cell(this.valueText(plan, e)));
|
|
1140
|
+
}
|
|
1141
|
+
return `${cells.join(this.options.syntax.delimiter)}\n`;
|
|
1004
1142
|
}
|
|
1005
1143
|
|
|
1006
1144
|
/**
|
|
@@ -1017,7 +1155,7 @@ class ExportPlan {
|
|
|
1017
1155
|
if (text.length === 0) {
|
|
1018
1156
|
return quote + quote;
|
|
1019
1157
|
}
|
|
1020
|
-
return quoteCsvCell(text, this.options.syntax.delimiter);
|
|
1158
|
+
return quoteCsvCell(text, this.options.syntax.delimiter, quote);
|
|
1021
1159
|
}
|
|
1022
1160
|
|
|
1023
1161
|
/**
|
|
@@ -1281,9 +1419,13 @@ function textOf(column: Column, row: number): string {
|
|
|
1281
1419
|
}
|
|
1282
1420
|
}
|
|
1283
1421
|
|
|
1284
|
-
/**
|
|
1422
|
+
/**
|
|
1423
|
+
* The Neo4j exporter.
|
|
1424
|
+
* @category Built-in formats
|
|
1425
|
+
*/
|
|
1285
1426
|
export const neo4jExporter: GraphExporter<Neo4jExportOptions> = Object.freeze({
|
|
1286
1427
|
format: NEO4J,
|
|
1428
|
+
options: Object.freeze(["arrayDelimiter", "delimiter", "idColumn", "part", "quote", "weightColumn"]),
|
|
1287
1429
|
capabilities: NEO4J_CAPABILITIES,
|
|
1288
1430
|
/**
|
|
1289
1431
|
* Pre-flight: what export() would lose.
|
|
@@ -1314,6 +1456,68 @@ export const neo4jExporter: GraphExporter<Neo4jExportOptions> = Object.freeze({
|
|
|
1314
1456
|
},
|
|
1315
1457
|
});
|
|
1316
1458
|
|
|
1459
|
+
/** One line of the export; a header line names the file it starts. */
|
|
1460
|
+
interface SectionLine {
|
|
1461
|
+
readonly line: string;
|
|
1462
|
+
readonly file: { readonly kind: "nodes" | "relationships"; readonly name: string } | null;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
/**
|
|
1466
|
+
* One file of exportNeo4jFiles(): the header row and the rows of one section kind.
|
|
1467
|
+
* @category Built-in formats
|
|
1468
|
+
*/
|
|
1469
|
+
export interface Neo4jFile {
|
|
1470
|
+
/** A file name made from the section: `nodes-Movie.csv`, `relationships-Person-Movie.csv`, or `nodes.csv` and `relationships.csv` without id spaces. */
|
|
1471
|
+
readonly name: string;
|
|
1472
|
+
/** Whether neo4j-admin takes the file with `--nodes` or with `--relationships`. */
|
|
1473
|
+
readonly kind: "nodes" | "relationships";
|
|
1474
|
+
/** The CSV text, one header row first. */
|
|
1475
|
+
readonly text: string;
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
/**
|
|
1479
|
+
* The file name of a section, without ".csv": the kind, then the id spaces that set it apart.
|
|
1480
|
+
* @param kind - "nodes" or "relationships"
|
|
1481
|
+
* @param first - the id space or id property (nodes), or the start id space (relationships)
|
|
1482
|
+
* @param second - the end id space (relationships)
|
|
1483
|
+
* @returns the name, with characters outside letters, digits, "." , "_" and "-" replaced by "_"
|
|
1484
|
+
*/
|
|
1485
|
+
function fileName(kind: string, first: string | null, second: string | null): string {
|
|
1486
|
+
const parts = [kind, first ?? "", second ?? ""].filter((p) => p !== "");
|
|
1487
|
+
return parts.join("-").replaceAll(/[^\w.-]/g, "_");
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
/**
|
|
1491
|
+
* Write a graph as the separate CSV files `neo4j-admin database import` takes: one node file per id
|
|
1492
|
+
* space and one relationship file per pair of endpoint id spaces, each with a single header row.
|
|
1493
|
+
* `exportGraph(snapshot, "neo4j")` writes the same sections into one file, which graph-io reads
|
|
1494
|
+
* back but neo4j-admin does not, since it reads one header per file. The options are the Neo4j
|
|
1495
|
+
* export options (`part` limits the result to the node or the relationship files), and
|
|
1496
|
+
* `checkExport(snapshot, "neo4j", options)` returns what the files lose.
|
|
1497
|
+
* @param snapshot - the graph to write
|
|
1498
|
+
* @param options - the Neo4j export options
|
|
1499
|
+
* @returns the files, node files first
|
|
1500
|
+
* @category Built-in formats
|
|
1501
|
+
* @example
|
|
1502
|
+
* ```ts
|
|
1503
|
+
* for (const file of await exportNeo4jFiles(snapshot)) {
|
|
1504
|
+
* await writeFile(file.name, file.text);
|
|
1505
|
+
* }
|
|
1506
|
+
* // neo4j-admin database import full --nodes=nodes-Movie.csv --nodes=nodes-Person.csv \
|
|
1507
|
+
* // --relationships=relationships-Person-Movie.csv neo4j
|
|
1508
|
+
* ```
|
|
1509
|
+
*/
|
|
1510
|
+
export function exportNeo4jFiles(
|
|
1511
|
+
snapshot: GraphSnapshot,
|
|
1512
|
+
options?: Neo4jExportOptions & CommonExportOptions,
|
|
1513
|
+
): Promise<Neo4jFile[]> {
|
|
1514
|
+
try {
|
|
1515
|
+
return Promise.resolve(plan(snapshot, options).files());
|
|
1516
|
+
} catch (err) {
|
|
1517
|
+
return Promise.reject(err as Error);
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1317
1521
|
/**
|
|
1318
1522
|
* Build the export plan of a snapshot.
|
|
1319
1523
|
* @param snapshot - the snapshot
|
|
@@ -1321,5 +1525,20 @@ export const neo4jExporter: GraphExporter<Neo4jExportOptions> = Object.freeze({
|
|
|
1321
1525
|
* @returns the plan
|
|
1322
1526
|
*/
|
|
1323
1527
|
function plan(snapshot: GraphSnapshot, options: (Neo4jExportOptions & CommonExportOptions) | undefined): ExportPlan {
|
|
1324
|
-
return new ExportPlan(
|
|
1528
|
+
return new ExportPlan(
|
|
1529
|
+
snapshot,
|
|
1530
|
+
resolveNeo4jExportOptions(options, weightPropertyOf(snapshot)),
|
|
1531
|
+
resolveExportOptions(options),
|
|
1532
|
+
);
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
/**
|
|
1536
|
+
* The relationship property a Neo4j import read the weights from, when it was not "weight".
|
|
1537
|
+
* @param snapshot - the snapshot
|
|
1538
|
+
* @returns the property name, or null
|
|
1539
|
+
*/
|
|
1540
|
+
function weightPropertyOf(snapshot: GraphSnapshot): string | null {
|
|
1541
|
+
const neo4j = (snapshot.meta.extra as { neo4j?: { weightProperty?: unknown } } | null)?.neo4j;
|
|
1542
|
+
const name = neo4j?.weightProperty;
|
|
1543
|
+
return typeof name === "string" && name !== "" ? name : null;
|
|
1325
1544
|
}
|