Add progressive web app companion for cross-platform access

Vite + TypeScript PWA that mirrors the Android app's core features:
- Pre-processed shelter data (build-time UTM33N→WGS84 conversion)
- Leaflet map with shelter markers, user location, and offline tiles
- Canvas compass arrow (ported from DirectionArrowView.kt)
- IndexedDB shelter cache with 7-day staleness check
- Service worker with CacheFirst tiles and precached app shell
- i18n for en, nb, nn (ported from Android strings.xml)
- iOS/Android compass handling with low-pass filter
- Respects user map interaction (no auto-snap on pan/zoom)
- Build revision cache-breaker for reliable SW updates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2026-03-08 17:41:38 +01:00
commit e8428de775
12051 changed files with 1799735 additions and 0 deletions

21
pwa/node_modules/@vitest/runner/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
pwa/node_modules/@vitest/runner/README.md generated vendored Normal file
View file

@ -0,0 +1,5 @@
# @vitest/runner
Vitest mechanism to collect and run tasks.
[GitHub](https://github.com/vitest-dev/vitest) | [Documentation](https://vitest.dev/advanced/runner)

249
pwa/node_modules/@vitest/runner/dist/chunk-tasks.js generated vendored Normal file
View file

@ -0,0 +1,249 @@
import { processError } from '@vitest/utils/error';
import { relative } from 'pathe';
import { toArray } from '@vitest/utils';
function createChainable(keys, fn) {
function create(context) {
const chain2 = function(...args) {
return fn.apply(context, args);
};
Object.assign(chain2, fn);
chain2.withContext = () => chain2.bind(context);
chain2.setContext = (key, value) => {
context[key] = value;
};
chain2.mergeContext = (ctx) => {
Object.assign(context, ctx);
};
for (const key of keys) {
Object.defineProperty(chain2, key, {
get() {
return create({ ...context, [key]: true });
}
});
}
return chain2;
}
const chain = create({});
chain.fn = fn;
return chain;
}
function interpretTaskModes(suite, namePattern, onlyMode, parentIsOnly, allowOnly) {
const suiteIsOnly = parentIsOnly || suite.mode === "only";
suite.tasks.forEach((t) => {
const includeTask = suiteIsOnly || t.mode === "only";
if (onlyMode) {
if (t.type === "suite" && (includeTask || someTasksAreOnly(t))) {
if (t.mode === "only") {
checkAllowOnly(t, allowOnly);
t.mode = "run";
}
} else if (t.mode === "run" && !includeTask) {
t.mode = "skip";
} else if (t.mode === "only") {
checkAllowOnly(t, allowOnly);
t.mode = "run";
}
}
if (t.type === "test") {
if (namePattern && !getTaskFullName(t).match(namePattern)) {
t.mode = "skip";
}
} else if (t.type === "suite") {
if (t.mode === "skip") {
skipAllTasks(t);
} else {
interpretTaskModes(t, namePattern, onlyMode, includeTask, allowOnly);
}
}
});
if (suite.mode === "run") {
if (suite.tasks.length && suite.tasks.every((i) => i.mode !== "run")) {
suite.mode = "skip";
}
}
}
function getTaskFullName(task) {
return `${task.suite ? `${getTaskFullName(task.suite)} ` : ""}${task.name}`;
}
function someTasksAreOnly(suite) {
return suite.tasks.some(
(t) => t.mode === "only" || t.type === "suite" && someTasksAreOnly(t)
);
}
function skipAllTasks(suite) {
suite.tasks.forEach((t) => {
if (t.mode === "run") {
t.mode = "skip";
if (t.type === "suite") {
skipAllTasks(t);
}
}
});
}
function checkAllowOnly(task, allowOnly) {
if (allowOnly) {
return;
}
const error = processError(
new Error(
"[Vitest] Unexpected .only modifier. Remove it or pass --allowOnly argument to bypass this error"
)
);
task.result = {
state: "fail",
errors: [error]
};
}
function generateHash(str) {
let hash = 0;
if (str.length === 0) {
return `${hash}`;
}
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
hash = (hash << 5) - hash + char;
hash = hash & hash;
}
return `${hash}`;
}
function calculateSuiteHash(parent) {
parent.tasks.forEach((t, idx) => {
t.id = `${parent.id}_${idx}`;
if (t.type === "suite") {
calculateSuiteHash(t);
}
});
}
function createFileTask(filepath, root, projectName, pool) {
const path = relative(root, filepath);
const file = {
id: generateHash(`${path}${projectName || ""}`),
name: path,
type: "suite",
mode: "run",
filepath,
tasks: [],
meta: /* @__PURE__ */ Object.create(null),
projectName,
file: void 0,
pool
};
file.file = file;
return file;
}
function limitConcurrency(concurrency = Infinity) {
let count = 0;
let head;
let tail;
const finish = () => {
count--;
if (head) {
head[0]();
head = head[1];
tail = head && tail;
}
};
return (func, ...args) => {
return new Promise((resolve) => {
if (count++ < concurrency) {
resolve();
} else if (tail) {
tail = tail[1] = [resolve];
} else {
head = tail = [resolve];
}
}).then(() => {
return func(...args);
}).finally(finish);
};
}
function partitionSuiteChildren(suite) {
let tasksGroup = [];
const tasksGroups = [];
for (const c of suite.tasks) {
if (tasksGroup.length === 0 || c.concurrent === tasksGroup[0].concurrent) {
tasksGroup.push(c);
} else {
tasksGroups.push(tasksGroup);
tasksGroup = [c];
}
}
if (tasksGroup.length > 0) {
tasksGroups.push(tasksGroup);
}
return tasksGroups;
}
function isAtomTest(s) {
return s.type === "test" || s.type === "custom";
}
function getTests(suite) {
const tests = [];
const arraySuites = toArray(suite);
for (const s of arraySuites) {
if (isAtomTest(s)) {
tests.push(s);
} else {
for (const task of s.tasks) {
if (isAtomTest(task)) {
tests.push(task);
} else {
const taskTests = getTests(task);
for (const test of taskTests) {
tests.push(test);
}
}
}
}
}
return tests;
}
function getTasks(tasks = []) {
return toArray(tasks).flatMap(
(s) => isAtomTest(s) ? [s] : [s, ...getTasks(s.tasks)]
);
}
function getSuites(suite) {
return toArray(suite).flatMap(
(s) => s.type === "suite" ? [s, ...getSuites(s.tasks)] : []
);
}
function hasTests(suite) {
return toArray(suite).some(
(s) => s.tasks.some((c) => isAtomTest(c) || hasTests(c))
);
}
function hasFailed(suite) {
return toArray(suite).some(
(s) => {
var _a;
return ((_a = s.result) == null ? void 0 : _a.state) === "fail" || s.type === "suite" && hasFailed(s.tasks);
}
);
}
function getNames(task) {
const names = [task.name];
let current = task;
while (current == null ? void 0 : current.suite) {
current = current.suite;
if (current == null ? void 0 : current.name) {
names.unshift(current.name);
}
}
if (current !== task.file) {
names.unshift(task.file.name);
}
return names;
}
function getFullName(task, separator = " > ") {
return getNames(task).join(separator);
}
function getTestName(task, separator = " > ") {
return getNames(task).slice(1).join(separator);
}
export { calculateSuiteHash as a, createFileTask as b, createChainable as c, getFullName as d, getNames as e, getSuites as f, generateHash as g, getTasks as h, interpretTaskModes as i, getTestName as j, getTests as k, limitConcurrency as l, hasFailed as m, hasTests as n, isAtomTest as o, partitionSuiteChildren as p, someTasksAreOnly as s };

