@mikro-orm/entity-generator 7.1.0-dev.3 → 7.1.0-dev.31

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
@@ -2,7 +2,7 @@
2
2
  <a href="https://mikro-orm.io"><img src="https://raw.githubusercontent.com/mikro-orm/mikro-orm/master/docs/static/img/logo-readme.svg?sanitize=true" alt="MikroORM" /></a>
3
3
  </h1>
4
4
 
5
- TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL, SQLite (including libSQL), MSSQL and Oracle databases.
5
+ TypeScript ORM for Node.js based on Data Mapper, [Unit of Work](https://mikro-orm.io/docs/unit-of-work/) and [Identity Map](https://mikro-orm.io/docs/identity-map/) patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL (including CockroachDB and PGlite), SQLite (including libSQL), MSSQL and Oracle databases.
6
6
 
7
7
  > Heavily inspired by [Doctrine](https://www.doctrine-project.org/) and [Hibernate](https://hibernate.org/).
8
8
 
@@ -19,6 +19,7 @@ Install a driver package for your database:
19
19
 
20
20
  ```sh
21
21
  npm install @mikro-orm/postgresql # PostgreSQL
22
+ npm install @mikro-orm/pglite # PGlite (embedded PostgreSQL in WASM)
22
23
  npm install @mikro-orm/mysql # MySQL
23
24
  npm install @mikro-orm/mariadb # MariaDB
24
25
  npm install @mikro-orm/sqlite # SQLite
package/SourceFile.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { type Dictionary, type EmbeddableOptions, type EntityMetadata, type EntityOptions, type EntityProperty, type GenerateOptions, type IndexOptions, type NamingStrategy, type OneToOneOptions, type Platform, type UniqueOptions } from '@mikro-orm/core';
1
+ import { type Dictionary, type EmbeddableOptions, type EntityMetadata, type EntityOptions, type EntityPartitionBy, type EntityProperty, type GenerateOptions, type IndexOptions, type NamingStrategy, type OneToOneOptions, type Platform, type UniqueOptions } from '@mikro-orm/core';
2
2
  /**
3
3
  * @see https://github.com/tc39/proposal-regexp-unicode-property-escapes#other-examples
4
4
  */
@@ -30,6 +30,7 @@ export declare class SourceFile {
30
30
  protected serializeObject(options: {}, wordwrap?: number, spaces?: number, level?: number): string;
31
31
  protected serializeValue(val: unknown, wordwrap?: number, spaces?: number, level?: number): unknown;
32
32
  protected getEntityDeclOptions(): EntityOptions<unknown>;
33
+ protected getPartitionByDecl(partitionBy: EntityPartitionBy): Dictionary;
33
34
  protected getEmbeddableDeclOptions(): EmbeddableOptions<unknown>;
34
35
  private getCollectionDecl;
35
36
  private getPropertyDecorator;
package/SourceFile.js CHANGED
@@ -130,6 +130,9 @@ export class SourceFile {
130
130
  else if (typeof index.expression === 'function') {
131
131
  indexOpt.expression = `${index.expression}`.replace(')=>`', ') => `');
132
132
  }
133
+ if (typeof index.where === 'string') {
134
+ indexOpt.where = this.quote(index.where);
135
+ }
133
136
  if (isAtEntityLevel && index.properties) {
134
137
  indexOpt.properties = Utils.asArray(index.properties).map(prop => this.quote('' + prop));
135
138
  }
@@ -170,6 +173,9 @@ export class SourceFile {
170
173
  else if (typeof index.expression === 'function') {
171
174
  uniqueOpt.expression = `${index.expression}`.replace(')=>`', ') => `');
172
175
  }
176
+ if (typeof index.where === 'string') {
177
+ uniqueOpt.where = this.quote(index.where);
178
+ }
173
179
  if (isAtEntityLevel && index.properties) {
174
180
  uniqueOpt.properties = Utils.asArray(index.properties).map(prop => this.quote('' + prop));
175
181
  }
@@ -397,8 +403,11 @@ export class SourceFile {
397
403
  const enumTypeName = this.namingStrategy.getEnumTypeName(prop.fieldNames[0], this.meta.collection, this.meta.schema);
398
404
  const padding = ' '.repeat(padLeft);
399
405
  const enumValues = prop.items;
406
+ // numeric enums arrive as strings; emit raw numbers so the generated TS reads `Foo: 1` not `Foo: '1'`
407
+ const allNumeric = enumValues.length > 0 && enumValues.every(item => /^-?\d+$/.test(item));
408
+ const formatValue = (item) => (allNumeric ? item : this.quote(item));
400
409
  if (enumMode === 'union-type') {
401
- return `export type ${enumTypeName} = ${enumValues.map(item => this.quote(item)).join(' | ')};\n`;
410
+ return `export type ${enumTypeName} = ${enumValues.map(formatValue).join(' | ')};\n`;
402
411
  }
403
412
  let ret = '';
404
413
  if (enumMode === 'dictionary') {
@@ -410,10 +419,10 @@ export class SourceFile {
410
419
  for (const enumValue of enumValues) {
411
420
  const enumName = this.namingStrategy.enumValueToEnumProperty(enumValue, prop.fieldNames[0], this.meta.collection, this.meta.schema);
412
421
  if (enumMode === 'dictionary') {
413
- ret += `${padding}${identifierRegex.test(enumName) ? enumName : this.quote(enumName)}: ${this.quote(enumValue)},\n`;
422
+ ret += `${padding}${identifierRegex.test(enumName) ? enumName : this.quote(enumName)}: ${formatValue(enumValue)},\n`;
414
423
  }
415
424
  else {
416
- ret += `${padding}${identifierRegex.test(enumName) ? enumName : this.quote(enumName)} = ${this.quote(enumValue)},\n`;
425
+ ret += `${padding}${identifierRegex.test(enumName) ? enumName : this.quote(enumName)} = ${formatValue(enumValue)},\n`;
417
426
  }
418
427
  }
419
428
  if (enumMode === 'dictionary') {
@@ -475,6 +484,9 @@ export class SourceFile {
475
484
  if (this.meta.comment) {
476
485
  options.comment = this.quote(this.meta.comment);
477
486
  }
487
+ if (this.meta.partitionBy) {
488
+ options.partitionBy = this.getPartitionByDecl(this.meta.partitionBy);
489
+ }
478
490
  if (this.meta.readonly && !this.meta.virtual) {
479
491
  options.readonly = this.meta.readonly;
480
492
  }
@@ -483,6 +495,40 @@ export class SourceFile {
483
495
  }
484
496
  return this.getCollectionDecl(options);
485
497
  }
498
+ getPartitionByDecl(partitionBy) {
499
+ const result = { type: this.quote(partitionBy.type) };
500
+ // Introspected metadata from `toEntityPartitionBy` always emits a string or string[];
501
+ // callback-form expressions only exist in hand-written entity metadata. Fail loud if a
502
+ // callback ever reaches the generator — stringifying `fn.toString()` would produce source
503
+ // that re-imports nothing and will not compile.
504
+ if (typeof partitionBy.expression === 'function') {
505
+ throw new Error(`Cannot emit entity source for ${this.meta.className}: partitionBy.expression is a callback. ` +
506
+ `Entity generator expects string or string[] expressions from catalog introspection.`);
507
+ }
508
+ const expression = partitionBy.expression;
509
+ if (Array.isArray(expression)) {
510
+ result.expression = expression.map(key => this.quote(String(key)));
511
+ }
512
+ else {
513
+ result.expression = this.quote(String(expression));
514
+ }
515
+ if (partitionBy.type === 'hash') {
516
+ result.partitions = Array.isArray(partitionBy.partitions)
517
+ ? partitionBy.partitions.map(name => this.quote(String(name)))
518
+ : partitionBy.partitions;
519
+ }
520
+ else {
521
+ result.partitions = partitionBy.partitions.map(partition => {
522
+ const entry = {};
523
+ if (partition.name) {
524
+ entry.name = this.quote(partition.name);
525
+ }
526
+ entry.values = this.quote(partition.values);
527
+ return entry;
528
+ });
529
+ }
530
+ return result;
531
+ }
486
532
  getEmbeddableDeclOptions() {
487
533
  const options = {};
488
534
  const result = this.getCollectionDecl(options);
@@ -615,6 +661,9 @@ export class SourceFile {
615
661
  if (typeof prop.comment === 'string') {
616
662
  options.comment = this.quote(prop.comment);
617
663
  }
664
+ if (typeof prop.collation === 'string') {
665
+ options.collation = this.quote(prop.collation);
666
+ }
618
667
  // TODO: Composite FKs with default values require additions to default/defaultRaw that are not yet supported.
619
668
  if (prop.fieldNames?.length <= 1) {
620
669
  if (typeof prop.defaultRaw !== 'undefined' &&
@@ -708,7 +757,9 @@ export class SourceFile {
708
757
  }
709
758
  if (prop.enum) {
710
759
  if (this.options.enumMode === 'union-type') {
711
- options.items = `[${prop.items.map(item => this.quote(item)).join(', ')}]`;
760
+ const items = prop.items;
761
+ const allNumeric = items.length > 0 && items.every(item => /^-?\d+$/.test(item));
762
+ options.items = `[${items.map(item => (allNumeric ? item : this.quote(item))).join(', ')}]`;
712
763
  }
713
764
  else if (prop.nativeEnumName) {
714
765
  const enumClassName = this.namingStrategy.getEnumClassName(prop.nativeEnumName, undefined, this.meta.schema);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikro-orm/entity-generator",
3
- "version": "7.1.0-dev.3",
3
+ "version": "7.1.0-dev.31",
4
4
  "description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
5
5
  "keywords": [
6
6
  "data-mapper",
@@ -47,13 +47,13 @@
47
47
  "copy": "node ../../scripts/copy.mjs"
48
48
  },
49
49
  "dependencies": {
50
- "@mikro-orm/sql": "7.1.0-dev.3"
50
+ "@mikro-orm/sql": "7.1.0-dev.31"
51
51
  },
52
52
  "devDependencies": {
53
- "@mikro-orm/core": "^7.0.11"
53
+ "@mikro-orm/core": "^7.0.15"
54
54
  },
55
55
  "peerDependencies": {
56
- "@mikro-orm/core": "7.1.0-dev.3"
56
+ "@mikro-orm/core": "7.1.0-dev.31"
57
57
  },
58
58
  "engines": {
59
59
  "node": ">= 22.17.0"