feat: Reinitialize frontend with SvelteKit and TypeScript

- Delete old Vite+Svelte frontend
- Initialize new SvelteKit project with TypeScript
- Configure Tailwind CSS v4 + DaisyUI
- Implement JWT authentication with auto-refresh
- Create login page with form validation (Zod)
- Add protected route guards
- Update Docker configuration for single-stage build
- Add E2E tests with Playwright (6/11 passing)
- Fix Svelte 5 reactivity with $state() runes

Known issues:
- 5 E2E tests failing (timing/async issues)
- Token refresh implementation needs debugging
- Validation error display timing
This commit is contained in:
2026-02-17 16:19:59 -05:00
parent 54df6018f5
commit de2d83092e
28274 changed files with 3816354 additions and 90 deletions

21
frontend/node_modules/@vitest/mocker/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021-Present Vitest Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

5
frontend/node_modules/@vitest/mocker/README.md generated vendored Normal file
View File

@@ -0,0 +1,5 @@
# @vitest/mocker
Vitest's module mocker implementation.
[GitHub](https://github.com/vitest-dev/vitest/blob/main/packages/mocker/) | [Documentation](https://github.com/vitest-dev/vitest/blob/main/packages/mocker/EXPORTS.md)

View File

@@ -0,0 +1,2 @@
export { };

View File

@@ -0,0 +1,9 @@
import { M as ModuleMockerServerInterceptor } from './chunk-interceptor-native.js';
import { registerModuleMocker } from './register.js';
import './chunk-mocker.js';
import './index.js';
import './chunk-registry.js';
import './chunk-pathe.M-eThtNZ.js';
import '@vitest/spy';
registerModuleMocker(() => new ModuleMockerServerInterceptor());

53
frontend/node_modules/@vitest/mocker/dist/browser.d.ts generated vendored Normal file
View File

@@ -0,0 +1,53 @@
import { M as ModuleMockerInterceptor } from './mocker.d-Ce9_ySj5.js';
export { C as CompilerHintsOptions, b as ModuleMocker, a as ModuleMockerCompilerHints, d as ModuleMockerConfig, e as ModuleMockerRPC, R as ResolveIdResult, f as ResolveMockResult, c as createCompilerHints } from './mocker.d-Ce9_ySj5.js';
import { StartOptions, SetupWorker } from 'msw/browser';
import { c as MockerRegistry, g as MockedModule } from './registry.d-D765pazg.js';
import '@vitest/spy';
import './types.d-D_aRZRdy.js';
interface ModuleMockerMSWInterceptorOptions {
/**
* The identifier to access the globalThis object in the worker.
* This will be injected into the script as is, so make sure it's a valid JS expression.
* @example
* ```js
* // globalThisAccessor: '__my_variable__' produces:
* globalThis[__my_variable__]
* // globalThisAccessor: 'Symbol.for('secret:mocks')' produces:
* globalThis[Symbol.for('secret:mocks')]
* // globalThisAccessor: '"__vitest_mocker__"' (notice quotes) produces:
* globalThis["__vitest_mocker__"]
* ```
* @default `"__vitest_mocker__"`
*/
globalThisAccessor?: string;
/**
* Options passed down to `msw.setupWorker().start(options)`
*/
mswOptions?: StartOptions;
/**
* A pre-configured `msw.setupWorker` instance.
*/
mswWorker?: SetupWorker;
}
declare class ModuleMockerMSWInterceptor implements ModuleMockerInterceptor {
private readonly options;
protected readonly mocks: MockerRegistry;
private startPromise;
private worker;
constructor(options?: ModuleMockerMSWInterceptorOptions);
register(module: MockedModule): Promise<void>;
delete(url: string): Promise<void>;
invalidate(): Promise<void>;
private resolveManualMock;
protected init(): Promise<SetupWorker>;
}
declare class ModuleMockerServerInterceptor implements ModuleMockerInterceptor {
register(module: MockedModule): Promise<void>;
delete(id: string): Promise<void>;
invalidate(): Promise<void>;
}
export { ModuleMockerInterceptor, ModuleMockerMSWInterceptor, ModuleMockerServerInterceptor };
export type { ModuleMockerMSWInterceptorOptions };

91
frontend/node_modules/@vitest/mocker/dist/browser.js generated vendored Normal file
View File

@@ -0,0 +1,91 @@
export { M as ModuleMocker, c as createCompilerHints } from './chunk-mocker.js';
import { M as MockerRegistry } from './chunk-registry.js';
import { c as createManualModuleSource, a as cleanUrl } from './chunk-utils.js';
export { M as ModuleMockerServerInterceptor } from './chunk-interceptor-native.js';
import './index.js';
import './chunk-pathe.M-eThtNZ.js';
class ModuleMockerMSWInterceptor {
mocks = new MockerRegistry();
startPromise;
worker;
constructor(options = {}) {
this.options = options;
if (!options.globalThisAccessor) {
options.globalThisAccessor = "\"__vitest_mocker__\"";
}
}
async register(module) {
await this.init();
this.mocks.add(module);
}
async delete(url) {
await this.init();
this.mocks.delete(url);
}
async invalidate() {
this.mocks.clear();
}
async resolveManualMock(mock) {
const exports = Object.keys(await mock.resolve());
const text = createManualModuleSource(mock.url, exports, this.options.globalThisAccessor);
return new Response(text, { headers: { "Content-Type": "application/javascript" } });
}
async init() {
if (this.worker) {
return this.worker;
}
if (this.startPromise) {
return this.startPromise;
}
const worker = this.options.mswWorker;
this.startPromise = Promise.all([worker ? { setupWorker(handler) {
worker.use(handler);
return worker;
} } : import('msw/browser'), import('msw/core/http')]).then(([{ setupWorker }, { http }]) => {
const worker = setupWorker(http.get(/.+/, async ({ request }) => {
const path = cleanQuery(request.url.slice(location.origin.length));
if (!this.mocks.has(path)) {
return passthrough();
}
const mock = this.mocks.get(path);
switch (mock.type) {
case "manual": return this.resolveManualMock(mock);
case "automock":
case "autospy": return Response.redirect(injectQuery(path, `mock=${mock.type}`));
case "redirect": return Response.redirect(mock.redirect);
default: throw new Error(`Unknown mock type: ${mock.type}`);
}
}));
return worker.start(this.options.mswOptions).then(() => worker);
}).finally(() => {
this.worker = worker;
this.startPromise = undefined;
});
return await this.startPromise;
}
}
const trailingSeparatorRE = /[?&]$/;
const timestampRE = /\bt=\d{13}&?\b/;
const versionRE = /\bv=\w{8}&?\b/;
function cleanQuery(url) {
return url.replace(timestampRE, "").replace(versionRE, "").replace(trailingSeparatorRE, "");
}
function passthrough() {
return new Response(null, {
status: 302,
statusText: "Passthrough",
headers: { "x-msw-intention": "passthrough" }
});
}
const replacePercentageRE = /%/g;
function injectQuery(url, queryToInject) {
// encode percents for consistent behavior with pathToFileURL
// see #2614 for details
const resolvedUrl = new URL(url.replace(replacePercentageRE, "%25"), location.href);
const { search, hash } = resolvedUrl;
const pathname = cleanUrl(url);
return `${pathname}?${queryToInject}${search ? `&${search.slice(1)}` : ""}${hash ?? ""}`;
}
export { ModuleMockerMSWInterceptor };

View File

@@ -0,0 +1,15 @@
import { r as rpc } from './chunk-mocker.js';
class ModuleMockerServerInterceptor {
async register(module) {
await rpc("vitest:interceptor:register", module.toJSON());
}
async delete(id) {
await rpc("vitest:interceptor:delete", id);
}
async invalidate() {
await rpc("vitest:interceptor:invalidate");
}
}
export { ModuleMockerServerInterceptor as M };

1602
frontend/node_modules/@vitest/mocker/dist/chunk-mocker.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,174 @@
const _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//;
function normalizeWindowsPath(input = "") {
if (!input) {
return input;
}
return input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase());
}
const _UNC_REGEX = /^[/\\]{2}/;
const _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/;
const _DRIVE_LETTER_RE = /^[A-Za-z]:$/;
const _EXTNAME_RE = /.(\.[^./]+|\.)$/;
const normalize = function(path) {
if (path.length === 0) {
return ".";
}
path = normalizeWindowsPath(path);
const isUNCPath = path.match(_UNC_REGEX);
const isPathAbsolute = isAbsolute(path);
const trailingSeparator = path[path.length - 1] === "/";
path = normalizeString(path, !isPathAbsolute);
if (path.length === 0) {
if (isPathAbsolute) {
return "/";
}
return trailingSeparator ? "./" : ".";
}
if (trailingSeparator) {
path += "/";
}
if (_DRIVE_LETTER_RE.test(path)) {
path += "/";
}
if (isUNCPath) {
if (!isPathAbsolute) {
return `//./${path}`;
}
return `//${path}`;
}
return isPathAbsolute && !isAbsolute(path) ? `/${path}` : path;
};
const join = function(...segments) {
let path = "";
for (const seg of segments) {
if (!seg) {
continue;
}
if (path.length > 0) {
const pathTrailing = path[path.length - 1] === "/";
const segLeading = seg[0] === "/";
const both = pathTrailing && segLeading;
if (both) {
path += seg.slice(1);
} else {
path += pathTrailing || segLeading ? seg : `/${seg}`;
}
} else {
path += seg;
}
}
return normalize(path);
};
function cwd() {
if (typeof process !== "undefined" && typeof process.cwd === "function") {
return process.cwd().replace(/\\/g, "/");
}
return "/";
}
const resolve = function(...arguments_) {
arguments_ = arguments_.map((argument) => normalizeWindowsPath(argument));
let resolvedPath = "";
let resolvedAbsolute = false;
for (let index = arguments_.length - 1; index >= -1 && !resolvedAbsolute; index--) {
const path = index >= 0 ? arguments_[index] : cwd();
if (!path || path.length === 0) {
continue;
}
resolvedPath = `${path}/${resolvedPath}`;
resolvedAbsolute = isAbsolute(path);
}
resolvedPath = normalizeString(resolvedPath, !resolvedAbsolute);
if (resolvedAbsolute && !isAbsolute(resolvedPath)) {
return `/${resolvedPath}`;
}
return resolvedPath.length > 0 ? resolvedPath : ".";
};
function normalizeString(path, allowAboveRoot) {
let res = "";
let lastSegmentLength = 0;
let lastSlash = -1;
let dots = 0;
let char = null;
for (let index = 0; index <= path.length; ++index) {
if (index < path.length) {
char = path[index];
} else if (char === "/") {
break;
} else {
char = "/";
}
if (char === "/") {
if (lastSlash === index - 1 || dots === 1) ; else if (dots === 2) {
if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") {
if (res.length > 2) {
const lastSlashIndex = res.lastIndexOf("/");
if (lastSlashIndex === -1) {
res = "";
lastSegmentLength = 0;
} else {
res = res.slice(0, lastSlashIndex);
lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
}
lastSlash = index;
dots = 0;
continue;
} else if (res.length > 0) {
res = "";
lastSegmentLength = 0;
lastSlash = index;
dots = 0;
continue;
}
}
if (allowAboveRoot) {
res += res.length > 0 ? "/.." : "..";
lastSegmentLength = 2;
}
} else {
if (res.length > 0) {
res += `/${path.slice(lastSlash + 1, index)}`;
} else {
res = path.slice(lastSlash + 1, index);
}
lastSegmentLength = index - lastSlash - 1;
}
lastSlash = index;
dots = 0;
} else if (char === "." && dots !== -1) {
++dots;
} else {
dots = -1;
}
}
return res;
}
const isAbsolute = function(p) {
return _IS_ABSOLUTE_RE.test(p);
};
const extname = function(p) {
if (p === "..") return "";
const match = _EXTNAME_RE.exec(normalizeWindowsPath(p));
return match && match[1] || "";
};
const dirname = function(p) {
const segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1);
if (segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0])) {
segments[0] += "/";
}
return segments.join("/") || (isAbsolute(p) ? "/" : ".");
};
const basename = function(p, extension) {
const segments = normalizeWindowsPath(p).split("/");
let lastSegment = "";
for (let i = segments.length - 1; i >= 0; i--) {
const val = segments[i];
if (val) {
lastSegment = val;
break;
}
}
return extension && lastSegment.endsWith(extension) ? lastSegment.slice(0, -extension.length) : lastSegment;
};
export { basename as b, dirname as d, extname as e, isAbsolute as i, join as j, resolve as r };

