@dudousxd/nestjs-codegen 0.6.1 → 0.7.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,17 @@
1
1
  # @dudousxd/nestjs-codegen
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ff8ad8b: Jsonify-by-default serialized response types, with an opt-out `serialization` config option.
8
+
9
+ The generated `api.ts` now reflects the **JSON wire shape** of each route's response rather than the in-process server return type. A controller returning `{ createdAt: Date }` now generates `response: Jsonify<{ createdAt: string }>` — because `Date.prototype.toJSON()` emits an ISO string. `Jsonify<T>` recurses arrays/objects, follows any `toJSON()` holder to its returned shape, drops non-serializable properties (functions/symbols), keeps optional properties optional, and passes `any`/`unknown` through untouched. It is a hand-rolled, type-only utility with no runtime footprint.
10
+
11
+ - **`@dudousxd/nestjs-client`** exports the new `Jsonify<T>` type.
12
+ - **`@dudousxd/nestjs-codegen`** wraps each route `response` field in `Jsonify<...>` by default and emits `import type { Jsonify } from '<runtime>'` (tracking `fetcher.importPath`) when at least one route is wrapped. Only the `response` field is wrapped — never `error`, `body`, or `query`.
13
+ - New config option `serialization?: 'json' | 'superjson'` (default `'json'`). In `'superjson'` mode the raw controller return type is emitted unchanged (Dates/Maps/Sets are revived on the client), and no `Jsonify` import is emitted.
14
+
3
15
  ## 0.6.1
4
16
 
5
17
  ### Patch Changes
package/dist/cli/main.cjs CHANGED
@@ -156,6 +156,7 @@ function applyDefaults(userConfig, cwd) {
156
156
  },
157
157
  app,
158
158
  fetcher: userConfig.fetcher ?? null,
159
+ serialization: userConfig.serialization ?? "json",
159
160
  forms: {
160
161
  enabled: userConfig.forms?.enabled ?? true,
161
162
  watch: userConfig.forms?.watch ?? "src/**/*.dto.ts",
@@ -739,7 +740,11 @@ function emitFilterQueryTypeArgs(c) {
739
740
  function emitFilterQueryType(c) {
740
741
  return `import('@dudousxd/nestjs-filter-client').TypedFilterQuery<${emitFilterQueryTypeArgs(c)}>`;
741
742
  }
742
- function buildResponseType(c, outDir) {
743
+ function buildResponseType(c, outDir, serialization) {
744
+ const raw = rawResponseType(c, outDir);
745
+ return serialization === "json" ? `Jsonify<${raw}>` : raw;
746
+ }
747
+ function rawResponseType(c, outDir) {
743
748
  const respRef = c.contractSource.responseRef;
744
749
  if (c.contractSource.stream) {
745
750
  if (respRef) return respRef.isArray ? `Array<${respRef.name}>` : respRef.name;
@@ -762,7 +767,7 @@ function buildErrorType(c) {
762
767
  }
763
768
  return c.contractSource.error ?? "unknown";
764
769
  }
765
- function emitRouterTypeBlock(tree, indent, outDir) {
770
+ function emitRouterTypeBlock(tree, indent, outDir, serialization) {
766
771
  const pad = " ".repeat(indent);
767
772
  const lines = [];
768
773
  for (const [key, node] of tree) {
@@ -775,7 +780,7 @@ function emitRouterTypeBlock(tree, indent, outDir) {
775
780
  const query = queryRef ? queryRef.isArray ? `Array<${queryRef.name}>` : queryRef.name : isFilterQuery ? emitFilterQueryType(c) : c.contractSource.query ?? "never";
776
781
  const bodyRef = c.contractSource.bodyRef;
777
782
  const body = method === "GET" ? "never" : bodyRef ? bodyRef.isArray ? `Array<${bodyRef.name}>` : bodyRef.name : c.contractSource.body ?? "never";
778
- const response = buildResponseType(c, outDir);
783
+ const response = buildResponseType(c, outDir, serialization);
779
784
  const error = buildErrorType(c);
780
785
  const params = buildParamsType(c.params);
781
786
  const safeMethod = JSON.stringify(method);
@@ -787,7 +792,7 @@ function emitRouterTypeBlock(tree, indent, outDir) {
787
792
  );
788
793
  } else {
789
794
  lines.push(`${pad}${objKey}: {`);
790
- lines.push(...emitRouterTypeBlock(node.children, indent + 2, outDir));
795
+ lines.push(...emitRouterTypeBlock(node.children, indent + 2, outDir, serialization));
791
796
  lines.push(`${pad}};`);
792
797
  }
793
798
  }
@@ -992,6 +997,7 @@ var EMPTY_PATH_NAMESPACE = [
992
997
  ];
993
998
  function buildApiFile(routes, outDir, opts = {}) {
994
999
  const fetcherImportPath = opts.fetcherImportPath;
1000
+ const serialization = opts.serialization ?? "json";
995
1001
  const extensions = opts.extensions ?? [];
996
1002
  const { layer } = resolveApiSlots(extensions);
997
1003
  const memberExts = extensions.filter((e) => e.apiMembers);
@@ -1048,6 +1054,9 @@ function buildApiFile(routes, outDir, opts = {}) {
1048
1054
  );
1049
1055
  const runtimeImport = fetcherImportPath ?? "@dudousxd/nestjs-client";
1050
1056
  lines.push(`import type { Fetcher } from '${runtimeImport}';`);
1057
+ if (serialization === "json" && contracted.length > 0) {
1058
+ lines.push(`import type { Jsonify } from '${runtimeImport}';`);
1059
+ }
1051
1060
  if (importsByFile.size > 0 && outDir) {
1052
1061
  lines.push("");
1053
1062
  const emittedNames = /* @__PURE__ */ new Set();
@@ -1107,7 +1116,7 @@ function buildApiFile(routes, outDir, opts = {}) {
1107
1116
  insertIntoTree(tree, segments, leaf, name);
1108
1117
  }
1109
1118
  lines.push("export type ApiRouter = {");
1110
- lines.push(...emitRouterTypeBlock(tree, 2, outDir ?? ""));
1119
+ lines.push(...emitRouterTypeBlock(tree, 2, outDir ?? "", serialization));
1111
1120
  lines.push("};");
1112
1121
  lines.push("");
1113
1122
  lines.push(...emitReqHelper());
@@ -2125,6 +2134,7 @@ async function generate(config, inputRoutes = []) {
2125
2134
  if (hasContracts) {
2126
2135
  await emitApi(routes, config.codegen.outDir, {
2127
2136
  ...config.fetcher?.importPath ? { fetcherImportPath: config.fetcher.importPath } : {},
2137
+ serialization: config.serialization,
2128
2138
  extensions,
2129
2139
  ctx
2130
2140
  });
@@ -4466,7 +4476,7 @@ async function watch(config, onChange) {
4466
4476
  }
4467
4477
 
4468
4478
  // src/index.ts
4469
- var VERSION = "0.6.1";
4479
+ var VERSION = "0.7.0";
4470
4480
 
4471
4481
  // src/cli/codegen.ts
4472
4482
  async function runCodegen(opts = {}) {