@drawbridge/drawbridge-utils 0.0.133 → 0.0.135
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 +81 -5
- package/dist/connections/index.d.cts +100 -4
- package/dist/connections/index.d.ts +100 -4
- package/dist/connections/index.js +81 -5
- package/dist/connections/oauth.cjs +8 -2
- package/dist/connections/oauth.d.cts +14 -3
- package/dist/connections/oauth.d.ts +14 -3
- package/dist/connections/oauth.js +8 -2
- package/dist/providers.cjs +81 -5
- package/dist/providers.js +81 -5
- package/dist/twilio.cjs +145 -7
- package/dist/twilio.d.cts +188 -7
- package/dist/twilio.d.ts +188 -7
- package/dist/twilio.js +145 -7
- package/package.json +1 -1
|
@@ -464,8 +464,14 @@ var authToken = async ({
|
|
|
464
464
|
});
|
|
465
465
|
const body = await response.json().catch(() => ({}));
|
|
466
466
|
if (!response.ok) {
|
|
467
|
-
throw
|
|
468
|
-
|
|
467
|
+
throw Object.assign(
|
|
468
|
+
new Error(
|
|
469
|
+
renewing ? "The vendor refused the refresh token (" + response.status + ") \u2014 reconnect the connection" : "The vendor refused the exchange (" + response.status + ")" + ((body == null ? void 0 : body.error) ? ": " + body.error : "")
|
|
470
|
+
),
|
|
471
|
+
{
|
|
472
|
+
status: response.status,
|
|
473
|
+
...renewing && { code: "grant_refused" }
|
|
474
|
+
}
|
|
469
475
|
);
|
|
470
476
|
}
|
|
471
477
|
if (!renewing && !body.access_token) throw new Error("The vendor returned no access token");
|
|
@@ -521,7 +527,10 @@ var accessToken = async ({
|
|
|
521
527
|
}
|
|
522
528
|
if (!force && !isStale(settings, now)) return settings.accessToken;
|
|
523
529
|
if (!settings.refreshToken) {
|
|
524
|
-
throw
|
|
530
|
+
throw Object.assign(
|
|
531
|
+
new Error("This connection has expired and cannot be renewed automatically. Reconnect it."),
|
|
532
|
+
{ code: "grant_refused" }
|
|
533
|
+
);
|
|
525
534
|
}
|
|
526
535
|
const minted = await manifest.hooks.auth.token({
|
|
527
536
|
clientId,
|
|
@@ -2735,8 +2744,62 @@ var klaviyo_default2 = {
|
|
|
2735
2744
|
sms: false,
|
|
2736
2745
|
inbound: false,
|
|
2737
2746
|
// Nothing to set up or tear down at the vendor: the grant is the whole
|
|
2738
|
-
// integration
|
|
2739
|
-
lifecycle
|
|
2747
|
+
// integration. What CAN rot is the grant itself, so health is the one
|
|
2748
|
+
// lifecycle hook Klaviyo carries.
|
|
2749
|
+
lifecycle: {
|
|
2750
|
+
// Nothing to set up, tear down, or re-register at the vendor — the
|
|
2751
|
+
// grant is the whole integration.
|
|
2752
|
+
cleanup: false,
|
|
2753
|
+
register: false,
|
|
2754
|
+
rehydrate: false,
|
|
2755
|
+
// KEEP THE GRANT PROVEN AND WARM. The shell mints a fresh access
|
|
2756
|
+
// token before every hook run — for Klaviyo that spends the refresh
|
|
2757
|
+
// token, which is the only question that reaches Klaviyo (see
|
|
2758
|
+
// auth.probe) — so this body running at all proves the grant still
|
|
2759
|
+
// rotates, and the daily run keeps it inside Klaviyo's 90-day idle
|
|
2760
|
+
// window. A dead grant never gets here: the shell's mint throws
|
|
2761
|
+
// `grant_refused` and the step runner errors the connection itself.
|
|
2762
|
+
//
|
|
2763
|
+
// The one call below proves the minted token is HONOURED — mint and
|
|
2764
|
+
// acceptance are different facts, and /accounts is already the call
|
|
2765
|
+
// the connect flow makes (auth.connect), so it needs no new scope.
|
|
2766
|
+
health: async ({ connection: connection2, token }, { fetcher, read } = {}) => {
|
|
2767
|
+
const request2 = { connectionId: connection2.id };
|
|
2768
|
+
try {
|
|
2769
|
+
await api2("/accounts", { fetcher, token });
|
|
2770
|
+
return {
|
|
2771
|
+
message: "Health check passed \u2014 token minted and accepted.",
|
|
2772
|
+
request: request2,
|
|
2773
|
+
response: { pingedAt: /* @__PURE__ */ new Date() }
|
|
2774
|
+
};
|
|
2775
|
+
} catch (error) {
|
|
2776
|
+
if ([401, 403].includes(error.status) && read) {
|
|
2777
|
+
const current = await read.get({ collection: "connection", query: { id: connection2.id } });
|
|
2778
|
+
if (current) {
|
|
2779
|
+
const others = (current.errors || []).filter((entry) => entry.source !== "oauth");
|
|
2780
|
+
error.writes = [{
|
|
2781
|
+
collection: "connection",
|
|
2782
|
+
data: {
|
|
2783
|
+
$set: {
|
|
2784
|
+
errors: [
|
|
2785
|
+
...others,
|
|
2786
|
+
{
|
|
2787
|
+
message: "Klaviyo no longer accepts this connection. Reconnect Klaviyo to resume syncing.",
|
|
2788
|
+
source: "oauth"
|
|
2789
|
+
}
|
|
2790
|
+
],
|
|
2791
|
+
status: "error"
|
|
2792
|
+
}
|
|
2793
|
+
},
|
|
2794
|
+
operation: "update",
|
|
2795
|
+
query: { id: connection2.id }
|
|
2796
|
+
}];
|
|
2797
|
+
}
|
|
2798
|
+
}
|
|
2799
|
+
throw error;
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
},
|
|
2740
2803
|
resources: {
|
|
2741
2804
|
// The lists a merchant can sync into, for the picker on their
|
|
2742
2805
|
// connection.
|
|
@@ -2812,6 +2875,19 @@ var klaviyo_default2 = {
|
|
|
2812
2875
|
return ((_a = data2 == null ? void 0 : data2.settings) == null ? void 0 : _a.list) ? data2.status : "pending";
|
|
2813
2876
|
},
|
|
2814
2877
|
steps: {
|
|
2878
|
+
connection: {
|
|
2879
|
+
// The daily grant check — same step type and workflow shape as
|
|
2880
|
+
// Shopify's, provisioned as a system workflow per connection.
|
|
2881
|
+
health: {
|
|
2882
|
+
check: () => ({
|
|
2883
|
+
description: "Keeps the Klaviyo grant working \u2014 spends the refresh token daily so a revoked or idle grant is reported instead of discovered by a failing sync.",
|
|
2884
|
+
hook: "lifecycle.health",
|
|
2885
|
+
key: "Klaviyo Connection Health",
|
|
2886
|
+
queue: "connection",
|
|
2887
|
+
system: true
|
|
2888
|
+
})
|
|
2889
|
+
}
|
|
2890
|
+
},
|
|
2815
2891
|
contacts: {
|
|
2816
2892
|
// A DECLARATION, not the work. It names the hook that does the work, and
|
|
2817
2893
|
// says where that hook's values belong. Nested like the hooks, and the
|
|
@@ -741,8 +741,12 @@ const accessToken = async ({
|
|
|
741
741
|
|
|
742
742
|
// Expired with no way to mint another. Said plainly rather than returning
|
|
743
743
|
// a token the vendor will refuse — the merchant has to reconnect and the
|
|
744
|
-
// error should say so.
|
|
745
|
-
|
|
744
|
+
// error should say so. Same `code` as a refused refresh: both mean the
|
|
745
|
+
// grant is dead and only reconnecting revives it.
|
|
746
|
+
throw Object.assign(
|
|
747
|
+
new Error( 'This connection has expired and cannot be renewed automatically. Reconnect it.' ),
|
|
748
|
+
{ code : 'grant_refused' }
|
|
749
|
+
);
|
|
746
750
|
|
|
747
751
|
}
|
|
748
752
|
|
|
@@ -2941,8 +2945,84 @@ var klaviyo = {
|
|
|
2941
2945
|
inbound : false,
|
|
2942
2946
|
|
|
2943
2947
|
// Nothing to set up or tear down at the vendor: the grant is the whole
|
|
2944
|
-
// integration
|
|
2945
|
-
lifecycle
|
|
2948
|
+
// integration. What CAN rot is the grant itself, so health is the one
|
|
2949
|
+
// lifecycle hook Klaviyo carries.
|
|
2950
|
+
lifecycle : {
|
|
2951
|
+
|
|
2952
|
+
// Nothing to set up, tear down, or re-register at the vendor — the
|
|
2953
|
+
// grant is the whole integration.
|
|
2954
|
+
cleanup : false,
|
|
2955
|
+
register : false,
|
|
2956
|
+
rehydrate : false,
|
|
2957
|
+
|
|
2958
|
+
// KEEP THE GRANT PROVEN AND WARM. The shell mints a fresh access
|
|
2959
|
+
// token before every hook run — for Klaviyo that spends the refresh
|
|
2960
|
+
// token, which is the only question that reaches Klaviyo (see
|
|
2961
|
+
// auth.probe) — so this body running at all proves the grant still
|
|
2962
|
+
// rotates, and the daily run keeps it inside Klaviyo's 90-day idle
|
|
2963
|
+
// window. A dead grant never gets here: the shell's mint throws
|
|
2964
|
+
// `grant_refused` and the step runner errors the connection itself.
|
|
2965
|
+
//
|
|
2966
|
+
// The one call below proves the minted token is HONOURED — mint and
|
|
2967
|
+
// acceptance are different facts, and /accounts is already the call
|
|
2968
|
+
// the connect flow makes (auth.connect), so it needs no new scope.
|
|
2969
|
+
health : async ( { connection, token }, { fetcher, read } = {} ) => {
|
|
2970
|
+
|
|
2971
|
+
const request = { connectionId : connection.id };
|
|
2972
|
+
|
|
2973
|
+
try {
|
|
2974
|
+
|
|
2975
|
+
await api$1( '/accounts', { fetcher, token });
|
|
2976
|
+
|
|
2977
|
+
return {
|
|
2978
|
+
message : 'Health check passed — token minted and accepted.',
|
|
2979
|
+
request,
|
|
2980
|
+
response : { pingedAt : new Date() }
|
|
2981
|
+
};
|
|
2982
|
+
|
|
2983
|
+
} catch ( error ) {
|
|
2984
|
+
|
|
2985
|
+
// The token we JUST minted was refused — a revoked or
|
|
2986
|
+
// downgraded grant, never a transient. The write rides out
|
|
2987
|
+
// on the rejection (the shell performs a thrown error's
|
|
2988
|
+
// effects) because the step must still fail.
|
|
2989
|
+
if( [ 401, 403 ].includes( error.status ) && read ){
|
|
2990
|
+
|
|
2991
|
+
const current = await read.get({ collection : 'connection', query : { id : connection.id } });
|
|
2992
|
+
|
|
2993
|
+
if( current ){
|
|
2994
|
+
|
|
2995
|
+
const others = ( current.errors || [] ).filter( ( entry ) => entry.source !== 'oauth' );
|
|
2996
|
+
|
|
2997
|
+
error.writes = [ {
|
|
2998
|
+
collection : 'connection',
|
|
2999
|
+
data : {
|
|
3000
|
+
$set : {
|
|
3001
|
+
errors : [
|
|
3002
|
+
...others,
|
|
3003
|
+
{
|
|
3004
|
+
message : 'Klaviyo no longer accepts this connection. Reconnect Klaviyo to resume syncing.',
|
|
3005
|
+
source : 'oauth'
|
|
3006
|
+
}
|
|
3007
|
+
],
|
|
3008
|
+
status : 'error'
|
|
3009
|
+
}
|
|
3010
|
+
},
|
|
3011
|
+
operation : 'update',
|
|
3012
|
+
query : { id : connection.id }
|
|
3013
|
+
} ];
|
|
3014
|
+
|
|
3015
|
+
}
|
|
3016
|
+
|
|
3017
|
+
}
|
|
3018
|
+
|
|
3019
|
+
throw error;
|
|
3020
|
+
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
}
|
|
3024
|
+
|
|
3025
|
+
},
|
|
2946
3026
|
|
|
2947
3027
|
resources : {
|
|
2948
3028
|
|
|
@@ -3049,6 +3129,22 @@ var klaviyo = {
|
|
|
3049
3129
|
|
|
3050
3130
|
steps : {
|
|
3051
3131
|
|
|
3132
|
+
connection : {
|
|
3133
|
+
|
|
3134
|
+
// The daily grant check — same step type and workflow shape as
|
|
3135
|
+
// Shopify's, provisioned as a system workflow per connection.
|
|
3136
|
+
health : {
|
|
3137
|
+
check : () => ({
|
|
3138
|
+
description : 'Keeps the Klaviyo grant working — spends the refresh token daily so a revoked or idle grant is reported instead of discovered by a failing sync.',
|
|
3139
|
+
hook : 'lifecycle.health',
|
|
3140
|
+
key : 'Klaviyo Connection Health',
|
|
3141
|
+
queue : 'connection',
|
|
3142
|
+
system : true
|
|
3143
|
+
})
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
},
|
|
3147
|
+
|
|
3052
3148
|
contacts : {
|
|
3053
3149
|
|
|
3054
3150
|
// A DECLARATION, not the work. It names the hook that does the work, and
|
|
@@ -741,8 +741,12 @@ const accessToken = async ({
|
|
|
741
741
|
|
|
742
742
|
// Expired with no way to mint another. Said plainly rather than returning
|
|
743
743
|
// a token the vendor will refuse — the merchant has to reconnect and the
|
|
744
|
-
// error should say so.
|
|
745
|
-
|
|
744
|
+
// error should say so. Same `code` as a refused refresh: both mean the
|
|
745
|
+
// grant is dead and only reconnecting revives it.
|
|
746
|
+
throw Object.assign(
|
|
747
|
+
new Error( 'This connection has expired and cannot be renewed automatically. Reconnect it.' ),
|
|
748
|
+
{ code : 'grant_refused' }
|
|
749
|
+
);
|
|
746
750
|
|
|
747
751
|
}
|
|
748
752
|
|
|
@@ -2941,8 +2945,84 @@ var klaviyo = {
|
|
|
2941
2945
|
inbound : false,
|
|
2942
2946
|
|
|
2943
2947
|
// Nothing to set up or tear down at the vendor: the grant is the whole
|
|
2944
|
-
// integration
|
|
2945
|
-
lifecycle
|
|
2948
|
+
// integration. What CAN rot is the grant itself, so health is the one
|
|
2949
|
+
// lifecycle hook Klaviyo carries.
|
|
2950
|
+
lifecycle : {
|
|
2951
|
+
|
|
2952
|
+
// Nothing to set up, tear down, or re-register at the vendor — the
|
|
2953
|
+
// grant is the whole integration.
|
|
2954
|
+
cleanup : false,
|
|
2955
|
+
register : false,
|
|
2956
|
+
rehydrate : false,
|
|
2957
|
+
|
|
2958
|
+
// KEEP THE GRANT PROVEN AND WARM. The shell mints a fresh access
|
|
2959
|
+
// token before every hook run — for Klaviyo that spends the refresh
|
|
2960
|
+
// token, which is the only question that reaches Klaviyo (see
|
|
2961
|
+
// auth.probe) — so this body running at all proves the grant still
|
|
2962
|
+
// rotates, and the daily run keeps it inside Klaviyo's 90-day idle
|
|
2963
|
+
// window. A dead grant never gets here: the shell's mint throws
|
|
2964
|
+
// `grant_refused` and the step runner errors the connection itself.
|
|
2965
|
+
//
|
|
2966
|
+
// The one call below proves the minted token is HONOURED — mint and
|
|
2967
|
+
// acceptance are different facts, and /accounts is already the call
|
|
2968
|
+
// the connect flow makes (auth.connect), so it needs no new scope.
|
|
2969
|
+
health : async ( { connection, token }, { fetcher, read } = {} ) => {
|
|
2970
|
+
|
|
2971
|
+
const request = { connectionId : connection.id };
|
|
2972
|
+
|
|
2973
|
+
try {
|
|
2974
|
+
|
|
2975
|
+
await api$1( '/accounts', { fetcher, token });
|
|
2976
|
+
|
|
2977
|
+
return {
|
|
2978
|
+
message : 'Health check passed — token minted and accepted.',
|
|
2979
|
+
request,
|
|
2980
|
+
response : { pingedAt : new Date() }
|
|
2981
|
+
};
|
|
2982
|
+
|
|
2983
|
+
} catch ( error ) {
|
|
2984
|
+
|
|
2985
|
+
// The token we JUST minted was refused — a revoked or
|
|
2986
|
+
// downgraded grant, never a transient. The write rides out
|
|
2987
|
+
// on the rejection (the shell performs a thrown error's
|
|
2988
|
+
// effects) because the step must still fail.
|
|
2989
|
+
if( [ 401, 403 ].includes( error.status ) && read ){
|
|
2990
|
+
|
|
2991
|
+
const current = await read.get({ collection : 'connection', query : { id : connection.id } });
|
|
2992
|
+
|
|
2993
|
+
if( current ){
|
|
2994
|
+
|
|
2995
|
+
const others = ( current.errors || [] ).filter( ( entry ) => entry.source !== 'oauth' );
|
|
2996
|
+
|
|
2997
|
+
error.writes = [ {
|
|
2998
|
+
collection : 'connection',
|
|
2999
|
+
data : {
|
|
3000
|
+
$set : {
|
|
3001
|
+
errors : [
|
|
3002
|
+
...others,
|
|
3003
|
+
{
|
|
3004
|
+
message : 'Klaviyo no longer accepts this connection. Reconnect Klaviyo to resume syncing.',
|
|
3005
|
+
source : 'oauth'
|
|
3006
|
+
}
|
|
3007
|
+
],
|
|
3008
|
+
status : 'error'
|
|
3009
|
+
}
|
|
3010
|
+
},
|
|
3011
|
+
operation : 'update',
|
|
3012
|
+
query : { id : connection.id }
|
|
3013
|
+
} ];
|
|
3014
|
+
|
|
3015
|
+
}
|
|
3016
|
+
|
|
3017
|
+
}
|
|
3018
|
+
|
|
3019
|
+
throw error;
|
|
3020
|
+
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
}
|
|
3024
|
+
|
|
3025
|
+
},
|
|
2946
3026
|
|
|
2947
3027
|
resources : {
|
|
2948
3028
|
|
|
@@ -3049,6 +3129,22 @@ var klaviyo = {
|
|
|
3049
3129
|
|
|
3050
3130
|
steps : {
|
|
3051
3131
|
|
|
3132
|
+
connection : {
|
|
3133
|
+
|
|
3134
|
+
// The daily grant check — same step type and workflow shape as
|
|
3135
|
+
// Shopify's, provisioned as a system workflow per connection.
|
|
3136
|
+
health : {
|
|
3137
|
+
check : () => ({
|
|
3138
|
+
description : 'Keeps the Klaviyo grant working — spends the refresh token daily so a revoked or idle grant is reported instead of discovered by a failing sync.',
|
|
3139
|
+
hook : 'lifecycle.health',
|
|
3140
|
+
key : 'Klaviyo Connection Health',
|
|
3141
|
+
queue : 'connection',
|
|
3142
|
+
system : true
|
|
3143
|
+
})
|
|
3144
|
+
}
|
|
3145
|
+
|
|
3146
|
+
},
|
|
3147
|
+
|
|
3052
3148
|
contacts : {
|
|
3053
3149
|
|
|
3054
3150
|
// A DECLARATION, not the work. It names the hook that does the work, and
|
|
@@ -390,8 +390,14 @@ var authToken = async ({
|
|
|
390
390
|
});
|
|
391
391
|
const body = await response.json().catch(() => ({}));
|
|
392
392
|
if (!response.ok) {
|
|
393
|
-
throw
|
|
394
|
-
|
|
393
|
+
throw Object.assign(
|
|
394
|
+
new Error(
|
|
395
|
+
renewing ? "The vendor refused the refresh token (" + response.status + ") \u2014 reconnect the connection" : "The vendor refused the exchange (" + response.status + ")" + ((body == null ? void 0 : body.error) ? ": " + body.error : "")
|
|
396
|
+
),
|
|
397
|
+
{
|
|
398
|
+
status: response.status,
|
|
399
|
+
...renewing && { code: "grant_refused" }
|
|
400
|
+
}
|
|
395
401
|
);
|
|
396
402
|
}
|
|
397
403
|
if (!renewing && !body.access_token) throw new Error("The vendor returned no access token");
|
|
@@ -447,7 +453,10 @@ var accessToken = async ({
|
|
|
447
453
|
}
|
|
448
454
|
if (!force && !isStale(settings, now)) return settings.accessToken;
|
|
449
455
|
if (!settings.refreshToken) {
|
|
450
|
-
throw
|
|
456
|
+
throw Object.assign(
|
|
457
|
+
new Error("This connection has expired and cannot be renewed automatically. Reconnect it."),
|
|
458
|
+
{ code: "grant_refused" }
|
|
459
|
+
);
|
|
451
460
|
}
|
|
452
461
|
const minted = await manifest.hooks.auth.token({
|
|
453
462
|
clientId,
|
|
@@ -2661,8 +2670,62 @@ var klaviyo_default2 = {
|
|
|
2661
2670
|
sms: false,
|
|
2662
2671
|
inbound: false,
|
|
2663
2672
|
// Nothing to set up or tear down at the vendor: the grant is the whole
|
|
2664
|
-
// integration
|
|
2665
|
-
lifecycle
|
|
2673
|
+
// integration. What CAN rot is the grant itself, so health is the one
|
|
2674
|
+
// lifecycle hook Klaviyo carries.
|
|
2675
|
+
lifecycle: {
|
|
2676
|
+
// Nothing to set up, tear down, or re-register at the vendor — the
|
|
2677
|
+
// grant is the whole integration.
|
|
2678
|
+
cleanup: false,
|
|
2679
|
+
register: false,
|
|
2680
|
+
rehydrate: false,
|
|
2681
|
+
// KEEP THE GRANT PROVEN AND WARM. The shell mints a fresh access
|
|
2682
|
+
// token before every hook run — for Klaviyo that spends the refresh
|
|
2683
|
+
// token, which is the only question that reaches Klaviyo (see
|
|
2684
|
+
// auth.probe) — so this body running at all proves the grant still
|
|
2685
|
+
// rotates, and the daily run keeps it inside Klaviyo's 90-day idle
|
|
2686
|
+
// window. A dead grant never gets here: the shell's mint throws
|
|
2687
|
+
// `grant_refused` and the step runner errors the connection itself.
|
|
2688
|
+
//
|
|
2689
|
+
// The one call below proves the minted token is HONOURED — mint and
|
|
2690
|
+
// acceptance are different facts, and /accounts is already the call
|
|
2691
|
+
// the connect flow makes (auth.connect), so it needs no new scope.
|
|
2692
|
+
health: async ({ connection: connection2, token }, { fetcher, read } = {}) => {
|
|
2693
|
+
const request2 = { connectionId: connection2.id };
|
|
2694
|
+
try {
|
|
2695
|
+
await api2("/accounts", { fetcher, token });
|
|
2696
|
+
return {
|
|
2697
|
+
message: "Health check passed \u2014 token minted and accepted.",
|
|
2698
|
+
request: request2,
|
|
2699
|
+
response: { pingedAt: /* @__PURE__ */ new Date() }
|
|
2700
|
+
};
|
|
2701
|
+
} catch (error) {
|
|
2702
|
+
if ([401, 403].includes(error.status) && read) {
|
|
2703
|
+
const current = await read.get({ collection: "connection", query: { id: connection2.id } });
|
|
2704
|
+
if (current) {
|
|
2705
|
+
const others = (current.errors || []).filter((entry) => entry.source !== "oauth");
|
|
2706
|
+
error.writes = [{
|
|
2707
|
+
collection: "connection",
|
|
2708
|
+
data: {
|
|
2709
|
+
$set: {
|
|
2710
|
+
errors: [
|
|
2711
|
+
...others,
|
|
2712
|
+
{
|
|
2713
|
+
message: "Klaviyo no longer accepts this connection. Reconnect Klaviyo to resume syncing.",
|
|
2714
|
+
source: "oauth"
|
|
2715
|
+
}
|
|
2716
|
+
],
|
|
2717
|
+
status: "error"
|
|
2718
|
+
}
|
|
2719
|
+
},
|
|
2720
|
+
operation: "update",
|
|
2721
|
+
query: { id: connection2.id }
|
|
2722
|
+
}];
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
throw error;
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
},
|
|
2666
2729
|
resources: {
|
|
2667
2730
|
// The lists a merchant can sync into, for the picker on their
|
|
2668
2731
|
// connection.
|
|
@@ -2738,6 +2801,19 @@ var klaviyo_default2 = {
|
|
|
2738
2801
|
return ((_a = data2 == null ? void 0 : data2.settings) == null ? void 0 : _a.list) ? data2.status : "pending";
|
|
2739
2802
|
},
|
|
2740
2803
|
steps: {
|
|
2804
|
+
connection: {
|
|
2805
|
+
// The daily grant check — same step type and workflow shape as
|
|
2806
|
+
// Shopify's, provisioned as a system workflow per connection.
|
|
2807
|
+
health: {
|
|
2808
|
+
check: () => ({
|
|
2809
|
+
description: "Keeps the Klaviyo grant working \u2014 spends the refresh token daily so a revoked or idle grant is reported instead of discovered by a failing sync.",
|
|
2810
|
+
hook: "lifecycle.health",
|
|
2811
|
+
key: "Klaviyo Connection Health",
|
|
2812
|
+
queue: "connection",
|
|
2813
|
+
system: true
|
|
2814
|
+
})
|
|
2815
|
+
}
|
|
2816
|
+
},
|
|
2741
2817
|
contacts: {
|
|
2742
2818
|
// A DECLARATION, not the work. It names the hook that does the work, and
|
|
2743
2819
|
// says where that hook's values belong. Nested like the hooks, and the
|
|
@@ -94,8 +94,14 @@ var authToken = async ({
|
|
|
94
94
|
});
|
|
95
95
|
const body = await response.json().catch(() => ({}));
|
|
96
96
|
if (!response.ok) {
|
|
97
|
-
throw
|
|
98
|
-
|
|
97
|
+
throw Object.assign(
|
|
98
|
+
new Error(
|
|
99
|
+
renewing ? "The vendor refused the refresh token (" + response.status + ") \u2014 reconnect the connection" : "The vendor refused the exchange (" + response.status + ")" + ((body == null ? void 0 : body.error) ? ": " + body.error : "")
|
|
100
|
+
),
|
|
101
|
+
{
|
|
102
|
+
status: response.status,
|
|
103
|
+
...renewing && { code: "grant_refused" }
|
|
104
|
+
}
|
|
99
105
|
);
|
|
100
106
|
}
|
|
101
107
|
if (!renewing && !body.access_token) throw new Error("The vendor returned no access token");
|
|
@@ -173,9 +173,20 @@ const authToken = async ({
|
|
|
173
173
|
// The two paths fail differently for the merchant: a refused exchange is
|
|
174
174
|
// "try connecting again", a refused refresh is "reconnect this connection",
|
|
175
175
|
// and collapsing them sends somebody to the wrong screen.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
176
|
+
//
|
|
177
|
+
// `code` marks the refused REFRESH machine-readably — the health-check
|
|
178
|
+
// shell errors the connection on it rather than retrying a dead grant
|
|
179
|
+
// into the log forever. Only the renewing branch: a refused exchange is
|
|
180
|
+
// a connect-flow failure with a person watching.
|
|
181
|
+
throw Object.assign(
|
|
182
|
+
new Error( renewing
|
|
183
|
+
? 'The vendor refused the refresh token (' + response.status + ') — reconnect the connection'
|
|
184
|
+
: 'The vendor refused the exchange (' + response.status + ')' + ( body?.error ? ': ' + body.error : '' )
|
|
185
|
+
),
|
|
186
|
+
{
|
|
187
|
+
status : response.status,
|
|
188
|
+
...( renewing && { code : 'grant_refused' })
|
|
189
|
+
}
|
|
179
190
|
);
|
|
180
191
|
|
|
181
192
|
}
|
|
@@ -173,9 +173,20 @@ const authToken = async ({
|
|
|
173
173
|
// The two paths fail differently for the merchant: a refused exchange is
|
|
174
174
|
// "try connecting again", a refused refresh is "reconnect this connection",
|
|
175
175
|
// and collapsing them sends somebody to the wrong screen.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
176
|
+
//
|
|
177
|
+
// `code` marks the refused REFRESH machine-readably — the health-check
|
|
178
|
+
// shell errors the connection on it rather than retrying a dead grant
|
|
179
|
+
// into the log forever. Only the renewing branch: a refused exchange is
|
|
180
|
+
// a connect-flow failure with a person watching.
|
|
181
|
+
throw Object.assign(
|
|
182
|
+
new Error( renewing
|
|
183
|
+
? 'The vendor refused the refresh token (' + response.status + ') — reconnect the connection'
|
|
184
|
+
: 'The vendor refused the exchange (' + response.status + ')' + ( body?.error ? ': ' + body.error : '' )
|
|
185
|
+
),
|
|
186
|
+
{
|
|
187
|
+
status : response.status,
|
|
188
|
+
...( renewing && { code : 'grant_refused' })
|
|
189
|
+
}
|
|
179
190
|
);
|
|
180
191
|
|
|
181
192
|
}
|
|
@@ -69,8 +69,14 @@ var authToken = async ({
|
|
|
69
69
|
});
|
|
70
70
|
const body = await response.json().catch(() => ({}));
|
|
71
71
|
if (!response.ok) {
|
|
72
|
-
throw
|
|
73
|
-
|
|
72
|
+
throw Object.assign(
|
|
73
|
+
new Error(
|
|
74
|
+
renewing ? "The vendor refused the refresh token (" + response.status + ") \u2014 reconnect the connection" : "The vendor refused the exchange (" + response.status + ")" + ((body == null ? void 0 : body.error) ? ": " + body.error : "")
|
|
75
|
+
),
|
|
76
|
+
{
|
|
77
|
+
status: response.status,
|
|
78
|
+
...renewing && { code: "grant_refused" }
|
|
79
|
+
}
|
|
74
80
|
);
|
|
75
81
|
}
|
|
76
82
|
if (!renewing && !body.access_token) throw new Error("The vendor returned no access token");
|