259
pwa/node_modules/@vitest/runner/dist/index.d.ts generated vendored Normal file
View file

@ -0,0 +1,259 @@
import { B as BeforeAllListener, A as AfterAllListener, d as BeforeEachListener, e as AfterEachListener, f as TaskHook, O as OnTestFailedHandler, g as OnTestFinishedHandler, a as Test, C as Custom, S as Suite, h as SuiteHooks, T as Task, F as File, i as SuiteAPI, j as TestAPI, k as SuiteCollector } from './tasks-3ZnPj1LR.js';
export { D as DoneCallback, E as ExtendedContext, l as Fixture, m as FixtureFn, n as FixtureOptions, o as Fixtures, H as HookCleanupCallback, p as HookListener, I as InferFixturesTypes, R as RunMode, q as RuntimeContext, r as SequenceHooks, s as SequenceSetupFiles, t as SuiteFactory, u as TaskBase, v as TaskContext, w as TaskCustomOptions, x as TaskMeta, y as TaskPopulated, z as TaskResult, G as TaskResultPack, J as TaskState, K as TestContext, L as TestFunction, M as TestOptions, U as Use } from './tasks-3ZnPj1LR.js';
import { Awaitable } from '@vitest/utils';
import { VitestRunner } from './types.js';
export { CancelReason, VitestRunnerConfig, VitestRunnerConstructor, VitestRunnerImportSource } from './types.js';
export { processError } from '@vitest/utils/error';
import '@vitest/utils/diff';
/**
* Registers a callback function to be executed once before all tests within the current suite.
* This hook is useful for scenarios where you need to perform setup operations that are common to all tests in a suite, such as initializing a database connection or setting up a test environment.
*
* **Note:** The `beforeAll` hooks are executed in the order they are defined one after another. You can configure this by changing the `sequence.hooks` option in the config file.
*
* @param {Function} fn - The callback function to be executed before all tests.
* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used.
* @returns {void}
* @example
* ```ts
* // Example of using beforeAll to set up a database connection
* beforeAll(async () => {
* await database.connect();
* });
* ```
*/
declare function beforeAll(fn: BeforeAllListener, timeout?: number): void;
/**
* Registers a callback function to be executed once after all tests within the current suite have completed.
* This hook is useful for scenarios where you need to perform cleanup operations after all tests in a suite have run, such as closing database connections or cleaning up temporary files.
*
* **Note:** The `afterAll` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file.
*
* @param {Function} fn - The callback function to be executed after all tests.
* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used.
* @returns {void}
* @example
* ```ts
* // Example of using afterAll to close a database connection
* afterAll(async () => {
* await database.disconnect();
* });
* ```
*/
declare function afterAll(fn: AfterAllListener, timeout?: number): void;
/**
* Registers a callback function to be executed before each test within the current suite.
* This hook is useful for scenarios where you need to reset or reinitialize the test environment before each test runs, such as resetting database states, clearing caches, or reinitializing variables.
*
* **Note:** The `beforeEach` hooks are executed in the order they are defined one after another. You can configure this by changing the `sequence.hooks` option in the config file.
*
* @param {Function} fn - The callback function to be executed before each test. This function receives an `TestContext` parameter if additional test context is needed.
* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used.
* @returns {void}
* @example
* ```ts
* // Example of using beforeEach to reset a database state
* beforeEach(async () => {
* await database.reset();
* });
* ```
*/
declare function beforeEach<ExtraContext = object>(fn: BeforeEachListener<ExtraContext>, timeout?: number): void;
/**
* Registers a callback function to be executed after each test within the current suite has completed.
* This hook is useful for scenarios where you need to clean up or reset the test environment after each test runs, such as deleting temporary files, clearing test-specific database entries, or resetting mocked functions.
*
* **Note:** The `afterEach` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file.
*
* @param {Function} fn - The callback function to be executed after each test. This function receives an `TestContext` parameter if additional test context is needed.
* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used.
* @returns {void}
* @example
* ```ts
* // Example of using afterEach to delete temporary files created during a test
* afterEach(async () => {
* await fileSystem.deleteTempFiles();
* });
* ```
*/
declare function afterEach<ExtraContext = object>(fn: AfterEachListener<ExtraContext>, timeout?: number): void;
/**
* Registers a callback function to be executed when a test fails within the current suite.
* This function allows for custom actions to be performed in response to test failures, such as logging, cleanup, or additional diagnostics.
*
* **Note:** The `onTestFailed` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file.
*
* @param {Function} fn - The callback function to be executed upon a test failure. The function receives the test result (including errors).
* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used.
* @throws {Error} Throws an error if the function is not called within a test.
* @returns {void}
* @example
* ```ts
* // Example of using onTestFailed to log failure details
* onTestFailed(({ errors }) => {
* console.log(`Test failed: ${test.name}`, errors);
* });
* ```
*/
declare const onTestFailed: TaskHook<OnTestFailedHandler>;
/**
* Registers a callback function to be executed when the current test finishes, regardless of the outcome (pass or fail).
* This function is ideal for performing actions that should occur after every test execution, such as cleanup, logging, or resetting shared resources.
*
* This hook is useful if you have access to a resource in the test itself and you want to clean it up after the test finishes. It is a more compact way to clean up resources than using the combination of `beforeEach` and `afterEach`.
*
* **Note:** The `onTestFinished` hooks are running in reverse order of their registration. You can configure this by changing the `sequence.hooks` option in the config file.
*
* @param {Function} fn - The callback function to be executed after a test finishes. The function can receive parameters providing details about the completed test, including its success or failure status.
* @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used.
* @throws {Error} Throws an error if the function is not called within a test.
* @returns {void}
* @example
* ```ts
* // Example of using onTestFinished for cleanup
* const db = await connectToDatabase();
* onTestFinished(async () => {
* await db.disconnect();
* });
* ```
*/
declare const onTestFinished: TaskHook<OnTestFinishedHandler>;
declare function setFn(key: Test | Custom, fn: () => Awaitable<void>): void;
declare function getFn<Task = Test | Custom>(key: Task): () => Awaitable<void>;
declare function setHooks(key: Suite, hooks: SuiteHooks): void;
declare function getHooks(key: Suite): SuiteHooks;
declare function updateTask(task: Task, runner: VitestRunner): void;
declare function startTests(paths: string[], runner: VitestRunner): Promise<File[]>;
declare function publicCollect(paths: string[], runner: VitestRunner): Promise<File[]>;
/**
* Creates a suite of tests, allowing for grouping and hierarchical organization of tests.
* Suites can contain both tests and other suites, enabling complex test structures.
*
* @param {string} name - The name of the suite, used for identification and reporting.
* @param {Function} fn - A function that defines the tests and suites within this suite.
* @example
* ```ts
* // Define a suite with two tests
* suite('Math operations', () => {
* test('should add two numbers', () => {
* expect(add(1, 2)).toBe(3);
* });
*
* test('should subtract two numbers', () => {
* expect(subtract(5, 2)).toBe(3);
* });
* });
* ```
* @example
* ```ts
* // Define nested suites
* suite('String operations', () => {
* suite('Trimming', () => {
* test('should trim whitespace from start and end', () => {
* expect(' hello '.trim()).toBe('hello');
* });
* });
*
* suite('Concatenation', () => {
* test('should concatenate two strings', () => {
* expect('hello' + ' ' + 'world').toBe('hello world');
* });
* });
* });
* ```
*/
declare const suite: SuiteAPI;
/**
* Defines a test case with a given name and test function. The test function can optionally be configured with test options.
*
* @param {string | Function} name - The name of the test or a function that will be used as a test name.
* @param {TestOptions | TestFunction} [optionsOrFn] - Optional. The test options or the test function if no explicit name is provided.
* @param {number | TestOptions | TestFunction} [optionsOrTest] - Optional. The test function or options, depending on the previous parameters.
* @throws {Error} If called inside another test function.
* @example
* ```ts
* // Define a simple test
* test('should add two numbers', () => {
* expect(add(1, 2)).toBe(3);
* });
* ```
* @example
* ```ts
* // Define a test with options
* test('should subtract two numbers', { retry: 3 }, () => {
* expect(subtract(5, 2)).toBe(3);
* });
* ```
*/
declare const test: TestAPI;
/**
* Creates a suite of tests, allowing for grouping and hierarchical organization of tests.
* Suites can contain both tests and other suites, enabling complex test structures.
*
* @param {string} name - The name of the suite, used for identification and reporting.
* @param {Function} fn - A function that defines the tests and suites within this suite.
* @example
* ```ts
* // Define a suite with two tests
* describe('Math operations', () => {
* test('should add two numbers', () => {
* expect(add(1, 2)).toBe(3);
* });
*
* test('should subtract two numbers', () => {
* expect(subtract(5, 2)).toBe(3);
* });
* });
* ```
* @example
* ```ts
* // Define nested suites
* describe('String operations', () => {
* describe('Trimming', () => {
* test('should trim whitespace from start and end', () => {
* expect(' hello '.trim()).toBe('hello');
* });
* });
*
* describe('Concatenation', () => {
* test('should concatenate two strings', () => {
* expect('hello' + ' ' + 'world').toBe('hello world');
* });
* });
* });
* ```
*/
declare const describe: SuiteAPI;
/**
* Defines a test case with a given name and test function. The test function can optionally be configured with test options.
*
* @param {string | Function} name - The name of the test or a function that will be used as a test name.
* @param {TestOptions | TestFunction} [optionsOrFn] - Optional. The test options or the test function if no explicit name is provided.
* @param {number | TestOptions | TestFunction} [optionsOrTest] - Optional. The test function or options, depending on the previous parameters.
* @throws {Error} If called inside another test function.
* @example
* ```ts
* // Define a simple test
* it('adds two numbers', () => {
* expect(add(1, 2)).toBe(3);
* });
* ```
* @example
* ```ts
* // Define a test with options
* it('subtracts two numbers', { retry: 3 }, () => {
* expect(subtract(5, 2)).toBe(3);
* });
* ```
*/
declare const it: TestAPI;
declare function getCurrentSuite<ExtraContext = object>(): SuiteCollector<ExtraContext>;
declare function createTaskCollector(fn: (...args: any[]) => any, context?: Record<string, unknown>): TestAPI;
declare function getCurrentTest<T extends Test | Custom | undefined>(): T;
export { AfterAllListener, AfterEachListener, BeforeAllListener, BeforeEachListener, Custom, TestAPI as CustomAPI, File, OnTestFailedHandler, OnTestFinishedHandler, Suite, SuiteAPI, SuiteCollector, SuiteHooks, Task, TaskHook, Test, TestAPI, VitestRunner, afterAll, afterEach, beforeAll, beforeEach, publicCollect as collectTests, createTaskCollector, describe, getCurrentSuite, getCurrentTest, getFn, getHooks, it, onTestFailed, onTestFinished, setFn, setHooks, startTests, suite, test, updateTask };

