@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.
Files changed (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +122 -0
  3. package/dist/domain/DeleteReferentialAction.d.ts +1 -2
  4. package/dist/domain/Model.d.ts +17 -1
  5. package/dist/domain/ModelMetadata.d.ts +7 -0
  6. package/dist/domain/ModelWriteHooks.d.ts +82 -0
  7. package/dist/domain/UpdateReferentialAction.d.ts +1 -2
  8. package/dist/domain/index.d.ts +2 -1
  9. package/dist/domain-Cufz6y1q.js.map +1 -1
  10. package/dist/index.d.ts +2 -2
  11. package/dist/index.js +2 -2
  12. package/dist/model/ModelAugmentorRegistry.d.ts +11 -0
  13. package/dist/model/ModelDefinition.d.ts +12 -1
  14. package/dist/model/RelationBuilder.d.ts +6 -0
  15. package/dist/model/constraints/Constraints.d.ts +19 -0
  16. package/dist/model/constraints/Indexes.d.ts +4 -0
  17. package/dist/model/constraints/index.d.ts +6 -0
  18. package/dist/model/decorators/Decorators.d.ts +35 -0
  19. package/dist/model/decorators/index.d.ts +6 -0
  20. package/dist/model/decorators/types.d.ts +29 -0
  21. package/dist/model/index.d.ts +8 -0
  22. package/dist/model/index.js +2 -2
  23. package/dist/model/inferFields.d.ts +8 -1
  24. package/dist/model/internal/FieldMetadataStore.d.ts +3 -0
  25. package/dist/model/meta/Meta.d.ts +22 -0
  26. package/dist/model/meta/index.d.ts +5 -0
  27. package/dist/model/registry/ModelRegistry.d.ts +68 -0
  28. package/dist/model-DI8lQH1W.js +585 -0
  29. package/dist/model-DI8lQH1W.js.map +1 -0
  30. package/package.json +52 -50
  31. package/dist/domain/DeleteReferentialAction.js +0 -1
  32. package/dist/domain/Model.js +0 -1
  33. package/dist/domain/UpdateReferentialAction.js +0 -1
  34. package/dist/domain/internal/InternalFieldType.js +0 -10
  35. package/dist/domain/internal/InternalReferentialAction.d.ts +0 -6
  36. package/dist/domain/internal/InternalReferentialAction.js +0 -6
  37. package/dist/domain/internal/InternalRelationType.js +0 -5
  38. package/dist/domain/internal/ZodGuards.d.ts +0 -13
  39. package/dist/domain/internal/ZodGuards.js +0 -39
  40. package/dist/domain/internal/zod/hasConstructorName.js +0 -5
  41. package/dist/domain/internal/zod/index.js +0 -13
  42. package/dist/domain/internal/zod/isDate.js +0 -3
  43. package/dist/domain/internal/zod/isZodArray.js +0 -5
  44. package/dist/domain/internal/zod/isZodBoolean.js +0 -5
  45. package/dist/domain/internal/zod/isZodDate.js +0 -5
  46. package/dist/domain/internal/zod/isZodDefault.js +0 -5
  47. package/dist/domain/internal/zod/isZodNullable.js +0 -5
  48. package/dist/domain/internal/zod/isZodNumber.js +0 -5
  49. package/dist/domain/internal/zod/isZodObject.js +0 -5
  50. package/dist/domain/internal/zod/isZodOptional.js +0 -5
  51. package/dist/domain/internal/zod/isZodString.js +0 -5
  52. package/dist/model/Model.js +0 -22
  53. package/dist/model/ModelDefinition.js +0 -1
  54. package/dist/model/inferFields.js +0 -64
  55. package/dist/model-DE1qDItF.js +0 -174
  56. package/dist/model-DE1qDItF.js.map +0 -1
package/package.json CHANGED
@@ -1,54 +1,56 @@
1
1
  {
2
- "name": "@danceroutine/tango-schema",
3
- "version": "0.1.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"
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
- "files": [
23
- "dist"
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
- "keywords": [
32
- "tango",
33
- "schema",
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';
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- import { InternalReferentialAction } from './internal/InternalReferentialAction';
@@ -1,10 +0,0 @@
1
- export const InternalFieldType = {
2
- SERIAL: 'serial',
3
- INT: 'int',
4
- BIGINT: 'bigint',
5
- TEXT: 'text',
6
- BOOL: 'bool',
7
- TIMESTAMPTZ: 'timestamptz',
8
- JSONB: 'jsonb',
9
- UUID: 'uuid',
10
- };
@@ -1,6 +0,0 @@
1
- export declare const InternalReferentialAction: {
2
- readonly CASCADE: "CASCADE";
3
- readonly SET_NULL: "SET NULL";
4
- readonly RESTRICT: "RESTRICT";
5
- readonly NO_ACTION: "NO ACTION";
6
- };
@@ -1,6 +0,0 @@
1
- export const InternalReferentialAction = {
2
- CASCADE: 'CASCADE',
3
- SET_NULL: 'SET NULL',
4
- RESTRICT: 'RESTRICT',
5
- NO_ACTION: 'NO ACTION',
6
- };
@@ -1,5 +0,0 @@
1
- export const InternalRelationType = {
2
- HAS_MANY: 'hasMany',
3
- BELONGS_TO: 'belongsTo',
4
- HAS_ONE: 'hasOne',
5
- };
@@ -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,5 +0,0 @@
1
- export function hasConstructorName(value, name) {
2
- return (!!value &&
3
- typeof value === 'object' &&
4
- value.constructor?.name === name);
5
- }
@@ -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';
@@ -1,3 +0,0 @@
1
- export function isDate(value) {
2
- return value != null && Object.prototype.toString.call(value) === '[object Date]';
3
- }
@@ -1,5 +0,0 @@
1
- import { z } from 'zod';
2
- import { hasConstructorName } from './hasConstructorName';
3
- export function isZodArray(value) {
4
- return hasConstructorName(value, 'ZodArray');
5
- }
@@ -1,5 +0,0 @@
1
- import { z } from 'zod';
2
- import { hasConstructorName } from './hasConstructorName';
3
- export function isZodBoolean(value) {
4
- return hasConstructorName(value, 'ZodBoolean');
5
- }
@@ -1,5 +0,0 @@
1
- import { z } from 'zod';
2
- import { hasConstructorName } from './hasConstructorName';
3
- export function isZodDate(value) {
4
- return hasConstructorName(value, 'ZodDate');
5
- }
@@ -1,5 +0,0 @@
1
- import { z } from 'zod';
2
- import { hasConstructorName } from './hasConstructorName';
3
- export function isZodDefault(value) {
4
- return hasConstructorName(value, 'ZodDefault');
5
- }
@@ -1,5 +0,0 @@
1
- import { z } from 'zod';
2
- import { hasConstructorName } from './hasConstructorName';
3
- export function isZodNullable(value) {
4
- return hasConstructorName(value, 'ZodNullable');
5
- }
@@ -1,5 +0,0 @@
1
- import { z } from 'zod';
2
- import { hasConstructorName } from './hasConstructorName';
3
- export function isZodNumber(value) {
4
- return hasConstructorName(value, 'ZodNumber');
5
- }
@@ -1,5 +0,0 @@
1
- import { z } from 'zod';
2
- import { hasConstructorName } from './hasConstructorName';
3
- export function isZodObject(value) {
4
- return hasConstructorName(value, 'ZodObject');
5
- }
@@ -1,5 +0,0 @@
1
- import { z } from 'zod';
2
- import { hasConstructorName } from './hasConstructorName';
3
- export function isZodOptional(value) {
4
- return hasConstructorName(value, 'ZodOptional');
5
- }
@@ -1,5 +0,0 @@
1
- import { z } from 'zod';
2
- import { hasConstructorName } from './hasConstructorName';
3
- export function isZodString(value) {
4
- return hasConstructorName(value, 'ZodString');
5
- }
@@ -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
- }
@@ -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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"}