@casekit/orm2-schema 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.
- package/package.json +15 -16
- package/{build/Config.d.ts → src/Config.ts} +9 -2
- package/{build/definition/FieldDefinition.d.ts → src/definition/FieldDefinition.ts} +19 -6
- package/{build/definition/ModelDefinition.d.ts → src/definition/ModelDefinition.ts} +7 -0
- package/{build/definition/ModelDefinitions.d.ts → src/definition/ModelDefinitions.ts} +1 -0
- package/{build/definition/OperatorDefinitions.d.ts → src/definition/OperatorDefinitions.ts} +1 -0
- package/{build/definition/PostgresDataTypes.d.ts → src/definition/PostgresDataTypes.ts} +3 -0
- package/{build/definition/RelationDefinition.d.ts → src/definition/RelationDefinition.ts} +7 -1
- package/{build/definition/RelationDefinitions.d.ts → src/definition/RelationDefinitions.ts} +1 -0
- package/{build/definition/UniqueConstraintDefinition.d.ts → src/definition/UniqueConstraintDefinition.ts} +1 -0
- package/src/definition/WhereOperator.ts +6 -0
- package/src/helper/DefaultFieldType.test-d.ts +60 -0
- package/src/helper/DefaultFieldType.ts +99 -0
- package/{build/helper/FieldName.test-d.js → src/helper/FieldName.test-d.ts} +9 -2
- package/{build/helper/FieldName.d.ts → src/helper/FieldName.ts} +1 -0
- package/src/helper/FieldType.test-d.ts +81 -0
- package/src/helper/FieldType.ts +16 -0
- package/{build/helper/FieldWithDefault.test-d.js → src/helper/FieldWithDefault.test-d.ts} +17 -6
- package/{build/helper/FieldWithDefault.d.ts → src/helper/FieldWithDefault.ts} +6 -1
- package/{build/helper/ModelName.test-d.js → src/helper/ModelName.test-d.ts} +9 -2
- package/{build/helper/ModelName.d.ts → src/helper/ModelName.ts} +5 -1
- package/{build/helper/ModelType.test-d.js → src/helper/ModelType.test-d.ts} +18 -3
- package/{build/helper/ModelType.d.ts → src/helper/ModelType.ts} +2 -0
- package/{build/helper/NullableField.test-d.js → src/helper/NullableField.test-d.ts} +17 -6
- package/{build/helper/NullableField.d.ts → src/helper/NullableField.ts} +4 -1
- package/{build/helper/OptionalField.test-d.js → src/helper/OptionalField.test-d.ts} +21 -6
- package/{build/helper/OptionalField.d.ts → src/helper/OptionalField.ts} +5 -1
- package/{build/helper/ProvidedField.test-d.js → src/helper/ProvidedField.test-d.ts} +17 -6
- package/{build/helper/ProvidedField.d.ts → src/helper/ProvidedField.ts} +4 -1
- package/{build/helper/RelationModel.test-d.js → src/helper/RelationModel.test-d.ts} +27 -6
- package/src/helper/RelationModel.ts +9 -0
- package/{build/helper/RelationName.test-d.js → src/helper/RelationName.test-d.ts} +14 -4
- package/src/helper/RelationName.ts +4 -0
- package/{build/helper/RequiredField.test-d.js → src/helper/RequiredField.test-d.ts} +19 -6
- package/{build/helper/RequiredField.d.ts → src/helper/RequiredField.ts} +8 -1
- package/{build/helper/SerialField.test-d.js → src/helper/SerialField.test-d.ts} +23 -8
- package/{build/helper/SerialField.d.ts → src/helper/SerialField.ts} +7 -1
- package/{build/index.d.ts → src/index.ts} +8 -1
- package/build/Config.js +0 -1
- package/build/Logger.js +0 -1
- package/build/definition/FieldDefinition.js +0 -1
- package/build/definition/ForeignKeyDefinition.js +0 -1
- package/build/definition/ModelDefinition.js +0 -1
- package/build/definition/ModelDefinitions.js +0 -1
- package/build/definition/OperatorDefinitions.js +0 -1
- package/build/definition/PostgresDataTypes.js +0 -1
- package/build/definition/RelationDefinition.js +0 -1
- package/build/definition/RelationDefinitions.js +0 -1
- package/build/definition/UniqueConstraintDefinition.js +0 -1
- package/build/definition/WhereOperator.d.ts +0 -5
- package/build/definition/WhereOperator.js +0 -1
- package/build/helper/DefaultFieldType.d.ts +0 -7
- package/build/helper/DefaultFieldType.js +0 -1
- package/build/helper/DefaultFieldType.test-d.d.ts +0 -1
- package/build/helper/DefaultFieldType.test-d.js +0 -57
- package/build/helper/FieldName.js +0 -1
- package/build/helper/FieldName.test-d.d.ts +0 -1
- package/build/helper/FieldType.d.ts +0 -5
- package/build/helper/FieldType.js +0 -1
- package/build/helper/FieldType.test-d.d.ts +0 -1
- package/build/helper/FieldType.test-d.js +0 -45
- package/build/helper/FieldWithDefault.js +0 -1
- package/build/helper/FieldWithDefault.test-d.d.ts +0 -1
- package/build/helper/ModelName.js +0 -1
- package/build/helper/ModelName.test-d.d.ts +0 -1
- package/build/helper/ModelType.js +0 -1
- package/build/helper/ModelType.test-d.d.ts +0 -1
- package/build/helper/NullableField.js +0 -1
- package/build/helper/NullableField.test-d.d.ts +0 -1
- package/build/helper/OptionalField.js +0 -1
- package/build/helper/OptionalField.test-d.d.ts +0 -1
- package/build/helper/ProvidedField.js +0 -1
- package/build/helper/ProvidedField.test-d.d.ts +0 -1
- package/build/helper/RelationModel.d.ts +0 -4
- package/build/helper/RelationModel.js +0 -1
- package/build/helper/RelationModel.test-d.d.ts +0 -1
- package/build/helper/RelationName.d.ts +0 -2
- package/build/helper/RelationName.js +0 -1
- package/build/helper/RelationName.test-d.d.ts +0 -1
- package/build/helper/RequiredField.js +0 -1
- package/build/helper/RequiredField.test-d.d.ts +0 -1
- package/build/helper/SerialField.js +0 -1
- package/build/helper/SerialField.test-d.d.ts +0 -1
- package/build/index.js +0 -1
- /package/{build/Logger.d.ts → src/Logger.ts} +0 -0
- /package/{build/definition/ForeignKeyDefinition.d.ts → src/definition/ForeignKeyDefinition.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,41 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@casekit/orm2-schema",
|
|
3
3
|
"description": "",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.1",
|
|
5
5
|
"author": "",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@casekit/sql": "0.0.
|
|
8
|
-
"@casekit/toolbox": "0.0.
|
|
7
|
+
"@casekit/sql": "0.0.1",
|
|
8
|
+
"@casekit/toolbox": "0.0.1"
|
|
9
9
|
},
|
|
10
10
|
"devDependencies": {
|
|
11
11
|
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
|
|
12
|
-
"@types/node": "^
|
|
13
|
-
"@types/pg": "^8.
|
|
12
|
+
"@types/node": "^24.0.3",
|
|
13
|
+
"@types/pg": "^8.15.4",
|
|
14
14
|
"@types/uuid": "^10.0.0",
|
|
15
15
|
"prettier": "^3.5.3",
|
|
16
|
-
"ts-essentials": "^10.
|
|
17
|
-
"typescript": "^5.8.
|
|
18
|
-
"typescript-eslint": "^8.
|
|
16
|
+
"ts-essentials": "^10.1.1",
|
|
17
|
+
"typescript": "^5.8.3",
|
|
18
|
+
"typescript-eslint": "^8.34.1",
|
|
19
19
|
"vite-tsconfig-paths": "^5.1.4",
|
|
20
|
-
"vitest": "^3.
|
|
21
|
-
"@casekit/tsconfig": "0.0.
|
|
22
|
-
"@casekit/prettier-config": "0.0.
|
|
20
|
+
"vitest": "^3.2.4",
|
|
21
|
+
"@casekit/tsconfig": "0.0.1",
|
|
22
|
+
"@casekit/prettier-config": "0.0.1"
|
|
23
23
|
},
|
|
24
24
|
"exports": {
|
|
25
|
-
".": "./
|
|
25
|
+
".": "./src/index.ts"
|
|
26
26
|
},
|
|
27
27
|
"files": [
|
|
28
|
-
"/
|
|
28
|
+
"/src"
|
|
29
29
|
],
|
|
30
30
|
"imports": {
|
|
31
|
-
"#*": "./
|
|
31
|
+
"#*": "./src/*"
|
|
32
32
|
},
|
|
33
33
|
"keywords": [],
|
|
34
34
|
"license": "ISC",
|
|
35
|
-
"main": "index.js",
|
|
36
35
|
"peerDependencies": {
|
|
37
36
|
"pg": "^8.13.1",
|
|
38
|
-
"zod": "^
|
|
37
|
+
"zod": "^4.0.17"
|
|
39
38
|
},
|
|
40
39
|
"prettier": "@casekit/prettier-config",
|
|
41
40
|
"type": "module",
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import pg from "pg";
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import { Logger } from "./Logger.js";
|
|
4
|
+
import { ModelDefinitions } from "./definition/ModelDefinitions.js";
|
|
5
|
+
import { OperatorDefinitions } from "./definition/OperatorDefinitions.js";
|
|
6
|
+
|
|
4
7
|
export interface Config {
|
|
5
8
|
readonly schema?: string;
|
|
6
9
|
readonly models: ModelDefinitions;
|
|
7
10
|
readonly operators?: OperatorDefinitions;
|
|
8
11
|
readonly extensions?: readonly string[];
|
|
9
|
-
readonly connection?:
|
|
12
|
+
readonly connection?:
|
|
13
|
+
| pg.ConnectionConfig
|
|
14
|
+
| pg.PoolConfig
|
|
15
|
+
| pg.PoolOptions
|
|
16
|
+
| null;
|
|
10
17
|
readonly pool?: boolean;
|
|
11
18
|
readonly logger?: Logger;
|
|
12
19
|
readonly naming?: {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
|
|
2
3
|
import { SQLStatement } from "@casekit/sql";
|
|
4
|
+
|
|
3
5
|
import { PostgresDataTypes } from "./PostgresDataTypes.js";
|
|
6
|
+
|
|
4
7
|
export interface FieldDefinition {
|
|
5
8
|
/**
|
|
6
9
|
* The name of the column in the database. If not specified,
|
|
@@ -9,10 +12,14 @@ export interface FieldDefinition {
|
|
|
9
12
|
* in the config applied.
|
|
10
13
|
*/
|
|
11
14
|
column?: string;
|
|
15
|
+
|
|
12
16
|
/**
|
|
13
17
|
* The postgresql datatype of the column.
|
|
14
18
|
*/
|
|
15
|
-
type:
|
|
19
|
+
type:
|
|
20
|
+
| `${PostgresDataTypes[keyof PostgresDataTypes]}${string}` // the string at the end allows for arrays
|
|
21
|
+
| `${Uppercase<PostgresDataTypes[keyof PostgresDataTypes]>}${string}`;
|
|
22
|
+
|
|
16
23
|
/**
|
|
17
24
|
* A Zod schema used to infer the type of the column and to
|
|
18
25
|
* validate/transform data coming from the database.
|
|
@@ -21,11 +28,13 @@ export interface FieldDefinition {
|
|
|
21
28
|
* allows to you configure more sophisticated parsing, validation,
|
|
22
29
|
* and transformations.
|
|
23
30
|
*/
|
|
24
|
-
zodSchema?: z.ZodType
|
|
31
|
+
zodSchema?: z.ZodType;
|
|
32
|
+
|
|
25
33
|
/**
|
|
26
34
|
* Are null values allowed in this column?
|
|
27
35
|
*/
|
|
28
36
|
nullable?: boolean;
|
|
37
|
+
|
|
29
38
|
/**
|
|
30
39
|
* The default value for this column, if it has one. This can be either a value such
|
|
31
40
|
* as a number or string, or if you want to specify a SQL function for the default,
|
|
@@ -42,19 +51,21 @@ export interface FieldDefinition {
|
|
|
42
51
|
* default: sql`uuid_generate_v4()`,
|
|
43
52
|
*/
|
|
44
53
|
default?: unknown;
|
|
54
|
+
|
|
45
55
|
/**
|
|
46
56
|
* Is this column unique? If so, you can specify a where clause to
|
|
47
57
|
* specify a partial unique index, and whether nulls should be considered
|
|
48
58
|
* distinct.
|
|
49
59
|
*/
|
|
50
|
-
unique?:
|
|
51
|
-
|
|
52
|
-
nullsNotDistinct?: boolean;
|
|
53
|
-
|
|
60
|
+
unique?:
|
|
61
|
+
| boolean
|
|
62
|
+
| { where?: SQLStatement | null; nullsNotDistinct?: boolean };
|
|
63
|
+
|
|
54
64
|
/**
|
|
55
65
|
* Is this column a single-column primary key?
|
|
56
66
|
*/
|
|
57
67
|
primaryKey?: boolean;
|
|
68
|
+
|
|
58
69
|
/**
|
|
59
70
|
* Is this column a foreign key? If so, you can specify the table and column it references,
|
|
60
71
|
* and what should happen on update or delete.
|
|
@@ -66,9 +77,11 @@ export interface FieldDefinition {
|
|
|
66
77
|
onUpdate?: "RESTRICT" | "CASCADE" | "SET NULL" | "SET DEFAULT" | null;
|
|
67
78
|
onDelete?: "RESTRICT" | "CASCADE" | "SET NULL" | "SET DEFAULT" | null;
|
|
68
79
|
} | null;
|
|
80
|
+
|
|
69
81
|
/**
|
|
70
82
|
* Is this column provided by middleware? If so, it will not be included in
|
|
71
83
|
* the set of required columns for inserts and updates.
|
|
72
84
|
*/
|
|
85
|
+
|
|
73
86
|
provided?: boolean;
|
|
74
87
|
}
|
|
@@ -2,6 +2,7 @@ import { FieldDefinition } from "./FieldDefinition.js";
|
|
|
2
2
|
import { ForeignKeyDefinition } from "./ForeignKeyDefinition.js";
|
|
3
3
|
import { RelationDefinitions } from "./RelationDefinitions.js";
|
|
4
4
|
import { UniqueConstraintDefinition } from "./UniqueConstraintDefinition.js";
|
|
5
|
+
|
|
5
6
|
/**
|
|
6
7
|
* Configuration object for a database model.
|
|
7
8
|
*/
|
|
@@ -12,32 +13,38 @@ export interface ModelDefinition {
|
|
|
12
13
|
* config applied.
|
|
13
14
|
*/
|
|
14
15
|
table?: string;
|
|
16
|
+
|
|
15
17
|
/**
|
|
16
18
|
* The schema in which the model sits. If not specified, will use the
|
|
17
19
|
* schema specified in the global config; if no schema is specified in
|
|
18
20
|
* the global config, will be set to `public`.
|
|
19
21
|
*/
|
|
20
22
|
schema?: string;
|
|
23
|
+
|
|
21
24
|
/**
|
|
22
25
|
* The model's fields - a map of field name to field
|
|
23
26
|
* definitions. The keys of this map will be used in generated functions
|
|
24
27
|
* and object fields, so must be valid Javascript identifiers.
|
|
25
28
|
*/
|
|
26
29
|
fields: Record<string, FieldDefinition>;
|
|
30
|
+
|
|
27
31
|
/**
|
|
28
32
|
* If the table's primary key contains multiple columns, specify them here.
|
|
29
33
|
* If the primary key is on a single column, you can specify it here or in the column definition.
|
|
30
34
|
*/
|
|
31
35
|
primaryKey?: string[] | null;
|
|
36
|
+
|
|
32
37
|
/**
|
|
33
38
|
* If the table has unique constraints that span multiple columns, you must specify them here.
|
|
34
39
|
* If the unique constraint is on a single column, you can specify it here or in the column definition.
|
|
35
40
|
*/
|
|
36
41
|
uniqueConstraints?: UniqueConstraintDefinition[];
|
|
42
|
+
|
|
37
43
|
/**
|
|
38
44
|
* If the table has foreign keys, you must specify them here. If the foreign key is on a single column,
|
|
39
45
|
* you can specify it here or in the column definition.
|
|
40
46
|
*/
|
|
41
47
|
foreignKeys?: ForeignKeyDefinition[];
|
|
48
|
+
|
|
42
49
|
relations?: RelationDefinitions;
|
|
43
50
|
}
|
|
@@ -14,6 +14,7 @@ export interface PostgresDataTypes {
|
|
|
14
14
|
character_varying: `character varying`;
|
|
15
15
|
character_varying_n: `character varying (${number})`;
|
|
16
16
|
cidr: "cidr";
|
|
17
|
+
// circle: "circle";
|
|
17
18
|
date: "date";
|
|
18
19
|
daterange: "daterange";
|
|
19
20
|
double_precision: "double precision";
|
|
@@ -22,6 +23,7 @@ export interface PostgresDataTypes {
|
|
|
22
23
|
int4range: "int4range";
|
|
23
24
|
int8range: "int8range";
|
|
24
25
|
integer: "integer";
|
|
26
|
+
// interval: `interval`;
|
|
25
27
|
json: "json";
|
|
26
28
|
jsonb: "jsonb";
|
|
27
29
|
line: "line";
|
|
@@ -35,6 +37,7 @@ export interface PostgresDataTypes {
|
|
|
35
37
|
oid: "oid";
|
|
36
38
|
path: "path";
|
|
37
39
|
pg_lsn: "pg_lsn";
|
|
40
|
+
// point: "point";
|
|
38
41
|
polygon: "polygon";
|
|
39
42
|
real: "real";
|
|
40
43
|
regclass: "regclass";
|
|
@@ -4,6 +4,7 @@ export interface OneToManyRelationDefinition {
|
|
|
4
4
|
fromField: string | string[];
|
|
5
5
|
toField: string | string[];
|
|
6
6
|
}
|
|
7
|
+
|
|
7
8
|
export interface ManyToOneRelationDefinition {
|
|
8
9
|
type: "N:1";
|
|
9
10
|
model: string;
|
|
@@ -11,6 +12,7 @@ export interface ManyToOneRelationDefinition {
|
|
|
11
12
|
toField: string | string[];
|
|
12
13
|
optional?: boolean | null;
|
|
13
14
|
}
|
|
15
|
+
|
|
14
16
|
export interface ManyToManyRelationDefinition {
|
|
15
17
|
type: "N:N";
|
|
16
18
|
model: string;
|
|
@@ -20,4 +22,8 @@ export interface ManyToManyRelationDefinition {
|
|
|
20
22
|
toRelation: string;
|
|
21
23
|
};
|
|
22
24
|
}
|
|
23
|
-
|
|
25
|
+
|
|
26
|
+
export type RelationDefinition =
|
|
27
|
+
| OneToManyRelationDefinition
|
|
28
|
+
| ManyToOneRelationDefinition
|
|
29
|
+
| ManyToManyRelationDefinition;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { expectTypeOf, test } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { DefaultFieldType } from "./DefaultFieldType.js";
|
|
4
|
+
|
|
5
|
+
test("DefaultFieldType", () => {
|
|
6
|
+
expectTypeOf<DefaultFieldType<"bigint">>().toBeBigInt();
|
|
7
|
+
expectTypeOf<DefaultFieldType<"integer">>().toBeNumber();
|
|
8
|
+
expectTypeOf<DefaultFieldType<"double precision">>().toBeNumber();
|
|
9
|
+
expectTypeOf<DefaultFieldType<"oid">>().toBeNumber();
|
|
10
|
+
expectTypeOf<DefaultFieldType<"real">>().toBeNumber();
|
|
11
|
+
expectTypeOf<DefaultFieldType<"smallint">>().toBeNumber();
|
|
12
|
+
expectTypeOf<DefaultFieldType<"smallserial">>().toBeNumber();
|
|
13
|
+
expectTypeOf<DefaultFieldType<"serial">>().toBeNumber();
|
|
14
|
+
expectTypeOf<DefaultFieldType<"text">>().toBeString();
|
|
15
|
+
expectTypeOf<DefaultFieldType<"uuid">>().toBeString();
|
|
16
|
+
expectTypeOf<DefaultFieldType<"bytea">>().toEqualTypeOf<Buffer>();
|
|
17
|
+
// expectTypeOf<DefaultFieldType<"circle">>().toEqualTypeOf<{
|
|
18
|
+
// x: number;
|
|
19
|
+
// y: number;
|
|
20
|
+
// radius: number;
|
|
21
|
+
// }>();
|
|
22
|
+
// expectTypeOf<DefaultFieldType<"point">>().toEqualTypeOf<{
|
|
23
|
+
// x: number;
|
|
24
|
+
// y: number;
|
|
25
|
+
// }>();
|
|
26
|
+
expectTypeOf<DefaultFieldType<"json">>().toBeUnknown();
|
|
27
|
+
expectTypeOf<DefaultFieldType<"jsonb">>().toBeUnknown();
|
|
28
|
+
expectTypeOf<DefaultFieldType<"boolean">>().toBeBoolean();
|
|
29
|
+
expectTypeOf<DefaultFieldType<"date">>().toEqualTypeOf<Date>();
|
|
30
|
+
expectTypeOf<DefaultFieldType<"timestamp">>().toEqualTypeOf<Date>();
|
|
31
|
+
// expectTypeOf<DefaultFieldType<"interval">>().toEqualTypeOf<{
|
|
32
|
+
// years?: number;
|
|
33
|
+
// months?: number;
|
|
34
|
+
// days?: number;
|
|
35
|
+
// hours?: number;
|
|
36
|
+
// minutes?: number;
|
|
37
|
+
// seconds?: number;
|
|
38
|
+
// milliseconds?: number;
|
|
39
|
+
// }>();
|
|
40
|
+
expectTypeOf<DefaultFieldType<"time">>().toEqualTypeOf<string>();
|
|
41
|
+
expectTypeOf<DefaultFieldType<"timetz">>().toEqualTypeOf<string>();
|
|
42
|
+
expectTypeOf<DefaultFieldType<"timestamptz">>().toEqualTypeOf<Date>();
|
|
43
|
+
expectTypeOf<DefaultFieldType<"varchar">>().toBeString();
|
|
44
|
+
expectTypeOf<DefaultFieldType<"char">>().toBeString();
|
|
45
|
+
expectTypeOf<DefaultFieldType<"numeric">>().toBeString();
|
|
46
|
+
expectTypeOf<DefaultFieldType<"decimal">>().toBeString();
|
|
47
|
+
expectTypeOf<DefaultFieldType<"money">>().toBeString();
|
|
48
|
+
expectTypeOf<DefaultFieldType<"bit">>().toBeString();
|
|
49
|
+
expectTypeOf<DefaultFieldType<"box">>().toBeString();
|
|
50
|
+
expectTypeOf<DefaultFieldType<"line">>().toBeString();
|
|
51
|
+
expectTypeOf<DefaultFieldType<"lseg">>().toBeString();
|
|
52
|
+
expectTypeOf<DefaultFieldType<"path">>().toBeString();
|
|
53
|
+
expectTypeOf<DefaultFieldType<"polygon">>().toBeString();
|
|
54
|
+
expectTypeOf<DefaultFieldType<"cidr">>().toBeString();
|
|
55
|
+
expectTypeOf<DefaultFieldType<"inet">>().toBeString();
|
|
56
|
+
expectTypeOf<DefaultFieldType<"macaddr">>().toBeString();
|
|
57
|
+
expectTypeOf<DefaultFieldType<"tsquery">>().toBeString();
|
|
58
|
+
expectTypeOf<DefaultFieldType<"tsvector">>().toBeString();
|
|
59
|
+
expectTypeOf<DefaultFieldType<"xml">>().toBeString();
|
|
60
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WARNING!!! The types in this file must be kept in sync
|
|
3
|
+
* with the zod schemas in packages/orm/src/config/defaultZodSchema.ts.
|
|
4
|
+
* If you make a change here, make sure to update the
|
|
5
|
+
* corresponding zod schema.
|
|
6
|
+
*/
|
|
7
|
+
export type DefaultFieldType<DataType extends string> =
|
|
8
|
+
DataType extends `${infer T extends string}[]`
|
|
9
|
+
? DefaultFieldType<T>[]
|
|
10
|
+
: Uppercase<DataType> extends "BIGINT" | "BIGSERIAL"
|
|
11
|
+
? bigint
|
|
12
|
+
: Uppercase<DataType> extends
|
|
13
|
+
| "DOUBLE PRECISION"
|
|
14
|
+
| "INTEGER"
|
|
15
|
+
| "OID"
|
|
16
|
+
| "REAL"
|
|
17
|
+
| "SMALLINT"
|
|
18
|
+
| "SMALLSERIAL"
|
|
19
|
+
| "SERIAL"
|
|
20
|
+
? number
|
|
21
|
+
: Uppercase<DataType> extends
|
|
22
|
+
| "BPCHAR"
|
|
23
|
+
| "BIT"
|
|
24
|
+
| "BOX"
|
|
25
|
+
| "CIDR"
|
|
26
|
+
| "CHAR"
|
|
27
|
+
| "DATERANGE"
|
|
28
|
+
| "DECIMAL"
|
|
29
|
+
| "INET"
|
|
30
|
+
| "INT4RANGE"
|
|
31
|
+
| "INT8RANGE"
|
|
32
|
+
| "INT2VECTOR"
|
|
33
|
+
| "PG_LSN"
|
|
34
|
+
| "REGCLASS"
|
|
35
|
+
| "REGCONFIG"
|
|
36
|
+
| "REGDICTIONARY"
|
|
37
|
+
| "REGNAMESPACE"
|
|
38
|
+
| "REGOPER"
|
|
39
|
+
| "REGOPERATOR"
|
|
40
|
+
| "REGPROC"
|
|
41
|
+
| "REGPROCEDURE"
|
|
42
|
+
| "REGROLE"
|
|
43
|
+
| "REGTYPE"
|
|
44
|
+
| "TID"
|
|
45
|
+
| "XID"
|
|
46
|
+
| "NUMRANGE"
|
|
47
|
+
| "TSRANGE"
|
|
48
|
+
| "TSTZRANGE"
|
|
49
|
+
| "LINE"
|
|
50
|
+
| "LSEG"
|
|
51
|
+
| "MACADDR"
|
|
52
|
+
| "MACADDR8"
|
|
53
|
+
| "MONEY"
|
|
54
|
+
| "PATH"
|
|
55
|
+
| "POLYGON"
|
|
56
|
+
| "TEXT"
|
|
57
|
+
| "TIME"
|
|
58
|
+
| "TIMETZ"
|
|
59
|
+
| "TSQUERY"
|
|
60
|
+
| "TSVECTOR"
|
|
61
|
+
| "TXID_SNAPSHOT"
|
|
62
|
+
| "XML"
|
|
63
|
+
| `BIT${string}`
|
|
64
|
+
| `CHARACTER${string}`
|
|
65
|
+
| `NUMERIC${string}`
|
|
66
|
+
| `TIME ${string}`
|
|
67
|
+
| `TIME(${string})`
|
|
68
|
+
| `VARCHAR`
|
|
69
|
+
| `VARCHAR ${string}`
|
|
70
|
+
? string
|
|
71
|
+
: Uppercase<DataType> extends "BYTEA"
|
|
72
|
+
? Buffer
|
|
73
|
+
: // : Uppercase<DataType> extends "CIRCLE"
|
|
74
|
+
// ? { x: number; y: number; radius: number }
|
|
75
|
+
// : Uppercase<DataType> extends "POINT"
|
|
76
|
+
// ? { x: number; y: number }
|
|
77
|
+
Uppercase<DataType> extends "JSON" | "JSONB"
|
|
78
|
+
? unknown
|
|
79
|
+
: Uppercase<DataType> extends "UUID"
|
|
80
|
+
? string
|
|
81
|
+
: Uppercase<DataType> extends "BOOLEAN"
|
|
82
|
+
? boolean
|
|
83
|
+
: Uppercase<DataType> extends
|
|
84
|
+
| "DATE"
|
|
85
|
+
| "TIMESTAMP"
|
|
86
|
+
| "TIMESTAMPTZ"
|
|
87
|
+
| `TIMESTAMP${string}`
|
|
88
|
+
? Date
|
|
89
|
+
: // : Uppercase<DataType> extends "INTERVAL"
|
|
90
|
+
// ? {
|
|
91
|
+
// years?: number;
|
|
92
|
+
// months?: number;
|
|
93
|
+
// days?: number;
|
|
94
|
+
// hours?: number;
|
|
95
|
+
// minutes?: number;
|
|
96
|
+
// seconds?: number;
|
|
97
|
+
// milliseconds?: number;
|
|
98
|
+
// }
|
|
99
|
+
unknown;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { describe, expectTypeOf, test } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { ModelDefinition } from "#definition/ModelDefinition.js";
|
|
4
|
+
import { FieldName } from "./FieldName.js";
|
|
5
|
+
|
|
2
6
|
describe("FieldName", () => {
|
|
3
7
|
test("it evaluates to a string union of the model's column names", () => {
|
|
4
8
|
const model = {
|
|
@@ -10,7 +14,10 @@ describe("FieldName", () => {
|
|
|
10
14
|
email: { type: "text" },
|
|
11
15
|
type: { type: "text" },
|
|
12
16
|
},
|
|
13
|
-
};
|
|
14
|
-
|
|
17
|
+
} as const satisfies ModelDefinition;
|
|
18
|
+
|
|
19
|
+
expectTypeOf<FieldName<typeof model>>().toEqualTypeOf<
|
|
20
|
+
"id" | "name" | "createdAt" | "dateOfBirth" | "email" | "type"
|
|
21
|
+
>();
|
|
15
22
|
});
|
|
16
23
|
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { describe, expectTypeOf } from "vitest";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
import type { ModelDefinition } from "#definition/ModelDefinition.js";
|
|
5
|
+
import type { FieldType } from "./FieldType.js";
|
|
6
|
+
|
|
7
|
+
const user = {
|
|
8
|
+
fields: {
|
|
9
|
+
email: {
|
|
10
|
+
type: "text",
|
|
11
|
+
zodSchema: z.email(),
|
|
12
|
+
},
|
|
13
|
+
id: {
|
|
14
|
+
type: "serial",
|
|
15
|
+
},
|
|
16
|
+
age: {
|
|
17
|
+
type: "integer",
|
|
18
|
+
zodSchema: z.number().min(0).max(150),
|
|
19
|
+
},
|
|
20
|
+
tags: {
|
|
21
|
+
type: "text[]",
|
|
22
|
+
zodSchema: z.array(z.string()),
|
|
23
|
+
},
|
|
24
|
+
status: {
|
|
25
|
+
type: "text",
|
|
26
|
+
zodSchema: z.enum(["active", "inactive", "pending"]),
|
|
27
|
+
},
|
|
28
|
+
createdAt: {
|
|
29
|
+
type: "timestamp with time zone",
|
|
30
|
+
},
|
|
31
|
+
deletedAt: {
|
|
32
|
+
type: "timestamp with time zone",
|
|
33
|
+
zodSchema: z.date().nullable(),
|
|
34
|
+
},
|
|
35
|
+
metadata: {
|
|
36
|
+
type: "jsonb",
|
|
37
|
+
default: "{}",
|
|
38
|
+
zodSchema: z.object({
|
|
39
|
+
foo: z.enum(["a", "b", "c"]),
|
|
40
|
+
bar: z.array(
|
|
41
|
+
z.object({
|
|
42
|
+
baz: z.enum(["good", "bad", "indifferent"]),
|
|
43
|
+
quux: z.boolean(),
|
|
44
|
+
}),
|
|
45
|
+
),
|
|
46
|
+
}),
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
} as const satisfies ModelDefinition;
|
|
50
|
+
|
|
51
|
+
type UserModel = typeof user;
|
|
52
|
+
|
|
53
|
+
describe("FieldType", () => {
|
|
54
|
+
describe("json field", () => {
|
|
55
|
+
expectTypeOf<FieldType<UserModel, "metadata">>().toEqualTypeOf<{
|
|
56
|
+
foo: "a" | "b" | "c";
|
|
57
|
+
bar: { baz: "good" | "bad" | "indifferent"; quux: boolean }[];
|
|
58
|
+
}>();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe("fields with Zod schemas", () => {
|
|
62
|
+
expectTypeOf<FieldType<UserModel, "email">>().toBeString();
|
|
63
|
+
|
|
64
|
+
expectTypeOf<FieldType<UserModel, "age">>().toBeNumber();
|
|
65
|
+
|
|
66
|
+
expectTypeOf<FieldType<UserModel, "tags">>().toEqualTypeOf<string[]>();
|
|
67
|
+
|
|
68
|
+
expectTypeOf<FieldType<UserModel, "status">>().toEqualTypeOf<
|
|
69
|
+
"active" | "inactive" | "pending"
|
|
70
|
+
>();
|
|
71
|
+
|
|
72
|
+
expectTypeOf<
|
|
73
|
+
FieldType<UserModel, "deletedAt">
|
|
74
|
+
>().toEqualTypeOf<Date | null>();
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe("fields without Zod schemas (using DefaultFieldType)", () => {
|
|
78
|
+
expectTypeOf<FieldType<UserModel, "id">>().toBeNumber();
|
|
79
|
+
expectTypeOf<FieldType<UserModel, "createdAt">>().toEqualTypeOf<Date>();
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
import { ModelDefinition } from "#definition/ModelDefinition.js";
|
|
4
|
+
import { DefaultFieldType } from "./DefaultFieldType.js";
|
|
5
|
+
import { FieldName } from "./FieldName.js";
|
|
6
|
+
|
|
7
|
+
export type FieldType<
|
|
8
|
+
Model extends ModelDefinition,
|
|
9
|
+
C extends FieldName<Model>,
|
|
10
|
+
> = Model["fields"][C]["zodSchema"] extends z.ZodType
|
|
11
|
+
?
|
|
12
|
+
| z.infer<Model["fields"][C]["zodSchema"]>
|
|
13
|
+
| (Model["fields"][C]["nullable"] extends true ? null : never)
|
|
14
|
+
:
|
|
15
|
+
| DefaultFieldType<Model["fields"][C]["type"]>
|
|
16
|
+
| (Model["fields"][C]["nullable"] extends true ? null : never);
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { describe, expectTypeOf, test } from "vitest";
|
|
2
|
+
|
|
3
|
+
import type { ModelDefinition } from "../definition/ModelDefinition.js";
|
|
4
|
+
import type { FieldWithDefault } from "./FieldWithDefault.js";
|
|
5
|
+
|
|
2
6
|
describe("FieldWithDefault", () => {
|
|
3
7
|
test("extracts just the fields with a default value from the model", () => {
|
|
4
8
|
const user = {
|
|
@@ -8,9 +12,13 @@ describe("FieldWithDefault", () => {
|
|
|
8
12
|
age: { type: "integer", default: 18 },
|
|
9
13
|
email: { type: "text", default: null },
|
|
10
14
|
},
|
|
11
|
-
};
|
|
12
|
-
|
|
15
|
+
} as const satisfies ModelDefinition;
|
|
16
|
+
|
|
17
|
+
expectTypeOf<FieldWithDefault<typeof user>>().toEqualTypeOf<
|
|
18
|
+
"name" | "age"
|
|
19
|
+
>();
|
|
13
20
|
});
|
|
21
|
+
|
|
14
22
|
test("returns never if there are no fields with defaults", () => {
|
|
15
23
|
const user = {
|
|
16
24
|
fields: {
|
|
@@ -18,9 +26,11 @@ describe("FieldWithDefault", () => {
|
|
|
18
26
|
name: { type: "text" },
|
|
19
27
|
age: { type: "integer" },
|
|
20
28
|
},
|
|
21
|
-
};
|
|
22
|
-
|
|
29
|
+
} as const satisfies ModelDefinition;
|
|
30
|
+
|
|
31
|
+
expectTypeOf<FieldWithDefault<typeof user>>().toEqualTypeOf<never>();
|
|
23
32
|
});
|
|
33
|
+
|
|
24
34
|
test("excludes fields with null or undefined defaults", () => {
|
|
25
35
|
const user = {
|
|
26
36
|
fields: {
|
|
@@ -29,7 +39,8 @@ describe("FieldWithDefault", () => {
|
|
|
29
39
|
email: { type: "text", default: null },
|
|
30
40
|
phone: { type: "text", default: undefined },
|
|
31
41
|
},
|
|
32
|
-
};
|
|
33
|
-
|
|
42
|
+
} as const satisfies ModelDefinition;
|
|
43
|
+
|
|
44
|
+
expectTypeOf<FieldWithDefault<typeof user>>().toEqualTypeOf<"name">();
|
|
34
45
|
});
|
|
35
46
|
});
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { ModelDefinition } from "../definition/ModelDefinition.js";
|
|
2
|
+
|
|
2
3
|
export type FieldWithDefault<Model extends ModelDefinition> = {
|
|
3
|
-
[K in keyof Model["fields"]]: Model["fields"][K]["default"] extends NonNullable<
|
|
4
|
+
[K in keyof Model["fields"]]: Model["fields"][K]["default"] extends NonNullable<
|
|
5
|
+
Model["fields"][K]["default"]
|
|
6
|
+
>
|
|
7
|
+
? K
|
|
8
|
+
: never;
|
|
4
9
|
}[keyof Model["fields"]];
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { describe, expectTypeOf, test } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { ModelDefinitions } from "../definition/ModelDefinitions.js";
|
|
4
|
+
import { ModelName } from "./ModelName.js";
|
|
5
|
+
|
|
2
6
|
describe("ModelName", () => {
|
|
3
7
|
test("it evaluates to a string union of the names of the models", () => {
|
|
4
8
|
const models = {
|
|
@@ -8,7 +12,10 @@ describe("ModelName", () => {
|
|
|
8
12
|
comment: { fields: {} },
|
|
9
13
|
mention: { fields: {} },
|
|
10
14
|
color: { fields: {} },
|
|
11
|
-
};
|
|
12
|
-
|
|
15
|
+
} as const satisfies ModelDefinitions;
|
|
16
|
+
|
|
17
|
+
expectTypeOf<ModelName<typeof models>>().toEqualTypeOf<
|
|
18
|
+
"user" | "post" | "like" | "comment" | "mention" | "color"
|
|
19
|
+
>();
|
|
13
20
|
});
|
|
14
21
|
});
|