@cronvello/shop-sdk 0.1.0 → 0.2.2
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/CONTRACT_SHA256 +1 -1
- package/README.md +34 -0
- package/dist/browser.cjs +115 -4
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.d.cts +3 -3
- package/dist/browser.d.ts +3 -3
- package/dist/browser.js +114 -5
- package/dist/browser.js.map +1 -1
- package/dist/contract.cjs +15 -2
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +1 -1
- package/dist/contract.d.ts +1 -1
- package/dist/contract.js +15 -2
- package/dist/contract.js.map +1 -1
- package/dist/{error-C-cJ6OgX.d.cts → error-1WqH-FhJ.d.cts} +55 -2
- package/dist/{error-BFzxyQkW.d.ts → error-D3Jrcd-j.d.ts} +55 -2
- package/dist/{index-CIpUb0vL.d.cts → index-DC6jGVkP.d.cts} +85 -5
- package/dist/{index-CIpUb0vL.d.ts → index-DC6jGVkP.d.ts} +85 -5
- package/dist/index.cjs +115 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +114 -5
- package/dist/index.js.map +1 -1
- package/dist/openapi.json +193 -3
- package/dist/server.cjs +115 -4
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +3 -3
- package/dist/server.d.ts +3 -3
- package/dist/server.js +114 -5
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -847,7 +847,7 @@ var apiRoutes_b2b = {
|
|
|
847
847
|
meta: {
|
|
848
848
|
tags: ["b2b"],
|
|
849
849
|
summary: "Create B2B dynamic checkout session",
|
|
850
|
-
description: "Creates a Stripe checkout session with dynamic price_data for trusted external apps. Supports mixed carts (one-time + recurring). Auth: Bearer BACKEND_TO_BACKEND_API_KEY.",
|
|
850
|
+
description: "Creates a Stripe checkout session with dynamic price_data for trusted external apps. Supports mixed carts (one-time + recurring). Auth: Bearer BACKEND_TO_BACKEND_API_KEY or App-Scoped API Key.",
|
|
851
851
|
bodyContentType: "application/json",
|
|
852
852
|
validated: { "params": false, "query": false, "body": true }
|
|
853
853
|
},
|
|
@@ -2059,6 +2059,19 @@ var apiRoutes_external_apps = {
|
|
|
2059
2059
|
},
|
|
2060
2060
|
types: null
|
|
2061
2061
|
},
|
|
2062
|
+
"external_apps_service_rotate_key": {
|
|
2063
|
+
method: "POST",
|
|
2064
|
+
path: "/external-apps/service/rotate-key/:appId",
|
|
2065
|
+
auth: { "type": "x_api_key_https" },
|
|
2066
|
+
meta: {
|
|
2067
|
+
tags: ["external-apps"],
|
|
2068
|
+
summary: "Rotate external app api key (B2B zero-downtime)",
|
|
2069
|
+
description: "Rotates the API key of an external app. The previous key remains valid during the specified gracePeriodHours (default: 2h) to prevent downtime during deployments. Authenticated via backend-to-backend API key.",
|
|
2070
|
+
bodyContentType: "application/json",
|
|
2071
|
+
validated: { "params": true, "query": true, "body": true }
|
|
2072
|
+
},
|
|
2073
|
+
types: null
|
|
2074
|
+
},
|
|
2062
2075
|
"external_apps_service_delete": {
|
|
2063
2076
|
method: "DELETE",
|
|
2064
2077
|
path: "/external-apps/service/delete/:appId",
|
|
@@ -2078,7 +2091,7 @@ var apiRoutes_external_apps = {
|
|
|
2078
2091
|
meta: {
|
|
2079
2092
|
tags: ["external-apps"],
|
|
2080
2093
|
summary: "Get external app registration status (B2B)",
|
|
2081
|
-
description: "Returns registration status for an app identified by its string appId. Used by AMP to discover existing connections."
|
|
2094
|
+
description: "Returns registration status for an app identified by its string appId. Used by AMP to discover existing connections. Includes authMethod and, for OAuth apps, the oauth client_id we will present to that app plus a truncated SHA-256 fingerprint of the stored client secret, so the other side can prove a rotation actually landed here. Never the secret itself. Also reports the entitlement paths we have stored, because registration is an upsert: a caller that only wants to hand us new credentials must send these back unchanged, or it silently repoints where we fetch entitlements from."
|
|
2082
2095
|
},
|
|
2083
2096
|
types: null
|
|
2084
2097
|
},
|
|
@@ -5621,7 +5634,7 @@ function createShopClient(options = {}) {
|
|
|
5621
5634
|
const defaultTimeoutMs = options.timeoutMs ?? 3e4;
|
|
5622
5635
|
const defaultRetries = options.retries ?? 2;
|
|
5623
5636
|
const retryDelayMs = options.retryDelayMs ?? 250;
|
|
5624
|
-
async function
|
|
5637
|
+
async function resolveBaseUrl2() {
|
|
5625
5638
|
const value = typeof baseUrl === "function" ? await baseUrl() : baseUrl;
|
|
5626
5639
|
return normalizeBaseUrl(value);
|
|
5627
5640
|
}
|
|
@@ -5643,7 +5656,7 @@ function createShopClient(options = {}) {
|
|
|
5643
5656
|
const body = hasBody ? JSON.stringify(values.body) : void 0;
|
|
5644
5657
|
const retries = Math.max(0, requestOptions.retries ?? defaultRetries);
|
|
5645
5658
|
const canRetry = SAFE_METHODS.has(route.method) || requestOptions.retryUnsafe === true;
|
|
5646
|
-
const resolvedBaseUrl = await
|
|
5659
|
+
const resolvedBaseUrl = await resolveBaseUrl2();
|
|
5647
5660
|
for (let attempt = 0; ; attempt += 1) {
|
|
5648
5661
|
const timeout = createRequestSignal(requestOptions.signal, requestOptions.timeoutMs ?? defaultTimeoutMs);
|
|
5649
5662
|
try {
|
|
@@ -5720,6 +5733,103 @@ function createShopClient(options = {}) {
|
|
|
5720
5733
|
return { baseUrl, request, requestText, requestRaw };
|
|
5721
5734
|
}
|
|
5722
5735
|
|
|
5736
|
+
// src/contract-hash.ts
|
|
5737
|
+
var CONTRACT_SHA256 = "05f34929e71fb2fcb3a4c04707facca22ee46f8960a4cc47ce0a3f1a6df36056";
|
|
5738
|
+
|
|
5739
|
+
// src/client/diagnose.ts
|
|
5740
|
+
var SDK_VERSION = "0.2.2" ;
|
|
5741
|
+
async function resolveBaseUrl(options) {
|
|
5742
|
+
const provider = options.client?.baseUrl ?? options.baseUrl ?? SHOP_API_URL;
|
|
5743
|
+
const value = typeof provider === "function" ? await provider() : provider;
|
|
5744
|
+
return normalizeBaseUrl(value);
|
|
5745
|
+
}
|
|
5746
|
+
async function diagnoseShop(options = {}) {
|
|
5747
|
+
const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5748
|
+
const baseUrl = await resolveBaseUrl(options);
|
|
5749
|
+
const doFetch = options.fetch ?? globalThis.fetch;
|
|
5750
|
+
const timeoutMs = options.timeoutMs ?? 5e3;
|
|
5751
|
+
const base = {
|
|
5752
|
+
ok: false,
|
|
5753
|
+
baseUrl,
|
|
5754
|
+
sdkVersion: SDK_VERSION,
|
|
5755
|
+
reachable: false,
|
|
5756
|
+
contract: { status: "unknown", sdk: CONTRACT_SHA256, live: null, files: null },
|
|
5757
|
+
problems: [],
|
|
5758
|
+
checkedAt
|
|
5759
|
+
};
|
|
5760
|
+
if (typeof doFetch !== "function") {
|
|
5761
|
+
return { ...base, problems: ["No fetch implementation available; pass `fetch` explicitly."] };
|
|
5762
|
+
}
|
|
5763
|
+
const controller = new AbortController();
|
|
5764
|
+
const onAbort = () => controller.abort(options.signal?.reason);
|
|
5765
|
+
options.signal?.addEventListener("abort", onAbort, { once: true });
|
|
5766
|
+
if (options.signal?.aborted) controller.abort(options.signal.reason);
|
|
5767
|
+
const timer = setTimeout(() => controller.abort(new Error(`Contract probe timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
5768
|
+
let response;
|
|
5769
|
+
try {
|
|
5770
|
+
response = await doFetch(`${baseUrl}/health/contract`, {
|
|
5771
|
+
method: "GET",
|
|
5772
|
+
headers: { accept: "application/json" },
|
|
5773
|
+
signal: controller.signal
|
|
5774
|
+
});
|
|
5775
|
+
} catch (error) {
|
|
5776
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
5777
|
+
return { ...base, problems: [`node-shop at ${baseUrl} could not be reached: ${detail}`] };
|
|
5778
|
+
} finally {
|
|
5779
|
+
clearTimeout(timer);
|
|
5780
|
+
options.signal?.removeEventListener("abort", onAbort);
|
|
5781
|
+
}
|
|
5782
|
+
if (response.status === 404) {
|
|
5783
|
+
return {
|
|
5784
|
+
...base,
|
|
5785
|
+
reachable: true,
|
|
5786
|
+
problems: [
|
|
5787
|
+
`node-shop at ${baseUrl} does not serve GET /health/contract, so the contract cannot be verified. Deploy a node-shop that includes it.`
|
|
5788
|
+
]
|
|
5789
|
+
};
|
|
5790
|
+
}
|
|
5791
|
+
if (!response.ok) {
|
|
5792
|
+
return {
|
|
5793
|
+
...base,
|
|
5794
|
+
reachable: true,
|
|
5795
|
+
problems: [`node-shop at ${baseUrl} answered ${response.status} for GET /health/contract; contract not verified.`]
|
|
5796
|
+
};
|
|
5797
|
+
}
|
|
5798
|
+
let body;
|
|
5799
|
+
try {
|
|
5800
|
+
body = await response.json();
|
|
5801
|
+
} catch {
|
|
5802
|
+
return { ...base, reachable: true, problems: [`node-shop at ${baseUrl} returned a non-JSON contract fingerprint.`] };
|
|
5803
|
+
}
|
|
5804
|
+
const live = typeof body.contractSha256 === "string" && body.contractSha256 ? body.contractSha256 : null;
|
|
5805
|
+
const files = typeof body.files === "number" ? body.files : null;
|
|
5806
|
+
if (!live) {
|
|
5807
|
+
return {
|
|
5808
|
+
...base,
|
|
5809
|
+
reachable: true,
|
|
5810
|
+
contract: { ...base.contract, files },
|
|
5811
|
+
problems: [`node-shop at ${baseUrl} could not compute its own contract fingerprint; contract not verified.`]
|
|
5812
|
+
};
|
|
5813
|
+
}
|
|
5814
|
+
if (live !== CONTRACT_SHA256) {
|
|
5815
|
+
return {
|
|
5816
|
+
...base,
|
|
5817
|
+
reachable: true,
|
|
5818
|
+
contract: { status: "drift", sdk: CONTRACT_SHA256, live, files },
|
|
5819
|
+
problems: [
|
|
5820
|
+
`Contract drift: node-shop at ${baseUrl} speaks ${live.slice(0, 12)}, @cronvello/shop-sdk ${SDK_VERSION} was built against ${CONTRACT_SHA256.slice(0, 12)}. Pin a newer SDK version, or deploy the node-shop the SDK was built from.`
|
|
5821
|
+
]
|
|
5822
|
+
};
|
|
5823
|
+
}
|
|
5824
|
+
return {
|
|
5825
|
+
...base,
|
|
5826
|
+
ok: true,
|
|
5827
|
+
reachable: true,
|
|
5828
|
+
contract: { status: "match", sdk: CONTRACT_SHA256, live, files }
|
|
5829
|
+
};
|
|
5830
|
+
}
|
|
5831
|
+
|
|
5832
|
+
exports.CONTRACT_SHA256 = CONTRACT_SHA256;
|
|
5723
5833
|
exports.SHOP_API_URL = SHOP_API_URL;
|
|
5724
5834
|
exports.ShopApiError = ShopApiError;
|
|
5725
5835
|
exports.ShopConfigurationError = ShopConfigurationError;
|
|
@@ -5774,5 +5884,6 @@ exports.apiRoutes_users = apiRoutes_users;
|
|
|
5774
5884
|
exports.apiRoutes_variant_entitlements = apiRoutes_variant_entitlements;
|
|
5775
5885
|
exports.apiRoutes_webhooks = apiRoutes_webhooks;
|
|
5776
5886
|
exports.createShopClient = createShopClient;
|
|
5887
|
+
exports.diagnoseShop = diagnoseShop;
|
|
5777
5888
|
//# sourceMappingURL=index.cjs.map
|
|
5778
5889
|
//# sourceMappingURL=index.cjs.map
|