@frigear-nu/subscriptions 0.1.2 → 0.2.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.
Files changed (45) hide show
  1. package/README.md +3 -3
  2. package/dist/module.d.mts +2 -2
  3. package/dist/module.json +1 -1
  4. package/dist/module.mjs +16 -31
  5. package/dist/runtime/app/components/SubscriptionPlans.d.vue.ts +51 -5
  6. package/dist/runtime/app/components/SubscriptionPlans.vue +6 -11
  7. package/dist/runtime/app/components/SubscriptionPlans.vue.d.ts +51 -5
  8. package/dist/runtime/app/components/SubscriptionStatus.d.vue.ts +16 -6
  9. package/dist/runtime/app/components/SubscriptionStatus.vue +25 -24
  10. package/dist/runtime/app/components/SubscriptionStatus.vue.d.ts +16 -6
  11. package/dist/runtime/app/components/Users/Admin/Membership.vue +4 -2
  12. package/dist/runtime/app/composables/usePlans.js +3 -1
  13. package/dist/runtime/app/composables/useSubscription.js +5 -3
  14. package/dist/runtime/app/middleware/subscription.d.ts +1 -1
  15. package/dist/runtime/app/middleware/subscription.js +1 -0
  16. package/dist/runtime/app/pages/cancel.vue +19 -6
  17. package/dist/runtime/app/pages/membership.vue +29 -17
  18. package/dist/runtime/app/pages/success.vue +19 -6
  19. package/dist/runtime/app/tabs/Membership.vue +9 -8
  20. package/dist/runtime/app/widgets/AdminCurrentSubscription.vue +1 -0
  21. package/dist/runtime/app/widgets/MembershipSummary.vue +1 -0
  22. package/dist/runtime/i18n/lang/da.json +13 -11
  23. package/dist/runtime/i18n/lang/en.json +15 -13
  24. package/dist/runtime/menus.js +5 -4
  25. package/dist/runtime/server/routes/admin/{subscription.delete.js → membership.delete.js} +3 -2
  26. package/dist/runtime/server/routes/admin/{subscription.get.js → membership.get.js} +2 -2
  27. package/dist/runtime/server/routes/admin/{subscription.post.js → membership.post.js} +9 -14
  28. package/dist/runtime/server/routes/admin/payment-link.post.js +3 -2
  29. package/dist/runtime/server/routes/{subscriptions → me}/checkout.post.js +9 -18
  30. package/dist/runtime/server/routes/{subscriptions → me}/portal.post.js +5 -8
  31. package/dist/runtime/server/utils/checkout.js +6 -5
  32. package/dist/runtime/server/utils/subscriptions.d.ts +6 -1
  33. package/dist/runtime/server/utils/subscriptions.js +15 -12
  34. package/dist/runtime/utils/api.d.ts +20 -0
  35. package/dist/runtime/utils/api.js +23 -0
  36. package/dist/runtime/utils/index.d.ts +2 -1
  37. package/dist/runtime/utils/index.js +2 -1
  38. package/package.json +17 -12
  39. /package/dist/runtime/server/routes/admin/{subscription.delete.d.ts → membership-history.get.d.ts} +0 -0
  40. /package/dist/runtime/server/routes/admin/{subscriptions.get.js → membership-history.get.js} +0 -0
  41. /package/dist/runtime/server/routes/admin/{subscription.get.d.ts → membership.delete.d.ts} +0 -0
  42. /package/dist/runtime/server/routes/admin/{subscription.post.d.ts → membership.get.d.ts} +0 -0
  43. /package/dist/runtime/server/routes/admin/{subscriptions.get.d.ts → membership.post.d.ts} +0 -0
  44. /package/dist/runtime/server/routes/{subscriptions → me}/checkout.post.d.ts +0 -0
  45. /package/dist/runtime/server/routes/{subscriptions → me}/portal.post.d.ts +0 -0
@@ -1,22 +1,25 @@
1
1
  import { db, schema } from "@nuxthub/db";
2
2
  import { desc, eq } from "drizzle-orm";
3
+ import { isoDate } from "@frigear-nu/module-kit/server";
3
4
  import { DEFAULT_ENTITLED_STATUSES, isEntitledRow } from "../../utils/plans.js";
