@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.
- package/LICENSE +21 -0
- package/README.md +26 -0
- package/dist/file-tree-CColHWG6.mjs +4436 -0
- package/dist/fs-bridges/index.d.mts +84 -0
- package/dist/fs-bridges/index.mjs +303 -0
- package/dist/helpers-D3XLw9D1.d.mts +1050 -0
- package/dist/index.d.mts +76 -0
- package/dist/index.mjs +89 -0
- package/dist/matchers/types.mjs +149 -0
- package/dist/matchers/vitest-setup.d.mts +1 -0
- package/dist/matchers/vitest-setup.mjs +239 -0
- package/dist/mock-store.d.mts +21 -0
- package/dist/mock-store.mjs +210 -0
- package/dist/msw/vitest-setup.d.mts +1 -0
- package/dist/msw/vitest-setup.mjs +14 -0
- package/dist/msw.d.mts +25 -0
- package/dist/msw.mjs +30 -0
- package/dist/pipelines.d.mts +21 -0
- package/dist/pipelines.mjs +35 -0
- package/package.json +79 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { mockFetch } from "./msw.mjs";
|
|
2
|
+
import { a as parseLatency, c as unsafeResponse, d as defaultArabicShapingFileContent, f as addPathsToFileNodes, i as omitChildrenAndContent, l as defaultDerivedBidClassFileContent, n as MOCK_ROUTES, o as wrapMockFetch, r as extractConfiguredMetadata, s as configure, t as createFileTree, u as defaultBidiBracketsFileContent } from "./file-tree-CColHWG6.mjs";
|
|
3
|
+
import { createDebugger, findFileByPath, isApiError } from "@ucdjs-internal/shared";
|
|
4
|
+
import { UCD_STAT_CHILDREN_DIRS_HEADER, UCD_STAT_CHILDREN_FILES_HEADER, UCD_STAT_CHILDREN_HEADER, UCD_STAT_SIZE_HEADER, UCD_STAT_TYPE_HEADER } from "@ucdjs/env";
|
|
5
|
+
import { HttpResponse } from "msw";
|
|
6
|
+
|
|
7
|
+
//#region src/mock-store/index.ts
|
|
8
|
+
const debug = createDebugger("ucdjs:test-utils:mock-store");
|
|
9
|
+
const DEFAULT_MOCK_STORE_FILES = { "*": [
|
|
10
|
+
{
|
|
11
|
+
type: "file",
|
|
12
|
+
name: "ArabicShaping.txt",
|
|
13
|
+
lastModified: 17552871e5,
|
|
14
|
+
_content: defaultArabicShapingFileContent
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
type: "file",
|
|
18
|
+
name: "BidiBrackets.txt",
|
|
19
|
+
lastModified: 17552871e5,
|
|
20
|
+
_content: defaultBidiBracketsFileContent
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
type: "directory",
|
|
24
|
+
name: "extracted",
|
|
25
|
+
lastModified: 17552871e5,
|
|
26
|
+
children: [{
|
|
27
|
+
type: "file",
|
|
28
|
+
name: "DerivedBidiClass.txt",
|
|
29
|
+
lastModified: 17552871e5,
|
|
30
|
+
_content: defaultDerivedBidClassFileContent
|
|
31
|
+
}]
|
|
32
|
+
}
|
|
33
|
+
] };
|
|
34
|
+
function mockStoreApi(config) {
|
|
35
|
+
const { baseUrl = "https://api.ucdjs.dev", responses, versions = [
|
|
36
|
+
"16.0.0",
|
|
37
|
+
"15.1.0",
|
|
38
|
+
"15.0.0"
|
|
39
|
+
], customResponses = [], onRequest, files = DEFAULT_MOCK_STORE_FILES } = config || {};
|
|
40
|
+
debug?.("Setting up mock store API with config:", config);
|
|
41
|
+
const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
42
|
+
for (const route of MOCK_ROUTES) {
|
|
43
|
+
const endpoint = route.endpoint;
|
|
44
|
+
const response = responses?.[endpoint] ?? false;
|
|
45
|
+
if (response === false) continue;
|
|
46
|
+
let { actualResponse, latency, headers, beforeHook, afterHook } = extractConfiguredMetadata(response);
|
|
47
|
+
if (typeof actualResponse === "object" && actualResponse !== null && "__useDefaultResolver" in actualResponse) actualResponse = true;
|
|
48
|
+
const shouldUseDefaultValue = actualResponse === true || response == null;
|
|
49
|
+
debug?.(`Setting up mock for endpoint: ${endpoint} with response:`, actualResponse);
|
|
50
|
+
if (isApiError(actualResponse)) {
|
|
51
|
+
debug?.(`Detected ApiError-like response for endpoint: ${endpoint}`);
|
|
52
|
+
let tmp = actualResponse;
|
|
53
|
+
function newHandler() {
|
|
54
|
+
return HttpResponse.json(tmp, { status: tmp.status });
|
|
55
|
+
}
|
|
56
|
+
actualResponse = newHandler;
|
|
57
|
+
}
|
|
58
|
+
const wrappedMockFetch = wrapMockFetch(mockFetch, {
|
|
59
|
+
onRequest,
|
|
60
|
+
beforeFetch: async (payload) => {
|
|
61
|
+
debug?.("Before fetch for endpoint:", endpoint);
|
|
62
|
+
if (latency) {
|
|
63
|
+
const ms = parseLatency(latency);
|
|
64
|
+
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
65
|
+
}
|
|
66
|
+
await beforeHook?.(payload);
|
|
67
|
+
},
|
|
68
|
+
afterFetch: async ({ response, ...payload }) => {
|
|
69
|
+
debug?.("After fetch for endpoint:", endpoint);
|
|
70
|
+
await afterHook?.({
|
|
71
|
+
...payload,
|
|
72
|
+
response
|
|
73
|
+
});
|
|
74
|
+
if (!response) {
|
|
75
|
+
debug?.("No response returned from resolver");
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (!headers || !("headers" in response) || !(response.headers instanceof Headers)) return;
|
|
79
|
+
for (const [key, value] of Object.entries(headers)) if (response.headers.get(key) !== value) response.headers.set(key, value);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
const mswPath = toMSWPath(endpoint);
|
|
83
|
+
debug?.(`MSW path for endpoint ${endpoint}: ${mswPath}`);
|
|
84
|
+
route.setup({
|
|
85
|
+
url: `${normalizedBaseUrl}${mswPath}`,
|
|
86
|
+
providedResponse: actualResponse,
|
|
87
|
+
shouldUseDefaultValue,
|
|
88
|
+
mockFetch: wrappedMockFetch,
|
|
89
|
+
versions,
|
|
90
|
+
files
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
if (customResponses.length > 0) {
|
|
94
|
+
debug?.("Setting up custom responses");
|
|
95
|
+
mockFetch(customResponses);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function toMSWPath(endpoint) {
|
|
99
|
+
return endpoint.replace(/\{(\w+)\}/g, (_, p1) => {
|
|
100
|
+
if (p1 === "wildcard") return `:${p1}*`;
|
|
101
|
+
return `:${p1}`;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Sets up mock handlers for the store subdomain (ucd-store.ucdjs.dev).
|
|
106
|
+
*
|
|
107
|
+
* This is used for the HTTP fs-bridge which directly accesses files via the store subdomain
|
|
108
|
+
* rather than through the API. The store subdomain handles paths like /:version/:filepath
|
|
109
|
+
* without the /ucd/ prefix (it's handled internally by the subdomain).
|
|
110
|
+
*
|
|
111
|
+
* @param {object} config - Configuration for the store subdomain mock
|
|
112
|
+
* @param {string} [config.storeBaseUrl] - Base URL for the store subdomain (defaults to https://ucd-store.ucdjs.dev)
|
|
113
|
+
* @param {MockStoreFiles} config.files - The files to mock
|
|
114
|
+
*/
|
|
115
|
+
function mockStoreSubdomain(config) {
|
|
116
|
+
const { storeBaseUrl = "https://ucd-store.ucdjs.dev", files } = config;
|
|
117
|
+
debug?.("Setting up mock store subdomain with config:", config);
|
|
118
|
+
mockFetch([[
|
|
119
|
+
["GET", "HEAD"],
|
|
120
|
+
`${storeBaseUrl.endsWith("/") ? storeBaseUrl.slice(0, -1) : storeBaseUrl}/:wildcard*`,
|
|
121
|
+
({ request, params }) => {
|
|
122
|
+
const wildcard = params.wildcard || "";
|
|
123
|
+
const isHeadRequest = request.method === "HEAD";
|
|
124
|
+
debug?.("Store subdomain request:", {
|
|
125
|
+
wildcard,
|
|
126
|
+
method: request.method
|
|
127
|
+
});
|
|
128
|
+
const [firstPart, ...pathParts] = wildcard.split("/");
|
|
129
|
+
const isVersionKey = firstPart && firstPart in files;
|
|
130
|
+
let version = "";
|
|
131
|
+
let filePath;
|
|
132
|
+
let versionFiles = [];
|
|
133
|
+
let lookupPath;
|
|
134
|
+
if (isVersionKey || firstPart && files["*"]) {
|
|
135
|
+
version = firstPart;
|
|
136
|
+
filePath = pathParts.join("/");
|
|
137
|
+
const versionFilesRaw = files[firstPart] || files["*"];
|
|
138
|
+
if (!versionFilesRaw || !Array.isArray(versionFilesRaw)) return HttpResponse.json({
|
|
139
|
+
message: "Resource not found",
|
|
140
|
+
status: 404,
|
|
141
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
142
|
+
}, { status: 404 });
|
|
143
|
+
versionFiles = addPathsToFileNodes(versionFilesRaw, version, "");
|
|
144
|
+
lookupPath = filePath ? `/${version}/${filePath}` : `/${version}`;
|
|
145
|
+
} else {
|
|
146
|
+
filePath = wildcard;
|
|
147
|
+
const rootFilesRaw = files.root;
|
|
148
|
+
if (!rootFilesRaw || !Array.isArray(rootFilesRaw)) return HttpResponse.json({
|
|
149
|
+
message: "Resource not found",
|
|
150
|
+
status: 404,
|
|
151
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
152
|
+
}, { status: 404 });
|
|
153
|
+
versionFiles = addPathsToFileNodes(rootFilesRaw, "", "");
|
|
154
|
+
lookupPath = filePath ? `/${filePath}` : "/";
|
|
155
|
+
}
|
|
156
|
+
debug?.("Looking up path:", {
|
|
157
|
+
lookupPath,
|
|
158
|
+
versionFilesCount: versionFiles.length
|
|
159
|
+
});
|
|
160
|
+
if (version && !filePath) {
|
|
161
|
+
const stripped = omitChildrenAndContent(versionFiles);
|
|
162
|
+
return HttpResponse.json(stripped, { headers: {
|
|
163
|
+
[UCD_STAT_TYPE_HEADER]: "directory",
|
|
164
|
+
[UCD_STAT_CHILDREN_HEADER]: `${stripped.length}`,
|
|
165
|
+
[UCD_STAT_CHILDREN_FILES_HEADER]: `${stripped.filter((f) => f.type === "file").length}`,
|
|
166
|
+
[UCD_STAT_CHILDREN_DIRS_HEADER]: `${stripped.filter((f) => f.type === "directory").length}`
|
|
167
|
+
} });
|
|
168
|
+
}
|
|
169
|
+
const fileNode = findFileByPath(versionFiles, lookupPath);
|
|
170
|
+
if (fileNode && fileNode.type === "directory") {
|
|
171
|
+
const stripped = omitChildrenAndContent(fileNode.children ?? []);
|
|
172
|
+
return HttpResponse.json(stripped, { headers: {
|
|
173
|
+
[UCD_STAT_TYPE_HEADER]: "directory",
|
|
174
|
+
[UCD_STAT_CHILDREN_HEADER]: `${stripped.length}`,
|
|
175
|
+
[UCD_STAT_CHILDREN_FILES_HEADER]: `${stripped.filter((f) => f.type === "file").length}`,
|
|
176
|
+
[UCD_STAT_CHILDREN_DIRS_HEADER]: `${stripped.filter((f) => f.type === "directory").length}`
|
|
177
|
+
} });
|
|
178
|
+
}
|
|
179
|
+
if (fileNode && "_content" in fileNode && typeof fileNode._content === "string") {
|
|
180
|
+
const content = fileNode._content;
|
|
181
|
+
const contentLength = new TextEncoder().encode(content).length;
|
|
182
|
+
const headers = {
|
|
183
|
+
"Content-Type": "text/plain; charset=utf-8",
|
|
184
|
+
[UCD_STAT_TYPE_HEADER]: "file"
|
|
185
|
+
};
|
|
186
|
+
if (isHeadRequest) {
|
|
187
|
+
headers["Content-Length"] = `${contentLength}`;
|
|
188
|
+
headers[UCD_STAT_SIZE_HEADER] = `${contentLength}`;
|
|
189
|
+
}
|
|
190
|
+
return HttpResponse.text(content, { headers });
|
|
191
|
+
}
|
|
192
|
+
if (fileNode) {
|
|
193
|
+
console.warn(`Mock store subdomain: File "${filePath}" found but has no _content. Returning 404.`);
|
|
194
|
+
return HttpResponse.json({
|
|
195
|
+
message: "Resource not found",
|
|
196
|
+
status: 404,
|
|
197
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
198
|
+
}, { status: 404 });
|
|
199
|
+
}
|
|
200
|
+
return HttpResponse.json({
|
|
201
|
+
message: "Resource not found",
|
|
202
|
+
status: 404,
|
|
203
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
204
|
+
}, { status: 404 });
|
|
205
|
+
}
|
|
206
|
+
]]);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
//#endregion
|
|
210
|
+
export { configure, createFileTree, mockStoreApi, mockStoreSubdomain, unsafeResponse };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { mswServer } from "../msw.mjs";
|
|
2
|
+
import { afterAll, afterEach, beforeAll } from "vitest";
|
|
3
|
+
|
|
4
|
+
//#region src/msw/vitest-setup.ts
|
|
5
|
+
beforeAll(() => {
|
|
6
|
+
mswServer.listen({ onUnhandledRequest: (_, print) => {
|
|
7
|
+
print.error();
|
|
8
|
+
} });
|
|
9
|
+
});
|
|
10
|
+
afterEach(() => mswServer.resetHandlers());
|
|
11
|
+
afterAll(() => mswServer.close());
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
export { };
|
package/dist/msw.d.mts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { HttpResponse, http } from "msw";
|
|
2
|
+
import * as _luxass_msw_utils0 from "@luxass/msw-utils";
|
|
3
|
+
import { createMockFetch } from "@luxass/msw-utils";
|
|
4
|
+
import { SetupServerApi } from "msw/node";
|
|
5
|
+
|
|
6
|
+
//#region src/msw.d.ts
|
|
7
|
+
declare global {
|
|
8
|
+
var __ucd_msw_server: SetupServerApi | undefined;
|
|
9
|
+
}
|
|
10
|
+
declare const mswServer: SetupServerApi;
|
|
11
|
+
declare const mockFetch: _luxass_msw_utils0.MockFetchFn;
|
|
12
|
+
/**
|
|
13
|
+
* A `Response` subclass that avoids default headers.
|
|
14
|
+
* Useful for MSW or unit tests to simulate "naked" responses from a server
|
|
15
|
+
* that lack a `Content-Type` header, allowing you to test fallback parsing logic.
|
|
16
|
+
*/
|
|
17
|
+
declare class RawResponse extends Response {
|
|
18
|
+
/**
|
|
19
|
+
* @param {BodyInit | null} body - The body of the response.
|
|
20
|
+
* @param {ResponseInit} [init] - Options including status code and headers.
|
|
21
|
+
*/
|
|
22
|
+
constructor(body?: BodyInit | null, init?: ResponseInit);
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { HttpResponse, RawResponse, createMockFetch, http, mockFetch, mswServer };
|
package/dist/msw.mjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { HttpResponse, http } from "msw";
|
|
2
|
+
import { createMockFetch, createMockFetch as createMockFetch$1 } from "@luxass/msw-utils";
|
|
3
|
+
import { setupServer } from "msw/node";
|
|
4
|
+
|
|
5
|
+
//#region src/msw.ts
|
|
6
|
+
const mswServer = setupServer();
|
|
7
|
+
globalThis.__ucd_msw_server = mswServer;
|
|
8
|
+
const mockFetch = createMockFetch$1({
|
|
9
|
+
mswServer,
|
|
10
|
+
replaceOpenAPIPathParams: true
|
|
11
|
+
});
|
|
12
|
+
/**
|
|
13
|
+
* A `Response` subclass that avoids default headers.
|
|
14
|
+
* Useful for MSW or unit tests to simulate "naked" responses from a server
|
|
15
|
+
* that lack a `Content-Type` header, allowing you to test fallback parsing logic.
|
|
16
|
+
*/
|
|
17
|
+
var RawResponse = class extends Response {
|
|
18
|
+
/**
|
|
19
|
+
* @param {BodyInit | null} body - The body of the response.
|
|
20
|
+
* @param {ResponseInit} [init] - Options including status code and headers.
|
|
21
|
+
*/
|
|
22
|
+
constructor(body, init) {
|
|
23
|
+
let processedBody = body;
|
|
24
|
+
if (typeof body === "string") processedBody = new TextEncoder().encode(body);
|
|
25
|
+
super(processedBody, init);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
//#endregion
|
|
30
|
+
export { HttpResponse, RawResponse, createMockFetch, http, mockFetch, mswServer };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/pipelines/source.d.ts
|
|
2
|
+
interface PipelineDefinition {
|
|
3
|
+
_type?: string;
|
|
4
|
+
id: string;
|
|
5
|
+
versions?: string[];
|
|
6
|
+
inputs?: unknown[];
|
|
7
|
+
routes?: unknown[];
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
type NamedExportValue = PipelineDefinition | string;
|
|
11
|
+
type NamedExportConfig = Record<string, NamedExportValue>;
|
|
12
|
+
type PipelineModuleSourceNamed = string[] | NamedExportConfig;
|
|
13
|
+
interface PipelineModuleSourceOptions {
|
|
14
|
+
named?: PipelineModuleSourceNamed;
|
|
15
|
+
definitions?: Record<string, Partial<PipelineDefinition>>;
|
|
16
|
+
extraExports?: string;
|
|
17
|
+
prelude?: string;
|
|
18
|
+
}
|
|
19
|
+
declare function createPipelineModuleSource(options?: PipelineModuleSourceOptions): string;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { type PipelineDefinition, type PipelineModuleSourceOptions, createPipelineModuleSource };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/pipelines/source.ts
|
|
2
|
+
function isStringArray(value) {
|
|
3
|
+
return Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
function isPipelineDefinition(value) {
|
|
6
|
+
return typeof value === "object" && value !== null && "id" in value;
|
|
7
|
+
}
|
|
8
|
+
function buildDefinition(id, overrides) {
|
|
9
|
+
const def = {
|
|
10
|
+
_type: "pipeline-definition",
|
|
11
|
+
id,
|
|
12
|
+
versions: ["16.0.0"],
|
|
13
|
+
inputs: [],
|
|
14
|
+
routes: [],
|
|
15
|
+
...overrides
|
|
16
|
+
};
|
|
17
|
+
return JSON.stringify(def).replace(/"(\w+)":/g, "$1:");
|
|
18
|
+
}
|
|
19
|
+
function buildNamedExports(named, definitions) {
|
|
20
|
+
if (isStringArray(named)) return named.map((name) => `export const ${name} = ${buildDefinition(name, definitions[name])};`).join("\n\n");
|
|
21
|
+
return Object.entries(named).map(([name, value]) => {
|
|
22
|
+
return `export const ${name} = ${isPipelineDefinition(value) ? buildDefinition(value.id, value) : value};`;
|
|
23
|
+
}).join("\n\n");
|
|
24
|
+
}
|
|
25
|
+
function createPipelineModuleSource(options = {}) {
|
|
26
|
+
const { named = [], definitions = {}, extraExports, prelude } = options;
|
|
27
|
+
return [
|
|
28
|
+
prelude,
|
|
29
|
+
buildNamedExports(named, definitions),
|
|
30
|
+
extraExports
|
|
31
|
+
].filter(Boolean).join("\n\n");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { createPipelineModuleSource };
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ucdjs/test-utils",
|
|
3
|
+
"version": "1.0.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/test-utils"
|
|
16
|
+
},
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/ucdjs/ucd/issues"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": "./dist/index.mjs",
|
|
22
|
+
"./fs-bridges": "./dist/fs-bridges/index.mjs",
|
|
23
|
+
"./matchers/types": "./dist/matchers/types.mjs",
|
|
24
|
+
"./matchers/vitest-setup": "./dist/matchers/vitest-setup.mjs",
|
|
25
|
+
"./mock-store": "./dist/mock-store.mjs",
|
|
26
|
+
"./msw": "./dist/msw.mjs",
|
|
27
|
+
"./msw/vitest-setup": "./dist/msw/vitest-setup.mjs",
|
|
28
|
+
"./pipelines": "./dist/pipelines.mjs",
|
|
29
|
+
"./package.json": "./package.json"
|
|
30
|
+
},
|
|
31
|
+
"types": "./dist/index.d.mts",
|
|
32
|
+
"files": [
|
|
33
|
+
"dist"
|
|
34
|
+
],
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=22.18"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"vitest-testdirs": "4.4.2",
|
|
40
|
+
"@ucdjs/ucd-store": "1.0.1-beta.1"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@luxass/msw-utils": "0.6.0",
|
|
44
|
+
"@luxass/utils": "2.7.3",
|
|
45
|
+
"@unicode-utils/core": "0.12.0-beta.19",
|
|
46
|
+
"msw": "2.12.10",
|
|
47
|
+
"zod": "4.3.6",
|
|
48
|
+
"@ucdjs-internal/shared": "0.1.1-beta.1",
|
|
49
|
+
"@ucdjs/fs-bridge": "0.1.1-beta.1",
|
|
50
|
+
"@ucdjs/schemas": "0.1.1-beta.1",
|
|
51
|
+
"@ucdjs/env": "0.1.1-beta.1"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@luxass/eslint-config": "7.2.0",
|
|
55
|
+
"@vitest/expect": "4.1.0-beta.1",
|
|
56
|
+
"eslint": "10.0.0",
|
|
57
|
+
"openapi-typescript": "7.13.0",
|
|
58
|
+
"publint": "0.3.17",
|
|
59
|
+
"tsdown": "0.20.3",
|
|
60
|
+
"tsx": "4.21.0",
|
|
61
|
+
"typescript": "5.9.3",
|
|
62
|
+
"vitest-testdirs": "4.4.2",
|
|
63
|
+
"@ucdjs-tooling/tsdown-config": "1.0.0",
|
|
64
|
+
"@ucdjs/ucd-store": "1.0.1-beta.1",
|
|
65
|
+
"@ucdjs-tooling/tsconfig": "1.0.0"
|
|
66
|
+
},
|
|
67
|
+
"publishConfig": {
|
|
68
|
+
"access": "public"
|
|
69
|
+
},
|
|
70
|
+
"scripts": {
|
|
71
|
+
"build": "tsdown --tsconfig=./tsconfig.build.json",
|
|
72
|
+
"dev": "tsdown --watch",
|
|
73
|
+
"clean": "git clean -xdf dist node_modules",
|
|
74
|
+
"lint": "eslint .",
|
|
75
|
+
"typecheck": "tsc --noEmit -p tsconfig.build.json",
|
|
76
|
+
"generate:client": "openapi-typescript ../../ucd-generated/api/openapi.json -o ./src/.generated/api.d.ts",
|
|
77
|
+
"generate:client:local": "openapi-typescript http://localhost:8787/openapi.json -o ./src/.generated/api.d.ts"
|
|
78
|
+
}
|
|
79
|
+
}
|