@dudousxd/nestjs-codegen 0.23.0 → 0.24.0

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.
@@ -1,2 +1,2 @@
1
- export { m as ApiClientLayer, n as ApiHeaderContribution, o as ApiModuleDeps, C as CodegenExtension, p as EmittedFile, E as ExtensionContext, L as LeafModel, q as RequestModel, s as RequestShape, t as defineExtension, u as requestShape } from '../index-BsptKWwz.cjs';
1
+ export { m as ApiClientLayer, n as ApiHeaderContribution, o as ApiModuleDeps, C as CodegenExtension, p as EmittedFile, E as ExtensionContext, L as LeafModel, q as RequestModel, s as RequestShape, t as defineExtension, u as requestShape } from '../index-Ce3YnfwS.cjs';
2
2
  import 'ts-morph';
@@ -1,2 +1,2 @@
1
- export { m as ApiClientLayer, n as ApiHeaderContribution, o as ApiModuleDeps, C as CodegenExtension, p as EmittedFile, E as ExtensionContext, L as LeafModel, q as RequestModel, s as RequestShape, t as defineExtension, u as requestShape } from '../index-BsptKWwz.js';
1
+ export { m as ApiClientLayer, n as ApiHeaderContribution, o as ApiModuleDeps, C as CodegenExtension, p as EmittedFile, E as ExtensionContext, L as LeafModel, q as RequestModel, s as RequestShape, t as defineExtension, u as requestShape } from '../index-Ce3YnfwS.js';
2
2
  import 'ts-morph';
