@pattern-stack/codegen 0.20.2 → 0.22.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/README.md +5 -1
- package/dist/{chunk-BKP72EDW.js → chunk-6DQEIXYU.js} +10 -10
- package/dist/{chunk-KK5A7B2T.js → chunk-6ECCJVYW.js} +136 -20
- package/dist/chunk-6ECCJVYW.js.map +1 -0
- package/dist/{chunk-QMN3LQR3.js → chunk-FNHNSFIJ.js} +9 -9
- package/dist/{chunk-JGGZUP64.js → chunk-NXHL5YII.js} +7 -7
- package/dist/{chunk-D44QFQJZ.js → chunk-QXVCRA23.js} +2 -2
- package/dist/{chunk-MVKW2BCR.js → chunk-YULGWXCY.js} +4 -4
- package/dist/runtime/base-classes/index.js +20 -20
- 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 +2 -2
- package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +1 -1
- package/dist/runtime/subsystems/bridge/bridge.module.js +10 -10
- package/dist/runtime/subsystems/bridge/index.js +18 -18
- package/dist/runtime/subsystems/cache/cache.module.js +1 -1
- package/dist/runtime/subsystems/cache/index.js +3 -3
- package/dist/runtime/subsystems/index.js +66 -66
- package/dist/runtime/subsystems/jobs/index.js +11 -11
- package/dist/runtime/subsystems/jobs/job-worker.module.js +5 -5
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js +4 -4
- package/dist/src/cli/index.js +94 -80
- 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-BKP72EDW.js.map → chunk-6DQEIXYU.js.map} +0 -0
- /package/dist/{chunk-QMN3LQR3.js.map → chunk-FNHNSFIJ.js.map} +0 -0
- /package/dist/{chunk-JGGZUP64.js.map → chunk-NXHL5YII.js.map} +0 -0
- /package/dist/{chunk-D44QFQJZ.js.map → chunk-QXVCRA23.js.map} +0 -0
- /package/dist/{chunk-MVKW2BCR.js.map → chunk-YULGWXCY.js.map} +0 -0
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
JobsDomainModule
|
|
3
|
-
} from "../../../chunk-
|
|
3
|
+
} from "../../../chunk-6DQEIXYU.js";
|
|
4
|
+
import "../../../chunk-VQOAATIG.js";
|
|
4
5
|
import "../../../chunk-3VEVGL74.js";
|
|
5
6
|
import "../../../chunk-CDLWYZVQ.js";
|
|
6
7
|
import "../../../chunk-L3LZWWSX.js";
|
|
7
8
|
import "../../../chunk-DV4RV2DC.js";
|
|
9
|
+
import "../../../chunk-PNZSGAB2.js";
|
|
10
|
+
import "../../../chunk-SNQ3TOWP.js";
|
|
8
11
|
import "../../../chunk-I6MVCB5A.js";
|
|
9
12
|
import "../../../chunk-RHVN6NA7.js";
|
|
10
13
|
import "../../../chunk-E6PLM6QG.js";
|
|
11
|
-
import "../../../chunk-VQOAATIG.js";
|
|
12
|
-
import "../../../chunk-PNZSGAB2.js";
|
|
13
|
-
import "../../../chunk-SNQ3TOWP.js";
|
|
14
14
|
import "../../../chunk-T4BIIU5E.js";
|
|
15
15
|
import "../../../chunk-Q6LRJ4VI.js";
|
|
16
16
|
import "../../../chunk-7P5ODGLA.js";
|
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-6ECCJVYW.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
|
}
|
|
5611
|
-
function
|
|
5574
|
+
function hasSoftDelete(parsed) {
|
|
5575
|
+
return parsed?.behaviors.includes("soft_delete") ?? false;
|
|
5576
|
+
}
|
|
5577
|
+
function displayFields(parsed, opts = {}) {
|
|
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, opts));
|
|
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
|
},`;
|
|
@@ -5639,9 +5625,10 @@ function humanizeClass(className) {
|
|
|
5639
5625
|
function buildEntityFieldsFile(entity, ctx) {
|
|
5640
5626
|
const parsed = ctx.parsed.get(entity.name);
|
|
5641
5627
|
const { camelName, className, classNamePlural, name, plural } = entity;
|
|
5642
|
-
const fields = displayFields(parsed);
|
|
5628
|
+
const fields = displayFields(parsed, { textareaThreshold: ctx.config.textareaThreshold });
|
|
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}
|
|
@@ -5950,11 +5954,20 @@ var FrontendCatalogConfigSchema = z.object({
|
|
|
5950
5954
|
}).strict()
|
|
5951
5955
|
).default([])
|
|
5952
5956
|
}).default({});
|
|
5957
|
+
var FrontendFieldsConfigSchema = z.object({
|
|
5958
|
+
/**
|
|
5959
|
+
* String → textarea cutoff (strictly greater than). Absent or `undefined`
|
|
5960
|
+
* ⇒ 500. Explicit `null` ⇒ heuristic disabled (all bounded strings stay
|
|
5961
|
+
* `text` unless the author sets `ui_type: textarea`).
|
|
5962
|
+
*/
|
|
5963
|
+
textareaThreshold: z.number().int().positive().nullable().default(500)
|
|
5964
|
+
}).strict().default({});
|
|
5953
5965
|
var FrontendConfigSchema = z.object({
|
|
5954
5966
|
auth: FrontendAuthConfigSchema,
|
|
5955
5967
|
parsers: z.record(z.string()).default({ timestamptz: "(date: string) => new Date(date)" }),
|
|
5956
5968
|
sync: FrontendSyncConfigSchema,
|
|
5957
|
-
catalog: FrontendCatalogConfigSchema
|
|
5969
|
+
catalog: FrontendCatalogConfigSchema,
|
|
5970
|
+
fields: FrontendFieldsConfigSchema
|
|
5958
5971
|
}).strict().default({});
|
|
5959
5972
|
|
|
5960
5973
|
// src/emitters/frontend/load-context.ts
|
|
@@ -6002,7 +6015,8 @@ function mapFrontendEmitConfig(config) {
|
|
|
6002
6015
|
parsers: fe.parsers,
|
|
6003
6016
|
architecture,
|
|
6004
6017
|
dbEntitiesImport: dbEntities.import,
|
|
6005
|
-
catalogCategories: fe.catalog.categories
|
|
6018
|
+
catalogCategories: fe.catalog.categories,
|
|
6019
|
+
textareaThreshold: fe.fields.textareaThreshold
|
|
6006
6020
|
};
|
|
6007
6021
|
}
|
|
6008
6022
|
function loadProviderCatalogInputs(cwd, config) {
|
|
@@ -8657,7 +8671,7 @@ function buildAuthImportRewriter(subsystemsRoot) {
|
|
|
8657
8671
|
const relPosix = rel2.split(path24.sep).join("/");
|
|
8658
8672
|
return content.replace(
|
|
8659
8673
|
AUTH_BARE_IMPORT_RE,
|
|
8660
|
-
(_match,
|
|
8674
|
+
(_match, quote2) => `${quote2}${relPosix}${quote2}`
|
|
8661
8675
|
);
|
|
8662
8676
|
};
|
|
8663
8677
|
}
|