@orpc/openapi 2.0.0-beta.42 → 2.0.0-beta.43

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 (31) hide show
  1. package/dist/adapters/aws-lambda/index.d.mts +1 -1
  2. package/dist/adapters/aws-lambda/index.d.ts +1 -1
  3. package/dist/adapters/aws-lambda/index.mjs +3 -3
  4. package/dist/adapters/fastify/index.d.mts +1 -1
  5. package/dist/adapters/fastify/index.d.ts +1 -1
  6. package/dist/adapters/fastify/index.mjs +3 -3
  7. package/dist/adapters/fetch/index.d.mts +1 -1
  8. package/dist/adapters/fetch/index.d.ts +1 -1
  9. package/dist/adapters/fetch/index.mjs +4 -4
  10. package/dist/adapters/node/index.d.mts +1 -1
  11. package/dist/adapters/node/index.d.ts +1 -1
  12. package/dist/adapters/node/index.mjs +3 -3
  13. package/dist/adapters/standard/index.d.mts +2 -2
  14. package/dist/adapters/standard/index.d.ts +2 -2
  15. package/dist/adapters/standard/index.mjs +4 -4
  16. package/dist/helpers/index.mjs +2 -2
  17. package/dist/index.d.mts +2 -2
  18. package/dist/index.d.ts +2 -2
  19. package/dist/index.mjs +42 -19
  20. package/dist/shared/{openapi.CkzUS83v.d.ts → openapi.1UQkZGBs.d.ts} +1 -1
  21. package/dist/shared/{openapi.BDiBd3_k.d.mts → openapi.BSLqRCwO.d.mts} +1 -1
  22. package/dist/shared/{openapi.Cg9h6jpm.d.mts → openapi.BVt3NPfo.d.mts} +1 -1
  23. package/dist/shared/{openapi.D326pNzT.mjs → openapi.C6KG7fwg.mjs} +2 -2
  24. package/dist/shared/{openapi.BJRea9Uu.mjs → openapi.DcQKf6ur.mjs} +16 -9
  25. package/dist/shared/{openapi.C2LayTNZ.d.mts → openapi.DjGhiceP.d.mts} +10 -11
  26. package/dist/shared/{openapi.C2LayTNZ.d.ts → openapi.DjGhiceP.d.ts} +10 -11
  27. package/dist/shared/openapi.DtEVcxuW.mjs +149 -0
  28. package/dist/shared/{openapi.Bu_PfTtX.mjs → openapi.PXVenYpE.mjs} +1 -1
  29. package/dist/shared/{openapi.D0yWs-uW.d.ts → openapi.aoP0G_Bv.d.ts} +1 -1
  30. package/package.json +9 -9
  31. package/dist/shared/openapi.B2G-HeFn.mjs +0 -123
@@ -6,7 +6,7 @@ import '@orpc/client';
6
6
  import '@orpc/shared';
7
7
  import '@standard-server/core';
8
8
  import '@orpc/contract';
9
- import '../../shared/openapi.C2LayTNZ.mjs';
9
+ import '../../shared/openapi.DjGhiceP.mjs';
10
10
 
11
11
  interface OpenAPIHandlerOptions<T extends Context> extends AwsLambdaHandlerOptions<T>, StandardHandlerOptions<T>, OpenAPIHandlerCodecOptions<T> {
12
12
  }
@@ -6,7 +6,7 @@ import '@orpc/client';
6
6
  import '@orpc/shared';
7
7
  import '@standard-server/core';
8
8
  import '@orpc/contract';
9
- import '../../shared/openapi.C2LayTNZ.js';
9
+ import '../../shared/openapi.DjGhiceP.js';
10
10
 
11
11
  interface OpenAPIHandlerOptions<T extends Context> extends AwsLambdaHandlerOptions<T>, StandardHandlerOptions<T>, OpenAPIHandlerCodecOptions<T> {
12
12
  }
@@ -1,12 +1,12 @@
1
1
  import { AwsLambdaHandler } from '@orpc/server/aws-lambda';
2
2
  import { StandardHandler } from '@orpc/server/standard';
3
- import { O as OpenAPIHandlerCodec } from '../../shared/openapi.BJRea9Uu.mjs';
3
+ import { O as OpenAPIHandlerCodec } from '../../shared/openapi.DcQKf6ur.mjs';
4
4
  import '@orpc/client';
5
5
  import '@orpc/server';
6
6
  import '@orpc/shared';
7
7
  import '@standard-server/core';
8
- import '../../shared/openapi.Bu_PfTtX.mjs';
9
- import '../../shared/openapi.B2G-HeFn.mjs';
8
+ import '../../shared/openapi.PXVenYpE.mjs';
9
+ import '../../shared/openapi.DtEVcxuW.mjs';
10
10
  import '../../shared/openapi.B9PQzqBn.mjs';
11
11
  import 'rou3';
12
12
 
@@ -6,7 +6,7 @@ import '@orpc/client';
6
6
  import '@orpc/shared';
7
7
  import '@standard-server/core';
8
8
  import '@orpc/contract';
9
- import '../../shared/openapi.C2LayTNZ.mjs';
9
+ import '../../shared/openapi.DjGhiceP.mjs';
10
10
 
11
11
  interface OpenAPIHandlerOptions<T extends Context> extends FastifyHandlerOptions<T>, StandardHandlerOptions<T>, OpenAPIHandlerCodecOptions<T> {
12
12
  }
@@ -6,7 +6,7 @@ import '@orpc/client';
6
6
  import '@orpc/shared';
7
7
  import '@standard-server/core';
8
8
  import '@orpc/contract';
9
- import '../../shared/openapi.C2LayTNZ.js';
9
+ import '../../shared/openapi.DjGhiceP.js';
10
10
 
11
11
  interface OpenAPIHandlerOptions<T extends Context> extends FastifyHandlerOptions<T>, StandardHandlerOptions<T>, OpenAPIHandlerCodecOptions<T> {
12
12
  }
@@ -1,12 +1,12 @@
1
1
  import { FastifyHandler } from '@orpc/server/fastify';
2
2
  import { StandardHandler } from '@orpc/server/standard';
3
- import { O as OpenAPIHandlerCodec } from '../../shared/openapi.BJRea9Uu.mjs';
3
+ import { O as OpenAPIHandlerCodec } from '../../shared/openapi.DcQKf6ur.mjs';
4
4
  import '@orpc/client';
5
5
  import '@orpc/server';
6
6
  import '@orpc/shared';
7
7
  import '@standard-server/core';
