@pattern-stack/codegen 0.20.2 → 0.21.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/CHANGELOG.md +48 -0
- package/dist/{chunk-3VEVGL74.js → chunk-3A34R6CI.js} +4 -4
- package/dist/{chunk-KK5A7B2T.js → chunk-524YKITE.js} +134 -20
- package/dist/chunk-524YKITE.js.map +1 -0
- package/dist/{chunk-VDL5CJ5C.js → chunk-6CJRZHV4.js} +4 -4
- package/dist/{chunk-COGHTKXY.js → chunk-7625PLY7.js} +4 -4
- package/dist/{chunk-QMN3LQR3.js → chunk-EEJC66ZF.js} +9 -9
- package/dist/{chunk-NR7QQ6ZI.js → chunk-G3IKPDTP.js} +2 -2
- package/dist/{chunk-BKP72EDW.js → chunk-GMRTI7AK.js} +12 -12
- package/dist/{chunk-E5FJWOMP.js → chunk-GV337QP3.js} +7 -7
- package/dist/{chunk-D44QFQJZ.js → chunk-MBFSG4KQ.js} +3 -3
- package/dist/{chunk-JGGZUP64.js → chunk-NXHL5YII.js} +7 -7
- package/dist/{chunk-E6PLM6QG.js → chunk-TKU6VYG3.js} +6 -6
- package/dist/{chunk-MVKW2BCR.js → chunk-YULGWXCY.js} +4 -4
- package/dist/{chunk-DB5UXJC3.js → chunk-YXI7K4MJ.js} +4 -4
- package/dist/runtime/base-classes/index.js +22 -22
- package/dist/runtime/shared/openapi/index.js +3 -3
- package/dist/runtime/subsystems/auth/auth.module.js +3 -3
- package/dist/runtime/subsystems/auth/index.js +15 -15
- package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js +3 -3
- package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +4 -4
- package/dist/runtime/subsystems/bridge/bridge.module.js +15 -15
- package/dist/runtime/subsystems/bridge/index.js +24 -24
- package/dist/runtime/subsystems/cache/cache.module.js +2 -2
- package/dist/runtime/subsystems/cache/index.js +4 -4
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +2 -2
- package/dist/runtime/subsystems/events/events.module.js +3 -3
- package/dist/runtime/subsystems/events/index.js +5 -5
- package/dist/runtime/subsystems/index.js +85 -85
- package/dist/runtime/subsystems/jobs/index.js +27 -27
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +5 -5
- package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js +2 -2
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js +2 -2
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +3 -3
- package/dist/runtime/subsystems/jobs/job-worker.js +2 -2
- package/dist/runtime/subsystems/jobs/job-worker.module.js +9 -9
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js +7 -7
- package/dist/runtime/subsystems/storage/index.js +1 -1
- package/dist/runtime/subsystems/storage/storage.module.js +1 -1
- package/dist/src/cli/index.js +80 -76
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/index.d.ts +111 -1
- package/dist/src/index.js +3 -1
- package/package.json +1 -1
- package/dist/chunk-KK5A7B2T.js.map +0 -1
- /package/dist/{chunk-3VEVGL74.js.map → chunk-3A34R6CI.js.map} +0 -0
- /package/dist/{chunk-VDL5CJ5C.js.map → chunk-6CJRZHV4.js.map} +0 -0
- /package/dist/{chunk-COGHTKXY.js.map → chunk-7625PLY7.js.map} +0 -0
- /package/dist/{chunk-QMN3LQR3.js.map → chunk-EEJC66ZF.js.map} +0 -0
- /package/dist/{chunk-NR7QQ6ZI.js.map → chunk-G3IKPDTP.js.map} +0 -0
- /package/dist/{chunk-BKP72EDW.js.map → chunk-GMRTI7AK.js.map} +0 -0
- /package/dist/{chunk-E5FJWOMP.js.map → chunk-GV337QP3.js.map} +0 -0
- /package/dist/{chunk-D44QFQJZ.js.map → chunk-MBFSG4KQ.js.map} +0 -0
- /package/dist/{chunk-JGGZUP64.js.map → chunk-NXHL5YII.js.map} +0 -0
- /package/dist/{chunk-E6PLM6QG.js.map → chunk-TKU6VYG3.js.map} +0 -0
- /package/dist/{chunk-MVKW2BCR.js.map → chunk-YULGWXCY.js.map} +0 -0
- /package/dist/{chunk-DB5UXJC3.js.map → chunk-YXI7K4MJ.js.map} +0 -0
package/dist/src/cli/index.js
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
DIRECTION_TO_POOL,
|
|
4
|
+
EAV_DATA_TYPE_TO_FIELD_TYPE,
|
|
4
5
|
EVENT_FIELD_TYPES,
|
|
6
|
+
EXTERNAL_SYNC_FIELDS,
|
|
7
|
+
EXTERNAL_SYNC_GROUP,
|
|
5
8
|
_resetRegistryForTests,
|
|
6
9
|
analyzeDomain,
|
|
7
10
|
buildManifest,
|
|
8
11
|
collectEntitySurfaces,
|
|
12
|
+
deriveFieldMeta,
|
|
9
13
|
detectYamlType,
|
|
10
14
|
findYamlFiles,
|
|
11
15
|
formatConsole,
|
|
@@ -17,7 +21,9 @@ import {
|
|
|
17
21
|
getManifestDir,
|
|
18
22
|
getOrchestrationPatternNames,
|
|
19
23
|
getPendingSuggestions,
|
|
24
|
+
hasExternalSyncShape,
|
|
20
25
|
isActiveProvider,
|
|
26
|
+
isEntityRefField,
|
|
21
27
|
isManifestStale,
|
|
22
28
|
loadAppPatterns,
|
|
23
29
|
loadEntities,
|
|
@@ -38,7 +44,7 @@ import {
|
|
|
38
44
|
validateOrchestrationProject,
|
|
39
45
|
validateProviders,
|
|
40
46
|
writeManifest
|
|
41
|
-
} from "../../chunk-
|
|
47
|
+
} from "../../chunk-524YKITE.js";
|
|
42
48
|
import "../../chunk-KVOWSC5S.js";
|
|
43
49
|
import "../../chunk-QFUIE37H.js";
|
|
44
50
|
import "../../chunk-FFUDEIFF.js";
|
|
@@ -5494,79 +5500,11 @@ function emitStore(ctx, outDir) {
|
|
|
5494
5500
|
|
|
5495
5501
|
// src/emitters/frontend/emit-fields.ts
|
|
5496
5502
|
import { join as join15 } from "path";
|
|
5497
|
-
|
|
5498
|
-
// src/emitters/frontend/field-meta.ts
|
|
5499
|
-
var CAMEL2 = (s) => s.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
5500
|
-
function formatLabel(fieldName) {
|
|
5501
|
-
return fieldName.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
5502
|
-
}
|
|
5503
|
-
function inferUiType(field) {
|
|
5504
|
-
if (field.ui.type) return field.ui.type;
|
|
5505
|
-
if (Array.isArray(field.choices) && field.choices.length > 0) return "enum";
|
|
5506
|
-
if (field.foreignKey) return "reference";
|
|
5507
|
-
const nameLower = field.name.toLowerCase();
|
|
5508
|
-
if (nameLower.includes("email")) return "email";
|
|
5509
|
-
if (nameLower.includes("url") || nameLower.includes("website")) return "url";
|
|
5510
|
-
if (nameLower.includes("password")) return "password";
|
|
5511
|
-
if (nameLower.includes("price") || nameLower.includes("amount") || nameLower.includes("cost") || nameLower.includes("value") || nameLower.includes("revenue")) {
|
|
5512
|
-
return "money";
|
|
5513
|
-
}
|
|
5514
|
-
if (nameLower.includes("percent") || nameLower.includes("rate")) {
|
|
5515
|
-
return "percentage";
|
|
5516
|
-
}
|
|
5517
|
-
switch (field.type) {
|
|
5518
|
-
case "string":
|
|
5519
|
-
return field.constraints.maxLength && field.constraints.maxLength > 500 ? "textarea" : "text";
|
|
5520
|
-
case "integer":
|
|
5521
|
-
case "decimal":
|
|
5522
|
-
return "number";
|
|
5523
|
-
case "boolean":
|
|
5524
|
-
return "boolean";
|
|
5525
|
-
case "uuid":
|
|
5526
|
-
return "text";
|
|
5527
|
-
case "date":
|
|
5528
|
-
return "date";
|
|
5529
|
-
case "datetime":
|
|
5530
|
-
return "datetime";
|
|
5531
|
-
case "json":
|
|
5532
|
-
return "json";
|
|
5533
|
-
default:
|
|
5534
|
-
return "text";
|
|
5535
|
-
}
|
|
5536
|
-
}
|
|
5537
|
-
function inferUiImportance(field) {
|
|
5538
|
-
if (field.ui.importance) return field.ui.importance;
|
|
5539
|
-
const nameLower = field.name.toLowerCase();
|
|
5540
|
-
if (["id", "created_at", "updated_at", "deleted_at"].includes(nameLower)) {
|
|
5541
|
-
return "tertiary";
|
|
5542
|
-
}
|
|
5543
|
-
if (field.foreignKey && nameLower.endsWith("_id")) return "secondary";
|
|
5544
|
-
if (field.required) return "primary";
|
|
5545
|
-
if (nameLower.includes("name") || nameLower.includes("title")) return "primary";
|
|
5546
|
-
return "secondary";
|
|
5547
|
-
}
|
|
5548
|
-
function isEntityRefField(field) {
|
|
5549
|
-
if (field.type === "entity_ref") return true;
|
|
5550
|
-
return field.name.endsWith("_entity_type") || field.name.endsWith("_entity_id");
|
|
5551
|
-
}
|
|
5552
|
-
function deriveFieldMeta(field) {
|
|
5553
|
-
const hasChoices = Array.isArray(field.choices) && field.choices.length > 0;
|
|
5554
|
-
const meta = {
|
|
5555
|
-
field: CAMEL2(field.name),
|
|
5556
|
-
label: field.ui.label ?? formatLabel(field.name),
|
|
5557
|
-
type: inferUiType(field),
|
|
5558
|
-
importance: inferUiImportance(field),
|
|
5559
|
-
sortable: field.ui.sortable ?? false,
|
|
5560
|
-
filterable: field.ui.filterable ?? false
|
|
5561
|
-
};
|
|
5562
|
-
if (hasChoices) meta.choices = field.choices;
|
|
5563
|
-
if (field.foreignKey) meta.reference = field.foreignKey.table;
|
|
5564
|
-
return meta;
|
|
5565
|
-
}
|
|
5566
|
-
|
|
5567
|
-
// src/emitters/frontend/emit-fields.ts
|
|
5568
5503
|
var SOURCE_DESC_SET5 = "the entity set";
|
|
5569
5504
|
function buildFieldMetaTypeFile() {
|
|
5505
|
+
const eavKeys = Object.keys(EAV_DATA_TYPE_TO_FIELD_TYPE);
|
|
5506
|
+
const eavUnion = eavKeys.map((k) => ` | '${k}'`).join("\n");
|
|
5507
|
+
const eavEntries = Object.entries(EAV_DATA_TYPE_TO_FIELD_TYPE).map(([k, v]) => ` ${k}: '${v}',`).join("\n");
|
|
5570
5508
|
const body = `/**
|
|
5571
5509
|
* Field metadata types for DataGrid, forms, and admin surfaces.
|
|
5572
5510
|
*/
|
|
@@ -5598,37 +5536,85 @@ export interface FieldMeta<T = unknown> {
|
|
|
5598
5536
|
importance: FieldImportance;
|
|
5599
5537
|
sortable?: boolean;
|
|
5600
5538
|
filterable?: boolean;
|
|
5539
|
+
/** Layout grouping (e.g. 'external_sync'). */
|
|
5540
|
+
group?: string;
|
|
5541
|
+
/** \`false\` \u21D2 hidden by default. Absent means visible. */
|
|
5542
|
+
visible?: boolean;
|
|
5543
|
+
placeholder?: string;
|
|
5544
|
+
/** Help/description text shown alongside the field. */
|
|
5545
|
+
help?: string;
|
|
5601
5546
|
format?: Record<string, unknown>;
|
|
5602
5547
|
choices?: string[];
|
|
5603
5548
|
reference?: string;
|
|
5549
|
+
/** Curated/displayed field \u2014 drives card & preview field selection. */
|
|
5550
|
+
isKeyField?: boolean;
|
|
5551
|
+
/** Sort position within the key-field set. */
|
|
5552
|
+
keyFieldOrder?: number;
|
|
5604
5553
|
}
|
|
5554
|
+
|
|
5555
|
+
/** EAV \`field_definitions.data_type\` vocabulary. */
|
|
5556
|
+
export type EavDataType =
|
|
5557
|
+
${eavUnion};
|
|
5558
|
+
|
|
5559
|
+
/**
|
|
5560
|
+
* EAV \`field_definitions.data_type\` \u2192 \`FieldType\` rendering contract: an EAV
|
|
5561
|
+
* field renders through the same vocabulary as a native column. Note both
|
|
5562
|
+
* \`picklist\` and \`multipicklist\` map to \`enum\` \u2014 multi-select rendering is a
|
|
5563
|
+
* consumer-side concern (check the EAV row's cardinality, not the FieldType).
|
|
5564
|
+
*/
|
|
5565
|
+
export const EAV_DATA_TYPE_TO_FIELD_TYPE: Record<EavDataType, FieldType> = {
|
|
5566
|
+
${eavEntries}
|
|
5567
|
+
};
|
|
5605
5568
|
`;
|
|
5606
5569
|
return withBanner(SOURCE_DESC_SET5, body);
|
|
5607
5570
|
}
|
|
5608
5571
|
function hasTimestamps(parsed) {
|
|
5609
5572
|
return parsed?.behaviors.includes("timestamps") ?? false;
|
|
5610
5573
|
}
|
|
5574
|
+
function hasSoftDelete(parsed) {
|
|
5575
|
+
return parsed?.behaviors.includes("soft_delete") ?? false;
|
|
5576
|
+
}
|
|
5611
5577
|
function displayFields(parsed) {
|
|
5612
5578
|
if (!parsed) return [];
|
|
5579
|
+
const syncShape = hasExternalSyncShape(parsed.fields.keys());
|
|
5613
5580
|
const out = [];
|
|
5614
5581
|
for (const field of parsed.fields.values()) {
|
|
5615
5582
|
if (field.name === "id") continue;
|
|
5616
5583
|
if (isEntityRefField(field)) continue;
|
|
5617
|
-
|
|
5584
|
+
const defaults = syncShape && EXTERNAL_SYNC_FIELDS.has(field.name) ? { group: EXTERNAL_SYNC_GROUP } : void 0;
|
|
5585
|
+
out.push(deriveFieldMeta(field, defaults));
|
|
5618
5586
|
}
|
|
5619
5587
|
return out;
|
|
5620
5588
|
}
|
|
5589
|
+
function quote(s) {
|
|
5590
|
+
return s.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
5591
|
+
}
|
|
5621
5592
|
function renderFieldMeta(meta) {
|
|
5622
5593
|
const lines = [
|
|
5623
5594
|
` field: '${meta.field}',`,
|
|
5624
|
-
` label: '${meta.label}',`,
|
|
5595
|
+
` label: '${quote(meta.label)}',`,
|
|
5625
5596
|
` type: '${meta.type}' as FieldType,`,
|
|
5626
5597
|
` importance: '${meta.importance}' as FieldImportance,`
|
|
5627
5598
|
];
|
|
5628
5599
|
if (meta.sortable) lines.push(" sortable: true,");
|
|
5629
5600
|
if (meta.filterable) lines.push(" filterable: true,");
|
|
5601
|
+
if (meta.group !== void 0) lines.push(` group: '${quote(meta.group)}',`);
|
|
5602
|
+
if (meta.visible !== void 0) lines.push(` visible: ${meta.visible},`);
|
|
5603
|
+
if (meta.placeholder !== void 0) {
|
|
5604
|
+
lines.push(` placeholder: '${quote(meta.placeholder)}',`);
|
|
5605
|
+
}
|
|
5606
|
+
if (meta.help !== void 0) lines.push(` help: '${quote(meta.help)}',`);
|
|
5607
|
+
if (meta.format !== void 0) {
|
|
5608
|
+
lines.push(` format: ${JSON.stringify(meta.format)},`);
|
|
5609
|
+
}
|
|
5630
5610
|
if (meta.choices) lines.push(` choices: ${JSON.stringify(meta.choices)},`);
|
|
5631
5611
|
if (meta.reference) lines.push(` reference: '${meta.reference}',`);
|
|
5612
|
+
if (meta.isKeyField) {
|
|
5613
|
+
lines.push(" isKeyField: true,");
|
|
5614
|
+
if (meta.keyFieldOrder !== void 0) {
|
|
5615
|
+
lines.push(` keyFieldOrder: ${meta.keyFieldOrder},`);
|
|
5616
|
+
}
|
|
5617
|
+
}
|
|
5632
5618
|
return ` ${meta.field}: {
|
|
5633
5619
|
${lines.join("\n")}
|
|
5634
5620
|
},`;
|
|
@@ -5642,6 +5628,7 @@ function buildEntityFieldsFile(entity, ctx) {
|
|
|
5642
5628
|
const fields = displayFields(parsed);
|
|
5643
5629
|
const rels = resolvableRels(entity, ctx);
|
|
5644
5630
|
const ts3 = hasTimestamps(parsed);
|
|
5631
|
+
const sd = hasSoftDelete(parsed);
|
|
5645
5632
|
const fieldEntries = fields.map(renderFieldMeta);
|
|
5646
5633
|
const relEntries = rels.map(
|
|
5647
5634
|
(r) => ` ${r.propertyName}: {
|
|
@@ -5668,8 +5655,22 @@ function buildEntityFieldsFile(entity, ctx) {
|
|
|
5668
5655
|
format: { dateFormat: 'relative' },
|
|
5669
5656
|
},`
|
|
5670
5657
|
] : [];
|
|
5671
|
-
const
|
|
5658
|
+
const sdEntries = sd ? [
|
|
5659
|
+
` deletedAt: {
|
|
5660
|
+
field: 'deletedAt',
|
|
5661
|
+
label: 'Deleted',
|
|
5662
|
+
type: 'datetime' as FieldType,
|
|
5663
|
+
importance: 'tertiary' as FieldImportance,
|
|
5664
|
+
format: { dateFormat: 'relative' },
|
|
5665
|
+
},`
|
|
5666
|
+
] : [];
|
|
5667
|
+
const allEntries = [...fieldEntries, ...relEntries, ...tsEntries, ...sdEntries].join(
|
|
5668
|
+
"\n"
|
|
5669
|
+
);
|
|
5672
5670
|
const primaryFields = fields.filter((f) => f.importance === "primary").map((f) => ` '${f.field}',`).join("\n");
|
|
5671
|
+
const keyFields = fields.filter((f) => f.isKeyField).sort(
|
|
5672
|
+
(a, b) => (a.keyFieldOrder ?? Number.MAX_SAFE_INTEGER) - (b.keyFieldOrder ?? Number.MAX_SAFE_INTEGER)
|
|
5673
|
+
).map((f) => ` '${f.field}',`).join("\n");
|
|
5673
5674
|
const searchFields = fields.filter((f) => f.filterable).map((f) => ` '${f.field}',`).join("\n");
|
|
5674
5675
|
const defaultSortField = ts3 ? "createdAt" : "id";
|
|
5675
5676
|
const expose = parsed?.expose ?? ["repository", "rest", "trpc"];
|
|
@@ -5691,6 +5692,9 @@ export const ${camelName}Metadata = {
|
|
|
5691
5692
|
|
|
5692
5693
|
primaryFields: [
|
|
5693
5694
|
${primaryFields}
|
|
5695
|
+
],
|
|
5696
|
+
keyFields: [
|
|
5697
|
+
${keyFields}
|
|
5694
5698
|
],
|
|
5695
5699
|
searchFields: [
|
|
5696
5700
|
${searchFields}
|
|
@@ -8657,7 +8661,7 @@ function buildAuthImportRewriter(subsystemsRoot) {
|
|
|
8657
8661
|
const relPosix = rel2.split(path24.sep).join("/");
|
|
8658
8662
|
return content.replace(
|
|
8659
8663
|
AUTH_BARE_IMPORT_RE,
|
|
8660
|
-
(_match,
|
|
8664
|
+
(_match, quote2) => `${quote2}${relPosix}${quote2}`
|
|
8661
8665
|
);
|
|
8662
8666
|
};
|
|
8663
8667
|
}
|