@sequenceholdings/orm 0.1.0 → 0.1.2
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 +1 -1
- package/dist/authoring.cjs +794 -0
- package/dist/authoring.cjs.map +1 -0
- package/dist/authoring.d.cts +274 -0
- package/dist/authoring.d.ts +274 -0
- package/dist/authoring.js +763 -0
- package/dist/authoring.js.map +1 -0
- package/dist/canonical.cjs +146 -0
- package/dist/canonical.cjs.map +1 -0
- package/dist/canonical.d.cts +369 -0
- package/dist/canonical.d.ts +369 -0
- package/dist/canonical.js +131 -0
- package/dist/canonical.js.map +1 -0
- package/dist/cli.cjs +6208 -1693
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +8 -1
- package/dist/cli.d.ts +8 -1
- package/dist/cli.js +6262 -1749
- package/dist/cli.js.map +1 -1
- package/dist/client.cjs +120 -0
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +74 -2
- package/dist/client.d.ts +74 -2
- package/dist/client.js +116 -1
- package/dist/client.js.map +1 -1
- package/dist/compiler.cjs +3001 -0
- package/dist/compiler.cjs.map +1 -0
- package/dist/compiler.d.cts +581 -0
- package/dist/compiler.d.ts +581 -0
- package/dist/compiler.js +2947 -0
- package/dist/compiler.js.map +1 -0
- package/dist/index.cjs +1730 -327
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +126 -56
- package/dist/index.d.ts +126 -56
- package/dist/index.js +1643 -324
- package/dist/index.js.map +1 -1
- package/dist/ir.cjs +407 -0
- package/dist/ir.cjs.map +1 -0
- package/dist/ir.d.cts +1179 -0
- package/dist/ir.d.ts +1179 -0
- package/dist/ir.js +388 -0
- package/dist/ir.js.map +1 -0
- package/dist/naming-CTvWSRTf.d.ts +79 -0
- package/dist/naming-DRyinU4u.d.cts +79 -0
- package/dist/sdl.cjs +833 -0
- package/dist/sdl.cjs.map +1 -0
- package/dist/sdl.d.cts +96 -0
- package/dist/sdl.d.ts +96 -0
- package/dist/sdl.js +809 -0
- package/dist/sdl.js.map +1 -0
- package/package.json +36 -3
- package/src/codegen-gql/apollo-hooks.cjs +98 -0
- package/src/codegen-gql/server-fns.cjs +101 -0
- package/templates/README.md +13 -0
- package/templates/orm-namespace/CLAUDE.md +81 -0
- package/templates/orm-namespace/codegen.ts +22 -0
- package/templates/orm-namespace/gitignore +5 -0
- package/templates/orm-namespace/graphql/example/queries.ts +56 -0
- package/templates/orm-namespace/package.json +24 -0
- package/templates/orm-namespace/schema/tables.ts +71 -0
- package/templates/orm-namespace/sequence.config.ts +32 -0
- package/templates/orm-namespace/tsconfig.json +15 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { ColumnType, CanonicalColumn, CanonicalDefinition } from './canonical.js';
|
|
2
|
+
import 'zod';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Fluent column builders for the v2 authoring surface — `t.uuid()`,
|
|
6
|
+
* `t.text().notNull().unique()`, `t.enum(status).default('open')`, …
|
|
7
|
+
*
|
|
8
|
+
* Builders carry plain serializable state and produce `CanonicalColumn` data
|
|
9
|
+
* (canonical definition v2). They never touch Drizzle: the server builds
|
|
10
|
+
* Drizzle entities from canonical JSON, consumer TypeScript never runs
|
|
11
|
+
* server-side (plan §2).
|
|
12
|
+
*
|
|
13
|
+
* Cross-copy safety: the jiti loader evaluates its own transpiled copy of
|
|
14
|
+
* this module, so identification uses the `kind` brand — never `instanceof`.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
declare const COLUMN_BRAND: "seq-column";
|
|
18
|
+
declare const ENUM_BRAND: "seq-enum";
|
|
19
|
+
/** A namespace-level Postgres enum, created with `defineEnum` (table.ts). */
|
|
20
|
+
interface EnumRef {
|
|
21
|
+
readonly kind: typeof ENUM_BRAND;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly values: readonly string[];
|
|
24
|
+
}
|
|
25
|
+
declare function isEnumRef(value: unknown): value is EnumRef;
|
|
26
|
+
/** The allowlisted SQL default functions — `.default('now()')` maps here, not to a literal. */
|
|
27
|
+
declare const COLUMN_DEFAULT_FNS: readonly ["gen_random_uuid()", "now()"];
|
|
28
|
+
type ColumnDefaultFn = (typeof COLUMN_DEFAULT_FNS)[number];
|
|
29
|
+
type ColumnDefaultLiteral = string | number | boolean | null;
|
|
30
|
+
type ColumnTypeSpec = ColumnType | {
|
|
31
|
+
readonly enum: string;
|
|
32
|
+
};
|
|
33
|
+
/** `authorSub` → `author_sub`, `authorURLPath` → `author_url_path`. */
|
|
34
|
+
declare function deriveColumnName(propertyName: string): string;
|
|
35
|
+
declare class ColumnBuilder {
|
|
36
|
+
readonly kind: "seq-column";
|
|
37
|
+
private readonly state;
|
|
38
|
+
constructor(type: ColumnTypeSpec, columnName?: string);
|
|
39
|
+
/** Marks this column as (part of) the primary key. Implies NOT NULL. */
|
|
40
|
+
primaryKey(): this;
|
|
41
|
+
notNull(): this;
|
|
42
|
+
unique(): this;
|
|
43
|
+
/**
|
|
44
|
+
* Column default: a literal, or one of the allowlisted SQL functions
|
|
45
|
+
* (`'gen_random_uuid()'` / `'now()'`), which serialize as `defaultFn`.
|
|
46
|
+
*/
|
|
47
|
+
default(value: ColumnDefaultLiteral): this;
|
|
48
|
+
description(text: string): this;
|
|
49
|
+
/** Migration rename hint: the previous Postgres column name. */
|
|
50
|
+
renamedFrom(previousColumnName: string): this;
|
|
51
|
+
/** Migration cast hint: the `USING` SQL applied when this column changes type. */
|
|
52
|
+
cast(usingSql: string): this;
|
|
53
|
+
/** Emits `@deprecated` in the generated SDL; the column stays queryable. */
|
|
54
|
+
deprecated(): this;
|
|
55
|
+
/** Whether `.primaryKey()` was called — collected into the table-level PK. */
|
|
56
|
+
get isPrimaryKey(): boolean;
|
|
57
|
+
/** The enum name when this is an enum column, else undefined. */
|
|
58
|
+
get enumName(): string | undefined;
|
|
59
|
+
/** Postgres column name: explicit override, else snake_case of the property name. */
|
|
60
|
+
columnNameFor(propertyName: string): string;
|
|
61
|
+
/** Serialize to a canonical v2 column. Validation happens in serializeNamespace. */
|
|
62
|
+
toCanonicalColumn(propertyName: string): CanonicalColumn;
|
|
63
|
+
}
|
|
64
|
+
declare function isColumnBuilder(value: unknown): value is ColumnBuilder;
|
|
65
|
+
/**
|
|
66
|
+
* The column-type factory. The optional argument overrides the derived
|
|
67
|
+
* snake_case Postgres column name: `t.text('legacy_name')`.
|
|
68
|
+
*/
|
|
69
|
+
declare const t: {
|
|
70
|
+
readonly uuid: (columnName?: string) => ColumnBuilder;
|
|
71
|
+
readonly text: (columnName?: string) => ColumnBuilder;
|
|
72
|
+
readonly integer: (columnName?: string) => ColumnBuilder;
|
|
73
|
+
readonly bigint: (columnName?: string) => ColumnBuilder;
|
|
74
|
+
readonly numeric: (columnName?: string) => ColumnBuilder;
|
|
75
|
+
readonly double: (columnName?: string) => ColumnBuilder;
|
|
76
|
+
readonly boolean: (columnName?: string) => ColumnBuilder;
|
|
77
|
+
readonly timestamptz: (columnName?: string) => ColumnBuilder;
|
|
78
|
+
readonly date: (columnName?: string) => ColumnBuilder;
|
|
79
|
+
readonly jsonb: (columnName?: string) => ColumnBuilder;
|
|
80
|
+
readonly enum: (ref: EnumRef, columnName?: string) => ColumnBuilder;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
declare const TABLE_BRAND: "seq-table";
|
|
84
|
+
declare const LINK_BRAND: "seq-link";
|
|
85
|
+
/** A link target: the table itself, or a lazy thunk for forward/cyclic references. */
|
|
86
|
+
type TableRef = SeqTable | (() => SeqTable);
|
|
87
|
+
type LinkKind = 'toOne' | 'toMany' | 'toPlatformUser';
|
|
88
|
+
interface SeqLink {
|
|
89
|
+
readonly kind: typeof LINK_BRAND;
|
|
90
|
+
readonly linkKind: LinkKind;
|
|
91
|
+
/** Absent for toPlatformUser — the platform-users view needs no target. */
|
|
92
|
+
readonly target: TableRef | undefined;
|
|
93
|
+
/** FK column (property or column name). toOne/toPlatformUser: on this table; toMany: on the target. */
|
|
94
|
+
readonly on: string;
|
|
95
|
+
readonly references: string | undefined;
|
|
96
|
+
readonly enforce: boolean;
|
|
97
|
+
readonly description: string | undefined;
|
|
98
|
+
}
|
|
99
|
+
interface ToOneOptions {
|
|
100
|
+
on: string;
|
|
101
|
+
references?: string;
|
|
102
|
+
/** Emit a real FK constraint (same-namespace toOne only). */
|
|
103
|
+
enforce?: boolean;
|
|
104
|
+
description?: string;
|
|
105
|
+
}
|
|
106
|
+
interface ToManyOptions {
|
|
107
|
+
on: string;
|
|
108
|
+
references?: string;
|
|
109
|
+
description?: string;
|
|
110
|
+
}
|
|
111
|
+
interface ToPlatformUserOptions {
|
|
112
|
+
/** Column on this table holding the platform user `sub` (or `references` override). */
|
|
113
|
+
on: string;
|
|
114
|
+
references?: string;
|
|
115
|
+
description?: string;
|
|
116
|
+
}
|
|
117
|
+
declare function toOne(target: TableRef, options: ToOneOptions): SeqLink;
|
|
118
|
+
declare function toMany(target: TableRef, options: ToManyOptions): SeqLink;
|
|
119
|
+
/** Link to the built-in read-only platform-users view (plan §4b) — no table definition needed. */
|
|
120
|
+
declare function toPlatformUser(options: ToPlatformUserOptions): SeqLink;
|
|
121
|
+
declare function isSeqLink(value: unknown): value is SeqLink;
|
|
122
|
+
interface PolicyVariantInput {
|
|
123
|
+
/** Claims-only guard: `capability('x')` / `role('y')` / claim comparisons. */
|
|
124
|
+
when: string;
|
|
125
|
+
/** Exactly one of `allow: true` or `policy` (validated at serialize time). */
|
|
126
|
+
allow?: true;
|
|
127
|
+
policy?: string;
|
|
128
|
+
}
|
|
129
|
+
interface PolicyWithVariantsInput {
|
|
130
|
+
default: string;
|
|
131
|
+
variants?: readonly PolicyVariantInput[];
|
|
132
|
+
}
|
|
133
|
+
/** A policy: a DSL source string, or a default + per-role/capability variants (§4c). */
|
|
134
|
+
type PolicyInput = string | PolicyWithVariantsInput;
|
|
135
|
+
interface TablePoliciesInput {
|
|
136
|
+
read?: PolicyInput;
|
|
137
|
+
write?: PolicyInput;
|
|
138
|
+
}
|
|
139
|
+
interface IndexInput {
|
|
140
|
+
/** Property names (camelCase) or Postgres column names. */
|
|
141
|
+
columns: readonly string[];
|
|
142
|
+
unique?: boolean;
|
|
143
|
+
name?: string;
|
|
144
|
+
}
|
|
145
|
+
interface ActionParamInput {
|
|
146
|
+
type: ColumnType;
|
|
147
|
+
nullable?: boolean;
|
|
148
|
+
}
|
|
149
|
+
interface ActionInput {
|
|
150
|
+
name: string;
|
|
151
|
+
requires?: string;
|
|
152
|
+
params?: Record<string, ActionParamInput>;
|
|
153
|
+
executes: string;
|
|
154
|
+
returns?: 'rows' | 'rowsAffected' | 'scalar';
|
|
155
|
+
audit?: {
|
|
156
|
+
action: string;
|
|
157
|
+
resource: string;
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
interface TableConfig {
|
|
161
|
+
description?: string;
|
|
162
|
+
/** Table-level migration rename hint (new in v2). */
|
|
163
|
+
renamedFrom?: string;
|
|
164
|
+
/** Composite primary key: property names (or column names). Mutually exclusive with column-level `.primaryKey()`. */
|
|
165
|
+
primaryKey?: readonly string[];
|
|
166
|
+
indexes?: readonly IndexInput[];
|
|
167
|
+
links?: Record<string, SeqLink>;
|
|
168
|
+
policies?: TablePoliciesInput;
|
|
169
|
+
actions?: readonly ActionInput[];
|
|
170
|
+
}
|
|
171
|
+
interface SeqTable {
|
|
172
|
+
readonly kind: typeof TABLE_BRAND;
|
|
173
|
+
readonly tableName: string;
|
|
174
|
+
readonly columns: Readonly<Record<string, ColumnBuilder>>;
|
|
175
|
+
readonly config: TableConfig;
|
|
176
|
+
/** Synced reflected source (`gold.*`) — set only by defineSyncedTable. */
|
|
177
|
+
readonly source: string | undefined;
|
|
178
|
+
/** Consumer file that defined the table (set when loaded via loadNamespaceFromDir). */
|
|
179
|
+
readonly file: string | undefined;
|
|
180
|
+
}
|
|
181
|
+
declare function isSeqTable(value: unknown): value is SeqTable;
|
|
182
|
+
declare function defineTable(name: string, columns: Record<string, ColumnBuilder>, config?: TableConfig): SeqTable;
|
|
183
|
+
interface SyncedTableConfig {
|
|
184
|
+
/** Reflected read-only source, restricted to the gold layer: `gold.<table>`. */
|
|
185
|
+
source: string;
|
|
186
|
+
description?: string;
|
|
187
|
+
}
|
|
188
|
+
declare function defineSyncedTable(name: string, config: SyncedTableConfig): SeqTable;
|
|
189
|
+
declare function defineEnum(name: string, values: readonly string[]): EnumRef;
|
|
190
|
+
|
|
191
|
+
declare const NAMESPACE_CONFIG_BRAND: "seq-namespace-config";
|
|
192
|
+
interface NamespaceCapabilitiesInput {
|
|
193
|
+
/** Verbatim custom-roles grammar (@sequenceholdings/custom-roles-manifest). */
|
|
194
|
+
roles?: unknown;
|
|
195
|
+
/** Org-level capability pins this namespace attaches to. */
|
|
196
|
+
uses?: readonly string[];
|
|
197
|
+
}
|
|
198
|
+
interface NamespaceConfigInput {
|
|
199
|
+
namespace: string;
|
|
200
|
+
description?: string;
|
|
201
|
+
capabilities?: NamespaceCapabilitiesInput;
|
|
202
|
+
}
|
|
203
|
+
interface SeqNamespaceConfig {
|
|
204
|
+
readonly kind: typeof NAMESPACE_CONFIG_BRAND;
|
|
205
|
+
readonly namespace: string;
|
|
206
|
+
readonly description: string | undefined;
|
|
207
|
+
readonly capabilities: NamespaceCapabilitiesInput;
|
|
208
|
+
readonly file: string | undefined;
|
|
209
|
+
}
|
|
210
|
+
declare function isSeqNamespaceConfig(value: unknown): value is SeqNamespaceConfig;
|
|
211
|
+
declare function defineNamespace(input: NamespaceConfigInput): SeqNamespaceConfig;
|
|
212
|
+
interface SerializeNamespaceInput {
|
|
213
|
+
config: SeqNamespaceConfig;
|
|
214
|
+
tables: readonly SeqTable[];
|
|
215
|
+
enums?: readonly EnumRef[];
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Serialize the authored namespace to a validated, normalized
|
|
219
|
+
* `CanonicalDefinition` (definition_format: 2). Throws `OrmDefinitionError`
|
|
220
|
+
* naming the table/file on any inconsistency.
|
|
221
|
+
*/
|
|
222
|
+
declare function serializeNamespace(input: SerializeNamespaceInput): CanonicalDefinition;
|
|
223
|
+
/** sha256 over the v1 hash domain + key-sorted JSON of the normalized canonical definition. */
|
|
224
|
+
declare function computeCanonicalHash(definition: CanonicalDefinition): string;
|
|
225
|
+
|
|
226
|
+
declare const NAMESPACE_CONFIG_FILE = "sequence.config.ts";
|
|
227
|
+
declare const SCHEMA_DIR = "schema";
|
|
228
|
+
interface LoadNamespaceOptions {
|
|
229
|
+
/**
|
|
230
|
+
* Test/dev hook: absolute path that bare `'@sequenceholdings/orm'` imports
|
|
231
|
+
* in consumer files resolve to (jiti alias). Leave unset in production —
|
|
232
|
+
* the consumer's own installed package resolves naturally.
|
|
233
|
+
*/
|
|
234
|
+
ormModulePath?: string;
|
|
235
|
+
}
|
|
236
|
+
interface LoadedNamespaceV2 {
|
|
237
|
+
readonly canonical: CanonicalDefinition;
|
|
238
|
+
readonly hash: string;
|
|
239
|
+
/** Relative paths of the files that were imported, config first. */
|
|
240
|
+
readonly files: readonly string[];
|
|
241
|
+
}
|
|
242
|
+
declare function loadNamespaceFromDir(dir: string, options?: LoadNamespaceOptions): Promise<LoadedNamespaceV2>;
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Module-registry pattern for the authoring surface: `defineTable` /
|
|
246
|
+
* `defineEnum` / `defineNamespace` register into the ACTIVE collection
|
|
247
|
+
* context while `loadNamespaceFromDir` imports a consumer's files, so the
|
|
248
|
+
* loader collects definitions without inspecting module exports.
|
|
249
|
+
*
|
|
250
|
+
* The context stack lives on `globalThis` under a `Symbol.for` key — NOT in
|
|
251
|
+
* module scope — because the jiti loader evaluates its own transpiled copy of
|
|
252
|
+
* this module when a consumer file imports '@sequenceholdings/orm'. Both
|
|
253
|
+
* copies must observe the same registrations (the graphql-js dual-package
|
|
254
|
+
* discipline), so everything registered is plain data identified by `kind`
|
|
255
|
+
* brand strings, never `instanceof`.
|
|
256
|
+
*/
|
|
257
|
+
interface AuthoringRegistration {
|
|
258
|
+
readonly value: unknown;
|
|
259
|
+
readonly file: string | undefined;
|
|
260
|
+
}
|
|
261
|
+
interface AuthoringContext {
|
|
262
|
+
/** Set by the loader before importing each consumer file — error attribution. */
|
|
263
|
+
currentFile: string | undefined;
|
|
264
|
+
readonly tables: AuthoringRegistration[];
|
|
265
|
+
readonly enums: AuthoringRegistration[];
|
|
266
|
+
readonly configs: AuthoringRegistration[];
|
|
267
|
+
}
|
|
268
|
+
/** Push a fresh collection context; every define* call registers into it until ended. */
|
|
269
|
+
declare function beginAuthoringContext(): AuthoringContext;
|
|
270
|
+
/** Pop the context; throws if collection begin/end calls are mismatched (programmer error). */
|
|
271
|
+
declare function endAuthoringContext(context: AuthoringContext): void;
|
|
272
|
+
declare function activeAuthoringContext(): AuthoringContext | undefined;
|
|
273
|
+
|
|
274
|
+
export { type ActionInput, type ActionParamInput, type AuthoringContext, type AuthoringRegistration, COLUMN_BRAND, COLUMN_DEFAULT_FNS, ColumnBuilder, type ColumnDefaultFn, type ColumnDefaultLiteral, type ColumnTypeSpec, ENUM_BRAND, type EnumRef, type IndexInput, LINK_BRAND, type LinkKind, type LoadNamespaceOptions, type LoadedNamespaceV2, NAMESPACE_CONFIG_BRAND, NAMESPACE_CONFIG_FILE, type NamespaceCapabilitiesInput, type NamespaceConfigInput, type PolicyInput, type PolicyVariantInput, type PolicyWithVariantsInput, SCHEMA_DIR, type SeqLink, type SeqNamespaceConfig, type SeqTable, type SerializeNamespaceInput, type SyncedTableConfig, TABLE_BRAND, type TableConfig, type TablePoliciesInput, type TableRef, type ToManyOptions, type ToOneOptions, type ToPlatformUserOptions, activeAuthoringContext, beginAuthoringContext, computeCanonicalHash, defineEnum, defineNamespace, defineSyncedTable, defineTable, deriveColumnName, endAuthoringContext, isColumnBuilder, isEnumRef, isSeqLink, isSeqNamespaceConfig, isSeqTable, loadNamespaceFromDir, serializeNamespace, t, toMany, toOne, toPlatformUser };
|