1284
pwa/node_modules/@vitest/runner/dist/index.js generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,471 @@
import { ErrorWithDiff, Awaitable } from '@vitest/utils';
interface FixtureItem extends FixtureOptions {
prop: string;
value: any;
/**
* Indicates whether the fixture is a function
*/
isFn: boolean;
/**
* The dependencies(fixtures) of current fixture function.
*/
deps?: FixtureItem[];
}
type ChainableFunction<T extends string, F extends (...args: any) => any, C = object> = F & {
[x in T]: ChainableFunction<T, F, C>;
} & {
fn: (this: Record<T, any>, ...args: Parameters<F>) => ReturnType<F>;
} & C;
declare function createChainable<T extends string, Args extends any[], R = any>(keys: T[], fn: (this: Record<T, any>, ...args: Args) => R): ChainableFunction<T, (...args: Args) => R>;
type RunMode = 'run' | 'skip' | 'only' | 'todo';
type TaskState = RunMode | 'pass' | 'fail';
interface TaskBase {
/**
* Unique task identifier. Based on the file id and the position of the task.
* The id of the file task is based on the file path relative to root and project name.
* It will not change between runs.
* @example `1201091390`, `1201091390_0`, `1201091390_0_1`
*/
id: string;
/**
* Task name provided by the user. If no name was provided, it will be an empty string.
*/
name: string;
/**
* Task mode.
* - **skip**: task is skipped
* - **only**: only this task and other tasks with `only` mode will run
* - **todo**: task is marked as a todo, alias for `skip`
* - **run**: task will run or already ran
*/
mode: RunMode;
/**
* Custom metadata for the task. JSON reporter will save this data.
*/
meta: TaskMeta;
/**
* Whether the task was produced with `.each()` method.
*/
each?: boolean;
/**
* Whether the task should run concurrently with other tasks.
*/
concurrent?: boolean;
/**
* Whether the tasks of the suite run in a random order.
*/
shuffle?: boolean;
/**
* Suite that this task is part of. File task or the global suite will have no parent.
*/
suite?: Suite;
/**
* Result of the task. Suite and file tasks will only have the result if there
* was an error during collection or inside `afterAll`/`beforeAll`.
*/
result?: TaskResult;
/**
* The amount of times the task should be retried if it fails.
* @default 0
*/
retry?: number;
/**
* The amount of times the task should be repeated after the successful run.
* If the task fails, it will not be retried unless `retry` is specified.
* @default 0
*/
repeats?: number;
/**
* Location of the task in the file. This field is populated only if
* `includeTaskLocation` option is set. It is generated by calling `new Error`
* and parsing the stack trace, so the location might differ depending on the runtime.
*/
location?: {
line: number;
column: number;
};
}
interface TaskPopulated extends TaskBase {
/**
* File task. It's the root task of the file.
*/
file: File;
/**
* Whether the task was skipped by calling `t.skip()`.
*/
pending?: boolean;
/**
* Whether the task should succeed if it fails. If the task fails, it will be marked as passed.
*/
fails?: boolean;
/**
* Hooks that will run if the task fails. The order depends on the `sequence.hooks` option.
*/
onFailed?: OnTestFailedHandler[];
/**
* Hooks that will run after the task finishes. The order depends on the `sequence.hooks` option.
*/
onFinished?: OnTestFinishedHandler[];
/**
* Store promises (from async expects) to wait for them before finishing the test
*/
promises?: Promise<any>[];
}
/**
* Custom metadata that can be used in reporters.
*/
interface TaskMeta {
}
/**
* The result of calling a task.
*/
interface TaskResult {
/**
* State of the task. Inherits the `task.mode` during collection.
* When the task has finished, it will be changed to `pass` or `fail`.
* - **pass**: task ran successfully
* - **fail**: task failed
*/
state: TaskState;
/**
* Errors that occurred during the task execution. It is possible to have several errors
* if `expect.soft()` failed multiple times.
*/
errors?: ErrorWithDiff[];
/**
* How long in milliseconds the task took to run.
*/
duration?: number;
/**
* Time in milliseconds when the task started running.
*/
startTime?: number;
/**
* Heap size in bytes after the task finished.
* Only available if `logHeapUsage` option is set and `process.memoryUsage` is defined.
*/
heap?: number;
/**
* State of related to this task hooks. Useful during reporting.
*/
hooks?: Partial<Record<keyof SuiteHooks, TaskState>>;
/**
* The amount of times the task was retried. The task is retried only if it
* failed and `retry` option is set.
*/
retryCount?: number;
/**
* The amount of times the task was repeated. The task is repeated only if
* `repeats` option is set. This number also contains `retryCount`.
*/
repeatCount?: number;
}
/**
* The tuple representing a single task update.
* Usually reported after the task finishes.
*/
type TaskResultPack = [
/**
* Unique task identifier from `task.id`.
*/
id: string,
/**
* The result of running the task from `task.result`.
*/
result: TaskResult | undefined,
/**
* Custom metadata from `task.meta`.
*/
meta: TaskMeta
];
interface Suite extends TaskBase {
type: 'suite';
/**
* File task. It's the root task of the file.
*/
file: File;
/**
* An array of tasks that are part of the suite.
*/
tasks: Task[];
}
interface File extends Suite {
/**
* The name of the pool that the file belongs to.
* @default 'forks'
*/
pool?: string;
/**
* The path to the file in UNIX format.
*/
filepath: string;
/**
* The name of the workspace project the file belongs to.
*/
projectName: string | undefined;
/**
* The time it took to collect all tests in the file.
* This time also includes importing all the file dependencies.
*/
collectDuration?: number;
/**
* The time it took to import the setup file.
*/
setupDuration?: number;
/**
* Whether the file is initiated without running any tests.
* This is done to populate state on the server side by Vitest.
*/
local?: boolean;
}
interface Test<ExtraContext = object> extends TaskPopulated {
type: 'test';
/**
* Test context that will be passed to the test function.
*/
context: TaskContext<Test> & ExtraContext & TestContext;
}
interface Custom<ExtraContext = object> extends TaskPopulated {
type: 'custom';
/**
* Task context that will be passed to the test function.
*/
context: TaskContext<Custom> & ExtraContext & TestContext;
}
type Task = Test | Suite | Custom | File;
type DoneCallback = (error?: any) => void;
type TestFunction<ExtraContext = object> = (context: ExtendedContext<Test> & ExtraContext) => Awaitable<any> | void;
type ExtractEachCallbackArgs<T extends ReadonlyArray<any>> = {
1: [T[0]];
2: [T[0], T[1]];
3: [T[0], T[1], T[2]];
4: [T[0], T[1], T[2], T[3]];
5: [T[0], T[1], T[2], T[3], T[4]];
6: [T[0], T[1], T[2], T[3], T[4], T[5]];
7: [T[0], T[1], T[2], T[3], T[4], T[5], T[6]];
8: [T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7]];
9: [T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8]];
10: [T[0], T[1], T[2], T[3], T[4], T[5], T[6], T[7], T[8], T[9]];
fallback: Array<T extends ReadonlyArray<infer U> ? U : any>;
}[T extends Readonly<[any]> ? 1 : T extends Readonly<[any, any]> ? 2 : T extends Readonly<[any, any, any]> ? 3 : T extends Readonly<[any, any, any, any]> ? 4 : T extends Readonly<[any, any, any, any, any]> ? 5 : T extends Readonly<[any, any, any, any, any, any]> ? 6 : T extends Readonly<[any, any, any, any, any, any, any]> ? 7 : T extends Readonly<[any, any, any, any, any, any, any, any]> ? 8 : T extends Readonly<[any, any, any, any, any, any, any, any, any]> ? 9 : T extends Readonly<[any, any, any, any, any, any, any, any, any, any]> ? 10 : 'fallback'];
interface EachFunctionReturn<T extends any[]> {
/**
* @deprecated Use options as the second argument instead
*/
(name: string | Function, fn: (...args: T) => Awaitable<void>, options: TestOptions): void;
(name: string | Function, fn: (...args: T) => Awaitable<void>, options?: number | TestOptions): void;
(name: string | Function, options: TestOptions, fn: (...args: T) => Awaitable<void>): void;
}
interface TestEachFunction {
<T extends any[] | [any]>(cases: ReadonlyArray<T>): EachFunctionReturn<T>;
<T extends ReadonlyArray<any>>(cases: ReadonlyArray<T>): EachFunctionReturn<ExtractEachCallbackArgs<T>>;
<T>(cases: ReadonlyArray<T>): EachFunctionReturn<T[]>;
(...args: [TemplateStringsArray, ...any]): EachFunctionReturn<any[]>;
}
interface TestForFunctionReturn<Arg, Context> {
(name: string | Function, fn: (arg: Arg, context: Context) => Awaitable<void>): void;
(name: string | Function, options: TestOptions, fn: (args: Arg, context: Context) => Awaitable<void>): void;
}
interface TestForFunction<ExtraContext> {
<T>(cases: ReadonlyArray<T>): TestForFunctionReturn<T, ExtendedContext<Test> & ExtraContext>;
(strings: TemplateStringsArray, ...values: any[]): TestForFunctionReturn<any, ExtendedContext<Test> & ExtraContext>;
}
interface TestCollectorCallable<C = object> {
/**
* @deprecated Use options as the second argument instead
*/
<ExtraContext extends C>(name: string | Function, fn: TestFunction<ExtraContext>, options: TestOptions): void;
<ExtraContext extends C>(name: string | Function, fn?: TestFunction<ExtraContext>, options?: number | TestOptions): void;
<ExtraContext extends C>(name: string | Function, options?: TestOptions, fn?: TestFunction<ExtraContext>): void;
}
type ChainableTestAPI<ExtraContext = object> = ChainableFunction<'concurrent' | 'sequential' | 'only' | 'skip' | 'todo' | 'fails', TestCollectorCallable<ExtraContext>, {
each: TestEachFunction;
for: TestForFunction<ExtraContext>;
}>;
interface TestOptions {
/**
* Test timeout.
*/
timeout?: number;
/**
* Times to retry the test if fails. Useful for making flaky tests more stable.
* When retries is up, the last test error will be thrown.
*
* @default 0
*/
retry?: number;
/**
* How many times the test will run again.
* Only inner tests will repeat if set on `describe()`, nested `describe()` will inherit parent's repeat by default.
*
* @default 0
*/
repeats?: number;
/**
* Whether suites and tests run concurrently.
* Tests inherit `concurrent` from `describe()` and nested `describe()` will inherit from parent's `concurrent`.
*/
concurrent?: boolean;
/**
* Whether tests run sequentially.
* Tests inherit `sequential` from `describe()` and nested `describe()` will inherit from parent's `sequential`.
*/
sequential?: boolean;
/**
* Whether the test should be skipped.
*/
skip?: boolean;
/**
* Should this test be the only one running in a suite.
*/
only?: boolean;
/**
* Whether the test should be skipped and marked as a todo.
*/
todo?: boolean;
/**
* Whether the test is expected to fail. If it does, the test will pass, otherwise it will fail.
*/
fails?: boolean;
}
interface ExtendedAPI<ExtraContext> {
skipIf: (condition: any) => ChainableTestAPI<ExtraContext>;
runIf: (condition: any) => ChainableTestAPI<ExtraContext>;
}
type TestAPI<ExtraContext = object> = ChainableTestAPI<ExtraContext> & ExtendedAPI<ExtraContext> & {
extend: <T extends Record<string, any> = object>(fixtures: Fixtures<T, ExtraContext>) => TestAPI<{
[K in keyof T | keyof ExtraContext]: K extends keyof T ? T[K] : K extends keyof ExtraContext ? ExtraContext[K] : never;
}>;
};
interface FixtureOptions {
/**
* Whether to automatically set up current fixture, even though it's not being used in tests.
*/
auto?: boolean;
}
type Use<T> = (value: T) => Promise<void>;
type FixtureFn<T, K extends keyof T, ExtraContext> = (context: Omit<T, K> & ExtraContext, use: Use<T[K]>) => Promise<void>;
type Fixture<T, K extends keyof T, ExtraContext = object> = ((...args: any) => any) extends T[K] ? T[K] extends any ? FixtureFn<T, K, Omit<ExtraContext, Exclude<keyof T, K>>> : never : T[K] | (T[K] extends any ? FixtureFn<T, K, Omit<ExtraContext, Exclude<keyof T, K>>> : never);
type Fixtures<T extends Record<string, any>, ExtraContext = object> = {
[K in keyof T]: Fixture<T, K, ExtraContext & ExtendedContext<Test>> | [Fixture<T, K, ExtraContext & ExtendedContext<Test>>, FixtureOptions?];
};
type InferFixturesTypes<T> = T extends TestAPI<infer C> ? C : T;
interface SuiteCollectorCallable<ExtraContext = object> {
/**
* @deprecated Use options as the second argument instead
*/
<OverrideExtraContext extends ExtraContext = ExtraContext>(name: string | Function, fn: SuiteFactory<OverrideExtraContext>, options: TestOptions): SuiteCollector<OverrideExtraContext>;
<OverrideExtraContext extends ExtraContext = ExtraContext>(name: string | Function, fn?: SuiteFactory<OverrideExtraContext>, options?: number | TestOptions): SuiteCollector<OverrideExtraContext>;
<OverrideExtraContext extends ExtraContext = ExtraContext>(name: string | Function, options: TestOptions, fn?: SuiteFactory<OverrideExtraContext>): SuiteCollector<OverrideExtraContext>;
}
type ChainableSuiteAPI<ExtraContext = object> = ChainableFunction<'concurrent' | 'sequential' | 'only' | 'skip' | 'todo' | 'shuffle', SuiteCollectorCallable<ExtraContext>, {
each: TestEachFunction;
}>;
type SuiteAPI<ExtraContext = object> = ChainableSuiteAPI<ExtraContext> & {
skipIf: (condition: any) => ChainableSuiteAPI<ExtraContext>;
runIf: (condition: any) => ChainableSuiteAPI<ExtraContext>;
};
/**
* @deprecated
*/
type HookListener<T extends any[], Return = void> = (...args: T) => Awaitable<Return>;
/**
* @deprecated
*/
type HookCleanupCallback = unknown;
interface BeforeAllListener {
(suite: Readonly<Suite | File>): Awaitable<unknown>;
}
interface AfterAllListener {
(suite: Readonly<Suite | File>): Awaitable<unknown>;
}
interface BeforeEachListener<ExtraContext = object> {
(context: ExtendedContext<Test | Custom> & ExtraContext, suite: Readonly<Suite>): Awaitable<unknown>;
}
interface AfterEachListener<ExtraContext = object> {
(context: ExtendedContext<Test | Custom> & ExtraContext, suite: Readonly<Suite>): Awaitable<unknown>;
}
interface SuiteHooks<ExtraContext = object> {
beforeAll: BeforeAllListener[];
afterAll: AfterAllListener[];
beforeEach: BeforeEachListener<ExtraContext>[];
afterEach: AfterEachListener<ExtraContext>[];
}
interface TaskCustomOptions extends TestOptions {
/**
* Whether the task was produced with `.each()` method.
*/
each?: boolean;
/**
* Custom metadata for the task that will be assigned to `task.meta`.
*/
meta?: Record<string, unknown>;
/**
* Task fixtures.
*/
fixtures?: FixtureItem[];
/**
* Function that will be called when the task is executed.
* If nothing is provided, the runner will try to get the function using `getFn(task)`.
* If the runner cannot find the function, the task will be marked as failed.
*/
handler?: (context: TaskContext<Custom>) => Awaitable<void>;
}
interface SuiteCollector<ExtraContext = object> {
readonly name: string;
readonly mode: RunMode;
options?: TestOptions;
type: 'collector';
test: TestAPI<ExtraContext>;
tasks: (Suite | Custom<ExtraContext> | Test<ExtraContext> | SuiteCollector<ExtraContext>)[];
task: (name: string, options?: TaskCustomOptions) => Custom<ExtraContext>;
collect: (file: File) => Promise<Suite>;
clear: () => void;
on: <T extends keyof SuiteHooks<ExtraContext>>(name: T, ...fn: SuiteHooks<ExtraContext>[T]) => void;
}
type SuiteFactory<ExtraContext = object> = (test: TestAPI<ExtraContext>) => Awaitable<void>;
interface RuntimeContext {
tasks: (SuiteCollector | Test)[];
currentSuite: SuiteCollector | null;
}
/**
* User's custom test context.
*/
interface TestContext {
}
/**
* Context that's always available in the test function.
*/
interface TaskContext<Task extends Custom | Test = Custom | Test> {
/**
* Metadata of the current test
*/
task: Readonly<Task>;
/**
* Extract hooks on test failed
*/
onTestFailed: (fn: OnTestFailedHandler) => void;
/**
* Extract hooks on test failed
*/
onTestFinished: (fn: OnTestFinishedHandler) => void;
/**
* Mark tests as skipped. All execution after this call will be skipped.
* This function throws an error, so make sure you are not catching it accidentally.
*/
skip: () => void;
}
type ExtendedContext<T extends Custom | Test> = TaskContext<T> & TestContext;
type OnTestFailedHandler = (result: TaskResult) => Awaitable<void>;
type OnTestFinishedHandler = (result: TaskResult) => Awaitable<void>;
interface TaskHook<HookListener> {
(fn: HookListener, timeout?: number): void;
}
type SequenceHooks = 'stack' | 'list' | 'parallel';
type SequenceSetupFiles = 'list' | 'parallel';
export { type AfterAllListener as A, type BeforeAllListener as B, type Custom as C, type DoneCallback as D, type ExtendedContext as E, type File as F, type TaskResultPack as G, type HookCleanupCallback as H, type InferFixturesTypes as I, type TaskState as J, type TestContext as K, type TestFunction as L, type TestOptions as M, type OnTestFailedHandler as O, type RunMode as R, type Suite as S, type Task as T, type Use as U, type Test as a, type ChainableFunction as b, createChainable as c, type BeforeEachListener as d, type AfterEachListener as e, type TaskHook as f, type OnTestFinishedHandler as g, type SuiteHooks as h, type SuiteAPI as i, type TestAPI as j, type SuiteCollector as k, type Fixture as l, type FixtureFn as m, type FixtureOptions as n, type Fixtures as o, type HookListener as p, type RuntimeContext as q, type SequenceHooks as r, type SequenceSetupFiles as s, type SuiteFactory as t, type TaskBase as u, type TaskContext as v, type TaskCustomOptions as w, type TaskMeta as x, type TaskPopulated as y, type TaskResult as z };

