@enbox/protocols 0.1.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/src/lists.ts ADDED
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Lists Protocol — flexible list management with folders and collaboration.
3
+ *
4
+ * Supports both nesting patterns:
5
+ * - **Fixed-depth folders**: `folder/folder/folder` (3 levels max)
6
+ * - **Flat items with tag-based hierarchy**: `list/item` with `parentItemId` tag
7
+ *
8
+ * Composes with Social Graph for friend-scoped read access and
9
+ * defines a `collaborator` role for write access to shared lists.
10
+ *
11
+ * @module
12
+ */
13
+
14
+ import type { ProtocolDefinition } from '@enbox/dwn-sdk-js';
15
+
16
+ import { defineProtocol } from '@enbox/api';
17
+
18
+ // ---------------------------------------------------------------------------
19
+ // Data types
20
+ // ---------------------------------------------------------------------------
21
+
22
+ /** Data shape for a list record. */
23
+ export type ListData = {
24
+ name: string;
25
+ description?: string;
26
+ icon?: string;
27
+ listType: 'todo' | 'bookmarks' | 'reading' | 'custom';
28
+ };
29
+
30
+ /** Data shape for a list item. */
31
+ export type ItemData = {
32
+ title: string;
33
+ url?: string;
34
+ note?: string;
35
+ completed?: boolean;
36
+ sortOrder?: number;
37
+ };
38
+
39
+ /** Data shape for a folder record. */
40
+ export type FolderData = {
41
+ name: string;
42
+ icon?: string;
43
+ sortOrder?: number;
44
+ };
45
+
46
+ /** Data shape for a collaborator record. */
47
+ export type CollaboratorData = {
48
+ did: string;
49
+ alias?: string;
50
+ };
51
+
52
+ /** Data shape for a comment on a list item. */
53
+ export type CommentData = {
54
+ text: string;
55
+ };
56
+
57
+ // ---------------------------------------------------------------------------
58
+ // Schema map
59
+ // ---------------------------------------------------------------------------
60
+
61
+ /** Maps protocol type names to their TypeScript data shapes. */
62
+ export type ListsSchemaMap = {
63
+ list: ListData;
64
+ item: ItemData;
65
+ folder: FolderData;
66
+ collaborator: CollaboratorData;
67
+ comment: CommentData;
68
+ };
69
+
70
+ // ---------------------------------------------------------------------------
71
+ // Protocol definition
72
+ // ---------------------------------------------------------------------------
73
+
74
+ export const ListsDefinition = {
75
+ protocol : 'https://enbox.org/protocols/lists',
76
+ published : false,
77
+ uses : {
78
+ social: 'https://enbox.org/protocols/social-graph',
79
+ },
80
+ types: {
81
+ list: {
82
+ schema : 'https://enbox.org/schemas/lists/list',
83
+ dataFormats : ['application/json'],
84
+ },
85
+ item: {
86
+ schema : 'https://enbox.org/schemas/lists/item',
87
+ dataFormats : ['application/json'],
88
+ },
89
+ folder: {
90
+ schema : 'https://enbox.org/schemas/lists/folder',
91
+ dataFormats : ['application/json'],
92
+ },
93
+ collaborator: {
94
+ schema : 'https://enbox.org/schemas/lists/collaborator',
95
+ dataFormats : ['application/json'],
96
+ },
97
+ comment: {
98
+ schema : 'https://enbox.org/schemas/lists/comment',
99
+ dataFormats : ['application/json'],
100
+ },
101
+ },
102
+ structure: {
103
+ list: {
104
+ $actions: [
105
+ { role: 'social:friend', can: ['read'] },
106
+ ],
107
+ $tags: {
108
+ $requiredTags : ['listType'],
109
+ $allowUndefinedTags : false,
110
+ listType : { type: 'string', enum: ['todo', 'bookmarks', 'reading', 'custom'] },
111
+ },
112
+ item: {
113
+ $actions: [
114
+ { role: 'social:friend', can: ['read'] },
115
+ { role: 'list/collaborator', can: ['create', 'read', 'update', 'delete'] },
116
+ ],
117
+ $tags: {
118
+ $allowUndefinedTags : true,
119
+ parentItemId : { type: 'string' },
120
+ },
121
+ comment: {
122
+ $actions: [
123
+ { role: 'list/collaborator', can: ['create', 'read'] },
124
+ ],
125
+ },
126
+ },
127
+ collaborator: {
128
+ $role : true,
129
+ $actions : [
130
+ { who: 'anyone', can: ['read'] },
131
+ ],
132
+ $tags: {
133
+ $requiredTags : ['did'],
134
+ $allowUndefinedTags : false,
135
+ did : { type: 'string' },
136
+ },
137
+ },
138
+ },
139
+ folder: {
140
+ $actions : [],
141
+ $tags : {
142
+ $allowUndefinedTags : true,
143
+ sortOrder : { type: 'number' },
144
+ },
145
+ folder: {
146
+ $actions : [],
147
+ folder : {
148
+ $actions: [],
149
+ },
150
+ },
151
+ },
152
+ },
153
+ } as const satisfies ProtocolDefinition;
154
+
155
+ // ---------------------------------------------------------------------------
156
+ // Typed protocol export
157
+ // ---------------------------------------------------------------------------
158
+
159
+ /** Typed Lists protocol for use with `dwn.using()`. */
160
+ export const ListsProtocol = defineProtocol(
161
+ ListsDefinition,
162
+ {} as ListsSchemaMap,
163
+ );
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Preferences Protocol — user configuration and settings.
3
+ *
4
+ * Stores theme, locale, privacy, and notification preferences.
5
+ * Fully owner-only (no external reads). The `privacy` type uses
6
+ * `encryptionRequired` for at-rest encryption of sensitive settings.
7
+ *
8
+ * @module
9
+ */
10
+
11
+ import type { ProtocolDefinition } from '@enbox/dwn-sdk-js';
12
+
13
+ import { defineProtocol } from '@enbox/api';
14
+
15
+ // ---------------------------------------------------------------------------
16
+ // Data types
17
+ // ---------------------------------------------------------------------------
18
+
19
+ /** Data shape for theme preferences. */
20
+ export type ThemeData = {
21
+ mode: 'light' | 'dark' | 'system';
22
+ accentColor?: string;
23
+ fontSize?: 'small' | 'medium' | 'large';
24
+ };
25
+
26
+ /** Data shape for locale preferences. */
27
+ export type LocaleData = {
28
+ language: string;
29
+ region?: string;
30
+ timezone?: string;
31
+ dateFormat?: string;
32
+ hourCycle?: '12h' | '24h';
33
+ };
34
+
35
+ /** Data shape for privacy preferences. */
36
+ export type PrivacyData = {
37
+ cookieConsent: {
38
+ analytics: boolean;
39
+ marketing: boolean;
40
+ functional: boolean;
41
+ };
42
+ shareUsageData: boolean;
43
+ };
44
+
45
+ /** Data shape for notification preferences. */
46
+ export type NotificationData = {
47
+ channel: string;
48
+ enabled: boolean;
49
+ quietHoursStart?: string;
50
+ quietHoursEnd?: string;
51
+ };
52
+
53
+ // ---------------------------------------------------------------------------
54
+ // Schema map
55
+ // ---------------------------------------------------------------------------
56
+
57
+ /** Maps protocol type names to their TypeScript data shapes. */
58
+ export type PreferencesSchemaMap = {
59
+ theme: ThemeData;
60
+ locale: LocaleData;
61
+ privacy: PrivacyData;
62
+ notification: NotificationData;
63
+ };
64
+
65
+ // ---------------------------------------------------------------------------
66
+ // Protocol definition
67
+ // ---------------------------------------------------------------------------
68
+
69
+ export const PreferencesDefinition = {
70
+ protocol : 'https://enbox.org/protocols/preferences',
71
+ published : false,
72
+ types : {
73
+ theme: {
74
+ schema : 'https://enbox.org/schemas/preferences/theme',
75
+ dataFormats : ['application/json'],
76
+ },
77
+ locale: {
78
+ schema : 'https://enbox.org/schemas/preferences/locale',
79
+ dataFormats : ['application/json'],
80
+ },
81
+ privacy: {
82
+ schema : 'https://enbox.org/schemas/preferences/privacy',
83
+ dataFormats : ['application/json'],
84
+ encryptionRequired : true,
85
+ },
86
+ notification: {
87
+ schema : 'https://enbox.org/schemas/preferences/notification',
88
+ dataFormats : ['application/json'],
89
+ },
90
+ },
91
+ structure: {
92
+ theme: {
93
+ $actions: [],
94
+ },
95
+ locale: {
96
+ $actions: [],
97
+ },
98
+ privacy: {
99
+ $actions: [],
100
+ },
101
+ notification: {
102
+ $actions : [],
103
+ $tags : {
104
+ $requiredTags : ['channel'],
105
+ $allowUndefinedTags : false,
106
+ channel : { type: 'string' },
107
+ },
108
+ },
109
+ },
110
+ } as const satisfies ProtocolDefinition;
111
+
112
+ // ---------------------------------------------------------------------------
113
+ // Typed protocol export
114
+ // ---------------------------------------------------------------------------
115
+
116
+ /** Typed Preferences protocol for use with `dwn.using()`. */
117
+ export const PreferencesProtocol = defineProtocol(
118
+ PreferencesDefinition,
119
+ {} as PreferencesSchemaMap,
120
+ );
package/src/profile.ts ADDED
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Profile Protocol — public and semi-private identity information.
3
+ *
4
+ * Supports a published profile record, avatar (binary), links, and
5
+ * private notes visible only to friends (via Social Graph composition).
6
+ *
7
+ * @module
8
+ */
9
+
10
+ import type { ProtocolDefinition } from '@enbox/dwn-sdk-js';
11
+
12
+ import { defineProtocol } from '@enbox/api';
13
+
14
+ // ---------------------------------------------------------------------------
15
+ // Data types
16
+ // ---------------------------------------------------------------------------
17
+
18
+ /** Data shape for a profile record. */
19
+ export type ProfileData = {
20
+ displayName: string;
21
+ bio?: string;
22
+ location?: string;
23
+ website?: string;
24
+ pronouns?: string;
25
+ };
26
+
27
+ /** Avatar is stored as binary data (Blob). */
28
+ export type AvatarData = Blob;
29
+
30
+ /** Data shape for a link record (e.g. social links). */
31
+ export type LinkData = {
32
+ url: string;
33
+ title: string;
34
+ icon?: string;
35
+ sortOrder?: number;
36
+ };
37
+
38
+ /** Data shape for a private note (visible only to friends). */
39
+ export type PrivateNoteData = {
40
+ content: string;
41
+ };
42
+
43
+ // ---------------------------------------------------------------------------
44
+ // Schema map
45
+ // ---------------------------------------------------------------------------
46
+
47
+ /** Maps protocol type names to their TypeScript data shapes. */
48
+ export type ProfileSchemaMap = {
49
+ profile: ProfileData;
50
+ avatar: AvatarData;
51
+ link: LinkData;
52
+ privateNote: PrivateNoteData;
53
+ };
54
+
55
+ // ---------------------------------------------------------------------------
56
+ // Protocol definition
57
+ // ---------------------------------------------------------------------------
58
+
59
+ export const ProfileDefinition = {
60
+ protocol : 'https://enbox.org/protocols/profile',
61
+ published : true,
62
+ uses : {
63
+ social: 'https://enbox.org/protocols/social-graph',
64
+ },
65
+ types: {
66
+ profile: {
67
+ schema : 'https://enbox.org/schemas/profile/profile',
68
+ dataFormats : ['application/json'],
69
+ },
70
+ avatar: {
71
+ dataFormats: ['image/png', 'image/jpeg', 'image/gif', 'image/webp'],
72
+ },
73
+ link: {
74
+ schema : 'https://enbox.org/schemas/profile/link',
75
+ dataFormats : ['application/json'],
76
+ },
77
+ privateNote: {
78
+ schema : 'https://enbox.org/schemas/profile/private-note',
79
+ dataFormats : ['application/json'],
80
+ },
81
+ },
82
+ structure: {
83
+ profile: {
84
+ $size : { max: 10000 },
85
+ $actions : [
86
+ { who: 'anyone', can: ['read'] },
87
+ ],
88
+ avatar: {
89
+ $size : { max: 1048576 },
90
+ $actions : [
91
+ { who: 'anyone', can: ['read'] },
92
+ ],
93
+ },
94
+ link: {
95
+ $actions: [
96
+ { who: 'anyone', can: ['read'] },
97
+ ],
98
+ },
99
+ },
100
+ privateNote: {
101
+ $actions: [
102
+ { role: 'social:friend', can: ['read'] },
103
+ ],
104
+ },
105
+ },
106
+ } as const satisfies ProtocolDefinition;
107
+
108
+ // ---------------------------------------------------------------------------
109
+ // Typed protocol export
110
+ // ---------------------------------------------------------------------------
111
+
112
+ /** Typed Profile protocol for use with `dwn.using()`. */
113
+ export const ProfileProtocol = defineProtocol(
114
+ ProfileDefinition,
115
+ {} as ProfileSchemaMap,
116
+ );
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Social Graph Protocol — foundation protocol for relationship management.
3
+ *
4
+ * Provides friend, block, group, and member types with role-based access.
5
+ * Other protocols compose with this via `uses` to leverage the `friend` role
6
+ * for cross-protocol authorization.
7
+ *
8
+ * @module
9
+ */
10
+
11
+ import type { ProtocolDefinition } from '@enbox/dwn-sdk-js';
12
+
13
+ import { defineProtocol } from '@enbox/api';
14
+
15
+ // ---------------------------------------------------------------------------
16
+ // Data types
17
+ // ---------------------------------------------------------------------------
18
+
19
+ /** Data shape for a friend record. */
20
+ export type FriendData = {
21
+ did: string;
22
+ alias?: string;
23
+ note?: string;
24
+ };
25
+
26
+ /** Data shape for a block record. */
27
+ export type BlockData = {
28
+ did: string;
29
+ reason?: string;
30
+ };
31
+
32
+ /** Data shape for a group record. */
33
+ export type GroupData = {
34
+ name: string;
35
+ description?: string;
36
+ icon?: string;
37
+ };
38
+
39
+ /** Data shape for a group member record. */
40
+ export type MemberData = {
41
+ did: string;
42
+ alias?: string;
43
+ };
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // Schema map
47
+ // ---------------------------------------------------------------------------
48
+
49
+ /** Maps protocol type names to their TypeScript data shapes. */
50
+ export type SocialGraphSchemaMap = {
51
+ friend: FriendData;
52
+ block: BlockData;
53
+ group: GroupData;
54
+ member: MemberData;
55
+ };
56
+
57
+ // ---------------------------------------------------------------------------
58
+ // Protocol definition
59
+ // ---------------------------------------------------------------------------
60
+
61
+ export const SocialGraphDefinition = {
62
+ protocol : 'https://enbox.org/protocols/social-graph',
63
+ published : true,
64
+ types : {
65
+ friend: {
66
+ schema : 'https://enbox.org/schemas/social-graph/friend',
67
+ dataFormats : ['application/json'],
68
+ },
69
+ block: {
70
+ schema : 'https://enbox.org/schemas/social-graph/block',
71
+ dataFormats : ['application/json'],
72
+ },
73
+ group: {
74
+ schema : 'https://enbox.org/schemas/social-graph/group',
75
+ dataFormats : ['application/json'],
76
+ },
77
+ member: {
78
+ schema : 'https://enbox.org/schemas/social-graph/member',
79
+ dataFormats : ['application/json'],
80
+ },
81
+ },
82
+ structure: {
83
+ friend: {
84
+ $role : true,
85
+ $actions : [
86
+ { who: 'anyone', can: ['create'] },
87
+ { who: 'author', of: 'friend', can: ['read'] },
88
+ ],
89
+ $tags: {
90
+ $requiredTags : ['did'],
91
+ $allowUndefinedTags : false,
92
+ did : { type: 'string' },
93
+ },
94
+ },
95
+ block: {
96
+ $actions: [
97
+ { who: 'anyone', can: ['create'] },
98
+ ],
99
+ $tags: {
100
+ $requiredTags : ['did'],
101
+ $allowUndefinedTags : false,
102
+ did : { type: 'string' },
103
+ },
104
+ },
105
+ group: {
106
+ $actions: [
107
+ { who: 'anyone', can: ['read'] },
108
+ ],
109
+ member: {
110
+ $actions: [
111
+ { who: 'anyone', can: ['read'] },
112
+ ],
113
+ $tags: {
114
+ $requiredTags : ['did'],
115
+ $allowUndefinedTags : false,
116
+ did : { type: 'string' },
117
+ },
118
+ },
119
+ },
120
+ },
121
+ } as const satisfies ProtocolDefinition;
122
+
123
+ // ---------------------------------------------------------------------------
124
+ // Typed protocol export
125
+ // ---------------------------------------------------------------------------
126
+
127
+ /** Typed Social Graph protocol for use with `dwn.using()`. */
128
+ export const SocialGraphProtocol = defineProtocol(
129
+ SocialGraphDefinition,
130
+ {} as SocialGraphSchemaMap,
131
+ );
package/src/status.ts ADDED
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Status Protocol — ephemeral status updates with reactions.
3
+ *
4
+ * Uses the `published` flag on individual records to control visibility:
5
+ * published statuses are readable by anyone, unpublished ones only by friends.
6
+ * Composes with Social Graph for friend-scoped access and reactions.
7
+ *
8
+ * @module
9
+ */
10
+
11
+ import type { ProtocolDefinition } from '@enbox/dwn-sdk-js';
12
+
13
+ import { defineProtocol } from '@enbox/api';
14
+
15
+ // ---------------------------------------------------------------------------
16
+ // Data types
17
+ // ---------------------------------------------------------------------------
18
+
19
+ /** Data shape for a status update. */
20
+ export type StatusData = {
21
+ text: string;
22
+ emoji?: string;
23
+ activity?: 'online' | 'away' | 'busy' | 'offline';
24
+ expiresAt?: string;
25
+ };
26
+
27
+ /** Data shape for a reaction to a status. */
28
+ export type ReactionData = {
29
+ emoji: string;
30
+ };
31
+
32
+ // ---------------------------------------------------------------------------
33
+ // Schema map
34
+ // ---------------------------------------------------------------------------
35
+
36
+ /** Maps protocol type names to their TypeScript data shapes. */
37
+ export type StatusSchemaMap = {
38
+ status: StatusData;
39
+ reaction: ReactionData;
40
+ };
41
+
42
+ // ---------------------------------------------------------------------------
43
+ // Protocol definition
44
+ // ---------------------------------------------------------------------------
45
+
46
+ export const StatusDefinition = {
47
+ protocol : 'https://enbox.org/protocols/status',
48
+ published : true,
49
+ uses : {
50
+ social: 'https://enbox.org/protocols/social-graph',
51
+ },
52
+ types: {
53
+ status: {
54
+ schema : 'https://enbox.org/schemas/status/status',
55
+ dataFormats : ['application/json'],
56
+ },
57
+ reaction: {
58
+ schema : 'https://enbox.org/schemas/status/reaction',
59
+ dataFormats : ['application/json'],
60
+ },
61
+ },
62
+ structure: {
63
+ status: {
64
+ $size : { max: 5000 },
65
+ $actions : [
66
+ { who: 'anyone', can: ['read'] },
67
+ { role: 'social:friend', can: ['read'] },
68
+ ],
69
+ reaction: {
70
+ $actions: [
71
+ { role: 'social:friend', can: ['create', 'read', 'delete'] },
72
+ ],
73
+ },
74
+ },
75
+ },
76
+ } as const satisfies ProtocolDefinition;
77
+
78
+ // ---------------------------------------------------------------------------
79
+ // Typed protocol export
80
+ // ---------------------------------------------------------------------------
81
+
82
+ /** Typed Status protocol for use with `dwn.using()`. */
83
+ export const StatusProtocol = defineProtocol(
84
+ StatusDefinition,
85
+ {} as StatusSchemaMap,
86
+ );