@dudousxd/nestjs-codegen 0.22.0 → 0.23.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @dudousxd/nestjs-codegen
2
2
 
3
+ ## 0.23.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 4b13eef: Classify through transparent type brands, so a MikroORM entity's columns stop coming back `unknown`.
8
+
9
+ `Opt<T>` is how MikroORM marks a column optional on insert, and it is how nearly every nullable column in a MikroORM entity is written. It is a compile-time marker with no runtime shape of its own — an `Opt<string>` column holds a string — but the classifier saw a type reference it did not recognise and answered `unknown`. On a real entity that meant 31 of 35 fields unclassified, including plain `Opt<string>` names; the four that worked were the two written as bare primitives and the two written `Date & Opt<Date>`, where the intersection happens to expose a type the classifier already knew.
10
+
11
+ That is not a cosmetic gap. `unknown` is indistinguishable from "the classifier could not tell", so every consumer that reads a kind — operator sets, a number/date gate, a UI picking a filter control from the column's type — has to fall back to permissive for an entity that had in fact declared its types perfectly well.
12
+
13
+ `Opt<T>` and `Hidden<T>` are now unwrapped to their argument, recursively, so `Opt<Hidden<number>>` is a number.
14
+
15
+ Deliberately a short allowlist rather than "unwrap any single-argument reference". `Ref<T>`, `Rel<T>`, `Collection<T>` and `IdentifiedReference<T>` are **not** transparent: their runtime value is a reference or a collection, not a `T`. Unwrapping those would classify a relation as whatever its target's shape happens to be — silently, and only visibly far downstream.
16
+
17
+ ## 0.22.1
18
+
19
+ ### Patch Changes
20
+
21
+ - da8ec39: Order routes by file path, so an unchanged source tree always generates the same client
22
+
23
+ Route order decided the order of everything emitted from it — the groups in
24
+ `api.ts`, the entries in `routes.ts` — and it was whatever order discovery
25
+ happened to reach the files in. The cold path adds controllers in `fast-glob`'s
26
+ directory-walk order, which is I/O-completion order from a concurrent walk: it
27
+ holds while the FS cache is warm and can differ on a cold one, so regenerating
28
+ an untouched project could move a controller group to a different position. The
29
+ watcher appended each newly-created controller to the end of its set, so from
30
+ the moment a file was added its output no longer matched a cold run's, for the
31
+ rest of the session.
32
+
33
+ Both extraction entry points now sort their roots by path. `discoverPages` has
34
+ sorted its glob from the start, which is why only the controller-derived
35
+ artifacts ever moved.
36
+
37
+ Nothing about the generated client changes except the order of its blocks —
38
+ same routes, same types, same members. Consumers who commit their generated
39
+ directory should expect one reorder-only diff on the first run after upgrading.
40
+
3
41
  ## 0.22.0
4
42
 
5
43
  ### Minor Changes
package/dist/cli/main.cjs CHANGED
@@ -1369,6 +1369,7 @@ function classifyTypeKeyword(raw) {
1369
1369
  function markNullable(r, nullable) {
1370
1370
  return nullable ? { ...r, nullable: true } : r;
1371
1371
  }
1372
+ var TRANSPARENT_TYPE_BRANDS = /* @__PURE__ */ new Set(["Opt", "Hidden"]);
1372
1373
  function classifyTypeNode(typeNode, sourceFile, project, opts) {
1373
1374
  if (import_ts_morph4.Node.isUnionTypeNode(typeNode)) {
1374
1375
  let nullable = false;
@@ -1427,6 +1428,11 @@ function classifyTypeNode(typeNode, sourceFile, project, opts) {
1427
1428
  const refName = typeNode.getTypeName().getText();
1428
1429
  if (refName === "Date") return { kind: "date" };
1429
1430
  if (refName === "Record" || refName === "Object") return { kind: "json" };
1431
+ const unwrapped = TRANSPARENT_TYPE_BRANDS.has(refName) ? typeNode.getTypeArguments()[0] : void 0;
1432
+ if (unwrapped) {
1433
+ const inner = classifyTypeNode(unwrapped, sourceFile, project, opts);
1434
+ return inner;
1435
+ }
1430
1436
  const typeRef = opts?.resolveRef?.(refName) ?? null;
1431
1437
  const en = resolveEnumValues(refName, sourceFile, project);
1432
1438
  if (en) {
@@ -2754,7 +2760,7 @@ function bindDiscoveryContext(project, cwd, tsconfigPath, tsconfig = loadDiscove
2754
2760
  }
2755
2761
  function extractRoutesFrom(project, controllerPaths) {
2756
2762
  const routes = [];
2757
- for (const path of controllerPaths) {
2763
+ for (const path of byPath([...controllerPaths])) {
2758
2764
  const sourceFile = project.getSourceFile(path);
2759
2765
  if (sourceFile) routes.push(...extractFromSourceFile(sourceFile, project));
2760
2766
  }
@@ -2762,11 +2768,17 @@ function extractRoutesFrom(project, controllerPaths) {
2762
2768
  }
2763
2769
  function extractAllRoutes(project) {
2764
2770
  const routes = [];
2765
- for (const sourceFile of project.getSourceFiles()) {
2771
+ for (const sourceFile of byPath(project.getSourceFiles(), (f) => f.getFilePath())) {
2766
2772
  routes.push(...extractFromSourceFile(sourceFile, project));
2767
2773
  }
2768
2774
  return routes;
2769
2775
  }
2776
+ function byPath(items, path = String) {
2777
+ return [...items].sort((a, b) => {
2778
+ const [x, y] = [path(a), path(b)];
2779
+ return x < y ? -1 : x > y ? 1 : 0;
2780
+ });
2781
+ }
2770
2782
  var PersistentDiscovery = class _PersistentDiscovery {
2771
2783
  project;
2772
2784
  cwd;
@@ -5247,7 +5259,7 @@ async function watch(config, onChange, options = {}) {
5247
5259
  }
5248
5260
 
5249
5261
  // src/index.ts
5250
- var VERSION = "0.22.0";
5262
+ var VERSION = "0.23.0";
5251
5263
 
5252
5264
  // src/cli/codegen.ts
5253
5265
  async function runCodegen(opts = {}) {