metal-orm 1.0.32 → 1.0.34

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/README.md CHANGED
@@ -335,7 +335,7 @@ const [user] = await new SelectQueryBuilder(users)
335
335
  .where(eq(users.columns.id, 1))
336
336
  .execute(session);
337
337
 
338
- // user is an Entity<typeof users>
338
+ // user is an EntityInstance<typeof users>
339
339
  // scalar props are normal:
340
340
  user.name = 'Updated Name'; // marks entity as Dirty
341
341
 
@@ -365,12 +365,14 @@ What the runtime gives you:
365
365
 
366
366
  Finally, you can describe your models with decorators and still use the same runtime and query builder.
367
367
 
368
- > Import paths here assume a `metal-orm/decorators` subpath export – adjust if your bundle exposes them differently.
369
-
370
368
  ```ts
371
369
  import mysql from 'mysql2/promise';
372
- import { Orm, OrmSession, MySqlDialect, col, createMysqlExecutor } from 'metal-orm';
373
370
  import {
371
+ Orm,
372
+ OrmSession,
373
+ MySqlDialect,
374
+ col,
375
+ createMysqlExecutor,
374
376
  Entity,
375
377
  Column,
376
378
  PrimaryKey,
@@ -378,7 +380,7 @@ import {
378
380
  BelongsTo,
379
381
  bootstrapEntities,
380
382
  selectFromEntity,
381
- } from 'metal-orm/decorators';
383
+ } from 'metal-orm';
382
384
 
383
385
  @Entity()
384
386
  class User {
package/dist/index.cjs CHANGED
@@ -44,17 +44,24 @@ var init_schema_plan_executor = __esm({
44
44
  var index_exports = {};
45
45
  __export(index_exports, {
46
46
  AsyncLocalStorage: () => AsyncLocalStorage,
47
+ BelongsTo: () => BelongsTo,
48
+ BelongsToMany: () => BelongsToMany,
49
+ Column: () => Column,
47
50
  DefaultBelongsToReference: () => DefaultBelongsToReference,
48
51
  DefaultHasManyCollection: () => DefaultHasManyCollection,
49
52
  DefaultManyToManyCollection: () => DefaultManyToManyCollection,
50
53
  DeleteQueryBuilder: () => DeleteQueryBuilder,
51
54
  DomainEventBus: () => DomainEventBus,
55
+ Entity: () => Entity,
52
56
  EntityStatus: () => EntityStatus,
57
+ HasMany: () => HasMany,
58
+ HasOne: () => HasOne,
53
59
  InsertQueryBuilder: () => InsertQueryBuilder,
54
60
  MySqlDialect: () => MySqlDialect,
55
61
  Orm: () => Orm,
56
62
  OrmSession: () => OrmSession,
57
63
  PostgresDialect: () => PostgresDialect,
64
+ PrimaryKey: () => PrimaryKey,
58
65
  RelationKinds: () => RelationKinds,
59
66
  SelectQueryBuilder: () => SelectQueryBuilder,
60
67
  SqlServerDialect: () => SqlServerDialect,
@@ -73,6 +80,7 @@ __export(index_exports, {
73
80
  belongsTo: () => belongsTo,
74
81
  belongsToMany: () => belongsToMany,
75
82
  between: () => between,
83
+ bootstrapEntities: () => bootstrapEntities,
76
84
  caseWhen: () => caseWhen,
77
85
  ceil: () => ceil,
78
86
  ceiling: () => ceiling,
@@ -127,6 +135,7 @@ __export(index_exports, {
127
135
  generateCreateTableSql: () => generateCreateTableSql,
128
136
  generateSchemaSql: () => generateSchemaSql,
129
137
  getSchemaIntrospector: () => getSchemaIntrospector,
138
+ getTableDefFromEntity: () => getTableDefFromEntity,
130
139
  groupConcat: () => groupConcat,
131
140
  gt: () => gt,
132
141
  gte: () => gte,
@@ -199,6 +208,7 @@ __export(index_exports, {
199
208
  rpad: () => rpad,
200
209
  rtrim: () => rtrim,
201
210
  sel: () => sel,
211
+ selectFromEntity: () => selectFromEntity,
202
212
  sign: () => sign,
203
213
  sin: () => sin,
204
214
  space: () => space,
@@ -5163,12 +5173,42 @@ var createLiteral = (val) => ({ type: "Literal", value: val });
5163
5173
 
5164
5174
  // src/orm/entity-metadata.ts
5165
5175
  var metadataMap = /* @__PURE__ */ new Map();
5176
+ var ensureEntityMetadata = (target) => {
5177
+ let meta = metadataMap.get(target);
5178
+ if (!meta) {
5179
+ meta = {
5180
+ target,
5181
+ tableName: target.name || "unknown",
5182
+ columns: {},
5183
+ relations: {}
5184
+ };
5185
+ metadataMap.set(target, meta);
5186
+ }
5187
+ return meta;
5188
+ };
5166
5189
  var getEntityMetadata = (target) => {
5167
5190
  return metadataMap.get(target);
5168
5191
  };
5169
5192
  var getAllEntityMetadata = () => {
5170
5193
  return Array.from(metadataMap.values());
5171
5194
  };
5195
+ var addColumnMetadata = (target, propertyKey, column) => {
5196
+ const meta = ensureEntityMetadata(target);
5197
+ meta.columns[propertyKey] = { ...column };
5198
+ };
5199
+ var addRelationMetadata = (target, propertyKey, relation) => {
5200
+ const meta = ensureEntityMetadata(target);
5201
+ meta.relations[propertyKey] = relation;
5202
+ };
5203
+ var setEntityTableName = (target, tableName, hooks) => {
5204
+ const meta = ensureEntityMetadata(target);
5205
+ if (tableName && tableName.length > 0) {
5206
+ meta.tableName = tableName;
5207
+ }
5208
+ if (hooks) {
5209
+ meta.hooks = hooks;
5210
+ }
5211
+ };
5172
5212
  var buildTableDef = (meta) => {
5173
5213
  if (meta.table) {
5174
5214
  return meta.table;
@@ -7666,6 +7706,251 @@ var Orm = class {
7666
7706
  }
7667
7707
  };
7668
7708
 
7709
+ // src/decorators/decorator-metadata.ts
7710
+ var METADATA_KEY = "metal-orm:decorators";
7711
+ var isStandardDecoratorContext = (value) => {
7712
+ return typeof value === "object" && value !== null && "kind" in value;
7713
+ };
7714
+ var getOrCreateMetadataBag = (context) => {
7715
+ const metadata = context.metadata || (context.metadata = {});
7716
+ const existing = metadata[METADATA_KEY];
7717
+ if (existing) {
7718
+ return existing;
7719
+ }
7720
+ const bag = { columns: [], relations: [] };
7721
+ metadata[METADATA_KEY] = bag;
7722
+ return bag;
7723
+ };
7724
+ var readMetadataBag = (context) => {
7725
+ return context.metadata?.[METADATA_KEY];
7726
+ };
7727
+ var registerInitializer = (context, initializer) => {
7728
+ context.addInitializer?.(initializer);
7729
+ };
7730
+
7731
+ // src/decorators/entity.ts
7732
+ var toSnakeCase = (value) => {
7733
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^a-z0-9_]+/gi, "_").replace(/__+/g, "_").replace(/^_|_$/g, "").toLowerCase();
7734
+ };
7735
+ var deriveTableNameFromConstructor = (ctor) => {
7736
+ const fallback = "unknown";
7737
+ const rawName = ctor.name || fallback;
7738
+ const strippedName = rawName.replace(/Entity$/i, "");
7739
+ const normalized = toSnakeCase(strippedName || rawName);
7740
+ if (!normalized) {
7741
+ return fallback;
7742
+ }
7743
+ return normalized.endsWith("s") ? normalized : `${normalized}s`;
7744
+ };
7745
+ function Entity(options = {}) {
7746
+ const decorator = (value) => {
7747
+ const tableName = options.tableName ?? deriveTableNameFromConstructor(value);
7748
+ setEntityTableName(value, tableName, options.hooks);
7749
+ return value;
7750
+ };
7751
+ const decoratorWithContext = (value, context) => {
7752
+ const ctor = value;
7753
+ decorator(ctor);
7754
+ if (context && isStandardDecoratorContext(context)) {
7755
+ const bag = readMetadataBag(context);
7756
+ if (bag) {
7757
+ const meta = ensureEntityMetadata(ctor);
7758
+ for (const entry of bag.columns) {
7759
+ if (!meta.columns[entry.propertyName]) {
7760
+ addColumnMetadata(ctor, entry.propertyName, { ...entry.column });
7761
+ }
7762
+ }
7763
+ for (const entry of bag.relations) {
7764
+ if (!meta.relations[entry.propertyName]) {
7765
+ addRelationMetadata(ctor, entry.propertyName, entry.relation);
7766
+ }
7767
+ }
7768
+ }
7769
+ }
7770
+ return ctor;
7771
+ };
7772
+ return decoratorWithContext;
7773
+ }
7774
+
7775
+ // src/decorators/column.ts
7776
+ var normalizeColumnInput = (input) => {
7777
+ const asOptions = input;
7778
+ const asDefinition = input;
7779
+ const column = {
7780
+ type: asOptions.type ?? asDefinition.type,
7781
+ args: asOptions.args ?? asDefinition.args,
7782
+ notNull: asOptions.notNull ?? asDefinition.notNull,
7783
+ primary: asOptions.primary ?? asDefinition.primary,
7784
+ unique: asDefinition.unique,
7785
+ default: asDefinition.default,
7786
+ autoIncrement: asDefinition.autoIncrement,
7787
+ generated: asDefinition.generated,
7788
+ check: asDefinition.check,
7789
+ references: asDefinition.references,
7790
+ comment: asDefinition.comment
7791
+ };
7792
+ if (!column.type) {
7793
+ throw new Error("Column decorator requires a column type");
7794
+ }
7795
+ return column;
7796
+ };
7797
+ var normalizePropertyName = (name) => {
7798
+ if (typeof name === "symbol") {
7799
+ return name.description ?? name.toString();
7800
+ }
7801
+ return name;
7802
+ };
7803
+ var resolveConstructor = (target) => {
7804
+ if (typeof target === "function") {
7805
+ return target;
7806
+ }
7807
+ if (target && typeof target.constructor === "function") {
7808
+ return target.constructor;
7809
+ }
7810
+ return void 0;
7811
+ };
7812
+ var registerColumn = (ctor, propertyName, column) => {
7813
+ const meta = ensureEntityMetadata(ctor);
7814
+ if (meta.columns[propertyName]) {
7815
+ return;
7816
+ }
7817
+ addColumnMetadata(ctor, propertyName, column);
7818
+ };
7819
+ var registerColumnFromContext = (context, column) => {
7820
+ if (!context.name) {
7821
+ throw new Error("Column decorator requires a property name");
7822
+ }
7823
+ const propertyName = normalizePropertyName(context.name);
7824
+ const bag = getOrCreateMetadataBag(context);
7825
+ if (!bag.columns.some((entry) => entry.propertyName === propertyName)) {
7826
+ bag.columns.push({ propertyName, column: { ...column } });
7827
+ }
7828
+ registerInitializer(context, function() {
7829
+ const ctor = resolveConstructor(this);
7830
+ if (!ctor) {
7831
+ return;
7832
+ }
7833
+ registerColumn(ctor, propertyName, column);
7834
+ });
7835
+ };
7836
+ function Column(definition) {
7837
+ const normalized = normalizeColumnInput(definition);
7838
+ const decorator = (targetOrValue, propertyKeyOrContext) => {
7839
+ if (isStandardDecoratorContext(propertyKeyOrContext)) {
7840
+ registerColumnFromContext(propertyKeyOrContext, normalized);
7841
+ return;
7842
+ }
7843
+ const propertyName = normalizePropertyName(propertyKeyOrContext);
7844
+ const ctor = resolveConstructor(targetOrValue);
7845
+ if (!ctor) {
7846
+ throw new Error("Unable to resolve constructor when registering column metadata");
7847
+ }
7848
+ registerColumn(ctor, propertyName, { ...normalized });
7849
+ };
7850
+ return decorator;
7851
+ }
7852
+ function PrimaryKey(definition) {
7853
+ const normalized = normalizeColumnInput(definition);
7854
+ normalized.primary = true;
7855
+ return Column(normalized);
7856
+ }
7857
+
7858
+ // src/decorators/relations.ts
7859
+ var normalizePropertyName2 = (name) => {
7860
+ if (typeof name === "symbol") {
7861
+ return name.description ?? name.toString();
7862
+ }
7863
+ return name;
7864
+ };
7865
+ var resolveConstructor2 = (instanceOrCtor) => {
7866
+ if (typeof instanceOrCtor === "function") {
7867
+ return instanceOrCtor;
7868
+ }
7869
+ if (instanceOrCtor && typeof instanceOrCtor.constructor === "function") {
7870
+ return instanceOrCtor.constructor;
7871
+ }
7872
+ return void 0;
7873
+ };
7874
+ var registerRelation = (ctor, propertyName, metadata) => {
7875
+ addRelationMetadata(ctor, propertyName, metadata);
7876
+ };
7877
+ var createFieldDecorator = (metadataFactory) => {
7878
+ const decorator = (targetOrValue, propertyKeyOrContext) => {
7879
+ if (isStandardDecoratorContext(propertyKeyOrContext)) {
7880
+ const ctx = propertyKeyOrContext;
7881
+ if (!ctx.name) {
7882
+ throw new Error("Relation decorator requires a property name");
7883
+ }
7884
+ const propertyName2 = normalizePropertyName2(ctx.name);
7885
+ const bag = getOrCreateMetadataBag(ctx);
7886
+ const relationMetadata = metadataFactory(propertyName2);
7887
+ if (!bag.relations.some((entry) => entry.propertyName === propertyName2)) {
7888
+ bag.relations.push({ propertyName: propertyName2, relation: relationMetadata });
7889
+ }
7890
+ registerInitializer(ctx, function() {
7891
+ const ctor2 = resolveConstructor2(this);
7892
+ if (!ctor2) {
7893
+ return;
7894
+ }
7895
+ registerRelation(ctor2, propertyName2, relationMetadata);
7896
+ });
7897
+ return;
7898
+ }
7899
+ const propertyName = normalizePropertyName2(propertyKeyOrContext);
7900
+ const ctor = resolveConstructor2(targetOrValue);
7901
+ if (!ctor) {
7902
+ throw new Error("Unable to resolve constructor when registering relation metadata");
7903
+ }
7904
+ registerRelation(ctor, propertyName, metadataFactory(propertyName));
7905
+ };
7906
+ return decorator;
7907
+ };
7908
+ function HasMany(options) {
7909
+ return createFieldDecorator((propertyName) => ({
7910
+ kind: RelationKinds.HasMany,
7911
+ propertyKey: propertyName,
7912
+ target: options.target,
7913
+ foreignKey: options.foreignKey,
7914
+ localKey: options.localKey,
7915
+ cascade: options.cascade
7916
+ }));
7917
+ }
7918
+ function HasOne(options) {
7919
+ return createFieldDecorator((propertyName) => ({
7920
+ kind: RelationKinds.HasOne,
7921
+ propertyKey: propertyName,
7922
+ target: options.target,
7923
+ foreignKey: options.foreignKey,
7924
+ localKey: options.localKey,
7925
+ cascade: options.cascade
7926
+ }));
7927
+ }
7928
+ function BelongsTo(options) {
7929
+ return createFieldDecorator((propertyName) => ({
7930
+ kind: RelationKinds.BelongsTo,
7931
+ propertyKey: propertyName,
7932
+ target: options.target,
7933
+ foreignKey: options.foreignKey,
7934
+ localKey: options.localKey,
7935
+ cascade: options.cascade
7936
+ }));
7937
+ }
7938
+ function BelongsToMany(options) {
7939
+ return createFieldDecorator((propertyName) => ({
7940
+ kind: RelationKinds.BelongsToMany,
7941
+ propertyKey: propertyName,
7942
+ target: options.target,
7943
+ pivotTable: options.pivotTable,
7944
+ pivotForeignKeyToRoot: options.pivotForeignKeyToRoot,
7945
+ pivotForeignKeyToTarget: options.pivotForeignKeyToTarget,
7946
+ localKey: options.localKey,
7947
+ targetKey: options.targetKey,
7948
+ pivotPrimaryKey: options.pivotPrimaryKey,
7949
+ defaultPivotColumns: options.defaultPivotColumns,
7950
+ cascade: options.cascade
7951
+ }));
7952
+ }
7953
+
7669
7954
  // src/core/execution/db-executor.ts
7670
7955
  function rowsToQueryResult(rows) {
7671
7956
  if (rows.length === 0) {
@@ -7839,17 +8124,24 @@ function createTediousExecutor(connection, module2, options) {
7839
8124
  // Annotate the CommonJS export names for ESM import in node:
7840
8125
  0 && (module.exports = {
7841
8126
  AsyncLocalStorage,
8127
+ BelongsTo,
8128
+ BelongsToMany,
8129
+ Column,
7842
8130
  DefaultBelongsToReference,
7843
8131
  DefaultHasManyCollection,
7844
8132
  DefaultManyToManyCollection,
7845
8133
  DeleteQueryBuilder,
7846
8134
  DomainEventBus,
8135
+ Entity,
7847
8136
  EntityStatus,
8137
+ HasMany,
8138
+ HasOne,
7848
8139
  InsertQueryBuilder,
7849
8140
  MySqlDialect,
7850
8141
  Orm,
7851
8142
  OrmSession,
7852
8143
  PostgresDialect,
8144
+ PrimaryKey,
7853
8145
  RelationKinds,
7854
8146
  SelectQueryBuilder,
7855
8147
  SqlServerDialect,
@@ -7868,6 +8160,7 @@ function createTediousExecutor(connection, module2, options) {
7868
8160
  belongsTo,
7869
8161
  belongsToMany,
7870
8162
  between,
8163
+ bootstrapEntities,
7871
8164
  caseWhen,
7872
8165
  ceil,
7873
8166
  ceiling,
@@ -7922,6 +8215,7 @@ function createTediousExecutor(connection, module2, options) {
7922
8215
  generateCreateTableSql,
7923
8216
  generateSchemaSql,
7924
8217
  getSchemaIntrospector,
8218
+ getTableDefFromEntity,
7925
8219
  groupConcat,
7926
8220
  gt,
7927
8221
  gte,
@@ -7994,6 +8288,7 @@ function createTediousExecutor(connection, module2, options) {
7994
8288
  rpad,
7995
8289
  rtrim,
7996
8290
  sel,
8291
+ selectFromEntity,
7997
8292
  sign,
7998
8293
  sin,
7999
8294
  space,