136
pwa/node_modules/@vitest/runner/dist/types.d.ts generated vendored Normal file
View file

@ -0,0 +1,136 @@
import { DiffOptions } from '@vitest/utils/diff';
import { r as SequenceHooks, s as SequenceSetupFiles, F as File, T as Task, a as Test, C as Custom, S as Suite, G as TaskResultPack, v as TaskContext, E as ExtendedContext } from './tasks-3ZnPj1LR.js';
export { A as AfterAllListener, e as AfterEachListener, B as BeforeAllListener, d as BeforeEachListener, j as CustomAPI, D as DoneCallback, l as Fixture, m as FixtureFn, n as FixtureOptions, o as Fixtures, H as HookCleanupCallback, p as HookListener, I as InferFixturesTypes, O as OnTestFailedHandler, g as OnTestFinishedHandler, R as RunMode, q as RuntimeContext, i as SuiteAPI, k as SuiteCollector, t as SuiteFactory, h as SuiteHooks, u as TaskBase, w as TaskCustomOptions, f as TaskHook, x as TaskMeta, y as TaskPopulated, z as TaskResult, J as TaskState, j as TestAPI, K as TestContext, L as TestFunction, M as TestOptions, U as Use } from './tasks-3ZnPj1LR.js';
import '@vitest/utils';
/**
* This is a subset of Vitest config that's required for the runner to work.
*/
interface VitestRunnerConfig {
root: string;
setupFiles: string[];
name?: string;
passWithNoTests: boolean;
testNamePattern?: RegExp;
allowOnly?: boolean;
sequence: {
shuffle?: boolean;
concurrent?: boolean;
seed: number;
hooks: SequenceHooks;
setupFiles: SequenceSetupFiles;
};
chaiConfig?: {
truncateThreshold?: number;
};
maxConcurrency: number;
testTimeout: number;
hookTimeout: number;
retry: number;
includeTaskLocation?: boolean;
diffOptions?: DiffOptions;
}
type VitestRunnerImportSource = 'collect' | 'setup';
interface VitestRunnerConstructor {
new (config: VitestRunnerConfig): VitestRunner;
}
type CancelReason = 'keyboard-input' | 'test-failure' | (string & Record<string, never>);
interface VitestRunner {
/**
* First thing that's getting called before actually collecting and running tests.
*/
onBeforeCollect?: (paths: string[]) => unknown;
/**
* Called after the file task was created but not collected yet.
*/
onCollectStart?: (file: File) => unknown;
/**
* Called after collecting tests and before "onBeforeRun".
*/
onCollected?: (files: File[]) => unknown;
/**
* Called when test runner should cancel next test runs.
* Runner should listen for this method and mark tests and suites as skipped in
* "onBeforeRunSuite" and "onBeforeRunTask" when called.
*/
onCancel?: (reason: CancelReason) => unknown;
/**
* Called before running a single test. Doesn't have "result" yet.
*/
onBeforeRunTask?: (test: Task) => unknown;
/**
* Called before actually running the test function. Already has "result" with "state" and "startTime".
*/
onBeforeTryTask?: (test: Task, options: {
retry: number;
repeats: number;
}) => unknown;
/**
* When the task has finished running, but before cleanup hooks are called
*/
onTaskFinished?: (test: Test | Custom) => unknown;
/**
* Called after result and state are set.
*/
onAfterRunTask?: (test: Task) => unknown;
/**
* Called right after running the test function. Doesn't have new state yet. Will not be called, if the test function throws.
*/
onAfterTryTask?: (test: Task, options: {
retry: number;
repeats: number;
}) => unknown;
/**
* Called before running a single suite. Doesn't have "result" yet.
*/
onBeforeRunSuite?: (suite: Suite) => unknown;
/**
* Called after running a single suite. Has state and result.
*/
onAfterRunSuite?: (suite: Suite) => unknown;
/**
* If defined, will be called instead of usual Vitest suite partition and handling.
* "before" and "after" hooks will not be ignored.
*/
runSuite?: (suite: Suite) => Promise<void>;
/**
* If defined, will be called instead of usual Vitest handling. Useful, if you have your custom test function.
* "before" and "after" hooks will not be ignored.
*/
runTask?: (test: Task) => Promise<void>;
/**
* Called, when a task is updated. The same as "onTaskUpdate" in a reporter, but this is running in the same thread as tests.
*/
onTaskUpdate?: (task: TaskResultPack[]) => Promise<void>;
/**
* Called before running all tests in collected paths.
*/
onBeforeRunFiles?: (files: File[]) => unknown;
/**
* Called right after running all tests in collected paths.
*/
onAfterRunFiles?: (files: File[]) => unknown;
/**
* Called when new context for a test is defined. Useful if you want to add custom properties to the context.
* If you only want to define custom context, consider using "beforeAll" in "setupFiles" instead.
*
* This method is called for both "test" and "custom" handlers.
*
* @see https://vitest.dev/advanced/runner.html#your-task-function
*/
extendTaskContext?: <T extends Test | Custom>(context: TaskContext<T>) => ExtendedContext<T>;
/**
* Called when test and setup files are imported. Can be called in two situations: when collecting tests and when importing setup files.
*/
importFile: (filepath: string, source: VitestRunnerImportSource) => unknown;
/**
* Publicly available configuration.
*/
config: VitestRunnerConfig;
/**
* The name of the current pool. Can affect how stack trace is inferred on the server side.
*/
pool?: string;
}
export { type CancelReason, Custom, ExtendedContext, File, SequenceHooks, SequenceSetupFiles, Suite, Task, TaskContext, TaskResultPack, Test, type VitestRunner, type VitestRunnerConfig, type VitestRunnerConstructor, type VitestRunnerImportSource };