View File

@@ -0,0 +1,182 @@
class MockerRegistry {
registryByUrl = new Map();
registryById = new Map();
clear() {
this.registryByUrl.clear();
this.registryById.clear();
}
keys() {
return this.registryByUrl.keys();
}
add(mock) {
this.registryByUrl.set(mock.url, mock);
this.registryById.set(mock.id, mock);
}
register(typeOrEvent, raw, id, url, factoryOrRedirect) {
const type = typeof typeOrEvent === "object" ? typeOrEvent.type : typeOrEvent;
if (typeof typeOrEvent === "object") {
const event = typeOrEvent;
if (event instanceof AutomockedModule || event instanceof AutospiedModule || event instanceof ManualMockedModule || event instanceof RedirectedModule) {
throw new TypeError(`[vitest] Cannot register a mock that is already defined. ` + `Expected a JSON representation from \`MockedModule.toJSON\`, instead got "${event.type}". ` + `Use "registry.add()" to update a mock instead.`);
}
if (event.type === "automock") {
const module = AutomockedModule.fromJSON(event);
this.add(module);
return module;
} else if (event.type === "autospy") {
const module = AutospiedModule.fromJSON(event);
this.add(module);
return module;
} else if (event.type === "redirect") {
const module = RedirectedModule.fromJSON(event);
this.add(module);
return module;
} else if (event.type === "manual") {
throw new Error(`Cannot set serialized manual mock. Define a factory function manually with \`ManualMockedModule.fromJSON()\`.`);
} else {
throw new Error(`Unknown mock type: ${event.type}`);
}
}
if (typeof raw !== "string") {
throw new TypeError("[vitest] Mocks require a raw string.");
}
if (typeof url !== "string") {
throw new TypeError("[vitest] Mocks require a url string.");
}
if (typeof id !== "string") {
throw new TypeError("[vitest] Mocks require an id string.");
}
if (type === "manual") {
if (typeof factoryOrRedirect !== "function") {
throw new TypeError("[vitest] Manual mocks require a factory function.");
}
const mock = new ManualMockedModule(raw, id, url, factoryOrRedirect);
this.add(mock);
return mock;
} else if (type === "automock" || type === "autospy") {
const mock = type === "automock" ? new AutomockedModule(raw, id, url) : new AutospiedModule(raw, id, url);
this.add(mock);
return mock;
} else if (type === "redirect") {
if (typeof factoryOrRedirect !== "string") {
throw new TypeError("[vitest] Redirect mocks require a redirect string.");
}
const mock = new RedirectedModule(raw, id, url, factoryOrRedirect);
this.add(mock);
return mock;
} else {
throw new Error(`[vitest] Unknown mock type: ${type}`);
}
}
delete(id) {
this.registryByUrl.delete(id);
}
get(id) {
return this.registryByUrl.get(id);
}
getById(id) {
return this.registryById.get(id);
}
has(id) {
return this.registryByUrl.has(id);
}
}
class AutomockedModule {
type = "automock";
constructor(raw, id, url) {
this.raw = raw;
this.id = id;
this.url = url;
}
static fromJSON(data) {
return new AutospiedModule(data.raw, data.id, data.url);
}
toJSON() {
return {
type: this.type,
url: this.url,
raw: this.raw,
id: this.id
};
}
}
class AutospiedModule {
type = "autospy";
constructor(raw, id, url) {
this.raw = raw;
this.id = id;
this.url = url;
}
static fromJSON(data) {
return new AutospiedModule(data.raw, data.id, data.url);
}
toJSON() {
return {
type: this.type,
url: this.url,
id: this.id,
raw: this.raw
};
}
}
class RedirectedModule {
type = "redirect";
constructor(raw, id, url, redirect) {
this.raw = raw;
this.id = id;
this.url = url;
this.redirect = redirect;
}
static fromJSON(data) {
return new RedirectedModule(data.raw, data.id, data.url, data.redirect);
}
toJSON() {
return {
type: this.type,
url: this.url,
raw: this.raw,
id: this.id,
redirect: this.redirect
};
}
}
class ManualMockedModule {
cache;
type = "manual";
constructor(raw, id, url, factory) {
this.raw = raw;
this.id = id;
this.url = url;
this.factory = factory;
}
async resolve() {
if (this.cache) {
return this.cache;
}
let exports;
try {
exports = await this.factory();
} catch (err) {
const vitestError = new Error("[vitest] There was an error when mocking a module. " + "If you are using \"vi.mock\" factory, make sure there are no top level variables inside, since this call is hoisted to top of the file. " + "Read more: https://vitest.dev/api/vi.html#vi-mock");
vitestError.cause = err;
throw vitestError;
}
if (exports === null || typeof exports !== "object" || Array.isArray(exports)) {
throw new TypeError(`[vitest] vi.mock("${this.raw}", factory?: () => unknown) is not returning an object. Did you mean to return an object with a "default" key?`);
}
return this.cache = exports;
}
static fromJSON(data, factory) {
return new ManualMockedModule(data.raw, data.id, data.url, factory);
}
toJSON() {
return {
type: this.type,
url: this.url,
id: this.id,
raw: this.raw
};
}
}
export { AutomockedModule as A, MockerRegistry as M, RedirectedModule as R, ManualMockedModule as a, AutospiedModule as b };

View File

