node-type-registry 0.17.1 → 0.18.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/blueprint-types.generated.d.ts +126 -79
- package/blueprint-types.generated.js +1 -0
- package/codegen/generate-types.js +76 -25
- package/esm/blueprint-types.generated.d.ts +126 -79
- package/esm/blueprint-types.generated.js +1 -0
- package/esm/codegen/generate-types.js +77 -26
- package/package.json +2 -2
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
20
20
|
const generate = require('@babel/generator').default ?? require('@babel/generator');
|
|
21
21
|
import * as t from '@babel/types';
|
|
22
|
-
import {
|
|
22
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
23
23
|
import { join } from 'path';
|
|
24
24
|
import { generateTypeScriptTypes } from 'schema-typescript';
|
|
25
25
|
import { allNodeTypes } from '../index';
|
|
@@ -29,7 +29,7 @@ import { allNodeTypes } from '../index';
|
|
|
29
29
|
/** Attach a JSDoc-style leading comment to an AST node. */
|
|
30
30
|
function addJSDoc(node, description) {
|
|
31
31
|
node.leadingComments = [
|
|
32
|
-
{ type: 'CommentBlock', value: `* ${description} ` }
|
|
32
|
+
{ type: 'CommentBlock', value: `* ${description} ` }
|
|
33
33
|
];
|
|
34
34
|
return node;
|
|
35
35
|
}
|
|
@@ -112,7 +112,7 @@ function generateParamsInterfaces(nodeTypes) {
|
|
|
112
112
|
const astNodes = generateTypeScriptTypes(sanitized, {
|
|
113
113
|
includePropertyComments: true,
|
|
114
114
|
includeTypeComments: false,
|
|
115
|
-
strictTypeSafety: true
|
|
115
|
+
strictTypeSafety: true
|
|
116
116
|
});
|
|
117
117
|
if (astNodes.length > 0) {
|
|
118
118
|
// The last node is the main interface for the title
|
|
@@ -208,7 +208,7 @@ function buildBlueprintField(meta) {
|
|
|
208
208
|
addJSDoc(requiredProp('type', t.tsStringKeyword()), 'The PostgreSQL type (e.g., "text", "integer", "boolean", "uuid").'),
|
|
209
209
|
addJSDoc(optionalProp('is_required', t.tsBooleanKeyword()), 'Whether the column has a NOT NULL constraint.'),
|
|
210
210
|
addJSDoc(optionalProp('default_value', t.tsStringKeyword()), 'SQL default value expression (e.g., "true", "now()").'),
|
|
211
|
-
addJSDoc(optionalProp('description', t.tsStringKeyword()), 'Comment/description for this field.')
|
|
211
|
+
addJSDoc(optionalProp('description', t.tsStringKeyword()), 'Comment/description for this field.')
|
|
212
212
|
]), 'A custom field (column) to add to a blueprint table.');
|
|
213
213
|
}
|
|
214
214
|
function buildBlueprintPolicy(authzNodes, _meta) {
|
|
@@ -225,14 +225,14 @@ function buildBlueprintPolicy(authzNodes, _meta) {
|
|
|
225
225
|
addJSDoc(optionalProp('permissive', t.tsBooleanKeyword()), 'Whether this policy is permissive (true) or restrictive (false). Defaults to true.'),
|
|
226
226
|
addJSDoc(optionalProp('policy_role', t.tsStringKeyword()), 'Role for this policy. Defaults to "authenticated".'),
|
|
227
227
|
addJSDoc(optionalProp('policy_name', t.tsStringKeyword()), 'Optional custom name for this policy.'),
|
|
228
|
-
addJSDoc(optionalProp('data', recordType(t.tsStringKeyword(), t.tsUnknownKeyword())), 'Policy-specific data (structure varies by policy type).')
|
|
228
|
+
addJSDoc(optionalProp('data', recordType(t.tsStringKeyword(), t.tsUnknownKeyword())), 'Policy-specific data (structure varies by policy type).')
|
|
229
229
|
]), 'An RLS policy entry for a blueprint table. Uses $type to match the blueprint JSON convention.');
|
|
230
230
|
}
|
|
231
231
|
function buildBlueprintFtsSource() {
|
|
232
232
|
return addJSDoc(exportInterface('BlueprintFtsSource', [
|
|
233
233
|
addJSDoc(requiredProp('field', t.tsStringKeyword()), 'Column name of the source field.'),
|
|
234
234
|
addJSDoc(requiredProp('weight', t.tsStringKeyword()), 'TSVector weight: "A", "B", "C", or "D".'),
|
|
235
|
-
addJSDoc(optionalProp('lang', t.tsStringKeyword()), 'Language for text search. Defaults to "english".')
|
|
235
|
+
addJSDoc(optionalProp('lang', t.tsStringKeyword()), 'Language for text search. Defaults to "english".')
|
|
236
236
|
]), 'A source field contributing to a full-text search tsvector column.');
|
|
237
237
|
}
|
|
238
238
|
function buildBlueprintFullTextSearch() {
|
|
@@ -240,14 +240,14 @@ function buildBlueprintFullTextSearch() {
|
|
|
240
240
|
addJSDoc(requiredProp('table_name', t.tsStringKeyword()), 'Table name this full-text search belongs to.'),
|
|
241
241
|
addJSDoc(optionalProp('schema_name', t.tsStringKeyword()), 'Optional schema name for disambiguation (falls back to top-level default).'),
|
|
242
242
|
addJSDoc(requiredProp('field', t.tsStringKeyword()), 'Name of the tsvector field on the table.'),
|
|
243
|
-
addJSDoc(requiredProp('sources', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintFtsSource')))), 'Source fields that feed into this tsvector.')
|
|
243
|
+
addJSDoc(requiredProp('sources', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintFtsSource')))), 'Source fields that feed into this tsvector.')
|
|
244
244
|
]), 'A full-text search configuration for a blueprint table (top-level, requires table_name).');
|
|
245
245
|
}
|
|
246
246
|
function buildBlueprintTableFullTextSearch() {
|
|
247
247
|
return addJSDoc(exportInterface('BlueprintTableFullTextSearch', [
|
|
248
248
|
addJSDoc(requiredProp('field', t.tsStringKeyword()), 'Name of the tsvector field on the table.'),
|
|
249
249
|
addJSDoc(requiredProp('sources', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintFtsSource')))), 'Source fields that feed into this tsvector.'),
|
|
250
|
-
addJSDoc(optionalProp('schema_name', t.tsStringKeyword()), 'Optional schema name override.')
|
|
250
|
+
addJSDoc(optionalProp('schema_name', t.tsStringKeyword()), 'Optional schema name override.')
|
|
251
251
|
]), 'A full-text search configuration nested inside a table definition (table_name not required).');
|
|
252
252
|
}
|
|
253
253
|
function buildBlueprintIndex(meta) {
|
|
@@ -257,7 +257,7 @@ function buildBlueprintIndex(meta) {
|
|
|
257
257
|
// JSONB columns get Record<string, unknown> instead of the default
|
|
258
258
|
index_params: recordType(t.tsStringKeyword(), t.tsUnknownKeyword()),
|
|
259
259
|
where_clause: recordType(t.tsStringKeyword(), t.tsUnknownKeyword()),
|
|
260
|
-
options: recordType(t.tsStringKeyword(), t.tsUnknownKeyword())
|
|
260
|
+
options: recordType(t.tsStringKeyword(), t.tsUnknownKeyword())
|
|
261
261
|
});
|
|
262
262
|
}
|
|
263
263
|
// Static fallback
|
|
@@ -270,7 +270,7 @@ function buildBlueprintIndex(meta) {
|
|
|
270
270
|
addJSDoc(optionalProp('is_unique', t.tsBooleanKeyword()), 'Whether this is a unique index.'),
|
|
271
271
|
addJSDoc(optionalProp('name', t.tsStringKeyword()), 'Optional custom name for the index.'),
|
|
272
272
|
addJSDoc(optionalProp('op_classes', t.tsArrayType(t.tsStringKeyword())), 'Operator classes for the index columns.'),
|
|
273
|
-
addJSDoc(optionalProp('options', recordType(t.tsStringKeyword(), t.tsUnknownKeyword())), 'Additional index-specific options.')
|
|
273
|
+
addJSDoc(optionalProp('options', recordType(t.tsStringKeyword(), t.tsUnknownKeyword())), 'Additional index-specific options.')
|
|
274
274
|
]), 'An index definition within a blueprint (top-level, requires table_name).');
|
|
275
275
|
}
|
|
276
276
|
function buildBlueprintTableIndex() {
|
|
@@ -282,7 +282,7 @@ function buildBlueprintTableIndex() {
|
|
|
282
282
|
addJSDoc(optionalProp('name', t.tsStringKeyword()), 'Optional custom name for the index.'),
|
|
283
283
|
addJSDoc(optionalProp('op_classes', t.tsArrayType(t.tsStringKeyword())), 'Operator classes for the index columns.'),
|
|
284
284
|
addJSDoc(optionalProp('options', recordType(t.tsStringKeyword(), t.tsUnknownKeyword())), 'Additional index-specific options.'),
|
|
285
|
-
addJSDoc(optionalProp('schema_name', t.tsStringKeyword()), 'Optional schema name override.')
|
|
285
|
+
addJSDoc(optionalProp('schema_name', t.tsStringKeyword()), 'Optional schema name override.')
|
|
286
286
|
]), 'An index definition nested inside a table definition (table_name not required).');
|
|
287
287
|
}
|
|
288
288
|
// ---------------------------------------------------------------------------
|
|
@@ -308,7 +308,7 @@ function buildNodeTypes(dataNodes) {
|
|
|
308
308
|
// BlueprintNode -- shorthand | object
|
|
309
309
|
results.push(addJSDoc(exportTypeAlias('BlueprintNode', t.tsUnionType([
|
|
310
310
|
t.tsTypeReference(t.identifier('BlueprintNodeShorthand')),
|
|
311
|
-
t.tsTypeReference(t.identifier('BlueprintNodeObject'))
|
|
311
|
+
t.tsTypeReference(t.identifier('BlueprintNodeObject'))
|
|
312
312
|
])), 'A node entry in a blueprint table. Either a string shorthand or a typed object.'));
|
|
313
313
|
return results;
|
|
314
314
|
}
|
|
@@ -322,7 +322,7 @@ function buildRelationTypes(relationNodes) {
|
|
|
322
322
|
requiredProp('source_table', t.tsStringKeyword()),
|
|
323
323
|
requiredProp('target_table', t.tsStringKeyword()),
|
|
324
324
|
optionalProp('source_schema_name', t.tsStringKeyword()),
|
|
325
|
-
optionalProp('target_schema_name', t.tsStringKeyword())
|
|
325
|
+
optionalProp('target_schema_name', t.tsStringKeyword())
|
|
326
326
|
];
|
|
327
327
|
// RelationSpatial is the only relation type that references *existing*
|
|
328
328
|
// columns rather than creating FK/junction fields. Its blueprint JSON
|
|
@@ -336,11 +336,11 @@ function buildRelationTypes(relationNodes) {
|
|
|
336
336
|
const baseType = t.tsTypeLiteral(baseMembers);
|
|
337
337
|
return t.tsIntersectionType([
|
|
338
338
|
baseType,
|
|
339
|
-
partialOf(t.tsTypeReference(t.identifier(`${nt.name}Params`)))
|
|
339
|
+
partialOf(t.tsTypeReference(t.identifier(`${nt.name}Params`)))
|
|
340
340
|
]);
|
|
341
341
|
});
|
|
342
342
|
return [
|
|
343
|
-
addJSDoc(exportTypeAlias('BlueprintRelation', t.tsUnionType(relationMembers)), 'A relation entry in a blueprint definition.')
|
|
343
|
+
addJSDoc(exportTypeAlias('BlueprintRelation', t.tsUnionType(relationMembers)), 'A relation entry in a blueprint definition.')
|
|
344
344
|
];
|
|
345
345
|
}
|
|
346
346
|
// ---------------------------------------------------------------------------
|
|
@@ -350,15 +350,60 @@ function buildBlueprintUniqueConstraint() {
|
|
|
350
350
|
return addJSDoc(exportInterface('BlueprintUniqueConstraint', [
|
|
351
351
|
addJSDoc(requiredProp('table_name', t.tsStringKeyword()), 'Table name this unique constraint belongs to.'),
|
|
352
352
|
addJSDoc(optionalProp('schema_name', t.tsStringKeyword()), 'Optional schema name for disambiguation (falls back to top-level default).'),
|
|
353
|
-
addJSDoc(requiredProp('columns', t.tsArrayType(t.tsStringKeyword())), 'Column names that form the unique constraint.')
|
|
353
|
+
addJSDoc(requiredProp('columns', t.tsArrayType(t.tsStringKeyword())), 'Column names that form the unique constraint.')
|
|
354
354
|
]), 'A unique constraint definition within a blueprint (top-level, requires table_name).');
|
|
355
355
|
}
|
|
356
356
|
function buildBlueprintTableUniqueConstraint() {
|
|
357
357
|
return addJSDoc(exportInterface('BlueprintTableUniqueConstraint', [
|
|
358
358
|
addJSDoc(requiredProp('columns', t.tsArrayType(t.tsStringKeyword())), 'Column names that form the unique constraint.'),
|
|
359
|
-
addJSDoc(optionalProp('schema_name', t.tsStringKeyword()), 'Optional schema name override.')
|
|
359
|
+
addJSDoc(optionalProp('schema_name', t.tsStringKeyword()), 'Optional schema name override.')
|
|
360
360
|
]), 'A unique constraint nested inside a table definition (table_name not required).');
|
|
361
361
|
}
|
|
362
|
+
/**
|
|
363
|
+
* Build the BlueprintStoragePolicy interface.
|
|
364
|
+
*
|
|
365
|
+
* Matches the jsonb policy objects accepted by apply_storage_security():
|
|
366
|
+
* { "$type": "AuthzPublishable", "privileges": ["select"], "data": {...}, "tables": [...], "policy_name": "pub" }
|
|
367
|
+
*/
|
|
368
|
+
function buildBlueprintStoragePolicy() {
|
|
369
|
+
return addJSDoc(exportInterface('BlueprintStoragePolicy', [
|
|
370
|
+
addJSDoc(requiredProp('$type', t.tsStringKeyword()), 'Authz* policy generator type (e.g., "AuthzPublishable", "AuthzDirectOwner", "AuthzEntityMembership").'),
|
|
371
|
+
addJSDoc(requiredProp('privileges', t.tsArrayType(t.tsStringKeyword())), 'Privilege array (e.g., ["select", "insert", "update", "delete"]). Intersected with each storage table\'s supported operations.'),
|
|
372
|
+
addJSDoc(optionalProp('data', recordType(t.tsStringKeyword(), t.tsUnknownKeyword())), 'Policy data config. Auto-derived from $type when omitted (e.g., AuthzPublishable defaults to {"is_published_field": "is_public", "require_published_at": false}).'),
|
|
373
|
+
addJSDoc(optionalProp('tables', t.tsArrayType(strUnion(['buckets', 'files', 'upload_requests']))), 'Which storage tables to apply this policy to. Defaults to all three when omitted. Uses logical names (not prefixed).'),
|
|
374
|
+
addJSDoc(optionalProp('policy_name', t.tsStringKeyword()), 'Custom RLS policy name suffix. Auto-derived from $type when omitted (pub/own/mem).')
|
|
375
|
+
]), 'A storage-specific RLS policy object for apply_storage_security(). Each entry defines an Authz* policy with explicit privileges, scoped to specific storage tables.');
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Build the BlueprintBucketSeed interface.
|
|
379
|
+
*
|
|
380
|
+
* Matches the bucket entries in storage_config.buckets[].
|
|
381
|
+
*/
|
|
382
|
+
function buildBlueprintBucketSeed() {
|
|
383
|
+
return addJSDoc(exportInterface('BlueprintBucketSeed', [
|
|
384
|
+
addJSDoc(requiredProp('name', t.tsStringKeyword()), 'Bucket key name (e.g., "avatars", "documents"). Becomes the key column value.'),
|
|
385
|
+
addJSDoc(optionalProp('description', t.tsStringKeyword()), 'Human-readable description of this bucket.'),
|
|
386
|
+
addJSDoc(optionalProp('is_public', t.tsBooleanKeyword()), 'Whether the bucket is publicly readable. Defaults to false.'),
|
|
387
|
+
addJSDoc(optionalProp('allowed_mime_types', t.tsArrayType(t.tsStringKeyword())), 'MIME type allowlist (e.g., ["image/png", "image/jpeg"]). NULL means all types allowed.'),
|
|
388
|
+
addJSDoc(optionalProp('max_file_size', t.tsNumberKeyword()), 'Maximum file size in bytes for this bucket. NULL means no limit.'),
|
|
389
|
+
addJSDoc(optionalProp('allowed_origins', t.tsArrayType(t.tsStringKeyword())), 'CORS allowed origins for this bucket.')
|
|
390
|
+
]), 'A bucket seed entry for storage_config.buckets[]. Creates an initial bucket row in the {prefix}_buckets table during entity type provisioning. Only used for app-level storage (not entity-scoped).');
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Build the BlueprintStorageConfig interface.
|
|
394
|
+
*
|
|
395
|
+
* Matches the jsonb shape accepted by storage_config on entity_type_provision.
|
|
396
|
+
*/
|
|
397
|
+
function buildBlueprintStorageConfig() {
|
|
398
|
+
return addJSDoc(exportInterface('BlueprintStorageConfig', [
|
|
399
|
+
addJSDoc(optionalProp('policies', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintStoragePolicy')))), 'Custom RLS policies for storage tables. When provided, replaces the default policy set (AuthzPublishable + membership + AuthzDirectOwner). Each entry is a policy object with $type, privileges, and optional data/tables/policy_name.'),
|
|
400
|
+
addJSDoc(optionalProp('buckets', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintBucketSeed')))), 'Initial bucket seed entries. Each creates a row in {prefix}_buckets during provisioning. Only used for app-level storage (not entity-scoped).'),
|
|
401
|
+
addJSDoc(optionalProp('upload_url_expiry_seconds', t.tsNumberKeyword()), 'Override for presigned upload URL expiry time in seconds.'),
|
|
402
|
+
addJSDoc(optionalProp('download_url_expiry_seconds', t.tsNumberKeyword()), 'Override for presigned download URL expiry time in seconds.'),
|
|
403
|
+
addJSDoc(optionalProp('default_max_file_size', t.tsNumberKeyword()), 'Default maximum file size in bytes for the storage module.'),
|
|
404
|
+
addJSDoc(optionalProp('allowed_origins', t.tsArrayType(t.tsStringKeyword())), 'CORS allowed origins for the storage module.')
|
|
405
|
+
]), 'Storage configuration for an entity type. Controls RLS policies on storage tables, seeds initial buckets, and overrides module-level settings (expiry times, file size limits, CORS).');
|
|
406
|
+
}
|
|
362
407
|
function buildBlueprintEntityTableProvision() {
|
|
363
408
|
return addJSDoc(exportInterface('BlueprintEntityTableProvision', [
|
|
364
409
|
addJSDoc(optionalProp('use_rls', t.tsBooleanKeyword()), 'Whether to enable RLS on the entity table. Forwarded to secure_table_provision. Defaults to true.'),
|
|
@@ -366,9 +411,9 @@ function buildBlueprintEntityTableProvision() {
|
|
|
366
411
|
addJSDoc(optionalProp('fields', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintField')))), 'Custom fields (columns) to add to the entity table. Forwarded to secure_table_provision as-is.'),
|
|
367
412
|
addJSDoc(optionalProp('grants', t.tsArrayType(t.tsTypeLiteral([
|
|
368
413
|
requiredProp('roles', t.tsArrayType(t.tsStringKeyword())),
|
|
369
|
-
requiredProp('privileges', t.tsArrayType(t.tsUnknownKeyword()))
|
|
414
|
+
requiredProp('privileges', t.tsArrayType(t.tsUnknownKeyword()))
|
|
370
415
|
]))), 'Unified grant objects for the entity table. Each entry is { roles: string[], privileges: unknown[] } where privileges are [verb, columns] tuples. Forwarded to secure_table_provision as-is. Defaults to [].'),
|
|
371
|
-
addJSDoc(optionalProp('policies', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintPolicy')))), 'RLS policies for the entity table. When present, these policies fully replace the five default entity-table policies (is_visible becomes a no-op).')
|
|
416
|
+
addJSDoc(optionalProp('policies', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintPolicy')))), 'RLS policies for the entity table. When present, these policies fully replace the five default entity-table policies (is_visible becomes a no-op).')
|
|
372
417
|
]), 'Override object for the entity table created by a BlueprintMembershipType. Shape mirrors BlueprintTable / secure_table_provision vocabulary. When supplied, policies[] replaces the default entity-table policies entirely.');
|
|
373
418
|
}
|
|
374
419
|
function buildBlueprintMembershipType() {
|
|
@@ -382,8 +427,10 @@ function buildBlueprintMembershipType() {
|
|
|
382
427
|
addJSDoc(optionalProp('has_limits', t.tsBooleanKeyword()), 'Whether to provision a limits module for this entity type. Defaults to false.'),
|
|
383
428
|
addJSDoc(optionalProp('has_profiles', t.tsBooleanKeyword()), 'Whether to provision a profiles module for this entity type. Defaults to false.'),
|
|
384
429
|
addJSDoc(optionalProp('has_levels', t.tsBooleanKeyword()), 'Whether to provision a levels module for this entity type. Defaults to false.'),
|
|
430
|
+
addJSDoc(optionalProp('has_storage', t.tsBooleanKeyword()), 'Whether to provision a storage module (buckets, files, upload_requests tables) for this entity type. Defaults to false.'),
|
|
385
431
|
addJSDoc(optionalProp('skip_entity_policies', t.tsBooleanKeyword()), 'Escape hatch: when true AND table_provision is NULL, zero policies are provisioned on the entity table. Defaults to false.'),
|
|
386
432
|
addJSDoc(optionalProp('table_provision', t.tsTypeReference(t.identifier('BlueprintEntityTableProvision'))), 'Override for the entity table. Shape mirrors BlueprintTable / secure_table_provision vocabulary. When supplied, its policies[] replaces the five default entity-table policies; is_visible becomes a no-op. When NULL (default), the five default policies are applied (gated by is_visible).'),
|
|
433
|
+
addJSDoc(optionalProp('storage', t.tsTypeReference(t.identifier('BlueprintStorageConfig'))), 'Storage configuration. Only used when has_storage is true. Controls RLS policies on storage tables, seeds initial buckets, and overrides module-level settings (expiry times, file size limits, CORS).')
|
|
387
434
|
]), 'A membership type entry for Phase 0 of construct_blueprint(). Provisions a full entity type with its own entity table, membership modules, and security policies via entity_type_provision.');
|
|
388
435
|
}
|
|
389
436
|
function buildBlueprintTable() {
|
|
@@ -395,12 +442,12 @@ function buildBlueprintTable() {
|
|
|
395
442
|
addJSDoc(optionalProp('policies', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintPolicy')))), 'RLS policies for this table.'),
|
|
396
443
|
addJSDoc(optionalProp('grants', t.tsArrayType(t.tsTypeLiteral([
|
|
397
444
|
requiredProp('roles', t.tsArrayType(t.tsStringKeyword())),
|
|
398
|
-
requiredProp('privileges', t.tsArrayType(t.tsUnknownKeyword()))
|
|
445
|
+
requiredProp('privileges', t.tsArrayType(t.tsUnknownKeyword()))
|
|
399
446
|
]))), 'Unified grant objects. Each entry is { roles: string[], privileges: unknown[] } where privileges are [verb, columns] tuples (e.g. [["select","*"]]). Enables per-role targeting. Defaults to [].'),
|
|
400
447
|
addJSDoc(optionalProp('use_rls', t.tsBooleanKeyword()), 'Whether to enable RLS on this table. Defaults to true.'),
|
|
401
448
|
addJSDoc(optionalProp('indexes', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintTableIndex')))), 'Table-level indexes (table_name inherited from parent).'),
|
|
402
449
|
addJSDoc(optionalProp('full_text_searches', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintTableFullTextSearch')))), 'Table-level full-text search configurations (table_name inherited from parent).'),
|
|
403
|
-
addJSDoc(optionalProp('unique_constraints', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintTableUniqueConstraint')))), 'Table-level unique constraints (table_name inherited from parent).')
|
|
450
|
+
addJSDoc(optionalProp('unique_constraints', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintTableUniqueConstraint')))), 'Table-level unique constraints (table_name inherited from parent).')
|
|
404
451
|
]), 'A table definition within a blueprint.');
|
|
405
452
|
}
|
|
406
453
|
function buildBlueprintDefinition() {
|
|
@@ -410,7 +457,7 @@ function buildBlueprintDefinition() {
|
|
|
410
457
|
addJSDoc(optionalProp('indexes', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintIndex')))), 'Indexes on table columns.'),
|
|
411
458
|
addJSDoc(optionalProp('full_text_searches', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintFullTextSearch')))), 'Full-text search configurations.'),
|
|
412
459
|
addJSDoc(optionalProp('unique_constraints', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintUniqueConstraint')))), 'Unique constraints on table columns.'),
|
|
413
|
-
addJSDoc(optionalProp('membership_types', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintMembershipType')))), 'Entity types to provision in Phase 0 (before tables). Each entry creates an entity table with membership modules and security.')
|
|
460
|
+
addJSDoc(optionalProp('membership_types', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintMembershipType')))), 'Entity types to provision in Phase 0 (before tables). Each entry creates an entity table with membership modules and security.')
|
|
414
461
|
]), 'The complete blueprint definition -- the JSONB shape accepted by construct_blueprint().');
|
|
415
462
|
}
|
|
416
463
|
// ---------------------------------------------------------------------------
|
|
@@ -421,8 +468,8 @@ function sectionComment(title) {
|
|
|
421
468
|
empty.leadingComments = [
|
|
422
469
|
{
|
|
423
470
|
type: 'CommentBlock',
|
|
424
|
-
value: `*\n * ===========================================================================\n * ${title}\n * ===========================================================================\n
|
|
425
|
-
}
|
|
471
|
+
value: `*\n * ===========================================================================\n * ${title}\n * ===========================================================================\n `
|
|
472
|
+
}
|
|
426
473
|
];
|
|
427
474
|
return empty;
|
|
428
475
|
}
|
|
@@ -464,6 +511,9 @@ function buildProgram(meta) {
|
|
|
464
511
|
statements.push(buildBlueprintTableIndex());
|
|
465
512
|
statements.push(buildBlueprintUniqueConstraint());
|
|
466
513
|
statements.push(buildBlueprintTableUniqueConstraint());
|
|
514
|
+
statements.push(buildBlueprintStoragePolicy());
|
|
515
|
+
statements.push(buildBlueprintBucketSeed());
|
|
516
|
+
statements.push(buildBlueprintStorageConfig());
|
|
467
517
|
statements.push(buildBlueprintEntityTableProvision());
|
|
468
518
|
statements.push(buildBlueprintMembershipType());
|
|
469
519
|
// -- Node types discriminated union --
|
|
@@ -481,6 +531,7 @@ function buildProgram(meta) {
|
|
|
481
531
|
const file = t.file(program);
|
|
482
532
|
const header = [
|
|
483
533
|
'// GENERATED FILE \u2014 DO NOT EDIT',
|
|
534
|
+
'/* eslint-disable @typescript-eslint/no-empty-object-type */',
|
|
484
535
|
'//',
|
|
485
536
|
'// Regenerate with:',
|
|
486
537
|
'// cd graphql/node-type-registry && pnpm generate:types',
|
|
@@ -488,9 +539,9 @@ function buildProgram(meta) {
|
|
|
488
539
|
'// These types match the JSONB shape expected by construct_blueprint().',
|
|
489
540
|
'// All field names are snake_case to match the SQL convention.',
|
|
490
541
|
'',
|
|
491
|
-
''
|
|
542
|
+
''
|
|
492
543
|
].join('\n');
|
|
493
|
-
const output = generate(file, { comments: true });
|
|
544
|
+
const output = generate(file, { comments: true, jsescOption: { quotes: 'single' } });
|
|
494
545
|
return header + output.code + '\n';
|
|
495
546
|
}
|
|
496
547
|
// ---------------------------------------------------------------------------
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-type-registry",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.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",
|
|
@@ -47,5 +47,5 @@
|
|
|
47
47
|
"registry",
|
|
48
48
|
"graphile"
|
|
49
49
|
],
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "058b8200e99eb505477d1599ee0d5ab795aa0123"
|
|
51
51
|
}
|