@zdavison/nestjs-rpc-toolkit 0.1.3 → 0.2.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.
@@ -4,4 +4,162 @@
4
4
  * These types help catch non-serializable types at compile time.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.undefinedToNull = undefinedToNull;
8
+ exports.nullToUndefined = nullToUndefined;
9
+ exports.encodeDates = encodeDates;
10
+ exports.decodeDates = decodeDates;
11
+ exports.createDateEncoder = createDateEncoder;
12
+ exports.createDateDecoder = createDateDecoder;
13
+ /**
14
+ * Recursively converts all `undefined` values to `null` in an object.
15
+ * Use this to prepare data for RPC calls where `undefined` is not JSON-serializable.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const input = { name: 'John', age: undefined, meta: { active: undefined } };
20
+ * const rpcReady = undefinedToNull(input);
21
+ * // { name: 'John', age: null, meta: { active: null } }
22
+ *
23
+ * // In RPC controller:
24
+ * await rpc.user.create({ createUserDto: undefinedToNull(dto) });
25
+ * ```
26
+ */
27
+ function undefinedToNull(value) {
28
+ if (value === undefined) {
29
+ return null;
30
+ }
31
+ if (value === null || typeof value !== 'object') {
32
+ return value;
33
+ }
34
+ if (Array.isArray(value)) {
35
+ return value.map(item => undefinedToNull(item));
36
+ }
37
+ const result = {};
38
+ for (const key of Object.keys(value)) {
39
+ const val = value[key];
40
+ result[key] = undefinedToNull(val);
41
+ }
42
+ return result;
43
+ }
44
+ /**
45
+ * Recursively converts all `null` values to `undefined` in an object.
46
+ * Use this to convert RPC response data back to TypeScript-friendly optionals.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const rpcResponse = { name: 'John', age: null, meta: { active: null } };
51
+ * const local = nullToUndefined(rpcResponse);
52
+ * // { name: 'John', age: undefined, meta: { active: undefined } }
53
+ * ```
54
+ */
55
+ function nullToUndefined(value) {
56
+ if (value === null) {
57
+ return undefined;
58
+ }
59
+ if (value === undefined || typeof value !== 'object') {
60
+ return value;
61
+ }
62
+ if (Array.isArray(value)) {
63
+ return value.map(item => nullToUndefined(item));
64
+ }
65
+ const result = {};
66
+ for (const key of Object.keys(value)) {
67
+ const val = value[key];
68
+ result[key] = nullToUndefined(val);
69
+ }
70
+ return result;
71
+ }
72
+ /**
73
+ * Recursively converts all Date instances to ISO strings.
74
+ * Use this to prepare data for RPC transport.
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const user = { name: 'John', createdAt: new Date() };
79
+ * const wire = encodeDates(user);
80
+ * // { name: 'John', createdAt: '2025-01-01T00:00:00.000Z' }
81
+ * ```
82
+ */
83
+ function encodeDates(value) {
84
+ if (value === null || value === undefined) {
85
+ return value;
86
+ }
87
+ if (value instanceof Date) {
88
+ return value.toISOString();
89
+ }
90
+ if (typeof value !== 'object') {
91
+ return value;
92
+ }
93
+ if (Array.isArray(value)) {
94
+ return value.map(item => encodeDates(item));
95
+ }
96
+ const result = {};
97
+ for (const key of Object.keys(value)) {
98
+ result[key] = encodeDates(value[key]);
99
+ }
100
+ return result;
101
+ }
102
+ /**
103
+ * Recursively converts ISO date strings back to Date objects based on metadata.
104
+ * The metadata specifies which fields should be treated as dates.
105
+ *
106
+ * @param value - The value to decode
107
+ * @param metadata - Map of type names to their date field paths
108
+ * @param typeName - The type name to look up in metadata (optional for nested calls)
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * import { RpcDateFields } from './all.rpc.gen';
113
+ *
114
+ * const wire = { name: 'John', createdAt: '2025-01-01T00:00:00.000Z' };
115
+ * const user = decodeDates(wire, RpcDateFields, 'User');
116
+ * // { name: 'John', createdAt: Date }
117
+ * ```
118
+ */
119
+ function decodeDates(value, metadata, typeName) {
120
+ if (value === null || value === undefined) {
121
+ return value;
122
+ }
123
+ if (typeof value !== 'object') {
124
+ return value;
125
+ }
126
+ if (Array.isArray(value)) {
127
+ return value.map(item => decodeDates(item, metadata, typeName));
128
+ }
129
+ // Get date fields for this type
130
+ const dateFields = typeName ? metadata[typeName] : undefined;
131
+ const dateFieldSet = dateFields ? new Set(dateFields) : new Set();
132
+ const result = {};
133
+ for (const key of Object.keys(value)) {
134
+ const val = value[key];
135
+ // Check if this field should be a Date
136
+ if (dateFieldSet.has(key) && typeof val === 'string') {
137
+ result[key] = new Date(val);
138
+ }
139
+ else if (typeof val === 'object' && val !== null) {
140
+ // For nested objects, try to infer the type name from the key
141
+ // This is a heuristic - the key might be the type name in camelCase
142
+ const nestedTypeName = key.charAt(0).toUpperCase() + key.slice(1);
143
+ result[key] = decodeDates(val, metadata, metadata[nestedTypeName] ? nestedTypeName : undefined);
144
+ }
145
+ else {
146
+ result[key] = val;
147
+ }
148
+ }
149
+ return result;
150
+ }
151
+ /**
152
+ * Creates an encoder function bound to specific metadata.
153
+ * Useful when you want to encode dates for a specific type.
154
+ */
155
+ function createDateEncoder() {
156
+ return encodeDates;
157
+ }
158
+ /**
159
+ * Creates a decoder function bound to specific metadata.
160
+ * Useful when you want to decode dates for a specific type.
161
+ */
162
+ function createDateDecoder(metadata) {
163
+ return (value, typeName) => decodeDates(value, metadata, typeName);
164
+ }
7
165
  //# sourceMappingURL=serializable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"serializable.js","sourceRoot":"","sources":["../../src/types/serializable.ts"],"names":[],"mappings":";AAAA;;;GAGG"}
