@ucdjs/test-utils 1.0.1-beta.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.
@@ -0,0 +1,1050 @@
1
+ import { AsyncResponseResolverReturnType, DefaultBodyType, HttpResponseResolver, PathParams } from "msw";
2
+ import { MockFetchFn } from "@luxass/msw-utils";
3
+ import { Prettify } from "@luxass/utils";
4
+ import { UnicodeFileTreeNode } from "@ucdjs/schemas";
5
+
6
+ //#region src/.generated/api.d.ts
7
+ /**
8
+ * This file was auto-generated by openapi-typescript.
9
+ * Do not make direct changes to the file.
10
+ */
11
+ interface paths {
12
+ "/api/v1/versions": {
13
+ parameters: {
14
+ query?: never;
15
+ header?: never;
16
+ path?: never;
17
+ cookie?: never;
18
+ };
19
+ /**
20
+ * @description ## List All Unicode Versions
21
+ *
22
+ * This endpoint retrieves a comprehensive list of all Unicode versions, including metadata and support status.
23
+ *
24
+ * - Provides **version metadata** such as documentation URLs and public URLs
25
+ * - Includes **draft versions** if available
26
+ * - Supports **caching** for performance optimization
27
+ */
28
+ get: {
29
+ parameters: {
30
+ query?: never;
31
+ header?: never;
32
+ path?: never;
33
+ cookie?: never;
34
+ };
35
+ requestBody?: never;
36
+ responses: {
37
+ /** @description List of Unicode Versions */200: {
38
+ headers: {
39
+ [name: string]: unknown;
40
+ };
41
+ content: {
42
+ "application/json": components["schemas"]["UnicodeVersionList"];
43
+ };
44
+ };
45
+ 404: components["responses"]["NotFoundError"];
46
+ 429: components["responses"]["TooManyRequestsError"];
47
+ 500: components["responses"]["InternalServerError"];
48
+ 502: components["responses"]["BadGatewayError"];
49
+ };
50
+ };
51
+ put?: never;
52
+ post?: never;
53
+ delete?: never;
54
+ options?: never;
55
+ head?: never;
56
+ patch?: never;
57
+ trace?: never;
58
+ };
59
+ "/api/v1/versions/{version}": {
60
+ parameters: {
61
+ query?: never;
62
+ header?: never;
63
+ path?: never;
64
+ cookie?: never;
65
+ };
66
+ /**
67
+ * @description ## Get Unicode Version Details
68
+ *
69
+ * This endpoint retrieves detailed information about a specific Unicode version.
70
+ *
71
+ * - Provides **version metadata** such as version name, documentation URL, release date, and type (stable/draft)
72
+ * - Includes **location information** (UCD URL and mapped version)
73
+ * - Returns **statistics** about characters, blocks, and scripts (if available)
74
+ * - Supports **caching** for performance optimization
75
+ */
76
+ get: {
77
+ parameters: {
78
+ query?: never;
79
+ header?: never;
80
+ path: {
81
+ /** @description A Unicode Version */version: string;
82
+ };
83
+ cookie?: never;
84
+ };
85
+ requestBody?: never;
86
+ responses: {
87
+ /** @description Detailed information about a Unicode version */200: {
88
+ headers: {
89
+ [name: string]: unknown;
90
+ };
91
+ content: {
92
+ "application/json": components["schemas"]["UnicodeVersionDetails"];
93
+ };
94
+ };
95
+ 400: components["responses"]["BadRequestError"];
96
+ 404: components["responses"]["NotFoundError"];
97
+ 429: components["responses"]["TooManyRequestsError"];
98
+ 500: components["responses"]["InternalServerError"];
99
+ 502: components["responses"]["BadGatewayError"];
100
+ };
101
+ };
102
+ put?: never;
103
+ post?: never;
104
+ delete?: never;
105
+ options?: never;
106
+ head?: never;
107
+ patch?: never;
108
+ trace?: never;
109
+ };
110
+ "/api/v1/versions/{version}/file-tree": {
111
+ parameters: {
112
+ query?: never;
113
+ header?: never;
114
+ path?: never;
115
+ cookie?: never;
116
+ };
117
+ /**
118
+ * @description This endpoint provides a **structured list of all files** inside the [`ucd folder`](https://unicode.org/Public/UCD/latest/ucd) associated with a specific Unicode version.
119
+ *
120
+ * For older versions, the files are retrieved without the `/ucd` prefix, while for the latest version, the `/ucd` prefix is included.
121
+ */
122
+ get: {
123
+ parameters: {
124
+ query?: never;
125
+ header?: never;
126
+ path: {
127
+ /** @description A Unicode Version */version: string;
128
+ };
129
+ cookie?: never;
130
+ };
131
+ requestBody?: never;
132
+ responses: {
133
+ /** @description Structured list of files for a Unicode version */200: {
134
+ headers: {
135
+ [name: string]: unknown;
136
+ };
137
+ content: {
138
+ "application/json": components["schemas"]["UnicodeFileTree"];
139
+ };
140
+ };
141
+ 400: components["responses"]["BadRequestError"];
142
+ 429: components["responses"]["TooManyRequestsError"];
143
+ 500: components["responses"]["InternalServerError"];
144
+ 502: components["responses"]["BadGatewayError"];
145
+ };
146
+ };
147
+ put?: never;
148
+ post?: never;
149
+ delete?: never;
150
+ options?: never;
151
+ head?: never;
152
+ patch?: never;
153
+ trace?: never;
154
+ };
155
+ "/api/v1/files/{wildcard}": {
156
+ parameters: {
157
+ query?: never;
158
+ header?: never;
159
+ path?: never;
160
+ cookie?: never;
161
+ };
162
+ /**
163
+ * @description This endpoint proxies requests to Unicode.org's Public directory, streaming files directly while transforming directory listings into structured JSON.
164
+ *
165
+ * All paths are relative to `/api/v1/files` — for example, requesting `/api/v1/files/15.1.0/ucd/emoji/emoji-data.txt` fetches the emoji data file from Unicode version 15.1.0.
166
+ *
167
+ * > [!IMPORTANT]
168
+ * > The `{wildcard}` parameter accepts any valid path, including deeply nested ones like `15.1.0/ucd/emoji/emoji-data.txt`. In directory listing responses, paths for directories include a trailing slash (e.g., `/15.1.0/ucd/charts/`), while file paths do not.
169
+ *
170
+ * > [!NOTE]
171
+ * > To retrieve only metadata without downloading content, use a `HEAD` request instead. See [here](#tag/files/head/api/v1/files/{wildcard})
172
+ *
173
+ * ### Directory Listing Features
174
+ *
175
+ * When accessing a directory, you can filter and sort entries using these query parameters:
176
+ *
177
+ * - `query` - Prefix-based search (case-insensitive) on entry names
178
+ * - `pattern` - Glob pattern matching for filtering
179
+ * - `type` - Filter by entry type: `all` (default), `files`, or `directories`
180
+ * - `sort` - Sort by `name` (default) or `lastModified`
181
+ * - `order` - Sort order: `asc` (default) or `desc`
182
+ *
183
+ * ### Modifications
184
+ *
185
+ * Directory responses are automatically transformed into JSON arrays containing file and directory entries. Files are streamed directly from Unicode.org with appropriate content types.
186
+ */
187
+ get: {
188
+ parameters: {
189
+ query?: {
190
+ /**
191
+ * @description A glob pattern to filter directory listing results by filename. Only applies when the response is a directory listing.
192
+ * The matching is **case-insensitive**.
193
+ *
194
+ * ## Supported Glob Syntax
195
+ *
196
+ * | Pattern | Description | Example |
197
+ * |-----------|-----------------------------------------------|------------------------------------------------------|
198
+ * | `*` | Match any characters (except path separators) | `*.txt` matches `file.txt` |
199
+ * | `?` | Match a single character | `file?.txt` matches `file1.txt` |
200
+ * | `{a,b}` | Match any of the patterns | `*.{txt,xml}` matches `file.txt` or `file.xml` |
201
+ * | `[abc]` | Match any character in the set | `file[123].txt` matches `file1.txt` |
202
+ *
203
+ * ## Examples
204
+ *
205
+ * - `*.txt` - Match all text files
206
+ * - `Uni*` - Match files starting with "Uni" (e.g., UnicodeData.txt)
207
+ * - `*Data*` - Match files containing "Data"
208
+ * - `*.{txt,xml}` - Match text or XML files
209
+ */
210
+ pattern?: string;
211
+ /**
212
+ * @description A search query to filter directory listing results. Entries are matched if their name **starts with** this value (case-insensitive).
213
+ * This is useful for quick prefix-based searching within a directory.
214
+ *
215
+ * ## Examples
216
+ *
217
+ * - `Uni` - Match entries starting with "Uni" (e.g., UnicodeData.txt)
218
+ * - `15` - Match version directories starting with "15"
219
+ */
220
+ query?: string;
221
+ /**
222
+ * @description Filter directory listing results by entry type.
223
+ *
224
+ * - `all` (default) - Return both files and directories
225
+ * - `files` - Return only files
226
+ * - `directories` - Return only directories
227
+ */
228
+ type?: "all" | "files" | "directories";
229
+ /**
230
+ * @description The field to sort directory listing results by.
231
+ *
232
+ * - `name` (default) - Sort alphabetically by entry name
233
+ * - `lastModified` - Sort by last modification timestamp
234
+ */
235
+ sort?: "name" | "lastModified";
236
+ /**
237
+ * @description The sort order for directory listing results.
238
+ *
239
+ * - `asc` (default) - Ascending order (A-Z, oldest first)
240
+ * - `desc` - Descending order (Z-A, newest first)
241
+ */
242
+ order?: "asc" | "desc";
243
+ };
244
+ header?: never;
245
+ path: {
246
+ /**
247
+ * @description The path to the Unicode data resource you want to access. This can be any valid path from the official Unicode Public directory structure.
248
+ *
249
+ * ## Path Format Options
250
+ *
251
+ * | Pattern | Description | Example |
252
+ * |--------------------------------|--------------------------------|-------------------------------------|
253
+ * | `{version}/ucd/{filename}` | UCD files for specific version | `15.1.0/ucd/UnicodeData.txt` |
254
+ * | `{version}/ucd/{sub}/{file}` | Files in subdirectories | `15.1.0/ucd/emoji/emoji-data.txt` |
255
+ * | `{version}` | List files for version | `15.1.0` |
256
+ * | `latest/ucd/{filename}` | Latest version of file | `latest/ucd/PropList.txt` |
257
+ */
258
+ wildcard: string;
259
+ };
260
+ cookie?: never;
261
+ };
262
+ requestBody?: never;
263
+ responses: {
264
+ /** @description Response from Unicode.org */200: {
265
+ headers: {
266
+ /** @description The type of the file or directory */"X-UCD-Stat-Type": "file" | "directory"; /** @description The size of the file in bytes (only for files) */
267
+ "X-UCD-Stat-Size"?: string; /** @description Number of children (only for directories) */
268
+ "X-UCD-Stat-Children"?: string; /** @description Number of child files (only for directories) */
269
+ "X-UCD-Stat-Children-Files"?: string; /** @description Number of child directories (only for directories) */
270
+ "X-UCD-Stat-Children-Dirs"?: string;
271
+ [name: string]: unknown;
272
+ };
273
+ content: {
274
+ "application/json": components["schemas"]["FileEntryList"];
275
+ "application/xml": string;
276
+ "text/plain": string;
277
+ "text/html": string;
278
+ "application/pdf": string;
279
+ "application/octet-stream": string;
280
+ };
281
+ };
282
+ 400: components["responses"]["BadRequestError"];
283
+ 404: components["responses"]["NotFoundError"];
284
+ 500: components["responses"]["InternalServerError"];
285
+ 502: components["responses"]["BadGatewayError"];
286
+ };
287
+ };
288
+ put?: never;
289
+ post?: never;
290
+ delete?: never;
291
+ options?: never;
292
+ /**
293
+ * @description Retrieve metadata about a file or directory without downloading the content. Useful for checking existence, file size, and other metadata.
294
+ *
295
+ * All paths are relative to `/api/v1/files`. Directory paths always include a trailing slash (e.g., `/15.1.0/ucd/charts/`), while file paths do not.
296
+ *
297
+ * > [!NOTE]
298
+ * > This endpoint returns the same headers as the `GET` request (file size, directory entry counts, last modified timestamps, content type) without the response body.
299
+ */
300
+ head: {
301
+ parameters: {
302
+ query?: {
303
+ /**
304
+ * @description A glob pattern to filter directory listing results by filename. Only applies when the response is a directory listing.
305
+ * The matching is **case-insensitive**.
306
+ *
307
+ * ## Supported Glob Syntax
308
+ *
309
+ * | Pattern | Description | Example |
310
+ * |-----------|-----------------------------------------------|------------------------------------------------------|
311
+ * | `*` | Match any characters (except path separators) | `*.txt` matches `file.txt` |
312
+ * | `?` | Match a single character | `file?.txt` matches `file1.txt` |
313
+ * | `{a,b}` | Match any of the patterns | `*.{txt,xml}` matches `file.txt` or `file.xml` |
314
+ * | `[abc]` | Match any character in the set | `file[123].txt` matches `file1.txt` |
315
+ *
316
+ * ## Examples
317
+ *
318
+ * - `*.txt` - Match all text files
319
+ * - `Uni*` - Match files starting with "Uni" (e.g., UnicodeData.txt)
320
+ * - `*Data*` - Match files containing "Data"
321
+ * - `*.{txt,xml}` - Match text or XML files
322
+ */
323
+ pattern?: string;
324
+ /**
325
+ * @description A search query to filter directory listing results. Entries are matched if their name **starts with** this value (case-insensitive).
326
+ * This is useful for quick prefix-based searching within a directory.
327
+ *
328
+ * ## Examples
329
+ *
330
+ * - `Uni` - Match entries starting with "Uni" (e.g., UnicodeData.txt)
331
+ * - `15` - Match version directories starting with "15"
332
+ */
333
+ query?: string;
334
+ /**
335
+ * @description Filter directory listing results by entry type.
336
+ *
337
+ * - `all` (default) - Return both files and directories
338
+ * - `files` - Return only files
339
+ * - `directories` - Return only directories
340
+ */
341
+ type?: "all" | "files" | "directories";
342
+ /**
343
+ * @description The field to sort directory listing results by.
344
+ *
345
+ * - `name` (default) - Sort alphabetically by entry name
346
+ * - `lastModified` - Sort by last modification timestamp
347
+ */
348
+ sort?: "name" | "lastModified";
349
+ /**
350
+ * @description The sort order for directory listing results.
351
+ *
352
+ * - `asc` (default) - Ascending order (A-Z, oldest first)
353
+ * - `desc` - Descending order (Z-A, newest first)
354
+ */
355
+ order?: "asc" | "desc";
356
+ };
357
+ header?: never;
358
+ path: {
359
+ /**
360
+ * @description The path to the Unicode data resource you want to access. This can be any valid path from the official Unicode Public directory structure.
361
+ *
362
+ * ## Path Format Options
363
+ *
364
+ * | Pattern | Description | Example |
365
+ * |--------------------------------|--------------------------------|-------------------------------------|
366
+ * | `{version}/ucd/{filename}` | UCD files for specific version | `15.1.0/ucd/UnicodeData.txt` |
367
+ * | `{version}/ucd/{sub}/{file}` | Files in subdirectories | `15.1.0/ucd/emoji/emoji-data.txt` |
368
+ * | `{version}` | List files for version | `15.1.0` |
369
+ * | `latest/ucd/{filename}` | Latest version of file | `latest/ucd/PropList.txt` |
370
+ */
371
+ wildcard: string;
372
+ };
373
+ cookie?: never;
374
+ };
375
+ requestBody?: never;
376
+ responses: {
377
+ /** @description Response from Unicode.org */200: {
378
+ headers: {
379
+ /** @description The type of the file or directory */"X-UCD-Stat-Type": "file" | "directory"; /** @description The size of the file in bytes (only for files) */
380
+ "X-UCD-Stat-Size": string; /** @description Number of children (only for directories) */
381
+ "X-UCD-Stat-Children"?: string; /** @description Number of child files (only for directories) */
382
+ "X-UCD-Stat-Children-Files"?: string; /** @description Number of child directories (only for directories) */
383
+ "X-UCD-Stat-Children-Dirs"?: string; /** @description The content type of the file */
384
+ "Content-Type": string; /** @description Last modification time from upstream */
385
+ "Last-Modified"?: string; /** @description Byte length when applicable */
386
+ "Content-Length": string;
387
+ [name: string]: unknown;
388
+ };
389
+ content?: never;
390
+ };
391
+ };
392
+ };
393
+ patch?: never;
394
+ trace?: never;
395
+ };
396
+ "/.well-known/ucd-config.json": {
397
+ parameters: {
398
+ query?: never;
399
+ header?: never;
400
+ path?: never;
401
+ cookie?: never;
402
+ };
403
+ /**
404
+ * @description ## UCD Configuration
405
+ *
406
+ * This endpoint retrieves the UCD configuration, including available API endpoints for accessing Unicode data resources.
407
+ *
408
+ * > [!NOTE]
409
+ * > The configuration follows the [UCD.js Well-Known Configuration](https://ucdjs.dev/docs/usage/well-known) specification.
410
+ */
411
+ get: {
412
+ parameters: {
413
+ query?: never;
414
+ header?: never;
415
+ path?: never;
416
+ cookie?: never;
417
+ };
418
+ requestBody?: never;
419
+ responses: {
420
+ /** @description Retrieves the UCD configuration */200: {
421
+ headers: {
422
+ [name: string]: unknown;
423
+ };
424
+ content: {
425
+ "application/json": components["schemas"]["UCDWellKnownConfig"];
426
+ };
427
+ };
428
+ 502: components["responses"]["BadGatewayError"];
429
+ };
430
+ };
431
+ put?: never;
432
+ post?: never;
433
+ delete?: never;
434
+ options?: never;
435
+ head?: never;
436
+ patch?: never;
437
+ trace?: never;
438
+ };
439
+ "/.well-known/ucd-store/{version}.json": {
440
+ parameters: {
441
+ query?: never;
442
+ header?: never;
443
+ path?: never;
444
+ cookie?: never;
445
+ };
446
+ /**
447
+ * @description ## UCD Store Manifest (Per Version)
448
+ *
449
+ * This endpoint retrieves the UCD Store manifest for a specific Unicode version, containing metadata about expected files for that version.
450
+ *
451
+ * This is the recommended endpoint for fetching manifest data, as it provides:
452
+ * - Smaller payloads (only the requested version)
453
+ * - Better caching (version-specific cache invalidation)
454
+ * - Reduced server load
455
+ *
456
+ * Each file entry includes:
457
+ * - `name`: The filename only
458
+ * - `path`: Path for the /api/v1/files endpoint (includes /ucd/ for versions >= 4.1.0)
459
+ * - `storePath`: Path for the store subdomain (ucd-store.ucdjs.dev)
460
+ *
461
+ * > [!NOTE]
462
+ * > The monolithic endpoint `/.well-known/ucd-store.json` is deprecated. Use this per-version endpoint instead.
463
+ */
464
+ get: {
465
+ parameters: {
466
+ query?: never;
467
+ header?: never;
468
+ path: {
469
+ /** @description Unicode version (e.g., '16.0.0') */version: string;
470
+ };
471
+ cookie?: never;
472
+ };
473
+ requestBody?: never;
474
+ responses: {
475
+ /** @description The UCD Store manifest for the specified version */200: {
476
+ headers: {
477
+ [name: string]: unknown;
478
+ };
479
+ content: {
480
+ "application/json": components["schemas"]["UCDStoreVersionManifest"];
481
+ };
482
+ };
483
+ 404: components["responses"]["NotFoundError"];
484
+ 429: components["responses"]["TooManyRequestsError"];
485
+ 500: components["responses"]["InternalServerError"];
486
+ 502: components["responses"]["BadGatewayError"];
487
+ };
488
+ };
489
+ put?: never;
490
+ post?: never;
491
+ delete?: never;
492
+ options?: never;
493
+ head?: never;
494
+ patch?: never;
495
+ trace?: never;
496
+ };
497
+ }
498
+ interface components {
499
+ schemas: {
500
+ /**
501
+ * @description Standard error response format used consistently across all API endpoints.
502
+ *
503
+ * Contains essential information for debugging and user feedback. The specific error scenarios and status codes are documented in the individual endpoint response definitions.
504
+ */
505
+ ApiError: {
506
+ /** @description Human-readable error message describing what went wrong */message: string; /** @description HTTP status code matching the response status */
507
+ status: number; /** @description ISO 8601 timestamp when the error occurred */
508
+ timestamp: string;
509
+ }; /** @description A list of Unicode versions with their metadata and support status. */
510
+ UnicodeVersionList: components["schemas"]["UnicodeVersion"][];
511
+ /**
512
+ * @description Represents a Unicode version with its metadata and support status.
513
+ * @example {
514
+ * "version": "17.0.0",
515
+ * "documentationUrl": "https://www.unicode.org/versions/Unicode17.0.0/",
516
+ * "date": null,
517
+ * "url": "https://www.unicode.org/Public/17.0.0",
518
+ * "mappedUcdVersion": null,
519
+ * "type": "draft"
520
+ * }
521
+ * @example {
522
+ * "version": "16.0.0",
523
+ * "documentationUrl": "https://www.unicode.org/versions/Unicode16.0.0/",
524
+ * "date": "2024",
525
+ * "url": "https://www.unicode.org/Public/16.0.0",
526
+ * "mappedUcdVersion": null,
527
+ * "type": "stable"
528
+ * }
529
+ * @example {
530
+ * "version": "15.1.0",
531
+ * "documentationUrl": "https://www.unicode.org/versions/Unicode15.1.0/",
532
+ * "date": "2023",
533
+ * "url": "https://www.unicode.org/Public/15.1.0",
534
+ * "mappedUcdVersion": null,
535
+ * "type": "stable"
536
+ * }
537
+ */
538
+ UnicodeVersion: {
539
+ /** @description The version of the Unicode standard. */version: string;
540
+ /**
541
+ * Format: uri
542
+ * @description The URL to the Unicode version documentation.
543
+ */
544
+ documentationUrl: string; /** @description The year of the Unicode version. */
545
+ date: string | null;
546
+ /**
547
+ * Format: uri
548
+ * @description The URL to the Unicode Character Database (UCD) for this version.
549
+ */
550
+ url: string; /** @description The corresponding UCD version mapping for this Unicode version. Null if same as version. */
551
+ mappedUcdVersion: string | null;
552
+ /**
553
+ * @description The status of the Unicode version. 'unsupported' means the version exists but is not yet supported by the API.
554
+ * @enum {string}
555
+ */
556
+ type: "draft" | "stable" | "unsupported";
557
+ };
558
+ /**
559
+ * @description Detailed information about a Unicode version, including metadata and statistics.
560
+ * @example {
561
+ * "version": "16.0.0",
562
+ * "documentationUrl": "https://www.unicode.org/versions/Unicode16.0.0/",
563
+ * "date": "2024",
564
+ * "url": "https://www.unicode.org/Public/16.0.0",
565
+ * "mappedUcdVersion": null,
566
+ * "type": "stable",
567
+ * "statistics": {
568
+ * "totalCharacters": 149813,
569
+ * "newCharacters": 5185,
570
+ * "totalBlocks": 331,
571
+ * "newBlocks": 4,
572
+ * "totalScripts": 165,
573
+ * "newScripts": 2
574
+ * }
575
+ * }
576
+ */
577
+ UnicodeVersionDetails: {
578
+ /** @description The version of the Unicode standard. */version: string;
579
+ /**
580
+ * Format: uri
581
+ * @description The URL to the Unicode version documentation.
582
+ */
583
+ documentationUrl: string; /** @description The year of the Unicode version. */
584
+ date: string | null;
585
+ /**
586
+ * Format: uri
587
+ * @description The URL to the Unicode Character Database (UCD) for this version.
588
+ */
589
+ url: string; /** @description The corresponding UCD version mapping for this Unicode version. Null if same as version. */
590
+ mappedUcdVersion: string | null;
591
+ /**
592
+ * @description The status of the Unicode version. 'unsupported' means the version exists but is not yet supported by the API.
593
+ * @enum {string}
594
+ */
595
+ type: "draft" | "stable" | "unsupported";
596
+ /**
597
+ * @description Statistics about this Unicode version. May be null if statistics are not available.
598
+ * @default {
599
+ * "newBlocks": 0,
600
+ * "newCharacters": 0,
601
+ * "newScripts": 0,
602
+ * "totalBlocks": 0,
603
+ * "totalCharacters": 0,
604
+ * "totalScripts": 0
605
+ * }
606
+ */
607
+ statistics: {
608
+ /** @description Total number of characters in this Unicode version. */totalCharacters: number; /** @description Number of new characters added in this version. */
609
+ newCharacters: number; /** @description Total number of blocks in this Unicode version. */
610
+ totalBlocks: number; /** @description Number of new blocks added in this version. */
611
+ newBlocks: number; /** @description Total number of scripts in this Unicode version. */
612
+ totalScripts: number; /** @description Number of new scripts added in this version. */
613
+ newScripts: number;
614
+ };
615
+ }; /** @description A recursive file tree structure rooted at an array of entries. */
616
+ UnicodeFileTree: components["schemas"]["UnicodeFileTreeNode"][]; /** @description A recursive file tree node; directories include children, files do not. */
617
+ UnicodeFileTreeNode: components["schemas"]["UnicodeFileTreeDirectory"] | components["schemas"]["UnicodeFileTreeFile"]; /** @description A directory node in the Unicode file tree, containing child nodes. */
618
+ UnicodeFileTreeDirectory: {
619
+ name: string;
620
+ path: string;
621
+ lastModified: number | null; /** @enum {string} */
622
+ type: "directory";
623
+ children: components["schemas"]["UnicodeFileTreeNode"][];
624
+ }; /** @description A file node in the Unicode file tree. */
625
+ UnicodeFileTreeFile: {
626
+ name: string;
627
+ path: string;
628
+ lastModified: number | null; /** @enum {string} */
629
+ type: "file";
630
+ }; /** @description An array of file entries, each representing either a file or a directory. */
631
+ FileEntryList: ({
632
+ name: string;
633
+ path: string;
634
+ lastModified: number | null; /** @enum {string} */
635
+ type: "directory";
636
+ } | {
637
+ name: string;
638
+ path: string;
639
+ lastModified: number | null; /** @enum {string} */
640
+ type: "file";
641
+ })[];
642
+ /**
643
+ * @description Configuration schema for the .well-known/ucd-config.json endpoint.
644
+ *
645
+ * This configuration provides clients with the necessary information to interact with the UCD API server, including endpoint paths and optional metadata about the server itself.
646
+ *
647
+ * The `manifest` endpoint is deprecated. Use the per-version endpoint `/.well-known/ucd-store/{version}.json` instead for better performance and caching.
648
+ */
649
+ UCDWellKnownConfig: {
650
+ /** @default 1.0 */version: string;
651
+ endpoints: {
652
+ files: string;
653
+ manifest: string;
654
+ versions: string;
655
+ }; /** @default [] */
656
+ versions: string[];
657
+ };
658
+ /**
659
+ * @description Response schema for per-version manifest endpoint.
660
+ * Matches the schema from /.well-known/ucd-store/{version}.json
661
+ */
662
+ UCDStoreVersionManifest: {
663
+ /** @description List of expected files for this version with their paths */expectedFiles: components["schemas"]["ExpectedFile"][];
664
+ }; /** @description A file expected to be present in a UCD version */
665
+ ExpectedFile: {
666
+ /** @description Filename only */name: string; /** @description Path relative to /api/v1/files endpoint (includes /ucd/ for versions >= 4.1.0) */
667
+ path: string; /** @description Path for store subdomain (without /ucd/ prefix) */
668
+ storePath: string;
669
+ };
670
+ };
671
+ responses: {
672
+ /** @description Bad request error */BadRequestError: {
673
+ headers: {
674
+ [name: string]: unknown;
675
+ };
676
+ content: {
677
+ "application/json": components["schemas"]["ApiError"];
678
+ };
679
+ }; /** @description Resource not found */
680
+ NotFoundError: {
681
+ headers: {
682
+ [name: string]: unknown;
683
+ };
684
+ content: {
685
+ "application/json": components["schemas"]["ApiError"];
686
+ };
687
+ }; /** @description Rate limit exceeded */
688
+ TooManyRequestsError: {
689
+ headers: {
690
+ [name: string]: unknown;
691
+ };
692
+ content: {
693
+ "application/json": components["schemas"]["ApiError"];
694
+ };
695
+ }; /** @description Internal server error */
696
+ InternalServerError: {
697
+ headers: {
698
+ [name: string]: unknown;
699
+ };
700
+ content: {
701
+ "application/json": components["schemas"]["ApiError"];
702
+ };
703
+ }; /** @description Bad gateway - upstream service failed */
704
+ BadGatewayError: {
705
+ headers: {
706
+ [name: string]: unknown;
707
+ };
708
+ content: {
709
+ "application/json": components["schemas"]["ApiError"];
710
+ };
711
+ };
712
+ };
713
+ parameters: never;
714
+ requestBodies: never;
715
+ headers: never;
716
+ pathItems: never;
717
+ }
718
+ //#endregion
719
+ //#region src/mock-store/handlers/index.d.ts
720
+ declare const MOCK_ROUTES: readonly [RouteHandlerDefinition<"/api/v1/files/{wildcard}">, RouteHandlerDefinition<"/api/v1/versions/{version}/file-tree">, RouteHandlerDefinition<"/.well-known/ucd-config.json">, RouteHandlerDefinition<"/.well-known/ucd-store/{version}.json">, RouteHandlerDefinition<"/api/v1/versions">];
721
+ //#endregion
722
+ //#region src/mock-store/types.d.ts
723
+ interface ContentTypeToType {
724
+ "application/json": any;
725
+ "text/plain": string;
726
+ "application/octet-stream": Blob | File | ArrayBuffer | Uint8Array;
727
+ }
728
+ type EndpointWithGet = { [K in keyof paths]: paths[K] extends {
729
+ get: any;
730
+ } ? K : never }[keyof paths];
731
+ type TypedResponseResolver<Params extends PathParams<string> = PathParams, Response extends DefaultBodyType = DefaultBodyType> = HttpResponseResolver<Params, DefaultBodyType, Response>;
732
+ type ExtractPathParams<Path extends string> = Path extends `${infer _Start}/{${infer Param}}${infer Rest}` ? PathParams<Param> & ExtractPathParams<Rest> : {};
733
+ type InferContentTypes<Content> = Content extends Record<string, any> ? { [K in keyof Content]: K extends keyof ContentTypeToType ? Content[K] extends ContentTypeToType[K] ? Content[K] : ContentTypeToType[K] : Content[K] }[keyof Content] : never;
734
+ type InferResponsesByEndpoint<Endpoint extends EndpointWithGet> = paths[Endpoint]["get"]["responses"] extends infer Responses ? { [StatusCode in keyof Responses]: Responses[StatusCode] extends {
735
+ content: infer Content;
736
+ } ? InferContentTypes<Content> : never }[keyof Responses] : never;
737
+ type InferEndpointConfig<Routes extends readonly RouteHandlerDefinition<any>[]> = { [K in Routes[number]["endpoint"]]: Extract<Routes[number], {
738
+ endpoint: K;
739
+ }> extends RouteHandlerDefinition<infer E> ? InferResponsesByEndpoint<E> | ConfiguredResponse<InferResponsesByEndpoint<E>> | TypedResponseResolver<ExtractPathParams<E>, InferResponsesByEndpoint<E>> | true : never };
740
+ interface MockRouteHandlerContext<Endpoint extends EndpointWithGet> {
741
+ url: string;
742
+ providedResponse: InferResponsesByEndpoint<Endpoint> | TypedResponseResolver<ExtractPathParams<Endpoint>, InferResponsesByEndpoint<Endpoint>> | true;
743
+ mockFetch: MockFetchFn;
744
+ versions: string[];
745
+ shouldUseDefaultValue: boolean;
746
+ files: MockStoreFiles;
747
+ }
748
+ interface RouteHandlerDefinition<Endpoint extends EndpointWithGet> {
749
+ endpoint: Endpoint;
750
+ setup: (context: MockRouteHandlerContext<Endpoint>) => void;
751
+ }
752
+ type DerivedEndpointConfig = InferEndpointConfig<typeof MOCK_ROUTES>;
753
+ type DerivedResponses = Partial<{ [K in keyof DerivedEndpointConfig]: false | DerivedEndpointConfig[K] }>;
754
+ type StoreVersionFileKey = "16.0.0" | "17.0.0";
755
+ type StoreFileKeyWildcard = "*" | "root";
756
+ type PartialRecord<K extends keyof any, T> = { [P in K]?: T };
757
+ type MockStoreKey = StoreVersionFileKey | StoreFileKeyWildcard | (string & {});
758
+ type MockStoreNode = Prettify<(Omit<UnicodeFileTreeNode, "type" | "path"> & {
759
+ type: "file";
760
+ path?: string;
761
+ _content?: string;
762
+ }) | (Omit<UnicodeFileTreeNode, "type" | "path"> & {
763
+ type: "directory";
764
+ path?: string;
765
+ _content?: string;
766
+ children: MockStoreNode[];
767
+ })>;
768
+ type MockStoreFiles = PartialRecord<MockStoreKey, MockStoreNode[]>;
769
+ interface MockStoreConfig {
770
+ /**
771
+ * The base URL for the store.
772
+ *
773
+ * @default "https://api.ucdjs.dev"
774
+ */
775
+ baseUrl?: string;
776
+ /**
777
+ * The responses to mock for the store endpoints.
778
+ *
779
+ * NOTE:
780
+ * If the value provided is `true`, then a default handler will be used.
781
+ * If the value is `false`, then no handler will be used.
782
+ * If the value provided is a specific response, then that response will be used.
783
+ *
784
+ * By default, all endpoints are disabled.
785
+ */
786
+ responses?: DerivedResponses;
787
+ /**
788
+ * The files to mock for the store endpoint.
789
+ *
790
+ * The keys are the version to mock the files for.
791
+ *
792
+ * It will be used by the following endpoints:
793
+ * - `/api/v1/versions/{version}/file-tree`
794
+ * - `/.well-known/ucd-store/{version}.json`
795
+ *
796
+ * A special key of `*` can be used to mock all versions.
797
+ */
798
+ files?: MockStoreFiles;
799
+ /**
800
+ * The versions to use for placeholders
801
+ * @default ["16.0.0","15.1.0","15.0.0"]
802
+ */
803
+ versions?: string[];
804
+ /**
805
+ * Custom mock fetch handlers to register
806
+ *
807
+ * @example
808
+ * ```ts
809
+ * customResponses: [
810
+ * ["GET", "/custom-endpoint", () => HttpResponse.json({ custom: true })],
811
+ * [["POST", "PUT"], "/another-endpoint", ({ params }) => {
812
+ * const id = params.id;
813
+ * return HttpResponse.json({ id });
814
+ * }],
815
+ * ]
816
+ * ```
817
+ */
818
+ customResponses?: MockFetchParamTupleList[0][];
819
+ /**
820
+ * Callback invoked on each request to the mock store
821
+ *
822
+ * NOTE:
823
+ * This is not invoked for `customResponses` handlers.
824
+ *
825
+ * @example
826
+ * ```ts
827
+ * onRequest: ({ path, method, params, url }) => {
828
+ * console.log(`Request to ${method} ${path} with params`, params);
829
+ * }
830
+ * ```
831
+ */
832
+ onRequest?: OnRequestCallback;
833
+ }
834
+ type MockFetchParamTupleList = MockFetchFn extends {
835
+ (...a: infer A): any;
836
+ (...a: infer B): any;
837
+ (...a: infer C): any;
838
+ } ? [A, B, C] : never;
839
+ interface ConfiguredResponseConfig<Response> {
840
+ /**
841
+ * The actual response to be returned
842
+ */
843
+ response: Response;
844
+ /**
845
+ * Optional latency in milliseconds or "random" for a random delay between 100-999ms
846
+ */
847
+ latency?: number | "random";
848
+ /**
849
+ * Optional custom headers to add to the response
850
+ */
851
+ headers?: Record<string, string>;
852
+ /**
853
+ * Optional hook that runs before the resolver is called
854
+ */
855
+ before?: OnBeforeMockFetchCallback;
856
+ /**
857
+ * Optional hook that runs after the resolver returns
858
+ */
859
+ after?: OnAfterMockFetchCallback;
860
+ }
861
+ type ConfiguredResponse<Response> = Response & {};
862
+ interface WrapMockFetchCallbackPayload {
863
+ path: string;
864
+ method: string;
865
+ params: Record<string, any>;
866
+ url: string;
867
+ }
868
+ interface WrapMockFetchCallbackPayloadWithResponse extends WrapMockFetchCallbackPayload {
869
+ response: AsyncResponseResolverReturnType<DefaultBodyType>;
870
+ }
871
+ type OnRequestCallback = (payload: WrapMockFetchCallbackPayload) => void;
872
+ type OnBeforeMockFetchCallback = (payload: WrapMockFetchCallbackPayload) => void | Promise<void>;
873
+ type OnAfterMockFetchCallback = (payload: WrapMockFetchCallbackPayloadWithResponse) => void | Promise<void>;
874
+ //#endregion
875
+ //#region src/mock-store/file-tree.d.ts
876
+ /**
877
+ * A file tree node with optional content for mocking file downloads.
878
+ * The `_content` property is used by the files handler to return content.
879
+ */
880
+ type FileTreeNodeWithContent = UnicodeFileTreeNode & {
881
+ _content?: string;
882
+ };
883
+ /**
884
+ * Input format for creating file trees.
885
+ * - String values represent file content
886
+ * - Nested objects represent directories with their contents
887
+ *
888
+ * @example
889
+ * ```ts
890
+ * // Simple flat files
891
+ * {
892
+ * "UnicodeData.txt": "file content",
893
+ * "Blocks.txt": "blocks content"
894
+ * }
895
+ *
896
+ * // Nested directories
897
+ * {
898
+ * "UnicodeData.txt": "content",
899
+ * "auxiliary": {
900
+ * "GraphemeBreakProperty.txt": "content",
901
+ * "WordBreakProperty.txt": "content"
902
+ * }
903
+ * }
904
+ *
905
+ * // Deeply nested
906
+ * {
907
+ * "extracted": {
908
+ * "DerivedBidiClass.txt": "content",
909
+ * "nested": {
910
+ * "DeepFile.txt": "content"
911
+ * }
912
+ * }
913
+ * }
914
+ * ```
915
+ */
916
+ interface FileTreeInput {
917
+ [name: string]: string | FileTreeInput;
918
+ }
919
+ /**
920
+ * Creates a file tree structure from a simplified input format.
921
+ *
922
+ * This utility converts a nested object structure into the UnicodeFileTreeNode format
923
+ * used by mockStoreApi. String values become files with that content, nested objects
924
+ * become directories.
925
+ *
926
+ * @param input - Object mapping names to content (files) or nested objects (directories)
927
+ * @param parentPath - Internal parameter for building nested paths (don't pass this)
928
+ * @returns Array of FileTreeNodeWithContent for use with mockStoreApi
929
+ *
930
+ * @example
931
+ * ```ts
932
+ * // Flat files
933
+ * createFileTree({
934
+ * "UnicodeData.txt": "0041;LATIN CAPITAL LETTER A",
935
+ * "Blocks.txt": "0000..007F; Basic Latin"
936
+ * })
937
+ *
938
+ * // With directories
939
+ * createFileTree({
940
+ * "UnicodeData.txt": "content",
941
+ * "auxiliary": {
942
+ * "GraphemeBreakProperty.txt": "content"
943
+ * }
944
+ * })
945
+ *
946
+ * // Use with mockStoreApi
947
+ * mockStoreApi({
948
+ * versions: ["16.0.0"],
949
+ * files: {
950
+ * "*": createFileTree({
951
+ * "UnicodeData.txt": "content",
952
+ * "Blocks.txt": "content"
953
+ * })
954
+ * }
955
+ * })
956
+ * ```
957
+ */
958
+ declare function createFileTree(input: FileTreeInput, parentPath?: string): FileTreeNodeWithContent[];
959
+ //#endregion
960
+ //#region src/mock-store/helpers.d.ts
961
+ /**
962
+ * Bypass type checking for testing edge cases and invalid responses.
963
+ * This is useful for testing error handling with responses that don't match the schema.
964
+ *
965
+ * @template {any} T - The type of the response being passed through
966
+ * @param {T} response - Any response data to return without type checking
967
+ * @returns {any} The response cast to `any` to bypass TypeScript type checking
968
+ *
969
+ * @example
970
+ * ```ts
971
+ * // Test with invalid schema
972
+ * mockStoreApi({
973
+ * responses: {
974
+ * "/api/v1/versions": unsafeResponse({ invalid: "data" })
975
+ * }
976
+ * });
977
+ *
978
+ * // Test with wrong type
979
+ * mockStoreApi({
980
+ * responses: {
981
+ * "/api/v1/versions": unsafeResponse("not-an-array")
982
+ * }
983
+ * });
984
+ * ```
985
+ */
986
+ declare function unsafeResponse<T = any>(response: T): any;
987
+ /**
988
+ * Configures a response with optional latency and headers for mocking purposes.
989
+ * This allows simulating network conditions or custom response metadata in tests.
990
+ *
991
+ * The configuration is stored as a non-enumerable symbol property on the response object,
992
+ * ensuring it doesn't interfere with serialization or iteration.
993
+ *
994
+ * @template Response - The type of the response being configured
995
+ * @param config - The configuration object containing the response and optional settings
996
+ * @returns The configured response with metadata attached as a symbol property
997
+ * @throws {Error} If the config is invalid or missing required properties
998
+ * @throws {TypeError} If the response is not a function or non-null object
999
+ *
1000
+ * @example
1001
+ * ```ts
1002
+ * // Configure with latency
1003
+ * mockStoreApi({
1004
+ * responses: {
1005
+ * "/api/v1/versions": configure({
1006
+ * response: [...],
1007
+ * latency: 200
1008
+ * })
1009
+ * }
1010
+ * });
1011
+ *
1012
+ * // Configure with custom headers
1013
+ * mockStoreApi({
1014
+ * responses: {
1015
+ * "/api/v1/versions": configure({
1016
+ * response: [...],
1017
+ * headers: { "X-Custom-Header": "value" }
1018
+ * })
1019
+ * }
1020
+ * });
1021
+ *
1022
+ * // Combine with unsafeResponse for testing
1023
+ * mockStoreApi({
1024
+ * responses: {
1025
+ * "/api/v1/versions": configure({
1026
+ * response: unsafeResponse({ invalid: "data" }),
1027
+ * latency: "random"
1028
+ * })
1029
+ * }
1030
+ * });
1031
+ *
1032
+ * // Configure with before/after hooks
1033
+ * mockStoreApi({
1034
+ * responses: {
1035
+ * "/api/v1/versions/{version}/file-tree": configure({
1036
+ * response: true,
1037
+ * before: async () => {
1038
+ * // Custom logic before resolver
1039
+ * },
1040
+ * after: async () => {
1041
+ * // Custom logic after resolver
1042
+ * },
1043
+ * })
1044
+ * }
1045
+ * });
1046
+ * ```
1047
+ */
1048
+ declare function configure<const Response>(config: ConfiguredResponseConfig<Response>): ConfiguredResponse<Response>;
1049
+ //#endregion
1050
+ export { createFileTree as a, FileTreeNodeWithContent as i, unsafeResponse as n, MockStoreConfig as o, FileTreeInput as r, MockStoreFiles as s, configure as t };