@techspokes/typescript-wsdl-client 0.18.0 → 0.19.2

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 (42) hide show
  1. package/README.md +1 -1
  2. package/dist/app/generateApp.d.ts +1 -0
  3. package/dist/app/generateApp.d.ts.map +1 -1
  4. package/dist/app/generateApp.js +73 -6
  5. package/dist/cli.js +12 -2
  6. package/dist/gateway/helpers.js +2 -2
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +1 -0
  10. package/dist/openapi/casing.d.ts +0 -14
  11. package/dist/openapi/casing.d.ts.map +1 -1
  12. package/dist/openapi/casing.js +3 -3
  13. package/dist/openapi/generateOpenAPI.d.ts.map +1 -1
  14. package/dist/openapi/generateOpenAPI.js +3 -0
  15. package/dist/openapi/security.d.ts +1 -81
  16. package/dist/openapi/security.d.ts.map +1 -1
  17. package/dist/openapi/security.js +1 -146
  18. package/dist/pipeline.d.ts +1 -0
  19. package/dist/pipeline.d.ts.map +1 -1
  20. package/dist/pipeline.js +1 -0
  21. package/dist/test/generateTests.js +2 -2
  22. package/dist/util/builder.js +1 -1
  23. package/dist/util/runtimeSource.d.ts +1 -0
  24. package/dist/util/runtimeSource.d.ts.map +1 -1
  25. package/dist/util/runtimeSource.js +4 -0
  26. package/dist/util/securityConfig.d.ts +115 -0
  27. package/dist/util/securityConfig.d.ts.map +1 -0
  28. package/dist/util/securityConfig.js +274 -0
  29. package/dist/util/tools.d.ts +8 -0
  30. package/dist/util/tools.d.ts.map +1 -1
  31. package/dist/util/tools.js +16 -0
  32. package/docs/README.md +2 -2
  33. package/docs/api-reference.md +28 -4
  34. package/docs/architecture.md +1 -1
  35. package/docs/cli-reference.md +4 -1
  36. package/docs/configuration.md +33 -18
  37. package/docs/gateway-guide.md +8 -8
  38. package/docs/generated-code.md +7 -0
  39. package/docs/migration-playbook.md +14 -5
  40. package/docs/troubleshooting.md +1 -1
  41. package/package.json +1 -1
  42. package/src/runtime/appSecurity.tpl.txt +108 -0
package/README.md CHANGED
@@ -211,7 +211,7 @@ See [CLI Reference](docs/cli-reference.md) for all flags and examples.
211
211
  |-------|-------------|
212
212
  | [CLI Reference](docs/cli-reference.md) | All commands with flags and examples |
213
213
  | [Working With Generated Code](docs/generated-code.md) | Using clients, types, and operations |
214
- | [Configuration](docs/configuration.md) | Security schemes, tags, operation overrides |
214
+ | [Configuration](docs/configuration.md) | Gateway security, upstream SOAP security, tags, operation overrides |
215
215
  | [Migration Playbook](docs/migration-playbook.md) | End-to-end SOAP modernization guide |
216
216
 
217
217
  ### Operate
@@ -28,6 +28,7 @@ export interface GenerateAppOptions {
28
28
  logger?: boolean;
29
29
  openapiMode?: "copy" | "reference";
30
30
  force?: boolean;
31
+ securityConfigFile?: string;
31
32
  }
