@autumnsgrove/groveengine 0.4.12 → 0.6.1

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 (48) hide show
  1. package/README.md +5 -3
  2. package/dist/components/OnboardingChecklist.svelte +118 -0
  3. package/dist/components/OnboardingChecklist.svelte.d.ts +14 -0
  4. package/dist/components/quota/QuotaWarning.svelte +125 -0
  5. package/dist/components/quota/QuotaWarning.svelte.d.ts +16 -0
  6. package/dist/components/quota/QuotaWidget.svelte +120 -0
  7. package/dist/components/quota/QuotaWidget.svelte.d.ts +15 -0
  8. package/dist/components/quota/UpgradePrompt.svelte +288 -0
  9. package/dist/components/quota/UpgradePrompt.svelte.d.ts +13 -0
  10. package/dist/components/quota/index.d.ts +8 -0
  11. package/dist/components/quota/index.js +8 -0
  12. package/dist/groveauth/client.d.ts +143 -0
  13. package/dist/groveauth/client.js +502 -0
  14. package/dist/groveauth/colors.d.ts +35 -0
  15. package/dist/groveauth/colors.js +91 -0
  16. package/dist/groveauth/index.d.ts +34 -0
  17. package/dist/groveauth/index.js +35 -0
  18. package/dist/groveauth/limits.d.ts +70 -0
  19. package/dist/groveauth/limits.js +202 -0
  20. package/dist/groveauth/rate-limit.d.ts +95 -0
  21. package/dist/groveauth/rate-limit.js +172 -0
  22. package/dist/groveauth/types.d.ts +139 -0
  23. package/dist/groveauth/types.js +61 -0
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.js +4 -0
  26. package/dist/payments/types.d.ts +7 -2
  27. package/dist/server/services/__mocks__/cloudflare.d.ts +54 -0
  28. package/dist/server/services/__mocks__/cloudflare.js +470 -0
  29. package/dist/server/services/cache.d.ts +170 -0
  30. package/dist/server/services/cache.js +335 -0
  31. package/dist/server/services/database.d.ts +236 -0
  32. package/dist/server/services/database.js +450 -0
  33. package/dist/server/services/index.d.ts +34 -0
  34. package/dist/server/services/index.js +77 -0
  35. package/dist/server/services/storage.d.ts +221 -0
  36. package/dist/server/services/storage.js +485 -0
  37. package/package.json +11 -1
  38. package/static/fonts/Calistoga-Regular.ttf +1438 -0
  39. package/static/fonts/Caveat-Regular.ttf +0 -0
  40. package/static/fonts/EBGaramond-Regular.ttf +0 -0
  41. package/static/fonts/Fraunces-Regular.ttf +0 -0
  42. package/static/fonts/InstrumentSans-Regular.ttf +0 -0
  43. package/static/fonts/Lora-Regular.ttf +0 -0
  44. package/static/fonts/Luciole-Regular.ttf +1438 -0
  45. package/static/fonts/Manrope-Regular.ttf +0 -0
  46. package/static/fonts/Merriweather-Regular.ttf +1439 -0
  47. package/static/fonts/Nunito-Regular.ttf +0 -0
  48. package/static/fonts/PlusJakartaSans-Regular.ttf +0 -0
