@orpc/nest 2.0.0-beta.24 → 2.0.0-beta.26

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.
Files changed (2) hide show
  1. package/dist/index.mjs +66 -40
  2. package/package.json +7 -6
package/dist/index.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  import { Readable } from 'node:stream';
2
- import { Module, applyDecorators, Options, Delete, Patch, Put, Post, Get, Head, HttpCode, UseInterceptors, StreamableFile, HttpException, Injectable, Inject, Optional } from '@nestjs/common';
2
+ import { Module, applyDecorators, UseInterceptors, StreamableFile, HttpException, Options, Delete, Patch, Put, Post, Get, Head, HttpCode, Injectable, Inject, Optional } from '@nestjs/common';
3
3
  import { HttpAdapterHost } from '@nestjs/core';
4
4
  import { ProcedureContract, getPathMeta } from '@orpc/contract';
5
5
  import { getOpenAPIMeta, DEFAULT_OPENAPI_METHOD, getDynamicPathParams } from '@orpc/openapi';
6
6
  import { OpenAPIHandlerCodecCore } from '@orpc/openapi/standard';
7
- import { DEFAULT_SUCCESS_STATUS, getRouter, unlazy, Procedure } from '@orpc/server';
7
+ import { unlazy, Procedure, DEFAULT_SUCCESS_STATUS, getRouter } from '@orpc/server';
8
8
  import { StandardHandler } from '@orpc/server/standard';
9
- import { mergeHttpPath, value, isAsyncIteratorObject, stringifyJSON } from '@orpc/shared';
9
+ import { value, isAsyncIteratorObject, stringifyJSON, mergeHttpPath, NullProtoObj } from '@orpc/shared';
10
10
  import { flattenStandardHeader, generateContentDisposition } from '@standardserver/core';
11
11
  import { toStandardLazyRequest, toEventStream } from '@standardserver/node';
12
12
  import { mergeMap } from 'rxjs';
@@ -76,45 +76,66 @@ const MethodDecoratorMap = {
76
76
  };
77
77
  function Implement(contract) {
78
78
  if (contract instanceof ProcedureContract) {
79
- const meta = getOpenAPIMeta(contract);
80
- if (meta?.path === void 0) {
81
- throw new TypeError(`
82
- @Implement decorator requires contract to have a 'openapi.path' meta.
83
- Please define one using '.meta(openapi({ path: '/example' }))'.
84
- Or use "populateRouterContractOpenAPIPaths" from "@orpc/openapi" utility to automatically fill in any missing paths.
85
- `);
86
- }
87
- const method = meta.method ?? DEFAULT_OPENAPI_METHOD;
88
- const path = toNestPattern(meta.prefix ? mergeHttpPath(meta.prefix, meta.path) : meta.path);
89
- const successStatus = meta.successStatus ?? DEFAULT_SUCCESS_STATUS;
90
79
  return (target, propertyKey, descriptor) => {
91
80
  applyDecorators(
92
- MethodDecoratorMap[method](path),
93
- HttpCode(successStatus),
81
+ toNestRouteDecorator(contract),
94
82
  UseInterceptors(ImplementInterceptor)
95
83
  )(target, propertyKey, descriptor);
96
84
  };
97
85
  }
98
86
  return (target, propertyKey, descriptor) => {
99
- for (const key in contract) {
100
- let methodName = `${propertyKey}_${key}`;
101
- let i = 0;
102
- while (methodName in target) {
103
- methodName = `${propertyKey}_${key}_${i++}`;
104
- }
105
- target[methodName] = async function(...args) {
106
- const router = await descriptor.value.apply(this, args);
107
- return getRouter(router, [key]);
108
- };
87
+ UseInterceptors(ImplementInterceptor)(target, propertyKey, descriptor);
88
+ implementRouterContract(contract, target, propertyKey, descriptor);
89
+ };
90
+ }
91
+ function toNestRouteDecorator(contract) {
92
+ const meta = getOpenAPIMeta(contract);
93
+ if (meta?.path === void 0) {
94
+ throw new TypeError(`
95
+ @Implement decorator requires contract to have a 'openapi.path' meta.
96
+ Please define one using '.meta(openapi({ path: '/example' }))'.
97
+ Or use "populateRouterContractOpenAPIPaths" from "@orpc/openapi" utility to automatically fill in any missing paths.
98
+ `);
99
+ }
100
+ const method = meta.method ?? DEFAULT_OPENAPI_METHOD;
101
+ const path = toNestPattern(meta.prefix ? mergeHttpPath(meta.prefix, meta.path) : meta.path);
102
+ const successStatus = meta.successStatus ?? DEFAULT_SUCCESS_STATUS;
103
+ return applyDecorators(
104
+ MethodDecoratorMap[method](path),
105
+ HttpCode(successStatus)
106
+ );
107
+ }
108
+ function implementRouterContract(contract, target, propertyKey, descriptor) {
109
+ for (const key in contract) {
110
+ let methodName = `${propertyKey}_${key}`;
111
+ let i = 0;
112
+ while (methodName in target) {
113
+ methodName = `${propertyKey}_${key}_${i++}`;
114
+ }
115
+ target[methodName] = async function(...args) {
116
+ const router = await descriptor.value.apply(this, args);
117
+ return getRouter(router, [key]);
118
+ };
119
+ Object.setPrototypeOf(target[methodName], descriptor.value);
120
+ queueMicrotask(() => {
109
121
  for (const p of Reflect.getOwnMetadataKeys(target, propertyKey)) {
110
122
  Reflect.defineMetadata(p, Reflect.getOwnMetadata(p, target, propertyKey), target, methodName);
111
123
  }
112
124
  for (const p of Reflect.getOwnMetadataKeys(target.constructor, propertyKey)) {
113
125
  Reflect.defineMetadata(p, Reflect.getOwnMetadata(p, target.constructor, propertyKey), target.constructor, methodName);
114
126
  }
115
- Implement(contract[key])(target, methodName, Object.getOwnPropertyDescriptor(target, methodName));
127
+ });
128
+ const childContract = contract[key];
129
+ const childDescriptor = Object.getOwnPropertyDescriptor(target, methodName);
130
+ if (childContract instanceof ProcedureContract) {
131
+ const routeDecorator = toNestRouteDecorator(childContract);
132
+ queueMicrotask(() => {
133
+ routeDecorator(target, methodName, childDescriptor);
134
+ });
135
+ } else {
136
+ implementRouterContract(childContract, target, methodName, childDescriptor);
116
137
  }
117
- };
138
+ }
118
139
  }
119
140
  let ImplementInterceptor = class {
120
141
  config;
@@ -239,21 +260,26 @@ function flattenParamValue(value2) {
239
260
  }
240
261
  function toORPCOpenAPIParams(contract, params) {
241
262
  const meta = getOpenAPIMeta(contract);
242
- if (!params || meta?.path === void 0) {
243
- return void 0;
244
- }
245
- const dynamicParams = getDynamicPathParams(meta.prefix ? mergeHttpPath(meta.prefix, meta.path) : meta.path);
246
- if (!dynamicParams) {
263
+ if (!params || meta?.path === void 0 || Object.keys(params).length === 0) {
247
264
  return void 0;
248
265
  }
249
- return dynamicParams.reduce((acc, config) => {
250
- const value2 = config.allowsSlash ? flattenParamValue(params?.["*"] ?? params?.path) : flattenParamValue(params?.[config.parameterName]);
251
- if (value2 === void 0) {
252
- return acc;
266
+ const orpcParams = new NullProtoObj();
267
+ const restKey = Object.hasOwn(params, "*") ? "*" : "path";
268
+ for (const [key, value2] of Object.entries(params)) {
269
+ if (key === restKey) {
270
+ const restParams = getDynamicPathParams(
271
+ meta.prefix ? mergeHttpPath(meta.prefix, meta.path) : meta.path
272
+ )?.filter((c) => c.allowsSlash);
273
+ if (restParams?.length) {
274
+ for (const c of restParams) {
275
+ orpcParams[c.parameterName] = flattenParamValue(value2);
276
+ }
277
+ continue;
278
+ }
253
279
  }
254
- acc[config.parameterName] = value2;
255
- return acc;
256
- }, {});
280
+ orpcParams[key] = flattenParamValue(value2);
281
+ }
282
+ return orpcParams;
257
283
  }
258
284
  function toNestPattern(path) {
259
285
  const params = getDynamicPathParams(path);
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@orpc/nest",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.24",
4
+ "version": "2.0.0-beta.26",
5
5
  "license": "MIT",
6
+ "funding": "https://github.com/sponsors/dinwwwh",
6
7
  "homepage": "https://orpc.dev",
7
8
  "repository": {
8
9
  "type": "git",
@@ -39,11 +40,11 @@
39
40
  "dependencies": {
40
41
  "@standardserver/core": "^0.7.1",
41
42
  "@standardserver/node": "^0.7.1",
42
- "@orpc/contract": "2.0.0-beta.24",
43
- "@orpc/client": "2.0.0-beta.24",
44
- "@orpc/openapi": "2.0.0-beta.24",
45
- "@orpc/shared": "2.0.0-beta.24",
46
- "@orpc/server": "2.0.0-beta.24"
43
+ "@orpc/client": "2.0.0-beta.26",
44
+ "@orpc/contract": "2.0.0-beta.26",
45
+ "@orpc/openapi": "2.0.0-beta.26",
46
+ "@orpc/server": "2.0.0-beta.26",
47
+ "@orpc/shared": "2.0.0-beta.26"
47
48
  },
48
49
  "devDependencies": {
49
50
  "@fastify/cookie": "^11.0.2",