typed-csv 1.0.0

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.
@@ -0,0 +1,2020 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/csv-loader/esbuild.ts
31
+ var esbuild_exports = {};
32
+ __export(esbuild_exports, {
33
+ csvLoader: () => csvLoader,
34
+ default: () => esbuild_default
35
+ });
36
+ module.exports = __toCommonJS(esbuild_exports);
37
+ var path4 = __toESM(require("path"));
38
+ var fs2 = __toESM(require("fs"));
39
+
40
+ // src/csv-loader/module-gen.ts
41
+ var path3 = __toESM(require("path"));
42
+
43
+ // src/csv-loader/loader.ts
44
+ var import_sync = require("csv-parse/sync");
45
+
46
+ // src/parser.ts
47
+ var ParseError = class extends Error {
48
+ constructor(message, position, schema, value) {
49
+ let fullMessage = message;
50
+ if (position !== void 0) {
51
+ fullMessage += ` at position ${position}`;
52
+ }
53
+ if (schema !== void 0) {
54
+ fullMessage += `. Schema: ${schema}`;
55
+ }
56
+ if (value !== void 0) {
57
+ fullMessage += `. Value: ${value}`;
58
+ }
59
+ super(fullMessage);
60
+ this.position = position;
61
+ this.schema = schema;
62
+ this.value = value;
63
+ this.name = "ParseError";
64
+ }
65
+ };
66
+ var Parser = class {
67
+ constructor(input) {
68
+ this.pos = 0;
69
+ this.input = input;
70
+ }
71
+ peek() {
72
+ return this.input[this.pos] || "";
73
+ }
74
+ consume() {
75
+ return this.input[this.pos++] || "";
76
+ }
77
+ skipWhitespace() {
78
+ while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) {
79
+ this.pos++;
80
+ }
81
+ }
82
+ match(str) {
83
+ return this.input.slice(this.pos, this.pos + str.length) === str;
84
+ }
85
+ consumeStr(str) {
86
+ if (this.match(str)) {
87
+ this.pos += str.length;
88
+ return true;
89
+ }
90
+ return false;
91
+ }
92
+ getPosition() {
93
+ return this.pos;
94
+ }
95
+ getInputLength() {
96
+ return this.input.length;
97
+ }
98
+ parseSchema() {
99
+ this.skipWhitespace();
100
+ let schema = this.parseSchemaInternal();
101
+ this.skipWhitespace();
102
+ if (this.consumeStr("[")) {
103
+ this.skipWhitespace();
104
+ if (!this.consumeStr("]")) {
105
+ throw new ParseError("Expected ]", this.pos);
106
+ }
107
+ schema = { type: "array", element: schema };
108
+ this.skipWhitespace();
109
+ }
110
+ if (this.consumeStr("|")) {
111
+ const members = [schema];
112
+ while (true) {
113
+ this.skipWhitespace();
114
+ const member = this.parseSchemaInternal();
115
+ members.push(member);
116
+ this.skipWhitespace();
117
+ if (!this.consumeStr("|")) {
118
+ break;
119
+ }
120
+ }
121
+ return {
122
+ type: "union",
123
+ members
124
+ };
125
+ }
126
+ return schema;
127
+ }
128
+ parseSchemaInternal() {
129
+ this.skipWhitespace();
130
+ if (this.consumeStr("(")) {
131
+ this.skipWhitespace();
132
+ const schema = this.parseSchema();
133
+ this.skipWhitespace();
134
+ if (!this.consumeStr(")")) {
135
+ throw new ParseError("Expected )", this.pos);
136
+ }
137
+ this.skipWhitespace();
138
+ if (this.consumeStr("[")) {
139
+ this.skipWhitespace();
140
+ if (!this.consumeStr("]")) {
141
+ throw new ParseError("Expected ]", this.pos);
142
+ }
143
+ return { type: "array", element: schema };
144
+ }
145
+ return schema;
146
+ }
147
+ if (this.peek() === '"' || this.peek() === "'") {
148
+ return this.parseStringLiteralSchema();
149
+ }
150
+ if (this.consumeStr("~")) {
151
+ return this.parseReverseReferenceSchema();
152
+ }
153
+ if (this.consumeStr("@")) {
154
+ return this.parseReferenceSchema();
155
+ }
156
+ if (this.consumeStr("string")) {
157
+ if (this.consumeStr("[")) {
158
+ this.skipWhitespace();
159
+ if (!this.consumeStr("]")) {
160
+ throw new ParseError("Expected ]", this.pos);
161
+ }
162
+ return { type: "array", element: { type: "string" } };
163
+ }
164
+ return { type: "string" };
165
+ }
166
+ if (this.consumeStr("number")) {
167
+ if (this.consumeStr("[")) {
168
+ this.skipWhitespace();
169
+ if (!this.consumeStr("]")) {
170
+ throw new ParseError("Expected ]", this.pos);
171
+ }
172
+ return { type: "array", element: { type: "number" } };
173
+ }
174
+ return { type: "number" };
175
+ }
176
+ if (this.consumeStr("int")) {
177
+ if (this.consumeStr("[")) {
178
+ this.skipWhitespace();
179
+ if (!this.consumeStr("]")) {
180
+ throw new ParseError("Expected ]", this.pos);
181
+ }
182
+ return { type: "array", element: { type: "int" } };
183
+ }
184
+ return { type: "int" };
185
+ }
186
+ if (this.consumeStr("float")) {
187
+ if (this.consumeStr("[")) {
188
+ this.skipWhitespace();
189
+ if (!this.consumeStr("]")) {
190
+ throw new ParseError("Expected ]", this.pos);
191
+ }
192
+ return { type: "array", element: { type: "float" } };
193
+ }
194
+ return { type: "float" };
195
+ }
196
+ if (this.consumeStr("boolean")) {
197
+ if (this.consumeStr("[")) {
198
+ this.skipWhitespace();
199
+ if (!this.consumeStr("]")) {
200
+ throw new ParseError("Expected ]", this.pos);
201
+ }
202
+ return { type: "array", element: { type: "boolean" } };
203
+ }
204
+ return { type: "boolean" };
205
+ }
206
+ if (this.consumeStr("[")) {
207
+ const elements = [];
208
+ this.skipWhitespace();
209
+ if (this.peek() === "]") {
210
+ this.consume();
211
+ throw new ParseError("Empty array/tuple not allowed", this.pos);
212
+ }
213
+ elements.push(this.parseNamedSchema());
214
+ this.skipWhitespace();
215
+ if (this.consumeStr(";")) {
216
+ const remainingElements = [];
217
+ while (true) {
218
+ this.skipWhitespace();
219
+ remainingElements.push(this.parseNamedSchema());
220
+ this.skipWhitespace();
221
+ if (!this.consumeStr(";")) {
222
+ break;
223
+ }
224
+ }
225
+ elements.push(...remainingElements);
226
+ }
227
+ this.skipWhitespace();
228
+ if (!this.consumeStr("]")) {
229
+ throw new ParseError("Expected ]", this.pos);
230
+ }
231
+ if (this.consumeStr("[")) {
232
+ this.skipWhitespace();
233
+ if (!this.consumeStr("]")) {
234
+ throw new ParseError("Expected ]", this.pos);
235
+ }
236
+ if (elements.length === 1 && !elements[0].name) {
237
+ return { type: "array", element: elements[0].schema };
238
+ }
239
+ return { type: "array", element: { type: "tuple", elements } };
240
+ }
241
+ if (elements.length === 1 && !elements[0].name) {
242
+ return { type: "array", element: elements[0].schema };
243
+ }
244
+ return { type: "tuple", elements };
245
+ }
246
+ throw new ParseError(
247
+ `Unknown type: ${this.peek() || "end of input"}`,
248
+ this.pos
249
+ );
250
+ }
251
+ parseStringLiteralSchema() {
252
+ const value = this.parseStringLiteral();
253
+ return {
254
+ type: "stringLiteral",
255
+ value
256
+ };
257
+ }
258
+ parseStringLiteral() {
259
+ const quote = this.peek();
260
+ if (quote !== '"' && quote !== "'") {
261
+ throw new ParseError("Expected string literal with quotes", this.pos);
262
+ }
263
+ this.consume();
264
+ let value = "";
265
+ while (this.pos < this.input.length) {
266
+ const char = this.peek();
267
+ if (char === "\\") {
268
+ this.consume();
269
+ const nextChar = this.consume();
270
+ if (nextChar === '"' || nextChar === "'" || nextChar === "\\" || nextChar === "|" || nextChar === ";" || nextChar === "(" || nextChar === ")") {
271
+ value += nextChar;
272
+ } else {
273
+ value += "\\" + nextChar;
274
+ }
275
+ } else if (char === quote) {
276
+ this.consume();
277
+ return value;
278
+ } else {
279
+ value += this.consume();
280
+ }
281
+ }
282
+ throw new ParseError("Unterminated string literal", this.pos);
283
+ }
284
+ parseNamedSchema() {
285
+ this.skipWhitespace();
286
+ const startpos = this.pos;
287
+ let identifier = "";
288
+ while (this.pos < this.input.length && /[a-zA-Z0-9\-_]/.test(this.peek())) {
289
+ identifier += this.consume();
290
+ }
291
+ if (identifier.length === 0) {
292
+ const schema = this.parseSchema();
293
+ return { schema };
294
+ }
295
+ this.skipWhitespace();
296
+ if (this.consumeStr(":")) {
297
+ this.skipWhitespace();
298
+ const name = identifier;
299
+ const schema = this.parseSchema();
300
+ return { name, schema };
301
+ } else {
302
+ this.pos = startpos;
303
+ const schema = this.parseSchema();
304
+ return { schema };
305
+ }
306
+ }
307
+ parseReferenceSchema() {
308
+ let tableName = "";
309
+ while (this.pos < this.input.length && /[a-zA-Z0-9\-_]/.test(this.peek())) {
310
+ tableName += this.consume();
311
+ }
312
+ if (tableName.length === 0) {
313
+ throw new ParseError("Expected table name after @", this.pos);
314
+ }
315
+ this.skipWhitespace();
316
+ if (this.consumeStr("[]")) {
317
+ this.skipWhitespace();
318
+ const isOptional2 = this.consumeStr("?");
319
+ return {
320
+ type: "reference",
321
+ tableName,
322
+ isArray: true,
323
+ isOptional: isOptional2
324
+ };
325
+ }
326
+ const isOptional = this.consumeStr("?");
327
+ return {
328
+ type: "reference",
329
+ tableName,
330
+ isArray: false,
331
+ isOptional
332
+ };
333
+ }
334
+ parseReverseReferenceSchema() {
335
+ let tableName = "";
336
+ while (this.pos < this.input.length && /[a-zA-Z0-9\-_]/.test(this.peek())) {
337
+ tableName += this.consume();
338
+ }
339
+ if (tableName.length === 0) {
340
+ throw new ParseError("Expected table name after ~", this.pos);
341
+ }
342
+ this.skipWhitespace();
343
+ if (!this.consumeStr("(")) {
344
+ throw new ParseError(
345
+ "Expected ( after reverse reference table name",
346
+ this.pos
347
+ );
348
+ }
349
+ this.skipWhitespace();
350
+ let foreignKey = "";
351
+ while (this.pos < this.input.length && /[a-zA-Z0-9\-_]/.test(this.peek())) {
352
+ foreignKey += this.consume();
353
+ }
354
+ if (foreignKey.length === 0) {
355
+ throw new ParseError("Expected foreign key name inside ()", this.pos);
356
+ }
357
+ this.skipWhitespace();
358
+ if (!this.consumeStr(")")) {
359
+ throw new ParseError("Expected ) after foreign key name", this.pos);
360
+ }
361
+ this.skipWhitespace();
362
+ const isOptional = this.consumeStr("?");
363
+ return {
364
+ type: "reverseReference",
365
+ tableName,
366
+ foreignKey,
367
+ isOptional
368
+ };
369
+ }
370
+ };
371
+ function parseSchema(schemaString) {
372
+ const parser = new Parser(schemaString.trim());
373
+ const schema = parser.parseSchema();
374
+ if (parser.getPosition() < parser.getInputLength()) {
375
+ throw new ParseError("Unexpected input after schema", parser.getPosition());
376
+ }
377
+ return schema;
378
+ }
379
+
380
+ // src/type-utils.ts
381
+ function schemaToTypeString(schema, resourceNames) {
382
+ switch (schema.type) {
383
+ case "string":
384
+ return "string";
385
+ case "number":
386
+ case "int":
387
+ case "float":
388
+ return "number";
389
+ case "boolean":
390
+ return "boolean";
391
+ case "stringLiteral":
392
+ return `"${schema.value}"`;
393
+ case "union":
394
+ return schema.members.map((m) => schemaToTypeString(m, resourceNames)).join(" | ");
395
+ case "reference": {
396
+ const typeName = resourceNames?.get(schema.tableName) || schema.tableName.charAt(0).toUpperCase() + schema.tableName.slice(1);
397
+ const baseType = schema.isArray ? `${typeName}[]` : typeName;
398
+ return schema.isOptional ? `${baseType} | null` : baseType;
399
+ }
400
+ case "reverseReference": {
401
+ const typeName = resourceNames?.get(schema.tableName) || schema.tableName.charAt(0).toUpperCase() + schema.tableName.slice(1);
402
+ const baseType = `${typeName}[]`;
403
+ return schema.isOptional ? `${baseType} | null` : baseType;
404
+ }
405
+ case "array":
406
+ if (schema.element.type === "tuple") {
407
+ const tupleElements2 = schema.element.elements.map((el) => {
408
+ const typeStr = schemaToTypeString(el.schema, resourceNames);
409
+ return el.name ? `${el.name}: ${typeStr}` : typeStr;
410
+ });
411
+ return `[${tupleElements2.join(", ")}][]`;
412
+ }
413
+ const elementType = schemaToTypeString(schema.element, resourceNames);
414
+ if (schema.element.type === "union") {
415
+ return `(${elementType})[]`;
416
+ }
417
+ return `${elementType}[]`;
418
+ case "tuple":
419
+ const tupleElements = schema.elements.map((el) => {
420
+ const typeStr = schemaToTypeString(el.schema, resourceNames);
421
+ return el.name ? `${el.name}: ${typeStr}` : typeStr;
422
+ });
423
+ return `[${tupleElements.join(", ")}]`;
424
+ default:
425
+ return "unknown";
426
+ }
427
+ }
428
+ function createValidator(schema) {
429
+ return function validate(value) {
430
+ switch (schema.type) {
431
+ case "string":
432
+ return typeof value === "string";
433
+ case "number":
434
+ return typeof value === "number" && !isNaN(value);
435
+ case "int":
436
+ return typeof value === "number" && !isNaN(value) && Number.isInteger(value);
437
+ case "float":
438
+ return typeof value === "number" && !isNaN(value);
439
+ case "boolean":
440
+ return typeof value === "boolean";
441
+ case "stringLiteral":
442
+ return typeof value === "string" && value === schema.value;
443
+ case "union":
444
+ return schema.members.some((member) => createValidator(member)(value));
445
+ case "tuple":
446
+ if (!Array.isArray(value)) return false;
447
+ if (value.length !== schema.elements.length) return false;
448
+ return schema.elements.every(
449
+ (elementSchema, index) => createValidator(elementSchema.schema)(value[index])
450
+ );
451
+ case "array":
452
+ if (!Array.isArray(value)) return false;
453
+ return value.every((item) => createValidator(schema.element)(item));
454
+ case "reference":
455
+ if (schema.isOptional && value === null) return true;
456
+ if (schema.isArray) {
457
+ return Array.isArray(value) && value.every((id) => typeof id === "string");
458
+ }
459
+ return typeof value === "string" || Array.isArray(value) && value.every((id) => typeof id === "string");
460
+ case "reverseReference":
461
+ if (schema.isOptional && value === null) return true;
462
+ return Array.isArray(value);
463
+ default:
464
+ return false;
465
+ }
466
+ };
467
+ }
468
+
469
+ // src/value-parser.ts
470
+ var ValueParser = class {
471
+ constructor(input, schemaString) {
472
+ this.pos = 0;
473
+ this.input = input;
474
+ this.schemaString = schemaString;
475
+ }
476
+ peek() {
477
+ return this.input[this.pos] || "";
478
+ }
479
+ consume() {
480
+ return this.input[this.pos++] || "";
481
+ }
482
+ skipWhitespace() {
483
+ while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) {
484
+ this.pos++;
485
+ }
486
+ }
487
+ consumeStr(str) {
488
+ if (this.input.slice(this.pos, this.pos + str.length) === str) {
489
+ this.pos += str.length;
490
+ return true;
491
+ }
492
+ return false;
493
+ }
494
+ parseValue(schema, allowOmitBrackets = false) {
495
+ this.skipWhitespace();
496
+ switch (schema.type) {
497
+ case "string":
498
+ return this.parseStringValue();
499
+ case "number":
500
+ return this.parseNumberValue();
501
+ case "int":
502
+ return this.parseIntValue();
503
+ case "float":
504
+ return this.parseFloatValue();
505
+ case "boolean":
506
+ return this.parseBooleanValue();
507
+ case "stringLiteral":
508
+ return this.parseStringLiteralValue(schema);
509
+ case "union":
510
+ return this.parseUnionValue(schema);
511
+ case "tuple":
512
+ return this.parseTupleValue(schema, allowOmitBrackets);
513
+ case "array":
514
+ return this.parseArrayValue(schema, allowOmitBrackets);
515
+ case "reference":
516
+ return this.parseReferenceValue(schema);
517
+ case "reverseReference":
518
+ return null;
519
+ default:
520
+ throw new ParseError(
521
+ `Unknown schema type: ${schema.type}`,
522
+ this.pos,
523
+ this.schemaString,
524
+ this.input
525
+ );
526
+ }
527
+ }
528
+ parseStringValue() {
529
+ let result = "";
530
+ while (this.pos < this.input.length) {
531
+ const char = this.peek();
532
+ if (char === "\\") {
533
+ this.consume();
534
+ const nextChar = this.consume();
535
+ if (nextChar === ";" || nextChar === "[" || nextChar === "]" || nextChar === "\\") {
536
+ result += nextChar;
537
+ } else {
538
+ result += "\\" + nextChar;
539
+ }
540
+ } else if (char === ";" || char === "]") {
541
+ break;
542
+ } else {
543
+ result += this.consume();
544
+ }
545
+ }
546
+ return result.trim();
547
+ }
548
+ parseNumberValue() {
549
+ let numStr = "";
550
+ while (this.pos < this.input.length && /[\d.\-+eE]/.test(this.peek())) {
551
+ numStr += this.consume();
552
+ }
553
+ const num = parseFloat(numStr);
554
+ if (isNaN(num)) {
555
+ throw new ParseError(
556
+ "Invalid number",
557
+ this.pos - numStr.length,
558
+ this.schemaString,
559
+ this.input
560
+ );
561
+ }
562
+ return num;
563
+ }
564
+ parseIntValue() {
565
+ let numStr = "";
566
+ while (this.pos < this.input.length && /[\d.\-+eE]/.test(this.peek())) {
567
+ numStr += this.consume();
568
+ }
569
+ const num = parseFloat(numStr);
570
+ if (isNaN(num)) {
571
+ throw new ParseError(
572
+ "Invalid number",
573
+ this.pos - numStr.length,
574
+ this.schemaString,
575
+ this.input
576
+ );
577
+ }
578
+ if (!Number.isInteger(num)) {
579
+ throw new ParseError(
580
+ "Expected integer value",
581
+ this.pos - numStr.length,
582
+ this.schemaString,
583
+ this.input
584
+ );
585
+ }
586
+ return num;
587
+ }
588
+ parseFloatValue() {
589
+ return this.parseNumberValue();
590
+ }
591
+ parseBooleanValue() {
592
+ if (this.consumeStr("true")) {
593
+ return true;
594
+ }
595
+ if (this.consumeStr("false")) {
596
+ return false;
597
+ }
598
+ throw new ParseError(
599
+ "Expected true or false",
600
+ this.pos,
601
+ this.schemaString,
602
+ this.input
603
+ );
604
+ }
605
+ parseStringLiteralValue(schema) {
606
+ const quote = this.peek();
607
+ if (quote === '"' || quote === "'") {
608
+ this.consume();
609
+ let value = "";
610
+ while (this.pos < this.input.length) {
611
+ const char = this.peek();
612
+ if (char === "\\") {
613
+ this.consume();
614
+ const nextChar = this.consume();
615
+ if (nextChar === '"' || nextChar === "'" || nextChar === "\\" || nextChar === ";") {
616
+ value += nextChar;
617
+ } else {
618
+ value += "\\" + nextChar;
619
+ }
620
+ } else if (char === quote) {
621
+ this.consume();
622
+ if (value !== schema.value) {
623
+ throw new ParseError(
624
+ `Invalid value '"${value}"'. Expected '"${schema.value}"'`,
625
+ this.pos,
626
+ this.schemaString,
627
+ this.input
628
+ );
629
+ }
630
+ return value;
631
+ } else {
632
+ value += this.consume();
633
+ }
634
+ }
635
+ throw new ParseError(
636
+ "Unterminated string literal",
637
+ this.pos,
638
+ this.schemaString,
639
+ this.input
640
+ );
641
+ } else {
642
+ let value = "";
643
+ while (this.pos < this.input.length) {
644
+ const char = this.peek();
645
+ if (char === ";" || char === "]" || char === ")") {
646
+ break;
647
+ }
648
+ value += this.consume();
649
+ }
650
+ value = value.trim();
651
+ if (value !== schema.value) {
652
+ throw new ParseError(
653
+ `Invalid value '${value}'. Expected '${schema.value}'`,
654
+ this.pos - value.length,
655
+ this.schemaString,
656
+ this.input
657
+ );
658
+ }
659
+ return value;
660
+ }
661
+ }
662
+ parseUnionValue(schema) {
663
+ const savedPos = this.pos;
664
+ const errors = [];
665
+ for (let i = 0; i < schema.members.length; i++) {
666
+ this.pos = savedPos;
667
+ try {
668
+ return this.parseValue(schema.members[i], false);
669
+ } catch (e) {
670
+ errors.push(e);
671
+ }
672
+ }
673
+ throw new ParseError(
674
+ `Value does not match any union member. Tried ${schema.members.length} alternatives.`,
675
+ this.pos,
676
+ this.schemaString,
677
+ this.input
678
+ );
679
+ }
680
+ parseTupleValue(schema, allowOmitBrackets) {
681
+ let hasOpenBracket = false;
682
+ if (this.peek() === "[") {
683
+ this.consume();
684
+ hasOpenBracket = true;
685
+ } else if (!allowOmitBrackets) {
686
+ throw new ParseError(
687
+ "Expected [",
688
+ this.pos,
689
+ this.schemaString,
690
+ this.input
691
+ );
692
+ }
693
+ this.skipWhitespace();
694
+ if (this.peek() === "]" && hasOpenBracket) {
695
+ this.consume();
696
+ return [];
697
+ }
698
+ const result = [];
699
+ for (let i = 0; i < schema.elements.length; i++) {
700
+ this.skipWhitespace();
701
+ const elementSchema = schema.elements[i];
702
+ if (elementSchema.name) {
703
+ this.skipWhitespace();
704
+ const savedPos = this.pos;
705
+ if (this.consumeStr(`${elementSchema.name}:`)) {
706
+ this.skipWhitespace();
707
+ } else {
708
+ this.pos = savedPos;
709
+ }
710
+ }
711
+ result.push(this.parseValue(elementSchema.schema, false));
712
+ this.skipWhitespace();
713
+ if (i < schema.elements.length - 1) {
714
+ if (!this.consumeStr(";")) {
715
+ throw new ParseError(
716
+ "Expected ;",
717
+ this.pos,
718
+ this.schemaString,
719
+ this.input
720
+ );
721
+ }
722
+ }
723
+ }
724
+ this.skipWhitespace();
725
+ if (hasOpenBracket) {
726
+ if (!this.consumeStr("]")) {
727
+ throw new ParseError(
728
+ "Expected ]",
729
+ this.pos,
730
+ this.schemaString,
731
+ this.input
732
+ );
733
+ }
734
+ }
735
+ return result;
736
+ }
737
+ parseArrayValue(schema, allowOmitBrackets) {
738
+ let hasOpenBracket = false;
739
+ const elementIsTupleOrArray = schema.element.type === "tuple" || schema.element.type === "array";
740
+ if (this.pos >= this.input.length || !this.input.trim()) {
741
+ return [];
742
+ }
743
+ if (this.peek() === "[") {
744
+ if (!elementIsTupleOrArray) {
745
+ this.consume();
746
+ hasOpenBracket = true;
747
+ } else {
748
+ const savedPos = this.pos;
749
+ this.consume();
750
+ this.skipWhitespace();
751
+ if (this.peek() === "]") {
752
+ this.consume();
753
+ return [];
754
+ } else if (this.peek() === "[") {
755
+ hasOpenBracket = true;
756
+ } else {
757
+ this.pos = savedPos;
758
+ }
759
+ }
760
+ }
761
+ if (!hasOpenBracket && !allowOmitBrackets && !elementIsTupleOrArray) {
762
+ throw new ParseError(
763
+ "Expected [",
764
+ this.pos,
765
+ this.schemaString,
766
+ this.input
767
+ );
768
+ }
769
+ this.skipWhitespace();
770
+ if (this.peek() === "]" && hasOpenBracket) {
771
+ this.consume();
772
+ return [];
773
+ }
774
+ const result = [];
775
+ while (true) {
776
+ this.skipWhitespace();
777
+ result.push(this.parseValue(schema.element, elementIsTupleOrArray));
778
+ this.skipWhitespace();
779
+ if (!this.consumeStr(";")) {
780
+ break;
781
+ }
782
+ }
783
+ this.skipWhitespace();
784
+ if (hasOpenBracket) {
785
+ if (!this.consumeStr("]")) {
786
+ throw new ParseError(
787
+ "Expected ]",
788
+ this.pos,
789
+ this.schemaString,
790
+ this.input
791
+ );
792
+ }
793
+ }
794
+ return result;
795
+ }
796
+ parseReferenceValue(schema) {
797
+ if (schema.isOptional) {
798
+ this.skipWhitespace();
799
+ if (this.pos >= this.input.length) {
800
+ return null;
801
+ }
802
+ }
803
+ if (schema.isArray) {
804
+ let hasOpenBracket = false;
805
+ if (this.peek() === "[") {
806
+ this.consume();
807
+ hasOpenBracket = true;
808
+ }
809
+ this.skipWhitespace();
810
+ if (this.peek() === "]" && hasOpenBracket) {
811
+ this.consume();
812
+ return [];
813
+ }
814
+ const ids = [];
815
+ while (true) {
816
+ this.skipWhitespace();
817
+ let id = "";
818
+ while (this.pos < this.input.length && this.peek() !== ";" && this.peek() !== "]") {
819
+ id += this.consume();
820
+ }
821
+ ids.push(id.trim());
822
+ this.skipWhitespace();
823
+ if (!this.consumeStr(";")) {
824
+ break;
825
+ }
826
+ }
827
+ if (hasOpenBracket) {
828
+ if (!this.consumeStr("]")) {
829
+ throw new ParseError(
830
+ "Expected ]",
831
+ this.pos,
832
+ this.schemaString,
833
+ this.input
834
+ );
835
+ }
836
+ }
837
+ return ids;
838
+ } else {
839
+ let id = "";
840
+ while (this.pos < this.input.length) {
841
+ const char = this.peek();
842
+ if (char === ";" || char === "]" || char === ",") {
843
+ break;
844
+ }
845
+ id += this.consume();
846
+ }
847
+ return id.trim();
848
+ }
849
+ }
850
+ getPosition() {
851
+ return this.pos;
852
+ }
853
+ getInputLength() {
854
+ return this.input.length;
855
+ }
856
+ };
857
+ function parseValue(schema, valueString, schemaString) {
858
+ const sStr = schemaString || schemaToTypeString(schema);
859
+ const parser = new ValueParser(valueString.trim(), sStr);
860
+ const allowOmitBrackets = schema.type === "tuple" || schema.type === "array";
861
+ const value = parser.parseValue(schema, allowOmitBrackets);
862
+ if (parser.getPosition() < parser.getInputLength()) {
863
+ throw new ParseError(
864
+ "Unexpected input after value",
865
+ parser.getPosition(),
866
+ sStr,
867
+ valueString.trim()
868
+ );
869
+ }
870
+ return value;
871
+ }
872
+
873
+ // src/csv-loader/reference-resolver.ts
874
+ var fs = __toESM(require("fs"));
875
+ var path = __toESM(require("path"));
876
+ var referenceTableCache = /* @__PURE__ */ new Map();
877
+ var loadingFiles = /* @__PURE__ */ new Set();
878
+ function hasNestedReferences(schema) {
879
+ switch (schema.type) {
880
+ case "reference":
881
+ case "reverseReference":
882
+ return true;
883
+ case "tuple":
884
+ return schema.elements.some((el) => hasNestedReferences(el.schema));
885
+ case "array":
886
+ return hasNestedReferences(schema.element);
887
+ case "union":
888
+ return schema.members.some((m) => hasNestedReferences(m));
889
+ default:
890
+ return false;
891
+ }
892
+ }
893
+ function loadReferenceTable(schema, refBaseDir, defaultPrimaryKey, currentFilePath) {
894
+ const baseDir = refBaseDir || (currentFilePath ? path.dirname(currentFilePath) : process.cwd());
895
+ const fileName = `${schema.tableName}.csv`;
896
+ const refFilePath = path.isAbsolute(fileName) ? fileName : path.join(baseDir, fileName);
897
+ let refTable;
898
+ if (referenceTableCache.has(refFilePath)) {
899
+ refTable = referenceTableCache.get(refFilePath);
900
+ } else {
901
+ if (loadingFiles.has(refFilePath)) {
902
+ throw new Error(
903
+ `Circular reference detected: table "${schema.tableName}" (${refFilePath}) is already being loaded`
904
+ );
905
+ }
906
+ loadingFiles.add(refFilePath);
907
+ try {
908
+ const refContent = fs.readFileSync(refFilePath, "utf-8");
909
+ const refResult = parseCsv(refContent, {
910
+ currentFilePath: refFilePath,
911
+ emitTypes: false
912
+ });
913
+ refTable = refResult.data;
914
+ referenceTableCache.set(refFilePath, refTable);
915
+ } catch (error) {
916
+ throw new Error(
917
+ `Failed to load referenced table "${schema.tableName}" from ${refFilePath}: ${error instanceof Error ? error.message : String(error)}`
918
+ );
919
+ } finally {
920
+ loadingFiles.delete(refFilePath);
921
+ }
922
+ }
923
+ const lookup = /* @__PURE__ */ new Map();
924
+ refTable.forEach((row) => {
925
+ const pkValue = row[defaultPrimaryKey];
926
+ if (pkValue !== void 0) {
927
+ lookup.set(String(pkValue), row);
928
+ }
929
+ });
930
+ return { lookup, refTable };
931
+ }
932
+ function resolveReferenceId(id, lookup, tableName) {
933
+ const obj = lookup.get(id);
934
+ if (!obj) {
935
+ throw new Error(`Reference to "${tableName}" with id="${id}" not found`);
936
+ }
937
+ return obj;
938
+ }
939
+ function parseReferenceIds(schema, valueString) {
940
+ const trimmed = valueString.trim();
941
+ if (schema.isOptional && trimmed === "") {
942
+ return null;
943
+ }
944
+ return parseValue(schema, trimmed);
945
+ }
946
+ function parseValueWithReferenceIds(valueString, schema) {
947
+ if (!hasNestedReferences(schema)) {
948
+ return parseValue(schema, valueString);
949
+ }
950
+ switch (schema.type) {
951
+ case "reference":
952
+ return parseReferenceIds(schema, valueString);
953
+ case "reverseReference":
954
+ return null;
955
+ case "tuple": {
956
+ const parsed = parseValue(schema, valueString);
957
+ return schema.elements.map(
958
+ (el, i) => hasNestedReferences(el.schema) ? extractNestedReferenceIds(parsed[i], el.schema) : parsed[i]
959
+ );
960
+ }
961
+ case "array": {
962
+ const parsed = parseValue(schema, valueString);
963
+ return parsed.map(
964
+ (item) => hasNestedReferences(schema.element) ? extractNestedReferenceIds(item, schema.element) : item
965
+ );
966
+ }
967
+ case "union": {
968
+ for (const member of schema.members) {
969
+ if (hasNestedReferences(member)) {
970
+ try {
971
+ const parsed = parseValue(member, valueString);
972
+ return extractNestedReferenceIds(parsed, member);
973
+ } catch {
974
+ }
975
+ }
976
+ }
977
+ return parseValue(schema, valueString);
978
+ }
979
+ default:
980
+ return parseValue(schema, valueString);
981
+ }
982
+ }
983
+ function extractNestedReferenceIds(value, schema) {
984
+ switch (schema.type) {
985
+ case "reference":
986
+ if (value === null || value === void 0) return value;
987
+ if (schema.isArray) {
988
+ const ids = Array.isArray(value) ? value : [value];
989
+ return ids.map((id) => String(id));
990
+ }
991
+ return String(value);
992
+ case "reverseReference":
993
+ return null;
994
+ case "tuple": {
995
+ if (!Array.isArray(value)) return value;
996
+ return schema.elements.map(
997
+ (el, i) => hasNestedReferences(el.schema) ? extractNestedReferenceIds(value[i], el.schema) : value[i]
998
+ );
999
+ }
1000
+ case "array": {
1001
+ if (!Array.isArray(value)) return value;
1002
+ return value.map(
1003
+ (item) => hasNestedReferences(schema.element) ? extractNestedReferenceIds(item, schema.element) : item
1004
+ );
1005
+ }
1006
+ case "union": {
1007
+ for (const member of schema.members) {
1008
+ if (hasNestedReferences(member)) {
1009
+ try {
1010
+ return extractNestedReferenceIds(value, member);
1011
+ } catch {
1012
+ }
1013
+ }
1014
+ }
1015
+ return value;
1016
+ }
1017
+ default:
1018
+ return value;
1019
+ }
1020
+ }
1021
+ function collectReferenceFields(schema, name) {
1022
+ const fields = [];
1023
+ switch (schema.type) {
1024
+ case "reference":
1025
+ fields.push({
1026
+ name,
1027
+ tableName: schema.tableName,
1028
+ isArray: schema.isArray,
1029
+ schema
1030
+ });
1031
+ break;
1032
+ case "reverseReference":
1033
+ fields.push({
1034
+ name,
1035
+ tableName: schema.tableName,
1036
+ isArray: true,
1037
+ foreignKey: schema.foreignKey,
1038
+ schema
1039
+ });
1040
+ break;
1041
+ case "tuple":
1042
+ for (const el of schema.elements) {
1043
+ fields.push(...collectReferenceFields(el.schema, name));
1044
+ }
1045
+ break;
1046
+ case "array":
1047
+ fields.push(...collectReferenceFields(schema.element, name));
1048
+ break;
1049
+ case "union":
1050
+ for (const member of schema.members) {
1051
+ fields.push(...collectReferenceFields(member, name));
1052
+ }
1053
+ break;
1054
+ }
1055
+ return fields;
1056
+ }
1057
+ function parseValueWithReferences(valueString, schema, refBaseDir, defaultPrimaryKey, currentFilePath, currentRowPk) {
1058
+ if (!hasNestedReferences(schema)) {
1059
+ return parseValue(schema, valueString);
1060
+ }
1061
+ switch (schema.type) {
1062
+ case "reference":
1063
+ return parseReferenceValue(
1064
+ schema,
1065
+ valueString,
1066
+ refBaseDir,
1067
+ defaultPrimaryKey,
1068
+ currentFilePath
1069
+ );
1070
+ case "reverseReference": {
1071
+ if (currentRowPk === void 0) return [];
1072
+ return resolveReverseReference(
1073
+ schema,
1074
+ currentRowPk,
1075
+ refBaseDir,
1076
+ defaultPrimaryKey,
1077
+ currentFilePath
1078
+ );
1079
+ }
1080
+ case "tuple": {
1081
+ const parsed = parseValue(schema, valueString);
1082
+ return schema.elements.map(
1083
+ (el, i) => resolveNestedReferences(
1084
+ parsed[i],
1085
+ el.schema,
1086
+ refBaseDir,
1087
+ defaultPrimaryKey,
1088
+ currentFilePath,
1089
+ currentRowPk
1090
+ )
1091
+ );
1092
+ }
1093
+ case "array": {
1094
+ const parsed = parseValue(schema, valueString);
1095
+ return parsed.map(
1096
+ (item) => resolveNestedReferences(
1097
+ item,
1098
+ schema.element,
1099
+ refBaseDir,
1100
+ defaultPrimaryKey,
1101
+ currentFilePath,
1102
+ currentRowPk
1103
+ )
1104
+ );
1105
+ }
1106
+ case "union": {
1107
+ const errors = [];
1108
+ for (const member of schema.members) {
1109
+ if (hasNestedReferences(member)) {
1110
+ try {
1111
+ const parsed = parseValue(member, valueString);
1112
+ return resolveNestedReferences(
1113
+ parsed,
1114
+ member,
1115
+ refBaseDir,
1116
+ defaultPrimaryKey,
1117
+ currentFilePath,
1118
+ currentRowPk
1119
+ );
1120
+ } catch (e) {
1121
+ errors.push(e instanceof Error ? e : new Error(String(e)));
1122
+ }
1123
+ }
1124
+ }
1125
+ if (errors.length > 0 && errors.every(
1126
+ (e) => /not found|Circular reference|Failed to load/.test(e.message)
1127
+ )) {
1128
+ for (const member of schema.members) {
1129
+ if (!hasNestedReferences(member)) {
1130
+ try {
1131
+ return parseValue(member, valueString);
1132
+ } catch {
1133
+ }
1134
+ }
1135
+ }
1136
+ }
1137
+ return parseValue(schema, valueString);
1138
+ }
1139
+ default:
1140
+ return parseValue(schema, valueString);
1141
+ }
1142
+ }
1143
+ function resolveReverseReference(schema, pkValue, refBaseDir, defaultPrimaryKey, currentFilePath) {
1144
+ const { refTable } = loadReferenceTable(
1145
+ schema,
1146
+ refBaseDir,
1147
+ defaultPrimaryKey,
1148
+ currentFilePath
1149
+ );
1150
+ const pkStr = String(pkValue);
1151
+ return refTable.filter((row) => {
1152
+ const fkValue = row[schema.foreignKey];
1153
+ const fkStr = fkValue !== null && fkValue !== void 0 && typeof fkValue === "object" ? String(fkValue[defaultPrimaryKey]) : String(fkValue);
1154
+ return fkStr === pkStr;
1155
+ });
1156
+ }
1157
+ function resolveNestedReferences(value, schema, refBaseDir, defaultPrimaryKey, currentFilePath, currentRowPk) {
1158
+ switch (schema.type) {
1159
+ case "reference": {
1160
+ if (value === null || value === void 0) return value;
1161
+ const { lookup } = loadReferenceTable(
1162
+ schema,
1163
+ refBaseDir,
1164
+ defaultPrimaryKey,
1165
+ currentFilePath
1166
+ );
1167
+ if (schema.isArray) {
1168
+ const ids = Array.isArray(value) ? value : [value];
1169
+ return ids.map(
1170
+ (id) => resolveReferenceId(String(id), lookup, schema.tableName)
1171
+ );
1172
+ }
1173
+ return resolveReferenceId(String(value), lookup, schema.tableName);
1174
+ }
1175
+ case "reverseReference": {
1176
+ if (currentRowPk === void 0) return [];
1177
+ const results = resolveReverseReference(
1178
+ schema,
1179
+ currentRowPk,
1180
+ refBaseDir,
1181
+ defaultPrimaryKey,
1182
+ currentFilePath
1183
+ );
1184
+ return results;
1185
+ }
1186
+ case "tuple": {
1187
+ if (!Array.isArray(value)) return value;
1188
+ return schema.elements.map(
1189
+ (el, i) => resolveNestedReferences(
1190
+ value[i],
1191
+ el.schema,
1192
+ refBaseDir,
1193
+ defaultPrimaryKey,
1194
+ currentFilePath,
1195
+ currentRowPk
1196
+ )
1197
+ );
1198
+ }
1199
+ case "array": {
1200
+ if (!Array.isArray(value)) return value;
1201
+ return value.map(
1202
+ (item) => resolveNestedReferences(
1203
+ item,
1204
+ schema.element,
1205
+ refBaseDir,
1206
+ defaultPrimaryKey,
1207
+ currentFilePath,
1208
+ currentRowPk
1209
+ )
1210
+ );
1211
+ }
1212
+ case "union": {
1213
+ const errors = [];
1214
+ for (const member of schema.members) {
1215
+ if (hasNestedReferences(member)) {
1216
+ try {
1217
+ return resolveNestedReferences(
1218
+ value,
1219
+ member,
1220
+ refBaseDir,
1221
+ defaultPrimaryKey,
1222
+ currentFilePath,
1223
+ currentRowPk
1224
+ );
1225
+ } catch (e) {
1226
+ errors.push(e instanceof Error ? e : new Error(String(e)));
1227
+ }
1228
+ }
1229
+ }
1230
+ if (errors.length > 0) {
1231
+ throw errors[0];
1232
+ }
1233
+ return value;
1234
+ }
1235
+ default:
1236
+ return value;
1237
+ }
1238
+ }
1239
+ function parseReferenceValue(schema, valueString, refBaseDir, defaultPrimaryKey, currentFilePath) {
1240
+ const trimmed = valueString.trim();
1241
+ if (schema.isOptional && trimmed === "") {
1242
+ return null;
1243
+ }
1244
+ const { lookup } = loadReferenceTable(
1245
+ schema,
1246
+ refBaseDir,
1247
+ defaultPrimaryKey,
1248
+ currentFilePath
1249
+ );
1250
+ const ids = parseValue(schema, trimmed);
1251
+ if (ids === null) return null;
1252
+ if (schema.isArray && Array.isArray(ids)) {
1253
+ return ids.map((id) => resolveReferenceId(id, lookup, schema.tableName));
1254
+ }
1255
+ return resolveReferenceId(ids, lookup, schema.tableName);
1256
+ }
1257
+
1258
+ // src/csv-loader/type-gen.ts
1259
+ var path2 = __toESM(require("path"));
1260
+ function resolveReferencesInSchemaString(schemaString, resourceNames) {
1261
+ return schemaString.replace(/@([a-zA-Z0-9\-_]+)(\[\])?/g, (_match, tableName, arraySuffix) => {
1262
+ const typeName = resourceNames.get(tableName) || tableName.charAt(0).toUpperCase() + tableName.slice(1);
1263
+ return arraySuffix ? `${typeName}[]` : typeName;
1264
+ }).replace(/; ?/g, ", ");
1265
+ }
1266
+ function generateTypeDefinition(resourceName, propertyConfigs, references, currentFilePath, typeDeclarations = []) {
1267
+ const typeName = resourceName ? `${resourceName}Table` : "Table";
1268
+ const currentTableName = currentFilePath ? path2.basename(currentFilePath, path2.extname(currentFilePath)) : void 0;
1269
+ const singularType = resourceName ? resourceName.charAt(0).toUpperCase() + resourceName.slice(1) : `${typeName}[number]`;
1270
+ const imports = [];
1271
+ const resourceNames = /* @__PURE__ */ new Map();
1272
+ references.forEach((tableName) => {
1273
+ if (tableName === currentTableName) {
1274
+ resourceNames.set(tableName, singularType);
1275
+ return;
1276
+ }
1277
+ const typeBase = tableName.charAt(0).toUpperCase() + tableName.slice(1);
1278
+ resourceNames.set(tableName, typeBase);
1279
+ let importPath;
1280
+ if (currentFilePath) {
1281
+ importPath = `./${tableName}.csv`;
1282
+ } else {
1283
+ importPath = `../${tableName}.csv`;
1284
+ }
1285
+ imports.push(`import type { ${typeBase} } from '${importPath}';`);
1286
+ });
1287
+ const importSection = imports.length > 0 ? imports.join("\n") + "\n\n" : "";
1288
+ const typeDeclarationSection = typeDeclarations.length > 0 ? typeDeclarations.map(
1289
+ (decl) => `export type ${decl.name} = ${decl.schemaString ? resolveReferencesInSchemaString(decl.schemaString, resourceNames) : schemaToTypeString(decl.schema, resourceNames)};`
1290
+ ).join("\n") + "\n\n" : "";
1291
+ const properties = propertyConfigs.map((config) => {
1292
+ const typeStr = config.declaredTypeName ? config.declaredTypeName : config.schemaString ? resolveReferencesInSchemaString(config.schemaString, resourceNames) : schemaToTypeString(config.schema, resourceNames);
1293
+ return ` readonly ${config.name}: ${typeStr};`;
1294
+ }).join("\n");
1295
+ let exportAlias = "";
1296
+ if (resourceName) {
1297
+ const singularType2 = resourceName.charAt(0).toUpperCase() + resourceName.slice(1);
1298
+ exportAlias = `
1299
+ export type ${singularType2} = ${typeName}[number];`;
1300
+ }
1301
+ return `${importSection}${typeDeclarationSection}type ${typeName} = readonly {
1302
+ ${properties}
1303
+ }[];
1304
+ ${exportAlias}
1305
+
1306
+ declare function getData(): ${typeName};
1307
+ export default getData;
1308
+ `;
1309
+ }
1310
+
1311
+ // src/csv-loader/type-declarations.ts
1312
+ function parseTypeDeclaration(line, commentChar = "#") {
1313
+ const trimmed = line.trim();
1314
+ if (!trimmed.startsWith(commentChar)) return null;
1315
+ const content = trimmed.slice(commentChar.length).trim();
1316
+ const match = content.match(/^type\s+([A-Z][a-zA-Z0-9]*)\s*=\s*(.+)$/);
1317
+ if (!match) return null;
1318
+ const [, typeName, schemaString] = match;
1319
+ return { typeName, schemaString };
1320
+ }
1321
+ function expandTypeName(schemaString, declaredTypes) {
1322
+ const trimmed = schemaString.trim();
1323
+ if (declaredTypes.has(trimmed)) {
1324
+ return declaredTypes.get(trimmed);
1325
+ }
1326
+ return null;
1327
+ }
1328
+ function expandSchemaString(schemaString, declaredTypes) {
1329
+ let result = schemaString;
1330
+ let prev = "";
1331
+ while (prev !== result) {
1332
+ prev = result;
1333
+ result = expandSchemaInString(result, declaredTypes);
1334
+ }
1335
+ return result;
1336
+ }
1337
+ function expandSchemaInString(schemaString, declaredTypes) {
1338
+ const expanded = expandTypeName(schemaString.trim(), declaredTypes);
1339
+ if (expanded !== null) {
1340
+ return expanded;
1341
+ }
1342
+ const trimmed = schemaString.trim();
1343
+ if (trimmed.endsWith("[]")) {
1344
+ const inner = trimmed.slice(0, -2);
1345
+ const expandedInner = expandSchemaInString(inner, declaredTypes);
1346
+ return `${expandedInner}[]`;
1347
+ }
1348
+ if (schemaString.includes("|")) {
1349
+ const parts = splitByToken(schemaString, "|");
1350
+ if (parts.length > 1) {
1351
+ const expandedParts = parts.map(
1352
+ (part) => expandSchemaInString(part.trim(), declaredTypes)
1353
+ );
1354
+ return expandedParts.join(" | ");
1355
+ }
1356
+ }
1357
+ if (schemaString.startsWith("[") && schemaString.endsWith("]")) {
1358
+ const inner = schemaString.slice(1, -1);
1359
+ if (inner.includes(";")) {
1360
+ const elements = splitByToken(inner, ";");
1361
+ const expandedElements = elements.map(
1362
+ (el) => expandSchemaInString(el.trim(), declaredTypes)
1363
+ );
1364
+ return `[${expandedElements.join("; ")}]`;
1365
+ }
1366
+ return `[${expandSchemaInString(inner, declaredTypes)}]`;
1367
+ }
1368
+ const typeNameMatch = schemaString.trim().match(/^[A-Z][a-zA-Z0-9]*$/);
1369
+ if (typeNameMatch) {
1370
+ const expanded2 = expandTypeName(schemaString.trim(), declaredTypes);
1371
+ if (expanded2 !== null) {
1372
+ return expanded2;
1373
+ }
1374
+ }
1375
+ return schemaString;
1376
+ }
1377
+ function splitByToken(str, token) {
1378
+ const result = [];
1379
+ let current = "";
1380
+ let inQuote = null;
1381
+ for (let i = 0; i < str.length; i++) {
1382
+ const char = str[i];
1383
+ if (inQuote) {
1384
+ if (char === inQuote && str[i - 1] !== "\\") {
1385
+ inQuote = null;
1386
+ }
1387
+ current += char;
1388
+ } else if (char === '"' || char === "'") {
1389
+ inQuote = char;
1390
+ current += char;
1391
+ } else if (char === token && inQuote === null) {
1392
+ result.push(current);
1393
+ current = "";
1394
+ } else {
1395
+ current += char;
1396
+ }
1397
+ }
1398
+ if (current.length > 0 || str.endsWith(token)) {
1399
+ result.push(current);
1400
+ }
1401
+ return result;
1402
+ }
1403
+ function resolveTypeReferences(schema, declaredTypes) {
1404
+ switch (schema.type) {
1405
+ case "union":
1406
+ return {
1407
+ type: "union",
1408
+ members: schema.members.map(
1409
+ (m) => resolveTypeReferences(m, declaredTypes)
1410
+ )
1411
+ };
1412
+ case "tuple":
1413
+ return {
1414
+ type: "tuple",
1415
+ elements: schema.elements.map((el) => ({
1416
+ name: el.name,
1417
+ schema: resolveTypeReferences(el.schema, declaredTypes)
1418
+ }))
1419
+ };
1420
+ case "array":
1421
+ return {
1422
+ type: "array",
1423
+ element: resolveTypeReferences(schema.element, declaredTypes)
1424
+ };
1425
+ case "reference":
1426
+ return schema;
1427
+ default:
1428
+ return schema;
1429
+ }
1430
+ }
1431
+ function parseReverseReferenceDeclaration(line, commentChar = "#") {
1432
+ const trimmed = line.trim();
1433
+ if (!trimmed.startsWith(commentChar)) return null;
1434
+ const content = trimmed.slice(commentChar.length).trim();
1435
+ const match = content.match(/^inject\s+(\w+)\s*=\s*~(\w+)\((\w+)\)(\?)?$/);
1436
+ if (!match) return null;
1437
+ const [, fieldName, tableName, foreignKey, optionalMark] = match;
1438
+ const isOptional = optionalMark === "?";
1439
+ const schema = {
1440
+ type: "reverseReference",
1441
+ tableName,
1442
+ foreignKey,
1443
+ isOptional
1444
+ };
1445
+ return {
1446
+ fieldName,
1447
+ tableName,
1448
+ foreignKey,
1449
+ isOptional,
1450
+ schema
1451
+ };
1452
+ }
1453
+
1454
+ // src/csv-loader/loader.ts
1455
+ function parseCsv(content, options = {}) {
1456
+ const delimiter = options.delimiter ?? ",";
1457
+ const quote = options.quote ?? '"';
1458
+ const escape = options.escape ?? "\\";
1459
+ const bom = options.bom ?? true;
1460
+ const comment = options.comment === false ? void 0 : options.comment ?? "#";
1461
+ const trim = options.trim ?? true;
1462
+ const emitTypes = options.emitTypes ?? true;
1463
+ const refBaseDir = options.refBaseDir;
1464
+ const defaultPrimaryKey = options.defaultPrimaryKey ?? "id";
1465
+ const reverseReferences = [];
1466
+ const typeDeclarationsRaw = [];
1467
+ let filteredContent = content;
1468
+ if (comment) {
1469
+ const lines = content.split(/\r?\n/);
1470
+ const nonCommentLines = [];
1471
+ for (const line of lines) {
1472
+ const trimmed = line.trim();
1473
+ if (trimmed.startsWith(comment)) {
1474
+ const typeDecl = parseTypeDeclaration(trimmed, comment);
1475
+ if (typeDecl) {
1476
+ typeDeclarationsRaw.push(typeDecl);
1477
+ continue;
1478
+ }
1479
+ const decl = parseReverseReferenceDeclaration(trimmed, comment);
1480
+ if (decl) {
1481
+ reverseReferences.push(decl);
1482
+ continue;
1483
+ }
1484
+ continue;
1485
+ }
1486
+ nonCommentLines.push(line);
1487
+ }
1488
+ filteredContent = nonCommentLines.join("\n");
1489
+ }
1490
+ const records = (0, import_sync.parse)(filteredContent, {
1491
+ delimiter,
1492
+ quote,
1493
+ escape,
1494
+ bom,
1495
+ comment: void 0,
1496
+ trim,
1497
+ skip_empty_lines: true,
1498
+ relax_column_count: true
1499
+ });
1500
+ const filteredRecords = records;
1501
+ if (filteredRecords.length < 2) {
1502
+ throw new Error("CSV must have at least 2 rows: headers and schemas");
1503
+ }
1504
+ const headers = filteredRecords[0];
1505
+ const schemas = filteredRecords[1];
1506
+ if (headers.length !== schemas.length) {
1507
+ throw new Error(
1508
+ `Header count (${headers.length}) does not match schema count (${schemas.length})`
1509
+ );
1510
+ }
1511
+ const dataRows = filteredRecords.slice(2);
1512
+ for (let col = 0; col < schemas.length; col++) {
1513
+ const cell = (schemas[col] ?? "").trim();
1514
+ if (comment && cell.startsWith(comment)) {
1515
+ const typeDecl = parseTypeDeclaration(cell, comment);
1516
+ if (typeDecl) {
1517
+ typeDeclarationsRaw.push(typeDecl);
1518
+ continue;
1519
+ }
1520
+ const decl = parseReverseReferenceDeclaration(cell, comment);
1521
+ if (decl) {
1522
+ reverseReferences.push(decl);
1523
+ }
1524
+ }
1525
+ }
1526
+ const declaredTypeNames = /* @__PURE__ */ new Set();
1527
+ for (const decl of typeDeclarationsRaw) {
1528
+ declaredTypeNames.add(decl.typeName);
1529
+ }
1530
+ const declaredSchemaStrings = /* @__PURE__ */ new Map();
1531
+ for (const decl of typeDeclarationsRaw) {
1532
+ declaredSchemaStrings.set(decl.typeName, decl.schemaString);
1533
+ }
1534
+ const typeDeclarationsParsed = [];
1535
+ for (const decl of typeDeclarationsRaw) {
1536
+ const expandedSchema = expandSchemaString(
1537
+ decl.schemaString,
1538
+ declaredSchemaStrings
1539
+ );
1540
+ const schema = parseSchema(expandedSchema.trim());
1541
+ typeDeclarationsParsed.push({
1542
+ name: decl.typeName,
1543
+ schema,
1544
+ schemaString: decl.schemaString
1545
+ });
1546
+ }
1547
+ const declaredTypes = /* @__PURE__ */ new Map();
1548
+ for (const decl of typeDeclarationsParsed) {
1549
+ declaredTypes.set(decl.name, decl.schema);
1550
+ }
1551
+ const typeDeclarations = [];
1552
+ for (const decl of typeDeclarationsParsed) {
1553
+ const resolvedSchema = resolveTypeReferences(decl.schema, declaredTypes);
1554
+ typeDeclarations.push({
1555
+ name: decl.name,
1556
+ schema: resolvedSchema,
1557
+ schemaString: decl.schemaString
1558
+ });
1559
+ }
1560
+ for (const decl of typeDeclarations) {
1561
+ declaredTypes.set(decl.name, decl.schema);
1562
+ }
1563
+ const resolveReferences = options.resolveReferences ?? true;
1564
+ const propertyConfigs = headers.map(
1565
+ (header, index) => {
1566
+ const schemaString = schemas[index];
1567
+ let schema;
1568
+ let declaredTypeName;
1569
+ let columnSchemaString;
1570
+ if (declaredTypes.has(schemaString)) {
1571
+ schema = declaredTypes.get(schemaString);
1572
+ declaredTypeName = schemaString;
1573
+ } else {
1574
+ const expandedSchema = expandSchemaString(
1575
+ schemaString,
1576
+ declaredSchemaStrings
1577
+ );
1578
+ schema = parseSchema(expandedSchema.trim());
1579
+ if (expandedSchema !== schemaString) {
1580
+ columnSchemaString = schemaString;
1581
+ }
1582
+ }
1583
+ const config = {
1584
+ name: header,
1585
+ schema,
1586
+ validator: createValidator(schema),
1587
+ parser: (valueString) => parseValue(schema, valueString),
1588
+ declaredTypeName,
1589
+ schemaString: columnSchemaString
1590
+ };
1591
+ if (schema.type === "reference") {
1592
+ config.isReference = true;
1593
+ config.referenceTableName = schema.tableName;
1594
+ config.referenceIsArray = schema.isArray;
1595
+ if (resolveReferences) {
1596
+ config.parser = (valueString) => {
1597
+ return parseReferenceValue(
1598
+ schema,
1599
+ valueString,
1600
+ refBaseDir,
1601
+ defaultPrimaryKey,
1602
+ options.currentFilePath
1603
+ );
1604
+ };
1605
+ } else {
1606
+ config.parser = (valueString) => {
1607
+ return parseReferenceIds(schema, valueString);
1608
+ };
1609
+ }
1610
+ } else if (hasNestedReferences(schema)) {
1611
+ config.isReference = true;
1612
+ if (resolveReferences) {
1613
+ config.parser = (valueString) => {
1614
+ return parseValueWithReferences(
1615
+ valueString,
1616
+ schema,
1617
+ refBaseDir,
1618
+ defaultPrimaryKey,
1619
+ options.currentFilePath
1620
+ );
1621
+ };
1622
+ } else {
1623
+ config.parser = (valueString) => {
1624
+ return parseValueWithReferenceIds(valueString, schema);
1625
+ };
1626
+ }
1627
+ }
1628
+ return config;
1629
+ }
1630
+ );
1631
+ for (const decl of reverseReferences) {
1632
+ const config = {
1633
+ name: decl.fieldName,
1634
+ schema: decl.schema,
1635
+ validator: createValidator(decl.schema),
1636
+ parser: (_valueString) => {
1637
+ return null;
1638
+ },
1639
+ isReference: true,
1640
+ isReverseReference: true,
1641
+ referenceTableName: decl.tableName,
1642
+ referenceIsArray: true,
1643
+ reverseReferenceForeignKey: decl.foreignKey
1644
+ };
1645
+ propertyConfigs.push(config);
1646
+ }
1647
+ const references = /* @__PURE__ */ new Set();
1648
+ function collectReferences(schema) {
1649
+ if (schema.type === "reference") {
1650
+ references.add(schema.tableName);
1651
+ } else if (schema.type === "reverseReference") {
1652
+ references.add(schema.tableName);
1653
+ } else if (schema.type === "tuple") {
1654
+ schema.elements.forEach((el) => collectReferences(el.schema));
1655
+ } else if (schema.type === "array") {
1656
+ collectReferences(schema.element);
1657
+ } else if (schema.type === "union") {
1658
+ schema.members.forEach((m) => collectReferences(m));
1659
+ }
1660
+ }
1661
+ propertyConfigs.forEach((config) => {
1662
+ if (config.isReference && config.referenceTableName) {
1663
+ references.add(config.referenceTableName);
1664
+ }
1665
+ collectReferences(config.schema);
1666
+ });
1667
+ const objects = dataRows.map((row, rowIndex) => {
1668
+ const obj = {};
1669
+ propertyConfigs.forEach((config, colIndex) => {
1670
+ if (config.isReverseReference) {
1671
+ return;
1672
+ }
1673
+ const rawValue = row[colIndex] ?? "";
1674
+ try {
1675
+ const parsed = config.parser(rawValue);
1676
+ if (!config.isReference && !config.validator(parsed)) {
1677
+ throw new Error(
1678
+ `Validation failed for property "${config.name}" at row ${rowIndex + 3}: ${rawValue}`
1679
+ );
1680
+ }
1681
+ obj[config.name] = parsed;
1682
+ } catch (error) {
1683
+ if (error instanceof Error) {
1684
+ throw new Error(
1685
+ `Failed to parse property "${config.name}" at row ${rowIndex + 3}, column ${colIndex + 1}: ${error.message}`
1686
+ );
1687
+ }
1688
+ throw error;
1689
+ }
1690
+ });
1691
+ return obj;
1692
+ });
1693
+ if (resolveReferences) {
1694
+ for (const decl of reverseReferences) {
1695
+ for (const obj of objects) {
1696
+ const pkValue = obj[defaultPrimaryKey];
1697
+ if (pkValue !== void 0) {
1698
+ const resolved = resolveReverseReference(
1699
+ decl.schema,
1700
+ pkValue,
1701
+ refBaseDir,
1702
+ defaultPrimaryKey,
1703
+ options.currentFilePath
1704
+ );
1705
+ obj[decl.fieldName] = decl.isOptional && resolved.length === 0 ? null : resolved;
1706
+ } else {
1707
+ obj[decl.fieldName] = decl.isOptional ? null : [];
1708
+ }
1709
+ }
1710
+ }
1711
+ }
1712
+ const referenceFields = [];
1713
+ if (!resolveReferences) {
1714
+ for (const config of propertyConfigs) {
1715
+ if (hasNestedReferences(config.schema)) {
1716
+ referenceFields.push(
1717
+ ...collectReferenceFields(config.schema, config.name)
1718
+ );
1719
+ }
1720
+ }
1721
+ }
1722
+ const result = {
1723
+ data: objects,
1724
+ propertyConfigs,
1725
+ references,
1726
+ referenceFields,
1727
+ reverseReferences,
1728
+ typeDeclarations
1729
+ };
1730
+ if (emitTypes) {
1731
+ result.typeDefinition = generateTypeDefinition(
1732
+ options.resourceName || "",
1733
+ propertyConfigs,
1734
+ references,
1735
+ options.currentFilePath,
1736
+ typeDeclarations
1737
+ );
1738
+ }
1739
+ return result;
1740
+ }
1741
+
1742
+ // src/csv-loader/module-gen.ts
1743
+ function generateSchemaResolutionCode(schema, valueExpr, lookupVar, pkField, reverseLookupVar) {
1744
+ switch (schema.type) {
1745
+ case "reference": {
1746
+ const lookup = lookupVar(schema.tableName);
1747
+ if (schema.isOptional) {
1748
+ if (schema.isArray) {
1749
+ return `(${valueExpr} === null || ${valueExpr} === undefined ? ${valueExpr} : (Array.isArray(${valueExpr}) ? ${valueExpr}.map(id => ${lookup}.get(String(id))) : ${lookup}.get(String(${valueExpr}))))`;
1750
+ }
1751
+ return `(${valueExpr} === null || ${valueExpr} === undefined ? ${valueExpr} : ${lookup}.get(String(${valueExpr})))`;
1752
+ }
1753
+ if (schema.isArray) {
1754
+ return `(Array.isArray(${valueExpr}) ? ${valueExpr}.map(id => ${lookup}.get(String(id))) : ${valueExpr})`;
1755
+ }
1756
+ return `${lookup}.get(String(${valueExpr}))`;
1757
+ }
1758
+ case "reverseReference": {
1759
+ if (!reverseLookupVar) return valueExpr;
1760
+ const reverseLookup = reverseLookupVar(
1761
+ schema.tableName,
1762
+ schema.foreignKey
1763
+ );
1764
+ if (schema.isOptional) {
1765
+ return `(${reverseLookup}.get(String(row.${pkField})) || null)`;
1766
+ }
1767
+ return `(${reverseLookup}.get(String(row.${pkField})) || [])`;
1768
+ }
1769
+ case "tuple": {
1770
+ const elementResolvers = schema.elements.map((el, i) => {
1771
+ if (hasNestedReferences(el.schema)) {
1772
+ return generateSchemaResolutionCode(
1773
+ el.schema,
1774
+ `${valueExpr}[${i}]`,
1775
+ lookupVar,
1776
+ pkField,
1777
+ reverseLookupVar
1778
+ );
1779
+ }
1780
+ return `${valueExpr}[${i}]`;
1781
+ });
1782
+ return `[${elementResolvers.join(", ")}]`;
1783
+ }
1784
+ case "array": {
1785
+ if (hasNestedReferences(schema.element)) {
1786
+ const itemResolve = generateSchemaResolutionCode(
1787
+ schema.element,
1788
+ "item",
1789
+ lookupVar,
1790
+ pkField,
1791
+ reverseLookupVar
1792
+ );
1793
+ return `(${valueExpr}).map(item => ${itemResolve})`;
1794
+ }
1795
+ return valueExpr;
1796
+ }
1797
+ case "union": {
1798
+ const refMembers = schema.members.filter((m) => hasNestedReferences(m));
1799
+ const nonRefMembers = schema.members.filter(
1800
+ (m) => !hasNestedReferences(m)
1801
+ );
1802
+ const resolveParts = [];
1803
+ for (const member of refMembers) {
1804
+ const resolveCode = generateSchemaResolutionCode(
1805
+ member,
1806
+ valueExpr,
1807
+ lookupVar,
1808
+ pkField,
1809
+ reverseLookupVar
1810
+ );
1811
+ resolveParts.push(resolveCode);
1812
+ }
1813
+ if (nonRefMembers.length > 0) {
1814
+ resolveParts.push(valueExpr);
1815
+ }
1816
+ if (resolveParts.length === 0) return valueExpr;
1817
+ if (resolveParts.length === 1) return resolveParts[0];
1818
+ return `(${resolveParts.join(" ?? ")})`;
1819
+ }
1820
+ default:
1821
+ return valueExpr;
1822
+ }
1823
+ }
1824
+ function csvToModule(content, options = {}) {
1825
+ const result = parseCsv(content, { ...options, resolveReferences: false });
1826
+ const hasRefs = result.referenceFields.length > 0 || result.reverseReferences.length > 0;
1827
+ const defaultPrimaryKey = options.defaultPrimaryKey ?? "id";
1828
+ const imports = [];
1829
+ const lookupInits = [];
1830
+ const lookupVarMap = /* @__PURE__ */ new Map();
1831
+ const reverseLookupInits = [];
1832
+ const reverseLookupVarMap = /* @__PURE__ */ new Map();
1833
+ const currentTableName = options.currentFilePath ? path3.basename(
1834
+ options.currentFilePath,
1835
+ path3.extname(options.currentFilePath)
1836
+ ) : void 0;
1837
+ const uniqueTables = new Set(result.referenceFields.map((f) => f.tableName));
1838
+ for (const decl of result.reverseReferences) {
1839
+ uniqueTables.add(decl.tableName);
1840
+ }
1841
+ uniqueTables.forEach((tableName) => {
1842
+ const lookupVar2 = `_${tableName}Lookup`;
1843
+ lookupVarMap.set(tableName, lookupVar2);
1844
+ if (tableName === currentTableName) {
1845
+ lookupInits.push(
1846
+ `const ${lookupVar2} = new Map(_raw.map(p => [String(p.${defaultPrimaryKey}), p]));`
1847
+ );
1848
+ } else {
1849
+ const varName = `_${tableName}`;
1850
+ imports.push(`import ${varName} from './${tableName}.csv';`);
1851
+ lookupInits.push(
1852
+ `const ${lookupVar2} = new Map(${varName}().map(p => [String(p.${defaultPrimaryKey}), p]));`
1853
+ );
1854
+ }
1855
+ });
1856
+ for (const decl of result.reverseReferences) {
1857
+ const key = `${decl.tableName}:${decl.foreignKey}`;
1858
+ if (reverseLookupVarMap.has(key)) continue;
1859
+ const revLookupVar = `_${decl.tableName}By_${decl.foreignKey}`;
1860
+ reverseLookupVarMap.set(key, revLookupVar);
1861
+ if (decl.tableName === currentTableName) {
1862
+ reverseLookupInits.push(
1863
+ `const ${revLookupVar} = new Map();`,
1864
+ `for (const r of _raw) {`,
1865
+ ` const kv = r.${decl.foreignKey};`,
1866
+ ` const k = String(typeof kv === "object" && "${defaultPrimaryKey}" in kv ? kv.${defaultPrimaryKey} : kv);`,
1867
+ ` if (!${revLookupVar}.has(k)) ${revLookupVar}.set(k, []);`,
1868
+ ` ${revLookupVar}.get(k).push(r);`,
1869
+ `}`
1870
+ );
1871
+ } else {
1872
+ const varName = `_${decl.tableName}`;
1873
+ reverseLookupInits.push(
1874
+ `const ${revLookupVar} = new Map();`,
1875
+ `for (const r of ${varName}()) {`,
1876
+ ` const kv = r.${decl.foreignKey};`,
1877
+ ` const k = String(typeof kv === "object" && "${defaultPrimaryKey}" in kv ? kv.${defaultPrimaryKey} : kv);`,
1878
+ ` if (!${revLookupVar}.has(k)) ${revLookupVar}.set(k, []);`,
1879
+ ` ${revLookupVar}.get(k).push(r);`,
1880
+ `}`
1881
+ );
1882
+ }
1883
+ }
1884
+ const lookupVar = (tableName) => lookupVarMap.get(tableName);
1885
+ const reverseLookupVar = (tableName, foreignKey) => reverseLookupVarMap.get(`${tableName}:${foreignKey}`);
1886
+ const rowResolvers = [];
1887
+ for (const config of result.propertyConfigs) {
1888
+ if (config.isReverseReference) {
1889
+ const decl = result.reverseReferences.find(
1890
+ (d) => d.fieldName === config.name
1891
+ );
1892
+ if (decl) {
1893
+ const revLookup = reverseLookupVar(decl.tableName, decl.foreignKey);
1894
+ if (decl.isOptional) {
1895
+ rowResolvers.push({
1896
+ name: config.name,
1897
+ code: `(${revLookup}.get(String(row.${defaultPrimaryKey})) || null)`
1898
+ });
1899
+ } else {
1900
+ rowResolvers.push({
1901
+ name: config.name,
1902
+ code: `(${revLookup}.get(String(row.${defaultPrimaryKey})) || [])`
1903
+ });
1904
+ }
1905
+ }
1906
+ } else if (hasNestedReferences(config.schema)) {
1907
+ const resolveCode = generateSchemaResolutionCode(
1908
+ config.schema,
1909
+ `row.${config.name}`,
1910
+ lookupVar,
1911
+ defaultPrimaryKey,
1912
+ reverseLookupVar
1913
+ );
1914
+ rowResolvers.push({ name: config.name, code: resolveCode });
1915
+ }
1916
+ }
1917
+ const rawJson = JSON.stringify(result.data, null, 2);
1918
+ const js = [
1919
+ ...imports,
1920
+ "",
1921
+ `const _raw = ${rawJson};`,
1922
+ "",
1923
+ "let _resolved = null;",
1924
+ "",
1925
+ "export default function getData() {",
1926
+ " if (_resolved) return _resolved;",
1927
+ " _resolved = _raw;",
1928
+ ...lookupInits.map((l) => ` ${l}`),
1929
+ ...reverseLookupInits.map((l) => ` ${l}`),
1930
+ ...rowResolvers.length > 0 ? [
1931
+ " _resolved = _raw.map(row => {",
1932
+ ...rowResolvers.map((r) => ` row.${r.name} = ${r.code};`),
1933
+ " return row;",
1934
+ " });"
1935
+ ] : [],
1936
+ " return _resolved;",
1937
+ "}"
1938
+ ].join("\n");
1939
+ return {
1940
+ js,
1941
+ dts: result.typeDefinition
1942
+ };
1943
+ }
1944
+
1945
+ // src/csv-loader/esbuild.ts
1946
+ function createFilter(pattern) {
1947
+ if (pattern instanceof RegExp) return pattern;
1948
+ if (Array.isArray(pattern)) {
1949
+ const first = pattern[0];
1950
+ return first instanceof RegExp ? first : new RegExp(first);
1951
+ }
1952
+ return new RegExp(pattern);
1953
+ }
1954
+ function matchesPattern(id, pattern) {
1955
+ if (!pattern) return true;
1956
+ const patterns = Array.isArray(pattern) ? pattern : [pattern];
1957
+ return patterns.some((p) => {
1958
+ if (p instanceof RegExp) return p.test(id);
1959
+ return id.includes(p);
1960
+ });
1961
+ }
1962
+ function csvLoader(options = {}) {
1963
+ const {
1964
+ include = /\.csv$/,
1965
+ exclude,
1966
+ emitTypes = true,
1967
+ typesOutputDir = "",
1968
+ writeToDisk = false,
1969
+ ...parseOptions
1970
+ } = options;
1971
+ const includeFilter = createFilter(include);
1972
+ return {
1973
+ name: "typed-csv",
1974
+ setup(build) {
1975
+ build.onLoad({ filter: includeFilter }, async (args) => {
1976
+ if (exclude && !matchesPattern(args.path, exclude)) {
1977
+ return null;
1978
+ }
1979
+ let content;
1980
+ try {
1981
+ content = await fs2.promises.readFile(args.path, "utf-8");
1982
+ } catch (error) {
1983
+ return {
1984
+ errors: [{ text: `Failed to read file: ${args.path}` }]
1985
+ };
1986
+ }
1987
+ const fileName = path4.basename(args.path, ".csv").split(".")[0];
1988
+ const resourceName = fileName.replace(
1989
+ /[-_\s]+(.)?/g,
1990
+ (_, char) => char ? char.toUpperCase() : ""
1991
+ ).replace(/^(.)/, (_, char) => char.toUpperCase());
1992
+ const result = csvToModule(content, {
1993
+ ...parseOptions,
1994
+ emitTypes,
1995
+ resourceName,
1996
+ currentFilePath: args.path,
1997
+ refBaseDir: options.refBaseDir,
1998
+ defaultPrimaryKey: options.defaultPrimaryKey
1999
+ });
2000
+ if (emitTypes && result.dts) {
2001
+ const dtsPath = typesOutputDir ? path4.join(typesOutputDir, path4.basename(args.path) + ".d.ts") : args.path + ".d.ts";
2002
+ if (writeToDisk) {
2003
+ const absolutePath = path4.isAbsolute(dtsPath) ? dtsPath : path4.join(process.cwd(), dtsPath);
2004
+ fs2.mkdirSync(path4.dirname(absolutePath), { recursive: true });
2005
+ fs2.writeFileSync(absolutePath, result.dts);
2006
+ }
2007
+ }
2008
+ return {
2009
+ contents: result.js,
2010
+ loader: "js"
2011
+ };
2012
+ });
2013
+ }
2014
+ };
2015
+ }
2016
+ var esbuild_default = csvLoader;
2017
+ // Annotate the CommonJS export names for ESM import in node:
2018
+ 0 && (module.exports = {
2019
+ csvLoader
2020
+ });