@graphty/graph-io 0.3.40 → 0.3.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/README.md +2 -0
  2. package/dist/chunks/{children-CL3Cy0ez.js → children-CA4coBi0.js} +36 -27
  3. package/dist/chunks/children-CA4coBi0.js.map +1 -0
  4. package/dist/chunks/{choose-CS3fvGT1.js → choose-DvpbdRuz.js} +2 -2
  5. package/dist/chunks/{choose-CS3fvGT1.js.map → choose-DvpbdRuz.js.map} +1 -1
  6. package/dist/chunks/{constants-DqKZT6cH.js → constants-fT3E8JYY.js} +2 -2
  7. package/dist/chunks/{constants-DqKZT6cH.js.map → constants-fT3E8JYY.js.map} +1 -1
  8. package/dist/chunks/{escape-BJRLd3vJ.js → escape-B62ZGM_a.js} +2 -2
  9. package/dist/chunks/{escape-BJRLd3vJ.js.map → escape-B62ZGM_a.js.map} +1 -1
  10. package/dist/chunks/{export-B-aVCwyG.js → export-rKLeGQMo.js} +404 -243
  11. package/dist/chunks/export-rKLeGQMo.js.map +1 -0
  12. package/dist/chunks/{exporter-6ocL_9x_.js → exporter-8hLNemFk.js} +4 -4
  13. package/dist/chunks/{exporter-6ocL_9x_.js.map → exporter-8hLNemFk.js.map} +1 -1
  14. package/dist/chunks/{exporter-BVXnV9-9.js → exporter-BWwEuOPT.js} +29 -17
  15. package/dist/chunks/exporter-BWwEuOPT.js.map +1 -0
  16. package/dist/chunks/{exporter-Bcp-l4Bo.js → exporter-CpRyHZ3H.js} +574 -475
  17. package/dist/chunks/exporter-CpRyHZ3H.js.map +1 -0
  18. package/dist/chunks/{exporter-SFYkDzD0.js → exporter-yLxKBvLE.js} +23 -20
  19. package/dist/chunks/{exporter-SFYkDzD0.js.map → exporter-yLxKBvLE.js.map} +1 -1
  20. package/dist/chunks/{importer-DcKB97kW.js → importer-BbNb7eNg.js} +111 -71
  21. package/dist/chunks/importer-BbNb7eNg.js.map +1 -0
  22. package/dist/chunks/{importer-D_srHyj6.js → importer-C98dpSH4.js} +5 -5
  23. package/dist/chunks/{importer-D_srHyj6.js.map → importer-C98dpSH4.js.map} +1 -1
  24. package/dist/chunks/{importer-BJlGAOht.js → importer-D794XUTe.js} +3 -3
  25. package/dist/chunks/{importer-BJlGAOht.js.map → importer-D794XUTe.js.map} +1 -1
  26. package/dist/chunks/{importer-AjwOJrn2.js → importer-Dz7tI8Sa.js} +202 -181
  27. package/dist/chunks/importer-Dz7tI8Sa.js.map +1 -0
  28. package/dist/chunks/{importer-DEp_fYjf.js → importer-Ht7LNg8L.js} +92 -64
  29. package/dist/chunks/importer-Ht7LNg8L.js.map +1 -0
  30. package/dist/chunks/{importer-CPqnIY8m.js → importer-WrGRZb0N.js} +42 -29
  31. package/dist/chunks/importer-WrGRZb0N.js.map +1 -0
  32. package/dist/chunks/{importer-BpuS3J8C.js → importer-xZ-3suY1.js} +74 -61
  33. package/dist/chunks/importer-xZ-3suY1.js.map +1 -0
  34. package/dist/chunks/{json-elements-DpO6AXIc.js → json-elements-DKSqpNW1.js} +3 -3
  35. package/dist/chunks/{json-elements-DpO6AXIc.js.map → json-elements-DKSqpNW1.js.map} +1 -1
  36. package/dist/chunks/{ontology-export-50L9DOV4.js → ontology-export-CtRXjg_i.js} +2 -2
  37. package/dist/chunks/{ontology-export-50L9DOV4.js.map → ontology-export-CtRXjg_i.js.map} +1 -1
  38. package/dist/chunks/{records-r3SFHz11.js → records-Cu4bxYOm.js} +69 -36
  39. package/dist/chunks/records-Cu4bxYOm.js.map +1 -0
  40. package/dist/chunks/{text-Bjfa1xYL.js → text-DHOJXnED.js} +20 -11
  41. package/dist/chunks/text-DHOJXnED.js.map +1 -0
  42. package/dist/csv.js +323 -241
  43. package/dist/csv.js.map +1 -1
  44. package/dist/cx.js +1 -1
  45. package/dist/cx2.js +2 -2
  46. package/dist/cys.js +1 -1
  47. package/dist/dot.js +1 -1
  48. package/dist/gexf.js +195 -97
  49. package/dist/gexf.js.map +1 -1
  50. package/dist/gml.js +170 -149
  51. package/dist/gml.js.map +1 -1
  52. package/dist/graph-io.js +27 -27
  53. package/dist/graphml.js +2 -2
  54. package/dist/json.js +1 -1
  55. package/dist/neo4j.js +103 -65
  56. package/dist/neo4j.js.map +1 -1
  57. package/dist/obo.js +1 -1
  58. package/dist/pajek.js +1 -1
  59. package/dist/src/children.d.ts.map +1 -1
  60. package/dist/src/children.js +50 -27
  61. package/dist/src/children.js.map +1 -1
  62. package/dist/src/common/attributes.d.ts.map +1 -1
  63. package/dist/src/common/attributes.js +86 -42
  64. package/dist/src/common/attributes.js.map +1 -1
  65. package/dist/src/common/input.d.ts.map +1 -1
  66. package/dist/src/common/input.js +358 -184
  67. package/dist/src/common/input.js.map +1 -1
  68. package/dist/src/common/lists.js +30 -15
  69. package/dist/src/common/lists.js.map +1 -1
  70. package/dist/src/common/text.d.ts +7 -0
  71. package/dist/src/common/text.d.ts.map +1 -1
  72. package/dist/src/common/text.js +15 -7
  73. package/dist/src/common/text.js.map +1 -1
  74. package/dist/src/common/zip.d.ts.map +1 -1
  75. package/dist/src/common/zip.js +36 -19
  76. package/dist/src/common/zip.js.map +1 -1
  77. package/dist/src/formats/csv/exporter.d.ts.map +1 -1
  78. package/dist/src/formats/csv/exporter.js +288 -146
  79. package/dist/src/formats/csv/exporter.js.map +1 -1
  80. package/dist/src/formats/csv/importer.d.ts.map +1 -1
  81. package/dist/src/formats/csv/importer.js +129 -80
  82. package/dist/src/formats/csv/importer.js.map +1 -1
  83. package/dist/src/formats/csv/records.d.ts.map +1 -1
  84. package/dist/src/formats/csv/records.js +78 -36
  85. package/dist/src/formats/csv/records.js.map +1 -1
  86. package/dist/src/formats/cys/tables.d.ts.map +1 -1
  87. package/dist/src/formats/cys/tables.js +11 -8
  88. package/dist/src/formats/cys/tables.js.map +1 -1
  89. package/dist/src/formats/dot/tokenizer.d.ts +39 -0
  90. package/dist/src/formats/dot/tokenizer.d.ts.map +1 -1
  91. package/dist/src/formats/dot/tokenizer.js +112 -66
  92. package/dist/src/formats/dot/tokenizer.js.map +1 -1
  93. package/dist/src/formats/gexf/exporter.d.ts.map +1 -1
  94. package/dist/src/formats/gexf/exporter.js +65 -37
  95. package/dist/src/formats/gexf/exporter.js.map +1 -1
  96. package/dist/src/formats/gexf/importer.d.ts.map +1 -1
  97. package/dist/src/formats/gexf/importer.js +138 -50
  98. package/dist/src/formats/gexf/importer.js.map +1 -1
  99. package/dist/src/formats/gml/exporter.d.ts.map +1 -1
  100. package/dist/src/formats/gml/exporter.js +51 -35
  101. package/dist/src/formats/gml/exporter.js.map +1 -1
  102. package/dist/src/formats/gml/importer.d.ts.map +1 -1
  103. package/dist/src/formats/gml/importer.js +103 -58
  104. package/dist/src/formats/gml/importer.js.map +1 -1
  105. package/dist/src/formats/gml/syntax.d.ts.map +1 -1
  106. package/dist/src/formats/gml/syntax.js +17 -8
  107. package/dist/src/formats/gml/syntax.js.map +1 -1
  108. package/dist/src/formats/graphml/exporter.d.ts.map +1 -1
  109. package/dist/src/formats/graphml/exporter.js +34 -24
  110. package/dist/src/formats/graphml/exporter.js.map +1 -1
  111. package/dist/src/formats/graphml/importer.d.ts.map +1 -1
  112. package/dist/src/formats/graphml/importer.js +17 -13
  113. package/dist/src/formats/graphml/importer.js.map +1 -1
  114. package/dist/src/formats/graphml/tree.js +23 -14
  115. package/dist/src/formats/graphml/tree.js.map +1 -1
  116. package/dist/src/formats/graphml/yfiles.d.ts.map +1 -1
  117. package/dist/src/formats/graphml/yfiles.js +22 -10
  118. package/dist/src/formats/graphml/yfiles.js.map +1 -1
  119. package/dist/src/formats/json/dialect.d.ts.map +1 -1
  120. package/dist/src/formats/json/dialect.js +54 -20
  121. package/dist/src/formats/json/dialect.js.map +1 -1
  122. package/dist/src/formats/json/exporter.d.ts.map +1 -1
  123. package/dist/src/formats/json/exporter.js +38 -21
  124. package/dist/src/formats/json/exporter.js.map +1 -1
  125. package/dist/src/formats/json/importer.d.ts.map +1 -1
  126. package/dist/src/formats/json/importer.js +536 -343
  127. package/dist/src/formats/json/importer.js.map +1 -1
  128. package/dist/src/formats/json/obographs.js +29 -17
  129. package/dist/src/formats/json/obographs.js.map +1 -1
  130. package/dist/src/formats/neo4j/exporter.d.ts.map +1 -1
  131. package/dist/src/formats/neo4j/exporter.js +73 -43
  132. package/dist/src/formats/neo4j/exporter.js.map +1 -1
  133. package/dist/src/formats/neo4j/header.d.ts.map +1 -1
  134. package/dist/src/formats/neo4j/header.js +37 -16
  135. package/dist/src/formats/neo4j/header.js.map +1 -1
  136. package/dist/src/formats/neo4j/importer.d.ts.map +1 -1
  137. package/dist/src/formats/neo4j/importer.js +21 -11
  138. package/dist/src/formats/neo4j/importer.js.map +1 -1
  139. package/dist/src/formats/obo/exporter.d.ts.map +1 -1
  140. package/dist/src/formats/obo/exporter.js +18 -7
  141. package/dist/src/formats/obo/exporter.js.map +1 -1
  142. package/dist/src/formats/pajek/exporter.d.ts.map +1 -1
  143. package/dist/src/formats/pajek/exporter.js +142 -73
  144. package/dist/src/formats/pajek/exporter.js.map +1 -1
  145. package/dist/src/formats/pajek/importer.d.ts.map +1 -1
  146. package/dist/src/formats/pajek/importer.js +26 -15
  147. package/dist/src/formats/pajek/importer.js.map +1 -1
  148. package/dist/src/formats/pajek/syntax.d.ts.map +1 -1
  149. package/dist/src/formats/pajek/syntax.js +85 -58
  150. package/dist/src/formats/pajek/syntax.js.map +1 -1
  151. package/dist/src/formats/xgmml/emit.d.ts +7 -0
  152. package/dist/src/formats/xgmml/emit.d.ts.map +1 -1
  153. package/dist/src/formats/xgmml/emit.js +79 -40
  154. package/dist/src/formats/xgmml/emit.js.map +1 -1
  155. package/dist/src/formats/xgmml/exporter.d.ts.map +1 -1
  156. package/dist/src/formats/xgmml/exporter.js +38 -12
  157. package/dist/src/formats/xgmml/exporter.js.map +1 -1
  158. package/dist/src/formats/xgmml/importer.d.ts.map +1 -1
  159. package/dist/src/formats/xgmml/importer.js +38 -18
  160. package/dist/src/formats/xgmml/importer.js.map +1 -1
  161. package/dist/src/sniff.js +109 -57
  162. package/dist/src/sniff.js.map +1 -1
  163. package/dist/xgmml.js +2 -2
  164. package/package.json +2 -2
  165. package/src/children.ts +54 -27
  166. package/src/common/attributes.ts +118 -49
  167. package/src/common/input.ts +439 -197
  168. package/src/common/lists.ts +29 -15
  169. package/src/common/text.ts +24 -15
  170. package/src/common/zip.ts +47 -18
  171. package/src/formats/csv/exporter.ts +377 -175
  172. package/src/formats/csv/importer.ts +155 -84
  173. package/src/formats/csv/records.ts +90 -35
  174. package/src/formats/cys/tables.ts +11 -10
  175. package/src/formats/dot/tokenizer.ts +118 -68
  176. package/src/formats/gexf/exporter.ts +67 -36
  177. package/src/formats/gexf/importer.ts +173 -63
  178. package/src/formats/gml/exporter.ts +78 -82
  179. package/src/formats/gml/importer.ts +119 -68
  180. package/src/formats/gml/syntax.ts +18 -8
  181. package/src/formats/graphml/exporter.ts +44 -24
  182. package/src/formats/graphml/importer.ts +18 -11
  183. package/src/formats/graphml/tree.ts +22 -12
  184. package/src/formats/graphml/yfiles.ts +23 -10
  185. package/src/formats/json/dialect.ts +61 -22
  186. package/src/formats/json/exporter.ts +40 -21
  187. package/src/formats/json/importer.ts +701 -385
  188. package/src/formats/json/obographs.ts +35 -15
  189. package/src/formats/neo4j/exporter.ts +79 -41
  190. package/src/formats/neo4j/header.ts +50 -16
  191. package/src/formats/neo4j/importer.ts +21 -10
  192. package/src/formats/obo/exporter.ts +34 -17
  193. package/src/formats/pajek/exporter.ts +180 -117
  194. package/src/formats/pajek/importer.ts +27 -15
  195. package/src/formats/pajek/syntax.ts +99 -58
  196. package/src/formats/xgmml/emit.ts +88 -40
  197. package/src/formats/xgmml/exporter.ts +40 -12
  198. package/src/formats/xgmml/importer.ts +45 -23
  199. package/src/sniff.ts +115 -59
  200. package/dist/chunks/children-CL3Cy0ez.js.map +0 -1
  201. package/dist/chunks/export-B-aVCwyG.js.map +0 -1
  202. package/dist/chunks/exporter-BVXnV9-9.js.map +0 -1
  203. package/dist/chunks/exporter-Bcp-l4Bo.js.map +0 -1
  204. package/dist/chunks/importer-AjwOJrn2.js.map +0 -1
  205. package/dist/chunks/importer-BpuS3J8C.js.map +0 -1
  206. package/dist/chunks/importer-CPqnIY8m.js.map +0 -1
  207. package/dist/chunks/importer-DEp_fYjf.js.map +0 -1
  208. package/dist/chunks/importer-DcKB97kW.js.map +0 -1
  209. package/dist/chunks/records-r3SFHz11.js.map +0 -1
  210. package/dist/chunks/text-Bjfa1xYL.js.map +0 -1
