metal-orm 1.0.113 → 1.0.115
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/README.md +11 -8
- package/dist/index.cjs +425 -205
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -1
- package/dist/index.d.ts +27 -1
- package/dist/index.js +419 -205
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/dto/openapi/generators/tree.ts +276 -0
- package/src/dto/openapi/index.ts +6 -5
- package/src/dto/openapi/type-mappings.ts +207 -191
package/dist/index.cjs
CHANGED
|
@@ -48,6 +48,7 @@ __export(index_exports, {
|
|
|
48
48
|
BelongsTo: () => BelongsTo,
|
|
49
49
|
BelongsToMany: () => BelongsToMany,
|
|
50
50
|
BigIntTypeStrategy: () => BigIntTypeStrategy,
|
|
51
|
+
BinaryTypeStrategy: () => BinaryTypeStrategy,
|
|
51
52
|
BooleanTypeStrategy: () => BooleanTypeStrategy,
|
|
52
53
|
CEP: () => CEP,
|
|
53
54
|
CNPJ: () => CNPJ,
|
|
@@ -217,6 +218,7 @@ __export(index_exports, {
|
|
|
217
218
|
generateRelationComponents: () => generateRelationComponents,
|
|
218
219
|
generateSchemaSql: () => generateSchemaSql,
|
|
219
220
|
generateSchemaSqlFor: () => generateSchemaSqlFor,
|
|
221
|
+
generateTreeComponents: () => generateTreeComponents,
|
|
220
222
|
getColumn: () => getColumn,
|
|
221
223
|
getColumnMap: () => getColumnMap,
|
|
222
224
|
getColumnType: () => getColumnType,
|
|
@@ -380,6 +382,7 @@ __export(index_exports, {
|
|
|
380
382
|
tableRef: () => tableRef,
|
|
381
383
|
tan: () => tan,
|
|
382
384
|
threadResults: () => threadResults,
|
|
385
|
+
threadedNodeToOpenApiSchema: () => threadedNodeToOpenApiSchema,
|
|
383
386
|
toColumnRef: () => toColumnRef,
|
|
384
387
|
toPagedResponse: () => toPagedResponse,
|
|
385
388
|
toPagedResponseBuilder: () => toPagedResponseBuilder,
|
|
@@ -388,6 +391,9 @@ __export(index_exports, {
|
|
|
388
391
|
toResponseBuilder: () => toResponseBuilder,
|
|
389
392
|
toTableRef: () => toTableRef,
|
|
390
393
|
treeEntityRegistry: () => treeEntityRegistry,
|
|
394
|
+
treeListEntryToOpenApiSchema: () => treeListEntryToOpenApiSchema,
|
|
395
|
+
treeNodeResultToOpenApiSchema: () => treeNodeResultToOpenApiSchema,
|
|
396
|
+
treeNodeToOpenApiSchema: () => treeNodeToOpenApiSchema,
|
|
391
397
|
treeQuery: () => treeQuery,
|
|
392
398
|
trim: () => trim,
|
|
393
399
|
trunc: () => trunc,
|
|
@@ -15073,6 +15079,18 @@ var UuidTypeStrategy = class {
|
|
|
15073
15079
|
return "uuid";
|
|
15074
15080
|
}
|
|
15075
15081
|
};
|
|
15082
|
+
var BinaryTypeStrategy = class {
|
|
15083
|
+
types = ["BLOB", "BINARY", "VARBINARY", "BYTEA"];
|
|
15084
|
+
supports(type) {
|
|
15085
|
+
return this.types.includes(type.toUpperCase());
|
|
15086
|
+
}
|
|
15087
|
+
getOpenApiType() {
|
|
15088
|
+
return "string";
|
|
15089
|
+
}
|
|
15090
|
+
getFormat() {
|
|
15091
|
+
return "byte";
|
|
15092
|
+
}
|
|
15093
|
+
};
|
|
15076
15094
|
var DateTimeTypeStrategy = class {
|
|
15077
15095
|
types = ["DATE", "DATETIME", "TIMESTAMP", "TIMESTAMPTZ"];
|
|
15078
15096
|
supports(type) {
|
|
@@ -15091,9 +15109,6 @@ var StringTypeStrategy = class {
|
|
|
15091
15109
|
"TEXT",
|
|
15092
15110
|
"VARCHAR",
|
|
15093
15111
|
"CHAR",
|
|
15094
|
-
"BINARY",
|
|
15095
|
-
"VARBINARY",
|
|
15096
|
-
"BLOB",
|
|
15097
15112
|
"ENUM"
|
|
15098
15113
|
];
|
|
15099
15114
|
supports(type) {
|
|
@@ -15127,6 +15142,7 @@ var TypeMappingService = class {
|
|
|
15127
15142
|
new BooleanTypeStrategy(),
|
|
15128
15143
|
new DateTimeTypeStrategy(),
|
|
15129
15144
|
new UuidTypeStrategy(),
|
|
15145
|
+
new BinaryTypeStrategy(),
|
|
15130
15146
|
new StringTypeStrategy(),
|
|
15131
15147
|
new DefaultTypeStrategy()
|
|
15132
15148
|
];
|
|
@@ -15955,6 +15971,406 @@ function extractReusableSchemas(schema, existing = {}, prefix = "") {
|
|
|
15955
15971
|
return existing;
|
|
15956
15972
|
}
|
|
15957
15973
|
|
|
15974
|
+
// src/tree/tree-types.ts
|
|
15975
|
+
var DEFAULT_TREE_CONFIG = {
|
|
15976
|
+
parentKey: "parentId",
|
|
15977
|
+
leftKey: "lft",
|
|
15978
|
+
rightKey: "rght",
|
|
15979
|
+
cascadeCallbacks: false
|
|
15980
|
+
};
|
|
15981
|
+
function isTreeConfig(value) {
|
|
15982
|
+
if (typeof value !== "object" || value === null) return false;
|
|
15983
|
+
const obj = value;
|
|
15984
|
+
return typeof obj.parentKey === "string" && typeof obj.leftKey === "string" && typeof obj.rightKey === "string";
|
|
15985
|
+
}
|
|
15986
|
+
function resolveTreeConfig(partial) {
|
|
15987
|
+
return {
|
|
15988
|
+
parentKey: partial.parentKey ?? DEFAULT_TREE_CONFIG.parentKey,
|
|
15989
|
+
leftKey: partial.leftKey ?? DEFAULT_TREE_CONFIG.leftKey,
|
|
15990
|
+
rightKey: partial.rightKey ?? DEFAULT_TREE_CONFIG.rightKey,
|
|
15991
|
+
depthKey: partial.depthKey,
|
|
15992
|
+
scope: partial.scope,
|
|
15993
|
+
cascadeCallbacks: partial.cascadeCallbacks ?? DEFAULT_TREE_CONFIG.cascadeCallbacks,
|
|
15994
|
+
recoverOrder: partial.recoverOrder
|
|
15995
|
+
};
|
|
15996
|
+
}
|
|
15997
|
+
function validateTreeTable(table, config) {
|
|
15998
|
+
const missingColumns = [];
|
|
15999
|
+
const warnings = [];
|
|
16000
|
+
const requiredColumns = [config.parentKey, config.leftKey, config.rightKey];
|
|
16001
|
+
for (const col2 of requiredColumns) {
|
|
16002
|
+
if (!(col2 in table.columns)) {
|
|
16003
|
+
missingColumns.push(col2);
|
|
16004
|
+
}
|
|
16005
|
+
}
|
|
16006
|
+
if (config.depthKey && !(config.depthKey in table.columns)) {
|
|
16007
|
+
warnings.push(`Optional depth column '${config.depthKey}' not found in table '${table.name}'`);
|
|
16008
|
+
}
|
|
16009
|
+
if (config.scope) {
|
|
16010
|
+
for (const scopeCol of config.scope) {
|
|
16011
|
+
if (!(scopeCol in table.columns)) {
|
|
16012
|
+
missingColumns.push(scopeCol);
|
|
16013
|
+
}
|
|
16014
|
+
}
|
|
16015
|
+
}
|
|
16016
|
+
const leftCol = table.columns[config.leftKey];
|
|
16017
|
+
const rightCol = table.columns[config.rightKey];
|
|
16018
|
+
if (leftCol && leftCol.type !== "int" && leftCol.type !== "integer") {
|
|
16019
|
+
warnings.push(`Left column '${config.leftKey}' should be an integer type`);
|
|
16020
|
+
}
|
|
16021
|
+
if (rightCol && rightCol.type !== "int" && rightCol.type !== "integer") {
|
|
16022
|
+
warnings.push(`Right column '${config.rightKey}' should be an integer type`);
|
|
16023
|
+
}
|
|
16024
|
+
return {
|
|
16025
|
+
valid: missingColumns.length === 0,
|
|
16026
|
+
missingColumns,
|
|
16027
|
+
warnings
|
|
16028
|
+
};
|
|
16029
|
+
}
|
|
16030
|
+
function getTreeColumns(table, config) {
|
|
16031
|
+
const parentColumn = table.columns[config.parentKey];
|
|
16032
|
+
const leftColumn = table.columns[config.leftKey];
|
|
16033
|
+
const rightColumn = table.columns[config.rightKey];
|
|
16034
|
+
const depthColumn = config.depthKey ? table.columns[config.depthKey] : void 0;
|
|
16035
|
+
const scopeColumns = (config.scope ?? []).map((s) => table.columns[s]).filter(Boolean);
|
|
16036
|
+
if (!parentColumn || !leftColumn || !rightColumn) {
|
|
16037
|
+
throw new Error(
|
|
16038
|
+
`Table '${table.name}' is missing required tree columns. Required: ${config.parentKey}, ${config.leftKey}, ${config.rightKey}`
|
|
16039
|
+
);
|
|
16040
|
+
}
|
|
16041
|
+
return {
|
|
16042
|
+
parentColumn,
|
|
16043
|
+
leftColumn,
|
|
16044
|
+
rightColumn,
|
|
16045
|
+
depthColumn,
|
|
16046
|
+
scopeColumns
|
|
16047
|
+
};
|
|
16048
|
+
}
|
|
16049
|
+
|
|
16050
|
+
// src/tree/tree-decorator.ts
|
|
16051
|
+
var TREE_METADATA_KEY = /* @__PURE__ */ Symbol("metal-orm:tree");
|
|
16052
|
+
function Tree(options = {}) {
|
|
16053
|
+
return function(target) {
|
|
16054
|
+
const config = resolveTreeConfig(options);
|
|
16055
|
+
const metadata = { config };
|
|
16056
|
+
setTreeMetadataOnClass(target, metadata);
|
|
16057
|
+
return target;
|
|
16058
|
+
};
|
|
16059
|
+
}
|
|
16060
|
+
function TreeParent() {
|
|
16061
|
+
return function(_value, context) {
|
|
16062
|
+
const propertyName = String(context.name);
|
|
16063
|
+
context.addInitializer(function() {
|
|
16064
|
+
const constructor = this.constructor;
|
|
16065
|
+
const metadata = getTreeMetadata(constructor);
|
|
16066
|
+
if (metadata) {
|
|
16067
|
+
metadata.parentProperty = propertyName;
|
|
16068
|
+
setTreeMetadata(constructor, metadata);
|
|
16069
|
+
}
|
|
16070
|
+
});
|
|
16071
|
+
};
|
|
16072
|
+
}
|
|
16073
|
+
function TreeChildren() {
|
|
16074
|
+
return function(_value, context) {
|
|
16075
|
+
const propertyName = String(context.name);
|
|
16076
|
+
context.addInitializer(function() {
|
|
16077
|
+
const constructor = this.constructor;
|
|
16078
|
+
const metadata = getTreeMetadata(constructor);
|
|
16079
|
+
if (metadata) {
|
|
16080
|
+
metadata.childrenProperty = propertyName;
|
|
16081
|
+
setTreeMetadata(constructor, metadata);
|
|
16082
|
+
}
|
|
16083
|
+
});
|
|
16084
|
+
};
|
|
16085
|
+
}
|
|
16086
|
+
function getTreeMetadata(target) {
|
|
16087
|
+
return target[TREE_METADATA_KEY];
|
|
16088
|
+
}
|
|
16089
|
+
function setTreeMetadata(target, metadata) {
|
|
16090
|
+
target[TREE_METADATA_KEY] = metadata;
|
|
16091
|
+
}
|
|
16092
|
+
function setTreeMetadataOnClass(target, metadata) {
|
|
16093
|
+
target[TREE_METADATA_KEY] = metadata;
|
|
16094
|
+
}
|
|
16095
|
+
function hasTreeBehavior(target) {
|
|
16096
|
+
return getTreeMetadata(target) !== void 0;
|
|
16097
|
+
}
|
|
16098
|
+
function getTreeConfig(target) {
|
|
16099
|
+
return getTreeMetadata(target)?.config;
|
|
16100
|
+
}
|
|
16101
|
+
var TreeEntityRegistry = class {
|
|
16102
|
+
entities = /* @__PURE__ */ new Map();
|
|
16103
|
+
tableNames = /* @__PURE__ */ new Map();
|
|
16104
|
+
/**
|
|
16105
|
+
* Registers an entity class with its table name.
|
|
16106
|
+
*/
|
|
16107
|
+
register(entityClass, tableName) {
|
|
16108
|
+
this.entities.set(tableName, entityClass);
|
|
16109
|
+
this.tableNames.set(entityClass, tableName);
|
|
16110
|
+
}
|
|
16111
|
+
/**
|
|
16112
|
+
* Gets the entity class for a table name.
|
|
16113
|
+
*/
|
|
16114
|
+
getByTableName(tableName) {
|
|
16115
|
+
return this.entities.get(tableName);
|
|
16116
|
+
}
|
|
16117
|
+
/**
|
|
16118
|
+
* Gets the table name for an entity class.
|
|
16119
|
+
*/
|
|
16120
|
+
getTableName(entityClass) {
|
|
16121
|
+
return this.tableNames.get(entityClass);
|
|
16122
|
+
}
|
|
16123
|
+
/**
|
|
16124
|
+
* Checks if a table has tree behavior.
|
|
16125
|
+
*/
|
|
16126
|
+
isTreeTable(tableName) {
|
|
16127
|
+
const entity = this.entities.get(tableName);
|
|
16128
|
+
return entity ? hasTreeBehavior(entity) : false;
|
|
16129
|
+
}
|
|
16130
|
+
/**
|
|
16131
|
+
* Gets all registered tree entities.
|
|
16132
|
+
*/
|
|
16133
|
+
getAll() {
|
|
16134
|
+
const result = [];
|
|
16135
|
+
for (const [tableName, entityClass] of this.entities) {
|
|
16136
|
+
const metadata = getTreeMetadata(entityClass);
|
|
16137
|
+
if (metadata) {
|
|
16138
|
+
result.push({ entityClass, tableName, metadata });
|
|
16139
|
+
}
|
|
16140
|
+
}
|
|
16141
|
+
return result;
|
|
16142
|
+
}
|
|
16143
|
+
/**
|
|
16144
|
+
* Clears the registry.
|
|
16145
|
+
*/
|
|
16146
|
+
clear() {
|
|
16147
|
+
this.entities.clear();
|
|
16148
|
+
this.tableNames.clear();
|
|
16149
|
+
}
|
|
16150
|
+
};
|
|
16151
|
+
var treeEntityRegistry = new TreeEntityRegistry();
|
|
16152
|
+
function getTreeBounds(entity, config) {
|
|
16153
|
+
const data = entity;
|
|
16154
|
+
const lft = data[config.leftKey];
|
|
16155
|
+
const rght = data[config.rightKey];
|
|
16156
|
+
if (typeof lft !== "number" || typeof rght !== "number") {
|
|
16157
|
+
return null;
|
|
16158
|
+
}
|
|
16159
|
+
return { lft, rght };
|
|
16160
|
+
}
|
|
16161
|
+
function getTreeParentId(entity, config) {
|
|
16162
|
+
return entity[config.parentKey];
|
|
16163
|
+
}
|
|
16164
|
+
function setTreeBounds(entity, config, lft, rght, depth) {
|
|
16165
|
+
const data = entity;
|
|
16166
|
+
data[config.leftKey] = lft;
|
|
16167
|
+
data[config.rightKey] = rght;
|
|
16168
|
+
if (config.depthKey && depth !== void 0) {
|
|
16169
|
+
data[config.depthKey] = depth;
|
|
16170
|
+
}
|
|
16171
|
+
}
|
|
16172
|
+
function setTreeParentId(entity, config, parentId) {
|
|
16173
|
+
entity[config.parentKey] = parentId;
|
|
16174
|
+
}
|
|
16175
|
+
|
|
16176
|
+
// src/dto/openapi/generators/tree.ts
|
|
16177
|
+
function threadedNodeToOpenApiSchema(target, options) {
|
|
16178
|
+
const componentName = options?.componentName;
|
|
16179
|
+
const nodeSchema = entityToOpenApiSchema(target, options);
|
|
16180
|
+
const treeNodeSchema = {
|
|
16181
|
+
type: "object",
|
|
16182
|
+
properties: {
|
|
16183
|
+
node: nodeSchema,
|
|
16184
|
+
children: {
|
|
16185
|
+
type: "array",
|
|
16186
|
+
items: componentName ? { $ref: `#/components/schemas/${componentName}` } : {},
|
|
16187
|
+
description: "Child nodes in the tree hierarchy"
|
|
16188
|
+
}
|
|
16189
|
+
},
|
|
16190
|
+
required: ["node", "children"],
|
|
16191
|
+
description: "A node in a threaded tree structure with nested children"
|
|
16192
|
+
};
|
|
16193
|
+
return treeNodeSchema;
|
|
16194
|
+
}
|
|
16195
|
+
function treeNodeToOpenApiSchema(target, options) {
|
|
16196
|
+
const includeMetadata = options?.includeTreeMetadata ?? true;
|
|
16197
|
+
const entitySchema = entityToOpenApiSchema(target, options);
|
|
16198
|
+
const properties = {
|
|
16199
|
+
entity: entitySchema,
|
|
16200
|
+
lft: {
|
|
16201
|
+
type: "integer",
|
|
16202
|
+
description: "Left boundary value (nested set)"
|
|
16203
|
+
},
|
|
16204
|
+
rght: {
|
|
16205
|
+
type: "integer",
|
|
16206
|
+
description: "Right boundary value (nested set)"
|
|
16207
|
+
},
|
|
16208
|
+
isLeaf: {
|
|
16209
|
+
type: "boolean",
|
|
16210
|
+
description: "Whether this node has no children"
|
|
16211
|
+
},
|
|
16212
|
+
isRoot: {
|
|
16213
|
+
type: "boolean",
|
|
16214
|
+
description: "Whether this node has no parent"
|
|
16215
|
+
},
|
|
16216
|
+
childCount: {
|
|
16217
|
+
type: "integer",
|
|
16218
|
+
minimum: 0,
|
|
16219
|
+
description: "Number of descendants"
|
|
16220
|
+
}
|
|
16221
|
+
};
|
|
16222
|
+
if (includeMetadata) {
|
|
16223
|
+
properties.depth = {
|
|
16224
|
+
type: "integer",
|
|
16225
|
+
minimum: 0,
|
|
16226
|
+
description: "Depth level (0 = root)"
|
|
16227
|
+
};
|
|
16228
|
+
}
|
|
16229
|
+
return {
|
|
16230
|
+
type: "object",
|
|
16231
|
+
properties,
|
|
16232
|
+
required: ["entity", "lft", "rght", "isLeaf", "isRoot", "childCount"],
|
|
16233
|
+
description: "A tree node with nested set boundaries and metadata"
|
|
16234
|
+
};
|
|
16235
|
+
}
|
|
16236
|
+
function treeNodeResultToOpenApiSchema(target, options) {
|
|
16237
|
+
const includeMetadata = options?.includeTreeMetadata ?? true;
|
|
16238
|
+
const entitySchema = entityToOpenApiSchema(target, options);
|
|
16239
|
+
const parentKey = resolveParentKey(target, options);
|
|
16240
|
+
const parentSchema = resolveParentSchema(target, parentKey, options?.dialect);
|
|
16241
|
+
const parentIdSchema = {
|
|
16242
|
+
...parentSchema,
|
|
16243
|
+
description: parentSchema.description ?? "Parent identifier (null for roots)"
|
|
16244
|
+
};
|
|
16245
|
+
const properties = {
|
|
16246
|
+
data: entitySchema,
|
|
16247
|
+
lft: {
|
|
16248
|
+
type: "integer",
|
|
16249
|
+
description: "Left boundary value (nested set)"
|
|
16250
|
+
},
|
|
16251
|
+
rght: {
|
|
16252
|
+
type: "integer",
|
|
16253
|
+
description: "Right boundary value (nested set)"
|
|
16254
|
+
},
|
|
16255
|
+
parentId: parentIdSchema,
|
|
16256
|
+
isLeaf: {
|
|
16257
|
+
type: "boolean",
|
|
16258
|
+
description: "Whether this node has no children"
|
|
16259
|
+
},
|
|
16260
|
+
isRoot: {
|
|
16261
|
+
type: "boolean",
|
|
16262
|
+
description: "Whether this node has no parent"
|
|
16263
|
+
}
|
|
16264
|
+
};
|
|
16265
|
+
if (includeMetadata) {
|
|
16266
|
+
properties.depth = {
|
|
16267
|
+
type: "integer",
|
|
16268
|
+
minimum: 0,
|
|
16269
|
+
description: "Depth level (0 = root)"
|
|
16270
|
+
};
|
|
16271
|
+
}
|
|
16272
|
+
return {
|
|
16273
|
+
type: "object",
|
|
16274
|
+
properties,
|
|
16275
|
+
required: ["data", "lft", "rght", "parentId", "isLeaf", "isRoot"],
|
|
16276
|
+
description: "A tree node result with nested set boundaries and metadata"
|
|
16277
|
+
};
|
|
16278
|
+
}
|
|
16279
|
+
function treeListEntryToOpenApiSchema(options) {
|
|
16280
|
+
const keyType = options?.keyType ?? "integer";
|
|
16281
|
+
const valueType = options?.valueType ?? "string";
|
|
16282
|
+
return {
|
|
16283
|
+
type: "object",
|
|
16284
|
+
properties: {
|
|
16285
|
+
key: {
|
|
16286
|
+
type: keyType,
|
|
16287
|
+
description: "The key (usually primary key)"
|
|
16288
|
+
},
|
|
16289
|
+
value: {
|
|
16290
|
+
type: valueType,
|
|
16291
|
+
description: "The display value with depth prefix"
|
|
16292
|
+
},
|
|
16293
|
+
depth: {
|
|
16294
|
+
type: "integer",
|
|
16295
|
+
minimum: 0,
|
|
16296
|
+
description: "The depth level"
|
|
16297
|
+
}
|
|
16298
|
+
},
|
|
16299
|
+
required: ["key", "value", "depth"],
|
|
16300
|
+
description: "A tree list entry for dropdown/select rendering"
|
|
16301
|
+
};
|
|
16302
|
+
}
|
|
16303
|
+
function generateTreeComponents(target, baseName, options) {
|
|
16304
|
+
const threadedNodeName = `${baseName}TreeNode`;
|
|
16305
|
+
return {
|
|
16306
|
+
[baseName]: entityToOpenApiSchema(target, options),
|
|
16307
|
+
[`${baseName}Node`]: treeNodeToOpenApiSchema(target, options),
|
|
16308
|
+
[`${baseName}NodeResult`]: treeNodeResultToOpenApiSchema(target, options),
|
|
16309
|
+
[threadedNodeName]: threadedNodeToOpenApiSchema(target, {
|
|
16310
|
+
...options,
|
|
16311
|
+
componentName: threadedNodeName
|
|
16312
|
+
}),
|
|
16313
|
+
[`${baseName}TreeList`]: {
|
|
16314
|
+
type: "array",
|
|
16315
|
+
items: treeListEntryToOpenApiSchema(),
|
|
16316
|
+
description: `Flat list of ${baseName} tree entries for dropdown/select`
|
|
16317
|
+
},
|
|
16318
|
+
[`${baseName}ThreadedTree`]: {
|
|
16319
|
+
type: "array",
|
|
16320
|
+
items: { $ref: `#/components/schemas/${threadedNodeName}` },
|
|
16321
|
+
description: `Threaded tree structure of ${baseName} nodes`
|
|
16322
|
+
}
|
|
16323
|
+
};
|
|
16324
|
+
}
|
|
16325
|
+
function entityToOpenApiSchema(target, options) {
|
|
16326
|
+
const columns = getColumnMap(target);
|
|
16327
|
+
const properties = {};
|
|
16328
|
+
const required = [];
|
|
16329
|
+
const dialect = options?.dialect ?? "openapi-3.1";
|
|
16330
|
+
for (const [key, col2] of Object.entries(columns)) {
|
|
16331
|
+
if (options?.exclude?.includes(key)) {
|
|
16332
|
+
continue;
|
|
16333
|
+
}
|
|
16334
|
+
if (options?.include && !options.include.includes(key)) {
|
|
16335
|
+
continue;
|
|
16336
|
+
}
|
|
16337
|
+
properties[key] = columnToOpenApiSchema(col2, dialect);
|
|
16338
|
+
if (col2.notNull || col2.primary) {
|
|
16339
|
+
required.push(key);
|
|
16340
|
+
}
|
|
16341
|
+
}
|
|
16342
|
+
return {
|
|
16343
|
+
type: "object",
|
|
16344
|
+
properties,
|
|
16345
|
+
...required.length > 0 && { required }
|
|
16346
|
+
};
|
|
16347
|
+
}
|
|
16348
|
+
function resolveParentSchema(target, parentKey, dialect = "openapi-3.1") {
|
|
16349
|
+
const columns = getColumnMap(target);
|
|
16350
|
+
const parentColumn = columns[parentKey] ?? findColumnByName(columns, parentKey);
|
|
16351
|
+
if (parentColumn) {
|
|
16352
|
+
return columnToOpenApiSchema(parentColumn, dialect);
|
|
16353
|
+
}
|
|
16354
|
+
return {
|
|
16355
|
+
type: ["string", "null"]
|
|
16356
|
+
};
|
|
16357
|
+
}
|
|
16358
|
+
function resolveParentKey(target, options) {
|
|
16359
|
+
if (options?.parentKey) {
|
|
16360
|
+
return options.parentKey;
|
|
16361
|
+
}
|
|
16362
|
+
if (!isTableDef2(target)) {
|
|
16363
|
+
const config = getTreeConfig(target);
|
|
16364
|
+
if (config?.parentKey) {
|
|
16365
|
+
return config.parentKey;
|
|
16366
|
+
}
|
|
16367
|
+
}
|
|
16368
|
+
return "parentId";
|
|
16369
|
+
}
|
|
16370
|
+
function findColumnByName(columns, columnName) {
|
|
16371
|
+
return Object.values(columns).find((col2) => col2.name === columnName);
|
|
16372
|
+
}
|
|
16373
|
+
|
|
15958
16374
|
// src/dto/openapi/generators/pagination.ts
|
|
15959
16375
|
var paginationParamsSchema = {
|
|
15960
16376
|
type: "object",
|
|
@@ -16055,82 +16471,6 @@ function pagedResponseToOpenApiSchema(itemSchema) {
|
|
|
16055
16471
|
};
|
|
16056
16472
|
}
|
|
16057
16473
|
|
|
16058
|
-
// src/tree/tree-types.ts
|
|
16059
|
-
var DEFAULT_TREE_CONFIG = {
|
|
16060
|
-
parentKey: "parentId",
|
|
16061
|
-
leftKey: "lft",
|
|
16062
|
-
rightKey: "rght",
|
|
16063
|
-
cascadeCallbacks: false
|
|
16064
|
-
};
|
|
16065
|
-
function isTreeConfig(value) {
|
|
16066
|
-
if (typeof value !== "object" || value === null) return false;
|
|
16067
|
-
const obj = value;
|
|
16068
|
-
return typeof obj.parentKey === "string" && typeof obj.leftKey === "string" && typeof obj.rightKey === "string";
|
|
16069
|
-
}
|
|
16070
|
-
function resolveTreeConfig(partial) {
|
|
16071
|
-
return {
|
|
16072
|
-
parentKey: partial.parentKey ?? DEFAULT_TREE_CONFIG.parentKey,
|
|
16073
|
-
leftKey: partial.leftKey ?? DEFAULT_TREE_CONFIG.leftKey,
|
|
16074
|
-
rightKey: partial.rightKey ?? DEFAULT_TREE_CONFIG.rightKey,
|
|
16075
|
-
depthKey: partial.depthKey,
|
|
16076
|
-
scope: partial.scope,
|
|
16077
|
-
cascadeCallbacks: partial.cascadeCallbacks ?? DEFAULT_TREE_CONFIG.cascadeCallbacks,
|
|
16078
|
-
recoverOrder: partial.recoverOrder
|
|
16079
|
-
};
|
|
16080
|
-
}
|
|
16081
|
-
function validateTreeTable(table, config) {
|
|
16082
|
-
const missingColumns = [];
|
|
16083
|
-
const warnings = [];
|
|
16084
|
-
const requiredColumns = [config.parentKey, config.leftKey, config.rightKey];
|
|
16085
|
-
for (const col2 of requiredColumns) {
|
|
16086
|
-
if (!(col2 in table.columns)) {
|
|
16087
|
-
missingColumns.push(col2);
|
|
16088
|
-
}
|
|
16089
|
-
}
|
|
16090
|
-
if (config.depthKey && !(config.depthKey in table.columns)) {
|
|
16091
|
-
warnings.push(`Optional depth column '${config.depthKey}' not found in table '${table.name}'`);
|
|
16092
|
-
}
|
|
16093
|
-
if (config.scope) {
|
|
16094
|
-
for (const scopeCol of config.scope) {
|
|
16095
|
-
if (!(scopeCol in table.columns)) {
|
|
16096
|
-
missingColumns.push(scopeCol);
|
|
16097
|
-
}
|
|
16098
|
-
}
|
|
16099
|
-
}
|
|
16100
|
-
const leftCol = table.columns[config.leftKey];
|
|
16101
|
-
const rightCol = table.columns[config.rightKey];
|
|
16102
|
-
if (leftCol && leftCol.type !== "int" && leftCol.type !== "integer") {
|
|
16103
|
-
warnings.push(`Left column '${config.leftKey}' should be an integer type`);
|
|
16104
|
-
}
|
|
16105
|
-
if (rightCol && rightCol.type !== "int" && rightCol.type !== "integer") {
|
|
16106
|
-
warnings.push(`Right column '${config.rightKey}' should be an integer type`);
|
|
16107
|
-
}
|
|
16108
|
-
return {
|
|
16109
|
-
valid: missingColumns.length === 0,
|
|
16110
|
-
missingColumns,
|
|
16111
|
-
warnings
|
|
16112
|
-
};
|
|
16113
|
-
}
|
|
16114
|
-
function getTreeColumns(table, config) {
|
|
16115
|
-
const parentColumn = table.columns[config.parentKey];
|
|
16116
|
-
const leftColumn = table.columns[config.leftKey];
|
|
16117
|
-
const rightColumn = table.columns[config.rightKey];
|
|
16118
|
-
const depthColumn = config.depthKey ? table.columns[config.depthKey] : void 0;
|
|
16119
|
-
const scopeColumns = (config.scope ?? []).map((s) => table.columns[s]).filter(Boolean);
|
|
16120
|
-
if (!parentColumn || !leftColumn || !rightColumn) {
|
|
16121
|
-
throw new Error(
|
|
16122
|
-
`Table '${table.name}' is missing required tree columns. Required: ${config.parentKey}, ${config.leftKey}, ${config.rightKey}`
|
|
16123
|
-
);
|
|
16124
|
-
}
|
|
16125
|
-
return {
|
|
16126
|
-
parentColumn,
|
|
16127
|
-
leftColumn,
|
|
16128
|
-
rightColumn,
|
|
16129
|
-
depthColumn,
|
|
16130
|
-
scopeColumns
|
|
16131
|
-
};
|
|
16132
|
-
}
|
|
16133
|
-
|
|
16134
16474
|
// src/tree/nested-set-strategy.ts
|
|
16135
16475
|
var NestedSetStrategy = class {
|
|
16136
16476
|
/**
|
|
@@ -17196,132 +17536,6 @@ function queryResultsToRows(results) {
|
|
|
17196
17536
|
}
|
|
17197
17537
|
return rows;
|
|
17198
17538
|
}
|
|
17199
|
-
|
|
17200
|
-
// src/tree/tree-decorator.ts
|
|
17201
|
-
var TREE_METADATA_KEY = /* @__PURE__ */ Symbol("metal-orm:tree");
|
|
17202
|
-
function Tree(options = {}) {
|
|
17203
|
-
return function(target) {
|
|
17204
|
-
const config = resolveTreeConfig(options);
|
|
17205
|
-
const metadata = { config };
|
|
17206
|
-
setTreeMetadataOnClass(target, metadata);
|
|
17207
|
-
return target;
|
|
17208
|
-
};
|
|
17209
|
-
}
|
|
17210
|
-
function TreeParent() {
|
|
17211
|
-
return function(_value, context) {
|
|
17212
|
-
const propertyName = String(context.name);
|
|
17213
|
-
context.addInitializer(function() {
|
|
17214
|
-
const constructor = this.constructor;
|
|
17215
|
-
const metadata = getTreeMetadata(constructor);
|
|
17216
|
-
if (metadata) {
|
|
17217
|
-
metadata.parentProperty = propertyName;
|
|
17218
|
-
setTreeMetadata(constructor, metadata);
|
|
17219
|
-
}
|
|
17220
|
-
});
|
|
17221
|
-
};
|
|
17222
|
-
}
|
|
17223
|
-
function TreeChildren() {
|
|
17224
|
-
return function(_value, context) {
|
|
17225
|
-
const propertyName = String(context.name);
|
|
17226
|
-
context.addInitializer(function() {
|
|
17227
|
-
const constructor = this.constructor;
|
|
17228
|
-
const metadata = getTreeMetadata(constructor);
|
|
17229
|
-
if (metadata) {
|
|
17230
|
-
metadata.childrenProperty = propertyName;
|
|
17231
|
-
setTreeMetadata(constructor, metadata);
|
|
17232
|
-
}
|
|
17233
|
-
});
|
|
17234
|
-
};
|
|
17235
|
-
}
|
|
17236
|
-
function getTreeMetadata(target) {
|
|
17237
|
-
return target[TREE_METADATA_KEY];
|
|
17238
|
-
}
|
|
17239
|
-
function setTreeMetadata(target, metadata) {
|
|
17240
|
-
target[TREE_METADATA_KEY] = metadata;
|
|
17241
|
-
}
|
|
17242
|
-
function setTreeMetadataOnClass(target, metadata) {
|
|
17243
|
-
target[TREE_METADATA_KEY] = metadata;
|
|
17244
|
-
}
|
|
17245
|
-
function hasTreeBehavior(target) {
|
|
17246
|
-
return getTreeMetadata(target) !== void 0;
|
|
17247
|
-
}
|
|
17248
|
-
function getTreeConfig(target) {
|
|
17249
|
-
return getTreeMetadata(target)?.config;
|
|
17250
|
-
}
|
|
17251
|
-
var TreeEntityRegistry = class {
|
|
17252
|
-
entities = /* @__PURE__ */ new Map();
|
|
17253
|
-
tableNames = /* @__PURE__ */ new Map();
|
|
17254
|
-
/**
|
|
17255
|
-
* Registers an entity class with its table name.
|
|
17256
|
-
*/
|
|
17257
|
-
register(entityClass, tableName) {
|
|
17258
|
-
this.entities.set(tableName, entityClass);
|
|
17259
|
-
this.tableNames.set(entityClass, tableName);
|
|
17260
|
-
}
|
|
17261
|
-
/**
|
|
17262
|
-
* Gets the entity class for a table name.
|
|
17263
|
-
*/
|
|
17264
|
-
getByTableName(tableName) {
|
|
17265
|
-
return this.entities.get(tableName);
|
|
17266
|
-
}
|
|
17267
|
-
/**
|
|
17268
|
-
* Gets the table name for an entity class.
|
|
17269
|
-
*/
|
|
17270
|
-
getTableName(entityClass) {
|
|
17271
|
-
return this.tableNames.get(entityClass);
|
|
17272
|
-
}
|
|
17273
|
-
/**
|
|
17274
|
-
* Checks if a table has tree behavior.
|
|
17275
|
-
*/
|
|
17276
|
-
isTreeTable(tableName) {
|
|
17277
|
-
const entity = this.entities.get(tableName);
|
|
17278
|
-
return entity ? hasTreeBehavior(entity) : false;
|
|
17279
|
-
}
|
|
17280
|
-
/**
|
|
17281
|
-
* Gets all registered tree entities.
|
|
17282
|
-
*/
|
|
17283
|
-
getAll() {
|
|
17284
|
-
const result = [];
|
|
17285
|
-
for (const [tableName, entityClass] of this.entities) {
|
|
17286
|
-
const metadata = getTreeMetadata(entityClass);
|
|
17287
|
-
if (metadata) {
|
|
17288
|
-
result.push({ entityClass, tableName, metadata });
|
|
17289
|
-
}
|
|
17290
|
-
}
|
|
17291
|
-
return result;
|
|
17292
|
-
}
|
|
17293
|
-
/**
|
|
17294
|
-
* Clears the registry.
|
|
17295
|
-
*/
|
|
17296
|
-
clear() {
|
|
17297
|
-
this.entities.clear();
|
|
17298
|
-
this.tableNames.clear();
|
|
17299
|
-
}
|
|
17300
|
-
};
|
|
17301
|
-
var treeEntityRegistry = new TreeEntityRegistry();
|
|
17302
|
-
function getTreeBounds(entity, config) {
|
|
17303
|
-
const data = entity;
|
|
17304
|
-
const lft = data[config.leftKey];
|
|
17305
|
-
const rght = data[config.rightKey];
|
|
17306
|
-
if (typeof lft !== "number" || typeof rght !== "number") {
|
|
17307
|
-
return null;
|
|
17308
|
-
}
|
|
17309
|
-
return { lft, rght };
|
|
17310
|
-
}
|
|
17311
|
-
function getTreeParentId(entity, config) {
|
|
17312
|
-
return entity[config.parentKey];
|
|
17313
|
-
}
|
|
17314
|
-
function setTreeBounds(entity, config, lft, rght, depth) {
|
|
17315
|
-
const data = entity;
|
|
17316
|
-
data[config.leftKey] = lft;
|
|
17317
|
-
data[config.rightKey] = rght;
|
|
17318
|
-
if (config.depthKey && depth !== void 0) {
|
|
17319
|
-
data[config.depthKey] = depth;
|
|
17320
|
-
}
|
|
17321
|
-
}
|
|
17322
|
-
function setTreeParentId(entity, config, parentId) {
|
|
17323
|
-
entity[config.parentKey] = parentId;
|
|
17324
|
-
}
|
|
17325
17539
|
// Annotate the CommonJS export names for ESM import in node:
|
|
17326
17540
|
0 && (module.exports = {
|
|
17327
17541
|
Alphanumeric,
|
|
@@ -17329,6 +17543,7 @@ function setTreeParentId(entity, config, parentId) {
|
|
|
17329
17543
|
BelongsTo,
|
|
17330
17544
|
BelongsToMany,
|
|
17331
17545
|
BigIntTypeStrategy,
|
|
17546
|
+
BinaryTypeStrategy,
|
|
17332
17547
|
BooleanTypeStrategy,
|
|
17333
17548
|
CEP,
|
|
17334
17549
|
CNPJ,
|
|
@@ -17498,6 +17713,7 @@ function setTreeParentId(entity, config, parentId) {
|
|
|
17498
17713
|
generateRelationComponents,
|
|
17499
17714
|
generateSchemaSql,
|
|
17500
17715
|
generateSchemaSqlFor,
|
|
17716
|
+
generateTreeComponents,
|
|
17501
17717
|
getColumn,
|
|
17502
17718
|
getColumnMap,
|
|
17503
17719
|
getColumnType,
|
|
@@ -17661,6 +17877,7 @@ function setTreeParentId(entity, config, parentId) {
|
|
|
17661
17877
|
tableRef,
|
|
17662
17878
|
tan,
|
|
17663
17879
|
threadResults,
|
|
17880
|
+
threadedNodeToOpenApiSchema,
|
|
17664
17881
|
toColumnRef,
|
|
17665
17882
|
toPagedResponse,
|
|
17666
17883
|
toPagedResponseBuilder,
|
|
@@ -17669,6 +17886,9 @@ function setTreeParentId(entity, config, parentId) {
|
|
|
17669
17886
|
toResponseBuilder,
|
|
17670
17887
|
toTableRef,
|
|
17671
17888
|
treeEntityRegistry,
|
|
17889
|
+
treeListEntryToOpenApiSchema,
|
|
17890
|
+
treeNodeResultToOpenApiSchema,
|
|
17891
|
+
treeNodeToOpenApiSchema,
|
|
17672
17892
|
treeQuery,
|
|
17673
17893
|
trim,
|
|
17674
17894
|
trunc,
|