@schemic/core 0.1.0-alpha.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 (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +212 -0
  3. package/lib/authoring.d.ts +89 -0
  4. package/lib/authoring.js +187 -0
  5. package/lib/authoring.js.map +1 -0
  6. package/lib/chunk-C4D6JWSE.js +54 -0
  7. package/lib/chunk-C4D6JWSE.js.map +1 -0
  8. package/lib/chunk-T23RNU7G.js +304 -0
  9. package/lib/chunk-T23RNU7G.js.map +1 -0
  10. package/lib/config-TIiKDd9t.d.ts +97 -0
  11. package/lib/config.d.ts +1 -0
  12. package/lib/config.js +8 -0
  13. package/lib/config.js.map +1 -0
  14. package/lib/driver-Dh5hLKHm.d.ts +736 -0
  15. package/lib/driver.d.ts +150 -0
  16. package/lib/driver.js +47 -0
  17. package/lib/driver.js.map +1 -0
  18. package/lib/index.d.ts +84 -0
  19. package/lib/index.js +794 -0
  20. package/lib/index.js.map +1 -0
  21. package/lib/testing.d.ts +29 -0
  22. package/lib/testing.js +111 -0
  23. package/lib/testing.js.map +1 -0
  24. package/package.json +93 -0
  25. package/src/authoring.ts +304 -0
  26. package/src/cli-kit/config.ts +179 -0
  27. package/src/cli-kit/diff.ts +230 -0
  28. package/src/cli-kit/filter.ts +159 -0
  29. package/src/cli-kit/merge.ts +380 -0
  30. package/src/cli-kit/meta.ts +123 -0
  31. package/src/cli-kit/pager.ts +42 -0
  32. package/src/cli-kit/schema.ts +186 -0
  33. package/src/cli-kit/style.ts +24 -0
  34. package/src/config.ts +51 -0
  35. package/src/connection.ts +78 -0
  36. package/src/driver/driver.ts +300 -0
  37. package/src/driver/index.ts +31 -0
  38. package/src/driver/portable-ir.ts +51 -0
  39. package/src/driver/portable.ts +124 -0
  40. package/src/driver/sdk.ts +66 -0
  41. package/src/index.ts +145 -0
  42. package/src/kind/index.ts +28 -0
  43. package/src/kind/plan.ts +390 -0
  44. package/src/kind/registry.ts +225 -0
  45. package/src/testing.ts +181 -0
@@ -0,0 +1,150 @@
1
+ export { T as ApplyOptions, A as Authored, a as AuthoredDef, U as ConnectionOverrides, a3 as Definable, c as Diff, d as DiffItem, D as Driver, W as EmitOptions, a7 as KindEngine, a8 as KindPlan, a9 as KindRegistry, aa as KindSnapshot, ab as KindSpec, Y as MigrationDirection, Z as MigrationRecord, _ as MigrationStore, ad as OrderNode, af as PortableObject, ah as Ref, R as ResolvedConfig, a0 as ShadowCapability, a1 as Statement, a2 as buildKindDiff, V as driverNames, a4 as emitKinds, X as getDriver, a5 as introspectKinds, ac as lowerSchema, ae as orderObjects, ag as planKinds, $ as registerDriver, aj as snapshotKinds, ak as snapshotObjects } from './driver-Dh5hLKHm.js';
2
+ export { C as ConnectionConfigBase, a as ConnectionEntry, b as ConnectionInput, R as ResolveContext, c as connectionEntry } from './config-TIiKDd9t.js';
3
+ import 'jiti';
4
+ import 'commander';
5
+
6
+ /**
7
+ * The portable scalar set — the common denominator every driver maps to a concrete column type and
8
+ * back. A driver MAY reject scalars it cannot represent (and authoring can pin a richer DB-native
9
+ * type via `{ t: "native" }`). Names are lowercase and dialect-neutral.
10
+ */
11
+ type ScalarName = "any" | "bool" | "string" | "int" | "float" | "decimal" | "number" | "datetime" | "duration" | "uuid" | "bytes" | "null";
12
+ /**
13
+ * A dialect-independent field type. Drivers translate this to their own type expression (`emitType`)
14
+ * and parse their introspection back into it (`parseType`). `option` and `nullable` are ORTHOGONAL
15
+ * and BOTH equality-relevant — see the note on `nullable` below; never collapse them.
16
+ */
17
+ type PortableType =
18
+ /** A primitive scalar. */
19
+ {
20
+ t: "scalar";
21
+ name: ScalarName;
22
+ }
23
+ /** A literal value type, e.g. the `'active'` in `'active' | 'archived'`. */
24
+ | {
25
+ t: "literal";
26
+ value: string | number | boolean;
27
+ }
28
+ /**
29
+ * The field may be ABSENT / NONE (Surreal `option<T>`; SQL "column omitted / has a DEFAULT").
30
+ * Orthogonal to `nullable`.
31
+ */
32
+ | {
33
+ t: "option";
34
+ inner: PortableType;
35
+ }
36
+ /**
37
+ * The field may be NULL (Surreal `T | null`; SQL `NULL` vs `NOT NULL`). Orthogonal to `option`:
38
+ * `option<T>`, `T | null`, and `option<T | null>` are THREE DISTINCT types. `normalize()` folds
39
+ * `nullable(option(X))` -> `option(nullable(X))` so `.optional().nullable()` ≡ `.nullish()`.
40
+ */
41
+ | {
42
+ t: "nullable";
43
+ inner: PortableType;
44
+ }
45
+ /** An ordered, possibly length-bounded list. */
46
+ | {
47
+ t: "array";
48
+ elem: PortableType;
49
+ size?: number;
50
+ }
51
+ /** A set (distinct elements), possibly length-bounded. */
52
+ | {
53
+ t: "set";
54
+ elem: PortableType;
55
+ size?: number;
56
+ }
57
+ /** A discriminated/plain union. `normalize()` keeps `members` canonically sorted. */
58
+ | {
59
+ t: "union";
60
+ members: PortableType[];
61
+ }
62
+ /** A nested object/record literal. `flexible` allows undeclared keys (Surreal FLEXIBLE). */
63
+ | {
64
+ t: "object";
65
+ fields: Record<string, PortableType>;
66
+ flexible?: boolean;
67
+ }
68
+ /**
69
+ * A link to a row in one of `tables` (Surreal `record<a | b>`; SQL foreign key). The id-VALUE type
70
+ * is intentionally NOT modelled here — the DDL never encodes it; it lives App/Wire-side (TS-only).
71
+ */
72
+ | {
73
+ t: "record";
74
+ tables: string[];
75
+ }
76
+ /** A geometry type (Surreal-native; PostGIS or unsupported elsewhere). */
77
+ | {
78
+ t: "geometry";
79
+ kind: GeometryKind;
80
+ }
81
+ /** The bottom type (no value). */
82
+ | {
83
+ t: "never";
84
+ }
85
+ /**
86
+ * An escape hatch for a DB-specific type with no portable meaning (PG `tsvector`, etc.). Carries
87
+ * the owning driver `db` so a schema authored for one DB can't silently typecheck against another.
88
+ * `params` carries the type's parameters for parameterized natives — `numeric(p,s)`, `varchar(n)`,
89
+ * `timestamp(p)` — so a driver round-trips `numeric(10,2)` exactly. Order matters; ignored when empty.
90
+ */
91
+ | {
92
+ t: "native";
93
+ db: string;
94
+ name: string;
95
+ params?: (string | number)[];
96
+ };
97
+ type GeometryKind = "feature" | "point" | "line" | "polygon" | "multipoint" | "multiline" | "multipolygon" | "collection";
98
+ declare const scalar: (name: ScalarName) => PortableType;
99
+ declare const literal: (value: string | number | boolean) => PortableType;
100
+ /** `option<T>` — but `option<any>` collapses to `any` (any already admits NONE), matching ddl.ts. */
101
+ declare const option: (inner: PortableType) => PortableType;
102
+ /**
103
+ * `T | null` — with the fold rule `nullable(option(X))` -> `option(nullable(X))` so
104
+ * `.optional().nullable()` ≡ `.nullish()`, and `nullable(any)` collapses to `any`.
105
+ */
106
+ declare const nullable: (inner: PortableType) => PortableType;
107
+ declare const array: (elem: PortableType, size?: number) => PortableType;
108
+ declare const union: (members: PortableType[]) => PortableType;
109
+ declare const record: (tables: string[]) => PortableType;
110
+
111
+ /** CRUD permissions — each a boolean (FULL/NONE) or a dialect WHERE-expression string (carried verbatim). */
112
+ interface PortablePermissions {
113
+ select?: boolean | string;
114
+ create?: boolean | string;
115
+ update?: boolean | string;
116
+ delete?: boolean | string;
117
+ }
118
+ /** A field in the portable substrate: a structured {@link PortableType} + its dialect clauses (verbatim). */
119
+ interface PortableField {
120
+ name: string;
121
+ type: PortableType;
122
+ flexible?: boolean;
123
+ readonly?: boolean;
124
+ default?: string;
125
+ default_always?: boolean;
126
+ value?: string;
127
+ computed?: string;
128
+ assert?: string;
129
+ /**
130
+ * A field-level CHECK constraint (dialect boolean expression, carried verbatim). DISTINCT from
131
+ * `assert`: that is Surreal's `ASSERT`; this is the SQL `CHECK` a driver like Postgres emits. A
132
+ * driver maps whichever of the two it supports and surfaces the other as a capability gap.
133
+ */
134
+ check?: string;
135
+ comment?: string;
136
+ /** Referential action(s) on a foreign reference. A driver honors the actions it supports. */
137
+ reference?: {
138
+ on_delete?: string;
139
+ on_update?: string;
140
+ };
141
+ /**
142
+ * Auto-generated identity column — `GENERATED ALWAYS`/`BY DEFAULT AS IDENTITY`; a `serial`/
143
+ * auto-increment column maps here too. Absent → an ordinary column. Drivers without identity ignore it.
144
+ */
145
+ identity?: "always" | "by-default";
146
+ permissions?: PortablePermissions;
147
+ table: string;
148
+ }
149
+
150
+ export { type GeometryKind, type PortableField, type PortablePermissions, type PortableType, type ScalarName, array, literal, nullable, option, record, scalar, union };
package/lib/driver.js ADDED
@@ -0,0 +1,47 @@
1
+ import {
2
+ array,
3
+ connectionEntry,
4
+ literal,
5
+ nullable,
6
+ option,
7
+ record,
8
+ scalar,
9
+ union
10
+ } from "./chunk-C4D6JWSE.js";
11
+ import {
12
+ KindRegistry,
13
+ buildKindDiff,
14
+ driverNames,
15
+ emitKinds,
16
+ getDriver,
17
+ introspectKinds,
18
+ lowerSchema,
19
+ orderObjects,
20
+ planKinds,
21
+ registerDriver,
22
+ snapshotKinds,
23
+ snapshotObjects
24
+ } from "./chunk-T23RNU7G.js";
25
+ export {
26
+ KindRegistry,
27
+ array,
28
+ buildKindDiff,
29
+ connectionEntry,
30
+ driverNames,
31
+ emitKinds,
32
+ getDriver,
33
+ introspectKinds,
34
+ literal,
35
+ lowerSchema,
36
+ nullable,
37
+ option,
38
+ orderObjects,
39
+ planKinds,
40
+ record,
41
+ registerDriver,
42
+ scalar,
43
+ snapshotKinds,
44
+ snapshotObjects,
45
+ union
46
+ };
47
+ //# sourceMappingURL=driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/lib/index.d.ts ADDED
@@ -0,0 +1,84 @@
1
+ import { A as Authored, a as AuthoredDef } from './driver-Dh5hLKHm.js';
2
+ export { T as ApplyOptions, U as ConnectionOverrides, a3 as Definable, c as Diff, d as DiffItem, D as Driver, H as EMPTY_STORED, W as EmitOptions, F as Filter, h as FilterOpts, a6 as KindDisplay, a7 as KindEngine, a8 as KindPlan, a9 as KindRegistry, aa as KindSnapshot, ab as KindSpec, L as LocalOnly, M as MergeOptions, y as MergeResult, J as Migration, Y as MigrationDirection, Z as MigrationRecord, _ as MigrationStore, ad as OrderNode, af as PortableObject, P as PullFilePlan, B as PullPlan, ah as Ref, C as RenderedUnit, R as ResolvedConfig, ai as ResolvedDisplay, a0 as ShadowCapability, a1 as Statement, S as StoredSnapshot, v as actionLabel, w as applyPull, a2 as buildKindDiff, G as checksum, V as driverNames, a4 as emitKinds, j as filterKinds, f as formatDiff, e as formatItems, g as formatPatch, X as getDriver, k as inCat, n as intersectKinds, a5 as introspectKinds, i as isEmptyDiff, o as kindFlags, x as lineDiff, I as listMigrations, l as loadConfig, b as loadProject, ac as lowerSchema, m as makeJiti, p as mergeStored, z as mergeUnits, ae as orderObjects, q as parseFilter, u as passesFilter, ag as planKinds, K as readSnapshot, $ as registerDriver, r as resolveConnectionConfig, N as slug, aj as snapshotKinds, ak as snapshotObjects, s as summarizeKinds, O as timestamp, t as tokenDiff, E as unifiedDiff, Q as writeSnapshot } from './driver-Dh5hLKHm.js';
3
+ export { C as ConnectionConfigBase, a as ConnectionEntry, b as ConnectionInput, R as ResolveContext, d as ResolvedConnectionHandle, c as connectionEntry, i as isConnectionEntry } from './config-TIiKDd9t.js';
4
+ export { PortableField, PortablePermissions, PortableType, ScalarName, array, literal, nullable, option, record, scalar, union } from './driver.js';
5
+ import 'jiti';
6
+ import 'commander';
7
+
8
+ /**
9
+ * The diff pager, resolved the way git does: `pager.diff` → `core.pager` → `$GIT_PAGER` →
10
+ * `$PAGER`. So a user with `core.pager = delta` gets delta for free, with their own config.
11
+ */
12
+ declare function resolvePager(): string | undefined;
13
+ /** Pipe `text` through `pager` (a shell command, possibly with args); resolve when it exits. */
14
+ declare function pipeThroughPager(pager: string, text: string): Promise<void>;
15
+
16
+ /**
17
+ * The NEUTRAL view of a loaded table the engine reads — just `name` plus the `config.relation` flag
18
+ * used for ordering. A driver casts this to its own concrete table builder in `lower`. (The runtime
19
+ * object is the driver's real `TableDef`; the engine never names that type.)
20
+ */
21
+ interface AnyTable extends Authored {
22
+ readonly config: {
23
+ readonly relation?: unknown;
24
+ };
25
+ }
26
+ /**
27
+ * Load every schema object from `schemaPath` (a single `.ts` module, or a directory of them): the
28
+ * tables/relations (ordered normal-before-relation, then by name, for stable DDL) and the standalone
29
+ * defs (`defineEvent`/`defineFunction`). One pass over the files.
30
+ */
31
+ declare function loadDefs(schemaPath: string): Promise<{
32
+ tables: AnyTable[];
33
+ defs: AuthoredDef[];
34
+ /** Absolute source file each table/def was loaded from (for `diff`'s file annotations). */
35
+ fileOf: Map<AnyTable | AuthoredDef, string>;
36
+ }>;
37
+ /** The tables/relations from `schemaPath` (standalone events excluded — see {@link loadDefs}). */
38
+ declare function loadSchemas(schemaPath: string): Promise<AnyTable[]>;
39
+ /** A schema file's exported entities (tables/functions/accesses) and whether it holds ONLY those. */
40
+ interface LocalFileEntities {
41
+ /** Each schema entity by its export-const identifier + its DB name (table/function/access name). */
42
+ entities: {
43
+ exportName: string;
44
+ name: string;
45
+ kind: "table" | "def";
46
+ }[];
47
+ /** True when EVERY runtime export of the file is a schema entity (no helpers / other exports). */
48
+ pureSchema: boolean;
49
+ }
50
+ /**
51
+ * Scan each schema file for the tables/functions/accesses it exports (by export-const name), and
52
+ * whether the file is purely schema. `pull` uses this to find whole-entity local-only schema
53
+ * (entities the live DB doesn't have) and to decide whether a file is safe to delete when mirroring
54
+ * the DB. Standalone events are not whole entities (they attach to a table), so they don't count as
55
+ * entities — a file exporting one is therefore not `pureSchema` and won't be auto-deleted.
56
+ */
57
+ declare function scanLocalEntities(schemaPath: string): Promise<Map<string, LocalFileEntities>>;
58
+ /** Map of table name → the file that defines it (for `pull`'s duplicate-definition check). */
59
+ declare function existingTables(schemaPath: string): Promise<Map<string, string>>;
60
+ /**
61
+ * Names defined in more than one place, mapped to the files that define them (a file repeats if it
62
+ * defines the same name twice). `loadSchemas` silently lets the last definition win, so this is how
63
+ * `doctor` surfaces the otherwise-invisible conflict.
64
+ */
65
+ declare function duplicateTables(schemaPath: string): Promise<Map<string, string[]>>;
66
+
67
+ /** Whether colored output is enabled (a TTY and `NO_COLOR` unset). */
68
+ declare const colorEnabled: () => boolean;
69
+ declare const style: {
70
+ green: (s: string) => string;
71
+ red: (s: string) => string;
72
+ yellow: (s: string) => string;
73
+ cyan: (s: string) => string;
74
+ dim: (s: string) => string;
75
+ bold: (s: string) => string;
76
+ };
77
+ /** A green ✓ success line. */
78
+ declare const ok: (s: string) => string;
79
+ /** A red ✗ failure line. */
80
+ declare const fail: (s: string) => string;
81
+ /** Pluralize `n thing` / `n things`. */
82
+ declare const plural: (n: number, word: string) => string;
83
+
84
+ export { type AnyTable, Authored, AuthoredDef, colorEnabled, duplicateTables, existingTables, fail, loadDefs, loadSchemas, ok, pipeThroughPager, plural, resolvePager, scanLocalEntities, style };