32
33
  /**
33
34
  * Generates a runnable Fastify application scaffold
@@ -1 +1 @@
1
- {"version":3,"file":"generateApp.d.ts","sourceRoot":"","sources":["../../src/app/generateApp.ts"],"names":[],"mappings":"AA8BA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA6kBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDzE"}
1
+ {"version":3,"file":"generateApp.d.ts","sourceRoot":"","sources":["../../src/app/generateApp.ts"],"names":[],"mappings":"AAgCA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAmpBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDzE"}
@@ -26,6 +26,8 @@ import path from "node:path";
26
26
  import { deriveClientName } from "../util/tools.js";
27
27
  import { info, success } from "../util/cli.js";
28
28
  import { computeRelativeImport } from "../util/imports.js";
29
+ import { loadRuntimeTemplate } from "../util/runtimeSource.js";
30
+ import { hasUpstreamRuntimeSecurity, loadSecurityConfigFile } from "../util/securityConfig.js";
29
31
  /**
30
32
  * Validates that all required files and directories exist
31
33
  *
@@ -38,6 +40,7 @@ function validateRequiredFiles(opts) {
38
40
  { path: opts.gatewayDir, type: "directory", label: "Gateway directory" },
39
41
  { path: opts.catalogFile, type: "file", label: "Catalog file" },
40
42
  { path: opts.openapiFile, type: "file", label: "OpenAPI file" },
43
+ ...(opts.securityConfigFile ? [{ path: opts.securityConfigFile, type: "file", label: "Security config file" }] : []),
41
44
  ];
42
45
  for (const check of checks) {
43
46
  const exists = fs.existsSync(check.path);
@@ -160,6 +163,21 @@ function generateServerFile(appDir, opts, clientClassName, force) {
160
163
  const configImport = computeRelativeImport(appDir, path.join(appDir, "config"), imports);
161
164
  const gatewayPluginImport = computeRelativeImport(appDir, path.join(opts.gatewayDir, "plugin"), imports);
162
165
  const clientImport = computeRelativeImport(appDir, path.join(opts.clientDir, "client"), imports);
166
+ const securityCfg = loadOptionalSecurityConfig(opts.securityConfigFile);
167
+ const emitSecurity = hasUpstreamRuntimeSecurity(securityCfg);
168
+ const securityImport = emitSecurity
169
+ ? `import { buildSoapRuntimeConfig } from "${computeRelativeImport(appDir, path.join(appDir, "security"), imports)}";\n`
170
+ : "";
171
+ const clientConstruction = emitSecurity
172
+ ? ` const soapRuntime = buildSoapRuntimeConfig();
173
+ const client = new ${clientClassName}({
174
+ source: config.wsdlSource,
175
+ options: soapRuntime.options,
176
+ security: soapRuntime.security,
177
+ });`
178
+ : ` const client = new ${clientClassName}({
179
+ source: config.wsdlSource,
180
+ });`;
163
181
  // For OpenAPI serving, we need to read and parse the file at startup in ESM mode
164
182
  const openapiServeLogic = opts.openapiMode === "copy"
165
183
  ? `
@@ -209,6 +227,7 @@ import Fastify from "fastify";
209
227
  import { loadConfig } from "${configImport}";
210
228
  import gatewayPlugin from "${gatewayPluginImport}";
211
229
  import { ${clientClassName} } from "${clientImport}";
230
+ ${securityImport}
212
231
 
213
232
  // ES module dirname/filename helpers
214
233
  const __filename = fileURLToPath(import.meta.url);
@@ -227,9 +246,7 @@ async function main() {
227
246
  });
228
247
 
229
248
  // Instantiate SOAP client
230
- const client = new ${clientClassName}({
231
- source: config.wsdlSource,
232
- });
249
+ ${clientConstruction}
233
250
 
234
251
  // Register gateway plugin
235
252
  await fastify.register(gatewayPlugin, {
@@ -366,6 +383,30 @@ export function loadConfig(): AppConfig {
366
383
  `;
367
384
  fs.writeFileSync(filePath, content, "utf-8");
368
385
  }
386
+ function loadOptionalSecurityConfig(filePath) {
387
+ return filePath ? loadSecurityConfigFile(filePath) : undefined;
388
+ }
389
+ function collectSecurityEnvVars(cfg) {
390
+ const upstream = cfg?.upstream;
391
+ if (!upstream)
392
+ return [];
393
+ const names = [
394
+ upstream.usernameEnv,
395
+ upstream.passwordEnv,
396
+ upstream.tokenEnv,
397
+ upstream.domainEnv,
398
+ upstream.workstationEnv,
399
+ upstream.keyFileEnv,
400
+ upstream.certFileEnv,
401
+ upstream.caFileEnv,
402
+ upstream.pfxFileEnv,
403
+ upstream.passphraseEnv,
404
+ upstream.endpointEnv,
405
+ ...Object.values(upstream.wsdlHeaderEnv || {}),
406
+ ...Object.values(upstream.requestHeaderEnv || {}),
407
+ ].filter((v) => typeof v === "string" && v.length > 0);
408
+ return Array.from(new Set(names)).sort((a, b) => a.localeCompare(b));
409
+ }
369
410
  /**
370
411
  * Generates .env.example file
371
412
  *
@@ -383,6 +424,8 @@ function generateEnvExample(appDir, opts, defaultWsdlSource, force) {
383
424
  const defaultPort = opts.port || 3000;
384
425
  const defaultPrefix = opts.prefix || "";
385
426
  const defaultLogger = opts.logger !== false;
427
+ const securityCfg = loadOptionalSecurityConfig(opts.securityConfigFile);
428
+ const securityEnv = collectSecurityEnvVars(securityCfg);
386
429
  // Resolve WSDL source relative to app directory
387
430
  const resolvedWsdlSource = defaultWsdlSource
388
431
  ? resolveWsdlSourceForApp(defaultWsdlSource, appDir)
@@ -425,13 +468,27 @@ LOGGER=${defaultLogger}
425
468
  # Override OpenAPI spec server URL at runtime (default: use generation-time value)
426
469
  #OPENAPI_SERVER_URL=http://localhost:${defaultPort}
427
470
 
428
- # Optional: SOAP security settings (configure based on your client requirements)
471
+ ${securityEnv.length
472
+ ? `# Upstream SOAP security values referenced by security.json
473
+ ${securityEnv.map(name => `${name}=`).join("\n")}`
474
+ : `# Optional: SOAP security settings (configure based on your client requirements)
429
475
  # SOAP_USERNAME=
430
476
  # SOAP_PASSWORD=
431
- # SOAP_ENDPOINT=
477
+ # SOAP_ENDPOINT=`}
432
478
  `;
433
479
  fs.writeFileSync(filePath, content, "utf-8");
434
480
  }
481
+ function generateSecurityFile(appDir, opts, force) {
482
+ const securityCfg = loadOptionalSecurityConfig(opts.securityConfigFile);
483
+ if (!hasUpstreamRuntimeSecurity(securityCfg))
484
+ return;
485
+ const filePath = path.join(appDir, `security${getAppFileExtension()}`);
486
+ if (!shouldWriteScaffoldFile(filePath, force))
487
+ return;
488
+ const upstreamJson = JSON.stringify(securityCfg?.upstream ?? {}, null, 2);
489
+ const content = loadRuntimeTemplate("appSecurity.tpl.txt").replace("__UPSTREAM_JSON__", upstreamJson);
490
+ fs.writeFileSync(filePath, content, "utf-8");
491
+ }
435
492
  /**
436
493
  * Generates package.json file (skipped if already exists)
437
494
  *
@@ -510,6 +567,13 @@ function generateReadme(appDir, opts, force) {
510
567
  const filePath = path.join(appDir, "README.md");
511
568
  if (!shouldWriteScaffoldFile(filePath, force))
512
569
  return;
570
+ const securityCfg = loadOptionalSecurityConfig(opts.securityConfigFile);
571
+ const securityStructureRow = hasUpstreamRuntimeSecurity(securityCfg)
572
+ ? "- `security.ts` - Upstream SOAP security factory\n"
573
+ : "";
574
+ const securityConfigRows = collectSecurityEnvVars(securityCfg)
575
+ .map(name => `| \`${name}\` | (required when configured) | Upstream SOAP security value |`)
576
+ .join("\n");
513
577
  const content = `# Generated Fastify Application
514
578
 
515
579
  This application was scaffolded by \`wsdl-tsc\`. Customize freely.
@@ -527,7 +591,7 @@ npm start
527
591
 
528
592
  - \`server.ts\` - Main application entry point
529
593
  - \`config.ts\` - Configuration loader (environment-based)
530
- - \`package.json\` - Dependencies and scripts
594
+ ${securityStructureRow}- \`package.json\` - Dependencies and scripts
531
595
  - \`tsconfig.json\` - TypeScript configuration
532
596
  - \`.env.example\` - Example environment configuration
533
597
  - \`openapi.json\` - OpenAPI specification${opts.openapiMode === "copy" ? " (copied)" : " (referenced)"}
@@ -550,6 +614,7 @@ npm start
550
614
  | \`PREFIX\` | (empty) | Route prefix |
551
615
  | \`LOGGER\` | ${opts.logger !== false} | Enable Fastify logger |
552
616
  | \`OPENAPI_SERVER_URL\` | (empty) | Override OpenAPI spec server URL at runtime |
617
+ ${securityConfigRows ? `${securityConfigRows}\n` : ""}
553
618
 
554
619
  ## Development
555
620
 
@@ -595,6 +660,7 @@ export async function generateApp(opts) {
595
660
  openapiFile: path.resolve(opts.openapiFile),
596
661
  catalogFile: path.resolve(opts.catalogFile),
597
662
  appDir: path.resolve(opts.appDir),
663
+ securityConfigFile: opts.securityConfigFile ? path.resolve(opts.securityConfigFile) : undefined,
598
664
  };
599
665
  const force = resolvedOpts.force ?? false;
600
666
  // Validate required files and directories
@@ -608,6 +674,7 @@ export async function generateApp(opts) {
608
674
  // Generate scaffold files (each checks for existing files unless force is set)
609
675
  generateServerFile(resolvedOpts.appDir, resolvedOpts, clientClassName, force);
610
676
  generateConfigFile(resolvedOpts.appDir, resolvedOpts, defaultWsdlSource, force);
677
+ generateSecurityFile(resolvedOpts.appDir, resolvedOpts, force);
611
678
  generatePackageJson(resolvedOpts.appDir, force);
612
679
  generateTsConfig(resolvedOpts.appDir, resolvedOpts, force);
613
680
  generateEnvExample(resolvedOpts.appDir, resolvedOpts, defaultWsdlSource, force);
package/dist/cli.js CHANGED
@@ -267,7 +267,11 @@ if (rawArgs[0] === "openapi") {
267
267
  default: "post",
268
268
  desc: "Default HTTP method for all operations (can be overridden via --openapi-ops-file)"
269
269
  })
270
- .option("openapi-security-file", { type: "string", desc: "Path to security.json configuration" })
270
+ .option("openapi-security-config-file", {
271
+ type: "string",
272
+ desc: "Path to security.json configuration",
273
+ alias: "openapi-security-file",
274
+ })
271
275
  .option("openapi-tags-file", { type: "string", desc: "Path to tags.json mapping operation name -> tag" })
272
276
  .option("openapi-ops-file", {
273
277
  type: "string",
@@ -508,6 +512,10 @@ if (rawArgs[0] === "app") {
508
512
  choices: ["copy", "reference"],
509
513
  default: "copy",
510
514
  desc: "How to handle OpenAPI file: copy into app dir or reference original"
515
+ })
516
+ .option("security-config-file", {
517
+ type: "string",
518
+ desc: "Path to security.json configuration used to scaffold upstream SOAP security",
511
519
  })
512
520
  .option("force", {
513
521
  type: "boolean",
@@ -557,6 +565,7 @@ if (rawArgs[0] === "app") {
557
565
  logger: Boolean(appArgv.logger),
558
566
  openapiMode: appArgv["openapi-mode"],
559
567
  force: Boolean(appArgv.force),
568
+ securityConfigFile: appArgv["security-config-file"] ? path.resolve(String(appArgv["security-config-file"])) : undefined,
560
569
  });
561
570
  process.exit(0);
562
571
  }
@@ -616,7 +625,7 @@ if (rawArgs[0] === "pipeline") {
616
625
  choices: ["post", "get", "put", "patch", "delete"],
617
626
  default: "post"
618
627
  })
619
- .option("openapi-security-file", { type: "string" })
628
+ .option("openapi-security-config-file", { type: "string", alias: "openapi-security-file" })
620
629
  .option("openapi-tags-file", { type: "string" })
621
630
  .option("openapi-ops-file", { type: "string" })
622
631
  .option("openapi-closed-schemas", { type: "boolean", default: false })
@@ -832,6 +841,7 @@ if (rawArgs[0] === "pipeline") {
832
841
  host: pipelineArgv["app-host"],
833
842
  port: pipelineArgv["app-port"],
834
843
  prefix: pipelineArgv["app-prefix"],
844
+ securityConfigFile: (pipelineArgv["openapi-security-config-file"] || pipelineArgv["openapi-security-file"]),
835
845
  } : undefined,
836
846
  test: testDir ? {
837
847
  testDir: path.resolve(testDir),
@@ -10,7 +10,7 @@
10
10
  * - Parameter resolution with path-level and operation-level override support
11
11
  * - Automatic version/service detection from OpenAPI paths
12
12
  */