8
- import '../../shared/openapi.Bu_PfTtX.mjs';
9
- import '../../shared/openapi.B2G-HeFn.mjs';
8
+ import '../../shared/openapi.PXVenYpE.mjs';
9
+ import '../../shared/openapi.DtEVcxuW.mjs';
10
10
  import '../../shared/openapi.B9PQzqBn.mjs';
11
11
  import 'rou3';
12
12
 
@@ -9,7 +9,7 @@ import { RouterContract } from '@orpc/contract';
9
9
  import { OpenAPILinkCodecOptions } from '../standard/index.mjs';
10
10
  import '@orpc/shared';
11
11
  import '@standard-server/core';
12
- import '../../shared/openapi.C2LayTNZ.mjs';
12
+ import '../../shared/openapi.DjGhiceP.mjs';
13
13
 
14
14
  interface OpenAPIHandlerOptions<T extends Context> extends FetchHandlerOptions<T>, StandardHandlerOptions<T>, OpenAPIHandlerCodecOptions<T> {
15
15
  }
@@ -9,7 +9,7 @@ import { RouterContract } from '@orpc/contract';
9
9
  import { OpenAPILinkCodecOptions } from '../standard/index.js';
10
10
  import '@orpc/shared';
11
11
  import '@standard-server/core';
12
- import '../../shared/openapi.C2LayTNZ.js';
12
+ import '../../shared/openapi.DjGhiceP.js';
13
13
 
14
14
  interface OpenAPIHandlerOptions<T extends Context> extends FetchHandlerOptions<T>, StandardHandlerOptions<T>, OpenAPIHandlerCodecOptions<T> {
15
15
  }
@@ -1,15 +1,15 @@
1
1
  import { FetchHandler } from '@orpc/server/fetch';
2
2
  import { StandardHandler } from '@orpc/server/standard';
3
- import { O as OpenAPIHandlerCodec } from '../../shared/openapi.BJRea9Uu.mjs';
3
+ import { O as OpenAPIHandlerCodec } from '../../shared/openapi.DcQKf6ur.mjs';
4
4
  import { FetchLinkTransport } from '@orpc/client/fetch';
5
5
  import { StandardLink } from '@orpc/client/standard';
6
- import { O as OpenAPILinkCodec } from '../../shared/openapi.D326pNzT.mjs';
6
+ import { O as OpenAPILinkCodec } from '../../shared/openapi.C6KG7fwg.mjs';
7
7
  import '@orpc/client';
8
8
  import '@orpc/server';
9
9
  import '@orpc/shared';
10
10
  import '@standard-server/core';
11
- import '../../shared/openapi.Bu_PfTtX.mjs';
12
- import '../../shared/openapi.B2G-HeFn.mjs';
11
+ import '../../shared/openapi.PXVenYpE.mjs';
12
+ import '../../shared/openapi.DtEVcxuW.mjs';
13
13
  import '../../shared/openapi.B9PQzqBn.mjs';
14
14
  import 'rou3';
15
15
  import '@orpc/contract';
@@ -6,7 +6,7 @@ import '@orpc/client';
6
6
  import '@orpc/shared';
7
7
  import '@standard-server/core';
8
8
  import '@orpc/contract';
9
- import '../../shared/openapi.C2LayTNZ.mjs';
9
+ import '../../shared/openapi.DjGhiceP.mjs';
10
10
 
11
11
  interface OpenAPIHandlerOptions<T extends Context> extends NodeHttpHandlerOptions<T>, StandardHandlerOptions<T>, OpenAPIHandlerCodecOptions<T> {
12
12
  }
@@ -6,7 +6,7 @@ import '@orpc/client';
6
6
  import '@orpc/shared';
7
7
  import '@standard-server/core';
8
8
  import '@orpc/contract';
9
- import '../../shared/openapi.C2LayTNZ.js';
9
+ import '../../shared/openapi.DjGhiceP.js';
10
10
 
11
11
  interface OpenAPIHandlerOptions<T extends Context> extends NodeHttpHandlerOptions<T>, StandardHandlerOptions<T>, OpenAPIHandlerCodecOptions<T> {
12
12
  }
@@ -1,12 +1,12 @@
1
1
  import { NodeHttpHandler } from '@orpc/server/node';
2
2
  import { StandardHandler } from '@orpc/server/standard';
3
- import { O as OpenAPIHandlerCodec } from '../../shared/openapi.BJRea9Uu.mjs';
3
+ import { O as OpenAPIHandlerCodec } from '../../shared/openapi.DcQKf6ur.mjs';
4
4
  import '@orpc/client';
5
5
  import '@orpc/server';
6
6
  import '@orpc/shared';
7
7
  import '@standard-server/core';
8
- import '../../shared/openapi.Bu_PfTtX.mjs';
9
- import '../../shared/openapi.B2G-HeFn.mjs';
8
+ import '../../shared/openapi.PXVenYpE.mjs';
9
+ import '../../shared/openapi.DtEVcxuW.mjs';
10
10
  import '../../shared/openapi.B9PQzqBn.mjs';
11
11
  import 'rou3';
12
12
 
@@ -1,5 +1,5 @@
1
- export { a as OpenAPIHandlerCodec, b as OpenAPIHandlerCodecCore, c as OpenAPIHandlerCodecCoreOptions, O as OpenAPIHandlerCodecOptions, d as OpenAPIMatcher, e as OpenAPIMatcherOptions } from '../../shared/openapi.BDiBd3_k.mjs';
2
- export { a as OpenAPILinkCodec, O as OpenAPILinkCodecOptions } from '../../shared/openapi.Cg9h6jpm.mjs';
1
+ export { a as OpenAPIHandlerCodec, b as OpenAPIHandlerCodecCore, c as OpenAPIHandlerCodecCoreOptions, O as OpenAPIHandlerCodecOptions, d as OpenAPIMatcher, e as OpenAPIMatcherOptions } from '../../shared/openapi.BSLqRCwO.mjs';
2
+ export { a as OpenAPILinkCodec, O as OpenAPILinkCodecOptions } from '../../shared/openapi.BVt3NPfo.mjs';
3
3
  import { StandardHeaders } from '@standard-server/core';
4
4
  import { OpenAPISerializer } from '../../index.mjs';
5
5
  import '@orpc/client';