1
pwa/node_modules/@vitest/runner/dist/types.js generated vendored Normal file
View file

@ -0,0 +1 @@

34
pwa/node_modules/@vitest/runner/dist/utils.d.ts generated vendored Normal file
View file

@ -0,0 +1,34 @@
import { S as Suite, F as File, T as Task, a as Test, C as Custom } from './tasks-3ZnPj1LR.js';
export { b as ChainableFunction, c as createChainable } from './tasks-3ZnPj1LR.js';
import { Arrayable } from '@vitest/utils';
/**
* If any tasks been marked as `only`, mark all other tasks as `skip`.
*/
declare function interpretTaskModes(suite: Suite, namePattern?: string | RegExp, onlyMode?: boolean, parentIsOnly?: boolean, allowOnly?: boolean): void;
declare function someTasksAreOnly(suite: Suite): boolean;
declare function generateHash(str: string): string;
declare function calculateSuiteHash(parent: Suite): void;
declare function createFileTask(filepath: string, root: string, projectName: string | undefined, pool?: string): File;
/**
* Return a function for running multiple async operations with limited concurrency.
*/
declare function limitConcurrency(concurrency?: number): <Args extends unknown[], T>(func: (...args: Args) => PromiseLike<T> | T, ...args: Args) => Promise<T>;
/**
* Partition in tasks groups by consecutive concurrent
*/
declare function partitionSuiteChildren(suite: Suite): Task[][];
declare function isAtomTest(s: Task): s is Test | Custom;
declare function getTests(suite: Arrayable<Task>): (Test | Custom)[];
declare function getTasks(tasks?: Arrayable<Task>): Task[];
declare function getSuites(suite: Arrayable<Task>): Suite[];
declare function hasTests(suite: Arrayable<Suite>): boolean;
declare function hasFailed(suite: Arrayable<Task>): boolean;
declare function getNames(task: Task): string[];
declare function getFullName(task: Task, separator?: string): string;
declare function getTestName(task: Task, separator?: string): string;
export { calculateSuiteHash, createFileTask, generateHash, getFullName, getNames, getSuites, getTasks, getTestName, getTests, hasFailed, hasTests, interpretTaskModes, isAtomTest, limitConcurrency, partitionSuiteChildren, someTasksAreOnly };