13
- import { pascal } from "../util/tools.js";
13
+ import { pascal, trimRepeatedEdgeChar } from "../util/tools.js";
14
14
  /**
15
15
  * Converts a name to a deterministic slug for use in file names and URN IDs
16
16
  *
@@ -30,7 +30,7 @@ import { pascal } from "../util/tools.js";
30
30
  export function slugName(name) {
31
31
  const lower = String(name ?? "").toLowerCase();
32
32
  const collapsed = lower.replace(/[^a-z0-9]+/g, "_");
33
- return collapsed.replace(/^_+|_+$/g, "");
33
+ return trimRepeatedEdgeChar(collapsed, "_");
34
34
  }
35
35
  /**
36
36
  * Checks if a status code string is numeric
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { CompilerOptions } from "./config.js";
2
2
  export { generateOpenAPI } from "./openapi/generateOpenAPI.js";
3
3
  export { generateGateway } from "./gateway/generateGateway.js";
4
+ export { buildSecurity, loadSecurityConfigFile, parseSecurityConfig, SecurityConfigError, type SecurityConfig, } from "./util/securityConfig.js";
4
5
  export { generateTests } from "./test/generateTests.js";
5
6
  export { runGenerationPipeline } from "./pipeline.js";
6
7
  export { loadStreamConfigFile, parseStreamConfig, StreamConfigError, type OperationStreamMetadata, type ShapeCatalogRef, type StreamConfig, } from "./util/streamConfig.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,aAAa,CAAC;AAWjD,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAC,qBAAqB,EAAC,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAC,kBAAkB,EAAE,KAAK,yBAAyB,EAAC,MAAM,6BAA6B,CAAC;AAG/F;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE;IACL,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,kHAAkH;IAClH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,YAAY,CAAC,EAAE,OAAO,wBAAwB,EAAE,YAAY,CAAC;CAC9D,GACA,OAAO,CAAC,IAAI,CAAC,CA2Ef"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,aAAa,CAAC;AAWjD,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAC,eAAe,EAAC,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,cAAc,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAC,qBAAqB,EAAC,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAC,kBAAkB,EAAE,KAAK,yBAAyB,EAAC,MAAM,6BAA6B,CAAC;AAG/F;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE;IACL,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,kHAAkH;IAClH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,YAAY,CAAC,EAAE,OAAO,wBAAwB,EAAE,YAAY,CAAC;CAC9D,GACA,OAAO,CAAC,IAAI,CAAC,CA2Ef"}
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ import { generateOperations } from "./client/generateOperations.js";
24
24
  import { info } from "./util/cli.js";
25
25
  export { generateOpenAPI } from "./openapi/generateOpenAPI.js";
26
26
  export { generateGateway } from "./gateway/generateGateway.js";
27
+ export { buildSecurity, loadSecurityConfigFile, parseSecurityConfig, SecurityConfigError, } from "./util/securityConfig.js";
27
28
  export { generateTests } from "./test/generateTests.js";
28
29
  export { runGenerationPipeline } from "./pipeline.js";
29
30
  export { loadStreamConfigFile, parseStreamConfig, StreamConfigError, } from "./util/streamConfig.js";
@@ -1,17 +1,3 @@
1
- /**
2
- * Path Segment Styling for OpenAPI Generation
3
- *
4
- * This module provides utilities for converting operation names to appropriately styled
5
- * path segments in the OpenAPI specification. It supports multiple styling options to
6
- * accommodate different API design preferences:
7
- *
8
- * - kebab-case: Transforms "GetUserDetails" to "get-user-details"
9
- * - as-is: Preserves the original operation name without modification
10
- * - lowercase: Converts to lowercase and removes all non-alphanumeric characters
11
- *
12
- * These transformations ensure that the generated API paths follow consistent conventions
13
- * and are properly formatted for RESTful API design.
14
- */
15
1
  /**
16
2
  * Path segment styling options for OpenAPI generation
17
3
  *
@@ -1 +1 @@
1
- {"version":3,"file":"casing.d.ts","sourceRoot":"","sources":["../../src/openapi/casing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAQnD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAepE"}
1
+ {"version":3,"file":"casing.d.ts","sourceRoot":"","sources":["../../src/openapi/casing.ts"],"names":[],"mappings":"AAgBA;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;AAQnD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,MAAM,CAiBpE"}
@@ -12,6 +12,7 @@
12
12
  * These transformations ensure that the generated API paths follow consistent conventions
13
13
  * and are properly formatted for RESTful API design.
14
14
  */