5
+ export function toSubscriptionDto(row) {
6
+ return {
7
+ id: row.id,
8
+ planKey: row.planKey,
9
+ priceId: row.priceId,
10
+ status: row.status,
11
+ cancelAtPeriodEnd: row.cancelAtPeriodEnd,
12
+ currentPeriodStart: isoDate(row.currentPeriodStart),
13
+ currentPeriodEnd: isoDate(row.currentPeriodEnd),
14
+ endedAt: isoDate(row.endedAt),
15
+ source: row.source === "manual" ? "manual" : "stripe"
16
+ };
17
+ }
4
18
  export async function listUserSubscriptions(userId) {
5
19
  const rows = await db.select().from(schema.subscriptions).where(eq(schema.subscriptions.userId, userId)).orderBy(desc(schema.subscriptions.createdAt));
6
- const iso = (date) => date ? date.toISOString() : null;
7
20
  const active = rows.filter((row) => isEntitledRow(row)).sort((a, b) => (b.currentPeriodEnd?.getTime() ?? 0) - (a.currentPeriodEnd?.getTime() ?? 0))[0];
8
21
  return {
9
- subscriptions: rows.map((row) => ({
10
- id: row.id,
11
- planKey: row.planKey,
12
- priceId: row.priceId,
13
- status: row.status,
14
- cancelAtPeriodEnd: row.cancelAtPeriodEnd,
15
- currentPeriodStart: iso(row.currentPeriodStart),
16
- currentPeriodEnd: iso(row.currentPeriodEnd),
17
- endedAt: iso(row.endedAt),
18
- source: row.source === "manual" ? "manual" : "stripe"
19
- })),
22
+ subscriptions: rows.map(toSubscriptionDto),
20
23
  activePlan: active?.planKey ?? null
21
24
  };
22
25
  }
@@ -0,0 +1,20 @@
1
+ export declare const subscriptionsApi: {
2
+ /** `GET` the configured plans with live prices (public). */
3
+ readonly plans: "/api/subscriptions/plans";
4
+ readonly me: {
5
+ /** `GET` the caller's subscriptions and active plan (also the account bootstrap's `subscriptions:me`). */
6
+ readonly subscriptions: "/api/subscriptions/me";
7
+ /** `POST` to start a checkout or change plan (sessions only). */
8
+ readonly checkout: "/api/subscriptions/me/checkout";
9
+ /** `POST` to open the Stripe billing portal (sessions only). */
10
+ readonly portal: "/api/subscriptions/me/portal";
11
+ };
12
+ readonly admin: {
13
+ /** `GET` the user's current membership and grantable plans / `POST` a free grant / `DELETE` the free grant (staff). */
14
+ readonly membership: (userId: number | string) => string;
15
+ /** `GET` the user's whole subscription history (staff). */
16
+ readonly history: (userId: number | string) => string;
17
+ /** `POST` a Checkout link for the user, optionally emailed (staff). */
18
+ readonly paymentLink: (userId: number | string) => string;
19
+ };
20
+ };
@@ -0,0 +1,23 @@
1
+ const BASE = "/api/subscriptions";
2
+ const enc = encodeURIComponent;
3
+ const userBase = (userId) => `/api/admin/users/${enc(String(userId))}/membership`;
4
+ export const subscriptionsApi = {
5
+ /** `GET` the configured plans with live prices (public). */
6
+ plans: `${BASE}/plans`,
7
+ me: {
8
+ /** `GET` the caller's subscriptions and active plan (also the account bootstrap's `subscriptions:me`). */
9
+ subscriptions: `${BASE}/me`,
10
+ /** `POST` to start a checkout or change plan (sessions only). */
11
+ checkout: `${BASE}/me/checkout`,
12
+ /** `POST` to open the Stripe billing portal (sessions only). */
13
+ portal: `${BASE}/me/portal`
14
+ },
15
+ admin: {
16
+ /** `GET` the user's current membership and grantable plans / `POST` a free grant / `DELETE` the free grant (staff). */
17
+ membership: userBase,
18
+ /** `GET` the user's whole subscription history (staff). */
19
+ history: (userId) => `${userBase(userId)}/history`,
20
+ /** `POST` a Checkout link for the user, optionally emailed (staff). */
21
+ paymentLink: (userId) => `${userBase(userId)}/payment-link`
22
+ }
23
+ };
@@ -1,4 +1,5 @@
1
1
  export { getUserSubscription, hasActiveSubscription } from '../server/utils/subscriptions.js';