4
pwa/node_modules/@vitest/runner/dist/utils.js generated vendored Normal file
View file

@ -0,0 +1,4 @@
export { a as calculateSuiteHash, c as createChainable, b as createFileTask, g as generateHash, d as getFullName, e as getNames, f as getSuites, h as getTasks, j as getTestName, k as getTests, m as hasFailed, n as hasTests, i as interpretTaskModes, o as isAtomTest, l as limitConcurrency, p as partitionSuiteChildren, s as someTasksAreOnly } from './chunk-tasks.js';
import '@vitest/utils/error';
import 'pathe';
import '@vitest/utils';

48
pwa/node_modules/@vitest/runner/package.json generated vendored Normal file
View file

@ -0,0 +1,48 @@
{
"name": "@vitest/runner",
"type": "module",
"version": "2.1.9",
"description": "Vitest test runner",
"license": "MIT",
"funding": "https://opencollective.com/vitest",
"homepage": "https://github.com/vitest-dev/vitest/tree/main/packages/runner#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/vitest-dev/vitest.git",
"directory": "packages/runner"
},
"bugs": {
"url": "https://github.com/vitest-dev/vitest/issues"
},
"sideEffects": true,
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./utils": {
"types": "./dist/utils.d.ts",
"default": "./dist/utils.js"
},
"./types": {
"types": "./dist/types.d.ts",
"default": "./dist/types.js"
},
"./*": "./*"
},
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"*.d.ts",
"dist"
],
"dependencies": {
"pathe": "^1.1.2",
"@vitest/utils": "2.1.9"
},
"scripts": {
"build": "rimraf dist && rollup -c",
"dev": "rollup -c --watch"
}
}

1
pwa/node_modules/@vitest/runner/types.d.ts generated vendored Normal file
View file

@ -0,0 +1 @@
export * from './dist/types.js'

1
pwa/node_modules/@vitest/runner/utils.d.ts generated vendored Normal file
View file

@ -0,0 +1 @@
export * from './dist/utils.js'