@azure-tools/typespec-ts 0.38.3 → 0.38.4-alpha.20250307.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 (51) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +16 -16
  3. package/dist/src/index.d.ts.map +1 -1
  4. package/dist/src/index.js +10 -8
  5. package/dist/src/index.js.map +1 -1
  6. package/dist/src/lib.d.ts +71 -2
  7. package/dist/src/lib.d.ts.map +1 -1
  8. package/dist/src/lib.js +108 -1
  9. package/dist/src/lib.js.map +1 -1
  10. package/dist/src/modular/buildClientContext.js +1 -1
  11. package/dist/src/modular/buildClientContext.js.map +1 -1
  12. package/dist/src/modular/emitModels.d.ts +1 -1
  13. package/dist/src/modular/emitModels.d.ts.map +1 -1
  14. package/dist/src/modular/emitModels.js +25 -7
  15. package/dist/src/modular/emitModels.js.map +1 -1
  16. package/dist/src/modular/emitSamples.js +1 -1
  17. package/dist/src/modular/emitSamples.js.map +1 -1
  18. package/dist/src/modular/helpers/classicalOperationHelpers.d.ts.map +1 -1
  19. package/dist/src/modular/helpers/classicalOperationHelpers.js +1 -1
  20. package/dist/src/modular/helpers/classicalOperationHelpers.js.map +1 -1
  21. package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
  22. package/dist/src/modular/helpers/operationHelpers.js +44 -20
  23. package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
  24. package/dist/src/modular/static-helpers-metadata.d.ts +7 -0
  25. package/dist/src/modular/static-helpers-metadata.d.ts.map +1 -1
  26. package/dist/src/modular/static-helpers-metadata.js +7 -0
  27. package/dist/src/modular/static-helpers-metadata.js.map +1 -1
  28. package/dist/src/transform/transform.d.ts.map +1 -1
  29. package/dist/src/transform/transform.js +4 -0
  30. package/dist/src/transform/transform.js.map +1 -1
  31. package/dist/src/transform/transfromRLCOptions.d.ts +4 -0
  32. package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
  33. package/dist/src/transform/transfromRLCOptions.js +283 -29
  34. package/dist/src/transform/transfromRLCOptions.js.map +1 -1
  35. package/dist/src/utils/operationUtil.d.ts.map +1 -1
  36. package/dist/src/utils/operationUtil.js +2 -4
  37. package/dist/src/utils/operationUtil.js.map +1 -1
  38. package/dist/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +23 -23
  40. package/src/index.ts +11 -4
  41. package/src/lib.ts +167 -2
  42. package/src/modular/buildClientContext.ts +5 -1
  43. package/src/modular/emitModels.ts +42 -10
  44. package/src/modular/emitSamples.ts +1 -1
  45. package/src/modular/helpers/classicalOperationHelpers.ts +5 -4
  46. package/src/modular/helpers/operationHelpers.ts +66 -30
  47. package/src/modular/static-helpers-metadata.ts +7 -0
  48. package/src/transform/transform.ts +4 -0
  49. package/src/transform/transfromRLCOptions.ts +340 -41
  50. package/src/utils/operationUtil.ts +2 -4
  51. package/static/static-helpers/urlTemplate.ts +196 -0
