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.cjs CHANGED
@@ -6446,9 +6446,9 @@ var flattenResults = (results) => {
6446
6446
  }
6447
6447
  return rows;
6448
6448
  };
6449
- var executeWithContexts = async (execCtx, entityCtx, qb, options) => {
6449
+ var executeWithContexts = async (execCtx, entityCtx, qb) => {
6450
6450
  const ast = qb.getAST();
6451
- const compiled = options?.allowParamOperands ? execCtx.dialect.compileSelectWithOptions(ast, { allowParams: true }) : execCtx.dialect.compileSelect(ast);
6451
+ const compiled = execCtx.dialect.compileSelect(ast);
6452
6452
  const executed = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
6453
6453
  const rows = flattenResults(executed);
6454
6454
  const lazyRelations = qb.getLazyRelations();
@@ -6466,9 +6466,9 @@ var executeWithContexts = async (execCtx, entityCtx, qb, options) => {
6466
6466
  await preloadRelationIncludes(entities, includeTree);
6467
6467
  return entities;
6468
6468
  };
6469
- var executePlainWithContexts = async (execCtx, qb, options) => {
6469
+ var executePlainWithContexts = async (execCtx, qb) => {
6470
6470
  const ast = qb.getAST();
6471
- const compiled = options?.allowParamOperands ? execCtx.dialect.compileSelectWithOptions(ast, { allowParams: true }) : execCtx.dialect.compileSelect(ast);
6471
+ const compiled = execCtx.dialect.compileSelect(ast);
6472
6472
  const executed = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
6473
6473
  const rows = flattenResults(executed);
6474
6474
  if (ast.setOps && ast.setOps.length > 0) {
@@ -6476,21 +6476,21 @@ var executePlainWithContexts = async (execCtx, qb, options) => {
6476
6476
  }
6477
6477
  return hydrateRows(rows, qb.getHydrationPlan());
6478
6478
  };
6479
- async function executeHydrated(session, qb, options) {
6480
- return executeWithContexts(session.getExecutionContext(), session, qb, options);
6479
+ async function executeHydrated(session, qb) {
6480
+ return executeWithContexts(session.getExecutionContext(), session, qb);
6481
6481
  }
6482
- async function executeHydratedPlain(session, qb, options) {
6483
- return executePlainWithContexts(session.getExecutionContext(), qb, options);
6482
+ async function executeHydratedPlain(session, qb) {
6483
+ return executePlainWithContexts(session.getExecutionContext(), qb);
6484
6484
  }
6485
- async function executeHydratedWithContexts(execCtx, hydCtx, qb, options) {
6485
+ async function executeHydratedWithContexts(execCtx, hydCtx, qb) {
6486
6486
  const entityCtx = hydCtx.entityContext;
6487
6487
  if (!entityCtx) {
6488
6488
  throw new Error("Hydration context is missing an EntityContext");
6489
6489
  }
6490
- return executeWithContexts(execCtx, entityCtx, qb, options);
6490
+ return executeWithContexts(execCtx, entityCtx, qb);
6491
6491
  }
6492
- async function executeHydratedPlainWithContexts(execCtx, qb, options) {
6493
- return executePlainWithContexts(execCtx, qb, options);
6492
+ async function executeHydratedPlainWithContexts(execCtx, qb) {
6493
+ return executePlainWithContexts(execCtx, qb);
6494
6494
  }
6495
6495
  var loadLazyRelationsForTable = async (ctx, table, lazyRelations, lazyRelationOptions) => {
6496
6496
  if (!lazyRelations.length) return;
@@ -6691,7 +6691,7 @@ function applyOrderBy(context, predicateFacet, term, directionOrOptions) {
6691
6691
  const dir = options.direction ?? ORDER_DIRECTIONS.ASC;
6692
6692
  return predicateFacet.orderBy(context, term, dir, options.nulls, options.collation);
6693
6693
  }
6694
- async function executeCount(context, env, session, options) {
6694
+ async function executeCount(context, env, session) {
6695
6695
  const unpagedAst = {
6696
6696
  ...context.state.ast,
6697
6697
  orderBy: void 0,
@@ -6711,7 +6711,7 @@ async function executeCount(context, env, session, options) {
6711
6711
  joins: []
6712
6712
  };
6713
6713
  const execCtx = session.getExecutionContext();
6714
- const compiled = options?.allowParamOperands ? execCtx.dialect.compileSelectWithOptions(countQuery, { allowParams: true }) : execCtx.dialect.compileSelect(countQuery);
6714
+ const compiled = execCtx.dialect.compileSelect(countQuery);
6715
6715
  const results = await execCtx.interceptors.run({ sql: compiled.sql, params: compiled.params }, execCtx.executor);
6716
6716
  const value = results[0]?.values?.[0]?.[0];
6717
6717
  if (typeof value === "number") return value;
@@ -6719,7 +6719,7 @@ async function executeCount(context, env, session, options) {
6719
6719
  if (typeof value === "string") return Number(value);
6720
6720
  return value === null || value === void 0 ? 0 : Number(value);
6721
6721
  }
6722
- async function executePagedQuery(builder, session, options, countCallback, paramOptions) {
6722
+ async function executePagedQuery(builder, session, options, countCallback) {
6723
6723
  const { page, pageSize } = options;
6724
6724
  if (!Number.isInteger(page) || page < 1) {
6725
6725
  throw new Error("executePaged: page must be an integer >= 1");
@@ -6729,7 +6729,7 @@ async function executePagedQuery(builder, session, options, countCallback, param
6729
6729
  }
6730
6730
  const offset = (page - 1) * pageSize;
6731
6731
  const totalItems = await countCallback(session);
6732
- const items = await builder.limit(pageSize).offset(offset).execute(session, paramOptions);
6732
+ const items = await builder.limit(pageSize).offset(offset).execute(session);
6733
6733
  return { items, totalItems, page, pageSize };
6734
6734
  }
6735
6735
  function buildWhereHasPredicate(env, context, relationFacet, createChildBuilder, relationName, callbackOrOptions, maybeOptions, negate = false) {
@@ -7249,47 +7249,52 @@ var getTemporalFormat = (sqlType) => {
7249
7249
  }
7250
7250
  };
7251
7251
 
7252
- // src/openapi/schema-extractor.ts
7253
- var DEFAULT_MAX_DEPTH = 5;
7254
- var extractSchema = (table, plan, projectionNodes, options = {}) => {
7255
- const outputOptions = resolveOutputOptions(options);
7256
- const outputContext = createContext(outputOptions.maxDepth ?? DEFAULT_MAX_DEPTH);
7257
- const output = extractOutputSchema(table, plan, projectionNodes, outputContext, outputOptions);
7258
- const inputOptions = resolveInputOptions(options);
7259
- if (!inputOptions) {
7260
- return { output };
7252
+ // src/openapi/schema-extractor-utils.ts
7253
+ var hasComputedProjection = (projectionNodes) => Boolean(projectionNodes && projectionNodes.some((node) => node.type !== "Column"));
7254
+ var shouldUseSelectedSchema = (options, plan, projectionNodes) => {
7255
+ if (!plan || options.mode !== "selected") return false;
7256
+ if (hasComputedProjection(projectionNodes)) return false;
7257
+ if (options.refMode === "components" && options.selectedRefMode !== "components") return false;
7258
+ return true;
7259
+ };
7260
+ var resolveComponentName = (table, options) => options.componentName ? options.componentName(table) : table.name;
7261
+ var normalizeColumns = (columns) => Array.from(new Set(columns)).sort((a, b) => a.localeCompare(b));
7262
+ var buildSelectionSignature = (plan) => {
7263
+ const relations = plan.relations.map((relation) => ({
7264
+ name: relation.name,
7265
+ columns: normalizeColumns(relation.columns)
7266
+ })).sort((a, b) => a.name.localeCompare(b.name));
7267
+ return JSON.stringify({
7268
+ root: normalizeColumns(plan.rootColumns),
7269
+ relations
7270
+ });
7271
+ };
7272
+ var hashString = (value) => {
7273
+ let hash = 2166136261;
7274
+ for (let i = 0; i < value.length; i += 1) {
7275
+ hash ^= value.charCodeAt(i);
7276
+ hash = hash * 16777619 >>> 0;
7261
7277
  }
7262
- const inputContext = createContext(inputOptions.maxDepth ?? DEFAULT_MAX_DEPTH);
7263
- const input = extractInputSchema(table, inputContext, inputOptions);
7264
- return { output, input };
7278
+ return hash.toString(16).padStart(8, "0");
7265
7279
  };
7266
- var resolveOutputOptions = (options) => ({
7267
- mode: options.mode ?? "full",
7268
- includeDescriptions: options.includeDescriptions,
7269
- includeEnums: options.includeEnums,
7270
- includeExamples: options.includeExamples,
7271
- includeDefaults: options.includeDefaults,
7272
- includeNullable: options.includeNullable,
7273
- maxDepth: options.maxDepth ?? DEFAULT_MAX_DEPTH
7274
- });
7275
- var resolveInputOptions = (options) => {
7276
- if (options.input === false) return void 0;
7277
- const input = options.input ?? {};
7278
- const mode = input.mode ?? "create";
7279
- return {
7280
- mode,
7281
- includeRelations: input.includeRelations ?? true,
7282
- relationMode: input.relationMode ?? "mixed",
7283
- includeDescriptions: input.includeDescriptions ?? options.includeDescriptions,
7284
- includeEnums: input.includeEnums ?? options.includeEnums,
7285
- includeExamples: input.includeExamples ?? options.includeExamples,
7286
- includeDefaults: input.includeDefaults ?? options.includeDefaults,
7287
- includeNullable: input.includeNullable ?? options.includeNullable,
7288
- maxDepth: input.maxDepth ?? options.maxDepth ?? DEFAULT_MAX_DEPTH,
7289
- omitReadOnly: input.omitReadOnly ?? true,
7290
- excludePrimaryKey: input.excludePrimaryKey ?? false,
7291
- requirePrimaryKey: input.requirePrimaryKey ?? mode === "update"
7292
- };
7280
+ var resolveSelectedComponentName = (table, plan, options) => {
7281
+ const base = resolveComponentName(table, options);
7282
+ const signature = buildSelectionSignature(plan);
7283
+ return `${base}__sel_${hashString(signature)}`;
7284
+ };
7285
+ var ensureComponentRef = (table, componentName, context, schemaFactory) => {
7286
+ if (context.components && !context.components.schemas[componentName]) {
7287
+ if (!context.visitedTables.has(table.name)) {
7288
+ context.components.schemas[componentName] = schemaFactory();
7289
+ }
7290
+ }
7291
+ return { $ref: `#/components/schemas/${componentName}` };
7292
+ };
7293
+ var registerComponentSchema = (name, schema, context) => {
7294
+ if (!context.components) return;
7295
+ if (!context.components.schemas[name]) {
7296
+ context.components.schemas[name] = schema;
7297
+ }
7293
7298
  };
7294
7299
  var createContext = (maxDepth) => ({
7295
7300
  visitedTables: /* @__PURE__ */ new Set(),
@@ -7297,19 +7302,18 @@ var createContext = (maxDepth) => ({
7297
7302
  depth: 0,
7298
7303
  maxDepth
7299
7304
  });
7300
- var extractOutputSchema = (table, plan, projectionNodes, context, options) => {
7301
- const mode = options.mode ?? "full";
7302
- const hasComputedFields = projectionNodes && projectionNodes.some(
7303
- (node) => node.type !== "Column"
7304
- );
7305
- if (hasComputedFields) {
7306
- return extractFromProjectionNodes(table, projectionNodes, context, options);
7307
- }
7308
- if (mode === "selected" && plan) {
7309
- return extractSelectedSchema(table, plan, context, options);
7310
- }
7311
- return extractFullTableSchema(table, context, options);
7312
- };
7305
+ var buildCircularReferenceSchema = (tableName, kind) => ({
7306
+ type: "object",
7307
+ properties: {
7308
+ _ref: {
7309
+ type: "string",
7310
+ description: `Circular ${kind} reference to ${tableName}`
7311
+ }
7312
+ },
7313
+ required: []
7314
+ });
7315
+
7316
+ // src/openapi/schema-extractor-input.ts
7313
7317
  var extractInputSchema = (table, context, options) => {
7314
7318
  const cacheKey = `${table.name}:${options.mode ?? "create"}`;
7315
7319
  if (context.schemaCache.has(cacheKey)) {
@@ -7397,6 +7401,18 @@ var extractInputRelationSchema = (relation, context, options) => {
7397
7401
  nullable: isNullable
7398
7402
  };
7399
7403
  };
7404
+
7405
+ // src/openapi/schema-extractor-output.ts
7406
+ var extractOutputSchema = (table, plan, projectionNodes, context, options) => {
7407
+ const hasComputedFields = hasComputedProjection(projectionNodes);
7408
+ if (hasComputedFields) {
7409
+ return extractFromProjectionNodes(table, projectionNodes, context, options);
7410
+ }
7411
+ if (shouldUseSelectedSchema(options, plan, projectionNodes)) {
7412
+ return extractSelectedSchema(table, plan, context, options);
7413
+ }
7414
+ return extractFullTableSchema(table, context, options);
7415
+ };
7400
7416
  var extractFromProjectionNodes = (table, projectionNodes, context, options) => {
7401
7417
  const properties = {};
7402
7418
  const required = [];
@@ -7602,6 +7618,52 @@ var extractFullTableSchema = (table, context, options) => {
7602
7618
  var extractRelationSchema = (relation, relationPlan, selectedColumns, context, options) => {
7603
7619
  const targetTable = relation.target;
7604
7620
  const { type: relationType, isNullable } = mapRelationType(relation.type);
7621
+ if (options.refMode === "components" && context.components) {
7622
+ if (relationPlan && selectedColumns.length > 0 && options.selectedRefMode === "components") {
7623
+ const plan = {
7624
+ rootTable: targetTable.name,
7625
+ rootPrimaryKey: relationPlan.targetPrimaryKey,
7626
+ rootColumns: selectedColumns,
7627
+ relations: []
7628
+ };
7629
+ const componentName2 = resolveSelectedComponentName(targetTable, plan, options);
7630
+ const ref2 = ensureComponentRef(
7631
+ targetTable,
7632
+ componentName2,
7633
+ context,
7634
+ () => extractSelectedSchema(targetTable, plan, context, options)
7635
+ );
7636
+ if (relationType === "array") {
7637
+ return {
7638
+ type: "array",
7639
+ items: ref2,
7640
+ nullable: isNullable
7641
+ };
7642
+ }
7643
+ return {
7644
+ ...ref2,
7645
+ nullable: isNullable
7646
+ };
7647
+ }
7648
+ const componentName = resolveComponentName(targetTable, options);
7649
+ const ref = ensureComponentRef(
7650
+ targetTable,
7651
+ componentName,
7652
+ context,
7653
+ () => extractFullTableSchema(targetTable, context, options)
7654
+ );
7655
+ if (relationType === "array") {
7656
+ return {
7657
+ type: "array",
7658
+ items: ref,
7659
+ nullable: isNullable
7660
+ };
7661
+ }
7662
+ return {
7663
+ ...ref,
7664
+ nullable: isNullable
7665
+ };
7666
+ }
7605
7667
  let targetSchema;
7606
7668
  if (relationPlan && selectedColumns.length > 0) {
7607
7669
  const plan = {
@@ -7629,16 +7691,68 @@ var extractRelationSchema = (relation, relationPlan, selectedColumns, context, o
7629
7691
  description: targetSchema.description
7630
7692
  };
7631
7693
  };
7632
- var buildCircularReferenceSchema = (tableName, kind) => ({
7633
- type: "object",
7634
- properties: {
7635
- _ref: {
7636
- type: "string",
7637
- description: `Circular ${kind} reference to ${tableName}`
7638
- }
7639
- },
7640
- required: []
7694
+
7695
+ // src/openapi/schema-extractor.ts
7696
+ var DEFAULT_MAX_DEPTH = 5;
7697
+ var extractSchema = (table, plan, projectionNodes, options = {}) => {
7698
+ const outputOptions = resolveOutputOptions(options);
7699
+ const outputContext = createContext(outputOptions.maxDepth ?? DEFAULT_MAX_DEPTH);
7700
+ if (outputOptions.refMode === "components") {
7701
+ outputContext.components = { schemas: {} };
7702
+ }
7703
+ const output = extractOutputSchema(table, plan, projectionNodes, outputContext, outputOptions);
7704
+ const useSelected = shouldUseSelectedSchema(outputOptions, plan, projectionNodes);
7705
+ const hasComputedFields = hasComputedProjection(projectionNodes);
7706
+ if (outputOptions.refMode === "components" && outputContext.components && !hasComputedFields) {
7707
+ const componentName = useSelected && plan ? resolveSelectedComponentName(table, plan, outputOptions) : resolveComponentName(table, outputOptions);
7708
+ registerComponentSchema(componentName, output, outputContext);
7709
+ }
7710
+ const inputOptions = resolveInputOptions(options);
7711
+ if (!inputOptions) {
7712
+ return {
7713
+ output,
7714
+ components: outputContext.components && Object.keys(outputContext.components.schemas).length ? outputContext.components : void 0
7715
+ };
7716
+ }
7717
+ const inputContext = createContext(inputOptions.maxDepth ?? DEFAULT_MAX_DEPTH);
7718
+ const input = extractInputSchema(table, inputContext, inputOptions);
7719
+ return {
7720
+ output,
7721
+ input,
7722
+ components: outputContext.components && Object.keys(outputContext.components.schemas).length ? outputContext.components : void 0
7723
+ };
7724
+ };
7725
+ var resolveOutputOptions = (options) => ({
7726
+ mode: options.mode ?? "full",
7727
+ includeDescriptions: options.includeDescriptions,
7728
+ includeEnums: options.includeEnums,
7729
+ includeExamples: options.includeExamples,
7730
+ includeDefaults: options.includeDefaults,
7731
+ includeNullable: options.includeNullable,
7732
+ maxDepth: options.maxDepth ?? DEFAULT_MAX_DEPTH,
7733
+ refMode: options.refMode ?? "inline",
7734
+ selectedRefMode: options.selectedRefMode ?? "inline",
7735
+ componentName: options.componentName
7641
7736
  });
7737
+ var resolveInputOptions = (options) => {
7738
+ if (options.input === false) return void 0;
7739
+ const input = options.input ?? {};
7740
+ const mode = input.mode ?? "create";
7741
+ return {
7742
+ mode,
7743
+ includeRelations: input.includeRelations ?? true,
7744
+ relationMode: input.relationMode ?? "mixed",
7745
+ includeDescriptions: input.includeDescriptions ?? options.includeDescriptions,
7746
+ includeEnums: input.includeEnums ?? options.includeEnums,
7747
+ includeExamples: input.includeExamples ?? options.includeExamples,
7748
+ includeDefaults: input.includeDefaults ?? options.includeDefaults,
7749
+ includeNullable: input.includeNullable ?? options.includeNullable,
7750
+ maxDepth: input.maxDepth ?? options.maxDepth ?? DEFAULT_MAX_DEPTH,
7751
+ omitReadOnly: input.omitReadOnly ?? true,
7752
+ excludePrimaryKey: input.excludePrimaryKey ?? false,
7753
+ requirePrimaryKey: input.requirePrimaryKey ?? mode === "update"
7754
+ };
7755
+ };
7642
7756
  var schemaToJson = (schema, pretty = false) => {
7643
7757
  return JSON.stringify(schema, null, pretty ? 2 : 0);
7644
7758
  };
@@ -8520,8 +8634,7 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8520
8634
  * Validates that the query does not contain Param operands.
8521
8635
  * Param proxies are only for schema generation, not execution.
8522
8636
  */
8523
- validateNoParamOperands(options) {
8524
- if (options?.allowParamOperands) return;
8637
+ validateNoParamOperands() {
8525
8638
  const ast = this.context.hydration.applyToAst(this.context.state.ast);
8526
8639
  const paramName = findFirstParamOperandName(ast);
8527
8640
  if (paramName) {
@@ -8540,13 +8653,13 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8540
8653
  * // users is User[]
8541
8654
  * users[0] instanceof User; // true
8542
8655
  */
8543
- async execute(ctx, options) {
8544
- this.validateNoParamOperands(options);
8656
+ async execute(ctx) {
8657
+ this.validateNoParamOperands();
8545
8658
  if (this.entityConstructor) {
8546
- return this.executeAs(this.entityConstructor, ctx, options);
8659
+ return this.executeAs(this.entityConstructor, ctx);
8547
8660
  }
8548
8661
  const builder = this.ensureDefaultSelection();
8549
- return executeHydrated(ctx, builder, options);
8662
+ return executeHydrated(ctx, builder);
8550
8663
  }
8551
8664
  /**
8552
8665
  * Executes the query and returns plain row objects (POJOs), ignoring any entity materialization.
@@ -8559,10 +8672,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8559
8672
  * // rows is EntityInstance<UserTable>[] (plain objects)
8560
8673
  * rows[0] instanceof User; // false
8561
8674
  */
8562
- async executePlain(ctx, options) {
8563
- this.validateNoParamOperands(options);
8675
+ async executePlain(ctx) {
8676
+ this.validateNoParamOperands();
8564
8677
  const builder = this.ensureDefaultSelection();
8565
- const rows = await executeHydratedPlain(ctx, builder, options);
8678
+ const rows = await executeHydratedPlain(ctx, builder);
8566
8679
  return rows;
8567
8680
  }
8568
8681
  /**
@@ -8579,10 +8692,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8579
8692
  * users[0] instanceof User; // true!
8580
8693
  * users[0].getFullName(); // works!
8581
8694
  */
8582
- async executeAs(entityClass, ctx, options) {
8583
- this.validateNoParamOperands(options);
8695
+ async executeAs(entityClass, ctx) {
8696
+ this.validateNoParamOperands();
8584
8697
  const builder = this.ensureDefaultSelection();
8585
- const results = await executeHydrated(ctx, builder, options);
8698
+ const results = await executeHydrated(ctx, builder);
8586
8699
  return materializeAs(entityClass, results);
8587
8700
  }
8588
8701
  /**
@@ -8591,9 +8704,9 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8591
8704
  * @example
8592
8705
  * const total = await qb.count(session);
8593
8706
  */
8594
- async count(session, options) {
8595
- this.validateNoParamOperands(options);
8596
- return executeCount(this.context, this.env, session, options);
8707
+ async count(session) {
8708
+ this.validateNoParamOperands();
8709
+ return executeCount(this.context, this.env, session);
8597
8710
  }
8598
8711
  /**
8599
8712
  * Executes the query and returns both the paged items and the total.
@@ -8602,9 +8715,9 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8602
8715
  * const { items, totalItems, page, pageSize } = await qb.executePaged(session, { page: 1, pageSize: 20 });
8603
8716
  */
8604
8717
  async executePaged(session, options) {
8605
- this.validateNoParamOperands(options);
8718
+ this.validateNoParamOperands();
8606
8719
  const builder = this.ensureDefaultSelection();
8607
- return executePagedQuery(builder, session, options, (sess) => builder.count(sess, options), options);
8720
+ return executePagedQuery(builder, session, options, (sess) => builder.count(sess));
8608
8721
  }
8609
8722
  /**
8610
8723
  * Executes the query with provided execution and hydration contexts
@@ -8616,10 +8729,10 @@ var SelectQueryBuilder = class _SelectQueryBuilder {
8616
8729
  * const hydCtx = new HydrationContext();
8617
8730
  * const users = await qb.executeWithContexts(execCtx, hydCtx);
8618
8731
  */
8619
- async executeWithContexts(execCtx, hydCtx, options) {
8620
- this.validateNoParamOperands(options);
8732
+ async executeWithContexts(execCtx, hydCtx) {
8733
+ this.validateNoParamOperands();
8621
8734
  const builder = this.ensureDefaultSelection();
8622
- const results = await executeHydratedWithContexts(execCtx, hydCtx, builder, options);
8735
+ const results = await executeHydratedWithContexts(execCtx, hydCtx, builder);
8623
8736
  if (this.entityConstructor) {
8624
8737
  return materializeAs(this.entityConstructor, results);
8625
8738
  }