@casekit/orm2-config 0.0.0-20250331202540 → 0.0.1

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 (73) hide show
  1. package/package.json +19 -19
  2. package/{build/index.d.ts → src/index.ts} +7 -1
  3. package/{build/normalize/defaultZodSchema.test.js → src/normalize/defaultZodSchema.test.ts} +13 -5
  4. package/{build/normalize/defaultZodSchema.js → src/normalize/defaultZodSchema.ts} +22 -30
  5. package/{build/normalize/getColumns.test.js → src/normalize/getColumns.test.ts} +17 -4
  6. package/{build/normalize/getColumns.js → src/normalize/getColumns.ts} +6 -1
  7. package/{build/normalize/normalizeConfig.test.js → src/normalize/normalizeConfig.test.ts} +70 -24
  8. package/{build/normalize/normalizeConfig.js → src/normalize/normalizeConfig.ts} +7 -2
  9. package/{build/normalize/normalizeField.test.js → src/normalize/normalizeField.test.ts} +12 -7
  10. package/src/normalize/normalizeField.ts +16 -0
  11. package/{build/normalize/normalizeForeignKeys.test.js → src/normalize/normalizeForeignKeys.test.ts} +26 -7
  12. package/src/normalize/normalizeForeignKeys.ts +89 -0
  13. package/{build/normalize/normalizeModel.test.js → src/normalize/normalizeModel.test.ts} +42 -18
  14. package/{build/normalize/normalizeModel.js → src/normalize/normalizeModel.ts} +8 -1
  15. package/{build/normalize/normalizePrimaryKey.test.js → src/normalize/normalizePrimaryKey.test.ts} +31 -7
  16. package/src/normalize/normalizePrimaryKey.ts +30 -0
  17. package/{build/normalize/normalizeRelations.test.js → src/normalize/normalizeRelations.test.ts} +38 -9
  18. package/{build/normalize/normalizeRelations.js → src/normalize/normalizeRelations.ts} +34 -12
  19. package/{build/normalize/normalizeUniqueConstraints.test.js → src/normalize/normalizeUniqueConstraints.test.ts} +46 -15
  20. package/src/normalize/normalizeUniqueConstraints.ts +58 -0
  21. package/src/normalize/populateField.test.ts +253 -0
  22. package/{build/normalize/populateField.js → src/normalize/populateField.ts} +9 -1
  23. package/{build/normalize/populateModels.test.js → src/normalize/populateModels.test.ts} +35 -14
  24. package/{build/normalize/populateModels.js → src/normalize/populateModels.ts} +11 -2
  25. package/{build/types/NormalizedConfig.d.ts → src/types/NormalizedConfig.ts} +8 -1
  26. package/{build/types/NormalizedFieldDefinition.d.ts → src/types/NormalizedFieldDefinition.ts} +2 -1
  27. package/{build/types/NormalizedModelDefinition.d.ts → src/types/NormalizedModelDefinition.ts} +1 -0
  28. package/{build/types/NormalizedRelationDefinition.d.ts → src/types/NormalizedRelationDefinition.ts} +7 -1
  29. package/{build/types/NormalizedUniqueConstraintDefinition.d.ts → src/types/NormalizedUniqueConstraintDefinition.ts} +1 -0
  30. package/{build/types/PopulatedFieldDefinition.d.ts → src/types/PopulatedFieldDefinition.ts} +1 -0
  31. package/{build/types/PopulatedModelDefinition.d.ts → src/types/PopulatedModelDefinition.ts} +2 -0
  32. package/src/util.ts +38 -0
  33. package/build/index.js +0 -4
  34. package/build/normalize/defaultZodSchema.d.ts +0 -8
  35. package/build/normalize/defaultZodSchema.test.d.ts +0 -1
  36. package/build/normalize/getColumns.d.ts +0 -2
  37. package/build/normalize/getColumns.test.d.ts +0 -1
  38. package/build/normalize/normalizeConfig.d.ts +0 -3
  39. package/build/normalize/normalizeConfig.test.d.ts +0 -1
  40. package/build/normalize/normalizeField.d.ts +0 -3
  41. package/build/normalize/normalizeField.js +0 -11
  42. package/build/normalize/normalizeField.test.d.ts +0 -1
  43. package/build/normalize/normalizeForeignKeys.d.ts +0 -5
  44. package/build/normalize/normalizeForeignKeys.js +0 -50
  45. package/build/normalize/normalizeForeignKeys.test.d.ts +0 -1
  46. package/build/normalize/normalizeModel.d.ts +0 -3
  47. package/build/normalize/normalizeModel.test.d.ts +0 -1
  48. package/build/normalize/normalizePrimaryKey.d.ts +0 -3
  49. package/build/normalize/normalizePrimaryKey.js +0 -18
  50. package/build/normalize/normalizePrimaryKey.test.d.ts +0 -1
  51. package/build/normalize/normalizeRelations.d.ts +0 -3
  52. package/build/normalize/normalizeRelations.test.d.ts +0 -1
  53. package/build/normalize/normalizeUniqueConstraints.d.ts +0 -5
  54. package/build/normalize/normalizeUniqueConstraints.js +0 -29
  55. package/build/normalize/normalizeUniqueConstraints.test.d.ts +0 -1
  56. package/build/normalize/populateField.d.ts +0 -3
  57. package/build/normalize/populateField.test.d.ts +0 -1
  58. package/build/normalize/populateField.test.js +0 -198
  59. package/build/normalize/populateModels.d.ts +0 -3
  60. package/build/normalize/populateModels.test.d.ts +0 -1
  61. package/build/types/NormalizedConfig.js +0 -1
  62. package/build/types/NormalizedFieldDefinition.js +0 -1
  63. package/build/types/NormalizedForeignKeyDefinition.js +0 -1
  64. package/build/types/NormalizedModelDefinition.js +0 -1
  65. package/build/types/NormalizedPrimaryKey.js +0 -1
  66. package/build/types/NormalizedRelationDefinition.js +0 -1
  67. package/build/types/NormalizedUniqueConstraintDefinition.js +0 -1
  68. package/build/types/PopulatedFieldDefinition.js +0 -1
  69. package/build/types/PopulatedModelDefinition.js +0 -1
  70. package/build/util.d.ts +0 -6
  71. package/build/util.js +0 -21
  72. /package/{build/types/NormalizedForeignKeyDefinition.d.ts → src/types/NormalizedForeignKeyDefinition.ts} +0 -0
  73. /package/{build/types/NormalizedPrimaryKey.d.ts → src/types/NormalizedPrimaryKey.ts} +0 -0
