@deterministic-code/datasources-cli 0.1.4 → 0.1.6

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 (33) hide show
  1. package/dist/generate/RepositoryPlan.js +12 -7
  2. package/node_modules/@deterministic-code/csharp-generators/dist/deterministic-type-converter.js +30 -0
  3. package/node_modules/@deterministic-code/csharp-generators/dist/generate-datasource-types.js +6 -2
  4. package/node_modules/@deterministic-code/csharp-generators/dist/generate-view-types.js +6 -2
  5. package/node_modules/@deterministic-code/csharp-generators/dist/templates/create-backend-app/csharp/App/App.csproj.tmpl +1 -0
  6. package/node_modules/@deterministic-code/csharp-generators/dist/templates/create-datasource-types/type.cs.tmpl +1 -1
  7. package/node_modules/@deterministic-code/csharp-generators/dist/templates/create-view-types/type.cs.tmpl +1 -1
  8. package/node_modules/@deterministic-code/csharp-generators/src/deterministic-type-converter.ts +41 -1
  9. package/node_modules/@deterministic-code/csharp-generators/src/generate-datasource-types.ts +7 -2
  10. package/node_modules/@deterministic-code/csharp-generators/src/generate-view-types.ts +8 -3
  11. package/node_modules/@deterministic-code/csharp-generators/src/templates/create-backend-app/csharp/App/App.csproj.tmpl +1 -0
  12. package/node_modules/@deterministic-code/csharp-generators/src/templates/create-datasource-types/type.cs.tmpl +1 -1
  13. package/node_modules/@deterministic-code/csharp-generators/src/templates/create-view-types/type.cs.tmpl +1 -1
  14. package/node_modules/@deterministic-code/datasources-code-generators/package.json +7 -7
  15. package/node_modules/@deterministic-code/deterministic-generators-common/typescript/parser/dist/specification-parser.js +8 -3
  16. package/node_modules/@deterministic-code/deterministic-generators-common/typescript/parser/parser/specification-parser.ts +7 -4
  17. package/node_modules/@deterministic-code/deterministic-generators-common/typescript/parser/specification.ts +1 -1
  18. package/node_modules/@deterministic-code/deterministic-generators-common/typescript/parser/yaml-node.ts +12 -0
  19. package/node_modules/@deterministic-code/deterministic-specifications-typescript/typescript/parser/parser/specification-parser.ts +7 -4
  20. package/node_modules/@deterministic-code/deterministic-specifications-typescript/typescript/parser/specification.ts +1 -1
  21. package/node_modules/@deterministic-code/deterministic-specifications-typescript/typescript/parser/yaml-node.ts +12 -0
  22. package/node_modules/@deterministic-code/generators-common/dist/spec-types.d.ts +1 -1
  23. package/node_modules/@deterministic-code/generators-common/dist/spec-types.js +22 -14
  24. package/node_modules/@deterministic-code/generators-common/src/spec-types.ts +24 -22
  25. package/node_modules/@deterministic-code/rust-generators/dist/deterministic-type-converter.js +3 -0
  26. package/node_modules/@deterministic-code/rust-generators/dist/generate-view-types.js +1 -1
  27. package/node_modules/@deterministic-code/rust-generators/src/deterministic-type-converter.ts +8 -1
  28. package/node_modules/@deterministic-code/rust-generators/src/generate-view-types.ts +5 -3
  29. package/node_modules/@deterministic-code/typescript-generators/dist/deterministic-type-converter.js +9 -0
  30. package/node_modules/@deterministic-code/typescript-generators/dist/emit-shaped-types.js +7 -3
  31. package/node_modules/@deterministic-code/typescript-generators/src/deterministic-type-converter.ts +19 -1
  32. package/node_modules/@deterministic-code/typescript-generators/src/emit-shaped-types.ts +9 -4
  33. package/package.json +8 -8
@@ -1,6 +1,6 @@
1
1
  import { createCasingStrategy } from "@deterministic-code/generators-common/casing-strategy";
2
2
  import { createDatasourceNaming } from "@deterministic-code/generators-common/datasource-naming";
