@ezcoder.dev/sdk 1.0.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 (44) hide show
  1. package/dist/analytics/index.d.ts +18 -0
  2. package/dist/analytics/index.js +76 -0
  3. package/dist/analytics/index.js.map +1 -0
  4. package/dist/animation/index.d.ts +172 -0
  5. package/dist/animation/index.js +81 -0
  6. package/dist/animation/index.js.map +1 -0
  7. package/dist/auth/index.d.ts +80 -0
  8. package/dist/auth/index.js +463 -0
  9. package/dist/auth/index.js.map +1 -0
  10. package/dist/chunk-5XIZHBKE.js +372 -0
  11. package/dist/chunk-5XIZHBKE.js.map +1 -0
  12. package/dist/chunk-G7XDUN3Z.js +141 -0
  13. package/dist/chunk-G7XDUN3Z.js.map +1 -0
  14. package/dist/chunk-YNDCD53D.js +212 -0
  15. package/dist/chunk-YNDCD53D.js.map +1 -0
  16. package/dist/cms/index.d.ts +44 -0
  17. package/dist/cms/index.js +106 -0
  18. package/dist/cms/index.js.map +1 -0
  19. package/dist/errors/index.d.ts +20 -0
  20. package/dist/errors/index.js +61 -0
  21. package/dist/errors/index.js.map +1 -0
  22. package/dist/index.d.ts +30 -0
  23. package/dist/index.js +21 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/notifications/index.d.ts +30 -0
  26. package/dist/notifications/index.js +191 -0
  27. package/dist/notifications/index.js.map +1 -0
  28. package/dist/payments/index.d.ts +89 -0
  29. package/dist/payments/index.js +408 -0
  30. package/dist/payments/index.js.map +1 -0
  31. package/dist/roles/index.d.ts +37 -0
  32. package/dist/roles/index.js +120 -0
  33. package/dist/roles/index.js.map +1 -0
  34. package/dist/seo/index.d.ts +39 -0
  35. package/dist/seo/index.js +89 -0
  36. package/dist/seo/index.js.map +1 -0
  37. package/dist/server/index.d.ts +72 -0
  38. package/dist/server/index.js +191 -0
  39. package/dist/server/index.js.map +1 -0
  40. package/dist/storage/index.d.ts +52 -0
  41. package/dist/storage/index.js +212 -0
  42. package/dist/storage/index.js.map +1 -0
  43. package/dist/types-DtY5lp3P.d.ts +90 -0
  44. package/package.json +105 -0
