@techspokes/typescript-wsdl-client 0.3.0 → 0.4.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 (37) hide show
  1. package/README.md +82 -45
  2. package/dist/cli.js +34 -21
  3. package/dist/compiler/schemaCompiler.d.ts +3 -2
  4. package/dist/compiler/schemaCompiler.d.ts.map +1 -1
  5. package/dist/compiler/schemaCompiler.js +8 -7
  6. package/dist/config.d.ts +15 -26
  7. package/dist/config.d.ts.map +1 -1
  8. package/dist/config.js +15 -6
  9. package/dist/emit/catalogEmitter.d.ts +3 -0
  10. package/dist/emit/catalogEmitter.d.ts.map +1 -0
  11. package/dist/emit/catalogEmitter.js +10 -0
  12. package/dist/emit/clientEmitter.d.ts +1 -4
  13. package/dist/emit/clientEmitter.d.ts.map +1 -1
  14. package/dist/emit/clientEmitter.js +336 -51
  15. package/dist/emit/typesEmitter.d.ts.map +1 -1
  16. package/dist/emit/typesEmitter.js +7 -1
  17. package/dist/emit/utilsEmitter.d.ts +3 -0
  18. package/dist/emit/utilsEmitter.d.ts.map +1 -0
  19. package/dist/emit/utilsEmitter.js +33 -0
  20. package/dist/index.d.ts +0 -4
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +47 -44
  23. package/dist/loader/wsdlLoader.js +1 -1
  24. package/dist/util/{xml.d.ts → tools.d.ts} +8 -1
  25. package/dist/util/tools.d.ts.map +1 -0
  26. package/dist/util/{xml.js → tools.js} +27 -0
  27. package/package.json +3 -2
  28. package/dist/emit/metaEmitter.d.ts +0 -4
  29. package/dist/emit/metaEmitter.d.ts.map +0 -1
  30. package/dist/emit/metaEmitter.js +0 -9
  31. package/dist/emit/opsEmitter.d.ts +0 -4
  32. package/dist/emit/opsEmitter.d.ts.map +0 -1
  33. package/dist/emit/opsEmitter.js +0 -13
  34. package/dist/emit/runtimeEmitter.d.ts +0 -2
  35. package/dist/emit/runtimeEmitter.d.ts.map +0 -1
  36. package/dist/emit/runtimeEmitter.js +0 -147
  37. package/dist/util/xml.d.ts.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techspokes/typescript-wsdl-client",
3
- "version": "0.3.0",
3
+ "version": "0.4.2",
4
4
  "description": "TypeScript WSDL → SOAP client generator with full xs:attribute support, complex types, sequences, inheritance, and namespace-collision merging.",
5
5
  "keywords": [
6
6
  "wsdl",
@@ -53,7 +53,7 @@
53
53
  "prepublishOnly": "npm run clean && npm run build",
54
54
  "test": "exit 0",
55
55
  "smoke": "tsx src/cli.ts --help",
56
- "smoke:gen": "rimraf tmp && tsx src/cli.ts --wsdl examples/minimal/weather.wsdl --out tmp && tsc --noEmit --module NodeNext --moduleResolution NodeNext --target ES2022 tmp/types.ts tmp/meta.ts tmp/operations.ts tmp/runtime.ts tmp/client.ts src/types/soap.d.ts",
56
+ "smoke:gen": "rimraf tmp && tsx src/cli.ts --wsdl examples/minimal/weather.wsdl --out tmp && tsc -p tsconfig.smoke.json",
57
57
  "ci": "npm run build && npm run typecheck && npm run smoke && npm run smoke:gen"
58
58
  },
59
59
  "devDependencies": {
@@ -65,6 +65,7 @@
65
65
  },
66
66
  "dependencies": {
67
67
  "fast-xml-parser": "^5.2.5",
68
+ "soap": "^1.3.0",
68
69
  "yargs": "^18.0.0"
69
70
  },
