better-ship 0.25.0 → 0.26.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/auth-secondary-storage-b9ptwPSB.d.ts +37 -0
- package/dist/auth-secondary-storage-b9ptwPSB.d.ts.map +1 -0
- package/dist/better-auth/secondary-storage.d.ts +1 -1
- package/dist/bin/notify-ci.d.ts +1 -0
- package/dist/bin/notify-ci.js +24 -0
- package/dist/bin/notify-ci.js.map +1 -0
- package/dist/client-Dv1Ch7yY.js +20 -0
- package/dist/client-Dv1Ch7yY.js.map +1 -0
- package/dist/cloudflare/auth-secondary-storage.d.ts +2 -36
- package/dist/cloudflare/durable-object-client.js +1 -1
- package/dist/cloudflare/durable-object-errors.js +2 -47
- package/dist/cloudflare/kv-client.js +1 -1
- package/dist/cloudflare/kv-errors.js +2 -143
- package/dist/cloudflare/r2-client.js +1 -1
- package/dist/cloudflare/r2-errors.js +2 -89
- package/dist/durable-object-errors-DkMFXQnK.js +48 -0
- package/dist/durable-object-errors-DkMFXQnK.js.map +1 -0
- package/dist/kv-errors-BUTpFy0t.js +144 -0
- package/dist/kv-errors-BUTpFy0t.js.map +1 -0
- package/dist/metrics-CWv37yf9.js +30 -0
- package/dist/metrics-CWv37yf9.js.map +1 -0
- package/dist/metrics-cv9P5nvk.d.ts +19 -0
- package/dist/metrics-cv9P5nvk.d.ts.map +1 -0
- package/dist/payment-service-DUYd3Itt.d.ts +52 -0
- package/dist/payment-service-DUYd3Itt.d.ts.map +1 -0
- package/dist/payment-service.error-CqF7GkNp.js +30 -0
- package/dist/payment-service.error-CqF7GkNp.js.map +1 -0
- package/dist/posthog/metrics.d.ts +2 -18
- package/dist/posthog/metrics.js +2 -29
- package/dist/posthog/server.d.ts +1 -1
- package/dist/posthog/server.js +1 -1
- package/dist/r2-errors-rk7n7rvk.js +90 -0
- package/dist/r2-errors-rk7n7rvk.js.map +1 -0
- package/dist/request-4vJEWxyZ.js +21 -0
- package/dist/request-4vJEWxyZ.js.map +1 -0
- package/dist/slack-webhook-j1FCPeu8.js +270 -0
- package/dist/slack-webhook-j1FCPeu8.js.map +1 -0
- package/dist/slack.d.ts +102 -0
- package/dist/slack.d.ts.map +1 -0
- package/dist/slack.js +3 -0
- package/dist/stripe/client.js +2 -19
- package/dist/stripe/payment-service.d.ts +2 -51
- package/dist/stripe/payment-service.error.js +2 -29
- package/dist/stripe/payment-service.js +1 -1
- package/dist/stripe/request.js +2 -20
- package/dist/stripe-fixture-yFUknTJO.js +33 -0
- package/dist/stripe-fixture-yFUknTJO.js.map +1 -0
- package/dist/testing/payment-service.d.ts +1 -1
- package/dist/testing/payment-service.js +2 -2
- package/dist/testing/stripe.js +2 -32
- package/package.json +6 -1
- package/src/infrastructure/slack/ci-message.ts +276 -0
- package/src/infrastructure/slack/index.ts +10 -0
- package/src/infrastructure/slack/notify-ci.ts +22 -0
- package/src/infrastructure/slack/slack-webhook.ts +36 -0
- package/dist/cloudflare/auth-secondary-storage.d.ts.map +0 -1
- package/dist/cloudflare/durable-object-errors.js.map +0 -1
- package/dist/cloudflare/kv-errors.js.map +0 -1
- package/dist/cloudflare/r2-errors.js.map +0 -1
- package/dist/posthog/metrics.d.ts.map +0 -1
- package/dist/posthog/metrics.js.map +0 -1
- package/dist/stripe/client.js.map +0 -1
- package/dist/stripe/payment-service.d.ts.map +0 -1
- package/dist/stripe/payment-service.error.js.map +0 -1
- package/dist/stripe/request.js.map +0 -1
- package/dist/testing/stripe.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack-webhook-j1FCPeu8.js","names":[],"sources":["../src/infrastructure/slack/ci-message.ts","../src/infrastructure/slack/slack-webhook.ts"],"sourcesContent":["import { z } from 'zod'\n\n/** The result of one CI job or step, in GitHub Actions terms. */\nexport type CiOutcome = 'success' | 'failure' | 'cancelled' | 'skipped'\n\n/** What the run delivers after its checks pass. */\nexport type CiTarget =\n | { readonly kind: 'check' }\n | {\n readonly kind: 'deploy'\n readonly accountId: string\n readonly worker: string\n readonly siteUrl: string\n /** Absent when the run reached no deploy, such as a pull request. */\n readonly versionId: string | undefined\n }\n | {\n readonly kind: 'publish'\n readonly packageName: string\n /** Absent when npm already has the package version. */\n readonly version: string | undefined\n }\n\n/** One CI run, parsed from the environment that the workflow sets. */\nexport interface CiRun {\n readonly repository: string\n readonly commitSha: string\n readonly ref:\n | { readonly kind: 'branch'; readonly name: string }\n | {\n readonly kind: 'pullRequest'\n readonly number: number\n readonly url: string\n readonly title: string\n }\n readonly runUrl: string\n readonly jobs: ReadonlyArray<CiStepResult>\n readonly steps: ReadonlyArray<CiStepResult>\n readonly target: CiTarget\n}\n\n/** A named job or step and its outcome. */\nexport interface CiStepResult {\n readonly name: string\n readonly outcome: CiOutcome\n}\n\n/** The commit facts that only git knows. */\nexport interface CiCommit {\n readonly subject: string\n readonly author: string\n}\n\n/** A Slack incoming-webhook payload. */\nexport interface SlackMessage {\n readonly text: string\n readonly blocks: ReadonlyArray<SlackBlock>\n}\n\ntype SlackElement =\n | { readonly type: 'mrkdwn'; readonly text: string }\n | { readonly type: 'image'; readonly image_url: string; readonly alt_text: string }\n\ntype SlackBlock =\n | { readonly type: 'section'; readonly text: { readonly type: 'mrkdwn'; readonly text: string } }\n | { readonly type: 'context'; readonly elements: ReadonlyArray<SlackElement> }\n\n/** The CI environment could not be parsed. `issues` names each invalid variable. */\nexport class CiRunParseError extends Error {\n readonly _tag = 'CiRunParseError' as const\n\n constructor(\n readonly issues: ReadonlyArray<string>,\n override readonly cause: unknown,\n ) {\n super(`Invalid CI environment: ${issues.join(', ')}`)\n }\n}\n\nconst OutcomeSchema = z.enum(['success', 'failure', 'cancelled', 'skipped'])\n\nconst jsonRecord = <T extends z.ZodType>(value: T) =>\n z\n .string()\n .transform((text, context) => {\n try {\n const value: unknown = JSON.parse(text)\n return value\n } catch {\n context.addIssue({ code: 'custom', message: 'Invalid JSON' })\n return z.NEVER\n }\n })\n .pipe(z.record(z.string(), value))\n\nconst CiEnvSchema = z.object({\n REPO: z.string().regex(/^[\\w.-]+\\/[\\w.-]+$/),\n COMMIT_SHA: z.string().regex(/^[0-9a-f]{40}$/),\n BRANCH: z.string().min(1),\n RUN_URL: z.httpUrl(),\n JOBS_JSON: jsonRecord(z.object({ result: OutcomeSchema })).optional(),\n STEPS_JSON: jsonRecord(z.object({ outcome: OutcomeSchema })).optional(),\n PR_NUMBER: z.coerce.number().int().positive().optional(),\n PR_URL: z.httpUrl().optional(),\n PR_TITLE: z.string().min(1).optional(),\n ACTION: z.enum(['check', 'deploy', 'publish']).default('check'),\n CLOUDFLARE_ACCOUNT_ID: z.string().min(1).optional(),\n CLOUDFLARE_WORKER: z.string().min(1).optional(),\n SITE_URL: z.httpUrl().optional(),\n DEPLOY_VERSION_ID: z.string().min(1).optional(),\n NPM_PACKAGE: z.string().min(1).optional(),\n NPM_VERSION: z.string().min(1).optional(),\n})\n\ntype CiEnv = z.infer<typeof CiEnvSchema>\n\n/**\n * Parse the variables that a workflow passes to the notifier. GitHub expressions render a\n * missing value as an empty string, so an empty variable counts as unset.\n * @throws {CiRunParseError} when a variable is missing or invalid.\n */\nexport function parseCiRun(env: Readonly<Record<string, string | undefined>>): CiRun {\n const present = Object.fromEntries(Object.entries(env).filter(([, value]) => value !== ''))\n const parsed = CiEnvSchema.safeParse(present)\n if (!parsed.success) {\n const issues = parsed.error.issues.map((issue) => issue.path.join('.'))\n throw new CiRunParseError(issues, parsed.error)\n }\n return toCiRun(parsed.data)\n}\n\nfunction toCiRun(env: CiEnv): CiRun {\n const ref: CiRun['ref'] =\n env.PR_NUMBER !== undefined && env.PR_URL !== undefined && env.PR_TITLE !== undefined\n ? { kind: 'pullRequest', number: env.PR_NUMBER, url: env.PR_URL, title: env.PR_TITLE }\n : { kind: 'branch', name: env.BRANCH }\n return {\n repository: env.REPO,\n commitSha: env.COMMIT_SHA,\n ref,\n runUrl: env.RUN_URL,\n jobs: Object.entries(env.JOBS_JSON ?? {}).map(([id, job]) => ({\n name: displayName(id),\n outcome: job.result,\n })),\n steps: Object.entries(env.STEPS_JSON ?? {}).map(([id, step]) => ({\n name: displayName(id),\n outcome: step.outcome,\n })),\n target: toTarget(env),\n }\n}\n\nfunction toTarget(env: CiEnv): CiTarget {\n switch (env.ACTION) {\n case 'check':\n return { kind: 'check' }\n case 'deploy': {\n const { CLOUDFLARE_ACCOUNT_ID: accountId, CLOUDFLARE_WORKER: worker, SITE_URL: siteUrl } = env\n if (accountId === undefined || worker === undefined || siteUrl === undefined) {\n throw new CiRunParseError(\n ['CLOUDFLARE_ACCOUNT_ID', 'CLOUDFLARE_WORKER', 'SITE_URL'],\n undefined,\n )\n }\n return { kind: 'deploy', accountId, worker, siteUrl, versionId: env.DEPLOY_VERSION_ID }\n }\n case 'publish':\n if (env.NPM_PACKAGE === undefined) throw new CiRunParseError(['NPM_PACKAGE'], undefined)\n return { kind: 'publish', packageName: env.NPM_PACKAGE, version: env.NPM_VERSION }\n }\n}\n\n// A job or step id such as `check-and-build` reads as \"Check and build\".\nfunction displayName(id: string): string {\n const words = id.replaceAll(/[-_]/g, ' ')\n return words.charAt(0).toUpperCase() + words.slice(1)\n}\n\nconst logos = {\n depot: 'https://avatars.githubusercontent.com/u/68166601?s=64',\n github: 'https://avatars.githubusercontent.com/u/9919?s=64',\n cloudflare: 'https://avatars.githubusercontent.com/u/314135?s=64',\n npm: 'https://avatars.githubusercontent.com/u/6078720?s=64',\n} as const\n\n/** Build the four-line CI message: result, change, links, and identity. */\nexport function buildCiMessage(run: CiRun, commit: CiCommit): SlackMessage {\n const headline = headlineFor(run)\n const change = run.ref.kind === 'pullRequest' ? run.ref.title : commit.subject\n return {\n text: `${headline} — ${change}`,\n blocks: [\n { type: 'section', text: { type: 'mrkdwn', text: `*${headline}*\\n${escape(change)}` } },\n { type: 'context', elements: linkElements(run) },\n { type: 'context', elements: [{ type: 'mrkdwn', text: identityLine(run, commit) }] },\n ],\n }\n}\n\nfunction headlineFor(run: CiRun): string {\n const failedJobs = namesWith(run.jobs, 'failure')\n if (failedJobs) return `:x: CI failed: ${failedJobs}`\n const cancelledJobs = namesWith(run.jobs, 'cancelled')\n if (cancelledJobs) return `:white_circle: CI cancelled: ${cancelledJobs}`\n const failedSteps = namesWith(run.steps, 'failure')\n const { target } = run\n switch (target.kind) {\n case 'check':\n return failedSteps ? `:x: CI failed: ${failedSteps}` : ':white_check_mark: CI passed'\n case 'deploy':\n if (failedSteps) return `:x: Deploy failed: ${failedSteps}`\n return target.versionId === undefined\n ? ':white_check_mark: CI passed'\n : ':white_check_mark: Deployed to production'\n case 'publish':\n if (failedSteps) return `:x: Publish failed: ${failedSteps}`\n return target.version === undefined\n ? ':white_check_mark: CI passed, nothing to publish'\n : `:white_check_mark: Published ${target.packageName} ${target.version}`\n }\n}\n\nfunction namesWith(results: ReadonlyArray<CiStepResult>, outcome: CiOutcome): string {\n return results\n .filter((result) => result.outcome === outcome)\n .map((result) => result.name)\n .join(', ')\n}\n\nfunction linkElements(run: CiRun): ReadonlyArray<SlackElement> {\n const runHost = new URL(run.runUrl).hostname\n const runLogo = runHost.endsWith('github.com') ? logos.github : logos.depot\n const elements: SlackElement[] = [\n { type: 'image', image_url: runLogo, alt_text: runHost },\n { type: 'mrkdwn', text: `<${run.runUrl}|CI run>` },\n ]\n const { target } = run\n if (target.kind === 'deploy' && target.versionId !== undefined) {\n const dashboard = `https://dash.cloudflare.com/${target.accountId}/workers/services/view/${target.worker}/production/deployments`\n const site = new URL(target.siteUrl)\n elements.push(\n { type: 'mrkdwn', text: '·' },\n { type: 'image', image_url: logos.cloudflare, alt_text: 'Cloudflare' },\n { type: 'mrkdwn', text: `<${dashboard}|Version \\`${target.versionId.slice(0, 8)}\\`>` },\n { type: 'mrkdwn', text: `· :globe_with_meridians: <${site.origin}|${site.host}>` },\n )\n }\n if (target.kind === 'publish' && target.version !== undefined) {\n const npm = `https://www.npmjs.com/package/${target.packageName}/v/${target.version}`\n elements.push(\n { type: 'mrkdwn', text: '·' },\n { type: 'image', image_url: logos.npm, alt_text: 'npm' },\n { type: 'mrkdwn', text: `<${npm}|${target.packageName}@${target.version}>` },\n )\n }\n return elements\n}\n\nfunction identityLine(run: CiRun, commit: CiCommit): string {\n const repository = run.repository.split('/').at(-1) ?? run.repository\n const ref =\n run.ref.kind === 'pullRequest' ? `<${run.ref.url}|PR #${run.ref.number}>` : run.ref.name\n const commitUrl = `https://github.com/${run.repository}/commit/${run.commitSha}`\n return [\n repository,\n ref,\n `<${commitUrl}|\\`${run.commitSha.slice(0, 7)}\\`>`,\n escape(commit.author),\n ].join(' · ')\n}\n\n// Slack mrkdwn treats these three characters as markup.\nfunction escape(text: string): string {\n return text.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>')\n}\n","import type { SlackMessage } from './ci-message.ts'\n\n/** Slack refused the message or could not be reached. */\nexport class SlackWebhookError extends Error {\n readonly _tag = 'SlackWebhookError' as const\n\n constructor(\n readonly status: number | undefined,\n override readonly cause: unknown,\n ) {\n super(status === undefined ? 'Slack webhook unreachable' : `Slack webhook returned ${status}`)\n }\n}\n\n/**\n * Post one message to a Slack incoming webhook.\n * @throws {SlackWebhookError} when the request fails or Slack answers with an error status.\n */\nexport async function postSlackMessage(\n webhookUrl: string,\n message: SlackMessage,\n fetcher: typeof fetch = fetch,\n): Promise<void> {\n let response: Response\n try {\n response = await fetcher(webhookUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(message),\n signal: AbortSignal.timeout(30_000),\n })\n } catch (cause) {\n throw new SlackWebhookError(undefined, cause)\n }\n if (!response.ok) throw new SlackWebhookError(response.status, await response.text())\n}\n"],"mappings":";;;;AAoEA,IAAa,kBAAb,cAAqC,MAAM;CAI9B;CACS;CAJpB,AAAS,OAAO;CAEhB,YACE,AAAS,QACT,AAAkB,OAClB;EACA,MAAM,2BAA2B,OAAO,KAAK,IAAI,GAAG;EAH3C;EACS;CAGpB;AACF;AAEA,MAAM,gBAAgB,EAAE,KAAK;CAAC;CAAW;CAAW;CAAa;AAAS,CAAC;AAE3E,MAAM,cAAmC,UACvC,EACG,OAAO,CAAC,CACR,WAAW,MAAM,YAAY;CAC5B,IAAI;EAEF,OADuB,KAAK,MAAM,IACvB;CACb,QAAQ;EACN,QAAQ,SAAS;GAAE,MAAM;GAAU,SAAS;EAAe,CAAC;EAC5D,OAAO,EAAE;CACX;AACF,CAAC,CAAC,CACD,KAAK,EAAE,OAAO,EAAE,OAAO,GAAG,KAAK,CAAC;AAErC,MAAM,cAAc,EAAE,OAAO;CAC3B,MAAM,EAAE,OAAO,CAAC,CAAC,MAAM,oBAAoB;CAC3C,YAAY,EAAE,OAAO,CAAC,CAAC,MAAM,gBAAgB;CAC7C,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACxB,SAAS,EAAE,QAAQ;CACnB,WAAW,WAAW,EAAE,OAAO,EAAE,QAAQ,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS;CACpE,YAAY,WAAW,EAAE,OAAO,EAAE,SAAS,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS;CACtE,WAAW,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;CACvD,QAAQ,EAAE,QAAQ,CAAC,CAAC,SAAS;CAC7B,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CACrC,QAAQ,EAAE,KAAK;EAAC;EAAS;EAAU;CAAS,CAAC,CAAC,CAAC,QAAQ,OAAO;CAC9D,uBAAuB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CAClD,mBAAmB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CAC9C,UAAU,EAAE,QAAQ,CAAC,CAAC,SAAS;CAC/B,mBAAmB,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CAC9C,aAAa,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;CACxC,aAAa,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;AAC1C,CAAC;;;;;;AASD,SAAgB,WAAW,KAA0D;CACnF,MAAM,UAAU,OAAO,YAAY,OAAO,QAAQ,GAAG,CAAC,CAAC,QAAQ,GAAG,WAAW,UAAU,EAAE,CAAC;CAC1F,MAAM,SAAS,YAAY,UAAU,OAAO;CAC5C,IAAI,CAAC,OAAO,SAAS;EACnB,MAAM,SAAS,OAAO,MAAM,OAAO,KAAK,UAAU,MAAM,KAAK,KAAK,GAAG,CAAC;EACtE,MAAM,IAAI,gBAAgB,QAAQ,OAAO,KAAK;CAChD;CACA,OAAO,QAAQ,OAAO,IAAI;AAC5B;AAEA,SAAS,QAAQ,KAAmB;CAClC,MAAM,MACJ,IAAI,cAAc,UAAa,IAAI,WAAW,UAAa,IAAI,aAAa,SACxE;EAAE,MAAM;EAAe,QAAQ,IAAI;EAAW,KAAK,IAAI;EAAQ,OAAO,IAAI;CAAS,IACnF;EAAE,MAAM;EAAU,MAAM,IAAI;CAAO;CACzC,OAAO;EACL,YAAY,IAAI;EAChB,WAAW,IAAI;EACf;EACA,QAAQ,IAAI;EACZ,MAAM,OAAO,QAAQ,IAAI,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,UAAU;GAC5D,MAAM,YAAY,EAAE;GACpB,SAAS,IAAI;EACf,EAAE;EACF,OAAO,OAAO,QAAQ,IAAI,cAAc,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,WAAW;GAC/D,MAAM,YAAY,EAAE;GACpB,SAAS,KAAK;EAChB,EAAE;EACF,QAAQ,SAAS,GAAG;CACtB;AACF;AAEA,SAAS,SAAS,KAAsB;CACtC,QAAQ,IAAI,QAAZ;EACE,KAAK,SACH,OAAO,EAAE,MAAM,QAAQ;EACzB,KAAK,UAAU;GACb,MAAM,EAAE,uBAAuB,WAAW,mBAAmB,QAAQ,UAAU,YAAY;GAC3F,IAAI,cAAc,UAAa,WAAW,UAAa,YAAY,QACjE,MAAM,IAAI,gBACR;IAAC;IAAyB;IAAqB;GAAU,GACzD,MACF;GAEF,OAAO;IAAE,MAAM;IAAU;IAAW;IAAQ;IAAS,WAAW,IAAI;GAAkB;EACxF;EACA,KAAK;GACH,IAAI,IAAI,gBAAgB,QAAW,MAAM,IAAI,gBAAgB,CAAC,aAAa,GAAG,MAAS;GACvF,OAAO;IAAE,MAAM;IAAW,aAAa,IAAI;IAAa,SAAS,IAAI;GAAY;CACrF;AACF;AAGA,SAAS,YAAY,IAAoB;CACvC,MAAM,QAAQ,GAAG,WAAW,SAAS,GAAG;CACxC,OAAO,MAAM,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,MAAM,MAAM,CAAC;AACtD;AAEA,MAAM,QAAQ;CACZ,OAAO;CACP,QAAQ;CACR,YAAY;CACZ,KAAK;AACP;;AAGA,SAAgB,eAAe,KAAY,QAAgC;CACzE,MAAM,WAAW,YAAY,GAAG;CAChC,MAAM,SAAS,IAAI,IAAI,SAAS,gBAAgB,IAAI,IAAI,QAAQ,OAAO;CACvE,OAAO;EACL,MAAM,GAAG,SAAS,KAAK;EACvB,QAAQ;GACN;IAAE,MAAM;IAAW,MAAM;KAAE,MAAM;KAAU,MAAM,IAAI,SAAS,KAAK,OAAO,MAAM;IAAI;GAAE;GACtF;IAAE,MAAM;IAAW,UAAU,aAAa,GAAG;GAAE;GAC/C;IAAE,MAAM;IAAW,UAAU,CAAC;KAAE,MAAM;KAAU,MAAM,aAAa,KAAK,MAAM;IAAE,CAAC;GAAE;EACrF;CACF;AACF;AAEA,SAAS,YAAY,KAAoB;CACvC,MAAM,aAAa,UAAU,IAAI,MAAM,SAAS;CAChD,IAAI,YAAY,OAAO,kBAAkB;CACzC,MAAM,gBAAgB,UAAU,IAAI,MAAM,WAAW;CACrD,IAAI,eAAe,OAAO,gCAAgC;CAC1D,MAAM,cAAc,UAAU,IAAI,OAAO,SAAS;CAClD,MAAM,EAAE,WAAW;CACnB,QAAQ,OAAO,MAAf;EACE,KAAK,SACH,OAAO,cAAc,kBAAkB,gBAAgB;EACzD,KAAK;GACH,IAAI,aAAa,OAAO,sBAAsB;GAC9C,OAAO,OAAO,cAAc,SACxB,iCACA;EACN,KAAK;GACH,IAAI,aAAa,OAAO,uBAAuB;GAC/C,OAAO,OAAO,YAAY,SACtB,qDACA,gCAAgC,OAAO,YAAY,GAAG,OAAO;CACrE;AACF;AAEA,SAAS,UAAU,SAAsC,SAA4B;CACnF,OAAO,QACJ,QAAQ,WAAW,OAAO,YAAY,OAAO,CAAC,CAC9C,KAAK,WAAW,OAAO,IAAI,CAAC,CAC5B,KAAK,IAAI;AACd;AAEA,SAAS,aAAa,KAAyC;CAC7D,MAAM,UAAU,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC;CAEpC,MAAM,WAA2B,CAC/B;EAAE,MAAM;EAAS,WAFH,QAAQ,SAAS,YAAY,IAAI,MAAM,SAAS,MAAM;EAE/B,UAAU;CAAQ,GACvD;EAAE,MAAM;EAAU,MAAM,IAAI,IAAI,OAAO;CAAU,CACnD;CACA,MAAM,EAAE,WAAW;CACnB,IAAI,OAAO,SAAS,YAAY,OAAO,cAAc,QAAW;EAC9D,MAAM,YAAY,+BAA+B,OAAO,UAAU,yBAAyB,OAAO,OAAO;EACzG,MAAM,OAAO,IAAI,IAAI,OAAO,OAAO;EACnC,SAAS,KACP;GAAE,MAAM;GAAU,MAAM;EAAI,GAC5B;GAAE,MAAM;GAAS,WAAW,MAAM;GAAY,UAAU;EAAa,GACrE;GAAE,MAAM;GAAU,MAAM,IAAI,UAAU,aAAa,OAAO,UAAU,MAAM,GAAG,CAAC,EAAE;EAAK,GACrF;GAAE,MAAM;GAAU,MAAM,8BAA8B,KAAK,OAAO,GAAG,KAAK,KAAK;EAAG,CACpF;CACF;CACA,IAAI,OAAO,SAAS,aAAa,OAAO,YAAY,QAAW;EAC7D,MAAM,MAAM,iCAAiC,OAAO,YAAY,KAAK,OAAO;EAC5E,SAAS,KACP;GAAE,MAAM;GAAU,MAAM;EAAI,GAC5B;GAAE,MAAM;GAAS,WAAW,MAAM;GAAK,UAAU;EAAM,GACvD;GAAE,MAAM;GAAU,MAAM,IAAI,IAAI,GAAG,OAAO,YAAY,GAAG,OAAO,QAAQ;EAAG,CAC7E;CACF;CACA,OAAO;AACT;AAEA,SAAS,aAAa,KAAY,QAA0B;CAK1D,OAAO;EAJY,IAAI,WAAW,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,IAAI;EAEzD,IAAI,IAAI,SAAS,gBAAgB,IAAI,IAAI,IAAI,IAAI,OAAO,IAAI,IAAI,OAAO,KAAK,IAAI,IAAI;EAKpF,IAAI,sBAJkC,IAAI,WAAW,UAAU,IAAI,YAIrD,KAAK,IAAI,UAAU,MAAM,GAAG,CAAC,EAAE;EAC7C,OAAO,OAAO,MAAM;CACtB,CAAC,CAAC,KAAK,OAAO;AAChB;AAGA,SAAS,OAAO,MAAsB;CACpC,OAAO,KAAK,WAAW,KAAK,OAAO,CAAC,CAAC,WAAW,KAAK,MAAM,CAAC,CAAC,WAAW,KAAK,MAAM;AACrF;;;;;AChRA,IAAa,oBAAb,cAAuC,MAAM;CAIhC;CACS;CAJpB,AAAS,OAAO;CAEhB,YACE,AAAS,QACT,AAAkB,OAClB;EACA,MAAM,WAAW,SAAY,8BAA8B,0BAA0B,QAAQ;EAHpF;EACS;CAGpB;AACF;;;;;AAMA,eAAsB,iBACpB,YACA,SACA,UAAwB,OACT;CACf,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,QAAQ,YAAY;GACnC,QAAQ;GACR,SAAS,EAAE,gBAAgB,mBAAmB;GAC9C,MAAM,KAAK,UAAU,OAAO;GAC5B,QAAQ,YAAY,QAAQ,GAAM;EACpC,CAAC;CACH,SAAS,OAAO;EACd,MAAM,IAAI,kBAAkB,QAAW,KAAK;CAC9C;CACA,IAAI,CAAC,SAAS,IAAI,MAAM,IAAI,kBAAkB,SAAS,QAAQ,MAAM,SAAS,KAAK,CAAC;AACtF"}
|
package/dist/slack.d.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
//#region src/infrastructure/slack/ci-message.d.ts
|
|
2
|
+
/** The result of one CI job or step, in GitHub Actions terms. */
|
|
3
|
+
type CiOutcome = 'success' | 'failure' | 'cancelled' | 'skipped';
|
|
4
|
+
/** What the run delivers after its checks pass. */
|
|
5
|
+
type CiTarget = {
|
|
6
|
+
readonly kind: 'check';
|
|
7
|
+
} | {
|
|
8
|
+
readonly kind: 'deploy';
|
|
9
|
+
readonly accountId: string;
|
|
10
|
+
readonly worker: string;
|
|
11
|
+
readonly siteUrl: string;
|
|
12
|
+
/** Absent when the run reached no deploy, such as a pull request. */
|
|
13
|
+
readonly versionId: string | undefined;
|
|
14
|
+
} | {
|
|
15
|
+
readonly kind: 'publish';
|
|
16
|
+
readonly packageName: string;
|
|
17
|
+
/** Absent when npm already has the package version. */
|
|
18
|
+
readonly version: string | undefined;
|
|
19
|
+
};
|
|
20
|
+
/** One CI run, parsed from the environment that the workflow sets. */
|
|
21
|
+
interface CiRun {
|
|
22
|
+
readonly repository: string;
|
|
23
|
+
readonly commitSha: string;
|
|
24
|
+
readonly ref: {
|
|
25
|
+
readonly kind: 'branch';
|
|
26
|
+
readonly name: string;
|
|
27
|
+
} | {
|
|
28
|
+
readonly kind: 'pullRequest';
|
|
29
|
+
readonly number: number;
|
|
30
|
+
readonly url: string;
|
|
31
|
+
readonly title: string;
|
|
32
|
+
};
|
|
33
|
+
readonly runUrl: string;
|
|
34
|
+
readonly jobs: ReadonlyArray<CiStepResult>;
|
|
35
|
+
readonly steps: ReadonlyArray<CiStepResult>;
|
|
36
|
+
readonly target: CiTarget;
|
|
37
|
+
}
|
|
38
|
+
/** A named job or step and its outcome. */
|
|
39
|
+
interface CiStepResult {
|
|
40
|
+
readonly name: string;
|
|
41
|
+
readonly outcome: CiOutcome;
|
|
42
|
+
}
|
|
43
|
+
/** The commit facts that only git knows. */
|
|
44
|
+
interface CiCommit {
|
|
45
|
+
readonly subject: string;
|
|
46
|
+
readonly author: string;
|
|
47
|
+
}
|
|
48
|
+
/** A Slack incoming-webhook payload. */
|
|
49
|
+
interface SlackMessage {
|
|
50
|
+
readonly text: string;
|
|
51
|
+
readonly blocks: ReadonlyArray<SlackBlock>;
|
|
52
|
+
}
|
|
53
|
+
type SlackElement = {
|
|
54
|
+
readonly type: 'mrkdwn';
|
|
55
|
+
readonly text: string;
|
|
56
|
+
} | {
|
|
57
|
+
readonly type: 'image';
|
|
58
|
+
readonly image_url: string;
|
|
59
|
+
readonly alt_text: string;
|
|
60
|
+
};
|
|
61
|
+
type SlackBlock = {
|
|
62
|
+
readonly type: 'section';
|
|
63
|
+
readonly text: {
|
|
64
|
+
readonly type: 'mrkdwn';
|
|
65
|
+
readonly text: string;
|
|
66
|
+
};
|
|
67
|
+
} | {
|
|
68
|
+
readonly type: 'context';
|
|
69
|
+
readonly elements: ReadonlyArray<SlackElement>;
|
|
70
|
+
};
|
|
71
|
+
/** The CI environment could not be parsed. `issues` names each invalid variable. */
|
|
72
|
+
export declare class CiRunParseError extends Error {
|
|
73
|
+
readonly issues: ReadonlyArray<string>;
|
|
74
|
+
readonly cause: unknown;
|
|
75
|
+
readonly _tag: 'CiRunParseError';
|
|
76
|
+
constructor(issues: ReadonlyArray<string>, cause: unknown);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Parse the variables that a workflow passes to the notifier. GitHub expressions render a
|
|
80
|
+
* missing value as an empty string, so an empty variable counts as unset.
|
|
81
|
+
* @throws {CiRunParseError} when a variable is missing or invalid.
|
|
82
|
+
*/
|
|
83
|
+
export declare function parseCiRun(env: Readonly<Record<string, string | undefined>>): CiRun;
|
|
84
|
+
/** Build the four-line CI message: result, change, links, and identity. */
|
|
85
|
+
export declare function buildCiMessage(run: CiRun, commit: CiCommit): SlackMessage;
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region src/infrastructure/slack/slack-webhook.d.ts
|
|
88
|
+
/** Slack refused the message or could not be reached. */
|
|
89
|
+
export declare class SlackWebhookError extends Error {
|
|
90
|
+
readonly status: number | undefined;
|
|
91
|
+
readonly cause: unknown;
|
|
92
|
+
readonly _tag: 'SlackWebhookError';
|
|
93
|
+
constructor(status: number | undefined, cause: unknown);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Post one message to a Slack incoming webhook.
|
|
97
|
+
* @throws {SlackWebhookError} when the request fails or Slack answers with an error status.
|
|
98
|
+
*/
|
|
99
|
+
export declare function postSlackMessage(webhookUrl: string, message: SlackMessage, fetcher?: typeof fetch): Promise<void>;
|
|
100
|
+
//#endregion
|
|
101
|
+
export type { CiCommit, CiOutcome, CiRun, CiStepResult, CiTarget, SlackMessage };
|
|
102
|
+
//# sourceMappingURL=slack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.d.ts","names":[],"sources":["../src/infrastructure/slack/ci-message.ts","../src/infrastructure/slack/slack-webhook.ts"],"mappings":";;KAGY;;KAGA;WACG;;WAEA;WACA;WACA;WACA;;WAEA;;WAGA;WACA;;WAEA;;;UAIE;WACN;WACA;WACA;aACM;aAAyB;;aAEzB;aACA;aACA;aACA;;WAEN;WACA,MAAM,cAAc;WACpB,OAAO,cAAc;WACrB,QAAQ;;;UAIF;WACN;WACA,SAAS;;;UAIH;WACN;WACA;;;UAIM;WACN;WACA,QAAQ,cAAc;;KAG5B;WACU;WAAyB;;WACzB;WAAwB;WAA4B;;KAE9D;WACU;WAA0B;aAAiB;aAAyB;;;WACpE;WAA0B,UAAU,cAAc;;;qBAGpD,wBAAwB;WAIxB,QAAQ;WACC;WAJX;EAET,YACW,QAAQ,uBACC;;;;;;;wBAgDN,WAAW,KAAK,SAAS,sCAAsC;;wBAkE/D,eAAe,KAAK,OAAO,QAAQ,WAAW;;;;qBCxLjD,0BAA0B;WAI1B;WACS;WAJX;EAET,YACW,4BACS;;;;;;wBAUA,iBACpB,oBACA,SAAS,cACT,iBAAgB,QACf"}
|
package/dist/slack.js
ADDED
package/dist/stripe/client.js
CHANGED
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { n as createStripeClient, t as STRIPE_REQUEST_OPTIONS } from "../client-Dv1Ch7yY.js";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
/** Default SDK retries; client configuration and individual requests can override this value. */
|
|
5
|
-
const STRIPE_REQUEST_OPTIONS = Object.freeze({ maxNetworkRetries: 2 });
|
|
6
|
-
/**
|
|
7
|
-
* Construct a native Stripe client with fetch transport and two SDK retries by default.
|
|
8
|
-
* Native configuration overrides these defaults. Inject the client into application services.
|
|
9
|
-
*/
|
|
10
|
-
function createStripeClient(secretKey, options = {}) {
|
|
11
|
-
return new Stripe(secretKey, {
|
|
12
|
-
httpClient: Stripe.createFetchHttpClient(),
|
|
13
|
-
...STRIPE_REQUEST_OPTIONS,
|
|
14
|
-
...options
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
//#endregion
|
|
19
|
-
export { STRIPE_REQUEST_OPTIONS, createStripeClient };
|
|
20
|
-
//# sourceMappingURL=client.js.map
|
|
3
|
+
export { STRIPE_REQUEST_OPTIONS, createStripeClient };
|
|
@@ -1,51 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
/** Supply the same key and parameters when repeating one durable payment attempt. */
|
|
4
|
-
export type PaymentRequestOptions = Stripe.RequestOptions & Required<Pick<Stripe.RequestOptions, 'idempotencyKey'>>;
|
|
5
|
-
/** Native Checkout parameters; the service selects payment or setup mode. */
|
|
6
|
-
export type CheckoutInput = Omit<Stripe.Checkout.SessionCreateParams, 'mode'>;
|
|
7
|
-
/** A saved customer method; the service confirms the payment off-session. */
|
|
8
|
-
export type SavedMethodCharge = Omit<Stripe.PaymentIntentCreateParams, 'confirm' | 'off_session'> & Required<Pick<Stripe.PaymentIntentCreateParams, 'customer' | 'payment_method'>>;
|
|
9
|
-
/** Native customer response, including Stripe request metadata. */
|
|
10
|
-
export type CustomerResult = Awaited<ReturnType<Stripe['customers']['create']>>;
|
|
11
|
-
/** Native Checkout response. Its URL can be null; this does not confirm payment. */
|
|
12
|
-
export type CheckoutResult = Awaited<ReturnType<Stripe['checkout']['sessions']['create']>>;
|
|
13
|
-
/** Native PaymentIntent response. Applications decide what each status permits. */
|
|
14
|
-
export type PaymentResult = Awaited<ReturnType<Stripe['paymentIntents']['create']>>;
|
|
15
|
-
/**
|
|
16
|
-
* Stripe payment operations, with native types and stable keys for mutations.
|
|
17
|
-
* Rejects with PaymentServiceError for Stripe failures; non-Stripe failures propagate unchanged.
|
|
18
|
-
*/
|
|
19
|
-
export interface IPaymentService {
|
|
20
|
-
/** Create a customer; the application owns persistence and reuse of the customer link. */
|
|
21
|
-
createCustomer(input: Stripe.CustomerCreateParams, options: PaymentRequestOptions): Promise<CustomerResult>;
|
|
22
|
-
/** Create one-time payment checkout; application fulfillment requires verified payment confirmation. */
|
|
23
|
-
createCheckout(input: CheckoutInput, options: PaymentRequestOptions): Promise<CheckoutResult>;
|
|
24
|
-
/** Create checkout in setup mode. The application records consent and verifies the saved method's owner. */
|
|
25
|
-
setupPaymentMethod(input: CheckoutInput, options: PaymentRequestOptions): Promise<CheckoutResult>;
|
|
26
|
-
/** Confirm a saved method off-session. PaymentServiceError retains card errors in cause. */
|
|
27
|
-
chargeSavedMethod(input: SavedMethodCharge, options: PaymentRequestOptions): Promise<PaymentResult>;
|
|
28
|
-
/** Retrieve an existing payment without starting another payment attempt. */
|
|
29
|
-
getPayment(paymentId: string, params?: Stripe.PaymentIntentRetrieveParams, options?: Stripe.RequestOptions): Promise<PaymentResult>;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Ported from Typist's StripeClient request boundary; the native SDK now owns retries.
|
|
33
|
-
* The injected client owns retry and timeout defaults. Native request options can override them.
|
|
34
|
-
*/
|
|
35
|
-
export declare class StripePaymentService implements IPaymentService {
|
|
36
|
-
private readonly stripe;
|
|
37
|
-
/** Inject a native SDK instance; its transport, credentials, and API version remain caller-owned. */
|
|
38
|
-
constructor(stripe: Stripe);
|
|
39
|
-
/** Create a customer with a stable application key and preserve the native response. */
|
|
40
|
-
createCustomer(input: Stripe.CustomerCreateParams, options: PaymentRequestOptions): Promise<CustomerResult>;
|
|
41
|
-
/** Force payment mode after caller parameters; return the native Checkout Session. */
|
|
42
|
-
createCheckout(input: CheckoutInput, options: PaymentRequestOptions): Promise<CheckoutResult>;
|
|
43
|
-
/** Force setup mode after caller parameters; this operation does not charge the customer. */
|
|
44
|
-
setupPaymentMethod(input: CheckoutInput, options: PaymentRequestOptions): Promise<CheckoutResult>;
|
|
45
|
-
/** Force confirmation and off-session use; retain native card failures in PaymentServiceError.cause. */
|
|
46
|
-
chargeSavedMethod(input: SavedMethodCharge, options: PaymentRequestOptions): Promise<PaymentResult>;
|
|
47
|
-
/** Preserve every native status and response field when reconciling an existing payment. */
|
|
48
|
-
getPayment(paymentId: string, params?: Stripe.PaymentIntentRetrieveParams, options?: Stripe.RequestOptions): Promise<PaymentResult>;
|
|
49
|
-
}
|
|
50
|
-
//#endregion
|
|
51
|
-
//# sourceMappingURL=payment-service.d.ts.map
|
|
1
|
+
import { a as PaymentRequestOptions, c as StripePaymentService, i as IPaymentService, n as CheckoutResult, o as PaymentResult, r as CustomerResult, s as SavedMethodCharge, t as CheckoutInput } from "../payment-service-DUYd3Itt.js";
|
|
2
|
+
export { CheckoutInput, CheckoutResult, CustomerResult, IPaymentService, PaymentRequestOptions, PaymentResult, SavedMethodCharge, StripePaymentService };
|
|
@@ -1,30 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import Stripe from "stripe";
|
|
1
|
+
import { t as PaymentServiceError } from "../payment-service.error-CqF7GkNp.js";
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
/** A final Stripe request failure. The caller logs once; native details remain in cause. */
|
|
6
|
-
var PaymentServiceError = class extends AppError {
|
|
7
|
-
operation;
|
|
8
|
-
_tag = "PaymentServiceError";
|
|
9
|
-
classification;
|
|
10
|
-
/** Classify the final SDK error without scheduling another payment attempt. */
|
|
11
|
-
constructor(operation, cause) {
|
|
12
|
-
super(`Stripe request failed: ${operation}`, { cause });
|
|
13
|
-
this.operation = operation;
|
|
14
|
-
this.classification = classifyStripeError(cause);
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
function classifyStripeError(error) {
|
|
18
|
-
if (error.headers?.["stripe-should-retry"] === "false") return "terminal";
|
|
19
|
-
const status = error.statusCode;
|
|
20
|
-
if (status !== void 0 && status >= 400 && status < 500 && status !== 409 && status !== 429) return "terminal";
|
|
21
|
-
if (error instanceof Stripe.errors.StripeAuthenticationError || error instanceof Stripe.errors.StripePermissionError || error instanceof Stripe.errors.StripeInvalidRequestError || error instanceof Stripe.errors.StripeIdempotencyError || error instanceof Stripe.errors.StripeCardError) return "terminal";
|
|
22
|
-
if (error.headers?.["stripe-should-retry"] === "true") return "transient";
|
|
23
|
-
if (status === 409 || status === 429 || status !== void 0 && status >= 500) return "transient";
|
|
24
|
-
if (error instanceof Stripe.errors.StripeConnectionError || error instanceof Stripe.errors.StripeAPIError || error instanceof Stripe.errors.StripeRateLimitError) return "transient";
|
|
25
|
-
return "unknown";
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
//#endregion
|
|
29
|
-
export { PaymentServiceError };
|
|
30
|
-
//# sourceMappingURL=payment-service.error.js.map
|
|
3
|
+
export { PaymentServiceError };
|
package/dist/stripe/request.js
CHANGED
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import Stripe from "stripe";
|
|
1
|
+
import { t as stripeRequest } from "../request-4vJEWxyZ.js";
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Invoke one SDK operation; the SDK owns retries configured on its client or request.
|
|
7
|
-
* Convert every Stripe error to PaymentServiceError without logging; preserve the original error in cause.
|
|
8
|
-
* Non-Stripe failures propagate unchanged.
|
|
9
|
-
*/
|
|
10
|
-
async function stripeRequest(operation, work) {
|
|
11
|
-
try {
|
|
12
|
-
return await work();
|
|
13
|
-
} catch (cause) {
|
|
14
|
-
if (!(cause instanceof Stripe.errors.StripeError)) throw cause;
|
|
15
|
-
throw new PaymentServiceError(operation, cause);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
//#endregion
|
|
20
|
-
export { stripeRequest };
|
|
21
|
-
//# sourceMappingURL=request.js.map
|
|
3
|
+
export { stripeRequest };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { n as createStripeClient } from "./client-Dv1Ch7yY.js";
|
|
2
|
+
import Stripe from "stripe";
|
|
3
|
+
|
|
4
|
+
//#region src/infrastructure/testing/stripe-fixture.ts
|
|
5
|
+
/**
|
|
6
|
+
* Construct the real SDK with a fake fetch transport and an ordered record of HTTP attempts.
|
|
7
|
+
* The responder receives an unread request. The shared client factory supplies retry defaults.
|
|
8
|
+
*/
|
|
9
|
+
function stripeFixture(respond) {
|
|
10
|
+
const requests = [];
|
|
11
|
+
return {
|
|
12
|
+
stripe: createStripeClient("sk_test_fixture", { httpClient: Stripe.createFetchHttpClient(async (input, init) => {
|
|
13
|
+
const request = new Request(input, init);
|
|
14
|
+
const url = new URL(request.url);
|
|
15
|
+
const call = {
|
|
16
|
+
method: request.method,
|
|
17
|
+
path: url.pathname,
|
|
18
|
+
query: url.searchParams,
|
|
19
|
+
body: new URLSearchParams(),
|
|
20
|
+
headers: new Headers(request.headers)
|
|
21
|
+
};
|
|
22
|
+
requests.push(call);
|
|
23
|
+
const body = new TextDecoder().decode(await request.clone().arrayBuffer());
|
|
24
|
+
for (const [key, value] of new URLSearchParams(body)) call.body.append(key, value);
|
|
25
|
+
return respond(request);
|
|
26
|
+
}) }),
|
|
27
|
+
requests
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
export { stripeFixture as t };
|
|
33
|
+
//# sourceMappingURL=stripe-fixture-yFUknTJO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe-fixture-yFUknTJO.js","names":[],"sources":["../src/infrastructure/testing/stripe-fixture.ts"],"sourcesContent":["import Stripe from 'stripe'\n\nimport { createStripeClient } from '../stripe/client.ts'\n\n/** One SDK HTTP attempt; query and body expose Stripe's URL-encoded parameters. */\nexport type StripeCall = {\n readonly method: string\n readonly path: string\n readonly query: URLSearchParams\n readonly body: URLSearchParams\n readonly headers: Headers\n}\n\ntype StripeFixture = { stripe: Stripe; requests: readonly StripeCall[] }\n\n/**\n * Construct the real SDK with a fake fetch transport and an ordered record of HTTP attempts.\n * The responder receives an unread request. The shared client factory supplies retry defaults.\n */\nexport function stripeFixture(\n respond: (request: Request) => Response | Promise<Response>,\n): StripeFixture {\n const requests: StripeCall[] = []\n const stripe = createStripeClient('sk_test_fixture', {\n httpClient: Stripe.createFetchHttpClient(async (input, init) => {\n const request = new Request(input, init)\n const url = new URL(request.url)\n const call: StripeCall = {\n method: request.method,\n path: url.pathname,\n query: url.searchParams,\n body: new URLSearchParams(),\n headers: new Headers(request.headers),\n }\n requests.push(call)\n const body = new TextDecoder().decode(await request.clone().arrayBuffer())\n for (const [key, value] of new URLSearchParams(body)) call.body.append(key, value)\n return respond(request)\n }),\n })\n return { stripe, requests }\n}\n"],"mappings":";;;;;;;;AAmBA,SAAgB,cACd,SACe;CACf,MAAM,WAAyB,CAAC;CAkBhC,OAAO;EAAE,QAjBM,mBAAmB,mBAAmB,EACnD,YAAY,OAAO,sBAAsB,OAAO,OAAO,SAAS;GAC9D,MAAM,UAAU,IAAI,QAAQ,OAAO,IAAI;GACvC,MAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;GAC/B,MAAM,OAAmB;IACvB,QAAQ,QAAQ;IAChB,MAAM,IAAI;IACV,OAAO,IAAI;IACX,MAAM,IAAI,gBAAgB;IAC1B,SAAS,IAAI,QAAQ,QAAQ,OAAO;GACtC;GACA,SAAS,KAAK,IAAI;GAClB,MAAM,OAAO,IAAI,YAAY,CAAC,CAAC,OAAO,MAAM,QAAQ,MAAM,CAAC,CAAC,YAAY,CAAC;GACzE,KAAK,MAAM,CAAC,KAAK,UAAU,IAAI,gBAAgB,IAAI,GAAG,KAAK,KAAK,OAAO,KAAK,KAAK;GACjF,OAAO,QAAQ,OAAO;EACxB,CAAC,EACH,CACc;EAAG;CAAS;AAC5B"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PaymentServiceError } from "../
|
|
2
|
-
import { stripeFixture } from "
|
|
1
|
+
import { t as PaymentServiceError } from "../payment-service.error-CqF7GkNp.js";
|
|
2
|
+
import { t as stripeFixture } from "../stripe-fixture-yFUknTJO.js";
|
|
3
3
|
import Stripe from "stripe";
|
|
4
4
|
import { deepStrictEqual, equal, ok, rejects } from "node:assert/strict";
|
|
5
5
|
|
package/dist/testing/stripe.js
CHANGED
|
@@ -1,33 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import Stripe from "stripe";
|
|
1
|
+
import { t as stripeFixture } from "../stripe-fixture-yFUknTJO.js";
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Construct the real SDK with a fake fetch transport and an ordered record of HTTP attempts.
|
|
7
|
-
* The responder receives an unread request. The shared client factory supplies retry defaults.
|
|
8
|
-
*/
|
|
9
|
-
function stripeFixture(respond) {
|
|
10
|
-
const requests = [];
|
|
11
|
-
return {
|
|
12
|
-
stripe: createStripeClient("sk_test_fixture", { httpClient: Stripe.createFetchHttpClient(async (input, init) => {
|
|
13
|
-
const request = new Request(input, init);
|
|
14
|
-
const url = new URL(request.url);
|
|
15
|
-
const call = {
|
|
16
|
-
method: request.method,
|
|
17
|
-
path: url.pathname,
|
|
18
|
-
query: url.searchParams,
|
|
19
|
-
body: new URLSearchParams(),
|
|
20
|
-
headers: new Headers(request.headers)
|
|
21
|
-
};
|
|
22
|
-
requests.push(call);
|
|
23
|
-
const body = new TextDecoder().decode(await request.clone().arrayBuffer());
|
|
24
|
-
for (const [key, value] of new URLSearchParams(body)) call.body.append(key, value);
|
|
25
|
-
return respond(request);
|
|
26
|
-
}) }),
|
|
27
|
-
requests
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
//#endregion
|
|
32
|
-
export { stripeFixture };
|
|
33
|
-
//# sourceMappingURL=stripe.js.map
|
|
3
|
+
export { stripeFixture };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://www.schemastore.org/package.json",
|
|
3
3
|
"name": "better-ship",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.26.0",
|
|
5
5
|
"description": "Foundation for applications on Cloudflare Workers: logger, errors, message bus, infrastructure adapters, and UI primitives",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"repository": {
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
"url": "git+https://github.com/alexander-zuev/better-ship.git",
|
|
10
10
|
"directory": "packages/better-ship"
|
|
11
11
|
},
|
|
12
|
+
"bin": {
|
|
13
|
+
"better-ship-notify-ci": "./dist/bin/notify-ci.js"
|
|
14
|
+
},
|
|
12
15
|
"files": [
|
|
13
16
|
"dist",
|
|
14
17
|
"src"
|
|
@@ -23,6 +26,7 @@
|
|
|
23
26
|
"./better-auth/secondary-storage": "./dist/better-auth/secondary-storage.js",
|
|
24
27
|
"./better-auth/stripe": "./dist/better-auth/stripe.js",
|
|
25
28
|
"./billing/client": "./dist/billing/client.js",
|
|
29
|
+
"./bin/notify-ci": "./dist/bin/notify-ci.js",
|
|
26
30
|
"./cloudflare": "./dist/cloudflare.js",
|
|
27
31
|
"./cloudflare/auth-secondary-storage": "./dist/cloudflare/auth-secondary-storage.js",
|
|
28
32
|
"./cloudflare/durable-object-client": "./dist/cloudflare/durable-object-client.js",
|
|
@@ -46,6 +50,7 @@
|
|
|
46
50
|
"./sentry/server": "./dist/sentry/server.js",
|
|
47
51
|
"./sentry/tanstack": "./dist/sentry/tanstack.js",
|
|
48
52
|
"./sentry/vite": "./dist/sentry/vite.js",
|
|
53
|
+
"./slack": "./dist/slack.js",
|
|
49
54
|
"./stripe/client": "./dist/stripe/client.js",
|
|
50
55
|
"./stripe/event-map": "./dist/stripe/event-map.js",
|
|
51
56
|
"./stripe/payment-service": "./dist/stripe/payment-service.js",
|