@@ -1,5 +1,5 @@
1
- export { a as OpenAPIHandlerCodec, b as OpenAPIHandlerCodecCore, c as OpenAPIHandlerCodecCoreOptions, O as OpenAPIHandlerCodecOptions, d as OpenAPIMatcher, e as OpenAPIMatcherOptions } from '../../shared/openapi.CkzUS83v.js';
2
- export { a as OpenAPILinkCodec, O as OpenAPILinkCodecOptions } from '../../shared/openapi.D0yWs-uW.js';
1
+ export { a as OpenAPIHandlerCodec, b as OpenAPIHandlerCodecCore, c as OpenAPIHandlerCodecCoreOptions, O as OpenAPIHandlerCodecOptions, d as OpenAPIMatcher, e as OpenAPIMatcherOptions } from '../../shared/openapi.1UQkZGBs.js';
2
+ export { a as OpenAPILinkCodec, O as OpenAPILinkCodecOptions } from '../../shared/openapi.aoP0G_Bv.js';
3
3
  import { StandardHeaders } from '@standard-server/core';
4
4
  import { OpenAPISerializer } from '../../index.js';
5
5
  import '@orpc/client';
@@ -1,11 +1,11 @@
1
- export { O as OpenAPIHandlerCodec, a as OpenAPIHandlerCodecCore, b as OpenAPIMatcher, s as serializeHeaders } from '../../shared/openapi.BJRea9Uu.mjs';
2
- export { O as OpenAPILinkCodec } from '../../shared/openapi.D326pNzT.mjs';
1
+ export { O as OpenAPIHandlerCodec, a as OpenAPIHandlerCodecCore, b as OpenAPIMatcher, s as serializeHeaders } from '../../shared/openapi.DcQKf6ur.mjs';
2
+ export { O as OpenAPILinkCodec } from '../../shared/openapi.C6KG7fwg.mjs';
3
3
  import '@orpc/client';
4
4
  import '@orpc/server';
5
5
  import '@orpc/shared';
6
6
  import '@standard-server/core';
7
- import '../../shared/openapi.Bu_PfTtX.mjs';
8
- import '../../shared/openapi.B2G-HeFn.mjs';
7
+ import '../../shared/openapi.PXVenYpE.mjs';
8
+ import '../../shared/openapi.DtEVcxuW.mjs';
9
9
  import '../../shared/openapi.B9PQzqBn.mjs';
10
10
  import 'rou3';
11
11
  import '@orpc/contract';
@@ -1,6 +1,6 @@
1
1
  import { isSchemaIssue } from '@orpc/contract';
2
2
  import { isTypescriptObject } from '@orpc/shared';
3
- import { B as BracketNotationSerializer } from '../shared/openapi.B2G-HeFn.mjs';
3
+ import { B as BracketNotationSerializer } from '../shared/openapi.DtEVcxuW.mjs';
4
4
 
