@frigear-nu/stripe 0.1.2 → 0.1.3

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/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@frigear-nu/stripe",
3
3
  "configKey": "stripe",
4
- "version": "0.1.2",
4
+ "version": "0.1.3",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.3",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { defineNuxtModule, createResolver, addServerHandler, addServerImportsDir, addServerImports, addTypeTemplate } from '@nuxt/kit';
2
- import { registerModule, inlineModuleRuntime, defineVirtualRegistry, extendDatabaseTable } from '@frigear-nu/module-kit/utils';
1
+ import { defineNuxtModule, createResolver, addServerImportsDir, addServerImports, addTypeTemplate } from '@nuxt/kit';
2
+ import { registerModule, addModuleRoutes, inlineModuleRuntime, defineVirtualRegistry, extendDatabaseTable } from '@frigear-nu/module-kit/utils';
3
3
 
4
4
  const STRIPE_API_VERSION = "2026-09-30.endive";
5
5
  const DEFAULT_WEBHOOK_PATH = "/api/stripe/webhook";
@@ -25,7 +25,8 @@ const module$1 = defineNuxtModule({
25
25
  async setup(options, nuxt) {
26
26
  registerModule("@frigear-nu/stripe", nuxt);
27
27
  const resolver = createResolver(import.meta.url);
28
- const webhookPath = options.settings?.webhookPath || DEFAULT_WEBHOOK_PATH;
28
+ const configuredPath = options.settings?.webhookPath || DEFAULT_WEBHOOK_PATH;
29
+ const webhookPath = configuredPath.startsWith("/") ? configuredPath : `/${configuredPath}`;
29
30
  if (!nuxt.options.hub?.kv) {
30
31
  throw new Error("[@frigear-nu/stripe] NuxtHub KV is required for webhook idempotency. Set `hub: { kv: true }` in your Nuxt config.");
31
32
  }
@@ -40,11 +41,7 @@ const module$1 = defineNuxtModule({
40
41
  publishableKey: "",
41
42
  ...runtimeConfig.public.stripe
42
43
  };
43
- addServerHandler({
44
- route: webhookPath,
45
- method: "post",
46
- handler: resolver.resolve("./runtime/server/routes/webhook.post")
47
- });
44
+ addModuleRoutes(resolver, [{ method: "post", path: webhookPath, file: "webhook.post" }], { base: "/api/stripe" });
48
45
  addServerImportsDir(resolver.resolve("./runtime/server/utils"));
49
46
  inlineModuleRuntime(nuxt, resolver);
50
47
  addServerImports([
@@ -2,6 +2,7 @@ import Stripe from "stripe";
2
2
  import { kv } from "@nuxthub/kv";
3
3
  import { handlers as registeredHandlers } from "#stripe/handlers";
4
4
  import { getRuntimeStripeEventHandlers } from "../../utils/registry.js";
5
+ import { apiError, badRequest, notConfigured } from "@frigear-nu/module-kit/server";
5
6
  const PROCESSED_TTL_SECONDS = 60 * 60 * 24 * 7;
6
7
  const DEFAULT_ORDER = 100;
7
8
  const matches = (events, type) => events === "*" || events.includes(type);
@@ -26,15 +27,15 @@ function getEventCustomerId(stripeEvent) {
26
27
  export default defineEventHandler(async (event) => {
27
28
  const { webhookSecret } = useRuntimeConfig(event).stripe;
28
29
  if (!webhookSecret) {
29
- throw createError({ statusCode: 500, statusMessage: "Stripe webhook is not configured (missing NUXT_STRIPE_WEBHOOK_SECRET)." });
30
+ throw notConfigured("Stripe webhook is not configured (missing NUXT_STRIPE_WEBHOOK_SECRET).");
30
31
  }
31
32
  const signature = getHeader(event, "stripe-signature");
32
33
  if (!signature) {
33
- throw createError({ statusCode: 400, statusMessage: "Missing stripe-signature header." });
34
+ throw badRequest("Missing stripe-signature header.");
34
35
  }
35
36
  const rawBody = await readRawBody(event, "utf8");
36
37
  if (!rawBody) {
37
- throw createError({ statusCode: 400, statusMessage: "Missing request body." });
38
+ throw badRequest("Missing request body.");
38
39
  }
39
40
  let stripeEvent;
40
41
  try {
@@ -47,7 +48,7 @@ export default defineEventHandler(async (event) => {
47
48
  );
48
49
  } catch (error) {
49
50
  console.warn("[@frigear-nu/stripe] Rejected webhook with an invalid signature:", error instanceof Error ? error.message : error);
50
- throw createError({ statusCode: 400, statusMessage: "Invalid Stripe signature." });
51
+ throw badRequest("Invalid Stripe signature.");
51
52
  }
52
53
  const processedKey = `stripe:event:${stripeEvent.id}`;
53
54
  if (await kv.has(processedKey)) {
@@ -75,7 +76,7 @@ export default defineEventHandler(async (event) => {
75
76
  console.error(`[@frigear-nu/stripe] "stripe:event" hook failed for ${stripeEvent.id}:`, error);
76
77
  }
77
78
  if (failures > 0) {
78
- throw createError({ statusCode: 500, statusMessage: `${failures} Stripe event handler(s) failed.` });
79
+ throw apiError(500, "handler_failed", `${failures} Stripe event handler(s) failed.`);
79
80
  }
80
81
  await kv.set(processedKey, Date.now(), { ttl: PROCESSED_TTL_SECONDS });
81
82
  return { received: true };
@@ -1,11 +1,12 @@
1
1
  import Stripe from "stripe";
2
2
  import { db, schema } from "@nuxthub/db";
3
3
  import { and, eq, isNull } from "drizzle-orm";
4
+ import { notConfigured, notFound } from "@frigear-nu/module-kit/server";
4
5
  let cached;
5
6
  export function useStripe() {
6
7
  const { secretKey, apiVersion } = useRuntimeConfig().stripe;
7
8
  if (!secretKey) {
8
- throw createError({ statusCode: 500, statusMessage: "Stripe is not configured (missing `runtimeConfig.stripe.secretKey` / NUXT_STRIPE_SECRET_KEY)." });
9
+ throw notConfigured("Stripe is not configured (missing `runtimeConfig.stripe.secretKey` / NUXT_STRIPE_SECRET_KEY).");
9
10
  }
10
11
  if (!cached || cached.key !== secretKey || cached.apiVersion !== apiVersion) {
11
12
  cached = {
@@ -23,7 +24,7 @@ const escapeSearchValue = (value) => value.replace(/\\/g, "\\\\").replace(/'/g,
23
24
  export async function ensureStripeCustomer(userId) {
24
25
  const [user] = await db.select().from(schema.users).where(eq(schema.users.id, userId)).limit(1);
25
26
  if (!user) {
26
- throw createError({ statusCode: 404, statusMessage: "User not found." });
27
+ throw notFound("User not found.");
27
28
  }
28
29
  if (user.stripeCustomerId) return user.stripeCustomerId;
29
30
  const stripe = useStripe();
@@ -1,5 +1,4 @@
1
1
  export { registerStripeEventHandler, defineStripeEventHandler } from './handlers.js';
2
2
  export type { RegisterStripeEventHandlerOptions } from './handlers.js';
3
3
  export { onStripeEvent } from './registry.js';
4
- export { resolveSameOriginUrl } from './url.js';
5
4
  export type { ModuleOptions, StripeEventType, StripeEventOf, StripeEventHandler, StripeEventHandlerContext, RegisteredStripeEventHandler, StripeRuntimeConfig, StripePublicRuntimeConfig, } from '../../types.js';
@@ -1,3 +1,2 @@
1
1
  export { registerStripeEventHandler, defineStripeEventHandler } from "./handlers.js";
2
2
  export { onStripeEvent } from "./registry.js";
3
- export { resolveSameOriginUrl } from "./url.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frigear-nu/stripe",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Core Stripe plumbing for the frigear ecosystem: SDK access, customer linking, and a verified, idempotent webhook that other modules can subscribe to.",
5
5
  "homepage": "https://docs.frigear.dev/modules/stripe",
6
6
  "repository": {
@@ -30,8 +30,8 @@
30
30
  "playground"
31
31
  ],
32
32
  "dependencies": {
33
- "@frigear-nu/module-kit": "1.1.2",
34
- "@frigear-nu/users": "1.1.3",
33
+ "@frigear-nu/module-kit": "1.1.3",
34
+ "@frigear-nu/users": "1.1.4",
35
35
  "@libsql/client": "^0.18.0",
36
36
  "@nuxt/kit": "^4.6.1",
37
37
  "h3": "^1.15.11",
@@ -1,6 +0,0 @@
1
- /**
2
- * Validates a redirect URL supplied by a client (a Stripe return URL): it must be a relative path (`/x`) or an absolute
3
- * URL on `origin`. Returns an absolute URL on that origin, or `null` when it is unsafe. Shared by every module that
4
- * sends people through Stripe so the open-redirect guard exists once.
5
- */
6
- export declare function resolveSameOriginUrl(input: string, origin: string): string | null;
@@ -1,11 +0,0 @@
1
- export function resolveSameOriginUrl(input, origin) {
2
- if (input.startsWith("/")) {
3
- if (input.startsWith("//") || input.startsWith("/\\")) return null;
4
- return `${origin}${input}`;
5
- }
6
- try {
7
- return new URL(input).origin === new URL(origin).origin ? input : null;
8
- } catch {
9
- return null;
10
- }
11
- }