@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
|
@@ -0,0 +1,1225 @@
|
|
|
1
|
+
import { GraphFormatError, INVALID_INDEX } from "@graphty/graph-format";
|
|
2
|
+
import { V as BAD_ASPECT_BLOCK_CODE, W as MULTI_ASPECT_FRAGMENT_CODE, Y as ASPECT_ORDER_CODE, j as COUNT_MISMATCH_CODE, Z as STATUS_FAILED_CODE, _ as STATUS_WARNING_CODE, b as plural, $ as agree, a0 as uniqueColumnName, C as COLUMN_RENAMED_CODE, a1 as declareResolved, a2 as JSON_NONSTANDARD_NUMBER_CODE, o as DUPLICATE_ATTRIBUTE_CODE, P as PRECISION_CODE, a3 as BAD_VALUE_CODE } from "./export-BTI4yQgy.js";
|
|
3
|
+
import { t as trimTrailingZeros } from "./text-DmcUs5_Q.js";
|
|
4
|
+
const MAYBE_UNSAFE_INTEGER = new RegExp("(?<![0-9.])[0-9]{16}");
|
|
5
|
+
const MAYBE_INEXACT_EXPONENT = new RegExp(
|
|
6
|
+
[
|
|
7
|
+
/\d[eE]\+?0*(?:1[5-9]|[2-9]\d|[1-9]\d{2,})/,
|
|
8
|
+
// an exponent of 15 or more
|
|
9
|
+
/\d[eE]-0*(?:[3-9]\d{2}|[1-9]\d{3,})/,
|
|
10
|
+
// an exponent of -300 or less
|
|
11
|
+
new RegExp("(?<![\\d.])(?=(?:\\d\\.?){16})\\d+\\.\\d+[eE]")
|
|
12
|
+
// 16 or more digits split by a decimal point
|
|
13
|
+
].map((r) => r.source).join("|")
|
|
14
|
+
);
|
|
15
|
+
const SENTINEL = `${String.fromCodePoint(0)}graph-io`;
|
|
16
|
+
const NONSTANDARD_TOKENS = [
|
|
17
|
+
["-Infinity", -Infinity],
|
|
18
|
+
["Infinity", Infinity],
|
|
19
|
+
["NaN", NaN]
|
|
20
|
+
];
|
|
21
|
+
const INTEGER_LITERAL = /^-?(0|[1-9][0-9]*)$/;
|
|
22
|
+
const NUMBER_PARTS = /^(-?)(\d+)(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/;
|
|
23
|
+
function sentinelFor(text) {
|
|
24
|
+
let haystack = text;
|
|
25
|
+
if (/\\u0000/i.test(text)) {
|
|
26
|
+
const decoded = [];
|
|
27
|
+
for (const [literal] of text.matchAll(/"(?:[^"\\]|\\.)*"/g)) {
|
|
28
|
+
if (literal.includes("\\")) {
|
|
29
|
+
decoded.push(decodeString(literal));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
haystack = `${decoded.join("\n")}
|
|
33
|
+
${text}`;
|
|
34
|
+
}
|
|
35
|
+
let k = 0;
|
|
36
|
+
while (haystack.includes(`graph-io${k === 0 ? "" : String(k)}:`)) {
|
|
37
|
+
k++;
|
|
38
|
+
}
|
|
39
|
+
return `${SENTINEL}${k === 0 ? "" : String(k)}:`;
|
|
40
|
+
}
|
|
41
|
+
function decodeString(literal) {
|
|
42
|
+
try {
|
|
43
|
+
return String(JSON.parse(literal));
|
|
44
|
+
} catch {
|
|
45
|
+
return literal;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function isInexactLiteral(literal) {
|
|
49
|
+
const value = Number(literal);
|
|
50
|
+
if (!Number.isFinite(value)) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
if (value === 0) {
|
|
54
|
+
return /[1-9]/.test(literal.split(/[eE]/)[0]);
|
|
55
|
+
}
|
|
56
|
+
if (Number.isSafeInteger(value) || !Number.isInteger(value)) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
const m = NUMBER_PARTS.exec(literal);
|
|
60
|
+
if (m === null) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
const digits = trimTrailingZeros(m[2] + (m[3] ?? ""));
|
|
64
|
+
const exponent = Number(m[4] ?? "0") - (m[3] ?? "").length + ((m[2] + (m[3] ?? "")).length - digits.length);
|
|
65
|
+
if (digits.replace(/^0+/, "").length <= 15 || exponent < 0) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
const exact = BigInt(digits) * 10n ** BigInt(exponent);
|
|
69
|
+
return exact !== BigInt(Math.abs(value));
|
|
70
|
+
}
|
|
71
|
+
function rewriteNumbers(text, options = {}) {
|
|
72
|
+
const nonstandard = options.nonstandard ?? true;
|
|
73
|
+
const exactSentinel = options.exactSentinel ?? false;
|
|
74
|
+
const sentinel = sentinelFor(text);
|
|
75
|
+
const exactPrefix = `${sentinel}exact:`;
|
|
76
|
+
const parts = [];
|
|
77
|
+
const tokens = /* @__PURE__ */ new Set();
|
|
78
|
+
const bigIntegers = [];
|
|
79
|
+
const inexact = [];
|
|
80
|
+
const arrays = [];
|
|
81
|
+
let expectValue = true;
|
|
82
|
+
let copied = 0;
|
|
83
|
+
let i = 0;
|
|
84
|
+
const n = text.length;
|
|
85
|
+
while (i < n) {
|
|
86
|
+
const ch = text[i];
|
|
87
|
+
if (ch === '"') {
|
|
88
|
+
i++;
|
|
89
|
+
while (i < n && text[i] !== '"') {
|
|
90
|
+
i += text[i] === "\\" ? 2 : 1;
|
|
91
|
+
}
|
|
92
|
+
i++;
|
|
93
|
+
expectValue = false;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (ch === "{" || ch === "[") {
|
|
97
|
+
arrays.push(ch === "[");
|
|
98
|
+
expectValue = ch === "[";
|
|
99
|
+
} else if (ch === "}" || ch === "]") {
|
|
100
|
+
arrays.pop();
|
|
101
|
+
expectValue = false;
|
|
102
|
+
} else if (ch === ":") {
|
|
103
|
+
expectValue = true;
|
|
104
|
+
} else if (ch === ",") {
|
|
105
|
+
expectValue = arrays.length > 0 && arrays[arrays.length - 1];
|
|
106
|
+
} else if (expectValue && ch !== " " && ch !== " " && ch !== "\n" && ch !== "\r") {
|
|
107
|
+
expectValue = false;
|
|
108
|
+
const token = nonstandard ? NONSTANDARD_TOKENS.find(([word]) => text.startsWith(word, i)) : void 0;
|
|
109
|
+
let end = i;
|
|
110
|
+
let replacement = null;
|
|
111
|
+
if (token !== void 0) {
|
|
112
|
+
end = i + token[0].length;
|
|
113
|
+
tokens.add(token[0]);
|
|
114
|
+
replacement = JSON.stringify(`${sentinel}${token[0]}`);
|
|
115
|
+
} else if (ch === "-" || ch >= "0" && ch <= "9") {
|
|
116
|
+
end = i + 1;
|
|
117
|
+
while (end < n && "0123456789+-.eE".includes(text[end])) {
|
|
118
|
+
end++;
|
|
119
|
+
}
|
|
120
|
+
const literal = text.slice(i, end);
|
|
121
|
+
if (INTEGER_LITERAL.test(literal)) {
|
|
122
|
+
if (!Number.isSafeInteger(Number(literal))) {
|
|
123
|
+
bigIntegers.push(literal);
|
|
124
|
+
replacement = exactSentinel ? JSON.stringify(`${exactPrefix}${literal}`) : `"${literal}"`;
|
|
125
|
+
}
|
|
126
|
+
} else if (isInexactLiteral(literal)) {
|
|
127
|
+
inexact.push(literal);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (replacement !== null) {
|
|
131
|
+
parts.push(text.slice(copied, i), replacement);
|
|
132
|
+
copied = end;
|
|
133
|
+
}
|
|
134
|
+
i = Math.max(end, i + 1);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
i++;
|
|
138
|
+
}
|
|
139
|
+
parts.push(text.slice(copied));
|
|
140
|
+
const revive = (_key, value) => {
|
|
141
|
+
if (typeof value === "string" && value.startsWith(sentinel)) {
|
|
142
|
+
const found = NONSTANDARD_TOKENS.find(([word]) => word === value.slice(sentinel.length));
|
|
143
|
+
return found === void 0 ? value : found[1];
|
|
144
|
+
}
|
|
145
|
+
return value;
|
|
146
|
+
};
|
|
147
|
+
const reviveExact = (_key, value) => typeof value === "string" && value.startsWith(exactPrefix) ? new ExactInteger(value.slice(exactPrefix.length)) : value;
|
|
148
|
+
return { text: parts.join(""), tokens, bigIntegers, inexact, revive, reviveExact };
|
|
149
|
+
}
|
|
150
|
+
const LINEAR_KEYS = 32;
|
|
151
|
+
function findDuplicateKeys(text) {
|
|
152
|
+
const found = [];
|
|
153
|
+
const spans = [];
|
|
154
|
+
const wide = [];
|
|
155
|
+
let depth = 0;
|
|
156
|
+
const n = text.length;
|
|
157
|
+
let at = 0;
|
|
158
|
+
while (at < n) {
|
|
159
|
+
const c = text.codePointAt(at);
|
|
160
|
+
if (c === 123 || c === 91) {
|
|
161
|
+
openContainer(spans, wide, depth, c === 91);
|
|
162
|
+
depth++;
|
|
163
|
+
} else if (c === 125 || c === 93) {
|
|
164
|
+
depth--;
|
|
165
|
+
} else if (c === 34) {
|
|
166
|
+
const end = closingQuote(text, at + 1);
|
|
167
|
+
const keys = depth > 0 ? spans[depth - 1] : null;
|
|
168
|
+
const isObjectKey = keys !== null && keys[0] !== -1 && isKey(text, end + 1);
|
|
169
|
+
if (isObjectKey && isRepeated(text, at + 1, end, keys, wide, depth - 1)) {
|
|
170
|
+
found.push({ key: text.slice(at + 1, end), offset: at });
|
|
171
|
+
}
|
|
172
|
+
at = end;
|
|
173
|
+
}
|
|
174
|
+
at++;
|
|
175
|
+
}
|
|
176
|
+
return found;
|
|
177
|
+
}
|
|
178
|
+
function openContainer(spans, wide, depth, isArray) {
|
|
179
|
+
if (spans.length === depth) {
|
|
180
|
+
spans.push([]);
|
|
181
|
+
wide.push(null);
|
|
182
|
+
}
|
|
183
|
+
spans[depth].length = 0;
|
|
184
|
+
if (isArray) {
|
|
185
|
+
spans[depth].push(-1);
|
|
186
|
+
}
|
|
187
|
+
wide[depth] = null;
|
|
188
|
+
}
|
|
189
|
+
function isRepeated(text, start, end, keys, wide, level) {
|
|
190
|
+
const set = wide[level];
|
|
191
|
+
if (set !== null) {
|
|
192
|
+
const key = text.slice(start, end);
|
|
193
|
+
return set.has(key) || (set.add(key), false);
|
|
194
|
+
}
|
|
195
|
+
const length = end - start;
|
|
196
|
+
for (let k = 0; k < keys.length; k += 2) {
|
|
197
|
+
if (keys[k + 1] - keys[k] === length && sameText(text, keys[k], start, length)) {
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
keys.push(start, end);
|
|
202
|
+
if (keys.length > 2 * LINEAR_KEYS) {
|
|
203
|
+
const all = /* @__PURE__ */ new Set();
|
|
204
|
+
for (let k = 0; k < keys.length; k += 2) {
|
|
205
|
+
all.add(text.slice(keys[k], keys[k + 1]));
|
|
206
|
+
}
|
|
207
|
+
wide[level] = all;
|
|
208
|
+
}
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
function sameText(text, a, b, length) {
|
|
212
|
+
for (let i = 0; i < length; i++) {
|
|
213
|
+
if (text.codePointAt(a + i) !== text.codePointAt(b + i)) {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return true;
|
|
218
|
+
}
|
|
219
|
+
function closingQuote(text, from) {
|
|
220
|
+
for (let q = text.indexOf('"', from); q >= 0; q = text.indexOf('"', q + 1)) {
|
|
221
|
+
let backslashes = 0;
|
|
222
|
+
while (text.codePointAt(q - 1 - backslashes) === 92) {
|
|
223
|
+
backslashes++;
|
|
224
|
+
}
|
|
225
|
+
if (backslashes % 2 === 0) {
|
|
226
|
+
return q;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return text.length;
|
|
230
|
+
}
|
|
231
|
+
function isKey(text, from) {
|
|
232
|
+
let i = from;
|
|
233
|
+
while (i < text.length && isSpace(text.codePointAt(i))) {
|
|
234
|
+
i++;
|
|
235
|
+
}
|
|
236
|
+
return text.codePointAt(i) === 58;
|
|
237
|
+
}
|
|
238
|
+
class ExactInteger {
|
|
239
|
+
/**
|
|
240
|
+
* Wrap the digits of an integer literal.
|
|
241
|
+
* @param digits - the literal
|
|
242
|
+
*/
|
|
243
|
+
constructor(digits) {
|
|
244
|
+
this.digits = digits;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* The nearest number (JSON.stringify writes it as such).
|
|
248
|
+
* @returns the number
|
|
249
|
+
*/
|
|
250
|
+
toJSON() {
|
|
251
|
+
return Number(this.digits);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function parseExact(text) {
|
|
255
|
+
if (!MAYBE_UNSAFE_INTEGER.test(text)) {
|
|
256
|
+
return { value: JSON.parse(text), exact: false };
|
|
257
|
+
}
|
|
258
|
+
const scan = rewriteNumbers(text, { nonstandard: false, exactSentinel: true });
|
|
259
|
+
if (scan.bigIntegers.length === 0) {
|
|
260
|
+
return { value: JSON.parse(text), exact: false };
|
|
261
|
+
}
|
|
262
|
+
return { value: JSON.parse(scan.text, scan.reviveExact), exact: true };
|
|
263
|
+
}
|
|
264
|
+
function plainJson(value, onPrecision) {
|
|
265
|
+
if (value instanceof ExactInteger) {
|
|
266
|
+
onPrecision?.(value.digits);
|
|
267
|
+
return Number(value.digits);
|
|
268
|
+
}
|
|
269
|
+
if (Array.isArray(value)) {
|
|
270
|
+
return value.map((item) => plainJson(item, onPrecision));
|
|
271
|
+
}
|
|
272
|
+
if (typeof value === "object" && value !== null) {
|
|
273
|
+
const out = {};
|
|
274
|
+
for (const [key, item] of Object.entries(value)) {
|
|
275
|
+
setOwn(out, key, plainJson(item, onPrecision));
|
|
276
|
+
}
|
|
277
|
+
return out;
|
|
278
|
+
}
|
|
279
|
+
return value;
|
|
280
|
+
}
|
|
281
|
+
function setOwn(target, key, value) {
|
|
282
|
+
if (key === "__proto__") {
|
|
283
|
+
Object.defineProperty(target, key, { value, enumerable: true, writable: true, configurable: true });
|
|
284
|
+
} else {
|
|
285
|
+
target[key] = value;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
function parseNonstandard(text) {
|
|
289
|
+
if (!/NaN|Infinity/.test(text)) {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
const scan = rewriteNumbers(text, { nonstandard: true, exactSentinel: true });
|
|
293
|
+
if (scan.tokens.size === 0) {
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
try {
|
|
297
|
+
const value = JSON.parse(scan.text, (key, raw) => scan.reviveExact(key, scan.revive(key, raw)));
|
|
298
|
+
return { value, exact: scan.bigIntegers.length > 0, tokens: scan.tokens };
|
|
299
|
+
} catch {
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
const SURROGATE_ESCAPES = String.raw`\uD800-\uDFFF`;
|
|
304
|
+
const LONE_SURROGATE = new RegExp("[\\ud800-\\udbff](?![\\udc00-\\udfff])|(?<![\\ud800-\\udbff])[\\udc00-\\udfff]", "g");
|
|
305
|
+
const MAYBE_SURROGATE = /\\u[dD][89a-fA-F]|[\ud800-\udfff]/;
|
|
306
|
+
function repairSurrogates(value, fixed) {
|
|
307
|
+
if (typeof value === "string") {
|
|
308
|
+
const repaired = value.replaceAll(LONE_SURROGATE, "�");
|
|
309
|
+
if (repaired !== value) {
|
|
310
|
+
fixed.count++;
|
|
311
|
+
}
|
|
312
|
+
return repaired;
|
|
313
|
+
}
|
|
314
|
+
if (Array.isArray(value)) {
|
|
315
|
+
for (let i = 0; i < value.length; i++) {
|
|
316
|
+
value[i] = repairSurrogates(value[i], fixed);
|
|
317
|
+
}
|
|
318
|
+
return value;
|
|
319
|
+
}
|
|
320
|
+
if (isRecord(value)) {
|
|
321
|
+
const keys = Object.keys(value);
|
|
322
|
+
const repairedKeys = keys.map((key) => key.replaceAll(LONE_SURROGATE, "�"));
|
|
323
|
+
const renamed = repairedKeys.some((key, i) => key !== keys[i]);
|
|
324
|
+
const out = renamed ? {} : value;
|
|
325
|
+
keys.forEach((key, i) => {
|
|
326
|
+
if (repairedKeys[i] !== key) {
|
|
327
|
+
fixed.count++;
|
|
328
|
+
}
|
|
329
|
+
if (renamed && Object.hasOwn(out, repairedKeys[i])) {
|
|
330
|
+
fixed.collisions.push(repairedKeys[i]);
|
|
331
|
+
}
|
|
332
|
+
setOwn(out, repairedKeys[i], repairSurrogates(value[key], fixed));
|
|
333
|
+
});
|
|
334
|
+
return out;
|
|
335
|
+
}
|
|
336
|
+
return value;
|
|
337
|
+
}
|
|
338
|
+
function keyCount(value) {
|
|
339
|
+
if (Array.isArray(value)) {
|
|
340
|
+
return value.reduce((n, item) => n + keyCount(item), 0);
|
|
341
|
+
}
|
|
342
|
+
if (isRecord(value)) {
|
|
343
|
+
return Object.keys(value).reduce((n, key) => n + 1 + keyCount(value[key]), 0);
|
|
344
|
+
}
|
|
345
|
+
return 0;
|
|
346
|
+
}
|
|
347
|
+
function duplicateKey(text) {
|
|
348
|
+
const stack = [];
|
|
349
|
+
let i = 0;
|
|
350
|
+
while (i < text.length) {
|
|
351
|
+
const c = text[i];
|
|
352
|
+
if (c === "{") {
|
|
353
|
+
stack.push(/* @__PURE__ */ new Set());
|
|
354
|
+
} else if (c === "[") {
|
|
355
|
+
stack.push(null);
|
|
356
|
+
} else if (c === "}" || c === "]") {
|
|
357
|
+
stack.pop();
|
|
358
|
+
} else if (c === '"') {
|
|
359
|
+
const start = i;
|
|
360
|
+
i = stringEnd(text, i + 1);
|
|
361
|
+
const keys = stack.at(-1) ?? null;
|
|
362
|
+
if (keys !== null && text[skipSpace(text, i + 1)] === ":") {
|
|
363
|
+
const key = JSON.parse(text.slice(start, i + 1));
|
|
364
|
+
if (keys.has(key)) {
|
|
365
|
+
return key;
|
|
366
|
+
}
|
|
367
|
+
keys.add(key);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
i++;
|
|
371
|
+
}
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
function stringEnd(text, from) {
|
|
375
|
+
let i = from;
|
|
376
|
+
while (i < text.length && text[i] !== '"') {
|
|
377
|
+
i += text[i] === "\\" ? 2 : 1;
|
|
378
|
+
}
|
|
379
|
+
return i;
|
|
380
|
+
}
|
|
381
|
+
function skipSpace(text, from) {
|
|
382
|
+
let i = from;
|
|
383
|
+
while (i < text.length && isSpace(text.codePointAt(i))) {
|
|
384
|
+
i++;
|
|
385
|
+
}
|
|
386
|
+
return i;
|
|
387
|
+
}
|
|
388
|
+
const KEY_COLON = /"\s*:/g;
|
|
389
|
+
function checkParsed(text, parsed, line, report) {
|
|
390
|
+
let value = parsed;
|
|
391
|
+
if (MAYBE_SURROGATE.test(text)) {
|
|
392
|
+
const fixed = { count: 0, collisions: [] };
|
|
393
|
+
value = repairSurrogates(value, fixed);
|
|
394
|
+
for (const key of fixed.collisions) {
|
|
395
|
+
report.warnOnce(
|
|
396
|
+
"validation-error",
|
|
397
|
+
DUPLICATE_ATTRIBUTE_CODE,
|
|
398
|
+
`an object holds two keys that are the same key ${JSON.stringify(key)} once their lone surrogates are replaced with U+FFFD; the later value is read`,
|
|
399
|
+
{ line, element: key },
|
|
400
|
+
`${DUPLICATE_ATTRIBUTE_CODE}:json:${key}`
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
if (fixed.count > 0) {
|
|
404
|
+
report.error(
|
|
405
|
+
"validation-error",
|
|
406
|
+
BAD_VALUE_CODE,
|
|
407
|
+
`${fixed.count} string${plural(fixed.count)} ${agree(fixed.count, "holds", "hold")} a lone surrogate (an unpaired ${SURROGATE_ESCAPES} escape); each is read with U+FFFD in its place`,
|
|
408
|
+
{ line }
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (typeof value === "object" && value !== null && (text.match(KEY_COLON)?.length ?? 0) > keyCount(value)) {
|
|
413
|
+
const key = duplicateKey(text);
|
|
414
|
+
if (key !== null) {
|
|
415
|
+
report.warnOnce(
|
|
416
|
+
"validation-error",
|
|
417
|
+
DUPLICATE_ATTRIBUTE_CODE,
|
|
418
|
+
`an object holds the key ${JSON.stringify(key)} twice; the later value is read`,
|
|
419
|
+
{ line, element: key },
|
|
420
|
+
`${DUPLICATE_ATTRIBUTE_CODE}:json:${key}`
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
return value;
|
|
425
|
+
}
|
|
426
|
+
class JsonScanError extends Error {
|
|
427
|
+
/**
|
|
428
|
+
* Create the error.
|
|
429
|
+
* @param message - what is wrong
|
|
430
|
+
* @param line - the 1-based line
|
|
431
|
+
* @param empty - whether the input is empty
|
|
432
|
+
*/
|
|
433
|
+
constructor(message, line, empty = false) {
|
|
434
|
+
super(message);
|
|
435
|
+
this.name = "JsonScanError";
|
|
436
|
+
this.line = line;
|
|
437
|
+
this.empty = empty;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
const isSpace = (c) => c === 32 || c === 10 || c === 13 || c === 9;
|
|
441
|
+
const endsScalar = (c) => isSpace(c) || c === 44 || c === 93 || c === 125 || c === 58;
|
|
442
|
+
const QUOTE_OR_BACKSLASH = /["\\]/g;
|
|
443
|
+
const MAX_ELEMENT_DEPTH = 200;
|
|
444
|
+
class ChunkCursor {
|
|
445
|
+
/**
|
|
446
|
+
* Wrap text chunks.
|
|
447
|
+
* @param chunks - the decoded text
|
|
448
|
+
*/
|
|
449
|
+
constructor(chunks) {
|
|
450
|
+
this.buf = "";
|
|
451
|
+
this.pos = 0;
|
|
452
|
+
this.linesBefore = 1;
|
|
453
|
+
this.parts = null;
|
|
454
|
+
this.captureStart = 0;
|
|
455
|
+
this.deepest = 0;
|
|
456
|
+
this.iterator = chunks[Symbol.asyncIterator]();
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Read the next chunk once the current one is consumed.
|
|
460
|
+
* @returns false at the end of the input
|
|
461
|
+
*/
|
|
462
|
+
async fill() {
|
|
463
|
+
if (this.parts !== null) {
|
|
464
|
+
this.parts.push(this.buf.slice(this.captureStart));
|
|
465
|
+
this.captureStart = 0;
|
|
466
|
+
}
|
|
467
|
+
this.linesBefore += countNewlines(this.buf, 0, this.buf.length);
|
|
468
|
+
const endsWithCr = this.buf.endsWith("\r");
|
|
469
|
+
for (; ; ) {
|
|
470
|
+
const next = await this.iterator.next();
|
|
471
|
+
if (next.done === true) {
|
|
472
|
+
this.buf = "";
|
|
473
|
+
this.pos = 0;
|
|
474
|
+
return false;
|
|
475
|
+
}
|
|
476
|
+
if (next.value.length > 0) {
|
|
477
|
+
if (endsWithCr && next.value.startsWith("\n")) {
|
|
478
|
+
this.linesBefore--;
|
|
479
|
+
}
|
|
480
|
+
this.buf = next.value;
|
|
481
|
+
this.pos = 0;
|
|
482
|
+
return true;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* The 1-based line of the read position.
|
|
488
|
+
* @returns the line
|
|
489
|
+
*/
|
|
490
|
+
line() {
|
|
491
|
+
return this.linesBefore + countNewlines(this.buf, 0, Math.min(this.pos, this.buf.length));
|
|
492
|
+
}
|
|
493
|
+
/**
|
|
494
|
+
* The text from the read position to the end of the current chunk, at most `length` characters.
|
|
495
|
+
* @param length - the most characters
|
|
496
|
+
* @returns the text
|
|
497
|
+
*/
|
|
498
|
+
ahead(length) {
|
|
499
|
+
return this.buf.slice(this.pos, this.pos + length);
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Skip whitespace and return the next character without consuming it.
|
|
503
|
+
* @returns the character, or "" at the end of the input
|
|
504
|
+
*/
|
|
505
|
+
async peek() {
|
|
506
|
+
for (; ; ) {
|
|
507
|
+
while (this.pos < this.buf.length && isSpace(this.buf.charCodeAt(this.pos))) {
|
|
508
|
+
this.pos++;
|
|
509
|
+
}
|
|
510
|
+
if (this.pos < this.buf.length) {
|
|
511
|
+
return this.buf[this.pos];
|
|
512
|
+
}
|
|
513
|
+
if (!await this.fill()) {
|
|
514
|
+
return "";
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
/** Start keeping the text from the read position. */
|
|
519
|
+
beginCapture() {
|
|
520
|
+
this.parts = [];
|
|
521
|
+
this.captureStart = this.pos;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Stop keeping text.
|
|
525
|
+
* @returns the text kept since beginCapture()
|
|
526
|
+
*/
|
|
527
|
+
endCapture() {
|
|
528
|
+
const parts = this.parts ?? [];
|
|
529
|
+
parts.push(this.buf.slice(this.captureStart, this.pos));
|
|
530
|
+
this.parts = null;
|
|
531
|
+
return parts.length === 1 ? parts[0] : parts.join("");
|
|
532
|
+
}
|
|
533
|
+
/** Drop the capture without building its text. */
|
|
534
|
+
dropCapture() {
|
|
535
|
+
this.parts = null;
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Advance past one JSON value starting at the read position (which holds its first
|
|
539
|
+
* character), tracking strings and nesting only; the value is validated when it is parsed.
|
|
540
|
+
* @param startDepth - the nesting depth already entered (1 when the opening brace was consumed)
|
|
541
|
+
*/
|
|
542
|
+
async skipValue(startDepth = 0) {
|
|
543
|
+
let depth = startDepth;
|
|
544
|
+
this.deepest = depth;
|
|
545
|
+
if (depth === 0) {
|
|
546
|
+
const c = this.buf.charCodeAt(this.pos);
|
|
547
|
+
if (c === 34) {
|
|
548
|
+
this.pos++;
|
|
549
|
+
await this.skipString();
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
if (c !== 123 && c !== 91) {
|
|
553
|
+
await this.skipScalar();
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
for (; ; ) {
|
|
558
|
+
if (this.pos >= this.buf.length && !await this.fill()) {
|
|
559
|
+
throw new JsonScanError("the document ends inside a value", this.line());
|
|
560
|
+
}
|
|
561
|
+
const c = this.buf.charCodeAt(this.pos);
|
|
562
|
+
this.pos++;
|
|
563
|
+
if (c === 34) {
|
|
564
|
+
await this.skipString();
|
|
565
|
+
} else if (c === 123 || c === 91) {
|
|
566
|
+
depth++;
|
|
567
|
+
if (depth > this.deepest) {
|
|
568
|
+
this.deepest = depth;
|
|
569
|
+
}
|
|
570
|
+
} else if (c === 125 || c === 93) {
|
|
571
|
+
depth--;
|
|
572
|
+
if (depth === 0) {
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
/** Advance past the rest of a string whose opening quote was consumed. */
|
|
579
|
+
async skipString() {
|
|
580
|
+
for (; ; ) {
|
|
581
|
+
QUOTE_OR_BACKSLASH.lastIndex = this.pos;
|
|
582
|
+
const found = QUOTE_OR_BACKSLASH.exec(this.buf);
|
|
583
|
+
if (found === null) {
|
|
584
|
+
this.pos = this.buf.length;
|
|
585
|
+
if (!await this.fill()) {
|
|
586
|
+
throw new JsonScanError("the document ends inside a string", this.line());
|
|
587
|
+
}
|
|
588
|
+
continue;
|
|
589
|
+
}
|
|
590
|
+
this.pos = found.index + 1;
|
|
591
|
+
if (found[0] === '"') {
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
if (this.pos >= this.buf.length && !await this.fill()) {
|
|
595
|
+
throw new JsonScanError("the document ends inside a string", this.line());
|
|
596
|
+
}
|
|
597
|
+
this.pos++;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
/** Advance past a bare scalar (a number, true, false, null or a stray word). */
|
|
601
|
+
async skipScalar() {
|
|
602
|
+
for (; ; ) {
|
|
603
|
+
while (this.pos < this.buf.length && !endsScalar(this.buf.charCodeAt(this.pos))) {
|
|
604
|
+
this.pos++;
|
|
605
|
+
}
|
|
606
|
+
if (this.pos < this.buf.length || !await this.fill()) {
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Read one JSON string literal at the read position (its opening quote).
|
|
613
|
+
* @returns the decoded string
|
|
614
|
+
*/
|
|
615
|
+
async readString() {
|
|
616
|
+
this.beginCapture();
|
|
617
|
+
this.pos++;
|
|
618
|
+
await this.skipString();
|
|
619
|
+
const literal = this.endCapture();
|
|
620
|
+
try {
|
|
621
|
+
return JSON.parse(literal);
|
|
622
|
+
} catch (err) {
|
|
623
|
+
throw new JsonScanError(`invalid string: ${messageOf(err)}`, this.line());
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
function countNewlines(text, from, to) {
|
|
628
|
+
let count = 0;
|
|
629
|
+
let i = text.indexOf("\n", from);
|
|
630
|
+
while (i >= 0 && i < to) {
|
|
631
|
+
count++;
|
|
632
|
+
i = text.indexOf("\n", i + 1);
|
|
633
|
+
}
|
|
634
|
+
i = text.indexOf("\r", from);
|
|
635
|
+
while (i >= 0 && i < to) {
|
|
636
|
+
if (text[i + 1] !== "\n") {
|
|
637
|
+
count++;
|
|
638
|
+
}
|
|
639
|
+
i = text.indexOf("\r", i + 1);
|
|
640
|
+
}
|
|
641
|
+
return count;
|
|
642
|
+
}
|
|
643
|
+
function messageOf(err) {
|
|
644
|
+
return err instanceof Error ? err.message : String(err);
|
|
645
|
+
}
|
|
646
|
+
function parseAt(text, line, report) {
|
|
647
|
+
let parsed;
|
|
648
|
+
try {
|
|
649
|
+
parsed = parseExact(text);
|
|
650
|
+
} catch (err) {
|
|
651
|
+
const recovered = report === null ? null : parseNonstandard(text);
|
|
652
|
+
if (recovered === null) {
|
|
653
|
+
throw new JsonScanError(`invalid JSON: ${messageOf(err)}`, line);
|
|
654
|
+
}
|
|
655
|
+
report?.warnOnce(
|
|
656
|
+
"coercion",
|
|
657
|
+
JSON_NONSTANDARD_NUMBER_CODE,
|
|
658
|
+
`the document uses the non-standard token${plural(recovered.tokens.size)} ${[...recovered.tokens].join(", ")}, which strict JSON does not allow; read as numbers`,
|
|
659
|
+
{ line }
|
|
660
|
+
);
|
|
661
|
+
parsed = recovered;
|
|
662
|
+
}
|
|
663
|
+
if (report !== null) {
|
|
664
|
+
parsed = { ...parsed, value: checkParsed(text, parsed.value, line, report) };
|
|
665
|
+
}
|
|
666
|
+
return parsed;
|
|
667
|
+
}
|
|
668
|
+
function notJsonHint(head) {
|
|
669
|
+
if (head.startsWith("<")) {
|
|
670
|
+
return "; the input looks like HTML or XML (an error page saved as the file?), not JSON";
|
|
671
|
+
}
|
|
672
|
+
if (head.startsWith("PK")) {
|
|
673
|
+
return "; the input is a ZIP archive (a Cytoscape session .cys is read by the cys importer), not JSON";
|
|
674
|
+
}
|
|
675
|
+
return "";
|
|
676
|
+
}
|
|
677
|
+
async function* scanAspects(chunks, report = null) {
|
|
678
|
+
const cur = new ChunkCursor(chunks);
|
|
679
|
+
const first = await cur.peek();
|
|
680
|
+
if (first === "") {
|
|
681
|
+
throw new JsonScanError("the input is empty", 1, true);
|
|
682
|
+
}
|
|
683
|
+
const hint = notJsonHint(cur.ahead(16));
|
|
684
|
+
if (hint === "" && cur.ahead(8).includes(String.fromCodePoint(0))) {
|
|
685
|
+
throw new JsonScanError(
|
|
686
|
+
'the input holds NUL characters: UTF-16 without a byte order mark (pass the encoding option, such as "utf-16le"), or binary data; not JSON',
|
|
687
|
+
cur.line()
|
|
688
|
+
);
|
|
689
|
+
}
|
|
690
|
+
if (first === "[") {
|
|
691
|
+
cur.pos++;
|
|
692
|
+
yield* members(cur, report);
|
|
693
|
+
return;
|
|
694
|
+
}
|
|
695
|
+
const line = cur.line();
|
|
696
|
+
if (first === "{") {
|
|
697
|
+
yield { kind: "root", value: void 0, object: true, line };
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
yield { kind: "root", value: await scalarRoot(cur, line, hint), object: false, line };
|
|
701
|
+
}
|
|
702
|
+
async function scalarRoot(cur, line, hint) {
|
|
703
|
+
cur.beginCapture();
|
|
704
|
+
await cur.skipValue();
|
|
705
|
+
let value;
|
|
706
|
+
try {
|
|
707
|
+
({ value } = parseAt(cur.endCapture(), line, null));
|
|
708
|
+
} catch (err) {
|
|
709
|
+
if (err instanceof JsonScanError && hint !== "") {
|
|
710
|
+
throw new JsonScanError(`${err.message}${hint}`, err.line);
|
|
711
|
+
}
|
|
712
|
+
throw err;
|
|
713
|
+
}
|
|
714
|
+
if (await cur.peek() !== "") {
|
|
715
|
+
throw new JsonScanError("unexpected text after the document", cur.line());
|
|
716
|
+
}
|
|
717
|
+
return value;
|
|
718
|
+
}
|
|
719
|
+
async function* members(cur, report) {
|
|
720
|
+
let block = 0;
|
|
721
|
+
let next = await cur.peek();
|
|
722
|
+
if (next === "]") {
|
|
723
|
+
cur.pos++;
|
|
724
|
+
}
|
|
725
|
+
while (next !== "]") {
|
|
726
|
+
yield* member(cur, block, report);
|
|
727
|
+
block++;
|
|
728
|
+
next = await cur.peek();
|
|
729
|
+
if (next !== "," && next !== "]") {
|
|
730
|
+
throw new JsonScanError(
|
|
731
|
+
next === "" ? "the document ends before its closing bracket" : `expected "," or "]", found "${next}"`,
|
|
732
|
+
cur.line()
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
cur.pos++;
|
|
736
|
+
}
|
|
737
|
+
if (await cur.peek() !== "") {
|
|
738
|
+
throw new JsonScanError("unexpected text after the closing bracket", cur.line());
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
async function* member(cur, block, report) {
|
|
742
|
+
const c = await cur.peek();
|
|
743
|
+
const line = cur.line();
|
|
744
|
+
if (c === "" || c === "]" || c === ",") {
|
|
745
|
+
throw new JsonScanError(c === "" ? "the document ends inside its array" : `unexpected "${c}"`, line);
|
|
746
|
+
}
|
|
747
|
+
cur.beginCapture();
|
|
748
|
+
if (c !== "{") {
|
|
749
|
+
await cur.skipValue();
|
|
750
|
+
yield wholeMember(cur, block, line, report);
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
cur.pos++;
|
|
754
|
+
if (await cur.peek() !== '"') {
|
|
755
|
+
await cur.skipValue(1);
|
|
756
|
+
yield wholeMember(cur, block, line, report);
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
const outer = cur.endCapture();
|
|
760
|
+
const firstLine = cur.line();
|
|
761
|
+
const keys = { others: [], firstBlock: null, deep: 0 };
|
|
762
|
+
let next = ",";
|
|
763
|
+
let index = 0;
|
|
764
|
+
while (next === ",") {
|
|
765
|
+
const key = await readKey(cur);
|
|
766
|
+
yield* keyValue(cur, key, index, block, keys, report);
|
|
767
|
+
index++;
|
|
768
|
+
next = await cur.peek();
|
|
769
|
+
if (next !== "," && next !== "}") {
|
|
770
|
+
throw new JsonScanError(
|
|
771
|
+
next === "" ? "the document ends inside a member" : `expected "," or "}" after the key "${key.name}"`,
|
|
772
|
+
cur.line()
|
|
773
|
+
);
|
|
774
|
+
}
|
|
775
|
+
cur.pos++;
|
|
776
|
+
}
|
|
777
|
+
yield* memberEnd(keys, block, line, { outer, firstLine }, report);
|
|
778
|
+
}
|
|
779
|
+
function wholeMember(cur, block, line, report) {
|
|
780
|
+
if (cur.deepest > MAX_ELEMENT_DEPTH) {
|
|
781
|
+
cur.dropCapture();
|
|
782
|
+
return { kind: "deep", aspect: null, block, depth: cur.deepest, line };
|
|
783
|
+
}
|
|
784
|
+
const text = cur.endCapture();
|
|
785
|
+
const parsed = parseAt(text, line, report);
|
|
786
|
+
return { kind: "member", block, value: parsed.value, exact: parsed.exact, text, line };
|
|
787
|
+
}
|
|
788
|
+
async function readKey(cur) {
|
|
789
|
+
if (await cur.peek() !== '"') {
|
|
790
|
+
throw new JsonScanError("expected a key", cur.line());
|
|
791
|
+
}
|
|
792
|
+
const line = cur.line();
|
|
793
|
+
const name = await cur.readString();
|
|
794
|
+
if (await cur.peek() !== ":") {
|
|
795
|
+
throw new JsonScanError(`expected ":" after the key "${name}"`, cur.line());
|
|
796
|
+
}
|
|
797
|
+
cur.pos++;
|
|
798
|
+
return { name, line };
|
|
799
|
+
}
|
|
800
|
+
async function* keyValue(cur, key, index, block, keys, report) {
|
|
801
|
+
if (await cur.peek() === "[") {
|
|
802
|
+
cur.pos++;
|
|
803
|
+
yield { kind: "block", aspect: key.name, block, shared: index > 0, line: key.line };
|
|
804
|
+
keys.firstBlock ??= key.name;
|
|
805
|
+
yield* blockElements(cur, key.name, block, report);
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
cur.beginCapture();
|
|
809
|
+
await cur.skipValue();
|
|
810
|
+
if (cur.deepest + 1 > MAX_ELEMENT_DEPTH) {
|
|
811
|
+
cur.dropCapture();
|
|
812
|
+
keys.deep = Math.max(keys.deep, cur.deepest + 1);
|
|
813
|
+
keys.others.push({ key: key.name, text: null, line: key.line });
|
|
814
|
+
} else {
|
|
815
|
+
keys.others.push({ key: key.name, text: cur.endCapture(), line: key.line });
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
function* memberEnd(keys, block, line, start, report) {
|
|
819
|
+
const { others, firstBlock, deep } = keys;
|
|
820
|
+
if (firstBlock !== null) {
|
|
821
|
+
for (const other of others) {
|
|
822
|
+
if (other.text !== null) {
|
|
823
|
+
parseAt(other.text, other.line, null);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
if (others.length > 0) {
|
|
827
|
+
yield {
|
|
828
|
+
kind: "extraKeys",
|
|
829
|
+
aspect: firstBlock,
|
|
830
|
+
block,
|
|
831
|
+
keys: others.map((o) => o.key),
|
|
832
|
+
line: others[0].line
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
if (deep > 0) {
|
|
838
|
+
yield { kind: "deep", aspect: others[0].key, block, depth: deep, line };
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
const members2 = others.map((o) => [JSON.stringify(o.key), o.text ?? ""].join(":"));
|
|
842
|
+
const text = `${start.outer}${members2.join(",")}}`;
|
|
843
|
+
const parsed = parseAt(text, start.firstLine, report);
|
|
844
|
+
yield { kind: "member", block, value: parsed.value, exact: parsed.exact, text, line };
|
|
845
|
+
}
|
|
846
|
+
async function* blockElements(cur, aspect, block, report) {
|
|
847
|
+
if (await cur.peek() === "]") {
|
|
848
|
+
cur.pos++;
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
for (; ; ) {
|
|
852
|
+
const e = await cur.peek();
|
|
853
|
+
if (e === "") {
|
|
854
|
+
throw new JsonScanError(`the document ends inside the "${aspect}" block`, cur.line());
|
|
855
|
+
}
|
|
856
|
+
const elementLine = cur.line();
|
|
857
|
+
cur.beginCapture();
|
|
858
|
+
await cur.skipValue();
|
|
859
|
+
if (cur.deepest > MAX_ELEMENT_DEPTH) {
|
|
860
|
+
cur.dropCapture();
|
|
861
|
+
yield { kind: "deep", aspect, block, depth: cur.deepest, line: elementLine };
|
|
862
|
+
} else {
|
|
863
|
+
const text = cur.endCapture();
|
|
864
|
+
const parsed = parseAt(text, elementLine, report);
|
|
865
|
+
yield {
|
|
866
|
+
kind: "element",
|
|
867
|
+
aspect,
|
|
868
|
+
block,
|
|
869
|
+
value: parsed.value,
|
|
870
|
+
exact: parsed.exact,
|
|
871
|
+
text,
|
|
872
|
+
line: elementLine
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
const next = await cur.peek();
|
|
876
|
+
if (next === ",") {
|
|
877
|
+
cur.pos++;
|
|
878
|
+
continue;
|
|
879
|
+
}
|
|
880
|
+
if (next === "]") {
|
|
881
|
+
cur.pos++;
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
throw new JsonScanError(
|
|
885
|
+
next === "" ? `the document ends inside the "${aspect}" block` : `expected "," or "]" in the "${aspect}" block, found "${next}"`,
|
|
886
|
+
cur.line()
|
|
887
|
+
);
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
function reportTooDeep(report, event) {
|
|
891
|
+
report.error(
|
|
892
|
+
"parse-error",
|
|
893
|
+
BAD_ASPECT_BLOCK_CODE,
|
|
894
|
+
`${event.aspect === null ? "a member of the document" : `an element of "${event.aspect}"`} is nested ${event.depth} levels deep, more than the ${MAX_ELEMENT_DEPTH} a graph keeps; skipped`,
|
|
895
|
+
{ line: event.line, element: event.aspect }
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
function keptPrecision(report, where) {
|
|
899
|
+
return (digits) => {
|
|
900
|
+
report.warnOnce(
|
|
901
|
+
"precision",
|
|
902
|
+
PRECISION_CODE,
|
|
903
|
+
`an aspect kept in ${where} holds ${digits}, beyond 2^53; it is kept as the nearest double`,
|
|
904
|
+
{ element: where },
|
|
905
|
+
`${PRECISION_CODE}:kept`
|
|
906
|
+
);
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
function reportSharedBlock(report, event) {
|
|
910
|
+
if (event.shared) {
|
|
911
|
+
report.warnOnce(
|
|
912
|
+
"coercion",
|
|
913
|
+
MULTI_ASPECT_FRAGMENT_CODE,
|
|
914
|
+
`the "${event.aspect}" aspect shares an array member with another aspect; each is read as its own fragment`,
|
|
915
|
+
{ line: event.line, element: event.aspect }
|
|
916
|
+
);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
const DECIMAL_INTEGER_TEXT = /^-?(0|[1-9][0-9]*)$/;
|
|
920
|
+
function cxId(raw, inexactLiteral2 = false) {
|
|
921
|
+
if (raw instanceof ExactInteger) {
|
|
922
|
+
return { id: raw.digits, note: "precision" };
|
|
923
|
+
}
|
|
924
|
+
if (typeof raw === "number") {
|
|
925
|
+
if (Number.isSafeInteger(raw)) {
|
|
926
|
+
return { id: raw === 0 ? 0 : raw, note: inexactLiteral2 ? "text" : null };
|
|
927
|
+
}
|
|
928
|
+
throw invalidCxId(raw, Number.isInteger(raw) ? "an integer beyond 2^53 written inexactly" : "not an integer");
|
|
929
|
+
}
|
|
930
|
+
if (typeof raw === "string" && raw !== "-0" && DECIMAL_INTEGER_TEXT.test(raw)) {
|
|
931
|
+
const n = Number(raw);
|
|
932
|
+
return Number.isSafeInteger(n) ? { id: n, note: "text" } : { id: raw, note: "precision" };
|
|
933
|
+
}
|
|
934
|
+
throw invalidCxId(raw, "a CX id is an integer");
|
|
935
|
+
}
|
|
936
|
+
function invalidCxId(raw, reason) {
|
|
937
|
+
const shown = typeof raw === "string" || typeof raw === "number" ? JSON.stringify(raw) : typeof raw;
|
|
938
|
+
return new GraphFormatError("E_INVALID_ID", `invalid id ${raw === null ? "null" : shown}: ${reason}`, {
|
|
939
|
+
reason
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
const NUMBER_LITERAL = /-?\d[\d.eE+-]*/y;
|
|
943
|
+
function inexactLiteral(text, key, keyDepth = 1) {
|
|
944
|
+
const quoted = JSON.stringify(key);
|
|
945
|
+
let depth = 0;
|
|
946
|
+
let i = 0;
|
|
947
|
+
while (i < text.length) {
|
|
948
|
+
const c = text[i];
|
|
949
|
+
if (c === "{" || c === "[") {
|
|
950
|
+
depth++;
|
|
951
|
+
} else if (c === "}" || c === "]") {
|
|
952
|
+
depth--;
|
|
953
|
+
} else if (c === '"') {
|
|
954
|
+
const start = i;
|
|
955
|
+
i = stringEnd(text, i + 1);
|
|
956
|
+
const colon = skipSpace(text, i + 1);
|
|
957
|
+
if (depth === keyDepth && text.startsWith(quoted, start) && text[colon] === ":") {
|
|
958
|
+
return inexactNumberAt(text, skipSpace(text, colon + 1));
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
i++;
|
|
962
|
+
}
|
|
963
|
+
return false;
|
|
964
|
+
}
|
|
965
|
+
function inexactNumberAt(text, at) {
|
|
966
|
+
NUMBER_LITERAL.lastIndex = at;
|
|
967
|
+
const match = NUMBER_LITERAL.exec(text);
|
|
968
|
+
return match !== null && /[.eE]/.test(match[0]);
|
|
969
|
+
}
|
|
970
|
+
const POSITION_COLUMN = "position";
|
|
971
|
+
const Z_COLUMN = "z";
|
|
972
|
+
function positionDecl(format, sourceDims = 2) {
|
|
973
|
+
return {
|
|
974
|
+
name: POSITION_COLUMN,
|
|
975
|
+
dtype: "f32",
|
|
976
|
+
components: 3,
|
|
977
|
+
role: "position",
|
|
978
|
+
mutable: true,
|
|
979
|
+
nullable: true,
|
|
980
|
+
extra: { sourceDims, units: "file" },
|
|
981
|
+
origin: { format, namespace: "cytoscape" }
|
|
982
|
+
};
|
|
983
|
+
}
|
|
984
|
+
function zDecl(format) {
|
|
985
|
+
return {
|
|
986
|
+
name: Z_COLUMN,
|
|
987
|
+
dtype: "f64",
|
|
988
|
+
nullable: true,
|
|
989
|
+
origin: { format, id: null, namespace: "cytoscape" },
|
|
990
|
+
extra: { cytoscape: "z" }
|
|
991
|
+
};
|
|
992
|
+
}
|
|
993
|
+
function fitsF32(value) {
|
|
994
|
+
return Number.isFinite(Math.fround(value));
|
|
995
|
+
}
|
|
996
|
+
function headText(head) {
|
|
997
|
+
let encoding = "utf-8";
|
|
998
|
+
if (head.byteLength >= 2 && head[0] === 255 && head[1] === 254) {
|
|
999
|
+
encoding = "utf-16le";
|
|
1000
|
+
} else if (head.byteLength >= 2 && head[0] === 254 && head[1] === 255) {
|
|
1001
|
+
encoding = "utf-16be";
|
|
1002
|
+
}
|
|
1003
|
+
return new TextDecoder(encoding).decode(head).replace(/^\uFEFF/, "");
|
|
1004
|
+
}
|
|
1005
|
+
function flipY(y) {
|
|
1006
|
+
return y === 0 ? 0 : -y;
|
|
1007
|
+
}
|
|
1008
|
+
const STRUCTURE_ASPECTS = /* @__PURE__ */ new Set(["metaData", "status", "numberVerification"]);
|
|
1009
|
+
class CxStructure {
|
|
1010
|
+
/**
|
|
1011
|
+
* Create the checker.
|
|
1012
|
+
* @param report - the report
|
|
1013
|
+
* @param canonical - the name an aspect named in metaData is counted under (default: itself)
|
|
1014
|
+
*/
|
|
1015
|
+
constructor(report, canonical = (name) => name) {
|
|
1016
|
+
this.counts = /* @__PURE__ */ new Map();
|
|
1017
|
+
this.blocks = /* @__PURE__ */ new Map();
|
|
1018
|
+
this.declared = /* @__PURE__ */ new Map();
|
|
1019
|
+
this.metaDataBlocks = 0;
|
|
1020
|
+
this.networkBlocks = 0;
|
|
1021
|
+
this.postMetadata = false;
|
|
1022
|
+
this.statusSeen = false;
|
|
1023
|
+
this.status = void 0;
|
|
1024
|
+
this.report = report;
|
|
1025
|
+
this.canonical = canonical;
|
|
1026
|
+
}
|
|
1027
|
+
/**
|
|
1028
|
+
* Whether a status block was read.
|
|
1029
|
+
* @returns true once a status block began
|
|
1030
|
+
*/
|
|
1031
|
+
get hasStatus() {
|
|
1032
|
+
return this.statusSeen;
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
1035
|
+
* Record the start of a block (or a member holding one aspect).
|
|
1036
|
+
* @param aspect - the aspect name
|
|
1037
|
+
* @param line - its line
|
|
1038
|
+
*/
|
|
1039
|
+
block(aspect, line) {
|
|
1040
|
+
this.blocks.set(aspect, (this.blocks.get(aspect) ?? 0) + 1);
|
|
1041
|
+
if (this.statusSeen) {
|
|
1042
|
+
this.report.warnOnce(
|
|
1043
|
+
"validation-error",
|
|
1044
|
+
ASPECT_ORDER_CODE,
|
|
1045
|
+
`the "${aspect}" block comes after the status block, which must be last; it is read`,
|
|
1046
|
+
{ line, element: aspect },
|
|
1047
|
+
`${ASPECT_ORDER_CODE}:status`
|
|
1048
|
+
);
|
|
1049
|
+
}
|
|
1050
|
+
if (aspect === "metaData") {
|
|
1051
|
+
this.metaDataBlocks++;
|
|
1052
|
+
if (this.networkBlocks > 0) {
|
|
1053
|
+
this.postMetadata = true;
|
|
1054
|
+
}
|
|
1055
|
+
if (this.metaDataBlocks > 2) {
|
|
1056
|
+
this.report.warnOnce(
|
|
1057
|
+
"validation-error",
|
|
1058
|
+
ASPECT_ORDER_CODE,
|
|
1059
|
+
`${this.metaDataBlocks} metaData blocks; a document has at most two (pre and post)`,
|
|
1060
|
+
{ line, element: aspect },
|
|
1061
|
+
`${ASPECT_ORDER_CODE}:metaData`
|
|
1062
|
+
);
|
|
1063
|
+
}
|
|
1064
|
+
return;
|
|
1065
|
+
}
|
|
1066
|
+
if (aspect === "status") {
|
|
1067
|
+
this.statusSeen = true;
|
|
1068
|
+
return;
|
|
1069
|
+
}
|
|
1070
|
+
if (STRUCTURE_ASPECTS.has(aspect)) {
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
this.networkBlocks++;
|
|
1074
|
+
if (this.postMetadata) {
|
|
1075
|
+
this.report.warnOnce(
|
|
1076
|
+
"validation-error",
|
|
1077
|
+
ASPECT_ORDER_CODE,
|
|
1078
|
+
`the "${aspect}" block comes after the post-metadata, where only status is allowed; it is read`,
|
|
1079
|
+
{ line, element: aspect },
|
|
1080
|
+
`${ASPECT_ORDER_CODE}:post`
|
|
1081
|
+
);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
/**
|
|
1085
|
+
* Record one element of a block; metaData and status elements are checked here.
|
|
1086
|
+
* @param aspect - the aspect name
|
|
1087
|
+
* @param value - the parsed element
|
|
1088
|
+
* @param line - its line
|
|
1089
|
+
*/
|
|
1090
|
+
element(aspect, value, line) {
|
|
1091
|
+
this.counts.set(aspect, (this.counts.get(aspect) ?? 0) + 1);
|
|
1092
|
+
if (aspect === "metaData") {
|
|
1093
|
+
this.readCount(value, line);
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
if (aspect === "status") {
|
|
1097
|
+
this.readStatus(value, line);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
/**
|
|
1101
|
+
* Record the element count a metaData element declares; a count that is not an integer (text,
|
|
1102
|
+
* a fraction) or that names no aspect is W_COUNT_MISMATCH and not checked.
|
|
1103
|
+
* @param value - the metaData element
|
|
1104
|
+
* @param line - its line
|
|
1105
|
+
*/
|
|
1106
|
+
readCount(value, line) {
|
|
1107
|
+
if (!isRecord(value) || value.elementCount === void 0 || value.elementCount === null) {
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
const raw = value.elementCount;
|
|
1111
|
+
let count = null;
|
|
1112
|
+
if (raw instanceof ExactInteger) {
|
|
1113
|
+
count = Number(raw.digits);
|
|
1114
|
+
} else if (typeof raw === "number" && Number.isInteger(raw)) {
|
|
1115
|
+
count = raw;
|
|
1116
|
+
}
|
|
1117
|
+
if (typeof value.name !== "string" || count === null) {
|
|
1118
|
+
const shownCount = raw instanceof ExactInteger ? raw.digits : JSON.stringify(raw);
|
|
1119
|
+
this.report.warning(
|
|
1120
|
+
"validation-error",
|
|
1121
|
+
COUNT_MISMATCH_CODE,
|
|
1122
|
+
`a metaData element declares the elementCount ${shownCount} for the name ${JSON.stringify(value.name) ?? "undefined"}; not a count of a named aspect, not checked`,
|
|
1123
|
+
{ line, element: "metaData" }
|
|
1124
|
+
);
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
this.declared.set(this.canonical(value.name), count);
|
|
1128
|
+
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Check a status element: success false is fatal, an error text with success true a warning.
|
|
1131
|
+
* @param value - the element
|
|
1132
|
+
* @param line - its line
|
|
1133
|
+
*/
|
|
1134
|
+
readStatus(value, line) {
|
|
1135
|
+
if (this.status !== void 0) {
|
|
1136
|
+
this.report.warnOnce(
|
|
1137
|
+
"validation-error",
|
|
1138
|
+
ASPECT_ORDER_CODE,
|
|
1139
|
+
"more than one status element; the last is used",
|
|
1140
|
+
{ line, element: "status" },
|
|
1141
|
+
`${ASPECT_ORDER_CODE}:status2`
|
|
1142
|
+
);
|
|
1143
|
+
}
|
|
1144
|
+
this.status = value;
|
|
1145
|
+
if (!isRecord(value)) {
|
|
1146
|
+
return;
|
|
1147
|
+
}
|
|
1148
|
+
const error = typeof value.error === "string" ? value.error : "";
|
|
1149
|
+
if (value.success === false) {
|
|
1150
|
+
const message = `the producer marked the document as failed${error.length > 0 ? `: ${error}` : ""}`;
|
|
1151
|
+
this.report.error("validation-error", STATUS_FAILED_CODE, message, { line, element: "status" });
|
|
1152
|
+
throw this.report.abort(message, { code: STATUS_FAILED_CODE });
|
|
1153
|
+
}
|
|
1154
|
+
if (value.success === true && error.length > 0) {
|
|
1155
|
+
this.report.warning("validation-error", STATUS_WARNING_CODE, `the producer reports a warning: ${error}`, {
|
|
1156
|
+
line,
|
|
1157
|
+
element: "status"
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1162
|
+
* Whether the status element is one object with a boolean success.
|
|
1163
|
+
* @returns true for a well-formed status
|
|
1164
|
+
*/
|
|
1165
|
+
statusWellFormed() {
|
|
1166
|
+
return isRecord(this.status) && typeof this.status.success === "boolean";
|
|
1167
|
+
}
|
|
1168
|
+
/** Compare the declared element counts with what was read (W_COUNT_MISMATCH per aspect). */
|
|
1169
|
+
checkCounts() {
|
|
1170
|
+
for (const [name, declared] of this.declared) {
|
|
1171
|
+
const read = this.counts.get(name) ?? 0;
|
|
1172
|
+
if (read !== declared) {
|
|
1173
|
+
this.report.warning(
|
|
1174
|
+
"validation-error",
|
|
1175
|
+
COUNT_MISMATCH_CODE,
|
|
1176
|
+
`metaData declares ${declared} "${name}" element${plural(declared)}; ${read} ${agree(read, "was", "were")} read`,
|
|
1177
|
+
{ element: name }
|
|
1178
|
+
);
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
function isRecord(value) {
|
|
1184
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && !(value instanceof ExactInteger);
|
|
1185
|
+
}
|
|
1186
|
+
function declareFresh(sink, domain, decl, report) {
|
|
1187
|
+
const taken = (name) => (domain === "node" ? sink.nodeColumn(name) : sink.edgeColumn(name)) !== INVALID_INDEX;
|
|
1188
|
+
let fresh = decl;
|
|
1189
|
+
if (taken(decl.name)) {
|
|
1190
|
+
fresh = { ...decl, name: uniqueColumnName(decl.name, null, taken) };
|
|
1191
|
+
report.warning(
|
|
1192
|
+
"coercion",
|
|
1193
|
+
COLUMN_RENAMED_CODE,
|
|
1194
|
+
`${domain} column "${decl.name}" renamed to "${fresh.name}": an attribute holds that name`,
|
|
1195
|
+
{ element: decl.name }
|
|
1196
|
+
);
|
|
1197
|
+
}
|
|
1198
|
+
return declareResolved(sink, domain, fresh, report).handle;
|
|
1199
|
+
}
|
|
1200
|
+
export {
|
|
1201
|
+
CxStructure as C,
|
|
1202
|
+
ExactInteger as E,
|
|
1203
|
+
JsonScanError as J,
|
|
1204
|
+
MAYBE_UNSAFE_INTEGER as M,
|
|
1205
|
+
POSITION_COLUMN as P,
|
|
1206
|
+
reportSharedBlock as a,
|
|
1207
|
+
flipY as b,
|
|
1208
|
+
cxId as c,
|
|
1209
|
+
positionDecl as d,
|
|
1210
|
+
declareFresh as e,
|
|
1211
|
+
fitsF32 as f,
|
|
1212
|
+
inexactLiteral as g,
|
|
1213
|
+
headText as h,
|
|
1214
|
+
isRecord as i,
|
|
1215
|
+
setOwn as j,
|
|
1216
|
+
keptPrecision as k,
|
|
1217
|
+
MAYBE_INEXACT_EXPONENT as l,
|
|
1218
|
+
rewriteNumbers as m,
|
|
1219
|
+
findDuplicateKeys as n,
|
|
1220
|
+
plainJson as p,
|
|
1221
|
+
reportTooDeep as r,
|
|
1222
|
+
scanAspects as s,
|
|
1223
|
+
zDecl as z
|
|
1224
|
+
};
|
|
1225
|
+
//# sourceMappingURL=json-elements-3tnyt5uZ.js.map
|