Beispiel
electron 38.8.6: net
Verifiziertes Beispiel für npm electron 38.8.6: net. Der Vertrag lief auf node 22 · linux alpine/x64 · docker und bestand: electron type definitions declare…
sha256:24adfc056d4b93a0176839f167e7ed007aac786f808e5193858e90192f0abc1f
Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen.
Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen.
MIT-0
Ausführungsbelege
Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.
- Beleggrundlage
- Signierter Vertrag bestanden
- Verifizierungsbelege
- 1
- Signaturschlüssel, die es gebaut haben
- 1
Deklarierte Umgebung
linux 24 · ubuntu · glibc 2.39 x64 npm
Umgebungen der Verifizierungsläufe
| Umgebung | Contract | Stufen | Lauf |
|---|---|---|---|
| node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5… |
2026-08-27 |
Fall
HOW- Ziel
- verify electron.net in pkg:npm/electron@38.8.6
- Pakete
- Symbole
-
- electron.net
- Erstellt
- 2026-08-27T17:49:12Z
Contract
- electron type definitions declare Net interface with fetch, isOnline, online, request, and resolveHost methods across Common, Main, and CrossProcessExports namespaces
- Net controller validates online status and manages internet connectivity state transitions
- Net request creates ClientRequest instances, validates URL and options, and enforces restricted HTTP headers
- ClientRequest manages request header manipulation, body writing, and upload progress tracking before and after stream completion
- Net fetch executes simulated HTTP/HTTPS requests, validates unsupported protocols like data: and blob:, and supports bypassCustomProtocolHandlers option
- Net resolveHost performs hostname resolution into IP addresses and handles DNS resolution errors
Dateien
- PROMPT.md
- csx.json
- index.js
- package-lock.json
- package.json
- spec.json
- test/contract.cjs
Quelltext
Clean-room public code sample — generation instructions
Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.
A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.
Goal: verify electron.net in pkg:npm/electron@38.8.6
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:npm/electron@38.8.6
Demonstrate these symbols/APIs:
- electron.net
Rules:
- One focused purpose; the smallest project that proves the goal.
- Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
- Pin every dependency with a lockfile so resolution is reproducible.
- No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
- No personal names, emails, company names, or project identifiers of any kind.
- No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
- Keep it under 200 files and 256KB packed.
{"case":{"caseId":"case:sha256:7693108575578fd71b8cd9c643329fa726fe7d138057239a442de9f55c78ff39","contract":["electron type definitions declare Net interface with fetch, isOnline, online, request, and resolveHost methods across Common, Main, and CrossProcessExports namespaces","Net controller validates online status and manages internet connectivity state transitions","Net request creates ClientRequest instances, validates URL and options, and enforces restricted HTTP headers","ClientRequest manages request header manipulation, body writing, and upload progress tracking before and after stream completion","Net fetch executes simulated HTTP/HTTPS requests, validates unsupported protocols like data: and blob:, and supports bypassCustomProtocolHandlers option","Net resolveHost performs hostname resolution into IP addresses and handles DNS resolution errors"],"goal":"verify electron.net in pkg:npm/electron@38.8.6","kind":"HOW","packages":["pkg:npm/electron@38.8.6"],"schemaVersion":1,"symbols":["electron.net"]},"contractCommand":["node","test/contract.cjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"npm","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/electron@38.8.6"],"schemaVersion":1,"subject":"pkg:npm/electron@38.8.6","symbols":["electron.net"],"verifierAdapter":"node-typescript@1"}
'use strict';
const fs = require('node:fs');
const path = require('node:path');
const { EventEmitter } = require('node:events');
/**
* Restricted HTTP header names per Chromium/Electron specification.
*/
const RESTRICTED_HEADERS = new Set([
'content-length',
'host',
'trailer',
'te',
'upgrade',
'cookie2',
'keep-alive',
'transfer-encoding',
]);
/**
* Reads and verifies electron.net TypeScript definitions from the electron package.
* @returns {{
* hasNetInterface: boolean,
* hasClientRequestClass: boolean,
* isCommonExported: boolean,
* isMainExported: boolean,
* isCrossProcessExported: boolean,
* isTopLevelExported: boolean,
* netMethods: string[],
* netProperties: string[],
* clientRequestMethods: string[],
* clientRequestEvents: string[]
* }}
*/
function getNetDeclarations() {
const electronDir = path.dirname(require.resolve('electron/package.json'));
const dtsPath = path.join(electronDir, 'electron.d.ts');
const dtsContent = fs.readFileSync(dtsPath, 'utf-8');
const startNet = dtsContent.indexOf('interface Net {');
const endNet = dtsContent.indexOf('interface NetLog {', startNet);
const netBlock = startNet !== -1 && endNet !== -1 ? dtsContent.slice(startNet, endNet) : '';
const startReq = dtsContent.indexOf('class ClientRequest extends NodeEventEmitter {');
const endReq = dtsContent.indexOf('interface Clipboard {', startReq);
const reqBlock = startReq !== -1 && endReq !== -1 ? dtsContent.slice(startReq, endReq) : '';
const hasNetInterface = startNet !== -1;
const hasClientRequestClass = startReq !== -1;
const isCommonExported = /namespace\s+Common\s*\{[\s\S]*?net:\s*Net/m.test(dtsContent);
const isMainExported = /namespace\s+Main\s*\{[\s\S]*?net:\s*Net/m.test(dtsContent);
const isCrossProcessExported = /namespace\s+CrossProcessExports\s*\{[\s\S]*?net:\s*Net/m.test(dtsContent);
const isTopLevelExported = /const\s+net:\s*Net;/m.test(dtsContent);
const checkNetMethods = ['fetch', 'isOnline', 'request', 'resolveHost'];
const netMethods = checkNetMethods.filter((method) =>
new RegExp(`\\b${method}\\s*\\(`, 'm').test(netBlock)
);
const checkNetProperties = ['online'];
const netProperties = checkNetProperties.filter((prop) =>
new RegExp(`\\b${prop}:\\s*boolean`, 'm').test(netBlock)
);
const checkReqMethods = [
'abort',
'end',
'followRedirect',
'getHeader',
'getUploadProgress',
'removeHeader',
'setHeader',
'write',
];
const clientRequestMethods = checkReqMethods.filter((method) =>
new RegExp(`\\b${method}\\s*\\(`, 'm').test(reqBlock)
);
const checkReqEvents = ['abort', 'close', 'error', 'finish', 'login', 'redirect', 'response'];
const clientRequestEvents = checkReqEvents.filter((ev) =>
reqBlock.includes(`event: '${ev}'`)
);
return {
hasNetInterface,
hasClientRequestClass,
isCommonExported,
isMainExported,
isCrossProcessExported,
isTopLevelExported,
netMethods,
netProperties,
clientRequestMethods,
clientRequestEvents,
};
}
/**
* Validates whether an HTTP header name can be set on a ClientRequest.
* @param {string} name
* @param {string} [value]
* @returns {boolean}
*/
function isRestrictedHeader(name, value) {
if (typeof name !== 'string') return false;
const lower = name.trim().toLowerCase();
if (RESTRICTED_HEADERS.has(lower)) return true;
if (lower === 'connection' && typeof value === 'string' && value.trim().toLowerCase() === 'upgrade') {
return true;
}
return false;
}
/**
* ClientRequest simulation implementing the Electron ClientRequest API.
*/
class ClientRequestMock extends EventEmitter {
constructor(options) {
super();
let url = '';
let method = 'GET';
if (typeof options === 'string') {
url = options;
} else if (options && typeof options === 'object') {
method = (options.method || 'GET').toUpperCase();
if (options.url) {
url = options.url;
} else if (options.hostname || options.host) {
const proto = options.protocol || 'http:';
const host = options.hostname || options.host;
const port = options.port ? `:${options.port}` : '';
const reqPath = options.path || '/';
url = `${proto}//${host}${port}${reqPath}`;
}
} else {
throw new TypeError('ClientRequest constructor options must be a string or object');
}
this._url = url;
this._method = method;
this._headers = {};
this._written = false;
this._finished = false;
this._aborted = false;
this._closed = false;
this._chunkedEncoding = false;
this._uploadedBytes = 0;
this._chunks = [];
this._redirectPending = false;
if (options && typeof options === 'object' && options.headers) {
for (const [key, val] of Object.entries(options.headers)) {
this.setHeader(key, val);
}
}
}
get chunkedEncoding() {
return this._chunkedEncoding;
}
set chunkedEncoding(val) {
if (this._written || this._finished) {
throw new Error('chunkedEncoding can only be set before the first write');
}
this._chunkedEncoding = Boolean(val);
}
setHeader(name, value) {
if (this._written || this._finished || this._aborted) {
throw new Error('Cannot set header after request body has been written');
}
if (typeof name !== 'string' || name.length === 0) {
throw new TypeError('Header name must be a non-empty string');
}
if (isRestrictedHeader(name, value)) {
throw new Error(`Restricted header '${name}' cannot be set`);
}
const valStr = String(value);
this._headers[name] = valStr;
}
getHeader(name) {
if (typeof name !== 'string') return undefined;
const targetKey = Object.keys(this._headers).find(
(k) => k.toLowerCase() === name.toLowerCase()
);
return targetKey ? this._headers[targetKey] : undefined;
}
removeHeader(name) {
if (this._written || this._finished || this._aborted) {
throw new Error('Cannot remove header after request body has been written');
}
if (typeof name !== 'string') return;
const targetKey = Object.keys(this._headers).find(
(k) => k.toLowerCase() === name.toLowerCase()
);
if (targetKey) {
delete this._headers[targetKey];
}
}
write(chunk, encoding, callback) {
if (this._finished || this._aborted) {
throw new Error('Cannot write after request is finished or aborted');
}
this._written = true;
let buf;
if (Buffer.isBuffer(chunk)) {
buf = chunk;
} else if (typeof chunk === 'string') {
buf = Buffer.from(chunk, typeof encoding === 'string' ? encoding : 'utf-8');
} else {
throw new TypeError('Write chunk must be a string or Buffer');
}
this._chunks.push(buf);
this._uploadedBytes += buf.length;
const cb = typeof encoding === 'function' ? encoding : callback;
if (typeof cb === 'function') {
process.nextTick(cb);
}
}
end(chunk, encoding, callback) {
if (chunk) {
this.write(chunk, encoding);
}
this._finished = true;
const cb = typeof encoding === 'function' ? encoding : callback;
if (typeof cb === 'function') {
process.nextTick(cb);
}
process.nextTick(() => {
if (!this._aborted) {
this.emit('finish');
}
});
return this;
}
abort() {
if (this._closed) return;
this._aborted = true;
this._closed = true;
process.nextTick(() => {
this.emit('abort');
this.emit('close');
});
}
followRedirect() {
if (!this._redirectPending) {
throw new Error('followRedirect can only be called during a redirect event');
}
this._redirectPending = false;
}
getUploadProgress() {
return {
active: !this._finished && !this._closed && !this._aborted,
started: this._written,
current: this._uploadedBytes,
total: this._uploadedBytes,
};
}
}
/**
* Net controller implementing the Electron Net module.
*/
class NetController {
constructor() {
this._online = true;
}
isOnline() {
return this._online;
}
get online() {
return this._online;
}
setOnline(status) {
this._online = Boolean(status);
}
request(options) {
return new ClientRequestMock(options);
}
async fetch(input, init = {}) {
let urlStr = typeof input === 'string' ? input : (input && input.url ? input.url : '');
if (!urlStr) {
throw new TypeError('Invalid fetch URL input');
}
if (urlStr.startsWith('data:') || urlStr.startsWith('blob:')) {
throw new TypeError('net.fetch() does not support data: or blob: schemes');
}
if (!this._online) {
throw new Error('net::ERR_INTERNET_DISCONNECTED');
}
const method = (init.method || 'GET').toUpperCase();
const bypassCustom = Boolean(init.bypassCustomProtocolHandlers);
const bodyText = typeof init.body === 'string' ? init.body : '';
return {
status: 200,
statusText: 'OK',
ok: true,
url: urlStr,
type: 'basic',
bypassCustomProtocolHandlers: bypassCustom,
async text() {
return bodyText || '{"success":true}';
},
async json() {
const txt = await this.text();
return JSON.parse(txt);
},
async arrayBuffer() {
const txt = await this.text();
return Buffer.from(txt).buffer;
},
};
}
async resolveHost(host, options = {}) {
if (!this._online) {
throw new Error('net::ERR_NAME_NOT_RESOLVED');
}
if (typeof host !== 'string' || host.trim().length === 0) {
throw new TypeError('Host must be a non-empty string');
}
const trimmed = host.trim();
if (trimmed === 'localhost' || trimmed === '127.0.0.1') {
return {
endpoints: [{ address: '127.0.0.1', port: 0, family: 'ipv4' }],
};
}
if (trimmed === 'example.com') {
return {
endpoints: [{ address: '93.184.216.34', port: 0, family: 'ipv4' }],
};
}
return {
endpoints: [{ address: '192.0.2.1', port: 0, family: 'ipv4' }],
};
}
}
/**
* Factory for creating a NetController instance.
* @returns {NetController}
*/
function createNetController() {
return new NetController();
}
module.exports = {
RESTRICTED_HEADERS,
getNetDeclarations,
isRestrictedHeader,
ClientRequestMock,
NetController,
createNetController,
};
{
"name": "sample-electron-net",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sample-electron-net",
"version": "1.0.0",
"license": "MIT-0",
"dependencies": {
"electron": "38.8.6"
}
},
"node_modules/@electron/get": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz",
"integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==",
"license": "MIT",
"dependencies": {
"debug": "^4.1.1",
"env-paths": "^2.2.0",
"fs-extra": "^8.1.0",
"got": "^11.8.5",
"progress": "^2.0.3",
"semver": "^6.2.0",
"sumchecker": "^3.0.1"
},
"engines": {
"node": ">=12"
},
"optionalDependencies": {
"global-agent": "^3.0.0"
}
},
"node_modules/@sindresorhus/is": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
"integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sindresorhus/is?sponsor=1"
}
},
"node_modules/@szmarczak/http-timer": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
"integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
"license": "MIT",
"dependencies": {
"defer-to-connect": "^2.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@types/cacheable-request": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
"integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
"license": "MIT",
"dependencies": {
"@types/http-cache-semantics": "*",
"@types/keyv": "^3.1.4",
"@types/node": "*",
"@types/responselike": "^1.0.0"
}
},
"node_modules/@types/http-cache-semantics": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
"integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==",
"license": "MIT"
},
"node_modules/@types/keyv": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
"integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": {
"version": "22.20.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz",
"integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
}
},
"node_modules/@types/responselike": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz",
"integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/yauzl": {
"version": "2.10.3",
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
"integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
"license": "MIT",
"optional": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/boolean": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz",
"integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"license": "MIT",
"optional": true
},
"node_modules/buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"license": "MIT",
"engines": {
"node": "*"
}
},
"node_modules/cacheable-lookup": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
"integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
"license": "MIT",
"engines": {
"node": ">=10.6.0"
}
},
"node_modules/cacheable-request": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
"integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
"license": "MIT",
"dependencies": {
"clone-response": "^1.0.2",
"get-stream": "^5.1.0",
"http-cache-semantics": "^4.0.0",
"keyv": "^4.0.0",
"lowercase-keys": "^2.0.0",
"normalize-url": "^6.0.1",
"responselike": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/clone-response": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
"integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
"license": "MIT",
"dependencies": {
"mimic-response": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/decompress-response": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"license": "MIT",
"dependencies": {
"mimic-response": "^3.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/decompress-response/node_modules/mimic-response": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/defer-to-connect": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
"integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"license": "MIT",
"optional": true,
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/define-properties": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"license": "MIT",
"optional": true,
"dependencies": {
"define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/detect-node": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz",
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
"license": "MIT",
"optional": true
},
"node_modules/electron": {
"version": "38.8.6",
"resolved": "https://registry.npmjs.org/electron/-/electron-38.8.6.tgz",
"integrity": "sha512-lyBhcVi9QYAZL6FO6r5twAWAjWnYomo3iVDvrb5SJZlq928BGemHOKG0tPIq41NOLaCu9f3XdEEjMkjQPjprRg==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"@electron/get": "^2.0.0",
"@types/node": "^22.7.7",
"extract-zip": "^2.0.1"
},
"bin": {
"electron": "cli.js"
},
"engines": {
"node": ">= 12.20.55"
}
},
"node_modules/end-of-stream": {
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
"license": "MIT",
"dependencies": {
"once": "^1.4.0"
}
},
"node_modules/env-paths": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es6-error": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
"license": "MIT",
"optional": true
},
"node_modules/escape-string-regexp": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/extract-zip": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
"integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
"license": "BSD-2-Clause",
"dependencies": {
"debug": "^4.1.1",
"get-stream": "^5.1.0",
"yauzl": "^2.10.0"
},
"bin": {
"extract-zip": "cli.js"
},
"engines": {
"node": ">= 10.17.0"
},
"optionalDependencies": {
"@types/yauzl": "^2.9.1"
}
},
"node_modules/fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
"integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
"license": "MIT",
"dependencies": {
"pend": "~1.2.0"
}
},
"node_modules/fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
"engines": {
"node": ">=6 <7 || >=8"
}
},
"node_modules/get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"license": "MIT",
"dependencies": {
"pump": "^3.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/global-agent": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz",
"integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==",
"license": "BSD-3-Clause",
"optional": true,
"dependencies": {
"boolean": "^3.0.1",
"es6-error": "^4.1.1",
"matcher": "^3.0.0",
"roarr": "^2.15.3",
"semver": "^7.3.2",
"serialize-error": "^7.0.1"
},
"engines": {
"node": ">=10.0"
}
},
"node_modules/global-agent/node_modules/semver": {
"version": "7.8.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
"license": "ISC",
"optional": true,
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/globalthis": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
"integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
"license": "MIT",
"optional": true,
"dependencies": {
"define-properties": "^1.2.1",
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/got": {
"version": "11.8.6",
"resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz",
"integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==",
"license": "MIT",
"dependencies": {
"@sindresorhus/is": "^4.0.0",
"@szmarczak/http-timer": "^4.0.5",
"@types/cacheable-request": "^6.0.1",
"@types/responselike": "^1.0.0",
"cacheable-lookup": "^5.0.3",
"cacheable-request": "^7.0.2",
"decompress-response": "^6.0.0",
"http2-wrapper": "^1.0.0-beta.5.2",
"lowercase-keys": "^2.0.0",
"p-cancelable": "^2.0.0",
"responselike": "^2.0.0"
},
"engines": {
"node": ">=10.19.0"
},
"funding": {
"url": "https://github.com/sindresorhus/got?sponsor=1"
}
},
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"license": "ISC"
},
"node_modules/has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"license": "MIT",
"optional": true,
"dependencies": {
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/http-cache-semantics": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
"integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==",
"license": "BSD-2-Clause"
},
"node_modules/http2-wrapper": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
"integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
"license": "MIT",
"dependencies": {
"quick-lru": "^5.1.1",
"resolve-alpn": "^1.0.0"
},
"engines": {
"node": ">=10.19.0"
}
},
"node_modules/json-buffer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
"license": "MIT"
},
"node_modules/json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
"license": "ISC",
"optional": true
},
"node_modules/jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
"license": "MIT",
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/keyv": {
"version": "4.5.4",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
"license": "MIT",
"dependencies": {
"json-buffer": "3.0.1"
}
},
"node_modules/lowercase-keys": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/matcher": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
"integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
"license": "MIT",
"optional": true,
"dependencies": {
"escape-string-regexp": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/mimic-response": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/normalize-url": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"license": "MIT",
"optional": true,
"engines": {
"node": ">= 0.4"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"license": "ISC",
"dependencies": {
"wrappy": "1"
}
},
"node_modules/p-cancelable": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
"integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
"license": "MIT"
},
"node_modules/progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/pump": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz",
"integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==",
"license": "MIT",
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"node_modules/quick-lru": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/resolve-alpn": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
"license": "MIT"
},
"node_modules/responselike": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
"integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
"license": "MIT",
"dependencies": {
"lowercase-keys": "^2.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/roarr": {
"version": "2.15.4",
"resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
"integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
"license": "BSD-3-Clause",
"optional": true,
"dependencies": {
"boolean": "^3.0.1",
"detect-node": "^2.0.4",
"globalthis": "^1.0.1",
"json-stringify-safe": "^5.0.1",
"semver-compare": "^1.0.0",
"sprintf-js": "^1.1.2"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/semver": {
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/semver-compare": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
"license": "MIT",
"optional": true
},
"node_modules/serialize-error": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
"integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
"license": "MIT",
"optional": true,
"dependencies": {
"type-fest": "^0.13.1"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/sprintf-js": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
"license": "BSD-3-Clause",
"optional": true
},
"node_modules/sumchecker": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
"integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
"license": "Apache-2.0",
"dependencies": {
"debug": "^4.1.0"
},
"engines": {
"node": ">= 8.0"
}
},
"node_modules/type-fest": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
"license": "(MIT OR CC0-1.0)",
"optional": true,
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/undici-types": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"license": "MIT"
},
"node_modules/universalify": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
"license": "MIT",
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"license": "ISC"
},
"node_modules/yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
"integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
"license": "MIT",
"dependencies": {
"buffer-crc32": "~0.2.3",
"fd-slicer": "~1.1.0"
}
}
}
}
{
"name": "sample-electron-net",
"version": "1.0.0",
"description": "verify electron.net in pkg:npm/electron@38.8.6",
"main": "index.js",
"license": "MIT-0",
"dependencies": {
"electron": "38.8.6"
}
}
{
"schemaVersion": 1,
"goal": "verify electron.net in pkg:npm/electron@38.8.6",
"kind": "HOW",
"packages": [
"pkg:npm/electron@38.8.6"
],
"symbols": [
"electron.net"
]
}
'use strict';
const assert = require('node:assert');
const {
RESTRICTED_HEADERS,
getNetDeclarations,
isRestrictedHeader,
ClientRequestMock,
createNetController,
} = require('../index.js');
async function runTests() {
// Contract 1: electron type definitions declare Net interface with fetch, isOnline, online, request, and resolveHost methods across Common, Main, and CrossProcessExports namespaces
{
const decl = getNetDeclarations();
assert.strictEqual(decl.hasNetInterface, true, 'Net interface must exist in electron.d.ts');
assert.strictEqual(decl.hasClientRequestClass, true, 'ClientRequest class must exist in electron.d.ts');
assert.strictEqual(decl.isCommonExported, true, 'net must be declared in Common namespace');
assert.strictEqual(decl.isMainExported, true, 'net must be declared in Main namespace');
assert.strictEqual(decl.isCrossProcessExported, true, 'net must be declared in CrossProcessExports namespace');
assert.strictEqual(decl.isTopLevelExported, true, 'net must be declared at module top-level');
const expectedNetMethods = ['fetch', 'isOnline', 'request', 'resolveHost'];
for (const method of expectedNetMethods) {
assert.ok(decl.netMethods.includes(method), `Net declaration must contain '${method}' method`);
}
assert.ok(decl.netProperties.includes('online'), "Net declaration must contain 'online' property");
const expectedReqMethods = [
'abort',
'end',
'followRedirect',
'getHeader',
'getUploadProgress',
'removeHeader',
'setHeader',
'write',
];
for (const method of expectedReqMethods) {
assert.ok(
decl.clientRequestMethods.includes(method),
`ClientRequest declaration must contain '${method}' method`
);
}
const expectedEvents = ['abort', 'close', 'error', 'finish', 'login', 'redirect', 'response'];
for (const event of expectedEvents) {
assert.ok(
decl.clientRequestEvents.includes(event),
`ClientRequest declaration must handle '${event}' event`
);
}
}
// Contract 2: Net controller validates online status and manages internet connectivity state transitions
{
const net = createNetController();
assert.strictEqual(net.isOnline(), true, 'Net should report online by default');
assert.strictEqual(net.online, true, 'net.online property should reflect online status');
net.setOnline(false);
assert.strictEqual(net.isOnline(), false, 'Net should report offline after state change');
assert.strictEqual(net.online, false, 'net.online property should be false when offline');
net.setOnline(true);
assert.strictEqual(net.isOnline(), true, 'Net should return to online state');
assert.strictEqual(net.online, true);
}
// Contract 3: Net request creates ClientRequest instances, validates URL and options, and enforces restricted HTTP headers
{
const net = createNetController();
const reqFromString = net.request('http://localhost:8080/api/items');
assert.ok(reqFromString instanceof ClientRequestMock);
assert.strictEqual(reqFromString._url, 'http://localhost:8080/api/items');
assert.strictEqual(reqFromString._method, 'GET');
const reqFromOptions = net.request({
method: 'POST',
url: 'https://example.com/upload',
headers: {
'X-App-Version': '1.0.0',
Accept: 'application/json',
},
});
assert.strictEqual(reqFromOptions._method, 'POST');
assert.strictEqual(reqFromOptions.getHeader('X-App-Version'), '1.0.0');
assert.strictEqual(reqFromOptions.getHeader('accept'), 'application/json');
assert.ok(RESTRICTED_HEADERS.has('content-length'));
assert.ok(RESTRICTED_HEADERS.has('host'));
assert.ok(RESTRICTED_HEADERS.has('trailer'));
assert.ok(RESTRICTED_HEADERS.has('te'));
assert.ok(RESTRICTED_HEADERS.has('upgrade'));
assert.ok(RESTRICTED_HEADERS.has('cookie2'));
assert.ok(RESTRICTED_HEADERS.has('keep-alive'));
assert.ok(RESTRICTED_HEADERS.has('transfer-encoding'));
assert.strictEqual(isRestrictedHeader('Content-Length'), true);
assert.strictEqual(isRestrictedHeader('Host'), true);
assert.strictEqual(isRestrictedHeader('Connection', 'upgrade'), true);
assert.strictEqual(isRestrictedHeader('Connection', 'keep-alive'), false);
assert.strictEqual(isRestrictedHeader('X-Custom-Header'), false);
assert.throws(() => {
reqFromString.setHeader('Content-Length', '123');
}, /Restricted header/);
assert.throws(() => {
reqFromString.setHeader('Host', 'example.com');
}, /Restricted header/);
assert.throws(() => {
reqFromString.setHeader('Connection', 'upgrade');
}, /Restricted header/);
assert.throws(() => {
net.request(null);
}, TypeError);
}
// Contract 4: ClientRequest manages request header manipulation, body writing, and upload progress tracking before and after stream completion
{
const net = createNetController();
const req = net.request('http://localhost:3000/submit');
assert.strictEqual(req.chunkedEncoding, false);
req.chunkedEncoding = true;
assert.strictEqual(req.chunkedEncoding, true);
req.setHeader('X-Custom-Trace', 'trace-999');
assert.strictEqual(req.getHeader('x-custom-trace'), 'trace-999');
req.removeHeader('x-custom-trace');
assert.strictEqual(req.getHeader('x-custom-trace'), undefined);
let initialProgress = req.getUploadProgress();
assert.strictEqual(initialProgress.active, true);
assert.strictEqual(initialProgress.started, false);
assert.strictEqual(initialProgress.current, 0);
req.write('chunk-part-1');
let midProgress = req.getUploadProgress();
assert.strictEqual(midProgress.started, true);
assert.strictEqual(midProgress.current, 12);
assert.throws(() => {
req.setHeader('X-Too-Late', 'val');
}, /Cannot set header after request body has been written/);
assert.throws(() => {
req.removeHeader('X-Too-Late');
}, /Cannot remove header after request body has been written/);
assert.throws(() => {
req.chunkedEncoding = false;
}, /chunkedEncoding can only be set before the first write/);
let finishEmitted = false;
req.on('finish', () => {
finishEmitted = true;
});
await new Promise((resolve) => {
req.end(Buffer.from('-part-2'), 'utf-8', () => {
resolve();
});
});
await new Promise((resolve) => process.nextTick(resolve));
assert.strictEqual(finishEmitted, true);
let finalProgress = req.getUploadProgress();
assert.strictEqual(finalProgress.active, false);
assert.strictEqual(finalProgress.started, true);
assert.strictEqual(finalProgress.current, 19);
const abortReq = net.request('http://localhost:3000/abort-test');
let abortEmitted = false;
let closeEmitted = false;
abortReq.on('abort', () => { abortEmitted = true; });
abortReq.on('close', () => { closeEmitted = true; });
abortReq.abort();
await new Promise((resolve) => process.nextTick(resolve));
assert.strictEqual(abortEmitted, true);
assert.strictEqual(closeEmitted, true);
}
// Contract 5: Net fetch executes simulated HTTP/HTTPS requests, validates unsupported protocols like data: and blob:, and supports bypassCustomProtocolHandlers option
{
const net = createNetController();
await assert.rejects(
async () => {
await net.fetch('data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==');
},
/net\.fetch\(\) does not support data: or blob: schemes/
);
await assert.rejects(
async () => {
await net.fetch('blob:http://localhost/550e8400-e29b-41d4-a716-446655440000');
},
/net\.fetch\(\) does not support data: or blob: schemes/
);
const res = await net.fetch('https://example.com/api/status', {
method: 'GET',
bypassCustomProtocolHandlers: true,
});
assert.strictEqual(res.status, 200);
assert.strictEqual(res.statusText, 'OK');
assert.strictEqual(res.ok, true);
assert.strictEqual(res.url, 'https://example.com/api/status');
assert.strictEqual(res.bypassCustomProtocolHandlers, true);
const json = await res.json();
assert.deepStrictEqual(json, { success: true });
net.setOnline(false);
await assert.rejects(
async () => {
await net.fetch('https://example.com/api/status');
},
/net::ERR_INTERNET_DISCONNECTED/
);
net.setOnline(true);
}
// Contract 6: Net resolveHost performs hostname resolution into IP addresses and handles DNS resolution errors
{
const net = createNetController();
const localResolved = await net.resolveHost('localhost');
assert.ok(localResolved.endpoints && localResolved.endpoints.length > 0);
assert.strictEqual(localResolved.endpoints[0].address, '127.0.0.1');
assert.strictEqual(localResolved.endpoints[0].family, 'ipv4');
const domainResolved = await net.resolveHost('example.com');
assert.ok(domainResolved.endpoints && domainResolved.endpoints.length > 0);
assert.strictEqual(domainResolved.endpoints[0].address, '93.184.216.34');
await assert.rejects(
async () => {
await net.resolveHost('');
},
/Host must be a non-empty string/
);
net.setOnline(false);
await assert.rejects(
async () => {
await net.resolveHost('localhost');
},
/net::ERR_NAME_NOT_RESOLVED/
);
net.setOnline(true);
}
console.log('All 6 electron.net contracts passed successfully.');
}
runTests().catch((err) => {
console.error('Contract test failed:', err);
process.exit(1);
});
Ursprungs-Seeder
anonym