@everystack/model 0.3.3 → 0.3.5
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 +2 -0
- package/package.json +1 -1
- package/src/drizzle.ts +9 -0
- package/src/field.ts +10 -1
- package/src/model.ts +12 -0
package/README.md
CHANGED
|
@@ -74,6 +74,8 @@ export const models = [Account, Note];
|
|
|
74
74
|
|
|
75
75
|
Modifiers: `.primaryKey()`, `.notNull()` / `.nullable()`, `.unique()`, `.default(value)` / `.defaultNow()` / `.defaultRandom()`, `.references(() => Other, { onDelete, onUpdate })`, `.private()` (never serialized), `.readonly()` (never accepted on write), `.validate(zodSchema)`, and `.renamedFrom('oldField')` (turns a drop+add into a data-preserving `RENAME COLUMN`).
|
|
76
76
|
|
|
77
|
+
Renaming a whole table works the same way, at the model level: `defineModel('articles', { renamedFrom: 'posts', ... })` compiles to one `ALTER TABLE … RENAME TO …` (data preserved, policies ride along) instead of CREATE plus a held DROP. Both markers are one-shot — remove them once every environment is past the state; a satisfied rename is an inert notice.
|
|
78
|
+
|
|
77
79
|
`.validate(...)` does double duty: the SQL-expressible refinements (`min`/`max`/`length`/range/enum) become a Postgres `CHECK` — the backstop for the SSR-direct write path that never runs app-layer Zod — while richer refinements stay app-layer only.
|
|
78
80
|
|
|
79
81
|
## Constraints
|
package/package.json
CHANGED
package/src/drizzle.ts
CHANGED
|
@@ -22,7 +22,10 @@ import {
|
|
|
22
22
|
uuid,
|
|
23
23
|
integer,
|
|
24
24
|
bigint,
|
|
25
|
+
serial,
|
|
25
26
|
bigserial,
|
|
27
|
+
real,
|
|
28
|
+
doublePrecision,
|
|
26
29
|
boolean,
|
|
27
30
|
timestamp,
|
|
28
31
|
date,
|
|
@@ -74,8 +77,14 @@ function baseColumn(columnName: string, spec: FieldSpec): PgColumnBuilderBase {
|
|
|
74
77
|
return integer(columnName);
|
|
75
78
|
case 'bigint':
|
|
76
79
|
return bigint(columnName, { mode: 'number' });
|
|
80
|
+
case 'serial':
|
|
81
|
+
return serial(columnName);
|
|
77
82
|
case 'bigserial':
|
|
78
83
|
return bigserial(columnName, { mode: 'number' });
|
|
84
|
+
case 'real':
|
|
85
|
+
return real(columnName);
|
|
86
|
+
case 'doublePrecision':
|
|
87
|
+
return doublePrecision(columnName);
|
|
79
88
|
case 'boolean':
|
|
80
89
|
return boolean(columnName);
|
|
81
90
|
case 'timestamptz':
|
package/src/field.ts
CHANGED
|
@@ -15,8 +15,11 @@ export type FieldType =
|
|
|
15
15
|
| 'text'
|
|
16
16
|
| 'uuid'
|
|
17
17
|
| 'bigint'
|
|
18
|
+
| 'serial'
|
|
18
19
|
| 'bigserial'
|
|
19
20
|
| 'integer'
|
|
21
|
+
| 'real'
|
|
22
|
+
| 'doublePrecision'
|
|
20
23
|
| 'boolean'
|
|
21
24
|
| 'timestamptz'
|
|
22
25
|
| 'timestamp'
|
|
@@ -186,8 +189,14 @@ export const field = {
|
|
|
186
189
|
text: (): FieldBuilder => new FieldBuilder('text'),
|
|
187
190
|
uuid: (): FieldBuilder => new FieldBuilder('uuid'),
|
|
188
191
|
bigint: (): FieldBuilder => new FieldBuilder('bigint'),
|
|
189
|
-
|
|
192
|
+
// A serial column is NOT NULL by Postgres definition, so the builder starts that way.
|
|
193
|
+
serial: (): FieldBuilder => new FieldBuilder('serial').notNull(),
|
|
194
|
+
bigserial: (): FieldBuilder => new FieldBuilder('bigserial').notNull(),
|
|
190
195
|
integer: (): FieldBuilder => new FieldBuilder('integer'),
|
|
196
|
+
/** `real` — single-precision float (float4). */
|
|
197
|
+
real: (): FieldBuilder => new FieldBuilder('real'),
|
|
198
|
+
/** `double precision` — double-precision float (float8). */
|
|
199
|
+
doublePrecision: (): FieldBuilder => new FieldBuilder('doublePrecision'),
|
|
191
200
|
boolean: (): FieldBuilder => new FieldBuilder('boolean'),
|
|
192
201
|
timestamptz: (): FieldBuilder => new FieldBuilder('timestamptz'),
|
|
193
202
|
timestamp: (): FieldBuilder => new FieldBuilder('timestamp'),
|
package/src/model.ts
CHANGED
|
@@ -63,6 +63,15 @@ export interface ModelDefinition {
|
|
|
63
63
|
* can span schemas — the model's schema always wins over a generate call's default.
|
|
64
64
|
*/
|
|
65
65
|
schema?: string;
|
|
66
|
+
/**
|
|
67
|
+
* `renamedFrom: 'old_table'` — a one-shot migration hint, the table-level
|
|
68
|
+
* analog of `field.renamedFrom()`. A diff cannot distinguish RENAME from
|
|
69
|
+
* DROP+ADD; the marker carries the intent, so the diff emits one
|
|
70
|
+
* `ALTER TABLE … RENAME TO …` (data preserved) instead of CREATE plus a
|
|
71
|
+
* held DROP. Same schema as the model. Remove it once every environment
|
|
72
|
+
* is past the state — a satisfied rename is an inert notice.
|
|
73
|
+
*/
|
|
74
|
+
renamedFrom?: string;
|
|
66
75
|
/**
|
|
67
76
|
* `true` removes the table from the generic data API — `deriveHandlerConfig`
|
|
68
77
|
* skips it, so it never enters `exposedTables`. Default `false`. Package-owned
|
|
@@ -90,6 +99,8 @@ export interface ModelDescriptor {
|
|
|
90
99
|
schema: string;
|
|
91
100
|
/** `true` removes the table from the generic data API (not in `exposedTables`). Default `false`. */
|
|
92
101
|
private: boolean;
|
|
102
|
+
/** One-shot rename hint: this table used to be named `renamedFrom` (same schema). */
|
|
103
|
+
renamedFrom?: string;
|
|
93
104
|
}
|
|
94
105
|
|
|
95
106
|
export function defineModel(table: string, def: ModelDefinition): ModelDescriptor {
|
|
@@ -108,5 +119,6 @@ export function defineModel(table: string, def: ModelDefinition): ModelDescripto
|
|
|
108
119
|
writtenBy: def.writtenBy ?? 'app',
|
|
109
120
|
schema: def.schema ?? 'public',
|
|
110
121
|
private: def.private ?? false,
|
|
122
|
+
...(def.renamedFrom ? { renamedFrom: def.renamedFrom } : {}),
|
|
111
123
|
};
|
|
112
124
|
}
|