metal-orm 1.0.86 → 1.0.88

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.js CHANGED
@@ -6160,9 +6160,9 @@ var flattenResults = (results) => {
6160
6160
  }
6161
6161
  return rows;
6162
6162
  };
6163
- var executeWithContexts = async (execCtx, entityCtx, qb, options) => {
6163
+ var executeWithContexts = async (execCtx, entityCtx, qb) => {
6164
6164
  const ast = qb.getAST();
6165
- const compiled = options?.allowParamOperands ? execCtx.dialect.compileSelectWithOptions(ast, { allowParams: true }) : execCtx.dialect.compileSelect(ast);
6165
+ const compiled = execCtx.dialect.compileSelect(ast);
6166
6166
  const executed = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
6167
6167
  const rows = flattenResults(executed);
6168
6168
  const lazyRelations = qb.getLazyRelations();
@@ -6180,9 +6180,9 @@ var executeWithContexts = async (execCtx, entityCtx, qb, options) => {
6180
6180
  await preloadRelationIncludes(entities, includeTree);
6181
6181
  return entities;
6182
6182
  };
6183
- var executePlainWithContexts = async (execCtx, qb, options) => {
6183
+ var executePlainWithContexts = async (execCtx, qb) => {
6184
6184
  const ast = qb.getAST();
6185
- const compiled = options?.allowParamOperands ? execCtx.dialect.compileSelectWithOptions(ast, { allowParams: true }) : execCtx.dialect.compileSelect(ast);
6185
+ const compiled = execCtx.dialect.compileSelect(ast);
6186
6186
  const executed = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
6187
6187
  const rows = flattenResults(executed);
6188
6188
  if (ast.setOps && ast.setOps.length > 0) {
@@ -6190,21 +6190,21 @@ var executePlainWithContexts = async (execCtx, qb, options) => {
6190
6190
  }
6191
6191
  return hydrateRows(rows, qb.getHydrationPlan());
6192
6192
  };
6193
- async function executeHydrated(session, qb, options) {
6194
- return executeWithContexts(session.getExecutionContext(), session, qb, options);
6193
+ async function executeHydrated(session, qb) {
6194
+ return executeWithContexts(session.getExecutionContext(), session, qb);
6195
6195
  }
6196
- async function executeHydratedPlain(session, qb, options) {
6197
- return executePlainWithContexts(session.getExecutionContext(), qb, options);
6196
+ async function executeHydratedPlain(session, qb) {
6197
+ return executePlainWithContexts(session.getExecutionContext(), qb);
6198
6198
  }
6199
- async function executeHydratedWithContexts(execCtx, hydCtx, qb, options) {
6199
+ async function executeHydratedWithContexts(execCtx, hydCtx, qb) {
6200
6200
  const entityCtx = hydCtx.entityContext;
6201
6201
  if (!entityCtx) {
6202
6202
  throw new Error("Hydration context is missing an EntityContext");
6203
6203
  }
6204
- return executeWithContexts(execCtx, entityCtx, qb, options);
6204
+ return executeWithContexts(execCtx, entityCtx, qb);
6205
6205
  }
6206
- async function executeHydratedPlainWithContexts(execCtx, qb, options) {
6207
- return executePlainWithContexts(execCtx, qb, options);
6206
+ async function executeHydratedPlainWithContexts(execCtx, qb) {
6207
+ return executePlainWithContexts(execCtx, qb);
6208
6208
  }
6209
6209
  var loadLazyRelationsForTable = async (ctx, table, lazyRelations, lazyRelationOptions) => {
6210
6210
  if (!lazyRelations.length) return;
@@ -6405,7 +6405,7 @@ function applyOrderBy(context, predicateFacet, term, directionOrOptions) {
6405
6405
  const dir = options.direction ?? ORDER_DIRECTIONS.ASC;
6406
6406
  return predicateFacet.orderBy(context, term, dir, options.nulls, options.collation);
6407
6407
  }
6408
- async function executeCount(context, env, session, options) {
6408
+ async function executeCount(context, env, session) {
6409
6409
  const unpagedAst = {
6410
6410
  ...context.state.ast,
6411
6411
  orderBy: void 0,
@@ -6425,7 +6425,7 @@ async function executeCount(context, env, session, options) {
6425
6425
  joins: []
6426
6426
  };
6427
6427
  const execCtx = session.getExecutionContext();
6428
- const compiled = options?.allowParamOperands ? execCtx.dialect.compileSelectWithOptions(countQuery, { allowParams: true }) : execCtx.dialect.compileSelect(countQuery);
6428
+ const compiled = execCtx.dialect.compileSelect(countQuery);
6429
6429
  const results = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
6430
6430
  const value = results[0]?.values?.[0]?.[0];
6431
6431
  if (typeof value === "number") return value;
@@ -6433,7 +6433,7 @@ async function executeCount(context, env, session, options) {
6433
6433
  if (typeof value === "string") return Number(value);
6434
6434
  return value === null || value === void 0 ? 0 : Number(value);
6435
6435
  }
6436
- async function executePagedQuery(builder, session, options, countCallback, paramOptions) {
6436
+ async function executePagedQuery(builder, session, options, countCallback) {
6437
6437
  const { page, pageSize } = options;
6438
6438
  if (!Number.isInteger(page) || page < 1) {
6439
6439
  throw new Error("executePaged: page must be an integer >= 1");
@@ -6443,7 +6443,7 @@ async function executePagedQuery(builder, session, options, countCallback, param
6443
6443
  }
6444
6444
  const offset = (page - 1) * pageSize;
6445
6445
  const totalItems = await countCallback(session);
6446
- const items = await builder.limit(pageSize).offset(offset).execute(session, paramOptions);
6446
+ const items = await builder.limit(pageSize).offset(offset).execute(session);
6447
6447
  return { items, totalItems, page, pageSize };
6448
6448
  }
6449
6449
  function buildWhereHasPredicate(env, context, relationFacet, createChildBuilder, relationName, callbackOrOptions, maybeOptions, negate = false) {
@@ -6963,47 +6963,52 @@ var getTemporalFormat = (sqlType) => {
6963
6963
  }
6964
6964
  };
6965
6965
 
6966
- // src/openapi/schema-extractor.ts
6967
- var DEFAULT_MAX_DEPTH = 5;
6968
- var extractSchema = (table, plan, projectionNodes, options = {}) => {
6969
- const outputOptions = resolveOutputOptions(options);
6970
- const outputContext = createContext(outputOptions.maxDepth ?? DEFAULT_MAX_DEPTH);
6971
- const output = extractOutputSchema(table, plan, projectionNodes, outputContext, outputOptions);
6972
- const inputOptions = resolveInputOptions(options);
6973
- if (!inputOptions) {
6974
- return { output };
6966
+ // src/openapi/schema-extractor-utils.ts
6967
+ var hasComputedProjection = (projectionNodes) => Boolean(projectionNodes && projectionNodes.some((node) => node.type !== "Column"));
6968
+ var shouldUseSelectedSchema = (options, plan, projectionNodes) => {
6969
+ if (!plan || options.mode !== "selected") return false;
6970
+ if (hasComputedProjection(projectionNodes)) return false;
6971
+ if (options.refMode === "components" && options.selectedRefMode !== "components") return false;
6972
+ return true;
6973
+ };
6974
+ var resolveComponentName = (table, options) => options.componentName ? options.componentName(table) : table.name;
6975
+ var normalizeColumns = (columns) => Array.from(new Set(columns)).sort((a, b) => a.localeCompare(b));
6976
+ var buildSelectionSignature = (plan) => {
6977
+ const relations = plan.relations.map((relation) => ({
6978
+ name: relation.name,
6979
+ columns: normalizeColumns(relation.columns)
6980
+ })).sort((a, b) => a.name.localeCompare(b.name));
6981
+ return JSON.stringify({
6982
+ root: normalizeColumns(plan.rootColumns),
6983
+ relations
6984
+ });
6985
+ };
6986
+ var hashString = (value) => {
6987
+ let hash = 2166136261;
6988
+ for (let i = 0; i < value.length; i += 1) {
6989
+ hash ^= value.charCodeAt(i);
6990
+ hash = hash * 16777619 >>> 0;
6975
6991
  }
6976
- const inputContext = createContext(inputOptions.maxDepth ?? DEFAULT_MAX_DEPTH);
6977
- const input = extractInputSchema(table, inputContext, inputOptions);
6978
- return { output, input };
6992
+ return hash.toString(16).padStart(8, "0");
6979
6993
  };
6980
- var resolveOutputOptions = (options) => ({
6981
- mode: options.mode ?? "full",
6982
- includeDescriptions: options.includeDescriptions,
6983
- includeEnums: options.includeEnums,
6984
- includeExamples: options.includeExamples,
6985
- includeDefaults: options.includeDefaults,
6986
- includeNullable: options.includeNullable,
6987
- maxDepth: options.maxDepth ?? DEFAULT_MAX_DEPTH
6988
- });
6989
- var resolveInputOptions = (options) => {
6990
- if (options.input === false) return void 0;
6991
- const input = options.input ?? {};
6992
- const mode = input.mode ?? "create";
6993
- return {
6994
- mode,
6995
- includeRelations: input.includeRelations ?? true,
6996
- relationMode: input.relationMode ?? "mixed",
6997
- includeDescriptions: input.includeDescriptions ?? options.includeDescriptions,
6998
- includeEnums: input.includeEnums ?? options.includeEnums,
6999
- includeExamples: input.includeExamples ?? options.includeExamples,
7000
- includeDefaults: input.includeDefaults ?? options.includeDefaults,
7001
- includeNullable: input.includeNullable ?? options.includeNullable,
7002
- maxDepth: input.maxDepth ?? options.maxDepth ?? DEFAULT_MAX_DEPTH,
7003
- omitReadOnly: input.omitReadOnly ?? true,
7004
- excludePrimaryKey: input.excludePrimaryKey ?? false,
7005
- requirePrimaryKey: input.requirePrimaryKey ?? mode === "update"
7006
- };
6994
+ var resolveSelectedComponentName = (table, plan, options) => {
6995
+ const base = resolveComponentName(table, options);
6996
+ const signature = buildSelectionSignature(plan);
6997
+ return `${base}__sel_${hashString(signature)}`;
6998
+ };
6999
+ var ensureComponentRef = (table, componentName, context, schemaFactory) => {
7000
+ if (context.components && !context.components.schemas[componentName]) {
7001
+ if (!context.visitedTables.has(table.name)) {
7002
+ context.components.schemas[componentName] = schemaFactory();
7003
+ }
7004
+ }
7005
+ return { $ref: `#/components/schemas/${componentName}` };
7006
+ };
7007
+ var registerComponentSchema = (name, schema, context) => {
7008
+ if (!context.components) return;
7009
+ if (!context.components.schemas[name]) {
7010
+ context.components.schemas[name] = schema;
7011
+ }
7007
7012
  };
7008
7013
  var createContext = (maxDepth) => ({
7009
7014
  visitedTables: /* @__PURE__ */ new Set(),
@@ -7011,19 +7016,18 @@ var createContext = (maxDepth) => ({
7011
7016
  depth: 0,
7012
7017
  maxDepth
7013
7018
  });
7014
- var extractOutputSchema = (table, plan, projectionNodes, context, options) => {
7015
- const mode = options.mode ?? "full";
7016
- const hasComputedFields = projectionNodes && projectionNodes.some(
7017
- (node) => node.type !== "Column"
7018
- );
7019
- if (hasComputedFields) {
7020
- return extractFromProjectionNodes(table, projectionNodes, context, options);
7021
- }
7022
- if (mode === "selected" && plan) {
7023
- return extractSelectedSchema(table, plan, context, options);
7024
- }
7025
- return extractFullTableSchema(table, context, options);
7026
- };
7019
+ var buildCircularReferenceSchema = (tableName, kind) => ({
7020
+ type: "object",
7021
+ properties: {
7022
+ _ref: {
7023
+ type: "string",
7024
+ description: `Circular ${kind} reference to ${tableName}`
7025
+ }
7026
+ },
7027
+ required: []
7028
+ });
7029
+
7030
+ // src/openapi/schema-extractor-input.ts
7027
7031
  var extractInputSchema = (table, context, options) => {
7028
7032
  const cacheKey = `${table.name}:${options.mode ?? "create"}`;
7029
7033
  if (context.schemaCache.has(cacheKey)) {
@@ -7111,6 +7115,18 @@ var extractInputRelationSchema = (relation, context, options) => {
7111
7115
  nullable: isNullable
7112
7116
  };
7113
7117
  };
7118
+
7119
+ // src/openapi/schema-extractor-output.ts
7120
+ var extractOutputSchema = (table, plan, projectionNodes, context, options) => {
7121
+ const hasComputedFields = hasComputedProjection(projectionNodes);
7122
+ if (hasComputedFields) {
7123
+ return extractFromProjectionNodes(table, projectionNodes, context, options);
7124
+ }
7125
+ if (shouldUseSelectedSchema(options, plan, projectionNodes)) {
7126
+ return extractSelectedSchema(table, plan, context, options);
7127
+ }
7128
+ return extractFullTableSchema(table, context, options);
7129
+ };
7114
7130
  var extractFromProjectionNodes = (table, projectionNodes, context, options) => {
7115
7131
  const properties = {};
7116
7132
  const required = [];
@@ -7316,6 +7332,52 @@ var extractFullTableSchema = (table, context, options) => {
7316
7332
  var extractRelationSchema = (relation, relationPlan, selectedColumns, context, options) => {
7317
7333
  const targetTable = relation.target;
7318
7334
  const { type: relationType, isNullable } = mapRelationType(relation.type);
7335
+ if (options.refMode === "components" && context.components) {
7336
+ if (relationPlan && selectedColumns.length > 0 && options.selectedRefMode === "components") {
7337
+ const plan = {
7338
+ rootTable: targetTable.name,
7339
+ rootPrimaryKey: relationPlan.targetPrimaryKey,
7340
+ rootColumns: selectedColumns,
7341
+ relations: []
7342
+ };
7343
+ const componentName2 = resolveSelectedComponentName(targetTable, plan, options);
7344
+ const ref2 = ensureComponentRef(
7345
+ targetTable,
7346
+ componentName2,
7347
+ context,
7348
+ () => extractSelectedSchema(targetTable, plan, context, options)
7349
+ );
7350
+ if (relationType === "array") {
7351
+ return {
7352
+ type: "array",
7353
+ items: ref2,
7354
+ nullable: isNullable
7355
+ };
7356
+ }
7357
+ return {
7358
+ ...ref2,
7359
+ nullable: isNullable
7360
+ };
7361
+ }
7362
+ const componentName = resolveComponentName(targetTable, options);
7363
+ const ref = ensureComponentRef(
7364
+ targetTable,
7365
+ componentName,
7366
+ context,
7367
+ () => extractFullTableSchema(targetTable, context, options)
7368
+ );
7369
+ if (relationType === "array") {
7370
+ return {
7371
+ type: "array",
7372
+ items: ref,
7373
+ nullable: isNullable
7374
+ };
7375
+ }
7376
+ return {
7377
+ ...ref,
7378
+ nullable: isNullable
7379
+ };
7380
+ }
7319
7381
  let targetSchema;
7320
7382
  if (relationPlan && selectedColumns.length > 0) {
7321
7383
  const plan = {
@@ -7343,16 +7405,68 @@ var extractRelationSchema = (relation, relationPlan, selectedColumns, context, o
7343
7405
  description: targetSchema.description
7344
7406
  };
7345
7407
  };
7346
- var buildCircularReferenceSchema = (tableName, kind) => ({
7347
- type: "object",
7348
- properties: {
7349
- _ref: {
7350
- type: "string",
7351
- description: `Circular ${kind} reference to ${tableName}`
7352
- }
7353
- },
7354
- required: []
7408
+
7409
+ // src/openapi/schema-extractor.ts
7410
+ var DEFAULT_MAX_DEPTH = 5;
7411
+ var extractSchema = (table, plan, projectionNodes, options = {}) => {
7412
+ const outputOptions = resolveOutputOptions(options);
7413
+ const outputContext = createContext(outputOptions.maxDepth ?? DEFAULT_MAX_DEPTH);
7414
+ if (outputOptions.refMode === "components") {
7415
+ outputContext.components = { schemas: {} };
7416
+ }
7417
+ const output = extractOutputSchema(table, plan, projectionNodes, outputContext, outputOptions);
7418
+ const useSelected = shouldUseSelectedSchema(outputOptions, plan, projectionNodes);
7419
+ const hasComputedFields = hasComputedProjection(projectionNodes);
7420
+ if (outputOptions.refMode === "components" && outputContext.components && !hasComputedFields) {
7421
+ const componentName = useSelected && plan ? resolveSelectedComponentName(table, plan, outputOptions) : resolveComponentName(table, outputOptions);
7422
+ registerComponentSchema(componentName, output, outputContext);
7423
+ }
7424
+ const inputOptions = resolveInputOptions(options);
7425
+ if (!inputOptions) {
7426
+ return {
7427
+ output,
7428
+ components: outputContext.components && Object.keys(outputContext.components.schemas).length ? outputContext.components : void 0
7429
+ };
7430
+ }
7431
+ const inputContext = createContext(inputOptions.maxDepth ?? DEFAULT_MAX_DEPTH);
7432
+ const input = extractInputSchema(table, inputContext, inputOptions);
7433
+ return {
7434
+ output,
7435
+ input,
7436
+ components: outputContext.components && Object.keys(outputContext.components.schemas).length ? outputContext.components : void 0
7437
+ };
7438
+ };
7439
+ var resolveOutputOptions = (options) => ({
7440
+ mode: options.mode ?? "full",
7441
+ includeDescriptions: options.includeDescriptions,
7442
+ includeEnums: options.includeEnums,
7443
+ includeExamples: options.includeExamples,
7444
+ includeDefaults: options.includeDefaults,
7445
+ includeNullable: options.includeNullable,
7446
+ maxDepth: options.maxDepth ?? DEFAULT_MAX_DEPTH,
7447
+ refMode: options.refMode ?? "inline",
7448
+ selectedRefMode: options.selectedRefMode ?? "inline",
7449
+ componentName: options.componentName
7355
7450
  });
7451
+ var resolveInputOptions = (options) => {
7452
+ if (options.input === false) return void 0;
7453
+ const input = options.input ?? {};
7454
+ const mode = input.mode ?? "create";
7455
+ return {
7456
+ mode,
7457
+ includeRelations: input.includeRelations ?? true,
7458
+ relationMode: input.relationMode ?? "mixed",
7459
+ includeDescriptions: input.includeDescriptions ?? options.includeDescriptions,
7460
+ includeEnums: input.includeEnums ?? options.includeEnums,
7461
+ includeExamples: input.includeExamples ?? options.includeExamples,
7462
+ includeDefaults: input.includeDefaults ?? options.includeDefaults,
7463
+ includeNullable: input.includeNullable ?? options.includeNullable,
7464
+ maxDepth: input.maxDepth ?? options.maxDepth ?? DEFAULT_MAX_DEPTH,
7465
+ omitReadOnly: input.omitReadOnly ?? true,
7466
+ excludePrimaryKey: input.excludePrimaryKey ?? false,
7467
+ requirePrimaryKey: input.requirePrimaryKey ?? mode === "update"
7468
+ };
7469
+ };
7356
7470
  var schemaToJson = (schema, pretty = false) => {
7357
7471
  return JSON.stringify(schema, null, pretty ? 2 : 0);
7358
7472
  };
@@ -8234,8 +8348,7 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8234
8348
  * Validates that the query does not contain Param operands.
8235
8349
  * Param proxies are only for schema generation, not execution.
8236
8350
  */
8237
- validateNoParamOperands(options) {
8238
- if (options?.allowParamOperands) return;
8351
+ validateNoParamOperands() {
8239
8352
  const ast = this.context.hydration.applyToAst(this.context.state.ast);
8240
8353
  const paramName = findFirstParamOperandName(ast);
8241
8354
  if (paramName) {
@@ -8254,13 +8367,13 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8254
8367
  * // users is User[]
8255
8368
  * users[0] instanceof User; // true
8256
8369
  */
8257
- async execute(ctx, options) {
8258
- this.validateNoParamOperands(options);
8370
+ async execute(ctx) {
8371
+ this.validateNoParamOperands();
8259
8372
  if (this.entityConstructor) {
8260
- return this.executeAs(this.entityConstructor, ctx, options);
8373
+ return this.executeAs(this.entityConstructor, ctx);
8261
8374
  }
8262
8375
  const builder = this.ensureDefaultSelection();
8263
- return executeHydrated(ctx, builder, options);
8376
+ return executeHydrated(ctx, builder);
8264
8377
  }
8265
8378
  /**
8266
8379
  * Executes the query and returns plain row objects (POJOs), ignoring any entity materialization.
@@ -8273,10 +8386,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8273
8386
  * // rows is EntityInstance<UserTable>[] (plain objects)
8274
8387
  * rows[0] instanceof User; // false
8275
8388
  */
8276
- async executePlain(ctx, options) {
8277
- this.validateNoParamOperands(options);
8389
+ async executePlain(ctx) {
8390
+ this.validateNoParamOperands();
8278
8391
  const builder = this.ensureDefaultSelection();
8279
- const rows = await executeHydratedPlain(ctx, builder, options);
8392
+ const rows = await executeHydratedPlain(ctx, builder);
8280
8393
  return rows;
8281
8394
  }
8282
8395
  /**
@@ -8293,10 +8406,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8293
8406
  * users[0] instanceof User; // true!
8294
8407
  * users[0].getFullName(); // works!
8295
8408
  */
8296
- async executeAs(entityClass, ctx, options) {
8297
- this.validateNoParamOperands(options);
8409
+ async executeAs(entityClass, ctx) {
8410
+ this.validateNoParamOperands();
8298
8411
  const builder = this.ensureDefaultSelection();
8299
- const results = await executeHydrated(ctx, builder, options);
8412
+ const results = await executeHydrated(ctx, builder);
8300
8413
  return materializeAs(entityClass, results);
8301
8414
  }
8302
8415
  /**
@@ -8305,9 +8418,9 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8305
8418
  * @example
8306
8419
  * const total = await qb.count(session);
8307
8420
  */
8308
- async count(session, options) {
8309
- this.validateNoParamOperands(options);
8310
- return executeCount(this.context, this.env, session, options);
8421
+ async count(session) {
8422
+ this.validateNoParamOperands();
8423
+ return executeCount(this.context, this.env, session);
8311
8424
  }
8312
8425
  /**
8313
8426
  * Executes the query and returns both the paged items and the total.
@@ -8316,9 +8429,9 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8316
8429
  * const { items, totalItems, page, pageSize } = await qb.executePaged(session, { page: 1, pageSize: 20 });
8317
8430
  */
8318
8431
  async executePaged(session, options) {
8319
- this.validateNoParamOperands(options);
8432
+ this.validateNoParamOperands();
8320
8433
  const builder = this.ensureDefaultSelection();
8321
- return executePagedQuery(builder, session, options, (sess) => builder.count(sess, options), options);
8434
+ return executePagedQuery(builder, session, options, (sess) => builder.count(sess));
8322
8435
  }
8323
8436
  /**
8324
8437
  * Executes the query with provided execution and hydration contexts
@@ -8330,10 +8443,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8330
8443
  * const hydCtx = new HydrationContext();
8331
8444
  * const users = await qb.executeWithContexts(execCtx, hydCtx);
8332
8445
  */
8333
- async executeWithContexts(execCtx, hydCtx, options) {
8334
- this.validateNoParamOperands(options);
8446
+ async executeWithContexts(execCtx, hydCtx) {
8447
+ this.validateNoParamOperands();
8335
8448
  const builder = this.ensureDefaultSelection();
8336
- const results = await executeHydratedWithContexts(execCtx, hydCtx, builder, options);
8449
+ const results = await executeHydratedWithContexts(execCtx, hydCtx, builder);
8337
8450
  if (this.entityConstructor) {
8338
8451
  return materializeAs(this.entityConstructor, results);
8339
8452
  }