@peers-app/peers-sdk 0.1.4

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 (234) hide show
  1. package/README.md +1 -0
  2. package/dist/context/data-context.d.ts +31 -0
  3. package/dist/context/data-context.js +56 -0
  4. package/dist/context/index.d.ts +3 -0
  5. package/dist/context/index.js +19 -0
  6. package/dist/context/user-context-singleton.d.ts +11 -0
  7. package/dist/context/user-context-singleton.js +121 -0
  8. package/dist/context/user-context.d.ts +55 -0
  9. package/dist/context/user-context.js +205 -0
  10. package/dist/data/assistants.d.ts +68 -0
  11. package/dist/data/assistants.js +64 -0
  12. package/dist/data/change-tracking.d.ts +219 -0
  13. package/dist/data/change-tracking.js +119 -0
  14. package/dist/data/channels.d.ts +29 -0
  15. package/dist/data/channels.js +25 -0
  16. package/dist/data/data-locks.d.ts +37 -0
  17. package/dist/data/data-locks.js +180 -0
  18. package/dist/data/data-locks.test.d.ts +1 -0
  19. package/dist/data/data-locks.test.js +456 -0
  20. package/dist/data/device-sync-info.d.ts +19 -0
  21. package/dist/data/device-sync-info.js +24 -0
  22. package/dist/data/devices.d.ts +51 -0
  23. package/dist/data/devices.js +36 -0
  24. package/dist/data/embeddings.d.ts +47 -0
  25. package/dist/data/embeddings.js +36 -0
  26. package/dist/data/files/file-read-stream.d.ts +27 -0
  27. package/dist/data/files/file-read-stream.js +195 -0
  28. package/dist/data/files/file-write-stream.d.ts +20 -0
  29. package/dist/data/files/file-write-stream.js +113 -0
  30. package/dist/data/files/file.types.d.ts +47 -0
  31. package/dist/data/files/file.types.js +55 -0
  32. package/dist/data/files/files.d.ts +28 -0
  33. package/dist/data/files/files.js +127 -0
  34. package/dist/data/files/files.test.d.ts +1 -0
  35. package/dist/data/files/files.test.js +728 -0
  36. package/dist/data/files/index.d.ts +4 -0
  37. package/dist/data/files/index.js +23 -0
  38. package/dist/data/group-member-roles.d.ts +9 -0
  39. package/dist/data/group-member-roles.js +25 -0
  40. package/dist/data/group-members.d.ts +39 -0
  41. package/dist/data/group-members.js +68 -0
  42. package/dist/data/group-members.test.d.ts +1 -0
  43. package/dist/data/group-members.test.js +287 -0
  44. package/dist/data/group-permissions.d.ts +8 -0
  45. package/dist/data/group-permissions.js +73 -0
  46. package/dist/data/group-share.d.ts +50 -0
  47. package/dist/data/group-share.js +196 -0
  48. package/dist/data/groups.d.ts +50 -0
  49. package/dist/data/groups.js +73 -0
  50. package/dist/data/groups.test.d.ts +1 -0
  51. package/dist/data/groups.test.js +153 -0
  52. package/dist/data/index.d.ts +31 -0
  53. package/dist/data/index.js +47 -0
  54. package/dist/data/knowledge/knowledge-frames.d.ts +34 -0
  55. package/dist/data/knowledge/knowledge-frames.js +34 -0
  56. package/dist/data/knowledge/knowledge-links.d.ts +30 -0
  57. package/dist/data/knowledge/knowledge-links.js +25 -0
  58. package/dist/data/knowledge/knowledge-values.d.ts +35 -0
  59. package/dist/data/knowledge/knowledge-values.js +35 -0
  60. package/dist/data/knowledge/peer-types.d.ts +112 -0
  61. package/dist/data/knowledge/peer-types.js +27 -0
  62. package/dist/data/knowledge/predicates.d.ts +34 -0
  63. package/dist/data/knowledge/predicates.js +27 -0
  64. package/dist/data/messages.d.ts +57 -0
  65. package/dist/data/messages.js +97 -0
  66. package/dist/data/orm/client-proxy.data-source.d.ts +27 -0
  67. package/dist/data/orm/client-proxy.data-source.js +65 -0
  68. package/dist/data/orm/cursor.d.ts +25 -0
  69. package/dist/data/orm/cursor.js +47 -0
  70. package/dist/data/orm/cursor.test.d.ts +1 -0
  71. package/dist/data/orm/cursor.test.js +315 -0
  72. package/dist/data/orm/data-query.d.ts +96 -0
  73. package/dist/data/orm/data-query.js +208 -0
  74. package/dist/data/orm/data-query.mongo.d.ts +17 -0
  75. package/dist/data/orm/data-query.mongo.js +267 -0
  76. package/dist/data/orm/data-query.mongo.test.d.ts +1 -0
  77. package/dist/data/orm/data-query.mongo.test.js +398 -0
  78. package/dist/data/orm/data-query.sqlite.d.ts +14 -0
  79. package/dist/data/orm/data-query.sqlite.js +297 -0
  80. package/dist/data/orm/data-query.sqlite.test.d.ts +1 -0
  81. package/dist/data/orm/data-query.sqlite.test.js +377 -0
  82. package/dist/data/orm/data-query.test.d.ts +1 -0
  83. package/dist/data/orm/data-query.test.js +553 -0
  84. package/dist/data/orm/decorators.d.ts +6 -0
  85. package/dist/data/orm/decorators.js +21 -0
  86. package/dist/data/orm/dependency-injection.test.d.ts +1 -0
  87. package/dist/data/orm/dependency-injection.test.js +171 -0
  88. package/dist/data/orm/doc.d.ts +26 -0
  89. package/dist/data/orm/doc.js +124 -0
  90. package/dist/data/orm/event-registry.d.ts +24 -0
  91. package/dist/data/orm/event-registry.js +40 -0
  92. package/dist/data/orm/event-registry.test.d.ts +1 -0
  93. package/dist/data/orm/event-registry.test.js +44 -0
  94. package/dist/data/orm/factory.d.ts +8 -0
  95. package/dist/data/orm/factory.js +147 -0
  96. package/dist/data/orm/index.d.ts +16 -0
  97. package/dist/data/orm/index.js +32 -0
  98. package/dist/data/orm/multi-cursors.d.ts +11 -0
  99. package/dist/data/orm/multi-cursors.js +146 -0
  100. package/dist/data/orm/multi-cursors.test.d.ts +1 -0
  101. package/dist/data/orm/multi-cursors.test.js +455 -0
  102. package/dist/data/orm/sql-db.d.ts +6 -0
  103. package/dist/data/orm/sql-db.js +2 -0
  104. package/dist/data/orm/sql.data-source.d.ts +38 -0
  105. package/dist/data/orm/sql.data-source.js +379 -0
  106. package/dist/data/orm/sql.data-source.test.d.ts +1 -0
  107. package/dist/data/orm/sql.data-source.test.js +406 -0
  108. package/dist/data/orm/subscribable.data-source.d.ts +25 -0
  109. package/dist/data/orm/subscribable.data-source.js +72 -0
  110. package/dist/data/orm/table-container-events.test.d.ts +1 -0
  111. package/dist/data/orm/table-container-events.test.js +93 -0
  112. package/dist/data/orm/table-container.d.ts +39 -0
  113. package/dist/data/orm/table-container.js +96 -0
  114. package/dist/data/orm/table-definitions.system.d.ts +9 -0
  115. package/dist/data/orm/table-definitions.system.js +29 -0
  116. package/dist/data/orm/table-definitions.type.d.ts +19 -0
  117. package/dist/data/orm/table-definitions.type.js +2 -0
  118. package/dist/data/orm/table-dependencies.d.ts +32 -0
  119. package/dist/data/orm/table-dependencies.js +2 -0
  120. package/dist/data/orm/table.d.ts +42 -0
  121. package/dist/data/orm/table.event-source.test.d.ts +1 -0
  122. package/dist/data/orm/table.event-source.test.js +341 -0
  123. package/dist/data/orm/table.js +244 -0
  124. package/dist/data/orm/types.d.ts +20 -0
  125. package/dist/data/orm/types.js +115 -0
  126. package/dist/data/orm/types.test.d.ts +1 -0
  127. package/dist/data/orm/types.test.js +71 -0
  128. package/dist/data/package-permissions.d.ts +7 -0
  129. package/dist/data/package-permissions.js +18 -0
  130. package/dist/data/packages.d.ts +92 -0
  131. package/dist/data/packages.js +90 -0
  132. package/dist/data/peer-events/peer-event-handlers.d.ts +21 -0
  133. package/dist/data/peer-events/peer-event-handlers.js +28 -0
  134. package/dist/data/peer-events/peer-event-types.d.ts +119 -0
  135. package/dist/data/peer-events/peer-event-types.js +29 -0
  136. package/dist/data/peer-events/peer-events.d.ts +41 -0
  137. package/dist/data/peer-events/peer-events.js +102 -0
  138. package/dist/data/persistent-vars.d.ts +87 -0
  139. package/dist/data/persistent-vars.js +230 -0
  140. package/dist/data/tool-tests.d.ts +37 -0
  141. package/dist/data/tool-tests.js +27 -0
  142. package/dist/data/tools.d.ts +358 -0
  143. package/dist/data/tools.js +48 -0
  144. package/dist/data/user-permissions.d.ts +15 -0
  145. package/dist/data/user-permissions.js +39 -0
  146. package/dist/data/user-permissions.test.d.ts +1 -0
  147. package/dist/data/user-permissions.test.js +252 -0
  148. package/dist/data/users.d.ts +38 -0
  149. package/dist/data/users.js +73 -0
  150. package/dist/data/workflow-logs.d.ts +106 -0
  151. package/dist/data/workflow-logs.js +67 -0
  152. package/dist/data/workflow-runs.d.ts +103 -0
  153. package/dist/data/workflow-runs.js +313 -0
  154. package/dist/data/workflows.d.ts +16 -0
  155. package/dist/data/workflows.js +21 -0
  156. package/dist/device/connection.d.ts +41 -0
  157. package/dist/device/connection.js +249 -0
  158. package/dist/device/connection.test.d.ts +1 -0
  159. package/dist/device/connection.test.js +292 -0
  160. package/dist/device/device-election.d.ts +36 -0
  161. package/dist/device/device-election.js +137 -0
  162. package/dist/device/device.d.ts +22 -0
  163. package/dist/device/device.js +110 -0
  164. package/dist/device/device.test.d.ts +1 -0
  165. package/dist/device/device.test.js +203 -0
  166. package/dist/device/get-trust-level.d.ts +3 -0
  167. package/dist/device/get-trust-level.js +87 -0
  168. package/dist/device/socket.type.d.ts +20 -0
  169. package/dist/device/socket.type.js +15 -0
  170. package/dist/device/streamed-socket.d.ts +27 -0
  171. package/dist/device/streamed-socket.js +154 -0
  172. package/dist/device/streamed-socket.test.d.ts +1 -0
  173. package/dist/device/streamed-socket.test.js +44 -0
  174. package/dist/events.d.ts +35 -0
  175. package/dist/events.js +128 -0
  176. package/dist/index.d.ts +33 -0
  177. package/dist/index.js +50 -0
  178. package/dist/keys.d.ts +51 -0
  179. package/dist/keys.js +234 -0
  180. package/dist/keys.test.d.ts +1 -0
  181. package/dist/keys.test.js +215 -0
  182. package/dist/mentions.d.ts +9 -0
  183. package/dist/mentions.js +46 -0
  184. package/dist/observable.d.ts +19 -0
  185. package/dist/observable.js +112 -0
  186. package/dist/observable.test.d.ts +1 -0
  187. package/dist/observable.test.js +183 -0
  188. package/dist/package-loader/get-require.d.ts +10 -0
  189. package/dist/package-loader/get-require.js +31 -0
  190. package/dist/package-loader/index.d.ts +1 -0
  191. package/dist/package-loader/index.js +17 -0
  192. package/dist/package-loader/package-loader.d.ts +16 -0
  193. package/dist/package-loader/package-loader.js +102 -0
  194. package/dist/peers-ui/peers-ui.d.ts +15 -0
  195. package/dist/peers-ui/peers-ui.js +23 -0
  196. package/dist/peers-ui/peers-ui.types.d.ts +35 -0
  197. package/dist/peers-ui/peers-ui.types.js +3 -0
  198. package/dist/rpc-types.d.ts +45 -0
  199. package/dist/rpc-types.js +47 -0
  200. package/dist/serial-json.d.ts +5 -0
  201. package/dist/serial-json.js +186 -0
  202. package/dist/serial-json.test.d.ts +1 -0
  203. package/dist/serial-json.test.js +86 -0
  204. package/dist/system-ids.d.ts +6 -0
  205. package/dist/system-ids.js +10 -0
  206. package/dist/tools/index.d.ts +1 -0
  207. package/dist/tools/index.js +17 -0
  208. package/dist/tools/tools-factory.d.ts +5 -0
  209. package/dist/tools/tools-factory.js +34 -0
  210. package/dist/types/app-nav.d.ts +18 -0
  211. package/dist/types/app-nav.js +10 -0
  212. package/dist/types/assistant-runner-args.d.ts +9 -0
  213. package/dist/types/assistant-runner-args.js +2 -0
  214. package/dist/types/field-type.d.ts +37 -0
  215. package/dist/types/field-type.js +26 -0
  216. package/dist/types/peer-device.d.ts +40 -0
  217. package/dist/types/peer-device.js +14 -0
  218. package/dist/types/peers-package.d.ts +23 -0
  219. package/dist/types/peers-package.js +2 -0
  220. package/dist/types/workflow-logger.d.ts +2 -0
  221. package/dist/types/workflow-logger.js +2 -0
  222. package/dist/types/workflow-run-context.d.ts +12 -0
  223. package/dist/types/workflow-run-context.js +2 -0
  224. package/dist/types/workflow.d.ts +72 -0
  225. package/dist/types/workflow.js +24 -0
  226. package/dist/types/zod-types.d.ts +7 -0
  227. package/dist/types/zod-types.js +12 -0
  228. package/dist/users.query.d.ts +13 -0
  229. package/dist/users.query.js +134 -0
  230. package/dist/utils.d.ts +39 -0
  231. package/dist/utils.js +240 -0
  232. package/dist/utils.test.d.ts +1 -0
  233. package/dist/utils.test.js +140 -0
  234. package/package.json +50 -0
