metal-orm 1.0.78 → 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 +466 -9
- 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 +460 -9
- 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/select-operations.ts +35 -37
- package/src/query-builder/select.ts +156 -142
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
|
|
@@ -6595,10 +6604,8 @@ async function executePagedQuery(builder, session, options, countCallback) {
|
|
|
6595
6604
|
throw new Error("executePaged: pageSize must be an integer >= 1");
|
|
6596
6605
|
}
|
|
6597
6606
|
const offset = (page - 1) * pageSize;
|
|
6598
|
-
const
|
|
6599
|
-
|
|
6600
|
-
countCallback(session)
|
|
6601
|
-
]);
|
|
6607
|
+
const totalItems = await countCallback(session);
|
|
6608
|
+
const items = await builder.limit(pageSize).offset(offset).execute(session);
|
|
6602
6609
|
return { items, totalItems, page, pageSize };
|
|
6603
6610
|
}
|
|
6604
6611
|
function buildWhereHasPredicate(env, context, relationFacet, createChildBuilder, relationName, callbackOrOptions, maybeOptions, negate = false) {
|
|
@@ -6942,6 +6949,438 @@ var SelectRelationFacet = class {
|
|
|
6942
6949
|
}
|
|
6943
6950
|
};
|
|
6944
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
|
+
|
|
6945
7384
|
// src/query-builder/select.ts
|
|
6946
7385
|
var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
6947
7386
|
env;
|
|
@@ -7486,7 +7925,7 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
7486
7925
|
*/
|
|
7487
7926
|
async executePaged(session, options) {
|
|
7488
7927
|
const builder = this.ensureDefaultSelection();
|
|
7489
|
-
return executePagedQuery(builder, session, options, (sess) =>
|
|
7928
|
+
return executePagedQuery(builder, session, options, (sess) => builder.count(sess));
|
|
7490
7929
|
}
|
|
7491
7930
|
/**
|
|
7492
7931
|
* Executes the query with provided execution and hydration contexts
|
|
@@ -7751,7 +8190,7 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
7751
8190
|
return this.compile(dialect).sql;
|
|
7752
8191
|
}
|
|
7753
8192
|
/**
|
|
7754
|
-
* Gets
|
|
8193
|
+
* Gets hydration plan for query
|
|
7755
8194
|
* @returns Hydration plan or undefined if none exists
|
|
7756
8195
|
* @example
|
|
7757
8196
|
* const plan = qb.include('posts').getHydrationPlan();
|
|
@@ -7760,6 +8199,18 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
|
|
|
7760
8199
|
getHydrationPlan() {
|
|
7761
8200
|
return this.context.hydration.getPlan();
|
|
7762
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
|
+
}
|
|
7763
8214
|
/**
|
|
7764
8215
|
* Gets the Abstract Syntax Tree (AST) representation of the query
|
|
7765
8216
|
* @returns Query AST with hydration applied
|
|
@@ -8789,14 +9240,14 @@ var buildAddColumnSql = (table, colName, dialect) => {
|
|
|
8789
9240
|
const rendered = renderColumnDefinition(table, column, dialect);
|
|
8790
9241
|
return `ALTER TABLE ${dialect.formatTableName(table)} ADD ${rendered.sql};`;
|
|
8791
9242
|
};
|
|
8792
|
-
var
|
|
9243
|
+
var normalizeType2 = (value) => (value || "").toLowerCase().replace(/\s+/g, " ").trim();
|
|
8793
9244
|
var normalizeDefault = (value) => {
|
|
8794
9245
|
if (value === void 0 || value === null) return void 0;
|
|
8795
9246
|
return String(value).trim();
|
|
8796
9247
|
};
|
|
8797
9248
|
var diffColumn = (expected, actual, dialect) => {
|
|
8798
|
-
const expectedType =
|
|
8799
|
-
const actualType =
|
|
9249
|
+
const expectedType = normalizeType2(dialect.renderColumnType(expected));
|
|
9250
|
+
const actualType = normalizeType2(actual.type);
|
|
8800
9251
|
const expectedDefault = expected.default !== void 0 ? normalizeDefault(dialect.renderDefault(expected.default, expected)) : void 0;
|
|
8801
9252
|
const actualDefault = normalizeDefault(actual.default);
|
|
8802
9253
|
return {
|
|
@@ -13278,6 +13729,7 @@ function createPooledExecutorFactory(opts) {
|
|
|
13278
13729
|
HasMany,
|
|
13279
13730
|
HasOne,
|
|
13280
13731
|
InsertQueryBuilder,
|
|
13732
|
+
InterceptorPipeline,
|
|
13281
13733
|
MySqlDialect,
|
|
13282
13734
|
Orm,
|
|
13283
13735
|
OrmSession,
|
|
@@ -13375,6 +13827,7 @@ function createPooledExecutorFactory(opts) {
|
|
|
13375
13827
|
exists,
|
|
13376
13828
|
exp,
|
|
13377
13829
|
extract,
|
|
13830
|
+
extractSchema,
|
|
13378
13831
|
firstValue,
|
|
13379
13832
|
floor,
|
|
13380
13833
|
fromUnixTime,
|
|
@@ -13385,6 +13838,7 @@ function createPooledExecutorFactory(opts) {
|
|
|
13385
13838
|
getDecoratorMetadata,
|
|
13386
13839
|
getSchemaIntrospector,
|
|
13387
13840
|
getTableDefFromEntity,
|
|
13841
|
+
getTemporalFormat,
|
|
13388
13842
|
greatest,
|
|
13389
13843
|
groupConcat,
|
|
13390
13844
|
gt,
|
|
@@ -13440,6 +13894,8 @@ function createPooledExecutorFactory(opts) {
|
|
|
13440
13894
|
lt,
|
|
13441
13895
|
lte,
|
|
13442
13896
|
ltrim,
|
|
13897
|
+
mapColumnType,
|
|
13898
|
+
mapRelationType,
|
|
13443
13899
|
materializeAs,
|
|
13444
13900
|
max,
|
|
13445
13901
|
md5,
|
|
@@ -13485,6 +13941,7 @@ function createPooledExecutorFactory(opts) {
|
|
|
13485
13941
|
rowsToQueryResult,
|
|
13486
13942
|
rpad,
|
|
13487
13943
|
rtrim,
|
|
13944
|
+
schemaToJson,
|
|
13488
13945
|
second,
|
|
13489
13946
|
sel,
|
|
13490
13947
|
selectFrom,
|