5
5
  function parseFormData(form) {
6
6
  const serializer = new BracketNotationSerializer();
@@ -30,7 +30,7 @@ function getIssueMessage(error, path) {
30
30
  if (path.endsWith("[]") && issuePath.replace(/\[(?:0|[1-9]\d*)\]$/, "[]") === path) {
31
31
  return issue.message;
32
32
  }
33
- if (path === "" && /(?:0|[1-9]\d*)$/.test(issuePath)) {
33
+ if (path === "" && /^(?:0|[1-9]\d*)$/.test(issuePath)) {
34
34
  return issue.message;
35
35
  }
36
36
  }
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { O as OpenAPISerializer } from './shared/openapi.C2LayTNZ.mjs';
2
- export { B as BracketNotationSerializeResult, a as BracketNotationSerializer, b as BracketNotationSerializerOptions, c as OpenAPIJsonSerialization, d as OpenAPIJsonSerializer, e as OpenAPIJsonSerializerHandler, f as OpenAPIJsonSerializerOptions, g as OpenAPISerializerOptions, h as OpenAPISerializerSerializeOptions } from './shared/openapi.C2LayTNZ.mjs';
1
+ import { O as OpenAPISerializer } from './shared/openapi.DjGhiceP.mjs';
2
+ export { B as BracketNotationSerializeResult, a as BracketNotationSerializer, b as BracketNotationSerializerOptions, c as OpenAPIJsonSerialization, d as OpenAPIJsonSerializer, e as OpenAPIJsonSerializerHandler, f as OpenAPIJsonSerializerOptions, g as OpenAPISerializerOptions, h as OpenAPISerializerSerializeOptions } from './shared/openapi.DjGhiceP.mjs';
3
3
  import { ClientContext, ORPCClientOptions, ClientLink } from '@orpc/client';
4
4
  export { COMMON_ERROR_STATUS_MAP } from '@orpc/client';
5
5
  import { RouterContract, RouterContractClient, AnyProcedureContract, ProcedureContract } from '@orpc/contract';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { O as OpenAPISerializer } from './shared/openapi.C2LayTNZ.js';
2
- export { B as BracketNotationSerializeResult, a as BracketNotationSerializer, b as BracketNotationSerializerOptions, c as OpenAPIJsonSerialization, d as OpenAPIJsonSerializer, e as OpenAPIJsonSerializerHandler, f as OpenAPIJsonSerializerOptions, g as OpenAPISerializerOptions, h as OpenAPISerializerSerializeOptions } from './shared/openapi.C2LayTNZ.js';
1
+ import { O as OpenAPISerializer } from './shared/openapi.DjGhiceP.js';
2
+ export { B as BracketNotationSerializeResult, a as BracketNotationSerializer, b as BracketNotationSerializerOptions, c as OpenAPIJsonSerialization, d as OpenAPIJsonSerializer, e as OpenAPIJsonSerializerHandler, f as OpenAPIJsonSerializerOptions, g as OpenAPISerializerOptions, h as OpenAPISerializerSerializeOptions } from './shared/openapi.DjGhiceP.js';
3
3
  import { ClientContext, ORPCClientOptions, ClientLink } from '@orpc/client';
4
4
  export { COMMON_ERROR_STATUS_MAP } from '@orpc/client';
5
5
  import { RouterContract, RouterContractClient, AnyProcedureContract, ProcedureContract } from '@orpc/contract';
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
- export { B as BracketNotationSerializer } from './shared/openapi.B2G-HeFn.mjs';
1
+ export { B as BracketNotationSerializer } from './shared/openapi.DtEVcxuW.mjs';
2
2
  import { createContractClientFactory, getAsyncIteratorObjectSchemaDetails, ProcedureContract, resolveMetaPlugins } from '@orpc/contract';
3
- import { D as DEFAULT_OPENAPI_METHOD, a as DEFAULT_OPENAPI_INPUT_STRUCTURE, c as DEFAULT_OPENAPI_SUCCESS_DESCRIPTION, b as DEFAULT_OPENAPI_OUTPUT_STRUCTURE, i as isBodylessMethod, O as OpenAPISerializer, g as getDynamicPathParams } from './shared/openapi.Bu_PfTtX.mjs';
4
- export { d as OpenAPIJsonSerializer } from './shared/openapi.Bu_PfTtX.mjs';
3
+ import { D as DEFAULT_OPENAPI_METHOD, a as DEFAULT_OPENAPI_INPUT_STRUCTURE, c as DEFAULT_OPENAPI_SUCCESS_DESCRIPTION, b as DEFAULT_OPENAPI_OUTPUT_STRUCTURE, i as isBodylessMethod, O as OpenAPISerializer, g as getDynamicPathParams } from './shared/openapi.PXVenYpE.mjs';
4
+ export { d as OpenAPIJsonSerializer } from './shared/openapi.PXVenYpE.mjs';
5
5
  import { g as getOpenAPIMeta, o as openapi } from './shared/openapi.B9PQzqBn.mjs';
6
6
  import { downgradeSpecV32ToV31, downgradeSpecV31ToV30 } from '@openapi-spec/downgrader';
7
7
  import { COMMON_ERROR_STATUS_MAP } from '@orpc/client';
@@ -457,33 +457,56 @@ function extractDetailedResponseParts(schema, defaultStatus) {
457
457
  );
458
458
  }
459
459
  const statusSchema = entries.find(([name]) => name === "status")?.[1];
460
- if (statusSchema !== void 0 && (typeof statusSchema !== "object" || !Number.isInteger(statusSchema.const) || statusSchema.const >= 400)) {
460
+ const statuses = statusSchema === void 0 ? /* @__PURE__ */ new Map([[defaultStatus, void 0]]) : extractDetailedStatuses(statusSchema);
461
+ if (!statuses) {
461
462
  throw new OpenAPIGeneratorError(
462
463
  `invalid "status" field in the detailed output schema.
463
- Expected: a literal (const) integer below 400
464
+ Expected: literal integers below 400 (const, enum, or a union of them)
464
465
  Received: ${stringifyJSON(statusSchema)}`
465
466
  );
466
467
  }
467
- const status = (statusSchema?.const || void 0) ?? defaultStatus;
468
- let parts = partsByStatus.get(status);
469
- if (!parts) {
470
- parts = { descriptions: [], bodies: [], headers: [] };
471
- partsByStatus.set(status, parts);
472
- }
473
- if (statusSchema?.description !== void 0) {
474
- parts.descriptions.push(statusSchema.description);
475
- }
476
468
  const headersSchema = entries.find(([name]) => name === "headers")?.[1];
477
- if (headersSchema !== void 0) {
478
- parts.headers.push(headersSchema);
479
- }
480
469
  const bodySchema = entries.find(([name]) => name === "body")?.[1];
481
- if (bodySchema !== void 0) {
482
- parts.bodies.push(bodySchema);
470
+ for (const [status, description] of statuses) {
471
+ let parts = partsByStatus.get(status);
472
+ if (!parts) {
473
+ parts = { descriptions: [], bodies: [], headers: [] };
474
+ partsByStatus.set(status, parts);
475
+ }
476
+ if (description !== void 0) {
477
+ parts.descriptions.push(description);
478
+ }
479
+ if (headersSchema !== void 0) {
480
+ parts.headers.push(headersSchema);
481
+ }
482
+ if (bodySchema !== void 0) {
483
+ parts.bodies.push(bodySchema);
484
+ }
483
485
  }
484
486
  }
485
487
  return partsByStatus;
486
488
  }
489
+ function extractDetailedStatuses(schema) {
490
+ const statuses = /* @__PURE__ */ new Map();
491
+ for (const member of flattenJsonUnionSchema(schema)) {
492
+ if (typeof member !== "object") {
493
+ return void 0;
494
+ }
495
+ const values = member.const !== void 0 ? [member.const] : member.enum;
496
+ if (!values?.length) {
497
+ return void 0;
498
+ }
499
+ for (const value2 of values) {
500
+ if (!Number.isInteger(value2) || value2 >= 400) {
501
+ return void 0;
502
+ }
503
+ if (!statuses.has(value2)) {
504
+ statuses.set(value2, member.description);
505
+ }
506
+ }
507
+ }
508
+ return statuses.size ? statuses : void 0;
509
+ }
487
510
  function buildErrorResponse(ctx, operation, def) {
488
511
  const definitionsByStatus = /* @__PURE__ */ new Map();
489
512
  for (const code of Object.keys(def.errorMap)) {
@@ -4,7 +4,7 @@ import { StandardHandlerCodec, ResolvedStandardHandlerHandleOptions, StandardHan
4
4
  import { Value, Public, Promisable } from '@orpc/shared';
5
5
  import { StandardLazyRequest, StandardResponse } from '@standard-server/core';
6
6
  import { AnyProcedureContract } from '@orpc/contract';
7
- import { O as OpenAPISerializer } from './openapi.C2LayTNZ.js';
7
+ import { O as OpenAPISerializer } from './openapi.DjGhiceP.js';
8
8
 
9
9
  interface OpenAPIMatcherOptions {
10
10
  /**
@@ -4,7 +4,7 @@ import { StandardHandlerCodec, ResolvedStandardHandlerHandleOptions, StandardHan
4
4
  import { Value, Public, Promisable } from '@orpc/shared';
5
5
  import { StandardLazyRequest, StandardResponse } from '@standard-server/core';
6
6
  import { AnyProcedureContract } from '@orpc/contract';
7
- import { O as OpenAPISerializer } from './openapi.C2LayTNZ.mjs';
7
+ import { O as OpenAPISerializer } from './openapi.DjGhiceP.mjs';
8
8
 
9
9
  interface OpenAPIMatcherOptions {
10
10
  /**
@@ -3,7 +3,7 @@ import { StandardLinkCodec, StandardLinkCodecDecodedResponse } from '@orpc/clien
3
3
  import { RouterContract } from '@orpc/contract';
4
4
  import { Value, Promisable, Public } from '@orpc/shared';
5
5
  import { StandardUrl, StandardHeaders, StandardLazyResponse, StandardRequest } from '@standard-server/core';
6
- import { O as OpenAPISerializer } from './openapi.C2LayTNZ.mjs';
6
+ import { O as OpenAPISerializer } from './openapi.DjGhiceP.mjs';
7
7
 
8
8
  interface OpenAPILinkCodecOptions<T extends ClientContext> {
9
9
  /**
@@ -4,9 +4,9 @@ import { unlazy } from '@orpc/server';
4
4
  import { value, pathToHttpPath, mergeHttpPath, isTypescriptObject, stringifyJSON, safeEncodeURIComponent } from '@orpc/shared';
5
5
  import { mergeStandardHeaders, parseStandardUrl } from '@standard-server/core';
6
6
  import { toStandardHeaders } from '@standard-server/fetch';
7
- import { O as OpenAPISerializer, D as DEFAULT_OPENAPI_METHOD, a as DEFAULT_OPENAPI_INPUT_STRUCTURE, g as getDynamicPathParams, i as isBodylessMethod, b as DEFAULT_OPENAPI_OUTPUT_STRUCTURE } from './openapi.Bu_PfTtX.mjs';
7
+ import { O as OpenAPISerializer, D as DEFAULT_OPENAPI_METHOD, a as DEFAULT_OPENAPI_INPUT_STRUCTURE, g as getDynamicPathParams, i as isBodylessMethod, b as DEFAULT_OPENAPI_OUTPUT_STRUCTURE } from './openapi.PXVenYpE.mjs';
8
8
  import { g as getOpenAPIMeta } from './openapi.B9PQzqBn.mjs';
9
- import { s as serializeHeaders } from './openapi.BJRea9Uu.mjs';
9
+ import { s as serializeHeaders } from './openapi.DcQKf6ur.mjs';
10
10
 
11
11
  const END_SLASH_REGEX = /\/$/;
12
12
  const DOT_SEGMENT_REGEX = /(?:^|\/)\.{1,2}(?:\/|$)/;
@@ -1,11 +1,14 @@
1
1
  import { COMMON_ERROR_STATUS_MAP } from '@orpc/client';
2
2
  import { walkProcedureContractsSync, unlazy, getRouter, Procedure, createContractProcedure, DEFAULT_SUCCESS_STATUS, DEFAULT_ERROR_STATUS } from '@orpc/server';
3
- import { value, pathToHttpPath, mergeHttpPath, normalizeHttpPath, setOwn, safeDecodeURIComponent, NullProtoObj, isTypescriptObject, isPlainObject, stringifyJSON, getOwn, parseEmptyableJSON } from '@orpc/shared';
3
+ import { value, pathToHttpPath, mergeHttpPath, safeDecodeURIComponent, safeEncodeURIComponent, setOwn, NullProtoObj, isTypescriptObject, isPlainObject, stringifyJSON, getOwn, parseEmptyableJSON } from '@orpc/shared';
4
4
  import { parseStandardUrl } from '@standard-server/core';
5
- import { D as DEFAULT_OPENAPI_METHOD, g as getDynamicPathParams, O as OpenAPISerializer, a as DEFAULT_OPENAPI_INPUT_STRUCTURE, i as isBodylessMethod, b as DEFAULT_OPENAPI_OUTPUT_STRUCTURE } from './openapi.Bu_PfTtX.mjs';
5
+ import { D as DEFAULT_OPENAPI_METHOD, g as getDynamicPathParams, O as OpenAPISerializer, a as DEFAULT_OPENAPI_INPUT_STRUCTURE, i as isBodylessMethod, b as DEFAULT_OPENAPI_OUTPUT_STRUCTURE } from './openapi.PXVenYpE.mjs';
6
6
  import { g as getOpenAPIMeta } from './openapi.B9PQzqBn.mjs';
7
7
  import { createRouter, addRoute, findRoute, findAllRoutes, routeToRegExp } from 'rou3';
8
8
 
9
+ const ROU3_RAW_CHARS = String.raw`\w!$&'()*+,\-.:;=@[\\\]|~`;
10
+ const NORMALIZABLE_PATHNAME_REGEX = new RegExp(`[^${ROU3_RAW_CHARS}/]`);
11
+ const ROU3_ENCODED_SEGMENT_TEXT_REGEX = new RegExp(`[^${ROU3_RAW_CHARS}]+`, "g");
9
12
  class OpenAPIMatcher {
10
13
  filter;
11
14
  rootRouter;
@@ -73,8 +76,8 @@ class OpenAPIMatcher {
73
76
  await loading;
74
77
  }
75
78
  let match = this.findMatch(method, pathname);
76
- if (match === void 0 && pathname.includes("%")) {
77
- const normalizedPathname = normalizeHttpPath(pathname);
79
+ if (match === void 0 && NORMALIZABLE_PATHNAME_REGEX.test(pathname)) {
80
+ const normalizedPathname = normalizeRou3Path(pathname);
78
81
  const normalizedLoading = this.resolvePendingLazyRouters(normalizedPathname);
79
82
  if (normalizedLoading !== void 0) {
80
83
  await normalizedLoading;
@@ -140,7 +143,7 @@ class OpenAPIMatcher {
140
143
  function toRou3Route(path) {
141
144
  const dynamicParams = getDynamicPathParams(path);
142
145
  if (!dynamicParams) {
143
- return { pattern: escapeRou3Literal(path) };
146
+ return { pattern: toRou3Literal(path) };
144
147
  }
145
148
  let pattern = "";
146
149
  let literalStart = 0;
@@ -149,7 +152,7 @@ function toRou3Route(path) {
149
152
  for (const param of dynamicParams) {
150
153
  const key = `p${params.length}`;
151
154
  params.push([key, param.parameterName]);
152
- pattern += escapeRou3Literal(path.slice(literalStart, param.startIndex));
155
+ pattern += toRou3Literal(path.slice(literalStart, param.startIndex));
153
156
  literalStart = param.startIndex + param.segment.length;
154
157
  if (param.allowsSlash) {
155
158
  if (catchAllKey !== void 0) {
@@ -161,12 +164,16 @@ function toRou3Route(path) {
161
164
  pattern += `:${key}`;
162
165
  }
163
166
  }
164
- pattern += escapeRou3Literal(path.slice(literalStart));
167
+ pattern += toRou3Literal(path.slice(literalStart));
165
168
  return { pattern, params, catchAllKey };
166
169
  }
167
170
  const ROU3_SYNTAX_REGEX = /[\\:*?+(){}]|(?<![^/])\.(?=\.?(?:\/|$))/g;
168
- function escapeRou3Literal(text) {
169
- return text.replace(ROU3_SYNTAX_REGEX, "\\$&");
171
+ function toRou3Literal(text) {
172
+ const normalized = NORMALIZABLE_PATHNAME_REGEX.test(text) ? normalizeRou3Path(text) : text;
173
+ return normalized.replace(ROU3_SYNTAX_REGEX, "\\$&");
174
+ }
175
+ function normalizeRou3Path(path) {
176
+ return path.split("/").map((segment) => safeDecodeURIComponent(segment).replace(ROU3_ENCODED_SEGMENT_TEXT_REGEX, safeEncodeURIComponent)).join("/");
170
177
  }
171
178
  function toRou3PrefixMatcher(prefix) {
172
179
  const catchAll = getDynamicPathParams(prefix)?.find((param) => param.allowsSlash);
@@ -4,22 +4,21 @@ import { Segment } from '@orpc/shared';
4
4
  type BracketNotationSerializeResult = [string, unknown][];
5
5
  interface BracketNotationSerializerOptions {
6
6
  /**
7
- * Maximum explicit array index allowed during deserialization (e.g., `arr[0]`, `arr[999]`).
8
- * If the index exceeds this limit, the array is deserialized as an object instead.
7
+ * Maximum number of empty slots that explicit array indexes may leave in total during deserialization
8
+ * (e.g., `a[0]=x&a[3]=y` leaves 2). An index that would exceed it turns its array into an object
9
+ * instead (e.g., `?arr[5000]=x` becomes `{ arr: { 5000: 'x' } }`).
9
10
  *
10
- * This guards against memory exhaustion attacks where malicious input uses extremely large
11
- * indices (e.g., `?arr[4294967296]=value`). Although orpc uses sparse arrays handle large indices
12
- * efficiently, downstream code may inadvertently densify them - creating millions of
13
- * undefined slots and exhausting memory.
11
+ * Empty slots take memory (a lone `?arr[999]=x` takes ~12KB in V8), and code iterating an array walks
12
+ * every one of them, so this keeps both in line with the input.
14
13
  *
15
- * NOTE: Does not apply to append-style notation (e.g., `arr[]`).
14
+ * NOTE: Append-style notation (e.g., `arr[]`) never leaves empty slots.
16
15
  *
17
- * @default 999 (array with 1,000 elements)
16
+ * @default 1_000
18
17
  */
19
- maxExplicitDeserializingArrayIndex?: number;
18
+ maxDeserializingEmptySlots?: number;
20
19
  }
21
20
  declare class BracketNotationSerializer {
22
- private readonly maxExplicitDeserializingArrayIndex;
21
+ private readonly maxDeserializingEmptySlots;
23
22
  constructor(options?: BracketNotationSerializerOptions);
24
23
  serialize(data: unknown): BracketNotationSerializeResult;
25
24
  private internalSerialize;
@@ -125,7 +124,7 @@ interface OpenAPISerializerSerializeOptions {
125
124
  }
126
125
  interface OpenAPISerializerOptions extends OpenAPIJsonSerializerOptions {
127
126
  /**
128
- * Options for bracket notation serializer, like maxExplicitDeserializingArrayIndex
127
+ * Options for bracket notation serializer, like maxDeserializingEmptySlots
129
128
  */
130
129
  bracketNotation?: BracketNotationSerializerOptions | undefined;
131
130
  /**
@@ -4,22 +4,21 @@ import { Segment } from '@orpc/shared';
4
4
  type BracketNotationSerializeResult = [string, unknown][];
5
5
  interface BracketNotationSerializerOptions {
6
6
  /**
7
- * Maximum explicit array index allowed during deserialization (e.g., `arr[0]`, `arr[999]`).
8
- * If the index exceeds this limit, the array is deserialized as an object instead.
7
+ * Maximum number of empty slots that explicit array indexes may leave in total during deserialization
8
+ * (e.g., `a[0]=x&a[3]=y` leaves 2). An index that would exceed it turns its array into an object
9
+ * instead (e.g., `?arr[5000]=x` becomes `{ arr: { 5000: 'x' } }`).
9
10
  *
10
- * This guards against memory exhaustion attacks where malicious input uses extremely large
11
- * indices (e.g., `?arr[4294967296]=value`). Although orpc uses sparse arrays handle large indices
12
- * efficiently, downstream code may inadvertently densify them - creating millions of
13
- * undefined slots and exhausting memory.
11
+ * Empty slots take memory (a lone `?arr[999]=x` takes ~12KB in V8), and code iterating an array walks
12
+ * every one of them, so this keeps both in line with the input.
14
13
  *
15
- * NOTE: Does not apply to append-style notation (e.g., `arr[]`).
14
+ * NOTE: Append-style notation (e.g., `arr[]`) never leaves empty slots.
16
15
  *
17
- * @default 999 (array with 1,000 elements)
16
+ * @default 1_000
18
17
  */
19
- maxExplicitDeserializingArrayIndex?: number;
18
+ maxDeserializingEmptySlots?: number;
20
19
  }
21
20
  declare class BracketNotationSerializer {
22
- private readonly maxExplicitDeserializingArrayIndex;
21
+ private readonly maxDeserializingEmptySlots;
23
22
  constructor(options?: BracketNotationSerializerOptions);
24
23
  serialize(data: unknown): BracketNotationSerializeResult;
25
24
  private internalSerialize;
@@ -125,7 +124,7 @@ interface OpenAPISerializerSerializeOptions {
125
124
  }
126
125
  interface OpenAPISerializerOptions extends OpenAPIJsonSerializerOptions {
127
126
  /**
128
- * Options for bracket notation serializer, like maxExplicitDeserializingArrayIndex
127
+ * Options for bracket notation serializer, like maxDeserializingEmptySlots
129
128
  */
130
129
  bracketNotation?: BracketNotationSerializerOptions | undefined;
131
130
  /**
@@ -0,0 +1,149 @@
1
+ import { isPlainObject, NullProtoObj, getOwn, setOwn } from '@orpc/shared';
2
+
3
+ class BracketNotationSerializer {
4
+ maxDeserializingEmptySlots;
5
+ constructor(options = {}) {
6
+ this.maxDeserializingEmptySlots = options.maxDeserializingEmptySlots ?? 1e3;
7
+ }
8
+ serialize(data) {
9
+ const result = [];
10
+ this.internalSerialize(data, "", true, result);
11
+ return result;
12
+ }
13
+ internalSerialize(data, path, isRoot, result) {
14
+ if (Array.isArray(data)) {
15
+ data.forEach((item, i) => {
16
+ this.internalSerialize(item, isRoot ? i.toString() : `${path}[${i}]`, false, result);
17
+ });
18
+ } else if (isPlainObject(data)) {
19
+ for (const key of Object.keys(data)) {
20
+ this.internalSerialize(data[key], isRoot ? key : `${path}[${key}]`, false, result);
21
+ }
22
+ } else {
23
+ result.push([path, data]);
24
+ }
25
+ }
26
+ deserialize(serialized) {
27
+ let arrayPushStyles;
28
+ const root = new NullProtoObj();
29
+ let emptySlotsLeft = this.maxDeserializingEmptySlots;
30
+ for (const [path, value] of serialized) {
31
+ const segments = this.parsePath(path);
32
+ let currentRef = root;
33
+ let nextSegment = segments[0];
34
+ for (let i = 1; i < segments.length; i++) {
35
+ const segment = segments[i];
36
+ const isLast = i === segments.length - 1;
37
+ const existing = getOwn(currentRef, nextSegment);
38
+ let child = existing;
39
+ let key = segment;
40
+ if (Array.isArray(child) || !isPlainObject(child)) {
41
+ const isArray = Array.isArray(child);
42
+ const isPushStyle = isArray && !!arrayPushStyles?.has(child);
43
+ const length = isArray ? child.length : 0;
44
+ const index = internalToArrayIndex(segment);
45
+ const emptySlots = index === void 0 ? 0 : Math.max(0, index - length);
46
+ const canBeArray = segment === "" ? isLast && (isPushStyle || length === 0) : index !== void 0 && !(isLast && isPushStyle) && emptySlots <= emptySlotsLeft;
47
+ if (canBeArray) {
48
+ emptySlotsLeft -= emptySlots;
49
+ child = isArray ? child : [];
50
+ key = index ?? segment;
51
+ } else if (isArray) {
52
+ arrayPushStyles?.delete(child);
53
+ child = isPushStyle ? internalPushStyleArrayToObject(child) : internalArrayToObject(child);
54
+ } else {
55
+ child = new NullProtoObj();
56
+ }
57
+ }
58
+ if (child !== existing) {
59
+ internalSetOwn(currentRef, nextSegment, child);
60
+ }
61
+ currentRef = child;
62
+ nextSegment = key;
63
+ }
64
+ if (Array.isArray(currentRef) && nextSegment === "") {
65
+ arrayPushStyles ??= /* @__PURE__ */ new WeakSet();
66
+ arrayPushStyles.add(currentRef);
67
+ currentRef.push(value);
68
+ } else if (Object.hasOwn(currentRef, nextSegment)) {
69
+ const current = currentRef[nextSegment];
70
+ if (Array.isArray(current)) {
71
+ current.push(value);
72
+ } else {
73
+ internalSetOwn(currentRef, nextSegment, [current, value]);
74
+ }
75
+ } else {
76
+ internalSetOwn(currentRef, nextSegment, value);
77
+ }
78
+ }
79
+ return root;
80
+ }
81
+ stringifyPath(segments) {
82
+ if (segments.length === 0) {
83
+ return "";
84
+ }
85
+ let result = segments[0].toString();
86
+ for (let i = 1; i < segments.length; i++) {
87
+ result += `[${segments[i]}]`;
88
+ }
89
+ return result;
90
+ }
91
+ parsePath(path) {
92
+ const start = path.indexOf("[");
93
+ if (start === -1 || path[path.length - 1] !== "]") {
94
+ return [path];
95
+ }
96
+ const segments = [path.slice(0, start)];
97
+ let from = start + 1;
98
+ let to = path.indexOf("][", from);
99
+ while (to !== -1) {
100
+ segments.push(path.slice(from, to));
101
+ from = to + 2;
102
+ to = path.indexOf("][", from);
103
+ }
104
+ segments.push(path.slice(from, -1));
105
+ return segments;
106
+ }
107
+ }
108
+ const MAX_ARRAY_INDEX = 2 ** 32 - 2;
109
+ function internalToArrayIndex(key) {
110
+ if (key.length === 0 || key.length > 10) {
111
+ return void 0;
112
+ }
113
+ let index = key.charCodeAt(0) - 48;
114
+ if (index < 0 || index > 9 || index === 0 && key.length > 1) {
115
+ return void 0;
116
+ }
117
+ for (let i = 1; i < key.length; i++) {
118
+ const digit = key.charCodeAt(i) - 48;
119
+ if (digit < 0 || digit > 9) {
120
+ return void 0;
121
+ }
122
+ index = index * 10 + digit;
123
+ }
124
+ return index <= MAX_ARRAY_INDEX ? index : void 0;
125
+ }
126
+ function internalArrayToObject(array) {
127
+ const obj = new NullProtoObj();
128
+ array.forEach((item, i) => {
129
+ obj[i] = item;
130
+ });
131
+ return obj;
132
+ }
133
+ function internalPushStyleArrayToObject(array) {
134
+ const obj = new NullProtoObj();
135
+ obj[""] = array.length === 1 ? array[0] : array;
136
+ return obj;
137
+ }
138
+ function internalSetOwn(container, key, value) {
139
+ if (typeof key === "string" && container instanceof NullProtoObj) {
140
+ const index = internalToArrayIndex(key);
141
+ if (index !== void 0 && index !== 0 && !Object.hasOwn(container, index - 1) && !Object.hasOwn(container, MAX_ARRAY_INDEX)) {
142
+ container[MAX_ARRAY_INDEX] = void 0;
143
+ delete container[MAX_ARRAY_INDEX];
144
+ }
145
+ }
146
+ setOwn(container, key, value);
147
+ }
148
+
149
+ export { BracketNotationSerializer as B };
@@ -1,7 +1,7 @@
1
1
  import { wrapAsyncIteratorPreservingEventMeta, toORPCError, isORPCErrorJson, createORPCErrorFromJson } from '@orpc/client';
2
2
  import { isPlainObject, NullProtoObj, copyOnWrite, isAsyncIteratorObject } from '@orpc/shared';
3
3
  import { ErrorEvent } from '@standard-server/core';
4
- import { B as BracketNotationSerializer } from './openapi.B2G-HeFn.mjs';
4
+ import { B as BracketNotationSerializer } from './openapi.DtEVcxuW.mjs';
5
5
 
6
6
  const DEFAULT_OPENAPI_METHOD = "POST";
7
7
  const DEFAULT_OPENAPI_SUCCESS_DESCRIPTION = "OK";
@@ -3,7 +3,7 @@ import { StandardLinkCodec, StandardLinkCodecDecodedResponse } from '@orpc/clien
3
3
  import { RouterContract } from '@orpc/contract';
4
4
  import { Value, Promisable, Public } from '@orpc/shared';
5
5
  import { StandardUrl, StandardHeaders, StandardLazyResponse, StandardRequest } from '@standard-server/core';
6
- import { O as OpenAPISerializer } from './openapi.C2LayTNZ.js';
6
+ import { O as OpenAPISerializer } from './openapi.DjGhiceP.js';
7
7
 
8
8
  interface OpenAPILinkCodecOptions<T extends ClientContext> {
9
9
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/openapi",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.42",
4
+ "version": "2.0.0-beta.43",
5
5
  "description": "Generate OpenAPI specs from oRPC routers and serve OpenAPI-compliant APIs with end-to-end type safety",
6
6
  "license": "MIT",
7
7
  "funding": [
@@ -99,18 +99,18 @@
99
99
  "dependencies": {
100
100
  "@openapi-spec/downgrader": "~0.3.0",
101
101
  "@openapi-spec/types": "~0.3.0",
102
- "@orpc/client": "2.0.0-beta.42",
103
- "@orpc/contract": "2.0.0-beta.42",
104
- "@orpc/json-schema": "2.0.0-beta.42",
105
- "@orpc/server": "2.0.0-beta.42",
106
- "@orpc/shared": "2.0.0-beta.42",
107
- "@standard-server/core": "~0.10.1",
108
- "@standard-server/fetch": "~0.10.1",
102
+ "@orpc/client": "2.0.0-beta.43",
103
+ "@orpc/contract": "2.0.0-beta.43",
104
+ "@orpc/json-schema": "2.0.0-beta.43",
105
+ "@orpc/server": "2.0.0-beta.43",
106
+ "@orpc/shared": "2.0.0-beta.43",
107
+ "@standard-server/core": "~0.10.2",
108
+ "@standard-server/fetch": "~0.10.2",
109
109
  "rou3": "^1.0.0"
110
110
  },
111
111
  "devDependencies": {
112
112
  "@scalar/api-reference": "^1.65.1",
113
- "@standard-server/aws-lambda": "~0.10.1",
113
+ "@standard-server/aws-lambda": "~0.10.2",
114
114
  "@types/swagger-ui": "^5.32.0",
115
115
  "fastify": "^5.12.1",
116
116
  "swagger-ui": "^5.32.14",
@@ -1,123 +0,0 @@
1
- import { isPlainObject, NullProtoObj, getOwn, setOwn } from '@orpc/shared';
2
-
3
- class BracketNotationSerializer {
4
- maxExplicitDeserializingArrayIndex;
5
- constructor(options = {}) {
6
- this.maxExplicitDeserializingArrayIndex = options.maxExplicitDeserializingArrayIndex ?? 999;
7
- }
8
- serialize(data) {
9
- const result = [];
10
- this.internalSerialize(data, "", true, result);
11
- return result;
12
- }
13
- internalSerialize(data, path, isRoot, result) {
14
- if (Array.isArray(data)) {
15
- data.forEach((item, i) => {
16
- this.internalSerialize(item, isRoot ? i.toString() : `${path}[${i}]`, false, result);
17
- });
18
- } else if (isPlainObject(data)) {
19
- for (const key of Object.keys(data)) {
20
- this.internalSerialize(data[key], isRoot ? key : `${path}[${key}]`, false, result);
21
- }
22
- } else {
23
- result.push([path, data]);
24
- }
25
- }
26
- deserialize(serialized) {
27
- const arrayPushStyles = /* @__PURE__ */ new WeakSet();
28
- const root = new NullProtoObj();
29
- for (const [path, value] of serialized) {
30
- const segments = this.parsePath(path);
31
- let currentRef = root;
32
- let nextSegment = segments[0];
33
- for (let i = 1; i < segments.length; i++) {
34
- const segment = segments[i];
35
- const isLast = i === segments.length - 1;
36
- const existing = getOwn(currentRef, nextSegment);
37
- let child = existing;
38
- if (!Array.isArray(child) && !isPlainObject(child)) {
39
- child = [];
40
- }
41
- if (Array.isArray(child)) {
42
- const isPushStyle = arrayPushStyles.has(child);
43
- const canStayArray = segment === "" ? isLast && (isPushStyle || child.length === 0) : internalIsValidArrayIndex(segment, this.maxExplicitDeserializingArrayIndex) && !(isLast && isPushStyle);
44
- if (!canStayArray) {
45
- arrayPushStyles.delete(child);
46
- child = isPushStyle ? internalPushStyleArrayToObject(child) : internalArrayToObject(child);
47
- }
48
- }
49
- if (child !== existing) {
50
- setOwn(currentRef, nextSegment, child);
51
- }
52
- currentRef = child;
53
- nextSegment = segment;
54
- }
55
- if (Array.isArray(currentRef) && nextSegment === "") {
56
- arrayPushStyles.add(currentRef);
57
- currentRef.push(value);
58
- } else if (Object.hasOwn(currentRef, nextSegment)) {
59
- const current = currentRef[nextSegment];
60
- if (Array.isArray(current)) {
61
- current.push(value);
62
- } else {
63
- setOwn(currentRef, nextSegment, [current, value]);
64
- }
65
- } else {
66
- setOwn(currentRef, nextSegment, value);
67
- }
68
- }
69
- return root;
70
- }
71
- stringifyPath(segments) {
72
- if (segments.length === 0) {
73
- return "";
74
- }
75
- let result = segments[0].toString();
76
- for (let i = 1; i < segments.length; i++) {
77
- result += `[${segments[i]}]`;
78
- }
79
- return result;
80
- }
81
- parsePath(path) {
82
- const segments = [];
83
- let inBrackets = false;
84
- let currentSegment = "";
85
- for (let i = 0; i < path.length; i++) {
86
- const char = path[i];
87
- const nextChar = path[i + 1];
88
- if (inBrackets && char === "]" && (nextChar === void 0 || nextChar === "[")) {
89
- if (nextChar === void 0) {
90
- inBrackets = false;
91
- }
92
- segments.push(currentSegment);
93
- currentSegment = "";
94
- i++;
95
- } else if (segments.length === 0 && char === "[") {
96
- inBrackets = true;
97
- segments.push(currentSegment);
98
- currentSegment = "";
99
- } else {
100
- currentSegment += char;
101
- }
102
- }
103
- return inBrackets || segments.length === 0 ? [path] : segments;
104
- }
105
- }
106
- const INTEGER_PATTERN = /^0$|^[1-9]\d*$/;
107
- function internalIsValidArrayIndex(value, maxIndex) {
108
- return INTEGER_PATTERN.test(value) && Number(value) <= maxIndex;
109
- }
110
- function internalArrayToObject(array) {
111
- const obj = new NullProtoObj();
112
- array.forEach((item, i) => {
113
- obj[i] = item;
114
- });
115
- return obj;
116
- }
117
- function internalPushStyleArrayToObject(array) {
118
- const obj = new NullProtoObj();
119
- obj[""] = array.length === 1 ? array[0] : array;
120
- return obj;
121
- }
122
-
123
- export { BracketNotationSerializer as B };