@@ -0,0 +1,4 @@
1
+ export * from './file.types';
2
+ export * from './files';
3
+ export { FileWriteStream } from './file-write-stream';
4
+ export { FileReadStream } from './file-read-stream';
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.FileReadStream = exports.FileWriteStream = void 0;
18
+ __exportStar(require("./file.types"), exports);
19
+ __exportStar(require("./files"), exports);
20
+ var file_write_stream_1 = require("./file-write-stream");
21
+ Object.defineProperty(exports, "FileWriteStream", { enumerable: true, get: function () { return file_write_stream_1.FileWriteStream; } });
22
+ var file_read_stream_1 = require("./file-read-stream");
23
+ Object.defineProperty(exports, "FileReadStream", { enumerable: true, get: function () { return file_read_stream_1.FileReadStream; } });
@@ -0,0 +1,9 @@
1
+ export declare enum GroupMemberRole {
2
+ None = 0,
3
+ Reader = 20,
4
+ Writer = 40,
5
+ Admin = 60,
6
+ Owner = 80,
7
+ Founder = 100
8
+ }
9
+ export declare function getRoleLabel(value: number): string;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GroupMemberRole = void 0;
4
+ exports.getRoleLabel = getRoleLabel;
5
+ var GroupMemberRole;
6
+ (function (GroupMemberRole) {
7
+ GroupMemberRole[GroupMemberRole["None"] = 0] = "None";
8
+ GroupMemberRole[GroupMemberRole["Reader"] = 20] = "Reader";
9
+ GroupMemberRole[GroupMemberRole["Writer"] = 40] = "Writer";
10
+ GroupMemberRole[GroupMemberRole["Admin"] = 60] = "Admin";
11
+ GroupMemberRole[GroupMemberRole["Owner"] = 80] = "Owner";
12
+ GroupMemberRole[GroupMemberRole["Founder"] = 100] = "Founder";
13
+ })(GroupMemberRole || (exports.GroupMemberRole = GroupMemberRole = {}));
14
+ function getRoleLabel(value) {
15
+ const roleEntries = Object.entries(GroupMemberRole)
16
+ .filter(([key, val]) => typeof val === 'number')
17
+ .map(([key, val]) => ({ level: val, label: key }))
18
+ .sort((a, b) => b.level - a.level);
19
+ for (const role of roleEntries) {
20
+ if (value >= role.level) {
21
+ return value === role.level ? role.label : `${role.label}+`;
22
+ }
23
+ }
24
+ return 'None';
25
+ }
@@ -0,0 +1,39 @@
1
+ import { z } from "zod";
2
+ import type { DataContext } from "../context/data-context";
3
+ import { Table } from "./orm";
4
+ import { GroupMemberRole } from './group-member-roles';
5
+ import { ISaveOptions } from "..";
6
+ export declare const groupMemberSchema: z.ZodObject<{
7
+ groupMemberId: z.ZodEffects<z.ZodString, string, string>;
8
+ groupId: z.ZodEffects<z.ZodString, string, string>;
9
+ userId: z.ZodEffects<z.ZodString, string, string>;
10
+ role: z.ZodNativeEnum<typeof GroupMemberRole>;
11
+ signature: z.ZodString;
12
+ deleted: z.ZodOptional<z.ZodBoolean>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ role: GroupMemberRole;
15
+ signature: string;
16
+ groupMemberId: string;
17
+ groupId: string;
18
+ userId: string;
19
+ deleted?: boolean | undefined;
20
+ }, {
21
+ role: GroupMemberRole;
22
+ signature: string;
23
+ groupMemberId: string;
24
+ groupId: string;
25
+ userId: string;
26
+ deleted?: boolean | undefined;
27
+ }>;
28
+ export type IGroupMember = z.infer<typeof groupMemberSchema>;
29
+ export declare const groupMembersTableName = "GroupMembers";
30
+ export declare class GroupMembersTable extends Table<IGroupMember> {
31
+ static isPassthrough: boolean;
32
+ save(groupMember: IGroupMember, opts?: ISaveOptions): Promise<IGroupMember>;
33
+ delete(groupMemberId: string): Promise<void>;
34
+ /** @deprecated Forbidden on GroupsTable; use save() */
35
+ insert(..._args: Parameters<Table<IGroupMember>['insert']>): never;
36
+ /** @deprecated Forbidden on GroupsTable; use save() */
37
+ update(..._args: Parameters<Table<IGroupMember>['update']>): never;
38
+ }
39
+ export declare function GroupMembers(dataContext?: DataContext): GroupMembersTable;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GroupMembersTable = exports.groupMembersTableName = exports.groupMemberSchema = void 0;
4
+ exports.GroupMembers = GroupMembers;
5
+ const zod_1 = require("zod");
6
+ const user_context_singleton_1 = require("../context/user-context-singleton");
7
+ const zod_types_1 = require("../types/zod-types");
8
+ const orm_1 = require("./orm");
9
+ const table_definitions_system_1 = require("./orm/table-definitions.system");
10
+ const types_1 = require("./orm/types");
11
+ const group_member_roles_1 = require("./group-member-roles");
12
+ const group_permissions_1 = require("./group-permissions");
13
+ const __1 = require("..");
14
+ exports.groupMemberSchema = zod_1.z.object({
15
+ groupMemberId: zod_types_1.zodPeerId,
16
+ groupId: zod_types_1.zodPeerId.describe('The id of the group'),
17
+ userId: zod_types_1.zodPeerId.describe('The id of the user who is a member of the group'),
18
+ role: zod_1.z.nativeEnum(group_member_roles_1.GroupMemberRole).describe('The role of the user in the group. Use "none" to explicitly block a user'),
19
+ signature: zod_1.z.string().describe('The signed hash of this data excluding the signature itself'),
20
+ deleted: zod_1.z.boolean().optional().describe('Whether this membership has been deleted (soft delete)'),
21
+ });
22
+ exports.groupMembersTableName = 'GroupMembers';
23
+ const metaData = {
24
+ name: exports.groupMembersTableName,
25
+ description: 'group membership associations',
26
+ primaryKeyName: 'groupMemberId',
27
+ fields: (0, types_1.schemaToFields)(exports.groupMemberSchema),
28
+ indexes: [
29
+ { fields: ['groupId', 'userId'], unique: true },
30
+ ]
31
+ };
32
+ class GroupMembersTable extends orm_1.Table {
33
+ static isPassthrough = false;
34
+ async save(groupMember, opts) {
35
+ if (GroupMembersTable.isPassthrough) {
36
+ return super.save(groupMember, opts);
37
+ }
38
+ const oldGroupMember = groupMember.groupMemberId ? await this.get(groupMember.groupMemberId) : undefined;
39
+ if (await (0, group_permissions_1.isGroupMemberSignatureValid)(groupMember.groupId, groupMember, oldGroupMember)) {
40
+ return super.save(groupMember, opts);
41
+ }
42
+ throw new Error('Group member signature is not valid');
43
+ }
44
+ async delete(groupMemberId) {
45
+ if (GroupMembersTable.isPassthrough) {
46
+ return super.delete(groupMemberId);
47
+ }
48
+ const groupMember = await this.get(groupMemberId);
49
+ if (groupMember) {
50
+ groupMember.deleted = true;
51
+ groupMember.role = group_member_roles_1.GroupMemberRole.None;
52
+ await __1.rpcServerCalls.tableSave(groupMember.groupId, "GroupMembers", groupMember);
53
+ }
54
+ }
55
+ /** @deprecated Forbidden on GroupsTable; use save() */
56
+ insert(..._args) {
57
+ throw new Error('GroupsTable forbids insert; use save()');
58
+ }
59
+ /** @deprecated Forbidden on GroupsTable; use save() */
60
+ update(..._args) {
61
+ throw new Error('GroupsTable forbids update; use save()');
62
+ }
63
+ }
64
+ exports.GroupMembersTable = GroupMembersTable;
65
+ (0, table_definitions_system_1.registerSystemTableDefinition)(metaData, exports.groupMemberSchema, GroupMembersTable);
66
+ function GroupMembers(dataContext) {
67
+ return (0, user_context_singleton_1.getTableContainer)(dataContext).getTable(metaData, exports.groupMemberSchema, GroupMembersTable);
68
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,287 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const keys_1 = require("../keys");
4
+ const group_permissions_1 = require("./group-permissions");
5
+ // Test the group members signature logic directly without ORM dependencies
6
+ describe('Group Members Signature Logic', () => {
7
+ let testGroupMember;
8
+ let ownerKeys;
9
+ let adminKeys;
10
+ beforeEach(() => {
11
+ ownerKeys = (0, keys_1.newKeys)();
12
+ adminKeys = (0, keys_1.newKeys)();
13
+ testGroupMember = {
14
+ groupMemberId: 'test-member-1',
15
+ groupId: 'test-group-1',
16
+ userId: 'test-user-1',
17
+ role: group_permissions_1.GroupMemberRole.Reader,
18
+ signature: ''
19
+ };
20
+ });
21
+ describe('basic signature functionality', () => {
22
+ it('should add signature to group member object', () => {
23
+ const signedGroupMember = (0, keys_1.addSignatureToObject)(testGroupMember, ownerKeys.secretKey);
24
+ expect(signedGroupMember.signature).toBeTruthy();
25
+ expect(signedGroupMember.signature).toContain(':');
26
+ expect(signedGroupMember.groupId).toBe(testGroupMember.groupId);
27
+ expect(signedGroupMember.userId).toBe(testGroupMember.userId);
28
+ expect(signedGroupMember.role).toBe(testGroupMember.role);
29
+ });
30
+ it('should verify valid signature', () => {
31
+ const signedGroupMember = (0, keys_1.addSignatureToObject)(testGroupMember, ownerKeys.secretKey);
32
+ const isValid = (0, keys_1.isObjectSignatureValid)(signedGroupMember);
33
+ expect(isValid).toBe(true);
34
+ });
35
+ it('should reject invalid signature after modification', () => {
36
+ const signedGroupMember = (0, keys_1.addSignatureToObject)(testGroupMember, ownerKeys.secretKey);
37
+ // Modify the group member after signing
38
+ signedGroupMember.role = group_permissions_1.GroupMemberRole.Admin;
39
+ const isValid = (0, keys_1.isObjectSignatureValid)(signedGroupMember);
40
+ expect(isValid).toBe(false);
41
+ });
42
+ it('should extract correct public key from signature', () => {
43
+ const signedGroupMember = (0, keys_1.addSignatureToObject)(testGroupMember, ownerKeys.secretKey);
44
+ const extractedKey = (0, keys_1.getPublicKeyFromObjectSignature)(signedGroupMember);
45
+ expect(extractedKey).toBe(ownerKeys.publicKey);
46
+ });
47
+ });
48
+ describe('permission validation with group context', () => {
49
+ // Note: These tests use basic signature verification since the new permission system
50
+ // requires actual user/group data context which isn't available in unit tests
51
+ it('should allow owner to add any role', () => {
52
+ const memberWithAdminRole = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Admin };
53
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithAdminRole, ownerKeys.secretKey);
54
+ expect(signedMember.signature).toBeTruthy();
55
+ expect(signedMember.role).toBe(group_permissions_1.GroupMemberRole.Admin);
56
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
57
+ });
58
+ it('should allow admin to add non-admin roles', () => {
59
+ const signedMember = (0, keys_1.addSignatureToObject)(testGroupMember, adminKeys.secretKey);
60
+ expect(signedMember.signature).toBeTruthy();
61
+ expect(signedMember.role).toBe(group_permissions_1.GroupMemberRole.Reader);
62
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
63
+ });
64
+ it('should allow admin to assign admin roles', () => {
65
+ const memberWithAdminRole = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Admin };
66
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithAdminRole, adminKeys.secretKey);
67
+ expect(signedMember.signature).toBeTruthy();
68
+ expect(signedMember.role).toBe(group_permissions_1.GroupMemberRole.Admin);
69
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
70
+ });
71
+ });
72
+ describe('role assignment rules', () => {
73
+ // Note: These tests focus on basic signature functionality since the new permission system
74
+ // requires actual user/group data context for role-based validation
75
+ it('should allow signing owner role', () => {
76
+ const memberWithOwnerRole = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Owner };
77
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithOwnerRole, ownerKeys.secretKey);
78
+ expect(signedMember.role).toBe(group_permissions_1.GroupMemberRole.Owner);
79
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
80
+ });
81
+ it('should allow signing founder role', () => {
82
+ const memberWithFounderRole = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Founder };
83
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithFounderRole, ownerKeys.secretKey);
84
+ expect(signedMember.role).toBe(group_permissions_1.GroupMemberRole.Founder);
85
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
86
+ });
87
+ it('should allow signing writer role', () => {
88
+ const memberWithWriterRole = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Writer };
89
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithWriterRole, adminKeys.secretKey);
90
+ expect(signedMember.role).toBe(group_permissions_1.GroupMemberRole.Writer);
91
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
92
+ });
93
+ it('should allow setting role to None (blocking user)', () => {
94
+ const memberWithNoneRole = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.None };
95
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithNoneRole, adminKeys.secretKey);
96
+ expect(signedMember.role).toBe(group_permissions_1.GroupMemberRole.None);
97
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
98
+ });
99
+ it('should handle role modifications with signatures', () => {
100
+ const demotedToWriter = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Writer };
101
+ const signedMember = (0, keys_1.addSignatureToObject)(demotedToWriter, adminKeys.secretKey);
102
+ expect(signedMember.role).toBe(group_permissions_1.GroupMemberRole.Writer);
103
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
104
+ });
105
+ });
106
+ describe('signature tampering detection', () => {
107
+ it('should detect tampered signature', () => {
108
+ const signedMember = (0, keys_1.addSignatureToObject)(testGroupMember, ownerKeys.secretKey);
109
+ // Tamper with signature by adding extra characters
110
+ signedMember.signature = signedMember.signature + 'tampered';
111
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(false);
112
+ });
113
+ it('should detect empty signature', () => {
114
+ testGroupMember.signature = '';
115
+ expect((0, keys_1.isObjectSignatureValid)(testGroupMember)).toBe(false);
116
+ });
117
+ it('should detect malformed signature', () => {
118
+ testGroupMember.signature = 'malformed-signature';
119
+ expect((0, keys_1.isObjectSignatureValid)(testGroupMember)).toBe(false);
120
+ });
121
+ it('should handle signature without colon separator', () => {
122
+ testGroupMember.signature = 'noseparator';
123
+ expect((0, keys_1.isObjectSignatureValid)(testGroupMember)).toBe(false);
124
+ expect((0, keys_1.getPublicKeyFromObjectSignature)(testGroupMember)).toBeUndefined();
125
+ });
126
+ });
127
+ describe('complex group member objects', () => {
128
+ it('should handle all role types', () => {
129
+ const roles = [
130
+ group_permissions_1.GroupMemberRole.None,
131
+ group_permissions_1.GroupMemberRole.Reader,
132
+ group_permissions_1.GroupMemberRole.Writer,
133
+ group_permissions_1.GroupMemberRole.Admin,
134
+ group_permissions_1.GroupMemberRole.Owner,
135
+ group_permissions_1.GroupMemberRole.Founder
136
+ ];
137
+ roles.forEach(role => {
138
+ const member = { ...testGroupMember, role };
139
+ const signedMember = (0, keys_1.addSignatureToObject)(member, ownerKeys.secretKey);
140
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
141
+ expect(signedMember.role).toBe(role);
142
+ });
143
+ });
144
+ it('should handle different user and group IDs', () => {
145
+ const memberWithDifferentIds = {
146
+ ...testGroupMember,
147
+ groupMemberId: 'member-123',
148
+ groupId: 'group-456',
149
+ userId: 'user-789'
150
+ };
151
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithDifferentIds, ownerKeys.secretKey);
152
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
153
+ expect(signedMember.groupMemberId).toBe('member-123');
154
+ expect(signedMember.groupId).toBe('group-456');
155
+ expect(signedMember.userId).toBe('user-789');
156
+ });
157
+ });
158
+ describe('edge cases', () => {
159
+ it('should handle long IDs', () => {
160
+ const memberWithLongIds = {
161
+ ...testGroupMember,
162
+ groupMemberId: 'A'.repeat(1000),
163
+ groupId: 'B'.repeat(1000),
164
+ userId: 'C'.repeat(1000)
165
+ };
166
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithLongIds, ownerKeys.secretKey);
167
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
168
+ });
169
+ it('should handle special characters in IDs', () => {
170
+ const memberWithSpecialIds = {
171
+ ...testGroupMember,
172
+ groupMemberId: 'member-🚀-test',
173
+ groupId: 'group-"with"-quotes',
174
+ userId: 'user\nwith\nnewlines'
175
+ };
176
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithSpecialIds, ownerKeys.secretKey);
177
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
178
+ expect(signedMember.groupMemberId).toContain('🚀');
179
+ });
180
+ it('should handle empty string IDs', () => {
181
+ const memberWithEmptyIds = {
182
+ ...testGroupMember,
183
+ groupMemberId: '',
184
+ groupId: '',
185
+ userId: ''
186
+ };
187
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithEmptyIds, ownerKeys.secretKey);
188
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
189
+ });
190
+ it('should handle modification of existing group member', () => {
191
+ const originalMember = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Reader };
192
+ const modifiedMember = { ...originalMember, role: group_permissions_1.GroupMemberRole.Writer };
193
+ const signedMember = (0, keys_1.addSignatureToObject)(modifiedMember, adminKeys.secretKey);
194
+ expect(signedMember.role).toBe(group_permissions_1.GroupMemberRole.Writer);
195
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
196
+ });
197
+ });
198
+ describe('permission functions with role override', () => {
199
+ // Use the optional signerRole parameter to avoid mocking complexity
200
+ describe('signGroupMemberObject', () => {
201
+ it('should allow admin to sign group member', async () => {
202
+ const memberToSign = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Writer };
203
+ const signedMember = await (0, keys_1.addSignatureToObject)(memberToSign, adminKeys.secretKey);
204
+ expect(signedMember.signature).toBeTruthy();
205
+ expect(signedMember.role).toBe(group_permissions_1.GroupMemberRole.Writer);
206
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
207
+ });
208
+ it('should allow owner to sign group member', async () => {
209
+ const memberToSign = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Admin };
210
+ const signedMember = await (0, keys_1.addSignatureToObject)(memberToSign, ownerKeys.secretKey);
211
+ expect(signedMember.signature).toBeTruthy();
212
+ expect(signedMember.role).toBe(group_permissions_1.GroupMemberRole.Admin);
213
+ expect((0, keys_1.isObjectSignatureValid)(signedMember)).toBe(true);
214
+ });
215
+ });
216
+ describe('verifyGroupMemberSignature with role override', () => {
217
+ it('should verify valid signature with admin signer role', async () => {
218
+ const signedMember = (0, keys_1.addSignatureToObject)(testGroupMember, adminKeys.secretKey);
219
+ const isValid = await (0, group_permissions_1.isGroupMemberSignatureValid)(testGroupMember.groupId, signedMember, undefined, group_permissions_1.GroupMemberRole.Admin);
220
+ expect(isValid).toBe(true);
221
+ });
222
+ it('should verify valid signature with owner signer role', async () => {
223
+ const memberWithAdminRole = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Admin };
224
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithAdminRole, ownerKeys.secretKey);
225
+ const isValid = await (0, group_permissions_1.isGroupMemberSignatureValid)(memberWithAdminRole.groupId, signedMember, undefined, group_permissions_1.GroupMemberRole.Owner);
226
+ expect(isValid).toBe(true);
227
+ });
228
+ it('should reject when signer role is below admin', async () => {
229
+ const signedMember = (0, keys_1.addSignatureToObject)(testGroupMember, adminKeys.secretKey);
230
+ const isValid = await (0, group_permissions_1.isGroupMemberSignatureValid)(testGroupMember.groupId, signedMember, undefined, group_permissions_1.GroupMemberRole.Writer);
231
+ expect(isValid).toBe(false);
232
+ });
233
+ it('should reject when signer role is below new member role', async () => {
234
+ const memberWithOwnerRole = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Owner };
235
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithOwnerRole, adminKeys.secretKey);
236
+ const isValid = await (0, group_permissions_1.isGroupMemberSignatureValid)(memberWithOwnerRole.groupId, signedMember, undefined, group_permissions_1.GroupMemberRole.Admin);
237
+ expect(isValid).toBe(false);
238
+ });
239
+ it('should reject when signer role is below old member role', async () => {
240
+ const oldMember = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Owner };
241
+ const newMember = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Writer };
242
+ const signedNewMember = (0, keys_1.addSignatureToObject)(newMember, adminKeys.secretKey);
243
+ const isValid = await (0, group_permissions_1.isGroupMemberSignatureValid)(newMember.groupId, signedNewMember, oldMember, group_permissions_1.GroupMemberRole.Admin);
244
+ expect(isValid).toBe(false);
245
+ });
246
+ it('should allow admin to modify reader role', async () => {
247
+ const memberWithReaderRole = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Reader };
248
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithReaderRole, adminKeys.secretKey);
249
+ const isValid = await (0, group_permissions_1.isGroupMemberSignatureValid)(memberWithReaderRole.groupId, signedMember, undefined, group_permissions_1.GroupMemberRole.Admin);
250
+ expect(isValid).toBe(true);
251
+ });
252
+ it('should allow owner to modify admin role', async () => {
253
+ const memberWithAdminRole = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Admin };
254
+ const signedMember = (0, keys_1.addSignatureToObject)(memberWithAdminRole, ownerKeys.secretKey);
255
+ const isValid = await (0, group_permissions_1.isGroupMemberSignatureValid)(memberWithAdminRole.groupId, signedMember, undefined, group_permissions_1.GroupMemberRole.Owner);
256
+ expect(isValid).toBe(true);
257
+ });
258
+ it('should reject invalid signature', async () => {
259
+ const signedMember = (0, keys_1.addSignatureToObject)(testGroupMember, adminKeys.secretKey);
260
+ signedMember.signature = 'invalid-signature';
261
+ const isValid = await (0, group_permissions_1.isGroupMemberSignatureValid)(testGroupMember.groupId, signedMember, undefined, group_permissions_1.GroupMemberRole.Admin);
262
+ expect(isValid).toBe(false);
263
+ });
264
+ it('should reject when signature is missing', async () => {
265
+ const memberWithoutSignature = { ...testGroupMember, signature: '' };
266
+ const isValid = await (0, group_permissions_1.isGroupMemberSignatureValid)(testGroupMember.groupId, memberWithoutSignature, undefined, group_permissions_1.GroupMemberRole.Admin);
267
+ expect(isValid).toBe(false);
268
+ });
269
+ it('should handle role modifications correctly', async () => {
270
+ const oldMember = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Writer };
271
+ const newMember = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Admin };
272
+ const signedNewMember = (0, keys_1.addSignatureToObject)(newMember, ownerKeys.secretKey);
273
+ // Owner can promote writer to admin
274
+ const isValid = await (0, group_permissions_1.isGroupMemberSignatureValid)(newMember.groupId, signedNewMember, oldMember, group_permissions_1.GroupMemberRole.Owner);
275
+ expect(isValid).toBe(true);
276
+ });
277
+ it('should handle role demotion correctly', async () => {
278
+ const oldMember = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Admin };
279
+ const newMember = { ...testGroupMember, role: group_permissions_1.GroupMemberRole.Writer };
280
+ const signedNewMember = (0, keys_1.addSignatureToObject)(newMember, ownerKeys.secretKey);
281
+ // Owner can demote admin to writer
282
+ const isValid = await (0, group_permissions_1.isGroupMemberSignatureValid)(newMember.groupId, signedNewMember, oldMember, group_permissions_1.GroupMemberRole.Owner);
283
+ expect(isValid).toBe(true);
284
+ });
285
+ });
286
+ });
287
+ });
@@ -0,0 +1,8 @@
1
+ import { GroupMemberRole } from './group-member-roles';
2
+ import type { IGroupMember } from './group-members';
3
+ import type { IGroup } from './groups';
4
+ export { GroupMemberRole };
5
+ export declare function getUserRole(groupId: string, userId: string): Promise<GroupMemberRole>;
6
+ export declare function getUserRoleFromPublicKey(groupId: string, publicKey: string): Promise<GroupMemberRole>;
7
+ export declare function verifyGroupSignature(group: IGroup, oldGroup?: IGroup): Promise<void>;
8
+ export declare function isGroupMemberSignatureValid(groupId: string, newGroupMember: IGroupMember, oldGroupMember?: IGroupMember, signerRole?: GroupMemberRole): Promise<boolean>;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GroupMemberRole = void 0;
4
+ exports.getUserRole = getUserRole;
5
+ exports.getUserRoleFromPublicKey = getUserRoleFromPublicKey;
6
+ exports.verifyGroupSignature = verifyGroupSignature;
7
+ exports.isGroupMemberSignatureValid = isGroupMemberSignatureValid;
8
+ const context_1 = require("../context");
9
+ const keys_1 = require("../keys");
10
+ const group_member_roles_1 = require("./group-member-roles");
11
+ Object.defineProperty(exports, "GroupMemberRole", { enumerable: true, get: function () { return group_member_roles_1.GroupMemberRole; } });
12
+ async function getUserRole(groupId, userId) {
13
+ const { Groups } = await Promise.resolve().then(() => require('./groups'));
14
+ const { GroupMembers } = await Promise.resolve().then(() => require('./group-members'));
15
+ const userContext = await (0, context_1.getUserContext)();
16
+ const groupDataContext = userContext.getDataContext(groupId);
17
+ const group = await Groups(groupDataContext).get(groupId)
18
+ || await Groups(userContext.userDataContext).get(groupId);
19
+ // If the group doesn't exist or the current user is explicitly the founder, return Founder role
20
+ if (!group || group.founderUserId === userId) {
21
+ return group_member_roles_1.GroupMemberRole.Founder;
22
+ }
23
+ const groupMembership = await GroupMembers(groupDataContext).findOne({ userId });
24
+ if (groupMembership) {
25
+ return groupMembership.role;
26
+ }
27
+ return group.publicRole || group_member_roles_1.GroupMemberRole.None;
28
+ }
29
+ async function getUserRoleFromPublicKey(groupId, publicKey) {
30
+ const { Users } = await Promise.resolve().then(() => require('./users'));
31
+ const userContext = await (0, context_1.getUserContext)();
32
+ const groupDataContext = userContext.getDataContext(groupId);
33
+ const user = await Users(groupDataContext).findOne({ publicKey })
34
+ || await Users(userContext.userDataContext).findOne({ publicKey });
35
+ if (user) {
36
+ return getUserRole(groupId, user?.userId);
37
+ }
38
+ return group_member_roles_1.GroupMemberRole.None;
39
+ }
40
+ async function verifyGroupSignature(group, oldGroup) {
41
+ (0, keys_1.verifyObjectSignature)(group);
42
+ const publicKey = (0, keys_1.getPublicKeyFromObjectSignature)(group) ?? '';
43
+ const signerRole = await getUserRoleFromPublicKey(group.groupId, publicKey);
44
+ if (oldGroup && oldGroup.founderUserId !== group.founderUserId && signerRole < group_member_roles_1.GroupMemberRole.Founder) {
45
+ throw new Error('Only group founders can change the founder of the group');
46
+ }
47
+ if (signerRole < group_member_roles_1.GroupMemberRole.Admin) {
48
+ throw new Error('Only group admins can modify group settings');
49
+ }
50
+ }
51
+ async function isGroupMemberSignatureValid(groupId, newGroupMember, oldGroupMember, signerRole) {
52
+ oldGroupMember ??= newGroupMember;
53
+ // Basic signature verification
54
+ if (!(0, keys_1.isObjectSignatureValid)(newGroupMember)) {
55
+ return false;
56
+ }
57
+ // Get the public key that signed this group member
58
+ const signerPublicKey = (0, keys_1.getPublicKeyFromObjectSignature)(newGroupMember);
59
+ if (!signerPublicKey) {
60
+ return false;
61
+ }
62
+ // Determine signer's role in the group using the user-based permission system
63
+ signerRole ??= await getUserRoleFromPublicKey(groupId, signerPublicKey);
64
+ // Validate permissions for group member modifications
65
+ if (signerRole < group_member_roles_1.GroupMemberRole.Admin) {
66
+ return false; // Only group admins or above can modify group membership
67
+ }
68
+ // admins or above can only modify roles up to their own level
69
+ if (signerRole < newGroupMember.role || signerRole < oldGroupMember.role) {
70
+ return false;
71
+ }
72
+ return true;
73
+ }
@@ -0,0 +1,50 @@
1
+ import { IGroupMember } from './group-members';
2
+ import { IGroup } from './groups';
3
+ /**
4
+ * Interface representing a shareable group with admin+ members
5
+ */
6
+ export interface IGroupShare {
7
+ /** The group information */
8
+ group: IGroup;
9
+ /** Members with Admin role or above (Admin=60, Owner=80, Founder=100) */
10
+ groupMembers: IGroupMember[];
11
+ }
12
+ /**
13
+ * Generates a GroupShare object containing the group and its admin+ members
14
+ * @param groupId The ID of the group to share
15
+ * @returns Promise<GroupShare> The shareable group data
16
+ * @throws Error if group not found or user lacks permission
17
+ */
18
+ export declare function generateGroupShare(groupId: string): Promise<IGroupShare>;
19
+ /**
20
+ * Validates that an object has the correct GroupShare structure
21
+ * @param obj Object to validate
22
+ * @returns boolean True if valid GroupShare structure
23
+ */
24
+ export declare function validateGroupShare(obj: any): obj is IGroupShare;
25
+ /**
26
+ * Estimates the size of a GroupShare object when serialized to JSON
27
+ * @param groupShare The GroupShare object to estimate
28
+ * @returns number Estimated size in characters
29
+ */
30
+ export declare function estimateGroupShareSize(groupShare: IGroupShare): number;
31
+ /**
32
+ * Checks if a GroupShare object would fit in a QR code of the specified version
33
+ * @param groupShare The GroupShare object to check
34
+ * @param qrVersion QR code version (10, 20, or 40)
35
+ * @returns Object with size info and QR code compatibility
36
+ */
37
+ export declare function checkQRCodeCompatibility(groupShare: IGroupShare, qrVersion?: 10 | 20 | 40): {
38
+ size: number;
39
+ maxSize: number;
40
+ fits: boolean;
41
+ usagePercent: number;
42
+ qrVersion: 10 | 20 | 40;
43
+ memberCount: number;
44
+ };
45
+ /**
46
+ * Copies text to clipboard with fallback handling
47
+ * @param text Text to copy to clipboard
48
+ * @returns Promise<boolean> True if successful
49
+ */
50
+ export declare function copyToClipboard(text: string): Promise<boolean>;