metal-orm 1.0.90 → 1.0.92

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.
Files changed (37) hide show
  1. package/dist/index.cjs +214 -118
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +71 -32
  4. package/dist/index.d.ts +71 -32
  5. package/dist/index.js +206 -118
  6. package/dist/index.js.map +1 -1
  7. package/package.json +4 -2
  8. package/scripts/generate-entities/render.mjs +16 -3
  9. package/src/core/ddl/introspect/utils.ts +45 -45
  10. package/src/decorators/bootstrap.ts +37 -37
  11. package/src/decorators/column-decorator.ts +3 -1
  12. package/src/dto/apply-filter.ts +279 -281
  13. package/src/dto/dto-types.ts +229 -229
  14. package/src/dto/filter-types.ts +193 -193
  15. package/src/dto/index.ts +97 -97
  16. package/src/dto/openapi/generators/base.ts +29 -29
  17. package/src/dto/openapi/generators/column.ts +37 -34
  18. package/src/dto/openapi/generators/dto.ts +94 -94
  19. package/src/dto/openapi/generators/filter.ts +75 -74
  20. package/src/dto/openapi/generators/nested-dto.ts +618 -532
  21. package/src/dto/openapi/generators/pagination.ts +111 -111
  22. package/src/dto/openapi/generators/relation-filter.ts +228 -210
  23. package/src/dto/openapi/index.ts +17 -17
  24. package/src/dto/openapi/type-mappings.ts +191 -191
  25. package/src/dto/openapi/types.ts +101 -83
  26. package/src/dto/openapi/utilities.ts +90 -45
  27. package/src/dto/pagination-utils.ts +150 -150
  28. package/src/dto/transform.ts +197 -193
  29. package/src/index.ts +69 -69
  30. package/src/orm/entity-context.ts +9 -9
  31. package/src/orm/entity-metadata.ts +14 -14
  32. package/src/orm/entity.ts +74 -74
  33. package/src/orm/orm-session.ts +159 -159
  34. package/src/orm/relation-change-processor.ts +3 -3
  35. package/src/orm/runtime-types.ts +5 -5
  36. package/src/schema/column-types.ts +4 -4
  37. package/src/schema/types.ts +5 -1
