@azure-tools/typespec-ts 0.49.0 → 0.49.1
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.
- package/CHANGELOG.md +24 -0
- package/dist/src/framework/hooks/binder.d.ts.map +1 -1
- package/dist/src/framework/hooks/binder.js +8 -17
- package/dist/src/framework/hooks/binder.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +13 -11
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib.d.ts +8 -0
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +10 -0
- package/dist/src/lib.js.map +1 -1
- package/dist/src/modular/buildOperations.d.ts.map +1 -1
- package/dist/src/modular/buildOperations.js +10 -5
- package/dist/src/modular/buildOperations.js.map +1 -1
- package/dist/src/modular/buildProjectFiles.d.ts.map +1 -1
- package/dist/src/modular/buildProjectFiles.js +13 -10
- package/dist/src/modular/buildProjectFiles.js.map +1 -1
- package/dist/src/modular/emitModels.d.ts.map +1 -1
- package/dist/src/modular/emitModels.js +43 -40
- package/dist/src/modular/emitModels.js.map +1 -1
- package/dist/src/modular/emitSamples.d.ts.map +1 -1
- package/dist/src/modular/emitSamples.js +9 -0
- package/dist/src/modular/emitSamples.js.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.js +4 -1
- package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
- package/dist/src/modular/helpers/namingHelpers.d.ts +7 -0
- package/dist/src/modular/helpers/namingHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/namingHelpers.js +15 -0
- package/dist/src/modular/helpers/namingHelpers.js.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts +19 -2
- package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.js +410 -39
- package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
- package/dist/src/modular/serialization/buildDeserializerFunction.d.ts.map +1 -1
- package/dist/src/modular/serialization/buildDeserializerFunction.js +9 -3
- package/dist/src/modular/serialization/buildDeserializerFunction.js.map +1 -1
- package/dist/src/modular/serialization/buildXmlSerializerFunction.d.ts +12 -0
- package/dist/src/modular/serialization/buildXmlSerializerFunction.d.ts.map +1 -1
- package/dist/src/modular/serialization/buildXmlSerializerFunction.js +259 -18
- package/dist/src/modular/serialization/buildXmlSerializerFunction.js.map +1 -1
- package/dist/src/modular/static-helpers-metadata.d.ts +10 -0
- package/dist/src/modular/static-helpers-metadata.d.ts.map +1 -1
- package/dist/src/modular/static-helpers-metadata.js +10 -0
- package/dist/src/modular/static-helpers-metadata.js.map +1 -1
- package/dist/src/modular/type-expressions/get-model-expression.d.ts +3 -1
- package/dist/src/modular/type-expressions/get-model-expression.d.ts.map +1 -1
- package/dist/src/modular/type-expressions/get-model-expression.js +50 -9
- package/dist/src/modular/type-expressions/get-model-expression.js.map +1 -1
- package/dist/src/modular/type-expressions/get-nullable-expression.d.ts.map +1 -1
- package/dist/src/modular/type-expressions/get-nullable-expression.js +8 -0
- package/dist/src/modular/type-expressions/get-nullable-expression.js.map +1 -1
- package/dist/src/modular/type-expressions/get-type-expression.d.ts +3 -2
- package/dist/src/modular/type-expressions/get-type-expression.d.ts.map +1 -1
- package/dist/src/modular/type-expressions/get-type-expression.js.map +1 -1
- package/dist/src/transform/transform.d.ts.map +1 -1
- package/dist/src/transform/transform.js +10 -10
- package/dist/src/transform/transform.js.map +1 -1
- package/dist/src/transform/transformSchemas.d.ts.map +1 -1
- package/dist/src/transform/transformSchemas.js +4 -4
- package/dist/src/transform/transformSchemas.js.map +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
- package/dist/src/transform/transfromRLCOptions.js +37 -24
- package/dist/src/transform/transfromRLCOptions.js.map +1 -1
- package/dist/src/utils/clientUtils.d.ts +1 -1
- package/dist/src/utils/clientUtils.d.ts.map +1 -1
- package/dist/src/utils/clientUtils.js +40 -17
- package/dist/src/utils/clientUtils.js.map +1 -1
- package/dist/src/utils/crossLanguageDef.d.ts.map +1 -1
- package/dist/src/utils/crossLanguageDef.js +9 -3
- package/dist/src/utils/crossLanguageDef.js.map +1 -1
- package/dist/src/utils/interfaces.d.ts +2 -1
- package/dist/src/utils/interfaces.d.ts.map +1 -1
- package/dist/src/utils/modelUtils.d.ts +2 -2
- package/dist/src/utils/modelUtils.d.ts.map +1 -1
- package/dist/src/utils/modelUtils.js +15 -16
- package/dist/src/utils/modelUtils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +22 -22
- package/src/framework/hooks/binder.ts +12 -22
- package/src/index.ts +17 -10
- package/src/lib.ts +20 -0
- package/src/modular/buildOperations.ts +12 -4
- package/src/modular/buildProjectFiles.ts +19 -16
- package/src/modular/emitModels.ts +72 -44
- package/src/modular/emitSamples.ts +11 -1
- package/src/modular/helpers/clientHelpers.ts +5 -1
- package/src/modular/helpers/namingHelpers.ts +19 -0
- package/src/modular/helpers/operationHelpers.ts +533 -40
- package/src/modular/serialization/buildDeserializerFunction.ts +11 -2
- package/src/modular/serialization/buildXmlSerializerFunction.ts +375 -24
- package/src/modular/static-helpers-metadata.ts +10 -0
- package/src/modular/type-expressions/get-model-expression.ts +78 -13
- package/src/modular/type-expressions/get-nullable-expression.ts +9 -0
- package/src/modular/type-expressions/get-type-expression.ts +3 -1
- package/src/transform/transform.ts +5 -2
- package/src/transform/transformSchemas.ts +4 -1
- package/src/transform/transfromRLCOptions.ts +65 -24
- package/src/utils/clientUtils.ts +49 -16
- package/src/utils/crossLanguageDef.ts +8 -0
- package/src/utils/interfaces.ts +2 -1
- package/src/utils/modelUtils.ts +22 -18
- package/static/static-helpers/serialization/serialize-record.ts +3 -3
- package/static/static-helpers/serialization/xml-helpers.ts +91 -36
- package/static/static-helpers/urlTemplate.ts +5 -5
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
3
|
|
|
4
4
|
import { XMLBuilder, XMLParser, XmlBuilderOptions } from "fast-xml-parser";
|
|
5
|
+
import { uint8ArrayToString, stringToUint8Array } from "@azure/core-util";
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* XML serialization options for a property or model
|
|
@@ -41,6 +42,10 @@ export interface XmlPropertyMetadata {
|
|
|
41
42
|
type?: "array" | "object" | "primitive" | "date" | "bytes" | "dict";
|
|
42
43
|
/** Date encoding format */
|
|
43
44
|
dateEncoding?: "rfc3339" | "rfc7231" | "unixTimestamp";
|
|
45
|
+
/** Bytes encoding format (base64 or base64url) */
|
|
46
|
+
bytesEncoding?: "base64" | "base64url";
|
|
47
|
+
/** For arrays - type of each item for special handling */
|
|
48
|
+
itemType?: "primitive" | "date" | "bytes";
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
/**
|
|
@@ -57,6 +62,10 @@ export interface XmlPropertyDeserializeMetadata {
|
|
|
57
62
|
type?: "array" | "object" | "primitive" | "date" | "bytes" | "dict";
|
|
58
63
|
/** Date encoding format */
|
|
59
64
|
dateEncoding?: "rfc3339" | "rfc7231" | "unixTimestamp";
|
|
65
|
+
/** Bytes encoding format (base64 or base64url) */
|
|
66
|
+
bytesEncoding?: "base64" | "base64url";
|
|
67
|
+
/** For arrays - type of each item for special handling */
|
|
68
|
+
itemType?: "primitive" | "date" | "bytes";
|
|
60
69
|
}
|
|
61
70
|
|
|
62
71
|
/**
|
|
@@ -97,7 +106,7 @@ const defaultBuilderOptions: Partial<XmlBuilderOptions> = {
|
|
|
97
106
|
ignoreAttributes: false,
|
|
98
107
|
attributeNamePrefix: "@_",
|
|
99
108
|
textNodeName: "#text",
|
|
100
|
-
format:
|
|
109
|
+
format: false,
|
|
101
110
|
suppressEmptyNode: true
|
|
102
111
|
};
|
|
103
112
|
|
|
@@ -165,7 +174,8 @@ function collectNamespaces(
|
|
|
165
174
|
function serializePrimitiveValue(
|
|
166
175
|
value: any,
|
|
167
176
|
type?: "array" | "object" | "primitive" | "date" | "bytes" | "dict",
|
|
168
|
-
dateEncoding?: "rfc3339" | "rfc7231" | "unixTimestamp"
|
|
177
|
+
dateEncoding?: "rfc3339" | "rfc7231" | "unixTimestamp",
|
|
178
|
+
bytesEncoding?: "base64" | "base64url"
|
|
169
179
|
): string | number | boolean {
|
|
170
180
|
if (value === null || value === undefined) {
|
|
171
181
|
return "";
|
|
@@ -184,8 +194,7 @@ function serializePrimitiveValue(
|
|
|
184
194
|
}
|
|
185
195
|
|
|
186
196
|
if (type === "bytes" && value instanceof Uint8Array) {
|
|
187
|
-
|
|
188
|
-
return btoa(String.fromCharCode(...value));
|
|
197
|
+
return uint8ArrayToString(value, bytesEncoding ?? "base64");
|
|
189
198
|
}
|
|
190
199
|
|
|
191
200
|
if (typeof value === "boolean" || typeof value === "number") {
|
|
@@ -212,7 +221,12 @@ function serializeArrayProperty(
|
|
|
212
221
|
if (serializer) {
|
|
213
222
|
return serializer(item);
|
|
214
223
|
}
|
|
215
|
-
return serializePrimitiveValue(
|
|
224
|
+
return serializePrimitiveValue(
|
|
225
|
+
item,
|
|
226
|
+
metadata.itemType ?? metadata.type,
|
|
227
|
+
metadata.dateEncoding,
|
|
228
|
+
metadata.bytesEncoding
|
|
229
|
+
);
|
|
216
230
|
});
|
|
217
231
|
|
|
218
232
|
if (xmlOptions.unwrapped) {
|
|
@@ -268,7 +282,8 @@ export function serializeModelToXml(
|
|
|
268
282
|
attributes[attrName] = serializePrimitiveValue(
|
|
269
283
|
value,
|
|
270
284
|
type,
|
|
271
|
-
prop.dateEncoding
|
|
285
|
+
prop.dateEncoding,
|
|
286
|
+
prop.bytesEncoding
|
|
272
287
|
);
|
|
273
288
|
} else if (type === "dict" && value !== null && typeof value === "object") {
|
|
274
289
|
// Serialize dictionary - each key-value pair becomes an element
|
|
@@ -295,13 +310,19 @@ export function serializeModelToXml(
|
|
|
295
310
|
result[elementName] = serializer(value);
|
|
296
311
|
} else if (xmlOptions.unwrapped && !Array.isArray(value)) {
|
|
297
312
|
// Unwrapped primitive - this becomes the text content of the parent element
|
|
298
|
-
result["#text"] = serializePrimitiveValue(
|
|
313
|
+
result["#text"] = serializePrimitiveValue(
|
|
314
|
+
value,
|
|
315
|
+
type,
|
|
316
|
+
prop.dateEncoding,
|
|
317
|
+
prop.bytesEncoding
|
|
318
|
+
);
|
|
299
319
|
} else {
|
|
300
320
|
// Serialize primitive
|
|
301
321
|
result[elementName] = serializePrimitiveValue(
|
|
302
322
|
value,
|
|
303
323
|
type,
|
|
304
|
-
prop.dateEncoding
|
|
324
|
+
prop.dateEncoding,
|
|
325
|
+
prop.bytesEncoding
|
|
305
326
|
);
|
|
306
327
|
}
|
|
307
328
|
}
|
|
@@ -328,7 +349,11 @@ export function xmlObjectToString(
|
|
|
328
349
|
...options
|
|
329
350
|
});
|
|
330
351
|
|
|
331
|
-
|
|
352
|
+
const xmlData: string = builder.build(xmlObject);
|
|
353
|
+
if (!xmlData) {
|
|
354
|
+
return "";
|
|
355
|
+
}
|
|
356
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>${xmlData}`;
|
|
332
357
|
}
|
|
333
358
|
|
|
334
359
|
/**
|
|
@@ -366,7 +391,8 @@ export function parseXmlString(
|
|
|
366
391
|
function deserializePrimitiveValue(
|
|
367
392
|
value: any,
|
|
368
393
|
type?: "array" | "object" | "primitive" | "date" | "bytes" | "dict",
|
|
369
|
-
dateEncoding?: "rfc3339" | "rfc7231" | "unixTimestamp"
|
|
394
|
+
dateEncoding?: "rfc3339" | "rfc7231" | "unixTimestamp",
|
|
395
|
+
bytesEncoding?: "base64" | "base64url"
|
|
370
396
|
): any {
|
|
371
397
|
if (value === null || value === undefined || value === "") {
|
|
372
398
|
return undefined;
|
|
@@ -380,13 +406,7 @@ function deserializePrimitiveValue(
|
|
|
380
406
|
}
|
|
381
407
|
|
|
382
408
|
if (type === "bytes" && typeof value === "string") {
|
|
383
|
-
|
|
384
|
-
const binaryString = atob(value);
|
|
385
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
386
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
387
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
388
|
-
}
|
|
389
|
-
return bytes;
|
|
409
|
+
return stringToUint8Array(value, bytesEncoding ?? "base64");
|
|
390
410
|
}
|
|
391
411
|
|
|
392
412
|
return value;
|
|
@@ -479,7 +499,12 @@ function deserializeArrayProperty(
|
|
|
479
499
|
if (deserializer) {
|
|
480
500
|
return deserializer(unwrappedItem);
|
|
481
501
|
}
|
|
482
|
-
return deserializePrimitiveValue(
|
|
502
|
+
return deserializePrimitiveValue(
|
|
503
|
+
unwrappedItem,
|
|
504
|
+
metadata.itemType ?? type,
|
|
505
|
+
dateEncoding,
|
|
506
|
+
metadata.bytesEncoding
|
|
507
|
+
);
|
|
483
508
|
});
|
|
484
509
|
}
|
|
485
510
|
|
|
@@ -501,6 +526,41 @@ export function deserializeXmlToModel<T = Record<string, any>>(
|
|
|
501
526
|
let content = xmlObject[rootElementName] ?? xmlObject[rootName] ?? xmlObject;
|
|
502
527
|
content = unwrapSingleElementArray(content);
|
|
503
528
|
|
|
529
|
+
return deserializeXmlObject<T>(content, properties);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Full deserialization: XML string to model
|
|
534
|
+
*/
|
|
535
|
+
export function deserializeFromXml<T = Record<string, any>>(
|
|
536
|
+
xmlString: string,
|
|
537
|
+
properties: XmlPropertyDeserializeMetadata[],
|
|
538
|
+
rootName: string,
|
|
539
|
+
rootNs?: { namespace: string; prefix: string },
|
|
540
|
+
parserOptions?: Partial<typeof defaultParserOptions>
|
|
541
|
+
): T {
|
|
542
|
+
const xmlObject = parseXmlString(xmlString, parserOptions);
|
|
543
|
+
return deserializeXmlToModel<T>(xmlObject, properties, rootName, rootNs);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Deserializes a pre-parsed XML object to a model.
|
|
548
|
+
* This is used for nested objects where the XML has already been parsed
|
|
549
|
+
* and we have the object content directly (without a root element wrapper).
|
|
550
|
+
* Unlike deserializeFromXml, this does not parse XML strings and does not
|
|
551
|
+
* expect a root element to unwrap.
|
|
552
|
+
*/
|
|
553
|
+
export function deserializeXmlObject<T = Record<string, any>>(
|
|
554
|
+
xmlObject: Record<string, unknown>,
|
|
555
|
+
properties: XmlPropertyDeserializeMetadata[]
|
|
556
|
+
): T {
|
|
557
|
+
if (!xmlObject) {
|
|
558
|
+
return {} as T;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// Unwrap if parser wrapped in single-element array
|
|
562
|
+
const content = unwrapSingleElementArray(xmlObject);
|
|
563
|
+
|
|
504
564
|
const result: Record<string, any> = {};
|
|
505
565
|
|
|
506
566
|
for (const prop of properties) {
|
|
@@ -529,7 +589,8 @@ export function deserializeXmlToModel<T = Record<string, any>>(
|
|
|
529
589
|
result[propertyName] = deserializePrimitiveValue(
|
|
530
590
|
rawValue,
|
|
531
591
|
type,
|
|
532
|
-
dateEncoding
|
|
592
|
+
dateEncoding,
|
|
593
|
+
prop.bytesEncoding
|
|
533
594
|
);
|
|
534
595
|
}
|
|
535
596
|
} else {
|
|
@@ -540,15 +601,23 @@ export function deserializeXmlToModel<T = Record<string, any>>(
|
|
|
540
601
|
continue;
|
|
541
602
|
}
|
|
542
603
|
|
|
543
|
-
if (deserializer
|
|
604
|
+
if (deserializer) {
|
|
544
605
|
// Deserialize nested object
|
|
545
|
-
|
|
606
|
+
if (typeof rawValue === "object") {
|
|
607
|
+
result[propertyName] = deserializer(rawValue);
|
|
608
|
+
} else {
|
|
609
|
+
// When the XML element only contains text content (like <Name>text</Name>),
|
|
610
|
+
// the parser returns the text as a string. Wrap it in an object with #text
|
|
611
|
+
// so the nested deserializer can extract unwrapped text content properly.
|
|
612
|
+
result[propertyName] = deserializer({ "#text": rawValue });
|
|
613
|
+
}
|
|
546
614
|
} else {
|
|
547
615
|
// Deserialize primitive
|
|
548
616
|
result[propertyName] = deserializePrimitiveValue(
|
|
549
617
|
rawValue,
|
|
550
618
|
type,
|
|
551
|
-
dateEncoding
|
|
619
|
+
dateEncoding,
|
|
620
|
+
prop.bytesEncoding
|
|
552
621
|
);
|
|
553
622
|
}
|
|
554
623
|
}
|
|
@@ -557,20 +626,6 @@ export function deserializeXmlToModel<T = Record<string, any>>(
|
|
|
557
626
|
return result as T;
|
|
558
627
|
}
|
|
559
628
|
|
|
560
|
-
/**
|
|
561
|
-
* Full deserialization: XML string to model
|
|
562
|
-
*/
|
|
563
|
-
export function deserializeFromXml<T = Record<string, any>>(
|
|
564
|
-
xmlString: string,
|
|
565
|
-
properties: XmlPropertyDeserializeMetadata[],
|
|
566
|
-
rootName: string,
|
|
567
|
-
rootNs?: { namespace: string; prefix: string },
|
|
568
|
-
parserOptions?: Partial<typeof defaultParserOptions>
|
|
569
|
-
): T {
|
|
570
|
-
const xmlObject = parseXmlString(xmlString, parserOptions);
|
|
571
|
-
return deserializeXmlToModel<T>(xmlObject, properties, rootName, rootNs);
|
|
572
|
-
}
|
|
573
|
-
|
|
574
629
|
/**
|
|
575
630
|
* Utility to check if a content type is XML
|
|
576
631
|
*/
|
|
@@ -187,14 +187,14 @@ export function expandUrlTemplate(
|
|
|
187
187
|
expr = expr.slice(1);
|
|
188
188
|
}
|
|
189
189
|
const varList = expr.split(/,/g);
|
|
190
|
-
const
|
|
190
|
+
const innerResult = [];
|
|
191
191
|
for (const varSpec of varList) {
|
|
192
192
|
const varMatch = /([^:*]*)(?::(\d+)|(\*))?/.exec(varSpec);
|
|
193
193
|
if (!varMatch || !varMatch[1]) {
|
|
194
194
|
continue;
|
|
195
195
|
}
|
|
196
196
|
const varValue = getVarValue({
|
|
197
|
-
isFirst:
|
|
197
|
+
isFirst: innerResult.length === 0,
|
|
198
198
|
op,
|
|
199
199
|
varValue: context[varMatch[1]],
|
|
200
200
|
varName: varMatch[1],
|
|
@@ -202,10 +202,10 @@ export function expandUrlTemplate(
|
|
|
202
202
|
reserved: option?.allowReserved
|
|
203
203
|
});
|
|
204
204
|
if (varValue) {
|
|
205
|
-
|
|
205
|
+
innerResult.push(varValue);
|
|
206
206
|
}
|
|
207
207
|
}
|
|
208
|
-
return
|
|
208
|
+
return innerResult.join("");
|
|
209
209
|
});
|
|
210
210
|
|
|
211
211
|
return normalizeUnreserved(result);
|
|
@@ -219,7 +219,7 @@ function normalizeUnreserved(uri: string): string {
|
|
|
219
219
|
return uri.replace(/%([0-9A-Fa-f]{2})/g, (match, hex) => {
|
|
220
220
|
const char = String.fromCharCode(parseInt(hex, 16));
|
|
221
221
|
// Decode only if it's unreserved
|
|
222
|
-
if (/[
|
|
222
|
+
if (/[.~-]/.test(char)) {
|
|
223
223
|
return char;
|
|
224
224
|
}
|
|
225
225
|
return match; // leave other encodings intact
|