@workos/oagen-emitters 0.7.2 → 0.7.3

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.
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.7.2"
2
+ ".": "0.7.3"
3
3
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.3](https://github.com/workos/oagen-emitters/compare/v0.7.2...v0.7.3) (2026-05-02)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * url-encode path parameters in php/node/python/kotlin emitters ([#75](https://github.com/workos/oagen-emitters/issues/75)) ([34c08fc](https://github.com/workos/oagen-emitters/commit/34c08fc10510db53f1f989edab5b4d0cead15aa9))
9
+
3
10
  ## [0.7.2](https://github.com/workos/oagen-emitters/compare/v0.7.1...v0.7.2) (2026-05-01)
4
11
 
5
12
 
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { _ as nodeEmitter, a as rustExtractor, c as pythonExtractor, d as rubyEmitter, f as kotlinEmitter, g as pythonEmitter, h as phpEmitter, i as kotlinExtractor, l as rubyExtractor, m as goEmitter, n as elixirExtractor, o as goExtractor, p as dotnetEmitter, r as dotnetExtractor, s as phpExtractor, t as workosEmittersPlugin, u as nodeExtractor } from "./plugin-CGPujyaL.mjs";
1
+ import { _ as nodeEmitter, a as rustExtractor, c as pythonExtractor, d as rubyEmitter, f as kotlinEmitter, g as pythonEmitter, h as phpEmitter, i as kotlinExtractor, l as rubyExtractor, m as goEmitter, n as elixirExtractor, o as goExtractor, p as dotnetEmitter, r as dotnetExtractor, s as phpExtractor, t as workosEmittersPlugin, u as nodeExtractor } from "./plugin-BoTAX4nl.mjs";
2
2
  export { dotnetEmitter, dotnetExtractor, elixirExtractor, goEmitter, goExtractor, kotlinEmitter, kotlinExtractor, nodeEmitter, nodeExtractor, phpEmitter, phpExtractor, pythonEmitter, pythonExtractor, rubyEmitter, rubyExtractor, rustExtractor, workosEmittersPlugin };
@@ -4475,6 +4475,79 @@ function formatWrapperDescription(name) {
4475
4475
  return name.split("_").map((w, i) => i === 0 ? w.charAt(0).toUpperCase() + w.slice(1) : w).join(" ");
4476
4476
  }
4477
4477
  //#endregion
4478
+ //#region src/shared/path-template.ts
4479
+ /**
4480
+ * Parse an OpenAPI path template into an ordered list of literal and
4481
+ * parameter segments. Adjacent literals are coalesced into a single segment
4482
+ * (the only way two literals can be adjacent is if the input had `{}{}`
4483
+ * which is malformed; we still handle it deterministically).
4484
+ *
4485
+ * Examples:
4486
+ * "/orgs/{id}/users/{uid}" → [
4487
+ * { kind: 'literal', value: '/orgs/' },
4488
+ * { kind: 'param', name: 'id' },
4489
+ * { kind: 'literal', value: '/users/' },
4490
+ * { kind: 'param', name: 'uid' },
4491
+ * ]
4492
+ * "/health" → [{ kind: 'literal', value: '/health' }]
4493
+ * "" → []
4494
+ */
4495
+ function parsePathTemplate(path, options = {}) {
4496
+ const normalized = options.stripLeadingSlash && path.startsWith("/") ? path.slice(1) : path;
4497
+ if (normalized === "") return [];
4498
+ const segments = [];
4499
+ const re = /\{([^{}]+)\}/g;
4500
+ let cursor = 0;
4501
+ let m;
4502
+ while ((m = re.exec(normalized)) !== null) {
4503
+ if (m.index > cursor) segments.push({
4504
+ kind: "literal",
4505
+ value: normalized.slice(cursor, m.index)
4506
+ });
4507
+ segments.push({
4508
+ kind: "param",
4509
+ name: m[1]
4510
+ });
4511
+ cursor = m.index + m[0].length;
4512
+ }
4513
+ if (cursor < normalized.length) segments.push({
4514
+ kind: "literal",
4515
+ value: normalized.slice(cursor)
4516
+ });
4517
+ return segments;
4518
+ }
4519
+ /** True when at least one segment is a parameter placeholder. */
4520
+ function hasPathParams(segments) {
4521
+ return segments.some((s) => s.kind === "param");
4522
+ }
4523
+ //#endregion
4524
+ //#region src/node/path-expression.ts
4525
+ /**
4526
+ * Build the TypeScript expression that the SDK passes as the request path.
4527
+ *
4528
+ * Every {paramName} placeholder becomes `${encodeURIComponent(name)}` inside a
4529
+ * template literal. encodeURIComponent is used (not encodeURI) because we want
4530
+ * "/" to be encoded too — otherwise a caller-supplied id containing "../" can
4531
+ * be normalized by the underlying HTTP transport (libcurl, fetch, etc.) into
4532
+ * a different endpoint of the WorkOS API while still authenticated with the
4533
+ * application's API key.
4534
+ *
4535
+ * "/orgs" → `'orgs'`
4536
+ * "/orgs/{id}" → `` `orgs/${encodeURIComponent(id)}` ``
4537
+ * "/orgs/{id}/foo" → `` `orgs/${encodeURIComponent(id)}/foo` ``
4538
+ */
4539
+ function buildNodePathExpression(rawPath) {
4540
+ const segments = parsePathTemplate(rawPath);
4541
+ if (!hasPathParams(segments)) return `'${rawPath}'`;
4542
+ let body = "";
4543
+ for (const seg of segments) body += renderSegment(seg);
4544
+ return `\`${body}\``;
4545
+ }
4546
+ function renderSegment(seg) {
4547
+ if (seg.kind === "literal") return seg.value.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
4548
+ return `\${encodeURIComponent(${fieldName$5(seg.name)})}`;
4549
+ }
4550
+ //#endregion
4478
4551
  //#region src/node/wrappers.ts
4479
4552
  /**
4480
4553
  * Generate TypeScript wrapper method lines for union split operations.
@@ -4564,8 +4637,7 @@ function emitWrapperMethod$6(lines, resolvedOp, wrapper, ctx) {
4564
4637
  }
4565
4638
  /** Build a path template string from an Operation. */
4566
4639
  function buildPathStr$1(op) {
4567
- const interpolated = op.path.replace(/\{(\w+)\}/g, (_, p) => `\${${fieldName$5(p)}}`);
4568
- return interpolated.includes("${") ? `\`${interpolated}\`` : `'${op.path}'`;
4640
+ return buildNodePathExpression(op.path);
4569
4641
  }
4570
4642
  /** Convert a JS value to a TypeScript literal. */
4571
4643
  function tsLiteral$1(value) {
@@ -5365,8 +5437,7 @@ function renderQueryExpr(queryParams) {
5365
5437
  return `options ? { ${parts.join(", ")} } : undefined`;
5366
5438
  }
5367
5439
  function buildPathStr(op) {
5368
- const interpolated = op.path.replace(/\{(\w+)\}/g, (_, p) => `\${${fieldName$5(p)}}`);
5369
- return interpolated.includes("${") ? `\`${interpolated}\`` : `'${op.path}'`;
5440
+ return buildNodePathExpression(op.path);
5370
5441
  }
5371
5442
  function buildPathParams(op, specEnumNames) {
5372
5443
  const declaredNames = new Set(op.pathParams.map((p) => fieldName$5(p.name)));
@@ -7638,6 +7709,46 @@ function buildRecursiveHashMap$1(models, enums) {
7638
7709
  return hashCache;
7639
7710
  }
7640
7711
  //#endregion
7712
+ //#region src/python/path-expression.ts
7713
+ /**
7714
+ * Build the Python f-string that the SDK passes to the request layer.
7715
+ *
7716
+ * Every {paramName} placeholder is wrapped in
7717
+ * `urllib.parse.quote(str(...), safe="")` so that an unencoded "/" or "../"
7718
+ * in a caller-supplied id cannot be normalized by the underlying HTTP
7719
+ * transport into a different endpoint of the WorkOS API while still
7720
+ * authenticated with the application's API key. `safe=""` is critical:
7721
+ * the stdlib default of `safe="/"` does NOT encode "/" and would leave the
7722
+ * traversal vector open.
7723
+ *
7724
+ * Generated files using this helper must import `quote` (e.g.
7725
+ * `from urllib.parse import quote`).
7726
+ *
7727
+ * "/orgs" → `"orgs"`
7728
+ * "/orgs/{id}" → `f"orgs/{quote(str(id), safe='')}"`
7729
+ * "/orgs/{id}" with id ∈ enums → `f"orgs/{quote(str(enum_value(id)), safe='')}"`
7730
+ */
7731
+ function buildPythonPathExpression(rawPath, options = {}) {
7732
+ const segments = parsePathTemplate(rawPath, { stripLeadingSlash: true });
7733
+ if (segments.length === 0) return "\"\"";
7734
+ if (!hasPathParams(segments)) {
7735
+ const literal = segments[0].value;
7736
+ return `"${escapePyDoubleQuoted(literal)}"`;
7737
+ }
7738
+ const enums = options.enumParams;
7739
+ let body = "";
7740
+ for (const seg of segments) if (seg.kind === "literal") body += escapePyDoubleQuoted(seg.value);
7741
+ else {
7742
+ const varName = fieldName$4(seg.name);
7743
+ const inner = enums?.has(seg.name) ? `enum_value(${varName})` : varName;
7744
+ body += `{quote(str(${inner}), safe='')}`;
7745
+ }
7746
+ return `f"${body}"`;
7747
+ }
7748
+ function escapePyDoubleQuoted(literal) {
7749
+ return literal.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\{/g, "{{").replace(/\}/g, "}}");
7750
+ }
7751
+ //#endregion
7641
7752
  //#region src/python/wrappers.ts
7642
7753
  /**
7643
7754
  * Generate Python wrapper method lines for split operations.
@@ -7707,12 +7818,7 @@ function emitWrapperMethod$5(lines, resolvedOp, wrapper, ctx, isAsync) {
7707
7818
  lines.push(` if ${pyName} is not None:`);
7708
7819
  lines.push(` body["${paramName}"] = ${pyName}`);
7709
7820
  }
7710
- let pathExpr;
7711
- if (op.pathParams.length > 0) {
7712
- let path = op.path.replace(/^\//, "");
7713
- for (const p of op.pathParams) path = path.replace(`{${p.name}}`, `{${fieldName$4(p.name)}}`);
7714
- pathExpr = `f"${path}"`;
7715
- } else pathExpr = `"${op.path.replace(/^\//, "")}"`;
7821
+ const pathExpr = buildPythonPathExpression(op.path);
7716
7822
  const awaitPrefix = isAsync ? "await " : "";
7717
7823
  lines.push("");
7718
7824
  if (wrapper.responseModelName) {
@@ -8397,6 +8503,7 @@ function generateResources$5(services, ctx) {
8397
8503
  lines.push("from __future__ import annotations");
8398
8504
  lines.push("");
8399
8505
  lines.push("from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Type, Union, cast");
8506
+ if (allOperations.some((op) => op.pathParams.length > 0) || allOperations.some((op) => /\{[^{}]+\}/.test(op.path))) lines.push("from urllib.parse import quote");
8400
8507
  lines.push("");
8401
8508
  lines.push("if TYPE_CHECKING:");
8402
8509
  lines.push(` from ${importPrefix}_client import AsyncWorkOSClient, WorkOSClient`);
@@ -8699,15 +8806,12 @@ function buildErrorRaisesBlock(op) {
8699
8806
  }
8700
8807
  /**
8701
8808
  * Build a Python f-string path expression from an operation path.
8702
- * E.g., "/organizations/{id}" -> f"organizations/{id}"
8809
+ * E.g., "/organizations/{id}" -> f"organizations/{quote(str(id), safe='')}"
8703
8810
  */
8704
8811
  function buildPathString$1(op) {
8705
- const path = op.path.replace(/^\//, "");
8706
- if (op.pathParams.length === 0) return `"${path}"`;
8707
- let fPath = path;
8708
- for (const param of op.pathParams) if (param.type.kind === "enum" || param.type.kind === "nullable" && param.type.inner?.kind === "enum") fPath = fPath.replace(`{${param.name}}`, `{enum_value(${fieldName$4(param.name)})}`);
8709
- else fPath = fPath.replace(`{${param.name}}`, `{${fieldName$4(param.name)}}`);
8710
- return `f"${fPath}"`;
8812
+ const enumParams = /* @__PURE__ */ new Set();
8813
+ for (const p of op.pathParams) if (p.type.kind === "enum" || p.type.kind === "nullable" && p.type.inner?.kind === "enum") enumParams.add(p.name);
8814
+ return buildPythonPathExpression(op.path, { enumParams });
8711
8815
  }
8712
8816
  //#endregion
8713
8817
  //#region src/shared/non-spec-services.ts
@@ -10794,6 +10898,39 @@ function generateEnums$4(enums, ctx) {
10794
10898
  return files;
10795
10899
  }
10796
10900
  //#endregion
10901
+ //#region src/php/path-expression.ts
10902
+ /**
10903
+ * Build the PHP expression that the SDK passes to HttpClient as `path:`.
10904
+ *
10905
+ * Concatenation, not interpolation: PHP does not allow function calls inside
10906
+ * "..." strings, and every parameter must be wrapped in `rawurlencode(...)` so
10907
+ * that an unencoded "../" in a caller-supplied id cannot be normalized by
10908
+ * libcurl into a different endpoint of the WorkOS API while still
10909
+ * authenticated with the application's API key.
10910
+ *
10911
+ * "/orgs" → `'orgs'`
10912
+ * "/orgs/{id}" → `'orgs/' . rawurlencode($id)`
10913
+ * "/orgs/{id}/users" → `'orgs/' . rawurlencode($id) . '/users'`
10914
+ * "/orgs/{id}" with id ∈ valueAccessorParams → `'orgs/' . rawurlencode($id->value)`
10915
+ */
10916
+ function buildPhpPathExpression(rawPath, options = {}) {
10917
+ const segments = parsePathTemplate(rawPath, { stripLeadingSlash: true });
10918
+ if (segments.length === 0) return "''";
10919
+ if (!hasPathParams(segments)) return phpSingleQuoted(segments[0].value);
10920
+ const valueAccessor = options.valueAccessorParams;
10921
+ const parts = [];
10922
+ for (const seg of segments) if (seg.kind === "literal") parts.push(phpSingleQuoted(seg.value));
10923
+ else {
10924
+ const varName = fieldName$3(seg.name);
10925
+ const accessor = valueAccessor?.has(seg.name) ? `$${varName}->value` : `$${varName}`;
10926
+ parts.push(`rawurlencode(${accessor})`);
10927
+ }
10928
+ return parts.join(" . ");
10929
+ }
10930
+ function phpSingleQuoted(literal) {
10931
+ return `'${literal.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
10932
+ }
10933
+ //#endregion
10797
10934
  //#region src/php/wrappers.ts
10798
10935
  /**
10799
10936
  * Generate PHP wrapper methods for split union operations.
@@ -10853,14 +10990,11 @@ function emitWrapperMethod$4(lines, resolvedOp, wrapper, ctx) {
10853
10990
  lines.push(` $body['${clientField}'] = ${clientExpr};`);
10854
10991
  }
10855
10992
  const httpMethod = op.httpMethod.toUpperCase();
10856
- let path = op.path.startsWith("/") ? op.path.slice(1) : op.path;
10857
- const hasInterpolation = /\{[^}]+\}/.test(path);
10858
- path = path.replace(/\{([^}]+)\}/g, (_match, param) => `{$${fieldName$3(param)}}`);
10859
- const pathQuote = hasInterpolation ? "\"" : "'";
10993
+ const pathExpr = buildPhpPathExpression(op.path);
10860
10994
  lines.push("");
10861
10995
  lines.push(" $response = $this->client->request(");
10862
10996
  lines.push(` method: '${httpMethod}',`);
10863
- lines.push(` path: ${pathQuote}${path}${pathQuote},`);
10997
+ lines.push(` path: ${pathExpr},`);
10864
10998
  lines.push(" body: $body,");
10865
10999
  lines.push(" options: $options,");
10866
11000
  lines.push(" );");
@@ -11345,16 +11479,9 @@ function buildBodyParamMap(op, bodyModel) {
11345
11479
  return map;
11346
11480
  }
11347
11481
  function buildPathString(op) {
11348
- let path = op.path.startsWith("/") ? op.path.slice(1) : op.path;
11349
- if (op.pathParams.length === 0) return `'${path}'`;
11350
- const paramExprs = /* @__PURE__ */ new Map();
11351
- for (const p of op.pathParams) {
11352
- const phpName = fieldName$3(p.name);
11353
- const isEnum = p.type.kind === "enum" || p.type.kind === "model";
11354
- paramExprs.set(p.name, isEnum ? `{$${phpName}->value}` : `{$${phpName}}`);
11355
- }
11356
- path = path.replace(/\{([^}]+)\}/g, (_match, param) => paramExprs.get(param) ?? `{$${fieldName$3(param)}}`);
11357
- return `"${path}"`;
11482
+ const valueAccessor = /* @__PURE__ */ new Set();
11483
+ for (const p of op.pathParams) if (p.type.kind === "enum" || p.type.kind === "model") valueAccessor.add(p.name);
11484
+ return buildPhpPathExpression(op.path, { valueAccessorParams: valueAccessor });
11358
11485
  }
11359
11486
  function isEnumType(ref) {
11360
11487
  if (ref.kind === "enum") return true;
@@ -13258,7 +13385,7 @@ function generateMethod$1(serviceType, mountName, method, op, plan, _ctx, resolv
13258
13385
  if (paramsType) params.push(`params ${paramsType}`);
13259
13386
  params.push("opts ...RequestOption");
13260
13387
  lines.push(`func (s *${serviceType}) ${method}(${params.join(", ")}) ${returnType} {`);
13261
- const pathExpr = buildPathExpr$2(op);
13388
+ const pathExpr = buildPathExpr$1(op);
13262
13389
  if (isUrlBuilder) {
13263
13390
  emitUrlBuilderMethod(lines, op, pathExpr, resolvedOp, paramsType);
13264
13391
  lines.push("}");
@@ -13557,7 +13684,7 @@ function needsStringsImport(operations, resolvedLookup) {
13557
13684
  }
13558
13685
  return false;
13559
13686
  }
13560
- function buildPathExpr$2(op) {
13687
+ function buildPathExpr$1(op) {
13561
13688
  if (op.pathParams.length === 0) return `"${op.path}"`;
13562
13689
  let fmtStr = op.path;
13563
13690
  const args = [];
@@ -16001,7 +16128,7 @@ function generateMethod(_serviceType, mountName, method, methodStem, op, plan, c
16001
16128
  for (const field of inferFromClient) if (field === "client_id") lines.push(` options.${fieldName$1(field)} = this.Client.RequireClientId();`);
16002
16129
  else lines.push(` options.${fieldName$1(field)} = this.Client.${clientFieldExpression$1(field)} ?? string.Empty;`);
16003
16130
  }
16004
- const pathExpr = buildPathExpr$1(op);
16131
+ const pathExpr = buildPathExpr(op);
16005
16132
  const needsInlineRequest = isUrlBuilder || hasBearerOverride && !!bearerParamName || hasGroups;
16006
16133
  const optionsArg = optionsClass ? "options" : "null";
16007
16134
  if (needsInlineRequest) {
@@ -16065,7 +16192,7 @@ function generateAutoPagingMethod(mountName, method, methodStem, op, plan, ctx,
16065
16192
  params.push("CancellationToken cancellationToken = default");
16066
16193
  lines.push(` public virtual IAsyncEnumerable<${itemType}> ${methodStem}AutoPagingAsync(${params.join(", ")})`);
16067
16194
  lines.push(" {");
16068
- const pathExpr = buildPathExpr$1(op);
16195
+ const pathExpr = buildPathExpr(op);
16069
16196
  const optionsArg = optionsClass ? "options" : "null";
16070
16197
  lines.push(` return this.ListAutoPagingAsync<${itemType}>(${pathExpr}, ${optionsArg}, requestOptions, cancellationToken);`);
16071
16198
  lines.push(" }");
@@ -16089,7 +16216,7 @@ function optionsClassName(mountName, method) {
16089
16216
  if (methodStem.startsWith(prefix)) return `${methodStem}Options`;
16090
16217
  return `${prefix}${methodStem}Options`;
16091
16218
  }
16092
- function buildPathExpr$1(op) {
16219
+ function buildPathExpr(op) {
16093
16220
  if (op.pathParams.length === 0) return `"${op.path}"`;
16094
16221
  let interpolated = op.path;
16095
16222
  for (const p of sortPathParamsByTemplateOrder$1(op)) interpolated = interpolated.replace(`{${p.name}}`, `{Uri.EscapeDataString(${localName(p.name)})}`);
@@ -17868,6 +17995,45 @@ function structuralHash(model) {
17868
17995
  return model.fields.map((f) => `${f.name}:${JSON.stringify(normalizeTypeForHash(f.type))}:${f.required}`).sort().join("|");
17869
17996
  }
17870
17997
  //#endregion
17998
+ //#region src/kotlin/path-expression.ts
17999
+ /**
18000
+ * The fully-qualified runtime helper that the generated code calls. Kotlin
18001
+ * doesn't ship a path-segment URL encoder out of the box (java.net.URLEncoder
18002
+ * is form-encoding — it encodes space as "+", which is wrong for path
18003
+ * segments). The runtime helper lives in workos-kotlin at
18004
+ * com.workos.common.http.encodePathSegment.
18005
+ */
18006
+ const KOTLIN_PATH_ENCODE_IMPORT = "com.workos.common.http.encodePathSegment";
18007
+ /**
18008
+ * Build the Kotlin string-template that the SDK passes as the request path.
18009
+ *
18010
+ * Every {paramName} placeholder is wrapped in `encodePathSegment(...)` so a
18011
+ * caller-supplied id containing "../" cannot be normalized by the underlying
18012
+ * HTTP transport into a different endpoint of the WorkOS API while still
18013
+ * authenticated with the application's API key.
18014
+ *
18015
+ * "/orgs" → `"orgs"`
18016
+ * "/orgs/{id}" → `"orgs/${encodePathSegment(id)}"`
18017
+ * "/orgs/{id}/foo" → `"orgs/${encodePathSegment(id)}/foo"`
18018
+ */
18019
+ function buildKotlinPathExpression(rawPath) {
18020
+ const segments = parsePathTemplate(rawPath);
18021
+ if (!hasPathParams(segments)) return {
18022
+ expression: ktLiteral(rawPath),
18023
+ requiresEncodeImport: false
18024
+ };
18025
+ let body = "";
18026
+ for (const seg of segments) if (seg.kind === "literal") body += escapeKotlinStringLiteral(seg.value);
18027
+ else body += `\${encodePathSegment(${propertyName(seg.name)})}`;
18028
+ return {
18029
+ expression: `"${body}"`,
18030
+ requiresEncodeImport: true
18031
+ };
18032
+ }
18033
+ function escapeKotlinStringLiteral(literal) {
18034
+ return literal.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\$/g, "\\$");
18035
+ }
18036
+ //#endregion
17871
18037
  //#region src/kotlin/wrappers.ts
17872
18038
  /**
17873
18039
  * Emit Kotlin wrapper methods for a union-split operation. Each wrapper
@@ -17953,7 +18119,7 @@ function emitWrapperMethod$1(resolvedOp, wrapper, ctx) {
17953
18119
  }
17954
18120
  lines.push(` )`);
17955
18121
  } else lines.push(` val body = linkedMapOf<String, Any?>()`);
17956
- const pathExpr = buildPathExpr(op.path, pathParams);
18122
+ const pathExpr = buildKotlinPathExpression(op.path).expression;
17957
18123
  const httpMethod = op.httpMethod.toUpperCase();
17958
18124
  lines.push(` val config =`);
17959
18125
  lines.push(` RequestConfig(`);
@@ -17971,17 +18137,6 @@ function emitWrapperMethod$1(resolvedOp, wrapper, ctx) {
17971
18137
  function escapeKdoc$1(s) {
17972
18138
  return s.replace(/\*\//g, "*​/");
17973
18139
  }
17974
- function buildPathExpr(path, pathParams) {
17975
- if (pathParams.length === 0) return ktLiteral(path);
17976
- let result = path;
17977
- for (const pp of pathParams) {
17978
- const placeholder = `{${pp.name}}`;
17979
- const propName = propertyName(pp.name);
17980
- const replacement = /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(propName) ? `\$${propName}` : `\${${propName}}`;
17981
- result = result.replaceAll(placeholder, replacement);
17982
- }
17983
- return `"${result.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
17984
- }
17985
18140
  //#endregion
17986
18141
  //#region src/kotlin/overrides.ts
17987
18142
  /**
@@ -18054,6 +18209,7 @@ function generateApiClass(mountName, operations, ctx, resolvedLookup) {
18054
18209
  for (const rp of resolvedParams) if (rp.field) registerTypeImports(rp.field.type, imports, ctx);
18055
18210
  }
18056
18211
  imports.add("com.workos.common.http.bodyOf");
18212
+ if (/\{[^{}]+\}/.test(resolvedOp.operation.path)) imports.add(KOTLIN_PATH_ENCODE_IMPORT);
18057
18213
  const wrapperLines = generateWrapperMethods$1(resolvedOp, ctx);
18058
18214
  if (body.length > 0) body.push("");
18059
18215
  for (const line of wrapperLines) body.push(line);
@@ -18216,7 +18372,9 @@ function renderMethod(_mountName, method, op, ctx, resolvedOp, imports) {
18216
18372
  const specDeclaresBody = op.requestBody !== void 0;
18217
18373
  const hasBody = methodAlwaysHasBody || specDeclaresBody && httpMethod !== "GET" || (httpMethod === "PUT" || httpMethod === "PATCH" || httpMethod === "POST" || httpMethod === "DELETE") && (Object.keys(defaults).length > 0 || inferFromClient.length > 0) && specDeclaresBody;
18218
18374
  const appendDefaultsAsQuery = !hasBody && (Object.keys(defaults).length > 0 || inferFromClient.length > 0);
18219
- const pathExpr = buildPathExpression(op.path, pathParams);
18375
+ const pathBuilt = buildKotlinPathExpression(op.path);
18376
+ const pathExpr = pathBuilt.expression;
18377
+ if (pathBuilt.requiresEncodeImport) imports.add(KOTLIN_PATH_ENCODE_IMPORT);
18220
18378
  if (op.path === "/user_management/authenticate" && httpMethod === "POST" && plan.responseModelName === "AuthenticateResponse") {
18221
18379
  imports.add("com.workos.models.AuthenticateResponse");
18222
18380
  const grantType = defaults.grant_type ?? "authorization_code";
@@ -18439,20 +18597,6 @@ function queryParamToString(type, varName) {
18439
18597
  if (type.kind === "primitive" && type.type === "string") return varName;
18440
18598
  return `${varName}.toString()`;
18441
18599
  }
18442
- function buildPathExpression(path, pathParams) {
18443
- if (pathParams.length === 0) return ktLiteral(path);
18444
- let result = path;
18445
- for (const pp of pathParams) {
18446
- const placeholder = `{${pp.name}}`;
18447
- const propName = propertyName(pp.name);
18448
- const replacement = isBareIdentifier(propName) ? `\$${propName}` : `\${${propName}}`;
18449
- result = result.replaceAll(placeholder, replacement);
18450
- }
18451
- return `"${result.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
18452
- }
18453
- function isBareIdentifier(name) {
18454
- return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name);
18455
- }
18456
18600
  function pickNamedQueryParam(sorted, name) {
18457
18601
  const match = sorted.find((p) => p.name === name);
18458
18602
  return match ? propertyName(match.name) : "null";
@@ -22009,4 +22153,4 @@ const workosEmittersPlugin = {
22009
22153
  //#endregion
22010
22154
  export { nodeEmitter as _, rustExtractor as a, pythonExtractor as c, rubyEmitter as d, kotlinEmitter as f, pythonEmitter as g, phpEmitter as h, kotlinExtractor as i, rubyExtractor as l, goEmitter as m, elixirExtractor as n, goExtractor as o, dotnetEmitter as p, dotnetExtractor as r, phpExtractor as s, workosEmittersPlugin as t, nodeExtractor as u };
22011
22155
 
22012
- //# sourceMappingURL=plugin-CGPujyaL.mjs.map
22156
+ //# sourceMappingURL=plugin-BoTAX4nl.mjs.map