@friggframework/core 2.0.0--canary.698.b1a2d30.0 → 2.0.0--canary.700.80ec1cc.0
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/generated/prisma-mongodb/edge.js +2 -2
- package/generated/prisma-mongodb/index.js +2 -2
- package/generated/prisma-mongodb/package.json +1 -1
- package/generated/prisma-mongodb/schema.prisma +2 -2
- package/generated/prisma-mongodb/wasm.js +2 -2
- package/generated/prisma-postgresql/edge.js +2 -2
- package/generated/prisma-postgresql/index.js +2 -2
- package/generated/prisma-postgresql/package.json +1 -1
- package/generated/prisma-postgresql/schema.prisma +2 -2
- package/generated/prisma-postgresql/wasm.js +2 -2
- package/handlers/app-handler-helpers.js +5 -2
- package/handlers/integration-event-dispatcher.js +1 -1
- package/integrations/{data-defined → definitions}/README.md +12 -12
- package/integrations/{data-defined → definitions}/capabilities/AUDIT.md +104 -75
- package/integrations/{data-defined → definitions}/capabilities/asana.capabilities.json +13 -8
- package/integrations/{data-defined → definitions}/capabilities/fathom.capabilities.json +4 -4
- package/integrations/{data-defined → definitions}/capabilities/hubspot.capabilities.json +77 -49
- package/integrations/{data-defined → definitions}/capabilities/linear.capabilities.json +38 -20
- package/integrations/{data-defined → definitions}/capabilities/phone.capabilities.json +1 -2
- package/integrations/{data-defined → definitions}/capabilities/pipedrive.capabilities.json +8 -6
- package/integrations/{data-defined → definitions}/capabilities/salesforce.capabilities.json +30 -15
- package/integrations/{data-defined → definitions}/capabilities/slack.capabilities.json +7 -4
- package/integrations/{data-defined → definitions}/capabilities/stripe.capabilities.json +27 -18
- package/integrations/{data-defined → definitions}/config-form.js +1 -1
- package/integrations/{data-defined → definitions}/examples/fathom-hubspot-notion.definition.json +9 -9
- package/integrations/{data-defined → definitions}/examples/hubspot-slack.definition.json +25 -7
- package/integrations/{data-defined → definitions}/examples/phone-hubspot.definition.json +1 -1
- package/integrations/{data-defined → definitions}/examples/pipedrive-hubspot.definition.json +1 -1
- package/integrations/{data-defined → definitions}/examples/records/phone-hubspot.definition-version.json +1 -1
- package/integrations/{data-defined → definitions}/examples/records/phone-hubspot.integration.json +1 -1
- package/integrations/{data-defined → definitions}/expressions.js +1 -1
- package/integrations/{data-defined → definitions}/index.js +2 -2
- package/integrations/{data-defined/data-defined-integration.js → definitions/integration-runtime.js} +22 -21
- package/integrations/{data-defined → definitions}/renderers/hubspot.js +13 -8
- package/integrations/{data-defined → definitions}/router.js +11 -11
- package/integrations/{data-defined → definitions}/runtime.js +1 -1
- package/integrations/{data-defined → definitions}/schema/installation.v0.1.schema.json +1 -1
- package/integrations/{data-defined → definitions}/schema/records.md +1 -1
- package/integrations/{data-defined → definitions}/scripts/validate.js +1 -1
- package/integrations/{data-defined → definitions}/use-cases/definition-use-cases.js +1 -1
- package/integrations/{data-defined → definitions}/versioning.js +1 -1
- package/integrations/integration-base.js +31 -1
- package/integrations/integration-router.js +1 -1
- package/package.json +6 -6
- package/prisma-mongodb/schema.prisma +2 -2
- package/prisma-postgresql/schema.prisma +2 -2
- /package/integrations/{data-defined → definitions}/canonical.js +0 -0
- /package/integrations/{data-defined → definitions}/capabilities/acmeerp.capabilities.json +0 -0
- /package/integrations/{data-defined → definitions}/capabilities/calendly.capabilities.json +0 -0
- /package/integrations/{data-defined → definitions}/capabilities/docusign.capabilities.json +0 -0
- /package/integrations/{data-defined → definitions}/capabilities/github.capabilities.json +0 -0
- /package/integrations/{data-defined → definitions}/capabilities/jira.capabilities.json +0 -0
- /package/integrations/{data-defined → definitions}/capabilities/klaviyo.capabilities.json +0 -0
- /package/integrations/{data-defined → definitions}/capabilities/netsuite.capabilities.json +0 -0
- /package/integrations/{data-defined → definitions}/capabilities/notion.capabilities.json +0 -0
- /package/integrations/{data-defined → definitions}/capabilities/quickbooks.capabilities.json +0 -0
- /package/integrations/{data-defined → definitions}/capabilities/shopify.capabilities.json +0 -0
- /package/integrations/{data-defined → definitions}/capabilities/webflow.capabilities.json +0 -0
- /package/integrations/{data-defined → definitions}/capabilities/zendesk.capabilities.json +0 -0
- /package/integrations/{data-defined → definitions}/compile.js +0 -0
- /package/integrations/{data-defined → definitions}/examples/acme-erp-quickbooks.definition.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/asana-slack.definition.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/calendly-salesforce.definition.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/docusign-salesforce.definition.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/github-linear.definition.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/klaviyo-hubspot.definition.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/pipedrive-phone.definition.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/records/phone-hubspot.mappings.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/records/phone-hubspot.workflow-run.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/shopify-klaviyo.definition.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/shopify-netsuite.definition.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/stripe-quickbooks.definition.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/webflow-hubspot-slack.definition.json +0 -0
- /package/integrations/{data-defined → definitions}/examples/zendesk-jira.definition.json +0 -0
- /package/integrations/{data-defined → definitions}/interpreter.js +0 -0
- /package/integrations/{data-defined → definitions}/manifests.js +0 -0
- /package/integrations/{data-defined → definitions}/renderers/common.js +0 -0
- /package/integrations/{data-defined → definitions}/renderers/html.js +0 -0
- /package/integrations/{data-defined → definitions}/renderers/preview.js +0 -0
- /package/integrations/{data-defined → definitions}/renderers/slack.js +0 -0
- /package/integrations/{data-defined → definitions}/repositories/definition-version-repository.js +0 -0
- /package/integrations/{data-defined → definitions}/repositories/workflow-run-repository.js +0 -0
- /package/integrations/{data-defined → definitions}/schema/capability-manifest.v0.1.schema.json +0 -0
- /package/integrations/{data-defined → definitions}/schema/integration-definition.v0.1.schema.json +0 -0
- /package/integrations/{data-defined → definitions}/schema-check.js +0 -0
- /package/integrations/{data-defined → definitions}/scripts/check-manifests.js +0 -0
- /package/integrations/{data-defined → definitions}/steps.js +0 -0
- /package/integrations/{data-defined → definitions}/sync-engine.js +0 -0
- /package/integrations/{data-defined → definitions}/tests/helpers-fake-crm.js +0 -0
- /package/integrations/{data-defined → definitions}/transforms.js +0 -0
- /package/integrations/{data-defined → definitions}/validate.js +0 -0
- /package/integrations/{data-defined → definitions}/webhooks.js +0 -0
|
@@ -428,8 +428,8 @@ const config = {
|
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
430
|
},
|
|
431
|
-
"inlineSchema": "// Frigg Framework - Prisma Schema (PostgreSQL)\n// PostgreSQL database schema for enterprise integration platform\n// Converted from MongoDB schema for relational database support\n\ngenerator client {\n provider = \"prisma-client-js\"\n output = \"../generated/prisma-postgresql\"\n binaryTargets = [\"native\", \"rhel-openssl-3.0.x\"] // native for local dev, rhel for Lambda deployment\n // Library engine (default since Prisma 3.x): Rust query engine loads as a\n // Node-API addon inside the same process. The binary engine forks a child\n // query-engine subprocess and communicates over a local HTTP/IPC pipe with\n // NO client-side timeout — a zombied child wedges the Node process until\n // Lambda's 900s cap. Switching to library eliminates that entire class of\n // silent hangs. See friggframework/frigg#580 for the investigation.\n engineType = \"library\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n url = env(\"DATABASE_URL\")\n}\n\n// ============================================================================\n// USER MODELS\n// ============================================================================\n\n/// User model with discriminator pattern support\n/// Replaces Mongoose discriminators (IndividualUser, OrganizationUser)\nmodel User {\n id Int @id @default(autoincrement())\n type UserType\n\n // Timestamps\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n // IndividualUser fields (nullable for organizations)\n email String?\n username String?\n hashword String? // Bcrypt hashed password (handled in application layer)\n appUserId String?\n organizationId Int?\n\n // Self-referential relation for organization membership\n organization User? @relation(\"OrgMembers\", fields: [organizationId], references: [id], onDelete: NoAction, onUpdate: NoAction)\n members User[] @relation(\"OrgMembers\")\n\n // OrganizationUser fields (nullable for individuals)\n appOrgId String?\n name String?\n\n // Relations\n tokens Token[]\n credentials Credential[]\n entities Entity[]\n integrations Integration[]\n processes Process[]\n\n @@unique([username, appUserId])\n @@index([type])\n @@index([appUserId])\n @@index([organizationId])\n}\n\nenum UserType {\n INDIVIDUAL\n ORGANIZATION\n}\n\n// ============================================================================\n// AUTHENTICATION MODELS\n// ============================================================================\n\n/// Authentication tokens with expiration\n/// Bcrypt hashed tokens stored (handled in application layer)\nmodel Token {\n id Int @id @default(autoincrement())\n token String // Bcrypt hashed\n created DateTime @default(now())\n expires DateTime?\n userId Int\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@index([userId])\n @@index([expires])\n}\n\n// ============================================================================\n// CREDENTIAL & ENTITY MODELS\n// ============================================================================\n\n/// OAuth credentials and API tokens\n/// All sensitive data encrypted with KMS at rest\nmodel Credential {\n id Int @id @default(autoincrement())\n userId Int?\n user User? @relation(fields: [userId], references: [id], onDelete: Cascade)\n authIsValid Boolean?\n externalId String?\n\n // Dynamic OAuth fields stored as JSON (encrypted via Prisma middleware)\n // Contains: access_token, refresh_token, domain, expires_in, token_type, etc.\n data Json @default(\"{}\")\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n // Relations\n entities Entity[]\n\n @@index([userId])\n @@index([externalId])\n}\n\n/// External service entities (API connections)\nmodel Entity {\n id Int @id @default(autoincrement())\n credentialId Int?\n credential Credential? @relation(fields: [credentialId], references: [id], onDelete: SetNull)\n userId Int?\n user User? @relation(fields: [userId], references: [id], onDelete: Cascade)\n name String?\n moduleName String?\n externalId String?\n\n data Json @default(\"{}\")\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n // Relations - many-to-many with implicit join tables\n integrations Integration[]\n syncs Sync[]\n\n dataIdentifiers DataIdentifier[]\n associationObjects AssociationObject[]\n\n @@index([userId])\n @@index([externalId])\n @@index([moduleName])\n @@index([credentialId])\n}\n\n// ============================================================================\n// INTEGRATION MODELS\n// ============================================================================\n\n/// Main integration configuration and state\nmodel Integration {\n id Int @id @default(autoincrement())\n userId Int?\n user User? @relation(fields: [userId], references: [id], onDelete: Cascade)\n status IntegrationStatus @default(IN_CREATION)\n\n // Configuration and version\n config Json? // Integration configuration object\n version String?\n\n // Entity references (many-to-many via implicit join table)\n entities Entity[]\n\n // Message arrays (stored as JSON)\n errors Json @default(\"[]\")\n warnings Json @default(\"[]\")\n info Json @default(\"[]\")\n logs Json @default(\"[]\")\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n // Relations\n associations Association[]\n syncs Sync[]\n mappings IntegrationMapping[]\n processes Process[]\n workflowRuns WorkflowRun[]\n\n @@index([userId])\n @@index([status])\n}\n\nenum IntegrationStatus {\n ENABLED\n NEEDS_CONFIG\n PROCESSING\n DISABLED\n ERROR\n IN_CREATION\n IN_DELETION\n}\n\n/// Integration-specific data mappings\n/// All mapping data encrypted with KMS\nmodel IntegrationMapping {\n id Int @id @default(autoincrement())\n integrationId Int\n integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)\n sourceId String?\n\n // Encrypted mapping data (handled via Prisma middleware)\n mapping Json?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@unique([integrationId, sourceId])\n @@index([integrationId])\n @@index([sourceId])\n}\n\n// ============================================================================\n// SYNC MODELS\n// ============================================================================\n\n/// Bidirectional data synchronization tracking\nmodel Sync {\n id Int @id @default(autoincrement())\n integrationId Int?\n integration Integration? @relation(fields: [integrationId], references: [id], onDelete: Cascade)\n\n // Entity references (many-to-many via implicit join table)\n entities Entity[]\n\n hash String\n name String\n\n // Data identifiers (extracted to separate model)\n dataIdentifiers DataIdentifier[]\n\n @@index([integrationId])\n @@index([hash])\n @@index([name])\n}\n\n/// Data identifier for sync operations\n/// Replaces nested array structure in Mongoose\nmodel DataIdentifier {\n id Int @id @default(autoincrement())\n syncId Int?\n sync Sync? @relation(fields: [syncId], references: [id], onDelete: Cascade)\n entityId Int\n entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)\n\n // Identifier data (can be any structure)\n idData Json\n\n hash String\n\n @@index([syncId])\n @@index([entityId])\n @@index([hash])\n}\n\n// ============================================================================\n// ASSOCIATION MODELS\n// ============================================================================\n\n/// Entity associations with cardinality tracking\nmodel Association {\n id Int @id @default(autoincrement())\n integrationId Int\n integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)\n name String\n type AssociationType\n primaryObject String\n\n // Associated objects (extracted to separate model)\n objects AssociationObject[]\n\n @@index([integrationId])\n @@index([name])\n}\n\n/// Association object entry\n/// Replaces nested array structure in Mongoose\nmodel AssociationObject {\n id Int @id @default(autoincrement())\n associationId Int\n association Association @relation(fields: [associationId], references: [id], onDelete: Cascade)\n entityId Int\n entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)\n objectType String\n objId String\n metadata Json? // Optional metadata\n\n @@index([associationId])\n @@index([entityId])\n}\n\nenum AssociationType {\n ONE_TO_MANY\n ONE_TO_ONE\n MANY_TO_ONE\n}\n\n// ============================================================================\n// PROCESS MODELS\n// ============================================================================\n\n/// Generic Process Model - tracks any long-running operation\n/// Used for: CRM syncs, data migrations, bulk operations, etc.\nmodel Process {\n id Int @id @default(autoincrement())\n\n // Core references\n userId Int\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n integrationId Int\n integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)\n\n // Process identification\n name String // e.g., \"zoho-crm-contact-sync\", \"pipedrive-lead-sync\"\n type String // e.g., \"CRM_SYNC\", \"DATA_MIGRATION\", \"BULK_OPERATION\"\n\n // State machine\n state String // Current state (integration-defined states)\n\n // Flexible storage\n context Json @default(\"{}\") // Process-specific data (pagination, metadata, etc.)\n results Json @default(\"{}\") // Process results and metrics\n\n // Hierarchy support - self-referential relation\n parentProcessId Int?\n parentProcess Process? @relation(\"ProcessHierarchy\", fields: [parentProcessId], references: [id], onDelete: SetNull)\n childProcesses Process[] @relation(\"ProcessHierarchy\")\n\n // Timestamps\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userId])\n @@index([integrationId])\n @@index([type])\n @@index([state])\n @@index([name])\n @@index([parentProcessId])\n}\n\n// ============================================================================\n// UTILITY MODELS\n// ============================================================================\n\n/// Generic state storage\nmodel State {\n id Int @id @default(autoincrement())\n state Json?\n}\n\n/// AWS API Gateway WebSocket connection tracking\nmodel WebsocketConnection {\n id Int @id @default(autoincrement())\n connectionId String?\n\n @@index([connectionId])\n}\n\n// ============================================================================\n// ADMIN PROCESS MODELS\n// ============================================================================\n\n/// Admin process state machine\nenum AdminScriptExecutionState {\n PENDING\n RUNNING\n COMPLETED\n FAILED\n}\n\n/// Admin process tracking (like Process but without user/integration FK)\n/// Used for: admin scripts, db migrations, system maintenance tasks\nmodel AdminScriptExecution {\n id Int @id @default(autoincrement())\n name String // e.g., \"oauth-token-refresh\", \"db-migration-xyz\"\n type String // e.g., \"ADMIN_SCRIPT\", \"DB_MIGRATION\"\n\n // State machine\n state AdminScriptExecutionState @default(PENDING)\n\n // Flexible storage (mirrors Process model pattern)\n context Json @default(\"{}\") // input, trigger, audit info, script version\n results Json @default(\"{}\") // output, logs, metrics, errors\n\n // Hierarchy support - self-referential relation\n parentExecutionId Int?\n parentExecution AdminScriptExecution? @relation(\"AdminScriptExecutionHierarchy\", fields: [parentExecutionId], references: [id], onDelete: SetNull)\n childExecutions AdminScriptExecution[] @relation(\"AdminScriptExecutionHierarchy\")\n\n // Timestamps\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([name, createdAt(sort: Desc)])\n @@index([state])\n @@index([type])\n}\n\n/// Script scheduling configuration for hybrid scheduling (SQS + EventBridge)\nmodel ScriptSchedule {\n id Int @id @default(autoincrement())\n scriptName String @unique\n enabled Boolean @default(false)\n cronExpression String?\n timezone String @default(\"UTC\")\n lastTriggeredAt DateTime?\n nextTriggerAt DateTime?\n\n // External Scheduler (e.g., AWS EventBridge Scheduler)\n externalScheduleId String?\n externalScheduleName String?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([enabled])\n}\n\n/// Durable usage counters, deliberately isolated: no userId and no foreign key\n/// to Integration, so a user-scoped query can never return a usage row and usage\n/// history survives integration deletion.\nmodel UsageCounter {\n id Int @id @default(autoincrement())\n\n integrationId String\n integrationType String\n metric String\n window String // e.g. \"day:2026-07-05\" or \"hour:2026-07-05T14\"\n value BigInt @default(0) // BigInt: a busy day/hour counter can exceed 32-bit\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@unique([integrationId, integrationType, metric, window])\n // Covers totals() (metric + window prefix/range, no integrationType filter).\n @@index([metric, window])\n // Covers series() (metric + integrationType + window range).\n @@index([metric, integrationType, window])\n}\n\n// Data-defined integrations (ADR-063): one immutable row per published definition version.\nenum DefinitionStatus {\n DRAFT\n PUBLISHED\n DEPRECATED\n RETIRED\n}\n\nmodel IntegrationDefinitionVersion {\n id Int @id @default(autoincrement())\n definitionId String\n version String\n schemaVersion String\n status DefinitionStatus @default(DRAFT)\n checksum String\n document Json\n changeLevel String?\n previousVersion String?\n notes String?\n createdBy String?\n // The workspace an integration a user built belongs to (null: the app's own catalogue, offered to everyone).\n workspaceId String?\n publishedAt DateTime?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@unique([definitionId, version])\n @@index([definitionId, status])\n @@index([workspaceId, status])\n}\n\n// One row per data-defined workflow run. trace holds step ids, statuses, timings and error messages, never request or\n// response bodies.\nmodel WorkflowRun {\n id Int @id @default(autoincrement())\n integrationId Int\n integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)\n definitionId String\n definitionVersion String\n workflowId String\n triggerType String\n eventId String?\n status String\n reason String?\n error String?\n retryable Boolean @default(false)\n trace Json @default(\"[]\")\n /// The runtime's run id (run_...): how routes and resume jobs address a run\n runKey String?\n /// A paused run (status waiting): which step, and what it waits for. Never request or response bodies.\n waitingFor Json?\n resumeAt DateTime?\n startedAt DateTime\n endedAt DateTime?\n createdAt DateTime @default(now())\n\n @@index([integrationId, runKey])\n @@index([integrationId, startedAt])\n @@index([integrationId, workflowId, startedAt])\n @@index([integrationId, status])\n}\n",
|
|
432
|
-
"inlineSchemaHash": "
|
|
431
|
+
"inlineSchema": "// Frigg Framework - Prisma Schema (PostgreSQL)\n// PostgreSQL database schema for enterprise integration platform\n// Converted from MongoDB schema for relational database support\n\ngenerator client {\n provider = \"prisma-client-js\"\n output = \"../generated/prisma-postgresql\"\n binaryTargets = [\"native\", \"rhel-openssl-3.0.x\"] // native for local dev, rhel for Lambda deployment\n // Library engine (default since Prisma 3.x): Rust query engine loads as a\n // Node-API addon inside the same process. The binary engine forks a child\n // query-engine subprocess and communicates over a local HTTP/IPC pipe with\n // NO client-side timeout — a zombied child wedges the Node process until\n // Lambda's 900s cap. Switching to library eliminates that entire class of\n // silent hangs. See friggframework/frigg#580 for the investigation.\n engineType = \"library\"\n}\n\ndatasource db {\n provider = \"postgresql\"\n url = env(\"DATABASE_URL\")\n}\n\n// ============================================================================\n// USER MODELS\n// ============================================================================\n\n/// User model with discriminator pattern support\n/// Replaces Mongoose discriminators (IndividualUser, OrganizationUser)\nmodel User {\n id Int @id @default(autoincrement())\n type UserType\n\n // Timestamps\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n // IndividualUser fields (nullable for organizations)\n email String?\n username String?\n hashword String? // Bcrypt hashed password (handled in application layer)\n appUserId String?\n organizationId Int?\n\n // Self-referential relation for organization membership\n organization User? @relation(\"OrgMembers\", fields: [organizationId], references: [id], onDelete: NoAction, onUpdate: NoAction)\n members User[] @relation(\"OrgMembers\")\n\n // OrganizationUser fields (nullable for individuals)\n appOrgId String?\n name String?\n\n // Relations\n tokens Token[]\n credentials Credential[]\n entities Entity[]\n integrations Integration[]\n processes Process[]\n\n @@unique([username, appUserId])\n @@index([type])\n @@index([appUserId])\n @@index([organizationId])\n}\n\nenum UserType {\n INDIVIDUAL\n ORGANIZATION\n}\n\n// ============================================================================\n// AUTHENTICATION MODELS\n// ============================================================================\n\n/// Authentication tokens with expiration\n/// Bcrypt hashed tokens stored (handled in application layer)\nmodel Token {\n id Int @id @default(autoincrement())\n token String // Bcrypt hashed\n created DateTime @default(now())\n expires DateTime?\n userId Int\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n\n @@index([userId])\n @@index([expires])\n}\n\n// ============================================================================\n// CREDENTIAL & ENTITY MODELS\n// ============================================================================\n\n/// OAuth credentials and API tokens\n/// All sensitive data encrypted with KMS at rest\nmodel Credential {\n id Int @id @default(autoincrement())\n userId Int?\n user User? @relation(fields: [userId], references: [id], onDelete: Cascade)\n authIsValid Boolean?\n externalId String?\n\n // Dynamic OAuth fields stored as JSON (encrypted via Prisma middleware)\n // Contains: access_token, refresh_token, domain, expires_in, token_type, etc.\n data Json @default(\"{}\")\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n // Relations\n entities Entity[]\n\n @@index([userId])\n @@index([externalId])\n}\n\n/// External service entities (API connections)\nmodel Entity {\n id Int @id @default(autoincrement())\n credentialId Int?\n credential Credential? @relation(fields: [credentialId], references: [id], onDelete: SetNull)\n userId Int?\n user User? @relation(fields: [userId], references: [id], onDelete: Cascade)\n name String?\n moduleName String?\n externalId String?\n\n data Json @default(\"{}\")\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n // Relations - many-to-many with implicit join tables\n integrations Integration[]\n syncs Sync[]\n\n dataIdentifiers DataIdentifier[]\n associationObjects AssociationObject[]\n\n @@index([userId])\n @@index([externalId])\n @@index([moduleName])\n @@index([credentialId])\n}\n\n// ============================================================================\n// INTEGRATION MODELS\n// ============================================================================\n\n/// Main integration configuration and state\nmodel Integration {\n id Int @id @default(autoincrement())\n userId Int?\n user User? @relation(fields: [userId], references: [id], onDelete: Cascade)\n status IntegrationStatus @default(IN_CREATION)\n\n // Configuration and version\n config Json? // Integration configuration object\n version String?\n\n // Entity references (many-to-many via implicit join table)\n entities Entity[]\n\n // Message arrays (stored as JSON)\n errors Json @default(\"[]\")\n warnings Json @default(\"[]\")\n info Json @default(\"[]\")\n logs Json @default(\"[]\")\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n // Relations\n associations Association[]\n syncs Sync[]\n mappings IntegrationMapping[]\n processes Process[]\n workflowRuns WorkflowRun[]\n\n @@index([userId])\n @@index([status])\n}\n\nenum IntegrationStatus {\n ENABLED\n NEEDS_CONFIG\n PROCESSING\n DISABLED\n ERROR\n IN_CREATION\n IN_DELETION\n}\n\n/// Integration-specific data mappings\n/// All mapping data encrypted with KMS\nmodel IntegrationMapping {\n id Int @id @default(autoincrement())\n integrationId Int\n integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)\n sourceId String?\n\n // Encrypted mapping data (handled via Prisma middleware)\n mapping Json?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@unique([integrationId, sourceId])\n @@index([integrationId])\n @@index([sourceId])\n}\n\n// ============================================================================\n// SYNC MODELS\n// ============================================================================\n\n/// Bidirectional data synchronization tracking\nmodel Sync {\n id Int @id @default(autoincrement())\n integrationId Int?\n integration Integration? @relation(fields: [integrationId], references: [id], onDelete: Cascade)\n\n // Entity references (many-to-many via implicit join table)\n entities Entity[]\n\n hash String\n name String\n\n // Data identifiers (extracted to separate model)\n dataIdentifiers DataIdentifier[]\n\n @@index([integrationId])\n @@index([hash])\n @@index([name])\n}\n\n/// Data identifier for sync operations\n/// Replaces nested array structure in Mongoose\nmodel DataIdentifier {\n id Int @id @default(autoincrement())\n syncId Int?\n sync Sync? @relation(fields: [syncId], references: [id], onDelete: Cascade)\n entityId Int\n entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)\n\n // Identifier data (can be any structure)\n idData Json\n\n hash String\n\n @@index([syncId])\n @@index([entityId])\n @@index([hash])\n}\n\n// ============================================================================\n// ASSOCIATION MODELS\n// ============================================================================\n\n/// Entity associations with cardinality tracking\nmodel Association {\n id Int @id @default(autoincrement())\n integrationId Int\n integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)\n name String\n type AssociationType\n primaryObject String\n\n // Associated objects (extracted to separate model)\n objects AssociationObject[]\n\n @@index([integrationId])\n @@index([name])\n}\n\n/// Association object entry\n/// Replaces nested array structure in Mongoose\nmodel AssociationObject {\n id Int @id @default(autoincrement())\n associationId Int\n association Association @relation(fields: [associationId], references: [id], onDelete: Cascade)\n entityId Int\n entity Entity @relation(fields: [entityId], references: [id], onDelete: Cascade)\n objectType String\n objId String\n metadata Json? // Optional metadata\n\n @@index([associationId])\n @@index([entityId])\n}\n\nenum AssociationType {\n ONE_TO_MANY\n ONE_TO_ONE\n MANY_TO_ONE\n}\n\n// ============================================================================\n// PROCESS MODELS\n// ============================================================================\n\n/// Generic Process Model - tracks any long-running operation\n/// Used for: CRM syncs, data migrations, bulk operations, etc.\nmodel Process {\n id Int @id @default(autoincrement())\n\n // Core references\n userId Int\n user User @relation(fields: [userId], references: [id], onDelete: Cascade)\n integrationId Int\n integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)\n\n // Process identification\n name String // e.g., \"zoho-crm-contact-sync\", \"pipedrive-lead-sync\"\n type String // e.g., \"CRM_SYNC\", \"DATA_MIGRATION\", \"BULK_OPERATION\"\n\n // State machine\n state String // Current state (integration-defined states)\n\n // Flexible storage\n context Json @default(\"{}\") // Process-specific data (pagination, metadata, etc.)\n results Json @default(\"{}\") // Process results and metrics\n\n // Hierarchy support - self-referential relation\n parentProcessId Int?\n parentProcess Process? @relation(\"ProcessHierarchy\", fields: [parentProcessId], references: [id], onDelete: SetNull)\n childProcesses Process[] @relation(\"ProcessHierarchy\")\n\n // Timestamps\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([userId])\n @@index([integrationId])\n @@index([type])\n @@index([state])\n @@index([name])\n @@index([parentProcessId])\n}\n\n// ============================================================================\n// UTILITY MODELS\n// ============================================================================\n\n/// Generic state storage\nmodel State {\n id Int @id @default(autoincrement())\n state Json?\n}\n\n/// AWS API Gateway WebSocket connection tracking\nmodel WebsocketConnection {\n id Int @id @default(autoincrement())\n connectionId String?\n\n @@index([connectionId])\n}\n\n// ============================================================================\n// ADMIN PROCESS MODELS\n// ============================================================================\n\n/// Admin process state machine\nenum AdminScriptExecutionState {\n PENDING\n RUNNING\n COMPLETED\n FAILED\n}\n\n/// Admin process tracking (like Process but without user/integration FK)\n/// Used for: admin scripts, db migrations, system maintenance tasks\nmodel AdminScriptExecution {\n id Int @id @default(autoincrement())\n name String // e.g., \"oauth-token-refresh\", \"db-migration-xyz\"\n type String // e.g., \"ADMIN_SCRIPT\", \"DB_MIGRATION\"\n\n // State machine\n state AdminScriptExecutionState @default(PENDING)\n\n // Flexible storage (mirrors Process model pattern)\n context Json @default(\"{}\") // input, trigger, audit info, script version\n results Json @default(\"{}\") // output, logs, metrics, errors\n\n // Hierarchy support - self-referential relation\n parentExecutionId Int?\n parentExecution AdminScriptExecution? @relation(\"AdminScriptExecutionHierarchy\", fields: [parentExecutionId], references: [id], onDelete: SetNull)\n childExecutions AdminScriptExecution[] @relation(\"AdminScriptExecutionHierarchy\")\n\n // Timestamps\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([name, createdAt(sort: Desc)])\n @@index([state])\n @@index([type])\n}\n\n/// Script scheduling configuration for hybrid scheduling (SQS + EventBridge)\nmodel ScriptSchedule {\n id Int @id @default(autoincrement())\n scriptName String @unique\n enabled Boolean @default(false)\n cronExpression String?\n timezone String @default(\"UTC\")\n lastTriggeredAt DateTime?\n nextTriggerAt DateTime?\n\n // External Scheduler (e.g., AWS EventBridge Scheduler)\n externalScheduleId String?\n externalScheduleName String?\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@index([enabled])\n}\n\n/// Durable usage counters, deliberately isolated: no userId and no foreign key\n/// to Integration, so a user-scoped query can never return a usage row and usage\n/// history survives integration deletion.\nmodel UsageCounter {\n id Int @id @default(autoincrement())\n\n integrationId String\n integrationType String\n metric String\n window String // e.g. \"day:2026-07-05\" or \"hour:2026-07-05T14\"\n value BigInt @default(0) // BigInt: a busy day/hour counter can exceed 32-bit\n\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@unique([integrationId, integrationType, metric, window])\n // Covers totals() (metric + window prefix/range, no integrationType filter).\n @@index([metric, window])\n // Covers series() (metric + integrationType + window range).\n @@index([metric, integrationType, window])\n}\n\n// Integrations published as definitions (ADR-063): one immutable row per published definition version.\nenum DefinitionStatus {\n DRAFT\n PUBLISHED\n DEPRECATED\n RETIRED\n}\n\nmodel IntegrationDefinitionVersion {\n id Int @id @default(autoincrement())\n definitionId String\n version String\n schemaVersion String\n status DefinitionStatus @default(DRAFT)\n checksum String\n document Json\n changeLevel String?\n previousVersion String?\n notes String?\n createdBy String?\n // The workspace an integration a user built belongs to (null: the app's own catalogue, offered to everyone).\n workspaceId String?\n publishedAt DateTime?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n\n @@unique([definitionId, version])\n @@index([definitionId, status])\n @@index([workspaceId, status])\n}\n\n// One row per workflow run. trace holds step ids, statuses, timings and error messages, never request or\n// response bodies.\nmodel WorkflowRun {\n id Int @id @default(autoincrement())\n integrationId Int\n integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)\n definitionId String\n definitionVersion String\n workflowId String\n triggerType String\n eventId String?\n status String\n reason String?\n error String?\n retryable Boolean @default(false)\n trace Json @default(\"[]\")\n /// The runtime's run id (run_...): how routes and resume jobs address a run\n runKey String?\n /// A paused run (status waiting): which step, and what it waits for. Never request or response bodies.\n waitingFor Json?\n resumeAt DateTime?\n startedAt DateTime\n endedAt DateTime?\n createdAt DateTime @default(now())\n\n @@index([integrationId, runKey])\n @@index([integrationId, startedAt])\n @@index([integrationId, workflowId, startedAt])\n @@index([integrationId, status])\n}\n",
|
|
432
|
+
"inlineSchemaHash": "5d11039694b44af001971b7239ab8290b642c385239660aee17e709d4fa0b509",
|
|
433
433
|
"copyEngine": true
|
|
434
434
|
}
|
|
435
435
|
config.dirname = '/'
|
|
@@ -12,8 +12,11 @@ const log = getLogger('frigg.http');
|
|
|
12
12
|
const createApp = (applyMiddleware) => {
|
|
13
13
|
const app = express();
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
// Keep the bytes as received: webhook signatures (HubSpot, Slack, Stripe, Linear…) are computed over the exact
|
|
16
|
+
// raw body, which re-serialising the parsed body does not reproduce. A reference to the buffer, not a copy.
|
|
17
|
+
const keepRaw = (req, res, buf) => { req.rawBody = buf; };
|
|
18
|
+
app.use(bodyParser.json({ limit: '10mb', verify: keepRaw }));
|
|
19
|
+
app.use(bodyParser.urlencoded({ extended: true, verify: keepRaw }));
|
|
17
20
|
app.use(
|
|
18
21
|
cors({
|
|
19
22
|
origin: '*',
|
|
@@ -21,7 +21,7 @@ class IntegrationEventDispatcher {
|
|
|
21
21
|
async dispatchJob({ event, data, context, delivery }) {
|
|
22
22
|
return this._dispatch(event, (instance, handler) => {
|
|
23
23
|
const invoke = () => handler.call(instance, { data, context, delivery });
|
|
24
|
-
// An integration that keeps run history records each queued event as a run (
|
|
24
|
+
// An integration that keeps run history records each queued event as a run (integration runtime).
|
|
25
25
|
return typeof instance.runEvent === 'function'
|
|
26
26
|
? instance.runEvent(event, invoke)
|
|
27
27
|
: invoke();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Integrations published as definitions (v0.1)
|
|
2
2
|
|
|
3
3
|
ADR-063, implemented to the point where a definition can be validated, compiled into Frigg events, executed, rendered
|
|
4
4
|
and versioned. An integration becomes a **document** (what it connects, what it syncs, which workflows and UI it has)
|
|
@@ -17,7 +17,7 @@ installation (Integration.config) ─┘ │
|
|
|
17
17
|
|---|---|
|
|
18
18
|
| `schema/integration-definition.v0.1.schema.json` | The definition format (JSON Schema 2020-12) |
|
|
19
19
|
| `schema/capability-manifest.v0.1.schema.json` | What an API module declares it can do |
|
|
20
|
-
| `schema/installation.v0.1.schema.json` | `Integration.config` for
|
|
20
|
+
| `schema/installation.v0.1.schema.json` | `Integration.config` for an installation |
|
|
21
21
|
| `schema/records.md` | Database records: definition versions, installation, mappings, workflow runs |
|
|
22
22
|
| `capabilities/*.capabilities.json` | Capability manifests. Nine are checked against the real Api classes (`capabilities/AUDIT.md`); the other twelve are still mock-shaped |
|
|
23
23
|
| `scripts/check-manifests.js` | Checks every manifest `method` exists on the real module's Api class, with the arguments it takes |
|
|
@@ -30,7 +30,7 @@ installation (Integration.config) ─┘ │
|
|
|
30
30
|
| `sync-engine.js` | Syncs: link → identity → search → create/update, master rules, backfill pages, polls |
|
|
31
31
|
| `runtime.js` | Ports (Api calls, link store), `runWorkflow`, `runQuery`, `renderSurface`, `runLifecycle`, `resolveOptions`, `installContext` |
|
|
32
32
|
| `versioning.js` | `diff`, `checkBump`, `planUpgrade` |
|
|
33
|
-
| `
|
|
33
|
+
| `integration-runtime.js` | `defineIntegrationClass`: the IntegrationBase subclass that runs it all |
|
|
34
34
|
| `use-cases/definition-use-cases.js` | Publish, deprecate, catalogue, history, upgrade plan; `createDefinitionCatalog()` (the store the runtime reads) |
|
|
35
35
|
| `repositories/` | `IntegrationDefinitionVersion` and `WorkflowRun` rows (MongoDB, PostgreSQL, DocumentDB) |
|
|
36
36
|
| `router.js` | The publish, catalogue, upgrade and run-history routes |
|
|
@@ -107,9 +107,9 @@ Definitions live in the `IntegrationDefinitionVersion` table (Prisma models in b
|
|
|
107
107
|
`20261018000000_add_data_defined_integrations`), and runs in `WorkflowRun`. Point the class at the store:
|
|
108
108
|
|
|
109
109
|
```js
|
|
110
|
-
const { defineSharedIntegrationClass, createDefinitionCatalog } = require('@friggframework/core/integrations/
|
|
110
|
+
const { defineSharedIntegrationClass, createDefinitionCatalog } = require('@friggframework/core/integrations/definitions');
|
|
111
111
|
// A database store is read asynchronously, so it goes with the shared class (one class, every definition).
|
|
112
|
-
const
|
|
112
|
+
const IntegrationRuntime = defineSharedIntegrationClass({ definitions: createDefinitionCatalog(), manifests, modules });
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
| Route | Auth | |
|
|
@@ -118,8 +118,8 @@ const DataDefined = defineSharedIntegrationClass({ definitions: createDefinition
|
|
|
118
118
|
| `GET /admin/integrations/:id/versions` | admin key | Version history |
|
|
119
119
|
| `POST /admin/integrations/:id/versions/:v/deprecate` | admin key | Stop new installs of a version |
|
|
120
120
|
| `GET /api/integrations` | user | What can be installed: code and published integrations in one list of options |
|
|
121
|
-
| `GET /api/
|
|
122
|
-
| `POST /api/integrations` with `config: { type: '<id>' }` | user | Install; pins the latest published version and its checksum
|
|
121
|
+
| `GET /api/integration-definitions` | user | The published ones, with their counts |
|
|
122
|
+
| `POST /api/integrations` with `config: { type: '<id>' }` | user | Install; pins the latest published version and its checksum |
|
|
123
123
|
| `GET` / `POST /api/integrations/:id/upgrade` `{ to? }` | user | Plan / apply an upgrade (409 with the plan while something is needed) |
|
|
124
124
|
| `GET /api/integrations/:id/runs` | user | Run history, newest first |
|
|
125
125
|
| `GET /api/integrations/:id/syncs` | user | Each sync's backfill progress and poll marks |
|
|
@@ -153,7 +153,7 @@ code production runs (`renderers/`):
|
|
|
153
153
|
|
|
154
154
|
| Function | Does |
|
|
155
155
|
|---|---|
|
|
156
|
-
| `previewSurface({ def, installation, surfaceId, record, ports, host? })` | `{ surface, view, html, slack?, hubspot? }`. `slack` is Block Kit (`{ blocks, text, truncated }`), `hubspot` a data description of `@hubspot/ui-extensions` components, `html` the same card framed as its host looks. `host` defaults to the surface's own |
|
|
156
|
+
| `previewSurface({ def, installation, surfaceId, record, ports, host? })` | `{ surface, view, html, slack?, hubspot? }`. `slack` is Block Kit (`{ blocks, text, truncated }`), `hubspot` a data description of `@hubspot/ui-extensions` components (names and props checked against 0.17.1; `props` are real component props, a userAction button carries our own node-level `action` for the card to post, an `open_url` button is a real `href`), `html` the same card framed as its host looks. `host` defaults to the surface's own |
|
|
157
157
|
| `previewWorkflow({ def, installation, workflowId, event?, record?, manifests, fixtures? })` | Dry run: `{ status, sends, calls, trace, waiting? }`. Each call is `{ stepId, module, capability, kind, args, output, rendered }`; `rendered` is `{ html, slack? }` for writes (a Slack post renders as the message, anything else as a "would call" card) |
|
|
158
158
|
| `recordingPorts({ def, manifests, fixtures })` | Ports that record and answer instead of calling an API; give them to `previewSurface` for sample data |
|
|
159
159
|
| `viewToSlack`, `viewToHubSpot`, `viewToHtml`, `slackMessageToHtml` | The renderers on their own. `decodeAction(value)` reads a Slack button click back to `{ integrationId?, workflow, surface }` |
|
|
@@ -231,14 +231,14 @@ they were routed under and finish on it.
|
|
|
231
231
|
## Running the tests
|
|
232
232
|
|
|
233
233
|
```bash
|
|
234
|
-
npx jest --config '{}' --rootDir packages/core/integrations/
|
|
234
|
+
npx jest --config '{}' --rootDir packages/core/integrations/definitions tests
|
|
235
235
|
```
|
|
236
236
|
|
|
237
237
|
`tests/persistence.test.js` runs the repositories and the publish rules against real databases. Each leg runs only
|
|
238
238
|
when its URL is set. Point them at a migrated PostgreSQL database and a MongoDB replica set with the schema pushed:
|
|
239
239
|
|
|
240
240
|
```bash
|
|
241
|
-
|
|
241
|
+
INTEGRATION_DEFINITIONS_POSTGRES_URL=postgresql://… INTEGRATION_DEFINITIONS_MONGO_URL=mongodb://… npx jest … tests
|
|
242
242
|
```
|
|
243
243
|
|
|
244
244
|
## Validating
|
|
@@ -251,8 +251,8 @@ Validation is two layers, and a document is valid only when both pass (`schema-c
|
|
|
251
251
|
|
|
252
252
|
```bash
|
|
253
253
|
npm run validate:definitions --workspace @friggframework/core # bundled manifests + examples
|
|
254
|
-
node packages/core/integrations/
|
|
255
|
-
node packages/core/integrations/
|
|
254
|
+
node packages/core/integrations/definitions/scripts/validate.js my.definition.json --strict
|
|
255
|
+
node packages/core/integrations/definitions/scripts/validate.js --manifests ./capabilities --json defs/
|
|
256
256
|
```
|
|
257
257
|
|
|
258
258
|
Exit codes: `0` valid, `1` invalid (or a warning with `--strict`), `2` could not run (unreadable JSON, missing file,
|
|
@@ -4,16 +4,45 @@ Audit of every `*.capabilities.json` in this directory against the Api class it
|
|
|
4
4
|
began as bundled mocks; for each module whose source could be found, every `method` was checked to exist on the real
|
|
5
5
|
Api class and every call shape was read against the method's real signature.
|
|
6
6
|
|
|
7
|
-
Re-run it (no network, nothing instantiated)
|
|
7
|
+
Re-run it (no network, nothing instantiated). **One run per module, with that module's checkout first**: the
|
|
8
|
+
api-module-library branches that carry the new methods are separate worktrees, and every worktree also holds an older copy
|
|
9
|
+
of the other modules, so a single run with several roots lets the first root's stale copy of (say) `stripe` win. The
|
|
10
|
+
roots below are the specific module directories, so nothing else can match:
|
|
8
11
|
|
|
9
12
|
```bash
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
M=packages/core/integrations/definitions/scripts/check-manifests.js
|
|
14
|
+
node $M --stub-missing ~/aml-hubspot/packages/v1-ready/hubspot # hubspot (PR #106)
|
|
15
|
+
node $M --stub-missing ~/aml-salesforce/packages/v1-ready/salesforce # salesforce (PR #107)
|
|
16
|
+
node $M --stub-missing ~/aml-stripe/packages/v1-ready/stripe # stripe (PR #108)
|
|
17
|
+
node $M --stub-missing ~/aml-linear/packages/v1-ready/linear # linear (PR #109)
|
|
18
|
+
node $M --stub-missing ~/aml-small/packages/v1-ready # asana, fathom (PR #110)
|
|
19
|
+
node $M --stub-missing ~/aml-small/packages/needs-updating # slack (PR #110)
|
|
20
|
+
node $M --stub-missing <built pipedrive> # pipedrive (PR #110): src/api.ts has no dist, so
|
|
21
|
+
# compile it first (tsc --outDir dist --noCheck)
|
|
22
|
+
node $M --stub-missing ~/phone-app/backend/src/api-modules # phone (the app's own module)
|
|
13
23
|
```
|
|
14
24
|
|
|
15
|
-
|
|
16
|
-
|
|
25
|
+
Each run reports every manifest, so read only the line for the module you are checking (the others resolve to nothing or
|
|
26
|
+
to an older copy). Run from the repo root: loading an Api pulls in `@friggframework/core`, which reads `package.json`
|
|
27
|
+
from the working directory. (`--stub-missing` stands in for dependencies that are not installed here, such as jsforce,
|
|
28
|
+
stripe and @linear/sdk, so the Api's methods can be read.)
|
|
29
|
+
|
|
30
|
+
## Methods that landed after this audit
|
|
31
|
+
|
|
32
|
+
The capabilities this file first marked unimplemented for hubspot, salesforce, stripe, linear, asana, pipedrive, fathom
|
|
33
|
+
and slack now have methods, on unmerged api-module-library branches: **#106 (hubspot), #107 (salesforce), #108 (stripe),
|
|
34
|
+
#109 (linear), #110 (asana, pipedrive, fathom, slack)**, stacked on #105. The manifests describe those methods, so **a
|
|
35
|
+
definition that uses them needs the module releases that carry those PRs**; against an older release the call fails at
|
|
36
|
+
runtime with "not a function". Exceptions that stay unimplemented: Salesforce's signed webhook (it has none: CDC arrives
|
|
37
|
+
over the Pub/Sub stream and Outbound Messages are unsigned), and Phone's `contact.search`, which is not part of that work.
|
|
38
|
+
Two shape notes:
|
|
39
|
+
|
|
40
|
+
- HubSpot `deal.search` was reshaped to the real `searchDeals({ filterGroups, sorts, props, limit, after, allProps })`;
|
|
41
|
+
the old open/closeDateBefore/closeDateAfter/minAmount inputs never existed in the Api and are now `filterGroups`
|
|
42
|
+
filters (`hs_is_closed`, `closedate`, `amount`). The Api returns HubSpot's `{ results, paging }` page, not a bare array,
|
|
43
|
+
so a step that indexes the result as a list (`$.steps.deals[0]`) reads the page object: the `hubspot-slack` example still
|
|
44
|
+
does and is a mock-era shape to revisit.
|
|
45
|
+
- HubSpot `deal.update` is `updateDeal({ dealId, properties })`: one object, so the input is now `dealId` (it was `id`).
|
|
17
46
|
|
|
18
47
|
## How to read this
|
|
19
48
|
|
|
@@ -29,31 +58,32 @@ the Api's methods can be read. Roots are searched in order and the first module
|
|
|
29
58
|
`runtime.js` `argumentsFor` spreads them. An input that is declared but never passed is refused by the manifest check,
|
|
30
59
|
because it would be accepted and silently dropped.
|
|
31
60
|
- **Webhook verification.** Every manifest names `verifyWebhookSignature`. No real module has it (only clio, which has no
|
|
32
|
-
manifest). Each real module's `webhook` block
|
|
61
|
+
manifest). Each real module's `webhook` block was marked `"status": "unimplemented"`; since api-module-library
|
|
62
|
+
659b90d eight of them verify signatures (Salesforce has no signed webhook and stays unimplemented), and a workflow that triggers on
|
|
33
63
|
its events validates with a warning: every delivery would fail signature verification.
|
|
34
64
|
|
|
35
65
|
## Summary
|
|
36
66
|
|
|
37
67
|
| Module | Source checked | Capabilities | Renamed method | Call shape fixed | Inputs changed | Unimplemented upstream |
|
|
38
68
|
|---|---|---|---|---|---|---|
|
|
39
|
-
| asana | ~/api-module-library/packages/v1-ready/asana | 6 | 3 | 1 | 2 |
|
|
69
|
+
| asana | ~/api-module-library/packages/v1-ready/asana | 6 | 3 | 1 | 2 | 0 |
|
|
40
70
|
| calendly | none found | 6 | - | - | - | - |
|
|
41
71
|
| docusign | none found | 5 | - | - | - | - |
|
|
42
|
-
| fathom | ~/api-module-library/packages/v1-ready/fathom | 5 | 2 | 2 | 0 |
|
|
72
|
+
| fathom | ~/api-module-library/packages/v1-ready/fathom | 5 | 2 | 2 | 0 | 0 |
|
|
43
73
|
| github | none found | 6 | - | - | - | - |
|
|
44
|
-
| hubspot | ~/api-module-library/packages/v1-ready/hubspot | 23 | 0 | 5 | 1 |
|
|
74
|
+
| hubspot | ~/api-module-library/packages/v1-ready/hubspot | 23 | 0 | 5 | 1 | 0 |
|
|
45
75
|
| jira | none found | 12 | - | - | - | - |
|
|
46
76
|
| klaviyo | none found | 14 | - | - | - | - |
|
|
47
|
-
| linear | ~/api-module-library/packages/v1-ready/linear | 9 | 0 | 0 | 0 |
|
|
77
|
+
| linear | ~/api-module-library/packages/v1-ready/linear | 9 | 0 | 0 | 0 | 0 |
|
|
48
78
|
| netsuite | none found | 15 | - | - | - | - |
|
|
49
79
|
| notion | none found | 6 | - | - | - | - |
|
|
50
|
-
| pipedrive | ~/
|
|
80
|
+
| pipedrive | ~/aml-small/packages/v1-ready/pipedrive (compiled src/api.ts) | 11 | 4 | 3 | 1 | 0 |
|
|
51
81
|
| quickbooks | none found | 14 | - | - | - | - |
|
|
52
82
|
| phone | ~/phone-app/backend/src/api-modules/phone | 13 | 1 | 4 | 0 | 1 |
|
|
53
|
-
| salesforce | ~/api-module-library/packages/v1-ready/salesforce | 12 | 5 | 5 | 0 |
|
|
83
|
+
| salesforce | ~/api-module-library/packages/v1-ready/salesforce | 12 | 5 | 5 | 0 | 0 (webhook signing aside) |
|
|
54
84
|
| shopify | none found | 15 | - | - | - | - |
|
|
55
|
-
| slack | ~/api-module-library/packages/needs-updating/slack | 7 | 2 | 1 | 0 |
|
|
56
|
-
| stripe | ~/api-module-library/packages/v1-ready/stripe | 9 | 1 | 0 | 0 |
|
|
85
|
+
| slack | ~/api-module-library/packages/needs-updating/slack | 7 | 2 | 1 | 0 | 0 |
|
|
86
|
+
| stripe | ~/api-module-library/packages/v1-ready/stripe | 9 | 1 | 0 | 0 | 0 |
|
|
57
87
|
| acmeerp | none found | 13 | - | - | - | - |
|
|
58
88
|
| webflow | none found | 5 | - | - | - | - |
|
|
59
89
|
| zendesk | none found | 8 | - | - | - | - |
|
|
@@ -63,8 +93,7 @@ nothing in them is known to exist.
|
|
|
63
93
|
|
|
64
94
|
Where a module has two candidates the first root given wins. Phone is checked against the deployed
|
|
65
95
|
`phone-app/backend/src/api-modules/phone` (the app's own module: `createUnifiedWebhook`, `updateContact`). The library's `v1-ready/phone` 1.0.0 lacks `updateContact` and has `createCallWebhook` and friends
|
|
66
|
-
instead of one webhook method. Pipedrive is checked against the
|
|
67
|
-
2.1.0-next.7 (the library copy is TypeScript source with no `dist`).
|
|
96
|
+
instead of one webhook method. Pipedrive is checked against the compiled TypeScript source of the api-module-library branch (the library copy has no `dist`).
|
|
68
97
|
|
|
69
98
|
Manifest versions in the files (for example HubSpot 1.4.0, Asana 1.5.1) are ahead of the module sources audited (HubSpot
|
|
70
99
|
1.1.7, Asana 1.1.5): the manifests describe modules that were never released as written.
|
|
@@ -76,12 +105,12 @@ Checked against `~/api-module-library/packages/v1-ready/asana` (@friggframework/
|
|
|
76
105
|
| Capability | Method | Status | Real signature | Note |
|
|
77
106
|
|---|---|---|---|---|
|
|
78
107
|
| `task.get` | `getTaskById` | ok | `getTaskById(id)` | Api.getTaskById(id) takes only the id; field selection (opt_fields) is not supported. (method was `getTask`; called with one object; now positional; inputs were taskGid, opt_fields) |
|
|
79
|
-
| `task.search` | `searchTasksInWorkspace` |
|
|
108
|
+
| `task.search` | `searchTasksInWorkspace` | ok (unreleased) | `searchTasksInWorkspace(workspaceId, params = {})` | Implemented in api-module-library #110; needs the release that includes it. |
|
|
80
109
|
| `project.list` | `listProjects` | ok | `listProjects(params)` | (method was `getProjects`; inputs were workspaceGid, archived) |
|
|
81
110
|
| `workspace.list` | `listWorkspaces` | ok | `listWorkspaces()` | (method was `getWorkspaces`) |
|
|
82
|
-
| `webhook.create` | `createWebhook` |
|
|
83
|
-
| `webhook.delete` | `deleteWebhook` |
|
|
84
|
-
| `webhook.verify` | `verifyWebhookSignature` |
|
|
111
|
+
| `webhook.create` | `createWebhook` | ok (unreleased) | `createWebhook(resource, target, filters)` | Implemented in api-module-library #110; needs the release that includes it. |
|
|
112
|
+
| `webhook.delete` | `deleteWebhook` | ok (unreleased) | `deleteWebhook(webhookGid)` | Implemented in api-module-library #110; needs the release that includes it. |
|
|
113
|
+
| `webhook.verify` | `verifyWebhookSignature` | ok (unreleased) | `verifyWebhookSignature({ headers, body, rawBody, method?, url?, now? })` | Implemented in api-module-library 659b90d per the vendor's signing docs; needs the release that includes it. |
|
|
85
114
|
|
|
86
115
|
## Calendly (`calendly`)
|
|
87
116
|
|
|
@@ -120,8 +149,8 @@ Checked against `~/api-module-library/packages/v1-ready/fathom` (@friggframework
|
|
|
120
149
|
| `meeting.summary` | `getSummary` | ok | `getSummary(recordingId, params = {})` | (method was `getRecordingSummary`; called with one object; now positional) |
|
|
121
150
|
| `meeting.transcript` | `getTranscript` | ok | `getTranscript(recordingId, params = {})` | (method was `getRecordingTranscript`; called with one object; now positional) |
|
|
122
151
|
| `webhook.create` | `createWebhook` | ok | `createWebhook(data)` | |
|
|
123
|
-
| `webhook.delete` | `deleteWebhook` |
|
|
124
|
-
| `webhook.verify` | `verifyWebhookSignature` |
|
|
152
|
+
| `webhook.delete` | `deleteWebhook` | ok (unreleased) | `deleteWebhook(id)` | Implemented in api-module-library #110; needs the release that includes it. |
|
|
153
|
+
| `webhook.verify` | `verifyWebhookSignature` | ok (unreleased) | `verifyWebhookSignature({ headers, body, rawBody, method?, url?, now? })` | Implemented in api-module-library 659b90d per the vendor's signing docs; needs the release that includes it. |
|
|
125
154
|
|
|
126
155
|
## GitHub (`github`)
|
|
127
156
|
|
|
@@ -144,29 +173,29 @@ Checked against `~/api-module-library/packages/v1-ready/hubspot` (@friggframewor
|
|
|
144
173
|
| Capability | Method | Status | Real signature | Note |
|
|
145
174
|
|---|---|---|---|---|
|
|
146
175
|
| `contact.get` | `getContactById` | ok | `getContactById(contactId)` | Api.getContactById(id) always requests the portal's full property list; a properties argument is not supported. (called with one object; now positional; inputs were id, properties) |
|
|
147
|
-
| `contact.search` | `searchContacts` |
|
|
176
|
+
| `contact.search` | `searchContacts` | ok (unreleased) | `searchContacts(params = {})` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
148
177
|
| `contact.list` | `listContacts` | ok | `listContacts(params)` | Api.listContacts({ after, limit, properties }) has no modified-since filter, so updatedSince is ignored and a poll re-lists every contact. |
|
|
149
178
|
| `contact.create` | `createContact` | ok | `createContact(body)` | (called with one object; now positional) |
|
|
150
179
|
| `contact.update` | `updateContact` | ok | `updateContact(contactId, properties)` | (called with one object; now positional) |
|
|
151
180
|
| `deal.get` | `getDealById` | ok | `getDealById(dealId)` | (called with one object; now positional) |
|
|
152
|
-
| `deal.listForContact` | `listDealsForContact` |
|
|
153
|
-
| `deal.contacts` | `listContactsForDeal` |
|
|
154
|
-
| `task.create` | `createTask` |
|
|
155
|
-
| `call.create` | `createCallEngagement` |
|
|
156
|
-
| `note.create` | `createNote` |
|
|
157
|
-
| `owner.list` | `listOwners` |
|
|
158
|
-
| `pipeline.stages` | `listDealStages` |
|
|
159
|
-
| `contact.upsertByEmail` | `upsertContactByEmail` |
|
|
160
|
-
| `deal.update` | `updateDeal` |
|
|
161
|
-
| `deal.search` | `searchDeals` |
|
|
162
|
-
| `task.get` | `getTaskById` |
|
|
163
|
-
| `task.update` | `updateTask` |
|
|
164
|
-
| `task.search` | `searchTasks` |
|
|
181
|
+
| `deal.listForContact` | `listDealsForContact` | ok (unreleased) | `listDealsForContact(contactId, open)` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
182
|
+
| `deal.contacts` | `listContactsForDeal` | ok (unreleased) | `listContactsForDeal(dealId)` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
183
|
+
| `task.create` | `createTask` | ok (unreleased) | `createTask(properties, contactId)` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
184
|
+
| `call.create` | `createCallEngagement` | ok (unreleased) | `createCallEngagement(properties, contactId)` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
185
|
+
| `note.create` | `createNote` | ok (unreleased) | `createNote(properties, contactId, dealId)` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
186
|
+
| `owner.list` | `listOwners` | ok (unreleased) | `listOwners()` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
187
|
+
| `pipeline.stages` | `listDealStages` | ok (unreleased) | `listDealStages(pipelineId)` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
188
|
+
| `contact.upsertByEmail` | `upsertContactByEmail` | ok (unreleased) | `upsertContactByEmail(email, properties)` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
189
|
+
| `deal.update` | `updateDeal` | ok (unreleased) | `updateDeal(params)` | Api.updateDeal({ dealId, properties }) takes one object, so the input is dealId (it was id). Implemented in api-module-library #106; needs the release that includes it. |
|
|
190
|
+
| `deal.search` | `searchDeals` | ok (unreleased) | `searchDeals(params)` | Api.searchDeals takes HubSpot filterGroups ([{ filters: [{ propertyName, operator, value }] }]), sorts, props, limit, after and allProps (default true: every deal property when props is empty). The capability was reshaped from open/closeDateBefore/closeDateAfter/minAmount, which the Api never had; a definition expresses those as filterGroups. Implemented in api-module-library #106; needs the release that includes it. |
|
|
191
|
+
| `task.get` | `getTaskById` | ok (unreleased) | `getTaskById(id, properties)` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
192
|
+
| `task.update` | `updateTask` | ok (unreleased) | `updateTask(id, properties)` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
193
|
+
| `task.search` | `searchTasks` | ok (unreleased) | `searchTasks(params = {})` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
165
194
|
| `owner.get` | `getOwnerById` | ok | `getOwnerById(ownerId)` | (called with one object; now positional) |
|
|
166
|
-
| `owner.findByEmail` | `getOwnerByEmail` |
|
|
167
|
-
| `subscription.definitions` | `listSubscriptionDefinitions` |
|
|
168
|
-
| `subscription.unsubscribe` | `unsubscribeEmail` |
|
|
169
|
-
| `webhook.verify` | `verifyWebhookSignature` |
|
|
195
|
+
| `owner.findByEmail` | `getOwnerByEmail` | ok (unreleased) | `getOwnerByEmail(email)` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
196
|
+
| `subscription.definitions` | `listSubscriptionDefinitions` | ok (unreleased) | `listSubscriptionDefinitions()` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
197
|
+
| `subscription.unsubscribe` | `unsubscribeEmail` | ok (unreleased) | `unsubscribeEmail(emailAddress, subscriptionId, legalBasis, legalBasisExplanation)` | Implemented in api-module-library #106; needs the release that includes it. |
|
|
198
|
+
| `webhook.verify` | `verifyWebhookSignature` | ok (unreleased) | `verifyWebhookSignature({ headers, body, rawBody, method?, url?, now? })` | Implemented in api-module-library 659b90d per the vendor's signing docs; needs the release that includes it. |
|
|
170
199
|
|
|
171
200
|
## Jira Cloud (`jira`)
|
|
172
201
|
|
|
@@ -216,16 +245,16 @@ Checked against `~/api-module-library/packages/v1-ready/linear` (@friggframework
|
|
|
216
245
|
|
|
217
246
|
| Capability | Method | Status | Real signature | Note |
|
|
218
247
|
|---|---|---|---|---|
|
|
219
|
-
| `issue.get` | `issue` |
|
|
220
|
-
| `issue.byIdentifier` | `issueByIdentifier` |
|
|
221
|
-
| `issue.search` | `searchIssues` |
|
|
222
|
-
| `issue.create` | `issueCreate` |
|
|
223
|
-
| `issue.update` | `issueUpdate` |
|
|
224
|
-
| `comment.create` | `commentCreate` |
|
|
225
|
-
| `attachment.link` | `attachmentLinkURL` |
|
|
226
|
-
| `team.list` | `teams` |
|
|
227
|
-
| `workflowState.list` | `workflowStates` |
|
|
228
|
-
| `webhook.verify` | `verifyWebhookSignature` |
|
|
248
|
+
| `issue.get` | `issue` | ok (unreleased) | `issue(id)` | Implemented in api-module-library #109; needs the release that includes it. |
|
|
249
|
+
| `issue.byIdentifier` | `issueByIdentifier` | ok (unreleased) | `issueByIdentifier(identifier)` | Implemented in api-module-library #109; needs the release that includes it. |
|
|
250
|
+
| `issue.search` | `searchIssues` | ok (unreleased) | `searchIssues(teamId, stateType, updatedBefore, first)` | Implemented in api-module-library #109; needs the release that includes it. |
|
|
251
|
+
| `issue.create` | `issueCreate` | ok (unreleased) | `issueCreate(teamId, title, description, priority, stateName, labelIds)` | Implemented in api-module-library #109; needs the release that includes it. |
|
|
252
|
+
| `issue.update` | `issueUpdate` | ok (unreleased) | `issueUpdate(id, input)` | Implemented in api-module-library #109; needs the release that includes it. |
|
|
253
|
+
| `comment.create` | `commentCreate` | ok (unreleased) | `commentCreate(issueId, body)` | Implemented in api-module-library #109; needs the release that includes it. |
|
|
254
|
+
| `attachment.link` | `attachmentLinkURL` | ok (unreleased) | `attachmentLinkURL(issueId, url, title)` | Implemented in api-module-library #109; needs the release that includes it. |
|
|
255
|
+
| `team.list` | `teams` | ok (unreleased) | `teams()` | Implemented in api-module-library #109; needs the release that includes it. |
|
|
256
|
+
| `workflowState.list` | `workflowStates` | ok (unreleased) | `workflowStates(teamId, name)` | Implemented in api-module-library #109; needs the release that includes it. |
|
|
257
|
+
| `webhook.verify` | `verifyWebhookSignature` | ok (unreleased) | `verifyWebhookSignature({ headers, body, rawBody, method?, url?, now? })` | Implemented in api-module-library 659b90d per the vendor's signing docs; needs the release that includes it. |
|
|
229
258
|
|
|
230
259
|
## NetSuite (`netsuite`)
|
|
231
260
|
|
|
@@ -265,22 +294,22 @@ Checked against `~/api-module-library/packages/v1-ready/linear` (@friggframework
|
|
|
265
294
|
|
|
266
295
|
## Pipedrive (`pipedrive`)
|
|
267
296
|
|
|
268
|
-
Checked against `~/
|
|
297
|
+
Checked against the api-module-library branch source `~/aml-small/packages/v1-ready/pipedrive` (src/api.ts, compiled; PR #110), manifest 2.1.0. The built 2.1.0 in `~/phone-app/backend/node_modules/@friggframework` predates `addPerson`/`updatePerson`.
|
|
269
298
|
|
|
270
299
|
| Capability | Method | Status | Real signature | Note |
|
|
271
300
|
|---|---|---|---|---|
|
|
272
301
|
| `person.get` | `getPerson` | ok | `getPerson(personId, params)` | (called with one object; now positional) |
|
|
273
302
|
| `person.search` | `searchPersons` | ok | `searchPersons(params)` | |
|
|
274
303
|
| `person.list` | `listPersons` | ok | `listPersons(params)` | |
|
|
275
|
-
| `person.create` | `addPerson` |
|
|
276
|
-
| `person.update` | `updatePerson` |
|
|
304
|
+
| `person.create` | `addPerson` | ok (unreleased) | `addPerson(person)` | Implemented in api-module-library #110; needs the release that includes it. |
|
|
305
|
+
| `person.update` | `updatePerson` | ok (unreleased) | `updatePerson(personId, person)` | Implemented in api-module-library #110; needs the release that includes it. |
|
|
277
306
|
| `activity.create` | `createActivity` | ok | `createActivity(params)` | (method was `addActivity`; called with one object; now positional) |
|
|
278
307
|
| `activity.list` | `listActivities` | ok | `listActivities(params)` | |
|
|
279
308
|
| `deal.listForPerson` | `listDeals` | ok | `listDeals(params)` | (method was `listPersonDeals`; inputs were personId, status) |
|
|
280
309
|
| `user.list` | `listUsers` | ok | `listUsers()` | (method was `getUsers`) |
|
|
281
310
|
| `webhook.create` | `createWebhook` | ok | `createWebhook(params)` | (method was `addWebhook`) |
|
|
282
311
|
| `webhook.delete` | `deleteWebhook` | ok | `deleteWebhook(webhookId)` | (called with one object; now positional) |
|
|
283
|
-
| `webhook.verify` | `verifyWebhookSignature` |
|
|
312
|
+
| `webhook.verify` | `verifyWebhookSignature` | ok (unreleased) | `verifyWebhookSignature({ headers, body, rawBody, method?, url?, now? })` | Implemented in api-module-library 659b90d per the vendor's signing docs; needs the release that includes it. |
|
|
284
313
|
|
|
285
314
|
## QuickBooks Online (`quickbooks`)
|
|
286
315
|
|
|
@@ -323,7 +352,7 @@ Checked against `~/phone-app/backend/src/api-modules/phone` (@acme/api-module-ph
|
|
|
323
352
|
| `user.list` | `listUsers` | ok | `listUsers(params = {})` | |
|
|
324
353
|
| `webhook.create` | `createUnifiedWebhook` | ok | `createUnifiedWebhook(data)` | (method was `createWebhook`) |
|
|
325
354
|
| `webhook.delete` | `deleteWebhook` | ok | `deleteWebhook(id)` | (called with one object; now positional) |
|
|
326
|
-
| `webhook.verify` | `verifyWebhookSignature` |
|
|
355
|
+
| `webhook.verify` | `verifyWebhookSignature` | ok (unreleased) | `verifyWebhookSignature({ headers, body, rawBody, method?, url?, now? })` | Implemented in api-module-library 659b90d per the vendor's signing docs; needs the release that includes it. |
|
|
327
356
|
|
|
328
357
|
## Salesforce (`salesforce`)
|
|
329
358
|
|
|
@@ -333,17 +362,17 @@ Checked against `~/api-module-library/packages/v1-ready/salesforce` (@friggframe
|
|
|
333
362
|
|---|---|---|---|---|
|
|
334
363
|
| `lead.get` | `get` | ok | `get(object, id)` | (method was `getLead`; called with one object; now positional) |
|
|
335
364
|
| `lead.create` | `create` | ok | `create(object, data)` | (method was `createLead`; called with one object; now positional) |
|
|
336
|
-
| `lead.update` | `updateLead` |
|
|
337
|
-
| `person.searchByEmail` | `searchPeopleByEmail` |
|
|
365
|
+
| `lead.update` | `updateLead` | ok (unreleased) | `updateLead(id, fields)` | Implemented in api-module-library #107; needs the release that includes it. |
|
|
366
|
+
| `person.searchByEmail` | `searchPeopleByEmail` | ok (unreleased) | `searchPeopleByEmail(email)` | Implemented in api-module-library #107; needs the release that includes it. |
|
|
338
367
|
| `event.create` | `create` | ok | `create(object, data)` | (method was `createEvent`; called with one object; now positional) |
|
|
339
|
-
| `event.update` | `updateEvent` |
|
|
368
|
+
| `event.update` | `updateEvent` | ok (unreleased) | `updateEvent(id, fields)` | Implemented in api-module-library #107; needs the release that includes it. |
|
|
340
369
|
| `opportunity.get` | `get` | ok | `get(object, id)` | (method was `getOpportunity`; called with one object; now positional) |
|
|
341
|
-
| `opportunity.update` | `updateOpportunity` |
|
|
370
|
+
| `opportunity.update` | `updateOpportunity` | ok (unreleased) | `updateOpportunity(id, fields)` | Implemented in api-module-library #107; needs the release that includes it. |
|
|
342
371
|
| `task.create` | `create` | ok | `create(object, data)` | (method was `createTask`; called with one object; now positional) |
|
|
343
|
-
| `file.attach` | `createContentVersion` |
|
|
344
|
-
| `note.create` | `createContentNote` |
|
|
345
|
-
| `user.list` | `listUsers` |
|
|
346
|
-
| `webhook.verify` | `verifyWebhookSignature` | unimplemented | |
|
|
372
|
+
| `file.attach` | `createContentVersion` | ok (unreleased) | `createContentVersion(title, pathOnClient, versionData, firstPublishLocationId)` | Implemented in api-module-library #107; needs the release that includes it. |
|
|
373
|
+
| `note.create` | `createContentNote` | ok (unreleased) | `createContentNote(title, content, linkedEntityId)` | Implemented in api-module-library #107; needs the release that includes it. |
|
|
374
|
+
| `user.list` | `listUsers` | ok (unreleased) | `listUsers(activeOnly = false)` | Implemented in api-module-library #107; needs the release that includes it. |
|
|
375
|
+
| `webhook.verify` | `verifyWebhookSignature` | unimplemented | | Not a webhook: CDC arrives over the Pub/Sub or CometD stream; Outbound Messages are unsigned (OrganizationId + IP allowlist). Deliveries are rejected. |
|
|
347
376
|
|
|
348
377
|
## Shopify (`shopify`)
|
|
349
378
|
|
|
@@ -379,9 +408,9 @@ Checked against `~/api-module-library/packages/needs-updating/slack` (@friggfram
|
|
|
379
408
|
| `message.postEphemeral` | `postEphemeral` | ok | `postEphemeral(body)` | |
|
|
380
409
|
| `message.permalink` | `getMessagePermalink` | ok | `getMessagePermalink(query)` | (method was `getPermalink`) |
|
|
381
410
|
| `channel.list` | `listChannels` | ok | `listChannels(query)` | (method was `listConversations`) |
|
|
382
|
-
| `user.list` | `listUsers` |
|
|
411
|
+
| `user.list` | `listUsers` | ok (unreleased) | `listUsers(query = {})` | Implemented in api-module-library #110; needs the release that includes it. |
|
|
383
412
|
| `user.lookupByEmail` | `lookupUserByEmail` | ok | `lookupUserByEmail(email)` | (called with one object; now positional) |
|
|
384
|
-
| `webhook.verify` | `verifyWebhookSignature` |
|
|
413
|
+
| `webhook.verify` | `verifyWebhookSignature` | ok (unreleased) | `verifyWebhookSignature({ headers, body, rawBody, method?, url?, now? })` | Implemented in api-module-library 659b90d per the vendor's signing docs; needs the release that includes it. |
|
|
385
414
|
|
|
386
415
|
## Stripe (`stripe`)
|
|
387
416
|
|
|
@@ -389,16 +418,16 @@ Checked against `~/api-module-library/packages/v1-ready/stripe` (@friggframework
|
|
|
389
418
|
|
|
390
419
|
| Capability | Method | Status | Real signature | Note |
|
|
391
420
|
|---|---|---|---|---|
|
|
392
|
-
| `customer.get` | `retrieveCustomer` |
|
|
393
|
-
| `customer.list` | `listCustomers` |
|
|
394
|
-
| `customer.search` | `searchCustomers` |
|
|
395
|
-
| `customer.create` | `createCustomer` |
|
|
396
|
-
| `customer.update` | `updateCustomer` |
|
|
397
|
-
| `paymentIntent.get` | `retrievePaymentIntent` |
|
|
398
|
-
| `refund.get` | `retrieveRefund` |
|
|
399
|
-
| `payout.list` | `listPayouts` |
|
|
421
|
+
| `customer.get` | `retrieveCustomer` | ok (unreleased) | `retrieveCustomer(id, params = {}, options = {})` | Implemented in api-module-library #108; needs the release that includes it. |
|
|
422
|
+
| `customer.list` | `listCustomers` | ok (unreleased) | `listCustomers(params = {}, options = {})` | Implemented in api-module-library #108; needs the release that includes it. |
|
|
423
|
+
| `customer.search` | `searchCustomers` | ok (unreleased) | `searchCustomers(query, params = {}, options = {})` | Implemented in api-module-library #108; needs the release that includes it. |
|
|
424
|
+
| `customer.create` | `createCustomer` | ok (unreleased) | `createCustomer(params = {}, options = {})` | Implemented in api-module-library #108; needs the release that includes it. |
|
|
425
|
+
| `customer.update` | `updateCustomer` | ok (unreleased) | `updateCustomer(id, params = {}, options = {})` | Implemented in api-module-library #108; needs the release that includes it. |
|
|
426
|
+
| `paymentIntent.get` | `retrievePaymentIntent` | ok (unreleased) | `retrievePaymentIntent(id, params = {}, options = {})` | Implemented in api-module-library #108; needs the release that includes it. |
|
|
427
|
+
| `refund.get` | `retrieveRefund` | ok (unreleased) | `retrieveRefund(id, params = {}, options = {})` | Implemented in api-module-library #108; needs the release that includes it. |
|
|
428
|
+
| `payout.list` | `listPayouts` | ok (unreleased) | `listPayouts(params = {}, options = {})` | Implemented in api-module-library #108; needs the release that includes it. |
|
|
400
429
|
| `balanceTransaction.list` | `getBalanceTransactions` | ok | `getBalanceTransactions(params)` | (method was `listBalanceTransactions`) |
|
|
401
|
-
| `webhook.verify` | `verifyWebhookSignature` |
|
|
430
|
+
| `webhook.verify` | `verifyWebhookSignature` | ok (unreleased) | `verifyWebhookSignature({ headers, body, rawBody, method?, url?, now? })` | Implemented in api-module-library 659b90d per the vendor's signing docs; needs the release that includes it. |
|
|
402
431
|
|
|
403
432
|
## Acme ERP (`acmeerp`)
|
|
404
433
|
|