2
2
  export type { HasActiveSubscriptionOptions } from '../server/utils/subscriptions.js';
3
- export { decideChangeKind, resolvePlanKey, resolveSameOriginUrl, isWithinDisabledRanges, DEFAULT_ENTITLED_STATUSES } from './plans.js';
3
+ export { decideChangeKind, resolvePlanKey, isWithinDisabledRanges, DEFAULT_ENTITLED_STATUSES } from './plans.js';
4
4
  export type { CheckoutBeforeContext, PlansFilterContext, ResolvedPlan, PlanPrice, SubscriptionDto, ModuleOptions, } from '../../types.js';
5
+ export * from './api.js';
@@ -1,2 +1,3 @@
1
1
  export { getUserSubscription, hasActiveSubscription } from "../server/utils/subscriptions.js";
2
- export { decideChangeKind, resolvePlanKey, resolveSameOriginUrl, isWithinDisabledRanges, DEFAULT_ENTITLED_STATUSES } from "./plans.js";
2
+ export { decideChangeKind, resolvePlanKey, isWithinDisabledRanges, DEFAULT_ENTITLED_STATUSES } from "./plans.js";
3
+ export * from "./api.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frigear-nu/subscriptions",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Recurring subscriptions (plans, checkout, upgrade/downgrade, billing portal and entitlements) for the frigear ecosystem, built on @frigear-nu/stripe.",
5
5
  "homepage": "https://docs.frigear.dev/modules/subscriptions",
6
6
  "repository": {
@@ -21,6 +21,11 @@
21
21
  "types": "./dist/runtime/utils/index.d.ts",
22
22
  "import": "./dist/runtime/utils/index.js",
23
23
  "default": "./dist/runtime/utils/index.js"
24
+ },
25
+ "./api": {
26
+ "types": "./dist/runtime/utils/api.d.ts",
27
+ "import": "./dist/runtime/utils/api.js",
28
+ "default": "./dist/runtime/utils/api.js"
24
29
  }
25
30
  },
26
31
  "files": [
@@ -30,13 +35,13 @@
30
35
  "playground"
31
36
  ],
32
37
  "dependencies": {
33
- "@frigear-nu/auth": "0.1.3",
34
- "@frigear-nu/mcp": "0.1.2",
35
- "@frigear-nu/module-kit": "1.1.2",
36
- "@frigear-nu/notify": "0.1.2",
37
- "@frigear-nu/stripe": "0.1.2",
38
- "@frigear-nu/ui": "0.1.2",
39
- "@frigear-nu/users": "1.1.3",
38
+ "@frigear-nu/auth": "0.2.0",
39
+ "@frigear-nu/mcp": "0.2.0",
40
+ "@frigear-nu/module-kit": "1.2.0",
41
+ "@frigear-nu/notify": "0.2.0",
42
+ "@frigear-nu/stripe": "0.2.0",
43
+ "@frigear-nu/ui": "0.2.0",
44
+ "@frigear-nu/users": "1.2.0",
40
45
  "@libsql/client": "^0.18.0",
41
46
  "@nuxt/kit": "^4.6.1",
42
47
  "@vueuse/core": "^15.0.0",
@@ -49,8 +54,8 @@
49
54
  },
50
55
  "peerDependencies": {
51
56
  "@frigear-nu/email-templates": "0.1.0",
52
- "@frigear-nu/menu": "0.1.2",
53
- "@frigear-nu/widget": "0.1.2",
57
+ "@frigear-nu/menu": "0.2.0",
58
+ "@frigear-nu/widget": "0.2.0",
54
59
  "@nuxt/ui": "^4.12.0",
55
60
  "@nuxthub/core": "^0.10.8"
56
61
  },
@@ -70,8 +75,8 @@
70
75
  },
71
76
  "devDependencies": {
72
77
  "@frigear-nu/email-templates": "0.1.0",
73
- "@frigear-nu/menu": "0.1.2",
74
- "@frigear-nu/widget": "0.1.2",
78
+ "@frigear-nu/menu": "0.2.0",
79
+ "@frigear-nu/widget": "0.2.0",
75
80
  "@nuxt/devtools": "^3.4.2",
76
81
  "@nuxt/eslint-config": "^1.17.0",
77
82
  "@nuxt/module-builder": "^1.0.3",