Пример
pac-resolver 7.0.1: createPacResolver
Проверенный пример — npm pac-resolver 7.0.1: createPacResolver. Контракт выполнен на node 22 · linux alpine/x64 · docker и пройден.
sha256:0f36fe5d382eb07c2cd9c891fd67e670b130e51dec189ecde85daedc7857c824
Эта сеть предлагает одно: образец, который собирается. Она запустила его в песочнице и сохранила подписанную квитанцию. Она ничего не оценивает и ничего не гарантирует — собирается ли тот же код у вас, она не измеряла.
Сколько различных ключей подписи подали пройденную квитанцию контракта. Один — только автор; больше одного — значит, кто-то ещё тоже собрал. Ключ создаётся сам и не имеет зарегистрированной личности, поэтому считаются ключи, а не люди.
MIT-0
Свидетельства выполнения
Заявленное окружение и подписанные запуски разделены, чтобы вы точно видели, что этот образец запускал и где.
- Основа свидетельства
- Подписанный контракт пройден
- Квитанции проверки
- 1
- Ключи подписи, собравшие его
- 1
Заявленная среда
linux 24 · ubuntu · glibc 2.39 x64 npm
Среды запусков проверки
| Окружение | Контракт | Этапы | Запуск |
|---|---|---|---|
| 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-23 |
Кейс
HOW- Цель
- verify createPacResolver in pkg:npm/pac-resolver@7.0.1
- Пакеты
- Символы
-
- createPacResolver
- Создан
- 2026-08-23T17:44:03Z
Контракт
- createPacResolver generates an asynchronous FindProxyForURL function from a PAC script string using QuickJS
- FindProxyForURL resolves proxies using standard PAC functions including isPlainHostName, dnsDomainIs, and shExpMatch
- createPacResolver accepts a PAC script supplied as a Node.js Buffer
- createPacResolver accepts custom sandbox functions in options
- FindProxyForURL accepts both URL strings and WHATWG URL instances with optional host override
- FindProxyForURL rejects with TypeError when host cannot be determined
Файлы
- PROMPT.md
- csx.json
- package-lock.json
- package.json
- spec.json
- src/index.js
- test/contract.mjs
Исходный код
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 createPacResolver in pkg:npm/pac-resolver@7.0.1
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:npm/pac-resolver@7.0.1
Demonstrate these symbols/APIs:
- createPacResolver
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:dae4135b89403f268f795d65794f307b8b9cfd1a448649c9a404d8b6dfb643fc","contract":["createPacResolver generates an asynchronous FindProxyForURL function from a PAC script string using QuickJS","FindProxyForURL resolves proxies using standard PAC functions including isPlainHostName, dnsDomainIs, and shExpMatch","createPacResolver accepts a PAC script supplied as a Node.js Buffer","createPacResolver accepts custom sandbox functions in options","FindProxyForURL accepts both URL strings and WHATWG URL instances with optional host override","FindProxyForURL rejects with TypeError when host cannot be determined"],"goal":"verify createPacResolver in pkg:npm/pac-resolver@7.0.1","kind":"HOW","packages":["pkg:npm/pac-resolver@7.0.1"],"schemaVersion":1,"symbols":["createPacResolver"]},"contractCommand":["node","test/contract.mjs"],"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/pac-resolver@7.0.1"],"schemaVersion":1,"subject":"pkg:npm/pac-resolver@7.0.1","symbols":["createPacResolver"],"verifierAdapter":"node-typescript@1"}
{
"name": "sample-pac-resolver-create",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sample-pac-resolver-create",
"version": "1.0.0",
"dependencies": {
"@tootallnate/quickjs-emscripten": "^0.23.0",
"pac-resolver": "7.0.1"
}
},
"node_modules/@tootallnate/quickjs-emscripten": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
"integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
"license": "MIT"
},
"node_modules/ast-types": {
"version": "0.13.4",
"resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
"integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
"license": "MIT",
"dependencies": {
"tslib": "^2.0.1"
},
"engines": {
"node": ">=4"
}
},
"node_modules/degenerator": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
"integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
"license": "MIT",
"dependencies": {
"ast-types": "^0.13.4",
"escodegen": "^2.1.0",
"esprima": "^4.0.1"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/escodegen": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
"integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
"license": "BSD-2-Clause",
"dependencies": {
"esprima": "^4.0.1",
"estraverse": "^5.2.0",
"esutils": "^2.0.2"
},
"bin": {
"escodegen": "bin/escodegen.js",
"esgenerate": "bin/esgenerate.js"
},
"engines": {
"node": ">=6.0"
},
"optionalDependencies": {
"source-map": "~0.6.1"
}
},
"node_modules/esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"license": "BSD-2-Clause",
"bin": {
"esparse": "bin/esparse.js",
"esvalidate": "bin/esvalidate.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/estraverse": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
}
},
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/netmask": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz",
"integrity": "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==",
"license": "MIT",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/pac-resolver": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
"integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
"license": "MIT",
"dependencies": {
"degenerator": "^5.0.0",
"netmask": "^2.0.2"
},
"engines": {
"node": ">= 14"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"license": "BSD-3-Clause",
"optional": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
}
}
}
{
"name": "sample-pac-resolver-create",
"version": "1.0.0",
"private": true,
"type": "module",
"dependencies": {
"@tootallnate/quickjs-emscripten": "^0.23.0",
"pac-resolver": "7.0.1"
}
}
{
"schemaVersion": 1,
"goal": "verify createPacResolver in pkg:npm/pac-resolver@7.0.1",
"kind": "HOW",
"packages": [
"pkg:npm/pac-resolver@7.0.1"
],
"symbols": [
"createPacResolver"
]
}
import { createPacResolver, sandbox } from 'pac-resolver';
/**
* Creates a PAC resolver function from PAC script source and a QuickJS WASM instance.
*
* @param {import('@tootallnate/quickjs-emscripten').QuickJSWASMModule} qjs - QuickJS WASM instance
* @param {string | Buffer} pacScript - JavaScript source code of the PAC script
* @param {import('pac-resolver').PacResolverOptions} [options] - Compiler and sandbox options
* @returns {(url: string | URL, host?: string) => Promise<string>} Async resolver function
*/
export function createProxyResolver(qjs, pacScript, options) {
return createPacResolver(qjs, pacScript, options);
}
/**
* Resolves the proxy for a given target URL using a compiled PAC resolver.
*
* @param {(url: string | URL, host?: string) => Promise<string>} resolver - PAC resolver function
* @param {string | URL} targetUrl - Destination URL or WHATWG URL instance
* @param {string} [host] - Optional explicit host name override
* @returns {Promise<string>} Proxy directive string (e.g. "DIRECT" or "PROXY host:port")
*/
export async function resolveProxy(resolver, targetUrl, host) {
if (typeof resolver !== 'function') {
throw new TypeError('resolver must be a function');
}
return resolver(targetUrl, host);
}
export { createPacResolver, sandbox };
import assert from 'node:assert/strict';
import { getQuickJS } from '@tootallnate/quickjs-emscripten';
import { createPacResolver, sandbox, createProxyResolver, resolveProxy } from '../src/index.js';
// Verify exports
assert.equal(typeof createPacResolver, 'function', 'createPacResolver must be exported as a function');
assert.equal(typeof sandbox, 'object', 'sandbox must be exported as an object');
assert.equal(typeof createProxyResolver, 'function', 'createProxyResolver must be exported as a function');
assert.equal(typeof resolveProxy, 'function', 'resolveProxy must be exported as a function');
const qjs = await getQuickJS();
// 1. Compile standard PAC script string and resolve
const standardPac = `
function FindProxyForURL(url, host) {
if (isPlainHostName(host)) {
return "DIRECT";
}
if (dnsDomainIs(host, ".internal.example.com")) {
return "PROXY proxy-internal.example.com:3128";
}
if (shExpMatch(host, "*.secure.example.com")) {
return "PROXY proxy-secure.example.com:8443";
}
return "DIRECT";
}
`;
const resolver = createProxyResolver(qjs, standardPac);
assert.equal(typeof resolver, 'function', 'createProxyResolver should return a function');
// Test isPlainHostName
const plainResult = await resolveProxy(resolver, 'http://localhost/api');
assert.equal(plainResult, 'DIRECT', 'Plain host should resolve to DIRECT');
// Test dnsDomainIs
const internalResult = await resolveProxy(resolver, 'http://service.internal.example.com/data');
assert.equal(internalResult, 'PROXY proxy-internal.example.com:3128', 'Domain match should route through proxy');
// Test shExpMatch
const secureResult = await resolveProxy(resolver, 'https://app.secure.example.com/login');
assert.equal(secureResult, 'PROXY proxy-secure.example.com:8443', 'Wildcard match should route through secure proxy');
// Test default fallback
const defaultResult = await resolveProxy(resolver, 'http://example.com/index.html');
assert.equal(defaultResult, 'DIRECT', 'Default route should resolve to DIRECT');
// 2. Accept Buffer input
const bufferPac = Buffer.from(`
function FindProxyForURL(url, host) {
if (host === "buffer-target.example.com") {
return "PROXY proxy-buffer.example.com:8080";
}
return "DIRECT";
}
`);
const bufferResolver = createPacResolver(qjs, bufferPac);
assert.equal(await bufferResolver('http://buffer-target.example.com/'), 'PROXY proxy-buffer.example.com:8080');
assert.equal(await bufferResolver('http://other.example.com/'), 'DIRECT');
// 3. Custom sandbox functions via options
const customSandboxPac = `
function FindProxyForURL(url, host) {
if (customMatcher(host)) {
return "PROXY custom-proxy.example.com:9000";
}
return "DIRECT";
}
`;
const customResolver = createPacResolver(qjs, customSandboxPac, {
sandbox: {
customMatcher: (h) => h.startsWith('corp-')
}
});
assert.equal(await customResolver('http://corp-portal.example.com/'), 'PROXY custom-proxy.example.com:9000');
assert.equal(await customResolver('http://portal.example.com/'), 'DIRECT');
// 4. WHATWG URL instance input and host override
const urlObj = new URL('http://example.com/path');
assert.equal(await bufferResolver(urlObj), 'DIRECT');
assert.equal(await bufferResolver(urlObj, 'buffer-target.example.com'), 'PROXY proxy-buffer.example.com:8080');
// 5. Error handling on missing/invalid host
await assert.rejects(
async () => {
await resolver('');
},
{
name: 'TypeError'
},
'resolver should reject with TypeError when host cannot be determined'
);
console.log('Contract tests passed.');
Исходный сидер
аноним