15
+ import { trimRepeatedEdgeChar } from "../util/tools.js";
15
16
  /**
16
17
  * Regular expression for detecting boundaries between words in camelCase
17
18
  * Matches transitions from lowercase/digit to uppercase letter
@@ -40,10 +41,9 @@ export function toPathSegment(name, style) {
40
41
  case "kebab":
41
42
  default:
42
43
  // insert hyphen between camelCase boundaries then sanitize
43
- return name
44
+ return trimRepeatedEdgeChar(name
44
45
  .replace(CAMEL_BOUNDARY, "$1-$2")
45
- .replace(/[^A-Za-z0-9]+/g, "-")
46
- .replace(/^-+|-+$/g, "")
46
+ .replace(/[^A-Za-z0-9]+/g, "-"), "-")
47
47
  .toLowerCase();
48
48
  }
49
49
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generateOpenAPI.d.ts","sourceRoot":"","sources":["../../src/openapi/generateOpenAPI.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,OAAO,EAAiB,KAAK,eAAe,EAAC,MAAM,+BAA+B,CAAC;AAKnF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IAC3C,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC;IAC3E,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC,CAsTD"}
1
+ {"version":3,"file":"generateOpenAPI.d.ts","sourceRoot":"","sources":["../../src/openapi/generateOpenAPI.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,OAAO,EAAiB,KAAK,eAAe,EAAC,MAAM,+BAA+B,CAAC;AAKnF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IAC3C,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC;IAC3E,GAAG,EAAE,GAAG,CAAC;IACT,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC,CAyTD"}
@@ -280,6 +280,9 @@ export async function generateOpenAPI(opts) {
280
280
  paths: sortedPaths,
281
281
  components,
282
282
  };
283
+ if (securityBuilt.globalSecurity) {
284
+ doc.security = securityBuilt.globalSecurity;
285
+ }
283
286
  if (opts.description)
284
287
  doc.info.description = opts.description;
285
288
  if (opts.servers && opts.servers.length) {
@@ -1,82 +1,2 @@
1
- /**
2
- * Authentication scheme types supported in the OpenAPI specification
3
- *
4
- * @property {"none"} string No authentication required
5
- * @property {"basic"} string HTTP Basic authentication
6
- * @property {"bearer"} string HTTP Bearer token authentication
7
- * @property {"apiKey"} string API key authentication
8
- * @property {"oauth2"} string OAuth 2.0 authentication
9
- */
10
- export type AuthScheme = "none" | "basic" | "bearer" | "apiKey" | "oauth2";
11
- /**
12
- * Security configuration schema for the OpenAPI generation
13
- *
14
- * @interface SecurityConfig
15
- * @property {Object} [global] - Global security settings applied to all operations by default
16
- * @property {AuthScheme} [global.scheme] - Default authentication scheme
17
- * @property {Object} [global.apiKey] - API key configuration (when scheme is "apiKey")
18
- * @property {Object} [global.bearer] - Bearer token configuration (when scheme is "bearer")
19
- * @property {Object} [global.basic] - Basic auth configuration (when scheme is "basic")
20
- * @property {Object} [global.oauth2] - OAuth2 configuration (when scheme is "oauth2")
21
- * @property {Array<Object>} [global.headers] - Global security headers
22
- * @property {Record<string, Object>} [overrides] - Operation-specific security overrides
23
- */
24
- export type SecurityConfig = {
25
- global?: {
26
- scheme?: AuthScheme;
27
- apiKey?: {
28
- in: "header" | "query" | "cookie";
29
- name: string;
30
- };
31
- bearer?: {
32
- bearerFormat?: string;
33
- };
34
- basic?: Record<string, never>;
35
- oauth2?: {
36
- flows: Record<string, any>;
37
- };
38
- headers?: Array<{
39
- name: string;
40
- required?: boolean;
41
- schema?: any;
42
- }>;
43
- };
44
- overrides?: Record<string, {
45
- scheme?: AuthScheme;
46
- headers?: Array<{
47
- name: string;
48
- required?: boolean;
49
- schema?: any;
50
- }>;
51
- }>;
52
- };
53
- /**
54
- * Built security components for OpenAPI generation
55
- *
56
- * @interface BuiltSecurity
57
- * @property {Record<string, any>} [securitySchemes] - Security schemes defined for the API
58
- * @property {Record<string, any>} headerParameters - Header parameters for security
59
- * @property {Record<string, any[]>} opSecurity - Operation security requirements
60
- * @property {Record<string, string[]>} opHeaderParameters - Operation-specific header parameters
61
- */
62
- export type BuiltSecurity = {
63
- securitySchemes?: Record<string, any>;
64
- headerParameters: Record<string, any>;
65
- opSecurity: Record<string, any[] | undefined>;
66
- opHeaderParameters: Record<string, string[]>;
67
- };
68
- /**
69
- * Load security configuration from a JSON file
70
- *
71
- * @param {string} [filePath] - Path to the security configuration file
72
- * @returns {SecurityConfig|undefined} Parsed security configuration object or undefined if loading failed
73
- */
74
- export declare function loadSecurityConfig(filePath?: string): SecurityConfig | undefined;
75
- /**
76
- * Build security schemes and parameters for OpenAPI generation
77
- *
78
- * @param {SecurityConfig} [cfg] - Security configuration object
79
- * @returns {BuiltSecurity} Object containing built security schemes and parameters
80
- */
81
- export declare function buildSecurity(cfg?: SecurityConfig): BuiltSecurity;
1
+ export { buildSecurity, loadSecurityConfigFile as loadSecurityConfig, parseSecurityConfig, SecurityConfigError, type BuiltSecurity, type GatewayAuthScheme as AuthScheme, type SecurityConfig, } from "../util/securityConfig.js";
82
2
  //# sourceMappingURL=security.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/openapi/security.ts"],"names":[],"mappings":"AAmBA;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE3E;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,UAAU,CAAC;QACpB,MAAM,CAAC,EAAE;YAAE,EAAE,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;QAC7D,MAAM,CAAC,EAAE;YAAE,YAAY,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACnC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;SAAE,CAAC;QACxC,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;YAAC,MAAM,CAAC,EAAE,GAAG,CAAA;SAAE,CAAC,CAAC;KACrE,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QACzB,MAAM,CAAC,EAAE,UAAU,CAAC;QACpB,OAAO,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;YAAC,MAAM,CAAC,EAAE,GAAG,CAAA;SAAE,CAAC,CAAA;KACpE,CAAC,CAAC;CACJ,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACtC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;IAC9C,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC9C,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAShF;AAeD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,cAAc,GAAG,aAAa,CA+FjE"}
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/openapi/security.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,sBAAsB,IAAI,kBAAkB,EAC5C,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,iBAAiB,IAAI,UAAU,EACpC,KAAK,cAAc,GACpB,MAAM,2BAA2B,CAAC"}
@@ -1,146 +1 @@
1
- /**
2
- * OpenAPI Security Configuration
3
- *
4
- * This module handles security scheme generation for the OpenAPI specification.
5
- * It provides functionality to define authentication and authorization requirements
6
- * for the API, including:
7
- *
8
- * - Basic authentication
9
- * - Bearer token authentication
10
- * - API key authentication
11
- * - OAuth2 flows
12
- * - Custom security headers
13
- *
14
- * The module supports both global security requirements and operation-specific
15
- * security overrides through an external JSON configuration file.
16
- */
17
- import fs from "node:fs";
18
- import { warn } from "../util/cli.js";
19
- /**
20
- * Load security configuration from a JSON file
21
- *
22
- * @param {string} [filePath] - Path to the security configuration file
23
- * @returns {SecurityConfig|undefined} Parsed security configuration object or undefined if loading failed
24
- */
25
- export function loadSecurityConfig(filePath) {
26
- if (!filePath)
27
- return undefined;
28
- try {
29
- const raw = fs.readFileSync(filePath, "utf8");
30
- return JSON.parse(raw);
31
- }
32
- catch (e) {
33
- warn(`Failed to read security config '${filePath}': ${e instanceof Error ? e.message : String(e)}`);
34
- return undefined;
35
- }
36
- }
37
- /**
38
- * Generate a canonical parameter component name from a header name
39
- *
40
- * @param {string} headerName - Original header name
41
- * @returns {string} Canonicalized component name
42
- */
43
- function makeParamComponentName(headerName) {
44
- return headerName
45
- .replace(/[^A-Za-z0-9]+/g, "_")
46
- .replace(/^_+|_+$/g, "")
47
- || "X_Header";
48
- }
49
- /**
50
- * Build security schemes and parameters for OpenAPI generation
51
- *
52
- * @param {SecurityConfig} [cfg] - Security configuration object
53
- * @returns {BuiltSecurity} Object containing built security schemes and parameters
54
- */
55
- export function buildSecurity(cfg) {
56
- const securitySchemes = {};
57
- const headerParameters = {};
58
- const opSecurity = {};
59
- const opHeaderParameters = {};
60
- if (!cfg || !cfg.global) {
61
- return { securitySchemes: undefined, headerParameters, opSecurity, opHeaderParameters };
62
- }
63
- const global = cfg.global;
64
- const schemeName = "defaultAuth";
65
- const scheme = global.scheme || "none";
66
- const hasGlobal = scheme !== "none";
67
- if (scheme !== "none") {
68
- switch (scheme) {
69
- case "basic":
70
- securitySchemes[schemeName] = { type: "http", scheme: "basic" };
71
- break;
72
- case "bearer":
73
- securitySchemes[schemeName] = { type: "http", scheme: "bearer", ...(global.bearer || {}) };
74
- break;
75
- case "apiKey":
76
- securitySchemes[schemeName] = { type: "apiKey", ...(global.apiKey || { in: "header", name: "X-API-Key" }) };
77
- break;
78
- case "oauth2":
79
- securitySchemes[schemeName] = { type: "oauth2", ...(global.oauth2 || { flows: {} }) };
80
- break;
81
- }
82
- }
83
- // Global headers
84
- for (const h of global.headers || []) {
85
- const compName = makeParamComponentName(h.name);
86
- headerParameters[compName] = {
87
- name: h.name,
88
- in: "header",
89
- required: !!h.required,
90
- schema: h.schema || { type: "string" },
91
- };
92
- }
93
- // Default op security (inherit global scheme)
94
- // (If scheme is none we omit entirely)
95
- // Overrides can set scheme to none to remove security
96
- for (const [opName, override] of Object.entries(cfg.overrides || {})) {
97
- const oScheme = override.scheme ?? scheme;
98
- if (oScheme === "none") {
99
- opSecurity[opName] = undefined;
100
- }
101
- else if (oScheme === scheme) {
102
- opSecurity[opName] = hasGlobal ? [{ [schemeName]: [] }] : undefined;
103
- }
104
- else {
105
- // Different scheme per operation -> create ad-hoc component name
106
- const altName = `${schemeName}_${oScheme}`;
107
- if (!securitySchemes[altName]) {
108
- switch (oScheme) {
109
- case "basic":
110
- securitySchemes[altName] = { type: "http", scheme: "basic" };
111
- break;
112
- case "bearer":
113
- securitySchemes[altName] = { type: "http", scheme: "bearer" };
114
- break;
115
- case "apiKey":
116
- securitySchemes[altName] = { type: "apiKey", ...(global.apiKey || { in: "header", name: "X-API-Key" }) };
117
- break;
118
- case "oauth2":
119
- securitySchemes[altName] = { type: "oauth2", ...(global.oauth2 || { flows: {} }) };
120
- break;
121
- }
122
- }
123
- opSecurity[opName] = [{ [altName]: [] }];
124
- }
125
- // Per-op headers merge global + override specific headers
126
- const headers = [...(global.headers || []), ...(override.headers || [])];
127
- opHeaderParameters[opName] = headers.map(h => makeParamComponentName(h.name));
128
- for (const h of override.headers || []) {
129
- const compName = makeParamComponentName(h.name);
130
- if (!headerParameters[compName]) {
131
- headerParameters[compName] = {
132
- name: h.name,
133
- in: "header",
134
- required: !!h.required,
135
- schema: h.schema || { type: "string" },
136
- };
137
- }
138
- }
139
- }
140
- return {
141
- securitySchemes: Object.keys(securitySchemes).length ? securitySchemes : undefined,
142
- headerParameters,
143
- opSecurity,
144
- opHeaderParameters
145
- };
146
- }
1
+ export { buildSecurity, loadSecurityConfigFile as loadSecurityConfig, parseSecurityConfig, SecurityConfigError, } from "../util/securityConfig.js";
@@ -40,6 +40,7 @@ export interface PipelineOptions {
40
40
  host?: string;
41
41
  port?: number;
42
42
  prefix?: string;
43
+ securityConfigFile?: string;
43
44
  };
