@vibeorm/parser 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/README.md +66 -0
- package/package.json +42 -0
- package/src/index.ts +27 -0
- package/src/parser.ts +688 -0
- package/src/schema-validator.ts +625 -0
- package/src/types.ts +223 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VibeORM Intermediate Representation (IR)
|
|
3
|
+
*
|
|
4
|
+
* The parser transforms a raw prisma-ast AST into this well-typed IR,
|
|
5
|
+
* resolving relations, type mappings, constraints, and defaults.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ─── Scalar Type Mapping ──────────────────────────────────────────
|
|
9
|
+
|
|
10
|
+
export type PrismaScalarType =
|
|
11
|
+
| "String"
|
|
12
|
+
| "Boolean"
|
|
13
|
+
| "Int"
|
|
14
|
+
| "BigInt"
|
|
15
|
+
| "Float"
|
|
16
|
+
| "Decimal"
|
|
17
|
+
| "DateTime"
|
|
18
|
+
| "Json"
|
|
19
|
+
| "Bytes";
|
|
20
|
+
|
|
21
|
+
export type TypeScriptType =
|
|
22
|
+
| "string"
|
|
23
|
+
| "boolean"
|
|
24
|
+
| "number"
|
|
25
|
+
| "bigint"
|
|
26
|
+
| "Date"
|
|
27
|
+
| "JsonValue"
|
|
28
|
+
| "Buffer";
|
|
29
|
+
|
|
30
|
+
export type PostgresType =
|
|
31
|
+
| "text"
|
|
32
|
+
| "varchar"
|
|
33
|
+
| "char"
|
|
34
|
+
| "uuid"
|
|
35
|
+
| "boolean"
|
|
36
|
+
| "integer"
|
|
37
|
+
| "bigint"
|
|
38
|
+
| "double precision"
|
|
39
|
+
| "decimal"
|
|
40
|
+
| "timestamp"
|
|
41
|
+
| "timestamptz"
|
|
42
|
+
| "jsonb"
|
|
43
|
+
| "json"
|
|
44
|
+
| "bytea"
|
|
45
|
+
| "serial"
|
|
46
|
+
| "bigserial"
|
|
47
|
+
| "smallint"
|
|
48
|
+
| "real";
|
|
49
|
+
|
|
50
|
+
export const PRISMA_TO_TS: Record<PrismaScalarType, TypeScriptType> = {
|
|
51
|
+
String: "string",
|
|
52
|
+
Boolean: "boolean",
|
|
53
|
+
Int: "number",
|
|
54
|
+
BigInt: "bigint",
|
|
55
|
+
Float: "number",
|
|
56
|
+
Decimal: "string", // Decimal is represented as string for precision
|
|
57
|
+
DateTime: "Date",
|
|
58
|
+
Json: "JsonValue",
|
|
59
|
+
Bytes: "Buffer",
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const PRISMA_TO_PG: Record<PrismaScalarType, PostgresType> = {
|
|
63
|
+
String: "text",
|
|
64
|
+
Boolean: "boolean",
|
|
65
|
+
Int: "integer",
|
|
66
|
+
BigInt: "bigint",
|
|
67
|
+
Float: "double precision",
|
|
68
|
+
Decimal: "decimal",
|
|
69
|
+
DateTime: "timestamptz",
|
|
70
|
+
Json: "jsonb",
|
|
71
|
+
Bytes: "bytea",
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// ─── Default Values ───────────────────────────────────────────────
|
|
75
|
+
|
|
76
|
+
export type DefaultValue =
|
|
77
|
+
| { kind: "autoincrement" }
|
|
78
|
+
| { kind: "now" }
|
|
79
|
+
| { kind: "uuid" }
|
|
80
|
+
| { kind: "cuid" }
|
|
81
|
+
| { kind: "nanoid" }
|
|
82
|
+
| { kind: "ulid" }
|
|
83
|
+
| { kind: "dbgenerated"; value: string }
|
|
84
|
+
| { kind: "literal"; value: string | number | boolean };
|
|
85
|
+
|
|
86
|
+
// ─── Relation Types ───────────────────────────────────────────────
|
|
87
|
+
|
|
88
|
+
export type RelationType =
|
|
89
|
+
| "oneToOne"
|
|
90
|
+
| "oneToMany"
|
|
91
|
+
| "manyToOne"
|
|
92
|
+
| "manyToMany";
|
|
93
|
+
|
|
94
|
+
export type RelationInfo = {
|
|
95
|
+
/** The name of the @relation("name") if specified */
|
|
96
|
+
name: string | undefined;
|
|
97
|
+
/** The field names on this model that hold the FK (e.g. ["authorId"]) */
|
|
98
|
+
fields: string[];
|
|
99
|
+
/** The field names on the related model that are referenced (e.g. ["id"]) */
|
|
100
|
+
references: string[];
|
|
101
|
+
/** The name of the related model */
|
|
102
|
+
relatedModel: string;
|
|
103
|
+
/** The resolved relation type */
|
|
104
|
+
type: RelationType;
|
|
105
|
+
/** Whether this side owns the FK (has fields/references) */
|
|
106
|
+
isForeignKey: boolean;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// ─── Field ────────────────────────────────────────────────────────
|
|
110
|
+
|
|
111
|
+
export type ScalarField = {
|
|
112
|
+
kind: "scalar";
|
|
113
|
+
name: string;
|
|
114
|
+
/** The DB column name (from @map or defaults to name) */
|
|
115
|
+
dbName: string;
|
|
116
|
+
/** The Prisma type (String, Int, etc.) */
|
|
117
|
+
prismaType: PrismaScalarType;
|
|
118
|
+
/** The TypeScript type */
|
|
119
|
+
tsType: TypeScriptType;
|
|
120
|
+
/** The PostgreSQL column type */
|
|
121
|
+
pgType: PostgresType;
|
|
122
|
+
/** Whether the field is required (not optional) */
|
|
123
|
+
isRequired: boolean;
|
|
124
|
+
/** Whether the field is a list (PostgreSQL array) */
|
|
125
|
+
isList: boolean;
|
|
126
|
+
/** Whether this field is the @id */
|
|
127
|
+
isId: boolean;
|
|
128
|
+
/** Whether this field has @unique */
|
|
129
|
+
isUnique: boolean;
|
|
130
|
+
/** Whether this field has @updatedAt */
|
|
131
|
+
isUpdatedAt: boolean;
|
|
132
|
+
/** The @default value if present */
|
|
133
|
+
default: DefaultValue | undefined;
|
|
134
|
+
/** Native database type override (@db.VarChar(255)) */
|
|
135
|
+
nativeType: string | undefined;
|
|
136
|
+
/** Triple-slash documentation comment (///) */
|
|
137
|
+
documentation: string | undefined;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export type EnumField = {
|
|
141
|
+
kind: "enum";
|
|
142
|
+
name: string;
|
|
143
|
+
dbName: string;
|
|
144
|
+
/** The name of the enum type */
|
|
145
|
+
enumName: string;
|
|
146
|
+
isRequired: boolean;
|
|
147
|
+
isList: boolean;
|
|
148
|
+
isId: boolean;
|
|
149
|
+
isUnique: boolean;
|
|
150
|
+
default: DefaultValue | undefined;
|
|
151
|
+
/** Triple-slash documentation comment (///) */
|
|
152
|
+
documentation: string | undefined;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export type RelationField = {
|
|
156
|
+
kind: "relation";
|
|
157
|
+
name: string;
|
|
158
|
+
/** The related model name */
|
|
159
|
+
relatedModel: string;
|
|
160
|
+
/** Whether this is a list relation (Post[]) */
|
|
161
|
+
isList: boolean;
|
|
162
|
+
/** Whether the field is optional (Profile?) */
|
|
163
|
+
isRequired: boolean;
|
|
164
|
+
/** Full relation info */
|
|
165
|
+
relation: RelationInfo;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export type Field = ScalarField | EnumField | RelationField;
|
|
169
|
+
|
|
170
|
+
// ─── Constraints ──────────────────────────────────────────────────
|
|
171
|
+
|
|
172
|
+
export type PrimaryKey = {
|
|
173
|
+
fields: string[];
|
|
174
|
+
isComposite: boolean;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export type UniqueConstraint = {
|
|
178
|
+
fields: string[];
|
|
179
|
+
name: string | undefined;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export type IndexDefinition = {
|
|
183
|
+
fields: string[];
|
|
184
|
+
name: string | undefined;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
// ─── Model ────────────────────────────────────────────────────────
|
|
188
|
+
|
|
189
|
+
export type Model = {
|
|
190
|
+
name: string;
|
|
191
|
+
/** The DB table name (from @@map or defaults to name) */
|
|
192
|
+
dbName: string;
|
|
193
|
+
/** All fields including scalars, enums, and relations */
|
|
194
|
+
fields: Field[];
|
|
195
|
+
/** The primary key */
|
|
196
|
+
primaryKey: PrimaryKey;
|
|
197
|
+
/** @@unique constraints */
|
|
198
|
+
uniqueConstraints: UniqueConstraint[];
|
|
199
|
+
/** @@index definitions */
|
|
200
|
+
indexes: IndexDefinition[];
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
// ─── Enum ─────────────────────────────────────────────────────────
|
|
204
|
+
|
|
205
|
+
export type EnumValue = {
|
|
206
|
+
name: string;
|
|
207
|
+
/** @map("DB_VALUE") if specified */
|
|
208
|
+
dbName: string | undefined;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
export type Enum = {
|
|
212
|
+
name: string;
|
|
213
|
+
/** @@map("db_name") if specified */
|
|
214
|
+
dbName: string | undefined;
|
|
215
|
+
values: EnumValue[];
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// ─── Schema (top-level IR) ────────────────────────────────────────
|
|
219
|
+
|
|
220
|
+
export type Schema = {
|
|
221
|
+
models: Model[];
|
|
222
|
+
enums: Enum[];
|
|
223
|
+
};
|