@danceroutine/tango-schema 0.1.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +122 -0
- package/dist/domain/DeleteReferentialAction.d.ts +1 -2
- package/dist/domain/Model.d.ts +17 -1
- package/dist/domain/ModelMetadata.d.ts +7 -0
- package/dist/domain/ModelWriteHooks.d.ts +82 -0
- package/dist/domain/UpdateReferentialAction.d.ts +1 -2
- package/dist/domain/index.d.ts +2 -1
- package/dist/domain-Cufz6y1q.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/model/ModelAugmentorRegistry.d.ts +11 -0
- package/dist/model/ModelDefinition.d.ts +12 -1
- package/dist/model/RelationBuilder.d.ts +6 -0
- package/dist/model/constraints/Constraints.d.ts +19 -0
- package/dist/model/constraints/Indexes.d.ts +4 -0
- package/dist/model/constraints/index.d.ts +6 -0
- package/dist/model/decorators/Decorators.d.ts +35 -0
- package/dist/model/decorators/index.d.ts +6 -0
- package/dist/model/decorators/types.d.ts +29 -0
- package/dist/model/index.d.ts +8 -0
- package/dist/model/index.js +2 -2
- package/dist/model/inferFields.d.ts +8 -1
- package/dist/model/internal/FieldMetadataStore.d.ts +3 -0
- package/dist/model/meta/Meta.d.ts +22 -0
- package/dist/model/meta/index.d.ts +5 -0
- package/dist/model/registry/ModelRegistry.d.ts +68 -0
- package/dist/model-DI8lQH1W.js +585 -0
- package/dist/model-DI8lQH1W.js.map +1 -0
- package/package.json +52 -50
- package/dist/domain/DeleteReferentialAction.js +0 -1
- package/dist/domain/Model.js +0 -1
- package/dist/domain/UpdateReferentialAction.js +0 -1
- package/dist/domain/internal/InternalFieldType.js +0 -10
- package/dist/domain/internal/InternalReferentialAction.d.ts +0 -6
- package/dist/domain/internal/InternalReferentialAction.js +0 -6
- package/dist/domain/internal/InternalRelationType.js +0 -5
- package/dist/domain/internal/ZodGuards.d.ts +0 -13
- package/dist/domain/internal/ZodGuards.js +0 -39
- package/dist/domain/internal/zod/hasConstructorName.js +0 -5
- package/dist/domain/internal/zod/index.js +0 -13
- package/dist/domain/internal/zod/isDate.js +0 -3
- package/dist/domain/internal/zod/isZodArray.js +0 -5
- package/dist/domain/internal/zod/isZodBoolean.js +0 -5
- package/dist/domain/internal/zod/isZodDate.js +0 -5
- package/dist/domain/internal/zod/isZodDefault.js +0 -5
- package/dist/domain/internal/zod/isZodNullable.js +0 -5
- package/dist/domain/internal/zod/isZodNumber.js +0 -5
- package/dist/domain/internal/zod/isZodObject.js +0 -5
- package/dist/domain/internal/zod/isZodOptional.js +0 -5
- package/dist/domain/internal/zod/isZodString.js +0 -5
- package/dist/model/Model.js +0 -22
- package/dist/model/ModelDefinition.js +0 -1
- package/dist/model/inferFields.js +0 -64
- package/dist/model-DE1qDItF.js +0 -174
- package/dist/model-DE1qDItF.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,54 +1,56 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
},
|
|
13
|
-
"./domain": {
|
|
14
|
-
"types": "./dist/domain/index.d.ts",
|
|
15
|
-
"import": "./dist/domain/index.js"
|
|
16
|
-
},
|
|
17
|
-
"./model": {
|
|
18
|
-
"types": "./dist/model/index.d.ts",
|
|
19
|
-
"import": "./dist/model/index.js"
|
|
20
|
-
}
|
|
2
|
+
"name": "@danceroutine/tango-schema",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Model factory, Zod helpers, and metadata utilities for Tango",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
21
12
|
},
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"scripts": {
|
|
26
|
-
"build": "tsdown",
|
|
27
|
-
"test": "vitest run --coverage",
|
|
28
|
-
"test:watch": "vitest",
|
|
29
|
-
"typecheck": "tsc --noEmit"
|
|
13
|
+
"./domain": {
|
|
14
|
+
"types": "./dist/domain/index.d.ts",
|
|
15
|
+
"import": "./dist/domain/index.js"
|
|
30
16
|
},
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"model",
|
|
35
|
-
"zod",
|
|
36
|
-
"validation"
|
|
37
|
-
],
|
|
38
|
-
"author": "Pedro Del Moral Lopez",
|
|
39
|
-
"license": "MIT",
|
|
40
|
-
"repository": {
|
|
41
|
-
"type": "git",
|
|
42
|
-
"url": "https://github.com/danceroutine/tango.git",
|
|
43
|
-
"directory": "packages/schema"
|
|
44
|
-
},
|
|
45
|
-
"dependencies": {
|
|
46
|
-
"zod": "^4.0.0"
|
|
47
|
-
},
|
|
48
|
-
"devDependencies": {
|
|
49
|
-
"@types/node": "^22.9.0",
|
|
50
|
-
"tsdown": "^0.4.0",
|
|
51
|
-
"typescript": "^5.6.3",
|
|
52
|
-
"vitest": "^4.0.6"
|
|
17
|
+
"./model": {
|
|
18
|
+
"types": "./dist/model/index.d.ts",
|
|
19
|
+
"import": "./dist/model/index.js"
|
|
53
20
|
}
|
|
54
|
-
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"keywords": [
|
|
26
|
+
"tango",
|
|
27
|
+
"schema",
|
|
28
|
+
"model",
|
|
29
|
+
"zod",
|
|
30
|
+
"validation"
|
|
31
|
+
],
|
|
32
|
+
"author": "Pedro Del Moral Lopez",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/danceroutine/tango.git",
|
|
37
|
+
"directory": "packages/schema"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"zod": "^4.0.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/node": "^22.9.0",
|
|
44
|
+
"tsdown": "^0.4.0",
|
|
45
|
+
"typescript": "^5.6.3",
|
|
46
|
+
"vitest": "^4.0.6"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsdown",
|
|
50
|
+
"test": "vitest run --coverage",
|
|
51
|
+
"test:watch": "vitest",
|
|
52
|
+
"typecheck": "pnpm run typecheck:prod && pnpm run typecheck:test",
|
|
53
|
+
"typecheck:prod": "tsc --noEmit -p tsconfig.json",
|
|
54
|
+
"typecheck:test": "tsc --noEmit -p tsconfig.tests.json"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import { InternalReferentialAction } from './internal/InternalReferentialAction';
|
package/dist/domain/Model.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import { InternalReferentialAction } from './internal/InternalReferentialAction';
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
export declare class ZodGuards {
|
|
3
|
-
static isZodOptional(value: unknown): value is z.ZodOptional<z.ZodTypeAny>;
|
|
4
|
-
static isZodNullable(value: unknown): value is z.ZodNullable<z.ZodTypeAny>;
|
|
5
|
-
static isZodDefault(value: unknown): value is z.ZodDefault<z.ZodTypeAny>;
|
|
6
|
-
static isZodString(value: unknown): value is z.ZodString;
|
|
7
|
-
static isZodNumber(value: unknown): value is z.ZodNumber;
|
|
8
|
-
static isZodBoolean(value: unknown): value is z.ZodBoolean;
|
|
9
|
-
static isZodDate(value: unknown): value is z.ZodDate;
|
|
10
|
-
static isZodObject(value: unknown): value is z.ZodObject<z.ZodRawShape>;
|
|
11
|
-
static isZodArray(value: unknown): value is z.ZodArray<z.ZodTypeAny>;
|
|
12
|
-
static isDate(value: unknown): value is Date;
|
|
13
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
function hasConstructorName(value, name) {
|
|
3
|
-
return (!!value &&
|
|
4
|
-
typeof value === 'object' &&
|
|
5
|
-
value.constructor?.name === name);
|
|
6
|
-
}
|
|
7
|
-
// TODO not sure this justifies being a class, typeguards being handled as first class functions would be better
|
|
8
|
-
export class ZodGuards {
|
|
9
|
-
static isZodOptional(value) {
|
|
10
|
-
return hasConstructorName(value, 'ZodOptional');
|
|
11
|
-
}
|
|
12
|
-
static isZodNullable(value) {
|
|
13
|
-
return hasConstructorName(value, 'ZodNullable');
|
|
14
|
-
}
|
|
15
|
-
static isZodDefault(value) {
|
|
16
|
-
return hasConstructorName(value, 'ZodDefault');
|
|
17
|
-
}
|
|
18
|
-
static isZodString(value) {
|
|
19
|
-
return hasConstructorName(value, 'ZodString');
|
|
20
|
-
}
|
|
21
|
-
static isZodNumber(value) {
|
|
22
|
-
return hasConstructorName(value, 'ZodNumber');
|
|
23
|
-
}
|
|
24
|
-
static isZodBoolean(value) {
|
|
25
|
-
return hasConstructorName(value, 'ZodBoolean');
|
|
26
|
-
}
|
|
27
|
-
static isZodDate(value) {
|
|
28
|
-
return hasConstructorName(value, 'ZodDate');
|
|
29
|
-
}
|
|
30
|
-
static isZodObject(value) {
|
|
31
|
-
return hasConstructorName(value, 'ZodObject');
|
|
32
|
-
}
|
|
33
|
-
static isZodArray(value) {
|
|
34
|
-
return hasConstructorName(value, 'ZodArray');
|
|
35
|
-
}
|
|
36
|
-
static isDate(value) {
|
|
37
|
-
return value != null && Object.prototype.toString.call(value) === '[object Date]';
|
|
38
|
-
}
|
|
39
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Domain boundary barrel: centralizes this subdomain's public contract.
|
|
3
|
-
*/
|
|
4
|
-
export { isDate } from './isDate';
|
|
5
|
-
export { isZodArray } from './isZodArray';
|
|
6
|
-
export { isZodBoolean } from './isZodBoolean';
|
|
7
|
-
export { isZodDate } from './isZodDate';
|
|
8
|
-
export { isZodDefault } from './isZodDefault';
|
|
9
|
-
export { isZodNullable } from './isZodNullable';
|
|
10
|
-
export { isZodNumber } from './isZodNumber';
|
|
11
|
-
export { isZodObject } from './isZodObject';
|
|
12
|
-
export { isZodOptional } from './isZodOptional';
|
|
13
|
-
export { isZodString } from './isZodString';
|
package/dist/model/Model.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { RelationBuilder } from './RelationBuilder';
|
|
3
|
-
import { inferFieldsFromSchema } from './inferFields';
|
|
4
|
-
/**
|
|
5
|
-
* Creates a model definition with metadata and schema validation.
|
|
6
|
-
* Automatically infers field types from Zod schema if fields are not explicitly provided.
|
|
7
|
-
*/
|
|
8
|
-
export function Model(definition) {
|
|
9
|
-
const builder = new RelationBuilder();
|
|
10
|
-
const relations = definition.relations ? definition.relations(builder) : undefined;
|
|
11
|
-
const fields = definition.fields || inferFieldsFromSchema(definition.schema);
|
|
12
|
-
const metadata = {
|
|
13
|
-
table: definition.table,
|
|
14
|
-
fields,
|
|
15
|
-
indexes: definition.indexes,
|
|
16
|
-
relations,
|
|
17
|
-
};
|
|
18
|
-
return {
|
|
19
|
-
metadata,
|
|
20
|
-
schema: definition.schema,
|
|
21
|
-
};
|
|
22
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { InternalFieldType } from '../domain/internal/InternalFieldType';
|
|
3
|
-
import { isDate, isZodArray, isZodBoolean, isZodDate, isZodDefault, isZodNullable, isZodNumber, isZodObject, isZodOptional, isZodString, } from '../domain/internal/zod/index';
|
|
4
|
-
export function inferFieldsFromSchema(schema) {
|
|
5
|
-
const shape = schema.shape;
|
|
6
|
-
const fields = [];
|
|
7
|
-
for (const [name, zodType] of Object.entries(shape)) {
|
|
8
|
-
const field = inferField(name, zodType);
|
|
9
|
-
if (field) {
|
|
10
|
-
fields.push(field);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
return fields;
|
|
14
|
-
}
|
|
15
|
-
function inferField(name, zodType) {
|
|
16
|
-
let type = InternalFieldType.TEXT;
|
|
17
|
-
let notNull = true;
|
|
18
|
-
let defaultValue = undefined;
|
|
19
|
-
let unwrapped = zodType;
|
|
20
|
-
if (isZodOptional(unwrapped)) {
|
|
21
|
-
notNull = false;
|
|
22
|
-
unwrapped = unwrapped.unwrap();
|
|
23
|
-
}
|
|
24
|
-
if (isZodNullable(unwrapped)) {
|
|
25
|
-
notNull = false;
|
|
26
|
-
unwrapped = unwrapped.unwrap();
|
|
27
|
-
}
|
|
28
|
-
if (isZodDefault(unwrapped)) {
|
|
29
|
-
const def = unwrapped._zod.def.defaultValue;
|
|
30
|
-
if (isDate(def)) {
|
|
31
|
-
defaultValue = { now: true };
|
|
32
|
-
}
|
|
33
|
-
else if (typeof def === 'string' || typeof def === 'number') {
|
|
34
|
-
defaultValue = String(def);
|
|
35
|
-
}
|
|
36
|
-
unwrapped = unwrapped.removeDefault();
|
|
37
|
-
}
|
|
38
|
-
if (isZodString(unwrapped)) {
|
|
39
|
-
type = InternalFieldType.TEXT;
|
|
40
|
-
}
|
|
41
|
-
else if (isZodNumber(unwrapped)) {
|
|
42
|
-
const checks = unwrapped._zod.def.checks ?? [];
|
|
43
|
-
const isInt = checks.some((c) => 'format' in c._zod.def && c._zod.def.format === 'safeint');
|
|
44
|
-
type = isInt ? InternalFieldType.INT : InternalFieldType.BIGINT;
|
|
45
|
-
}
|
|
46
|
-
else if (isZodBoolean(unwrapped)) {
|
|
47
|
-
type = InternalFieldType.BOOL;
|
|
48
|
-
}
|
|
49
|
-
else if (isZodDate(unwrapped)) {
|
|
50
|
-
type = InternalFieldType.TIMESTAMPTZ;
|
|
51
|
-
}
|
|
52
|
-
else if (isZodObject(unwrapped) || isZodArray(unwrapped)) {
|
|
53
|
-
type = InternalFieldType.JSONB;
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
return {
|
|
59
|
-
name,
|
|
60
|
-
type,
|
|
61
|
-
notNull,
|
|
62
|
-
default: defaultValue,
|
|
63
|
-
};
|
|
64
|
-
}
|
package/dist/model-DE1qDItF.js
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
//#region rolldown:runtime
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __export = (target, all) => {
|
|
5
|
-
for (var name in all) __defProp(target, name, {
|
|
6
|
-
get: all[name],
|
|
7
|
-
enumerable: true
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
//#endregion
|
|
12
|
-
//#region src/domain/internal/InternalRelationType.ts
|
|
13
|
-
let InternalRelationType = function(InternalRelationType$1) {
|
|
14
|
-
InternalRelationType$1["HAS_MANY"] = "hasMany";
|
|
15
|
-
InternalRelationType$1["BELONGS_TO"] = "belongsTo";
|
|
16
|
-
InternalRelationType$1["HAS_ONE"] = "hasOne";
|
|
17
|
-
return InternalRelationType$1;
|
|
18
|
-
}({});
|
|
19
|
-
|
|
20
|
-
//#endregion
|
|
21
|
-
//#region src/model/RelationBuilder.ts
|
|
22
|
-
var RelationBuilder = class {
|
|
23
|
-
hasMany(target, foreignKey) {
|
|
24
|
-
return {
|
|
25
|
-
type: InternalRelationType.HAS_MANY,
|
|
26
|
-
target,
|
|
27
|
-
foreignKey
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
belongsTo(target, foreignKey, localKey) {
|
|
31
|
-
return {
|
|
32
|
-
type: InternalRelationType.BELONGS_TO,
|
|
33
|
-
target,
|
|
34
|
-
foreignKey,
|
|
35
|
-
localKey
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
hasOne(target, foreignKey) {
|
|
39
|
-
return {
|
|
40
|
-
type: InternalRelationType.HAS_ONE,
|
|
41
|
-
target,
|
|
42
|
-
foreignKey
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
//#endregion
|
|
48
|
-
//#region src/domain/internal/InternalFieldType.ts
|
|
49
|
-
let InternalFieldType = function(InternalFieldType$1) {
|
|
50
|
-
InternalFieldType$1["SERIAL"] = "serial";
|
|
51
|
-
InternalFieldType$1["INT"] = "int";
|
|
52
|
-
InternalFieldType$1["BIGINT"] = "bigint";
|
|
53
|
-
InternalFieldType$1["TEXT"] = "text";
|
|
54
|
-
InternalFieldType$1["BOOL"] = "bool";
|
|
55
|
-
InternalFieldType$1["TIMESTAMPTZ"] = "timestamptz";
|
|
56
|
-
InternalFieldType$1["JSONB"] = "jsonb";
|
|
57
|
-
InternalFieldType$1["UUID"] = "uuid";
|
|
58
|
-
return InternalFieldType$1;
|
|
59
|
-
}({});
|
|
60
|
-
|
|
61
|
-
//#endregion
|
|
62
|
-
//#region src/domain/internal/ZodGuards.ts
|
|
63
|
-
function hasConstructorName(value, name) {
|
|
64
|
-
return !!value && typeof value === "object" && value.constructor?.name === name;
|
|
65
|
-
}
|
|
66
|
-
var ZodGuards = class {
|
|
67
|
-
static isZodOptional(value) {
|
|
68
|
-
return hasConstructorName(value, "ZodOptional");
|
|
69
|
-
}
|
|
70
|
-
static isZodNullable(value) {
|
|
71
|
-
return hasConstructorName(value, "ZodNullable");
|
|
72
|
-
}
|
|
73
|
-
static isZodDefault(value) {
|
|
74
|
-
return hasConstructorName(value, "ZodDefault");
|
|
75
|
-
}
|
|
76
|
-
static isZodString(value) {
|
|
77
|
-
return hasConstructorName(value, "ZodString");
|
|
78
|
-
}
|
|
79
|
-
static isZodNumber(value) {
|
|
80
|
-
return hasConstructorName(value, "ZodNumber");
|
|
81
|
-
}
|
|
82
|
-
static isZodBoolean(value) {
|
|
83
|
-
return hasConstructorName(value, "ZodBoolean");
|
|
84
|
-
}
|
|
85
|
-
static isZodDate(value) {
|
|
86
|
-
return hasConstructorName(value, "ZodDate");
|
|
87
|
-
}
|
|
88
|
-
static isZodObject(value) {
|
|
89
|
-
return hasConstructorName(value, "ZodObject");
|
|
90
|
-
}
|
|
91
|
-
static isZodArray(value) {
|
|
92
|
-
return hasConstructorName(value, "ZodArray");
|
|
93
|
-
}
|
|
94
|
-
static isDate(value) {
|
|
95
|
-
return value != null && Object.prototype.toString.call(value) === "[object Date]";
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
//#endregion
|
|
100
|
-
//#region src/model/inferFields.ts
|
|
101
|
-
function inferFieldsFromSchema(schema) {
|
|
102
|
-
const shape = schema.shape;
|
|
103
|
-
const fields = [];
|
|
104
|
-
for (const [name, zodType] of Object.entries(shape)) {
|
|
105
|
-
const field = inferField(name, zodType);
|
|
106
|
-
if (field) fields.push(field);
|
|
107
|
-
}
|
|
108
|
-
return fields;
|
|
109
|
-
}
|
|
110
|
-
function inferField(name, zodType) {
|
|
111
|
-
let type = InternalFieldType.TEXT;
|
|
112
|
-
let notNull = true;
|
|
113
|
-
let defaultValue = undefined;
|
|
114
|
-
let unwrapped = zodType;
|
|
115
|
-
if (ZodGuards.isZodOptional(unwrapped)) {
|
|
116
|
-
notNull = false;
|
|
117
|
-
unwrapped = unwrapped.unwrap();
|
|
118
|
-
}
|
|
119
|
-
if (ZodGuards.isZodNullable(unwrapped)) {
|
|
120
|
-
notNull = false;
|
|
121
|
-
unwrapped = unwrapped.unwrap();
|
|
122
|
-
}
|
|
123
|
-
if (ZodGuards.isZodDefault(unwrapped)) {
|
|
124
|
-
const def = unwrapped._zod.def.defaultValue;
|
|
125
|
-
if (ZodGuards.isDate(def)) defaultValue = { now: true };
|
|
126
|
-
else if (typeof def === "string" || typeof def === "number") defaultValue = String(def);
|
|
127
|
-
unwrapped = unwrapped.removeDefault();
|
|
128
|
-
}
|
|
129
|
-
if (ZodGuards.isZodString(unwrapped)) type = InternalFieldType.TEXT;
|
|
130
|
-
else if (ZodGuards.isZodNumber(unwrapped)) {
|
|
131
|
-
const checks = unwrapped._zod.def.checks ?? [];
|
|
132
|
-
const isInt = checks.some((c) => "format" in c._zod.def && c._zod.def.format === "safeint");
|
|
133
|
-
type = isInt ? InternalFieldType.INT : InternalFieldType.BIGINT;
|
|
134
|
-
} else if (ZodGuards.isZodBoolean(unwrapped)) type = InternalFieldType.BOOL;
|
|
135
|
-
else if (ZodGuards.isZodDate(unwrapped)) type = InternalFieldType.TIMESTAMPTZ;
|
|
136
|
-
else if (ZodGuards.isZodObject(unwrapped) || ZodGuards.isZodArray(unwrapped)) type = InternalFieldType.JSONB;
|
|
137
|
-
else return null;
|
|
138
|
-
return {
|
|
139
|
-
name,
|
|
140
|
-
type,
|
|
141
|
-
notNull,
|
|
142
|
-
default: defaultValue
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
//#endregion
|
|
147
|
-
//#region src/model/Model.ts
|
|
148
|
-
function Model(definition) {
|
|
149
|
-
const builder = new RelationBuilder();
|
|
150
|
-
const relations = definition.relations ? definition.relations(builder) : undefined;
|
|
151
|
-
const fields = definition.fields || inferFieldsFromSchema(definition.schema);
|
|
152
|
-
const metadata = {
|
|
153
|
-
table: definition.table,
|
|
154
|
-
fields,
|
|
155
|
-
indexes: definition.indexes,
|
|
156
|
-
relations
|
|
157
|
-
};
|
|
158
|
-
return {
|
|
159
|
-
metadata,
|
|
160
|
-
schema: definition.schema
|
|
161
|
-
};
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
//#endregion
|
|
165
|
-
//#region src/model/index.ts
|
|
166
|
-
var model_exports = {};
|
|
167
|
-
__export(model_exports, {
|
|
168
|
-
Model: () => Model,
|
|
169
|
-
RelationBuilder: () => RelationBuilder
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
//#endregion
|
|
173
|
-
export { Model, RelationBuilder, model_exports };
|
|
174
|
-
//# sourceMappingURL=model-DE1qDItF.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"model-DE1qDItF.js","names":["target: string","foreignKey: string","localKey?: string","value: unknown","name: string","schema: z.ZodObject<any>","fields: Field[]","name: string","zodType: z.ZodType","type: FieldType","defaultValue: Field['default']","unwrapped: z.ZodType","definition: ModelDefinition<TSchema>","metadata: ModelMetadata"],"sources":["../src/domain/internal/InternalRelationType.ts","../src/model/RelationBuilder.ts","../src/domain/internal/InternalFieldType.ts","../src/domain/internal/ZodGuards.ts","../src/model/inferFields.ts","../src/model/Model.ts","../src/model/index.ts"],"sourcesContent":["export enum InternalRelationType {\n HAS_MANY = 'hasMany',\n BELONGS_TO = 'belongsTo',\n HAS_ONE = 'hasOne',\n}\n","import type { RelationDef } from '../domain/index';\nimport { InternalRelationType } from '../domain/internal/InternalRelationType';\n\nexport class RelationBuilder {\n hasMany(target: string, foreignKey: string): RelationDef {\n return {\n type: InternalRelationType.HAS_MANY,\n target,\n foreignKey,\n };\n }\n\n belongsTo(target: string, foreignKey: string, localKey?: string): RelationDef {\n return {\n type: InternalRelationType.BELONGS_TO,\n target,\n foreignKey,\n localKey,\n };\n }\n\n hasOne(target: string, foreignKey: string): RelationDef {\n return {\n type: InternalRelationType.HAS_ONE,\n target,\n foreignKey,\n };\n }\n}\n","export enum InternalFieldType {\n SERIAL = 'serial',\n INT = 'int',\n BIGINT = 'bigint',\n TEXT = 'text',\n BOOL = 'bool',\n TIMESTAMPTZ = 'timestamptz',\n JSONB = 'jsonb',\n UUID = 'uuid',\n}\n","import { z } from 'zod';\n\nfunction hasConstructorName(value: unknown, name: string): boolean {\n return !!value && typeof value === 'object' && (value as { constructor?: { name?: unknown } }).constructor?.name === name;\n}\n\nexport class ZodGuards {\n static isZodOptional(value: unknown): value is z.ZodOptional<z.ZodTypeAny> {\n return hasConstructorName(value, 'ZodOptional');\n }\n\n static isZodNullable(value: unknown): value is z.ZodNullable<z.ZodTypeAny> {\n return hasConstructorName(value, 'ZodNullable');\n }\n\n static isZodDefault(value: unknown): value is z.ZodDefault<z.ZodTypeAny> {\n return hasConstructorName(value, 'ZodDefault');\n }\n\n static isZodString(value: unknown): value is z.ZodString {\n return hasConstructorName(value, 'ZodString');\n }\n\n static isZodNumber(value: unknown): value is z.ZodNumber {\n return hasConstructorName(value, 'ZodNumber');\n }\n\n static isZodBoolean(value: unknown): value is z.ZodBoolean {\n return hasConstructorName(value, 'ZodBoolean');\n }\n\n static isZodDate(value: unknown): value is z.ZodDate {\n return hasConstructorName(value, 'ZodDate');\n }\n\n static isZodObject(value: unknown): value is z.ZodObject<any> {\n return hasConstructorName(value, 'ZodObject');\n }\n\n static isZodArray(value: unknown): value is z.ZodArray<any> {\n return hasConstructorName(value, 'ZodArray');\n }\n\n static isDate(value: unknown): value is Date {\n return value != null && Object.prototype.toString.call(value) === '[object Date]';\n }\n}\n","import { z } from 'zod';\nimport type { Field, FieldType } from '../domain/index';\nimport { InternalFieldType } from '../domain/internal/InternalFieldType';\nimport { ZodGuards } from '../domain/internal/ZodGuards';\n\nexport function inferFieldsFromSchema(schema: z.ZodObject<any>): Field[] {\n const shape = schema.shape;\n const fields: Field[] = [];\n\n for (const [name, zodType] of Object.entries(shape)) {\n const field = inferField(name, zodType as z.ZodType);\n if (field) {\n fields.push(field);\n }\n }\n\n return fields;\n}\n\nfunction inferField(name: string, zodType: z.ZodType): Field | null {\n let type: FieldType = InternalFieldType.TEXT;\n let notNull = true;\n let defaultValue: Field['default'] = undefined;\n\n let unwrapped: z.ZodType = zodType;\n\n if (ZodGuards.isZodOptional(unwrapped)) {\n notNull = false;\n unwrapped = unwrapped.unwrap() as z.ZodType;\n }\n\n if (ZodGuards.isZodNullable(unwrapped)) {\n notNull = false;\n unwrapped = unwrapped.unwrap() as z.ZodType;\n }\n\n if (ZodGuards.isZodDefault(unwrapped)) {\n const def = unwrapped._zod.def.defaultValue;\n if (ZodGuards.isDate(def)) {\n defaultValue = { now: true };\n } else if (typeof def === 'string' || typeof def === 'number') {\n defaultValue = String(def);\n }\n unwrapped = unwrapped.removeDefault() as z.ZodType;\n }\n\n if (ZodGuards.isZodString(unwrapped)) {\n type = InternalFieldType.TEXT;\n } else if (ZodGuards.isZodNumber(unwrapped)) {\n const checks = unwrapped._zod.def.checks ?? [];\n const isInt = checks.some((c) => 'format' in c._zod.def && c._zod.def.format === 'safeint');\n type = isInt ? InternalFieldType.INT : InternalFieldType.BIGINT;\n } else if (ZodGuards.isZodBoolean(unwrapped)) {\n type = InternalFieldType.BOOL;\n } else if (ZodGuards.isZodDate(unwrapped)) {\n type = InternalFieldType.TIMESTAMPTZ;\n } else if (ZodGuards.isZodObject(unwrapped) || ZodGuards.isZodArray(unwrapped)) {\n type = InternalFieldType.JSONB;\n } else {\n return null;\n }\n\n return {\n name,\n type,\n notNull,\n default: defaultValue,\n };\n}\n","import { z } from 'zod';\nimport type { Model as SchemaModel } from '../domain/Model';\nimport type { ModelMetadata } from '../domain/index';\nimport type { ModelDefinition } from './ModelDefinition';\nimport { RelationBuilder } from './RelationBuilder';\nimport { inferFieldsFromSchema } from './inferFields';\n\n/**\n * Creates a model definition with metadata and schema validation.\n * Automatically infers field types from Zod schema if fields are not explicitly provided.\n */\nexport function Model<TSchema extends z.ZodObject<any>>(definition: ModelDefinition<TSchema>): SchemaModel<TSchema> {\n const builder = new RelationBuilder();\n const relations = definition.relations ? definition.relations(builder) : undefined;\n\n const fields = definition.fields || inferFieldsFromSchema(definition.schema);\n\n const metadata: ModelMetadata = {\n table: definition.table,\n fields,\n indexes: definition.indexes,\n relations,\n };\n\n return {\n metadata,\n schema: definition.schema,\n };\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport type { ModelDefinition } from './ModelDefinition';\nexport { RelationBuilder } from './RelationBuilder';\nexport { Model } from './Model';\n"],"mappings":"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"}
|