70
71
  "funding": {
@@ -1,4 +0,0 @@
1
- import type { CompiledCatalog } from "../compiler/schemaCompiler.js";
2
- import type { CompilerOptions } from "../config.js";
3
- export declare function emitMeta(outFile: string, compiled: CompiledCatalog, opts?: CompilerOptions): void;
4
- //# sourceMappingURL=metaEmitter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"metaEmitter.d.ts","sourceRoot":"","sources":["../../src/emit/metaEmitter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,IAAI,CAAC,EAAE,eAAe,QAQ1F"}
@@ -1,9 +0,0 @@
1
- import fs from "node:fs";
2
- export function emitMeta(outFile, compiled, opts) {
3
- const { attrSpec, childType, propMeta } = compiled.meta;
4
- const src = `export const ATTR_SPEC = ${JSON.stringify(attrSpec, null, 2)} as const;\n` +
5
- `export const CHILD_TYPE = ${JSON.stringify(childType, null, 2)} as const;\n` +
6
- `export const PROP_META = ${JSON.stringify(propMeta, null, 2)} as const;\n` +
7
- `export const OPTIONS = ${JSON.stringify(opts || {}, null, 2)} as const;\n`;
8
- fs.writeFileSync(outFile, src, "utf8");
9
- }
@@ -1,4 +0,0 @@
1
- import type { CompiledCatalog } from "../compiler/schemaCompiler.js";
2
- export declare function emitOperations(outFile: string, compiled: CompiledCatalog): void;
3
- export declare function emitOps(outFile: string, compiled: CompiledCatalog): void;
4
- //# sourceMappingURL=opsEmitter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"opsEmitter.d.ts","sourceRoot":"","sources":["../../src/emit/opsEmitter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,QAExE;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,QAOjE"}
@@ -1,13 +0,0 @@
1
- import fs from "node:fs";
2
- export function emitOperations(outFile, compiled) {
3
- fs.writeFileSync(outFile, JSON.stringify(compiled.operations, null, 2), "utf8");
4
- }
5
- export function emitOps(outFile, compiled) {
6
- if (outFile.endsWith(".ts")) {
7
- const src = `export const OPERATIONS = ${JSON.stringify(compiled.operations, null, 2)} as const;\n`;
8
- fs.writeFileSync(outFile, src, "utf8");
9
- }
10
- else {
11
- emitOperations(outFile, compiled);
12
- }
13
- }
@@ -1,2 +0,0 @@
1
- export declare function emitRuntime(outFile: string): void;
2
- //# sourceMappingURL=runtimeEmitter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runtimeEmitter.d.ts","sourceRoot":"","sources":["../../src/emit/runtimeEmitter.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,QAgJ1C"}
@@ -1,147 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- export function emitRuntime(outFile) {
4
- // noinspection UnreachableCodeJS,NpmUsedModulesInstalled,JSLastCommaInObjectLiteral,CommaExpressionJS,JSUnresolvedReference,BadExpressionStatementJS,JSCheckFunctionSignatures
5
- const code = `export type CreateSoapClientOptions = {
6
- wsdlUrl: string;
7
- endpoint?: string;
8
- wsdlOptions?: Record<string, any>;
9
- requestOptions?: Record<string, any>;
10
- security?: any;
11
- }
12
-
13
- export type AttrSpec = Record<string, readonly string[]>;
14
- export type ChildType = Record<string, Readonly<Record<string, string>>>;
15
- export type PropMeta = Record<string, Readonly<Record<string, any>>>;
16
-
17
- // Universal CJS/ESM loader without import.meta
18
- async function loadSoap(): Promise<any> {
19
- // Prefer CJS require when available (CommonJS or transpiled output)
20
- try {
21
- // eslint-disable-next-line @typescript-eslint/no-var-requires
22
- const cjsMod = typeof require === "function" ? require("soap") : undefined;
23
- if (cjsMod) return cjsMod;
24
- } catch {
25
- // ignore and fall back to dynamic import
26
- }
27
- // ESM fallback (Node wraps CJS under default)
28
- const esmMod: any = await import("soap");
29
- return (esmMod && esmMod.default) ? esmMod.default : esmMod;
30
- }
31
-
32
- export async function createSoapClient(opts: CreateSoapClientOptions): Promise<any> {
33
- try {
34
- const soapModule = await loadSoap();
35
-
36
- console.log("Creating SOAP client with WSDL:", opts.wsdlUrl);
37
- console.log("SOAP module methods available:", typeof soapModule.createClientAsync);
38
-
39
- const client = await soapModule.createClientAsync(opts.wsdlUrl, opts.wsdlOptions || {});
40
- if (opts.endpoint) client.setEndpoint(opts.endpoint);
41
- if (opts.security) client.setSecurity(opts.security);
42
-
43
- console.log("SOAP client created successfully");
44
- return client;
45
- } catch (error) {
46
- console.error("Error creating SOAP client:", error);
47
- throw error;
48
- }
49
- }
50
-
51
- // Normalize simple attribute values to strings (WCF prefers string attrs)
52
- function normalizeAttrValue(v: unknown): string {
53
- if (v == null) return "";
54
- if (typeof v === "boolean") return v ? "true" : "false";
55
- if (typeof v === "number") return Number.isFinite(v) ? String(v) : "";
56
- return String(v);
57
- }
58
-
59
- export function toSoapArgs(
60
- value: any,
61
- typeName?: string,
62
- meta?: { ATTR_SPEC: AttrSpec; CHILD_TYPE: ChildType; PROP_META: PropMeta },
63
- attributesKeyIn: string = "$attributes", // accepted TS-side bag
64
- attributesKeyOut: string = "attributes" // node-soap expects "attributes"
65
- ): any {
66
- if (value == null) return value;
67
- if (typeof value !== "object") return value;
68
- if (Array.isArray(value)) {
69
- return value.map(v => toSoapArgs(v, typeName, meta, attributesKeyIn, attributesKeyOut));
70
- }
71
-
72
- const attrList = (typeName && meta?.ATTR_SPEC?.[typeName]) || [];
73
- const childType = (typeName && meta?.CHILD_TYPE?.[typeName]) || {};
74
-
75
- const out: any = {};
76
- const attrBag: Record<string, any> = {};
77
-
78
- // text content
79
- if ("$value" in value) {
80
- out.$value = (value as any).$value;
81
- }
82
-
83
- // merge user-provided attr bags ("$attributes" or "attributes")
84
- const inAttrNode = (value as any)[attributesKeyIn] ?? (value as any)["attributes"];
85
- if (inAttrNode && typeof inAttrNode === "object") {
86
- for (const [ak, av] of Object.entries(inAttrNode)) {
87
- attrBag[ak] = normalizeAttrValue(av);
88
- }
89
- }
90
-
91
- // split attributes vs elements
92
- for (const [k, v] of Object.entries<any>(value)) {
93
- if (k === "$value" || k === attributesKeyIn || k === "attributes") continue;
94
-
95
- if (attrList.includes(k)) {
96
- attrBag[k] = normalizeAttrValue(v);
97
- continue;
98
- }
99
-
100
- const childT = (childType as any)[k] as string | undefined;
101
- out[k] = Array.isArray(v)
102
- ? v.map(it => toSoapArgs(it, childT, meta, attributesKeyIn, attributesKeyOut))
103
- : toSoapArgs(v, childT, meta, attributesKeyIn, attributesKeyOut);
104
- }
105
-
106
- if (Object.keys(attrBag).length) {
107
- out[attributesKeyOut] = attrBag; // renders as XML attributes
108
- }
109
-
110
- return out;
111
- }
112
-
113
- export function fromSoapResult(
114
- node: any,
115
- typeName?: string,
116
- meta?: { ATTR_SPEC: AttrSpec; CHILD_TYPE: ChildType; PROP_META: PropMeta },
117
- attributesKeyOut: string = "$attributes"
118
- ): any {
119
- if (node == null) return node;
120
- if (typeof node !== "object") return node;
121
- if (Array.isArray(node)) return node.map(n => fromSoapResult(n, typeName, meta, attributesKeyOut));
122
-
123
- const childType = (typeName && meta?.CHILD_TYPE?.[typeName]) || {};
124
- const result: any = {};
125
-
126
- if ("$value" in node) result.$value = (node as any).$value;
127
-
128
- // hoist attributes from supported buckets
129
- const inAttrNode = (node as any)[attributesKeyOut] || (node as any)["attributes"] || (node as any)["$"];
130
- if (inAttrNode && typeof inAttrNode === "object") {
131
- Object.assign(result, inAttrNode);
132
- }
133
-
134
- for (const [k, v] of Object.entries<any>(node)) {
135
- if (k === attributesKeyOut || k === "attributes" || k === "$" || k === "$value") continue;
136
- const childT = (childType as any)[k] as string | undefined;
137
- result[k] = Array.isArray(v)
138
- ? v.map(it => fromSoapResult(it, childT, meta, attributesKeyOut))
139
- : fromSoapResult(v, childT, meta, attributesKeyOut);
140
- }
141
-
142
- return result;
143
- }
144
- `;
145
- fs.mkdirSync(path.dirname(outFile), { recursive: true });
146
- fs.writeFileSync(outFile, code, "utf8");
147
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"xml.d.ts","sourceRoot":"","sources":["../../src/util/xml.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,wBAAgB,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,GAAG,IAAI,GAAG,CAAC,EAAE,CAGpE;AAED,0EAA0E;AAC1E,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,EAAE,CASxE;AAED,gFAAgF;AAChF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAK/E;AAED,6DAA6D;AAC7D,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CA6BxC;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAS/B"}