@@ -0,0 +1,139 @@
1
+ /**
2
+ * GroveAuth Client Types
3
+ *
4
+ * Type definitions for integrating with GroveAuth service.
5
+ */
6
+ export interface GroveAuthConfig {
7
+ /** Client ID registered with GroveAuth */
8
+ clientId: string;
9
+ /** Client secret for token exchange (keep secure!) */
10
+ clientSecret: string;
11
+ /** OAuth callback URL for this application */
12
+ redirectUri: string;
13
+ /** GroveAuth base URL (defaults to https://auth.grove.place) */
14
+ authBaseUrl?: string;
15
+ }
16
+ export interface TokenResponse {
17
+ access_token: string;
18
+ token_type: "Bearer";
19
+ expires_in: number;
20
+ refresh_token: string;
21
+ scope: string;
22
+ }
23
+ export interface TokenInfo {
24
+ active: boolean;
25
+ sub?: string;
26
+ email?: string;
27
+ name?: string;
28
+ exp?: number;
29
+ iat?: number;
30
+ client_id?: string;
31
+ }
32
+ export interface UserInfo {
33
+ sub: string;
34
+ email: string;
35
+ name: string | null;
36
+ picture: string | null;
37
+ provider: "google" | "github" | "magic_code";
38
+ }
39
+ export interface LoginUrlResult {
40
+ url: string;
41
+ state: string;
42
+ codeVerifier: string;
43
+ }
44
+ export type SubscriptionTier = "seedling" | "sapling" | "oak" | "evergreen";
45
+ export interface UserSubscription {
46
+ id: string;
47
+ user_id: string;
48
+ tier: SubscriptionTier;
49
+ post_limit: number | null;
50
+ post_count: number;
51
+ grace_period_start: string | null;
52
+ grace_period_days: number;
53
+ stripe_customer_id: string | null;
54
+ stripe_subscription_id: string | null;
55
+ billing_period_start: string | null;
56
+ billing_period_end: string | null;
57
+ custom_domain: string | null;
58
+ custom_domain_verified: number;
59
+ created_at: string;
60
+ updated_at: string;
61
+ }
62
+ export interface SubscriptionStatus {
63
+ tier: SubscriptionTier;
64
+ post_count: number;
65
+ post_limit: number | null;
66
+ posts_remaining: number | null;
67
+ percentage_used: number | null;
68
+ is_at_limit: boolean;
69
+ is_in_grace_period: boolean;
70
+ grace_period_days_remaining: number | null;
71
+ can_create_post: boolean;
72
+ upgrade_required: boolean;
73
+ }
74
+ export interface SubscriptionResponse {
75
+ subscription: UserSubscription;
76
+ status: SubscriptionStatus;
77
+ }
78
+ export interface CanPostResponse {
79
+ allowed: boolean;
80
+ status: SubscriptionStatus;
81
+ subscription: UserSubscription;
82
+ }
83
+ /**
84
+ * Post limits per subscription tier.
85
+ *
86
+ * Business rationale:
87
+ * - Seedling (50 posts): Entry-level tier for curious newcomers testing the
88
+ * platform. Low commitment, creates upgrade path.
89
+ * - Sapling (250 posts): For hobbyists and regular bloggers who know they'll
90
+ * stick around. ~1 post/day for 8 months.
91
+ * - Oak (unlimited): For serious bloggers whose blog is part of their
92
+ * identity. Includes BYOD (bring your own domain) and full email.
93
+ * - Evergreen (unlimited): Full-service tier for professionals. Includes domain
94
+ * search, registration, and priority support.
95
+ *
96
+ * Grace period: When users hit their limit, they have 14 days to upgrade or
97
+ * delete posts before their account becomes read-only.
98
+ *
99
+ * @see docs/implementing-post-limits.md for full specification
100
+ */
101
+ export declare const TIER_POST_LIMITS: Record<SubscriptionTier, number | null>;
102
+ /**
103
+ * Human-readable tier names for UI display.
104
+ */
105
+ export declare const TIER_NAMES: Record<SubscriptionTier, string>;
106
+ /**
107
+ * OAuth/API error response structure from GroveAuth.
108
+ * Used to parse error responses from the authentication API.
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const response = await fetch('/token');
113
+ * if (!response.ok) {
114
+ * const error: AuthError = await response.json();
115
+ * console.error(error.error, error.error_description);
116
+ * }
117
+ * ```
118
+ */
119
+ export interface AuthError {
120
+ /** OAuth error code (e.g., 'invalid_grant', 'access_denied') */
121
+ error: string;
122
+ /** Human-readable error description (OAuth standard) */
123
+ error_description?: string;
124
+ /** Alternative message field used by some endpoints */
125
+ message?: string;
126
+ }
127
+ /**
128
+ * Client-side error class for GroveAuth operations.
129
+ * Thrown when authentication or subscription operations fail.
130
+ */
131
+ export declare class GroveAuthError extends Error {
132
+ /** Error code (e.g., 'invalid_user_id', 'subscription_error') */
133
+ readonly code: string;
134
+ /** HTTP status code from the response */
135
+ readonly statusCode: number;
136
+ constructor(code: string, message: string, statusCode?: number);
137
+ /** Alias for statusCode for compatibility */
138
+ get status(): number;
139
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * GroveAuth Client Types
3
+ *
4
+ * Type definitions for integrating with GroveAuth service.
5
+ */
6
+ // =============================================================================
7
+ // POST LIMIT CONSTANTS
8
+ // =============================================================================
9
+ /**
10
+ * Post limits per subscription tier.
11
+ *
12
+ * Business rationale:
13
+ * - Seedling (50 posts): Entry-level tier for curious newcomers testing the
14
+ * platform. Low commitment, creates upgrade path.
15
+ * - Sapling (250 posts): For hobbyists and regular bloggers who know they'll
16
+ * stick around. ~1 post/day for 8 months.
17
+ * - Oak (unlimited): For serious bloggers whose blog is part of their
18
+ * identity. Includes BYOD (bring your own domain) and full email.
19
+ * - Evergreen (unlimited): Full-service tier for professionals. Includes domain
20
+ * search, registration, and priority support.
21
+ *
22
+ * Grace period: When users hit their limit, they have 14 days to upgrade or
23
+ * delete posts before their account becomes read-only.
24
+ *
25
+ * @see docs/implementing-post-limits.md for full specification
26
+ */
27
+ export const TIER_POST_LIMITS = {
28
+ seedling: 50, // For curious newcomers trying blogging
29
+ sapling: 250, // For hobbyists and regular bloggers
30
+ oak: null, // Unlimited for serious bloggers
31
+ evergreen: null, // Unlimited for professionals
32
+ };
33
+ /**
34
+ * Human-readable tier names for UI display.
35
+ */
36
+ export const TIER_NAMES = {
37
+ seedling: "Seedling",
38
+ sapling: "Sapling",
39
+ oak: "Oak",
40
+ evergreen: "Evergreen",
41
+ };
42
+ /**
43
+ * Client-side error class for GroveAuth operations.
44
+ * Thrown when authentication or subscription operations fail.
45
+ */
46
+ export class GroveAuthError extends Error {
47
+ /** Error code (e.g., 'invalid_user_id', 'subscription_error') */
48
+ code;
49
+ /** HTTP status code from the response */
50
+ statusCode;
51
+ constructor(code, message, statusCode = 400) {
52
+ super(message);
53
+ this.name = "GroveAuthError";
54
+ this.code = code;
55
+ this.statusCode = statusCode;
56
+ }
57
+ /** Alias for statusCode for compatibility */
58
+ get status() {
59
+ return this.statusCode;
60
+ }
61
+ }
package/dist/index.d.ts CHANGED
@@ -6,9 +6,11 @@ export { default as MobileTOC } from './components/custom/MobileTOC.svelte';
6
6
  export { default as CollapsibleSection } from './components/custom/CollapsibleSection.svelte';
7
7
  export { default as MarkdownEditor } from './components/admin/MarkdownEditor.svelte';
8
8
  export { default as GutterManager } from './components/admin/GutterManager.svelte';
9
+ export { QuotaWidget, QuotaWarning, UpgradePrompt } from './components/quota/index';
9
10
  export { default as ImageGallery } from './ui/components/gallery/ImageGallery.svelte';
10
11
  export { default as Lightbox } from './ui/components/gallery/Lightbox.svelte';
11
12
  export { default as LightboxCaption } from './ui/components/gallery/LightboxCaption.svelte';
12
13
  export { default as ZoomableImage } from './ui/components/gallery/ZoomableImage.svelte';
13
14
  export * from './ui/index';
14
15
  export { cn } from './utils/cn';
16
+ export * from './groveauth/index';
package/dist/index.js CHANGED
@@ -9,6 +9,8 @@ export { default as CollapsibleSection } from './components/custom/CollapsibleSe
9
9
  // Admin components
10
10
  export { default as MarkdownEditor } from './components/admin/MarkdownEditor.svelte';
11
11
  export { default as GutterManager } from './components/admin/GutterManager.svelte';
12
+ // Quota components
13
+ export { QuotaWidget, QuotaWarning, UpgradePrompt } from './components/quota/index';
12
14
  // Gallery components (from UI module)
13
15
  export { default as ImageGallery } from './ui/components/gallery/ImageGallery.svelte';
14
16
  export { default as Lightbox } from './ui/components/gallery/Lightbox.svelte';
@@ -18,3 +20,5 @@ export { default as ZoomableImage } from './ui/components/gallery/ZoomableImage.
18
20
  export * from './ui/index';
19
21
  // Utilities
20
22
  export { cn } from './utils/cn';
23
+ // GroveAuth client (re-export for convenience)
24
+ export * from './groveauth/index';
@@ -227,21 +227,26 @@ export interface ConnectOnboardingResult {
227
227
  onboardingUrl: string;
228
228
  expiresAt?: Date;
229
229
  }
230
- export type PlanTier = 'starter' | 'professional' | 'business';
230
+ export type PlanTier = 'seedling' | 'sapling' | 'oak' | 'evergreen';
231
231
  export interface PlatformPlan {
232
232
  tier: PlanTier;
233
233
  name: string;
234
234
  price: Money;
235
+ yearlyPrice?: Money;
235
236
  interval: BillingInterval;
236
237
  features: string[];
237
238
  limits: {
238
239
  posts?: number;
239
240
  storage?: number;
240
241
  customDomain?: boolean;
241
- analytics?: boolean;
242
+ byod?: boolean;
243
+ email?: 'none' | 'forward' | 'full';
244
+ analytics?: 'basic' | 'full';
245
+ supportHours?: number;
242
246
  shop?: boolean;
243
247
  };
244
248
  providerPriceId?: string;
249
+ yearlyPriceId?: string;
245
250
  }
246
251
  export interface TenantBilling {
247
252
  tenantId: string;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Mock implementations for Cloudflare services (D1, KV, R2)
3
+ * Used for testing the service abstraction layer
4
+ */
5
+ interface MockRow {
6
+ [key: string]: unknown;
7
+ }
8
+ /**
9
+ * Creates a mock D1 database with in-memory storage
10
+ */
11
+ export declare function createMockD1(): D1Database & {
12
+ _tables: Map<string, MockRow[]>;
13
+ };
14
+ interface KVEntry {
15
+ value: string;
16
+ expiresAt?: number;
17
+ metadata?: unknown;
18
+ }
19
+ /**
20
+ * Creates a mock KV namespace with in-memory storage
21
+ */
22
+ export declare function createMockKV(): KVNamespace & {
23
+ _store: Map<string, KVEntry>;
24
+ };
25
+ interface R2Entry {
26
+ body: ArrayBuffer;
27
+ httpMetadata?: {
28
+ contentType?: string;
29
+ cacheControl?: string;
30
+ };
31
+ customMetadata?: Record<string, string>;
32
+ etag: string;
33
+ uploaded: Date;
34
+ size: number;
35
+ }
36
+ /**
37
+ * Creates a mock R2 bucket with in-memory storage
38
+ */
39
+ export declare function createMockR2(): R2Bucket & {
40
+ _objects: Map<string, R2Entry>;
41
+ };
42
+ /**
43
+ * Seed a mock D1 database with initial data
44
+ */
45
+ export declare function seedMockD1(db: ReturnType<typeof createMockD1>, tableName: string, rows: MockRow[]): void;
46
+ /**
47
+ * Clear all data from a mock D1 database
48
+ */
49
+ export declare function clearMockD1(db: ReturnType<typeof createMockD1>): void;
50
+ /**
51
+ * Advance time for KV expiration testing
52
+ */
53
+ export declare function advanceKVTime(kv: ReturnType<typeof createMockKV>, ms: number): void;
54
+ export {};