@techspokes/typescript-wsdl-client 0.2.72 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtimeEmitter.d.ts","sourceRoot":"","sources":["../../src/emit/runtimeEmitter.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"runtimeEmitter.d.ts","sourceRoot":"","sources":["../../src/emit/runtimeEmitter.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,QAgJ1C"}
|
|
@@ -7,39 +7,48 @@ export function emitRuntime(outFile) {
|
|
|
7
7
|
endpoint?: string;
|
|
8
8
|
wsdlOptions?: Record<string, any>;
|
|
9
9
|
requestOptions?: Record<string, any>;
|
|
10
|
-
security?: any;
|
|
10
|
+
security?: any;
|
|
11
11
|
}
|
|
12
|
+
|
|
12
13
|
export type AttrSpec = Record<string, readonly string[]>;
|
|
13
14
|
export type ChildType = Record<string, Readonly<Record<string, string>>>;
|
|
14
15
|
export type PropMeta = Record<string, Readonly<Record<string, any>>>;
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
// Universal CJS/ESM loader without import.meta
|
|
18
|
+
async function loadSoap(): Promise<any> {
|
|
19
|
+
// Prefer CJS require when available (CommonJS or transpiled output)
|
|
18
20
|
try {
|
|
19
|
-
// @
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
} catch
|
|
23
|
-
|
|
24
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
25
|
-
const req = (typeof require !== "undefined") ? require : (await import("node:module")).createRequire(import.meta.url);
|
|
26
|
-
return req("soap");
|
|
27
|
-
} catch {
|
|
28
|
-
throw e;
|
|
29
|
-
}
|
|
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
|
|
30
26
|
}
|
|
27
|
+
// ESM fallback (Node wraps CJS under default)
|
|
28
|
+
const esmMod: any = await import("soap");
|
|
29
|
+
return (esmMod && esmMod.default) ? esmMod.default : esmMod;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
export async function createSoapClient(opts: CreateSoapClientOptions): Promise<any> {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
+
}
|
|
40
49
|
}
|
|
41
50
|
|
|
42
|
-
// Normalize
|
|
51
|
+
// Normalize simple attribute values to strings (WCF prefers string attrs)
|
|
43
52
|
function normalizeAttrValue(v: unknown): string {
|
|
44
53
|
if (v == null) return "";
|
|
45
54
|
if (typeof v === "boolean") return v ? "true" : "false";
|
|
@@ -51,36 +60,53 @@ export function toSoapArgs(
|
|
|
51
60
|
value: any,
|
|
52
61
|
typeName?: string,
|
|
53
62
|
meta?: { ATTR_SPEC: AttrSpec; CHILD_TYPE: ChildType; PROP_META: PropMeta },
|
|
54
|
-
|
|
63
|
+
attributesKeyIn: string = "$attributes", // accepted TS-side bag
|
|
64
|
+
attributesKeyOut: string = "attributes" // node-soap expects "attributes"
|
|
55
65
|
): any {
|
|
56
66
|
if (value == null) return value;
|
|
57
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
|
+
|
|
58
72
|
const attrList = (typeName && meta?.ATTR_SPEC?.[typeName]) || [];
|
|
59
73
|
const childType = (typeName && meta?.CHILD_TYPE?.[typeName]) || {};
|
|
74
|
+
|
|
60
75
|
const out: any = {};
|
|
61
76
|
const attrBag: Record<string, any> = {};
|
|
62
|
-
// map TS $value -> SOAP $value
|
|
63
|
-
if ("$value" in value && Object.keys(value).length >= 1) out.$value = (value as any).$value;
|
|
64
77
|
|
|
65
|
-
//
|
|
66
|
-
|
|
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"];
|
|
67
85
|
if (inAttrNode && typeof inAttrNode === "object") {
|
|
68
86
|
for (const [ak, av] of Object.entries(inAttrNode)) {
|
|
69
87
|
attrBag[ak] = normalizeAttrValue(av);
|
|
70
88
|
}
|
|
71
89
|
}
|
|
72
90
|
|
|
91
|
+
// split attributes vs elements
|
|
73
92
|
for (const [k, v] of Object.entries<any>(value)) {
|
|
74
|
-
if (k === "$value"
|
|
75
|
-
|
|
76
|
-
if (attrList.includes(k)) {
|
|
93
|
+
if (k === "$value" || k === attributesKeyIn || k === "attributes") continue;
|
|
94
|
+
|
|
95
|
+
if (attrList.includes(k)) {
|
|
96
|
+
attrBag[k] = normalizeAttrValue(v);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
77
100
|
const childT = (childType as any)[k] as string | undefined;
|
|
78
101
|
out[k] = Array.isArray(v)
|
|
79
|
-
? v.map(it => toSoapArgs(it, childT, meta,
|
|
80
|
-
: toSoapArgs(v, childT, meta,
|
|
102
|
+
? v.map(it => toSoapArgs(it, childT, meta, attributesKeyIn, attributesKeyOut))
|
|
103
|
+
: toSoapArgs(v, childT, meta, attributesKeyIn, attributesKeyOut);
|
|
81
104
|
}
|
|
82
|
-
|
|
83
|
-
if (Object.keys(attrBag).length)
|
|
105
|
+
|
|
106
|
+
if (Object.keys(attrBag).length) {
|
|
107
|
+
out[attributesKeyOut] = attrBag; // renders as XML attributes
|
|
108
|
+
}
|
|
109
|
+
|
|
84
110
|
return out;
|
|
85
111
|
}
|
|
86
112
|
|
|
@@ -88,31 +114,31 @@ export function fromSoapResult(
|
|
|
88
114
|
node: any,
|
|
89
115
|
typeName?: string,
|
|
90
116
|
meta?: { ATTR_SPEC: AttrSpec; CHILD_TYPE: ChildType; PROP_META: PropMeta },
|
|
91
|
-
|
|
117
|
+
attributesKeyOut: string = "$attributes"
|
|
92
118
|
): any {
|
|
93
119
|
if (node == null) return node;
|
|
94
120
|
if (typeof node !== "object") return node;
|
|
95
|
-
if (Array.isArray(node)) return node.map(n => fromSoapResult(n, typeName, meta,
|
|
121
|
+
if (Array.isArray(node)) return node.map(n => fromSoapResult(n, typeName, meta, attributesKeyOut));
|
|
96
122
|
|
|
97
123
|
const childType = (typeName && meta?.CHILD_TYPE?.[typeName]) || {};
|
|
98
124
|
const result: any = {};
|
|
99
125
|
|
|
100
|
-
// map SOAP $value -> TS $value
|
|
101
126
|
if ("$value" in node) result.$value = (node as any).$value;
|
|
102
127
|
|
|
103
|
-
// hoist attributes from
|
|
104
|
-
const inAttrNode = (node as any)[
|
|
128
|
+
// hoist attributes from supported buckets
|
|
129
|
+
const inAttrNode = (node as any)[attributesKeyOut] || (node as any)["attributes"] || (node as any)["$"];
|
|
105
130
|
if (inAttrNode && typeof inAttrNode === "object") {
|
|
106
131
|
Object.assign(result, inAttrNode);
|
|
107
132
|
}
|
|
108
133
|
|
|
109
134
|
for (const [k, v] of Object.entries<any>(node)) {
|
|
110
|
-
if (k ===
|
|
135
|
+
if (k === attributesKeyOut || k === "attributes" || k === "$" || k === "$value") continue;
|
|
111
136
|
const childT = (childType as any)[k] as string | undefined;
|
|
112
137
|
result[k] = Array.isArray(v)
|
|
113
|
-
? v.map(it => fromSoapResult(it, childT, meta,
|
|
114
|
-
: fromSoapResult(v, childT, meta,
|
|
138
|
+
? v.map(it => fromSoapResult(it, childT, meta, attributesKeyOut))
|
|
139
|
+
: fromSoapResult(v, childT, meta, attributesKeyOut);
|
|
115
140
|
}
|
|
141
|
+
|
|
116
142
|
return result;
|
|
117
143
|
}
|
|
118
144
|
`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@techspokes/typescript-wsdl-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
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",
|