import { listUserSecretNames, ADMIN_ACCESS_TOKEN_SECRET, CLIENT_ID_SECRET, CLIENT_SECRET_SECRET, resolveAuthMode, resolveShop, } from './lib/client.ts' import { runShopHelperSelfCheck } from './lib/shop.ts' import { getShop } from './shop.ts' import type { ShopifyClientOptions } from './types.ts' export type ShopifySmokeTestResult = { ok: boolean selfCheck: { ok: true; checks: number } live: boolean authMode: 'admin-token' | 'client-credentials' | null shop: string | null shopName: string | null setup: { secrets: { shopifyAdminAccessToken: boolean shopifyClientId: boolean shopifyClientSecret: boolean } nextSteps: Array } } /** * Local helper checks, plus an optional live `shop { name }` read. * * Pass `shop` (and have secrets saved) to exercise credentials. Without * them this still returns `{ ok: true, live: false }` and setup URLs so * the package is forkable before anyone connects a store. * * @example * import smokeTest from 'kody:@kody/shopify/smoke-test' * const result = await smokeTest({ shop: 'acme' }) */ export async function smokeTest( params: ShopifyClientOptions = {}, ): Promise { const selfCheck = runShopHelperSelfCheck() const names = await listUserSecretNames() const secrets = { shopifyAdminAccessToken: names.has(ADMIN_ACCESS_TOKEN_SECRET), shopifyClientId: names.has(CLIENT_ID_SECRET), shopifyClientSecret: names.has(CLIENT_SECRET_SECRET), } const nextSteps: Array = [] if (!secrets.shopifyAdminAccessToken && !(secrets.shopifyClientId && secrets.shopifyClientSecret)) { nextSteps.push( 'Save shopifyClientId and shopifyClientSecret from the Shopify Dev Dashboard, or shopifyAdminAccessToken from a legacy custom app.', ) nextSteps.push( 'https://kody.codes/account/secrets/new?name=shopifyClientId&description=Shopify%20Dev%20Dashboard%20client%20id&scope=user', ) nextSteps.push( 'https://kody.codes/account/secrets/new?name=shopifyClientSecret&description=Shopify%20Dev%20Dashboard%20client%20secret&scope=user', ) } let shop: string | null = null try { shop = await resolveShop(params.shop) } catch { shop = null nextSteps.push( 'Pass shop: "your-store" (the *.myshopify.com handle) or set a default after forking via kody:@kody/shopify/config.', ) } if (shop) { nextSteps.push( `Approve host ${shop}.myshopify.com in the account secrets UI after the secret is saved.`, ) } const canLive = Boolean(shop) && (secrets.shopifyAdminAccessToken || (secrets.shopifyClientId && secrets.shopifyClientSecret)) if (!canLive) { return { ok: true, selfCheck, live: false, authMode: null, shop, shopName: null, setup: { secrets, nextSteps }, } } const authMode = await resolveAuthMode() const profile = await getShop({ shop: shop || undefined, apiVersion: params.apiVersion }) return { ok: true, selfCheck, live: true, authMode, shop: profile.myshopifyDomain, shopName: profile.name, setup: { secrets, nextSteps: [] }, } } /** Default export: smoke test. */ export default smokeTest