1
+ {"version":3,"file":"serializable.js","sourceRoot":"","sources":["../../src/types/serializable.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AA4EH,0CAmBC;AAaD,0CAmBC;AAoBD,kCAsBC;AAmBD,kCAsCC;AAMD,8CAEC;AAMD,8CAEC;AApLD;;;;;;;;;;;;;GAaG;AACH,SAAgB,eAAe,CAAI,KAAQ;IACzC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,IAA0B,CAAC;IACpC,CAAC;IAED,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,KAA2B,CAAC;IACrC,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAuB,CAAC;IACxE,CAAC;IAED,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,GAAG,GAAI,KAAiC,CAAC,GAAG,CAAC,CAAC;QACpD,MAAM,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,MAA4B,CAAC;AACtC,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,eAAe,CAAI,KAAQ;IACzC,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,SAA+B,CAAC;IACzC,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrD,OAAO,KAA2B,CAAC;IACrC,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAuB,CAAC;IACxE,CAAC;IAED,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,GAAG,GAAI,KAAiC,CAAC,GAAG,CAAC,CAAC;QACpD,MAAM,CAAC,GAAG,CAAC,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,MAA4B,CAAC;AACtC,CAAC;AASD;;;;;;;;;;GAUG;AACH,SAAgB,WAAW,CAAI,KAAQ;IACrC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC1B,OAAO,KAAK,CAAC,WAAW,EAAkB,CAAC;IAC7C,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAiB,CAAC;IAC9D,CAAC;IAED,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,GAAG,WAAW,CAAE,KAAiC,CAAC,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,MAAW,CAAC;AACrB,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,WAAW,CACzB,KAAQ,EACR,QAA4B,EAC5B,QAAiB;IAEjB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAiB,CAAC;IAClF,CAAC;IAED,gCAAgC;IAChC,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAU,CAAC;IAE1E,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,GAAG,GAAI,KAAiC,CAAC,GAAG,CAAC,CAAC;QAEpD,uCAAuC;QACvC,IAAI,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YACrD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC;aAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACnD,8DAA8D;YAC9D,oEAAoE;YACpE,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAClE,MAAM,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAClG,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,MAAW,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,SAAgB,iBAAiB;IAC/B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,QAA4B;IAC5D,OAAO,CAAI,KAAQ,EAAE,QAAiB,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACpF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zdavison/nestjs-rpc-toolkit",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "Toolkit for type-safe RPC calls in NestJS monorepos.",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
@@ -11,6 +11,11 @@
11
11
  "bin": {
12
12
  "bootstrap": "dist/bin/bootstrap.js"
13
13
  },
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "clean": "rm -rf dist",
17
+ "dev": "tsc --watch"
18
+ },
14
19
  "dependencies": {
15
20
  "glob": "^10.0.0",
16
21
  "rxjs": "^7.8.0",
@@ -33,10 +38,5 @@
33
38
  "@nestjs/common": "^11.0.0",
34
39
  "@nestjs/microservices": "^11.0.0",
35
40
  "reflect-metadata": "^0.1.13 || ^0.2.0"
36
- },
37
- "scripts": {
38
- "build": "tsc",
39
- "clean": "rm -rf dist",
40
- "dev": "tsc --watch"
41
41
  }
42
- }
42
+ }
@@ -1,7 +0,0 @@
1
- /**
2
- * Detects the package manager being used in the project
3
- * @param rootDir The root directory of the project
4
- * @returns The package manager name (pnpm, npm, yarn, or bun)
5
- */
6
- export declare function detectPackageManager(rootDir: string): string;
7
- //# sourceMappingURL=package-manager.utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"package-manager.utils.d.ts","sourceRoot":"","sources":["../../src/utils/package-manager.utils.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAkC5D"}
@@ -1,78 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.detectPackageManager = detectPackageManager;
37
- const fs = __importStar(require("fs"));
38
- const path = __importStar(require("path"));
39
- /**
40
- * Detects the package manager being used in the project
41
- * @param rootDir The root directory of the project
42
- * @returns The package manager name (pnpm, npm, yarn, or bun)
43
- */
44
- function detectPackageManager(rootDir) {
45
- // Check for packageManager field in root package.json
46
- const rootPackageJsonPath = path.join(rootDir, 'package.json');
47
- if (fs.existsSync(rootPackageJsonPath)) {
48
- try {
49
- const rootPackageJson = JSON.parse(fs.readFileSync(rootPackageJsonPath, 'utf-8'));
50
- if (rootPackageJson.packageManager) {
51
- // Format: "pnpm@8.0.0" or "npm@9.0.0" or "bun@1.0.0"
52
- const pm = rootPackageJson.packageManager.split('@')[0];
53
- if (['pnpm', 'npm', 'yarn', 'bun'].includes(pm)) {
54
- return pm;
55
- }
56
- }
57
- }
58
- catch (error) {
59
- // Ignore and fall back to lock file detection
60
- }
61
- }
62
- // Check for lock files in order of preference
63
- if (fs.existsSync(path.join(rootDir, 'pnpm-lock.yaml'))) {
64
- return 'pnpm';
65
- }
66
- if (fs.existsSync(path.join(rootDir, 'bun.lockb'))) {
67
- return 'bun';
68
- }
69
- if (fs.existsSync(path.join(rootDir, 'yarn.lock'))) {
70
- return 'yarn';
71
- }
72
- if (fs.existsSync(path.join(rootDir, 'package-lock.json'))) {
73
- return 'npm';
74
- }
75
- // Default to npm if nothing detected
76
- return 'npm';
77
- }
78
- //# sourceMappingURL=package-manager.utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"package-manager.utils.js","sourceRoot":"","sources":["../../src/utils/package-manager.utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,oDAkCC;AA1CD,uCAAyB;AACzB,2CAA6B;AAE7B;;;;GAIG;AACH,SAAgB,oBAAoB,CAAC,OAAe;IAClD,sDAAsD;IACtD,MAAM,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAC/D,IAAI,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC,CAAC;YAClF,IAAI,eAAe,CAAC,cAAc,EAAE,CAAC;gBACnC,qDAAqD;gBACrD,MAAM,EAAE,GAAG,eAAe,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxD,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;oBAChD,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,8CAA8C;QAChD,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC;QACxD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QACnD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QACnD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC;QAC3D,OAAO,KAAK,CAAC;IACf,CAAC;IAED,qCAAqC;IACrC,OAAO,KAAK,CAAC;AACf,CAAC"}