@porulle/adapter-shopify 0.66.0 → 0.68.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/dist/graphql.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Err, Ok } from "@porulle/core";
1
+ import { CHANNEL_CREDENTIALS_REJECTED, Err, Ok } from "@porulle/core";
2
2
  import { z } from "zod";
3
3
  /**
4
4
  * The one way this adapter talks to a store: the GraphQL Admin API.
@@ -69,7 +69,7 @@ export async function shopifyGraphql(target, query, variables, schema) {
69
69
  return Err({ code: "SHOPIFY_API_FAILED", message: error instanceof Error ? error.message : "Shopify API request failed.", retriable: true });
70
70
  }
71
71
  if (response.status === 401 || response.status === 403) {
72
- return Err({ code: "SHOPIFY_UNAUTHORIZED", message: `Shopify refused the access token (${response.status}); the store must be reconnected.`, retriable: false });
72
+ return Err({ code: CHANNEL_CREDENTIALS_REJECTED, message: `Shopify refused the access token (${response.status}).`, retriable: false });
73
73
  }
74
74
  if (response.status !== 429 && !response.ok) {
75
75
  return Err({ code: "SHOPIFY_API_FAILED", message: `Shopify API request failed (${response.status}).`, retriable: response.status >= 500 });
package/dist/index.js CHANGED
@@ -107,11 +107,11 @@ export function shopifyConnector(options) {
107
107
  return credentials;
108
108
  return Ok({ credentials: { ...credentials.value }, storeDomain: shop });
109
109
  },
110
- async liveCredentials(store) {
110
+ async liveCredentials(store, refresh) {
111
111
  const credentials = parseShopifyCredentials(store.credentials);
112
112
  if (!credentials)
113
113
  return Err(credentialsRequired);
114
- const refreshed = await refreshIfExpiring({ fetchImpl, origin: origin(store.storeDomain), clientId: options.clientId, clientSecret: options.clientSecret, credentials, now: Date.now() });
114
+ const refreshed = await refreshIfExpiring({ fetchImpl, origin: origin(store.storeDomain), clientId: options.clientId, clientSecret: options.clientSecret, credentials, now: Date.now(), ...(refresh?.force === true ? { force: true } : {}) });
115
115
  if (!refreshed.ok)
116
116
  return refreshed;
117
117
  return Ok(refreshed.value === null ? null : { ...refreshed.value });
package/dist/oauth.d.ts CHANGED
@@ -63,4 +63,6 @@ export declare function refreshIfExpiring(params: {
63
63
  clientSecret: string;
64
64
  credentials: ShopifyCredentials;
65
65
  now: number;
66
+ /** Refresh even though the stated expiry is far off: Shopify just rejected the token. */
67
+ force?: boolean;
66
68
  }): Promise<Result<ShopifyCredentials | null, ChannelConnectorError>>;
package/dist/oauth.js CHANGED
@@ -149,11 +149,13 @@ export async function exchangeCallback(params) {
149
149
  */
150
150
  export async function refreshIfExpiring(params) {
151
151
  const { credentials } = params;
152
- if (credentials.accessTokenExpiresAt === undefined)
153
- return Ok(null);
154
- const expiresAt = Date.parse(credentials.accessTokenExpiresAt);
155
- if (Number.isFinite(expiresAt) && expiresAt - params.now > ACCESS_TOKEN_REFRESH_MARGIN_MS)
156
- return Ok(null);
152
+ if (params.force !== true) {
153
+ if (credentials.accessTokenExpiresAt === undefined)
154
+ return Ok(null);
155
+ const expiresAt = Date.parse(credentials.accessTokenExpiresAt);
156
+ if (Number.isFinite(expiresAt) && expiresAt - params.now > ACCESS_TOKEN_REFRESH_MARGIN_MS)
157
+ return Ok(null);
158
+ }
157
159
  if (credentials.refreshToken === undefined)
158
160
  return oauthError("SHOPIFY_REAUTHORIZATION_REQUIRED", "The store's access token expired and no refresh token is held; the store must be reconnected.");
159
161
  const token = await postTokenEndpoint(params.fetchImpl, params.origin, {