package/dist/index.js CHANGED
@@ -6179,7 +6179,7 @@ var buildTableDef = (meta) => {
6179
6179
  for (const [key, def] of Object.entries(meta.columns)) {
6180
6180
  columns[key] = {
6181
6181
  ...def,
6182
- name: key,
6182
+ name: def.name ?? key,
6183
6183
  table: meta.tableName
6184
6184
  };
6185
6185
  }
@@ -12357,7 +12357,8 @@ var normalizeColumnInput = (input) => {
12357
12357
  generated: asDefinition.generated,
12358
12358
  check: asDefinition.check,
12359
12359
  references: asDefinition.references,
12360
- comment: asDefinition.comment
12360
+ comment: asDefinition.comment,
12361
+ name: asOptions.name ?? asDefinition.name
12361
12362
  };
12362
12363
  if (!column.type) {
12363
12364
  throw new Error("Column decorator requires a column type");
@@ -13404,7 +13405,38 @@ function mergeSchemas(base, override) {
13404
13405
  required: override.required ?? base.required
13405
13406
  };
13406
13407
  }
13407
- function generateOpenApiDocument(info, routes) {
13408
+ function applyNullability(schema, isNullable, dialect) {
13409
+ if (!isNullable) {
13410
+ const { nullable: _2, ...clean2 } = schema;
13411
+ return clean2;
13412
+ }
13413
+ if (dialect === "openapi-3.0") {
13414
+ return { ...schema, nullable: true };
13415
+ }
13416
+ const type = schema.type;
13417
+ if (Array.isArray(type)) {
13418
+ if (!type.includes("null")) {
13419
+ const { nullable: _2, ...clean2 } = schema;
13420
+ return { ...clean2, type: [...type, "null"] };
13421
+ }
13422
+ } else if (type) {
13423
+ const { nullable: _2, ...clean2 } = schema;
13424
+ return { ...clean2, type: [type, "null"] };
13425
+ } else {
13426
+ const { nullable: _2, ...clean2 } = schema;
13427
+ return { ...clean2, type: ["null"] };
13428
+ }
13429
+ const { nullable: _, ...clean } = schema;
13430
+ return clean;
13431
+ }
13432
+ function isNullableColumn(col2) {
13433
+ return !col2.notNull;
13434
+ }
13435
+ function getOpenApiVersionForDialect(dialect) {
13436
+ return dialect === "openapi-3.0" ? "3.0.3" : "3.1.0";
13437
+ }
13438
+ function generateOpenApiDocument(info, routes, options) {
13439
+ const dialect = options?.dialect ?? "openapi-3.1";
13408
13440
  const paths = {};
13409
13441
  for (const route of routes) {
13410
13442
  if (!paths[route.path]) {
@@ -13413,7 +13445,7 @@ function generateOpenApiDocument(info, routes) {
13413
13445
  paths[route.path][route.method] = route.operation;
13414
13446
  }
13415
13447
  return {
13416
- openapi: "3.1.0",
13448
+ openapi: getOpenApiVersionForDialect(dialect),
13417
13449
  info: {
13418
13450
  title: info.title,
13419
13451
  version: info.version,
@@ -13447,34 +13479,33 @@ function getColumnMap(target) {
13447
13479
  }
13448
13480
 
13449
13481
  // src/dto/openapi/generators/column.ts
13450
- function columnToOpenApiSchema(col2) {
13482
+ function columnToOpenApiSchema(col2, dialect = "openapi-3.1") {
13451
13483
  const schema = {
13452
13484
  type: columnTypeToOpenApiType(col2),
13453
13485
  format: columnTypeToOpenApiFormat(col2)
13454
13486
  };
13455
- if (!col2.notNull) {
13456
- schema.nullable = true;
13457
- }
13487
+ const nullable = isNullableColumn(col2);
13488
+ const result = applyNullability(schema, nullable, dialect);
13458
13489
  if (col2.comment) {
13459
- schema.description = col2.comment;
13490
+ result.description = col2.comment;
13460
13491
  }
13461
13492
  if (col2.type.toUpperCase() === "ENUM" && col2.args && Array.isArray(col2.args) && col2.args.every((v) => typeof v === "string")) {
13462
- schema.enum = col2.args;
13493
+ result.enum = col2.args;
13463
13494
  }
13464
13495
  const args = col2.args;
13465
13496
  if (args && args.length > 0) {
13466
13497
  if (col2.type.toUpperCase() === "VARCHAR" || col2.type.toUpperCase() === "CHAR") {
13467
13498
  const length2 = args[0];
13468
13499
  if (length2) {
13469
- schema.example = "a".repeat(length2);
13500
+ result.example = "a".repeat(length2);
13470
13501
  }
13471
13502
  }
13472
13503
  }
13473
- return schema;
13504
+ return result;
13474
13505
  }
13475
13506
 
13476
13507
  // src/dto/openapi/generators/dto.ts
13477
- function dtoToOpenApiSchema(target, exclude2) {
13508
+ function dtoToOpenApiSchema(target, exclude2, dialect = "openapi-3.1") {
13478
13509
  const columns = getColumnMap(target);
13479
13510
  const properties = {};
13480
13511
  const required = [];
@@ -13482,7 +13513,7 @@ function dtoToOpenApiSchema(target, exclude2) {
13482
13513
  if (exclude2?.includes(key)) {
13483
13514
  continue;
13484
13515
  }
13485
- properties[key] = columnToOpenApiSchema(col2);
13516
+ properties[key] = columnToOpenApiSchema(col2, dialect);
13486
13517
  if (col2.notNull || col2.primary) {
13487
13518
  required.push(key);
13488
13519
  }
@@ -13493,7 +13524,7 @@ function dtoToOpenApiSchema(target, exclude2) {
13493
13524
  ...required.length > 0 && { required }
13494
13525
  };
13495
13526
  }
13496
- function createDtoToOpenApiSchema(target, exclude2) {
13527
+ function createDtoToOpenApiSchema(target, exclude2, dialect = "openapi-3.1") {
13497
13528
  const columns = getColumnMap(target);
13498
13529
  const properties = {};
13499
13530
  const required = [];
@@ -13504,7 +13535,7 @@ function createDtoToOpenApiSchema(target, exclude2) {
13504
13535
  if (col2.autoIncrement || col2.generated) {
13505
13536
  continue;
13506
13537
  }
13507
- properties[key] = columnToOpenApiSchema(col2);
13538
+ properties[key] = columnToOpenApiSchema(col2, dialect);
13508
13539
  if (col2.notNull && !col2.default) {
13509
13540
  required.push(key);
13510
13541
  }
@@ -13515,7 +13546,7 @@ function createDtoToOpenApiSchema(target, exclude2) {
13515
13546
  ...required.length > 0 && { required }
13516
13547
  };
13517
13548
  }
13518
- function updateDtoToOpenApiSchema(target, exclude2) {
13549
+ function updateDtoToOpenApiSchema(target, exclude2, dialect = "openapi-3.1") {
13519
13550
  const columns = getColumnMap(target);
13520
13551
  const properties = {};
13521
13552
  for (const [key, col2] of Object.entries(columns)) {
@@ -13525,10 +13556,7 @@ function updateDtoToOpenApiSchema(target, exclude2) {
13525
13556
  if (col2.autoIncrement || col2.generated) {
13526
13557
  continue;
13527
13558
  }
13528
- properties[key] = {
13529
- ...columnToOpenApiSchema(col2),
13530
- ...!col2.notNull ? { nullable: true } : {}
13531
- };
13559
+ properties[key] = columnToOpenApiSchema(col2, dialect);
13532
13560
  }
13533
13561
  return {
13534
13562
  type: "object",
@@ -13538,58 +13566,49 @@ function updateDtoToOpenApiSchema(target, exclude2) {
13538
13566
 
13539
13567
  // src/dto/openapi/generators/filter.ts
13540
13568
  function filterFieldToOpenApiSchema(col2) {
13541
- const normalizedType = col2.type.toUpperCase();
13542
- columnTypeToOpenApiType(col2);
13543
- let filterProperties = {};
13544
- if (["INT", "INTEGER", "BIGINT", "DECIMAL", "FLOAT", "DOUBLE"].includes(normalizedType)) {
13545
- filterProperties = {
13546
- equals: { type: "number" },
13547
- not: { type: "number" },
13548
- in: { type: "array", items: { type: "number" } },
13549
- notIn: { type: "array", items: { type: "number" } },
13550
- lt: { type: "number" },
13551
- lte: { type: "number" },
13552
- gt: { type: "number" },
13553
- gte: { type: "number" }
13554
- };
13555
- } else if (["BOOLEAN"].includes(normalizedType)) {
13556
- filterProperties = {
13557
- equals: { type: "boolean" },
13558
- not: { type: "boolean" }
13559
- };
13560
- } else if (["DATE", "DATETIME", "TIMESTAMP", "TIMESTAMPTZ"].includes(normalizedType)) {
13561
- filterProperties = {
13562
- equals: { type: "string", format: "date-time" },
13563
- not: { type: "string", format: "date-time" },
13564
- in: { type: "array", items: { type: "string", format: "date-time" } },
13565
- notIn: { type: "array", items: { type: "string", format: "date-time" } },
13566
- lt: { type: "string", format: "date-time" },
13567
- lte: { type: "string", format: "date-time" },
13568
- gt: { type: "string", format: "date-time" },
13569
- gte: { type: "string", format: "date-time" }
13570
- };
13571
- } else {
13572
- filterProperties = {
13573
- equals: { type: "string" },
13574
- not: { type: "string" },
13575
- in: { type: "array", items: { type: "string" } },
13576
- notIn: { type: "array", items: { type: "string" } },
13577
- contains: { type: "string" },
13578
- startsWith: { type: "string" },
13579
- endsWith: { type: "string" },
13580
- mode: { type: "string", enum: ["default", "insensitive"] }
13581
- };
13569
+ const openApiType = columnTypeToOpenApiType(col2);
13570
+ const openApiFormat = columnTypeToOpenApiFormat(col2);
13571
+ const filterProperties = {};
13572
+ filterProperties.equals = { type: openApiType, format: openApiFormat };
13573
+ filterProperties.not = { type: openApiType, format: openApiFormat };
13574
+ filterProperties.in = { type: "array", items: { type: openApiType, format: openApiFormat } };
13575
+ filterProperties.notIn = { type: "array", items: { type: openApiType, format: openApiFormat } };
13576
+ const isNumeric = openApiType === "integer" || openApiType === "number";
13577
+ const isDateOrTime = openApiType === "string" && (openApiFormat === "date" || openApiFormat === "date-time");
13578
+ const isString = openApiType === "string" && !isDateOrTime;
13579
+ if (isNumeric) {
13580
+ filterProperties.lt = { type: openApiType, format: openApiFormat };
13581
+ filterProperties.lte = { type: openApiType, format: openApiFormat };
13582
+ filterProperties.gt = { type: openApiType, format: openApiFormat };
13583
+ filterProperties.gte = { type: openApiType, format: openApiFormat };
13584
+ }
13585
+ if (isDateOrTime) {
13586
+ filterProperties.lt = { type: openApiType, format: openApiFormat };
13587
+ filterProperties.lte = { type: openApiType, format: openApiFormat };
13588
+ filterProperties.gt = { type: openApiType, format: openApiFormat };
13589
+ filterProperties.gte = { type: openApiType, format: openApiFormat };
13590
+ }
13591
+ if (isString) {
13592
+ filterProperties.contains = { type: "string" };
13593
+ filterProperties.startsWith = { type: "string" };
13594
+ filterProperties.endsWith = { type: "string" };
13595
+ filterProperties.mode = { type: "string", enum: ["default", "insensitive"] };
13582
13596
  }
13583
13597
  return {
13584
13598
  type: "object",
13585
13599
  properties: filterProperties
13586
13600
  };
13587
13601
  }
13588
- function whereInputToOpenApiSchema(target) {
13602
+ function columnToFilterSchema(col2, dialect = "openapi-3.1") {
13603
+ const filterSchema = filterFieldToOpenApiSchema(col2);
13604
+ const nullable = isNullableColumn(col2);
13605
+ return applyNullability(filterSchema, nullable, dialect);
13606
+ }
13607
+ function whereInputToOpenApiSchema(target, dialect = "openapi-3.1") {
13589
13608
  const columns = getColumnMap(target);
13590
13609
  const properties = {};
13591
13610
  for (const [key, col2] of Object.entries(columns)) {
13592
- properties[key] = filterFieldToOpenApiSchema(col2);
13611
+ properties[key] = columnToFilterSchema(col2, dialect);
13593
13612
  }
13594
13613
  return {
13595
13614
  type: "object",
@@ -13598,16 +13617,26 @@ function whereInputToOpenApiSchema(target) {
13598
13617
  }
13599
13618
 
13600
13619
  // src/dto/openapi/generators/relation-filter.ts
13601
- function relationFilterToOpenApiSchema(relation, options) {
13620
+ function relationFilterToOpenApiSchema(relation, options, dialect = "openapi-3.1", depth = 0) {
13602
13621
  if (relation.type === RelationKinds.BelongsTo || relation.type === RelationKinds.HasOne) {
13603
- return singleRelationFilterToOpenApiSchema(relation.target, options);
13622
+ return singleRelationFilterToOpenApiSchema(
13623
+ relation.target,
13624
+ options,
13625
+ dialect,
13626
+ depth
13627
+ );
13604
13628
  }
13605
13629
  if (relation.type === RelationKinds.HasMany || relation.type === RelationKinds.BelongsToMany) {
13606
- return manyRelationFilterToOpenApiSchema(relation.target, options);
13630
+ return manyRelationFilterToOpenApiSchema(
13631
+ relation.target,
13632
+ options,
13633
+ dialect,
13634
+ depth
13635
+ );
13607
13636
  }
13608
13637
  return { type: "object", properties: {} };
13609
13638
  }
13610
- function singleRelationFilterToOpenApiSchema(target, options) {
13639
+ function singleRelationFilterToOpenApiSchema(target, options, dialect = "openapi-3.1", depth = 0) {
13611
13640
  const columns = getColumnMap(target);
13612
13641
  const properties = {};
13613
13642
  const required = [];
@@ -13618,35 +13647,44 @@ function singleRelationFilterToOpenApiSchema(target, options) {
13618
13647
  if (options?.include && !options.include.includes(key)) {
13619
13648
  continue;
13620
13649
  }
13621
- properties[key] = columnToOpenApiSchema(col2);
13650
+ properties[key] = columnToFilterSchema(col2, dialect);
13622
13651
  if (col2.notNull || col2.primary) {
13623
13652
  required.push(key);
13624
13653
  }
13625
13654
  }
13655
+ if (depth > 0) {
13656
+ const tableDef = target;
13657
+ if (tableDef.relations) {
13658
+ for (const [relationName, relation] of Object.entries(tableDef.relations)) {
13659
+ properties[relationName] = relationFilterToOpenApiSchema(relation, void 0, dialect, depth - 1);
13660
+ }
13661
+ }
13662
+ }
13626
13663
  return {
13627
13664
  type: "object",
13628
13665
  properties,
13629
13666
  ...required.length > 0 && { required }
13630
13667
  };
13631
13668
  }
13632
- function manyRelationFilterToOpenApiSchema(target, options) {
13669
+ function manyRelationFilterToOpenApiSchema(target, options, dialect = "openapi-3.1", depth = 0) {
13670
+ const nestedSchema = depth > 0 ? nestedWhereInputToOpenApiSchema(target, depth, dialect) : {
13671
+ type: "object",
13672
+ properties: generateNestedProperties(target, options, dialect)
13673
+ };
13633
13674
  return {
13634
13675
  type: "object",
13635
13676
  properties: {
13636
13677
  some: {
13637
- type: "object",
13638
- description: "Filter related records that match all conditions",
13639
- properties: generateNestedProperties(target, options)
13678
+ ...nestedSchema,
13679
+ description: "Filter related records that match all conditions"
13640
13680
  },
13641
13681
  every: {
13642
- type: "object",
13643
- description: "Filter related records where all match conditions",
13644
- properties: generateNestedProperties(target, options)
13682
+ ...nestedSchema,
13683
+ description: "Filter related records where all match conditions"
13645
13684
  },
13646
13685
  none: {
13647
- type: "object",
13648
- description: "Filter where no related records match",
13649
- properties: generateNestedProperties(target, options)
13686
+ ...nestedSchema,
13687
+ description: "Filter where no related records match"
13650
13688
  },
13651
13689
  isEmpty: {
13652
13690
  type: "boolean",
@@ -13659,7 +13697,7 @@ function manyRelationFilterToOpenApiSchema(target, options) {
13659
13697
  }
13660
13698
  };
13661
13699
  }
13662
- function generateNestedProperties(target, options) {
13700
+ function generateNestedProperties(target, options, dialect = "openapi-3.1") {
13663
13701
  const columns = getColumnMap(target);
13664
13702
  const properties = {};
13665
13703
  for (const [key, col2] of Object.entries(columns)) {
@@ -13669,11 +13707,11 @@ function generateNestedProperties(target, options) {
13669
13707
  if (options?.include && !options.include.includes(key)) {
13670
13708
  continue;
13671
13709
  }
13672
- properties[key] = columnToOpenApiSchema(col2);
13710
+ properties[key] = columnToFilterSchema(col2, dialect);
13673
13711
  }
13674
13712
  return properties;
13675
13713
  }
13676
- function whereInputWithRelationsToOpenApiSchema(target, options) {
13714
+ function whereInputWithRelationsToOpenApiSchema(target, options, dialect = "openapi-3.1") {
13677
13715
  const columns = getColumnMap(target);
13678
13716
  const properties = {};
13679
13717
  const depth = options?.maxDepth ?? 3;
@@ -13684,7 +13722,7 @@ function whereInputWithRelationsToOpenApiSchema(target, options) {
13684
13722
  if (options?.columnInclude && !options.columnInclude.includes(key)) {
13685
13723
  continue;
13686
13724
  }
13687
- properties[key] = columnToOpenApiSchema(col2);
13725
+ properties[key] = columnToFilterSchema(col2, dialect);
13688
13726
  }
13689
13727
  const tableDef = target;
13690
13728
  if (tableDef.relations && depth > 0) {
@@ -13698,7 +13736,7 @@ function whereInputWithRelationsToOpenApiSchema(target, options) {
13698
13736
  properties[relationName] = relationFilterToOpenApiSchema(relation, {
13699
13737
  exclude: options?.columnExclude,
13700
13738
  include: options?.columnInclude
13701
- });
13739
+ }, dialect);
13702
13740
  }
13703
13741
  }
13704
13742
  return {
@@ -13706,32 +13744,19 @@ function whereInputWithRelationsToOpenApiSchema(target, options) {
13706
13744
  properties
13707
13745
  };
13708
13746
  }
13709
- function nestedWhereInputToOpenApiSchema(target, depth = 2) {
13747
+ function nestedWhereInputToOpenApiSchema(target, depth = 2, dialect = "openapi-3.1") {
13710
13748
  if (depth <= 0) {
13711
13749
  return { type: "object", properties: {} };
13712
13750
  }
13713
13751
  const columns = getColumnMap(target);
13714
13752
  const properties = {};
13715
13753
  for (const [key, col2] of Object.entries(columns)) {
13716
- properties[key] = columnToOpenApiSchema(col2);
13754
+ properties[key] = columnToFilterSchema(col2, dialect);
13717
13755
  }
13718
13756
  const tableDef = target;
13719
13757
  if (tableDef.relations) {
13720
13758
  for (const [relationName, relation] of Object.entries(tableDef.relations)) {
13721
- properties[relationName] = relationFilterToOpenApiSchema(relation);
13722
- if (depth > 1) {
13723
- if (relation.type === RelationKinds.BelongsTo || relation.type === RelationKinds.HasOne) {
13724
- properties[relationName] = singleRelationFilterToOpenApiSchema(relation.target);
13725
- } else if (relation.type === RelationKinds.HasMany || relation.type === RelationKinds.BelongsToMany) {
13726
- properties[relationName] = {
13727
- type: "object",
13728
- properties: {
13729
- some: nestedWhereInputToOpenApiSchema(relation.target, depth - 1),
13730
- every: nestedWhereInputToOpenApiSchema(relation.target, depth - 1)
13731
- }
13732
- };
13733
- }
13734
- }
13759
+ properties[relationName] = relationFilterToOpenApiSchema(relation, void 0, dialect, depth - 1);
13735
13760
  }
13736
13761
  }
13737
13762
  return {
@@ -13805,10 +13830,7 @@ function updateDtoWithRelationsToOpenApiSchema(target, _options) {
13805
13830
  if (col2.autoIncrement || col2.generated) {
13806
13831
  continue;
13807
13832
  }
13808
- properties[key] = {
13809
- ...columnToOpenApiSchema(col2),
13810
- nullable: true
13811
- };
13833
+ properties[key] = columnToOpenApiSchema(col2);
13812
13834
  }
13813
13835
  const tableDef = target;
13814
13836
  if (_options?.includeRelations !== false && tableDef.relations) {
@@ -13832,10 +13854,7 @@ function updateDtoToOpenApiSchemaForComponent(target) {
13832
13854
  if (col2.autoIncrement || col2.generated) {
13833
13855
  continue;
13834
13856
  }
13835
- properties[key] = {
13836
- ...columnToOpenApiSchema(col2),
13837
- nullable: true
13838
- };
13857
+ properties[key] = columnToOpenApiSchema(col2);
13839
13858
  }
13840
13859
  return {
13841
13860
  type: "object",
@@ -13905,7 +13924,7 @@ function createDtoToOpenApiSchemaForComponent(target) {
13905
13924
  properties
13906
13925
  };
13907
13926
  }
13908
- function whereInputWithRelationsToOpenApiSchema2(target, options) {
13927
+ function whereInputWithRelationsToOpenApiSchema2(target, options, dialect = "openapi-3.1") {
13909
13928
  const columns = getColumnMap(target);
13910
13929
  const properties = {};
13911
13930
  const depth = options?.maxDepth ?? 3;
@@ -13916,7 +13935,7 @@ function whereInputWithRelationsToOpenApiSchema2(target, options) {
13916
13935
  if (options?.columnInclude && !options.columnInclude.includes(key)) {
13917
13936
  continue;
13918
13937
  }
13919
- properties[key] = columnToOpenApiSchema(col2);
13938
+ properties[key] = columnToFilterSchema(col2, dialect);
13920
13939
  }
13921
13940
  const tableDef = target;
13922
13941
  if (tableDef.relations && depth > 0) {
@@ -13928,9 +13947,9 @@ function whereInputWithRelationsToOpenApiSchema2(target, options) {
13928
13947
  continue;
13929
13948
  }
13930
13949
  properties[relationName] = relationFilterToOpenApiSchema2(relation, {
13931
- exclude: options?.columnExclude,
13932
- include: options?.columnInclude
13933
- });
13950
+ exclude: options.columnExclude,
13951
+ include: options.columnInclude
13952
+ }, dialect);
13934
13953
  }
13935
13954
  }
13936
13955
  return {
@@ -13938,16 +13957,16 @@ function whereInputWithRelationsToOpenApiSchema2(target, options) {
13938
13957
  properties
13939
13958
  };
13940
13959
  }
13941
- function relationFilterToOpenApiSchema2(relation, options) {
13960
+ function relationFilterToOpenApiSchema2(relation, options, dialect = "openapi-3.1") {
13942
13961
  if (relation.type === RelationKinds.BelongsTo || relation.type === RelationKinds.HasOne) {
13943
- return singleRelationFilterToOpenApiSchema2(relation.target, options);
13962
+ return singleRelationFilterToOpenApiSchema2(relation.target, options, dialect);
13944
13963
  }
13945
13964
  if (relation.type === RelationKinds.HasMany || relation.type === RelationKinds.BelongsToMany) {
13946
13965
  return manyRelationFilterToOpenApiSchema2(relation.target);
13947
13966
  }
13948
13967
  return { type: "object", properties: {} };
13949
13968
  }
13950
- function singleRelationFilterToOpenApiSchema2(target, options) {
13969
+ function singleRelationFilterToOpenApiSchema2(target, options, dialect = "openapi-3.1") {
13951
13970
  const columns = getColumnMap(target);
13952
13971
  const properties = {};
13953
13972
  for (const [key, col2] of Object.entries(columns)) {
@@ -13957,7 +13976,7 @@ function singleRelationFilterToOpenApiSchema2(target, options) {
13957
13976
  if (options?.include && !options.include.includes(key)) {
13958
13977
  continue;
13959
13978
  }
13960
- properties[key] = columnToOpenApiSchema(col2);
13979
+ properties[key] = columnToFilterSchema(col2, dialect);
13961
13980
  }
13962
13981
  return {
13963
13982
  type: "object",
@@ -13998,7 +14017,7 @@ function generateNestedProperties2(target) {
13998
14017
  const columns = getColumnMap(target);
13999
14018
  const properties = {};
14000
14019
  for (const [key, col2] of Object.entries(columns)) {
14001
- properties[key] = columnToOpenApiSchema(col2);
14020
+ properties[key] = columnToFilterSchema(col2);
14002
14021
  }
14003
14022
  return properties;
14004
14023
  }
@@ -14027,6 +14046,67 @@ function parameterToRef(paramName) {
14027
14046
  function responseToRef(responseName) {
14028
14047
  return createRef(`responses/${responseName}`);
14029
14048
  }
14049
+ function canonicalizeSchema(schema) {
14050
+ if (typeof schema !== "object" || schema === null) {
14051
+ return schema;
14052
+ }
14053
+ if (Array.isArray(schema)) {
14054
+ return schema.map(canonicalizeSchema);
14055
+ }
14056
+ const canonical = {};
14057
+ const keys = Object.keys(schema).sort();
14058
+ for (const key of keys) {
14059
+ if (key === "description" || key === "example") {
14060
+ continue;
14061
+ }
14062
+ const value = schema[key];
14063
+ if (typeof value === "object" && value !== null) {
14064
+ canonical[key] = canonicalizeSchema(value);
14065
+ } else {
14066
+ canonical[key] = value;
14067
+ }
14068
+ }
14069
+ return canonical;
14070
+ }
14071
+ function computeSchemaHash(schema) {
14072
+ const canonical = canonicalizeSchema(schema);
14073
+ const json = JSON.stringify(canonical);
14074
+ let hash = 0;
14075
+ for (let i = 0; i < json.length; i++) {
14076
+ const char2 = json.charCodeAt(i);
14077
+ hash = (hash << 5) - hash + char2;
14078
+ hash = hash & hash;
14079
+ }
14080
+ const hex = Math.abs(hash).toString(16);
14081
+ return hex.padStart(8, "0").slice(0, 6);
14082
+ }
14083
+ function createDeterministicNamingState() {
14084
+ return {
14085
+ contentHashToName: /* @__PURE__ */ new Map(),
14086
+ nameToContentHash: /* @__PURE__ */ new Map()
14087
+ };
14088
+ }
14089
+ function getDeterministicComponentName(baseName, schema, state) {
14090
+ const hash = computeSchemaHash(schema);
14091
+ const normalizedBase = baseName.replace(/[^A-Za-z0-9_]/g, "");
14092
+ const existingName = state.contentHashToName.get(hash);
14093
+ if (existingName) {
14094
+ return existingName;
14095
+ }
14096
+ if (!state.nameToContentHash.has(normalizedBase)) {
14097
+ state.contentHashToName.set(hash, normalizedBase);
14098
+ state.nameToContentHash.set(normalizedBase, hash);
14099
+ return normalizedBase;
14100
+ }
14101
+ const existingHash = state.nameToContentHash.get(normalizedBase);
14102
+ if (existingHash === hash) {
14103
+ return normalizedBase;
14104
+ }
14105
+ const uniqueName = `${normalizedBase}_${hash}`;
14106
+ state.contentHashToName.set(hash, uniqueName);
14107
+ state.nameToContentHash.set(uniqueName, hash);
14108
+ return uniqueName;
14109
+ }
14030
14110
  function replaceWithRefs(schema, schemaMap, path = "components/schemas") {
14031
14111
  if (typeof schema === "object" && schema !== null) {
14032
14112
  if ("$ref" in schema) {
@@ -14247,6 +14327,7 @@ export {
14247
14327
  aliasRef,
14248
14328
  and,
14249
14329
  applyFilter,
14330
+ applyNullability,
14250
14331
  arrayAppend,
14251
14332
  asType,
14252
14333
  ascii,
@@ -14264,6 +14345,7 @@ export {
14264
14345
  bootstrapEntities,
14265
14346
  buildFilterExpression,
14266
14347
  calculateTotalPages,
14348
+ canonicalizeSchema,
14267
14349
  caseWhen,
14268
14350
  cast,
14269
14351
  cbrt,
@@ -14278,10 +14360,12 @@ export {
14278
14360
  col,
14279
14361
  collate,
14280
14362
  columnOperand,
14363
+ columnToFilterSchema,
14281
14364
  columnToOpenApiSchema,
14282
14365
  columnTypeToOpenApiFormat,
14283
14366
  columnTypeToOpenApiType,
14284
14367
  computePaginationMetadata,
14368
+ computeSchemaHash,
14285
14369
  concat,
14286
14370
  concatWs,
14287
14371
  correlateBy,
@@ -14290,6 +14374,7 @@ export {
14290
14374
  count,
14291
14375
  countAll,
14292
14376
  createApiComponentsSection,
14377
+ createDeterministicNamingState,
14293
14378
  createDtoToOpenApiSchema,
14294
14379
  createEntityFromRow,
14295
14380
  createEntityProxy,
@@ -14348,6 +14433,8 @@ export {
14348
14433
  getColumn,
14349
14434
  getColumnMap,
14350
14435
  getDecoratorMetadata,
14436
+ getDeterministicComponentName,
14437
+ getOpenApiVersionForDialect,
14351
14438
  getSchemaIntrospector,
14352
14439
  getTableDefFromEntity,
14353
14440
  greatest,
@@ -14375,6 +14462,7 @@ export {
14375
14462
  isFunctionNode,
14376
14463
  isNotNull,
14377
14464
  isNull,
14465
+ isNullableColumn,
14378
14466
  isOperandNode,
14379
14467
  isTableDef2 as isTableDef,
14380
14468
  isValueOperandInput,