@drawbridge/drawbridge-utils 0.0.174 → 0.0.175
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/connections/index.cjs +451 -239
- package/dist/connections/index.d.cts +613 -316
- package/dist/connections/index.d.ts +613 -316
- package/dist/connections/index.js +450 -238
- package/dist/providers.cjs +451 -241
- package/dist/providers.d.cts +6 -6
- package/dist/providers.d.ts +6 -6
- package/dist/providers.js +451 -241
- package/package.json +1 -1
|
@@ -810,7 +810,7 @@ const accessToken = async ({
|
|
|
810
810
|
// A .js wrapper around otherwise untouched SVG so `node --test` can run against
|
|
811
811
|
// lib/ directly. A bare .svg import would need a bundler loader and force the
|
|
812
812
|
// tests through dist.
|
|
813
|
-
var icon$
|
|
813
|
+
var icon$7 = `<svg width="500" height="500" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
814
814
|
<rect width="500" height="500" fill="#FFD967"/>
|
|
815
815
|
<path d="M239.369 127.404C260.863 122.013 284.964 132.569 295.576 152.039C321.796 201.286 347.928 250.567 374.131 299.825C380.149 311.989 381.244 326.564 376.733 339.41C371.446 355.097 358.039 367.69 342.107 372.089C326.274 376.67 308.351 372.871 295.741 362.255C288.865 356.892 284.161 349.359 280.354 341.629C261.869 306.95 243.478 272.217 225.071 237.501C214.409 218.614 187.221 212.656 169.622 225.315C168.104 227.309 164.159 226.857 164.72 223.796C176.911 202.569 189.361 181.497 201.662 160.331C205.183 154.428 208.214 148.129 212.967 143.091C219.844 135.272 229.263 129.782 239.374 127.404" fill="#1E1C1C"/>
|
|
816
816
|
<path d="M166.04 261.805C180.228 259.107 195.528 261.893 207.581 269.971C218.512 277.079 226.908 288.136 230.604 300.657C234.835 314.103 233.614 329.124 227.485 341.788C220.097 356.875 205.782 368.543 189.317 372.089C173.957 375.652 157.089 372.386 144.304 363.103C132.971 355.295 124.912 342.989 121.891 329.581C118.943 316.636 120.725 302.656 127.002 290.938C134.699 275.951 149.503 264.933 166.046 261.811" fill="#1E1C1C"/>
|
|
@@ -1469,27 +1469,7 @@ var attentive = {
|
|
|
1469
1469
|
webhook : false
|
|
1470
1470
|
|
|
1471
1471
|
},
|
|
1472
|
-
icon: icon$
|
|
1473
|
-
// DRAWBRIDGE'S OWN CREDENTIALS for this vendor, as opposed to a merchant's —
|
|
1474
|
-
// what an admin types on the provider screen, and the only declaration of it.
|
|
1475
|
-
// It lives beside `requires`, which names the same variables: the manifest
|
|
1476
|
-
// says what it needs and this says how someone supplies it, so a credential
|
|
1477
|
-
// cannot be required by a vendor that offers nowhere to enter it.
|
|
1478
|
-
//
|
|
1479
|
-
// `redact` marks a secret — never returned by the api, and blank on save means
|
|
1480
|
-
// keep the stored value. `required` drives the live check.
|
|
1481
|
-
provider : {
|
|
1482
|
-
vendors : {
|
|
1483
|
-
attentive : {
|
|
1484
|
-
fields : [
|
|
1485
|
-
{ input : 'text', key : 'clientId', credential : 'ATTENTIVE_OAUTH_CLIENT_ID', label : 'Client ID', message : 'From our app\'s registration in the Attentive developer portal.', required : true },
|
|
1486
|
-
{ input : 'password', key : 'clientSecret', credential : 'ATTENTIVE_OAUTH_CLIENT_SECRET', label : 'Client secret', message : 'Beside the Client ID in the Attentive developer portal.', redact : true, required : true }
|
|
1487
|
-
],
|
|
1488
|
-
icon: icon$4,
|
|
1489
|
-
name : 'Attentive'
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1492
|
-
},
|
|
1472
|
+
icon: icon$7,
|
|
1493
1473
|
requires : [
|
|
1494
1474
|
'ATTENTIVE_OAUTH_CLIENT_ID',
|
|
1495
1475
|
'ATTENTIVE_OAUTH_CLIENT_SECRET'
|
|
@@ -1593,6 +1573,11 @@ var attentive = {
|
|
|
1593
1573
|
}
|
|
1594
1574
|
]
|
|
1595
1575
|
),
|
|
1576
|
+
// THE VENDORS THIS CONNECTION SPENDS, by slug. Each is declared once in
|
|
1577
|
+
// lib/connections/vendors/, and named here by whoever uses it — the block that
|
|
1578
|
+
// used to sit here declared them inline, so two manifests naming one vendor had
|
|
1579
|
+
// to be reconciled at import by mergeVendors().
|
|
1580
|
+
vendors : [ 'attentive' ],
|
|
1596
1581
|
title : 'Attentive',
|
|
1597
1582
|
|
|
1598
1583
|
// ATTENTIVE'S SEGMENTS INDEX. There is no documented per-segment url, and the
|
|
@@ -2069,7 +2054,7 @@ const contacts = {
|
|
|
2069
2054
|
// A .js wrapper around otherwise untouched SVG so `node --test` can run against
|
|
2070
2055
|
// lib/ directly. A bare .svg import would need a bundler loader and force the
|
|
2071
2056
|
// tests onto dist/, which is a worse trade than one line of wrapper.
|
|
2072
|
-
var icon$
|
|
2057
|
+
var icon$6 = `<svg width="500" height="500" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2073
2058
|
<rect width="500" height="500" fill="#0D1314"/>
|
|
2074
2059
|
<g clip-path="url(#clip0_2115_2832)">
|
|
2075
2060
|
<path d="M153.198 142.241L183.69 196.065V303.852L153 357.676L184.82 375.028L220.116 313.163V186.865L185.046 125L153.198 142.241Z" fill="#BAEC5F"/>
|
|
@@ -2090,7 +2075,7 @@ var icon$3 = `<svg width="500" height="500" viewBox="0 0 500 500" fill="none" xm
|
|
|
2090
2075
|
// A .js wrapper around otherwise untouched SVG so `node --test` can run against
|
|
2091
2076
|
// lib/ directly. A bare .svg import would need a bundler loader and force the
|
|
2092
2077
|
// tests onto dist/, which is a worse trade than one line of wrapper.
|
|
2093
|
-
var
|
|
2078
|
+
var icon$5 = `<svg width="500" height="500" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2094
2079
|
<rect width="500" height="500" fill="#FF7A59"/>
|
|
2095
2080
|
<circle cx="290" cy="290" r="78" stroke="white" stroke-width="30"/>
|
|
2096
2081
|
<circle cx="290" cy="290" r="18" fill="white"/>
|
|
@@ -2108,7 +2093,7 @@ var hubspotIcon = `<svg width="500" height="500" viewBox="0 0 500 500" fill="non
|
|
|
2108
2093
|
// A .js wrapper around otherwise untouched SVG so `node --test` can run against
|
|
2109
2094
|
// lib/ directly. A bare .svg import would need a bundler loader and force the
|
|
2110
2095
|
// tests onto dist/, which is a worse trade than one line of wrapper.
|
|
2111
|
-
var
|
|
2096
|
+
var icon$4 = `<svg width="500" height="500" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2112
2097
|
<rect width="500" height="500" fill="#F1FAFF"/>
|
|
2113
2098
|
<g clip-path="url(#clip0_1011_2743)">
|
|
2114
2099
|
<path d="M366.676 134.534V289.172H289.203V366.487H134.258L134.258 289.171L134.256 289.172V211.851H211.729V134.534H366.676Z" fill="#9DD6E3"/>
|
|
@@ -2131,7 +2116,7 @@ var sendgridIcon = `<svg width="500" height="500" viewBox="0 0 500 500" fill="no
|
|
|
2131
2116
|
// A .js wrapper around otherwise untouched SVG so `node --test` can run against
|
|
2132
2117
|
// lib/ directly. A bare .svg import would need a bundler loader and force the
|
|
2133
2118
|
// tests onto dist/, which is a worse trade than one line of wrapper.
|
|
2134
|
-
var
|
|
2119
|
+
var icon$3 = `<svg width="500" height="500" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2135
2120
|
<rect width="500" height="500" fill="#F22F46"/>
|
|
2136
2121
|
<path d="M250 134.954C186.341 134.954 134.954 186.341 134.954 250C134.954 313.659 186.341 365.047 250 365.047C313.659 365.047 365.047 313.659 365.047 250C365.047 186.341 313.659 134.954 250 134.954ZM250 334.368C203.215 334.368 165.633 296.786 165.633 250C165.633 203.215 203.215 165.633 250 165.633C296.786 165.633 334.368 203.215 334.368 250C334.368 296.786 296.786 334.368 250 334.368ZM302.155 221.622C302.155 234.661 291.417 245.399 278.378 245.399C265.34 245.399 254.602 234.661 254.602 221.622C254.602 208.584 265.34 197.846 278.378 197.846C291.417 197.846 302.155 208.584 302.155 221.622ZM302.155 278.378C302.155 291.417 291.417 302.155 278.378 302.155C265.34 302.155 254.602 291.417 254.602 278.378C254.602 265.34 265.34 254.602 278.378 254.602C291.417 254.602 302.155 265.34 302.155 278.378ZM245.399 278.378C245.399 291.417 234.661 302.155 221.622 302.155C208.584 302.155 197.846 291.417 197.846 278.378C197.846 265.34 208.584 254.602 221.622 254.602C234.661 254.602 245.399 265.34 245.399 278.378ZM245.399 221.622C245.399 234.661 234.661 245.399 221.622 245.399C208.584 245.399 197.846 234.661 197.846 221.622C197.846 208.584 208.584 197.846 221.622 197.846C234.661 197.846 245.399 208.584 245.399 221.622Z" fill="white"/>
|
|
2137
2122
|
</svg>`;
|
|
@@ -3183,7 +3168,7 @@ var drawbridge = {
|
|
|
3183
3168
|
},
|
|
3184
3169
|
webhook : false
|
|
3185
3170
|
},
|
|
3186
|
-
icon: icon$
|
|
3171
|
+
icon: icon$6,
|
|
3187
3172
|
|
|
3188
3173
|
// WHERE TWILIO PUTS THINGS on an inbound request, and WHICH credential
|
|
3189
3174
|
// verifies each channel. The route resolves the NAME to the stored value and
|
|
@@ -3214,70 +3199,6 @@ var drawbridge = {
|
|
|
3214
3199
|
},
|
|
3215
3200
|
// PRIVATE: never in the catalog, always available to the builder.
|
|
3216
3201
|
private : true,
|
|
3217
|
-
// THE PLATFORM'S OWN SENDING CREDENTIALS — SendGrid, Twilio, and the internal
|
|
3218
|
-
// HubSpot portal. No merchant ever sees these; they are what an admin types on
|
|
3219
|
-
// the provider screen so that Drawbridge itself can send.
|
|
3220
|
-
//
|
|
3221
|
-
// They belong on THIS manifest because this is the connection that sends: the
|
|
3222
|
-
// email, sms and segment hooks below are the only things that spend them, and
|
|
3223
|
-
// a private connection is still where a vendor fact lives. They are THREE
|
|
3224
|
-
// VENDORS, not one, and each is its own row and its own admin card — so
|
|
3225
|
-
// SendGrid reads live on a deployment that never configured Twilio, instead
|
|
3226
|
-
// of one card for all three that could only ever be as live as its weakest.
|
|
3227
|
-
//
|
|
3228
|
-
// UNLIKE every public vendor, none of these appear in `requires` — see the
|
|
3229
|
-
// comment there. Availability and configuration are different questions, and a
|
|
3230
|
-
// missing CRM token must not take every base workflow step away.
|
|
3231
|
-
//
|
|
3232
|
-
// ponytail: the field keys keep the names they had on the shared row
|
|
3233
|
-
// (smsSid, hubspotToken) so the readers destructuring vendorSettings() did
|
|
3234
|
-
// not move. Rename them to sid/token when those readers are next touched.
|
|
3235
|
-
provider : {
|
|
3236
|
-
vendors : {
|
|
3237
|
-
sendgrid : {
|
|
3238
|
-
fields : [
|
|
3239
|
-
{ input : 'email', key : 'accountSender', credential : 'SENDGRID_FROM_ADDRESS', label : 'Account sender', message : 'Verification codes and security alerts send from here.', required : true },
|
|
3240
|
-
{ input : 'password', key : 'apiKey', credential : 'SENDGRID_API_KEY', label : 'SendGrid API key', message : 'SendGrid dashboard, Settings, API Keys — full access for sends.', redact : true, required : true },
|
|
3241
|
-
// Optional: SENDGRID_SEND_FROM_ADDRESS is not boot-required in sync
|
|
3242
|
-
// either. Unset, it degrades to the account sender rather than
|
|
3243
|
-
// refusing to start.
|
|
3244
|
-
// NOT redacted, because it is a PUBLIC key. Marking it secret would
|
|
3245
|
-
// be theatre, and it would stop an operator reading back the value
|
|
3246
|
-
// they need to compare against the SendGrid console.
|
|
3247
|
-
//
|
|
3248
|
-
// Optional: absent, the event webhook answers 500 on verify rather
|
|
3249
|
-
// than accepting unverified deliveries, and nothing else notices.
|
|
3250
|
-
{ input : 'text', key : 'eventKey', credential : 'SENDGRID_EVENT_WEBHOOK_KEY', label : 'Event webhook key', message : 'SendGrid, Settings, Mail Settings, Event Webhook — the verification key shown once signature verification is enabled. Public, not a secret.' },
|
|
3251
|
-
{ input : 'email', key : 'leadSender', credential : 'SENDGRID_SEND_FROM_ADDRESS', label : 'Lead sender', message : 'The default for lead-facing mail when a merchant has not verified their own domain.' }
|
|
3252
|
-
],
|
|
3253
|
-
icon : sendgridIcon,
|
|
3254
|
-
name : 'SendGrid'
|
|
3255
|
-
},
|
|
3256
|
-
// Missing, SMS is LOCKED DOWN rather than broken: every send path
|
|
3257
|
-
// refuses cleanly (queue/notification.js cancels, the otc stream skips
|
|
3258
|
-
// and logs), the number-purchase routes deny, and identityDefaults.sms
|
|
3259
|
-
// hides the org's SMS settings entirely. The card reads not live, which
|
|
3260
|
-
// is the truth about Twilio and says nothing about email.
|
|
3261
|
-
twilio : {
|
|
3262
|
-
fields : [
|
|
3263
|
-
{ input : 'text', key : 'smsFrom', credential : 'TWILIO_ACCOUNT_FROM', label : 'SMS number', message : 'Without Twilio credentials, SMS is disabled across the platform.', required : true },
|
|
3264
|
-
{ input : 'password', key : 'smsSid', credential : 'TWILIO_ACCOUNT_SID', label : 'Twilio account SID', message : 'Twilio console home — the AC… identifier on the account dashboard.', redact : true, required : true },
|
|
3265
|
-
{ input : 'password', key : 'smsToken', credential : 'TWILIO_AUTH_TOKEN', label : 'Twilio auth token', message : 'Beside the account SID on the Twilio console dashboard.', redact : true, required : true }
|
|
3266
|
-
],
|
|
3267
|
-
icon : twilioIcon,
|
|
3268
|
-
name : 'Twilio'
|
|
3269
|
-
},
|
|
3270
|
-
// The CRM sync is best-effort internal tooling and no-ops without a
|
|
3271
|
-
// token. Not live here costs nothing a merchant can see.
|
|
3272
|
-
hubspot : {
|
|
3273
|
-
fields : [
|
|
3274
|
-
{ input : 'password', key : 'hubspotToken', credential : 'HUBSPOT_ACCESS_TOKEN', label : 'HubSpot access token', message : 'Drawbridge\'s own CRM portal. Internal — no merchant sees this.', redact : true, required : true }
|
|
3275
|
-
],
|
|
3276
|
-
icon : hubspotIcon,
|
|
3277
|
-
name : 'HubSpot'
|
|
3278
|
-
}
|
|
3279
|
-
}
|
|
3280
|
-
},
|
|
3281
3202
|
// NOTHING, and HUBSPOT_ACCESS_TOKEN in particular must not be here.
|
|
3282
3203
|
//
|
|
3283
3204
|
// `requires` gates AVAILABILITY: a name in it that is unset removes the whole
|
|
@@ -3488,6 +3409,16 @@ var drawbridge = {
|
|
|
3488
3409
|
|
|
3489
3410
|
},
|
|
3490
3411
|
tasks : () => [],
|
|
3412
|
+
// THE VENDORS THIS CONNECTION SPENDS, by slug. Each is declared once in
|
|
3413
|
+
// lib/connections/vendors/, and named here by whoever uses it — the block that
|
|
3414
|
+
// used to sit here declared them inline, so two manifests naming one vendor had
|
|
3415
|
+
// to be reconciled at import by mergeVendors().
|
|
3416
|
+
//
|
|
3417
|
+
// THREE, and they have nothing to do with each other: drawbridge is the
|
|
3418
|
+
// platform's own sender and spends SendGrid for email, Twilio for SMS and
|
|
3419
|
+
// HubSpot for CRM. They were bundled under one manifest only because one
|
|
3420
|
+
// connection happens to use all three.
|
|
3421
|
+
vendors : [ 'sendgrid', 'twilio', 'hubspot' ],
|
|
3491
3422
|
title : 'Drawbridge'
|
|
3492
3423
|
};
|
|
3493
3424
|
|
|
@@ -4461,24 +4392,6 @@ var klaviyo = {
|
|
|
4461
4392
|
|
|
4462
4393
|
},
|
|
4463
4394
|
icon: icon$2,
|
|
4464
|
-
// DRAWBRIDGE'S OWN CREDENTIALS for this vendor, as opposed to a merchant's —
|
|
4465
|
-
// what an admin types on the provider screen. Declared here rather than in a
|
|
4466
|
-
// table in lib/providers.js, so a vendor's credentials sit beside the
|
|
4467
|
-
// `requires` that names the same variables. Keyed by the VENDOR that holds
|
|
4468
|
-
// them — here the vendor and the connection are the same thing, which is not
|
|
4469
|
-
// true of every manifest.
|
|
4470
|
-
provider : {
|
|
4471
|
-
vendors : {
|
|
4472
|
-
klaviyo : {
|
|
4473
|
-
fields : [
|
|
4474
|
-
{ input : 'text', key : 'clientId', credential : 'KLAVIYO_OAUTH_CLIENT_ID', label : 'Client ID', message : 'From our app in the Klaviyo developer portal (developers.klaviyo.com).', required : true },
|
|
4475
|
-
{ input : 'password', key : 'clientSecret', credential : 'KLAVIYO_OAUTH_CLIENT_SECRET', label : 'Client secret', message : 'Beside the Client ID on the Klaviyo app.', redact : true, required : true }
|
|
4476
|
-
],
|
|
4477
|
-
icon: icon$2,
|
|
4478
|
-
name : 'Klaviyo'
|
|
4479
|
-
}
|
|
4480
|
-
}
|
|
4481
|
-
},
|
|
4482
4395
|
requires : [
|
|
4483
4396
|
'KLAVIYO_OAUTH_CLIENT_ID',
|
|
4484
4397
|
'KLAVIYO_OAUTH_CLIENT_SECRET'
|
|
@@ -4639,6 +4552,11 @@ var klaviyo = {
|
|
|
4639
4552
|
|
|
4640
4553
|
},
|
|
4641
4554
|
|
|
4555
|
+
// THE VENDORS THIS CONNECTION SPENDS, by slug. Each is declared once in
|
|
4556
|
+
// lib/connections/vendors/, and named here by whoever uses it — the block that
|
|
4557
|
+
// used to sit here declared them inline, so two manifests naming one vendor had
|
|
4558
|
+
// to be reconciled at import by mergeVendors().
|
|
4559
|
+
vendors : [ 'klaviyo' ],
|
|
4642
4560
|
title : 'Klaviyo',
|
|
4643
4561
|
|
|
4644
4562
|
// KLAVIYO PUBLISHES NO DASHBOARD URLS in its API reference. What is on record
|
|
@@ -5374,21 +5292,6 @@ var mailchimp = {
|
|
|
5374
5292
|
webhook : false
|
|
5375
5293
|
},
|
|
5376
5294
|
icon: icon$1,
|
|
5377
|
-
// DRAWBRIDGE'S OWN CREDENTIALS for this vendor, as opposed to a merchant's —
|
|
5378
|
-
// what an admin types on the provider screen, beside the `requires` naming the
|
|
5379
|
-
// same variables.
|
|
5380
|
-
provider : {
|
|
5381
|
-
vendors : {
|
|
5382
|
-
mailchimp : {
|
|
5383
|
-
fields : [
|
|
5384
|
-
{ input : 'text', key : 'clientId', credential : 'MAILCHIMP_OAUTH_CLIENT_ID', label : 'Client ID', message : 'From our registered app — Mailchimp account, Extras, Registered apps.', required : true },
|
|
5385
|
-
{ input : 'password', key : 'clientSecret', credential : 'MAILCHIMP_OAUTH_CLIENT_SECRET', label : 'Client secret', message : 'Beside the Client ID on the registered app.', redact : true, required : true }
|
|
5386
|
-
],
|
|
5387
|
-
icon: icon$1,
|
|
5388
|
-
name : 'Mailchimp'
|
|
5389
|
-
}
|
|
5390
|
-
}
|
|
5391
|
-
},
|
|
5392
5295
|
// The OAuth client this deployment registered. Without both, the vendor drops
|
|
5393
5296
|
// out of availableConnections rather than offering a Connect button that
|
|
5394
5297
|
// cannot complete.
|
|
@@ -5505,6 +5408,11 @@ var mailchimp = {
|
|
|
5505
5408
|
}
|
|
5506
5409
|
]
|
|
5507
5410
|
),
|
|
5411
|
+
// THE VENDORS THIS CONNECTION SPENDS, by slug. Each is declared once in
|
|
5412
|
+
// lib/connections/vendors/, and named here by whoever uses it — the block that
|
|
5413
|
+
// used to sit here declared them inline, so two manifests naming one vendor had
|
|
5414
|
+
// to be reconciled at import by mergeVendors().
|
|
5415
|
+
vendors : [ 'mailchimp' ],
|
|
5508
5416
|
title : 'Mailchimp',
|
|
5509
5417
|
// THE MERCHANT'S OWN ADMIN. Mailchimp's list schema states the shape outright:
|
|
5510
5418
|
// the web_id field is "The ID used in the Mailchimp web application. View this
|
|
@@ -7304,41 +7212,6 @@ var shopify = {
|
|
|
7304
7212
|
},
|
|
7305
7213
|
icon,
|
|
7306
7214
|
inbound,
|
|
7307
|
-
// DRAWBRIDGE'S OWN CREDENTIALS for this vendor, as opposed to a merchant's —
|
|
7308
|
-
// what an admin types on the provider screen. The four names below are exactly
|
|
7309
|
-
// what `requires` gates on, which is the point of declaring them together: a
|
|
7310
|
-
// name required by the manifest and enterable nowhere is a vendor that can
|
|
7311
|
-
// never go live from the admin screen.
|
|
7312
|
-
provider : {
|
|
7313
|
-
vendors : {
|
|
7314
|
-
shopify : {
|
|
7315
|
-
fields : [
|
|
7316
|
-
{ input : 'text', key : 'apiKey', credential : 'SHOPIFY_API_KEY', label : 'API key', message : 'The app\'s Client ID — Dev Dashboard, the app, Settings.', required : true },
|
|
7317
|
-
{ input : 'password', key : 'apiSecret', credential : 'SHOPIFY_API_SECRET', label : 'API secret', message : 'The app\'s Client secret, beside the Client ID in the app\'s settings.', redact : true, required : true },
|
|
7318
|
-
{ input : 'text', key : 'appHandle', credential : 'SHOPIFY_APP_HANDLE', label : 'App handle', message : 'The app\'s URL handle (for example drawbridge-development), from the app\'s configuration.', required : true },
|
|
7319
|
-
{ input : 'text', key : 'listingUrl', credential : 'SHOPIFY_APP_LISTING_URL', label : 'App listing URL', message : 'Where "View on the Shopify App Store" sends merchants — the public listing, or the Dev Dashboard install link for the dev app.', required : true },
|
|
7320
|
-
// The usage meter's event handle, when the plan config's meter ever
|
|
7321
|
-
// changes: stored value overrides the built-in default
|
|
7322
|
-
// (events.order.handle) at the mint point, and `format : 'slug'`
|
|
7323
|
-
// normalizes it on save — a handle can carry no spaces or capitals,
|
|
7324
|
-
// and classification against it is case-sensitive. Optional: empty
|
|
7325
|
-
// means the default, and the sender still refuses any handle that
|
|
7326
|
-
// disagrees with the transaction it minted.
|
|
7327
|
-
{ format : 'slug', input : 'text', key : 'orderEventHandle', label : 'Order event handle', message : 'Must match the usage meter\'s Handle field on the plan exactly — lowercase and hyphens. Leave empty to use drawbridge-orders.', required : false, setting : true },
|
|
7328
|
-
// The Partner API credential set — the ONE place meter billing is
|
|
7329
|
-
// observable (CHARGE_USAGE accrual events). Org id and numeric app
|
|
7330
|
-
// id come from the Partner Dashboard; the token from Settings →
|
|
7331
|
-
// Partner API clients (Manage-apps permission). All optional: the
|
|
7332
|
-
// accrual probe simply stays off until they exist.
|
|
7333
|
-
{ input : 'text', key : 'partnerOrgId', label : 'Partner organization ID', message : 'The number in the Partner Dashboard URL — partners.shopify.com/<this number>/… — NOT the admin organization_id from the app listing link.', required : false, setting : true },
|
|
7334
|
-
{ input : 'text', key : 'partnerAppId', label : 'Partner app ID (numeric)', message : 'The numeric id in the app\'s Partner Dashboard URL — not the Client ID.', required : false, setting : true },
|
|
7335
|
-
{ input : 'password', key : 'partnerToken', label : 'Partner API token', message : 'Partner Dashboard, Settings, Partner API clients — create one with Manage apps and paste the prtapi_ token.', redact : true, required : false, setting : true }
|
|
7336
|
-
],
|
|
7337
|
-
icon,
|
|
7338
|
-
name : 'Shopify'
|
|
7339
|
-
}
|
|
7340
|
-
}
|
|
7341
|
-
},
|
|
7342
7215
|
// A pre-launch integration: it only surfaces once the App Store listing
|
|
7343
7216
|
// exists and the app is fully configured. Requiring all four means it can
|
|
7344
7217
|
// never render half-configured — and absence of any one excludes the
|
|
@@ -7557,6 +7430,13 @@ var shopify = {
|
|
|
7557
7430
|
: []
|
|
7558
7431
|
)
|
|
7559
7432
|
],
|
|
7433
|
+
// THE VENDORS THIS CONNECTION SPENDS, by slug. Declared once in
|
|
7434
|
+
// lib/connections/vendors/shopify.js, and named here by whoever uses it.
|
|
7435
|
+
//
|
|
7436
|
+
// SHOPIFY_API_SECRET is spent by drawbridge-shopify-app and drawbridge-webhooks
|
|
7437
|
+
// too, which is the clearest case for why a vendor is not owned by whichever
|
|
7438
|
+
// connection happened to declare it first.
|
|
7439
|
+
vendors : [ 'shopify' ],
|
|
7560
7440
|
title : 'Shopify',
|
|
7561
7441
|
// THE VENDOR'S OWN ADMIN, one function per thing worth linking to. It lives
|
|
7562
7442
|
// here rather than at the top level so a second link (a product, an order)
|
|
@@ -7763,7 +7643,7 @@ var webhook = {
|
|
|
7763
7643
|
// Borrowed: this is the Drawbridge mark, because Webhooks has none of its own.
|
|
7764
7644
|
// It is the one card that reads wrong — our logo among vendor logos — and it
|
|
7765
7645
|
// wants a mark of its own when there is one.
|
|
7766
|
-
icon: icon$
|
|
7646
|
+
icon: icon$6,
|
|
7767
7647
|
// Gated on the encryption secret: without it the signing secret could not be
|
|
7768
7648
|
// stored safely, so the connection must not be offered at all.
|
|
7769
7649
|
requires : [ 'ENCRYPT_CONNECTION_SECRET' ],
|
|
@@ -7829,9 +7709,481 @@ var webhook = {
|
|
|
7829
7709
|
}
|
|
7830
7710
|
]
|
|
7831
7711
|
),
|
|
7712
|
+
// THE VENDORS THIS CONNECTION SPENDS, by slug. Each is declared once in
|
|
7713
|
+
// lib/connections/vendors/, and named here by whoever uses it — the block that
|
|
7714
|
+
// used to sit here declared them inline, so two manifests naming one vendor had
|
|
7715
|
+
// to be reconciled at import by mergeVendors().
|
|
7716
|
+
//
|
|
7717
|
+
// Empty: webhook has no third party behind it — nothing to authenticate
|
|
7718
|
+
// against and nothing for an admin to type.
|
|
7719
|
+
vendors : [],
|
|
7832
7720
|
title : 'Webhooks'
|
|
7833
7721
|
};
|
|
7834
7722
|
|
|
7723
|
+
// DRAWBRIDGE'S OWN CREDENTIALS FOR ATTENTIVE, and where the facts about it came
|
|
7724
|
+
// from. One file per vendor, because a vendor is NOT a connection: it is the row
|
|
7725
|
+
// in the `provider` collection holding our keys for it, and a connection names
|
|
7726
|
+
// the ones it spends.
|
|
7727
|
+
//
|
|
7728
|
+
// This lived inside attentive.js until 2026-09-13, for a reason that no longer
|
|
7729
|
+
// holds — "so a vendor's credentials sit beside the `requires` that names the same
|
|
7730
|
+
// variables". `requires` derives from the `credential` keys below now, so the
|
|
7731
|
+
// proximity bought nothing, and the nesting cost mergeVendors(): 66 lines and four
|
|
7732
|
+
// throw-guards whose only job was reconciling two manifests that described one
|
|
7733
|
+
// vendor differently. Declared once, none of that can happen.
|
|
7734
|
+
var attentiveVendor = {
|
|
7735
|
+
|
|
7736
|
+
// WHAT AN ADMIN TYPES on the provider screen. `credential` names the env var a
|
|
7737
|
+
// field falls back to, and is the only place that name is written now — it used
|
|
7738
|
+
// to appear three times per manifest.
|
|
7739
|
+
fields : [
|
|
7740
|
+
{
|
|
7741
|
+
credential : 'ATTENTIVE_OAUTH_CLIENT_ID',
|
|
7742
|
+
input : 'text',
|
|
7743
|
+
key : 'clientId',
|
|
7744
|
+
label : 'Client ID',
|
|
7745
|
+
message : 'From our app\'s registration in the Attentive developer portal.',
|
|
7746
|
+
required : true
|
|
7747
|
+
},
|
|
7748
|
+
{
|
|
7749
|
+
credential : 'ATTENTIVE_OAUTH_CLIENT_SECRET',
|
|
7750
|
+
input : 'password',
|
|
7751
|
+
key : 'clientSecret',
|
|
7752
|
+
label : 'Client secret',
|
|
7753
|
+
message : 'Beside the Client ID in the Attentive developer portal.',
|
|
7754
|
+
redact : true,
|
|
7755
|
+
required : true
|
|
7756
|
+
}
|
|
7757
|
+
],
|
|
7758
|
+
|
|
7759
|
+
// The same mark the connection carries. One vendor, one icon — mergeVendors
|
|
7760
|
+
// used to throw when two manifests disagreed about this.
|
|
7761
|
+
icon: icon$7,
|
|
7762
|
+
|
|
7763
|
+
name : 'Attentive',
|
|
7764
|
+
|
|
7765
|
+
slug : 'attentive',
|
|
7766
|
+
|
|
7767
|
+
// WHERE THE FACTS CAME FROM. Was review.api / .dashboard / .scopes on the
|
|
7768
|
+
// manifest. They are per-vendor documentation, which is exactly why drawbridge
|
|
7769
|
+
// answered two of them with an object keyed by vendor while the other four
|
|
7770
|
+
// answered with a string — two incompatible shapes for one key, and the shape
|
|
7771
|
+
// was saying where the data belonged.
|
|
7772
|
+
urls : {
|
|
7773
|
+
api : 'https://docs.attentive.com/reference/listsegments',
|
|
7774
|
+
dashboard : 'https://docs.attentive.com/docs/segments',
|
|
7775
|
+
scopes : 'https://docs.attentive.com/docs/authentication'
|
|
7776
|
+
}
|
|
7777
|
+
|
|
7778
|
+
};
|
|
7779
|
+
|
|
7780
|
+
// DRAWBRIDGE'S OWN CREDENTIALS FOR HUBSPOT, and where the facts about it came
|
|
7781
|
+
// from. One file per vendor, because a vendor is NOT a connection: it is the row
|
|
7782
|
+
// in the `provider` collection holding our keys for it, and a connection names
|
|
7783
|
+
// the ones it spends.
|
|
7784
|
+
//
|
|
7785
|
+
// This lived inside drawbridge.js until 2026-09-13, for a reason that no longer
|
|
7786
|
+
// holds — "so a vendor's credentials sit beside the `requires` that names the same
|
|
7787
|
+
// variables". `requires` derives from the `credential` keys below now, so the
|
|
7788
|
+
// proximity bought nothing, and the nesting cost mergeVendors(): 66 lines and four
|
|
7789
|
+
// throw-guards whose only job was reconciling two manifests that described one
|
|
7790
|
+
// vendor differently. Declared once, none of that can happen.
|
|
7791
|
+
var hubspotVendor = {
|
|
7792
|
+
|
|
7793
|
+
// WHAT AN ADMIN TYPES on the provider screen. `credential` names the env var a
|
|
7794
|
+
// field falls back to, and is the only place that name is written now — it used
|
|
7795
|
+
// to appear three times per manifest.
|
|
7796
|
+
fields : [
|
|
7797
|
+
{
|
|
7798
|
+
credential : 'HUBSPOT_ACCESS_TOKEN',
|
|
7799
|
+
input : 'password',
|
|
7800
|
+
key : 'hubspotToken',
|
|
7801
|
+
label : 'HubSpot access token',
|
|
7802
|
+
message : 'Drawbridge\'s own CRM portal. Internal — no merchant sees this.',
|
|
7803
|
+
redact : true,
|
|
7804
|
+
required : true
|
|
7805
|
+
}
|
|
7806
|
+
],
|
|
7807
|
+
|
|
7808
|
+
// The vendor's own mark rather than the connection's: drawbridge fronts three
|
|
7809
|
+
// vendors and none of them is Drawbridge.
|
|
7810
|
+
icon: icon$5,
|
|
7811
|
+
|
|
7812
|
+
name : 'HubSpot',
|
|
7813
|
+
|
|
7814
|
+
slug : 'hubspot',
|
|
7815
|
+
|
|
7816
|
+
// WHERE THE FACTS CAME FROM. Was review.api / .dashboard / .scopes on the
|
|
7817
|
+
// manifest. They are per-vendor documentation, which is exactly why drawbridge
|
|
7818
|
+
// answered two of them with an object keyed by vendor while the other four
|
|
7819
|
+
// answered with a string — two incompatible shapes for one key, and the shape
|
|
7820
|
+
// was saying where the data belonged.
|
|
7821
|
+
urls : {
|
|
7822
|
+
api : 'https://developers.hubspot.com/docs/reference/api/crm/objects/contacts',
|
|
7823
|
+
dashboard : 'https://knowledge.hubspot.com/contacts/create-contacts',
|
|
7824
|
+
scopes : false
|
|
7825
|
+
}
|
|
7826
|
+
|
|
7827
|
+
};
|
|
7828
|
+
|
|
7829
|
+
// DRAWBRIDGE'S OWN CREDENTIALS FOR KLAVIYO, and where the facts about it came
|
|
7830
|
+
// from. One file per vendor, because a vendor is NOT a connection: it is the row
|
|
7831
|
+
// in the `provider` collection holding our keys for it, and a connection names
|
|
7832
|
+
// the ones it spends.
|
|
7833
|
+
//
|
|
7834
|
+
// This lived inside klaviyo.js until 2026-09-13, for a reason that no longer
|
|
7835
|
+
// holds — "so a vendor's credentials sit beside the `requires` that names the same
|
|
7836
|
+
// variables". `requires` derives from the `credential` keys below now, so the
|
|
7837
|
+
// proximity bought nothing, and the nesting cost mergeVendors(): 66 lines and four
|
|
7838
|
+
// throw-guards whose only job was reconciling two manifests that described one
|
|
7839
|
+
// vendor differently. Declared once, none of that can happen.
|
|
7840
|
+
var klaviyoVendor = {
|
|
7841
|
+
|
|
7842
|
+
// WHAT AN ADMIN TYPES on the provider screen. `credential` names the env var a
|
|
7843
|
+
// field falls back to, and is the only place that name is written now — it used
|
|
7844
|
+
// to appear three times per manifest.
|
|
7845
|
+
fields : [
|
|
7846
|
+
{
|
|
7847
|
+
credential : 'KLAVIYO_OAUTH_CLIENT_ID',
|
|
7848
|
+
input : 'text',
|
|
7849
|
+
key : 'clientId',
|
|
7850
|
+
label : 'Client ID',
|
|
7851
|
+
message : 'From our app in the Klaviyo developer portal (developers.klaviyo.com).',
|
|
7852
|
+
required : true
|
|
7853
|
+
},
|
|
7854
|
+
{
|
|
7855
|
+
credential : 'KLAVIYO_OAUTH_CLIENT_SECRET',
|
|
7856
|
+
input : 'password',
|
|
7857
|
+
key : 'clientSecret',
|
|
7858
|
+
label : 'Client secret',
|
|
7859
|
+
message : 'Beside the Client ID on the Klaviyo app.',
|
|
7860
|
+
redact : true,
|
|
7861
|
+
required : true
|
|
7862
|
+
}
|
|
7863
|
+
],
|
|
7864
|
+
|
|
7865
|
+
// The same mark the connection carries. One vendor, one icon — mergeVendors
|
|
7866
|
+
// used to throw when two manifests disagreed about this.
|
|
7867
|
+
icon: icon$2,
|
|
7868
|
+
|
|
7869
|
+
name : 'Klaviyo',
|
|
7870
|
+
|
|
7871
|
+
slug : 'klaviyo',
|
|
7872
|
+
|
|
7873
|
+
// WHERE THE FACTS CAME FROM. Was review.api / .dashboard / .scopes on the
|
|
7874
|
+
// manifest. They are per-vendor documentation, which is exactly why drawbridge
|
|
7875
|
+
// answered two of them with an object keyed by vendor while the other four
|
|
7876
|
+
// answered with a string — two incompatible shapes for one key, and the shape
|
|
7877
|
+
// was saying where the data belonged.
|
|
7878
|
+
urls : {
|
|
7879
|
+
api : 'https://developers.klaviyo.com/en/reference/api_overview',
|
|
7880
|
+
dashboard : 'https://help.klaviyo.com/hc/en-us/articles/115005078647',
|
|
7881
|
+
scopes : 'https://developers.klaviyo.com/en/docs/authenticate_'
|
|
7882
|
+
}
|
|
7883
|
+
|
|
7884
|
+
};
|
|
7885
|
+
|
|
7886
|
+
// DRAWBRIDGE'S OWN CREDENTIALS FOR MAILCHIMP, and where the facts about it came
|
|
7887
|
+
// from. One file per vendor, because a vendor is NOT a connection: it is the row
|
|
7888
|
+
// in the `provider` collection holding our keys for it, and a connection names
|
|
7889
|
+
// the ones it spends.
|
|
7890
|
+
//
|
|
7891
|
+
// This lived inside mailchimp.js until 2026-09-13, for a reason that no longer
|
|
7892
|
+
// holds — "so a vendor's credentials sit beside the `requires` that names the same
|
|
7893
|
+
// variables". `requires` derives from the `credential` keys below now, so the
|
|
7894
|
+
// proximity bought nothing, and the nesting cost mergeVendors(): 66 lines and four
|
|
7895
|
+
// throw-guards whose only job was reconciling two manifests that described one
|
|
7896
|
+
// vendor differently. Declared once, none of that can happen.
|
|
7897
|
+
var mailchimpVendor = {
|
|
7898
|
+
|
|
7899
|
+
// WHAT AN ADMIN TYPES on the provider screen. `credential` names the env var a
|
|
7900
|
+
// field falls back to, and is the only place that name is written now — it used
|
|
7901
|
+
// to appear three times per manifest.
|
|
7902
|
+
fields : [
|
|
7903
|
+
{
|
|
7904
|
+
credential : 'MAILCHIMP_OAUTH_CLIENT_ID',
|
|
7905
|
+
input : 'text',
|
|
7906
|
+
key : 'clientId',
|
|
7907
|
+
label : 'Client ID',
|
|
7908
|
+
message : 'From our registered app — Mailchimp account, Extras, Registered apps.',
|
|
7909
|
+
required : true
|
|
7910
|
+
},
|
|
7911
|
+
{
|
|
7912
|
+
credential : 'MAILCHIMP_OAUTH_CLIENT_SECRET',
|
|
7913
|
+
input : 'password',
|
|
7914
|
+
key : 'clientSecret',
|
|
7915
|
+
label : 'Client secret',
|
|
7916
|
+
message : 'Beside the Client ID on the registered app.',
|
|
7917
|
+
redact : true,
|
|
7918
|
+
required : true
|
|
7919
|
+
}
|
|
7920
|
+
],
|
|
7921
|
+
|
|
7922
|
+
// The same mark the connection carries. One vendor, one icon — mergeVendors
|
|
7923
|
+
// used to throw when two manifests disagreed about this.
|
|
7924
|
+
icon: icon$1,
|
|
7925
|
+
|
|
7926
|
+
name : 'Mailchimp',
|
|
7927
|
+
|
|
7928
|
+
slug : 'mailchimp',
|
|
7929
|
+
|
|
7930
|
+
// WHERE THE FACTS CAME FROM. Was review.api / .dashboard / .scopes on the
|
|
7931
|
+
// manifest. They are per-vendor documentation, which is exactly why drawbridge
|
|
7932
|
+
// answered two of them with an object keyed by vendor while the other four
|
|
7933
|
+
// answered with a string — two incompatible shapes for one key, and the shape
|
|
7934
|
+
// was saying where the data belonged.
|
|
7935
|
+
urls : {
|
|
7936
|
+
api : 'https://mailchimp.com/developer/marketing/guides/access-user-data-oauth-2/',
|
|
7937
|
+
dashboard : 'https://mailchimp.com/help/manage-tags/',
|
|
7938
|
+
scopes : false
|
|
7939
|
+
}
|
|
7940
|
+
|
|
7941
|
+
};
|
|
7942
|
+
|
|
7943
|
+
// DRAWBRIDGE'S OWN CREDENTIALS FOR SENDGRID, and where the facts about it came
|
|
7944
|
+
// from. One file per vendor, because a vendor is NOT a connection: it is the row
|
|
7945
|
+
// in the `provider` collection holding our keys for it, and a connection names
|
|
7946
|
+
// the ones it spends.
|
|
7947
|
+
//
|
|
7948
|
+
// This lived inside drawbridge.js until 2026-09-13, for a reason that no longer
|
|
7949
|
+
// holds — "so a vendor's credentials sit beside the `requires` that names the same
|
|
7950
|
+
// variables". `requires` derives from the `credential` keys below now, so the
|
|
7951
|
+
// proximity bought nothing, and the nesting cost mergeVendors(): 66 lines and four
|
|
7952
|
+
// throw-guards whose only job was reconciling two manifests that described one
|
|
7953
|
+
// vendor differently. Declared once, none of that can happen.
|
|
7954
|
+
var sendgridVendor = {
|
|
7955
|
+
|
|
7956
|
+
// WHAT AN ADMIN TYPES on the provider screen. `credential` names the env var a
|
|
7957
|
+
// field falls back to, and is the only place that name is written now — it used
|
|
7958
|
+
// to appear three times per manifest.
|
|
7959
|
+
fields : [
|
|
7960
|
+
{
|
|
7961
|
+
credential : 'SENDGRID_FROM_ADDRESS',
|
|
7962
|
+
input : 'email',
|
|
7963
|
+
key : 'accountSender',
|
|
7964
|
+
label : 'Account sender',
|
|
7965
|
+
message : 'Verification codes and security alerts send from here.',
|
|
7966
|
+
required : true
|
|
7967
|
+
},
|
|
7968
|
+
{
|
|
7969
|
+
credential : 'SENDGRID_API_KEY',
|
|
7970
|
+
input : 'password',
|
|
7971
|
+
key : 'apiKey',
|
|
7972
|
+
label : 'SendGrid API key',
|
|
7973
|
+
message : 'SendGrid dashboard, Settings, API Keys — full access for sends.',
|
|
7974
|
+
redact : true,
|
|
7975
|
+
required : true
|
|
7976
|
+
},
|
|
7977
|
+
{
|
|
7978
|
+
credential : 'SENDGRID_EVENT_WEBHOOK_KEY',
|
|
7979
|
+
input : 'text',
|
|
7980
|
+
key : 'eventKey',
|
|
7981
|
+
label : 'Event webhook key',
|
|
7982
|
+
message : 'SendGrid, Settings, Mail Settings, Event Webhook — the verification key shown once signature verification is enabled. Public, not a secret.'
|
|
7983
|
+
},
|
|
7984
|
+
{
|
|
7985
|
+
credential : 'SENDGRID_SEND_FROM_ADDRESS',
|
|
7986
|
+
input : 'email',
|
|
7987
|
+
key : 'leadSender',
|
|
7988
|
+
label : 'Lead sender',
|
|
7989
|
+
message : 'The default for lead-facing mail when a merchant has not verified their own domain.'
|
|
7990
|
+
}
|
|
7991
|
+
],
|
|
7992
|
+
|
|
7993
|
+
// The vendor's own mark rather than the connection's: drawbridge fronts three
|
|
7994
|
+
// vendors and none of them is Drawbridge.
|
|
7995
|
+
icon: icon$4,
|
|
7996
|
+
|
|
7997
|
+
name : 'SendGrid',
|
|
7998
|
+
|
|
7999
|
+
slug : 'sendgrid',
|
|
8000
|
+
|
|
8001
|
+
// WHERE THE FACTS CAME FROM. Was review.api / .dashboard / .scopes on the
|
|
8002
|
+
// manifest. They are per-vendor documentation, which is exactly why drawbridge
|
|
8003
|
+
// answered two of them with an object keyed by vendor while the other four
|
|
8004
|
+
// answered with a string — two incompatible shapes for one key, and the shape
|
|
8005
|
+
// was saying where the data belonged.
|
|
8006
|
+
urls : {
|
|
8007
|
+
api : 'https://www.twilio.com/docs/sendgrid/api-reference/mail-send/mail-send',
|
|
8008
|
+
dashboard : 'https://www.twilio.com/docs/sendgrid/ui/analytics-and-reporting/email-activity-feed',
|
|
8009
|
+
scopes : false
|
|
8010
|
+
}
|
|
8011
|
+
|
|
8012
|
+
};
|
|
8013
|
+
|
|
8014
|
+
// DRAWBRIDGE'S OWN CREDENTIALS FOR SHOPIFY, and where the facts about it came
|
|
8015
|
+
// from. One file per vendor, because a vendor is NOT a connection: it is the row
|
|
8016
|
+
// in the `provider` collection holding our keys for it, and a connection names
|
|
8017
|
+
// the ones it spends.
|
|
8018
|
+
//
|
|
8019
|
+
// This lived inside shopify.js until 2026-09-13, for a reason that no longer
|
|
8020
|
+
// holds — "so a vendor's credentials sit beside the `requires` that names the same
|
|
8021
|
+
// variables". `requires` derives from the `credential` keys below now, so the
|
|
8022
|
+
// proximity bought nothing, and the nesting cost mergeVendors(): 66 lines and four
|
|
8023
|
+
// throw-guards whose only job was reconciling two manifests that described one
|
|
8024
|
+
// vendor differently. Declared once, none of that can happen.
|
|
8025
|
+
var shopifyVendor = {
|
|
8026
|
+
|
|
8027
|
+
// WHAT AN ADMIN TYPES on the provider screen. `credential` names the env var a
|
|
8028
|
+
// field falls back to, and is the only place that name is written now — it used
|
|
8029
|
+
// to appear three times per manifest.
|
|
8030
|
+
fields : [
|
|
8031
|
+
{
|
|
8032
|
+
credential : 'SHOPIFY_API_KEY',
|
|
8033
|
+
input : 'text',
|
|
8034
|
+
key : 'apiKey',
|
|
8035
|
+
label : 'API key',
|
|
8036
|
+
message : 'The app\'s Client ID — Dev Dashboard, the app, Settings.',
|
|
8037
|
+
required : true
|
|
8038
|
+
},
|
|
8039
|
+
{
|
|
8040
|
+
credential : 'SHOPIFY_API_SECRET',
|
|
8041
|
+
input : 'password',
|
|
8042
|
+
key : 'apiSecret',
|
|
8043
|
+
label : 'API secret',
|
|
8044
|
+
message : 'The app\'s Client secret, beside the Client ID in the app\'s settings.',
|
|
8045
|
+
redact : true,
|
|
8046
|
+
required : true
|
|
8047
|
+
},
|
|
8048
|
+
{
|
|
8049
|
+
credential : 'SHOPIFY_APP_HANDLE',
|
|
8050
|
+
input : 'text',
|
|
8051
|
+
key : 'appHandle',
|
|
8052
|
+
label : 'App handle',
|
|
8053
|
+
message : 'The app\'s URL handle (for example drawbridge-development), from the app\'s configuration.',
|
|
8054
|
+
required : true
|
|
8055
|
+
},
|
|
8056
|
+
{
|
|
8057
|
+
credential : 'SHOPIFY_APP_LISTING_URL',
|
|
8058
|
+
input : 'text',
|
|
8059
|
+
key : 'listingUrl',
|
|
8060
|
+
label : 'App listing URL',
|
|
8061
|
+
message : 'Where "View on the Shopify App Store" sends merchants — the public listing, or the Dev Dashboard install link for the dev app.',
|
|
8062
|
+
required : true
|
|
8063
|
+
},
|
|
8064
|
+
{
|
|
8065
|
+
format : 'slug',
|
|
8066
|
+
input : 'text',
|
|
8067
|
+
key : 'orderEventHandle',
|
|
8068
|
+
label : 'Order event handle',
|
|
8069
|
+
message : 'Must match the usage meter\'s Handle field on the plan exactly — lowercase and hyphens. Leave empty to use drawbridge-orders.',
|
|
8070
|
+
required : false,
|
|
8071
|
+
setting : true
|
|
8072
|
+
},
|
|
8073
|
+
{
|
|
8074
|
+
input : 'text',
|
|
8075
|
+
key : 'partnerOrgId',
|
|
8076
|
+
label : 'Partner organization ID',
|
|
8077
|
+
message : 'The number in the Partner Dashboard URL — partners.shopify.com/<this number>/… — NOT the admin organization_id from the app listing link.',
|
|
8078
|
+
required : false,
|
|
8079
|
+
setting : true
|
|
8080
|
+
},
|
|
8081
|
+
{
|
|
8082
|
+
input : 'text',
|
|
8083
|
+
key : 'partnerAppId',
|
|
8084
|
+
label : 'Partner app ID (numeric)',
|
|
8085
|
+
message : 'The numeric id in the app\'s Partner Dashboard URL — not the Client ID.',
|
|
8086
|
+
required : false,
|
|
8087
|
+
setting : true
|
|
8088
|
+
},
|
|
8089
|
+
{
|
|
8090
|
+
input : 'password',
|
|
8091
|
+
key : 'partnerToken',
|
|
8092
|
+
label : 'Partner API token',
|
|
8093
|
+
message : 'Partner Dashboard, Settings, Partner API clients — create one with Manage apps and paste the prtapi_ token.',
|
|
8094
|
+
redact : true,
|
|
8095
|
+
required : false,
|
|
8096
|
+
setting : true
|
|
8097
|
+
}
|
|
8098
|
+
],
|
|
8099
|
+
|
|
8100
|
+
// The same mark the connection carries. One vendor, one icon — mergeVendors
|
|
8101
|
+
// used to throw when two manifests disagreed about this.
|
|
8102
|
+
icon,
|
|
8103
|
+
|
|
8104
|
+
name : 'Shopify',
|
|
8105
|
+
|
|
8106
|
+
slug : 'shopify',
|
|
8107
|
+
|
|
8108
|
+
// WHERE THE FACTS CAME FROM. Was review.api / .dashboard / .scopes on the
|
|
8109
|
+
// manifest. They are per-vendor documentation, which is exactly why drawbridge
|
|
8110
|
+
// answered two of them with an object keyed by vendor while the other four
|
|
8111
|
+
// answered with a string — two incompatible shapes for one key, and the shape
|
|
8112
|
+
// was saying where the data belonged.
|
|
8113
|
+
urls : {
|
|
8114
|
+
api : 'https://shopify.dev/docs/api/admin-graphql',
|
|
8115
|
+
dashboard : 'https://help.shopify.com/en/manual/apps',
|
|
8116
|
+
scopes : 'https://shopify.dev/docs/api/usage/access-scopes'
|
|
8117
|
+
}
|
|
8118
|
+
|
|
8119
|
+
};
|
|
8120
|
+
|
|
8121
|
+
// DRAWBRIDGE'S OWN CREDENTIALS FOR TWILIO, and where the facts about it came
|
|
8122
|
+
// from. One file per vendor, because a vendor is NOT a connection: it is the row
|
|
8123
|
+
// in the `provider` collection holding our keys for it, and a connection names
|
|
8124
|
+
// the ones it spends.
|
|
8125
|
+
//
|
|
8126
|
+
// This lived inside drawbridge.js until 2026-09-13, for a reason that no longer
|
|
8127
|
+
// holds — "so a vendor's credentials sit beside the `requires` that names the same
|
|
8128
|
+
// variables". `requires` derives from the `credential` keys below now, so the
|
|
8129
|
+
// proximity bought nothing, and the nesting cost mergeVendors(): 66 lines and four
|
|
8130
|
+
// throw-guards whose only job was reconciling two manifests that described one
|
|
8131
|
+
// vendor differently. Declared once, none of that can happen.
|
|
8132
|
+
var twilioVendor = {
|
|
8133
|
+
|
|
8134
|
+
// WHAT AN ADMIN TYPES on the provider screen. `credential` names the env var a
|
|
8135
|
+
// field falls back to, and is the only place that name is written now — it used
|
|
8136
|
+
// to appear three times per manifest.
|
|
8137
|
+
fields : [
|
|
8138
|
+
{
|
|
8139
|
+
credential : 'TWILIO_ACCOUNT_FROM',
|
|
8140
|
+
input : 'text',
|
|
8141
|
+
key : 'smsFrom',
|
|
8142
|
+
label : 'SMS number',
|
|
8143
|
+
message : 'Without Twilio credentials, SMS is disabled across the platform.',
|
|
8144
|
+
required : true
|
|
8145
|
+
},
|
|
8146
|
+
{
|
|
8147
|
+
credential : 'TWILIO_ACCOUNT_SID',
|
|
8148
|
+
input : 'password',
|
|
8149
|
+
key : 'smsSid',
|
|
8150
|
+
label : 'Twilio account SID',
|
|
8151
|
+
message : 'Twilio console home — the AC… identifier on the account dashboard.',
|
|
8152
|
+
redact : true,
|
|
8153
|
+
required : true
|
|
8154
|
+
},
|
|
8155
|
+
{
|
|
8156
|
+
credential : 'TWILIO_AUTH_TOKEN',
|
|
8157
|
+
input : 'password',
|
|
8158
|
+
key : 'smsToken',
|
|
8159
|
+
label : 'Twilio auth token',
|
|
8160
|
+
message : 'Beside the account SID on the Twilio console dashboard.',
|
|
8161
|
+
redact : true,
|
|
8162
|
+
required : true
|
|
8163
|
+
}
|
|
8164
|
+
],
|
|
8165
|
+
|
|
8166
|
+
// The vendor's own mark rather than the connection's: drawbridge fronts three
|
|
8167
|
+
// vendors and none of them is Drawbridge.
|
|
8168
|
+
icon: icon$3,
|
|
8169
|
+
|
|
8170
|
+
name : 'Twilio',
|
|
8171
|
+
|
|
8172
|
+
slug : 'twilio',
|
|
8173
|
+
|
|
8174
|
+
// WHERE THE FACTS CAME FROM. Was review.api / .dashboard / .scopes on the
|
|
8175
|
+
// manifest. They are per-vendor documentation, which is exactly why drawbridge
|
|
8176
|
+
// answered two of them with an object keyed by vendor while the other four
|
|
8177
|
+
// answered with a string — two incompatible shapes for one key, and the shape
|
|
8178
|
+
// was saying where the data belonged.
|
|
8179
|
+
urls : {
|
|
8180
|
+
api : 'https://www.twilio.com/docs/messaging/api/message-resource',
|
|
8181
|
+
dashboard : 'https://www.twilio.com/docs/messaging/guides/debugging-tools',
|
|
8182
|
+
scopes : false
|
|
8183
|
+
}
|
|
8184
|
+
|
|
8185
|
+
};
|
|
8186
|
+
|
|
7835
8187
|
// Every connection, one file each, and this is the whole registry.
|
|
7836
8188
|
//
|
|
7837
8189
|
// It lives in utils rather than in the api because BOTH sides need it and they
|
|
@@ -7909,6 +8261,81 @@ const checkIcon = ( owner, icon ) => {
|
|
|
7909
8261
|
|
|
7910
8262
|
};
|
|
7911
8263
|
|
|
8264
|
+
// KEYED BY SLUG, from the files themselves. This was mergeVendors( connections ) —
|
|
8265
|
+
// 66 lines walking every manifest's provider.vendors and reconciling them, with
|
|
8266
|
+
// four throw-guards for two manifests naming one vendor differently, differing on
|
|
8267
|
+
// its icon, declaring one of its fields two ways, or claiming the same credential.
|
|
8268
|
+
// None of those can happen when a vendor is declared once, so all of it is gone.
|
|
8269
|
+
const vendors = Object.freeze( Object.fromEntries(
|
|
8270
|
+
[ attentiveVendor, hubspotVendor, klaviyoVendor, mailchimpVendor, sendgridVendor, shopifyVendor, twilioVendor ]
|
|
8271
|
+
.map( ( vendor ) => [ vendor.slug, vendor ] )
|
|
8272
|
+
) );
|
|
8273
|
+
|
|
8274
|
+
// WHAT A VENDOR MUST DECLARE. Thrown at import, the same way build() refuses a
|
|
8275
|
+
// manifest — exported so the refusal itself is testable rather than only
|
|
8276
|
+
// observable by breaking a real vendor file.
|
|
8277
|
+
//
|
|
8278
|
+
// This ran inside build() over each manifest's provider.vendors until 2026-09-13,
|
|
8279
|
+
// which meant a vendor declared by two manifests was validated twice and could
|
|
8280
|
+
// disagree with itself between them. Declared once, checked once.
|
|
8281
|
+
//
|
|
8282
|
+
// A field is checked harder than a merchant field: it must be editable — an admin
|
|
8283
|
+
// cannot type into a read-only descriptor, and a credential nobody can enter is a
|
|
8284
|
+
// vendor that can never go live — and a `password` MUST be redacted. That last one
|
|
8285
|
+
// is a SECURITY BOUNDARY rather than tidiness: providerFields is what the api's
|
|
8286
|
+
// redaction derives from, so a password field that forgot `redact : true` is a
|
|
8287
|
+
// platform secret handed back over the wire to every admin screen that asks.
|
|
8288
|
+
const buildVendor = ( vendor ) => {
|
|
8289
|
+
|
|
8290
|
+
if( ! vendor?.slug ) throw new Error( 'A vendor needs a slug' );
|
|
8291
|
+
|
|
8292
|
+
if( ! vendor.name ) throw new Error( 'vendor ' + vendor.slug + ' has no name' );
|
|
8293
|
+
|
|
8294
|
+
// The admin card shows the vendor's own mark, which is not always the
|
|
8295
|
+
// connection's — SendGrid's card is not the Drawbridge logo.
|
|
8296
|
+
checkIcon( 'vendor ' + vendor.slug, vendor.icon );
|
|
8297
|
+
|
|
8298
|
+
if( ! Array.isArray( vendor.fields ) || ! vendor.fields.length ){
|
|
8299
|
+
|
|
8300
|
+
throw new Error( 'vendor ' + vendor.slug + ' has no fields — a vendor nothing is typed into holds nothing' );
|
|
8301
|
+
|
|
8302
|
+
}
|
|
8303
|
+
|
|
8304
|
+
for( const field of vendor.fields ){
|
|
8305
|
+
|
|
8306
|
+
if( ! field?.key || ! field?.label ){
|
|
8307
|
+
|
|
8308
|
+
throw new Error( 'vendor ' + vendor.slug + ' declares a field with no key or label' );
|
|
8309
|
+
|
|
8310
|
+
}
|
|
8311
|
+
|
|
8312
|
+
if( ! INPUTS.includes( field.input ) ){
|
|
8313
|
+
|
|
8314
|
+
throw new Error( vendor.slug + '.' + field.key + ' needs an input the admin form can render — one of ' + INPUTS.join( ', ' ) );
|
|
8315
|
+
|
|
8316
|
+
}
|
|
8317
|
+
|
|
8318
|
+
if( field.input === 'password' && ! field.redact ){
|
|
8319
|
+
|
|
8320
|
+
throw new Error( vendor.slug + '.' + field.key + ' is a password and must declare redact : true — the api would hand the value back' );
|
|
8321
|
+
|
|
8322
|
+
}
|
|
8323
|
+
|
|
8324
|
+
}
|
|
8325
|
+
|
|
8326
|
+
return Object.freeze( vendor );
|
|
8327
|
+
|
|
8328
|
+
};
|
|
8329
|
+
|
|
8330
|
+
for( const [ slug, vendor ] of Object.entries( vendors ) ){
|
|
8331
|
+
|
|
8332
|
+
if( vendor.slug !== slug ) throw new Error( 'vendor file ' + slug + ' declares slug ' + vendor.slug );
|
|
8333
|
+
|
|
8334
|
+
buildVendor( vendor );
|
|
8335
|
+
|
|
8336
|
+
}
|
|
8337
|
+
|
|
8338
|
+
|
|
7912
8339
|
// WHAT A CONNECTION MUST DECLARE. Thrown at import rather than discovered by a
|
|
7913
8340
|
// merchant looking at a broken card, or by a workflow that accepted a step it
|
|
7914
8341
|
// could never run.
|
|
@@ -8008,75 +8435,44 @@ const build = ( manifest ) => {
|
|
|
8008
8435
|
|
|
8009
8436
|
}
|
|
8010
8437
|
|
|
8011
|
-
//
|
|
8012
|
-
//
|
|
8013
|
-
//
|
|
8014
|
-
|
|
8015
|
-
|
|
8016
|
-
//
|
|
8017
|
-
// manifest declares the fields IT spends, subkeyed by vendor, and mergeVendors
|
|
8018
|
-
// below unions every manifest's declarations into one vendor each. Nobody
|
|
8019
|
-
// owns a vendor — removing a manifest removes its fields and nothing else.
|
|
8020
|
-
//
|
|
8021
|
-
// A connection with no third party behind it — webhook — declares no block at
|
|
8022
|
-
// all, which is what keeps it off the provider screen.
|
|
8438
|
+
// THE ICON RIDES WITH THE MANIFEST, so a vendor cannot name an asset nobody
|
|
8439
|
+
// added — which is what the old arrangement allowed, with the markup in one
|
|
8440
|
+
// repo and the file in another.
|
|
8441
|
+
checkIcon( manifest.slug, manifest?.icon );
|
|
8442
|
+
|
|
8443
|
+
// WHICH VENDORS THIS CONNECTION SPENDS, and they have to exist.
|
|
8023
8444
|
//
|
|
8024
|
-
//
|
|
8025
|
-
//
|
|
8026
|
-
//
|
|
8027
|
-
//
|
|
8028
|
-
|
|
8029
|
-
// that forgot `redact : true` is a platform secret handed back over the wire
|
|
8030
|
-
// to every admin screen that asks.
|
|
8031
|
-
if( manifest.provider?.fields ){
|
|
8445
|
+
// This used to be the whole vendor declaration, nested here — name, icon,
|
|
8446
|
+
// fields and all — which is why mergeVendors() existed to reconcile two
|
|
8447
|
+
// manifests describing one vendor. The vendors are their own files now and are
|
|
8448
|
+
// checked above; a manifest names slugs.
|
|
8449
|
+
if( ! Array.isArray( manifest.vendors ) ){
|
|
8032
8450
|
|
|
8033
|
-
throw new Error( manifest.slug + '
|
|
8451
|
+
throw new Error( manifest.slug + ' must declare vendors — an array of vendor slugs, empty when it spends none' );
|
|
8034
8452
|
|
|
8035
8453
|
}
|
|
8036
8454
|
|
|
8037
8455
|
const declaredKeys = new Set();
|
|
8038
8456
|
|
|
8039
|
-
for( const
|
|
8457
|
+
for( const slug of manifest.vendors ){
|
|
8040
8458
|
|
|
8041
|
-
if( !
|
|
8459
|
+
if( ! Object.hasOwn( vendors, slug ) ){
|
|
8042
8460
|
|
|
8043
|
-
|
|
8044
|
-
// connection's — SendGrid's card is not the Drawbridge logo.
|
|
8045
|
-
checkIcon( manifest.slug + ' vendor ' + vendor, declared.icon );
|
|
8046
|
-
|
|
8047
|
-
if( ! Array.isArray( declared.fields ) || ! declared.fields.length ){
|
|
8048
|
-
|
|
8049
|
-
throw new Error( manifest.slug + ' declares vendor ' + vendor + ' with no fields — a vendor nothing is typed into holds nothing' );
|
|
8461
|
+
throw new Error( manifest.slug + ' spends vendor ' + slug + ', which has no file in lib/connections/vendors' );
|
|
8050
8462
|
|
|
8051
8463
|
}
|
|
8052
8464
|
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
if( ! INPUTS.includes( field.input ) ){
|
|
8062
|
-
|
|
8063
|
-
throw new Error( manifest.slug + '.provider.' + field.key + ' needs an input the admin form can render — one of ' + INPUTS.join( ', ' ) );
|
|
8064
|
-
|
|
8065
|
-
}
|
|
8066
|
-
|
|
8067
|
-
if( field.input === 'password' && ! field.redact ){
|
|
8068
|
-
|
|
8069
|
-
throw new Error( manifest.slug + '.provider.' + field.key + ' is a password and must declare redact : true — the api would hand the value back' );
|
|
8070
|
-
|
|
8071
|
-
}
|
|
8465
|
+
// ONE KEY PER CONNECTION across its vendors. vendorSettings() hands a
|
|
8466
|
+
// connection every vendor's settings merged into one object, so two vendors
|
|
8467
|
+
// on one manifest sharing a key would be one value silently winning over the
|
|
8468
|
+
// other. Checked here rather than on the vendor, because it is a fact about
|
|
8469
|
+
// the COMBINATION a connection spends: sendgrid and twilio are each fine, and
|
|
8470
|
+
// only drawbridge naming both makes a shared key a problem.
|
|
8471
|
+
for( const field of vendors[ slug ].fields ){
|
|
8072
8472
|
|
|
8073
|
-
// ONE KEY PER CONNECTION across its vendors. vendorSettings() hands a
|
|
8074
|
-
// connection every vendor's settings merged into one object, so two
|
|
8075
|
-
// vendors on one manifest sharing a key would be one value silently
|
|
8076
|
-
// winning over the other.
|
|
8077
8473
|
if( declaredKeys.has( field.key ) ){
|
|
8078
8474
|
|
|
8079
|
-
throw new Error( manifest.slug + '
|
|
8475
|
+
throw new Error( manifest.slug + ' spends ' + field.key + ' under two vendors — vendorSettings() merges them and one would win' );
|
|
8080
8476
|
|
|
8081
8477
|
}
|
|
8082
8478
|
|
|
@@ -8086,11 +8482,6 @@ const build = ( manifest ) => {
|
|
|
8086
8482
|
|
|
8087
8483
|
}
|
|
8088
8484
|
|
|
8089
|
-
// THE ICON RIDES WITH THE MANIFEST, so a vendor cannot name an asset nobody
|
|
8090
|
-
// added — which is what the old arrangement allowed, with the markup in one
|
|
8091
|
-
// repo and the file in another.
|
|
8092
|
-
checkIcon( manifest.slug, manifest?.icon );
|
|
8093
|
-
|
|
8094
8485
|
// `group` does the actual grouping on the connections page, and `category`
|
|
8095
8486
|
// was a second word for the same fact — so it is gone rather than kept as an
|
|
8096
8487
|
// alias nobody could tell apart from this one.
|
|
@@ -8367,96 +8758,6 @@ const connections = Object.freeze({
|
|
|
8367
8758
|
webhook : build( webhook )
|
|
8368
8759
|
});
|
|
8369
8760
|
|
|
8370
|
-
// A field declaration, with its keys in a fixed order, so two manifests that
|
|
8371
|
-
// declare the same field can be compared as strings whatever order they wrote
|
|
8372
|
-
// the keys in.
|
|
8373
|
-
const canonical = ( field ) => JSON.stringify( Object.fromEntries( Object.entries( field ).sort() ) );
|
|
8374
|
-
|
|
8375
|
-
// DRAWBRIDGE'S OWN VENDOR ACCOUNTS, one entry per vendor, unioned from every
|
|
8376
|
-
// manifest that spends one. This is what the provider screen lists and what
|
|
8377
|
-
// the `provider` collection is keyed by: one row per key here.
|
|
8378
|
-
//
|
|
8379
|
-
// Exported as a function over a catalog, and not only as the merged constant,
|
|
8380
|
-
// so the guards can be exercised against a catalog that breaks them — the real
|
|
8381
|
-
// one is built to pass.
|
|
8382
|
-
//
|
|
8383
|
-
// THREE GUARDS, and each one is a way two files could disagree about one fact:
|
|
8384
|
-
// the vendor's name and icon the same vendor drawn two ways is two cards
|
|
8385
|
-
// a field two manifests both the same key declared differently is a form
|
|
8386
|
-
// declare that renders whichever manifest loaded last
|
|
8387
|
-
// a credential name the join between `requires` and a row — two
|
|
8388
|
-
// fields answering one name is one value silently
|
|
8389
|
-
// winning, which is exactly the drift a row per
|
|
8390
|
-
// vendor exists to end
|
|
8391
|
-
const mergeVendors = ( catalog ) => {
|
|
8392
|
-
|
|
8393
|
-
const merged = {};
|
|
8394
|
-
const claimed = new Map();
|
|
8395
|
-
|
|
8396
|
-
for( const [ slug, manifest ] of Object.entries( catalog ) ){
|
|
8397
|
-
|
|
8398
|
-
for( const [ vendor, declared ] of Object.entries( manifest.provider?.vendors || {} ) ){
|
|
8399
|
-
|
|
8400
|
-
const held = merged[ vendor ] || ( merged[ vendor ] = { fields : [], icon : declared.icon, name : declared.name } );
|
|
8401
|
-
|
|
8402
|
-
if( held.name !== declared.name ){
|
|
8403
|
-
|
|
8404
|
-
throw new Error( slug + ' names vendor ' + vendor + ' "' + declared.name + '" but another manifest names it "' + held.name + '"' );
|
|
8405
|
-
|
|
8406
|
-
}
|
|
8407
|
-
|
|
8408
|
-
if( held.icon !== declared.icon ){
|
|
8409
|
-
|
|
8410
|
-
throw new Error( slug + ' declares a different icon for vendor ' + vendor + ' than another manifest — one vendor, one mark' );
|
|
8411
|
-
|
|
8412
|
-
}
|
|
8413
|
-
|
|
8414
|
-
for( const field of declared.fields ){
|
|
8415
|
-
|
|
8416
|
-
const existing = held.fields.find( ( entry ) => entry.key === field.key );
|
|
8417
|
-
|
|
8418
|
-
if( existing ){
|
|
8419
|
-
|
|
8420
|
-
if( canonical( existing ) !== canonical( field ) ){
|
|
8421
|
-
|
|
8422
|
-
throw new Error( slug + ' declares ' + vendor + '.' + field.key + ' differently from another manifest — a field two connections spend is declared identically in both' );
|
|
8423
|
-
|
|
8424
|
-
}
|
|
8425
|
-
|
|
8426
|
-
continue;
|
|
8427
|
-
|
|
8428
|
-
}
|
|
8429
|
-
|
|
8430
|
-
if( field.credential ){
|
|
8431
|
-
|
|
8432
|
-
const owner = claimed.get( field.credential );
|
|
8433
|
-
|
|
8434
|
-
if( owner ){
|
|
8435
|
-
|
|
8436
|
-
throw new Error( field.credential + ' is claimed by both ' + owner + ' and ' + vendor + '.' + field.key + ' — one would silently overwrite the other' );
|
|
8437
|
-
|
|
8438
|
-
}
|
|
8439
|
-
|
|
8440
|
-
claimed.set( field.credential, vendor + '.' + field.key );
|
|
8441
|
-
|
|
8442
|
-
}
|
|
8443
|
-
|
|
8444
|
-
held.fields.push( field );
|
|
8445
|
-
|
|
8446
|
-
}
|
|
8447
|
-
|
|
8448
|
-
}
|
|
8449
|
-
|
|
8450
|
-
}
|
|
8451
|
-
|
|
8452
|
-
return Object.freeze( Object.fromEntries(
|
|
8453
|
-
Object.entries( merged ).map( ( [ vendor, held ] ) => [ vendor, Object.freeze({ ...held, fields : Object.freeze( held.fields ) }) ] )
|
|
8454
|
-
) );
|
|
8455
|
-
|
|
8456
|
-
};
|
|
8457
|
-
|
|
8458
|
-
const vendors = mergeVendors( connections );
|
|
8459
|
-
|
|
8460
8761
|
// A STEP TYPE MAY BE SHARED, BUT NOT ITS QUEUE.
|
|
8461
8762
|
//
|
|
8462
8763
|
// A step type belongs to the CAPABILITY rather than to whoever implements it —
|
|
@@ -8512,6 +8813,8 @@ const availableConnections = ( env = {} ) => Object.fromEntries(
|
|
|
8512
8813
|
)
|
|
8513
8814
|
);
|
|
8514
8815
|
|
|
8816
|
+
|
|
8817
|
+
|
|
8515
8818
|
// WHAT A MERCHANT CAN SEE AND CONNECT. Everything available, minus the private
|
|
8516
8819
|
// ones.
|
|
8517
8820
|
//
|
|
@@ -8774,12 +9077,6 @@ const publicConnectionKeys = Object.freeze([
|
|
|
8774
9077
|
// excerpt, guide, and any vendor redirect copy.
|
|
8775
9078
|
'content',
|
|
8776
9079
|
'createdAt',
|
|
8777
|
-
// THE MERCHANT'S OWN SWITCH. `enabled : false` is a connection the merchant
|
|
8778
|
-
// paused — kept, configured, and not run — as distinct from a vendor the
|
|
8779
|
-
// platform switched off (which the api overlays as an error). Absent means
|
|
8780
|
-
// on; the dashboard renders Paused from it and the sync gates refuse a paused
|
|
8781
|
-
// connection the way they refuse a missing one.
|
|
8782
|
-
'enabled',
|
|
8783
9080
|
// The connection DOCUMENT's own errors array — scope-drift entries written by
|
|
8784
9081
|
// drawbridge-sync. NOT the manifest's error copy, which is content.errors:
|
|
8785
9082
|
// the document is spread OVER the resolved manifest downstream, so the two
|
|
@@ -8873,4 +9170,4 @@ const resolveConnection = ( item, data, env = {} ) => {
|
|
|
8873
9170
|
|
|
8874
9171
|
};
|
|
8875
9172
|
|
|
8876
|
-
export { AUTH_TYPES, GROUPS, HOOKS, HOOK_EFFECTS, HOOK_NAMES, HOOK_OPTIONS, HOOK_PROPS, INPUTS, OAUTH_FIELDS, OUTCOMES, RETIRED, STATUSES, STEPS, STEP_TYPES, WRITE_OPERATIONS, accessToken, authToken, availableConnections, build, catalogConnections, connectFields, connectionSteps, connections, effectsOf, hookSupport, isStale, mergeSettings,
|
|
9173
|
+
export { AUTH_TYPES, GROUPS, HOOKS, HOOK_EFFECTS, HOOK_NAMES, HOOK_OPTIONS, HOOK_PROPS, INPUTS, OAUTH_FIELDS, OUTCOMES, RETIRED, STATUSES, STEPS, STEP_TYPES, WRITE_OPERATIONS, accessToken, authToken, availableConnections, build, buildVendor, catalogConnections, connectFields, connectionSteps, connections, effectsOf, hookSupport, isStale, mergeSettings, projectConnection, publicConnectionKeys, publicSettingsBySlug, redactSettings, resolveConnection, runHook, scopesMessage, stepLabels, stepQueues, stepRoutes, tokenSettings, vendors };
|