@@ -0,0 +1,16 @@
const postfixRE = /[?#].*$/;
function cleanUrl(url) {
return url.replace(postfixRE, "");
}
function createManualModuleSource(moduleUrl, exports, globalAccessor = "\"__vitest_mocker__\"") {
const source = `const module = globalThis[${globalAccessor}].getFactoryModule("${moduleUrl}");`;
const keys = exports.map((name) => {
if (name === "default") {
return `export default module["default"];`;
}
return `export const ${name} = module["${name}"];`;
}).join("\n");
return `${source}\n${keys}`;
}
export { cleanUrl as a, createManualModuleSource as c };

21
frontend/node_modules/@vitest/mocker/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,21 @@
import { M as MockedModuleType } from './registry.d-D765pazg.js';
export { A as AutomockedModule, d as AutomockedModuleSerialized, a as AutospiedModule, e as AutospiedModuleSerialized, b as ManualMockedModule, f as ManualMockedModuleSerialized, g as MockedModule, h as MockedModuleSerialized, c as MockerRegistry, R as RedirectedModule, i as RedirectedModuleSerialized } from './registry.d-D765pazg.js';
export { M as ModuleMockFactory, a as ModuleMockFactoryWithHelper, b as ModuleMockOptions } from './types.d-D_aRZRdy.js';
type Key = string | symbol;
interface MockObjectOptions {
type: MockedModuleType;
globalConstructors: GlobalConstructors;
spyOn: (obj: any, prop: Key) => any;
}
declare function mockObject(options: MockObjectOptions, object: Record<Key, any>, mockExports?: Record<Key, any>): Record<Key, any>;
interface GlobalConstructors {
Object: ObjectConstructor;
Function: FunctionConstructor;
RegExp: RegExpConstructor;
Array: ArrayConstructor;
Map: MapConstructor;
}
export { MockedModuleType, mockObject };
export type { GlobalConstructors, MockObjectOptions };

174
frontend/node_modules/@vitest/mocker/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,174 @@
export { A as AutomockedModule, b as AutospiedModule, a as ManualMockedModule, M as MockerRegistry, R as RedirectedModule } from './chunk-registry.js';
function mockObject(options, object, mockExports = {}) {
const finalizers = new Array();
const refs = new RefTracker();
const define = (container, key, value) => {
try {
container[key] = value;
return true;
} catch {
return false;
}
};
const mockPropertiesOf = (container, newContainer) => {
const containerType = getType(container);
const isModule = containerType === "Module" || !!container.__esModule;
for (const { key: property, descriptor } of getAllMockableProperties(container, isModule, options.globalConstructors)) {
// Modules define their exports as getters. We want to process those.
if (!isModule && descriptor.get) {
try {
Object.defineProperty(newContainer, property, descriptor);
} catch {}
continue;
}
// Skip special read-only props, we don't want to mess with those.
if (isSpecialProp(property, containerType)) {
continue;
}
const value = container[property];
// Special handling of references we've seen before to prevent infinite
// recursion in circular objects.
const refId = refs.getId(value);
if (refId !== undefined) {
finalizers.push(() => define(newContainer, property, refs.getMockedValue(refId)));
continue;
}
const type = getType(value);
if (Array.isArray(value)) {
define(newContainer, property, []);
continue;
}
const isFunction = type.includes("Function") && typeof value === "function";
if ((!isFunction || value._isMockFunction) && type !== "Object" && type !== "Module") {
define(newContainer, property, value);
continue;
}
// Sometimes this assignment fails for some unknown reason. If it does,
// just move along.
if (!define(newContainer, property, isFunction ? value : {})) {
continue;
}
if (isFunction) {
if (!options.spyOn) {
throw new Error("[@vitest/mocker] `spyOn` is not defined. This is a Vitest error. Please open a new issue with reproduction.");
}
const spyOn = options.spyOn;
function mockFunction() {
// detect constructor call and mock each instance's methods
// so that mock states between prototype/instances don't affect each other
// (jest reference https://github.com/jestjs/jest/blob/2c3d2409879952157433de215ae0eee5188a4384/packages/jest-mock/src/index.ts#L678-L691)
if (this instanceof newContainer[property]) {
for (const { key, descriptor } of getAllMockableProperties(this, false, options.globalConstructors)) {
// skip getter since it's not mocked on prototype as well
if (descriptor.get) {
continue;
}
const value = this[key];
const type = getType(value);
const isFunction = type.includes("Function") && typeof value === "function";
if (isFunction) {
// mock and delegate calls to original prototype method, which should be also mocked already
const original = this[key];
const mock = spyOn(this, key).mockImplementation(original);
const origMockReset = mock.mockReset;
mock.mockRestore = mock.mockReset = () => {
origMockReset.call(mock);
mock.mockImplementation(original);
return mock;
};
}
}
}
}
const mock = spyOn(newContainer, property);
if (options.type === "automock") {
mock.mockImplementation(mockFunction);
const origMockReset = mock.mockReset;
mock.mockRestore = mock.mockReset = () => {
origMockReset.call(mock);
mock.mockImplementation(mockFunction);
return mock;
};
}
// tinyspy retains length, but jest doesn't.
Object.defineProperty(newContainer[property], "length", { value: 0 });
}
refs.track(value, newContainer[property]);
mockPropertiesOf(value, newContainer[property]);
}
};
const mockedObject = mockExports;
mockPropertiesOf(object, mockedObject);
// Plug together refs
for (const finalizer of finalizers) {
finalizer();
}
return mockedObject;
}
class RefTracker {
idMap = new Map();
mockedValueMap = new Map();
getId(value) {
return this.idMap.get(value);
}
getMockedValue(id) {
return this.mockedValueMap.get(id);
}
track(originalValue, mockedValue) {
const newId = this.idMap.size;
this.idMap.set(originalValue, newId);
this.mockedValueMap.set(newId, mockedValue);
return newId;
}
}
function getType(value) {
return Object.prototype.toString.apply(value).slice(8, -1);
}
function isSpecialProp(prop, parentType) {
return parentType.includes("Function") && typeof prop === "string" && [
"arguments",
"callee",
"caller",
"length",
"name"
].includes(prop);
}
function getAllMockableProperties(obj, isModule, constructors) {
const { Map, Object, Function, RegExp, Array } = constructors;
const allProps = new Map();
let curr = obj;
do {
// we don't need properties from these
if (curr === Object.prototype || curr === Function.prototype || curr === RegExp.prototype) {
break;
}
collectOwnProperties(curr, (key) => {
const descriptor = Object.getOwnPropertyDescriptor(curr, key);
if (descriptor) {
allProps.set(key, {
key,
descriptor
});
}
});
} while (curr = Object.getPrototypeOf(curr));
// default is not specified in ownKeys, if module is interoped
if (isModule && !allProps.has("default") && "default" in obj) {
const descriptor = Object.getOwnPropertyDescriptor(obj, "default");
if (descriptor) {
allProps.set("default", {
key: "default",
descriptor
});
}
}
return Array.from(allProps.values());
}
function collectOwnProperties(obj, collector) {
const collect = typeof collector === "function" ? collector : (key) => collector.add(key);
Object.getOwnPropertyNames(obj).forEach(collect);
Object.getOwnPropertySymbols(obj).forEach(collect);
}
export { mockObject };

View File

@@ -0,0 +1,83 @@
import { MaybeMockedDeep } from '@vitest/spy';
import { b as ModuleMockOptions, a as ModuleMockFactoryWithHelper } from './types.d-D_aRZRdy.js';
import { g as MockedModule, c as MockerRegistry, M as MockedModuleType } from './registry.d-D765pazg.js';
interface CompilerHintsOptions {
/**
* This is the key used to access the globalThis object in the worker.
* Unlike `globalThisAccessor` in other APIs, this is not injected into the script.
* ```ts
* // globalThisKey: '__my_variable__' produces:
* globalThis['__my_variable__']
* // globalThisKey: '"__my_variable__"' produces:
* globalThis['"__my_variable__"'] // notice double quotes
* ```
* @default '__vitest_mocker__'
*/
globalThisKey?: string;
}
interface ModuleMockerCompilerHints {
hoisted: <T>(factory: () => T) => T;
mock: (path: string | Promise<unknown>, factory?: ModuleMockOptions | ModuleMockFactoryWithHelper) => void;
unmock: (path: string | Promise<unknown>) => void;
doMock: (path: string | Promise<unknown>, factory?: ModuleMockOptions | ModuleMockFactoryWithHelper) => void;
doUnmock: (path: string | Promise<unknown>) => void;
importActual: <T>(path: string) => Promise<T>;
importMock: <T>(path: string) => Promise<MaybeMockedDeep<T>>;
}
declare function createCompilerHints(options?: CompilerHintsOptions): ModuleMockerCompilerHints;
interface ModuleMockerInterceptor {
register: (module: MockedModule) => Promise<void>;
delete: (url: string) => Promise<void>;
invalidate: () => Promise<void>;
}
declare class ModuleMocker {
private interceptor;
private rpc;
private spyOn;
private config;
protected registry: MockerRegistry;
private queue;
private mockedIds;
constructor(interceptor: ModuleMockerInterceptor, rpc: ModuleMockerRPC, spyOn: (obj: any, method: string | symbol) => any, config: ModuleMockerConfig);
prepare(): Promise<void>;
resolveFactoryModule(id: string): Promise<Record<string | symbol, any>>;
getFactoryModule(id: string): any;
invalidate(): Promise<void>;
importActual<T>(id: string, importer: string): Promise<T>;
importMock<T>(rawId: string, importer: string): Promise<T>;
mockObject(object: Record<string | symbol, any>, moduleType?: MockedModuleType): Record<string | symbol, any>;
queueMock(rawId: string, importer: string, factoryOrOptions?: ModuleMockOptions | (() => any)): void;
queueUnmock(id: string, importer: string): void;
// We need to await mock registration before importing the actual module
// In case there is a mocked module in the import chain
wrapDynamicImport<T>(moduleFactory: () => Promise<T>): Promise<T>;
private resolveMockPath;
}
interface ResolveIdResult {
id: string;
url: string;
optimized: boolean;
}
interface ResolveMockResult {
mockType: MockedModuleType;
resolvedId: string;
resolvedUrl: string;
redirectUrl?: string | null;
needsInterop?: boolean;
}
interface ModuleMockerRPC {
invalidate: (ids: string[]) => Promise<void>;
resolveId: (id: string, importer: string) => Promise<ResolveIdResult | null>;
resolveMock: (id: string, importer: string, options: {
mock: "spy" | "factory" | "auto"
}) => Promise<ResolveMockResult>;
}
interface ModuleMockerConfig {
root: string;
}
export { ModuleMocker as b, createCompilerHints as c };
export type { CompilerHintsOptions as C, ModuleMockerInterceptor as M, ResolveIdResult as R, ModuleMockerCompilerHints as a, ModuleMockerConfig as d, ModuleMockerRPC as e, ResolveMockResult as f };

821
frontend/node_modules/@vitest/mocker/dist/node.d.ts generated vendored Normal file
View File

@@ -0,0 +1,821 @@
import { Plugin, Rollup, ViteDevServer } from 'vite';
import MagicString, { SourceMap } from 'magic-string';
import { c as MockerRegistry } from './registry.d-D765pazg.js';
export { findMockRedirect } from './redirect.js';
declare function createManualModuleSource(moduleUrl: string, exports: string[], globalAccessor?: string): string;
interface AutomockPluginOptions {
/**
* @default "__vitest_mocker__"
*/
globalThisAccessor?: string;
}
declare function automockPlugin(options?: AutomockPluginOptions): Plugin;
// TODO: better source map replacement
declare function automockModule(code: string, mockType: "automock" | "autospy", parse: (code: string) => any, options?: AutomockPluginOptions): MagicString;
interface DynamicImportPluginOptions {
/**
* @default `"__vitest_mocker__"`
*/
globalThisAccessor?: string;
filter?: (id: string) => boolean;
}
declare function dynamicImportPlugin(options?: DynamicImportPluginOptions): Plugin;
// This definition file follows a somewhat unusual format. ESTree allows
// runtime type checks based on the `type` parameter. In order to explain this
// to typescript we want to use discriminated union types:
// https://github.com/Microsoft/TypeScript/pull/9163
//
// For ESTree this is a bit tricky because the high level interfaces like
// Node or Function are pulling double duty. We want to pass common fields down
// to the interfaces that extend them (like Identifier or
// ArrowFunctionExpression), but you can't extend a type union or enforce
// common fields on them. So we've split the high level interfaces into two
// types, a base type which passes down inherited fields, and a type union of
// all types which extend the base type. Only the type union is exported, and
// the union is how other types refer to the collection of inheriting types.
//
// This makes the definitions file here somewhat more difficult to maintain,
// but it has the notable advantage of making ESTree much easier to use as
// an end user.
interface BaseNodeWithoutComments {
// Every leaf interface that extends BaseNode must specify a type property.
// The type property should be a string literal. For example, Identifier
// has: `type: "Identifier"`
type: string;
loc?: SourceLocation | null | undefined;
range?: [number, number] | undefined;
}
interface BaseNode extends BaseNodeWithoutComments {
leadingComments?: Comment[] | undefined;
trailingComments?: Comment[] | undefined;
}
interface NodeMap {
AssignmentProperty: AssignmentProperty;
CatchClause: CatchClause;
Class: Class;
ClassBody: ClassBody;
Expression: Expression;
Function: Function;
Identifier: Identifier;
Literal: Literal;
MethodDefinition: MethodDefinition;
ModuleDeclaration: ModuleDeclaration;
ModuleSpecifier: ModuleSpecifier;
Pattern: Pattern;
PrivateIdentifier: PrivateIdentifier;
Program: Program;
Property: Property;
PropertyDefinition: PropertyDefinition;
SpreadElement: SpreadElement;
Statement: Statement;
Super: Super;
SwitchCase: SwitchCase;
TemplateElement: TemplateElement;
VariableDeclarator: VariableDeclarator;
}
type Node$1 = NodeMap[keyof NodeMap];
interface Comment extends BaseNodeWithoutComments {
type: "Line" | "Block";
value: string;
}
interface SourceLocation {
source?: string | null | undefined;
start: Position;
end: Position;
}
interface Position {
/** >= 1 */
line: number;
/** >= 0 */
column: number;
}
interface Program extends BaseNode {
type: "Program";
sourceType: "script" | "module";
body: Array<Directive | Statement | ModuleDeclaration>;
comments?: Comment[] | undefined;
}
interface Directive extends BaseNode {
type: "ExpressionStatement";
expression: Literal;
directive: string;
}
interface BaseFunction extends BaseNode {
params: Pattern[];
generator?: boolean | undefined;
async?: boolean | undefined;
// The body is either BlockStatement or Expression because arrow functions
// can have a body that's either. FunctionDeclarations and
// FunctionExpressions have only BlockStatement bodies.
body: BlockStatement | Expression;
}
type Function = FunctionDeclaration | FunctionExpression | ArrowFunctionExpression;
type Statement =
| ExpressionStatement
| BlockStatement
| StaticBlock
| EmptyStatement
| DebuggerStatement
| WithStatement
| ReturnStatement
| LabeledStatement
| BreakStatement
| ContinueStatement
| IfStatement
| SwitchStatement
| ThrowStatement
| TryStatement
| WhileStatement
| DoWhileStatement
| ForStatement
| ForInStatement
| ForOfStatement
| Declaration;
interface BaseStatement extends BaseNode {}
interface EmptyStatement extends BaseStatement {
type: "EmptyStatement";
}
interface BlockStatement extends BaseStatement {
type: "BlockStatement";
body: Statement[];
innerComments?: Comment[] | undefined;
}
interface StaticBlock extends Omit<BlockStatement, "type"> {
type: "StaticBlock";
}
interface ExpressionStatement extends BaseStatement {
type: "ExpressionStatement";
expression: Expression;
}
interface IfStatement extends BaseStatement {
type: "IfStatement";
test: Expression;
consequent: Statement;
alternate?: Statement | null | undefined;
}
interface LabeledStatement extends BaseStatement {
type: "LabeledStatement";
label: Identifier;
body: Statement;
}
interface BreakStatement extends BaseStatement {
type: "BreakStatement";
label?: Identifier | null | undefined;
}
interface ContinueStatement extends BaseStatement {
type: "ContinueStatement";
label?: Identifier | null | undefined;
}
interface WithStatement extends BaseStatement {
type: "WithStatement";
object: Expression;
body: Statement;
}
interface SwitchStatement extends BaseStatement {
type: "SwitchStatement";
discriminant: Expression;
cases: SwitchCase[];
}
interface ReturnStatement extends BaseStatement {
type: "ReturnStatement";
argument?: Expression | null | undefined;
}
interface ThrowStatement extends BaseStatement {
type: "ThrowStatement";
argument: Expression;
}
interface TryStatement extends BaseStatement {
type: "TryStatement";
block: BlockStatement;
handler?: CatchClause | null | undefined;
finalizer?: BlockStatement | null | undefined;
}
interface WhileStatement extends BaseStatement {
type: "WhileStatement";
test: Expression;
body: Statement;
}
interface DoWhileStatement extends BaseStatement {
type: "DoWhileStatement";
body: Statement;
test: Expression;
}
interface ForStatement extends BaseStatement {
type: "ForStatement";
init?: VariableDeclaration | Expression | null | undefined;
test?: Expression | null | undefined;
update?: Expression | null | undefined;
body: Statement;
}
interface BaseForXStatement extends BaseStatement {
left: VariableDeclaration | Pattern;
right: Expression;
body: Statement;
}
interface ForInStatement extends BaseForXStatement {
type: "ForInStatement";
}
interface DebuggerStatement extends BaseStatement {
type: "DebuggerStatement";
}
type Declaration = FunctionDeclaration | VariableDeclaration | ClassDeclaration;
interface BaseDeclaration extends BaseStatement {}
interface MaybeNamedFunctionDeclaration extends BaseFunction, BaseDeclaration {
type: "FunctionDeclaration";
/** It is null when a function declaration is a part of the `export default function` statement */
id: Identifier | null;
body: BlockStatement;
}
interface FunctionDeclaration extends MaybeNamedFunctionDeclaration {
id: Identifier;
}
interface VariableDeclaration extends BaseDeclaration {
type: "VariableDeclaration";
declarations: VariableDeclarator[];
kind: "var" | "let" | "const" | "using" | "await using";
}
interface VariableDeclarator extends BaseNode {
type: "VariableDeclarator";
id: Pattern;
init?: Expression | null | undefined;
}
interface ExpressionMap {
ArrayExpression: ArrayExpression;
ArrowFunctionExpression: ArrowFunctionExpression;
AssignmentExpression: AssignmentExpression;
AwaitExpression: AwaitExpression;
BinaryExpression: BinaryExpression;
CallExpression: CallExpression;
ChainExpression: ChainExpression;
ClassExpression: ClassExpression;
ConditionalExpression: ConditionalExpression;
FunctionExpression: FunctionExpression;
Identifier: Identifier;
ImportExpression: ImportExpression;
Literal: Literal;
LogicalExpression: LogicalExpression;
MemberExpression: MemberExpression;
MetaProperty: MetaProperty;
NewExpression: NewExpression;
ObjectExpression: ObjectExpression;
SequenceExpression: SequenceExpression;
TaggedTemplateExpression: TaggedTemplateExpression;
TemplateLiteral: TemplateLiteral;
ThisExpression: ThisExpression;
UnaryExpression: UnaryExpression;
UpdateExpression: UpdateExpression;
YieldExpression: YieldExpression;
}
type Expression = ExpressionMap[keyof ExpressionMap];
interface BaseExpression extends BaseNode {}
type ChainElement = SimpleCallExpression | MemberExpression;
interface ChainExpression extends BaseExpression {
type: "ChainExpression";
expression: ChainElement;
}
interface ThisExpression extends BaseExpression {
type: "ThisExpression";
}
interface ArrayExpression extends BaseExpression {
type: "ArrayExpression";
elements: Array<Expression | SpreadElement | null>;
}
interface ObjectExpression extends BaseExpression {
type: "ObjectExpression";
properties: Array<Property | SpreadElement>;
}
interface PrivateIdentifier extends BaseNode {
type: "PrivateIdentifier";
name: string;
}
interface Property extends BaseNode {
type: "Property";
key: Expression | PrivateIdentifier;
value: Expression | Pattern; // Could be an AssignmentProperty
kind: "init" | "get" | "set";
method: boolean;
shorthand: boolean;
computed: boolean;
}
interface PropertyDefinition extends BaseNode {
type: "PropertyDefinition";
key: Expression | PrivateIdentifier;
value?: Expression | null | undefined;
computed: boolean;
static: boolean;
}
interface FunctionExpression extends BaseFunction, BaseExpression {
id?: Identifier | null | undefined;
type: "FunctionExpression";
body: BlockStatement;
}
interface SequenceExpression extends BaseExpression {
type: "SequenceExpression";
expressions: Expression[];
}
interface UnaryExpression extends BaseExpression {
type: "UnaryExpression";
operator: UnaryOperator;
prefix: true;
argument: Expression;
}
interface BinaryExpression extends BaseExpression {
type: "BinaryExpression";
operator: BinaryOperator;
left: Expression | PrivateIdentifier;
right: Expression;
}
interface AssignmentExpression extends BaseExpression {
type: "AssignmentExpression";
operator: AssignmentOperator;
left: Pattern | MemberExpression;
right: Expression;
}
interface UpdateExpression extends BaseExpression {
type: "UpdateExpression";
operator: UpdateOperator;
argument: Expression;
prefix: boolean;
}
interface LogicalExpression extends BaseExpression {
type: "LogicalExpression";
operator: LogicalOperator;
left: Expression;
right: Expression;
}
interface ConditionalExpression extends BaseExpression {
type: "ConditionalExpression";
test: Expression;
alternate: Expression;
consequent: Expression;
}
interface BaseCallExpression extends BaseExpression {
callee: Expression | Super;
arguments: Array<Expression | SpreadElement>;
}
type CallExpression = SimpleCallExpression | NewExpression;
interface SimpleCallExpression extends BaseCallExpression {
type: "CallExpression";
optional: boolean;
}
interface NewExpression extends BaseCallExpression {
type: "NewExpression";
}
interface MemberExpression extends BaseExpression, BasePattern {
type: "MemberExpression";
object: Expression | Super;
property: Expression | PrivateIdentifier;
computed: boolean;
optional: boolean;
}
type Pattern = Identifier | ObjectPattern | ArrayPattern | RestElement | AssignmentPattern | MemberExpression;
interface BasePattern extends BaseNode {}
interface SwitchCase extends BaseNode {
type: "SwitchCase";
test?: Expression | null | undefined;
consequent: Statement[];
}
interface CatchClause extends BaseNode {
type: "CatchClause";
param: Pattern | null;
body: BlockStatement;
}
interface Identifier extends BaseNode, BaseExpression, BasePattern {
type: "Identifier";
name: string;
}
type Literal = SimpleLiteral | RegExpLiteral | BigIntLiteral;
interface SimpleLiteral extends BaseNode, BaseExpression {
type: "Literal";
value: string | boolean | number | null;
raw?: string | undefined;
}
interface RegExpLiteral extends BaseNode, BaseExpression {
type: "Literal";
value?: RegExp | null | undefined;
regex: {
pattern: string;
flags: string;
};
raw?: string | undefined;
}
interface BigIntLiteral extends BaseNode, BaseExpression {
type: "Literal";
value?: bigint | null | undefined;
bigint: string;
raw?: string | undefined;
}
type UnaryOperator = "-" | "+" | "!" | "~" | "typeof" | "void" | "delete";
type BinaryOperator =
| "=="
| "!="
| "==="
| "!=="
| "<"
| "<="
| ">"
| ">="
| "<<"
| ">>"
| ">>>"
| "+"
| "-"
| "*"
| "/"
| "%"
| "**"
| "|"
| "^"
| "&"
| "in"
| "instanceof";
type LogicalOperator = "||" | "&&" | "??";
type AssignmentOperator =
| "="
| "+="
| "-="
| "*="
| "/="
| "%="
| "**="
| "<<="
| ">>="
| ">>>="
| "|="
| "^="
| "&="
| "||="
| "&&="
| "??=";
type UpdateOperator = "++" | "--";
interface ForOfStatement extends BaseForXStatement {
type: "ForOfStatement";
await: boolean;
}
interface Super extends BaseNode {
type: "Super";
}
interface SpreadElement extends BaseNode {
type: "SpreadElement";
argument: Expression;
}
interface ArrowFunctionExpression extends BaseExpression, BaseFunction {
type: "ArrowFunctionExpression";
expression: boolean;
body: BlockStatement | Expression;
}
interface YieldExpression extends BaseExpression {
type: "YieldExpression";
argument?: Expression | null | undefined;
delegate: boolean;
}
interface TemplateLiteral extends BaseExpression {
type: "TemplateLiteral";
quasis: TemplateElement[];
expressions: Expression[];
}
interface TaggedTemplateExpression extends BaseExpression {
type: "TaggedTemplateExpression";
tag: Expression;
quasi: TemplateLiteral;
}
interface TemplateElement extends BaseNode {
type: "TemplateElement";
tail: boolean;
value: {
/** It is null when the template literal is tagged and the text has an invalid escape (e.g. - tag`\unicode and \u{55}`) */
cooked?: string | null | undefined;
raw: string;
};
}
interface AssignmentProperty extends Property {
value: Pattern;
kind: "init";
method: boolean; // false
}
interface ObjectPattern extends BasePattern {
type: "ObjectPattern";
properties: Array<AssignmentProperty | RestElement>;
}
interface ArrayPattern extends BasePattern {
type: "ArrayPattern";
elements: Array<Pattern | null>;
}
interface RestElement extends BasePattern {
type: "RestElement";
argument: Pattern;
}
interface AssignmentPattern extends BasePattern {
type: "AssignmentPattern";
left: Pattern;
right: Expression;
}
type Class = ClassDeclaration | ClassExpression;
interface BaseClass extends BaseNode {
superClass?: Expression | null | undefined;
body: ClassBody;
}
interface ClassBody extends BaseNode {
type: "ClassBody";
body: Array<MethodDefinition | PropertyDefinition | StaticBlock>;
}
interface MethodDefinition extends BaseNode {
type: "MethodDefinition";
key: Expression | PrivateIdentifier;
value: FunctionExpression;
kind: "constructor" | "method" | "get" | "set";
computed: boolean;
static: boolean;
}
interface MaybeNamedClassDeclaration extends BaseClass, BaseDeclaration {
type: "ClassDeclaration";
/** It is null when a class declaration is a part of the `export default class` statement */
id: Identifier | null;
}
interface ClassDeclaration extends MaybeNamedClassDeclaration {
id: Identifier;
}
interface ClassExpression extends BaseClass, BaseExpression {
type: "ClassExpression";
id?: Identifier | null | undefined;
}
interface MetaProperty extends BaseExpression {
type: "MetaProperty";
meta: Identifier;
property: Identifier;
}
type ModuleDeclaration =
| ImportDeclaration
| ExportNamedDeclaration
| ExportDefaultDeclaration
| ExportAllDeclaration;
interface BaseModuleDeclaration extends BaseNode {}
type ModuleSpecifier = ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ExportSpecifier;
interface BaseModuleSpecifier extends BaseNode {
local: Identifier;
}
interface ImportDeclaration extends BaseModuleDeclaration {
type: "ImportDeclaration";
specifiers: Array<ImportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier>;
attributes: ImportAttribute[];
source: Literal;
}
interface ImportSpecifier extends BaseModuleSpecifier {
type: "ImportSpecifier";
imported: Identifier | Literal;
}
interface ImportAttribute extends BaseNode {
type: "ImportAttribute";
key: Identifier | Literal;
value: Literal;
}
interface ImportExpression extends BaseExpression {
type: "ImportExpression";
source: Expression;
options?: Expression | null | undefined;
}
interface ImportDefaultSpecifier extends BaseModuleSpecifier {
type: "ImportDefaultSpecifier";
}
interface ImportNamespaceSpecifier extends BaseModuleSpecifier {
type: "ImportNamespaceSpecifier";
}
interface ExportNamedDeclaration extends BaseModuleDeclaration {
type: "ExportNamedDeclaration";
declaration?: Declaration | null | undefined;
specifiers: ExportSpecifier[];
attributes: ImportAttribute[];
source?: Literal | null | undefined;
}
interface ExportSpecifier extends Omit<BaseModuleSpecifier, "local"> {
type: "ExportSpecifier";
local: Identifier | Literal;
exported: Identifier | Literal;
}
interface ExportDefaultDeclaration extends BaseModuleDeclaration {
type: "ExportDefaultDeclaration";
declaration: MaybeNamedFunctionDeclaration | MaybeNamedClassDeclaration | Expression;
}
interface ExportAllDeclaration extends BaseModuleDeclaration {
type: "ExportAllDeclaration";
exported: Identifier | Literal | null;
attributes: ImportAttribute[];
source: Literal;
}
interface AwaitExpression extends BaseExpression {
type: "AwaitExpression";
argument: Expression;
}
type Positioned<T> = T & {
start: number
end: number
};
type Node = Positioned<Node$1>;
interface HoistMocksOptions {
/**
* List of modules that should always be imported before compiler hints.
* @default 'vitest'
*/
hoistedModule?: string;
/**
* @default ["vi", "vitest"]
*/
utilsObjectNames?: string[];
/**
* @default ["mock", "unmock"]
*/
hoistableMockMethodNames?: string[];
/**
* @default ["mock", "unmock", "doMock", "doUnmock"]
*/
dynamicImportMockMethodNames?: string[];
/**
* @default ["hoisted"]
*/
hoistedMethodNames?: string[];
regexpHoistable?: RegExp;
codeFrameGenerator?: CodeFrameGenerator;
}
interface HoistMocksPluginOptions extends Omit<HoistMocksOptions, "regexpHoistable"> {
include?: string | RegExp | (string | RegExp)[];
exclude?: string | RegExp | (string | RegExp)[];
/**
* overrides include/exclude options
*/
filter?: (id: string) => boolean;
}
declare function hoistMocksPlugin(options?: HoistMocksPluginOptions): Plugin;
interface HoistMocksResult {
code: string;
map: SourceMap;
}
interface CodeFrameGenerator {
(node: Positioned<Node>, id: string, code: string): string;
}
// this is a fork of Vite SSR transform
declare function hoistMocks(code: string, id: string, parse: Rollup.PluginContext["parse"], options?: HoistMocksOptions): HoistMocksResult | undefined;
interface InterceptorPluginOptions {
/**
* @default "__vitest_mocker__"
*/
globalThisAccessor?: string;
registry?: MockerRegistry;
}
declare function interceptorPlugin(options?: InterceptorPluginOptions): Plugin;
interface MockerPluginOptions extends AutomockPluginOptions {
hoistMocks?: HoistMocksPluginOptions;
}
// this is an implementation for public usage
// vitest doesn't use this plugin directly
declare function mockerPlugin(options?: MockerPluginOptions): Plugin[];
interface ServerResolverOptions {
/**
* @default ['/node_modules/']
*/
moduleDirectories?: string[];
}
declare class ServerMockResolver {
private server;
private options;
constructor(server: ViteDevServer, options?: ServerResolverOptions);
resolveMock(rawId: string, importer: string, options: {
mock: "spy" | "factory" | "auto"
}): Promise<ServerMockResolution>;
invalidate(ids: string[]): void;
resolveId(id: string, importer?: string): Promise<ServerIdResolution | null>;
private normalizeResolveIdToUrl;
private resolveMockId;
private resolveModule;
}
interface ServerMockResolution {
mockType: "manual" | "redirect" | "automock" | "autospy";
resolvedId: string;
resolvedUrl: string;
needsInterop?: boolean;
redirectUrl?: string | null;
}
interface ServerIdResolution {
id: string;
url: string;
optimized: boolean;
}
export { ServerMockResolver, automockModule, automockPlugin, createManualModuleSource, dynamicImportPlugin, hoistMocks, hoistMocksPlugin, interceptorPlugin, mockerPlugin };
export type { AutomockPluginOptions, HoistMocksPluginOptions, HoistMocksResult, InterceptorPluginOptions, ServerIdResolution, ServerMockResolution, ServerResolverOptions };

1306
frontend/node_modules/@vitest/mocker/dist/node.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
declare function findMockRedirect(root: string, mockPath: string, external: string | null): string | null;
export { findMockRedirect };

75
frontend/node_modules/@vitest/mocker/dist/redirect.js generated vendored Normal file
View File

@@ -0,0 +1,75 @@
import fs from 'node:fs';
import { builtinModules } from 'node:module';
import { d as dirname, j as join, b as basename, r as resolve, e as extname } from './chunk-pathe.M-eThtNZ.js';
const { existsSync, readdirSync, statSync } = fs;
function findMockRedirect(root, mockPath, external) {
const path = external || mockPath;
// it's a node_module alias
// all mocks should be inside <root>/__mocks__
if (external || isNodeBuiltin(mockPath) || !existsSync(mockPath)) {
const mockDirname = dirname(path);
const mockFolder = join(root, "__mocks__", mockDirname);
if (!existsSync(mockFolder)) {
return null;
}
const baseOriginal = basename(path);
function findFile(mockFolder, baseOriginal) {
const files = readdirSync(mockFolder);
for (const file of files) {
const baseFile = basename(file, extname(file));
if (baseFile === baseOriginal) {
const path = resolve(mockFolder, file);
// if the same name, return the file
if (statSync(path).isFile()) {
return path;
} else {
// find folder/index.{js,ts}
const indexFile = findFile(path, "index");
if (indexFile) {
return indexFile;
}
}
}
}
return null;
}
return findFile(mockFolder, baseOriginal);
}
const dir = dirname(path);
const baseId = basename(path);
const fullPath = resolve(dir, "__mocks__", baseId);
return existsSync(fullPath) ? fullPath : null;
}
const builtins = new Set([
...builtinModules,
"assert/strict",
"diagnostics_channel",
"dns/promises",
"fs/promises",
"path/posix",
"path/win32",
"readline/promises",
"stream/consumers",
"stream/promises",
"stream/web",
"timers/promises",
"util/types",
"wasi"
]);
// https://nodejs.org/api/modules.html#built-in-modules-with-mandatory-node-prefix
const prefixedBuiltins = new Set([
"node:sea",
"node:sqlite",
"node:test",
"node:test/reporters"
]);
const NODE_BUILTIN_NAMESPACE = "node:";
function isNodeBuiltin(id) {
if (prefixedBuiltins.has(id)) {
return true;
}
return builtins.has(id.startsWith(NODE_BUILTIN_NAMESPACE) ? id.slice(NODE_BUILTIN_NAMESPACE.length) : id);
}
export { findMockRedirect };

View File

@@ -0,0 +1,9 @@
import { M as ModuleMockerInterceptor, a as ModuleMockerCompilerHints, b as ModuleMocker } from './mocker.d-Ce9_ySj5.js';
import '@vitest/spy';
import './types.d-D_aRZRdy.js';
import './registry.d-D765pazg.js';
declare function registerModuleMocker(interceptor: (accessor: string) => ModuleMockerInterceptor): ModuleMockerCompilerHints;
declare function registerNativeFactoryResolver(mocker: ModuleMocker): void;
export { registerModuleMocker, registerNativeFactoryResolver };

41
frontend/node_modules/@vitest/mocker/dist/register.js generated vendored Normal file
View File

@@ -0,0 +1,41 @@
import { spyOn } from '@vitest/spy';
import { M as ModuleMocker, r as rpc, c as createCompilerHints, h as hot } from './chunk-mocker.js';
import './index.js';
import './chunk-registry.js';
import './chunk-pathe.M-eThtNZ.js';
function registerModuleMocker(interceptor) {
const mocker = new ModuleMocker(interceptor(__VITEST_GLOBAL_THIS_ACCESSOR__), {
resolveId(id, importer) {
return rpc("vitest:mocks:resolveId", {
id,
importer
});
},
resolveMock(id, importer, options) {
return rpc("vitest:mocks:resolveMock", {
id,
importer,
options
});
},
async invalidate(ids) {
return rpc("vitest:mocks:invalidate", { ids });
}
}, spyOn, { root: __VITEST_MOCKER_ROOT__ });
globalThis[__VITEST_GLOBAL_THIS_ACCESSOR__] = mocker;
registerNativeFactoryResolver(mocker);
return createCompilerHints({ globalThisKey: __VITEST_GLOBAL_THIS_ACCESSOR__ });
}
function registerNativeFactoryResolver(mocker) {
hot.on("vitest:interceptor:resolve", async (url) => {
const exports = await mocker.resolveFactoryModule(url);
const keys = Object.keys(exports);
hot.send("vitest:interceptor:resolved", {
url,
keys
});
});
}
export { registerModuleMocker, registerNativeFactoryResolver };

View File

@@ -0,0 +1,87 @@
declare class MockerRegistry {
private readonly registryByUrl;
private readonly registryById;
clear(): void;
keys(): IterableIterator<string>;
add(mock: MockedModule): void;
register(json: MockedModuleSerialized): MockedModule;
register(type: "redirect", raw: string, id: string, url: string, redirect: string): RedirectedModule;
register(type: "manual", raw: string, id: string, url: string, factory: () => any): ManualMockedModule;
register(type: "automock", raw: string, id: string, url: string): AutomockedModule;
register(type: "autospy", id: string, raw: string, url: string): AutospiedModule;
delete(id: string): void;
get(id: string): MockedModule | undefined;
getById(id: string): MockedModule | undefined;
has(id: string): boolean;
}
type MockedModule = AutomockedModule | AutospiedModule | ManualMockedModule | RedirectedModule;
type MockedModuleType = "automock" | "autospy" | "manual" | "redirect";
type MockedModuleSerialized = AutomockedModuleSerialized | AutospiedModuleSerialized | ManualMockedModuleSerialized | RedirectedModuleSerialized;
declare class AutomockedModule {
raw: string;
id: string;
url: string;
readonly type = "automock";
constructor(raw: string, id: string, url: string);
static fromJSON(data: AutomockedModuleSerialized): AutospiedModule;
toJSON(): AutomockedModuleSerialized;
}
interface AutomockedModuleSerialized {
type: "automock";
url: string;
raw: string;
id: string;
}
declare class AutospiedModule {
raw: string;
id: string;
url: string;
readonly type = "autospy";
constructor(raw: string, id: string, url: string);
static fromJSON(data: AutospiedModuleSerialized): AutospiedModule;
toJSON(): AutospiedModuleSerialized;
}
interface AutospiedModuleSerialized {
type: "autospy";
url: string;
raw: string;
id: string;
}
declare class RedirectedModule {
raw: string;
id: string;
url: string;
redirect: string;
readonly type = "redirect";
constructor(raw: string, id: string, url: string, redirect: string);
static fromJSON(data: RedirectedModuleSerialized): RedirectedModule;
toJSON(): RedirectedModuleSerialized;
}
interface RedirectedModuleSerialized {
type: "redirect";
url: string;
id: string;
raw: string;
redirect: string;
}
declare class ManualMockedModule {
raw: string;
id: string;
url: string;
factory: () => any;
cache: Record<string | symbol, any> | undefined;
readonly type = "manual";
constructor(raw: string, id: string, url: string, factory: () => any);
resolve(): Promise<Record<string | symbol, any>>;
static fromJSON(data: ManualMockedModuleSerialized, factory: () => any): ManualMockedModule;
toJSON(): ManualMockedModuleSerialized;
}
interface ManualMockedModuleSerialized {
type: "manual";
url: string;
id: string;
raw: string;
}
export { AutomockedModule as A, RedirectedModule as R, AutospiedModule as a, ManualMockedModule as b, MockerRegistry as c };
export type { MockedModuleType as M, AutomockedModuleSerialized as d, AutospiedModuleSerialized as e, ManualMockedModuleSerialized as f, MockedModule as g, MockedModuleSerialized as h, RedirectedModuleSerialized as i };

View File

@@ -0,0 +1,8 @@
type Awaitable<T> = T | PromiseLike<T>;
type ModuleMockFactoryWithHelper<M = unknown> = (importOriginal: <T extends M = M>() => Promise<T>) => Awaitable<Partial<M>>;
type ModuleMockFactory = () => any;
interface ModuleMockOptions {
spy?: boolean;
}
export type { ModuleMockFactory as M, ModuleMockFactoryWithHelper as a, ModuleMockOptions as b };

View File

@@ -0,0 +1,7 @@
Copyright (c) 2015-20 [these people](https://github.com/Rich-Harris/estree-walker/graphs/contributors)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,48 @@
# estree-walker
Simple utility for walking an [ESTree](https://github.com/estree/estree)-compliant AST, such as one generated by [acorn](https://github.com/marijnh/acorn).
## Installation
```bash
npm i estree-walker
```
## Usage
```js
var walk = require('estree-walker').walk;
var acorn = require('acorn');
ast = acorn.parse(sourceCode, options); // https://github.com/acornjs/acorn
walk(ast, {
enter(node, parent, prop, index) {
// some code happens
},
leave(node, parent, prop, index) {
// some code happens
}
});
```
Inside the `enter` function, calling `this.skip()` will prevent the node's children being walked, or the `leave` function (which is optional) being called.
Call `this.replace(new_node)` in either `enter` or `leave` to replace the current node with a new one.
Call `this.remove()` in either `enter` or `leave` to remove the current node.
## Why not use estraverse?
The ESTree spec is evolving to accommodate ES6/7. I've had a couple of experiences where [estraverse](https://github.com/estools/estraverse) was unable to handle an AST generated by recent versions of acorn, because it hard-codes visitor keys.
estree-walker, by contrast, simply enumerates a node's properties to find child nodes (and child lists of nodes), and is therefore resistant to spec changes. It's also much smaller. (The performance, if you're wondering, is basically identical.)
None of which should be taken as criticism of estraverse, which has more features and has been battle-tested in many more situations, and for which I'm very grateful.
## License
MIT

View File

@@ -0,0 +1,38 @@
{
"name": "estree-walker",
"description": "Traverse an ESTree-compliant AST",
"version": "3.0.3",
"private": false,
"author": "Rich Harris",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Rich-Harris/estree-walker"
},
"type": "module",
"module": "./src/index.js",
"exports": {
"./package.json": "./package.json",
".": {
"types": "./types/index.d.ts",
"import": "./src/index.js"
}
},
"types": "types/index.d.ts",
"scripts": {
"prepublishOnly": "tsc && npm test",
"test": "uvu test"
},
"dependencies": {
"@types/estree": "^1.0.0"
},
"devDependencies": {
"typescript": "^4.9.0",
"uvu": "^0.5.1"
},
"files": [
"src",
"types",
"README.md"
]
}

View File

@@ -0,0 +1,152 @@
import { WalkerBase } from './walker.js';
/**
* @typedef { import('estree').Node} Node
* @typedef { import('./walker.js').WalkerContext} WalkerContext
* @typedef {(
* this: WalkerContext,
* node: Node,
* parent: Node | null,
* key: string | number | symbol | null | undefined,
* index: number | null | undefined
* ) => Promise<void>} AsyncHandler
*/
export class AsyncWalker extends WalkerBase {
/**
*
* @param {AsyncHandler} [enter]
* @param {AsyncHandler} [leave]
*/
constructor(enter, leave) {
super();
/** @type {boolean} */
this.should_skip = false;
/** @type {boolean} */
this.should_remove = false;
/** @type {Node | null} */
this.replacement = null;
/** @type {WalkerContext} */
this.context = {
skip: () => (this.should_skip = true),
remove: () => (this.should_remove = true),
replace: (node) => (this.replacement = node)
};
/** @type {AsyncHandler | undefined} */
this.enter = enter;
/** @type {AsyncHandler | undefined} */
this.leave = leave;
}
/**
* @template {Node} Parent
* @param {Node} node
* @param {Parent | null} parent
* @param {keyof Parent} [prop]
* @param {number | null} [index]
* @returns {Promise<Node | null>}
*/
async visit(node, parent, prop, index) {
if (node) {
if (this.enter) {
const _should_skip = this.should_skip;
const _should_remove = this.should_remove;
const _replacement = this.replacement;
this.should_skip = false;
this.should_remove = false;
this.replacement = null;
await this.enter.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const skipped = this.should_skip;
const removed = this.should_remove;
this.should_skip = _should_skip;
this.should_remove = _should_remove;
this.replacement = _replacement;
if (skipped) return node;
if (removed) return null;
}
/** @type {keyof Node} */
let key;
for (key in node) {
/** @type {unknown} */
const value = node[key];
if (value && typeof value === 'object') {
if (Array.isArray(value)) {
const nodes = /** @type {Array<unknown>} */ (value);
for (let i = 0; i < nodes.length; i += 1) {
const item = nodes[i];
if (isNode(item)) {
if (!(await this.visit(item, node, key, i))) {
// removed
i--;
}
}
}
} else if (isNode(value)) {
await this.visit(value, node, key, null);
}
}
}
if (this.leave) {
const _replacement = this.replacement;
const _should_remove = this.should_remove;
this.replacement = null;
this.should_remove = false;
await this.leave.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const removed = this.should_remove;
this.replacement = _replacement;
this.should_remove = _should_remove;
if (removed) return null;
}
}
return node;
}
}
/**
* Ducktype a node.
*
* @param {unknown} value
* @returns {value is Node}
*/
function isNode(value) {
return (
value !== null && typeof value === 'object' && 'type' in value && typeof value.type === 'string'
);
}

View File

@@ -0,0 +1,34 @@
import { SyncWalker } from './sync.js';
import { AsyncWalker } from './async.js';
/**
* @typedef {import('estree').Node} Node
* @typedef {import('./sync.js').SyncHandler} SyncHandler
* @typedef {import('./async.js').AsyncHandler} AsyncHandler
*/
/**
* @param {Node} ast
* @param {{
* enter?: SyncHandler
* leave?: SyncHandler
* }} walker
* @returns {Node | null}
*/
export function walk(ast, { enter, leave }) {
const instance = new SyncWalker(enter, leave);
return instance.visit(ast, null);
}
/**
* @param {Node} ast
* @param {{
* enter?: AsyncHandler
* leave?: AsyncHandler
* }} walker
* @returns {Promise<Node | null>}
*/
export async function asyncWalk(ast, { enter, leave }) {
const instance = new AsyncWalker(enter, leave);
return await instance.visit(ast, null);
}

View File

@@ -0,0 +1,152 @@
import { WalkerBase } from './walker.js';
/**
* @typedef { import('estree').Node} Node
* @typedef { import('./walker.js').WalkerContext} WalkerContext
* @typedef {(
* this: WalkerContext,
* node: Node,
* parent: Node | null,
* key: string | number | symbol | null | undefined,
* index: number | null | undefined
* ) => void} SyncHandler
*/
export class SyncWalker extends WalkerBase {
/**
*
* @param {SyncHandler} [enter]
* @param {SyncHandler} [leave]
*/
constructor(enter, leave) {
super();
/** @type {boolean} */
this.should_skip = false;
/** @type {boolean} */
this.should_remove = false;
/** @type {Node | null} */
this.replacement = null;
/** @type {WalkerContext} */
this.context = {
skip: () => (this.should_skip = true),
remove: () => (this.should_remove = true),
replace: (node) => (this.replacement = node)
};
/** @type {SyncHandler | undefined} */
this.enter = enter;
/** @type {SyncHandler | undefined} */
this.leave = leave;
}
/**
* @template {Node} Parent
* @param {Node} node
* @param {Parent | null} parent
* @param {keyof Parent} [prop]
* @param {number | null} [index]
* @returns {Node | null}
*/
visit(node, parent, prop, index) {
if (node) {
if (this.enter) {
const _should_skip = this.should_skip;
const _should_remove = this.should_remove;
const _replacement = this.replacement;
this.should_skip = false;
this.should_remove = false;
this.replacement = null;
this.enter.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const skipped = this.should_skip;
const removed = this.should_remove;
this.should_skip = _should_skip;
this.should_remove = _should_remove;
this.replacement = _replacement;
if (skipped) return node;
if (removed) return null;
}
/** @type {keyof Node} */
let key;
for (key in node) {
/** @type {unknown} */
const value = node[key];
if (value && typeof value === 'object') {
if (Array.isArray(value)) {
const nodes = /** @type {Array<unknown>} */ (value);
for (let i = 0; i < nodes.length; i += 1) {
const item = nodes[i];
if (isNode(item)) {
if (!this.visit(item, node, key, i)) {
// removed
i--;
}
}
}
} else if (isNode(value)) {
this.visit(value, node, key, null);
}
}
}
if (this.leave) {
const _replacement = this.replacement;
const _should_remove = this.should_remove;
this.replacement = null;
this.should_remove = false;
this.leave.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const removed = this.should_remove;
this.replacement = _replacement;
this.should_remove = _should_remove;
if (removed) return null;
}
}
return node;
}
}
/**
* Ducktype a node.
*
* @param {unknown} value
* @returns {value is Node}
*/
function isNode(value) {
return (
value !== null && typeof value === 'object' && 'type' in value && typeof value.type === 'string'
);
}

View File

@@ -0,0 +1,61 @@
/**
* @typedef { import('estree').Node} Node
* @typedef {{
* skip: () => void;
* remove: () => void;
* replace: (node: Node) => void;
* }} WalkerContext
*/
export class WalkerBase {
constructor() {
/** @type {boolean} */
this.should_skip = false;
/** @type {boolean} */
this.should_remove = false;
/** @type {Node | null} */
this.replacement = null;
/** @type {WalkerContext} */
this.context = {
skip: () => (this.should_skip = true),
remove: () => (this.should_remove = true),
replace: (node) => (this.replacement = node)
};
}
/**
* @template {Node} Parent
* @param {Parent | null | undefined} parent
* @param {keyof Parent | null | undefined} prop
* @param {number | null | undefined} index
* @param {Node} node
*/
replace(parent, prop, index, node) {
if (parent && prop) {
if (index != null) {
/** @type {Array<Node>} */ (parent[prop])[index] = node;
} else {
/** @type {Node} */ (parent[prop]) = node;
}
}
}
/**
* @template {Node} Parent
* @param {Parent | null | undefined} parent
* @param {keyof Parent | null | undefined} prop
* @param {number | null | undefined} index
*/
remove(parent, prop, index) {
if (parent && prop) {
if (index !== null && index !== undefined) {
/** @type {Array<Node>} */ (parent[prop]).splice(index, 1);
} else {
delete parent[prop];
}
}
}
}

View File

@@ -0,0 +1,36 @@
/**
* @typedef { import('estree').Node} Node
* @typedef { import('./walker.js').WalkerContext} WalkerContext
* @typedef {(
* this: WalkerContext,
* node: Node,
* parent: Node | null,
* key: string | number | symbol | null | undefined,
* index: number | null | undefined
* ) => Promise<void>} AsyncHandler
*/
export class AsyncWalker extends WalkerBase {
/**
*
* @param {AsyncHandler} [enter]
* @param {AsyncHandler} [leave]
*/
constructor(enter?: AsyncHandler | undefined, leave?: AsyncHandler | undefined);
/** @type {AsyncHandler | undefined} */
enter: AsyncHandler | undefined;
/** @type {AsyncHandler | undefined} */
leave: AsyncHandler | undefined;
/**
* @template {Node} Parent
* @param {Node} node
* @param {Parent | null} parent
* @param {keyof Parent} [prop]
* @param {number | null} [index]
* @returns {Promise<Node | null>}
*/
visit<Parent extends import("estree").Node>(node: Node, parent: Parent | null, prop?: keyof Parent | undefined, index?: number | null | undefined): Promise<Node | null>;
}
export type Node = import('estree').Node;
export type WalkerContext = import('./walker.js').WalkerContext;
export type AsyncHandler = (this: WalkerContext, node: Node, parent: Node | null, key: string | number | symbol | null | undefined, index: number | null | undefined) => Promise<void>;
import { WalkerBase } from "./walker.js";

View File

@@ -0,0 +1,32 @@
/**
* @typedef {import('estree').Node} Node
* @typedef {import('./sync.js').SyncHandler} SyncHandler
* @typedef {import('./async.js').AsyncHandler} AsyncHandler
*/
/**
* @param {Node} ast
* @param {{
* enter?: SyncHandler
* leave?: SyncHandler
* }} walker
* @returns {Node | null}
*/
export function walk(ast: Node, { enter, leave }: {
enter?: SyncHandler;
leave?: SyncHandler;
}): Node | null;
/**
* @param {Node} ast
* @param {{
* enter?: AsyncHandler
* leave?: AsyncHandler
* }} walker
* @returns {Promise<Node | null>}
*/
export function asyncWalk(ast: Node, { enter, leave }: {
enter?: AsyncHandler;
leave?: AsyncHandler;
}): Promise<Node | null>;
export type Node = import('estree').Node;
export type SyncHandler = import('./sync.js').SyncHandler;
export type AsyncHandler = import('./async.js').AsyncHandler;

View File

@@ -0,0 +1,36 @@
/**
* @typedef { import('estree').Node} Node
* @typedef { import('./walker.js').WalkerContext} WalkerContext
* @typedef {(
* this: WalkerContext,
* node: Node,
* parent: Node | null,
* key: string | number | symbol | null | undefined,
* index: number | null | undefined
* ) => void} SyncHandler
*/
export class SyncWalker extends WalkerBase {
/**
*
* @param {SyncHandler} [enter]
* @param {SyncHandler} [leave]
*/
constructor(enter?: SyncHandler | undefined, leave?: SyncHandler | undefined);
/** @type {SyncHandler | undefined} */
enter: SyncHandler | undefined;
/** @type {SyncHandler | undefined} */
leave: SyncHandler | undefined;
/**
* @template {Node} Parent
* @param {Node} node
* @param {Parent | null} parent
* @param {keyof Parent} [prop]
* @param {number | null} [index]
* @returns {Node | null}
*/
visit<Parent extends import("estree").Node>(node: Node, parent: Parent | null, prop?: keyof Parent | undefined, index?: number | null | undefined): Node | null;
}
export type Node = import('estree').Node;
export type WalkerContext = import('./walker.js').WalkerContext;
export type SyncHandler = (this: WalkerContext, node: Node, parent: Node | null, key: string | number | symbol | null | undefined, index: number | null | undefined) => void;
import { WalkerBase } from "./walker.js";

View File

@@ -0,0 +1,39 @@
/**
* @typedef { import('estree').Node} Node
* @typedef {{
* skip: () => void;
* remove: () => void;
* replace: (node: Node) => void;
* }} WalkerContext
*/
export class WalkerBase {
/** @type {boolean} */
should_skip: boolean;
/** @type {boolean} */
should_remove: boolean;
/** @type {Node | null} */
replacement: Node | null;
/** @type {WalkerContext} */
context: WalkerContext;
/**
* @template {Node} Parent
* @param {Parent | null | undefined} parent
* @param {keyof Parent | null | undefined} prop
* @param {number | null | undefined} index
* @param {Node} node
*/
replace<Parent extends import("estree").Node>(parent: Parent | null | undefined, prop: keyof Parent | null | undefined, index: number | null | undefined, node: Node): void;
/**
* @template {Node} Parent
* @param {Parent | null | undefined} parent
* @param {keyof Parent | null | undefined} prop
* @param {number | null | undefined} index
*/
remove<Parent_1 extends import("estree").Node>(parent: Parent_1 | null | undefined, prop: keyof Parent_1 | null | undefined, index: number | null | undefined): void;
}
export type Node = import('estree').Node;
export type WalkerContext = {
skip: () => void;
remove: () => void;
replace: (node: Node) => void;
};

82
frontend/node_modules/@vitest/mocker/package.json generated vendored Normal file
View File

@@ -0,0 +1,82 @@
{
"name": "@vitest/mocker",
"type": "module",
"version": "3.2.4",
"description": "Vitest module mocker implementation",
"license": "MIT",
"funding": "https://opencollective.com/vitest",
"homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/mocker#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/vitest-dev/vitest.git",
"directory": "packages/mocker"
},
"bugs": {
"url": "https://github.com/vitest-dev/vitest/issues"
},
"sideEffects": false,
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./node": {
"types": "./dist/node.d.ts",
"default": "./dist/node.js"
},
"./browser": {
"types": "./dist/browser.d.ts",
"default": "./dist/browser.js"
},
"./redirect": {
"types": "./dist/redirect.d.ts",
"default": "./dist/redirect.js"
},
"./register": {
"types": "./dist/register.d.ts",
"default": "./dist/register.js"
},
"./auto-register": {
"types": "./dist/register.d.ts",
"default": "./dist/register.js"
},
"./*": "./*"
},
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"*.d.ts",
"dist"
],
"peerDependencies": {
"msw": "^2.4.9",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
},
"peerDependenciesMeta": {
"msw": {
"optional": true
},
"vite": {
"optional": true
}
},
"dependencies": {
"estree-walker": "^3.0.3",
"magic-string": "^0.30.17",
"@vitest/spy": "3.2.4"
},
"devDependencies": {
"@types/estree": "^1.0.8",
"acorn-walk": "^8.3.4",
"msw": "^2.10.2",
"pathe": "^2.0.3",
"vite": "^5.4.0",
"@vitest/spy": "3.2.4",
"@vitest/utils": "3.2.4"
},
"scripts": {
"build": "rimraf dist && rollup -c",
"dev": "rollup -c --watch"
}
}