@graphty/graph-io 0.3.27 → 0.3.29
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/dist/chunks/{choose-DrXtu_96.js → choose-DT5da6OC.js} +2 -2
- package/dist/chunks/{choose-DrXtu_96.js.map → choose-DT5da6OC.js.map} +1 -1
- package/dist/chunks/{constants-ikG85dT8.js → constants-DowRD9ai.js} +2 -2
- package/dist/chunks/{constants-ikG85dT8.js.map → constants-DowRD9ai.js.map} +1 -1
- package/dist/chunks/{escape-D1HPTUrP.js → escape-DQC5HWqF.js} +2 -2
- package/dist/chunks/{escape-D1HPTUrP.js.map → escape-DQC5HWqF.js.map} +1 -1
- package/dist/chunks/{export-CHd4tQE2.js → export-CVi12U7J.js} +81 -60
- package/dist/chunks/export-CVi12U7J.js.map +1 -0
- package/dist/chunks/{exporter-D23CKNqF.js → exporter-C3Pa2PSd.js} +5 -5
- package/dist/chunks/exporter-C3Pa2PSd.js.map +1 -0
- package/dist/chunks/{exporter-DfWTgrti.js → exporter-CgsO2nSl.js} +4 -4
- package/dist/chunks/{exporter-DfWTgrti.js.map → exporter-CgsO2nSl.js.map} +1 -1
- package/dist/chunks/{exporter-IHv4nkCm.js → exporter-Cy_1da4c.js} +72 -48
- package/dist/chunks/exporter-Cy_1da4c.js.map +1 -0
- package/dist/chunks/{exporter-DhtW6FxK.js → exporter-JubAlNWi.js} +34 -34
- package/dist/chunks/exporter-JubAlNWi.js.map +1 -0
- package/dist/chunks/{importer-CIAzt-wo.js → importer-BA_hZKo7.js} +4 -4
- package/dist/chunks/{importer-CIAzt-wo.js.map → importer-BA_hZKo7.js.map} +1 -1
- package/dist/chunks/{importer-B1wmPQjr.js → importer-CDXlxXlS.js} +35 -9
- package/dist/chunks/importer-CDXlxXlS.js.map +1 -0
- package/dist/chunks/{importer-BVRE--Un.js → importer-DLz2Vb4q.js} +3 -3
- package/dist/chunks/{importer-BVRE--Un.js.map → importer-DLz2Vb4q.js.map} +1 -1
- package/dist/chunks/{importer-B2W_58pz.js → importer-DVxzzibh.js} +4 -4
- package/dist/chunks/{importer-B2W_58pz.js.map → importer-DVxzzibh.js.map} +1 -1
- package/dist/chunks/{importer-BSALvkui.js → importer-Dej72hIF.js} +6 -6
- package/dist/chunks/importer-Dej72hIF.js.map +1 -0
- package/dist/chunks/{importer-z_FL4VMb.js → importer-lLH9gQF_.js} +5 -5
- package/dist/chunks/{importer-z_FL4VMb.js.map → importer-lLH9gQF_.js.map} +1 -1
- package/dist/chunks/{importer-DpEW5zeG.js → importer-q-R-Q98w.js} +4 -4
- package/dist/chunks/{importer-DpEW5zeG.js.map → importer-q-R-Q98w.js.map} +1 -1
- package/dist/chunks/{json-elements-BAmNBZok.js → json-elements-1IUzkRNy.js} +3 -3
- package/dist/chunks/{json-elements-BAmNBZok.js.map → json-elements-1IUzkRNy.js.map} +1 -1
- package/dist/chunks/{ontology-export-Bab4eUA8.js → ontology-export-b0GLNIj-.js} +2 -2
- package/dist/chunks/{ontology-export-Bab4eUA8.js.map → ontology-export-b0GLNIj-.js.map} +1 -1
- package/dist/chunks/{records-CdlvL4RO.js → records-CdyqwXeY.js} +2 -2
- package/dist/chunks/{records-CdlvL4RO.js.map → records-CdyqwXeY.js.map} +1 -1
- package/dist/chunks/{text-DzXjAiTl.js → text-CDgjbkLC.js} +2 -2
- package/dist/chunks/{text-DzXjAiTl.js.map → text-CDgjbkLC.js.map} +1 -1
- package/dist/csv.js +33 -16
- package/dist/csv.js.map +1 -1
- package/dist/cx.js +1 -1
- package/dist/cx2.js +2 -2
- package/dist/cys.js +1 -1
- package/dist/dot.js +1 -1
- package/dist/gexf.js +2 -2
- package/dist/gml.js +18 -9
- package/dist/gml.js.map +1 -1
- package/dist/graph-io.js +26 -26
- package/dist/graph-io.js.map +1 -1
- package/dist/graphml.js +2 -2
- package/dist/json.js +1 -1
- package/dist/neo4j.js +3 -3
- package/dist/obo.js +1 -1
- package/dist/pajek.js +1 -1
- package/dist/src/common/declared-types.d.ts.map +1 -1
- package/dist/src/common/declared-types.js.map +1 -1
- package/dist/src/common/export.d.ts +6 -0
- package/dist/src/common/export.d.ts.map +1 -1
- package/dist/src/common/export.js +62 -28
- package/dist/src/common/export.js.map +1 -1
- package/dist/src/common/zip.js.map +1 -1
- package/dist/src/formats/csv/exporter.d.ts.map +1 -1
- package/dist/src/formats/csv/exporter.js +18 -7
- package/dist/src/formats/csv/exporter.js.map +1 -1
- package/dist/src/formats/csv/importer.d.ts.map +1 -1
- package/dist/src/formats/csv/importer.js +20 -2
- package/dist/src/formats/csv/importer.js.map +1 -1
- package/dist/src/formats/cx2/exporter.d.ts.map +1 -1
- package/dist/src/formats/cx2/exporter.js +84 -33
- package/dist/src/formats/cx2/exporter.js.map +1 -1
- package/dist/src/formats/dot/exporter.js +30 -4
- package/dist/src/formats/dot/exporter.js.map +1 -1
- package/dist/src/formats/dot/importer.js.map +1 -1
- package/dist/src/formats/gml/exporter.d.ts.map +1 -1
- package/dist/src/formats/gml/exporter.js +23 -6
- package/dist/src/formats/gml/exporter.js.map +1 -1
- package/dist/src/formats/obo/syntax.d.ts +4 -0
- package/dist/src/formats/obo/syntax.d.ts.map +1 -1
- package/dist/src/formats/obo/syntax.js +35 -31
- package/dist/src/formats/obo/syntax.js.map +1 -1
- package/dist/src/formats/pajek/importer.js.map +1 -1
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js.map +1 -1
- package/dist/src/sniff.d.ts.map +1 -1
- package/dist/src/sniff.js.map +1 -1
- package/dist/src/types.d.ts +6 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/xgmml.js +2 -2
- package/package.json +2 -2
- package/src/common/declared-types.ts +1 -10
- package/src/common/export.ts +105 -62
- package/src/common/zip.ts +1 -1
- package/src/formats/csv/exporter.ts +19 -15
- package/src/formats/csv/importer.ts +21 -2
- package/src/formats/cx2/exporter.ts +123 -49
- package/src/formats/dot/exporter.ts +37 -4
- package/src/formats/dot/importer.ts +1 -1
- package/src/formats/gml/exporter.ts +24 -6
- package/src/formats/obo/syntax.ts +35 -31
- package/src/formats/pajek/importer.ts +1 -1
- package/src/registry.ts +9 -10
- package/src/sniff.ts +2 -21
- package/src/types.ts +7 -7
- package/dist/chunks/export-CHd4tQE2.js.map +0 -1
- package/dist/chunks/exporter-D23CKNqF.js.map +0 -1
- package/dist/chunks/exporter-DhtW6FxK.js.map +0 -1
- package/dist/chunks/exporter-IHv4nkCm.js.map +0 -1
- package/dist/chunks/importer-B1wmPQjr.js.map +0 -1
- package/dist/chunks/importer-BSALvkui.js.map +0 -1
|
@@ -305,6 +305,25 @@ function versionText(text: string): string {
|
|
|
305
305
|
return NUMBER_TEXT.test(text) ? text : quoteGmlString(text);
|
|
306
306
|
}
|
|
307
307
|
|
|
308
|
+
/**
|
|
309
|
+
* A node or edge table's label role column, which is written under "label" (the key the importer
|
|
310
|
+
* gives the role back to): the key is marked used so a plain column of that name cannot have it.
|
|
311
|
+
* @param columns - the written columns
|
|
312
|
+
* @param label - the table name
|
|
313
|
+
* @param used - the keys already taken, gaining "label" when there is a label role column
|
|
314
|
+
* @returns the label role column, or undefined
|
|
315
|
+
*/
|
|
316
|
+
function labelRoleColumn(columns: readonly Column[], label: string, used: Set<string>): Column | undefined {
|
|
317
|
+
if (label !== "node" && label !== "edge") {
|
|
318
|
+
return undefined;
|
|
319
|
+
}
|
|
320
|
+
const column = columns.find((c) => c.meta.role === "label");
|
|
321
|
+
if (column !== undefined) {
|
|
322
|
+
used.add("label");
|
|
323
|
+
}
|
|
324
|
+
return column;
|
|
325
|
+
}
|
|
326
|
+
|
|
308
327
|
/**
|
|
309
328
|
* Select the written columns of a table and assign their keys, recording invalid and reserved
|
|
310
329
|
* keys as notes (or rewriting them under mangle).
|
|
@@ -326,14 +345,13 @@ function selectColumns(
|
|
|
326
345
|
): WrittenColumn[] {
|
|
327
346
|
const used = new Set<string>(reserved);
|
|
328
347
|
const out: WrittenColumn[] = [];
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
const preferred = preferredKey(column.meta);
|
|
348
|
+
const columns = [...table].filter((c) => isWritten(c) && filter(c));
|
|
349
|
+
const labelRole = labelRoleColumn(columns, label, used);
|
|
350
|
+
for (const column of columns) {
|
|
351
|
+
const preferred = column === labelRole ? "label" : preferredKey(column.meta);
|
|
334
352
|
let key = preferred;
|
|
335
353
|
const valid = isGmlKey(preferred);
|
|
336
|
-
const taken = used.has(preferred);
|
|
354
|
+
const taken = column !== labelRole && used.has(preferred);
|
|
337
355
|
if (!valid || taken) {
|
|
338
356
|
const code = valid ? RESERVED_KEY_CODE : INVALID_KEY_CODE;
|
|
339
357
|
let why = "is not a GML key";
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Every function works on the RAW text (escapes still in place) and unescapes only the pieces it
|
|
8
8
|
* hands back, so an escaped quote, colon, comma, brace or `!` never ends a construct.
|
|
9
|
+
*
|
|
10
|
+
* The scanners read characters with charAt(), never `text[i]`: the importer's linear-time tests
|
|
11
|
+
* count the characters the import reads through the string methods, and an index read is
|
|
12
|
+
* invisible to them, so a quadratic scan written with it would pass unnoticed.
|
|
9
13
|
*/
|
|
10
14
|
|
|
11
15
|
/** The OBO escapes with a meaning of their own; any other `\x` is `x` (the guides). */
|
|
@@ -29,14 +33,14 @@ export function unescapeObo(text: string): string {
|
|
|
29
33
|
}
|
|
30
34
|
let out = "";
|
|
31
35
|
for (let i = 0; i < text.length; i++) {
|
|
32
|
-
const ch = text
|
|
36
|
+
const ch = text.charAt(i);
|
|
33
37
|
if (ch !== "\\") {
|
|
34
38
|
out += ch;
|
|
35
39
|
continue;
|
|
36
40
|
}
|
|
37
41
|
i++;
|
|
38
42
|
if (i < text.length) {
|
|
39
|
-
const next = text
|
|
43
|
+
const next = text.charAt(i);
|
|
40
44
|
out += ESCAPES[next] ?? next;
|
|
41
45
|
}
|
|
42
46
|
}
|
|
@@ -51,7 +55,7 @@ export function unescapeObo(text: string): string {
|
|
|
51
55
|
*/
|
|
52
56
|
function isEscaped(text: string, index: number): boolean {
|
|
53
57
|
let run = 0;
|
|
54
|
-
for (let i = index - 1; i >= 0 && text
|
|
58
|
+
for (let i = index - 1; i >= 0 && text.charAt(i) === "\\"; i--) {
|
|
55
59
|
run++;
|
|
56
60
|
}
|
|
57
61
|
return run % 2 === 1;
|
|
@@ -71,8 +75,8 @@ export function splitFormFeeds(line: string): string[] {
|
|
|
71
75
|
const pieces: string[] = [];
|
|
72
76
|
let quoted = false;
|
|
73
77
|
let start = 0;
|
|
74
|
-
for (let i = 0; i < line.length; i += line
|
|
75
|
-
const ch = line
|
|
78
|
+
for (let i = 0; i < line.length; i += line.charAt(i) === "\\" ? 2 : 1) {
|
|
79
|
+
const ch = line.charAt(i);
|
|
76
80
|
if (ch === '"') {
|
|
77
81
|
quoted = !quoted;
|
|
78
82
|
} else if (ch === "\f" && !quoted) {
|
|
@@ -110,11 +114,11 @@ interface TagValue {
|
|
|
110
114
|
*/
|
|
111
115
|
export function splitTagValue(line: string): TagValue | null {
|
|
112
116
|
for (let i = 0; i < line.length; i++) {
|
|
113
|
-
if (line
|
|
117
|
+
if (line.charAt(i) === "\\") {
|
|
114
118
|
i++;
|
|
115
119
|
continue;
|
|
116
120
|
}
|
|
117
|
-
if (line
|
|
121
|
+
if (line.charAt(i) === ":") {
|
|
118
122
|
return { tag: unescapeObo(line.slice(0, i).trim()), rest: line.slice(i + 1).trimStart() };
|
|
119
123
|
}
|
|
120
124
|
}
|
|
@@ -134,12 +138,12 @@ export function splitTagValue(line: string): TagValue | null {
|
|
|
134
138
|
export function stripComment(rest: string): string {
|
|
135
139
|
let quoted = false;
|
|
136
140
|
for (let i = 0; i < rest.length; i++) {
|
|
137
|
-
const ch = rest
|
|
141
|
+
const ch = rest.charAt(i);
|
|
138
142
|
if (ch === "\\") {
|
|
139
143
|
i++;
|
|
140
144
|
continue;
|
|
141
145
|
}
|
|
142
|
-
const atStart = i === 0 || rest
|
|
146
|
+
const atStart = i === 0 || rest.charAt(i - 1) === " " || rest.charAt(i - 1) === "\t";
|
|
143
147
|
if (ch === '"' && (quoted || atStart)) {
|
|
144
148
|
quoted = !quoted;
|
|
145
149
|
} else if (ch === "!" && !quoted && atStart) {
|
|
@@ -183,7 +187,7 @@ export function splitQualifiers(value: string): QualifiedValue {
|
|
|
183
187
|
const parsed: Qualifiers[] = [];
|
|
184
188
|
let end = value.length;
|
|
185
189
|
let badBlock: string | null = null;
|
|
186
|
-
while (end > 0 && value
|
|
190
|
+
while (end > 0 && value.charAt(end - 1) === "}" && !isEscaped(value, end - 1)) {
|
|
187
191
|
const open = blocks.get(end - 1) ?? -1;
|
|
188
192
|
const block = open < 0 ? null : parseQualifiers(value.slice(open + 1, end - 1));
|
|
189
193
|
if (block === null) {
|
|
@@ -192,7 +196,7 @@ export function splitQualifiers(value: string): QualifiedValue {
|
|
|
192
196
|
}
|
|
193
197
|
parsed.push(block);
|
|
194
198
|
end = open;
|
|
195
|
-
while (end > 0 && /\s/.test(value
|
|
199
|
+
while (end > 0 && /\s/.test(value.charAt(end - 1))) {
|
|
196
200
|
end--;
|
|
197
201
|
}
|
|
198
202
|
}
|
|
@@ -217,7 +221,7 @@ function braceBlocks(value: string): Map<number, number> {
|
|
|
217
221
|
let quoted = false;
|
|
218
222
|
let open = -1;
|
|
219
223
|
for (let i = 0; i < value.length; i++) {
|
|
220
|
-
const ch = value
|
|
224
|
+
const ch = value.charAt(i);
|
|
221
225
|
if (ch === "\\") {
|
|
222
226
|
i++;
|
|
223
227
|
continue;
|
|
@@ -244,8 +248,8 @@ function braceBlocks(value: string): Map<number, number> {
|
|
|
244
248
|
export function unclosedBlock(value: string): number {
|
|
245
249
|
let quoted = false;
|
|
246
250
|
let open = -1;
|
|
247
|
-
for (let i = 0; i < value.length; i += value
|
|
248
|
-
const ch = value
|
|
251
|
+
for (let i = 0; i < value.length; i += value.charAt(i) === "\\" ? 2 : 1) {
|
|
252
|
+
const ch = value.charAt(i);
|
|
249
253
|
if (ch === "\\") {
|
|
250
254
|
continue;
|
|
251
255
|
}
|
|
@@ -297,7 +301,7 @@ export function parseQualifiers(inner: string): Qualifiers | null {
|
|
|
297
301
|
const n = inner.length;
|
|
298
302
|
let any = false;
|
|
299
303
|
while (i < n) {
|
|
300
|
-
while (i < n && (inner
|
|
304
|
+
while (i < n && (inner.charAt(i) === " " || inner.charAt(i) === "\t" || inner.charAt(i) === ",")) {
|
|
301
305
|
i++;
|
|
302
306
|
}
|
|
303
307
|
if (i >= n) {
|
|
@@ -312,11 +316,11 @@ export function parseQualifiers(inner: string): Qualifiers | null {
|
|
|
312
316
|
return null;
|
|
313
317
|
}
|
|
314
318
|
i = eq + 1;
|
|
315
|
-
while (i < n && (inner
|
|
319
|
+
while (i < n && (inner.charAt(i) === " " || inner.charAt(i) === "\t")) {
|
|
316
320
|
i++;
|
|
317
321
|
}
|
|
318
322
|
let value: string;
|
|
319
|
-
if (inner
|
|
323
|
+
if (inner.charAt(i) === '"') {
|
|
320
324
|
const end = closingQuote(inner, i + 1);
|
|
321
325
|
if (end < 0) {
|
|
322
326
|
return null;
|
|
@@ -325,8 +329,8 @@ export function parseQualifiers(inner: string): Qualifiers | null {
|
|
|
325
329
|
i = end + 1;
|
|
326
330
|
} else {
|
|
327
331
|
let end = i;
|
|
328
|
-
while (end < n && inner
|
|
329
|
-
end += inner
|
|
332
|
+
while (end < n && inner.charAt(end) !== ",") {
|
|
333
|
+
end += inner.charAt(end) === "\\" ? 2 : 1;
|
|
330
334
|
}
|
|
331
335
|
value = unescapeObo(inner.slice(i, end).trim());
|
|
332
336
|
i = end;
|
|
@@ -345,9 +349,9 @@ export function parseQualifiers(inner: string): Qualifiers | null {
|
|
|
345
349
|
*/
|
|
346
350
|
function closingQuote(text: string, from: number): number {
|
|
347
351
|
for (let i = from; i < text.length; i++) {
|
|
348
|
-
if (text
|
|
352
|
+
if (text.charAt(i) === "\\") {
|
|
349
353
|
i++;
|
|
350
|
-
} else if (text
|
|
354
|
+
} else if (text.charAt(i) === '"') {
|
|
351
355
|
return i;
|
|
352
356
|
}
|
|
353
357
|
}
|
|
@@ -379,7 +383,7 @@ export function tokenize(value: string): Token[] {
|
|
|
379
383
|
const n = value.length;
|
|
380
384
|
let i = 0;
|
|
381
385
|
while (i < n) {
|
|
382
|
-
const ch = value
|
|
386
|
+
const ch = value.charAt(i);
|
|
383
387
|
if (ch === " " || ch === "\t") {
|
|
384
388
|
i++;
|
|
385
389
|
continue;
|
|
@@ -390,8 +394,8 @@ export function tokenize(value: string): Token[] {
|
|
|
390
394
|
// a 1.4 language tag glued to the closing quote ("chat"@fr) is kept with the text, as an
|
|
391
395
|
// unquoted chat@fr is (research-obo.md 4.1: no language is split out)
|
|
392
396
|
let after = stop + 1;
|
|
393
|
-
if (end >= 0 && value
|
|
394
|
-
while (after < n && value
|
|
397
|
+
if (end >= 0 && value.charAt(after) === "@") {
|
|
398
|
+
while (after < n && value.charAt(after) !== " " && value.charAt(after) !== "\t") {
|
|
395
399
|
after++;
|
|
396
400
|
}
|
|
397
401
|
}
|
|
@@ -412,8 +416,8 @@ export function tokenize(value: string): Token[] {
|
|
|
412
416
|
continue;
|
|
413
417
|
}
|
|
414
418
|
let end = i;
|
|
415
|
-
while (end < n && value
|
|
416
|
-
end += value
|
|
419
|
+
while (end < n && value.charAt(end) !== " " && value.charAt(end) !== "\t") {
|
|
420
|
+
end += value.charAt(end) === "\\" ? 2 : 1;
|
|
417
421
|
}
|
|
418
422
|
tokens.push({ kind: "word", text: unescapeObo(value.slice(i, Math.min(end, n))), unterminated: false });
|
|
419
423
|
i = end;
|
|
@@ -430,7 +434,7 @@ export function tokenize(value: string): Token[] {
|
|
|
430
434
|
function closingBracket(text: string, from: number): number {
|
|
431
435
|
let quoted = false;
|
|
432
436
|
for (let i = from; i < text.length; i++) {
|
|
433
|
-
const ch = text
|
|
437
|
+
const ch = text.charAt(i);
|
|
434
438
|
if (ch === "\\") {
|
|
435
439
|
i++;
|
|
436
440
|
} else if (ch === '"') {
|
|
@@ -468,9 +472,9 @@ export function parseXref(raw: string): Xref | null {
|
|
|
468
472
|
const { value, qualifiers } = splitQualifiers(raw.trim());
|
|
469
473
|
let quote = -1;
|
|
470
474
|
for (let i = 0; i < value.length; i++) {
|
|
471
|
-
if (value
|
|
475
|
+
if (value.charAt(i) === "\\") {
|
|
472
476
|
i++;
|
|
473
|
-
} else if (value
|
|
477
|
+
} else if (value.charAt(i) === '"') {
|
|
474
478
|
quote = i;
|
|
475
479
|
break;
|
|
476
480
|
}
|
|
@@ -508,7 +512,7 @@ export function parseXrefList(inner: string): Xref[] {
|
|
|
508
512
|
}
|
|
509
513
|
};
|
|
510
514
|
for (let i = 0; i < inner.length; i++) {
|
|
511
|
-
const ch = inner
|
|
515
|
+
const ch = inner.charAt(i);
|
|
512
516
|
if (ch === "\\") {
|
|
513
517
|
i++;
|
|
514
518
|
} else if (ch === '"') {
|
|
@@ -538,7 +542,7 @@ export function hasStrayBrace(value: string): boolean {
|
|
|
538
542
|
let quoted = false;
|
|
539
543
|
let listed = false;
|
|
540
544
|
for (let i = 0; i < value.length; i++) {
|
|
541
|
-
const ch = value
|
|
545
|
+
const ch = value.charAt(i);
|
|
542
546
|
if (ch === "\\") {
|
|
543
547
|
i++;
|
|
544
548
|
} else if (ch === '"') {
|
|
@@ -1607,7 +1607,7 @@ class PajekParser {
|
|
|
1607
1607
|
private extras(tokens: readonly string[], start: number, domain: "node" | "edge", line: number): RowExtras {
|
|
1608
1608
|
const extras: RowExtras = { keys: [], values: [], spells: null };
|
|
1609
1609
|
const seen = new Set<string>();
|
|
1610
|
-
for (let i = start; i < tokens.length;
|
|
1610
|
+
for (let i = start; i < tokens.length;) {
|
|
1611
1611
|
const token = tokens[i];
|
|
1612
1612
|
if (token.startsWith("[")) {
|
|
1613
1613
|
extras.spells = this.intervals(token, domain);
|
package/src/registry.ts
CHANGED
|
@@ -421,16 +421,15 @@ export class FormatRegistry {
|
|
|
421
421
|
): Promise<ImportGraphResult> {
|
|
422
422
|
const opts = options as ImportGraphOptions;
|
|
423
423
|
const picked = await this.choose(input, opts);
|
|
424
|
-
const unknown = this.unknownOptions(opts).map(
|
|
425
|
-
(
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
}),
|
|
424
|
+
const unknown = this.unknownOptions(opts).map((name): ImportIssue =>
|
|
425
|
+
Object.freeze({
|
|
426
|
+
category: "unsupported",
|
|
427
|
+
severity: "warning",
|
|
428
|
+
code: UNKNOWN_OPTION_CODE,
|
|
429
|
+
message: unknownOptionText(name),
|
|
430
|
+
line: null,
|
|
431
|
+
element: name,
|
|
432
|
+
}),
|
|
434
433
|
);
|
|
435
434
|
const chosen = unknown.length === 0 ? picked : { ...picked, warnings: [...picked.warnings, ...unknown] };
|
|
436
435
|
const { importer } = chosen;
|
package/src/sniff.ts
CHANGED
|
@@ -32,19 +32,7 @@ import { type GraphImporter } from "./types.js";
|
|
|
32
32
|
* @category Formats and detection
|
|
33
33
|
*/
|
|
34
34
|
export type GraphFormatName =
|
|
35
|
-
| "
|
|
36
|
-
| "graphml"
|
|
37
|
-
| "gml"
|
|
38
|
-
| "dot"
|
|
39
|
-
| "pajek"
|
|
40
|
-
| "csv"
|
|
41
|
-
| "json"
|
|
42
|
-
| "neo4j"
|
|
43
|
-
| "xgmml"
|
|
44
|
-
| "cx2"
|
|
45
|
-
| "cx"
|
|
46
|
-
| "obo"
|
|
47
|
-
| "cys";
|
|
35
|
+
"gexf" | "graphml" | "gml" | "dot" | "pajek" | "csv" | "json" | "neo4j" | "xgmml" | "cx2" | "cx" | "obo" | "cys";
|
|
48
36
|
|
|
49
37
|
/**
|
|
50
38
|
* A format name: one of the built-in names (with editor autocomplete) or the name of a format you
|
|
@@ -345,14 +333,7 @@ export function sniffJsonDialectHead(head: Uint8Array | string): JsonImportDiale
|
|
|
345
333
|
|
|
346
334
|
/** Where a key was seen while scanning a truncated head. */
|
|
347
335
|
type KeyPath =
|
|
348
|
-
| ""
|
|
349
|
-
| "graph"
|
|
350
|
-
| "options"
|
|
351
|
-
| "nodes[0]"
|
|
352
|
-
| "edges[0]"
|
|
353
|
-
| "links[0]"
|
|
354
|
-
| "graphs[0].nodes[]"
|
|
355
|
-
| "graphs[0].edges[]";
|
|
336
|
+
"" | "graph" | "options" | "nodes[0]" | "edges[0]" | "links[0]" | "graphs[0].nodes[]" | "graphs[0].edges[]";
|
|
356
337
|
|
|
357
338
|
/**
|
|
358
339
|
* A partial document rebuilt from the keys a truncated head reveals: every key gets a placeholder
|
package/src/types.ts
CHANGED
|
@@ -368,6 +368,12 @@ export interface LossNote {
|
|
|
368
368
|
readonly column: string | null;
|
|
369
369
|
/** How many nodes, edges or values are affected, or null when not counted. */
|
|
370
370
|
readonly count: number | null;
|
|
371
|
+
/**
|
|
372
|
+
* Every column the note is about, when it is about several and `column` is null: the graph
|
|
373
|
+
* attributes a format has no place for, or the node columns a CSV edge table leaves for the node
|
|
374
|
+
* table. Absent on a note about one column or none.
|
|
375
|
+
*/
|
|
376
|
+
readonly columns?: readonly string[];
|
|
371
377
|
}
|
|
372
378
|
|
|
373
379
|
/**
|
|
@@ -458,13 +464,7 @@ export interface GraphExporter<Opts = unknown> {
|
|
|
458
464
|
* @category Reports and errors
|
|
459
465
|
*/
|
|
460
466
|
export type IssueCategory =
|
|
461
|
-
| "
|
|
462
|
-
| "missing-value"
|
|
463
|
-
| "validation-error"
|
|
464
|
-
| "unsupported"
|
|
465
|
-
| "precision"
|
|
466
|
-
| "coercion"
|
|
467
|
-
| "merged";
|
|
467
|
+
"parse-error" | "missing-value" | "validation-error" | "unsupported" | "precision" | "coercion" | "merged";
|
|
468
468
|
|
|
469
469
|
/**
|
|
470
470
|
* One problem found while importing.
|