node-type-registry 0.11.0 → 0.14.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-type-registry",
3
- "version": "0.11.0",
3
+ "version": "0.14.0",
4
4
  "description": "Node type definitions for the Constructive blueprint system. Single source of truth for all Authz*, Data*, Relation*, and View* node types.",
5
5
  "author": "Constructive <developers@constructive.io>",
6
6
  "main": "index.js",
@@ -27,7 +27,6 @@
27
27
  "lint": "eslint . --fix",
28
28
  "test": "jest",
29
29
  "test:watch": "jest --watch",
30
- "generate:seed": "ts-node src/codegen/generate-seed.ts",
31
30
  "generate:types": "ts-node src/codegen/generate-types.ts"
32
31
  },
33
32
  "dependencies": {
@@ -48,5 +47,5 @@
48
47
  "registry",
49
48
  "graphile"
50
49
  ],
51
- "gitHead": "ec793fd5de36264f5c9738732657522c1d783a6d"
50
+ "gitHead": "1b3af3c5189b9ca2e765b9239a4b287099e64a03"
52
51
  }
@@ -2,3 +2,4 @@ export { RelationBelongsTo } from './relation-belongs-to';
2
2
  export { RelationHasOne } from './relation-has-one';
3
3
  export { RelationHasMany } from './relation-has-many';
4
4
  export { RelationManyToMany } from './relation-many-to-many';
5
+ export { RelationSpatial } from './relation-spatial';
package/relation/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RelationManyToMany = exports.RelationHasMany = exports.RelationHasOne = exports.RelationBelongsTo = void 0;
3
+ exports.RelationSpatial = exports.RelationManyToMany = exports.RelationHasMany = exports.RelationHasOne = exports.RelationBelongsTo = void 0;
4
4
  var relation_belongs_to_1 = require("./relation-belongs-to");
5
5
  Object.defineProperty(exports, "RelationBelongsTo", { enumerable: true, get: function () { return relation_belongs_to_1.RelationBelongsTo; } });
6
6
  var relation_has_one_1 = require("./relation-has-one");
@@ -9,3 +9,5 @@ var relation_has_many_1 = require("./relation-has-many");
9
9
  Object.defineProperty(exports, "RelationHasMany", { enumerable: true, get: function () { return relation_has_many_1.RelationHasMany; } });
10
10
  var relation_many_to_many_1 = require("./relation-many-to-many");
11
11
  Object.defineProperty(exports, "RelationManyToMany", { enumerable: true, get: function () { return relation_many_to_many_1.RelationManyToMany; } });