3
- import { identityColumns, isCollectionField, isDictionaryType, isOwnerIdentityRef, persistedColumnFields } from "@deterministic-code/generators-common/spec-types";
3
+ import { identityColumns, isCollectionField, persistedColumnFields } from "@deterministic-code/generators-common/spec-types";
4
4
  const referenceOf = (references) => {
5
5
  if (references === void 0) return void 0;
6
6
  const [type, field] = [references].flat().join(".").split(".");
@@ -55,7 +55,7 @@ const planRepositories = (spec, dialect, settings) => {
55
55
  const tableType = expanded.get(table.name) ?? types.get(table.name) ?? full;
56
56
  const overlays = new Map(table.fields.map((field) => [field.name, field]));
57
57
  const projected = new Set(Object.values(authored.mapping ?? {}));
58
- const columns = (isDictionaryType(tableType) ? persistedColumnFields(tableType, expanded) : tableType.fields).filter((field) => !isCollectionField(field) && !projected.has(field.name));
58
+ const columns = persistedColumnFields(tableType, expanded).filter((field) => !projected.has(field.name));
59
59
  return [
60
60
  {
61
61
  specName: authored.name,
@@ -101,16 +101,21 @@ const relations = (authored, full, casing, types, expanded, repoName, identity)
101
101
  if (!isCollectionField(field)) continue;
102
102
  if (field.isMap === true) {
103
103
  const dict = expanded.get(field.base) ?? types.get(field.base);
104
- const owner = dict?.fields.find((item) => isOwnerIdentityRef(item.references, dict.name, expanded));
104
+ const owner = referenceOf(field.references);
105
105
  if (dict === void 0 || owner === void 0) continue;
106
- const via = named(dict.name);
106
+ const via = named(owner.type);
107
107
  const value = dict.fields.find((item) => item.name === "value");
108
- const nested = value === void 0 ? void 0 : expanded.get(value.base) ?? types.get(value.base);
108
+ const nested = value !== void 0 && value.kind === "type" && !value.isArray && value.isMap !== true ? expanded.get(value.base) ?? types.get(value.base) : void 0;
109
+ const roleColumn = (role) => {
110
+ const item = dict.fields.find((entry) => entry.name === role);
111
+ const ref2 = referenceOf(item?.references);
112
+ return ref2?.type === owner.type ? ref2.field : role;
113
+ };
109
114
  planned.push({
110
115
  destination: property(field.name),
111
116
  source,
112
- relatedKey: property(owner.name),
113
- relatedProperty: nested === void 0 ? property("value") : void 0,
117
+ relatedKey: property(owner.field),
118
+ relatedProperty: nested === void 0 ? property(roleColumn("value")) : void 0,
114
119
  kind: "dictionary",
115
120
  via: via.via,
116
121
  viaType: via.viaType
@@ -105,8 +105,36 @@ const isCsZero = (specType, expr) => {
105
105
  if (CS_NUMERIC.has(native)) return /^0(\.0+)?$/.test(expr);
106
106
  return false;
107
107
  };
108
+ const CS_VALUE_TYPES = /* @__PURE__ */ new Set([
109
+ "bool",
110
+ "byte",
111
+ "sbyte",
112
+ "short",
113
+ "ushort",
114
+ "int",
115
+ "uint",
116
+ "long",
117
+ "ulong",
118
+ "float",
119
+ "double",
120
+ "decimal",
121
+ "DateTime",
122
+ "Guid"
123
+ ]);
124
+ const isCsValueType = (csType) => {
125
+ const t = csType.endsWith("?") ? csType.slice(0, -1) : csType;
126
+ return CS_VALUE_TYPES.has(t.slice(t.lastIndexOf(".") + 1));
127
+ };
128
+ const collectionDefaultExpr = (field) => {
129
+ if (!field.isArray && field.isMap !== true) return void 0;
130
+ if (field.isNullable && field.defaultValue === null) return void 0;
131
+ return "[]";
132
+ };
108
133
  const nativeDefaultExpr = (specType, field) => {
109
134
  if (field.hasDefault !== true) return void 0;
135
+ if (field.defaultValue === null || Array.isArray(field.defaultValue) || typeof field.defaultValue === "object" && field.defaultValue !== null) {
136
+ return void 0;
137
+ }
110
138
  const expr = defaultValueConverter.convert(
111
139
  specType,
112
140
  String(field.defaultValue)
@@ -116,8 +144,10 @@ const nativeDefaultExpr = (specType, field) => {
116
144
  return isCsZero(specType, expr) ? void 0 : expr;
117
145
  };
118
146
  export {
147
+ collectionDefaultExpr,
119
148
  convertSpecType,
120
149
  defaultValueConverter,
150
+ isCsValueType,
121
151
  nativeDefaultExpr,
122
152
  toNative,
123
153
  typeConverter
@@ -15,7 +15,9 @@ import {
15
15
  withClassParents
16
16
  } from "./common/view-shape.js";
17
17
  import {
18
+ collectionDefaultExpr,
18
19
  convertSpecType,
20
+ isCsValueType,
19
21
  nativeDefaultExpr
20
22
  } from "./deterministic-type-converter.js";
21
23
  import { Emit } from "./emit.js";
@@ -39,10 +41,12 @@ class Generator extends Emit {
39
41
  const { schemaVersion, simpleDoc, descriptionDoc } = this.settings;
40
42
  const parent = classParent(table, "datasource", typesByName);
41
43
  const fields = declaredFields(table, "datasource", typesByName).map((f) => {
42
- const initializer = nativeDefaultExpr(fieldTypeOf(f, typesByName), f);
44
+ const csType = csTypeFor(f, typesByName);
45
+ const initializer = collectionDefaultExpr(f) ?? nativeDefaultExpr(fieldTypeOf(f, typesByName), f);
43
46
  return {
44
47
  ident: this.casing.convertFields(f.name),
45
- csType: csTypeFor(f, typesByName),
48
+ csType,
49
+ required: !f.isNullable && initializer === void 0 && !isCsValueType(csType),
46
50
  hasInitializer: initializer !== void 0,
47
51
  initializer: initializer ?? ""
48
52
  };
@@ -18,7 +18,9 @@ import {
18
18
  typeHasTag
19
19
  } from "./specification-parser.js";
20
20
  import {
21
+ collectionDefaultExpr,
21
22
  convertSpecType,
23
+ isCsValueType,
22
24
  nativeDefaultExpr
23
25
  } from "./deterministic-type-converter.js";
24
26
  import { Emit } from "./emit.js";
@@ -59,10 +61,12 @@ class Generator extends Emit {
59
61
  const isUnion = isUnionLike(view);
60
62
  const parent = classParent(view, "view", typesByName);
61
63
  const fields = declaredFields(view, "view", typesByName).map((f) => {
62
- const initializer = f.kind === "primitive" ? nativeDefaultExpr(fieldTypeOf(f, typesByName), f) : void 0;
64
+ const csType = this.csTypeFor(f, typesByName);
65
+ const initializer = collectionDefaultExpr(f) ?? (f.kind === "primitive" ? nativeDefaultExpr(fieldTypeOf(f, typesByName), f) : void 0);
63
66
  return {
64
67
  ident: this.casing.convertFields(f.name),
65
- csType: this.csTypeFor(f, typesByName),
68
+ csType,
69
+ required: !f.isNullable && initializer === void 0 && !isCsValueType(csType),
66
70
  hasInitializer: initializer !== void 0,
67
71
  initializer: initializer ?? ""
68
72
  };
@@ -6,6 +6,7 @@
6
6
  <AssemblyName>{{PROJECT_NAME}}</AssemblyName>
7
7
  <LangVersion>latest</LangVersion>
8
8
  <Nullable>enable</Nullable>
9
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
9
10
  <ImplicitUsings>enable</ImplicitUsings>
10
11
  <IsPackable>false</IsPackable>
11
12
  <!-- MigrateRunner/ (single-lang) and migrate/ (multi-lang) are sibling projects (see create-migrate-scripts.mjs); both excluded so the app's autoglob doesn't pull in their sources and trip on CS8802 (two top-level Program.cs) plus CS0234/CS0246 for MySqlConnector/Npgsql/Microsoft.Data (those packages are declared in MigrateRunner.csproj, not here). -->
@@ -10,6 +10,6 @@ namespace Backend.Types.Datasource;
10
10
  {{/descriptionDoc}}public class {{className}}{{#hasExtends}} : {{&extendsType}}{{/hasExtends}}
11
11
  {
12
12
  {{#fields}}
13
- public {{csType}} {{ident}} { get; set; }{{#hasInitializer}} = {{&initializer}};{{/hasInitializer}}
13
+ public {{#required}}required {{/required}}{{csType}} {{ident}} { get; set; }{{#hasInitializer}} = {{&initializer}};{{/hasInitializer}}
14
14
  {{/fields}}
15
15
  }
@@ -15,6 +15,6 @@ namespace Backend.Types.View;
15
15
  {{/descriptionDoc}}public class {{className}}{{#hasExtends}} : {{&extendsType}}{{/hasExtends}}
16
16
  {
17
17
  {{#fields}}
18
- public {{&csType}} {{ident}} { get; set; }{{#hasInitializer}} = {{&initializer}};{{/hasInitializer}}
18
+ public {{#required}}required {{/required}}{{&csType}} {{ident}} { get; set; }{{#hasInitializer}} = {{&initializer}};{{/hasInitializer}}
19
19
  {{/fields}}
20
20
  }
@@ -124,16 +124,56 @@ const isCsZero = (specType: string, expr: string): boolean => {
124
124
  return false;
125
125
  };
126
126
 
127
+ const CS_VALUE_TYPES = new Set([
128
+ "bool",
129
+ "byte",
130
+ "sbyte",
131
+ "short",
132
+ "ushort",
133
+ "int",
134
+ "uint",
135
+ "long",
136
+ "ulong",
137
+ "float",
138
+ "double",
139
+ "decimal",
140
+ "DateTime",
141
+ "Guid",
142
+ ]);
143
+
144
+ export const isCsValueType = (csType: string): boolean => {
145
+ const t = csType.endsWith("?") ? csType.slice(0, -1) : csType;
146
+ return CS_VALUE_TYPES.has(t.slice(t.lastIndexOf(".") + 1));
147
+ };
148
+
149
+ export const collectionDefaultExpr = (field: {
150
+ isArray: boolean;
151
+ isMap?: boolean;
152
+ isNullable: boolean;
153
+ defaultValue?: string | number | boolean | null | readonly [] | object;
154
+ }): string | undefined => {
155
+ if (!field.isArray && field.isMap !== true) return undefined;
156
+ if (field.isNullable && field.defaultValue === null) return undefined;
157
+ return "[]";
158
+ };
159
+
127
160
  /** Native initializer, or `undefined` when absent or the language zero. */
128
161
  export const nativeDefaultExpr = (
129
162
  specType: string,
130
163
  field: {
131
164
  hasDefault?: boolean;
132
- defaultValue?: string | number | boolean | null;
165
+ defaultValue?: string | number | boolean | null | readonly [] | object;
133
166
  isNullable: boolean;
134
167
  },
135
168
  ): string | undefined => {
136
169
  if (field.hasDefault !== true) return undefined;
170
+ if (
171
+ field.defaultValue === null ||
172
+ Array.isArray(field.defaultValue) ||
173
+ (typeof field.defaultValue === "object" && field.defaultValue !== null)
174
+ ) {
175
+ return undefined;
176
+ }
137
177
  const expr = defaultValueConverter.convert(
138
178
  specType,
139
179
  String(field.defaultValue),
@@ -19,7 +19,9 @@ import {
19
19
  withClassParents,
20
20
  } from "./common/view-shape.ts";
21
21
  import {
22
+ collectionDefaultExpr,
22
23
  convertSpecType,
24
+ isCsValueType,
23
25
  nativeDefaultExpr,
24
26
  } from "./deterministic-type-converter.ts";
25
27
  import { Emit } from "./emit.ts";
@@ -49,10 +51,13 @@ class Generator extends Emit {
49
51
  const { schemaVersion, simpleDoc, descriptionDoc } = this.settings;
50
52
  const parent = classParent(table, "datasource", typesByName);
51
53
  const fields = declaredFields(table, "datasource", typesByName).map((f) => {
52
- const initializer = nativeDefaultExpr(fieldTypeOf(f, typesByName), f);
54
+ const csType = csTypeFor(f, typesByName);
55
+ const initializer =
56
+ collectionDefaultExpr(f) ?? nativeDefaultExpr(fieldTypeOf(f, typesByName), f);
53
57
  return {
54
58
  ident: this.casing.convertFields(f.name),
55
- csType: csTypeFor(f, typesByName),
59
+ csType,
60
+ required: !f.isNullable && initializer === undefined && !isCsValueType(csType),
56
61
  hasInitializer: initializer !== undefined,
57
62
  initializer: initializer ?? "",
58
63
  };
@@ -22,7 +22,9 @@ import {
22
22
  type TypeField,
23
23
  } from "./specification-parser.ts";
24
24
  import {
25
+ collectionDefaultExpr,
25
26
  convertSpecType,
27
+ isCsValueType,
26
28
  nativeDefaultExpr,
27
29
  } from "./deterministic-type-converter.ts";
28
30
  import { Emit } from "./emit.ts";
@@ -75,13 +77,16 @@ class Generator extends Emit {
75
77
  const isUnion = isUnionLike(view);
76
78
  const parent = classParent(view, "view", typesByName);
77
79
  const fields = declaredFields(view, "view", typesByName).map((f) => {
80
+ const csType = this.csTypeFor(f, typesByName);
78
81
  const initializer =
79
- f.kind === "primitive"
82
+ collectionDefaultExpr(f) ??
83
+ (f.kind === "primitive"
80
84
  ? nativeDefaultExpr(fieldTypeOf(f, typesByName), f)
81
- : undefined;
85
+ : undefined);
82
86
  return {
83
87
  ident: this.casing.convertFields(f.name),
84
- csType: this.csTypeFor(f, typesByName),
88
+ csType,
89
+ required: !f.isNullable && initializer === undefined && !isCsValueType(csType),
85
90
  hasInitializer: initializer !== undefined,
86
91
  initializer: initializer ?? "",
87
92
  };
@@ -6,6 +6,7 @@
6
6
  <AssemblyName>{{PROJECT_NAME}}</AssemblyName>
7
7
  <LangVersion>latest</LangVersion>
8
8
  <Nullable>enable</Nullable>
9
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
9
10
  <ImplicitUsings>enable</ImplicitUsings>
10
11
  <IsPackable>false</IsPackable>
11
12
  <!-- MigrateRunner/ (single-lang) and migrate/ (multi-lang) are sibling projects (see create-migrate-scripts.mjs); both excluded so the app's autoglob doesn't pull in their sources and trip on CS8802 (two top-level Program.cs) plus CS0234/CS0246 for MySqlConnector/Npgsql/Microsoft.Data (those packages are declared in MigrateRunner.csproj, not here). -->
@@ -10,6 +10,6 @@ namespace Backend.Types.Datasource;
10
10
  {{/descriptionDoc}}public class {{className}}{{#hasExtends}} : {{&extendsType}}{{/hasExtends}}
11
11
  {
12
12
  {{#fields}}
13
- public {{csType}} {{ident}} { get; set; }{{#hasInitializer}} = {{&initializer}};{{/hasInitializer}}
13
+ public {{#required}}required {{/required}}{{csType}} {{ident}} { get; set; }{{#hasInitializer}} = {{&initializer}};{{/hasInitializer}}
14
14
  {{/fields}}
15
15
  }
@@ -15,6 +15,6 @@ namespace Backend.Types.View;
15
15
  {{/descriptionDoc}}public class {{className}}{{#hasExtends}} : {{&extendsType}}{{/hasExtends}}
16
16
  {
17
17
  {{#fields}}
18
- public {{&csType}} {{ident}} { get; set; }{{#hasInitializer}} = {{&initializer}};{{/hasInitializer}}
18
+ public {{#required}}required {{/required}}{{&csType}} {{ident}} { get; set; }{{#hasInitializer}} = {{&initializer}};{{/hasInitializer}}
19
19
  {{/fields}}
20
20
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deterministic-code/datasources-code-generators",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dist/generateSql.js",
@@ -10,12 +10,12 @@
10
10
  "./sql/dialect-converters": "./dist/sql/dialect-converters.js"
11
11
  },
12
12
  "dependencies": {
13
- "@deterministic-code/datasources": "^0.1.4",
14
- "@deterministic-code/datasources-mysql": "^0.1.4",
15
- "@deterministic-code/datasources-oracle": "^0.1.4",
16
- "@deterministic-code/datasources-postgres": "^0.1.4",
17
- "@deterministic-code/datasources-sqlite": "^0.1.4",
18
- "@deterministic-code/datasources-sqlserver": "^0.1.4",
13
+ "@deterministic-code/datasources": "^0.1.6",
14
+ "@deterministic-code/datasources-mysql": "^0.1.6",
15
+ "@deterministic-code/datasources-oracle": "^0.1.6",
16
+ "@deterministic-code/datasources-postgres": "^0.1.6",
17
+ "@deterministic-code/datasources-sqlite": "^0.1.6",
18
+ "@deterministic-code/datasources-sqlserver": "^0.1.6",
19
19
  "@deterministic-code/deterministic-generators-common": "0.1.0",
20
20
  "@deterministic-code/generators-common": "0.0.1",
21
21
  "pluralize": "^8.0.0",
@@ -488,7 +488,10 @@ var isMap = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
488
488
  var isString = (v) => typeof v === "string";
489
489
  var isFiniteNumber = (v) => typeof v === "number" && Number.isFinite(v);
490
490
  var isFiniteInt = (v) => isFiniteNumber(v) && Number.isInteger(v);
491
+ var isEmptyList = (v) => Array.isArray(v) && v.length === 0;
492
+ var isEmptyMap = (v) => isMap(v) && Object.keys(v).length === 0;
491
493
  var isLiteral = (v) => v === null || typeof v === "string" || typeof v === "number" || typeof v === "boolean";
494
+ var isFieldDefault = (v) => isLiteral(v) || isEmptyList(v) || isEmptyMap(v);
492
495
  var yamlNode = (value, path = "$") => {
493
496
  const record = isMap(value) ? value : void 0;
494
497
  const at = (key) => record?.[key];
@@ -509,6 +512,7 @@ var yamlNode = (value, path = "$") => {
509
512
  finiteNumber: pick(isFiniteNumber),
510
513
  finiteInt: pick(isFiniteInt),
511
514
  literal: pick(isLiteral),
515
+ fieldDefault: pick(isFieldDefault),
512
516
  strings: (key) => {
513
517
  const v = at(key);
514
518
  return Array.isArray(v) ? v.filter(isString) : [];
@@ -614,7 +618,7 @@ var Parser = class {
614
618
  constructor(reader) {
615
619
  this.#reader = reader;
616
620
  }
617
- async parse(settings, opts) {
621
+ async parse(_settings, opts) {
618
622
  const reader = this.#reader;
619
623
  const serviceClassName = opts?.serviceClassName ?? ((entity) => entity);
620
624
  const [hasTypes, hasDs, hasSeeds, hasServices, hasRoutes] = await Promise.all([
@@ -693,6 +697,7 @@ var Parser = class {
693
697
  const references = referencesOf(node);
694
698
  const size = sizeOf(node);
695
699
  const minSize = node.finiteInt("min_size");
700
+ const collectionDefault = parsed.isArray ? [] : parsed.isMap ? {} : void 0;
696
701
  return {
697
702
  name,
698
703
  type: rawType,
@@ -705,7 +710,7 @@ var Parser = class {
705
710
  ...size !== void 0 ? { size } : {},
706
711
  ...minSize !== void 0 ? { minSize } : {},
707
712
  ...references !== void 0 ? { references } : {},
708
- ...node.has("default_value") ? { hasDefault: true, defaultValue: node.literal("default_value") } : {}
713
+ ...node.has("default_value") ? { hasDefault: true, defaultValue: node.fieldDefault("default_value") } : collectionDefault !== void 0 ? { hasDefault: true, defaultValue: collectionDefault } : {}
709
714
  };
710
715
  }
711
716
  #parseDatasource(yaml, types) {
@@ -1105,7 +1110,7 @@ var Parser = class {
1105
1110
  }
1106
1111
  }
1107
1112
  }
1108
- #extractCustomRoutes(root, dsByName, typeByName) {
1113
+ #extractCustomRoutes(root, _dsByName, typeByName) {
1109
1114
  const customs = [];
1110
1115
  for (const entry of root.child("routes").items()) {
1111
1116
  if (entry.record === void 0) continue;
@@ -179,7 +179,7 @@ class Parser {
179
179
  }
180
180
 
181
181
  async parse(
182
- settings: Record<string, string>,
182
+ _settings: Record<string, string>,
183
183
  opts?: { serviceClassName?: (entity: string) => string },
184
184
  ): Promise<IDeterministic> {
185
185
  const reader = this.#reader;
@@ -285,6 +285,7 @@ class Parser {
285
285
  const references = referencesOf(node);
286
286
  const size = sizeOf(node);
287
287
  const minSize = node.finiteInt("min_size");
288
+ const collectionDefault = parsed.isArray ? [] : parsed.isMap ? {} : undefined;
288
289
  return {
289
290
  name,
290
291
  type: rawType,
@@ -298,8 +299,10 @@ class Parser {
298
299
  ...(minSize !== undefined ? { minSize } : {}),
299
300
  ...(references !== undefined ? { references } : {}),
300
301
  ...(node.has("default_value")
301
- ? { hasDefault: true, defaultValue: node.literal("default_value") }
302
- : {}),
302
+ ? { hasDefault: true, defaultValue: node.fieldDefault("default_value") }
303
+ : collectionDefault !== undefined
304
+ ? { hasDefault: true, defaultValue: collectionDefault }
305
+ : {}),
303
306
  };
304
307
  }
305
308
 
@@ -838,7 +841,7 @@ class Parser {
838
841
 
839
842
  #extractCustomRoutes(
840
843
  root: YamlNode,
841
- dsByName: Map<string, DatasourceTable>,
844
+ _dsByName: Map<string, DatasourceTable>,
842
845
  typeByName: Map<string, Type>,
843
846
  ): CustomRouteEntry[] {
844
847
  const customs: CustomRouteEntry[] = [];
@@ -21,7 +21,7 @@ export type TypeField = {
21
21
  minSize?: number;
22
22
  references?: string | [string, string];
23
23
  hasDefault?: boolean;
24
- defaultValue?: string | number | boolean | null;
24
+ defaultValue?: string | number | boolean | null | object;
25
25
  };
26
26
 
27
27
  /** Primary label. `inherit` may also carry `union` — those members compose. */
@@ -3,6 +3,7 @@ import { parse } from "yaml";
3
3
  type YamlLiteral = string | number | boolean | null;
4
4
  type YamlMap = { readonly [key: string]: YamlValue };
5
5
  type YamlValue = YamlLiteral | YamlValue[] | YamlMap;
6
+ type FieldDefault = YamlLiteral | YamlValue[] | YamlMap;
6
7
  type Named = { name: string; node: YamlNode };
7
8
 
8
9
  const isMap = (v: YamlValue | undefined): v is YamlMap =>
@@ -16,12 +17,21 @@ const isFiniteNumber = (v: YamlValue | undefined): v is number =>
16
17
  const isFiniteInt = (v: YamlValue | undefined): v is number =>
17
18
  isFiniteNumber(v) && Number.isInteger(v);
18
19
 
20
+ const isEmptyList = (v: YamlValue | undefined): v is YamlValue[] =>
21
+ Array.isArray(v) && v.length === 0;
22
+
23
+ const isEmptyMap = (v: YamlValue | undefined): v is YamlMap =>
24
+ isMap(v) && Object.keys(v).length === 0;
25
+
19
26
  const isLiteral = (v: YamlValue | undefined): v is YamlLiteral =>
20
27
  v === null ||
21
28
  typeof v === "string" ||
22
29
  typeof v === "number" ||
23
30
  typeof v === "boolean";
24
31
 
32
+ const isFieldDefault = (v: YamlValue | undefined): v is FieldDefault =>
33
+ isLiteral(v) || isEmptyList(v) || isEmptyMap(v);
34
+
25
35
  /** Typed cursor over a YAML value. Missing keys are empty nodes, not throws. */
26
36
  export type YamlNode = {
27
37
  readonly value: YamlValue | undefined;
@@ -34,6 +44,7 @@ export type YamlNode = {
34
44
  finiteNumber: (key: string) => number | undefined;
35
45
  finiteInt: (key: string) => number | undefined;
36
46
  literal: (key: string) => YamlLiteral | undefined;
47
+ fieldDefault: (key: string) => FieldDefault | undefined;
37
48
  strings: (key: string) => string[];
38
49
  items: () => YamlNode[];
39
50
  namedItems: () => Named[];
@@ -66,6 +77,7 @@ const yamlNode = (value: YamlValue | undefined, path = "$"): YamlNode => {
66
77
  finiteNumber: pick(isFiniteNumber),
67
78
  finiteInt: pick(isFiniteInt),
68
79
  literal: pick(isLiteral),
80
+ fieldDefault: pick(isFieldDefault),
69
81
  strings: (key) => {
70
82
  const v = at(key);
71
83
  return Array.isArray(v) ? v.filter(isString) : [];
@@ -178,7 +178,7 @@ class Parser {
178
178
  }
179
179
 
180
180
  async parse(
181
- settings: Record<string, string>,
181
+ _settings: Record<string, string>,
182
182
  opts?: { serviceClassName?: (entity: string) => string },
183
183
  ): Promise<IDeterministic> {
184
184
  const reader = this.#reader;
@@ -284,6 +284,7 @@ class Parser {
284
284
  const references = referencesOf(node);
285
285
  const size = sizeOf(node);
286
286
  const minSize = node.finiteInt("min_size");
287
+ const collectionDefault = parsed.isArray ? [] : parsed.isMap ? {} : undefined;
287
288
  return {
288
289
  name,
289
290
  type: rawType,
@@ -297,8 +298,10 @@ class Parser {
297
298
  ...(minSize !== undefined ? { minSize } : {}),
298
299
  ...(references !== undefined ? { references } : {}),
299
300
  ...(node.has("default_value")
300
- ? { hasDefault: true, defaultValue: node.literal("default_value") }
301
- : {}),
301
+ ? { hasDefault: true, defaultValue: node.fieldDefault("default_value") }
302
+ : collectionDefault !== undefined
303
+ ? { hasDefault: true, defaultValue: collectionDefault }
304
+ : {}),
302
305
  };
303
306
  }
304
307
 
@@ -837,7 +840,7 @@ class Parser {
837
840
 
838
841
  #extractCustomRoutes(
839
842
  root: YamlNode,
840
- dsByName: Map<string, DatasourceTable>,
843
+ _dsByName: Map<string, DatasourceTable>,
841
844
  typeByName: Map<string, Type>,
842
845
  ): CustomRouteEntry[] {
843
846
  const customs: CustomRouteEntry[] = [];
@@ -21,7 +21,7 @@ export type TypeField = {
21
21
  minSize?: number;
22
22
  references?: string | [string, string];
23
23
  hasDefault?: boolean;
24
- defaultValue?: string | number | boolean | null;
24
+ defaultValue?: string | number | boolean | null | object;
25
25
  };
26
26
 
27
27
  /** Primary label. `inherit` may also carry `union` — those members compose. */
@@ -3,6 +3,7 @@ import { parse } from "yaml";
3
3
  type YamlLiteral = string | number | boolean | null;
4
4
  type YamlMap = { readonly [key: string]: YamlValue };
5
5
  type YamlValue = YamlLiteral | YamlValue[] | YamlMap;
6
+ type FieldDefault = YamlLiteral | YamlValue[] | YamlMap;
6
7
  type Named = { name: string; node: YamlNode };
7
8
 
8
9
  const isMap = (v: YamlValue | undefined): v is YamlMap =>
@@ -16,12 +17,21 @@ const isFiniteNumber = (v: YamlValue | undefined): v is number =>
16
17
  const isFiniteInt = (v: YamlValue | undefined): v is number =>
17
18
  isFiniteNumber(v) && Number.isInteger(v);
18
19
 
20
+ const isEmptyList = (v: YamlValue | undefined): v is YamlValue[] =>
21
+ Array.isArray(v) && v.length === 0;
22
+
23
+ const isEmptyMap = (v: YamlValue | undefined): v is YamlMap =>
24
+ isMap(v) && Object.keys(v).length === 0;
25
+
19
26
  const isLiteral = (v: YamlValue | undefined): v is YamlLiteral =>
20
27
  v === null ||
21
28
  typeof v === "string" ||
22
29
  typeof v === "number" ||
23
30
  typeof v === "boolean";
24
31
 
32
+ const isFieldDefault = (v: YamlValue | undefined): v is FieldDefault =>
33
+ isLiteral(v) || isEmptyList(v) || isEmptyMap(v);
34
+
25
35
  /** Typed cursor over a YAML value. Missing keys are empty nodes, not throws. */
26
36
  export type YamlNode = {
27
37
  readonly value: YamlValue | undefined;
@@ -34,6 +44,7 @@ export type YamlNode = {
34
44
  finiteNumber: (key: string) => number | undefined;
35
45
  finiteInt: (key: string) => number | undefined;
36
46
  literal: (key: string) => YamlLiteral | undefined;
47
+ fieldDefault: (key: string) => FieldDefault | undefined;
37
48
  strings: (key: string) => string[];
38
49
  items: () => YamlNode[];
39
50
  namedItems: () => Named[];
@@ -66,6 +77,7 @@ const yamlNode = (value: YamlValue | undefined, path = "$"): YamlNode => {
66
77
  finiteNumber: pick(isFiniteNumber),
67
78
  finiteInt: pick(isFiniteInt),
68
79
  literal: pick(isLiteral),
80
+ fieldDefault: pick(isFieldDefault),
69
81
  strings: (key) => {
70
82
  const v = at(key);
71
83
  return Array.isArray(v) ? v.filter(isString) : [];
@@ -32,6 +32,6 @@ export declare const dictionaryEntryFields: (dict: Type) => {
32
32
  value: TypeField;
33
33
  } | undefined;
34
34
  export declare const dictionaryOfField: (field: TypeField, byName: Map<string, Type>) => Type | undefined;
35
- export declare const persistedColumnFields: (type: Type, byName: Map<string, Type>) => TypeField[];
35
+ export declare const persistedColumnFields: (type: Type, _byName?: Map<string, Type>) => TypeField[];
36
36
  export declare const dictionaryUniqueColumns: (type: Type, byName: Map<string, Type>) => string[];
37
37
  export {};
@@ -112,23 +112,31 @@ const dictionaryOfField = (field, byName) => {
112
112
  const dict = byName.get(field.base);
113
113
  return isDictionaryType(dict) ? dict : void 0;
114
114
  };
115
- const persistedColumnFields = (type, byName) => {
116
- if (!isDictionaryType(type)) return columnFields(type.fields);
117
- const value = type.fields.find((f) => f.name === "value");
118
- if (value === void 0 || value.kind !== "type" || value.isArray || value.isMap === true) {
119
- return columnFields(type.fields);
115
+ const persistedColumnFields = (type, _byName) => columnFields(type.fields);
116
+ const roleColumn = (dict, role, tableName) => {
117
+ const field = dict.fields.find((item) => item.name === role);
118
+ const references = field?.references;
119
+ if (typeof references === "string") {
120
+ const [table, column] = references.split(".");
121
+ if (table === tableName && column !== void 0 && column.length > 0) {
122
+ return column;
123
+ }
120
124
  }
121
- const nested = byName.get(value.base);
122
- if (nested === void 0) return columnFields(type.fields);
123
- return [
124
- ...columnFields(type.fields.filter((f) => f.name !== "value")),
125
- ...columnFields(nested.fields)
126
- ];
125
+ return role;
127
126
  };
128
127
  const dictionaryUniqueColumns = (type, byName) => {
129
- if (!isDictionaryType(type)) return [];
130
- const owners = type.fields.filter((f) => isOwnerIdentityRef(f.references, type.name, byName)).map((f) => f.name);
131
- return type.fields.some((f) => f.name === "key") ? [...owners, "key"] : owners;
128
+ for (const candidate of byName.values()) {
129
+ for (const field of candidate.fields) {
130
+ if (field.isMap !== true) continue;
131
+ const dict = byName.get(field.base);
132
+ if (!isDictionaryType(dict) || dict === void 0) continue;
133
+ if (typeof field.references !== "string") continue;
134
+ const [table, owner] = field.references.split(".");
135
+ if (table !== type.name || owner === void 0 || owner.length === 0) continue;
136
+ return [owner, roleColumn(dict, "key", type.name)];
137
+ }
138
+ }
139
+ return [];
132
140
  };
133
141
  export {
134
142
  DATASOURCE_SEEDS_YAML,
@@ -202,33 +202,35 @@ export const dictionaryOfField = (
202
202
 
203
203
  export const persistedColumnFields = (
204
204
  type: Type,
205
- byName: Map<string, Type>,
206
- ): TypeField[] => {
207
- if (!isDictionaryType(type)) return columnFields(type.fields);
208
- const value = type.fields.find((f) => f.name === "value");
209
- if (
210
- value === undefined ||
211
- value.kind !== "type" ||
212
- value.isArray ||
213
- value.isMap === true
214
- ) {
215
- return columnFields(type.fields);
205
+ _byName?: Map<string, Type>,
206
+ ): TypeField[] => columnFields(type.fields);
207
+
208
+ const roleColumn = (dict: Type, role: string, tableName: string): string => {
209
+ const field = dict.fields.find((item) => item.name === role);
210
+ const references = field?.references;
211
+ if (typeof references === "string") {
212
+ const [table, column] = references.split(".");
213
+ if (table === tableName && column !== undefined && column.length > 0) {
214
+ return column;
215
+ }
216
216
  }
217
- const nested = byName.get(value.base);
218
- if (nested === undefined) return columnFields(type.fields);
219
- return [
220
- ...columnFields(type.fields.filter((f) => f.name !== "value")),
221
- ...columnFields(nested.fields),
222
- ];
217
+ return role;
223
218
  };
224
219
 
225
220
  export const dictionaryUniqueColumns = (
226
221
  type: Type,
227
222
  byName: Map<string, Type>,
228
223
  ): string[] => {
229
- if (!isDictionaryType(type)) return [];
230
- const owners = type.fields
231
- .filter((f) => isOwnerIdentityRef(f.references, type.name, byName))
232
- .map((f) => f.name);
233
- return type.fields.some((f) => f.name === "key") ? [...owners, "key"] : owners;
224
+ for (const candidate of byName.values()) {
225
+ for (const field of candidate.fields) {
226
+ if (field.isMap !== true) continue;
227
+ const dict = byName.get(field.base);
228
+ if (!isDictionaryType(dict) || dict === undefined) continue;
229
+ if (typeof field.references !== "string") continue;
230
+ const [table, owner] = field.references.split(".");
231
+ if (table !== type.name || owner === undefined || owner.length === 0) continue;
232
+ return [owner, roleColumn(dict, "key", type.name)];
233
+ }
234
+ }
235
+ return [];
234
236
  };
@@ -101,6 +101,9 @@ const convertSpecType = toNative;
101
101
  const isRustZeroExpr = (expr) => expr === "false" || expr === "0" || expr === "0.0" || expr === "String::new()" || expr === 'String::from("")' || expr === "vec![]" || expr === "None";
102
102
  const rustSpecDefaultExpr = (specType, field) => {
103
103
  if (field.hasDefault !== true) return void 0;
104
+ if (field.defaultValue === null || Array.isArray(field.defaultValue) || typeof field.defaultValue === "object" && field.defaultValue !== null) {
105
+ return void 0;
106
+ }
104
107
  const expr = defaultValueConverter.convert(
105
108
  specType,
106
109
  String(field.defaultValue)
@@ -68,7 +68,7 @@ class Generator extends Emit {
68
68
  }
69
69
  fieldToken(field) {
70
70
  const rustType = this.rustTypeFor(field);
71
- const specExpr = field.kind === "primitive" ? rustSpecDefaultExpr(fieldTypeOf(field, this.typesByName), field) : void 0;
71
+ const specExpr = field.isArray || field.isMap === true ? void 0 : field.kind === "primitive" ? rustSpecDefaultExpr(fieldTypeOf(field, this.typesByName), field) : void 0;
72
72
  return {
73
73
  ident: this.casing.convertFields(field.name),
74
74
  rustType,
@@ -130,11 +130,18 @@ export const rustSpecDefaultExpr = (
130
130
  specType: string,
131
131
  field: {
132
132
  hasDefault?: boolean;
133
- defaultValue?: string | number | boolean | null;
133
+ defaultValue?: string | number | boolean | null | readonly [] | object;
134
134
  isNullable: boolean;
135
135
  },
136
136
  ): string | undefined => {
137
137
  if (field.hasDefault !== true) return undefined;
138
+ if (
139
+ field.defaultValue === null ||
140
+ Array.isArray(field.defaultValue) ||
141
+ (typeof field.defaultValue === "object" && field.defaultValue !== null)
142
+ ) {
143
+ return undefined;
144
+ }
138
145
  const expr = defaultValueConverter.convert(
139
146
  specType,
140
147
  String(field.defaultValue),
@@ -83,9 +83,11 @@ class Generator extends Emit {
83
83
  private fieldToken(field: TypeField) {
84
84
  const rustType = this.rustTypeFor(field);
85
85
  const specExpr =
86
- field.kind === "primitive"
87
- ? rustSpecDefaultExpr(fieldTypeOf(field, this.typesByName), field)
88
- : undefined;
86
+ field.isArray || field.isMap === true
87
+ ? undefined
88
+ : field.kind === "primitive"
89
+ ? rustSpecDefaultExpr(fieldTypeOf(field, this.typesByName), field)
90
+ : undefined;
89
91
  return {
90
92
  ident: this.casing.convertFields(field.name),
91
93
  rustType,
@@ -92,8 +92,16 @@ const defaultValueConverter = new DeterministicDefaultValueConverter({
92
92
  });
93
93
  const toNative = (specType) => typeConverter.convert(specType);
94
94
  const isTsZeroExpr = (expr) => expr === "false" || expr === "0" || expr === '""';
95
+ const collectionDefaultExpr = (field) => {
96
+ if (!field.isArray && field.isMap !== true) return void 0;
97
+ if (field.isNullable && field.defaultValue === null) return void 0;
98
+ return field.isMap === true ? "{}" : "[]";
99
+ };
95
100
  const nativeDefaultExpr = (specType, field) => {
96
101
  if (field.hasDefault !== true) return void 0;
102
+ if (field.defaultValue === null || Array.isArray(field.defaultValue) || typeof field.defaultValue === "object" && field.defaultValue !== null) {
103
+ return void 0;
104
+ }
97
105
  const expr = defaultValueConverter.convert(
98
106
  specType,
99
107
  String(field.defaultValue)
@@ -103,6 +111,7 @@ const nativeDefaultExpr = (specType, field) => {
103
111
  return isTsZeroExpr(expr) ? void 0 : expr;
104
112
  };
105
113
  export {
114
+ collectionDefaultExpr,
106
115
  defaultValueConverter,
107
116
  nativeDefaultExpr,
108
117
  toNative,
@@ -17,7 +17,11 @@ import {
17
17
  import {
18
18
  DeterministicParser
19
19
  } from "@deterministic-code/deterministic-generators-common/parser";
20
- import { nativeDefaultExpr, toNative } from "./deterministic-type-converter.js";
20
+ import {
21
+ collectionDefaultExpr,
22
+ nativeDefaultExpr,
23
+ toNative
24
+ } from "./deterministic-type-converter.js";
21
25
  import { fieldRefKind, fieldsBeyondParent, isAlias } from "./common/view-shape.js";
22
26
  import { bag, Emit } from "./emit.js";
23
27
  import {
@@ -277,14 +281,14 @@ class Generator extends Emit {
277
281
  const parent = flatten ? void 0 : this.extendsType(type, aliasByClass);
278
282
  const fields = this.emitFields(type, expanded, flatten);
279
283
  const fieldTokens = fields.map((f) => {
280
- const initializer = f.kind === "primitive" ? nativeDefaultExpr(fieldTypeOf(f, this.typesByName), f) : void 0;
284
+ const initializer = collectionDefaultExpr(f) ?? (f.kind === "primitive" ? nativeDefaultExpr(fieldTypeOf(f, this.typesByName), f) : void 0);
281
285
  return {
282
286
  ident: this.casing.fieldIdent(f.name),
283
287
  tsType: this.fieldTs(f, aliasByClass),
284
288
  nullable: f.isNullable,
285
289
  hasInitializer: isClass && initializer !== void 0,
286
290
  initializer: initializer ?? "",
287
- definite: isClass && initializer === void 0
291
+ definite: isClass && initializer === void 0 && !f.isNullable
288
292
  };
289
293
  });
290
294
  const refs = this.refs(type, expanded, flatten);
@@ -114,16 +114,34 @@ export const toNative = (specType: string): string =>
114
114
  const isTsZeroExpr = (expr: string): boolean =>
115
115
  expr === "false" || expr === "0" || expr === '""';
116
116
 
117
+ export const collectionDefaultExpr = (field: {
118
+ isArray: boolean;
119
+ isMap?: boolean;
120
+ isNullable: boolean;
121
+ defaultValue?: string | number | boolean | null | readonly [] | object;
122
+ }): string | undefined => {
123
+ if (!field.isArray && field.isMap !== true) return undefined;
124
+ if (field.isNullable && field.defaultValue === null) return undefined;
125
+ return field.isMap === true ? "{}" : "[]";
126
+ };
127
+
117
128
  /** Native initializer, or `undefined` when absent or the language zero. */
118
129
  export const nativeDefaultExpr = (
119
130
  specType: string,
120
131
  field: {
121
132
  hasDefault?: boolean;
122
- defaultValue?: string | number | boolean | null;
133
+ defaultValue?: string | number | boolean | null | readonly [] | object;
123
134
  isNullable: boolean;
124
135
  },
125
136
  ): string | undefined => {
126
137
  if (field.hasDefault !== true) return undefined;
138
+ if (
139
+ field.defaultValue === null ||
140
+ Array.isArray(field.defaultValue) ||
141
+ (typeof field.defaultValue === "object" && field.defaultValue !== null)
142
+ ) {
143
+ return undefined;
144
+ }
127
145
  const expr = defaultValueConverter.convert(
128
146
  specType,
129
147
  String(field.defaultValue),
@@ -21,7 +21,11 @@ import {
21
21
  type Type,
22
22
  type TypeField,
23
23
  } from "@deterministic-code/deterministic-generators-common/parser";
24
- import { nativeDefaultExpr, toNative } from "./deterministic-type-converter.ts";
24
+ import {
25
+ collectionDefaultExpr,
26
+ nativeDefaultExpr,
27
+ toNative,
28
+ } from "./deterministic-type-converter.ts";
25
29
  import { fieldRefKind, fieldsBeyondParent, isAlias } from "./common/view-shape.ts";
26
30
  import { bag, Emit } from "./emit.ts";
27
31
  import {
@@ -457,16 +461,17 @@ class Generator extends Emit {
457
461
  const fields = this.emitFields(type, expanded, flatten);
458
462
  const fieldTokens = fields.map((f) => {
459
463
  const initializer =
460
- f.kind === "primitive"
464
+ collectionDefaultExpr(f) ??
465
+ (f.kind === "primitive"
461
466
  ? nativeDefaultExpr(fieldTypeOf(f, this.typesByName), f)
462
- : undefined;
467
+ : undefined);
463
468
  return {
464
469
  ident: this.casing.fieldIdent(f.name),
465
470
  tsType: this.fieldTs(f, aliasByClass),
466
471
  nullable: f.isNullable,
467
472
  hasInitializer: isClass && initializer !== undefined,
468
473
  initializer: initializer ?? "",
469
- definite: isClass && initializer === undefined,
474
+ definite: isClass && initializer === undefined && !f.isNullable,
470
475
  };
471
476
  });
472
477
  const refs = this.refs(type, expanded, flatten);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deterministic-code/datasources-cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "datasources": "./bin/datasources.mjs"
@@ -13,7 +13,7 @@
13
13
  "access": "public"
14
14
  },
15
15
  "dependencies": {
16
- "@deterministic-code/datasources-code-generators": "0.1.4",
16
+ "@deterministic-code/datasources-code-generators": "0.1.6",
17
17
  "@deterministic-code/generators-common": "0.0.1",
18
18
  "@deterministic-code/deterministic-generators-common": "0.1.0",
19
19
  "@deterministic-code/typescript-generators": "0.0.1",
@@ -21,12 +21,12 @@
21
21
  "@deterministic-code/rust-generators": "0.0.1",
22
22
  "@deterministic-code/generators-openapi": "0.0.1",
23
23
  "@deterministic-code/patch-merger": "0.1.0",
24
- "@deterministic-code/datasources": "^0.1.4",
25
- "@deterministic-code/datasources-sqlite": "^0.1.4",
26
- "@deterministic-code/datasources-mysql": "^0.1.4",
27
- "@deterministic-code/datasources-postgres": "^0.1.4",
28
- "@deterministic-code/datasources-sqlserver": "^0.1.4",
29
- "@deterministic-code/datasources-oracle": "^0.1.4",
24
+ "@deterministic-code/datasources": "^0.1.6",
25
+ "@deterministic-code/datasources-sqlite": "^0.1.6",
26
+ "@deterministic-code/datasources-mysql": "^0.1.6",
27
+ "@deterministic-code/datasources-postgres": "^0.1.6",
28
+ "@deterministic-code/datasources-sqlserver": "^0.1.6",
29
+ "@deterministic-code/datasources-oracle": "^0.1.6",
30
30
  "@inquirer/prompts": "^7.8.0",
31
31
  "yaml": "^2.6.0",
32
32
  "mustache": "^4.2.0",