@distilled.cloud/core 1.0.0-rc.1 → 1.0.0-rc.10

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 (148) hide show
  1. package/LICENSE +201 -0
  2. package/lib/api.d.ts.map +1 -1
  3. package/lib/api.js +16 -4
  4. package/lib/api.js.map +1 -1
  5. package/lib/category.d.ts +4 -4
  6. package/lib/category.js +4 -4
  7. package/lib/codegen/boolean-string-enums.d.ts +36 -0
  8. package/lib/codegen/boolean-string-enums.d.ts.map +1 -0
  9. package/lib/codegen/boolean-string-enums.js +94 -0
  10. package/lib/codegen/boolean-string-enums.js.map +1 -0
  11. package/lib/codegen/boolean-string-enums.test.d.ts +2 -0
  12. package/lib/codegen/boolean-string-enums.test.d.ts.map +1 -0
  13. package/lib/codegen/boolean-string-enums.test.js +147 -0
  14. package/lib/codegen/boolean-string-enums.test.js.map +1 -0
  15. package/lib/codegen/cli.d.ts +56 -6
  16. package/lib/codegen/cli.d.ts.map +1 -1
  17. package/lib/codegen/cli.js +59 -75
  18. package/lib/codegen/cli.js.map +1 -1
  19. package/lib/codegen/emit.d.ts +3 -7
  20. package/lib/codegen/emit.d.ts.map +1 -1
  21. package/lib/codegen/emit.js +6 -10
  22. package/lib/codegen/emit.js.map +1 -1
  23. package/lib/codegen/generator.d.ts.map +1 -1
  24. package/lib/codegen/generator.js +142 -20
  25. package/lib/codegen/generator.js.map +1 -1
  26. package/lib/codegen/graphql-client.d.ts +62 -0
  27. package/lib/codegen/graphql-client.d.ts.map +1 -0
  28. package/lib/codegen/graphql-client.js +294 -0
  29. package/lib/codegen/graphql-client.js.map +1 -0
  30. package/lib/codegen/graphql-client.test.d.ts +2 -0
  31. package/lib/codegen/graphql-client.test.d.ts.map +1 -0
  32. package/lib/codegen/graphql-client.test.js +311 -0
  33. package/lib/codegen/graphql-client.test.js.map +1 -0
  34. package/lib/codegen/graphql.d.ts +207 -0
  35. package/lib/codegen/graphql.d.ts.map +1 -0
  36. package/lib/codegen/graphql.js +799 -0
  37. package/lib/codegen/graphql.js.map +1 -0
  38. package/lib/codegen/openapi-cli.d.ts +17 -3
  39. package/lib/codegen/openapi-cli.d.ts.map +1 -1
  40. package/lib/codegen/openapi-cli.js +50 -48
  41. package/lib/codegen/openapi-cli.js.map +1 -1
  42. package/lib/codegen/openapi.d.ts +69 -6
  43. package/lib/codegen/openapi.d.ts.map +1 -1
  44. package/lib/codegen/openapi.js +173 -16
  45. package/lib/codegen/openapi.js.map +1 -1
  46. package/lib/codegen/patches.d.ts +65 -0
  47. package/lib/codegen/patches.d.ts.map +1 -0
  48. package/lib/codegen/patches.js +236 -0
  49. package/lib/codegen/patches.js.map +1 -0
  50. package/lib/codegen/patches.test.d.ts +2 -0
  51. package/lib/codegen/patches.test.d.ts.map +1 -0
  52. package/lib/codegen/patches.test.js +105 -0
  53. package/lib/codegen/patches.test.js.map +1 -0
  54. package/lib/codegen/proto.d.ts +121 -0
  55. package/lib/codegen/proto.d.ts.map +1 -0
  56. package/lib/codegen/proto.js +962 -0
  57. package/lib/codegen/proto.js.map +1 -0
  58. package/lib/codegen/rewrite-operation-ids.d.ts +131 -0
  59. package/lib/codegen/rewrite-operation-ids.d.ts.map +1 -0
  60. package/lib/codegen/rewrite-operation-ids.js +1079 -0
  61. package/lib/codegen/rewrite-operation-ids.js.map +1 -0
  62. package/lib/codegen/rewrite-operation-ids.test.d.ts +2 -0
  63. package/lib/codegen/rewrite-operation-ids.test.d.ts.map +1 -0
  64. package/lib/codegen/rewrite-operation-ids.test.js +533 -0
  65. package/lib/codegen/rewrite-operation-ids.test.js.map +1 -0
  66. package/lib/codegen/spec-path.d.ts +16 -0
  67. package/lib/codegen/spec-path.d.ts.map +1 -0
  68. package/lib/codegen/spec-path.js +101 -0
  69. package/lib/codegen/spec-path.js.map +1 -0
  70. package/lib/errors.d.ts.map +1 -1
  71. package/lib/errors.js +17 -13
  72. package/lib/errors.js.map +1 -1
  73. package/lib/graphql.d.ts +284 -0
  74. package/lib/graphql.d.ts.map +1 -0
  75. package/lib/graphql.fixture.d.ts +249 -0
  76. package/lib/graphql.fixture.d.ts.map +1 -0
  77. package/lib/graphql.fixture.js +240 -0
  78. package/lib/graphql.fixture.js.map +1 -0
  79. package/lib/graphql.js +718 -0
  80. package/lib/graphql.js.map +1 -0
  81. package/lib/graphql.test.d.ts +2 -0
  82. package/lib/graphql.test.d.ts.map +1 -0
  83. package/lib/graphql.test.js +780 -0
  84. package/lib/graphql.test.js.map +1 -0
  85. package/lib/graphql.types.d.ts +2 -0
  86. package/lib/graphql.types.d.ts.map +1 -0
  87. package/lib/graphql.types.js +45 -0
  88. package/lib/graphql.types.js.map +1 -0
  89. package/lib/json-patch.d.ts +18 -11
  90. package/lib/json-patch.d.ts.map +1 -1
  91. package/lib/json-patch.js +63 -25
  92. package/lib/json-patch.js.map +1 -1
  93. package/lib/pagination.d.ts +43 -3
  94. package/lib/pagination.d.ts.map +1 -1
  95. package/lib/pagination.js +91 -5
  96. package/lib/pagination.js.map +1 -1
  97. package/lib/protocol-http.d.ts.map +1 -1
  98. package/lib/protocol-http.js +62 -26
  99. package/lib/protocol-http.js.map +1 -1
  100. package/lib/protocol-http.test.d.ts +2 -0
  101. package/lib/protocol-http.test.d.ts.map +1 -0
  102. package/lib/protocol-http.test.js +88 -0
  103. package/lib/protocol-http.test.js.map +1 -0
  104. package/lib/protocol-rest.d.ts +12 -2
  105. package/lib/protocol-rest.d.ts.map +1 -1
  106. package/lib/protocol-rest.js +17 -3
  107. package/lib/protocol-rest.js.map +1 -1
  108. package/lib/retry.js +1 -1
  109. package/lib/schema.d.ts +1 -1
  110. package/lib/schema.d.ts.map +1 -1
  111. package/lib/schema.js +1 -1
  112. package/lib/schema.js.map +1 -1
  113. package/lib/trait.d.ts +27 -3
  114. package/lib/trait.d.ts.map +1 -1
  115. package/lib/trait.js +17 -1
  116. package/lib/trait.js.map +1 -1
  117. package/package.json +13 -10
  118. package/src/api.ts +18 -4
  119. package/src/category.ts +4 -4
  120. package/src/codegen/boolean-string-enums.test.ts +168 -0
  121. package/src/codegen/boolean-string-enums.ts +106 -0
  122. package/src/codegen/cli.ts +127 -110
  123. package/src/codegen/emit.ts +6 -10
  124. package/src/codegen/generator.ts +151 -21
  125. package/src/codegen/graphql-client.test.ts +386 -0
  126. package/src/codegen/graphql-client.ts +419 -0
  127. package/src/codegen/graphql.ts +1217 -0
  128. package/src/codegen/openapi-cli.ts +75 -59
  129. package/src/codegen/openapi.ts +255 -16
  130. package/src/codegen/patches.test.ts +130 -0
  131. package/src/codegen/patches.ts +291 -0
  132. package/src/codegen/proto.ts +1128 -0
  133. package/src/codegen/rewrite-operation-ids.test.ts +563 -0
  134. package/src/codegen/rewrite-operation-ids.ts +1206 -0
  135. package/src/codegen/spec-path.ts +115 -0
  136. package/src/errors.ts +20 -25
  137. package/src/graphql.fixture.ts +371 -0
  138. package/src/graphql.test.ts +974 -0
  139. package/src/graphql.ts +1321 -0
  140. package/src/graphql.types.ts +185 -0
  141. package/src/json-patch.ts +82 -25
  142. package/src/pagination.ts +134 -7
  143. package/src/protocol-http.test.ts +107 -0
  144. package/src/protocol-http.ts +67 -31
  145. package/src/protocol-rest.ts +28 -4
  146. package/src/retry.ts +1 -1
  147. package/src/schema.ts +2 -2
  148. package/src/trait.ts +39 -3