@@ -0,0 +1,196 @@
1
+ //---------------------
2
+ // interfaces
3
+ //---------------------
4
+ interface ValueOptions {
5
+ isFirst: boolean; // is first value in the expression
6
+ op?: string; // operator
7
+ varValue?: any; // variable value
8
+ varName?: string; // variable name
9
+ modifier?: string; // modifier e.g *
10
+ reserved?: boolean; // if true we'll keep reserved words with not encoding
11
+ }
12
+
13
+ export interface UrlTemplateOptions {
14
+ // if set to true, reserved characters will not be encoded
15
+ allowReserved?: boolean;
16
+ }
17
+
18
+ // ---------------------
19
+ // helpers
20
+ // ---------------------
21
+ function encodeComponent(val: string, reserved?: boolean, op?: string) {
22
+ return (reserved ?? op === "+") || op === "#"
23
+ ? encodeReservedComponent(val)
24
+ : encodeRFC3986URIComponent(val);
25
+ }
26
+
27
+ function encodeReservedComponent(str: string) {
28
+ return str
29
+ .split(/(%[0-9A-Fa-f]{2})/g)
30
+ .map((part) => (!/%[0-9A-Fa-f]/.test(part) ? encodeURI(part) : part))
31
+ .join("");
32
+ }
33
+
34
+ function encodeRFC3986URIComponent(str: string) {
35
+ return encodeURIComponent(str).replace(
36
+ /[!'()*]/g,
37
+ (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
38
+ );
39
+ }
40
+
41
+ function isDefined(val: any) {
42
+ return val !== undefined && val !== null;
43
+ }
44
+
45
+ function getNamedAndIfEmpty(op?: string): [boolean, string] {
46
+ return [
47
+ !!op && [";", "?", "&"].includes(op),
48
+ !!op && ["?", "&"].includes(op) ? "=" : ""
49
+ ];
50
+ }
51
+
52
+ function getFirstOrSep(op?: string, isFirst = false) {
53
+ if (isFirst) {
54
+ return !op || op === "+" ? "" : op;
55
+ } else if (!op || op === "+" || op === "#") {
56
+ return ",";
57
+ } else if (op === "?") {
58
+ return "&";
59
+ } else {
60
+ return op;
61
+ }
62
+ }
63
+
64
+ function getExpandedValue(option: ValueOptions) {
65
+ let isFirst = option.isFirst;
66
+ const { op, varName, varValue: value, reserved } = option;
67
+ const vals: string[] = [];
68
+ const [named, ifEmpty] = getNamedAndIfEmpty(op);
69
+
70
+ if (Array.isArray(value)) {
71
+ for (const val of value.filter(isDefined)) {
72
+ // prepare the following parts: separator, varName, value
73
+ vals.push(`${getFirstOrSep(op, isFirst)}`);
74
+ if (named && varName) {
75
+ vals.push(`${encodeURIComponent(varName)}`);
76
+ val === "" ? vals.push(ifEmpty) : vals.push("=");
77
+ }
78
+ vals.push(encodeComponent(val, reserved, op));
79
+ isFirst = false;
80
+ }
81
+ } else if (typeof value === "object") {
82
+ for (const key of Object.keys(value)) {
83
+ const val = value[key];
84
+ if (!isDefined(val)) {
85
+ continue;
86
+ }
87
+ // prepare the following parts: separator, key, value
88
+ vals.push(`${getFirstOrSep(op, isFirst)}`);
89
+ if (key) {
90
+ vals.push(`${encodeURIComponent(key)}`);
91
+ named && val === "" ? vals.push(ifEmpty) : vals.push("=");
92
+ }
93
+ vals.push(encodeComponent(val, reserved, op));
94
+ isFirst = false;
95
+ }
96
+ }
97
+ return vals.join("");
98
+ }
99
+
100
+ function getNonExpandedValue(option: ValueOptions) {
101
+ const { op, varName, varValue: value, isFirst, reserved } = option;
102
+ const vals: string[] = [];
103
+ const first = getFirstOrSep(op, isFirst);
104
+ const [named, ifEmpty] = getNamedAndIfEmpty(op);
105
+ if (named && varName) {
106
+ vals.push(encodeComponent(varName, reserved, op));
107
+ if (value === "") {
108
+ if (!ifEmpty) {
109
+ vals.push(ifEmpty);
110
+ }
111
+ return !vals.join("") ? undefined : `${first}${vals.join("")}`;
112
+ }
113
+ vals.push("=");
114
+ }
115
+
116
+ const items = [];
117
+ if (Array.isArray(value)) {
118
+ for (const val of value.filter(isDefined)) {
119
+ items.push(encodeComponent(val, reserved, op));
120
+ }
121
+ } else if (typeof value === "object") {
122
+ for (const key of Object.keys(value)) {
123
+ if (!isDefined(value[key])) {
124
+ continue;
125
+ }
126
+ items.push(encodeRFC3986URIComponent(key));
127
+ items.push(encodeComponent(value[key], reserved, op));
128
+ }
129
+ }
130
+ vals.push(items.join(","));
131
+ return !vals.join(",") ? undefined : `${first}${vals.join("")}`;
132
+ }
133
+
134
+ function getVarValue(option: ValueOptions): string | undefined {
135
+ const { op, varName, modifier, isFirst, reserved, varValue: value } = option;
136
+
137
+ if (!isDefined(value)) {
138
+ return undefined;
139
+ } else if (["string", "number", "boolean"].includes(typeof value)) {
140
+ let val = value.toString();
141
+ const [named, ifEmpty] = getNamedAndIfEmpty(op);
142
+ const vals: string[] = [getFirstOrSep(op, isFirst)];
143
+ if (named && varName) {
144
+ vals.push(encodeRFC3986URIComponent(varName));
145
+ val === "" ? vals.push(ifEmpty) : vals.push("=");
146
+ }
147
+ if (modifier && modifier !== "*") {
148
+ val = val.substring(0, parseInt(modifier, 10));
149
+ }
150
+ vals.push(encodeComponent(val, reserved, op));
151
+ return vals.join("");
152
+ } else if (modifier === "*") {
153
+ return getExpandedValue(option);
154
+ } else {
155
+ return getNonExpandedValue(option);
156
+ }
157
+ }
158
+
159
+ // ---------------------------------------------------------------------------------------------------
160
+ // This is an implementation of RFC 6570 URI Template: https://datatracker.ietf.org/doc/html/rfc6570.
161
+ // ---------------------------------------------------------------------------------------------------
162
+ export function expandUrlTemplate(
163
+ template: string,
164
+ context: Record<string, any>,
165
+ option?: UrlTemplateOptions
166
+ ): string {
167
+ return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, (_, expr, text) => {
168
+ if (!expr) {
169
+ return encodeReservedComponent(text);
170
+ }
171
+ let op;
172
+ if (["+", "#", ".", "/", ";", "?", "&"].includes(expr[0])) {
173
+ (op = expr[0]), (expr = expr.slice(1));
174
+ }
175
+ const varList = expr.split(/,/g);
176
+ const result = [];
177
+ for (const varSpec of varList) {
178
+ const varMatch = /([^:\*]*)(?::(\d+)|(\*))?/.exec(varSpec);
179
+ if (!varMatch || !varMatch[1]) {
180
+ continue;
181
+ }
182
+ const varValue = getVarValue({
183
+ isFirst: result.length === 0,
184
+ op,
185
+ varValue: context[varMatch[1]],
186
+ varName: varMatch[1],
187
+ modifier: varMatch[2] || varMatch[3],
188
+ reserved: option?.allowReserved
189
+ });
190
+ if (varValue) {
191
+ result.push(varValue);
192
+ }
193
+ }
194
+ return result.join("");
195
+ });
196
+ }