dzql 0.6.15 → 0.6.16
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 +1 -1
- package/src/cli/codegen/sql.ts +28 -1
- package/src/cli/compiler/ir.ts +4 -0
- package/src/shared/ir.ts +1 -0
package/package.json
CHANGED
package/src/cli/codegen/sql.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { compilePermission } from "../compiler/permissions.js";
|
|
2
2
|
import { compileGraphRules } from "../compiler/graph_rules.js";
|
|
3
|
-
import type { EntityIR, ManyToManyIR } from "../../shared/ir.js";
|
|
3
|
+
import type { EntityIR, ManyToManyIR, IncludeIR } from "../../shared/ir.js";
|
|
4
4
|
|
|
5
5
|
/** Column info from EntityIR */
|
|
6
6
|
interface ColumnInfo {
|
|
@@ -313,6 +313,32 @@ export function generateSaveFunction(name: string, entityIR: EntityIR): string {
|
|
|
313
313
|
return sql;
|
|
314
314
|
}).join('\n');
|
|
315
315
|
|
|
316
|
+
// FK expansion (add related objects to output for real-time events)
|
|
317
|
+
// Only expand direct FKs (where key_id column exists), not reverse FKs (child arrays)
|
|
318
|
+
const includes: Record<string, IncludeIR> = entityIR.includes || {};
|
|
319
|
+
const includeKeys = Object.keys(includes);
|
|
320
|
+
const fkExpansion = includeKeys.map(key => {
|
|
321
|
+
const config: IncludeIR = includes[key];
|
|
322
|
+
const targetEntity = config.entity;
|
|
323
|
+
const fkField = `${key}_id`; // Convention: author -> author_id
|
|
324
|
+
|
|
325
|
+
// Only expand if this is a direct FK (key_id column exists)
|
|
326
|
+
const hasFkColumn = entityIR.columns.some((c: ColumnInfo) => c.name === fkField);
|
|
327
|
+
|
|
328
|
+
if (hasFkColumn) {
|
|
329
|
+
// Direct FK: single object expansion (e.g., author_id -> author object)
|
|
330
|
+
return `
|
|
331
|
+
-- FK: Add ${key} to output (from ${fkField})
|
|
332
|
+
IF (v_result->>'${fkField}') IS NOT NULL THEN
|
|
333
|
+
v_result := v_result || jsonb_build_object('${key}',
|
|
334
|
+
(SELECT to_jsonb(t.*) FROM ${targetEntity} t WHERE t.id = (v_result->>'${fkField}')::int));
|
|
335
|
+
END IF;`;
|
|
336
|
+
}
|
|
337
|
+
// Skip reverse FKs - they would require querying child tables which may not exist
|
|
338
|
+
// and are not needed for the primary use case of expanding the saved record
|
|
339
|
+
return '';
|
|
340
|
+
}).filter(s => s).join('\n');
|
|
341
|
+
|
|
316
342
|
return `
|
|
317
343
|
CREATE OR REPLACE FUNCTION dzql_v2.save_${name}(p_user_id int, p_data jsonb)
|
|
318
344
|
RETURNS jsonb
|
|
@@ -365,6 +391,7 @@ ${m2mExtraction}
|
|
|
365
391
|
END IF;
|
|
366
392
|
${m2mSync}
|
|
367
393
|
${m2mExpansion}
|
|
394
|
+
${fkExpansion}
|
|
368
395
|
|
|
369
396
|
-- Resolve notification recipients
|
|
370
397
|
v_notify_users := dzql_v2.${name}_notify_users(p_user_id, v_result);
|
package/src/cli/compiler/ir.ts
CHANGED
|
@@ -175,6 +175,9 @@ export function generateIR(domain: DomainConfig): DomainIR {
|
|
|
175
175
|
};
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
// Parse includes (FK expansions)
|
|
179
|
+
const includes = parseIncludes(config.includes as Record<string, string | IncludeConfig> | undefined);
|
|
180
|
+
|
|
178
181
|
entities[name] = {
|
|
179
182
|
name,
|
|
180
183
|
table: name,
|
|
@@ -187,6 +190,7 @@ export function generateIR(domain: DomainConfig): DomainIR {
|
|
|
187
190
|
fieldDefaults: config.fieldDefaults || {},
|
|
188
191
|
permissions,
|
|
189
192
|
relationships: {},
|
|
193
|
+
includes,
|
|
190
194
|
manyToMany,
|
|
191
195
|
graphRules: {
|
|
192
196
|
onCreate: onCreateRules,
|
package/src/shared/ir.ts
CHANGED
|
@@ -130,6 +130,7 @@ export interface EntityIR {
|
|
|
130
130
|
delete: string[];
|
|
131
131
|
};
|
|
132
132
|
relationships: Record<string, RelationshipIR>;
|
|
133
|
+
includes: Record<string, IncludeIR>; // FK expansions (e.g., author: users)
|
|
133
134
|
manyToMany: Record<string, ManyToManyIR>;
|
|
134
135
|
graphRules: {
|
|
135
136
|
onCreate: GraphRuleIR[];
|