@ucdjs/schemas 0.1.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.
- package/LICENSE +21 -0
- package/README.md +24 -0
- package/dist/index.d.mts +189 -0
- package/dist/index.mjs +262 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-PRESENT Lucas Nørgård
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# @ucdjs/schemas
|
|
2
|
+
|
|
3
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
4
|
+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
5
|
+
[![codecov][codecov-src]][codecov-href]
|
|
6
|
+
|
|
7
|
+
This package provides schemas for different UCDJS components, including Api Responses, Environment Variables, and more.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @ucdjs/schemas
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 📄 License
|
|
16
|
+
|
|
17
|
+
Published under [MIT License](./LICENSE).
|
|
18
|
+
|
|
19
|
+
[npm-version-src]: https://img.shields.io/npm/v/@ucdjs/schemas?style=flat&colorA=18181B&colorB=4169E1
|
|
20
|
+
[npm-version-href]: https://npmjs.com/package/@ucdjs/schemas
|
|
21
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/@ucdjs/schemas?style=flat&colorA=18181B&colorB=4169E1
|
|
22
|
+
[npm-downloads-href]: https://npmjs.com/package/@ucdjs/schemas
|
|
23
|
+
[codecov-src]: https://img.shields.io/codecov/c/gh/ucdjs/ucd?style=flat&colorA=18181B&colorB=4169E1
|
|
24
|
+
[codecov-href]: https://codecov.io/gh/ucdjs/ucd
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region src/api.d.ts
|
|
4
|
+
declare const ApiErrorSchema: z.ZodObject<{
|
|
5
|
+
message: z.ZodString;
|
|
6
|
+
status: z.ZodNumber;
|
|
7
|
+
timestamp: z.ZodString;
|
|
8
|
+
}, z.core.$strip>;
|
|
9
|
+
type ApiError = z.infer<typeof ApiErrorSchema>;
|
|
10
|
+
/**
|
|
11
|
+
* Schema for .well-known/ucd-config.json endpoint configuration
|
|
12
|
+
*/
|
|
13
|
+
declare const UCDWellKnownConfigSchema: z.ZodObject<{
|
|
14
|
+
version: z.ZodDefault<z.ZodString>;
|
|
15
|
+
endpoints: z.ZodObject<{
|
|
16
|
+
files: z.ZodString;
|
|
17
|
+
manifest: z.ZodString;
|
|
18
|
+
versions: z.ZodString;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
versions: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
type UCDWellKnownConfig = z.infer<typeof UCDWellKnownConfigSchema>;
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region src/fs.d.ts
|
|
25
|
+
declare const UCDStoreManifestSchema: z.ZodRecord<z.ZodString, z.ZodDefault<z.ZodObject<{
|
|
26
|
+
expectedFiles: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
27
|
+
}, z.core.$strip>>>;
|
|
28
|
+
type UCDStoreManifest = z.output<typeof UCDStoreManifestSchema>;
|
|
29
|
+
declare const FileEntrySchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
30
|
+
name: z.ZodString;
|
|
31
|
+
path: z.ZodString;
|
|
32
|
+
lastModified: z.ZodUnion<[z.ZodNumber, z.ZodNull]>;
|
|
33
|
+
type: z.ZodLiteral<"directory">;
|
|
34
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
35
|
+
name: z.ZodString;
|
|
36
|
+
path: z.ZodString;
|
|
37
|
+
lastModified: z.ZodUnion<[z.ZodNumber, z.ZodNull]>;
|
|
38
|
+
type: z.ZodLiteral<"file">;
|
|
39
|
+
}, z.core.$strip>]>;
|
|
40
|
+
type FileEntry = z.infer<typeof FileEntrySchema>;
|
|
41
|
+
declare const FileEntryListSchema: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
42
|
+
name: z.ZodString;
|
|
43
|
+
path: z.ZodString;
|
|
44
|
+
lastModified: z.ZodUnion<[z.ZodNumber, z.ZodNull]>;
|
|
45
|
+
type: z.ZodLiteral<"directory">;
|
|
46
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
47
|
+
name: z.ZodString;
|
|
48
|
+
path: z.ZodString;
|
|
49
|
+
lastModified: z.ZodUnion<[z.ZodNumber, z.ZodNull]>;
|
|
50
|
+
type: z.ZodLiteral<"file">;
|
|
51
|
+
}, z.core.$strip>]>>;
|
|
52
|
+
type FileEntryList = z.infer<typeof FileEntryListSchema>;
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/lockfile.d.ts
|
|
55
|
+
/**
|
|
56
|
+
* Schema for the lockfile structure
|
|
57
|
+
*/
|
|
58
|
+
declare const LockfileSchema: z.ZodObject<{
|
|
59
|
+
lockfileVersion: z.ZodLiteral<1>;
|
|
60
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
61
|
+
updatedAt: z.ZodCoercedDate<unknown>;
|
|
62
|
+
versions: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
63
|
+
path: z.ZodString;
|
|
64
|
+
fileCount: z.ZodInt;
|
|
65
|
+
totalSize: z.ZodInt;
|
|
66
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
67
|
+
updatedAt: z.ZodCoercedDate<unknown>;
|
|
68
|
+
}, z.core.$strip>>;
|
|
69
|
+
filters: z.ZodOptional<z.ZodObject<{
|
|
70
|
+
include: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
71
|
+
exclude: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
72
|
+
disableDefaultExclusions: z.ZodOptional<z.ZodBoolean>;
|
|
73
|
+
}, z.core.$strip>>;
|
|
74
|
+
}, z.core.$strip>;
|
|
75
|
+
type Lockfile = z.output<typeof LockfileSchema>;
|
|
76
|
+
type LockfileInput = z.input<typeof LockfileSchema>;
|
|
77
|
+
/**
|
|
78
|
+
* Schema for a version snapshot
|
|
79
|
+
*/
|
|
80
|
+
declare const SnapshotSchema: z.ZodObject<{
|
|
81
|
+
unicodeVersion: z.ZodString;
|
|
82
|
+
files: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
83
|
+
hash: z.ZodString;
|
|
84
|
+
fileHash: z.ZodString;
|
|
85
|
+
size: z.ZodInt;
|
|
86
|
+
}, z.core.$strip>>;
|
|
87
|
+
}, z.core.$strip>;
|
|
88
|
+
type Snapshot = z.output<typeof SnapshotSchema>;
|
|
89
|
+
//#endregion
|
|
90
|
+
//#region src/manifest.d.ts
|
|
91
|
+
/**
|
|
92
|
+
* Schema for a single expected file in the manifest.
|
|
93
|
+
* Provides multiple path formats for different use cases.
|
|
94
|
+
*/
|
|
95
|
+
declare const ExpectedFileSchema: z.ZodObject<{
|
|
96
|
+
name: z.ZodString;
|
|
97
|
+
path: z.ZodString;
|
|
98
|
+
storePath: z.ZodString;
|
|
99
|
+
}, z.core.$strip>;
|
|
100
|
+
type ExpectedFile = z.infer<typeof ExpectedFileSchema>;
|
|
101
|
+
declare const UCDStoreVersionManifestSchema: z.ZodObject<{
|
|
102
|
+
expectedFiles: z.ZodArray<z.ZodObject<{
|
|
103
|
+
name: z.ZodString;
|
|
104
|
+
path: z.ZodString;
|
|
105
|
+
storePath: z.ZodString;
|
|
106
|
+
}, z.core.$strip>>;
|
|
107
|
+
}, z.core.$strip>;
|
|
108
|
+
type UCDStoreVersionManifest = z.infer<typeof UCDStoreVersionManifestSchema>;
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/types.d.ts
|
|
111
|
+
type DeepOmit<T, K extends PropertyKey> = T extends object ? T extends any[] ? DeepOmit<T[number], K>[] : { [P in Exclude<keyof T, K>]: DeepOmit<T[P], K> } : T;
|
|
112
|
+
//#endregion
|
|
113
|
+
//#region src/unicode.d.ts
|
|
114
|
+
declare const UnicodeVersionSchema: z.ZodObject<{
|
|
115
|
+
version: z.ZodString;
|
|
116
|
+
documentationUrl: z.ZodURL;
|
|
117
|
+
date: z.ZodNullable<z.ZodString>;
|
|
118
|
+
url: z.ZodURL;
|
|
119
|
+
mappedUcdVersion: z.ZodNullable<z.ZodString>;
|
|
120
|
+
type: z.ZodEnum<{
|
|
121
|
+
draft: "draft";
|
|
122
|
+
stable: "stable";
|
|
123
|
+
unsupported: "unsupported";
|
|
124
|
+
}>;
|
|
125
|
+
}, z.core.$strip>;
|
|
126
|
+
type UnicodeVersion = z.output<typeof UnicodeVersionSchema>;
|
|
127
|
+
declare const UnicodeVersionListSchema: z.ZodArray<z.ZodObject<{
|
|
128
|
+
version: z.ZodString;
|
|
129
|
+
documentationUrl: z.ZodURL;
|
|
130
|
+
date: z.ZodNullable<z.ZodString>;
|
|
131
|
+
url: z.ZodURL;
|
|
132
|
+
mappedUcdVersion: z.ZodNullable<z.ZodString>;
|
|
133
|
+
type: z.ZodEnum<{
|
|
134
|
+
draft: "draft";
|
|
135
|
+
stable: "stable";
|
|
136
|
+
unsupported: "unsupported";
|
|
137
|
+
}>;
|
|
138
|
+
}, z.core.$strip>>;
|
|
139
|
+
type UnicodeVersionList = z.output<typeof UnicodeVersionListSchema>;
|
|
140
|
+
declare const UnicodeVersionDetailsSchema: z.ZodObject<{
|
|
141
|
+
version: z.ZodString;
|
|
142
|
+
documentationUrl: z.ZodURL;
|
|
143
|
+
date: z.ZodNullable<z.ZodString>;
|
|
144
|
+
url: z.ZodURL;
|
|
145
|
+
mappedUcdVersion: z.ZodNullable<z.ZodString>;
|
|
146
|
+
type: z.ZodEnum<{
|
|
147
|
+
draft: "draft";
|
|
148
|
+
stable: "stable";
|
|
149
|
+
unsupported: "unsupported";
|
|
150
|
+
}>;
|
|
151
|
+
statistics: z.ZodDefault<z.ZodObject<{
|
|
152
|
+
totalCharacters: z.ZodInt;
|
|
153
|
+
newCharacters: z.ZodInt;
|
|
154
|
+
totalBlocks: z.ZodInt;
|
|
155
|
+
newBlocks: z.ZodInt;
|
|
156
|
+
totalScripts: z.ZodInt;
|
|
157
|
+
newScripts: z.ZodInt;
|
|
158
|
+
}, z.core.$strip>>;
|
|
159
|
+
}, z.core.$strip>;
|
|
160
|
+
type UnicodeVersionDetails = z.output<typeof UnicodeVersionDetailsSchema>;
|
|
161
|
+
declare const UnicodeFileTreeNodeSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
162
|
+
name: z.ZodString;
|
|
163
|
+
path: z.ZodString;
|
|
164
|
+
lastModified: z.ZodUnion<[z.ZodNumber, z.ZodNull]>;
|
|
165
|
+
type: z.ZodLiteral<"directory">;
|
|
166
|
+
readonly children: z.ZodArray<typeof UnicodeFileTreeNodeSchema>;
|
|
167
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
168
|
+
name: z.ZodString;
|
|
169
|
+
path: z.ZodString;
|
|
170
|
+
lastModified: z.ZodUnion<[z.ZodNumber, z.ZodNull]>;
|
|
171
|
+
type: z.ZodLiteral<"file">;
|
|
172
|
+
}, z.core.$strip>]>;
|
|
173
|
+
type UnicodeFileTreeNode = z.infer<typeof UnicodeFileTreeNodeSchema>;
|
|
174
|
+
type UnicodeFileTreeNodeWithoutLastModified = DeepOmit<UnicodeFileTreeNode, "lastModified">;
|
|
175
|
+
declare const UnicodeFileTreeSchema: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
176
|
+
name: z.ZodString;
|
|
177
|
+
path: z.ZodString;
|
|
178
|
+
lastModified: z.ZodUnion<[z.ZodNumber, z.ZodNull]>;
|
|
179
|
+
type: z.ZodLiteral<"directory">;
|
|
180
|
+
readonly children: z.ZodArray<typeof UnicodeFileTreeNodeSchema>;
|
|
181
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
182
|
+
name: z.ZodString;
|
|
183
|
+
path: z.ZodString;
|
|
184
|
+
lastModified: z.ZodUnion<[z.ZodNumber, z.ZodNull]>;
|
|
185
|
+
type: z.ZodLiteral<"file">;
|
|
186
|
+
}, z.core.$strip>]>>;
|
|
187
|
+
type UnicodeFileTree = z.infer<typeof UnicodeFileTreeSchema>;
|
|
188
|
+
//#endregion
|
|
189
|
+
export { type ApiError, ApiErrorSchema, type ExpectedFile, ExpectedFileSchema, type FileEntry, type FileEntryList, FileEntryListSchema, FileEntrySchema, type Lockfile, type LockfileInput, LockfileSchema, type Snapshot, SnapshotSchema, type UCDStoreManifest, UCDStoreManifestSchema, type UCDStoreVersionManifest, UCDStoreVersionManifestSchema, type UCDWellKnownConfig, UCDWellKnownConfigSchema, type UnicodeFileTree, type UnicodeFileTreeNode, UnicodeFileTreeNodeSchema, type UnicodeFileTreeNodeWithoutLastModified, UnicodeFileTreeSchema, type UnicodeVersion, type UnicodeVersionDetails, UnicodeVersionDetailsSchema, type UnicodeVersionList, UnicodeVersionListSchema, UnicodeVersionSchema };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { dedent } from "@luxass/utils";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/api.ts
|
|
5
|
+
const ApiErrorSchema = z.object({
|
|
6
|
+
message: z.string().meta({ description: "Human-readable error message describing what went wrong" }),
|
|
7
|
+
status: z.number().meta({ description: "HTTP status code matching the response status" }),
|
|
8
|
+
timestamp: z.string().meta({ description: "ISO 8601 timestamp when the error occurred" })
|
|
9
|
+
}).meta({ description: dedent`
|
|
10
|
+
Standard error response format used consistently across all API endpoints.
|
|
11
|
+
|
|
12
|
+
Contains essential information for debugging and user feedback. The specific error scenarios and status codes are documented in the individual endpoint response definitions.
|
|
13
|
+
` });
|
|
14
|
+
/**
|
|
15
|
+
* Schema for .well-known/ucd-config.json endpoint configuration
|
|
16
|
+
*/
|
|
17
|
+
const UCDWellKnownConfigSchema = z.object({
|
|
18
|
+
version: z.string().default("1.0"),
|
|
19
|
+
endpoints: z.object({
|
|
20
|
+
files: z.string(),
|
|
21
|
+
manifest: z.string(),
|
|
22
|
+
versions: z.string()
|
|
23
|
+
}),
|
|
24
|
+
versions: z.array(z.string()).default([])
|
|
25
|
+
}).meta({
|
|
26
|
+
id: "UCDWellKnownConfig",
|
|
27
|
+
description: dedent`
|
|
28
|
+
Configuration schema for the .well-known/ucd-config.json endpoint.
|
|
29
|
+
|
|
30
|
+
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.
|
|
31
|
+
|
|
32
|
+
The \`manifest\` endpoint is deprecated. Use the per-version endpoint \`/.well-known/ucd-store/{version}.json\` instead for better performance and caching.
|
|
33
|
+
`
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/fs.ts
|
|
38
|
+
const UCDStoreManifestSchema = z.record(z.string(), z.object({ expectedFiles: z.array(z.string()).default([]) }).default({ expectedFiles: [] })).meta({
|
|
39
|
+
id: "UCDStoreManifest",
|
|
40
|
+
description: dedent`
|
|
41
|
+
A record of per-version metadata for the UCD store.
|
|
42
|
+
Each key is the version string, and the value is an object holding metadata.
|
|
43
|
+
|
|
44
|
+
Fields:
|
|
45
|
+
- expectedFiles: string[] (defaults to [])
|
|
46
|
+
|
|
47
|
+
## Example
|
|
48
|
+
\`\`\`json
|
|
49
|
+
{
|
|
50
|
+
"15.1.0": { "expectedFiles": ["UnicodeData.txt", "PropList.txt"] },
|
|
51
|
+
"14.0.0": { "expectedFiles": [] }
|
|
52
|
+
}
|
|
53
|
+
\`\`\`
|
|
54
|
+
|
|
55
|
+
The path is relative to the root of the UCD Api Server, typically \`https://api.ucdjs.dev/api/v1/files\`. E.g. \`15.1.0\` would resolve to \`https://api.ucdjs.dev/api/v1/files/15.1.0\`.
|
|
56
|
+
`
|
|
57
|
+
});
|
|
58
|
+
const FileEntryBaseSchema = z.object({
|
|
59
|
+
name: z.string(),
|
|
60
|
+
path: z.string(),
|
|
61
|
+
lastModified: z.number().or(z.null())
|
|
62
|
+
});
|
|
63
|
+
const FileEntryDirectorySchema = FileEntryBaseSchema.extend({ type: z.literal("directory") });
|
|
64
|
+
const FileEntryFileSchema = FileEntryBaseSchema.extend({ type: z.literal("file") });
|
|
65
|
+
const FileEntrySchema = z.union([FileEntryDirectorySchema, FileEntryFileSchema]).meta({
|
|
66
|
+
id: "FileEntry",
|
|
67
|
+
description: dedent`
|
|
68
|
+
Response schema for a file entry in the UCD store.
|
|
69
|
+
|
|
70
|
+
This schema represents either a directory listing or a file response.
|
|
71
|
+
`
|
|
72
|
+
}).superRefine((data, ctx) => {
|
|
73
|
+
if (data.type === "directory" && !data.path.endsWith("/")) ctx.addIssue({
|
|
74
|
+
code: "custom",
|
|
75
|
+
message: "Directory paths must end with a trailing slash ('/')."
|
|
76
|
+
});
|
|
77
|
+
if (!data.path.startsWith("/")) ctx.addIssue({
|
|
78
|
+
code: "custom",
|
|
79
|
+
message: "Paths must start with a leading slash ('/')."
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
const FileEntryListSchema = z.array(FileEntrySchema).meta({
|
|
83
|
+
id: "FileEntryList",
|
|
84
|
+
description: "An array of file entries, each representing either a file or a directory."
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/lockfile.ts
|
|
89
|
+
/**
|
|
90
|
+
* Schema for ISO 8601 date strings that coerces to Date objects.
|
|
91
|
+
* Accepts ISO date strings, numbers (timestamps), or Date objects as input.
|
|
92
|
+
* Always outputs a Date object after parsing.
|
|
93
|
+
*/
|
|
94
|
+
const DateSchema = z.coerce.date();
|
|
95
|
+
/**
|
|
96
|
+
* Schema for a single version entry in the lockfile
|
|
97
|
+
*/
|
|
98
|
+
const LockfileVersionEntrySchema = z.object({
|
|
99
|
+
path: z.string(),
|
|
100
|
+
fileCount: z.int().nonnegative(),
|
|
101
|
+
totalSize: z.int().nonnegative(),
|
|
102
|
+
createdAt: DateSchema,
|
|
103
|
+
updatedAt: DateSchema
|
|
104
|
+
});
|
|
105
|
+
/**
|
|
106
|
+
* Schema for filters applied when creating/updating the lockfile.
|
|
107
|
+
*/
|
|
108
|
+
const LockfileFiltersSchema = z.object({
|
|
109
|
+
include: z.array(z.string()).optional(),
|
|
110
|
+
exclude: z.array(z.string()).optional(),
|
|
111
|
+
disableDefaultExclusions: z.boolean().optional()
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* Schema for the lockfile structure
|
|
115
|
+
*/
|
|
116
|
+
const LockfileSchema = z.object({
|
|
117
|
+
lockfileVersion: z.literal(1),
|
|
118
|
+
createdAt: DateSchema,
|
|
119
|
+
updatedAt: DateSchema,
|
|
120
|
+
versions: z.record(z.string(), LockfileVersionEntrySchema),
|
|
121
|
+
filters: LockfileFiltersSchema.optional()
|
|
122
|
+
});
|
|
123
|
+
/**
|
|
124
|
+
* Schema for a single file entry in a snapshot
|
|
125
|
+
*/
|
|
126
|
+
const SnapshotFileEntrySchema = z.object({
|
|
127
|
+
hash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
|
|
128
|
+
fileHash: z.string().regex(/^sha256:[a-f0-9]{64}$/),
|
|
129
|
+
size: z.int().nonnegative()
|
|
130
|
+
});
|
|
131
|
+
/**
|
|
132
|
+
* Schema for a version snapshot
|
|
133
|
+
*/
|
|
134
|
+
const SnapshotSchema = z.object({
|
|
135
|
+
unicodeVersion: z.string(),
|
|
136
|
+
files: z.record(z.string(), SnapshotFileEntrySchema)
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/manifest.ts
|
|
141
|
+
/**
|
|
142
|
+
* Schema for a single expected file in the manifest.
|
|
143
|
+
* Provides multiple path formats for different use cases.
|
|
144
|
+
*/
|
|
145
|
+
const ExpectedFileSchema = z.object({
|
|
146
|
+
name: z.string().meta({ description: "Filename only" }),
|
|
147
|
+
path: z.string().meta({ description: "Path relative to /api/v1/files endpoint (includes /ucd/ for versions >= 4.1.0)" }),
|
|
148
|
+
storePath: z.string().meta({ description: "Path for store subdomain (without /ucd/ prefix)" })
|
|
149
|
+
}).meta({
|
|
150
|
+
id: "ExpectedFile",
|
|
151
|
+
description: "A file expected to be present in a UCD version"
|
|
152
|
+
});
|
|
153
|
+
const UCDStoreVersionManifestSchema = z.object({ expectedFiles: z.array(ExpectedFileSchema).meta({ description: "List of expected files for this version with their paths" }) }).meta({
|
|
154
|
+
id: "UCDStoreVersionManifest",
|
|
155
|
+
description: dedent`
|
|
156
|
+
Response schema for per-version manifest endpoint.
|
|
157
|
+
Matches the schema from /.well-known/ucd-store/{version}.json
|
|
158
|
+
`
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
//#endregion
|
|
162
|
+
//#region src/unicode.ts
|
|
163
|
+
const UnicodeVersionSchema = z.object({
|
|
164
|
+
version: z.string().meta({ description: "The version of the Unicode standard." }),
|
|
165
|
+
documentationUrl: z.url().meta({ description: "The URL to the Unicode version documentation." }),
|
|
166
|
+
date: z.string().regex(/^\d{4}$/, "Year must be a four-digit number").meta({ description: "The year of the Unicode version." }).nullable(),
|
|
167
|
+
url: z.url().meta({ description: "The URL to the Unicode Character Database (UCD) for this version." }),
|
|
168
|
+
mappedUcdVersion: z.string().nullable().meta({ description: "The corresponding UCD version mapping for this Unicode version. Null if same as version." }),
|
|
169
|
+
type: z.enum([
|
|
170
|
+
"draft",
|
|
171
|
+
"stable",
|
|
172
|
+
"unsupported"
|
|
173
|
+
]).meta({ description: "The status of the Unicode version. 'unsupported' means the version exists but is not yet supported by the API." })
|
|
174
|
+
}).meta({
|
|
175
|
+
id: "UnicodeVersion",
|
|
176
|
+
description: "Represents a Unicode version with its metadata and support status.",
|
|
177
|
+
examples: [
|
|
178
|
+
{
|
|
179
|
+
version: "17.0.0",
|
|
180
|
+
documentationUrl: "https://www.unicode.org/versions/Unicode17.0.0/",
|
|
181
|
+
date: null,
|
|
182
|
+
url: "https://www.unicode.org/Public/17.0.0",
|
|
183
|
+
mappedUcdVersion: null,
|
|
184
|
+
type: "draft"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
version: "16.0.0",
|
|
188
|
+
documentationUrl: "https://www.unicode.org/versions/Unicode16.0.0/",
|
|
189
|
+
date: "2024",
|
|
190
|
+
url: "https://www.unicode.org/Public/16.0.0",
|
|
191
|
+
mappedUcdVersion: null,
|
|
192
|
+
type: "stable"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
version: "15.1.0",
|
|
196
|
+
documentationUrl: "https://www.unicode.org/versions/Unicode15.1.0/",
|
|
197
|
+
date: "2023",
|
|
198
|
+
url: "https://www.unicode.org/Public/15.1.0",
|
|
199
|
+
mappedUcdVersion: null,
|
|
200
|
+
type: "stable"
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
});
|
|
204
|
+
const UnicodeVersionListSchema = z.array(UnicodeVersionSchema).meta({
|
|
205
|
+
id: "UnicodeVersionList",
|
|
206
|
+
description: "A list of Unicode versions with their metadata and support status."
|
|
207
|
+
});
|
|
208
|
+
const UnicodeVersionDetailsSchema = UnicodeVersionSchema.extend({ statistics: z.object({
|
|
209
|
+
totalCharacters: z.int().nonnegative().meta({ description: "Total number of characters in this Unicode version." }),
|
|
210
|
+
newCharacters: z.int().nonnegative().meta({ description: "Number of new characters added in this version." }),
|
|
211
|
+
totalBlocks: z.int().nonnegative().meta({ description: "Total number of blocks in this Unicode version." }),
|
|
212
|
+
newBlocks: z.int().nonnegative().meta({ description: "Number of new blocks added in this version." }),
|
|
213
|
+
totalScripts: z.int().nonnegative().meta({ description: "Total number of scripts in this Unicode version." }),
|
|
214
|
+
newScripts: z.int().nonnegative().meta({ description: "Number of new scripts added in this version." })
|
|
215
|
+
}).default({
|
|
216
|
+
newBlocks: 0,
|
|
217
|
+
newCharacters: 0,
|
|
218
|
+
newScripts: 0,
|
|
219
|
+
totalBlocks: 0,
|
|
220
|
+
totalCharacters: 0,
|
|
221
|
+
totalScripts: 0
|
|
222
|
+
}).meta({ description: "Statistics about this Unicode version. May be null if statistics are not available." }) }).meta({
|
|
223
|
+
id: "UnicodeVersionDetails",
|
|
224
|
+
description: "Detailed information about a Unicode version, including metadata and statistics.",
|
|
225
|
+
examples: [{
|
|
226
|
+
version: "16.0.0",
|
|
227
|
+
documentationUrl: "https://www.unicode.org/versions/Unicode16.0.0/",
|
|
228
|
+
date: "2024",
|
|
229
|
+
url: "https://www.unicode.org/Public/16.0.0",
|
|
230
|
+
mappedUcdVersion: null,
|
|
231
|
+
type: "stable",
|
|
232
|
+
statistics: {
|
|
233
|
+
totalCharacters: 149813,
|
|
234
|
+
newCharacters: 5185,
|
|
235
|
+
totalBlocks: 331,
|
|
236
|
+
newBlocks: 4,
|
|
237
|
+
totalScripts: 165,
|
|
238
|
+
newScripts: 2
|
|
239
|
+
}
|
|
240
|
+
}]
|
|
241
|
+
});
|
|
242
|
+
const UnicodeFileTreeFileSchema = FileEntryFileSchema.meta({
|
|
243
|
+
id: "UnicodeFileTreeFile",
|
|
244
|
+
description: "A file node in the Unicode file tree."
|
|
245
|
+
});
|
|
246
|
+
const UnicodeFileTreeDirectorySchema = FileEntryDirectorySchema.extend({ get children() {
|
|
247
|
+
return z.array(UnicodeFileTreeNodeSchema);
|
|
248
|
+
} }).meta({
|
|
249
|
+
id: "UnicodeFileTreeDirectory",
|
|
250
|
+
description: "A directory node in the Unicode file tree, containing child nodes."
|
|
251
|
+
});
|
|
252
|
+
const UnicodeFileTreeNodeSchema = z.union([UnicodeFileTreeDirectorySchema, UnicodeFileTreeFileSchema]).meta({
|
|
253
|
+
id: "UnicodeFileTreeNode",
|
|
254
|
+
description: "A recursive file tree node; directories include children, files do not."
|
|
255
|
+
});
|
|
256
|
+
const UnicodeFileTreeSchema = z.array(UnicodeFileTreeNodeSchema).meta({
|
|
257
|
+
id: "UnicodeFileTree",
|
|
258
|
+
description: "A recursive file tree structure rooted at an array of entries."
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
//#endregion
|
|
262
|
+
export { ApiErrorSchema, ExpectedFileSchema, FileEntryListSchema, FileEntrySchema, LockfileSchema, SnapshotSchema, UCDStoreManifestSchema, UCDStoreVersionManifestSchema, UCDWellKnownConfigSchema, UnicodeFileTreeNodeSchema, UnicodeFileTreeSchema, UnicodeVersionDetailsSchema, UnicodeVersionListSchema, UnicodeVersionSchema };
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ucdjs/schemas",
|
|
3
|
+
"version": "0.1.1-beta.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Lucas Nørgård",
|
|
7
|
+
"email": "lucasnrgaard@gmail.com",
|
|
8
|
+
"url": "https://luxass.dev"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"homepage": "https://github.com/ucdjs/ucd",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/ucdjs/ucd.git",
|
|
15
|
+
"directory": "packages/schemas"
|
|
16
|
+
},
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/ucdjs/ucd/issues"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": "./dist/index.mjs",
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"types": "./dist/index.d.mts",
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=22.18"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@luxass/utils": "2.7.3",
|
|
33
|
+
"zod": "4.3.6"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@luxass/eslint-config": "7.2.0",
|
|
37
|
+
"eslint": "10.0.0",
|
|
38
|
+
"publint": "0.3.17",
|
|
39
|
+
"tsdown": "0.20.3",
|
|
40
|
+
"typescript": "5.9.3",
|
|
41
|
+
"@ucdjs-tooling/tsconfig": "1.0.0",
|
|
42
|
+
"@ucdjs-tooling/tsdown-config": "1.0.0"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsdown --tsconfig=./tsconfig.build.json",
|
|
49
|
+
"dev": "tsdown --watch",
|
|
50
|
+
"clean": "git clean -xdf dist node_modules",
|
|
51
|
+
"lint": "eslint .",
|
|
52
|
+
"typecheck": "tsc --noEmit -p tsconfig.build.json"
|
|
53
|
+
}
|
|
54
|
+
}
|