@volter/twin-hubspot 0.1.36 → 1.0.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/README.md +9 -193
- package/dist/generated/pack-facts.json +42 -0
- package/dist/journeys/coverage.json +60 -0
- package/dist/journeys/customer-life.json +7 -0
- package/dist/journeys/customer-life.outline.md +6 -0
- package/dist/journeys/decisions.json +623 -0
- package/dist/journeys/demand.json +171 -0
- package/dist/journeys/score.json +82 -0
- package/dist/journeys/unreachable.json +12 -0
- package/dist/journeys/vendor-examples.json +7 -0
- package/dist/spec/SOURCE.md +40 -0
- package/dist/spec/openapi/associations.json.gz +0 -0
- package/dist/spec/openapi/companies.json.gz +0 -0
- package/dist/spec/openapi/contacts.json.gz +0 -0
- package/dist/spec/openapi/deals.json.gz +0 -0
- package/dist/spec/openapi/meetings.json.gz +0 -0
- package/dist/spec/openapi/oauth.json.gz +0 -0
- package/dist/spec/openapi/owners.json.gz +0 -0
- package/dist/spec/openapi/pipelines.json.gz +0 -0
- package/dist/spec/openapi/properties.json.gz +0 -0
- package/dist/spec/openapi/tickets.json.gz +0 -0
- package/dist/spec/patches.json +235 -0
- package/dist/spec/sources.json +32 -0
- package/dist/src/cli.js +10 -22
- package/dist/src/fetch.d.ts +2 -0
- package/dist/src/fetch.js +13 -0
- package/dist/src/generated/surface.gen.json +1 -1
- package/dist/src/index.d.ts +5 -11
- package/dist/src/index.js +10 -94
- package/dist/src/manifest.js +32 -66
- package/dist/src/semantics/index.d.ts +2 -0
- package/dist/src/semantics/index.js +1 -0
- package/dist/src/semantics/states.d.ts +1 -0
- package/dist/src/semantics/states.js +2 -0
- package/dist/src/server.d.ts +7 -0
- package/dist/src/server.js +7 -0
- package/generated/pack-facts.json +42 -0
- package/journeys/coverage.json +60 -0
- package/journeys/customer-life.json +7 -0
- package/journeys/customer-life.outline.md +6 -0
- package/journeys/decisions.json +623 -0
- package/journeys/demand.json +171 -0
- package/journeys/score.json +82 -0
- package/journeys/unreachable.json +12 -0
- package/journeys/vendor-examples.json +7 -0
- package/package.json +10 -23
- package/spec/SOURCE.md +40 -0
- package/spec/openapi/associations.json.gz +0 -0
- package/spec/openapi/companies.json.gz +0 -0
- package/spec/openapi/contacts.json.gz +0 -0
- package/spec/openapi/deals.json.gz +0 -0
- package/spec/openapi/meetings.json.gz +0 -0
- package/spec/openapi/oauth.json.gz +0 -0
- package/spec/openapi/owners.json.gz +0 -0
- package/spec/openapi/pipelines.json.gz +0 -0
- package/spec/openapi/properties.json.gz +0 -0
- package/spec/openapi/tickets.json.gz +0 -0
- package/spec/patches.json +235 -0
- package/spec/sources.json +32 -0
- package/src/cli.ts +10 -19
- package/src/fetch.ts +14 -0
- package/src/generated/surface.gen.json +1 -1
- package/src/index.ts +12 -152
- package/src/manifest.ts +33 -92
- package/src/semantics/index.ts +6 -0
- package/src/semantics/states.ts +2 -0
- package/src/server.ts +8 -0
- package/client/hubspot-mirror.css +0 -43
- package/client/hubspot-mirror.tsx +0 -132
- package/dist/client/hubspot-mirror.bundle.js +0 -516
- package/dist/client/hubspot-mirror.css +0 -43
- package/dist/client/hubspot-mirror.d.ts +0 -15
- package/dist/client/hubspot-mirror.js +0 -59
- package/dist/client/hubspot-mirror.tsx +0 -132
- package/dist/src/accounts.d.ts +0 -30
- package/dist/src/accounts.js +0 -122
- package/dist/src/hubspot-areas.d.ts +0 -10
- package/dist/src/hubspot-areas.js +0 -114
- package/dist/src/hubspot-budget.d.ts +0 -58
- package/dist/src/hubspot-budget.js +0 -176
- package/dist/src/hubspot-capabilities.d.ts +0 -3
- package/dist/src/hubspot-capabilities.js +0 -1588
- package/dist/src/hubspot-conformance.d.ts +0 -16
- package/dist/src/hubspot-conformance.js +0 -523
- package/dist/src/hubspot-connector.d.ts +0 -125
- package/dist/src/hubspot-connector.js +0 -390
- package/dist/src/hubspot-deferred-capabilities.d.ts +0 -6
- package/dist/src/hubspot-deferred-capabilities.js +0 -64
- package/dist/src/hubspot-mirror-ui.d.ts +0 -62
- package/dist/src/hubspot-mirror-ui.js +0 -152
- package/dist/src/hubspot-oauth.d.ts +0 -8
- package/dist/src/hubspot-oauth.js +0 -291
- package/dist/src/hubspot-server.d.ts +0 -24
- package/dist/src/hubspot-server.js +0 -116
- package/dist/src/hubspot-twin.d.ts +0 -65
- package/dist/src/hubspot-twin.js +0 -1558
- package/dist/src/portal.d.ts +0 -20
- package/dist/src/portal.js +0 -30
- package/dist/src/screens/account.d.ts +0 -1
- package/dist/src/screens/account.js +0 -139
- package/dist/src/screens/crm.d.ts +0 -2
- package/dist/src/screens/crm.js +0 -153
- package/dist/src/screens/developer.d.ts +0 -4
- package/dist/src/screens/developer.js +0 -191
- package/dist/src/screens/forms.d.ts +0 -5
- package/dist/src/screens/forms.js +0 -126
- package/dist/src/screens/page.d.ts +0 -21
- package/dist/src/screens/page.js +0 -49
- package/dist/src/screens/session.d.ts +0 -1
- package/dist/src/screens/session.js +0 -32
- package/dist/src/semantics/crm.d.ts +0 -8
- package/dist/src/semantics/crm.js +0 -101
- package/dist/src/webhooks.d.ts +0 -12
- package/dist/src/webhooks.js +0 -79
- package/src/accounts.ts +0 -127
- package/src/hubspot-areas.ts +0 -155
- package/src/hubspot-budget.ts +0 -202
- package/src/hubspot-capabilities.ts +0 -1523
- package/src/hubspot-conformance.ts +0 -537
- package/src/hubspot-connector.ts +0 -419
- package/src/hubspot-deferred-capabilities.ts +0 -99
- package/src/hubspot-journey.uitest.ts +0 -104
- package/src/hubspot-mirror-ui.ts +0 -166
- package/src/hubspot-oauth.tsx +0 -296
- package/src/hubspot-server.ts +0 -115
- package/src/hubspot-twin.ts +0 -1534
- package/src/portal.ts +0 -40
- package/src/screens/account.tsx +0 -129
- package/src/screens/crm.tsx +0 -154
- package/src/screens/developer.tsx +0 -181
- package/src/screens/forms.tsx +0 -117
- package/src/screens/page.tsx +0 -55
- package/src/screens/session.tsx +0 -36
- package/src/semantics/crm.ts +0 -116
- package/src/webhooks.ts +0 -82
package/dist/src/index.d.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export
|
|
6
|
-
export { HUBSPOT_BUDGET_CEILING, HUBSPOT_BUDGET_MAX_RETRY_AFTER_S, HUBSPOT_BUDGET_WINDOW_MS, HUBSPOT_CALL_WEIGHTS, HUBSPOT_RATE_BUDGET, HubspotBudget, HubspotBudgetError, hubspotBudgetPath, hubspotCallWeight, } from './hubspot-budget.js';
|
|
7
|
-
export type { HubspotBudgetErrorKind, HubspotBudgetOptions, HubspotBudgetReservation, HubspotBudgetSnapshot } from './hubspot-budget.js';
|
|
8
|
-
export { MIRROR_SECTIONS, SECTION_COLUMNS, TITLE_PROPERTY, buildHubspotMirrorClient, createHubspotMirrorServer, formatAmount, groupByStage, hubspotMirrorHtml, recordTitle, stageTone, } from './hubspot-mirror-ui.js';
|
|
9
|
-
export type { HubspotRow, MirrorSectionKey, PillTone } from './hubspot-mirror-ui.js';
|
|
10
|
-
import { type TwinPack } from '@volter/world-core';
|
|
11
|
-
export declare const pack: TwinPack;
|
|
1
|
+
import { manifest } from './manifest.js';
|
|
2
|
+
export { createHubspotFetch } from './fetch.js';
|
|
3
|
+
export { createHubspotTwinServer } from './server.js';
|
|
4
|
+
export { manifest };
|
|
5
|
+
export declare const pack: import("@volter/world-core").PackDescriptor;
|
package/dist/src/index.js
CHANGED
|
@@ -1,94 +1,10 @@
|
|
|
1
|
-
// @volter/twin-hubspot — the
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export {
|
|
10
|
-
export
|
|
11
|
-
export { hubspotRequestForAction, liveHubspotExecute, mapCrmObject, mapOwner, pollTimestamp, pullHubspotAll, pullHubspotObjects, pullHubspotOwners, pushPendingHubspotActions, syncHubspotFromReal, } from "./hubspot-connector.js";
|
|
12
|
-
// The client-side rate budget — the fail-closed backstop `liveHubspotExecute` routes every live
|
|
13
|
-
// request through. The MECHANISM is the kernel's shared, vendor-agnostic `RateBudget`; what lives
|
|
14
|
-
// here is HubSpot's DECLARATION (window/ceiling/per-endpoint weights) plus the vendor-bound
|
|
15
|
-
// bindings. Exported so an operator can inspect spend (`snapshot`) and so a caller can catch
|
|
16
|
-
// `HubspotBudgetError` by type; there is deliberately no export that disables the guard.
|
|
17
|
-
export { HUBSPOT_BUDGET_CEILING, HUBSPOT_BUDGET_MAX_RETRY_AFTER_S, HUBSPOT_BUDGET_WINDOW_MS, HUBSPOT_CALL_WEIGHTS, HUBSPOT_RATE_BUDGET, HubspotBudget, HubspotBudgetError, hubspotBudgetPath, hubspotCallWeight, } from "./hubspot-budget.js";
|
|
18
|
-
export { MIRROR_SECTIONS, SECTION_COLUMNS, TITLE_PROPERTY, buildHubspotMirrorClient, createHubspotMirrorServer, formatAmount, groupByStage, hubspotMirrorHtml, recordTitle, stageTone, } from "./hubspot-mirror-ui.js";
|
|
19
|
-
// Registry descriptor: the pack self-describes so tooling can discover it.
|
|
20
|
-
import { registerPack } from '@volter/world-core';
|
|
21
|
-
import { performHubspotAction, syncHubspotFromRemote } from "./hubspot-connector.js";
|
|
22
|
-
import { HUBSPOT_RATE_BUDGET as RATE_BUDGET } from "./hubspot-budget.js";
|
|
23
|
-
export const pack = {
|
|
24
|
-
// PROTOCOL 2 (docs/contributing/architecture.md#protocol-2-the-pack-is-a-plugin): the pack is a plugin — its wire, its tree, and its half of
|
|
25
|
-
// the real state system. Moved 2026-09-08.
|
|
26
|
-
protocol: '2',
|
|
27
|
-
// HubSpot publishes webhooks for CRM object changes, which is what actually moves; the refresh
|
|
28
|
-
// walks every object type and is the backstop.
|
|
29
|
-
refresh: { every: '15m', webhook: true, onDemand: { atMost: '30s' } },
|
|
30
|
-
stateSystem: { perform: performHubspotAction, refresh: syncHubspotFromRemote },
|
|
31
|
-
// The round trip is a CONTACT create — HubSpot's own write, and the portal mints a fresh record
|
|
32
|
-
// id for every one, so a second send on a branch is a second contact rather than a collision.
|
|
33
|
-
roundTrip: { method: 'POST', path: '/crm/v3/objects/contacts', body: { properties: { email: 'round@trip.test', firstname: 'Round', lastname: 'Trip' } }, headers: { authorization: 'Bearer twin' } },
|
|
34
|
-
parityOrigin: 'http://twin',
|
|
35
|
-
vendor: 'hubspot',
|
|
36
|
-
// The SAME object hubspot-budget.ts declares at module load — one source of truth, so
|
|
37
|
-
// registering the pack and importing the connector can never arm two different ceilings.
|
|
38
|
-
rateBudget: RATE_BUDGET,
|
|
39
|
-
transport: 'rest',
|
|
40
|
-
archetype: 'crud',
|
|
41
|
-
bin: 'world-hubspot',
|
|
42
|
-
// R2 adopted-as-debt, legibly: declared types no replay can create, each with its reason.
|
|
43
|
-
resourcesUnreachable: {
|
|
44
|
-
'owner': "a portal user provisioned in HubSpot's admin, never through the CRM API",
|
|
45
|
-
},
|
|
46
|
-
resources: ['crm_object', 'property', 'property_group', 'pipeline', 'association', 'owner'],
|
|
47
|
-
specSource: "nine documents of HubSpot's public spec catalog (api.hubspot.com/public/api/spec/v1/specs): Contacts, Companies, "
|
|
48
|
-
+ 'Deals, Tickets, Crm Owners, Properties and Pipelines v3, Associations v4 and OAuth v1, vendored under spec/openapi/ '
|
|
49
|
-
+ '(provenance in spec/SOURCE.md) and read as their union; the calls dubinc/dub makes (apps/web/lib/integrations/hubspot/).',
|
|
50
|
-
description: 'HubSpot CRM twin — v3/v4 objects, properties, associations, pipelines and owners, with the vendor error envelope, paging.next.after and a CRM mirror.',
|
|
51
|
-
// A browser-side HubSpot call goes to api.hubapi.com/crm/… — the dev proxy forwards '/crm/'
|
|
52
|
-
// to the twin and strips the absolute host so calls come back same-origin.
|
|
53
|
-
browserRouting: { apiPathPrefix: '/crm/', loaderHost: 'https://api.hubapi.com' },
|
|
54
|
-
// ADOPTION — how an app repo betrays that it talks to HubSpot.
|
|
55
|
-
// • `@hubspot/api-client` is the ONE official npm client of the surface modeled here.
|
|
56
|
-
// • The `@hubspot/` scope is NOT claimed wholesale: it also carries the CMS/CLI toolchain
|
|
57
|
-
// (`@hubspot/cli`, `@hubspot/local-dev-lib`, the `@hubspot/cms-components` family), which
|
|
58
|
-
// are build tooling for a product area this twin explicitly does not model. Claiming the
|
|
59
|
-
// scope would report a CMS-theme repo as covered by a CRM twin — the exact lie `covers`
|
|
60
|
-
// exists to prevent (the `googleapis` precedent in covers.ts).
|
|
61
|
-
// • `HUBSPOT` is the credential stem: HUBSPOT_ACCESS_TOKEN / HUBSPOT_API_KEY /
|
|
62
|
-
// HUBSPOT_CLIENT_ID / HUBSPOT_CLIENT_SECRET all normalize to it under covers.ts's
|
|
63
|
-
// ENV_SUFFIX rules (framework prefix stripped, suffix matched, remainder lowercased with
|
|
64
|
-
// punctuation removed). `HUBSPOT_PRIVATE_APP_TOKEN` — the name HubSpot's own private-app
|
|
65
|
-
// docs use — stems to `hubspotprivateapp` instead, because `_TOKEN` is the matched suffix,
|
|
66
|
-
// so it is claimed explicitly rather than assumed.
|
|
67
|
-
adoption: {
|
|
68
|
-
// HubSpot's official Python client, the counterpart of `@hubspot/api-client`.
|
|
69
|
-
pypi: ['hubspot-api-client'],
|
|
70
|
-
sdks: ['@hubspot/api-client'],
|
|
71
|
-
envStems: ['HUBSPOT', 'HUBSPOTPRIVATEAPP'],
|
|
72
|
-
},
|
|
73
|
-
// INTERCEPTION — api.hubapi.com is the SDK's only API server: every generated
|
|
74
|
-
// `servers.ts` in @hubspot/api-client 14.0.1 declares exactly
|
|
75
|
-
// `new ServerConfiguration("https://api.hubapi.com", {})`, and a sweep of the whole published
|
|
76
|
-
// tarball finds no other API host. `app.hubspot.com` appears once, in
|
|
77
|
-
// `OauthDiscovery.getAuthorizationUrl`: the URL a person is sent to for consent, which the twin serves
|
|
78
|
-
// (hubspot-oauth.tsx).
|
|
79
|
-
// app.hubspot.com carries every page the twin builds (sign-in, consent, apps, records, forms, settings) and
|
|
80
|
-
// api.hsforms.com a form's submission (src/screens/).
|
|
81
|
-
hosts: [{ host: 'api.hubapi.com' }, { host: 'app.hubspot.com' }, { host: 'api.hsforms.com' }],
|
|
82
|
-
// WORLD WIRING — `endpointEnvNone`, and this is a ruling, not an omission. The SDK IS
|
|
83
|
-
// base-URL-configurable, but through a CONSTRUCTOR OPTION (`IConfiguration.basePath`, read by
|
|
84
|
-
// `ApiClientConfigurator.getBaseServer`), never an environment variable: nothing in
|
|
85
|
-
// @hubspot/api-client 14.0.1 reads `process.env`, and HubSpot documents no `HUBSPOT_BASE_URL`.
|
|
86
|
-
// Inventing one would make `covers` report a world covered while the app, reading no such var,
|
|
87
|
-
// still talked to the real portal. Interception is the `hosts` entry above.
|
|
88
|
-
endpointEnvNone: 'the @hubspot/api-client SDK takes its base URL from the `basePath` CONSTRUCTOR option '
|
|
89
|
-
+ '(IConfiguration.basePath → ApiClientConfigurator.getBaseServer), not from any environment '
|
|
90
|
-
+ 'variable — it reads no process.env at all, and HubSpot documents no base-URL env var. '
|
|
91
|
-
+ 'Interception is the api.hubapi.com host entry; inventing a HUBSPOT_BASE_URL the app does '
|
|
92
|
-
+ 'not read would report a world covered while its traffic still left the machine.',
|
|
93
|
-
};
|
|
94
|
-
registerPack(pack);
|
|
1
|
+
// @volter/twin-hubspot — the hubspot twin (Protocol 3). A fixed file (create-pack): the descriptor is the manifest's, and the
|
|
2
|
+
// kernel derives the vendor-backed half from the generated surface, unless the manifest declares none (vendorBacked.none;
|
|
3
|
+
// architecture, "The real-system adapters").
|
|
4
|
+
import { packOf, registerPack } from '@volter/world-core';
|
|
5
|
+
import { manifest } from "./manifest.js";
|
|
6
|
+
import surface from './generated/surface.gen.json' with { type: 'json' };
|
|
7
|
+
export { createHubspotFetch } from "./fetch.js";
|
|
8
|
+
export { createHubspotTwinServer } from "./server.js";
|
|
9
|
+
export { manifest };
|
|
10
|
+
export const pack = registerPack(packOf(manifest, surface));
|
package/dist/src/manifest.js
CHANGED
|
@@ -1,68 +1,34 @@
|
|
|
1
1
|
export const manifest = {
|
|
2
|
-
vendor: 'hubspot',
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
{
|
|
35
|
-
id: 'app-distribution', kind: 'workspace', host: 'app.hubspot.com', path: '/developer-projects/:hubId/project/:name/component/:uid/distribution',
|
|
36
|
-
demand: 'an OAuth marketplace app is published (Begin publishing, the AUP) before any install; a static app is installed and its token shown here',
|
|
37
|
-
status: 'done', controls: ['Begin publishing', 'Sign', 'Install now', 'Show'],
|
|
38
|
-
source: 'https://developers.hubspot.com/docs/apps/developer-platform/build-apps/manage-apps-in-hubspot',
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
id: 'records', kind: 'workspace', host: 'app.hubspot.com', path: '/contacts/:hubId/record/:objectTypeId/:id',
|
|
42
|
-
demand: "reps create deals on a contact's record and move a deal's stage; account managers add companies", status: 'done',
|
|
43
|
-
controls: ['Create deal', 'Deal stage', 'Save', 'Create company'], source: 'https://knowledge.hubspot.com/records/create-records-on-the-updated-index-page',
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
id: 'pipelines', kind: 'workspace', host: 'app.hubspot.com', path: '/settings/:hubId/objects/deals/pipelines',
|
|
47
|
-
demand: "a custom pipeline's closed-won stage ID is read here (Dub's guide: \"enter the stage ID corresponding to your custom Closed Won stage\")",
|
|
48
|
-
status: 'done', source: 'https://knowledge.hubspot.com/object-settings/set-up-and-customize-pipelines',
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
id: 'forms', kind: 'workspace', host: 'app.hubspot.com', path: '/forms/:hubId',
|
|
52
|
-
demand: "Dub's guide: \"In the HubSpot form builder, add a hidden field and map it to the Dub Id contact property\"", status: 'done',
|
|
53
|
-
controls: ['Create form', 'Add hidden field'], source: 'https://dub.co/docs/integrations/hubspot',
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
id: 'connected-apps', kind: 'workspace', host: 'app.hubspot.com', path: '/connected-apps/:hubId/installed',
|
|
57
|
-
demand: 'a client uninstalls the app it connected', status: 'done', controls: ['Uninstall', 'Type uninstall'],
|
|
58
|
-
source: 'https://knowledge.hubspot.com/marketplace/install-apps-in-the-hubspot-marketplace',
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
id: 'account-and-billing', kind: 'workspace', host: 'app.hubspot.com', path: '/account-and-billing/:hubId/subscriptions',
|
|
62
|
-
demand: "a company leaving HubSpot cancels its subscription's auto-renewal, then deletes the account once the subscription has ended",
|
|
63
|
-
status: 'done', controls: ['Cancel auto-renewal', 'Next', 'Delete account', 'Enter your Hub ID to confirm', 'Yes, delete'],
|
|
64
|
-
source: 'https://knowledge.hubspot.com/account/how-do-i-cancel-my-hubspot-account',
|
|
65
|
-
},
|
|
66
|
-
],
|
|
67
|
-
resources: {},
|
|
2
|
+
vendor: 'hubspot', service: 'hubspot', body: { json: 'always', form: { coerce: false } },
|
|
3
|
+
ids: { template: '{n}' }, time: 'iso',
|
|
4
|
+
// source: https://developers.hubspot.com/docs/api-reference/error-handling "return a JSON formatted response with details about the error"
|
|
5
|
+
error: { status: 'error', message: '{message}', correlationId: '{id}' },
|
|
6
|
+
readOnly: { status: 403, message: 'This World is read-only.' },
|
|
7
|
+
// source: https://developers.hubspot.com/docs/api-reference/webhooks-webhooks-v3/guide "404 Not Found : requested resource not found"
|
|
8
|
+
// The documentation gives the not-found class, not words for every unknown path; use that class in its documented JSON envelope.
|
|
9
|
+
notFound: { status: 404, message: 'requested resource not found' },
|
|
10
|
+
gap: { status: 404, message: 'requested resource not found' },
|
|
11
|
+
// source: https://developers.hubspot.com/docs/api-reference/webhooks-webhooks-v3/guide "Authorization : Bearer YOUR_ACCESS_TOKEN"
|
|
12
|
+
// source: https://developers.hubspot.com/docs/api-reference/error-handling "Returned when the authentication provided is invalid."
|
|
13
|
+
// Where documentation stops: The 401 rule describes invalid authentication, not missing-key versus unknown-route precedence; the gap stands.
|
|
14
|
+
auth: { header: 'authorization', scheme: 'Bearer', paths: '^/crm/', gateWhenAbsent: true,
|
|
15
|
+
missing: { status: 401, message: 'Unauthorized' }, invalid: { status: 401, message: 'Unauthorized' }, invalidKeys: ['invalid'] },
|
|
16
|
+
deleted: {}, resources: {},
|
|
17
|
+
unmodeled: ["get-/crm/v3/objects/0-3_getPage", "post-/crm/v3/objects/0-3_create", "get-/crm/v3/objects/0-3/{dealId}_getById", "patch-/crm/v3/objects/0-3/{dealId}_update", "delete-/crm/v3/objects/0-3/{dealId}_archive", "post-/crm/v3/objects/0-3/batch/archive_archive", "post-/crm/v3/objects/0-3/batch/create_create", "post-/crm/v3/objects/0-3/batch/read_read", "post-/crm/v3/objects/0-3/batch/update_update", "post-/crm/v3/objects/0-3/batch/upsert_upsert", "post-/crm/v3/objects/0-3/merge_merge", "post-/crm/v3/objects/0-3/search_doSearch", "get-/crm/v3/objects/companies_getPage", "post-/crm/v3/objects/companies_create", "get-/crm/v3/objects/companies/{companyId}_getById", "patch-/crm/v3/objects/companies/{companyId}_update", "delete-/crm/v3/objects/companies/{companyId}_archive", "post-/crm/v3/objects/companies/batch/archive_archive", "post-/crm/v3/objects/companies/batch/create_create", "post-/crm/v3/objects/companies/batch/read_read", "post-/crm/v3/objects/companies/batch/update_update", "post-/crm/v3/objects/companies/batch/upsert_upsert", "post-/crm/v3/objects/companies/merge_merge", "post-/crm/v3/objects/companies/search_doSearch", "get-/crm/v3/objects/contacts_getPage", "post-/crm/v3/objects/contacts_create", "get-/crm/v3/objects/contacts/{contactId}_getById", "patch-/crm/v3/objects/contacts/{contactId}_update", "delete-/crm/v3/objects/contacts/{contactId}_archive", "post-/crm/v3/objects/contacts/batch/archive_archive", "post-/crm/v3/objects/contacts/batch/create_create", "post-/crm/v3/objects/contacts/batch/read_read", "post-/crm/v3/objects/contacts/batch/update_update", "post-/crm/v3/objects/contacts/batch/upsert_upsert", "post-/crm/v3/objects/contacts/gdpr-delete_purge", "post-/crm/v3/objects/contacts/merge_merge", "post-/crm/v3/objects/contacts/search_doSearch", "get-/crm/v3/objects/meetings_getPage", "post-/crm/v3/objects/meetings_create", "get-/crm/v3/objects/meetings/{meetingId}_getById", "patch-/crm/v3/objects/meetings/{meetingId}_update", "delete-/crm/v3/objects/meetings/{meetingId}_archive", "post-/crm/v3/objects/meetings/batch/archive_archive", "post-/crm/v3/objects/meetings/batch/create_create", "post-/crm/v3/objects/meetings/batch/read_read", "post-/crm/v3/objects/meetings/batch/update_update", "post-/crm/v3/objects/meetings/batch/upsert_upsert", "post-/crm/v3/objects/meetings/search_doSearch", "get-/crm/v3/objects/tickets_getPage", "post-/crm/v3/objects/tickets_create", "get-/crm/v3/objects/tickets/{ticketId}_getById", "patch-/crm/v3/objects/tickets/{ticketId}_update", "delete-/crm/v3/objects/tickets/{ticketId}_archive", "post-/crm/v3/objects/tickets/batch/archive_archive", "post-/crm/v3/objects/tickets/batch/create_create", "post-/crm/v3/objects/tickets/batch/read_read", "post-/crm/v3/objects/tickets/batch/update_update", "post-/crm/v3/objects/tickets/batch/upsert_upsert", "post-/crm/v3/objects/tickets/merge_merge", "post-/crm/v3/objects/tickets/search_doSearch", "get-/crm/v3/owners_/crm/v3/owners", "get-/crm/v3/owners/{ownerId}_getById", "get-/crm/v3/pipelines/{objectType}_getAll", "post-/crm/v3/pipelines/{objectType}_create", "get-/crm/v3/pipelines/{objectType}/{pipelineId}_getById", "put-/crm/v3/pipelines/{objectType}/{pipelineId}_replace", "patch-/crm/v3/pipelines/{objectType}/{pipelineId}_update", "delete-/crm/v3/pipelines/{objectType}/{pipelineId}_archive", "get-/crm/v3/pipelines/{objectType}/{pipelineId}/audit_getAudit", "get-/crm/v3/pipelines/{objectType}/{pipelineId}/stages_getAll", "post-/crm/v3/pipelines/{objectType}/{pipelineId}/stages_create", "get-/crm/v3/pipelines/{objectType}/{pipelineId}/stages/{stageId}_getById", "put-/crm/v3/pipelines/{objectType}/{pipelineId}/stages/{stageId}_replace", "patch-/crm/v3/pipelines/{objectType}/{pipelineId}/stages/{stageId}_update", "delete-/crm/v3/pipelines/{objectType}/{pipelineId}/stages/{stageId}_archive", "get-/crm/v3/pipelines/{objectType}/{pipelineId}/stages/{stageId}/audit_getAudit", "get-/crm/v3/properties/{objectType}_getAll", "post-/crm/v3/properties/{objectType}_create", "get-/crm/v3/properties/{objectType}/{propertyName}_getByName", "patch-/crm/v3/properties/{objectType}/{propertyName}_update", "delete-/crm/v3/properties/{objectType}/{propertyName}_archive", "post-/crm/v3/properties/{objectType}/batch/archive_archive", "post-/crm/v3/properties/{objectType}/batch/create_create", "post-/crm/v3/properties/{objectType}/batch/read_read", "get-/crm/v3/properties/{objectType}/groups_getAll", "post-/crm/v3/properties/{objectType}/groups_create", "get-/crm/v3/properties/{objectType}/groups/{groupName}_getByName", "patch-/crm/v3/properties/{objectType}/groups/{groupName}_update", "delete-/crm/v3/properties/{objectType}/groups/{groupName}_archive", "post-/crm/v4/associations/{fromObjectType}/{toObjectType}/batch/archive_archive", "post-/crm/v4/associations/{fromObjectType}/{toObjectType}/batch/associate/default_createDefault", "post-/crm/v4/associations/{fromObjectType}/{toObjectType}/batch/create_create", "post-/crm/v4/associations/{fromObjectType}/{toObjectType}/batch/labels/archive_archiveLabels", "post-/crm/v4/associations/{fromObjectType}/{toObjectType}/batch/read_getPage", "post-/crm/v4/associations/usage/high-usage-report/{userId}_request", "put-/crm/v4/objects/{fromObjectType}/{fromObjectId}/associations/default/{toObjectType}/{toObjectId}_createDefault", "get-/crm/v4/objects/{objectType}/{objectId}/associations/{toObjectType}_getPage", "put-/crm/v4/objects/{objectType}/{objectId}/associations/{toObjectType}/{toObjectId}_create", "delete-/crm/v4/objects/{objectType}/{objectId}/associations/{toObjectType}/{toObjectId}_archive", "get-/oauth/v1/access-tokens/{token}_get", "get-/oauth/v1/refresh-tokens/{token}_get", "delete-/oauth/v1/refresh-tokens/{token}_archive", "post-/oauth/v1/token_create"],
|
|
18
|
+
vendorBacked: { none: 'No vendor resource or operation is served; every spec operation answers the gap.' },
|
|
19
|
+
// source: https://developers.hubspot.com/docs/developer-tooling/platform/usage-guidelines "110 requests every 10 seconds"
|
|
20
|
+
rateBudget: { windowMs: 60000, ceiling: 660, defaultWeight: 1, maxRetryAfterSeconds: 60, reason: 'Public OAuth allowance of 110 requests per 10 seconds, expressed as 660 per minute.',
|
|
21
|
+
allowance: { perMinute: 660, source: 'https://developers.hubspot.com/docs/developer-tooling/platform/usage-guidelines' } },
|
|
22
|
+
discovery: { twinOf: 'HubSpot CRM, Meetings and OAuth v1 APIs', stores: 'No vendor resources',
|
|
23
|
+
behavior: 'Every spec operation answers the vendor-shaped gap; Cal.com and Dub require an optional HubSpot app installation.' },
|
|
24
|
+
descriptor: {
|
|
25
|
+
protocol: '3', transport: 'rest', archetype: 'crud', bin: 'world-hubspot', resources: [],
|
|
26
|
+
specSource: 'HubSpot CRM, Meetings and OAuth v1 OpenAPI documents; provenance in spec/SOURCE.md',
|
|
27
|
+
description: 'HubSpot API twin: every spec operation answers the vendor-shaped gap.',
|
|
28
|
+
adoption: { sdks: ['@hubspot/api-client'], pypi: ['hubspot-api-client'], envStems: ['HUBSPOT', 'HUBSPOTPRIVATEAPP'] },
|
|
29
|
+
hosts: [{ host: 'api.hubapi.com' }, { host: 'app.hubspot.com', demandPathPattern: false }, { host: 'api.hsforms.com' }],
|
|
30
|
+
endpointEnvNone: 'The optional integrations address HubSpot hosts; no SDK base-URL environment variable is injected.',
|
|
31
|
+
// source: https://raw.githubusercontent.com/dubinc/dub/7e0101363b2ab30afc537c1893f159d1dcba513a/apps/web/lib/integrations/hubspot/oauth.ts "process.env.HUBSPOT_CLIENT_ID"
|
|
32
|
+
clientCasesNone: 'Optional integration calls remain unserved; no SDK case is claimed for the retained gap.',
|
|
33
|
+
},
|
|
68
34
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const hubspotSemantics = {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const states: {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// FETCH-FIRST (runtime contract R12b): a fixed file, the kernel's serve seam around the pack's fetch (./fetch.ts).
|
|
2
|
+
import { serveHttp } from '@volter/world-core';
|
|
3
|
+
import { createHubspotFetch } from "./fetch.js";
|
|
4
|
+
export async function createHubspotTwinServer(options = {}) {
|
|
5
|
+
const server = await serveHttp({ port: options.port ?? 0, idleTimeout: 60, fetch: createHubspotFetch(options) });
|
|
6
|
+
return { port: server.port ?? options.port ?? 0, stop: () => server.stop(true) };
|
|
7
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"//": "GENERATED by scripts/pack-facts.ts — current pack descriptors and explicit world-runtime server backings; no prior-artifact entries are retained.",
|
|
3
|
+
"packs": {
|
|
4
|
+
"hubspot": {
|
|
5
|
+
"adoption": {
|
|
6
|
+
"sdks": [
|
|
7
|
+
"@hubspot/api-client"
|
|
8
|
+
],
|
|
9
|
+
"pypi": [
|
|
10
|
+
"hubspot-api-client"
|
|
11
|
+
],
|
|
12
|
+
"envStems": [
|
|
13
|
+
"HUBSPOT",
|
|
14
|
+
"HUBSPOTPRIVATEAPP"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"hosts": [
|
|
18
|
+
{
|
|
19
|
+
"host": "api.hubapi.com"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"host": "app.hubspot.com",
|
|
23
|
+
"demandPathPattern": false
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"host": "api.hsforms.com"
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"archetype": "crud",
|
|
30
|
+
"protocol": {
|
|
31
|
+
"declared": "3",
|
|
32
|
+
"major": 3,
|
|
33
|
+
"standing": "current"
|
|
34
|
+
},
|
|
35
|
+
"transport": "rest",
|
|
36
|
+
"resources": [],
|
|
37
|
+
"endpointEnvNone": "The optional integrations address HubSpot hosts; no SDK base-URL environment variable is injected.",
|
|
38
|
+
"serveExport": "createHubspotTwinServer"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"undeclared": []
|
|
42
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"vendor": "hubspot",
|
|
3
|
+
"missing": 0,
|
|
4
|
+
"stale": [],
|
|
5
|
+
"code": {
|
|
6
|
+
"lines": 49,
|
|
7
|
+
"run": 47,
|
|
8
|
+
"recorded": 2,
|
|
9
|
+
"missing": 0
|
|
10
|
+
},
|
|
11
|
+
"state": {
|
|
12
|
+
"declared": 0,
|
|
13
|
+
"reached": 0,
|
|
14
|
+
"recorded": 0,
|
|
15
|
+
"missing": [],
|
|
16
|
+
"undeclared": []
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
{
|
|
20
|
+
"file": "semantics/index.ts",
|
|
21
|
+
"lines": {
|
|
22
|
+
"found": 2,
|
|
23
|
+
"hit": 2
|
|
24
|
+
},
|
|
25
|
+
"missing": []
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"file": "manifest.ts",
|
|
29
|
+
"lines": {
|
|
30
|
+
"found": 26,
|
|
31
|
+
"hit": 26
|
|
32
|
+
},
|
|
33
|
+
"missing": []
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"file": "index.ts",
|
|
37
|
+
"lines": {
|
|
38
|
+
"found": 7,
|
|
39
|
+
"hit": 7
|
|
40
|
+
},
|
|
41
|
+
"missing": []
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"file": "server.ts",
|
|
45
|
+
"lines": {
|
|
46
|
+
"found": 4,
|
|
47
|
+
"hit": 2
|
|
48
|
+
},
|
|
49
|
+
"missing": []
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"file": "fetch.ts",
|
|
53
|
+
"lines": {
|
|
54
|
+
"found": 10,
|
|
55
|
+
"hit": 10
|
|
56
|
+
},
|
|
57
|
+
"missing": []
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"vendor": "hubspot",
|
|
3
|
+
"host": "api.hubapi.com",
|
|
4
|
+
"author": "Codex",
|
|
5
|
+
"about": "Demanded calls are recorded in demand.json and remain unserved in the retained gap. Scope is unchanged pending a separate implementation; supplying credentials is not opt-in.",
|
|
6
|
+
"steps": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# HubSpot customer life
|
|
2
|
+
|
|
3
|
+
Author: `Codex`.
|
|
4
|
+
|
|
5
|
+
Cal.com’s shipped CRM app is demand; Dub’s additional integration installation is optional. Pinned evidence for both is in `demand.json`.
|
|
6
|
+
Demanded calls are recorded in demand.json and remain unserved in the retained gap. Scope is unchanged pending a separate implementation; supplying credentials is not opt-in.
|