12
+ var relation_spatial_1 = require("./relation-spatial");
13
+ Object.defineProperty(exports, "RelationSpatial", { enumerable: true, get: function () { return relation_spatial_1.RelationSpatial; } });
@@ -0,0 +1,2 @@
1
+ import type { NodeTypeDefinition } from '../types';
2
+ export declare const RelationSpatial: NodeTypeDefinition;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RelationSpatial = void 0;
4
+ exports.RelationSpatial = {
5
+ "name": "RelationSpatial",
6
+ "slug": "relation_spatial",
7
+ "category": "relation",
8
+ "display_name": "Spatial Relation",
9
+ "description": "Declares a spatial predicate between two existing geometry/geography columns. Inserts a metaschema_public.spatial_relation row; the sync_spatial_relation_tags trigger then projects a @spatialRelation smart tag onto the owner column so graphile-postgis' PostgisSpatialRelationsPlugin can expose it as a cross-table filter in GraphQL. Metadata-only: both source_field and target_field must already exist on their tables. Idempotent on (source_table_id, name). One direction per tag — author two RelationSpatial entries if symmetry is desired.",
10
+ "parameter_schema": {
11
+ "type": "object",
12
+ "properties": {
13
+ "source_table_id": {
14
+ "type": "string",
15
+ "format": "uuid",
16
+ "description": "Table that owns the relation (the @spatialRelation tag is emitted on the owner column of this table)"
17
+ },
18
+ "source_field_id": {
19
+ "type": "string",
20
+ "format": "uuid",
21
+ "description": "Geometry/geography column on source_table that carries the @spatialRelation smart tag"
22
+ },
23
+ "target_table_id": {
24
+ "type": "string",
25
+ "format": "uuid",
26
+ "description": "Table being referenced by the spatial predicate"
27
+ },
28
+ "target_field_id": {
29
+ "type": "string",
30
+ "format": "uuid",
31
+ "description": "Geometry/geography column on target_table that the predicate is evaluated against"
32
+ },
33
+ "name": {
34
+ "type": "string",
35
+ "description": "Relation name (stable, snake_case). Becomes the generated filter field name in GraphQL (e.g. nearby_clinic). Unique per (source_table_id, name) — idempotency key."
36
+ },
37
+ "operator": {
38
+ "type": "string",
39
+ "enum": [
40
+ "st_contains",
41
+ "st_within",
42
+ "st_intersects",
43
+ "st_covers",
44
+ "st_coveredby",
45
+ "st_overlaps",
46
+ "st_touches",
47
+ "st_dwithin"
48
+ ],
49
+ "description": "PostGIS spatial predicate. One of the 8 whitelisted operators. st_dwithin requires param_name."
50
+ },
51
+ "param_name": {
52
+ "type": "string",
53
+ "description": "Parameter name for parametric operators (currently only st_dwithin, which needs a distance argument). Must be NULL for all other operators. Enforced by table CHECK."
54
+ }
55
+ },
56
+ "required": [
57
+ "source_table_id",
58
+ "source_field_id",
59
+ "target_table_id",
60
+ "target_field_id",
61
+ "name",
62
+ "operator"
63
+ ]
64
+ },
65
+ "tags": [
66
+ "relation",
67
+ "spatial",
68
+ "postgis",
69
+ "schema"
70
+ ]
71
+ };
@@ -1,32 +0,0 @@
1
- /**
2
- * Generate SQL seed scripts from TypeScript node type definitions.
3
- *
4
- * Uses pgsql-deparser to produce individual INSERT statements per node type,
5
- * suitable for use as separate pgpm migration files.
6
- *
7
- * Usage:
8
- * npx ts-node src/codegen/generate-seed.ts [--outdir <dir>] [--single] [--pgpm <dir>]
9
- *
10
- * --outdir <dir> Directory to write individual SQL files (default: stdout)
11
- * --single Emit a single combined seed.sql instead of per-node files
12
- * --pgpm <dir> Generate deploy/revert/verify files in pgpm package layout.
13
- * <dir> is the pgpm package root (e.g. packages/metaschema).
14
- * Files are written relative to this root at:
15
- * deploy/schemas/metaschema_public/tables/node_type_registry/data/seed.sql
16
- * revert/schemas/metaschema_public/tables/node_type_registry/data/seed.sql
17
- * verify/schemas/metaschema_public/tables/node_type_registry/data/seed.sql
18
- *
19
- * Examples:
20
- * # Print all INSERT statements to stdout
21
- * npx ts-node src/codegen/generate-seed.ts
22
- *
23
- * # Generate individual migration files
24
- * npx ts-node src/codegen/generate-seed.ts --outdir ./deploy/seed
25
- *
26
- * # Generate a single combined seed file
27
- * npx ts-node src/codegen/generate-seed.ts --single --outdir ./deploy
28
- *
29
- * # Generate pgpm deploy/revert/verify files
30
- * npx ts-node src/codegen/generate-seed.ts --pgpm ../../constructive-db/packages/metaschema
31
- */
32
- export {};
@@ -1,252 +0,0 @@
1
- "use strict";
2
- /**
3
- * Generate SQL seed scripts from TypeScript node type definitions.
4
- *
5
- * Uses pgsql-deparser to produce individual INSERT statements per node type,
6
- * suitable for use as separate pgpm migration files.
7
- *
8
- * Usage:
9
- * npx ts-node src/codegen/generate-seed.ts [--outdir <dir>] [--single] [--pgpm <dir>]
10
- *
11
- * --outdir <dir> Directory to write individual SQL files (default: stdout)
12
- * --single Emit a single combined seed.sql instead of per-node files
13
- * --pgpm <dir> Generate deploy/revert/verify files in pgpm package layout.
14
- * <dir> is the pgpm package root (e.g. packages/metaschema).
15
- * Files are written relative to this root at:
16
- * deploy/schemas/metaschema_public/tables/node_type_registry/data/seed.sql
17
- * revert/schemas/metaschema_public/tables/node_type_registry/data/seed.sql
18
- * verify/schemas/metaschema_public/tables/node_type_registry/data/seed.sql
19
- *
20
- * Examples:
21
- * # Print all INSERT statements to stdout
22
- * npx ts-node src/codegen/generate-seed.ts
23
- *
24
- * # Generate individual migration files
25
- * npx ts-node src/codegen/generate-seed.ts --outdir ./deploy/seed
26
- *
27
- * # Generate a single combined seed file
28
- * npx ts-node src/codegen/generate-seed.ts --single --outdir ./deploy
29
- *
30
- * # Generate pgpm deploy/revert/verify files
31
- * npx ts-node src/codegen/generate-seed.ts --pgpm ../../constructive-db/packages/metaschema
32
- */
33
- Object.defineProperty(exports, "__esModule", { value: true });
34
- const fs_1 = require("fs");
35
- const path_1 = require("path");
36
- const pgsql_deparser_1 = require("pgsql-deparser");
37
- const utils_1 = require("@pgsql/utils");
38
- const index_1 = require("../index");
39
- // ---------------------------------------------------------------------------
40
- // Constants
41
- // ---------------------------------------------------------------------------
42
- const MIGRATION_PATH = 'schemas/metaschema_public/tables/node_type_registry/data/seed';
43
- // ---------------------------------------------------------------------------
44
- // AST helpers
45
- // ---------------------------------------------------------------------------
46
- const astr = (val) => utils_1.nodes.aConst({ sval: utils_1.ast.string({ sval: val }) });
47
- const makeCast = (arg, typeName) => ({
48
- TypeCast: {
49
- arg,
50
- typeName: {
51
- names: [{ String: { sval: typeName } }],
52
- typemod: -1,
53
- },
54
- },
55
- });
56
- const makeArrayExpr = (elements) => ({
57
- A_ArrayExpr: { elements },
58
- });
59
- // ---------------------------------------------------------------------------
60
- // Build a single INSERT statement for one node type
61
- // ---------------------------------------------------------------------------
62
- function buildInsertStmt(nt) {
63
- const cols = [
64
- 'name',
65
- 'slug',
66
- 'category',
67
- 'display_name',
68
- 'description',
69
- 'parameter_schema',
70
- 'tags',
71
- ];
72
- const vals = [
73
- astr(nt.name),
74
- astr(nt.slug),
75
- astr(nt.category),
76
- astr(nt.display_name),
77
- astr(nt.description),
78
- makeCast(astr(JSON.stringify(nt.parameter_schema)), 'jsonb'),
79
- makeArrayExpr(nt.tags.map((t) => astr(t))),
80
- ];
81
- return {
82
- RawStmt: {
83
- stmt: {
84
- InsertStmt: {
85
- relation: {
86
- schemaname: 'metaschema_public',
87
- relname: 'node_type_registry',
88
- inh: true,
89
- relpersistence: 'p',
90
- },
91
- cols: cols.map((name) => utils_1.nodes.resTarget({ name })),
92
- selectStmt: {
93
- SelectStmt: {
94
- valuesLists: [
95
- {
96
- List: { items: vals },
97
- },
98
- ],
99
- op: 'SETOP_NONE',
100
- limitOption: 'LIMIT_OPTION_DEFAULT',
101
- },
102
- },
103
- onConflictClause: {
104
- action: 'ONCONFLICT_NOTHING',
105
- infer: {
106
- indexElems: [
107
- {
108
- IndexElem: {
109
- name: 'slug',
110
- ordering: 'SORTBY_DEFAULT',
111
- nulls_ordering: 'SORTBY_NULLS_DEFAULT',
112
- },
113
- },
114
- ],
115
- },
116
- },
117
- override: 'OVERRIDING_NOT_SET',
118
- },
119
- },
120
- stmt_len: 1,
121
- },
122
- };
123
- }
124
- // ---------------------------------------------------------------------------
125
- // pgpm file generators
126
- // ---------------------------------------------------------------------------
127
- const GENERATED_HEADER = [
128
- '-- GENERATED FILE — DO NOT EDIT',
129
- '--',
130
- '-- Regenerate with:',
131
- '-- cd graphql/node-type-registry && pnpm generate:seed --pgpm ../../constructive-db/packages/metaschema',
132
- '--',
133
- '',
134
- ].join('\n');
135
- async function buildDeploySql() {
136
- const header = [
137
- `-- Deploy ${MIGRATION_PATH} to pg`,
138
- '',
139
- GENERATED_HEADER,
140
- '-- requires: schemas/metaschema_public/tables/node_type_registry/table',
141
- '',
142
- ].join('\n');
143
- const stmts = index_1.allNodeTypes.map(buildInsertStmt);
144
- const body = await (0, pgsql_deparser_1.deparse)(stmts);
145
- return header + body + '\n';
146
- }
147
- function buildRevertSql() {
148
- const names = index_1.allNodeTypes.map((nt) => ` '${nt.name}'`);
149
- // Wrap names at ~4 per line for readability
150
- const chunks = [];
151
- for (let i = 0; i < names.length; i += 4) {
152
- chunks.push(names.slice(i, i + 4).join(', '));
153
- }
154
- return [
155
- `-- Revert ${MIGRATION_PATH} from pg`,
156
- '',
157
- GENERATED_HEADER,
158
- 'DELETE FROM metaschema_public.node_type_registry',
159
- 'WHERE name IN (',
160
- chunks.join(',\n'),
161
- ');',
162
- '',
163
- ].join('\n');
164
- }
165
- function buildVerifySql() {
166
- // Pick one representative from each category
167
- const categories = new Map();
168
- for (const nt of index_1.allNodeTypes) {
169
- if (!categories.has(nt.category)) {
170
- categories.set(nt.category, nt);
171
- }
172
- }
173
- const checks = Array.from(categories.values()).map((nt) => `SELECT 1 FROM metaschema_public.node_type_registry WHERE name = '${nt.name}';`);
174
- return [
175
- `-- Verify ${MIGRATION_PATH} on pg`,
176
- '',
177
- GENERATED_HEADER,
178
- ...checks,
179
- '',
180
- ].join('\n');
181
- }
182
- // ---------------------------------------------------------------------------
183
- // File writer helper
184
- // ---------------------------------------------------------------------------
185
- function writeFile(filePath, content) {
186
- const dir = (0, path_1.join)(filePath, '..');
187
- if (!(0, fs_1.existsSync)(dir))
188
- (0, fs_1.mkdirSync)(dir, { recursive: true });
189
- (0, fs_1.writeFileSync)(filePath, content);
190
- }
191
- // ---------------------------------------------------------------------------
192
- // CLI
193
- // ---------------------------------------------------------------------------
194
- async function main() {
195
- const args = process.argv.slice(2);
196
- const outdirIdx = args.indexOf('--outdir');
197
- const outdir = outdirIdx !== -1 ? args[outdirIdx + 1] : undefined;
198
- const single = args.includes('--single');
199
- const pgpmIdx = args.indexOf('--pgpm');
200
- const pgpmRoot = pgpmIdx !== -1 ? args[pgpmIdx + 1] : undefined;
201
- // --pgpm mode: generate deploy/revert/verify in pgpm package layout
202
- if (pgpmRoot) {
203
- const relPath = 'schemas/metaschema_public/tables/node_type_registry/data/seed.sql';
204
- const deployPath = (0, path_1.join)(pgpmRoot, 'deploy', relPath);
205
- const revertPath = (0, path_1.join)(pgpmRoot, 'revert', relPath);
206
- const verifyPath = (0, path_1.join)(pgpmRoot, 'verify', relPath);
207
- writeFile(deployPath, await buildDeploySql());
208
- writeFile(revertPath, buildRevertSql());
209
- writeFile(verifyPath, buildVerifySql());
210
- console.log(`Wrote ${index_1.allNodeTypes.length} node types to pgpm layout:`);
211
- console.log(` deploy: ${deployPath}`);
212
- console.log(` revert: ${revertPath}`);
213
- console.log(` verify: ${verifyPath}`);
214
- return;
215
- }
216
- if (single) {
217
- // Emit all INSERT statements as a single SQL string
218
- const stmts = index_1.allNodeTypes.map(buildInsertStmt);
219
- const sql = await (0, pgsql_deparser_1.deparse)(stmts);
220
- if (outdir) {
221
- if (!(0, fs_1.existsSync)(outdir))
222
- (0, fs_1.mkdirSync)(outdir, { recursive: true });
223
- (0, fs_1.writeFileSync)((0, path_1.join)(outdir, 'seed.sql'), sql + '\n');
224
- console.log(`Wrote ${index_1.allNodeTypes.length} node types to ${(0, path_1.join)(outdir, 'seed.sql')}`);
225
- }
226
- else {
227
- process.stdout.write(sql + '\n');
228
- }
229
- return;
230
- }
231
- // Emit individual SQL files per node type
232
- const stmts = await Promise.all(index_1.allNodeTypes.map(async (nt) => ({
233
- nt,
234
- sql: await (0, pgsql_deparser_1.deparse)([buildInsertStmt(nt)]),
235
- })));
236
- if (outdir) {
237
- if (!(0, fs_1.existsSync)(outdir))
238
- (0, fs_1.mkdirSync)(outdir, { recursive: true });
239
- for (const { nt, sql } of stmts) {
240
- const filename = `${nt.slug}.sql`;
241
- (0, fs_1.writeFileSync)((0, path_1.join)(outdir, filename), sql + '\n');
242
- }
243
- console.log(`Wrote ${stmts.length} individual migration files to ${outdir}/`);
244
- }
245
- else {
246
- for (const { nt, sql } of stmts) {
247
- console.log(`-- ${nt.name} (${nt.slug})`);
248
- console.log(sql + ';\n');
249
- }
250
- }
251
- }
252
- main();
@@ -1,32 +0,0 @@
1
- /**
2
- * Generate SQL seed scripts from TypeScript node type definitions.
3
- *
4
- * Uses pgsql-deparser to produce individual INSERT statements per node type,
5
- * suitable for use as separate pgpm migration files.
6
- *
7
- * Usage:
8
- * npx ts-node src/codegen/generate-seed.ts [--outdir <dir>] [--single] [--pgpm <dir>]
9
- *
10
- * --outdir <dir> Directory to write individual SQL files (default: stdout)
11
- * --single Emit a single combined seed.sql instead of per-node files
12
- * --pgpm <dir> Generate deploy/revert/verify files in pgpm package layout.
13
- * <dir> is the pgpm package root (e.g. packages/metaschema).
14
- * Files are written relative to this root at:
15
- * deploy/schemas/metaschema_public/tables/node_type_registry/data/seed.sql
16
- * revert/schemas/metaschema_public/tables/node_type_registry/data/seed.sql
17
- * verify/schemas/metaschema_public/tables/node_type_registry/data/seed.sql
18
- *
19
- * Examples:
20
- * # Print all INSERT statements to stdout
21
- * npx ts-node src/codegen/generate-seed.ts
22
- *
23
- * # Generate individual migration files
24
- * npx ts-node src/codegen/generate-seed.ts --outdir ./deploy/seed
25
- *
26
- * # Generate a single combined seed file
27
- * npx ts-node src/codegen/generate-seed.ts --single --outdir ./deploy
28
- *
29
- * # Generate pgpm deploy/revert/verify files
30
- * npx ts-node src/codegen/generate-seed.ts --pgpm ../../constructive-db/packages/metaschema
31
- */
32
- export {};