@yiaany/ghostapi 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -2
- package/CONTRIBUTING.md +119 -117
- package/LICENSE +21 -21
- package/README.md +208 -185
- package/SECURITY.md +53 -37
- package/dist/actions/gateway.d.ts +179 -0
- package/dist/actions/gateway.js +514 -0
- package/dist/actions/gateway.js.map +1 -0
- package/dist/actions/index.d.ts +2 -0
- package/dist/actions/index.js +2 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/ai/aiClient.js +4 -4
- package/dist/ai/aiClient.js.map +1 -1
- package/dist/ai/aiGenerator.d.ts +2 -2
- package/dist/ai/aiGenerator.js +21 -72
- package/dist/ai/aiGenerator.js.map +1 -1
- package/dist/ai/prompts.js +51 -51
- package/dist/ai/prompts.js.map +1 -1
- package/dist/approvals/approvalInbox.d.ts +150 -0
- package/dist/approvals/approvalInbox.js +412 -0
- package/dist/approvals/approvalInbox.js.map +1 -0
- package/dist/approvals/index.d.ts +2 -0
- package/dist/approvals/index.js +2 -0
- package/dist/approvals/index.js.map +1 -0
- package/dist/behavior/behaviorStore.d.ts +2 -0
- package/dist/behavior/behaviorStore.js +50 -46
- package/dist/behavior/behaviorStore.js.map +1 -1
- package/dist/cache/index.d.ts +2 -0
- package/dist/cache/index.js +58 -14
- package/dist/cache/index.js.map +1 -1
- package/dist/cli/index.js +438 -58
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/openUrl.d.ts +10 -0
- package/dist/cli/openUrl.js +31 -0
- package/dist/cli/openUrl.js.map +1 -0
- package/dist/cli/parser.d.ts +155 -0
- package/dist/cli/parser.js +504 -2
- package/dist/cli/parser.js.map +1 -1
- package/dist/config/dataPaths.d.ts +31 -0
- package/dist/config/dataPaths.js +45 -0
- package/dist/config/dataPaths.js.map +1 -0
- package/dist/config/localConfig.d.ts +1 -2
- package/dist/config/localConfig.js +27 -21
- package/dist/config/localConfig.js.map +1 -1
- package/dist/config/serverConfig.d.ts +2 -0
- package/dist/config/serverConfig.js +8 -1
- package/dist/config/serverConfig.js.map +1 -1
- package/dist/contracts/contract.d.ts +76 -0
- package/dist/contracts/contract.js +603 -0
- package/dist/contracts/contract.js.map +1 -0
- package/dist/contracts/index.d.ts +2 -0
- package/dist/contracts/index.js +2 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/credentials/credentialBroker.d.ts +207 -0
- package/dist/credentials/credentialBroker.js +588 -0
- package/dist/credentials/credentialBroker.js.map +1 -0
- package/dist/credentials/index.d.ts +2 -0
- package/dist/credentials/index.js +2 -0
- package/dist/credentials/index.js.map +1 -0
- package/dist/dashboard/app.js +685 -615
- package/dist/dashboard/index.html +13 -7
- package/dist/dashboard/styles.css +349 -349
- package/dist/egress/capabilities.d.ts +32 -0
- package/dist/egress/capabilities.js +165 -0
- package/dist/egress/capabilities.js.map +1 -0
- package/dist/egress/linuxBootstrap.d.ts +1 -0
- package/dist/egress/linuxBootstrap.js +121 -0
- package/dist/egress/linuxBootstrap.js.map +1 -0
- package/dist/egress/run.d.ts +18 -0
- package/dist/egress/run.js +305 -0
- package/dist/egress/run.js.map +1 -0
- package/dist/errors/errorEngine.d.ts +2 -2
- package/dist/errors/errorEngine.js +3 -40
- package/dist/errors/errorEngine.js.map +1 -1
- package/dist/evals/evals.d.ts +126 -0
- package/dist/evals/evals.js +466 -0
- package/dist/evals/evals.js.map +1 -0
- package/dist/evals/index.d.ts +2 -0
- package/dist/evals/index.js +2 -0
- package/dist/evals/index.js.map +1 -0
- package/dist/evidence/index.d.ts +2 -0
- package/dist/evidence/index.js +2 -0
- package/dist/evidence/index.js.map +1 -0
- package/dist/evidence/report.d.ts +143 -0
- package/dist/evidence/report.js +556 -0
- package/dist/evidence/report.js.map +1 -0
- package/dist/fault/faultLab.d.ts +5 -4
- package/dist/fault/faultLab.js +66 -24
- package/dist/fault/faultLab.js.map +1 -1
- package/dist/index.d.ts +46 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -1
- package/dist/inventory/analysis.d.ts +12 -0
- package/dist/inventory/analysis.js +457 -0
- package/dist/inventory/analysis.js.map +1 -0
- package/dist/inventory/index.d.ts +5 -0
- package/dist/inventory/index.js +4 -0
- package/dist/inventory/index.js.map +1 -0
- package/dist/inventory/inventoryController.d.ts +53 -0
- package/dist/inventory/inventoryController.js +1044 -0
- package/dist/inventory/inventoryController.js.map +1 -0
- package/dist/inventory/types.d.ts +579 -0
- package/dist/inventory/types.js +787 -0
- package/dist/inventory/types.js.map +1 -0
- package/dist/landing/assets/index-CxWsopzP.css +1 -0
- package/dist/landing/assets/index-DZlpyhqd.js +55 -0
- package/dist/landing/assets/index-Dk-Xezs3.js +55 -0
- package/dist/landing/index.html +15 -15
- package/dist/ledger/actionLedger.d.ts +125 -0
- package/dist/ledger/actionLedger.js +594 -0
- package/dist/ledger/actionLedger.js.map +1 -0
- package/dist/ledger/index.d.ts +2 -0
- package/dist/ledger/index.js +2 -0
- package/dist/ledger/index.js.map +1 -0
- package/dist/mcp/server.js +4 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/policy/index.d.ts +3 -0
- package/dist/policy/index.js +2 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/policy.d.ts +14 -0
- package/dist/policy/policy.js +282 -0
- package/dist/policy/policy.js.map +1 -0
- package/dist/policy/types.d.ts +52 -0
- package/dist/policy/types.js +2 -0
- package/dist/policy/types.js.map +1 -0
- package/dist/productTelemetry/index.d.ts +16 -0
- package/dist/productTelemetry/index.js +142 -0
- package/dist/productTelemetry/index.js.map +1 -0
- package/dist/providers/conformance.d.ts +7 -0
- package/dist/providers/conformance.js +48 -0
- package/dist/providers/conformance.js.map +1 -0
- package/dist/providers/index.d.ts +4 -2
- package/dist/providers/index.js +3 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/packs/resendPack.d.ts +2 -0
- package/dist/providers/packs/resendPack.js +147 -0
- package/dist/providers/packs/resendPack.js.map +1 -0
- package/dist/providers/packs/stripePack.d.ts +2 -0
- package/dist/providers/packs/stripePack.js +852 -0
- package/dist/providers/packs/stripePack.js.map +1 -0
- package/dist/providers/registry.d.ts +7 -3
- package/dist/providers/registry.js +55 -4
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/resend.js +2 -11
- package/dist/providers/resend.js.map +1 -1
- package/dist/providers/runtime.d.ts +8 -0
- package/dist/providers/runtime.js +48 -0
- package/dist/providers/runtime.js.map +1 -0
- package/dist/providers/stripeWebhook.d.ts +13 -0
- package/dist/providers/stripeWebhook.js +50 -0
- package/dist/providers/stripeWebhook.js.map +1 -0
- package/dist/providers/types.d.ts +153 -0
- package/dist/proxy/cacheKey.js +3 -3
- package/dist/proxy/cacheKey.js.map +1 -1
- package/dist/proxy/providerDetector.d.ts +2 -7
- package/dist/proxy/providerDetector.js +4 -4
- package/dist/proxy/providerDetector.js.map +1 -1
- package/dist/proxy/proxyHandler.js +116 -12
- package/dist/proxy/proxyHandler.js.map +1 -1
- package/dist/proxy/requestNormalizer.d.ts +0 -1
- package/dist/proxy/requestNormalizer.js +2 -5
- package/dist/proxy/requestNormalizer.js.map +1 -1
- package/dist/reliability/costGovernance.d.ts +175 -0
- package/dist/reliability/costGovernance.js +515 -0
- package/dist/reliability/costGovernance.js.map +1 -0
- package/dist/reliability/index.d.ts +8 -0
- package/dist/reliability/index.js +5 -0
- package/dist/reliability/index.js.map +1 -0
- package/dist/reliability/reconciliation.d.ts +157 -0
- package/dist/reliability/reconciliation.js +522 -0
- package/dist/reliability/reconciliation.js.map +1 -0
- package/dist/reliability/runtimeHealth.d.ts +60 -0
- package/dist/reliability/runtimeHealth.js +356 -0
- package/dist/reliability/runtimeHealth.js.map +1 -0
- package/dist/reliability/slo.d.ts +131 -0
- package/dist/reliability/slo.js +375 -0
- package/dist/reliability/slo.js.map +1 -0
- package/dist/report/safetyReport.js +7 -3
- package/dist/report/safetyReport.js.map +1 -1
- package/dist/safety/index.d.ts +2 -0
- package/dist/safety/index.js +2 -0
- package/dist/safety/index.js.map +1 -0
- package/dist/safety/safetyController.d.ts +187 -0
- package/dist/safety/safetyController.js +477 -0
- package/dist/safety/safetyController.js.map +1 -0
- package/dist/scenarios/scenarioBundle.d.ts +75 -0
- package/dist/scenarios/scenarioBundle.js +750 -0
- package/dist/scenarios/scenarioBundle.js.map +1 -0
- package/dist/scenarios/scenarioStore.d.ts +1 -0
- package/dist/scenarios/scenarioStore.js +47 -32
- package/dist/scenarios/scenarioStore.js.map +1 -1
- package/dist/security/headerSanitizer.d.ts +2 -0
- package/dist/security/headerSanitizer.js +36 -1
- package/dist/security/headerSanitizer.js.map +1 -1
- package/dist/security/secrets.js +24 -4
- package/dist/security/secrets.js.map +1 -1
- package/dist/server/accessControl.d.ts +5 -0
- package/dist/server/accessControl.js +100 -0
- package/dist/server/accessControl.js.map +1 -0
- package/dist/server/createServer.d.ts +0 -5
- package/dist/server/createServer.js +9 -29
- package/dist/server/createServer.js.map +1 -1
- package/dist/server/eventsStore.d.ts +6 -1
- package/dist/server/eventsStore.js +83 -15
- package/dist/server/eventsStore.js.map +1 -1
- package/dist/server/routes.js +36 -10
- package/dist/server/routes.js.map +1 -1
- package/dist/server/sse.d.ts +2 -1
- package/dist/server/sse.js +15 -3
- package/dist/server/sse.js.map +1 -1
- package/dist/setup/setupGenerator.js +53 -6
- package/dist/setup/setupGenerator.js.map +1 -1
- package/dist/state/stateStore.d.ts +5 -0
- package/dist/state/stateStore.js +48 -62
- package/dist/state/stateStore.js.map +1 -1
- package/dist/storage/fileStore.d.ts +10 -0
- package/dist/storage/fileStore.js +131 -0
- package/dist/storage/fileStore.js.map +1 -0
- package/dist/teamControl/controlPlane.d.ts +255 -0
- package/dist/teamControl/controlPlane.js +918 -0
- package/dist/teamControl/controlPlane.js.map +1 -0
- package/dist/teamControl/deployment.d.ts +33 -0
- package/dist/teamControl/deployment.js +67 -0
- package/dist/teamControl/deployment.js.map +1 -0
- package/dist/teamControl/index.d.ts +4 -0
- package/dist/teamControl/index.js +3 -0
- package/dist/teamControl/index.js.map +1 -0
- package/dist/tests/testGenerator.js +4 -1
- package/dist/tests/testGenerator.js.map +1 -1
- package/dist/trust/index.d.ts +2 -0
- package/dist/trust/index.js +2 -0
- package/dist/trust/index.js.map +1 -0
- package/dist/trust/trustLadder.d.ts +182 -0
- package/dist/trust/trustLadder.js +560 -0
- package/dist/trust/trustLadder.js.map +1 -0
- package/dist/worlds/index.d.ts +2 -0
- package/dist/worlds/index.js +2 -0
- package/dist/worlds/index.js.map +1 -0
- package/dist/worlds/worlds.d.ts +160 -0
- package/dist/worlds/worlds.js +491 -0
- package/dist/worlds/worlds.js.map +1 -0
- package/docs/assets/dashboard.png +0 -0
- package/docs/ci.md +49 -0
- package/docs/commercial/README.md +29 -0
- package/docs/commercial/data-inventory.md +36 -0
- package/docs/commercial/manual-invoicing.md +44 -0
- package/docs/commercial/metrics.md +51 -0
- package/docs/commercial/pricing.md +103 -0
- package/docs/commercial/privacy-policy-draft.md +41 -0
- package/docs/commercial/terms-topics-for-counsel.md +51 -0
- package/docs/design-partners/README.md +52 -0
- package/docs/design-partners/demo-narratives.md +33 -0
- package/docs/design-partners/design-partner-offer.md +39 -0
- package/docs/design-partners/discovery-questions.md +28 -0
- package/docs/design-partners/feedback-capture-template.md +48 -0
- package/docs/design-partners/icp-one-pager.md +43 -0
- package/docs/design-partners/onboarding-checklist.md +33 -0
- package/docs/design-partners/pilot-success-criteria.md +27 -0
- package/docs/design-partners/pricing-interview-script.md +18 -0
- package/docs/design-partners/telemetry-plan.md +48 -0
- package/docs/development/baseline.md +114 -0
- package/docs/development/onboarding-smoke.md +37 -0
- package/docs/development/verification-0.1.8.md +25 -0
- package/docs/enterprise-product-roadmap-ru.md +1879 -0
- package/docs/fundraising/README.md +87 -0
- package/docs/fundraising/data-room-checklist.md +72 -0
- package/docs/fundraising/demo-script.md +52 -0
- package/docs/fundraising/design-partners-50.md +74 -0
- package/docs/fundraising/launch-posts.md +37 -0
- package/docs/fundraising/metrics-and-evidence.md +30 -0
- package/docs/fundraising/roadmap-12-month.md +25 -0
- package/docs/fundraising/technical-due-diligence-index.md +37 -0
- package/docs/fundraising/yc-application.md +25 -0
- package/docs/github-actions.md +84 -0
- package/docs/hosted-pilot.md +111 -0
- package/docs/mcp.md +52 -50
- package/docs/operations/disaster-recovery-runbook.md +81 -0
- package/docs/operations/kill-switch-runbook.md +32 -0
- package/docs/policy.md +61 -0
- package/docs/providers/authoring-packs.md +175 -0
- package/docs/providers/stripe-core-pack.md +82 -0
- package/docs/release-checklist.md +83 -71
- package/docs/release-migration-and-rollback.md +63 -0
- package/docs/release-readiness.md +39 -0
- package/docs/security/action-gateway-threat-model.md +34 -0
- package/docs/security/action-ledger-incident-replay-threat-model.md +42 -0
- package/docs/security/approval-inbox-threat-model.md +35 -0
- package/docs/security/credential-broker-threat-model.md +52 -0
- package/docs/security/egress-threat-model.md +126 -0
- package/docs/security/inventory-threat-model.md +104 -0
- package/docs/security/kill-switch-budgets-threat-model.md +37 -0
- package/docs/security/reliability-threat-model.md +111 -0
- package/docs/security/trust-ladder-threat-model.md +33 -0
- package/docs/team-control-plane.md +72 -0
- package/docs/usage.md +571 -57
- package/examples/README.md +10 -0
- package/examples/agent-instructions/README.md +39 -39
- package/examples/ci-smoke/README.md +21 -0
- package/examples/ci-smoke/ghostapi.policy.yaml +22 -0
- package/examples/ci-smoke/package.json +9 -0
- package/examples/ci-smoke/production-egress.mjs +2 -0
- package/examples/ci-smoke/safe.mjs +17 -0
- package/examples/evals/README.md +24 -0
- package/examples/evals/retry-after.eval.json +52 -0
- package/examples/generic-rest/README.md +27 -27
- package/examples/github-fetch/README.md +35 -35
- package/examples/openai-streaming/README.md +16 -0
- package/examples/openai-streaming/streaming-tool-call.mjs +31 -0
- package/examples/policy/ghostapi.policy.yaml +27 -0
- package/examples/record-replay/README.md +19 -0
- package/examples/record-replay/replay-requests.json +22 -0
- package/examples/record-replay/stripe-checkout.har.json +30 -0
- package/examples/resend-node/README.md +22 -22
- package/examples/stripe-node/README.md +35 -29
- package/examples/stripe-node/checkout-flow.mjs +61 -0
- package/examples/twilio-node/README.md +21 -21
- package/examples/worlds/README.md +19 -0
- package/examples/worlds/subscription-recovery.mjs +12 -0
- package/package.json +26 -11
- package/dist/providers/stripe.d.ts +0 -2
- package/dist/providers/stripe.js +0 -15
- package/dist/providers/stripe.js.map +0 -1
- package/docs/assets/ghostapi-avatar.png +0 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { lstat, rm } from "node:fs/promises";
|
|
2
|
+
import { getDataPaths } from "../config/dataPaths.js";
|
|
3
|
+
import { atomicWriteJson, readJsonFile, withFileLock } from "../storage/fileStore.js";
|
|
4
|
+
import { isJsonObject } from "../utils/json.js";
|
|
5
|
+
const SCHEMA_VERSION = 1;
|
|
6
|
+
const MAX_ACTIVE_WEEKS = 8;
|
|
7
|
+
export class ProductTelemetryError extends Error {
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "ProductTelemetryError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export async function readProductTelemetry() {
|
|
14
|
+
return readSnapshot(getDataPaths().productTelemetry);
|
|
15
|
+
}
|
|
16
|
+
export async function setProductTelemetryEnabled(enabled) {
|
|
17
|
+
const path = getDataPaths().productTelemetry;
|
|
18
|
+
return withFileLock(path, async () => {
|
|
19
|
+
if (!enabled) {
|
|
20
|
+
await rm(path, { force: true });
|
|
21
|
+
return emptySnapshot();
|
|
22
|
+
}
|
|
23
|
+
const current = await readSnapshot(path);
|
|
24
|
+
const next = { ...current, enabled: true };
|
|
25
|
+
await atomicWriteJson(path, next);
|
|
26
|
+
return next;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
export async function recordProductTelemetry(event, now = new Date()) {
|
|
30
|
+
if (!isTelemetryEvent(event))
|
|
31
|
+
throw new ProductTelemetryError("Unknown local product telemetry event.");
|
|
32
|
+
if (Number.isNaN(now.getTime()))
|
|
33
|
+
throw new ProductTelemetryError("Local product telemetry received an invalid clock value.");
|
|
34
|
+
const path = getDataPaths().productTelemetry;
|
|
35
|
+
return withFileLock(path, async () => {
|
|
36
|
+
const current = await readSnapshot(path);
|
|
37
|
+
if (!current.enabled)
|
|
38
|
+
return current;
|
|
39
|
+
const timestamp = now.toISOString();
|
|
40
|
+
if (current.lastActivityAt !== undefined && timestamp < current.lastActivityAt) {
|
|
41
|
+
throw new ProductTelemetryError("Local product telemetry clock moved backwards; refusing to write inconsistent activity state.");
|
|
42
|
+
}
|
|
43
|
+
if (current.counters[event] === Number.MAX_SAFE_INTEGER) {
|
|
44
|
+
throw new ProductTelemetryError("Local product telemetry counter capacity reached.");
|
|
45
|
+
}
|
|
46
|
+
const week = isoWeek(now);
|
|
47
|
+
const activeWeeks = [...new Set([...current.activeWeeks, week])].sort().slice(-MAX_ACTIVE_WEEKS);
|
|
48
|
+
const counters = { ...current.counters, [event]: current.counters[event] + 1 };
|
|
49
|
+
const activation = event === "enforced_run_completed" || event === "evidence_generated";
|
|
50
|
+
const next = {
|
|
51
|
+
schemaVersion: SCHEMA_VERSION,
|
|
52
|
+
enabled: true,
|
|
53
|
+
counters,
|
|
54
|
+
activeWeeks,
|
|
55
|
+
...(activation && current.firstActivationAt === undefined ? { firstActivationAt: timestamp } : current.firstActivationAt === undefined ? {} : { firstActivationAt: current.firstActivationAt }),
|
|
56
|
+
lastActivityAt: timestamp
|
|
57
|
+
};
|
|
58
|
+
await atomicWriteJson(path, next);
|
|
59
|
+
return next;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
export function formatProductTelemetry(snapshot) {
|
|
63
|
+
const activation = snapshot.firstActivationAt === undefined ? "not reached" : `reached at ${snapshot.firstActivationAt}`;
|
|
64
|
+
return [
|
|
65
|
+
`Local product telemetry: ${snapshot.enabled ? "enabled" : "disabled"}`,
|
|
66
|
+
"Network export: disabled (this feature has no network transport).",
|
|
67
|
+
`Activation: ${activation}.`,
|
|
68
|
+
`Active weeks retained: ${snapshot.activeWeeks.length}/${MAX_ACTIVE_WEEKS}.`,
|
|
69
|
+
`Counters: init=${snapshot.counters.init_completed}, enforced-runs=${snapshot.counters.enforced_run_completed}, evidence=${snapshot.counters.evidence_generated}, evals=${snapshot.counters.eval_completed}.`
|
|
70
|
+
].join("\n");
|
|
71
|
+
}
|
|
72
|
+
function emptySnapshot() {
|
|
73
|
+
return {
|
|
74
|
+
schemaVersion: SCHEMA_VERSION,
|
|
75
|
+
enabled: false,
|
|
76
|
+
counters: { init_completed: 0, enforced_run_completed: 0, evidence_generated: 0, eval_completed: 0 },
|
|
77
|
+
activeWeeks: []
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
async function readSnapshot(path) {
|
|
81
|
+
const info = await lstat(path).catch((error) => isErrorCode(error, "ENOENT") ? null : Promise.reject(error));
|
|
82
|
+
if (info === null)
|
|
83
|
+
return emptySnapshot();
|
|
84
|
+
if (!info.isFile() || info.isSymbolicLink())
|
|
85
|
+
throw new ProductTelemetryError("Local product telemetry must be a regular non-symlink file.");
|
|
86
|
+
return readJsonFile(path, emptySnapshot(), parseSnapshot);
|
|
87
|
+
}
|
|
88
|
+
function parseSnapshot(value) {
|
|
89
|
+
if (!isJsonObject(value))
|
|
90
|
+
throw new ProductTelemetryError("Local product telemetry file must be a JSON object.");
|
|
91
|
+
assertExactKeys(value, ["schemaVersion", "enabled", "counters", "activeWeeks", "firstActivationAt", "lastActivityAt"]);
|
|
92
|
+
if (value.schemaVersion !== SCHEMA_VERSION || typeof value.enabled !== "boolean")
|
|
93
|
+
throw new ProductTelemetryError("Local product telemetry file has an unsupported schema.");
|
|
94
|
+
if (!isJsonObject(value.counters))
|
|
95
|
+
throw new ProductTelemetryError("Local product telemetry counters must be an object.");
|
|
96
|
+
assertExactKeys(value.counters, ["init_completed", "enforced_run_completed", "evidence_generated", "eval_completed"]);
|
|
97
|
+
const counters = {};
|
|
98
|
+
for (const event of ["init_completed", "enforced_run_completed", "evidence_generated", "eval_completed"]) {
|
|
99
|
+
const count = value.counters[event];
|
|
100
|
+
if (typeof count !== "number" || !Number.isSafeInteger(count) || count < 0)
|
|
101
|
+
throw new ProductTelemetryError("Local product telemetry counters must be non-negative safe integers.");
|
|
102
|
+
counters[event] = count;
|
|
103
|
+
}
|
|
104
|
+
if (!Array.isArray(value.activeWeeks) || value.activeWeeks.length > MAX_ACTIVE_WEEKS || !value.activeWeeks.every((week) => typeof week === "string" && /^\d{4}-W\d{2}$/.test(week))) {
|
|
105
|
+
throw new ProductTelemetryError("Local product telemetry active weeks are invalid.");
|
|
106
|
+
}
|
|
107
|
+
const activeWeeks = [...new Set(value.activeWeeks)].sort();
|
|
108
|
+
if (activeWeeks.length !== value.activeWeeks.length)
|
|
109
|
+
throw new ProductTelemetryError("Local product telemetry active weeks must be unique.");
|
|
110
|
+
const firstActivationAt = parseTimestamp(value.firstActivationAt);
|
|
111
|
+
const lastActivityAt = parseTimestamp(value.lastActivityAt);
|
|
112
|
+
if (firstActivationAt !== undefined && lastActivityAt !== undefined && firstActivationAt > lastActivityAt) {
|
|
113
|
+
throw new ProductTelemetryError("Local product telemetry timestamps are out of order.");
|
|
114
|
+
}
|
|
115
|
+
return { schemaVersion: SCHEMA_VERSION, enabled: value.enabled, counters, activeWeeks, ...(firstActivationAt === undefined ? {} : { firstActivationAt }), ...(lastActivityAt === undefined ? {} : { lastActivityAt }) };
|
|
116
|
+
}
|
|
117
|
+
function assertExactKeys(value, allowed) {
|
|
118
|
+
if (Object.keys(value).some((key) => !allowed.includes(key)))
|
|
119
|
+
throw new ProductTelemetryError("Local product telemetry file contains unsupported fields.");
|
|
120
|
+
}
|
|
121
|
+
function parseTimestamp(value) {
|
|
122
|
+
if (value === undefined)
|
|
123
|
+
return undefined;
|
|
124
|
+
if (typeof value !== "string" || Number.isNaN(Date.parse(value)) || new Date(value).toISOString() !== value)
|
|
125
|
+
throw new ProductTelemetryError("Local product telemetry timestamp is invalid.");
|
|
126
|
+
return value;
|
|
127
|
+
}
|
|
128
|
+
function isErrorCode(error, code) {
|
|
129
|
+
return error instanceof Error && "code" in error && error.code === code;
|
|
130
|
+
}
|
|
131
|
+
function isTelemetryEvent(value) {
|
|
132
|
+
return value === "init_completed" || value === "enforced_run_completed" || value === "evidence_generated" || value === "eval_completed";
|
|
133
|
+
}
|
|
134
|
+
function isoWeek(date) {
|
|
135
|
+
const utc = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
|
|
136
|
+
const day = utc.getUTCDay() || 7;
|
|
137
|
+
utc.setUTCDate(utc.getUTCDate() + 4 - day);
|
|
138
|
+
const yearStart = new Date(Date.UTC(utc.getUTCFullYear(), 0, 1));
|
|
139
|
+
const week = Math.ceil((((utc.getTime() - yearStart.getTime()) / 86_400_000) + 1) / 7);
|
|
140
|
+
return `${utc.getUTCFullYear()}-W${String(week).padStart(2, "0")}`;
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/productTelemetry/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ProviderPack, ProviderRuntime } from "./types.js";
|
|
2
|
+
export type ProviderConformanceResult = {
|
|
3
|
+
provider: string;
|
|
4
|
+
apiVersion: string;
|
|
5
|
+
fixtures: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function runProviderPackConformance(pack: ProviderPack, runtime: ProviderRuntime): ProviderConformanceResult;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { assertProviderStateTransition, prepareProviderPackExecution } from "./runtime.js";
|
|
2
|
+
export function runProviderPackConformance(pack, runtime) {
|
|
3
|
+
if (pack.manifest.name !== pack.name || pack.manifest.displayName !== pack.displayName) {
|
|
4
|
+
throw new Error(`Provider pack ${pack.name} manifest identity does not match the pack.`);
|
|
5
|
+
}
|
|
6
|
+
if (!pack.manifest.apiVersions.supported.includes(pack.manifest.apiVersions.default)) {
|
|
7
|
+
throw new Error(`Provider pack ${pack.name} default API version is not declared as supported.`);
|
|
8
|
+
}
|
|
9
|
+
if (pack.conformanceFixtures.length === 0) {
|
|
10
|
+
throw new Error(`Provider pack ${pack.name} must declare at least one conformance fixture.`);
|
|
11
|
+
}
|
|
12
|
+
let apiVersion = pack.manifest.apiVersions.default;
|
|
13
|
+
for (const fixture of pack.conformanceFixtures) {
|
|
14
|
+
const prepared = prepareProviderPackExecution(pack, fixture.request, runtime);
|
|
15
|
+
if ("error" in prepared) {
|
|
16
|
+
throw new Error(`Conformance fixture "${fixture.name}" rejected API version: ${prepared.error.message}`);
|
|
17
|
+
}
|
|
18
|
+
apiVersion = prepared.apiVersion;
|
|
19
|
+
const validationError = pack.validate(prepared.parsedRequest, fixture.request);
|
|
20
|
+
if (validationError !== null) {
|
|
21
|
+
throw new Error(`Conformance fixture "${fixture.name}" failed request validation: ${validationError.message}`);
|
|
22
|
+
}
|
|
23
|
+
const response = pack.handleDeterministic({
|
|
24
|
+
request: fixture.request,
|
|
25
|
+
parsedRequest: prepared.parsedRequest,
|
|
26
|
+
apiVersion: prepared.apiVersion,
|
|
27
|
+
runtime
|
|
28
|
+
});
|
|
29
|
+
const responseError = fixture.assertResponse(response);
|
|
30
|
+
if (responseError !== null) {
|
|
31
|
+
throw new Error(`Conformance fixture "${fixture.name}" response: ${responseError}`);
|
|
32
|
+
}
|
|
33
|
+
const transition = pack.transitionState({
|
|
34
|
+
request: fixture.request,
|
|
35
|
+
response,
|
|
36
|
+
apiVersion: prepared.apiVersion,
|
|
37
|
+
runtime
|
|
38
|
+
});
|
|
39
|
+
if (transition !== null)
|
|
40
|
+
assertProviderStateTransition(pack, transition);
|
|
41
|
+
const transitionError = fixture.assertStateTransition(transition, response);
|
|
42
|
+
if (transitionError !== null) {
|
|
43
|
+
throw new Error(`Conformance fixture "${fixture.name}" state transition: ${transitionError}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return { provider: pack.name, apiVersion, fixtures: pack.conformanceFixtures.length };
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=conformance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conformance.js","sourceRoot":"","sources":["../../src/providers/conformance.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
export { getProviderAdapter, isRegisteredProvider, providerRegistry } from "./registry.js";
|
|
2
|
-
export
|
|
1
|
+
export { detectProviderPack, getProviderAdapter, getProviderManifests, getProviderPack, getProviderScenarios, isRegisteredProvider, providerRegistry } from "./registry.js";
|
|
2
|
+
export { runProviderPackConformance } from "./conformance.js";
|
|
3
|
+
export { assertProviderStateTransition, createProviderRuntime, getProviderPackHeaders, prepareProviderPackExecution } from "./runtime.js";
|
|
4
|
+
export type { ProviderAdapter, ProviderConformanceFixture, ProviderDetectionInput, ProviderName, ProviderPack, ProviderPackDetectionInput, ProviderPackExecution, ProviderPackManifest, ProviderResponse, ProviderRuntime, ProviderRuntimeCapabilities, ProviderScenario, ProviderScenarioStep, ProviderStateTransition, ProviderWebhookHook } from "./types.js";
|
package/dist/providers/index.js
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
export { getProviderAdapter, isRegisteredProvider, providerRegistry } from "./registry.js";
|
|
1
|
+
export { detectProviderPack, getProviderAdapter, getProviderManifests, getProviderPack, getProviderScenarios, isRegisteredProvider, providerRegistry } from "./registry.js";
|
|
2
|
+
export { runProviderPackConformance } from "./conformance.js";
|
|
3
|
+
export { assertProviderStateTransition, createProviderRuntime, getProviderPackHeaders, prepareProviderPackExecution } from "./runtime.js";
|
|
2
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,gBAAgB,EACjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,6BAA6B,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { isJsonObject } from "../../utils/json.js";
|
|
2
|
+
const RESEND_API_VERSION = "v1";
|
|
3
|
+
const resendScenarios = [
|
|
4
|
+
{
|
|
5
|
+
id: "resend-email-send",
|
|
6
|
+
title: "Resend email send",
|
|
7
|
+
provider: "resend",
|
|
8
|
+
description: "Returns a delivered email ID for transactional email flows.",
|
|
9
|
+
steps: [
|
|
10
|
+
{
|
|
11
|
+
name: "Send email",
|
|
12
|
+
method: "POST",
|
|
13
|
+
path: "/emails",
|
|
14
|
+
status: 200,
|
|
15
|
+
body: { id: "email_ghostapi_123", object: "email", status: "sent" }
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
];
|
|
20
|
+
const resendConformanceFixtures = [
|
|
21
|
+
{
|
|
22
|
+
name: "send email",
|
|
23
|
+
request: {
|
|
24
|
+
method: "POST",
|
|
25
|
+
path: "/emails",
|
|
26
|
+
query: {},
|
|
27
|
+
headers: { "content-type": "application/json" },
|
|
28
|
+
body: { from: "sender@example.com", to: "reader@example.com", subject: "Hello" },
|
|
29
|
+
receivedAt: "2026-08-06T12:00:00.000Z"
|
|
30
|
+
},
|
|
31
|
+
assertResponse(response) {
|
|
32
|
+
if (!isJsonObject(response.body) || typeof response.body.id !== "string" || !response.body.id.startsWith("email_mock_")) {
|
|
33
|
+
return "response body must contain an email_mock_ id";
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
},
|
|
37
|
+
assertStateTransition(transition, response) {
|
|
38
|
+
const id = isJsonObject(response.body) && typeof response.body.id === "string" ? response.body.id : "";
|
|
39
|
+
if (transition === null || transition.key !== `resend:${id}` || transition.value !== response.body) {
|
|
40
|
+
return "state transition must persist the exact response under the resend response id key";
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
];
|
|
46
|
+
export const resendPack = {
|
|
47
|
+
name: "resend",
|
|
48
|
+
displayName: "Resend",
|
|
49
|
+
manifest: {
|
|
50
|
+
schemaVersion: 1,
|
|
51
|
+
name: "resend",
|
|
52
|
+
displayName: "Resend",
|
|
53
|
+
implementation: "pack",
|
|
54
|
+
packVersion: "1.0.0",
|
|
55
|
+
apiVersions: { default: RESEND_API_VERSION, supported: [RESEND_API_VERSION] },
|
|
56
|
+
capabilities: {
|
|
57
|
+
detection: true,
|
|
58
|
+
requestParsing: true,
|
|
59
|
+
validation: true,
|
|
60
|
+
deterministicResponses: true,
|
|
61
|
+
stateTransitions: true,
|
|
62
|
+
providerErrors: true,
|
|
63
|
+
scenarios: true,
|
|
64
|
+
webhooks: false,
|
|
65
|
+
conformanceFixtures: true
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
detection: {
|
|
69
|
+
priority: 300,
|
|
70
|
+
matches(input) {
|
|
71
|
+
const path = input.path.toLowerCase();
|
|
72
|
+
return path === "/emails" || path.startsWith("/emails/");
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
parseRequest(request) {
|
|
76
|
+
return { body: isJsonObject(request.body) ? request.body : {} };
|
|
77
|
+
},
|
|
78
|
+
selectApiVersion(request) {
|
|
79
|
+
const requested = firstHeaderValue(request.headers["x-ghostapi-api-version"]) ?? RESEND_API_VERSION;
|
|
80
|
+
if (requested === RESEND_API_VERSION)
|
|
81
|
+
return { version: requested };
|
|
82
|
+
return {
|
|
83
|
+
error: {
|
|
84
|
+
status: 400,
|
|
85
|
+
type: "invalid_api_version",
|
|
86
|
+
message: `Unsupported Resend API version: ${requested}. Supported versions: ${RESEND_API_VERSION}.`
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
validate(parsedRequest, request) {
|
|
91
|
+
if (request.method !== "POST" || (request.path !== "/emails" && !request.path.startsWith("/emails/")))
|
|
92
|
+
return null;
|
|
93
|
+
const body = readResendRequest(parsedRequest).body;
|
|
94
|
+
if (!body.from)
|
|
95
|
+
return validationError("from");
|
|
96
|
+
if (!body.to)
|
|
97
|
+
return validationError("to");
|
|
98
|
+
if (!body.subject)
|
|
99
|
+
return validationError("subject");
|
|
100
|
+
return null;
|
|
101
|
+
},
|
|
102
|
+
handleDeterministic({ request, runtime }) {
|
|
103
|
+
const id = runtime.requireCapability("idGenerator").create("email_mock");
|
|
104
|
+
return {
|
|
105
|
+
status: 200,
|
|
106
|
+
headers: { "content-type": "application/json" },
|
|
107
|
+
body: { id, provider: "resend", method: request.method, path: request.path }
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
createResponseHeaders() {
|
|
111
|
+
return {};
|
|
112
|
+
},
|
|
113
|
+
transitionState({ request, response }) {
|
|
114
|
+
if (!isMutation(request.method) || !isJsonObject(response.body) || typeof response.body.id !== "string")
|
|
115
|
+
return null;
|
|
116
|
+
return { key: `resend:${response.body.id}`, value: response.body };
|
|
117
|
+
},
|
|
118
|
+
stateful: false,
|
|
119
|
+
formatError(details) {
|
|
120
|
+
return {
|
|
121
|
+
statusCode: details.status,
|
|
122
|
+
name: details.type ?? "validation_error",
|
|
123
|
+
message: details.message
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
promptHints: [
|
|
127
|
+
"This is the Resend Email API.",
|
|
128
|
+
"The standard response for sending an email is a single object with an 'id' string."
|
|
129
|
+
],
|
|
130
|
+
scenarios: resendScenarios,
|
|
131
|
+
conformanceFixtures: resendConformanceFixtures
|
|
132
|
+
};
|
|
133
|
+
function readResendRequest(value) {
|
|
134
|
+
if (!isJsonObject(value) || !isJsonObject(value.body))
|
|
135
|
+
return { body: {} };
|
|
136
|
+
return { body: value.body };
|
|
137
|
+
}
|
|
138
|
+
function validationError(field) {
|
|
139
|
+
return { status: 400, message: `Missing required field: ${field}`, type: "validation_error" };
|
|
140
|
+
}
|
|
141
|
+
function firstHeaderValue(value) {
|
|
142
|
+
return Array.isArray(value) ? value[0] : value;
|
|
143
|
+
}
|
|
144
|
+
function isMutation(method) {
|
|
145
|
+
return method === "POST" || method === "PUT" || method === "PATCH";
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=resendPack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resendPack.js","sourceRoot":"","sources":["../../../src/providers/packs/resendPack.ts"],"names":[],"mappings":"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"}
|