@@ -430,7 +430,26 @@ type FieldTypeKind = 'string' | 'number' | 'boolean' | 'date' | 'json' | 'unknow
430
430
  interface FilterFieldType {
431
431
  /** Field name, e.g. 'age' or 'tasks.id' (dot-notation for relations). */
432
432
  name: string;
433
+ /**
434
+ * What the COLUMN is — the semantics an operator set is derived from. A DATE
435
+ * column is `date` here even when its value arrives as a string.
436
+ */
433
437
  kind: FieldTypeKind;
438
+ /**
439
+ * What the VALUE is, when that differs from {@link kind}.
440
+ *
441
+ * A mapped column declares two things that can both be true and disagree:
442
+ * `@Property({ columnType: 'date', type: DateType }) x?: Opt<string>` is a
443
+ * DATE column whose JS value is `'YYYY-MM-DD'`. Collapsing them loses one or
444
+ * the other — answer `string` and the field stops accepting the ordering and
445
+ * range operators the column supports; answer `date` and the emitted type
446
+ * promises a `Date` the value never holds, which a type-preserving wire
447
+ * format like superjson then contradicts at runtime.
448
+ *
449
+ * So the two travel separately: `kind` gates operators, this types the value.
450
+ * Absent when they agree, which is the overwhelming majority of columns.
451
+ */
452
+ valueKind?: FieldTypeKind;
434
453
  /** String/number-literal union members (enums), if any. */
435
454
  enumValues?: string[];
436
455
  /** Whether the field's TS type includes null/undefined. */
@@ -430,7 +430,26 @@ type FieldTypeKind = 'string' | 'number' | 'boolean' | 'date' | 'json' | 'unknow
430
430
  interface FilterFieldType {
431
431
  /** Field name, e.g. 'age' or 'tasks.id' (dot-notation for relations). */
432
432
  name: string;
433
+ /**
434
+ * What the COLUMN is — the semantics an operator set is derived from. A DATE
435
+ * column is `date` here even when its value arrives as a string.
436
+ */
433
437
  kind: FieldTypeKind;
438
+ /**
439
+ * What the VALUE is, when that differs from {@link kind}.
440
+ *
441
+ * A mapped column declares two things that can both be true and disagree:
442
+ * `@Property({ columnType: 'date', type: DateType }) x?: Opt<string>` is a
443
+ * DATE column whose JS value is `'YYYY-MM-DD'`. Collapsing them loses one or
444
+ * the other — answer `string` and the field stops accepting the ordering and
445
+ * range operators the column supports; answer `date` and the emitted type
446
+ * promises a `Date` the value never holds, which a type-preserving wire
447
+ * format like superjson then contradicts at runtime.
448
+ *
449
+ * So the two travel separately: `kind` gates operators, this types the value.
450
+ * Absent when they agree, which is the overwhelming majority of columns.
451
+ */
452
+ valueKind?: FieldTypeKind;
434
453
  /** String/number-literal union members (enums), if any. */
435
454
  enumValues?: string[];
436
455
  /** Whether the field's TS type includes null/undefined. */
package/dist/index.cjs CHANGED
@@ -1535,12 +1535,19 @@ function classifyFromColumnDecorator(prop, sourceFile, project) {
1535
1535
  return { kind: "string" };
1536
1536
  }
1537
1537
  }
1538
- const typeProp = arg.getProperty("type");
1539
- if (typeProp && import_ts_morph4.Node.isPropertyAssignment(typeProp)) {
1538
+ for (const key of ["columnType", "type"]) {
1539
+ const typeProp = arg.getProperty(key);
1540
+ if (!typeProp || !import_ts_morph4.Node.isPropertyAssignment(typeProp)) continue;
1540
1541
  const init = typeProp.getInitializer();
1541
- if (init && import_ts_morph4.Node.isStringLiteral(init)) {
1542
+ if (!init) continue;
1543
+ if (import_ts_morph4.Node.isStringLiteral(init)) {
1542
1544
  const kind = classifyTypeKeyword(init.getLiteralValue());
1543
1545
  if (kind) return { kind };
1546
+ continue;
1547
+ }
1548
+ if (import_ts_morph4.Node.isIdentifier(init)) {
1549
+ const kind = classifyTypeKeyword(init.getText());
1550
+ if (kind) return { kind };
1544
1551
  }
1545
1552
  }
1546
1553
  }
@@ -1552,12 +1559,18 @@ function classifyFromColumnDecorator(prop, sourceFile, project) {
1552
1559
  function classifyFieldType(prop, sourceFile, project) {
1553
1560
  let nullable = prop.hasQuestionToken();
1554
1561
  const typeNode = prop.getTypeNode();
1562
+ const fromDecorator = classifyFromColumnDecorator(prop, sourceFile, project);
1555
1563
  if (typeNode) {
1556
1564
  const r = classifyTypeNode(typeNode, sourceFile, project);
1557
1565
  if (r.nullable) nullable = true;
1558
- if (r.kind !== "unknown") return markNullable(r, nullable);
1566
+ if (r.kind !== "unknown") {
1567
+ const conflicts = fromDecorator !== null && fromDecorator.kind !== "unknown" && fromDecorator.kind !== r.kind;
1568
+ if (conflicts) {
1569
+ return markNullable({ ...fromDecorator, valueKind: r.kind }, nullable);
1570
+ }
1571
+ return markNullable(r, nullable);
1572
+ }
1559
1573
  }
1560
- const fromDecorator = classifyFromColumnDecorator(prop, sourceFile, project);
1561
1574
  if (fromDecorator) {
1562
1575
  return markNullable(fromDecorator, nullable || fromDecorator.nullable === true);
1563
1576
  }
@@ -1565,6 +1578,7 @@ function classifyFieldType(prop, sourceFile, project) {
1565
1578
  }
1566
1579
  function toFilterFieldType(name, r) {
1567
1580
  const ft = { name, kind: r.kind };
1581
+ if (r.valueKind && r.valueKind !== r.kind) ft.valueKind = r.valueKind;
1568
1582
  if (r.enumValues && r.enumValues.length > 0) ft.enumValues = r.enumValues;
1569
1583
  if (r.nullable) ft.nullable = true;
1570
1584
  if (r.numericEnum) ft.numericEnum = true;
@@ -3370,7 +3384,7 @@ function kindToTs(kind, enumValues, numericEnum) {
3370
3384
  }
3371
3385
  function emitFieldTypesLiteral(fts) {
3372
3386
  const entries = fts.map((f) => {
3373
- let t = f.typeRef ? f.typeRef.name : kindToTs(f.kind, f.enumValues, f.numericEnum);
3387
+ let t = f.typeRef ? f.typeRef.name : kindToTs(f.valueKind ?? f.kind, f.enumValues, f.numericEnum);
3374
3388
  if (f.nullable) t = `${t} | null`;
3375
3389
  return `${JSON.stringify(f.name)}: ${t}`;
3376
3390
  });
@@ -5377,7 +5391,7 @@ function createChainModuleRenderer(opts) {
5377
5391
  }
5378
5392
 
5379
5393
  // src/index.ts
5380
- var VERSION = "0.23.0";
5394
+ var VERSION = "0.24.0";
5381
5395
  // Annotate the CommonJS export names for ESM import in node:
5382
5396
  0 && (module.exports = {
5383
5397
  CodegenError,