config2ts 2.5.4 → 2.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,6 +27,7 @@ config2ts -d config -o dist -n csv.ts -a public
27
27
  | RefEnum | namespace.type |
28
28
  | RefEnum[] | namespace.type[] |
29
29
  | Object | type (Record) |
30
+ | Object[] | type[] (Record[]) |
30
31
 
31
32
  * `Number` support Infinity and NaN
32
33
  * `Enum` support empty string type
@@ -34,6 +35,8 @@ config2ts -d config -o dist -n csv.ts -a public
34
35
  * `EnumIndex` will generate index type, and will use `Enum` type to generate interface
35
36
  * `Ref` / `RefEnum` reference another csv's Record/type by id
36
37
  * `Object` parse `key:value,key:value` format, auto-infer value types (number/boolean/string), generates a dedicated `type` that merges all keys
38
+ * `Object[]` parse `key:value,key:value;key:value,key:value` format (`;` separates objects, `,` separates key-value pairs), empty value generates `[]`, generates a dedicated element `type` with the field typed as `type[]`
39
+ * unrecognized field types fall back to `string` and print a warning (check for typos)
37
40
 
38
41
  ## assets2ts
39
42
 
package/lib/config2ts.js CHANGED
@@ -50,6 +50,7 @@ const EnumIndexStr = "EnumIndex";
50
50
  const EnumArrayString = "Enum[]";
51
51
  const IndexStr = "Index";
52
52
  const ObjectStr = "Object";
53
+ const ObjectArrayString = "Object[]";
53
54
  const RefPrefix = "Ref[";
54
55
  const RefSuffix = "]";
55
56
  const RefEnumPrefix = "RefEnum[";
@@ -82,6 +83,9 @@ function csv2ts(csvString, moduleName) {
82
83
  if (parseRefEnum(convert[k])) {
83
84
  refEnumFields.push(k);
84
85
  }
86
+ if (!isKnownType(convert[k])) {
87
+ console.warn(`[config2ts] warning: ${moduleName} field "${k}" has unrecognized type "${convert[k]}", values will be treated as string`);
88
+ }
85
89
  }
86
90
  return null;
87
91
  }
@@ -90,6 +94,9 @@ function csv2ts(csvString, moduleName) {
90
94
  if (convert[k] === ObjectStr) {
91
95
  d[k] = parseObject(d[k]);
92
96
  }
97
+ else if (convert[k] === ObjectArrayString) {
98
+ d[k] = parseObjectArray(d[k]);
99
+ }
93
100
  else if (typeof global[convert[k]] === "function") {
94
101
  d[k] = global[convert[k]](d[k]);
95
102
  }
@@ -172,15 +179,18 @@ function csv2ts(csvString, moduleName) {
172
179
  template += ` export type ${field} = ${enumValueStrings.join(" | ")};\n`;
173
180
  template += ` export const ${field}List: ${field}[] = [${enumValueStrings.join(", ")}];\n\n`;
174
181
  }
175
- else if (convert[field] == ObjectStr) {
182
+ else if (convert[field] == ObjectStr || convert[field] == ObjectArrayString) {
176
183
  const keyTypes = {};
184
+ const isArray = convert[field] == ObjectArrayString;
177
185
  for (const row of result) {
178
- const objValue = row[field];
179
- for (const key in objValue) {
180
- if (!keyTypes[key]) {
181
- keyTypes[key] = new Set();
186
+ const objValues = isArray ? row[field] : [row[field]];
187
+ for (const objValue of objValues) {
188
+ for (const key in objValue) {
189
+ if (!keyTypes[key]) {
190
+ keyTypes[key] = new Set();
191
+ }
192
+ keyTypes[key].add(getTypeName(objValue[key]));
182
193
  }
183
- keyTypes[key].add(getTypeName(objValue[key]));
184
194
  }
185
195
  }
186
196
  template += ` export type ${field} = {\n`;
@@ -212,6 +222,9 @@ function csv2ts(csvString, moduleName) {
212
222
  else if (convert[field] == ObjectStr) {
213
223
  fieldType = field;
214
224
  }
225
+ else if (convert[field] == ObjectArrayString) {
226
+ fieldType = field + "[]";
227
+ }
215
228
  else if (convert[field].startsWith(RefPrefix) && convert[field].endsWith(RefSuffix)) {
216
229
  const refModule = convert[field].slice(RefPrefix.length, -RefSuffix.length);
217
230
  const refModuleName = changeCase.pascalCase(refModule);
@@ -291,6 +304,13 @@ function parseObject(str) {
291
304
  }
292
305
  return result;
293
306
  }
307
+ function parseObjectArray(str) {
308
+ const trimmed = str.trim();
309
+ if (trimmed === "") {
310
+ return [];
311
+ }
312
+ return trimmed.split(";").map((part) => parseObject(part));
313
+ }
294
314
  function parseObjectValue(value) {
295
315
  if (value === "true")
296
316
  return true;
@@ -311,6 +331,25 @@ function getTypeName(value) {
311
331
  return "boolean";
312
332
  return "string";
313
333
  }
334
+ function isKnownType(typeStr) {
335
+ if (typeStr === "") {
336
+ return true;
337
+ }
338
+ const knownTypes = [EnumStr, EnumIndexStr, EnumArrayString, IndexStr, ObjectStr, ObjectArrayString, "String[]", "Number[]"];
339
+ if (knownTypes.includes(typeStr)) {
340
+ return true;
341
+ }
342
+ if (typeStr.startsWith(RefPrefix) && typeStr.endsWith(RefSuffix)) {
343
+ return true;
344
+ }
345
+ if (parseRefEnum(typeStr)) {
346
+ return true;
347
+ }
348
+ if (typeof global[typeStr] === "function") {
349
+ return true;
350
+ }
351
+ return false;
352
+ }
314
353
  function parseRefEnum(typeStr) {
315
354
  if (typeStr.startsWith(RefEnumPrefix)) {
316
355
  let isArray = false;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "config2ts",
3
- "version": "2.5.4",
4
- "description": "convert config to ts file.",
3
+ "version": "2.5.5",
4
+ "description": "Generate type-safe TypeScript from CSV/INI/TOML config tables — inferred types, enums, cross-table references, and a typed asset index, all from one CLI command.",
5
5
  "main": "lib/config2ts.js",
6
6
  "types": "lib/config2ts.d.ts",
7
7
  "bin": {