44
45
  test?: {
45
46
  testDir: string;
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAkB,KAAK,sBAAsB,EAAC,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EAAkB,KAAK,sBAAsB,EAAC,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EAAC,KAAK,eAAe,EAAyB,MAAM,aAAa,CAAC;AAEzE,OAAO,EAAuB,KAAK,YAAY,EAAC,MAAM,wBAAwB,CAAC;AAG/E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,MAAM,GAAG,aAAa,GAAG,iBAAiB,CAAC,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1G,OAAO,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,aAAa,GAAG,iBAAiB,CAAC,GAAG;QAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,GAAG,CAAC,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;QACnC,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAChC,CAAC;IACF;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,UAAU,CAAC,EAAE,GAAG,CAAC;CAAE,CAAC,CAiKhH"}
1
+ {"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAkB,KAAK,sBAAsB,EAAC,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EAAkB,KAAK,sBAAsB,EAAC,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EAAC,KAAK,eAAe,EAAyB,MAAM,aAAa,CAAC;AAEzE,OAAO,EAAuB,KAAK,YAAY,EAAC,MAAM,wBAAwB,CAAC;AAG/E;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACpC,OAAO,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,MAAM,GAAG,aAAa,GAAG,iBAAiB,CAAC,GAAG;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1G,OAAO,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,aAAa,GAAG,iBAAiB,CAAC,GAAG;QAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,GAAG,CAAC,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;QACnC,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,IAAI,CAAC,EAAE;QACL,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAChC,CAAC;IACF;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,UAAU,CAAC,EAAE,GAAG,CAAC;CAAE,CAAC,CAkKhH"}
package/dist/pipeline.js CHANGED
@@ -142,6 +142,7 @@ export async function runGenerationPipeline(opts) {
142
142
  host: opts.app.host,
143
143
  port: opts.app.port,
144
144
  prefix: opts.app.prefix,
145
+ securityConfigFile: opts.app.securityConfigFile,
145
146
  });