@@ -0,0 +1,386 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { buildSchema, introspectionFromSchema, parse, validate } from "graphql";
3
+ import { compile } from "../graphql.ts";
4
+ import { fixtureSDL } from "../graphql.fixture.ts";
5
+ import { applyOperation } from "../json-patch.ts";
6
+ import {
7
+ convertGraphQLClient,
8
+ generateGraphQLClient,
9
+ graphqlTypeString,
10
+ validateGraphQLModel,
11
+ } from "./graphql-client.ts";
12
+
13
+ const named = (name: string, kind = "OBJECT") => ({ kind, name });
14
+ const required = (ofType: object) => ({ kind: "NON_NULL", ofType });
15
+ const list = (ofType: object) => ({ kind: "LIST", ofType });
16
+ const field = (name: string, type: object, args: object[] = []) => ({
17
+ name,
18
+ type,
19
+ args,
20
+ });
21
+ const fixture = {
22
+ queryType: { name: "Query" },
23
+ mutationType: { name: "Mutation" },
24
+ types: [
25
+ { kind: "SCALAR", name: "String" },
26
+ { kind: "SCALAR", name: "Int" },
27
+ { kind: "SCALAR", name: "JSON" },
28
+ {
29
+ kind: "ENUM",
30
+ name: "Status",
31
+ enumValues: [{ name: "ACTIVE" }, { name: "OLD", isDeprecated: true }],
32
+ },
33
+ {
34
+ kind: "INPUT_OBJECT",
35
+ name: "Filter",
36
+ inputFields: [
37
+ {
38
+ name: "status",
39
+ type: named("Status", "ENUM"),
40
+ defaultValue: "ACTIVE",
41
+ },
42
+ ],
43
+ },
44
+ {
45
+ kind: "OBJECT",
46
+ name: "Query",
47
+ fields: [
48
+ field("project", required(named("Project")), [
49
+ { name: "id", type: required(named("String", "SCALAR")) },
50
+ ]),
51
+ field("search", list(named("Search", "UNION"))),
52
+ ],
53
+ },
54
+ {
55
+ kind: "OBJECT",
56
+ name: "Mutation",
57
+ fields: [
58
+ field("projectCreate", named("Project"), [
59
+ { name: "filter", type: named("Filter", "INPUT_OBJECT") },
60
+ ]),
61
+ ],
62
+ },
63
+ {
64
+ kind: "OBJECT",
65
+ name: "Project",
66
+ interfaces: [named("Node", "INTERFACE")],
67
+ fields: [
68
+ field("id", required(named("String", "SCALAR"))),
69
+ field("children", required(list(required(named("Project")))), [
70
+ {
71
+ name: "first",
72
+ type: required(named("Int", "SCALAR")),
73
+ defaultValue: "20",
74
+ },
75
+ { name: "filter", type: named("Filter", "INPUT_OBJECT") },
76
+ ]),
77
+ {
78
+ ...field("legacy", named("String", "SCALAR")),
79
+ isDeprecated: true,
80
+ deprecationReason: "Use id",
81
+ },
82
+ ],
83
+ },
84
+ {
85
+ kind: "OBJECT",
86
+ name: "Service",
87
+ fields: [field("id", required(named("String", "SCALAR")))],
88
+ },
89
+ {
90
+ kind: "INTERFACE",
91
+ name: "Node",
92
+ fields: [field("id", required(named("String", "SCALAR")))],
93
+ possibleTypes: [named("Project")],
94
+ },
95
+ {
96
+ kind: "UNION",
97
+ name: "Search",
98
+ possibleTypes: [named("Project"), named("Service")],
99
+ },
100
+ ],
101
+ };
102
+
103
+ const options = {
104
+ transportImport: "./transport.ts",
105
+ requirementsImport: "./transport.ts",
106
+ requirementsType: "Requirements",
107
+ operationAliases: { createProject: "projectCreate" },
108
+ };
109
+
110
+ describe("GraphQL-native compiler", () => {
111
+ test("root helpers allocate safe unique names without hiding schema operations", () => {
112
+ const source = buildSchema(`
113
+ type Query {
114
+ query: String report: String schema: String transport: String G: String
115
+ catchTags: String delete: String Scalars: String Selection: String
116
+ same: String mutationSame: String
117
+ }
118
+ type Mutation { same: String }
119
+ `);
120
+ const model = convertGraphQLClient(introspectionFromSchema(source));
121
+ const output = generateGraphQLClient(model, {
122
+ ...options,
123
+ operationAliases: {
124
+ default: "delete",
125
+ deleteField: "delete",
126
+ transport: "report",
127
+ readReport: "report",
128
+ },
129
+ });
130
+ expect(output).toContain(
131
+ 'export const queryQuery = client.operation("query", "query");',
132
+ );
133
+ expect(output).toContain(
134
+ 'export const queryReport = client.operation("query", "report");',
135
+ );
136
+ expect(output).toContain(
137
+ 'export const queryTransport = client.operation("query", "transport");',
138
+ );
139
+ expect(output).toContain(
140
+ 'export const queryDelete = client.operation("query", "delete");',
141
+ );
142
+ expect(output).toContain(
143
+ 'export const queryScalars = client.operation("query", "Scalars");',
144
+ );
145
+ expect(output).toContain(
146
+ 'export const mutationSame2 = client.operation("mutation", "same");',
147
+ );
148
+ expect(output).toContain("export const deleteField = queryDelete;");
149
+ expect(output).toContain("export const readReport = queryReport;");
150
+ expect(output).not.toContain("export const default =");
151
+ expect(
152
+ [...output.matchAll(/export const ([A-Za-z_$][\w$]*) =/g)].map(
153
+ (match) => match[1],
154
+ ),
155
+ ).toEqual(expect.arrayContaining(["query", "report", "queryCatchTags"]));
156
+ const declarations = [
157
+ ...output.matchAll(/export (?:const|class|type) ([A-Za-z_$][\w$]*)/g),
158
+ ].map((match) => match[1]);
159
+ expect(new Set(declarations).size).toBe(declarations.length);
160
+ expect(output.match(/client\.operation\(/g)).toHaveLength(12);
161
+ expect(() =>
162
+ new Bun.Transpiler({ loader: "ts" }).transformSync(output),
163
+ ).not.toThrow();
164
+ expect(
165
+ generateGraphQLClient(model, {
166
+ ...options,
167
+ operationAliases: {
168
+ default: "delete",
169
+ deleteField: "delete",
170
+ transport: "report",
171
+ readReport: "report",
172
+ },
173
+ }),
174
+ ).toBe(output);
175
+ });
176
+
177
+ test("schema type names and patched error tags cannot shadow generated support symbols", () => {
178
+ const model = convertGraphQLClient(
179
+ introspectionFromSchema(
180
+ buildSchema(`
181
+ type Query { data: Schema }
182
+ type Schema { selection: Selection }
183
+ type Selection { id: ID! }
184
+ `),
185
+ ),
186
+ );
187
+ for (const tag of ["Schema", "catchTags", "class"]) {
188
+ applyOperation(model, {
189
+ op: "add",
190
+ path: `/errors/${tag}`,
191
+ value: { matchers: [{ code: tag }] },
192
+ });
193
+ applyOperation(model, {
194
+ op: "add",
195
+ path: "/types/Query/fields/data/errors/-",
196
+ value: tag,
197
+ });
198
+ }
199
+ const output = generateGraphQLClient(model, options);
200
+ expect(output).toContain(
201
+ 'export class SchemaError extends S.TaggedError<SchemaError>()("Schema", G.errorFields)',
202
+ );
203
+ expect(output).toContain(
204
+ 'export class catchTagsError extends S.TaggedError<catchTagsError>()("catchTags", G.errorFields)',
205
+ );
206
+ expect(output).toContain(
207
+ 'export class classError extends S.TaggedError<classError>()("class", G.errorFields)',
208
+ );
209
+ expect(output).toContain('"Schema": SchemaError;');
210
+ expect(output).toContain('"Schema": {');
211
+ expect(output).toContain('"Selection": {');
212
+ expect(() =>
213
+ new Bun.Transpiler({ loader: "ts" }).transformSync(output),
214
+ ).not.toThrow();
215
+ });
216
+
217
+ test("real introspection round-trips abstract fragments, recursive selections and defaulted required arguments", () => {
218
+ const schema = buildSchema(
219
+ fixtureSDL.replaceAll("first: Int = 20", "first: Int! = 20"),
220
+ );
221
+ const model = convertGraphQLClient(introspectionFromSchema(schema));
222
+ const compiled = compile(model, "query", {
223
+ node: {
224
+ where: { id: "node-id" },
225
+ select: {
226
+ id: true,
227
+ __typename: true,
228
+ __on: {
229
+ Project: {
230
+ services: { select: { edges: { node: { id: true } } } },
231
+ },
232
+ Service: { status: true, project: { parent: { name: true } } },
233
+ },
234
+ },
235
+ },
236
+ search: {
237
+ where: { text: "query" },
238
+ select: {
239
+ __typename: true,
240
+ __on: { Project: { name: true }, Service: { status: true } },
241
+ },
242
+ },
243
+ });
244
+ expect(validate(schema, parse(compiled.query))).toEqual([]);
245
+ expect(compiled.query).not.toContain("first:");
246
+ expect(model.types.Project!.fields!.services!.args.first).toEqual({
247
+ type: "Int!",
248
+ defaultValue: "20",
249
+ });
250
+ expect(model.types.ProjectFilter!.inputFields!.statuses).toEqual({
251
+ type: "[Status!]",
252
+ defaultValue: "[ACTIVE]",
253
+ });
254
+ const output = generateGraphQLClient(model, options);
255
+ expect(output).toContain('"first"?: Scalars["Int"]');
256
+ expect(output).toContain('"Node": "Project" | "Service"');
257
+ expect(output).toContain('"SearchResult": "Project" | "Service"');
258
+ });
259
+
260
+ test("required input fields with defaults are omittable but other required fields stay required", () => {
261
+ const schema = buildSchema(`
262
+ input Paging { limit: Int! = 20, owner: ID!, statuses: [String!]! = [] }
263
+ type Query { names(paging: Paging!): [String!]! }
264
+ `);
265
+ const model = convertGraphQLClient(introspectionFromSchema(schema));
266
+ const output = generateGraphQLClient(model, options);
267
+ expect(output).toContain('"limit"?: Scalars["Int"]');
268
+ expect(output).toContain('"owner": Scalars["ID"]');
269
+ expect(output).toContain('"statuses"?: ReadonlyArray<Scalars["String"]>');
270
+ const compiled = compile(model, "query", {
271
+ names: { where: { paging: { owner: "account" } } },
272
+ });
273
+ expect(Object.values(compiled.variables)).toEqual([{ owner: "account" }]);
274
+ expect(validate(schema, parse(compiled.query))).toEqual([]);
275
+ expect(() =>
276
+ compile(model, "query", { names: { where: { paging: {} } } }),
277
+ ).toThrow("owner is required");
278
+ });
279
+
280
+ test("provider scalar overrides stay aligned in runtime metadata and generated scalar types", () => {
281
+ const schema = buildSchema(
282
+ `scalar DateTime scalar JSON type Query { date: DateTime! blob: JSON! }`,
283
+ );
284
+ const model = convertGraphQLClient(introspectionFromSchema(schema), {
285
+ scalars: { DateTime: "string" },
286
+ });
287
+ const output = generateGraphQLClient(model, options);
288
+ expect(model.types.DateTime!.scalar).toBe("string");
289
+ expect(model.types.JSON!.scalar).toBe("unknown");
290
+ expect(output).toContain('"DateTime": string;');
291
+ expect(output).toContain('"JSON": unknown;');
292
+ expect(
293
+ validate(
294
+ schema,
295
+ parse(compile(model, "query", { date: true, blob: true }).query),
296
+ ),
297
+ ).toEqual([]);
298
+ });
299
+
300
+ test("preserves nested required arguments, defaults, recursion, union/interface members and deprecated fields", () => {
301
+ const model = convertGraphQLClient({ data: { __schema: fixture } });
302
+ expect(model.types.Project!.fields!.children).toEqual({
303
+ type: "[Project!]!",
304
+ args: {
305
+ first: { type: "Int!", defaultValue: "20" },
306
+ filter: { type: "Filter" },
307
+ },
308
+ errors: [],
309
+ });
310
+ expect(model.types.Project!.interfaces).toEqual(["Node"]);
311
+ expect(model.types.Node!.possibleTypes).toEqual(["Project"]);
312
+ expect(model.types.Search!.possibleTypes).toEqual(["Project", "Service"]);
313
+ expect(model.types.Project!.fields!.legacy!.deprecated).toBe("Use id");
314
+ expect(model.types.Status!.enumValues).toEqual(["ACTIVE", "OLD"]);
315
+ expect(model.types.Filter!.inputFields!.status!.defaultValue).toBe(
316
+ "ACTIVE",
317
+ );
318
+ expect(model.types.JSON!.scalar).toBe("unknown");
319
+ validateGraphQLModel(model);
320
+ });
321
+
322
+ test("field errors patch the one model used by emitted type unions and runtime classification", () => {
323
+ const model = convertGraphQLClient(fixture);
324
+ applyOperation(model, {
325
+ op: "add",
326
+ path: "/errors/ChildrenUnavailable",
327
+ value: {
328
+ category: "server",
329
+ matchers: [{ code: "CHILDREN_UNAVAILABLE" }],
330
+ },
331
+ });
332
+ applyOperation(model, {
333
+ op: "add",
334
+ path: "/types/Project/fields/children/errors/-",
335
+ value: "ChildrenUnavailable",
336
+ });
337
+ const output = generateGraphQLClient(model, options);
338
+ expect(output).toContain(
339
+ '"children": G.Field<{ "first"?: Scalars["Int"]; "filter"?: Inputs["Filter"] | null }, "[Project!]!", "ChildrenUnavailable">;',
340
+ );
341
+ expect(output).toContain(
342
+ 'export class ChildrenUnavailable extends S.TaggedError<ChildrenUnavailable>()("ChildrenUnavailable", G.errorFields).pipe(Category.withServerError)',
343
+ );
344
+ expect(output).toContain('"errors":["ChildrenUnavailable"]');
345
+ expect(output).toContain('"matchers":[{"code":"CHILDREN_UNAVAILABLE"}]');
346
+ expect(output).toContain(
347
+ 'export const projectCreate = client.operation("mutation", "projectCreate");',
348
+ );
349
+ expect(output).toContain("export const createProject = projectCreate;");
350
+ });
351
+
352
+ test("generation has no fixed depth projection or artificial output optionality", () => {
353
+ const output = generateGraphQLClient(
354
+ convertGraphQLClient(fixture),
355
+ options,
356
+ );
357
+ expect(output).toContain('"Project": {');
358
+ expect(output).toContain('"Search": "Project" | "Service";');
359
+ expect(output).toContain('"Node": "Project";');
360
+ expect(output).toContain('"id": G.Field<{ }, "String!", never>;');
361
+ expect(output).not.toContain('"id"?: G.Field');
362
+ expect(output).not.toContain("maxDepth");
363
+ });
364
+
365
+ test("unknown coordinates, incomplete references and stale patches fail immediately", () => {
366
+ const model = convertGraphQLClient(fixture);
367
+ applyOperation(model, {
368
+ op: "add",
369
+ path: "/types/Project/fields/children/errors/-",
370
+ value: "MissingError",
371
+ });
372
+ expect(() => validateGraphQLModel(model)).toThrow(
373
+ "Project.children: unknown GraphQL error MissingError",
374
+ );
375
+ expect(() => graphqlTypeString({ kind: "NON_NULL" })).toThrow(
376
+ "Incomplete GraphQL NON_NULL",
377
+ );
378
+ expect(() =>
379
+ applyOperation(model, {
380
+ op: "replace",
381
+ path: "/types/Project/fields/removed/errors",
382
+ value: [],
383
+ }),
384
+ ).toThrow();
385
+ });
386
+ });