@@ -132,22 +132,7 @@ export const DICT_SAMPLE_ROWS = 1024;
132
132
  export function declareAttribute(input: AttributeDeclarationInput): DeclaredAttribute {
133
133
  const issues: DeclarationIssue[] = [];
134
134
  const listSyntax = input.listSyntax ?? "gexf";
135
- let spec: DeclaredTypeSpec;
136
- if (input.type === null) {
137
- spec = stringSpec(null);
138
- } else {
139
- const mapped = mapDeclaredType(input.format, input.type, input.long);
140
- if (mapped === null) {
141
- spec = stringSpec(input.type);
142
- issues.push({
143
- category: "unsupported",
144
- code: UNKNOWN_TYPE_CODE,
145
- message: `${input.format} type "${input.type}" is not supported; values kept as text`,
146
- });
147
- } else {
148
- spec = mapped;
149
- }
150
- }
135
+ let spec = declaredSpec(input, issues);
151
136
  const { name, renamed } = resolveName(input);
152
137
  if (renamed) {
153
138
  issues.push({
@@ -179,20 +164,7 @@ export function declareAttribute(input: AttributeDeclarationInput): DeclaredAttr
179
164
  }
180
165
  const optionsText = input.optionsText ?? null;
181
166
  if (optionsText !== null) {
182
- try {
183
- const options = splitListText(optionsText, listSyntax).map((item) => parseItem(item, spec));
184
- decl.options = options;
185
- if (spec.dtype === "string" && !spec.list && options.every((o) => typeof o === "string")) {
186
- decl.dtype = "dict";
187
- spec = { ...spec, dtype: "dict" };
188
- }
189
- } catch (err) {
190
- issues.push({
191
- category: "validation-error",
192
- code: BAD_OPTIONS_CODE,
193
- message: `options "${optionsText}" of attribute "${name}" do not parse as ${spec.declared}: ${messageOf(err)}`,
194
- });
195
- }
167
+ spec = declareOptions(decl, spec, optionsText, listSyntax, issues);
196
168
  }
197
169
  const defaultText = input.defaultText ?? null;
198
170
  if (defaultText !== null) {
@@ -210,6 +182,63 @@ export function declareAttribute(input: AttributeDeclarationInput): DeclaredAttr
210
182
  return { decl, spec, listSyntax, companion, renamed, issues };
211
183
  }
212
184
 
185
+ /**
186
+ * The value spec of a declared type: string for no type, string with UNKNOWN_TYPE_CODE for a type
187
+ * the format does not define.
188
+ * @param input - what the file declares
189
+ * @param issues - receives the unknown-type warning
190
+ * @returns the spec
191
+ */
192
+ function declaredSpec(input: AttributeDeclarationInput, issues: DeclarationIssue[]): DeclaredTypeSpec {
193
+ if (input.type === null) {
194
+ return stringSpec(null);
195
+ }
196
+ const mapped = mapDeclaredType(input.format, input.type, input.long);
197
+ if (mapped !== null) {
198
+ return mapped;
199
+ }
200
+ issues.push({
201
+ category: "unsupported",
202
+ code: UNKNOWN_TYPE_CODE,
203
+ message: `${input.format} type "${input.type}" is not supported; values kept as text`,
204
+ });
205
+ return stringSpec(input.type);
206
+ }
207
+
208
+ /**
209
+ * Put the parsed options of an attribute on its declaration; a plain string attribute whose
210
+ * options are all strings becomes a dict column.
211
+ * @param decl - the declaration to complete
212
+ * @param spec - the value spec
213
+ * @param optionsText - the options text
214
+ * @param listSyntax - the list syntax the options are split with
215
+ * @param issues - receives BAD_OPTIONS_CODE when the options do not parse
216
+ * @returns the spec, with dtype dict when the column became a dict
217
+ */
218
+ function declareOptions(
219
+ decl: ColumnDecl,
220
+ spec: DeclaredTypeSpec,
221
+ optionsText: string,
222
+ listSyntax: ListSyntax,
223
+ issues: DeclarationIssue[],
224
+ ): DeclaredTypeSpec {
225
+ try {
226
+ const options = splitListText(optionsText, listSyntax).map((item) => parseItem(item, spec));
227
+ decl.options = options;
228
+ if (spec.dtype === "string" && !spec.list && options.every((o) => typeof o === "string")) {
229
+ decl.dtype = "dict";
230
+ return { ...spec, dtype: "dict" };
231
+ }
232
+ } catch (err) {
233
+ issues.push({
234
+ category: "validation-error",
235
+ code: BAD_OPTIONS_CODE,
236
+ message: `options "${optionsText}" of attribute "${decl.name}" do not parse as ${spec.declared}: ${messageOf(err)}`,
237
+ });
238
+ }
239
+ return spec;
240
+ }
241
+
213
242
  /**
214
243
  * Parse a value text by a declaration: a scalar, or a list split by the syntax with each item
215
244
  * parsed by the item kind.
@@ -326,29 +355,12 @@ export function declareResolved(
326
355
  throw err;
327
356
  }
328
357
  if (err.code === "E_COLUMN_EXISTS" && !renamed) {
329
- const taken = takenIn(sink, domain);
330
- const id = current.origin?.id ?? null;
331
- const name = uniqueColumnName(current.name, id, taken);
332
- report.warning(
333
- "coercion",
334
- COLUMN_RENAMED_CODE,
335
- `${domain} column "${current.name}" renamed to "${name}": the sink already holds that name with another shape`,
336
- { ...where, element: where?.element ?? current.name },
337
- );
338
- current = { ...current, name };
358
+ current = renameColumn(sink, domain, current, report, where);
339
359
  renamed = true;
340
360
  continue;
341
361
  }
342
362
  if (err.code === "E_DUPLICATE_ROLE" && current.role !== undefined && !roleDropped) {
343
- const holder = typeof err.details.holder === "string" ? err.details.holder : "another column";
344
- report.warning(
345
- "coercion",
346
- ROLE_TAKEN_CODE,
347
- `${domain} column "${current.name}" loses the ${current.role} role: "${holder}" already holds it`,
348
- { ...where, element: where?.element ?? current.name },
349
- );
350
- const { role: _role, ...withoutRole } = current;
351
- current = withoutRole;
363
+ current = dropRole(err, domain, current, current.role, report, where);
352
364
  roleDropped = true;
353
365
  continue;
354
366
  }
@@ -357,6 +369,63 @@ export function declareResolved(
357
369
  }
358
370
  }
359
371
 
372
+ /**
373
+ * The declaration under a name the sink does not hold yet, recording W_COLUMN_RENAMED.
374
+ * @param sink - the sink
375
+ * @param domain - node or edge
376
+ * @param decl - the declaration whose name clashed
377
+ * @param report - the report
378
+ * @param where - the line and element, when known
379
+ * @returns the renamed declaration
380
+ */
381
+ function renameColumn(
382
+ sink: GraphSink,
383
+ domain: "node" | "edge",
384
+ decl: ColumnDecl,
385
+ report: ImportReportBuilder,
386
+ where: IssueLocation | undefined,
387
+ ): ColumnDecl {
388
+ const taken = takenIn(sink, domain);
389
+ const id = decl.origin?.id ?? null;
390
+ const name = uniqueColumnName(decl.name, id, taken);
391
+ report.warning(
392
+ "coercion",
393
+ COLUMN_RENAMED_CODE,
394
+ `${domain} column "${decl.name}" renamed to "${name}": the sink already holds that name with another shape`,
395
+ { ...where, element: where?.element ?? decl.name },
396
+ );
397
+ return { ...decl, name };
398
+ }
399
+
400
+ /**
401
+ * The declaration without the role another column holds, recording W_ROLE_TAKEN.
402
+ * @param err - the sink's E_DUPLICATE_ROLE error
403
+ * @param domain - node or edge
404
+ * @param decl - the declaration whose role clashed
405
+ * @param role - its role
406
+ * @param report - the report
407
+ * @param where - the line and element, when known
408
+ * @returns the declaration without its role
409
+ */
410
+ function dropRole(
411
+ err: GraphFormatError,
412
+ domain: "node" | "edge",
413
+ decl: ColumnDecl,
414
+ role: ColumnRole,
415
+ report: ImportReportBuilder,
416
+ where: IssueLocation | undefined,
417
+ ): ColumnDecl {
418
+ const holder = typeof err.details.holder === "string" ? err.details.holder : "another column";
419
+ report.warning(
420
+ "coercion",
421
+ ROLE_TAKEN_CODE,
422
+ `${domain} column "${decl.name}" loses the ${role} role: "${holder}" already holds it`,
423
+ { ...where, element: where?.element ?? decl.name },
424
+ );
425
+ const { role: _role, ...withoutRole } = decl;
426
+ return withoutRole;
427
+ }
428
+
360
429
  /**
361
430
  * Declare the companion text column of a temporal column. A table holds at
362
431
  * most one column per role, so when another companion already carries `timeText` this one is