spaps-sdk 0.1.0 → 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.
package/dist/index.d.mts CHANGED
@@ -1,3 +1,86 @@
1
+ /**
2
+ * Permission checking utilities for SPAPS SDK
3
+ * Client-side role and permission management
4
+ */
5
+ interface User$1 {
6
+ id: string;
7
+ email?: string;
8
+ wallet_address?: string;
9
+ role?: string;
10
+ permissions?: string[];
11
+ tier?: string;
12
+ }
13
+ interface AdminConfig {
14
+ email: string;
15
+ wallets: {
16
+ ethereum: string;
17
+ solana: string;
18
+ };
19
+ }
20
+ interface PermissionCheckResult {
21
+ allowed: boolean;
22
+ reason?: string;
23
+ userRole: string;
24
+ requiredRole?: string;
25
+ }
26
+ declare const DEFAULT_ADMIN_ACCOUNTS: AdminConfig;
27
+ /**
28
+ * Check if an identifier (email/wallet) is an admin account
29
+ */
30
+ declare function isAdminAccount(identifier: string, customAdmins?: (string | AdminConfig)[]): boolean;
31
+ /**
32
+ * Get user role based on identifier
33
+ */
34
+ declare function getUserRole(identifier?: string, customAdmins?: (string | AdminConfig)[]): string;
35
+ /**
36
+ * Check if user has specific permissions
37
+ */
38
+ declare function hasPermission(user: User$1 | null, requiredPermissions: string | string[], customAdmins?: (string | AdminConfig)[]): boolean;
39
+ /**
40
+ * Check if user can access admin features
41
+ */
42
+ declare function canAccessAdmin(user: User$1 | null, customAdmins?: (string | AdminConfig)[]): PermissionCheckResult;
43
+ /**
44
+ * Get role-aware error message
45
+ */
46
+ declare function getRoleAwareErrorMessage(requiredRole: string, userRole: string, action?: string): string;
47
+ /**
48
+ * Get user display information with role indicators
49
+ */
50
+ declare function getUserDisplay(user: User$1 | null, customAdmins?: (string | AdminConfig)[]): {
51
+ displayName: string;
52
+ role: string;
53
+ badge: string | null;
54
+ isAdmin: boolean;
55
+ };
56
+ /**
57
+ * Permission checker class for easier usage
58
+ */
59
+ declare class PermissionChecker {
60
+ private customAdmins;
61
+ constructor(customAdmins?: (string | AdminConfig)[]);
62
+ isAdmin(identifier: string): boolean;
63
+ getRole(identifier?: string): string;
64
+ hasPermission(user: User$1 | null, permissions: string | string[]): boolean;
65
+ canAccessAdmin(user: User$1 | null): PermissionCheckResult;
66
+ getErrorMessage(requiredRole: string, userRole: string, action?: string): string;
67
+ getUserDisplay(user: User$1 | null): {
68
+ displayName: string;
69
+ role: string;
70
+ badge: string | null;
71
+ isAdmin: boolean;
72
+ };
73
+ requiresAuth(user: User$1 | null): boolean;
74
+ requiresAdmin(user: User$1 | null): boolean;
75
+ addCustomAdmin(admin: string | AdminConfig): void;
76
+ removeCustomAdmin(admin: string | AdminConfig): void;
77
+ }
78
+ /**
79
+ * Create a permission checker instance
80
+ */
81
+ declare function createPermissionChecker(customAdmins?: (string | AdminConfig)[]): PermissionChecker;
82
+ declare const defaultPermissionChecker: PermissionChecker;
83
+
1
84
  /**
2
85
  * @spaps/sdk - Sweet Potato Authentication & Payment Service SDK
3
86
  * Zero-config client for SPAPS authentication and payments
@@ -79,4 +162,4 @@ declare class SPAPSClient {
79
162
  }>;
80
163
  }
81
164
 
82
- export { type AuthResponse, type CheckoutSession, SPAPSClient as SPAPS, SPAPSClient, type SPAPSConfig, type Subscription, SPAPSClient as SweetPotatoSDK, type UsageBalance, type User, SPAPSClient as default };
165
+ export { type AdminConfig, type AuthResponse, type CheckoutSession, DEFAULT_ADMIN_ACCOUNTS, type PermissionCheckResult, PermissionChecker, SPAPSClient as SPAPS, SPAPSClient, type SPAPSConfig, type Subscription, SPAPSClient as SweetPotatoSDK, type UsageBalance, type User, canAccessAdmin, createPermissionChecker, SPAPSClient as default, defaultPermissionChecker, getRoleAwareErrorMessage, getUserDisplay, getUserRole, hasPermission, isAdminAccount };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,86 @@
1
+ /**
2
+ * Permission checking utilities for SPAPS SDK
3
+ * Client-side role and permission management
4
+ */
5
+ interface User$1 {
6
+ id: string;
7
+ email?: string;
8
+ wallet_address?: string;
9
+ role?: string;
10
+ permissions?: string[];
11
+ tier?: string;
12
+ }
13
+ interface AdminConfig {
14
+ email: string;
15
+ wallets: {
16
+ ethereum: string;
17
+ solana: string;
18
+ };
19
+ }
20
+ interface PermissionCheckResult {
21
+ allowed: boolean;
22
+ reason?: string;
23
+ userRole: string;
24
+ requiredRole?: string;
25
+ }
26
+ declare const DEFAULT_ADMIN_ACCOUNTS: AdminConfig;
27
+ /**
28
+ * Check if an identifier (email/wallet) is an admin account
29
+ */
30
+ declare function isAdminAccount(identifier: string, customAdmins?: (string | AdminConfig)[]): boolean;
31
+ /**
32
+ * Get user role based on identifier
33
+ */
34
+ declare function getUserRole(identifier?: string, customAdmins?: (string | AdminConfig)[]): string;
35
+ /**
36
+ * Check if user has specific permissions
37
+ */
38
+ declare function hasPermission(user: User$1 | null, requiredPermissions: string | string[], customAdmins?: (string | AdminConfig)[]): boolean;
39
+ /**
40
+ * Check if user can access admin features
41
+ */
42
+ declare function canAccessAdmin(user: User$1 | null, customAdmins?: (string | AdminConfig)[]): PermissionCheckResult;
43
+ /**
44
+ * Get role-aware error message
45
+ */
46
+ declare function getRoleAwareErrorMessage(requiredRole: string, userRole: string, action?: string): string;
47
+ /**
48
+ * Get user display information with role indicators
49
+ */
50
+ declare function getUserDisplay(user: User$1 | null, customAdmins?: (string | AdminConfig)[]): {
51
+ displayName: string;
52
+ role: string;
53
+ badge: string | null;
54
+ isAdmin: boolean;
55
+ };
56
+ /**
57
+ * Permission checker class for easier usage
58
+ */
59
+ declare class PermissionChecker {
60
+ private customAdmins;
61
+ constructor(customAdmins?: (string | AdminConfig)[]);
62
+ isAdmin(identifier: string): boolean;
63
+ getRole(identifier?: string): string;
64
+ hasPermission(user: User$1 | null, permissions: string | string[]): boolean;
65
+ canAccessAdmin(user: User$1 | null): PermissionCheckResult;
66
+ getErrorMessage(requiredRole: string, userRole: string, action?: string): string;
67
+ getUserDisplay(user: User$1 | null): {
68
+ displayName: string;
69
+ role: string;
70
+ badge: string | null;
71
+ isAdmin: boolean;
72
+ };
73
+ requiresAuth(user: User$1 | null): boolean;
74
+ requiresAdmin(user: User$1 | null): boolean;
75
+ addCustomAdmin(admin: string | AdminConfig): void;
76
+ removeCustomAdmin(admin: string | AdminConfig): void;
77
+ }
78
+ /**
79
+ * Create a permission checker instance
80
+ */
81
+ declare function createPermissionChecker(customAdmins?: (string | AdminConfig)[]): PermissionChecker;
82
+ declare const defaultPermissionChecker: PermissionChecker;
83
+
1
84
  /**
2
85
  * @spaps/sdk - Sweet Potato Authentication & Payment Service SDK
3
86
  * Zero-config client for SPAPS authentication and payments
@@ -79,4 +162,4 @@ declare class SPAPSClient {
79
162
  }>;
80
163
  }
81
164
 
82
- export { type AuthResponse, type CheckoutSession, SPAPSClient as SPAPS, SPAPSClient, type SPAPSConfig, type Subscription, SPAPSClient as SweetPotatoSDK, type UsageBalance, type User, SPAPSClient as default };
165
+ export { type AdminConfig, type AuthResponse, type CheckoutSession, DEFAULT_ADMIN_ACCOUNTS, type PermissionCheckResult, PermissionChecker, SPAPSClient as SPAPS, SPAPSClient, type SPAPSConfig, type Subscription, SPAPSClient as SweetPotatoSDK, type UsageBalance, type User, canAccessAdmin, createPermissionChecker, SPAPSClient as default, defaultPermissionChecker, getRoleAwareErrorMessage, getUserDisplay, getUserRole, hasPermission, isAdminAccount };
package/dist/index.js CHANGED
@@ -30,13 +30,167 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ DEFAULT_ADMIN_ACCOUNTS: () => DEFAULT_ADMIN_ACCOUNTS,
34
+ PermissionChecker: () => PermissionChecker,
33
35
  SPAPS: () => SPAPSClient,
34
36
  SPAPSClient: () => SPAPSClient,
35
37
  SweetPotatoSDK: () => SPAPSClient,
36
- default: () => index_default
38
+ canAccessAdmin: () => canAccessAdmin,
39
+ createPermissionChecker: () => createPermissionChecker,
40
+ default: () => index_default,
41
+ defaultPermissionChecker: () => defaultPermissionChecker,
42
+ getRoleAwareErrorMessage: () => getRoleAwareErrorMessage,
43
+ getUserDisplay: () => getUserDisplay,
44
+ getUserRole: () => getUserRole,
45
+ hasPermission: () => hasPermission,
46
+ isAdminAccount: () => isAdminAccount
37
47
  });
38
48
  module.exports = __toCommonJS(index_exports);
39
49
  var import_axios = __toESM(require("axios"));
50
+
51
+ // src/permissions.ts
52
+ var DEFAULT_ADMIN_ACCOUNTS = {
53
+ email: "buildooor@gmail.com",
54
+ wallets: {
55
+ ethereum: "0xa72bb7CeF1e4B2Cc144373d8dE0Add7CCc8DF4Ba",
56
+ solana: "HVEbdiYU3Rr34NHBSgKs7q8cvdTeZLqNL77Z1FB2vjLy"
57
+ }
58
+ };
59
+ function isAdminAccount(identifier, customAdmins = []) {
60
+ if (!identifier) return false;
61
+ const normalized = identifier.toLowerCase();
62
+ if (normalized === DEFAULT_ADMIN_ACCOUNTS.email.toLowerCase() || normalized === DEFAULT_ADMIN_ACCOUNTS.wallets.ethereum.toLowerCase() || normalized === DEFAULT_ADMIN_ACCOUNTS.wallets.solana.toLowerCase()) {
63
+ return true;
64
+ }
65
+ return customAdmins.some((admin) => {
66
+ if (typeof admin === "string") {
67
+ return admin.toLowerCase() === normalized;
68
+ }
69
+ if ("email" in admin && admin.email.toLowerCase() === normalized) {
70
+ return true;
71
+ }
72
+ if ("wallets" in admin) {
73
+ return Object.values(admin.wallets).some(
74
+ (wallet) => wallet.toLowerCase() === normalized
75
+ );
76
+ }
77
+ return false;
78
+ });
79
+ }
80
+ function getUserRole(identifier, customAdmins = []) {
81
+ if (!identifier) return "guest";
82
+ if (isAdminAccount(identifier, customAdmins)) {
83
+ return "admin";
84
+ }
85
+ return "user";
86
+ }
87
+ function hasPermission(user, requiredPermissions, customAdmins = []) {
88
+ if (!user) return false;
89
+ const identifier = user.email || user.wallet_address;
90
+ const userRole = getUserRole(identifier, customAdmins);
91
+ if (userRole === "admin") {
92
+ return true;
93
+ }
94
+ if (Array.isArray(requiredPermissions)) {
95
+ return requiredPermissions.every(
96
+ (permission) => user.permissions?.includes(permission)
97
+ );
98
+ }
99
+ return user.permissions?.includes(requiredPermissions) || false;
100
+ }
101
+ function canAccessAdmin(user, customAdmins = []) {
102
+ if (!user) {
103
+ return {
104
+ allowed: false,
105
+ reason: "Authentication required",
106
+ userRole: "guest",
107
+ requiredRole: "admin"
108
+ };
109
+ }
110
+ const identifier = user.email || user.wallet_address;
111
+ const userRole = getUserRole(identifier, customAdmins);
112
+ const isAdmin = userRole === "admin";
113
+ return {
114
+ allowed: isAdmin,
115
+ reason: isAdmin ? void 0 : "Admin privileges required",
116
+ userRole,
117
+ requiredRole: "admin"
118
+ };
119
+ }
120
+ function getRoleAwareErrorMessage(requiredRole, userRole, action = "perform this action") {
121
+ const messages = {
122
+ admin: {
123
+ user: `\u{1F512} Admin privileges required to ${action}. Please authenticate with an admin account.`,
124
+ guest: `\u{1F510} Authentication required. Please sign in with an admin account to ${action}.`
125
+ },
126
+ user: {
127
+ guest: `\u{1F510} Authentication required. Please sign in to ${action}.`
128
+ }
129
+ };
130
+ return messages[requiredRole]?.[userRole] || `Access denied. Required role: ${requiredRole}, current role: ${userRole}`;
131
+ }
132
+ function getUserDisplay(user, customAdmins = []) {
133
+ if (!user) {
134
+ return {
135
+ displayName: "Guest",
136
+ role: "guest",
137
+ badge: null,
138
+ isAdmin: false
139
+ };
140
+ }
141
+ const identifier = user.email || user.wallet_address;
142
+ const role = getUserRole(identifier, customAdmins);
143
+ const isAdmin = role === "admin";
144
+ return {
145
+ displayName: user.email || `${user.wallet_address?.slice(0, 6)}...${user.wallet_address?.slice(-4)}` || "User",
146
+ role,
147
+ badge: isAdmin ? "\u{1F451} Admin" : null,
148
+ isAdmin
149
+ };
150
+ }
151
+ var PermissionChecker = class {
152
+ customAdmins;
153
+ constructor(customAdmins = []) {
154
+ this.customAdmins = customAdmins;
155
+ }
156
+ isAdmin(identifier) {
157
+ return isAdminAccount(identifier, this.customAdmins);
158
+ }
159
+ getRole(identifier) {
160
+ return getUserRole(identifier, this.customAdmins);
161
+ }
162
+ hasPermission(user, permissions) {
163
+ return hasPermission(user, permissions, this.customAdmins);
164
+ }
165
+ canAccessAdmin(user) {
166
+ return canAccessAdmin(user, this.customAdmins);
167
+ }
168
+ getErrorMessage(requiredRole, userRole, action) {
169
+ return getRoleAwareErrorMessage(requiredRole, userRole, action);
170
+ }
171
+ getUserDisplay(user) {
172
+ return getUserDisplay(user, this.customAdmins);
173
+ }
174
+ // Convenience methods
175
+ requiresAuth(user) {
176
+ return !user;
177
+ }
178
+ requiresAdmin(user) {
179
+ return !this.canAccessAdmin(user).allowed;
180
+ }
181
+ addCustomAdmin(admin) {
182
+ this.customAdmins.push(admin);
183
+ }
184
+ removeCustomAdmin(admin) {
185
+ this.customAdmins = this.customAdmins.filter((a) => a !== admin);
186
+ }
187
+ };
188
+ function createPermissionChecker(customAdmins = []) {
189
+ return new PermissionChecker(customAdmins);
190
+ }
191
+ var defaultPermissionChecker = new PermissionChecker();
192
+
193
+ // src/index.ts
40
194
  var SPAPSClient = class {
41
195
  client;
42
196
  apiKey;
@@ -185,7 +339,17 @@ var SPAPSClient = class {
185
339
  var index_default = SPAPSClient;
186
340
  // Annotate the CommonJS export names for ESM import in node:
187
341
  0 && (module.exports = {
342
+ DEFAULT_ADMIN_ACCOUNTS,
343
+ PermissionChecker,
188
344
  SPAPS,
189
345
  SPAPSClient,
190
- SweetPotatoSDK
346
+ SweetPotatoSDK,
347
+ canAccessAdmin,
348
+ createPermissionChecker,
349
+ defaultPermissionChecker,
350
+ getRoleAwareErrorMessage,
351
+ getUserDisplay,
352
+ getUserRole,
353
+ hasPermission,
354
+ isAdminAccount
191
355
  });
package/dist/index.mjs CHANGED
@@ -1,5 +1,149 @@
1
1
  // src/index.ts
2
2
  import axios from "axios";
3
+
4
+ // src/permissions.ts
5
+ var DEFAULT_ADMIN_ACCOUNTS = {
6
+ email: "buildooor@gmail.com",
7
+ wallets: {
8
+ ethereum: "0xa72bb7CeF1e4B2Cc144373d8dE0Add7CCc8DF4Ba",
9
+ solana: "HVEbdiYU3Rr34NHBSgKs7q8cvdTeZLqNL77Z1FB2vjLy"
10
+ }
11
+ };
12
+ function isAdminAccount(identifier, customAdmins = []) {
13
+ if (!identifier) return false;
14
+ const normalized = identifier.toLowerCase();
15
+ if (normalized === DEFAULT_ADMIN_ACCOUNTS.email.toLowerCase() || normalized === DEFAULT_ADMIN_ACCOUNTS.wallets.ethereum.toLowerCase() || normalized === DEFAULT_ADMIN_ACCOUNTS.wallets.solana.toLowerCase()) {
16
+ return true;
17
+ }
18
+ return customAdmins.some((admin) => {
19
+ if (typeof admin === "string") {
20
+ return admin.toLowerCase() === normalized;
21
+ }
22
+ if ("email" in admin && admin.email.toLowerCase() === normalized) {
23
+ return true;
24
+ }
25
+ if ("wallets" in admin) {
26
+ return Object.values(admin.wallets).some(
27
+ (wallet) => wallet.toLowerCase() === normalized
28
+ );
29
+ }
30
+ return false;
31
+ });
32
+ }
33
+ function getUserRole(identifier, customAdmins = []) {
34
+ if (!identifier) return "guest";
35
+ if (isAdminAccount(identifier, customAdmins)) {
36
+ return "admin";
37
+ }
38
+ return "user";
39
+ }
40
+ function hasPermission(user, requiredPermissions, customAdmins = []) {
41
+ if (!user) return false;
42
+ const identifier = user.email || user.wallet_address;
43
+ const userRole = getUserRole(identifier, customAdmins);
44
+ if (userRole === "admin") {
45
+ return true;
46
+ }
47
+ if (Array.isArray(requiredPermissions)) {
48
+ return requiredPermissions.every(
49
+ (permission) => user.permissions?.includes(permission)
50
+ );
51
+ }
52
+ return user.permissions?.includes(requiredPermissions) || false;
53
+ }
54
+ function canAccessAdmin(user, customAdmins = []) {
55
+ if (!user) {
56
+ return {
57
+ allowed: false,
58
+ reason: "Authentication required",
59
+ userRole: "guest",
60
+ requiredRole: "admin"
61
+ };
62
+ }
63
+ const identifier = user.email || user.wallet_address;
64
+ const userRole = getUserRole(identifier, customAdmins);
65
+ const isAdmin = userRole === "admin";
66
+ return {
67
+ allowed: isAdmin,
68
+ reason: isAdmin ? void 0 : "Admin privileges required",
69
+ userRole,
70
+ requiredRole: "admin"
71
+ };
72
+ }
73
+ function getRoleAwareErrorMessage(requiredRole, userRole, action = "perform this action") {
74
+ const messages = {
75
+ admin: {
76
+ user: `\u{1F512} Admin privileges required to ${action}. Please authenticate with an admin account.`,
77
+ guest: `\u{1F510} Authentication required. Please sign in with an admin account to ${action}.`
78
+ },
79
+ user: {
80
+ guest: `\u{1F510} Authentication required. Please sign in to ${action}.`
81
+ }
82
+ };
83
+ return messages[requiredRole]?.[userRole] || `Access denied. Required role: ${requiredRole}, current role: ${userRole}`;
84
+ }
85
+ function getUserDisplay(user, customAdmins = []) {
86
+ if (!user) {
87
+ return {
88
+ displayName: "Guest",
89
+ role: "guest",
90
+ badge: null,
91
+ isAdmin: false
92
+ };
93
+ }
94
+ const identifier = user.email || user.wallet_address;
95
+ const role = getUserRole(identifier, customAdmins);
96
+ const isAdmin = role === "admin";
97
+ return {
98
+ displayName: user.email || `${user.wallet_address?.slice(0, 6)}...${user.wallet_address?.slice(-4)}` || "User",
99
+ role,
100
+ badge: isAdmin ? "\u{1F451} Admin" : null,
101
+ isAdmin
102
+ };
103
+ }
104
+ var PermissionChecker = class {
105
+ customAdmins;
106
+ constructor(customAdmins = []) {
107
+ this.customAdmins = customAdmins;
108
+ }
109
+ isAdmin(identifier) {
110
+ return isAdminAccount(identifier, this.customAdmins);
111
+ }
112
+ getRole(identifier) {
113
+ return getUserRole(identifier, this.customAdmins);
114
+ }
115
+ hasPermission(user, permissions) {
116
+ return hasPermission(user, permissions, this.customAdmins);
117
+ }
118
+ canAccessAdmin(user) {
119
+ return canAccessAdmin(user, this.customAdmins);
120
+ }
121
+ getErrorMessage(requiredRole, userRole, action) {
122
+ return getRoleAwareErrorMessage(requiredRole, userRole, action);
123
+ }
124
+ getUserDisplay(user) {
125
+ return getUserDisplay(user, this.customAdmins);
126
+ }
127
+ // Convenience methods
128
+ requiresAuth(user) {
129
+ return !user;
130
+ }
131
+ requiresAdmin(user) {
132
+ return !this.canAccessAdmin(user).allowed;
133
+ }
134
+ addCustomAdmin(admin) {
135
+ this.customAdmins.push(admin);
136
+ }
137
+ removeCustomAdmin(admin) {
138
+ this.customAdmins = this.customAdmins.filter((a) => a !== admin);
139
+ }
140
+ };
141
+ function createPermissionChecker(customAdmins = []) {
142
+ return new PermissionChecker(customAdmins);
143
+ }
144
+ var defaultPermissionChecker = new PermissionChecker();
145
+
146
+ // src/index.ts
3
147
  var SPAPSClient = class {
4
148
  client;
5
149
  apiKey;
@@ -147,8 +291,18 @@ var SPAPSClient = class {
147
291
  };
148
292
  var index_default = SPAPSClient;
149
293
  export {
294
+ DEFAULT_ADMIN_ACCOUNTS,
295
+ PermissionChecker,
150
296
  SPAPSClient as SPAPS,
151
297
  SPAPSClient,
152
298
  SPAPSClient as SweetPotatoSDK,
153
- index_default as default
299
+ canAccessAdmin,
300
+ createPermissionChecker,
301
+ index_default as default,
302
+ defaultPermissionChecker,
303
+ getRoleAwareErrorMessage,
304
+ getUserDisplay,
305
+ getUserRole,
306
+ hasPermission,
307
+ isAdminAccount
154
308
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "spaps-sdk",
3
- "version": "0.1.0",
4
- "description": "Sweet Potato Authentication & Payment Service SDK - Zero-config client for SPAPS",
3
+ "version": "1.0.0",
4
+ "description": "Sweet Potato Authentication & Payment Service SDK - Zero-config client with built-in permission checking and role-based access control",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {