vovk 3.0.0-draft.99 → 3.0.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.
Files changed (167) hide show
  1. package/README.md +22 -13
  2. package/bin/index.mjs +10 -0
  3. package/dist/client/createRPC.d.ts +13 -3
  4. package/dist/client/createRPC.js +112 -50
  5. package/dist/client/defaultHandler.d.ts +5 -1
  6. package/dist/client/defaultHandler.js +12 -9
  7. package/dist/client/defaultStreamHandler.d.ts +16 -4
  8. package/dist/client/defaultStreamHandler.js +259 -62
  9. package/dist/client/fetcher.d.ts +41 -3
  10. package/dist/client/fetcher.js +125 -60
  11. package/dist/client/progressive.d.ts +15 -0
  12. package/dist/client/progressive.js +56 -0
  13. package/dist/{utils → client}/serializeQuery.d.ts +2 -2
  14. package/dist/{utils → client}/serializeQuery.js +1 -4
  15. package/dist/core/HttpException.d.ts +16 -0
  16. package/dist/core/HttpException.js +26 -0
  17. package/dist/core/JSONLinesResponder.d.ts +42 -0
  18. package/dist/core/JSONLinesResponder.js +92 -0
  19. package/dist/core/controllersToStaticParams.d.ts +13 -0
  20. package/dist/core/controllersToStaticParams.js +36 -0
  21. package/dist/core/createDecorator.d.ts +12 -0
  22. package/dist/{createDecorator.js → core/createDecorator.js} +18 -12
  23. package/dist/core/decorators.d.ts +59 -0
  24. package/dist/core/decorators.js +132 -0
  25. package/dist/core/getSchema.d.ts +21 -0
  26. package/dist/core/getSchema.js +31 -0
  27. package/dist/core/initSegment.d.ts +33 -0
  28. package/dist/core/initSegment.js +35 -0
  29. package/dist/core/multitenant.d.ts +33 -0
  30. package/dist/core/multitenant.js +132 -0
  31. package/dist/core/resolveGeneratorConfigValues.d.ts +19 -0
  32. package/dist/core/resolveGeneratorConfigValues.js +59 -0
  33. package/dist/{utils → core}/setHandlerSchema.d.ts +2 -2
  34. package/dist/{utils → core}/setHandlerSchema.js +1 -4
  35. package/dist/core/toDownloadResponse.d.ts +11 -0
  36. package/dist/core/toDownloadResponse.js +25 -0
  37. package/dist/core/vovkApp.d.ts +36 -0
  38. package/dist/core/vovkApp.js +316 -0
  39. package/dist/index.d.ts +25 -59
  40. package/dist/index.js +23 -23
  41. package/dist/internal.d.ts +17 -0
  42. package/dist/internal.js +10 -0
  43. package/dist/openapi/error.d.ts +2 -0
  44. package/dist/openapi/error.js +97 -0
  45. package/dist/openapi/openAPIToVovkSchema/applyComponentsSchemas.d.ts +3 -0
  46. package/dist/openapi/openAPIToVovkSchema/applyComponentsSchemas.js +65 -0
  47. package/dist/openapi/openAPIToVovkSchema/index.d.ts +5 -0
  48. package/dist/openapi/openAPIToVovkSchema/index.js +153 -0
  49. package/dist/openapi/openAPIToVovkSchema/inlineRefs.d.ts +9 -0
  50. package/dist/openapi/openAPIToVovkSchema/inlineRefs.js +99 -0
  51. package/dist/openapi/operation.d.ts +10 -0
  52. package/dist/openapi/operation.js +19 -0
  53. package/dist/openapi/tool.d.ts +2 -0
  54. package/dist/openapi/tool.js +12 -0
  55. package/dist/openapi/vovkSchemaToOpenAPI.d.ts +21 -0
  56. package/dist/openapi/vovkSchemaToOpenAPI.js +250 -0
  57. package/dist/req/bufferBody.d.ts +1 -0
  58. package/dist/req/bufferBody.js +30 -0
  59. package/dist/req/parseBody.d.ts +4 -0
  60. package/dist/req/parseBody.js +49 -0
  61. package/dist/req/parseForm.d.ts +1 -0
  62. package/dist/req/parseForm.js +24 -0
  63. package/dist/{utils → req}/parseQuery.d.ts +1 -2
  64. package/dist/{utils → req}/parseQuery.js +2 -5
  65. package/dist/req/reqMeta.d.ts +2 -0
  66. package/dist/{utils → req}/reqMeta.js +1 -4
  67. package/dist/req/reqQuery.d.ts +2 -0
  68. package/dist/req/reqQuery.js +4 -0
  69. package/dist/req/validateContentType.d.ts +1 -0
  70. package/dist/req/validateContentType.js +32 -0
  71. package/dist/samples/createCodeSamples.d.ts +20 -0
  72. package/dist/samples/createCodeSamples.js +293 -0
  73. package/dist/samples/objectToCode.d.ts +8 -0
  74. package/dist/samples/objectToCode.js +38 -0
  75. package/dist/samples/schemaToCode.d.ts +11 -0
  76. package/dist/samples/schemaToCode.js +264 -0
  77. package/dist/samples/schemaToObject.d.ts +2 -0
  78. package/dist/samples/schemaToObject.js +164 -0
  79. package/dist/samples/schemaToTsType.d.ts +2 -0
  80. package/dist/samples/schemaToTsType.js +114 -0
  81. package/dist/tools/ToModelOutput.d.ts +8 -0
  82. package/dist/tools/ToModelOutput.js +10 -0
  83. package/dist/tools/createTool.d.ts +126 -0
  84. package/dist/tools/createTool.js +6 -0
  85. package/dist/tools/createToolFactory.d.ts +135 -0
  86. package/dist/tools/createToolFactory.js +61 -0
  87. package/dist/tools/deriveTools.d.ts +46 -0
  88. package/dist/tools/deriveTools.js +134 -0
  89. package/dist/tools/toModelOutputDefault.d.ts +7 -0
  90. package/dist/tools/toModelOutputDefault.js +7 -0
  91. package/dist/tools/toModelOutputMCP.d.ts +30 -0
  92. package/dist/tools/toModelOutputMCP.js +54 -0
  93. package/dist/tsconfig.tsbuildinfo +1 -0
  94. package/dist/types/client.d.ts +140 -0
  95. package/dist/types/client.js +1 -0
  96. package/dist/types/config.d.ts +151 -0
  97. package/dist/types/config.js +1 -0
  98. package/dist/types/core.d.ts +115 -0
  99. package/dist/types/core.js +1 -0
  100. package/dist/types/enums.d.ts +75 -0
  101. package/dist/{types.js → types/enums.js} +21 -9
  102. package/dist/types/inference.d.ts +117 -0
  103. package/dist/types/inference.js +1 -0
  104. package/dist/types/json-schema.d.ts +51 -0
  105. package/dist/types/json-schema.js +1 -0
  106. package/dist/types/operation.d.ts +5 -0
  107. package/dist/types/operation.js +1 -0
  108. package/dist/types/package.d.ts +544 -0
  109. package/dist/types/package.js +5 -0
  110. package/dist/types/request.d.ts +48 -0
  111. package/dist/types/request.js +1 -0
  112. package/dist/types/standard-schema.d.ts +117 -0
  113. package/dist/types/standard-schema.js +6 -0
  114. package/dist/types/tools.d.ts +43 -0
  115. package/dist/types/tools.js +1 -0
  116. package/dist/types/utils.d.ts +9 -0
  117. package/dist/types/utils.js +1 -0
  118. package/dist/types/validation.d.ts +48 -0
  119. package/dist/types/validation.js +1 -0
  120. package/dist/utils/camelCase.d.ts +6 -0
  121. package/dist/utils/camelCase.js +34 -0
  122. package/dist/utils/deepExtend.d.ts +53 -0
  123. package/dist/utils/deepExtend.js +128 -0
  124. package/dist/utils/fileNameToDisposition.d.ts +1 -0
  125. package/dist/utils/fileNameToDisposition.js +3 -0
  126. package/dist/utils/shim.d.ts +1 -0
  127. package/dist/utils/shim.js +1 -1
  128. package/dist/utils/toKebabCase.d.ts +1 -0
  129. package/dist/utils/toKebabCase.js +5 -0
  130. package/dist/utils/trimPath.d.ts +1 -0
  131. package/dist/utils/trimPath.js +1 -0
  132. package/dist/utils/upperFirst.d.ts +1 -0
  133. package/dist/utils/upperFirst.js +3 -0
  134. package/dist/validation/createStandardValidation.d.ts +268 -0
  135. package/dist/validation/createStandardValidation.js +45 -0
  136. package/dist/validation/createValidateOnClient.d.ts +14 -0
  137. package/dist/validation/createValidateOnClient.js +23 -0
  138. package/dist/validation/procedure.d.ts +261 -0
  139. package/dist/validation/procedure.js +8 -0
  140. package/dist/validation/withValidationLibrary.d.ts +119 -0
  141. package/dist/validation/withValidationLibrary.js +174 -0
  142. package/package.json +44 -10
  143. package/dist/HttpException.d.ts +0 -7
  144. package/dist/HttpException.js +0 -15
  145. package/dist/StreamJSONResponse.d.ts +0 -14
  146. package/dist/StreamJSONResponse.js +0 -57
  147. package/dist/VovkApp.d.ts +0 -29
  148. package/dist/VovkApp.js +0 -188
  149. package/dist/client/index.d.ts +0 -3
  150. package/dist/client/index.js +0 -7
  151. package/dist/client/types.d.ts +0 -104
  152. package/dist/client/types.js +0 -2
  153. package/dist/createDecorator.d.ts +0 -6
  154. package/dist/createVovkApp.d.ts +0 -62
  155. package/dist/createVovkApp.js +0 -118
  156. package/dist/types.d.ts +0 -220
  157. package/dist/utils/generateStaticAPI.d.ts +0 -4
  158. package/dist/utils/generateStaticAPI.js +0 -18
  159. package/dist/utils/getSchema.d.ts +0 -20
  160. package/dist/utils/getSchema.js +0 -33
  161. package/dist/utils/reqForm.d.ts +0 -2
  162. package/dist/utils/reqForm.js +0 -13
  163. package/dist/utils/reqMeta.d.ts +0 -2
  164. package/dist/utils/reqQuery.d.ts +0 -2
  165. package/dist/utils/reqQuery.js +0 -10
  166. package/dist/utils/withValidation.d.ts +0 -20
  167. package/dist/utils/withValidation.js +0 -72
package/README.md CHANGED
@@ -1,24 +1,33 @@
1
- <p align="center">
2
- <picture>
3
- <source width="300" media="(prefers-color-scheme: dark)" srcset="https://vovk.dev/vovk-logo-white.svg">
4
- <source width="300" media="(prefers-color-scheme: light)" srcset="https://vovk.dev/vovk-logo.svg">
5
- <img width="300" alt="vovk" src="https://vovk.dev/vovk-logo.svg">
6
- </picture><br>
7
- <strong>REST + RPC = ♥️</strong>
8
- </p>
9
-
10
1
  <p align="center">
11
- Back-end meta-framework for <a href="https://nextjs.org/docs/app">Next.js</a>
2
+ <a href="https://vovk.dev">
3
+ <picture>
4
+ <source width="300" media="(prefers-color-scheme: dark)" srcset="https://vovk.dev/vovk-logo-white.svg">
5
+ <source width="300" media="(prefers-color-scheme: light)" srcset="https://vovk.dev/vovk-logo.svg">
6
+ <img width="300" alt="vovk" src="https://vovk.dev/vovk-logo.svg">
7
+ </picture>
8
+ </a>
9
+ <br>
10
+ <strong>Back-end Framework for Next.js App Router</strong>
11
+ <br />
12
+ <a href="https://vovk.dev/">Documentation</a>
13
+ &nbsp;&nbsp;
14
+ <a href="https://vovk.dev/quick-install">Quick Start</a>
15
+ &nbsp;&nbsp;
16
+ <a href="https://vovk.dev/performance">Performance</a>
12
17
  </p>
13
18
 
14
19
  ---
15
20
 
16
21
  ## vovk [![npm version](https://badge.fury.io/js/vovk.svg)](https://www.npmjs.com/package/vovk)
17
22
 
18
- The main library with [zero dependencies](https://bundlephobia.com/result?p=vovk) that's going to be used in production. It provides a wrapper for Next.js API routes, internal RPC API, utilities and types.
23
+ The Vovk.ts runtime library with [100% self-composition](https://bundlephobia.com/result?p=vovk). It provides a wrapper for Next.js API routes, client-side tooling, utilities and types.
19
24
 
20
25
  ```sh
21
- npm install vovk
26
+ npm install vovk openapi3-ts
22
27
  ```
23
28
 
24
- For more information, please visit the [getting started guide](https://vovk.dev/getting-started) or check out the [Vovk.ts examples](https://vovk-examples.vercel.app/).
29
+ ## Links
30
+
31
+ - Docs: https://vovk.dev
32
+ - Quick Start: https://vovk.dev/quick-install
33
+ - Manual install: https://vovk.dev/manual-install
package/bin/index.mjs ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from 'child_process';
3
+
4
+ console.warn(
5
+ `\x1b[33m🐺 Vovk CLI requires vovk-cli package. Running npx vovk-cli@latest ${process.argv.slice(2).join(' ')} instead.\x1b[0m`
6
+ );
7
+
8
+ spawn('npx', ['vovk-cli@latest', ...process.argv.slice(2)], { stdio: 'inherit' }).on('exit', (code) => {
9
+ process.exit(code);
10
+ });
@@ -1,3 +1,13 @@
1
- import type { KnownAny, VovkFullSchema } from '../types';
2
- import type { VovkClientOptions, VovkClient, VovkDefaultFetcherOptions } from './types';
3
- export declare const createRPC: <T, OPTS extends Record<string, KnownAny> = VovkDefaultFetcherOptions>(fullSchema: VovkFullSchema, segmentName: string, controllerName: string, options?: VovkClientOptions<OPTS>) => VovkClient<T, OPTS>;
1
+ import type { VovkHandlerSchema } from '../internal.js';
2
+ import type { VovkRequest } from '../types/request.js';
3
+ import type { VovkRPCModule, VovkFetcher, VovkFetcherOptions } from '../types/client.js';
4
+ import type { CombinedSpec } from '../types/validation.js';
5
+ import type { KnownAny } from '../types/utils.js';
6
+ export type { VovkHandlerSchema, VovkRequest, CombinedSpec };
7
+ /**
8
+ * Creates a client-side RPC module for interacting with server-side controllers.
9
+ * @see https://vovk.dev/typescript
10
+ */
11
+ export declare const createRPC: <T, OPTS extends Record<string, KnownAny> = Record<string, never>>(givenSchema: unknown, segmentName: string, rpcModuleName: string, givenFetcher?: VovkFetcher<OPTS> | Promise<{
12
+ fetcher: VovkFetcher<OPTS>;
13
+ }>, options?: VovkFetcherOptions<OPTS>) => VovkRPCModule<T, OPTS>;
@@ -1,85 +1,147 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.createRPC = void 0;
7
- const fetcher_1 = require("./fetcher");
8
- const defaultHandler_1 = require("./defaultHandler");
9
- const defaultStreamHandler_1 = require("./defaultStreamHandler");
10
- const serializeQuery_1 = __importDefault(require("../utils/serializeQuery"));
1
+ import { fetcher as defaultFetcher } from './fetcher.js';
2
+ import { defaultHandler } from './defaultHandler.js';
3
+ import { defaultStreamHandler } from './defaultStreamHandler.js';
4
+ import { serializeQuery } from './serializeQuery.js';
5
+ import { deepExtend } from '../utils/deepExtend.js';
11
6
  const trimPath = (path) => path.trim().replace(/^\/|\/$/g, '');
12
7
  const getHandlerPath = (endpoint, params, query) => {
13
8
  let result = endpoint;
14
- const queryStr = query ? (0, serializeQuery_1.default)(query) : null;
9
+ const queryStr = query ? serializeQuery(query) : null;
15
10
  for (const [key, value] of Object.entries(params ?? {})) {
16
- result = result.replace(`:${key}`, value);
11
+ result = result.replace(`{${key}}`, value);
17
12
  }
18
- return `${result}${queryStr ? '?' : ''}${queryStr}`;
13
+ return `${result}${queryStr ? `?${queryStr}` : ''}`;
19
14
  };
20
- const createRPC = (fullSchema, segmentName, controllerName, options) => {
21
- const segmentSchema = fullSchema.segments[segmentName];
15
+ /**
16
+ * Creates a client-side RPC module for interacting with server-side controllers.
17
+ * @see https://vovk.dev/typescript
18
+ */
19
+ export const createRPC = (givenSchema, segmentName, rpcModuleName, givenFetcher, options) => {
20
+ const schema = givenSchema; // fixes incompatibilities with JSON module
21
+ // fetcher ??= defaultFetcher as NonNullable<typeof fetcher>;
22
+ const segmentNamePath = options?.segmentNameOverride ?? segmentName;
23
+ const segmentSchema = schema.segments[segmentName];
22
24
  if (!segmentSchema)
23
- throw new Error(`Unable to create RPC object. Segment schema is missing. Check client template.`);
24
- const controllerSchema = fullSchema.segments[segmentName]?.controllers[controllerName];
25
+ throw new Error(`Unable to create RPC module. Segment schema is missing for segment "${segmentName}".`);
26
+ let controllerSchema = schema.segments[segmentName]?.controllers[rpcModuleName];
25
27
  const client = {};
26
- if (!controllerSchema)
27
- throw new Error(`Unable to create RPC object. Controller schema is missing. Check client template.`);
28
+ if (!controllerSchema) {
29
+ // eslint-disable-next-line no-console
30
+ console.warn(`🐺 Unable to create RPC module. Controller schema is missing for module "${rpcModuleName}" from segment "${segmentName}". Assuming that schema is not ready yet and a segment is importing an uncompiled RPC module.`);
31
+ controllerSchema = {
32
+ rpcModuleName,
33
+ prefix: '',
34
+ handlers: {},
35
+ };
36
+ }
28
37
  const controllerPrefix = trimPath(controllerSchema.prefix ?? '');
29
- const { fetcher: settingsFetcher = fetcher_1.fetcher } = options ?? {};
30
- for (const [staticMethodName, handlerSchema] of Object.entries(controllerSchema.handlers)) {
38
+ const forceApiRoot = segmentSchema.forceApiRoot;
39
+ const configRootEntry = schema.meta?.config?.rootEntry;
40
+ const originalApiRoot = forceApiRoot ?? options?.apiRoot ?? (configRootEntry ? `/${configRootEntry}` : '/api');
41
+ for (const [staticMethodName, handlerSchema] of Object.entries(controllerSchema.handlers ?? {})) {
31
42
  const { path, httpMethod, validation } = handlerSchema;
32
- const getEndpoint = ({ apiRoot, params, query, }) => {
33
- const mainPrefix = (apiRoot.startsWith('http://') || apiRoot.startsWith('https://') || apiRoot.startsWith('/') ? '' : '/') +
34
- (apiRoot.endsWith('/') ? apiRoot : `${apiRoot}/`) +
35
- (segmentName ? `${segmentName}/` : '');
36
- return mainPrefix + getHandlerPath([controllerPrefix, path].filter(Boolean).join('/'), params, query);
43
+ const getURL = ({ apiRoot, params, query } = {}) => {
44
+ apiRoot = apiRoot ?? originalApiRoot;
45
+ const endpoint = [
46
+ apiRoot.startsWith('http://') || apiRoot.startsWith('https://') || apiRoot.startsWith('/') ? '' : '/',
47
+ apiRoot,
48
+ forceApiRoot ? '' : segmentNamePath,
49
+ getHandlerPath([controllerPrefix, path].filter(Boolean).join('/'), params, query),
50
+ ]
51
+ .filter(Boolean)
52
+ .join('/')
53
+ .replace(/([^:])\/+/g, '$1/'); // replace // by / but not for protocols (http://, https://)
54
+ return endpoint;
37
55
  };
38
- const handler = (input = {}) => {
39
- const fetcher = input.fetcher ?? settingsFetcher;
40
- const validate = async ({ body, query, params, endpoint, }) => {
41
- const validateOnClient = input.validateOnClient ?? options?.validateOnClient;
42
- if (validateOnClient) {
56
+ const handler = (async (input = {}) => {
57
+ const optionsResolvedValidateOnClient = options?.validateOnClient instanceof Promise
58
+ ? (await options?.validateOnClient)?.validateOnClient
59
+ : options?.validateOnClient;
60
+ const fetcher = givenFetcher instanceof Promise
61
+ ? (await givenFetcher).fetcher
62
+ : (givenFetcher ?? defaultFetcher);
63
+ const validate = async (validationInput, { endpoint, }) => {
64
+ const validateOnClient = input.validateOnClient ?? optionsResolvedValidateOnClient;
65
+ if (validateOnClient && validation) {
43
66
  if (typeof validateOnClient !== 'function') {
44
67
  throw new Error('validateOnClient must be a function');
45
68
  }
46
- await validateOnClient({ body, query, params, endpoint }, validation ?? {}, fullSchema);
69
+ return ((await validateOnClient({ ...validationInput }, validation, { fullSchema: schema, endpoint })) ??
70
+ validationInput);
47
71
  }
72
+ return validationInput;
48
73
  };
49
74
  const internalOptions = {
50
75
  name: staticMethodName,
51
76
  httpMethod: httpMethod,
52
- getEndpoint,
77
+ getURL,
53
78
  validate,
54
- defaultHandler: defaultHandler_1.defaultHandler,
55
- defaultStreamHandler: defaultStreamHandler_1.defaultStreamHandler,
79
+ defaultHandler,
80
+ defaultStreamHandler,
81
+ schema: handlerSchema,
56
82
  };
83
+ let processedBody = input.body;
84
+ if ((validation?.body?.['x-contentType']?.includes('multipart/form-data') ||
85
+ validation?.body?.['x-contentType']?.includes('application/x-www-form-urlencoded')) &&
86
+ input.body &&
87
+ !(input.body instanceof FormData || input.body instanceof URLSearchParams || input.body instanceof Blob)) {
88
+ processedBody = new FormData();
89
+ for (const [key, value] of Object.entries(input.body)) {
90
+ if (value instanceof Array) {
91
+ value.forEach((item) => {
92
+ processedBody.append(key, item);
93
+ });
94
+ }
95
+ else {
96
+ processedBody.append(key, value);
97
+ }
98
+ }
99
+ }
100
+ else {
101
+ processedBody = input.body;
102
+ }
57
103
  const internalInput = {
58
- ...options?.defaultOptions,
59
- ...input,
60
- body: input.body ?? null,
104
+ ...deepExtend({}, options, {
105
+ validateOnClient: optionsResolvedValidateOnClient,
106
+ }, input),
107
+ body: processedBody ?? null,
61
108
  query: input.query ?? {},
62
109
  params: input.params ?? {},
63
- // TS workaround
64
- fetcher: undefined,
65
- validateOnClient: undefined,
66
110
  };
67
- delete internalInput.fetcher;
68
- delete internalInput.validateOnClient;
69
111
  if (!fetcher)
70
112
  throw new Error('Fetcher is not provided');
71
- const fetcherPromise = fetcher(internalOptions, internalInput);
72
- if (!(fetcherPromise instanceof Promise))
73
- return Promise.resolve(fetcherPromise);
74
- return input.transform ? fetcherPromise.then(input.transform) : fetcherPromise;
75
- };
113
+ const [respData, resp] = await fetcher(internalOptions, internalInput);
114
+ return input.transform ? input.transform(respData, resp) : respData;
115
+ });
116
+ // TODO use Object.freeze, Object.seal or Object.defineProperty to avoid mutation
76
117
  handler.schema = handlerSchema;
77
118
  handler.controllerSchema = controllerSchema;
78
119
  handler.segmentSchema = segmentSchema;
79
- handler.fullSchema = fullSchema;
120
+ handler.fullSchema = schema;
121
+ handler.isRPC = true;
122
+ handler.apiRoot = originalApiRoot;
123
+ handler.getURL = getURL;
124
+ handler.queryKey = (key) => [
125
+ handler.segmentSchema.segmentName,
126
+ handler.controllerSchema.prefix ?? '',
127
+ handler.controllerSchema.rpcModuleName,
128
+ handler.schema.path,
129
+ handler.schema.httpMethod,
130
+ ...(key ?? []),
131
+ ];
80
132
  // @ts-expect-error TODO
81
133
  client[staticMethodName] = handler;
82
134
  }
135
+ Object.defineProperty(client, 'withDefaults', {
136
+ value: (newOptions) => {
137
+ return createRPC(schema, segmentName, rpcModuleName, givenFetcher, {
138
+ ...options,
139
+ ...newOptions,
140
+ });
141
+ },
142
+ enumerable: false,
143
+ writable: false,
144
+ configurable: false,
145
+ });
83
146
  return client;
84
147
  };
85
- exports.createRPC = createRPC;
@@ -1,2 +1,6 @@
1
+ import type { VovkHandlerSchema } from '../types/core.js';
1
2
  export declare const DEFAULT_ERROR_MESSAGE = "Unknown error at defaultHandler";
2
- export declare const defaultHandler: (response: Response) => Promise<unknown>;
3
+ export declare const defaultHandler: ({ response, schema }: {
4
+ response: Response;
5
+ schema: VovkHandlerSchema;
6
+ }) => Promise<unknown>;
@@ -1,22 +1,25 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultHandler = exports.DEFAULT_ERROR_MESSAGE = void 0;
4
- const HttpException_1 = require("../HttpException");
5
- exports.DEFAULT_ERROR_MESSAGE = 'Unknown error at defaultHandler';
6
- const defaultHandler = async (response) => {
1
+ import { HttpException } from '../core/HttpException.js';
2
+ export const DEFAULT_ERROR_MESSAGE = 'Unknown error at defaultHandler';
3
+ // Helper function to get a value from an object using dot notation path
4
+ const getNestedValue = (obj, path) => {
5
+ return path.split('.').reduce((o, key) => (o && typeof o === 'object' ? o[key] : undefined), obj);
6
+ };
7
+ export const defaultHandler = async ({ response, schema }) => {
7
8
  let result;
8
9
  try {
9
10
  result = await response.json();
10
11
  }
11
12
  catch (e) {
12
13
  // handle parsing errors
13
- throw new HttpException_1.HttpException(response.status, e?.message ?? exports.DEFAULT_ERROR_MESSAGE);
14
+ throw new HttpException(response.status, e?.message ?? DEFAULT_ERROR_MESSAGE);
14
15
  }
15
16
  if (!response.ok) {
17
+ const errorKey = schema.operationObject && 'x-errorMessageKey' in schema.operationObject
18
+ ? schema.operationObject['x-errorMessageKey']
19
+ : 'message';
16
20
  // handle server errors
17
21
  const errorResponse = result;
18
- throw new HttpException_1.HttpException(response.status, errorResponse?.message ?? exports.DEFAULT_ERROR_MESSAGE, errorResponse?.cause);
22
+ throw new HttpException(response.status, getNestedValue(errorResponse, errorKey) ?? DEFAULT_ERROR_MESSAGE, errorResponse?.cause ?? JSON.stringify(result));
19
23
  }
20
24
  return result;
21
25
  };
22
- exports.defaultHandler = defaultHandler;
@@ -1,4 +1,16 @@
1
- import type { VovkStreamAsyncIterable } from './types';
2
- import '../utils/shim';
3
- export declare const DEFAULT_ERROR_MESSAGE = "Unknown error at defaultStreamHandler";
4
- export declare const defaultStreamHandler: (response: Response) => Promise<VovkStreamAsyncIterable<unknown>>;
1
+ import type { VovkStreamAsyncIterable } from '../types/client.js';
2
+ import '../utils/shim.js';
3
+ export declare const DEFAULT_ERROR_MESSAGE = "An unknown error at the default stream handler";
4
+ /**
5
+ * Converts a ReadableStream of JSON Lines into a VovkStreamAsyncIterable.
6
+ * This is the core streaming logic extracted for reuse outside of HTTP contexts.
7
+ * @see https://vovk.dev/jsonlines
8
+ */
9
+ export declare const readableStreamToAsyncIterable: <T = unknown>({ readableStream, abortController, }: {
10
+ readableStream: ReadableStream<Uint8Array | string>;
11
+ abortController?: AbortController;
12
+ }) => Omit<VovkStreamAsyncIterable<T>, "abortController" | "status">;
13
+ export declare const defaultStreamHandler: ({ response, abortController, }: {
14
+ response: Response;
15
+ abortController: AbortController;
16
+ }) => VovkStreamAsyncIterable<unknown>;