@typespec/http-server-js 0.58.0-alpha.11-dev.4 → 0.58.0-alpha.11-dev.6

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.
@@ -0,0 +1,221 @@
1
+ import {
2
+ isErrorType,
3
+ isVoidType,
4
+ LiteralType,
5
+ Model,
6
+ ModelProperty,
7
+ Scalar,
8
+ Type,
9
+ Union,
10
+ } from "@typespec/compiler";
11
+ import { $ } from "@typespec/compiler/experimental/typekit";
12
+ import { parseCase } from "../../util/case.js";
13
+
14
+ /**
15
+ * Generates a mock value for a TypeSpec Model.
16
+ * Handles arrays and records as special cases.
17
+ *
18
+ * @param type - The TypeSpec Model to mock
19
+ * @returns A JavaScript string representation of the mock data
20
+ * @throws Error if a property cannot be mocked
21
+ */
22
+ function mockModel(type: Model): string {
23
+ if ($.array.is(type)) {
24
+ return mockArray(type);
25
+ }
26
+
27
+ if ($.record.is(type)) {
28
+ return mockRecord(type);
29
+ }
30
+
31
+ const mock: string[][] = [];
32
+ const properties = $.model.getProperties(type, { includeExtended: true });
33
+
34
+ // If no properties exist, return an empty object
35
+ if (properties.size === 0) {
36
+ return "{}";
37
+ }
38
+
39
+ for (const [name, prop] of properties) {
40
+ if (prop.optional) {
41
+ continue;
42
+ }
43
+
44
+ const propMock = mockType(prop.type);
45
+
46
+ if (!propMock) {
47
+ throw new Error(`Could not mock property ${name} of type ${prop.type.kind}`);
48
+ }
49
+
50
+ const propName = parseCase(name).camelCase;
51
+ mock.push([propName, propMock]);
52
+ }
53
+
54
+ // If all properties were optional, return an empty object
55
+ if (mock.length === 0) {
56
+ return "{}";
57
+ }
58
+
59
+ return `{
60
+ ${mock.map(([name, value]) => `${name}: ${value}`).join(",\n")}
61
+ }`;
62
+ }
63
+
64
+ /**
65
+ * Generates a mock array containing a single mocked element.
66
+ *
67
+ * @param type - The TypeSpec array Model to mock
68
+ * @returns A JavaScript string representation of the mock array
69
+ */
70
+ function mockArray(type: Model): string {
71
+ const elementType = $.array.getElementType(type);
72
+ const mockedType = mockType(elementType);
73
+
74
+ // If we can't mock the element type, return an empty array
75
+ if (mockedType === undefined) {
76
+ return "[]";
77
+ }
78
+
79
+ return `[${mockedType}]`;
80
+ }
81
+
82
+ /**
83
+ * Generates a mock for a TypeSpec record type with a sample key.
84
+ *
85
+ * @param type - The TypeSpec record Model to mock
86
+ * @returns A JavaScript string representation of the mock record
87
+ */
88
+ function mockRecord(type: Model): string {
89
+ const elementType = $.record.getElementType(type);
90
+ const mockedType = mockType(elementType);
91
+
92
+ if (mockedType === undefined) {
93
+ return "{}";
94
+ }
95
+
96
+ return `{
97
+ mockKey: ${mockedType},
98
+ }`;
99
+ }
100
+
101
+ /**
102
+ * Mocks a TypeSpec Model property by mocking its type.
103
+ *
104
+ * @param prop - The TypeSpec model property to mock
105
+ * @returns A JavaScript string representation of the mocked property or undefined if it cannot be mocked
106
+ */
107
+ function mockModelProperty(prop: ModelProperty): string | undefined {
108
+ return mockType(prop.type);
109
+ }
110
+
111
+ /**
112
+ * Generates a mock for a TypeSpec literal value.
113
+ *
114
+ * @param type - The TypeSpec literal type to mock
115
+ * @returns A JavaScript string representation of the literal value
116
+ */
117
+ function mockLiteral(type: LiteralType): string {
118
+ return JSON.stringify(type.value);
119
+ }
120
+
121
+ /**
122
+ * Entry point for generating mock data for any TypeSpec type.
123
+ * Delegates to specific mock functions based on the type kind.
124
+ *
125
+ * @param type - The TypeSpec type to mock
126
+ * @returns A JavaScript string representation of the mock data, or undefined if the type cannot be mocked
127
+ */
128
+ export function mockType(type: Type): string | undefined {
129
+ if ($.model.is(type)) {
130
+ return mockModel(type);
131
+ }
132
+
133
+ if ($.literal.is(type)) {
134
+ return mockLiteral(type);
135
+ }
136
+
137
+ if ($.modelProperty.is(type)) {
138
+ return mockModelProperty(type);
139
+ }
140
+
141
+ if ($.scalar.is(type)) {
142
+ return mockScalar(type);
143
+ }
144
+
145
+ if ($.union.is(type)) {
146
+ return mockUnion(type);
147
+ }
148
+
149
+ if (isVoidType(type)) {
150
+ return "void";
151
+ }
152
+
153
+ return undefined;
154
+ }
155
+
156
+ /**
157
+ * Generates a mock for a TypeSpec union by mocking the first non-error variant.
158
+ *
159
+ * @param union - The TypeSpec union to mock
160
+ * @returns A JavaScript string representation of a mock for one variant, or undefined if no suitable variant is found
161
+ */
162
+ function mockUnion(union: Union): string | undefined {
163
+ for (const variant of union.variants.values()) {
164
+ if (isErrorType(variant.type)) {
165
+ continue;
166
+ }
167
+ return mockType(variant.type);
168
+ }
169
+
170
+ return undefined;
171
+ }
172
+
173
+ /**
174
+ * Generates appropriate mock values for TypeSpec scalar types.
175
+ * Handles various scalar types including primitives and specialized types like dates.
176
+ *
177
+ * @param scalar - The TypeSpec scalar to mock
178
+ * @returns A JavaScript string representation of a suitable mock value for the scalar type
179
+ */
180
+ function mockScalar(scalar: Scalar): string | undefined {
181
+ if ($.scalar.isBoolean(scalar) || $.scalar.extendsBoolean(scalar)) {
182
+ return JSON.stringify(true);
183
+ }
184
+ if ($.scalar.isNumeric(scalar) || $.scalar.extendsNumeric(scalar)) {
185
+ return JSON.stringify(42);
186
+ }
187
+
188
+ if ($.scalar.isUtcDateTime(scalar) || $.scalar.extendsUtcDateTime(scalar)) {
189
+ return "new Date()";
190
+ }
191
+
192
+ if ($.scalar.isBytes(scalar) || $.scalar.extendsBytes(scalar)) {
193
+ return "new Uint8Array()";
194
+ }
195
+
196
+ if ($.scalar.isDuration(scalar) || $.scalar.extendsDuration(scalar)) {
197
+ return JSON.stringify("P1Y2M3DT4H5M6S");
198
+ }
199
+
200
+ if ($.scalar.isOffsetDateTime(scalar) || $.scalar.extendsOffsetDateTime(scalar)) {
201
+ return JSON.stringify("2022-01-01T00:00:00Z");
202
+ }
203
+
204
+ if ($.scalar.isPlainDate(scalar) || $.scalar.extendsPlainDate(scalar)) {
205
+ return JSON.stringify("2022-01-01");
206
+ }
207
+
208
+ if ($.scalar.isPlainTime(scalar) || $.scalar.extendsPlainTime(scalar)) {
209
+ return JSON.stringify("00:00:00");
210
+ }
211
+
212
+ if ($.scalar.isUrl(scalar) || $.scalar.extendsUrl(scalar)) {
213
+ return JSON.stringify("https://example.com");
214
+ }
215
+
216
+ if ($.scalar.isString(scalar) || $.scalar.extendsString(scalar)) {
217
+ return JSON.stringify("mock-string");
218
+ }
219
+
220
+ return undefined;
221
+ }