pubky-app-specs 0.4.4 → 0.5.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/LICENSE +21 -0
- package/README.md +166 -321
- package/package.json +11 -52
- package/pubky_app_specs.d.ts +448 -361
- package/{index.cjs → pubky_app_specs.js} +1840 -1902
- package/pubky_app_specs_bg.wasm +0 -0
- package/example.js +0 -295
- package/index.js +0 -3002
- package/validationLimits.cjs +0 -9
- package/validationLimits.js +0 -5
- package/validationLimits.json +0 -35
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 Synonym
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,409 +1,254 @@
|
|
|
1
|
-
# Pubky
|
|
1
|
+
# Pubky.app Data Model Specification
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[](https://opensource.org/licenses/MIT)
|
|
3
|
+
_Version 0.4.4_
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
> ⚠️ **Warning: Rapid Development Phase**
|
|
6
|
+
> This specification is in an **early development phase** and is evolving quickly. Expect frequent changes and updates as the system matures. Consider this a **v0 draft**.
|
|
7
|
+
>
|
|
8
|
+
> When we reach the first stable, long-term support version of the schemas, paths will adopt the format: `pubky.app/v1/` to indicate compatibility and stability.
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
- **Auto-ID’ed** and **Auto-Pathed** according to your domain rules.
|
|
10
|
-
- **Exported** to JavaScript/TypeScript with minimal overhead.
|
|
10
|
+
### JS package
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- **Validation Consistency**: Ensures your app uses the same sanitization and validation rules as [Pubky indexers](https://github.com/pubky/pubky-nexus), avoiding errors.
|
|
15
|
-
- **Schema Versioning**: Automatically stay up-to-date with schema changes, reducing maintenance overhead.
|
|
16
|
-
- **Auto IDs & Paths**: Generates unique IDs, paths, and URLs according to Pubky standards.
|
|
17
|
-
- **Rust-to-JavaScript Compatibility**: Type-safe models that work seamlessly across Rust and JavaScript/TypeScript.
|
|
18
|
-
- **Future-Proof**: Easily adapt to new Pubky object types without rewriting JSON manually.
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## ⚙️ Installation
|
|
12
|
+
The package is available as an npm module [pubky-app-specs](https://www.npmjs.com/package/pubky-app-specs). Alternatively, you can build from source using the provided build scripts:
|
|
23
13
|
|
|
24
14
|
```bash
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
yarn add pubky-app-specs
|
|
15
|
+
cd pkg
|
|
16
|
+
npm run build
|
|
28
17
|
```
|
|
29
18
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## 🚀 Quick Start
|
|
19
|
+
Test with:
|
|
35
20
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
### Import & Usage
|
|
42
|
-
|
|
43
|
-
```js
|
|
44
|
-
// ES Modules
|
|
45
|
-
import { PubkySpecsBuilder } from "pubky-app-specs";
|
|
21
|
+
```bash
|
|
22
|
+
cd pkg
|
|
23
|
+
npm run install
|
|
24
|
+
npm run test
|
|
25
|
+
```
|
|
46
26
|
|
|
47
|
-
|
|
48
|
-
const { PubkySpecsBuilder } = require("pubky-app-specs");
|
|
27
|
+
Examples with:
|
|
49
28
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return specs;
|
|
54
|
-
}
|
|
29
|
+
```bash
|
|
30
|
+
cd pkg
|
|
31
|
+
npm run example
|
|
55
32
|
```
|
|
56
33
|
|
|
57
34
|
---
|
|
58
35
|
|
|
59
|
-
##
|
|
36
|
+
## Table of Contents
|
|
37
|
+
|
|
38
|
+
- [Pubky.app Data Model Specification](#pubkyapp-data-model-specification)
|
|
39
|
+
- [JS package](#js-package)
|
|
40
|
+
- [Table of Contents](#table-of-contents)
|
|
41
|
+
- [Introduction](#introduction)
|
|
42
|
+
- [Quick Start](#quick-start)
|
|
43
|
+
- [Concepts:](#concepts)
|
|
44
|
+
- [Data Models](#data-models)
|
|
45
|
+
- [PubkyAppUser](#pubkyappuser)
|
|
46
|
+
- [PubkyAppFile](#pubkyappfile)
|
|
47
|
+
- [PubkyAppPost](#pubkyapppost)
|
|
48
|
+
- [PubkyAppTag](#pubkyapptag)
|
|
49
|
+
- [PubkyAppBookmark](#pubkyappbookmark)
|
|
50
|
+
- [PubkyAppFollow](#pubkyappfollow)
|
|
51
|
+
- [PubkyAppFeed](#pubkyappfeed)
|
|
52
|
+
- [Validation Rules](#validation-rules)
|
|
53
|
+
- [Common Rules](#common-rules)
|
|
54
|
+
- [License](#license)
|
|
55
|
+
|
|
56
|
+
---
|
|
60
57
|
|
|
61
|
-
|
|
58
|
+
## Introduction
|
|
62
59
|
|
|
63
|
-
|
|
60
|
+
This document specifies the data models and validation rules for the **Pubky.app** clients interactions. It defines the structure of data entities, their properties, and the validation rules to ensure data integrity and consistency. This is intended for developers building compatible libraries or clients.
|
|
64
61
|
|
|
65
|
-
|
|
66
|
-
import { Client, PublicKey } from "@synonymdev/pubky";
|
|
67
|
-
import { PubkySpecsBuilder } from "pubky-app-specs";
|
|
62
|
+
This document intents to be a faithful representation of our [Rust pubky.app models](https://github.com/pubky/pubky-app-specs/tree/main/src). If you intend to develop in Rust, use them directly. In case of disagreement between this document and the Rust implementation, the Rust implementation prevails.
|
|
68
63
|
|
|
69
|
-
|
|
70
|
-
const client = new Client();
|
|
71
|
-
const specs = new PubkySpecsBuilder(pubkyId);
|
|
64
|
+
---
|
|
72
65
|
|
|
73
|
-
|
|
74
|
-
const { user, meta } = specs.createUser(
|
|
75
|
-
"Alice", // Name
|
|
76
|
-
"Hello from WASM", // Bio
|
|
77
|
-
null, // Image URL or File
|
|
78
|
-
null, // Links
|
|
79
|
-
"active", // Status
|
|
80
|
-
);
|
|
66
|
+
## Quick Start
|
|
81
67
|
|
|
82
|
-
|
|
83
|
-
// user is the Rust "PubkyAppUser" object.
|
|
68
|
+
Pubky.app models are designed for decentralized content sharing. The system uses a combination of timestamp-based IDs and Blake3-hashed IDs encoded in Crockford Base32 to ensure unique identifiers for each entity.
|
|
84
69
|
|
|
85
|
-
|
|
86
|
-
const userJson = user.toJson();
|
|
70
|
+
### Concepts:
|
|
87
71
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
body: JSON.stringify(userJson),
|
|
92
|
-
credentials: "include",
|
|
93
|
-
});
|
|
72
|
+
- **Timestamp IDs** for sequential objects like posts and files.
|
|
73
|
+
- **Hash IDs** for content-based uniqueness (e.g., tags and bookmarks).
|
|
74
|
+
- **Validation Rules** ensure consistent and interoperable data formats.
|
|
94
75
|
|
|
95
|
-
|
|
96
|
-
throw new Error(`Failed to store user: ${response.statusText}`);
|
|
97
|
-
}
|
|
76
|
+
---
|
|
98
77
|
|
|
99
|
-
|
|
100
|
-
return { user, meta };
|
|
101
|
-
}
|
|
102
|
-
```
|
|
78
|
+
## Data Models
|
|
103
79
|
|
|
104
|
-
###
|
|
105
|
-
|
|
106
|
-
```js
|
|
107
|
-
import { Client } from "@synonymdev/pubky";
|
|
108
|
-
import { PubkySpecsBuilder, PubkyAppPostKind } from "pubky-app-specs";
|
|
109
|
-
|
|
110
|
-
async function createPost(pubkyId, content) {
|
|
111
|
-
const client = new Client();
|
|
112
|
-
const specs = new PubkySpecsBuilder(pubkyId);
|
|
113
|
-
|
|
114
|
-
// Create the Post object
|
|
115
|
-
const { post, meta } = specs.createPost(
|
|
116
|
-
content,
|
|
117
|
-
PubkyAppPostKind.Short,
|
|
118
|
-
null, // parent post URI (for replies)
|
|
119
|
-
null, // embed object (for reposts)
|
|
120
|
-
null, // attachments (array of file URLs, max 3)
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
// Store the post
|
|
124
|
-
const postJson = post.toJson();
|
|
125
|
-
await client.fetch(meta.url, {
|
|
126
|
-
method: "PUT",
|
|
127
|
-
body: JSON.stringify(postJson),
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
console.log("Post stored at:", meta.url);
|
|
131
|
-
return { post, meta };
|
|
132
|
-
}
|
|
133
|
-
```
|
|
80
|
+
### PubkyAppUser
|
|
134
81
|
|
|
135
|
-
|
|
82
|
+
**Description:** Represents a user's profile information.
|
|
136
83
|
|
|
137
|
-
|
|
138
|
-
import { Client } from "@synonymdev/pubky";
|
|
139
|
-
import { PubkySpecsBuilder, PubkyAppPostKind } from "pubky-app-specs";
|
|
84
|
+
**URI:** `/pub/pubky.app/profile.json`
|
|
140
85
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
86
|
+
| **Field** | **Type** | **Description** | **Validation Rules** |
|
|
87
|
+
| --------- | -------- | --------------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
88
|
+
| `name` | String | User's name. | Required. Length: 3–50 characters. Cannot be `"[DELETED]"`. |
|
|
89
|
+
| `bio` | String | Short biography. | Optional. Maximum length: 160 characters. |
|
|
90
|
+
| `image` | String | URL to the user's profile image. | Optional. Valid URL. Maximum length: 300 characters. |
|
|
91
|
+
| `links` | Array | List of associated links (title + URL). | Optional. Maximum of 5 links, each with title (100 chars max) and valid URL (300 chars max). |
|
|
92
|
+
| `status` | String | User's current status. | Optional. Maximum length: 50 characters. |
|
|
144
93
|
|
|
145
|
-
|
|
146
|
-
const { post, meta } = specs.createPost(
|
|
147
|
-
content,
|
|
148
|
-
PubkyAppPostKind.Image,
|
|
149
|
-
null, // parent
|
|
150
|
-
null, // embed
|
|
151
|
-
fileUrls, // e.g. ["pubky://user/pub/pubky.app/files/abc123"]
|
|
152
|
-
);
|
|
94
|
+
**Validation Notes:**
|
|
153
95
|
|
|
154
|
-
|
|
155
|
-
|
|
96
|
+
- Reserved keyword `[DELETED]` cannot be used for `name`.
|
|
97
|
+
- Each `UserLink` in `links` must have a valid title and URL.
|
|
156
98
|
|
|
157
|
-
|
|
158
|
-
method: "PUT",
|
|
159
|
-
body: JSON.stringify(postJson),
|
|
160
|
-
});
|
|
99
|
+
**Example: Valid User**
|
|
161
100
|
|
|
162
|
-
|
|
163
|
-
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"name": "Alice",
|
|
104
|
+
"bio": "Toxic maximalist.",
|
|
105
|
+
"image": "pubky://user_id/pub/pubky.app/files/0000000000000",
|
|
106
|
+
"links": [
|
|
107
|
+
{
|
|
108
|
+
"title": "GitHub",
|
|
109
|
+
"url": "https://github.com/alice"
|
|
110
|
+
}
|
|
111
|
+
],
|
|
112
|
+
"status": "Exploring decentralized tech."
|
|
164
113
|
}
|
|
165
114
|
```
|
|
166
115
|
|
|
167
|
-
|
|
116
|
+
---
|
|
168
117
|
|
|
169
|
-
|
|
170
|
-
import { Client } from "@synonymdev/pubky";
|
|
171
|
-
import { PubkySpecsBuilder } from "pubky-app-specs";
|
|
118
|
+
### PubkyAppFile
|
|
172
119
|
|
|
173
|
-
|
|
174
|
-
const client = new Client();
|
|
175
|
-
const specs = new PubkySpecsBuilder(myPubkyId);
|
|
120
|
+
**Description:** Represents a file uploaded by the user, containing its metadata, including a reference to the actual blob of the file in `src` property.
|
|
176
121
|
|
|
177
|
-
|
|
122
|
+
**URI:** `/pub/pubky.app/files/:file_id`
|
|
178
123
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
124
|
+
| **Field** | **Type** | **Description** | **Validation Rules** |
|
|
125
|
+
| -------------- | -------- | --------------------------- | ---------------------------------------------- |
|
|
126
|
+
| `name` | String | Name of the file. | Required. Must be 1-255 characters |
|
|
127
|
+
| `created_at` | Integer | Unix timestamp of creation. | Required. |
|
|
128
|
+
| `src` | String | File blob URL | Required. must be a valid URL. Max length 1024 |
|
|
129
|
+
| `content_type` | String | MIME type of the file. | Required. Valid IANA mime types |
|
|
130
|
+
| `size` | Integer | Size of the file in bytes. | Required. Positive integer. Max size is 10Mb |
|
|
184
131
|
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
---
|
|
132
|
+
**Validation Notes:**
|
|
190
133
|
|
|
191
|
-
|
|
134
|
+
- The `file_id` in the URI must be a valid **Timestamp ID**.
|
|
192
135
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
- **Feeds**: `createFeed(...)`
|
|
196
|
-
- **Bookmarks**: `createBookmark(...)`
|
|
197
|
-
- **Tags**: `createTag(...)`
|
|
198
|
-
- **Mutes**: `createMute(...)`
|
|
199
|
-
- **Follows**: `createFollow(...)`
|
|
200
|
-
- **LastRead**: `createLastRead(...)`
|
|
201
|
-
- **Blobs**: `createBlob(...)`
|
|
202
|
-
- **Files**: `createFile(...)`
|
|
203
|
-
|
|
204
|
-
Each has a `meta` field for storing relevant IDs/paths and a typed data object.
|
|
136
|
+
---
|
|
205
137
|
|
|
206
|
-
###
|
|
138
|
+
### PubkyAppPost
|
|
207
139
|
|
|
208
|
-
|
|
209
|
-
import { Client } from "@synonymdev/pubky";
|
|
210
|
-
import { PubkySpecsBuilder, getValidMimeTypes } from "pubky-app-specs";
|
|
140
|
+
**Description:** Represents a user's post.
|
|
211
141
|
|
|
212
|
-
|
|
213
|
-
const client = new Client();
|
|
214
|
-
const specs = new PubkySpecsBuilder(pubkyId);
|
|
142
|
+
**URI:** `/pub/pubky.app/posts/:post_id`
|
|
215
143
|
|
|
216
|
-
|
|
217
|
-
|
|
144
|
+
| **Field** | **Type** | **Description** | **Validation Rules** |
|
|
145
|
+
| ------------- | -------- | ------------------------------------ | -------------------------------------------------------------------------- |
|
|
146
|
+
| `content` | String | Content of the post. | Required. Max length: 2000 (short), 50000 (long). Cannot be `"[DELETED]"`. |
|
|
147
|
+
| `kind` | String | Type of post. | Required. Must be a valid `PubkyAppPostKind` value. |
|
|
148
|
+
| `parent` | String | URI of the parent post (if a reply). | Optional. Must be a valid URI if present. |
|
|
149
|
+
| `embed` | Object | Reposted content (type + URI). | Optional. URI must be valid if present. |
|
|
150
|
+
| `attachments` | Array | List of attachment URIs. | Optional. Each must be a valid URI. |
|
|
218
151
|
|
|
219
|
-
|
|
220
|
-
method: "PUT",
|
|
221
|
-
body: JSON.stringify(blob.toJson()),
|
|
222
|
-
});
|
|
152
|
+
**Post Kinds:**
|
|
223
153
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
);
|
|
154
|
+
- `short`
|
|
155
|
+
- `long`
|
|
156
|
+
- `image`
|
|
157
|
+
- `video`
|
|
158
|
+
- `link`
|
|
159
|
+
- `file`
|
|
231
160
|
|
|
232
|
-
|
|
233
|
-
method: "PUT",
|
|
234
|
-
body: JSON.stringify(file.toJson()),
|
|
235
|
-
});
|
|
161
|
+
**Example: Valid Post**
|
|
236
162
|
|
|
237
|
-
|
|
238
|
-
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"content": "Hello world! This is my first post.",
|
|
166
|
+
"kind": "short",
|
|
167
|
+
"parent": null,
|
|
168
|
+
"embed": {
|
|
169
|
+
"kind": "short",
|
|
170
|
+
"uri": "pubky://user_id/pub/pubky.app/posts/0000000000000"
|
|
171
|
+
},
|
|
172
|
+
"attachments": ["pubky://user_id/pub/pubky.app/files/0000000000000"]
|
|
239
173
|
}
|
|
240
174
|
```
|
|
241
175
|
|
|
242
176
|
---
|
|
243
177
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
Use `getValidMimeTypes()` to get the list of allowed MIME types for file attachments. This helps validate files before upload without duplicating the validation list.
|
|
178
|
+
### PubkyAppTag
|
|
247
179
|
|
|
248
|
-
|
|
249
|
-
import { getValidMimeTypes } from "pubky-app-specs";
|
|
180
|
+
**Description:** Represents a tag applied to a URI.
|
|
250
181
|
|
|
251
|
-
|
|
252
|
-
const validMimeTypes = getValidMimeTypes();
|
|
253
|
-
// Returns: ["application/javascript", "application/json", "application/pdf", "image/png", ...]
|
|
182
|
+
**URI:** `/pub/pubky.app/tags/:tag_id`
|
|
254
183
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
184
|
+
| **Field** | **Type** | **Description** | **Validation Rules** |
|
|
185
|
+
| ------------ | -------- | --------------------------- | -------------------------------------------------------- |
|
|
186
|
+
| `uri` | String | URI of the tagged object. | Required. Must be a valid URI. |
|
|
187
|
+
| `label` | String | Label for the tag. | Required. Trimmed, lowercase. Max length: 20 characters. |
|
|
188
|
+
| `created_at` | Integer | Unix timestamp of creation. | Required. |
|
|
259
189
|
|
|
260
|
-
|
|
261
|
-
if (isValidFileType(file.type)) {
|
|
262
|
-
// Proceed with upload
|
|
263
|
-
} else {
|
|
264
|
-
console.error(`Invalid file type: ${file.type}`);
|
|
265
|
-
}
|
|
266
|
-
```
|
|
190
|
+
**Validation Notes:**
|
|
267
191
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
These helper functions construct properly formatted Pubky URIs:
|
|
271
|
-
|
|
272
|
-
```js
|
|
273
|
-
import {
|
|
274
|
-
userUriBuilder,
|
|
275
|
-
postUriBuilder,
|
|
276
|
-
bookmarkUriBuilder,
|
|
277
|
-
followUriBuilder,
|
|
278
|
-
tagUriBuilder,
|
|
279
|
-
muteUriBuilder,
|
|
280
|
-
lastReadUriBuilder,
|
|
281
|
-
blobUriBuilder,
|
|
282
|
-
fileUriBuilder,
|
|
283
|
-
feedUriBuilder,
|
|
284
|
-
} from "pubky-app-specs";
|
|
285
|
-
|
|
286
|
-
const userId = "8kkppkmiubfq4pxn6f73nqrhhhgkb5xyfprntc9si3np9ydbotto";
|
|
287
|
-
const targetUserId = "dzswkfy7ek3bqnoc89jxuqqfbzhjrj6mi8qthgbxxcqkdugm3rio";
|
|
288
|
-
|
|
289
|
-
// Build URIs for different resources
|
|
290
|
-
userUriBuilder(userId); // pubky://{userId}/pub/pubky.app/profile.json
|
|
291
|
-
postUriBuilder(userId, "0033SSE3B1FQ0"); // pubky://{userId}/pub/pubky.app/posts/{postId}
|
|
292
|
-
bookmarkUriBuilder(userId, "ABC123"); // pubky://{userId}/pub/pubky.app/bookmarks/{bookmarkId}
|
|
293
|
-
followUriBuilder(userId, targetUserId); // pubky://{userId}/pub/pubky.app/follows/{targetUserId}
|
|
294
|
-
tagUriBuilder(userId, "XYZ789"); // pubky://{userId}/pub/pubky.app/tags/{tagId}
|
|
295
|
-
muteUriBuilder(userId, targetUserId); // pubky://{userId}/pub/pubky.app/mutes/{targetUserId}
|
|
296
|
-
lastReadUriBuilder(userId); // pubky://{userId}/pub/pubky.app/last_read
|
|
297
|
-
blobUriBuilder(userId, "BLOB123"); // pubky://{userId}/pub/pubky.app/blobs/{blobId}
|
|
298
|
-
fileUriBuilder(userId, "FILE456"); // pubky://{userId}/pub/pubky.app/files/{fileId}
|
|
299
|
-
feedUriBuilder(userId, "FEED789"); // pubky://{userId}/pub/pubky.app/feeds/{feedId}
|
|
300
|
-
```
|
|
192
|
+
- The `tag_id` is a **Hash ID** derived from the `uri` and `label`.
|
|
301
193
|
|
|
302
194
|
---
|
|
303
195
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
The `parse_uri()` function converts a Pubky URI string into a strongly typed object.
|
|
196
|
+
### PubkyAppBookmark
|
|
307
197
|
|
|
308
|
-
**
|
|
198
|
+
**Description:** Represents a bookmark to a URI.
|
|
309
199
|
|
|
310
|
-
|
|
311
|
-
import { parse_uri } from "pubky-app-specs";
|
|
312
|
-
|
|
313
|
-
try {
|
|
314
|
-
const result = parse_uri("pubky://userID/pub/pubky.app/posts/postID");
|
|
315
|
-
console.log(result.user_id); // "userID"
|
|
316
|
-
console.log(result.resource); // e.g. "posts"
|
|
317
|
-
console.log(result.resource_id); // "postID" or null
|
|
318
|
-
} catch (error) {
|
|
319
|
-
console.error("URI parse error:", error);
|
|
320
|
-
}
|
|
321
|
-
```
|
|
200
|
+
**URI:** `/pub/pubky.app/bookmarks/:bookmark_id`
|
|
322
201
|
|
|
323
|
-
**
|
|
202
|
+
| **Field** | **Type** | **Description** | **Validation Rules** |
|
|
203
|
+
| ------------ | -------- | ---------------------- | ------------------------------ |
|
|
204
|
+
| `uri` | String | URI of the bookmark. | Required. Must be a valid URI. |
|
|
205
|
+
| `created_at` | Integer | Timestamp of creation. | Required. |
|
|
324
206
|
|
|
325
|
-
|
|
207
|
+
**Validation Notes:**
|
|
326
208
|
|
|
327
|
-
- **
|
|
328
|
-
- **resource:** A string indicating the resource type.
|
|
329
|
-
- **resource_id:** An optional resource identifier.
|
|
209
|
+
- The `bookmark_id` is a **Hash ID** derived from the `uri`.
|
|
330
210
|
|
|
331
211
|
---
|
|
332
212
|
|
|
333
|
-
|
|
213
|
+
### PubkyAppFollow
|
|
334
214
|
|
|
335
|
-
|
|
336
|
-
canonical rules without WASM, plus optional WASM accessors when needed.
|
|
215
|
+
**Description:** Represents a follow relationship.
|
|
337
216
|
|
|
338
|
-
|
|
217
|
+
**URI:** `/pub/pubky.app/follows/:user_id`
|
|
339
218
|
|
|
340
|
-
**
|
|
219
|
+
| **Field** | **Type** | **Description** | **Validation Rules** |
|
|
220
|
+
| ------------ | -------- | ---------------------- | -------------------- |
|
|
221
|
+
| `created_at` | Integer | Timestamp of creation. | Required. |
|
|
341
222
|
|
|
342
|
-
|
|
343
|
-
import { validationLimits, getValidationLimits } from "pubky-app-specs";
|
|
344
|
-
|
|
345
|
-
console.log(validationLimits);
|
|
346
|
-
const copy = getValidationLimits();
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
**Direct subpath import (ESM):**
|
|
350
|
-
|
|
351
|
-
```js
|
|
352
|
-
import limits from "pubky-app-specs/validationLimits";
|
|
353
|
-
// or
|
|
354
|
-
import limitsJson from "pubky-app-specs/validationLimits.json";
|
|
355
|
-
```
|
|
223
|
+
---
|
|
356
224
|
|
|
357
|
-
|
|
225
|
+
### PubkyAppFeed
|
|
358
226
|
|
|
359
|
-
|
|
360
|
-
const { validationLimits, getValidationLimits } = require("pubky-app-specs");
|
|
361
|
-
// or
|
|
362
|
-
const limits = require("pubky-app-specs/validationLimits");
|
|
363
|
-
```
|
|
227
|
+
**Description:** Represents a feed configuration.
|
|
364
228
|
|
|
365
|
-
|
|
229
|
+
**URI:** `/pub/pubky.app/feeds/:feed_id`
|
|
366
230
|
|
|
367
|
-
|
|
368
|
-
|
|
231
|
+
| **Field** | **Type** | **Description** | **Validation Rules** |
|
|
232
|
+
| --------- | -------- | ----------------------------------------- | ---------------------------------- |
|
|
233
|
+
| `tags` | Array | List of tags for filtering. | Optional. Strings must be trimmed. |
|
|
234
|
+
| `reach` | String | Feed visibility (e.g., `all`, `friends`). | Required. Must be a valid reach. |
|
|
235
|
+
| `layout` | String | Feed layout style (e.g., `columns`). | Required. Must be valid layout. |
|
|
236
|
+
| `sort` | String | Sort order (e.g., `recent`). | Required. Must be valid sort. |
|
|
237
|
+
| `content` | String | Type of content filtered. | Optional. |
|
|
238
|
+
| `name` | String | Name of the feed. | Required. |
|
|
369
239
|
|
|
370
|
-
|
|
240
|
+
---
|
|
371
241
|
|
|
372
|
-
|
|
373
|
-
const limitsFromBuilder = builder.validationLimits;
|
|
374
|
-
```
|
|
242
|
+
## Validation Rules
|
|
375
243
|
|
|
376
|
-
|
|
244
|
+
### Common Rules
|
|
377
245
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
"maxFileSizeBytes": 104857600,
|
|
382
|
-
"tagLabelMinLength": 1,
|
|
383
|
-
"tagLabelMaxLength": 20,
|
|
384
|
-
"tagInvalidChars": [",", ":", " ", "\t", "\n", "\r"],
|
|
385
|
-
"userNameMinLength": 3,
|
|
386
|
-
"userNameMaxLength": 50,
|
|
387
|
-
"userBioMaxLength": 160,
|
|
388
|
-
"userImageUrlMaxLength": 300,
|
|
389
|
-
"userLinksMaxCount": 5,
|
|
390
|
-
"userLinkTitleMaxLength": 100,
|
|
391
|
-
"userLinkUrlMaxLength": 300,
|
|
392
|
-
"userStatusMaxLength": 50,
|
|
393
|
-
"postShortContentMaxLength": 2000,
|
|
394
|
-
"postLongContentMaxLength": 50000,
|
|
395
|
-
"postAttachmentsMaxCount": 4,
|
|
396
|
-
"postAttachmentUrlMaxLength": 200,
|
|
397
|
-
"postAllowedAttachmentProtocols": ["pubky", "http", "https"],
|
|
398
|
-
"fileNameMinLength": 1,
|
|
399
|
-
"fileNameMaxLength": 255,
|
|
400
|
-
"fileSrcMaxLength": 1024,
|
|
401
|
-
"feedTagsMaxCount": 5
|
|
402
|
-
}
|
|
403
|
-
```
|
|
246
|
+
1. **Timestamp IDs:** 13-character Crockford Base32 strings derived from timestamps (in microseconds).
|
|
247
|
+
2. **Hash IDs:** First half of the bytes from the resulting Blake3-hashed strings encoded in Crockford Base32.
|
|
248
|
+
3. **URLs:** All URLs must pass standard validation.
|
|
404
249
|
|
|
405
250
|
---
|
|
406
251
|
|
|
407
|
-
##
|
|
252
|
+
## License
|
|
408
253
|
|
|
409
|
-
MIT
|
|
254
|
+
This specification is released under the MIT License.
|
package/package.json
CHANGED
|
@@ -1,59 +1,18 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"url": "https://github.com/pubky/pubky-app-specs/issues"
|
|
4
|
-
},
|
|
5
|
-
"contributors": [
|
|
6
|
-
"SHAcollision",
|
|
7
|
-
"tipogi",
|
|
8
|
-
"ok300"
|
|
9
|
-
],
|
|
2
|
+
"name": "pubky-app-specs",
|
|
10
3
|
"description": "Pubky.app Data Model Specifications",
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"
|
|
16
|
-
"import": "./index.js",
|
|
17
|
-
"require": "./index.cjs",
|
|
18
|
-
"types": "./pubky_app_specs.d.ts"
|
|
19
|
-
},
|
|
20
|
-
"./validationLimits": {
|
|
21
|
-
"import": "./validationLimits.js",
|
|
22
|
-
"require": "./validationLimits.cjs"
|
|
23
|
-
},
|
|
24
|
-
"./validationLimits.json": "./validationLimits.json"
|
|
4
|
+
"version": "0.5.0",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/pubky/pubky-app-specs"
|
|
25
9
|
},
|
|
26
10
|
"files": [
|
|
27
11
|
"pubky_app_specs_bg.wasm",
|
|
28
|
-
"pubky_app_specs.
|
|
29
|
-
"
|
|
30
|
-
"index.js",
|
|
31
|
-
"example.js",
|
|
32
|
-
"validationLimits.json",
|
|
33
|
-
"validationLimits.js",
|
|
34
|
-
"validationLimits.cjs"
|
|
12
|
+
"pubky_app_specs.js",
|
|
13
|
+
"pubky_app_specs.d.ts"
|
|
35
14
|
],
|
|
15
|
+
"main": "pubky_app_specs.js",
|
|
36
16
|
"homepage": "https://pubky.app",
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
"pubky-nexus",
|
|
40
|
-
"specs"
|
|
41
|
-
],
|
|
42
|
-
"license": "MIT",
|
|
43
|
-
"main": "index.cjs",
|
|
44
|
-
"module": "index.js",
|
|
45
|
-
"name": "pubky-app-specs",
|
|
46
|
-
"repository": {
|
|
47
|
-
"type": "git",
|
|
48
|
-
"url": "git+https://github.com/pubky/pubky-app-specs.git"
|
|
49
|
-
},
|
|
50
|
-
"scripts": {
|
|
51
|
-
"build": "cargo run --bin bundle_specs_npm",
|
|
52
|
-
"example": "node example.js",
|
|
53
|
-
"test": "mocha test.js"
|
|
54
|
-
},
|
|
55
|
-
"sideEffects": false,
|
|
56
|
-
"type": "module",
|
|
57
|
-
"types": "pubky_app_specs.d.ts",
|
|
58
|
-
"version": "0.4.4"
|
|
59
|
-
}
|
|
17
|
+
"types": "pubky_app_specs.d.ts"
|
|
18
|
+
}
|