package/package.json CHANGED
@@ -1,44 +1,44 @@
1
1
  {
2
2
  "name": "@casekit/orm2-config",
3
3
  "description": "",
4
- "version": "0.0.0-20250331202540",
4
+ "version": "0.0.1",
5
5
  "author": "",
6
6
  "dependencies": {
7
- "es-toolkit": "^1.33.0",
8
- "@casekit/orm2-schema": "0.0.0-20250331202540",
9
- "@casekit/sql": "0.0.0-20250331202540",
10
- "@casekit/toolbox": "0.0.0-20250331202540"
7
+ "es-toolkit": "^1.39.3",
8
+ "@casekit/orm2-schema": "0.0.1",
9
+ "@casekit/sql": "0.0.1",
10
+ "@casekit/toolbox": "0.0.1"
11
11
  },
12
12
  "devDependencies": {
13
13
  "@trivago/prettier-plugin-sort-imports": "^5.2.2",
14
- "@types/node": "^22.13.13",
15
- "@types/pg": "^8.11.11",
14
+ "@types/node": "^24.0.3",
15
+ "@types/pg": "^8.15.4",
16
16
  "@types/uuid": "^10.0.0",
17
- "dotenv": "^16.4.7",
17
+ "dotenv": "^16.5.0",
18
18
  "prettier": "^3.5.3",
19
- "ts-essentials": "^10.0.4",
20
- "typescript": "^5.8.2",
21
- "typescript-eslint": "^8.28.0",
19
+ "ts-essentials": "^10.1.1",
20
+ "typescript": "^5.8.3",
21
+ "typescript-eslint": "^8.34.1",
22
22
  "vite-tsconfig-paths": "^5.1.4",
23
- "vitest": "^3.0.9",
24
- "@casekit/tsconfig": "0.0.0-20250331202540",
25
- "@casekit/prettier-config": "0.0.0-20250331202540"
23
+ "vitest": "^3.2.4",
24
+ "@casekit/tsconfig": "0.0.1",
25
+ "@casekit/orm2-schema": "0.0.1",
26
+ "@casekit/prettier-config": "0.0.1"
26
27
  },
27
28
  "exports": {
28
- ".": "./build/index.js"
29
+ ".": "./src/index.ts"
29
30
  },
30
31
  "files": [
31
- "/build"
32
+ "/src"
32
33
  ],
33
34
  "imports": {
34
- "#*": "./build/*"
35
+ "#*": "./src/*"
35
36
  },
36
37
  "keywords": [],
37
38
  "license": "ISC",
38
- "main": "index.js",
39
39
  "peerDependencies": {
40
40
  "pg": "^8.13.1",
41
- "zod": "^3.24.2"
41
+ "zod": "^4.0.17"
42
42
  },
43
43
  "prettier": "@casekit/prettier-config",
44
44
  "type": "module",
@@ -6,6 +6,12 @@ export type { NormalizedFieldDefinition } from "./types/NormalizedFieldDefinitio
6
6
  export type { NormalizedForeignKeyDefinition } from "./types/NormalizedForeignKeyDefinition.js";
7
7
  export type { NormalizedModelDefinition } from "./types/NormalizedModelDefinition.js";
8
8
  export type { NormalizedPrimaryKey } from "./types/NormalizedPrimaryKey.js";
9
- export type { NormalizedManyToManyRelationDefinition, NormalizedManyToOneRelationDefinition, NormalizedOneToManyRelationDefinition, NormalizedRelationDefinition, } from "./types/NormalizedRelationDefinition.js";
9
+ export type {
10
+ NormalizedManyToManyRelationDefinition,
11
+ NormalizedManyToOneRelationDefinition,
12
+ NormalizedOneToManyRelationDefinition,
13
+ NormalizedRelationDefinition,
14
+ } from "./types/NormalizedRelationDefinition.js";
10
15
  export type { NormalizedUniqueConstraintDefinition } from "./types/NormalizedUniqueConstraintDefinition.js";
16
+
11
17
  export { getField, getModel, getRelation } from "./util.js";
@@ -1,18 +1,24 @@
1
1
  import pg from "pg";
2
2
  import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
3
+
3
4
  import { defaultZodSchema } from "./defaultZodSchema.js";
5
+
4
6
  describe("defaultZodSchema", () => {
5
- let db;
7
+ let db: pg.Client;
8
+
6
9
  beforeAll(async () => {
7
10
  db = new pg.Client();
8
11
  await db.connect();
9
12
  });
13
+
10
14
  afterEach(async () => {
11
15
  await db.query("ROLLBACK");
12
16
  });
17
+
13
18
  afterAll(async () => {
14
19
  await db.end();
15
20
  });
21
+
16
22
  test.for([
17
23
  ["char", "a", "a"],
18
24
  ["character", "a", "a"],
@@ -135,18 +141,20 @@ describe("defaultZodSchema", () => {
135
141
  ],
136
142
  ],
137
143
  ],
138
- ])("%s columns", async ([datatype, value, expected = value]) => {
144
+ ] as const)("%s columns", async ([datatype, value, expected = value]) => {
139
145
  await db.query("BEGIN TRANSACTION");
140
146
  await db.query(`CREATE TABLE foo (value ${datatype})`);
147
+
141
148
  if (datatype.endsWith("serial")) {
142
149
  await db.query("INSERT INTO foo DEFAULT VALUES");
143
- }
144
- else {
150
+ } else {
145
151
  await db.query(`INSERT INTO foo (value) VALUES ($1::${datatype})`, [
146
152
  value,
147
153
  ]);
148
154
  }
149
- const result = await db.query(`SELECT * FROM foo`);
155
+
156
+ const result = await db.query<{ value: unknown }>(`SELECT * FROM foo`);
157
+
150
158
  const parsed = defaultZodSchema(datatype).parse(result.rows[0]?.value);
151
159
  expect(parsed).toEqual(expected);
152
160
  });
@@ -1,37 +1,26 @@
1
1
  import { z } from "zod";
2
+
2
3
  /**
3
4
  * WARNING!!! The schemas in this file must be kept in sync
4
5
  * with DefaultFieldType in packages/orm-schema/src/helper/DefaultFieldType.ts.
5
6
  * If you make a change here, make sure to update the
6
7
  * corresponding type.
7
8
  */
8
- export const defaultZodSchema = (type) => {
9
+ export const defaultZodSchema = (type: string): z.ZodType => {
9
10
  if (type.endsWith("[]"))
10
11
  return z.array(defaultZodSchema(type.slice(0, -2)));
11
- if (type.startsWith("bit "))
12
- return z.string();
13
- if (type.startsWith("bit("))
14
- return z.string();
15
- if (type.startsWith("character varying"))
16
- return z.string();
17
- if (type.startsWith("character"))
18
- return z.string();
19
- if (type.startsWith("numeric "))
20
- return z.string();
21
- if (type.startsWith("numeric("))
22
- return z.string();
23
- if (type.startsWith("timestamp "))
24
- return z.date();
25
- if (type.startsWith("timestamp("))
26
- return z.date();
27
- if (type.startsWith("time "))
28
- return z.string();
29
- if (type.startsWith("time("))
30
- return z.string();
31
- if (type.startsWith("varchar "))
32
- return z.string();
33
- if (type.startsWith("varchar("))
34
- return z.string();
12
+ if (type.startsWith("bit ")) return z.string();
13
+ if (type.startsWith("bit(")) return z.string();
14
+ if (type.startsWith("character varying")) return z.string();
15
+ if (type.startsWith("character")) return z.string();
16
+ if (type.startsWith("numeric ")) return z.string();
17
+ if (type.startsWith("numeric(")) return z.string();
18
+ if (type.startsWith("timestamp ")) return z.date();
19
+ if (type.startsWith("timestamp(")) return z.date();
20
+ if (type.startsWith("time ")) return z.string();
21
+ if (type.startsWith("time(")) return z.string();
22
+ if (type.startsWith("varchar ")) return z.string();
23
+ if (type.startsWith("varchar(")) return z.string();
35
24
  // if (type.startsWith("interval"))
36
25
  // return z.object({
37
26
  // years: z.number().optional(),
@@ -42,6 +31,7 @@ export const defaultZodSchema = (type) => {
42
31
  // seconds: z.number().optional(),
43
32
  // milliseconds: z.number().optional(),
44
33
  // });
34
+
45
35
  switch (type) {
46
36
  case "bigint":
47
37
  case "bigserial":
@@ -110,9 +100,9 @@ export const defaultZodSchema = (type) => {
110
100
  // return z.object({ x: z.number(), y: z.number() });
111
101
  case "json":
112
102
  case "jsonb":
113
- return z.record(z.any());
103
+ return z.record(z.string(), z.any());
114
104
  case "uuid":
115
- return z.string().uuid();
105
+ return z.uuid();
116
106
  case "boolean":
117
107
  return z.boolean();
118
108
  case "date":
@@ -120,8 +110,10 @@ export const defaultZodSchema = (type) => {
120
110
  case "timestamptz":
121
111
  return z.date();
122
112
  default:
123
- throw new Error("Unsupported type: " +
124
- type +
125
- " - please specify a zod schema in the field definition");
113
+ throw new Error(
114
+ "Unsupported type: " +
115
+ type +
116
+ " - please specify a zod schema in the field definition",
117
+ );
126
118
  }
127
119
  };
@@ -1,7 +1,9 @@
1
1
  import { snakeCase } from "es-toolkit";
2
2
  import { describe, expect, test } from "vitest";
3
+
3
4
  import { getColumns } from "./getColumns.js";
4
5
  import { populateModels } from "./populateModels.js";
6
+
5
7
  describe("getColumns", () => {
6
8
  test("returns column names for given fields", () => {
7
9
  const models = populateModels({
@@ -16,8 +18,12 @@ describe("getColumns", () => {
16
18
  },
17
19
  },
18
20
  });
19
- expect(getColumns(models["user"], ["id", "fullName", "emailAddress"])).toEqual(["id", "full_name", "email_address"]);
21
+
22
+ expect(
23
+ getColumns(models["user"]!, ["id", "fullName", "emailAddress"]),
24
+ ).toEqual(["id", "full_name", "email_address"]);
20
25
  });
26
+
21
27
  test("throws error for non-existent field", () => {
22
28
  const models = populateModels({
23
29
  naming: { column: snakeCase },
@@ -29,8 +35,12 @@ describe("getColumns", () => {
29
35
  },
30
36
  },
31
37
  });
32
- expect(() => getColumns(models["user"], ["id", "nonexistent"])).toThrow('Field "nonexistent" not found in model "user"');
38
+
39
+ expect(() =>
40
+ getColumns(models["user"]!, ["id", "nonexistent"]),
41
+ ).toThrow('Field "nonexistent" not found in model "user"');
33
42
  });
43
+
34
44
  test("returns empty array for empty fields array", () => {
35
45
  const models = populateModels({
36
46
  naming: { column: snakeCase },
@@ -42,8 +52,10 @@ describe("getColumns", () => {
42
52
  },
43
53
  },
44
54
  });
45
- expect(getColumns(models["user"], [])).toEqual([]);
55
+
56
+ expect(getColumns(models["user"]!, [])).toEqual([]);
46
57
  });
58
+
47
59
  test("handles custom column names", () => {
48
60
  const models = populateModels({
49
61
  models: {
@@ -55,7 +67,8 @@ describe("getColumns", () => {
55
67
  },
56
68
  },
57
69
  });
58
- expect(getColumns(models["user"], ["id", "name"])).toEqual([
70
+
71
+ expect(getColumns(models["user"]!, ["id", "name"])).toEqual([
59
72
  "id",
60
73
  "user_full_name",
61
74
  ]);
@@ -1,4 +1,9 @@
1
- export const getColumns = (model, fields) => {
1
+ import { PopulatedModelDefinition } from "#types/PopulatedModelDefinition.js";
2
+
3
+ export const getColumns = (
4
+ model: PopulatedModelDefinition,
5
+ fields: string[],
6
+ ): string[] => {
2
7
  return fields.map((f) => {
3
8
  if (!model.fields[f]) {
4
9
  throw new Error(`Field "${f}" not found in model "${model.name}"`);
@@ -1,8 +1,11 @@
1
1
  import { snakeCase } from "es-toolkit";
2
2
  import { describe, expect, test } from "vitest";
3
3
  import { z } from "zod";
4
+
4
5
  import { sql } from "@casekit/sql";
6
+
5
7
  import { normalizeConfig } from "./normalizeConfig.js";
8
+
6
9
  describe("normalizeConfig", () => {
7
10
  test("normalizes minimal config with defaults", () => {
8
11
  const config = {
@@ -14,20 +17,24 @@ describe("normalizeConfig", () => {
14
17
  },
15
18
  },
16
19
  },
17
- };
20
+ } as const;
21
+
18
22
  const result = normalizeConfig(config);
23
+
19
24
  expect(result.schema).toBe("public");
20
25
  expect(result.operators).toEqual({ where: {} });
21
26
  expect(result.extensions).toEqual([]);
22
27
  expect(result.connection).toBeNull();
23
- expect(result.pool).toBe(false);
28
+ expect(result.pool).toBe(true);
24
29
  expect(result.logger).toBe(console);
25
30
  expect(typeof result.naming.column).toBe("function");
26
31
  expect(typeof result.naming.table).toBe("function");
32
+
27
33
  // Test that default identity functions don't transform names
28
34
  expect(result.naming.column("userName")).toBe("userName");
29
35
  expect(result.naming.table("UserProfile")).toBe("UserProfile");
30
36
  });
37
+
31
38
  test("preserves provided config values", () => {
32
39
  const customLogger = {
33
40
  debug: () => {
@@ -43,7 +50,9 @@ describe("normalizeConfig", () => {
43
50
  /* empty */
44
51
  },
45
52
  };
53
+
46
54
  const $contains = Symbol("contains");
55
+
47
56
  const config = {
48
57
  schema: "custom",
49
58
  models: {
@@ -55,7 +64,7 @@ describe("normalizeConfig", () => {
55
64
  },
56
65
  operators: {
57
66
  where: {
58
- [$contains]: () => sql ``,
67
+ [$contains]: () => sql``,
59
68
  },
60
69
  },
61
70
  extensions: ["uuid-ossp"],
@@ -69,8 +78,10 @@ describe("normalizeConfig", () => {
69
78
  column: snakeCase,
70
79
  table: snakeCase,
71
80
  },
72
- };
81
+ } as const;
82
+
73
83
  const result = normalizeConfig(config);
84
+
74
85
  expect(result.schema).toBe("custom");
75
86
  expect(result.operators).toBe(config.operators);
76
87
  expect(result.extensions).toEqual(["uuid-ossp"]);
@@ -80,6 +91,7 @@ describe("normalizeConfig", () => {
80
91
  expect(result.naming.column).toBe(snakeCase);
81
92
  expect(result.naming.table).toBe(snakeCase);
82
93
  });
94
+
83
95
  test("normalizes models with relationships", () => {
84
96
  const config = {
85
97
  models: {
@@ -90,7 +102,7 @@ describe("normalizeConfig", () => {
90
102
  },
91
103
  relations: {
92
104
  posts: {
93
- type: "1:N",
105
+ type: "1:N" as const,
94
106
  model: "post",
95
107
  fromField: "id",
96
108
  toField: "authorId",
@@ -104,9 +116,11 @@ describe("normalizeConfig", () => {
104
116
  },
105
117
  },
106
118
  },
107
- };
119
+ } as const;
120
+
108
121
  const result = normalizeConfig(config);
109
- expect(result.models["user"].relations["posts"]).toEqual({
122
+
123
+ expect(result.models["user"]!.relations["posts"]!).toEqual({
110
124
  name: "posts",
111
125
  type: "1:N",
112
126
  model: "post",
@@ -121,6 +135,7 @@ describe("normalizeConfig", () => {
121
135
  },
122
136
  });
123
137
  });
138
+
124
139
  test("applies naming functions to all models", () => {
125
140
  const config = {
126
141
  naming: {
@@ -143,20 +158,37 @@ describe("normalizeConfig", () => {
143
158
  },
144
159
  },
145
160
  },
146
- };
161
+ } as const;
162
+
147
163
  const result = normalizeConfig(config);
164
+
148
165
  // Check table names
149
- expect(result.models["userProfile"].table).toBe("user_profile");
150
- expect(result.models["orderItem"].table).toBe("order_item");
166
+ expect(result.models["userProfile"]!.table).toBe("user_profile");
167
+ expect(result.models["orderItem"]!.table).toBe("order_item");
168
+
151
169
  // Check column names in first model
152
- expect(result.models["userProfile"].fields["userId"].column).toBe("user_id");
153
- expect(result.models["userProfile"].fields["firstName"].column).toBe("first_name");
154
- expect(result.models["userProfile"].fields["lastName"].column).toBe("last_name");
170
+ expect(result.models["userProfile"]!.fields["userId"]!.column).toBe(
171
+ "user_id",
172
+ );
173
+ expect(result.models["userProfile"]!.fields["firstName"]!.column).toBe(
174
+ "first_name",
175
+ );
176
+ expect(result.models["userProfile"]!.fields["lastName"]!.column).toBe(
177
+ "last_name",
178
+ );
179
+
155
180
  // Check column names in second model
156
- expect(result.models["orderItem"].fields["orderId"].column).toBe("order_id");
157
- expect(result.models["orderItem"].fields["productId"].column).toBe("product_id");
158
- expect(result.models["orderItem"].fields["unitPrice"].column).toBe("unit_price");
181
+ expect(result.models["orderItem"]!.fields["orderId"]!.column).toBe(
182
+ "order_id",
183
+ );
184
+ expect(result.models["orderItem"]!.fields["productId"]!.column).toBe(
185
+ "product_id",
186
+ );
187
+ expect(result.models["orderItem"]!.fields["unitPrice"]!.column).toBe(
188
+ "unit_price",
189
+ );
159
190
  });
191
+
160
192
  test("normalizes custom Zod schemas in models", () => {
161
193
  const config = {
162
194
  models: {
@@ -165,7 +197,7 @@ describe("normalizeConfig", () => {
165
197
  id: { type: "serial", primaryKey: true },
166
198
  email: {
167
199
  type: "text",
168
- zodSchema: z.string().email(),
200
+ zodSchema: z.email(),
169
201
  },
170
202
  age: {
171
203
  type: "integer",
@@ -174,12 +206,19 @@ describe("normalizeConfig", () => {
174
206
  },
175
207
  },
176
208
  },
177
- };
209
+ } as const;
210
+
178
211
  const result = normalizeConfig(config);
212
+
179
213
  // Verify that Zod schemas are preserved
180
- expect(result.models["user"].fields["email"].zodSchema).toBeInstanceOf(z.ZodString);
181
- expect(result.models["user"].fields["age"].zodSchema).toBeInstanceOf(z.ZodNumber);
214
+ expect(
215
+ result.models["user"]!.fields["email"]!.zodSchema,
216
+ ).toBeInstanceOf(z.ZodEmail);
217
+ expect(result.models["user"]!.fields["age"]!.zodSchema).toBeInstanceOf(
218
+ z.ZodNumber,
219
+ );
182
220
  });
221
+
183
222
  test("handles partial naming configuration", () => {
184
223
  const config = {
185
224
  naming: {
@@ -193,13 +232,18 @@ describe("normalizeConfig", () => {
193
232
  },
194
233
  },
195
234
  },
196
- };
235
+ } as const;
236
+
197
237
  const result = normalizeConfig(config);
238
+
198
239
  // Column should be transformed
199
- expect(result.models["userProfile"].fields["userId"].column).toBe("user_id");
240
+ expect(result.models["userProfile"]!.fields["userId"]!.column).toBe(
241
+ "user_id",
242
+ );
200
243
  // Table should remain unchanged due to default identity function
201
- expect(result.models["userProfile"].table).toBe("userProfile");
244
+ expect(result.models["userProfile"]!.table).toBe("userProfile");
202
245
  });
246
+
203
247
  test("handles empty extensions array", () => {
204
248
  const config = {
205
249
  models: {
@@ -210,8 +254,10 @@ describe("normalizeConfig", () => {
210
254
  },
211
255
  },
212
256
  extensions: [],
213
- };
257
+ } as const;
258
+
214
259
  const result = normalizeConfig(config);
260
+
215
261
  expect(result.extensions).toEqual([]);
216
262
  });
217
263
  });
@@ -1,7 +1,12 @@
1
1
  import { identity, mapValues } from "es-toolkit";
2
+
3
+ import { Config } from "@casekit/orm2-schema";
4
+
5
+ import { NormalizedConfig } from "#types/NormalizedConfig.js";
2
6
  import { normalizeModel } from "./normalizeModel.js";
3
7
  import { populateModels } from "./populateModels.js";
4
- export const normalizeConfig = (config) => {
8
+
9
+ export const normalizeConfig = (config: Config): NormalizedConfig => {
5
10
  const models = populateModels(config);
6
11
  return {
7
12
  ...config,
@@ -10,7 +15,7 @@ export const normalizeConfig = (config) => {
10
15
  operators: config.operators ?? { where: {} },
11
16
  extensions: config.extensions ?? [],
12
17
  connection: config.connection ?? null,
13
- pool: config.pool ?? false,
18
+ pool: config.pool ?? true,
14
19
  logger: config.logger ?? console,
15
20
  naming: {
16
21
  column: config.naming?.column ?? identity,
@@ -1,8 +1,10 @@
1
1
  import { snakeCase } from "es-toolkit";
2
2
  import { describe, expect, test } from "vitest";
3
- import { ZodSchema } from "zod";
3
+ import { ZodType } from "zod";
4
+
4
5
  import { normalizeField } from "./normalizeField.js";
5
6
  import { populateModels } from "./populateModels.js";
7
+
6
8
  describe("normalizeField", () => {
7
9
  test("strips out references, unique, and primary key properties", () => {
8
10
  const models = populateModels({
@@ -28,29 +30,32 @@ describe("normalizeField", () => {
28
30
  },
29
31
  },
30
32
  });
31
- expect(normalizeField(models["post"].fields["id"])).toEqual({
33
+
34
+ expect(normalizeField(models["post"]!.fields["id"]!)).toEqual({
32
35
  name: "id",
33
36
  column: "id",
34
37
  type: "serial",
35
- zodSchema: expect.any(ZodSchema),
38
+ zodSchema: expect.any(ZodType),
36
39
  nullable: false,
37
40
  default: null,
38
41
  provided: false,
39
42
  });
40
- expect(normalizeField(models["post"].fields["slug"])).toEqual({
43
+
44
+ expect(normalizeField(models["post"]!.fields["slug"]!)).toEqual({
41
45
  name: "slug",
42
46
  column: "slug",
43
47
  type: "text",
44
- zodSchema: expect.any(ZodSchema),
48
+ zodSchema: expect.any(ZodType),
45
49
  nullable: false,
46
50
  default: null,
47
51
  provided: false,
48
52
  });
49
- expect(normalizeField(models["post"].fields["authorId"])).toEqual({
53
+
54
+ expect(normalizeField(models["post"]!.fields["authorId"]!)).toEqual({
50
55
  name: "authorId",
51
56
  column: "author_id",
52
57
  type: "integer",
53
- zodSchema: expect.any(ZodSchema),
58
+ zodSchema: expect.any(ZodType),
54
59
  nullable: false,
55
60
  default: null,
56
61
  provided: false,
@@ -0,0 +1,16 @@
1
+ import { NormalizedFieldDefinition } from "#types/NormalizedFieldDefinition.js";
2
+ import { PopulatedFieldDefinition } from "#types/PopulatedFieldDefinition.js";
3
+
4
+ export const normalizeField = (
5
+ field: PopulatedFieldDefinition,
6
+ ): NormalizedFieldDefinition => {
7
+ return {
8
+ name: field.name,
9
+ column: field.column,
10
+ type: field.type,
11
+ zodSchema: field.zodSchema,
12
+ nullable: field.nullable,
13
+ default: field.default,
14
+ provided: field.provided,
15
+ };
16
+ };