146
147
  }
147
148
  // Step 7: Optionally generate test suite
@@ -14,7 +14,7 @@
14
14
  import fs from "node:fs";
15
15
  import path from "node:path";
16
16
  import { info, success } from "../util/cli.js";
17
- import { resolveClientMeta, resolveOperationMeta } from "../gateway/helpers.js";
17
+ import { resolveClientMeta, resolveOperationMeta, slugName } from "../gateway/helpers.js";
18
18
  import { generateAllOperationMocks } from "./mockData.js";
19
19
  import { emitVitestConfig, emitMockClientHelper, emitTestAppHelper, emitRoutesTest, emitErrorsTest, emitEnvelopeTest, emitValidationTest, emitClassifyErrorTest, emitEnvelopeBuildersTest, emitUnwrapTest, } from "./generators.js";
20
20
  /**
@@ -77,7 +77,7 @@ export async function generateTests(opts) {
77
77
  // Read OpenAPI doc paths from the gateway's generated routes to get URL paths
78
78
  // We use the catalog operations and derive paths using the same pattern as gateway generation
79
79
  for (const op of catalog.operations) {
80
- const operationSlug = op.name.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
80
+ const operationSlug = slugName(op.name);
81
81
  // Try to find the path from the generated operation schema
82
82
  const opSchemaPath = path.join(gatewayDir, "schemas", "operations", `${operationSlug}.json`);
83
83
  let urlPath = `/${operationSlug.replace(/_/g, "-")}`;
@@ -40,7 +40,7 @@ export function buildOpenApiOptionsFromArgv(argv, format, servers) {
40
40
  opsFile: argv["openapi-ops-file"],
41
41
  pathStyle: argv["openapi-path-style"],
42
42
  pruneUnusedSchemas: argv["openapi-prune-unused-schemas"],
43
- securityConfigFile: argv["openapi-security-file"],
43
+ securityConfigFile: (argv["openapi-security-config-file"] || argv["openapi-security-file"]),
44
44
  servers,
45
45
  skipValidate: false, // Always validate
46
46
  tagStyle: argv["openapi-tag-style"],