@@ -0,0 +1,212 @@
1
+ import {
2
+ AuthContext
3
+ } from "../chunk-YNDCD53D.js";
4
+ import "../chunk-5XIZHBKE.js";
5
+ import {
6
+ features,
7
+ supabase
8
+ } from "../chunk-G7XDUN3Z.js";
9
+
10
+ // src/storage/useStorage.ts
11
+ import { useState, useCallback, useContext } from "react";
12
+ var TIER_RETENTION_DAYS = {
13
+ free: 7,
14
+ starter: 30,
15
+ pro: 90,
16
+ creator: 90,
17
+ business: 365,
18
+ enterprise: -1
19
+ };
20
+ function useStorage() {
21
+ const auth = useContext(AuthContext);
22
+ const [provider] = useState(features.storage ? "supabase" : "stub");
23
+ const tier = auth?.profile?.subscription_tier || "free";
24
+ const retentionDays = TIER_RETENTION_DAYS[tier] ?? 7;
25
+ const getUserPath = useCallback((path) => {
26
+ const userId = auth?.user?.id;
27
+ const basePath = userId ? `user/${userId}` : "public";
28
+ return path ? `${basePath}/${path}` : basePath;
29
+ }, [auth?.user?.id]);
30
+ const upload = useCallback(async (file, options = {}) => {
31
+ if (!features.storage) {
32
+ throw new Error("Storage is not configured. Set SUPABASE_URL to enable file storage.");
33
+ }
34
+ const bucket = options.bucket || "uploads";
35
+ const filePath = getUserPath(options.path || `${Date.now()}_${file.name}`);
36
+ const { data, error } = await supabase.storage.from(bucket).upload(filePath, file, {
37
+ cacheControl: "3600",
38
+ upsert: false
39
+ });
40
+ if (error) throw error;
41
+ let url;
42
+ if (options.public) {
43
+ const { data: urlData } = supabase.storage.from(bucket).getPublicUrl(filePath);
44
+ url = urlData.publicUrl;
45
+ } else {
46
+ const { data: signedData, error: signedError } = await supabase.storage.from(bucket).createSignedUrl(filePath, 3600);
47
+ if (signedError) throw signedError;
48
+ url = signedData.signedUrl;
49
+ }
50
+ return {
51
+ path: data.path,
52
+ url,
53
+ size: file.size,
54
+ type: file.type
55
+ };
56
+ }, [getUserPath]);
57
+ const download = useCallback(async (path, bucket = "uploads") => {
58
+ if (!features.storage) throw new Error("Storage is not configured");
59
+ const { data, error } = await supabase.storage.from(bucket).download(path);
60
+ if (error) throw error;
61
+ return data;
62
+ }, []);
63
+ const getUrl = useCallback(async (path, options = {}) => {
64
+ if (!features.storage) return "";
65
+ const bucket = options.bucket || "uploads";
66
+ if (options.signed !== false) {
67
+ const { data: data2, error } = await supabase.storage.from(bucket).createSignedUrl(path, options.expiresIn || 3600);
68
+ if (error) throw error;
69
+ return data2.signedUrl;
70
+ }
71
+ const { data } = supabase.storage.from(bucket).getPublicUrl(path);
72
+ return data.publicUrl;
73
+ }, []);
74
+ const list = useCallback(async (prefix, bucket = "uploads") => {
75
+ if (!features.storage) return [];
76
+ const searchPath = prefix || getUserPath();
77
+ const { data, error } = await supabase.storage.from(bucket).list(searchPath);
78
+ if (error) throw error;
79
+ return (data || []).map((item) => ({
80
+ name: item.name,
81
+ path: `${searchPath}/${item.name}`,
82
+ size: item.metadata?.size || 0,
83
+ type: item.metadata?.mimetype || "",
84
+ created_at: item.created_at || "",
85
+ updated_at: item.updated_at || item.created_at || ""
86
+ }));
87
+ }, [getUserPath]);
88
+ const remove = useCallback(async (path, bucket = "uploads") => {
89
+ if (!features.storage) throw new Error("Storage is not configured");
90
+ const { error } = await supabase.storage.from(bucket).remove([path]);
91
+ if (error) throw error;
92
+ }, []);
93
+ return { upload, download, getUrl, list, remove, isConfigured: features.storage, provider, retentionDays };
94
+ }
95
+
96
+ // src/storage/FileUpload.tsx
97
+ import { useState as useState2, useRef, useCallback as useCallback2 } from "react";
98
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
99
+ function FileUpload({
100
+ onUpload,
101
+ onError,
102
+ accept,
103
+ maxSize = 10 * 1024 * 1024,
104
+ multiple = false,
105
+ children,
106
+ className = "",
107
+ bucket,
108
+ public: isPublic = false
109
+ }) {
110
+ const { upload, isConfigured } = useStorage();
111
+ const [uploading, setUploading] = useState2(false);
112
+ const [dragOver, setDragOver] = useState2(false);
113
+ const fileInputRef = useRef(null);
114
+ const handleFiles = useCallback2(async (files) => {
115
+ if (!files || files.length === 0) return;
116
+ setUploading(true);
117
+ for (const file of Array.from(files)) {
118
+ if (file.size > maxSize) {
119
+ onError?.(new Error(`File ${file.name} exceeds maximum size of ${Math.round(maxSize / 1024 / 1024)}MB`));
120
+ continue;
121
+ }
122
+ try {
123
+ const result = await upload(file, { bucket, public: isPublic });
124
+ onUpload?.(result);
125
+ } catch (err) {
126
+ onError?.(err instanceof Error ? err : new Error("Upload failed"));
127
+ }
128
+ }
129
+ setUploading(false);
130
+ }, [upload, maxSize, onUpload, onError, bucket, isPublic]);
131
+ const handleDrop = useCallback2((e) => {
132
+ e.preventDefault();
133
+ setDragOver(false);
134
+ handleFiles(e.dataTransfer.files);
135
+ }, [handleFiles]);
136
+ if (!isConfigured) {
137
+ return /* @__PURE__ */ jsx("div", { style: { padding: "20px", textAlign: "center", color: "#6b7280", border: "1px dashed #d1d5db", borderRadius: "8px" }, children: "Storage is not configured" });
138
+ }
139
+ return /* @__PURE__ */ jsxs(
140
+ "div",
141
+ {
142
+ className,
143
+ onDrop: handleDrop,
144
+ onDragOver: (e) => {
145
+ e.preventDefault();
146
+ setDragOver(true);
147
+ },
148
+ onDragLeave: () => setDragOver(false),
149
+ onClick: () => fileInputRef.current?.click(),
150
+ style: {
151
+ border: `2px dashed ${dragOver ? "#3b82f6" : "#d1d5db"}`,
152
+ borderRadius: "8px",
153
+ padding: "24px",
154
+ textAlign: "center",
155
+ cursor: "pointer",
156
+ backgroundColor: dragOver ? "#eff6ff" : "transparent",
157
+ transition: "all 0.2s"
158
+ },
159
+ children: [
160
+ /* @__PURE__ */ jsx(
161
+ "input",
162
+ {
163
+ ref: fileInputRef,
164
+ type: "file",
165
+ accept,
166
+ multiple,
167
+ onChange: (e) => handleFiles(e.target.files),
168
+ style: { display: "none" }
169
+ }
170
+ ),
171
+ children || /* @__PURE__ */ jsx("div", { children: uploading ? /* @__PURE__ */ jsx("p", { style: { color: "#3b82f6" }, children: "Uploading..." }) : /* @__PURE__ */ jsxs(Fragment, { children: [
172
+ /* @__PURE__ */ jsx("p", { style: { fontWeight: 500, marginBottom: "4px" }, children: "Drop files here or click to upload" }),
173
+ /* @__PURE__ */ jsxs("p", { style: { color: "#9ca3af", fontSize: "14px" }, children: [
174
+ "Max size: ",
175
+ Math.round(maxSize / 1024 / 1024),
176
+ "MB"
177
+ ] })
178
+ ] }) })
179
+ ]
180
+ }
181
+ );
182
+ }
183
+
184
+ // src/storage/ImagePreview.tsx
185
+ import { useState as useState3, useEffect } from "react";
186
+ import { jsx as jsx2 } from "react/jsx-runtime";
187
+ function ImagePreview({ path, alt = "", className = "", width, height, bucket, signed = true }) {
188
+ const { getUrl, isConfigured } = useStorage();
189
+ const [url, setUrl] = useState3("");
190
+ const [loading, setLoading] = useState3(true);
191
+ const [error, setError] = useState3(false);
192
+ useEffect(() => {
193
+ if (!isConfigured || !path) {
194
+ setLoading(false);
195
+ return;
196
+ }
197
+ getUrl(path, { signed, bucket }).then(setUrl).catch(() => setError(true)).finally(() => setLoading(false));
198
+ }, [path, signed, bucket, getUrl, isConfigured]);
199
+ if (loading) {
200
+ return /* @__PURE__ */ jsx2("div", { style: { width: width || "100%", height: height || "200px", backgroundColor: "#f3f4f6", borderRadius: "8px", display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx2("span", { style: { color: "#9ca3af" }, children: "Loading..." }) });
201
+ }
202
+ if (error || !url) {
203
+ return /* @__PURE__ */ jsx2("div", { style: { width: width || "100%", height: height || "200px", backgroundColor: "#f3f4f6", borderRadius: "8px", display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsx2("span", { style: { color: "#9ca3af" }, children: "Image not available" }) });
204
+ }
205
+ return /* @__PURE__ */ jsx2("img", { src: url, alt, className, style: { width, height, objectFit: "cover", borderRadius: "8px" } });
206
+ }
207
+ export {
208
+ FileUpload,
209
+ ImagePreview,
210
+ useStorage
211
+ };
212
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/storage/useStorage.ts","../../src/storage/FileUpload.tsx","../../src/storage/ImagePreview.tsx"],"sourcesContent":["import { useState, useCallback, useContext } from 'react';\nimport { supabase } from '../core/supabase';\nimport { features } from '../core/config';\nimport { AuthContext } from '../auth/AuthProvider';\nimport type { StorageResult, StorageFile } from '../core/types';\n\ntype StorageProvider = 'supabase' | 'stub';\n\nconst TIER_RETENTION_DAYS: Record<string, number> = {\n free: 7,\n starter: 30,\n pro: 90,\n creator: 90,\n business: 365,\n enterprise: -1,\n};\n\ninterface UploadOptions {\n path?: string;\n public?: boolean;\n bucket?: string;\n}\n\ninterface UrlOptions {\n signed?: boolean;\n expiresIn?: number;\n}\n\ninterface UseStorageReturn {\n upload: (file: File, options?: UploadOptions) => Promise<StorageResult>;\n download: (path: string, bucket?: string) => Promise<Blob>;\n getUrl: (path: string, options?: UrlOptions & { bucket?: string }) => Promise<string>;\n list: (prefix?: string, bucket?: string) => Promise<StorageFile[]>;\n remove: (path: string, bucket?: string) => Promise<void>;\n isConfigured: boolean;\n provider: StorageProvider;\n retentionDays: number;\n}\n\nexport function useStorage(): UseStorageReturn {\n const auth = useContext(AuthContext);\n const [provider] = useState<StorageProvider>(features.storage ? 'supabase' : 'stub');\n const tier = (auth?.profile as unknown as Record<string, unknown>)?.subscription_tier as string || 'free';\n const retentionDays = TIER_RETENTION_DAYS[tier] ?? 7;\n\n const getUserPath = useCallback((path?: string): string => {\n const userId = auth?.user?.id;\n const basePath = userId ? `user/${userId}` : 'public';\n return path ? `${basePath}/${path}` : basePath;\n }, [auth?.user?.id]);\n\n const upload = useCallback(async (file: File, options: UploadOptions = {}): Promise<StorageResult> => {\n if (!features.storage) {\n throw new Error('Storage is not configured. Set SUPABASE_URL to enable file storage.');\n }\n\n const bucket = options.bucket || 'uploads';\n const filePath = getUserPath(options.path || `${Date.now()}_${file.name}`);\n\n const { data, error } = await supabase.storage\n .from(bucket)\n .upload(filePath, file, {\n cacheControl: '3600',\n upsert: false,\n });\n\n if (error) throw error;\n\n let url: string;\n if (options.public) {\n const { data: urlData } = supabase.storage.from(bucket).getPublicUrl(filePath);\n url = urlData.publicUrl;\n } else {\n const { data: signedData, error: signedError } = await supabase.storage\n .from(bucket)\n .createSignedUrl(filePath, 3600);\n if (signedError) throw signedError;\n url = signedData.signedUrl;\n }\n\n return {\n path: data.path,\n url,\n size: file.size,\n type: file.type,\n };\n }, [getUserPath]);\n\n const download = useCallback(async (path: string, bucket = 'uploads'): Promise<Blob> => {\n if (!features.storage) throw new Error('Storage is not configured');\n\n const { data, error } = await supabase.storage.from(bucket).download(path);\n if (error) throw error;\n return data;\n }, []);\n\n const getUrl = useCallback(async (path: string, options: UrlOptions & { bucket?: string } = {}): Promise<string> => {\n if (!features.storage) return '';\n\n const bucket = options.bucket || 'uploads';\n\n if (options.signed !== false) {\n const { data, error } = await supabase.storage\n .from(bucket)\n .createSignedUrl(path, options.expiresIn || 3600);\n if (error) throw error;\n return data.signedUrl;\n }\n\n const { data } = supabase.storage.from(bucket).getPublicUrl(path);\n return data.publicUrl;\n }, []);\n\n const list = useCallback(async (prefix?: string, bucket = 'uploads'): Promise<StorageFile[]> => {\n if (!features.storage) return [];\n\n const searchPath = prefix || getUserPath();\n const { data, error } = await supabase.storage.from(bucket).list(searchPath);\n if (error) throw error;\n\n return (data || []).map((item) => ({\n name: item.name,\n path: `${searchPath}/${item.name}`,\n size: (item.metadata as Record<string, unknown>)?.size as number || 0,\n type: (item.metadata as Record<string, unknown>)?.mimetype as string || '',\n created_at: item.created_at || '',\n updated_at: item.updated_at || item.created_at || '',\n }));\n }, [getUserPath]);\n\n const remove = useCallback(async (path: string, bucket = 'uploads'): Promise<void> => {\n if (!features.storage) throw new Error('Storage is not configured');\n\n const { error } = await supabase.storage.from(bucket).remove([path]);\n if (error) throw error;\n }, []);\n\n return { upload, download, getUrl, list, remove, isConfigured: features.storage, provider, retentionDays };\n}\n","import { useState, useRef, useCallback } from 'react';\nimport { useStorage } from './useStorage';\nimport type { StorageResult } from '../core/types';\n\ninterface FileUploadProps {\n onUpload?: (result: StorageResult) => void;\n onError?: (error: Error) => void;\n accept?: string;\n maxSize?: number;\n multiple?: boolean;\n children?: React.ReactNode;\n className?: string;\n bucket?: string;\n public?: boolean;\n}\n\nexport function FileUpload({\n onUpload,\n onError,\n accept,\n maxSize = 10 * 1024 * 1024,\n multiple = false,\n children,\n className = '',\n bucket,\n public: isPublic = false,\n}: FileUploadProps) {\n const { upload, isConfigured } = useStorage();\n const [uploading, setUploading] = useState(false);\n const [dragOver, setDragOver] = useState(false);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const handleFiles = useCallback(async (files: FileList | null) => {\n if (!files || files.length === 0) return;\n\n setUploading(true);\n\n for (const file of Array.from(files)) {\n if (file.size > maxSize) {\n onError?.(new Error(`File ${file.name} exceeds maximum size of ${Math.round(maxSize / 1024 / 1024)}MB`));\n continue;\n }\n\n try {\n const result = await upload(file, { bucket, public: isPublic });\n onUpload?.(result);\n } catch (err: unknown) {\n onError?.(err instanceof Error ? err : new Error('Upload failed'));\n }\n }\n\n setUploading(false);\n }, [upload, maxSize, onUpload, onError, bucket, isPublic]);\n\n const handleDrop = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n setDragOver(false);\n handleFiles(e.dataTransfer.files);\n }, [handleFiles]);\n\n if (!isConfigured) {\n return (\n <div style={{ padding: '20px', textAlign: 'center', color: '#6b7280', border: '1px dashed #d1d5db', borderRadius: '8px' }}>\n Storage is not configured\n </div>\n );\n }\n\n return (\n <div\n className={className}\n onDrop={handleDrop}\n onDragOver={(e) => { e.preventDefault(); setDragOver(true); }}\n onDragLeave={() => setDragOver(false)}\n onClick={() => fileInputRef.current?.click()}\n style={{\n border: `2px dashed ${dragOver ? '#3b82f6' : '#d1d5db'}`,\n borderRadius: '8px',\n padding: '24px',\n textAlign: 'center',\n cursor: 'pointer',\n backgroundColor: dragOver ? '#eff6ff' : 'transparent',\n transition: 'all 0.2s',\n }}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={accept}\n multiple={multiple}\n onChange={(e) => handleFiles(e.target.files)}\n style={{ display: 'none' }}\n />\n\n {children || (\n <div>\n {uploading ? (\n <p style={{ color: '#3b82f6' }}>Uploading...</p>\n ) : (\n <>\n <p style={{ fontWeight: 500, marginBottom: '4px' }}>Drop files here or click to upload</p>\n <p style={{ color: '#9ca3af', fontSize: '14px' }}>\n Max size: {Math.round(maxSize / 1024 / 1024)}MB\n </p>\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n","import { useState, useEffect } from 'react';\nimport { useStorage } from './useStorage';\n\ninterface ImagePreviewProps {\n path: string;\n alt?: string;\n className?: string;\n width?: number | string;\n height?: number | string;\n bucket?: string;\n signed?: boolean;\n}\n\nexport function ImagePreview({ path, alt = '', className = '', width, height, bucket, signed = true }: ImagePreviewProps) {\n const { getUrl, isConfigured } = useStorage();\n const [url, setUrl] = useState<string>('');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState(false);\n\n useEffect(() => {\n if (!isConfigured || !path) {\n setLoading(false);\n return;\n }\n\n getUrl(path, { signed, bucket })\n .then(setUrl)\n .catch(() => setError(true))\n .finally(() => setLoading(false));\n }, [path, signed, bucket, getUrl, isConfigured]);\n\n if (loading) {\n return (\n <div style={{ width: width || '100%', height: height || '200px', backgroundColor: '#f3f4f6', borderRadius: '8px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n <span style={{ color: '#9ca3af' }}>Loading...</span>\n </div>\n );\n }\n\n if (error || !url) {\n return (\n <div style={{ width: width || '100%', height: height || '200px', backgroundColor: '#f3f4f6', borderRadius: '8px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>\n <span style={{ color: '#9ca3af' }}>Image not available</span>\n </div>\n );\n }\n\n return <img src={url} alt={alt} className={className} style={{ width, height, objectFit: 'cover', borderRadius: '8px' }} />;\n}\n"],"mappings":"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","names":["data","useState","useCallback","useState","useCallback","useState","jsx","useState"]}
@@ -0,0 +1,90 @@
1
+ interface AnalyticsResult {
2
+ success: boolean;
3
+ error?: string;
4
+ }
5
+ interface CheckoutOptions {
6
+ successUrl?: string;
7
+ cancelUrl?: string;
8
+ customerEmail?: string;
9
+ quantity?: number;
10
+ redirect?: boolean;
11
+ }
12
+ interface EzcoderClient {
13
+ isConfigured: () => boolean;
14
+ analytics: {
15
+ track: (eventType: string, properties?: Record<string, unknown>) => Promise<AnalyticsResult>;
16
+ pageView: (path?: string) => Promise<AnalyticsResult>;
17
+ identify: (userId: string, traits?: Record<string, unknown>) => Promise<AnalyticsResult>;
18
+ error: (message: string, context?: Record<string, unknown>) => Promise<AnalyticsResult>;
19
+ };
20
+ stripe: {
21
+ createCheckout: (priceId: string, options?: CheckoutOptions) => Promise<AnalyticsResult & {
22
+ url?: string;
23
+ }>;
24
+ getProducts: () => Promise<{
25
+ products: unknown[];
26
+ message: string;
27
+ }>;
28
+ verifySession: (sessionId: string) => Promise<AnalyticsResult & Record<string, unknown>>;
29
+ getCustomerStatus: (options?: {
30
+ customerId?: string;
31
+ email?: string;
32
+ }) => Promise<AnalyticsResult & Record<string, unknown>>;
33
+ createPortalSession: (customerId: string, options?: {
34
+ returnUrl?: string;
35
+ redirect?: boolean;
36
+ }) => Promise<AnalyticsResult & {
37
+ url?: string;
38
+ }>;
39
+ };
40
+ users: {
41
+ trackSignup: (userId: string, email: string, role?: string | null) => Promise<AnalyticsResult>;
42
+ trackLogin: (userId: string) => Promise<AnalyticsResult>;
43
+ trackLogout: (userId: string) => Promise<AnalyticsResult>;
44
+ trackRoleChange: (userId: string, oldRole: string, newRole: string) => Promise<AnalyticsResult>;
45
+ };
46
+ }
47
+ interface AuthUser {
48
+ id?: string;
49
+ email?: string;
50
+ user_metadata?: {
51
+ full_name?: string;
52
+ };
53
+ }
54
+ interface AuthIntegration {
55
+ onLogin: (user: AuthUser) => void;
56
+ onSignup: (user: AuthUser) => void;
57
+ onLogout: (userId: string) => void;
58
+ }
59
+ interface UserProfile {
60
+ id: string;
61
+ external_id?: string;
62
+ email?: string;
63
+ display_name?: string;
64
+ avatar_url?: string;
65
+ metadata?: Record<string, unknown>;
66
+ subscription_tier?: string;
67
+ subscription_status?: string;
68
+ stripe_customer_id?: string;
69
+ subscription_period_end?: string;
70
+ created_at?: string;
71
+ updated_at?: string;
72
+ }
73
+ interface StorageResult {
74
+ path: string;
75
+ url: string;
76
+ size: number;
77
+ type: string;
78
+ }
79
+ interface StorageFile {
80
+ name: string;
81
+ path: string;
82
+ size: number;
83
+ type: string;
84
+ created_at: string;
85
+ updated_at: string;
86
+ }
87
+ type SubscriptionTier = 'free' | 'starter' | 'creator' | 'pro' | 'business' | 'enterprise';
88
+ type SubscriptionStatus = 'active' | 'trialing' | 'past_due' | 'canceled' | 'unpaid' | 'incomplete';
89
+
90
+ export type { AuthIntegration as A, CheckoutOptions as C, EzcoderClient as E, StorageFile as S, UserProfile as U, AnalyticsResult as a, AuthUser as b, StorageResult as c, SubscriptionStatus as d, SubscriptionTier as e };
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "@ezcoder.dev/sdk",
3
+ "version": "1.0.0",
4
+ "description": "EzCoder Platform SDK — auth, payments, storage, analytics, and more with zero configuration",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./auth": {
14
+ "types": "./dist/auth/index.d.ts",
15
+ "import": "./dist/auth/index.js"
16
+ },
17
+ "./payments": {
18
+ "types": "./dist/payments/index.d.ts",
19
+ "import": "./dist/payments/index.js"
20
+ },
21
+ "./storage": {
22
+ "types": "./dist/storage/index.d.ts",
23
+ "import": "./dist/storage/index.js"
24
+ },
25
+ "./analytics": {
26
+ "types": "./dist/analytics/index.d.ts",
27
+ "import": "./dist/analytics/index.js"
28
+ },
29
+ "./roles": {
30
+ "types": "./dist/roles/index.d.ts",
31
+ "import": "./dist/roles/index.js"
32
+ },
33
+ "./seo": {
34
+ "types": "./dist/seo/index.d.ts",
35
+ "import": "./dist/seo/index.js"
36
+ },
37
+ "./errors": {
38
+ "types": "./dist/errors/index.d.ts",
39
+ "import": "./dist/errors/index.js"
40
+ },
41
+ "./notifications": {
42
+ "types": "./dist/notifications/index.d.ts",
43
+ "import": "./dist/notifications/index.js"
44
+ },
45
+ "./cms": {
46
+ "types": "./dist/cms/index.d.ts",
47
+ "import": "./dist/cms/index.js"
48
+ },
49
+ "./animation": {
50
+ "types": "./dist/animation/index.d.ts",
51
+ "import": "./dist/animation/index.js"
52
+ },
53
+ "./server": {
54
+ "types": "./dist/server/index.d.ts",
55
+ "import": "./dist/server/index.js"
56
+ }
57
+ },
58
+ "typesVersions": {
59
+ "*": {
60
+ "auth": ["dist/auth/index.d.ts"],
61
+ "payments": ["dist/payments/index.d.ts"],
62
+ "storage": ["dist/storage/index.d.ts"],
63
+ "analytics": ["dist/analytics/index.d.ts"],
64
+ "roles": ["dist/roles/index.d.ts"],
65
+ "seo": ["dist/seo/index.d.ts"],
66
+ "errors": ["dist/errors/index.d.ts"],
67
+ "notifications": ["dist/notifications/index.d.ts"],
68
+ "cms": ["dist/cms/index.d.ts"],
69
+ "animation": ["dist/animation/index.d.ts"],
70
+ "server": ["dist/server/index.d.ts"]
71
+ }
72
+ },
73
+ "files": [
74
+ "dist"
75
+ ],
76
+ "scripts": {
77
+ "build": "tsup",
78
+ "dev": "tsup --watch",
79
+ "typecheck": "tsc --noEmit",
80
+ "clean": "rm -rf dist"
81
+ },
82
+ "peerDependencies": {
83
+ "react": "^18.0.0",
84
+ "react-dom": "^18.0.0",
85
+ "@supabase/supabase-js": "^2.0.0"
86
+ },
87
+ "peerDependenciesMeta": {
88
+ "framer-motion": {
89
+ "optional": true
90
+ },
91
+ "react-helmet-async": {
92
+ "optional": true
93
+ },
94
+ "stripe": {
95
+ "optional": true
96
+ }
97
+ },
98
+ "devDependencies": {
99
+ "tsup": "^8.0.0",
100
+ "typescript": "^5.5.0",
101
+ "@types/react": "^18.0.0",
102
+ "@types/react-dom": "^18.0.0"
103
+ },
104
+ "license": "MIT"
105
+ }