witnora 0.18.1 → 0.18.2
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/dist/onboard.js +2 -1
- package/dist/private-discovery.js +25 -0
- package/dist/real-path-activation.js +26 -2
- package/dist/vendor/onegent-runtime/production-evaluator-kit.d.ts +2 -1
- package/dist/vendor/onegent-runtime/production-evaluator-kit.d.ts.map +1 -1
- package/dist/vendor/onegent-runtime/production-evaluator-kit.js +1 -0
- package/dist/vendor/onegent-runtime/provider-integration-packs.d.ts +1 -1
- package/dist/vendor/onegent-runtime/provider-integration-packs.d.ts.map +1 -1
- package/dist/vendor/onegent-runtime/provider-integration-packs.js +7 -1
- package/package.json +1 -1
package/dist/onboard.js
CHANGED
|
@@ -390,7 +390,8 @@ export async function inspectRepository(repositoryPath, explicitTemplate) {
|
|
|
390
390
|
...Object.keys(record(packageJson.devDependencies)),
|
|
391
391
|
...Object.keys(record(packageJson.peerDependencies)),
|
|
392
392
|
] : [];
|
|
393
|
-
const
|
|
393
|
+
const manifest = await optionalJson(join(repositoryPath, "witnora.discovery.json"));
|
|
394
|
+
const capabilities = inferPrivateCapabilities({ dependencyNames, topLevelNames: names, manifest });
|
|
394
395
|
return { kind, name, slug, template, fingerprintSha256, capabilities };
|
|
395
396
|
}
|
|
396
397
|
async function generateRepositoryConfig(repositoryPath, template, subject) {
|
|
@@ -83,8 +83,33 @@ export function inferPrivateCapabilities(input) {
|
|
|
83
83
|
add("data:structured", "Structured data access", "data");
|
|
84
84
|
if (/slack|discord|twilio|resend|sendgrid|postmark|nodemailer|email/.test(searchable))
|
|
85
85
|
add("messaging:external", "External messaging", "messaging");
|
|
86
|
+
for (const capability of repositoryManifestCapabilities(input.manifest))
|
|
87
|
+
add(capability.key, capability.observedName, capability.transport);
|
|
86
88
|
return [...detected.values()].sort((left, right) => left.key.localeCompare(right.key));
|
|
87
89
|
}
|
|
90
|
+
function repositoryManifestCapabilities(value) {
|
|
91
|
+
if (value === undefined)
|
|
92
|
+
return [];
|
|
93
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
94
|
+
throw new Error("Repository discovery manifest is invalid.");
|
|
95
|
+
const manifest = value;
|
|
96
|
+
if (Object.keys(manifest).some((key) => key !== "schemaVersion" && key !== "capabilities") || manifest.schemaVersion !== "witnora.repository_discovery.v0.1" || !Array.isArray(manifest.capabilities) || manifest.capabilities.length > 100) {
|
|
97
|
+
throw new Error("Repository discovery manifest failed its bounded contract.");
|
|
98
|
+
}
|
|
99
|
+
const transports = new Set(["tool", "mcp", "http", "browser", "coding", "workflow", "data", "messaging"]);
|
|
100
|
+
return manifest.capabilities.map((item, index) => {
|
|
101
|
+
if (!item || typeof item !== "object" || Array.isArray(item))
|
|
102
|
+
throw new Error(`Repository discovery manifest capability ${index} is invalid.`);
|
|
103
|
+
const capability = item;
|
|
104
|
+
if (Object.keys(capability).some((key) => key !== "key" && key !== "observedName" && key !== "transport")
|
|
105
|
+
|| typeof capability.key !== "string" || !/^[A-Za-z0-9._:-]{1,120}$/.test(capability.key)
|
|
106
|
+
|| typeof capability.observedName !== "string" || !/^[A-Za-z0-9._:-]{1,120}$/.test(capability.observedName)
|
|
107
|
+
|| !transports.has(capability.transport)) {
|
|
108
|
+
throw new Error(`Repository discovery manifest capability ${index} failed its bounded contract.`);
|
|
109
|
+
}
|
|
110
|
+
return { key: capability.key, observedName: capability.observedName, transport: capability.transport };
|
|
111
|
+
});
|
|
112
|
+
}
|
|
88
113
|
function discoveryIdentityPath(projectId, configHome) {
|
|
89
114
|
const root = configHome ?? process.env.WITNORA_CONFIG_HOME ?? process.env.AGENTCERT_CONFIG_HOME
|
|
90
115
|
?? join(process.env.USERPROFILE ?? process.env.HOME ?? ".", ".witnora");
|
|
@@ -12,7 +12,7 @@ export async function activateRealPathIntegrations(options) {
|
|
|
12
12
|
throw new Error(`Could not load approved real-path integrations (${response.status}).`);
|
|
13
13
|
const body = await boundedJson(response);
|
|
14
14
|
const approved = Array.isArray(body.integrations) ? body.integrations.map(parsePlan).filter((plan) => plan.status === "READY_TO_ACTIVATE") : [];
|
|
15
|
-
const plans = approved.filter((plan) => ["STRIPE_REFUND", "ZENDESK_TICKET", "SALESFORCE_RECORD", "HUBSPOT_CRM_RECORD", "POSTGRES_RECORD"].includes(plan.generated.providerPackId) && plan.environment === "sandbox" && plan.customerSummary.evaluationMode === "SHADOW");
|
|
15
|
+
const plans = approved.filter((plan) => ["STRIPE_REFUND", "SHOPIFY_DISPUTE", "ZENDESK_TICKET", "SALESFORCE_RECORD", "HUBSPOT_CRM_RECORD", "POSTGRES_RECORD"].includes(plan.generated.providerPackId) && plan.environment === "sandbox" && plan.customerSummary.evaluationMode === "SHADOW");
|
|
16
16
|
if (!plans.length)
|
|
17
17
|
return { state: "NOT_CONFIGURED", created: false, activations: [], generatedFiles: [] };
|
|
18
18
|
const environment = options.env ?? process.env;
|
|
@@ -71,6 +71,8 @@ async function providerPreflight(request, env, plan, now, postgresClientFactory)
|
|
|
71
71
|
throw new Error("Stripe test-mode activation requires STRIPE_SECRET_KEY to reference an sk_test_ credential in the customer environment.");
|
|
72
72
|
return stripePreflight(request, secret, plan, now);
|
|
73
73
|
}
|
|
74
|
+
if (plan.generated.providerPackId === "SHOPIFY_DISPUTE")
|
|
75
|
+
return shopifyDisputePreflight(request, env, plan, now);
|
|
74
76
|
if (plan.generated.providerPackId === "ZENDESK_TICKET")
|
|
75
77
|
return zendeskPreflight(request, env, plan, now);
|
|
76
78
|
if (plan.generated.providerPackId === "SALESFORCE_RECORD")
|
|
@@ -81,6 +83,26 @@ async function providerPreflight(request, env, plan, now, postgresClientFactory)
|
|
|
81
83
|
return postgresPreflight(env, plan, now, postgresClientFactory);
|
|
82
84
|
throw new Error(`${plan.generated.providerPackId} activation is not implemented by this CLI version.`);
|
|
83
85
|
}
|
|
86
|
+
async function shopifyDisputePreflight(request, env, plan, now) {
|
|
87
|
+
const token = env.SHOPIFY_READ_ACCESS_TOKEN;
|
|
88
|
+
if (!token || token.length < 8)
|
|
89
|
+
throw new Error("Shopify activation requires the read-only SHOPIFY_READ_ACCESS_TOKEN in the customer environment.");
|
|
90
|
+
const origin = providerOrigin(plan, "Shopify", ".myshopify.com");
|
|
91
|
+
if (!/^[a-z0-9][a-z0-9-]*\.myshopify\.com$/.test(new URL(origin).hostname))
|
|
92
|
+
throw new Error("Shopify integration requires the exact myshopify.com shop origin.");
|
|
93
|
+
const response = await request(`${origin}/admin/api/2025-07/shopify_payments/disputes.json?limit=1`, { method: "GET", headers: { accept: "application/json", "x-shopify-access-token": token }, redirect: "error", signal: AbortSignal.timeout(5_000) });
|
|
94
|
+
if (!response.ok)
|
|
95
|
+
throw new Error(`Shopify read-only dispute preflight failed (${response.status}).`);
|
|
96
|
+
const body = await boundedJson(response);
|
|
97
|
+
const disputes = Array.isArray(body.disputes) ? body.disputes : [];
|
|
98
|
+
const first = record(disputes[0], "Shopify dispute");
|
|
99
|
+
const id = first.id;
|
|
100
|
+
if (typeof id !== "string" && !Number.isInteger(id))
|
|
101
|
+
throw new Error("Shopify preflight requires one existing sandbox dispute.");
|
|
102
|
+
const observation = pick(first, ["status", "type", "amount", "currency", "evidence_due_by"]);
|
|
103
|
+
assertCriterion(plan, observation);
|
|
104
|
+
return preflightResult(plan, now, "shopify", id, observation);
|
|
105
|
+
}
|
|
84
106
|
async function stripePreflight(request, secret, plan, now) {
|
|
85
107
|
const response = await request("https://api.stripe.com/v1/refunds?limit=1", { headers: { authorization: `Bearer ${secret}` }, redirect: "error", signal: AbortSignal.timeout(5_000) });
|
|
86
108
|
if (!response.ok)
|
|
@@ -199,7 +221,7 @@ import {join} from "node:path";
|
|
|
199
221
|
const contracts=${JSON.stringify(contracts)};
|
|
200
222
|
const sha=(value)=>createHash("sha256").update(typeof value==="string"?value:JSON.stringify(value)).digest("hex");
|
|
201
223
|
const request=async(url,key)=>{const response=await fetch(url,{method:"GET",headers:{accept:"application/json",authorization:"Bearer "+key},redirect:"error",signal:AbortSignal.timeout(5000)});if(!response.ok)throw new Error("Provider read-only observation failed ("+response.status+").");return response.json();};
|
|
202
|
-
const observe=async(contract,resourceId,repository)=>{const key=(await readFile(join(repository,contract.credentialHandle),"utf8")).trim();if(!key)throw new Error("The local read-only Provider credential is unavailable.");if(contract.providerPackId==="STRIPE_REFUND"){if(!key.startsWith("sk_test_"))throw new Error("Stripe test-mode credential is unavailable.");return request("https://api.stripe.com/v1/refunds/"+encodeURIComponent(resourceId),key);}if(contract.providerPackId==="ZENDESK_TICKET")return (await request(contract.providerConfiguration.origin+"/api/v2/tickets/"+encodeURIComponent(resourceId)+".json",key)).ticket;if(contract.providerPackId==="SALESFORCE_RECORD")return request(contract.providerConfiguration.origin+"/services/data/v61.0/sobjects/"+encodeURIComponent(contract.providerConfiguration.resourceType)+"/"+encodeURIComponent(resourceId),key);if(contract.providerPackId==="HUBSPOT_CRM_RECORD")return (await request("https://api.hubapi.com/crm/v3/objects/"+encodeURIComponent(contract.providerConfiguration.resourceType)+"/"+encodeURIComponent(resourceId)+"?properties="+encodeURIComponent(contract.criterion.field),key)).properties;if(contract.providerPackId==="POSTGRES_RECORD"){for(const name of [contract.providerConfiguration.viewName,contract.providerConfiguration.idColumn,contract.criterion.field])if(!/^[A-Za-z][A-Za-z0-9_]{0,99}$/.test(name))throw new Error("PostgreSQL identifier is invalid.");const {Client}=await import("pg");const client=new Client({connectionString:key,application_name:"witnora-read-only-probe"});await client.connect();try{await client.query("BEGIN READ ONLY");const result=await client.query({name:"witnora-provider-observe",text:'SELECT "'+contract.criterion.field+'" FROM "'+contract.providerConfiguration.viewName+'" WHERE "'+contract.providerConfiguration.idColumn+'" = $1 LIMIT 1',values:[resourceId]});await client.query("ROLLBACK");return result.rows[0]??{};}catch(error){await client.query("ROLLBACK").catch(()=>{});throw error;}finally{await client.end();}}throw new Error("Provider Harness contract is unsupported.");};
|
|
224
|
+
const observe=async(contract,resourceId,repository)=>{const key=(await readFile(join(repository,contract.credentialHandle),"utf8")).trim();if(!key)throw new Error("The local read-only Provider credential is unavailable.");if(contract.providerPackId==="STRIPE_REFUND"){if(!key.startsWith("sk_test_"))throw new Error("Stripe test-mode credential is unavailable.");return request("https://api.stripe.com/v1/refunds/"+encodeURIComponent(resourceId),key);}if(contract.providerPackId==="SHOPIFY_DISPUTE"){const response=await fetch(contract.providerConfiguration.origin+"/admin/api/2025-07/shopify_payments/disputes/"+encodeURIComponent(resourceId)+".json",{method:"GET",headers:{accept:"application/json","x-shopify-access-token":key},redirect:"error",signal:AbortSignal.timeout(5000)});if(!response.ok)throw new Error("Provider read-only observation failed ("+response.status+").");return (await response.json()).dispute;}if(contract.providerPackId==="ZENDESK_TICKET")return (await request(contract.providerConfiguration.origin+"/api/v2/tickets/"+encodeURIComponent(resourceId)+".json",key)).ticket;if(contract.providerPackId==="SALESFORCE_RECORD")return request(contract.providerConfiguration.origin+"/services/data/v61.0/sobjects/"+encodeURIComponent(contract.providerConfiguration.resourceType)+"/"+encodeURIComponent(resourceId),key);if(contract.providerPackId==="HUBSPOT_CRM_RECORD")return (await request("https://api.hubapi.com/crm/v3/objects/"+encodeURIComponent(contract.providerConfiguration.resourceType)+"/"+encodeURIComponent(resourceId)+"?properties="+encodeURIComponent(contract.criterion.field),key)).properties;if(contract.providerPackId==="POSTGRES_RECORD"){for(const name of [contract.providerConfiguration.viewName,contract.providerConfiguration.idColumn,contract.criterion.field])if(!/^[A-Za-z][A-Za-z0-9_]{0,99}$/.test(name))throw new Error("PostgreSQL identifier is invalid.");const {Client}=await import("pg");const client=new Client({connectionString:key,application_name:"witnora-read-only-probe"});await client.connect();try{await client.query("BEGIN READ ONLY");const result=await client.query({name:"witnora-provider-observe",text:'SELECT "'+contract.criterion.field+'" FROM "'+contract.providerConfiguration.viewName+'" WHERE "'+contract.providerConfiguration.idColumn+'" = $1 LIMIT 1',values:[resourceId]});await client.query("ROLLBACK");return result.rows[0]??{};}catch(error){await client.query("ROLLBACK").catch(()=>{});throw error;}finally{await client.end();}}throw new Error("Provider Harness contract is unsupported.");};
|
|
203
225
|
export function createWitnoraBusinessTaskEvaluatorOptions(context){return {
|
|
204
226
|
loadShadowObservations:async(task)=>{const contract=contracts.find((item)=>item.taskContractId===task.id);if(!contract)throw new Error("No exact real-path contract.");const path=join(context.repository,".witnora","scenarios",task.id+".json");const value=JSON.parse(await readFile(path,"utf8"));if(!Array.isArray(value)||value.length>100)throw new Error("Local scenario file is invalid.");return value;},
|
|
205
227
|
evaluateShadowCandidate:async(candidate,task)=>{const contract=contracts.find((item)=>item.taskContractId===task.id);if(!contract)throw new Error("No exact real-path contract.");const resourceId=String(candidate.input?.resourceId??"");if(!/^[A-Za-z0-9._:-]{1,200}$/.test(resourceId))throw new Error("Provider resourceId is invalid.");for(const pathId of contract.actionPathIds)candidate.propose({pathId,parametersDigestSha256:sha(resourceId)});const raw=await observe(contract,resourceId,context.repository);const actual=raw?.[contract.criterion.field];const observed=actual===undefined?{}:{[contract.criterion.field]:actual};return {resultDigestSha256:sha(observed),criteria:[{id:contract.criterion.id,passed:actual===contract.criterion.expected}]};}
|
|
@@ -224,6 +246,8 @@ async function persistProviderCredential(repository, plan, environment) {
|
|
|
224
246
|
function providerCredentialEnvironmentName(packId) {
|
|
225
247
|
if (packId === "STRIPE_REFUND")
|
|
226
248
|
return "STRIPE_SECRET_KEY";
|
|
249
|
+
if (packId === "SHOPIFY_DISPUTE")
|
|
250
|
+
return "SHOPIFY_READ_ACCESS_TOKEN";
|
|
227
251
|
if (packId === "ZENDESK_TICKET")
|
|
228
252
|
return "ZENDESK_API_TOKEN";
|
|
229
253
|
if (packId === "SALESFORCE_RECORD")
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const PRODUCTION_EVALUATOR_OBSERVATION_VERSION: "witnora.production_evaluator_observation.v0.1";
|
|
2
|
-
export type ProductionEvaluatorTemplate = "CRM_RECORD_STATE" | "TICKET_STATUS" | "EMAIL_DELIVERY" | "DATABASE_READ_ONLY" | "WEBHOOK_DELIVERY" | "QUEUE_JOB_COMPLETION" | "PAYMENT_REFUND_RESULT" | "BROWSER_WORKFLOW_OUTCOME";
|
|
2
|
+
export type ProductionEvaluatorTemplate = "CRM_RECORD_STATE" | "TICKET_STATUS" | "EMAIL_DELIVERY" | "DATABASE_READ_ONLY" | "WEBHOOK_DELIVERY" | "QUEUE_JOB_COMPLETION" | "PAYMENT_REFUND_RESULT" | "DISPUTE_STATUS" | "BROWSER_WORKFLOW_OUTCOME";
|
|
3
3
|
type SafeScalar = string | number | boolean | null;
|
|
4
4
|
type SafeFields = Record<string, SafeScalar>;
|
|
5
5
|
export interface ProductionEvaluatorRequest {
|
|
@@ -79,6 +79,7 @@ export declare const createEmailDeliveryEvaluator: (options: HttpProductionEvalu
|
|
|
79
79
|
export declare const createWebhookDeliveryEvaluator: (options: HttpProductionEvaluatorOptions) => ProductionOutcomeEvaluator;
|
|
80
80
|
export declare const createQueueJobCompletionEvaluator: (options: HttpProductionEvaluatorOptions) => ProductionOutcomeEvaluator;
|
|
81
81
|
export declare const createPaymentRefundResultEvaluator: (options: HttpProductionEvaluatorOptions) => ProductionOutcomeEvaluator;
|
|
82
|
+
export declare const createDisputeStatusEvaluator: (options: HttpProductionEvaluatorOptions) => ProductionOutcomeEvaluator;
|
|
82
83
|
export declare function createDatabaseReadOnlyEvaluator(options: DatabaseReadOnlyEvaluatorOptions): ProductionOutcomeEvaluator;
|
|
83
84
|
export declare function createBrowserWorkflowOutcomeEvaluator(options: BrowserWorkflowOutcomeEvaluatorOptions): ProductionOutcomeEvaluator;
|
|
84
85
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"production-evaluator-kit.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/production-evaluator-kit.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,wCAAwC,EAAG,+CAAwD,CAAC;AACjH,MAAM,MAAM,2BAA2B,GAAG,kBAAkB,GAAG,eAAe,GAAG,gBAAgB,GAAG,oBAAoB,GAAG,kBAAkB,GAAG,sBAAsB,GAAG,uBAAuB,GAAG,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"production-evaluator-kit.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/production-evaluator-kit.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ export const createEmailDeliveryEvaluator = (options) => createHttpEvaluator("EM
|
|
|
8
8
|
export const createWebhookDeliveryEvaluator = (options) => createHttpEvaluator("WEBHOOK_DELIVERY", options);
|
|
9
9
|
export const createQueueJobCompletionEvaluator = (options) => createHttpEvaluator("QUEUE_JOB_COMPLETION", options);
|
|
10
10
|
export const createPaymentRefundResultEvaluator = (options) => createHttpEvaluator("PAYMENT_REFUND_RESULT", options);
|
|
11
|
+
export const createDisputeStatusEvaluator = (options) => createHttpEvaluator("DISPUTE_STATUS", options);
|
|
11
12
|
export function createDatabaseReadOnlyEvaluator(options) {
|
|
12
13
|
validateCommon(options);
|
|
13
14
|
identifier(options.statementId, "statementId");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type BrowserWorkflowOutcomeEvaluatorOptions, type DatabaseReadOnlyEvaluatorOptions, type HttpProductionEvaluatorOptions, type ProductionOutcomeEvaluator, type ProductionEvaluatorTemplate } from "./production-evaluator-kit.js";
|
|
2
2
|
export declare const PROVIDER_INTEGRATION_PACK_SCHEMA_VERSION: "witnora.provider_integration_pack.v0.1";
|
|
3
|
-
export type ProviderIntegrationPackId = "STRIPE_REFUND" | "SALESFORCE_RECORD" | "HUBSPOT_CRM_RECORD" | "ZENDESK_TICKET" | "INTERCOM_TICKET" | "POSTGRES_RECORD" | "MYSQL_RECORD" | "WEBHOOK_DELIVERY" | "QUEUE_JOB" | "EMAIL_DELIVERY" | "BROWSER_WORKFLOW";
|
|
3
|
+
export type ProviderIntegrationPackId = "STRIPE_REFUND" | "SHOPIFY_DISPUTE" | "SALESFORCE_RECORD" | "HUBSPOT_CRM_RECORD" | "ZENDESK_TICKET" | "INTERCOM_TICKET" | "POSTGRES_RECORD" | "MYSQL_RECORD" | "WEBHOOK_DELIVERY" | "QUEUE_JOB" | "EMAIL_DELIVERY" | "BROWSER_WORKFLOW";
|
|
4
4
|
export interface ProviderIntegrationPack {
|
|
5
5
|
schemaVersion: typeof PROVIDER_INTEGRATION_PACK_SCHEMA_VERSION;
|
|
6
6
|
id: ProviderIntegrationPackId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-integration-packs.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/provider-integration-packs.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"provider-integration-packs.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/provider-integration-packs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { createBrowserWorkflowOutcomeEvaluator, createCrmRecordStateEvaluator, createDatabaseReadOnlyEvaluator, createEmailDeliveryEvaluator, createPaymentRefundResultEvaluator, createQueueJobCompletionEvaluator, createTicketStatusEvaluator, createWebhookDeliveryEvaluator, } from "./production-evaluator-kit.js";
|
|
2
|
+
import { createBrowserWorkflowOutcomeEvaluator, createCrmRecordStateEvaluator, createDatabaseReadOnlyEvaluator, createDisputeStatusEvaluator, createEmailDeliveryEvaluator, createPaymentRefundResultEvaluator, createQueueJobCompletionEvaluator, createTicketStatusEvaluator, createWebhookDeliveryEvaluator, } from "./production-evaluator-kit.js";
|
|
3
3
|
import { canonicalJson } from "./trust-crypto.js";
|
|
4
4
|
export const PROVIDER_INTEGRATION_PACK_SCHEMA_VERSION = "witnora.provider_integration_pack.v0.1";
|
|
5
5
|
const BASE = [
|
|
6
6
|
pack("STRIPE_REFUND", "stripe", "Stripe refund result", "PAYMENT_REFUND_RESULT", ["sandbox", "production"], ["refunds:read"], "env://STRIPE_SECRET_KEY", ["status", "amount", "currency", "failure_reason"], "/v1/refunds/{resourceId}", "https://api.stripe.com", [criterion("refund-complete", "Which Stripe status means the refund completed?", "status", ["succeeded"])]),
|
|
7
|
+
pack("SHOPIFY_DISPUTE", "shopify", "Shopify Payments dispute status", "DISPUTE_STATUS", ["sandbox", "production"], ["shopify_payments_disputes:read"], "env://SHOPIFY_READ_ACCESS_TOKEN", ["status", "type", "amount", "currency", "evidence_due_by"], "/admin/api/2025-07/shopify_payments/disputes/{resourceId}.json", undefined, [criterion("dispute-decided", "Which Shopify dispute state establishes the final business result?", "status", ["won", "lost"])]),
|
|
7
8
|
pack("SALESFORCE_RECORD", "salesforce", "Salesforce record state", "CRM_RECORD_STATE", ["sandbox", "production"], ["API enabled with object and field read-only permission set"], "env://SALESFORCE_ACCESS_TOKEN", ["Status__c", "Refund_Status__c", "IsClosed", "StageName"], "/services/data/v61.0/sobjects/{object}/{resourceId}", undefined, [criterion("crm-state", "Which Salesforce field and value establish success?", "Status__c", ["Completed", "Approved"])]),
|
|
8
9
|
pack("HUBSPOT_CRM_RECORD", "hubspot", "HubSpot CRM record", "CRM_RECORD_STATE", ["sandbox", "production"], ["crm.objects.read"], "env://HUBSPOT_ACCESS_TOKEN", ["hs_pipeline_stage", "hs_status", "closedate", "amount"], "/crm/v3/objects/{object}/{resourceId}", "https://api.hubapi.com", [criterion("crm-state", "Which HubSpot property means the business task completed?", "hs_status", ["closed", "completed"])]),
|
|
9
10
|
pack("ZENDESK_TICKET", "zendesk", "Zendesk ticket status", "TICKET_STATUS", ["sandbox", "production"], ["tickets:read"], "env://ZENDESK_API_TOKEN", ["status", "priority", "type", "via.channel"], "/api/v2/tickets/{resourceId}.json", undefined, [criterion("ticket-complete", "Which Zendesk status means the ticket is complete?", "status", ["solved", "closed"])]),
|
|
@@ -47,6 +48,7 @@ export function createProviderPackEvaluator(options) {
|
|
|
47
48
|
case "WEBHOOK_DELIVERY": return createWebhookDeliveryEvaluator(input);
|
|
48
49
|
case "QUEUE_JOB_COMPLETION": return createQueueJobCompletionEvaluator(input);
|
|
49
50
|
case "PAYMENT_REFUND_RESULT": return createPaymentRefundResultEvaluator(input);
|
|
51
|
+
case "DISPUTE_STATUS": return createDisputeStatusEvaluator(input);
|
|
50
52
|
default: throw new Error("Provider pack evaluator template is unsupported.");
|
|
51
53
|
}
|
|
52
54
|
}
|
|
@@ -80,6 +82,8 @@ function resourcePathBuilder(packId, pattern, resourceType, fields) {
|
|
|
80
82
|
};
|
|
81
83
|
}
|
|
82
84
|
function providerPayload(packId, value) {
|
|
85
|
+
if (packId === "SHOPIFY_DISPUTE")
|
|
86
|
+
return nestedRecord(value, "dispute", "Shopify dispute response");
|
|
83
87
|
if (packId === "ZENDESK_TICKET")
|
|
84
88
|
return nestedRecord(value, "ticket", "Zendesk ticket response");
|
|
85
89
|
if (packId === "HUBSPOT_CRM_RECORD")
|
|
@@ -88,6 +92,8 @@ function providerPayload(packId, value) {
|
|
|
88
92
|
}
|
|
89
93
|
function validateProviderOrigin(packId, value) {
|
|
90
94
|
const url = new URL(value);
|
|
95
|
+
if (packId === "SHOPIFY_DISPUTE" && (url.protocol !== "https:" || !/^[a-z0-9][a-z0-9-]*\.myshopify\.com$/.test(url.hostname)))
|
|
96
|
+
throw new Error("Shopify origin must be the exact HTTPS myshopify.com shop domain.");
|
|
91
97
|
if (packId === "ZENDESK_TICKET" && (url.protocol !== "https:" || !url.hostname.endsWith(".zendesk.com")))
|
|
92
98
|
throw new Error("Zendesk origin must be an HTTPS customer subdomain of zendesk.com.");
|
|
93
99
|
if (packId === "SALESFORCE_RECORD" && (url.protocol !== "https:" || !url.hostname.endsWith(".my.salesforce.com")))
|