metal-orm 1.0.79 → 1.0.80
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/dist/index.cjs +463 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +118 -2
- package/dist/index.d.ts +118 -2
- package/dist/index.js +457 -4
- package/dist/index.js.map +1 -1
- package/package.json +8 -2
- package/src/core/dialect/postgres/index.ts +9 -5
- package/src/index.ts +6 -4
- package/src/openapi/index.ts +3 -0
- package/src/openapi/schema-extractor.ts +418 -0
- package/src/openapi/schema-types.ts +92 -0
- package/src/openapi/type-mappers.ts +207 -0
- package/src/query-builder/select.ts +25 -11
package/dist/index.cjs
CHANGED
|
@@ -59,6 +59,7 @@ __export(index_exports, {
|
|
|
59
59
|
HasMany: () => HasMany,
|
|
60
60
|
HasOne: () => HasOne,
|
|
61
61
|
InsertQueryBuilder: () => InsertQueryBuilder,
|
|
62
|
+
InterceptorPipeline: () => InterceptorPipeline,
|
|
62
63
|
MySqlDialect: () => MySqlDialect,
|
|
63
64
|
Orm: () => Orm,
|
|
64
65
|
OrmSession: () => OrmSession,
|
|
@@ -156,6 +157,7 @@ __export(index_exports, {
|
|
|
156
157
|
exists: () => exists,
|
|
157
158
|
exp: () => exp,
|
|
158
159
|
extract: () => extract,
|
|
160
|
+
extractSchema: () => extractSchema,
|
|
159
161
|
firstValue: () => firstValue,
|
|
160
162
|
floor: () => floor,
|
|
161
163
|
fromUnixTime: () => fromUnixTime,
|
|
@@ -166,6 +168,7 @@ __export(index_exports, {
|
|
|
166
168
|
getDecoratorMetadata: () => getDecoratorMetadata,
|
|
167
169
|
getSchemaIntrospector: () => getSchemaIntrospector,
|
|
168
170
|
getTableDefFromEntity: () => getTableDefFromEntity,
|
|
171
|
+
getTemporalFormat: () => getTemporalFormat,
|
|
169
172
|
greatest: () => greatest,
|
|
170
173
|
groupConcat: () => groupConcat,
|
|
171
174
|
gt: () => gt,
|
|
@@ -221,6 +224,8 @@ __export(index_exports, {
|
|
|
221
224
|
lt: () => lt,
|
|
222
225
|
lte: () => lte,
|
|
223
226
|
ltrim: () => ltrim,
|
|
227
|
+
mapColumnType: () => mapColumnType,
|
|
228
|
+
mapRelationType: () => mapRelationType,
|
|
224
229
|
materializeAs: () => materializeAs,
|
|
225
230
|
max: () => max,
|
|
226
231
|
md5: () => md5,
|
|
@@ -266,6 +271,7 @@ __export(index_exports, {
|
|
|
266
271
|
rowsToQueryResult: () => rowsToQueryResult,
|
|
267
272
|
rpad: () => rpad,
|
|
268
273
|
rtrim: () => rtrim,
|
|
274
|
+
schemaToJson: () => schemaToJson,
|
|
269
275
|
second: () => second,
|
|
270
276
|
sel: () => sel,
|
|
271
277
|
selectFrom: () => selectFrom,
|
|
@@ -2545,6 +2551,9 @@ var PostgresDialect = class extends SqlDialectBase {
|
|
|
2545
2551
|
quoteIdentifier(id) {
|
|
2546
2552
|
return `"${id}"`;
|
|
2547
2553
|
}
|
|
2554
|
+
formatPlaceholder(index) {
|
|
2555
|
+
return `$${index}`;
|
|
2556
|
+
}
|
|
2548
2557
|
/**
|
|
2549
2558
|
* Compiles JSON path expression using PostgreSQL syntax
|
|
2550
2559
|
* @param node - JSON path node
|
|
@@ -6940,6 +6949,438 @@ var SelectRelationFacet = class {
|
|
|
6940
6949
|
}
|
|
6941
6950
|
};
|
|
6942
6951
|
|
|
6952
|
+
// src/openapi/type-mappers.ts
|
|
6953
|
+
var mapColumnType = (column) => {
|
|
6954
|
+
const sqlType = normalizeType(column.type);
|
|
6955
|
+
const baseSchema = mapSqlTypeToBaseSchema(sqlType, column);
|
|
6956
|
+
const schema = {
|
|
6957
|
+
...baseSchema,
|
|
6958
|
+
description: column.comment,
|
|
6959
|
+
nullable: !column.notNull && !column.primary
|
|
6960
|
+
};
|
|
6961
|
+
if (column.args && sqlType === "varchar" || sqlType === "char") {
|
|
6962
|
+
schema.maxLength = column.args[0];
|
|
6963
|
+
}
|
|
6964
|
+
if (column.args && sqlType === "decimal" || sqlType === "float") {
|
|
6965
|
+
if (column.args.length >= 1) {
|
|
6966
|
+
schema.minimum = -(10 ** column.args[0]);
|
|
6967
|
+
}
|
|
6968
|
+
}
|
|
6969
|
+
if (sqlType === "enum" && column.args && column.args.length > 0) {
|
|
6970
|
+
schema.enum = column.args;
|
|
6971
|
+
}
|
|
6972
|
+
if (column.default !== void 0) {
|
|
6973
|
+
schema.default = column.default;
|
|
6974
|
+
}
|
|
6975
|
+
return schema;
|
|
6976
|
+
};
|
|
6977
|
+
var normalizeType = (type) => {
|
|
6978
|
+
return type.toLowerCase();
|
|
6979
|
+
};
|
|
6980
|
+
var mapSqlTypeToBaseSchema = (sqlType, column) => {
|
|
6981
|
+
const type = normalizeType(sqlType);
|
|
6982
|
+
const hasCustomTsType = column.tsType !== void 0;
|
|
6983
|
+
switch (type) {
|
|
6984
|
+
case "int":
|
|
6985
|
+
case "integer":
|
|
6986
|
+
case "bigint":
|
|
6987
|
+
return {
|
|
6988
|
+
type: hasCustomTsType ? inferTypeFromTsType(column.tsType) : "integer",
|
|
6989
|
+
format: type === "bigint" ? "int64" : "int32",
|
|
6990
|
+
minimum: column.autoIncrement ? 1 : void 0
|
|
6991
|
+
};
|
|
6992
|
+
case "decimal":
|
|
6993
|
+
case "float":
|
|
6994
|
+
case "double":
|
|
6995
|
+
return {
|
|
6996
|
+
type: hasCustomTsType ? inferTypeFromTsType(column.tsType) : "number"
|
|
6997
|
+
};
|
|
6998
|
+
case "varchar":
|
|
6999
|
+
return {
|
|
7000
|
+
type: "string",
|
|
7001
|
+
minLength: column.notNull ? 1 : void 0,
|
|
7002
|
+
maxLength: column.args?.[0]
|
|
7003
|
+
};
|
|
7004
|
+
case "text":
|
|
7005
|
+
return {
|
|
7006
|
+
type: "string",
|
|
7007
|
+
minLength: column.notNull ? 1 : void 0
|
|
7008
|
+
};
|
|
7009
|
+
case "char":
|
|
7010
|
+
return {
|
|
7011
|
+
type: "string",
|
|
7012
|
+
minLength: column.notNull ? column.args?.[0] || 1 : void 0,
|
|
7013
|
+
maxLength: column.args?.[0]
|
|
7014
|
+
};
|
|
7015
|
+
case "boolean":
|
|
7016
|
+
return {
|
|
7017
|
+
type: "boolean"
|
|
7018
|
+
};
|
|
7019
|
+
case "json":
|
|
7020
|
+
return {
|
|
7021
|
+
anyOf: [
|
|
7022
|
+
{ type: "object" },
|
|
7023
|
+
{ type: "array" }
|
|
7024
|
+
]
|
|
7025
|
+
};
|
|
7026
|
+
case "blob":
|
|
7027
|
+
case "binary":
|
|
7028
|
+
case "varbinary":
|
|
7029
|
+
return {
|
|
7030
|
+
type: "string",
|
|
7031
|
+
format: "base64"
|
|
7032
|
+
};
|
|
7033
|
+
case "date":
|
|
7034
|
+
return {
|
|
7035
|
+
type: "string",
|
|
7036
|
+
format: "date"
|
|
7037
|
+
};
|
|
7038
|
+
case "datetime":
|
|
7039
|
+
case "timestamp":
|
|
7040
|
+
return {
|
|
7041
|
+
type: "string",
|
|
7042
|
+
format: "date-time"
|
|
7043
|
+
};
|
|
7044
|
+
case "timestamptz":
|
|
7045
|
+
return {
|
|
7046
|
+
type: "string",
|
|
7047
|
+
format: "date-time"
|
|
7048
|
+
};
|
|
7049
|
+
case "uuid":
|
|
7050
|
+
return {
|
|
7051
|
+
type: "string",
|
|
7052
|
+
format: "uuid",
|
|
7053
|
+
pattern: "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
|
|
7054
|
+
};
|
|
7055
|
+
case "enum":
|
|
7056
|
+
return {
|
|
7057
|
+
type: "string",
|
|
7058
|
+
enum: column.args || []
|
|
7059
|
+
};
|
|
7060
|
+
default:
|
|
7061
|
+
if (column.dialectTypes?.postgres && column.dialectTypes.postgres === "bytea") {
|
|
7062
|
+
return {
|
|
7063
|
+
type: "string",
|
|
7064
|
+
format: "base64"
|
|
7065
|
+
};
|
|
7066
|
+
}
|
|
7067
|
+
return {
|
|
7068
|
+
type: "string"
|
|
7069
|
+
};
|
|
7070
|
+
}
|
|
7071
|
+
};
|
|
7072
|
+
var inferTypeFromTsType = (tsType) => {
|
|
7073
|
+
if (typeof tsType === "string") {
|
|
7074
|
+
if (tsType === "number") return "number";
|
|
7075
|
+
if (tsType === "string") return "string";
|
|
7076
|
+
if (tsType === "boolean") return "boolean";
|
|
7077
|
+
}
|
|
7078
|
+
if (typeof tsType === "function") {
|
|
7079
|
+
const typeStr = tsType.name?.toLowerCase();
|
|
7080
|
+
if (typeStr === "number") return "number";
|
|
7081
|
+
if (typeStr === "string") return "string";
|
|
7082
|
+
if (typeStr === "boolean") return "boolean";
|
|
7083
|
+
if (typeStr === "array") return "array";
|
|
7084
|
+
if (typeStr === "object") return "object";
|
|
7085
|
+
}
|
|
7086
|
+
return "string";
|
|
7087
|
+
};
|
|
7088
|
+
var mapRelationType = (relationType) => {
|
|
7089
|
+
switch (relationType) {
|
|
7090
|
+
case "HAS_MANY":
|
|
7091
|
+
case "BELONGS_TO_MANY":
|
|
7092
|
+
return { type: "array", isNullable: false };
|
|
7093
|
+
case "HAS_ONE":
|
|
7094
|
+
case "BELONGS_TO":
|
|
7095
|
+
return { type: "object", isNullable: true };
|
|
7096
|
+
default:
|
|
7097
|
+
return { type: "object", isNullable: true };
|
|
7098
|
+
}
|
|
7099
|
+
};
|
|
7100
|
+
var getTemporalFormat = (sqlType) => {
|
|
7101
|
+
const type = normalizeType(sqlType);
|
|
7102
|
+
switch (type) {
|
|
7103
|
+
case "date":
|
|
7104
|
+
return "date";
|
|
7105
|
+
case "datetime":
|
|
7106
|
+
case "timestamp":
|
|
7107
|
+
case "timestamptz":
|
|
7108
|
+
return "date-time";
|
|
7109
|
+
default:
|
|
7110
|
+
return void 0;
|
|
7111
|
+
}
|
|
7112
|
+
};
|
|
7113
|
+
|
|
7114
|
+
// src/openapi/schema-extractor.ts
|
|
7115
|
+
var extractSchema = (table, plan, projectionNodes, options = {}) => {
|
|
7116
|
+
const mode = options.mode ?? "full";
|
|
7117
|
+
const context = {
|
|
7118
|
+
visitedTables: /* @__PURE__ */ new Set(),
|
|
7119
|
+
schemaCache: /* @__PURE__ */ new Map(),
|
|
7120
|
+
depth: 0,
|
|
7121
|
+
maxDepth: options.maxDepth ?? 5
|
|
7122
|
+
};
|
|
7123
|
+
const hasComputedFields = projectionNodes && projectionNodes.some(
|
|
7124
|
+
(node) => node.type !== "Column"
|
|
7125
|
+
);
|
|
7126
|
+
if (hasComputedFields) {
|
|
7127
|
+
return extractFromProjectionNodes(table, projectionNodes, context, options);
|
|
7128
|
+
}
|
|
7129
|
+
if (mode === "selected" && plan) {
|
|
7130
|
+
return extractSelectedSchema(table, plan, context, options);
|
|
7131
|
+
}
|
|
7132
|
+
return extractFullTableSchema(table, context, options);
|
|
7133
|
+
};
|
|
7134
|
+
var extractFromProjectionNodes = (table, projectionNodes, context, options) => {
|
|
7135
|
+
const properties = {};
|
|
7136
|
+
const required = [];
|
|
7137
|
+
for (const node of projectionNodes) {
|
|
7138
|
+
if (!node || typeof node !== "object") continue;
|
|
7139
|
+
const projection = node;
|
|
7140
|
+
const propertyName = projection.alias ?? "";
|
|
7141
|
+
if (!propertyName) continue;
|
|
7142
|
+
if (projection.type === "Column") {
|
|
7143
|
+
const columnNode4 = node;
|
|
7144
|
+
const column = table.columns[columnNode4.name];
|
|
7145
|
+
if (!column) continue;
|
|
7146
|
+
const property = mapColumnType(column);
|
|
7147
|
+
if (!property.description && options.includeDescriptions && column.comment) {
|
|
7148
|
+
property.description = column.comment;
|
|
7149
|
+
}
|
|
7150
|
+
properties[propertyName] = property;
|
|
7151
|
+
if (column.notNull || column.primary) {
|
|
7152
|
+
required.push(propertyName);
|
|
7153
|
+
}
|
|
7154
|
+
} else if (projection.type === "Function" || projection.type === "WindowFunction") {
|
|
7155
|
+
const fnNode = node;
|
|
7156
|
+
const functionName = fnNode.fn?.toUpperCase() ?? fnNode.name?.toUpperCase() ?? "";
|
|
7157
|
+
const propertySchema = projection.type === "Function" ? mapFunctionNodeToSchema(functionName) : mapWindowFunctionToSchema(functionName);
|
|
7158
|
+
properties[propertyName] = propertySchema;
|
|
7159
|
+
const isCountFunction = functionName === "COUNT";
|
|
7160
|
+
const isWindowRankFunction = functionName === "ROW_NUMBER" || functionName === "RANK";
|
|
7161
|
+
if (isCountFunction || isWindowRankFunction) {
|
|
7162
|
+
required.push(propertyName);
|
|
7163
|
+
}
|
|
7164
|
+
} else if (projection.type === "CaseExpression") {
|
|
7165
|
+
const propertySchema = {
|
|
7166
|
+
type: "string",
|
|
7167
|
+
description: "Computed CASE expression",
|
|
7168
|
+
nullable: true
|
|
7169
|
+
};
|
|
7170
|
+
properties[propertyName] = propertySchema;
|
|
7171
|
+
} else if (projection.type === "ScalarSubquery") {
|
|
7172
|
+
const propertySchema = {
|
|
7173
|
+
type: "object",
|
|
7174
|
+
description: "Subquery result",
|
|
7175
|
+
nullable: true
|
|
7176
|
+
};
|
|
7177
|
+
properties[propertyName] = propertySchema;
|
|
7178
|
+
} else if (projection.type === "CastExpression") {
|
|
7179
|
+
const propertySchema = {
|
|
7180
|
+
type: "string",
|
|
7181
|
+
description: "CAST expression result",
|
|
7182
|
+
nullable: true
|
|
7183
|
+
};
|
|
7184
|
+
properties[propertyName] = propertySchema;
|
|
7185
|
+
}
|
|
7186
|
+
}
|
|
7187
|
+
return {
|
|
7188
|
+
type: "object",
|
|
7189
|
+
properties,
|
|
7190
|
+
required
|
|
7191
|
+
};
|
|
7192
|
+
};
|
|
7193
|
+
var mapFunctionNodeToSchema = (functionName) => {
|
|
7194
|
+
const upperName = functionName.toUpperCase();
|
|
7195
|
+
switch (upperName) {
|
|
7196
|
+
case "COUNT":
|
|
7197
|
+
case "SUM":
|
|
7198
|
+
case "AVG":
|
|
7199
|
+
case "MIN":
|
|
7200
|
+
case "MAX":
|
|
7201
|
+
return {
|
|
7202
|
+
type: "number",
|
|
7203
|
+
description: `${upperName} aggregate function result`,
|
|
7204
|
+
nullable: false
|
|
7205
|
+
};
|
|
7206
|
+
case "GROUP_CONCAT":
|
|
7207
|
+
case "STRING_AGG":
|
|
7208
|
+
case "ARRAY_AGG":
|
|
7209
|
+
return {
|
|
7210
|
+
type: "string",
|
|
7211
|
+
description: `${upperName} aggregate function result`,
|
|
7212
|
+
nullable: true
|
|
7213
|
+
};
|
|
7214
|
+
case "JSON_ARRAYAGG":
|
|
7215
|
+
case "JSON_OBJECTAGG":
|
|
7216
|
+
return {
|
|
7217
|
+
type: "object",
|
|
7218
|
+
description: `${upperName} aggregate function result`,
|
|
7219
|
+
nullable: true
|
|
7220
|
+
};
|
|
7221
|
+
default:
|
|
7222
|
+
return {
|
|
7223
|
+
type: "string",
|
|
7224
|
+
description: `Unknown function: ${functionName}`,
|
|
7225
|
+
nullable: true
|
|
7226
|
+
};
|
|
7227
|
+
}
|
|
7228
|
+
};
|
|
7229
|
+
var mapWindowFunctionToSchema = (functionName) => {
|
|
7230
|
+
const upperName = functionName.toUpperCase();
|
|
7231
|
+
switch (upperName) {
|
|
7232
|
+
case "ROW_NUMBER":
|
|
7233
|
+
case "RANK":
|
|
7234
|
+
case "DENSE_RANK":
|
|
7235
|
+
case "NTILE":
|
|
7236
|
+
return {
|
|
7237
|
+
type: "integer",
|
|
7238
|
+
description: `${upperName} window function result`,
|
|
7239
|
+
nullable: false
|
|
7240
|
+
};
|
|
7241
|
+
case "LAG":
|
|
7242
|
+
case "LEAD":
|
|
7243
|
+
case "FIRST_VALUE":
|
|
7244
|
+
case "LAST_VALUE":
|
|
7245
|
+
return {
|
|
7246
|
+
type: "string",
|
|
7247
|
+
description: `${upperName} window function result`,
|
|
7248
|
+
nullable: true
|
|
7249
|
+
};
|
|
7250
|
+
default:
|
|
7251
|
+
return {
|
|
7252
|
+
type: "string",
|
|
7253
|
+
description: `Unknown window function: ${functionName}`,
|
|
7254
|
+
nullable: true
|
|
7255
|
+
};
|
|
7256
|
+
}
|
|
7257
|
+
};
|
|
7258
|
+
var extractSelectedSchema = (table, plan, context, options) => {
|
|
7259
|
+
const properties = {};
|
|
7260
|
+
const required = [];
|
|
7261
|
+
plan.rootColumns.forEach((columnName) => {
|
|
7262
|
+
const column = table.columns[columnName];
|
|
7263
|
+
if (!column) return;
|
|
7264
|
+
const property = mapColumnType(column);
|
|
7265
|
+
if (!property.description && options.includeDescriptions && column.comment) {
|
|
7266
|
+
property.description = column.comment;
|
|
7267
|
+
}
|
|
7268
|
+
properties[columnName] = property;
|
|
7269
|
+
if (column.notNull || column.primary) {
|
|
7270
|
+
required.push(columnName);
|
|
7271
|
+
}
|
|
7272
|
+
});
|
|
7273
|
+
plan.relations.forEach((relationPlan) => {
|
|
7274
|
+
const relation = table.relations[relationPlan.name];
|
|
7275
|
+
if (!relation) return;
|
|
7276
|
+
const relationSchema = extractRelationSchema(
|
|
7277
|
+
relation,
|
|
7278
|
+
relationPlan,
|
|
7279
|
+
relationPlan.columns,
|
|
7280
|
+
context,
|
|
7281
|
+
options
|
|
7282
|
+
);
|
|
7283
|
+
properties[relationPlan.name] = relationSchema;
|
|
7284
|
+
const { isNullable } = mapRelationType(relation.type);
|
|
7285
|
+
if (!isNullable && relationPlan.name) {
|
|
7286
|
+
required.push(relationPlan.name);
|
|
7287
|
+
}
|
|
7288
|
+
});
|
|
7289
|
+
return {
|
|
7290
|
+
type: "object",
|
|
7291
|
+
properties,
|
|
7292
|
+
required
|
|
7293
|
+
};
|
|
7294
|
+
};
|
|
7295
|
+
var extractFullTableSchema = (table, context, options) => {
|
|
7296
|
+
const cacheKey = table.name;
|
|
7297
|
+
if (context.schemaCache.has(cacheKey)) {
|
|
7298
|
+
return context.schemaCache.get(cacheKey);
|
|
7299
|
+
}
|
|
7300
|
+
if (context.visitedTables.has(cacheKey) && context.depth > 0) {
|
|
7301
|
+
return {
|
|
7302
|
+
type: "object",
|
|
7303
|
+
properties: {
|
|
7304
|
+
_ref: {
|
|
7305
|
+
type: "string",
|
|
7306
|
+
description: `Circular reference to ${table.name}`
|
|
7307
|
+
}
|
|
7308
|
+
},
|
|
7309
|
+
required: []
|
|
7310
|
+
};
|
|
7311
|
+
}
|
|
7312
|
+
context.visitedTables.add(cacheKey);
|
|
7313
|
+
const properties = {};
|
|
7314
|
+
const required = [];
|
|
7315
|
+
Object.entries(table.columns).forEach(([columnName, column]) => {
|
|
7316
|
+
const property = mapColumnType(column);
|
|
7317
|
+
if (!property.description && options.includeDescriptions && column.comment) {
|
|
7318
|
+
property.description = column.comment;
|
|
7319
|
+
}
|
|
7320
|
+
properties[columnName] = property;
|
|
7321
|
+
if (column.notNull || column.primary) {
|
|
7322
|
+
required.push(columnName);
|
|
7323
|
+
}
|
|
7324
|
+
});
|
|
7325
|
+
Object.entries(table.relations).forEach(([relationName, relation]) => {
|
|
7326
|
+
if (context.depth >= context.maxDepth) {
|
|
7327
|
+
return;
|
|
7328
|
+
}
|
|
7329
|
+
const relationSchema = extractRelationSchema(
|
|
7330
|
+
relation,
|
|
7331
|
+
void 0,
|
|
7332
|
+
[],
|
|
7333
|
+
{ ...context, depth: context.depth + 1 },
|
|
7334
|
+
options
|
|
7335
|
+
);
|
|
7336
|
+
properties[relationName] = relationSchema;
|
|
7337
|
+
const { isNullable } = mapRelationType(relation.type);
|
|
7338
|
+
if (!isNullable) {
|
|
7339
|
+
required.push(relationName);
|
|
7340
|
+
}
|
|
7341
|
+
});
|
|
7342
|
+
const schema = {
|
|
7343
|
+
type: "object",
|
|
7344
|
+
properties,
|
|
7345
|
+
required
|
|
7346
|
+
};
|
|
7347
|
+
context.schemaCache.set(cacheKey, schema);
|
|
7348
|
+
return schema;
|
|
7349
|
+
};
|
|
7350
|
+
var extractRelationSchema = (relation, relationPlan, selectedColumns, context, options) => {
|
|
7351
|
+
const targetTable = relation.target;
|
|
7352
|
+
const { type: relationType, isNullable } = mapRelationType(relation.type);
|
|
7353
|
+
let targetSchema;
|
|
7354
|
+
if (relationPlan && selectedColumns.length > 0) {
|
|
7355
|
+
const plan = {
|
|
7356
|
+
rootTable: targetTable.name,
|
|
7357
|
+
rootPrimaryKey: relationPlan.targetPrimaryKey,
|
|
7358
|
+
rootColumns: selectedColumns,
|
|
7359
|
+
relations: []
|
|
7360
|
+
};
|
|
7361
|
+
targetSchema = extractSelectedSchema(targetTable, plan, context, options);
|
|
7362
|
+
} else {
|
|
7363
|
+
targetSchema = extractFullTableSchema(targetTable, context, options);
|
|
7364
|
+
}
|
|
7365
|
+
if (relationType === "array") {
|
|
7366
|
+
return {
|
|
7367
|
+
type: "array",
|
|
7368
|
+
items: targetSchema,
|
|
7369
|
+
nullable: isNullable
|
|
7370
|
+
};
|
|
7371
|
+
}
|
|
7372
|
+
return {
|
|
7373
|
+
type: "object",
|
|
7374
|
+
properties: targetSchema.properties,
|
|
7375
|
+
required: targetSchema.required,
|
|
7376
|
+
nullable: isNullable,
|
|
7377
|
+
description: targetSchema.description
|
|
7378
|
+
};
|
|
7379
|
+
};
|
|
7380
|
+
var schemaToJson = (schema, pretty = false) => {
|
|
7381
|
+
return JSON.stringify(schema, null, pretty ? 2 : 0);
|
|
7382
|
+
};
|
|
7383
|
+
|
|
6943
7384
|
// src/query-builder/select.ts
|
|
6944
7385
|
var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
6945
7386
|
env;
|
|
@@ -7749,7 +8190,7 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
7749
8190
|
return this.compile(dialect).sql;
|
|
7750
8191
|
}
|
|
7751
8192
|
/**
|
|
7752
|
-
* Gets
|
|
8193
|
+
* Gets hydration plan for query
|
|
7753
8194
|
* @returns Hydration plan or undefined if none exists
|
|
7754
8195
|
* @example
|
|
7755
8196
|
* const plan = qb.include('posts').getHydrationPlan();
|
|
@@ -7758,6 +8199,18 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
7758
8199
|
getHydrationPlan() {
|
|
7759
8200
|
return this.context.hydration.getPlan();
|
|
7760
8201
|
}
|
|
8202
|
+
/**
|
|
8203
|
+
* Gets OpenAPI 3.1 JSON Schema for query result
|
|
8204
|
+
* @param options - Schema generation options
|
|
8205
|
+
* @returns OpenAPI 3.1 JSON Schema for query result
|
|
8206
|
+
* @example
|
|
8207
|
+
* const schema = qb.select('id', 'title', 'author').getSchema();
|
|
8208
|
+
* console.log(JSON.stringify(schema, null, 2));
|
|
8209
|
+
*/
|
|
8210
|
+
getSchema(options) {
|
|
8211
|
+
const plan = this.context.hydration.getPlan();
|
|
8212
|
+
return extractSchema(this.env.table, plan, this.context.state.ast.columns, options);
|
|
8213
|
+
}
|
|
7761
8214
|
/**
|
|
7762
8215
|
* Gets the Abstract Syntax Tree (AST) representation of the query
|
|
7763
8216
|
* @returns Query AST with hydration applied
|
|
@@ -8787,14 +9240,14 @@ var buildAddColumnSql = (table, colName, dialect) => {
|
|
|
8787
9240
|
const rendered = renderColumnDefinition(table, column, dialect);
|
|
8788
9241
|
return `ALTER TABLE ${dialect.formatTableName(table)} ADD ${rendered.sql};`;
|
|
8789
9242
|
};
|
|
8790
|
-
var
|
|
9243
|
+
var normalizeType2 = (value) => (value || "").toLowerCase().replace(/\s+/g, " ").trim();
|
|
8791
9244
|
var normalizeDefault = (value) => {
|
|
8792
9245
|
if (value === void 0 || value === null) return void 0;
|
|
8793
9246
|
return String(value).trim();
|
|
8794
9247
|
};
|
|
8795
9248
|
var diffColumn = (expected, actual, dialect) => {
|
|
8796
|
-
const expectedType =
|
|
8797
|
-
const actualType =
|
|
9249
|
+
const expectedType = normalizeType2(dialect.renderColumnType(expected));
|
|
9250
|
+
const actualType = normalizeType2(actual.type);
|
|
8798
9251
|
const expectedDefault = expected.default !== void 0 ? normalizeDefault(dialect.renderDefault(expected.default, expected)) : void 0;
|
|
8799
9252
|
const actualDefault = normalizeDefault(actual.default);
|
|
8800
9253
|
return {
|
|
@@ -13276,6 +13729,7 @@ function createPooledExecutorFactory(opts) {
|
|
|
13276
13729
|
HasMany,
|
|
13277
13730
|
HasOne,
|
|
13278
13731
|
InsertQueryBuilder,
|
|
13732
|
+
InterceptorPipeline,
|
|
13279
13733
|
MySqlDialect,
|
|
13280
13734
|
Orm,
|
|
13281
13735
|
OrmSession,
|
|
@@ -13373,6 +13827,7 @@ function createPooledExecutorFactory(opts) {
|
|
|
13373
13827
|
exists,
|
|
13374
13828
|
exp,
|
|
13375
13829
|
extract,
|
|
13830
|
+
extractSchema,
|
|
13376
13831
|
firstValue,
|
|
13377
13832
|
floor,
|
|
13378
13833
|
fromUnixTime,
|
|
@@ -13383,6 +13838,7 @@ function createPooledExecutorFactory(opts) {
|
|
|
13383
13838
|
getDecoratorMetadata,
|
|
13384
13839
|
getSchemaIntrospector,
|
|
13385
13840
|
getTableDefFromEntity,
|
|
13841
|
+
getTemporalFormat,
|
|
13386
13842
|
greatest,
|
|
13387
13843
|
groupConcat,
|
|
13388
13844
|
gt,
|
|
@@ -13438,6 +13894,8 @@ function createPooledExecutorFactory(opts) {
|
|
|
13438
13894
|
lt,
|
|
13439
13895
|
lte,
|
|
13440
13896
|
ltrim,
|
|
13897
|
+
mapColumnType,
|
|
13898
|
+
mapRelationType,
|
|
13441
13899
|
materializeAs,
|
|
13442
13900
|
max,
|
|
13443
13901
|
md5,
|
|
@@ -13483,6 +13941,7 @@ function createPooledExecutorFactory(opts) {
|
|
|
13483
13941
|
rowsToQueryResult,
|
|
13484
13942
|
rpad,
|
|
13485
13943
|
rtrim,
|
|
13944
|
+
schemaToJson,
|
|
13486
13945
|
second,
|
|
13487
13946
|
sel,
|
|
13488
13947
|
selectFrom,
|