Set up comprehensive frontend testing infrastructure

- Install Jest for unit testing with React Testing Library
- Install Playwright for end-to-end testing
- Configure Jest with proper TypeScript support and module mapping
- Create test setup files and utilities for both unit and e2e tests

Components:
* Jest configuration with coverage thresholds
* Playwright configuration with browser automation
* Unit tests for LoginForm, AuthContext, and useSocketIO hook
* E2E tests for authentication, dashboard, and agents workflows
* GitHub Actions workflow for automated testing
* Mock data and API utilities for consistent testing
* Test documentation with best practices

Testing features:
- Unit tests with 70% coverage threshold
- E2E tests with API mocking and user journey testing
- CI/CD integration for automated test runs
- Cross-browser testing support with Playwright
- Authentication system testing end-to-end

🚀 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-07-11 14:06:34 +10:00
parent c6d69695a8
commit aacb45156b
6109 changed files with 777927 additions and 1 deletions

21
frontend/node_modules/napi-postinstall/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021-present UnTS
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.

147
frontend/node_modules/napi-postinstall/README.md generated vendored Normal file
View File

@@ -0,0 +1,147 @@
# napi-postinstall
[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/un-ts/napi-postinstall/ci.yml?branch=main)](https://github.com/un-ts/napi-postinstall/actions/workflows/ci.yml?query=branch%3Amain)
[![Codecov](https://img.shields.io/codecov/c/github/un-ts/napi-postinstall.svg)](https://codecov.io/gh/un-ts/napi-postinstall)
[![type-coverage](https://img.shields.io/badge/dynamic/json.svg?label=type-coverage&prefix=%E2%89%A5&suffix=%&query=$.typeCoverage.atLeast&uri=https%3A%2F%2Fraw.githubusercontent.com%2Fun-ts%2Fnapi-postinstall%2Fmain%2Fpackage.json)](https://github.com/plantain-00/type-coverage)
[![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/un-ts/napi-postinstall)](https://coderabbit.ai)
[![npm](https://img.shields.io/npm/v/napi-postinstall.svg)](https://www.npmjs.com/package/napi-postinstall)
[![GitHub Release](https://img.shields.io/github/release/un-ts/napi-postinstall)](https://github.com/un-ts/napi-postinstall/releases)
[![Conventional Commits](https://img.shields.io/badge/conventional%20commits-1.0.0-yellow.svg)](https://conventionalcommits.org)
[![Renovate enabled](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![Code Style: Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
[![changesets](https://img.shields.io/badge/maintained%20with-changesets-176de3.svg)](https://github.com/changesets/changesets)
The `postinstall` script helper for handling native bindings in legacy `npm` versions, this is a reimplementation of the [`node-install`][node-install] functionality from [`esbuild`][esbuild] for [`napi-rs`][napi-rs] ecosystem packages like [`rollup`][rollup], [`@swc/core`][swc-core] and [`unrs-resolver`][unrs-resolver].
For more details, please refer to the following issues:
- [npm/cli#4828](https://github.com/npm/cli/issues/4828) -- root cause
- [napi-rs/napi-rs#2569](https://github.com/napi-rs/napi-rs/issues/2569)
- [unrs/unrs-resolver#56](https://github.com/unrs/unrs-resolver/issues/56)
## TOC <!-- omit in toc -->
- [Usage](#usage)
- [Install](#install)
- [CLI](#cli)
- [API](#api)
- [Types](#types)
- [Example](#example)
- [Sponsors and Backers](#sponsors-and-backers)
- [Sponsors](#sponsors)
- [Backers](#backers)
- [Changelog](#changelog)
- [License](#license)
## Usage
### Install
```sh
# pnpm
pnpm add napi-postinstall
# yarn
yarn add napi-postinstall
# npm
npm i napi-postinstall
# bun
bun add napi-postinstall
```
### CLI
```sh
napi-postinstall unrs-resolver #<napi-package-name>
```
You can put it into `scripts#postinstall` of your `package.json`:
```json
{
"scripts": {
"postinstall": "napi-postinstall unrs-resolver"
}
}
```
This will check and prepare the napi binding packages for you automatically.
### API
#### Types
```ts
// napi-postinstall
export interface PackageJson {
name: string
version: string
}
export declare function checkAndPreparePackage(
packageNameOrPackageJson: PackageJson | string,
checkVersion?: boolean,
): Promise<void>
// napi-postinstall/fallback
declare function fallback<T = unknown>(
packageJsonPath: string,
checkVersion?: boolean,
): T
export = fallback
```
#### Example
```js
// index.js
const { checkAndPreparePackage, isNpm } = require('napi-postinstall')
if (isNpm()) {
void checkAndPreparePackage('unrs-resolver' /* <napi-package-name> */)
}
// fallback.js
module.exports = require('napi-postinstall/fallback')(
require.resolve('../package.json') /* <napi-package-json-path> */,
true /* <check-version> */,
)
```
## Sponsors and Backers
[![Sponsors](https://raw.githubusercontent.com/1stG/static/master/sponsors.svg)](https://github.com/sponsors/JounQin)
### Sponsors
| 1stG | RxTS | UnTS |
| ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| [![1stG Open Collective sponsors](https://opencollective.com/1stG/organizations.svg)](https://opencollective.com/1stG) | [![RxTS Open Collective sponsors](https://opencollective.com/rxts/organizations.svg)](https://opencollective.com/rxts) | [![UnTS Open Collective sponsors](https://opencollective.com/unts/organizations.svg)](https://opencollective.com/unts) |
### Backers
| 1stG | RxTS | UnTS |
| ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| [![1stG Open Collective backers](https://opencollective.com/1stG/individuals.svg)](https://opencollective.com/1stG) | [![RxTS Open Collective backers](https://opencollective.com/rxts/individuals.svg)](https://opencollective.com/rxts) | [![UnTS Open Collective backers](https://opencollective.com/unts/individuals.svg)](https://opencollective.com/unts) |
## Changelog
Detailed changes for each release are documented in [CHANGELOG.md](./CHANGELOG.md).
## License
[MIT][] © [JounQin][]@[1stG.me][]
[node-install]: https://github.com/evanw/esbuild/blob/4475787eef4c4923b92b9fa37ebba1c88b9e1d9b/lib/npm/node-install.ts
[esbuild]: https://github.com/evanw/esbuild
[napi-rs]: https://github.com/napi-rs/napi-rs
[rollup]: https://github.com/rollup/rollup
[swc-core]: https://github.com/swc-project/swc
[unrs-resolver]: https://github.com/unrs/unrs-resolver
[1stG.me]: https://www.1stG.me
[JounQin]: https://github.com/JounQin
[MIT]: http://opensource.org/licenses/MIT

2
frontend/node_modules/napi-postinstall/lib/cli.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
#!/usr/bin/env node
export {};

6
frontend/node_modules/napi-postinstall/lib/cli.js generated vendored Executable file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/env node
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const index_js_1 = require("./index.js");
void (0, index_js_1.checkAndPreparePackage)(process.argv[2], process.argv[3], ['1', 'check', 'true', 'yes'].includes(process.argv[4]));
//# sourceMappingURL=cli.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAmD;AAEnD,KAAK,IAAA,iCAAsB,EACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EACf,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CACxD,CAAA"}

View File

@@ -0,0 +1,9 @@
import type { PackageJson } from './types.js';
export declare const DEFAULT_NPM_REGISTRY = "https://registry.npmjs.org/";
export declare const meta: PackageJson;
export declare const LOG_PREFIX: string;
export declare const WASM32 = "wasm32";
export declare const WASI = "wasi";
export declare const WASM32_WASI = "wasm32-wasi";
export declare const EABI = "eabi";
export declare const PACKAGE_JSON = "package.json";

View File

@@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PACKAGE_JSON = exports.EABI = exports.WASM32_WASI = exports.WASI = exports.WASM32 = exports.LOG_PREFIX = exports.meta = exports.DEFAULT_NPM_REGISTRY = void 0;
const path = require("node:path");
exports.DEFAULT_NPM_REGISTRY = 'https://registry.npmjs.org/';
exports.meta = require(path.resolve(__dirname, '../package.json'));
const { name, version } = exports.meta;
exports.LOG_PREFIX = `[${name}@${version}] `;
exports.WASM32 = 'wasm32';
exports.WASI = 'wasi';
exports.WASM32_WASI = `${exports.WASM32}-${exports.WASI}`;
exports.EABI = 'eabi';
exports.PACKAGE_JSON = 'package.json';
//# sourceMappingURL=constants.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";;;AAAA,kCAAiC;AAIpB,QAAA,oBAAoB,GAAG,6BAA6B,CAAA;AAEpD,QAAA,IAAI,GAAG,OAAO,CACzB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAC5B,CAAA;AAEhB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,YAAI,CAAA;AAEjB,QAAA,UAAU,GAAG,IAAI,IAAI,IAAI,OAAO,IAAI,CAAA;AAEpC,QAAA,MAAM,GAAG,QAAQ,CAAA;AACjB,QAAA,IAAI,GAAG,MAAM,CAAA;AACb,QAAA,WAAW,GAAG,GAAG,cAAM,IAAI,YAAI,EAAE,CAAA;AAEjC,QAAA,IAAI,GAAG,MAAM,CAAA;AAEb,QAAA,YAAY,GAAG,cAAc,CAAA"}

View File

@@ -0,0 +1,2 @@
declare function fallback<T = unknown>(packageJsonPath: string, checkVersion?: boolean): T;
export = fallback;

74
frontend/node_modules/napi-postinstall/lib/fallback.js generated vendored Normal file
View File

@@ -0,0 +1,74 @@
"use strict";
const node_child_process_1 = require("node:child_process");
const fs = require("node:fs");
const os = require("node:os");
const path = require("node:path");
const constants_js_1 = require("./constants.js");
const helpers_js_1 = require("./helpers.js");
const EXECUTORS = {
npm: 'npx',
pnpm: 'pnpm',
yarn: 'yarn',
bun: 'bun',
deno: (args) => ['deno', 'run', `npm:${args[0]}`, ...args.slice(1)],
};
function constructCommand(value, args) {
const list = typeof value === 'function'
? value(args)
:
[].concat(value, args);
return {
command: list[0],
args: list.slice(1),
};
}
function fallback(packageJsonPath, checkVersion) {
const packageJson = require(packageJsonPath);
const { name, version: pkgVersion, optionalDependencies } = packageJson;
const { napi, version = pkgVersion } = (0, helpers_js_1.getNapiInfoFromPackageJson)(packageJson, checkVersion);
if (checkVersion && pkgVersion !== version) {
throw new Error((0, helpers_js_1.errorMessage)(`Inconsistent package versions found for \`${name}\` v${pkgVersion} vs \`${napi.packageName}\` v${version}.`));
}
if (process.versions.webcontainer) {
const bindingPkgName = `${napi.packageName}-${constants_js_1.WASM32_WASI}`;
if (!optionalDependencies?.[bindingPkgName]) {
throw new Error((0, helpers_js_1.errorMessage)(`\`${constants_js_1.WASM32_WASI}\` target is unavailable for \`${name}\` v${version}`));
}
const baseDir = path.resolve(os.tmpdir(), `${name}-${version}`);
const bindingEntry = path.resolve(baseDir, `node_modules/${bindingPkgName}/${napi.binaryName}.wasi.cjs`);
if (!fs.existsSync(bindingEntry)) {
fs.rmSync(baseDir, { recursive: true, force: true });
fs.mkdirSync(baseDir, { recursive: true });
const bindingPkg = `${bindingPkgName}@${version}`;
console.log((0, helpers_js_1.errorMessage)(`Downloading \`${bindingPkg}\` on WebContainer...`));
(0, node_child_process_1.execFileSync)('pnpm', ['i', bindingPkg], {
cwd: baseDir,
stdio: 'inherit',
});
}
return require(bindingEntry);
}
const userAgent = ((process.env.npm_config_user_agent || '').split('/')[0] ||
'npm');
const executor = EXECUTORS[userAgent];
if (!executor) {
throw new Error((0, helpers_js_1.errorMessage)(`Unsupported package manager: ${userAgent}. Supported managers are: ${Object.keys(EXECUTORS).join(', ')}.`));
}
const { command, args } = constructCommand(executor, [
'napi-postinstall',
name,
version,
checkVersion ? '1' : '0',
]);
const pkgDir = path.dirname(packageJsonPath);
(0, node_child_process_1.execFileSync)(command, args, {
cwd: pkgDir,
stdio: 'inherit',
});
process.env[`SKIP_${name.replace(/-/g, '_').toUpperCase()}_FALLBACK`] = '1';
const PKG_RESOLVED_PATH = require.resolve(pkgDir);
delete require.cache[PKG_RESOLVED_PATH];
return require(pkgDir);
}
module.exports = fallback;
//# sourceMappingURL=fallback.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"fallback.js","sourceRoot":"","sources":["../src/fallback.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,13 @@
import type { NapiInfo, PackageJson } from './types.js';
export declare function getGlobalNpmRegistry(): string;
export declare function removeRecursive(dir: string): void;
export declare function downloadedNodePath(name: string, subpath: string): string;
export declare function getNapiInfoFromPackageJson(packageJson: PackageJson, checkVersion: true): NapiInfo & {
version: string;
};
export declare function getNapiInfoFromPackageJson(packageJson: PackageJson, checkVersion?: boolean): NapiInfo;
export declare function getNapiNativeTarget(): string[] | string;
export declare function getNapiNativeTargets(): string[];
export declare function getErrorMessage(err: unknown): string;
export declare function errorLog(message: string, ...args: unknown[]): void;
export declare function errorMessage(message: string, extra?: string): string;

234
frontend/node_modules/napi-postinstall/lib/helpers.js generated vendored Normal file
View File

@@ -0,0 +1,234 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getGlobalNpmRegistry = getGlobalNpmRegistry;
exports.removeRecursive = removeRecursive;
exports.downloadedNodePath = downloadedNodePath;
exports.getNapiInfoFromPackageJson = getNapiInfoFromPackageJson;
exports.getNapiNativeTarget = getNapiNativeTarget;
exports.getNapiNativeTargets = getNapiNativeTargets;
exports.getErrorMessage = getErrorMessage;
exports.errorLog = errorLog;
exports.errorMessage = errorMessage;
const node_child_process_1 = require("node:child_process");
const fs = require("node:fs");
const path = require("node:path");
const constants_js_1 = require("./constants.js");
const target_js_1 = require("./target.js");
function getGlobalNpmRegistry() {
try {
const registry = (0, node_child_process_1.execSync)('npm config get registry', {
encoding: 'utf8',
}).trim();
return registry.endsWith('/') ? registry : `${registry}/`;
}
catch {
return constants_js_1.DEFAULT_NPM_REGISTRY;
}
}
function removeRecursive(dir) {
for (const entry of fs.readdirSync(dir)) {
const entryPath = path.join(dir, entry);
let stats;
try {
stats = fs.lstatSync(entryPath);
}
catch {
continue;
}
if (stats.isDirectory()) {
removeRecursive(entryPath);
}
else {
fs.unlinkSync(entryPath);
}
}
fs.rmdirSync(dir);
}
function downloadedNodePath(name, subpath) {
const pkgLibDir = path.dirname(require.resolve(name + '/package.json'));
return path.join(pkgLibDir, path.basename(subpath));
}
function getNapiInfoFromPackageJson(packageJson, checkVersion) {
const { name, napi: napi_, optionalDependencies } = packageJson;
const targets = napi_?.targets ?? napi_?.triples?.additional;
if (!targets?.length) {
throw new Error(errorMessage(`No \`napi.targets\` nor \`napi.triples.additional\` field found in \`${name}\`'s \`package.json\`. Please ensure the package is built with NAPI support.`));
}
const napi = napi_;
napi.binaryName ?? (napi.binaryName = napi.name);
napi.packageName ?? (napi.packageName = napi.package?.name ?? name);
napi.targets = targets;
if (!optionalDependencies) {
return { napi };
}
let version;
for (const target of targets) {
const { platformArchABI } = (0, target_js_1.parseTriple)(target);
const pkg = `${napi.packageName}-${platformArchABI}`;
const packageVersion = optionalDependencies[pkg];
if (!packageVersion) {
continue;
}
if (version) {
if (checkVersion && version !== packageVersion) {
throw new Error(errorMessage(`Inconsistent package versions found for \`${name}\` with \`${pkg}\` v${packageVersion} vs v${version}.`));
}
}
else if (packageVersion) {
version = packageVersion;
if (!checkVersion) {
break;
}
}
}
return { napi, version };
}
function isMusl() {
let musl = false;
if (process.platform === 'linux') {
musl = isMuslFromFilesystem();
if (musl === null) {
musl = isMuslFromReport();
}
if (musl === null) {
musl = isMuslFromChildProcess();
}
}
return musl;
}
const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-');
function isMuslFromFilesystem() {
try {
return fs.readFileSync('/usr/bin/ldd', 'utf8').includes('musl');
}
catch {
return null;
}
}
function isMuslFromReport() {
let report = null;
if (typeof process.report.getReport === 'function') {
process.report.excludeNetwork = true;
report = process.report.getReport();
}
if (!report) {
return null;
}
if ('header' in report &&
report.header != null &&
typeof report.header === 'object' &&
'glibcVersionRuntime' in report.header &&
report.header.glibcVersionRuntime) {
return false;
}
return ('sharedObjects' in report &&
Array.isArray(report.sharedObjects) &&
report.sharedObjects.some(isFileMusl));
}
function isMuslFromChildProcess() {
try {
return (0, node_child_process_1.execSync)('ldd --version', { encoding: 'utf8' }).includes('musl');
}
catch {
return false;
}
}
function getNapiNativeTarget() {
switch (process.platform) {
case 'android': {
if (process.arch === 'arm64') {
return 'android-arm64';
}
if (process.arch === 'arm') {
return 'android-arm-eabi';
}
break;
}
case 'win32': {
if (process.arch === 'x64') {
return 'win32-x64-msvc';
}
if (process.arch === 'ia32') {
return 'win32-ia32-msvc';
}
if (process.arch === 'arm64') {
return 'win32-arm64-msvc';
}
break;
}
case 'darwin': {
const targets = ['darwin-universal'];
if (process.arch === 'x64') {
targets.push('darwin-x64');
}
else if (process.arch === 'arm64') {
targets.push('darwin-arm64');
}
return targets;
}
case 'freebsd': {
if (process.arch === 'x64') {
return 'freebsd-x64';
}
if (process.arch === 'arm64') {
return 'freebsd-arm64';
}
break;
}
case 'linux': {
if (process.arch === 'x64') {
if (isMusl()) {
return 'linux-x64-musl';
}
return 'linux-x64-gnu';
}
if (process.arch === 'arm64') {
if (isMusl()) {
return 'linux-arm64-musl';
}
return 'linux-arm64-gnu';
}
if (process.arch === 'arm') {
if (isMusl()) {
return 'linux-arm-musleabihf';
}
return 'linux-arm-gnueabihf';
}
if (process.arch === 'riscv64') {
if (isMusl()) {
return 'linux-riscv64-musl';
}
return 'linux-riscv64-gnu';
}
if (process.arch === 'ppc64') {
return 'linux-ppc64-gnu';
}
if (process.arch === 's390x') {
return 'linux-s390x-gnu';
}
break;
}
}
return [];
}
const WASI_TARGET = 'wasm32-wasi';
function getNapiNativeTargets() {
if (process.versions.webcontainer) {
return [WASI_TARGET];
}
const targets = getNapiNativeTarget();
if (Array.isArray(targets)) {
return [...targets, WASI_TARGET];
}
return [targets, WASI_TARGET];
}
function getErrorMessage(err) {
return err?.message || String(err);
}
function errorLog(message, ...args) {
console.error(`${constants_js_1.LOG_PREFIX}${message}`, ...args);
}
function errorMessage(message, extra) {
return `${constants_js_1.LOG_PREFIX}${message}` + (extra ? ': ' + extra : '');
}
//# sourceMappingURL=helpers.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
import type { PackageJson } from './types.js';
export type * from './types.js';
export declare function isNpm(): boolean | undefined;
export declare function isPnp(): boolean;
export declare function checkAndPreparePackage(packageName: string, version?: string, checkVersion?: boolean): Promise<void>;
export declare function checkAndPreparePackage(packageJson: PackageJson, checkVersion?: boolean): Promise<void>;

240
frontend/node_modules/napi-postinstall/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,240 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isNpm = isNpm;
exports.isPnp = isPnp;
exports.checkAndPreparePackage = checkAndPreparePackage;
const node_child_process_1 = require("node:child_process");
const fs = require("node:fs");
const https = require("node:https");
const path = require("node:path");
const zlib = require("node:zlib");
const constants_js_1 = require("./constants.js");
const helpers_js_1 = require("./helpers.js");
const REDIRECT_STATUS_CODES = new Set([301, 302, 307, 308]);
function fetch(url) {
return new Promise((resolve, reject) => {
https
.get(url, res => {
if (REDIRECT_STATUS_CODES.has(res.statusCode) &&
res.headers.location) {
fetch(res.headers.location).then(resolve, reject);
return;
}
if (res.statusCode !== 200) {
return reject(new Error(`Server responded with ${res.statusCode}`));
}
const chunks = [];
res.on('data', (chunk) => chunks.push(chunk));
res.on('end', () => resolve(Buffer.concat(chunks)));
})
.on('error', reject);
});
}
function extractFileFromTarGzip(buffer, subpath) {
try {
buffer = zlib.unzipSync(buffer);
}
catch (err) {
throw new Error((0, helpers_js_1.errorMessage)(`Invalid gzip data in archive`, (0, helpers_js_1.getErrorMessage)(err)));
}
const str = (i, n) => String.fromCodePoint(...buffer.subarray(i, i + n)).replace(/\0.*$/, '');
let offset = 0;
subpath = `package/${subpath}`;
while (offset < buffer.length) {
const name = str(offset, 100);
const size = Number.parseInt(str(offset + 124, 12), 8);
offset += 512;
if (!Number.isNaN(size)) {
if (name === subpath) {
return buffer.subarray(offset, offset + size);
}
offset += (size + 511) & ~511;
}
}
throw new Error((0, helpers_js_1.errorMessage)(`Could not find \`${subpath}\` in archive`));
}
function isNpm() {
return process.env.npm_config_user_agent?.startsWith('npm/');
}
function isPnp() {
return !!process.versions.pnp;
}
function installUsingNPM(hostPkg, pkg, version, target, subpath, nodePath) {
const isWasm32Wasi = target === constants_js_1.WASM32_WASI;
const env = { ...process.env, npm_config_global: undefined };
const pkgDir = path.dirname(require.resolve(hostPkg + `/${constants_js_1.PACKAGE_JSON}`));
const installDir = path.join(pkgDir, 'npm-install');
try {
fs.mkdirSync(installDir, { recursive: true });
}
catch (err) {
const error = err;
if (error.code === 'EROFS') {
(0, helpers_js_1.errorLog)(`Failed to create the temporary directory on read-only location: ${error.message}`);
(0, helpers_js_1.errorLog)(`You have to install \`${pkg}\` manually in this case.`);
return;
}
throw err;
}
try {
const packageJsonPath = path.join(installDir, constants_js_1.PACKAGE_JSON);
fs.writeFileSync(packageJsonPath, '{}');
(0, node_child_process_1.execSync)(`npm install --loglevel=error --prefer-offline --no-audit --progress=false${isWasm32Wasi ? ` --cpu=${constants_js_1.WASM32} --force` : ''} ${pkg}@${version}`, { cwd: installDir, stdio: 'pipe', env });
if (isWasm32Wasi) {
fs.unlinkSync(packageJsonPath);
}
const nodeModulesDir = path.join(installDir, 'node_modules');
try {
if (isWasm32Wasi) {
const newNodeModulesDir = path.resolve(installDir, '../node_modules');
const dirs = fs.readdirSync(nodeModulesDir);
for (const dir of dirs) {
if (dir.startsWith('@')) {
const newPath = path.join(newNodeModulesDir, dir);
fs.mkdirSync(newPath, { recursive: true });
const subdir = path.join(nodeModulesDir, dir);
const nestedDirs = fs.readdirSync(subdir);
for (const nestedDir of nestedDirs) {
try {
fs.renameSync(path.join(subdir, nestedDir), path.join(newPath, nestedDir));
}
catch {
}
}
}
else {
try {
fs.renameSync(path.join(nodeModulesDir, dir), path.join(newNodeModulesDir, dir));
}
catch {
}
}
}
}
else {
const newPath = path.resolve(pkgDir, hostPkg
.split('/')
.map(() => '..')
.join('/'), pkg);
fs.mkdirSync(newPath, { recursive: true });
fs.renameSync(path.join(nodeModulesDir, pkg), newPath);
}
}
catch {
fs.renameSync(path.join(nodeModulesDir, pkg, subpath), nodePath);
}
}
finally {
try {
(0, helpers_js_1.removeRecursive)(installDir);
}
catch {
}
}
}
async function downloadDirectlyFromNPM(pkg, version, subpath, nodePath) {
const url = `${(0, helpers_js_1.getGlobalNpmRegistry)()}${pkg}/-/${pkg.startsWith('@') ? pkg.split('/')[1] : pkg}-${version}.tgz`;
(0, helpers_js_1.errorLog)(`Trying to download ${JSON.stringify(url)}`);
try {
fs.writeFileSync(nodePath, extractFileFromTarGzip(await fetch(url), subpath));
}
catch (err) {
(0, helpers_js_1.errorLog)(`Failed to download ${JSON.stringify(url)}`, (0, helpers_js_1.getErrorMessage)(err));
throw err;
}
}
async function checkAndPreparePackage(packageNameOrPackageJson, versionOrCheckVersion, checkVersion) {
let packageJson;
if (typeof packageNameOrPackageJson === 'string') {
try {
packageJson = require(packageNameOrPackageJson + `/${constants_js_1.PACKAGE_JSON}`);
}
catch {
if (typeof versionOrCheckVersion !== 'string') {
throw new TypeError((0, helpers_js_1.errorMessage)(`Failed to load \`${constants_js_1.PACKAGE_JSON}\` from \`${packageNameOrPackageJson}\`, please provide a version.`));
}
const pkg = packageNameOrPackageJson;
const packageJsonBuffer = await fetch(`${(0, helpers_js_1.getGlobalNpmRegistry)()}${pkg}/${versionOrCheckVersion}`);
packageJson = JSON.parse(packageJsonBuffer.toString('utf8'));
}
}
else {
packageJson = packageNameOrPackageJson;
if (checkVersion === undefined &&
typeof versionOrCheckVersion === 'boolean') {
checkVersion = versionOrCheckVersion;
}
}
const { name, version: pkgVersion, optionalDependencies } = packageJson;
const { napi, version = pkgVersion } = (0, helpers_js_1.getNapiInfoFromPackageJson)(packageJson, checkVersion);
if (checkVersion && pkgVersion !== version) {
throw new Error((0, helpers_js_1.errorMessage)(`Inconsistent package versions found for \`${name}\` v${pkgVersion} vs \`${napi.packageName}\` v${version}.`));
}
const targets = (0, helpers_js_1.getNapiNativeTargets)();
for (const target of targets) {
const pkg = `${napi.packageName}-${target}`;
if (!optionalDependencies?.[pkg]) {
continue;
}
const isWasm32Wasi = target === constants_js_1.WASM32_WASI;
const binaryPrefix = napi.binaryName ? `${napi.binaryName}.` : '';
const subpath = `${binaryPrefix}${target}.${isWasm32Wasi ? 'wasm' : 'node'}`;
try {
require.resolve(`${pkg}/${subpath}`);
break;
}
catch {
try {
require.resolve(`${name}/${subpath}`);
break;
}
catch { }
if (isPnp()) {
if (isWasm32Wasi) {
try {
(0, node_child_process_1.execSync)(`yarn add -D ${pkg}@${version}`);
}
catch (err) {
(0, helpers_js_1.errorLog)(`Failed to install package \`${pkg}\` automatically in the yarn P'n'P environment`, (0, helpers_js_1.getErrorMessage)(err));
(0, helpers_js_1.errorLog)("You'll have to install it manually in this case.");
}
}
return;
}
if (!isNpm()) {
(0, helpers_js_1.errorLog)(`Failed to find package "${pkg}" on the file system
This can happen if you use the "--no-optional" flag. The "optionalDependencies"
${constants_js_1.PACKAGE_JSON} feature is used by ${name} to install the correct napi binary
for your current platform. This install script will now attempt to work around
this. If that fails, you need to remove the "--no-optional" flag to use ${name}.
`);
}
let nodePath;
try {
nodePath = (0, helpers_js_1.downloadedNodePath)(name, subpath);
}
catch {
const nodeModulesDir = path.resolve(require.resolve(constants_js_1.meta.name + `/${constants_js_1.PACKAGE_JSON}`), '../..');
nodePath = path.join(nodeModulesDir, name, subpath);
fs.mkdirSync(path.dirname(nodePath), { recursive: true });
}
try {
(0, helpers_js_1.errorLog)(`Trying to install package "${pkg}" using npm`);
installUsingNPM(name, pkg, version, target, subpath, nodePath);
break;
}
catch (err) {
(0, helpers_js_1.errorLog)(`Failed to install package "${pkg}" using npm`, (0, helpers_js_1.getErrorMessage)(err));
try {
await downloadDirectlyFromNPM(pkg, version, subpath, nodePath);
break;
}
catch (err) {
throw new Error((0, helpers_js_1.errorMessage)(`Failed to install package "${pkg}"`, (0, helpers_js_1.getErrorMessage)(err)));
}
}
}
}
}
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,2 @@
import type { Target } from './types.js';
export declare function parseTriple(rawTriple: string): Target;

56
frontend/node_modules/napi-postinstall/lib/target.js generated vendored Normal file
View File

@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseTriple = parseTriple;
const constants_js_1 = require("./constants.js");
const CpuToNodeArch = {
x86_64: 'x64',
aarch64: 'arm64',
i686: 'ia32',
armv7: 'arm',
riscv64gc: 'riscv64',
powerpc64le: 'ppc64',
};
const SysToNodePlatform = {
linux: 'linux',
freebsd: 'freebsd',
darwin: 'darwin',
windows: 'win32',
};
function parseTriple(rawTriple) {
if (rawTriple === constants_js_1.WASM32_WASI ||
rawTriple === `${constants_js_1.WASM32_WASI}-preview1-threads` ||
rawTriple.startsWith(`${constants_js_1.WASM32}-${constants_js_1.WASI}p`)) {
return {
triple: rawTriple,
platformArchABI: constants_js_1.WASM32_WASI,
platform: constants_js_1.WASI,
arch: constants_js_1.WASM32,
abi: constants_js_1.WASI,
};
}
const triple = rawTriple.endsWith(constants_js_1.EABI)
? `${rawTriple.slice(0, -4)}-${constants_js_1.EABI}`
: rawTriple;
const triples = triple.split('-');
let cpu;
let sys;
let abi = null;
if (triples.length === 2) {
;
[cpu, sys] = triples;
}
else {
;
[cpu, , sys, abi = null] = triples;
}
const platform = SysToNodePlatform[sys] ?? sys;
const arch = CpuToNodeArch[cpu] ?? cpu;
return {
triple: rawTriple,
platformArchABI: abi ? `${platform}-${arch}-${abi}` : `${platform}-${arch}`,
platform,
arch,
abi,
};
}
//# sourceMappingURL=target.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"target.js","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":";;AAqCA,kCA0CC;AA7ED,iDAAgE;AAGhE,MAAM,aAAa,GAA+B;IAChD,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE,MAAM;IACZ,KAAK,EAAE,KAAK;IACZ,SAAS,EAAE,SAAS;IACpB,WAAW,EAAE,OAAO;CACrB,CAAA;AAED,MAAM,iBAAiB,GAA6B;IAClD,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,OAAO,EAAE,OAAO;CACjB,CAAA;AAkBD,SAAgB,WAAW,CAAC,SAAiB;IAC3C,IACE,SAAS,KAAK,0BAAW;QACzB,SAAS,KAAK,GAAG,0BAAW,mBAAmB;QAC/C,SAAS,CAAC,UAAU,CAAC,GAAG,qBAAM,IAAI,mBAAI,GAAG,CAAC,EAC1C,CAAC;QACD,OAAO;YACL,MAAM,EAAE,SAAS;YACjB,eAAe,EAAE,0BAAW;YAC5B,QAAQ,EAAE,mBAAI;YACd,IAAI,EAAE,qBAAM;YACZ,GAAG,EAAE,mBAAI;SACV,CAAA;IACH,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,mBAAI,CAAC;QACrC,CAAC,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,mBAAI,EAAE;QACrC,CAAC,CAAC,SAAS,CAAA;IACb,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACjC,IAAI,GAAW,CAAA;IACf,IAAI,GAAW,CAAA;IACf,IAAI,GAAG,GAAkB,IAAI,CAAA;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAGzB,CAAC;QAAA,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,OAAO,CAAA;IACvB,CAAC;SAAM,CAAC;QAKN,CAAC;QAAA,CAAC,GAAG,EAAE,AAAD,EAAG,GAAG,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,OAAO,CAAA;IACrC,CAAC;IAED,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAK,GAAgB,CAAA;IAC5D,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,IAAK,GAAkB,CAAA;IACtD,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,eAAe,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,IAAI,EAAE;QAC3E,QAAQ;QACR,IAAI;QACJ,GAAG;KACJ,CAAA;AACH,CAAC"}

37
frontend/node_modules/napi-postinstall/lib/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,37 @@
export interface Napi {
binaryName?: string;
name?: string;
packageName?: string;
package?: {
name: string;
};
targets?: string[];
triples?: {
defaults?: boolean;
additional?: string[];
};
wasm?: {
browser?: {
fs?: boolean;
};
};
}
export interface NapiInfo {
napi: Napi;
version?: string;
}
export interface PackageJson {
name: string;
version: string;
optionalDependencies?: Partial<Record<string, string>>;
napi?: Napi;
}
export type Platform = NodeJS.Platform | 'wasi' | 'wasm';
export type NodeJSArch = NodeJS.Architecture | 'universal' | 'wasm32' | 'x32';
export interface Target {
triple: string;
platformArchABI: string;
platform: Platform;
arch: NodeJSArch;
abi: string | null;
}

3
frontend/node_modules/napi-postinstall/lib/types.js generated vendored Normal file
View File

@@ -0,0 +1,3 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}

32
frontend/node_modules/napi-postinstall/package.json generated vendored Normal file
View File

@@ -0,0 +1,32 @@
{
"name": "napi-postinstall",
"version": "0.3.0",
"type": "commonjs",
"description": "The `postinstall` script helper for handling native bindings in legacy `npm` versions",
"repository": "git+https://github.com/un-ts/napi-postinstall.git",
"author": "JounQin <admin@1stg.me> (https://www.1stG.me)",
"funding": "https://opencollective.com/napi-postinstall",
"license": "MIT",
"engines": {
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
},
"bin": "./lib/cli.js",
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"exports": {
".": {
"types": "./lib/index.d.ts",
"default": "./lib/index.js"
},
"./fallback": {
"types": "./lib/fallback.d.ts",
"default": "./lib/fallback.js"
},
"./package.json": "./package.json"
},
"files": [
"lib",
"!**/*.tsbuildinfo"
],
"packageManager": "npm@11.4.2+sha512.f90c1ec8b207b625d6edb6693aef23dacb39c38e4217fe8c46a973f119cab392ac0de23fe3f07e583188dae9fd9108b3845ad6f525b598742bd060ebad60bff3"
}