pubky-app-specs 0.4.3 → 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 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,381 +1,254 @@
1
- # Pubky App Specs · `pubky-app-specs`
1
+ # Pubky.app Data Model Specification
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/pubky-app-specs)](https://www.npmjs.com/package/pubky-app-specs)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
3
+ _Version 0.4.4_
5
4
 
6
- A WASM library for building and validating structured JSON models compatible with Pubky.App social powered by [`@synonymdev/pubky`](https://www.npmjs.com/package/@synonymdev/pubky). It handles domain objects like **Users**, **Posts**, **Feeds**, **Bookmarks**, **Tags**, and more. Each object is:
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
- - **Sanitized** and **Validated** via Rust logic.
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
- ## 🤔 Why Use This Crate Instead of [Manual JSONs](https://github.com/pubky/pubky-app-specs?tab=readme-ov-file#data-models)?
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
- npm install pubky-app-specs
26
- # or
27
- yarn add pubky-app-specs
15
+ cd pkg
16
+ npm run build
28
17
  ```
29
18
 
30
- > **Note**: This package uses WASM with embedded bytes for automatic initialization. No manual WASM loading required - just import and use!
31
-
32
- ---
33
-
34
- ## 🚀 Quick Start
19
+ Test with:
35
20
 
36
- 1. **Import** the library.
37
- 2. **Construct** a `PubkySpecsBuilder(pubkyId)` object.
38
- 3. **Create** validated domain objects (User, Post, Tag, etc.).
39
- 4. **Store** them on the [PubKy homeserver](https://github.com/synonymdev/pubky) or any distributed storage solution you prefer.
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
- // OR CommonJS
48
- const { PubkySpecsBuilder } = require("pubky-app-specs");
27
+ Examples with:
49
28
 
50
- function loadSpecs(pubkyId) {
51
- // Create a specs builder instance - WASM is already initialized
52
- const specs = new PubkySpecsBuilder(pubkyId);
53
- return specs;
54
- }
29
+ ```bash
30
+ cd pkg
31
+ npm run example
55
32
  ```
56
33
 
57
34
  ---
58
35
 
59
- ## 🎨 Example Usage
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)
60
55
 
61
- Below are **succinct** examples to illustrate how to create or update data using **`pubky-app-specs`** and then **store** it with [`@synonymdev/pubky`](https://www.npmjs.com/package/@synonymdev/pubky).
56
+ ---
62
57
 
63
- ### 1) Creating a New User
58
+ ## Introduction
64
59
 
65
- ```js
66
- import { Client, PublicKey } from "@synonymdev/pubky";
67
- import { PubkySpecsBuilder } from "pubky-app-specs";
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.
68
61
 
69
- async function createUser(pubkyId) {
70
- const client = new Client();
71
- const specs = new PubkySpecsBuilder(pubkyId);
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.
72
63
 
73
- // Create user object with minimal fields
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
- );
64
+ ---
81
65
 
82
- // meta contains { id, path, url }.
83
- // user is the Rust "PubkyAppUser" object.
66
+ ## Quick Start
84
67
 
85
- // We bring the Rust object to JS using the .toJson() method.
86
- const userJson = user.toJson();
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.
87
69
 
88
- // Store in homeserver via pubky
89
- const response = await client.fetch(meta.url, {
90
- method: "PUT",
91
- body: JSON.stringify(userJson),
92
- credentials: "include",
93
- });
70
+ ### Concepts:
94
71
 
95
- if (!response.ok) {
96
- throw new Error(`Failed to store user: ${response.statusText}`);
97
- }
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.
98
75
 
99
- console.log("User stored at:", meta.url);
100
- return { user, meta };
101
- }
102
- ```
76
+ ---
103
77
 
104
- ### 2) Creating a Post
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
- ```
78
+ ## Data Models
134
79
 
135
- ### 3) Creating a Post with Attachments
80
+ ### PubkyAppUser
136
81
 
137
- ```js
138
- import { Client } from "@synonymdev/pubky";
139
- import { PubkySpecsBuilder, PubkyAppPostKind } from "pubky-app-specs";
82
+ **Description:** Represents a user's profile information.
140
83
 
141
- async function createPostWithAttachments(pubkyId, content, fileUrls) {
142
- const client = new Client();
143
- const specs = new PubkySpecsBuilder(pubkyId);
84
+ **URI:** `/pub/pubky.app/profile.json`
144
85
 
145
- // Create post with attachments (max 3 allowed)
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
- );
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. |
153
93
 
154
- const postJson = post.toJson();
155
- console.log("Attachments:", postJson.attachments);
94
+ **Validation Notes:**
156
95
 
157
- await client.fetch(meta.url, {
158
- method: "PUT",
159
- body: JSON.stringify(postJson),
160
- });
96
+ - Reserved keyword `[DELETED]` cannot be used for `name`.
97
+ - Each `UserLink` in `links` must have a valid title and URL.
161
98
 
162
- console.log("Post with attachments stored at:", meta.url);
163
- return { post, meta };
99
+ **Example: Valid User**
100
+
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
- ### 4) Following a User
168
-
169
- ```js
170
- import { Client } from "@synonymdev/pubky";
171
- import { PubkySpecsBuilder } from "pubky-app-specs";
172
-
173
- async function followUser(myPubkyId, userToFollow) {
174
- const client = new Client();
175
- const specs = new PubkySpecsBuilder(myPubkyId);
176
-
177
- const { follow, meta } = specs.createFollow(userToFollow);
116
+ ---
178
117
 
179
- // We only need to store the JSON in the homeserver
180
- await client.fetch(meta.url, {
181
- method: "PUT",
182
- body: JSON.stringify(follow.toJson()),
183
- });
118
+ ### PubkyAppFile
184
119
 
185
- console.log(`Successfully followed: ${userToFollow}`);
186
- }
187
- ```
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.
188
121
 
189
- ---
122
+ **URI:** `/pub/pubky.app/files/:file_id`
190
123
 
191
- ## 📁 Additional Models
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 |
192
131
 
193
- This library supports many more domain objects beyond `User` and `Post`. Here are a few more you can explore:
132
+ **Validation Notes:**
194
133
 
195
- - **Feeds**: `createFeed(...)`
196
- - **Bookmarks**: `createBookmark(...)`
197
- - **Tags**: `createTag(...)`
198
- - **Mutes**: `createMute(...)`
199
- - **Follows**: `createFollow(...)`
200
- - **LastRead**: `createLastRead(...)`
201
- - **Blobs**: `createBlob(...)`
202
- - **Files**: `createFile(...)`
134
+ - The `file_id` in the URI must be a valid **Timestamp ID**.
203
135
 
204
- Each has a `meta` field for storing relevant IDs/paths and a typed data object.
136
+ ---
205
137
 
206
- ### Creating a File with Blob
138
+ ### PubkyAppPost
207
139
 
208
- ```js
209
- import { Client } from "@synonymdev/pubky";
210
- import { PubkySpecsBuilder, getValidMimeTypes } from "pubky-app-specs";
140
+ **Description:** Represents a user's post.
211
141
 
212
- async function uploadFile(pubkyId, fileData, fileName, contentType, fileSize) {
213
- const client = new Client();
214
- const specs = new PubkySpecsBuilder(pubkyId);
142
+ **URI:** `/pub/pubky.app/posts/:post_id`
215
143
 
216
- // First, create and store the blob (raw binary data)
217
- const { blob, meta: blobMeta } = specs.createBlob(fileData);
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
- await client.fetch(blobMeta.url, {
220
- method: "PUT",
221
- body: JSON.stringify(blob.toJson()),
222
- });
152
+ **Post Kinds:**
223
153
 
224
- // Then create the file metadata pointing to the blob
225
- const { file, meta: fileMeta } = specs.createFile(
226
- fileName, // e.g. "vacation-photo.jpg"
227
- blobMeta.url, // Reference to the blob
228
- contentType, // e.g. "image/jpeg"
229
- fileSize, // Size in bytes
230
- );
154
+ - `short`
155
+ - `long`
156
+ - `image`
157
+ - `video`
158
+ - `link`
159
+ - `file`
231
160
 
232
- await client.fetch(fileMeta.url, {
233
- method: "PUT",
234
- body: JSON.stringify(file.toJson()),
235
- });
161
+ **Example: Valid Post**
236
162
 
237
- console.log("File stored at:", fileMeta.url);
238
- return { file, meta: fileMeta };
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
- ## ✅ Validating File MIME Types
178
+ ### PubkyAppTag
245
179
 
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.
180
+ **Description:** Represents a tag applied to a URI.
247
181
 
248
- ```js
249
- import { getValidMimeTypes } from "pubky-app-specs";
182
+ **URI:** `/pub/pubky.app/tags/:tag_id`
250
183
 
251
- // Get the list of valid MIME types
252
- const validMimeTypes = getValidMimeTypes();
253
- // Returns: ["application/javascript", "application/json", "application/pdf", "image/png", ...]
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. |
254
189
 
255
- // Validate a file before upload
256
- function isValidFileType(mimeType) {
257
- return validMimeTypes.includes(mimeType);
258
- }
259
-
260
- // Example usage
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
- ## 🔗 URI Builder Utilities
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
- ## 📌 Parsing a Pubky URI
196
+ ### PubkyAppBookmark
305
197
 
306
- The `parse_uri()` function converts a Pubky URI string into a strongly typed object.
198
+ **Description:** Represents a bookmark to a URI.
307
199
 
308
- **Usage:**
200
+ **URI:** `/pub/pubky.app/bookmarks/:bookmark_id`
309
201
 
310
- ```js
311
- import { parse_uri } from "pubky-app-specs";
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. |
312
206
 
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
- ```
207
+ **Validation Notes:**
208
+
209
+ - The `bookmark_id` is a **Hash ID** derived from the `uri`.
210
+
211
+ ---
212
+
213
+ ### PubkyAppFollow
322
214
 
323
- **Returns:**
215
+ **Description:** Represents a follow relationship.
324
216
 
325
- A `ParsedUriResult` object with:
217
+ **URI:** `/pub/pubky.app/follows/:user_id`
326
218
 
327
- - **user_id:** The parsed user identifier.
328
- - **resource:** A string indicating the resource type.
329
- - **resource_id:** An optional resource identifier.
219
+ | **Field** | **Type** | **Description** | **Validation Rules** |
220
+ | ------------ | -------- | ---------------------- | -------------------- |
221
+ | `created_at` | Integer | Timestamp of creation. | Required. |
330
222
 
331
223
  ---
332
224
 
333
- ## Validation limits
225
+ ### PubkyAppFeed
334
226
 
335
- The WASM builder exposes validation limits as a JSON object so UIs can reuse
336
- the canonical rules without duplicating magic numbers.
227
+ **Description:** Represents a feed configuration.
337
228
 
338
- ```js
339
- import init, { PubkySpecsBuilder } from "pubky-app-specs";
229
+ **URI:** `/pub/pubky.app/feeds/:feed_id`
340
230
 
341
- await init();
342
- const builder = new PubkySpecsBuilder("pubky_id_here");
343
- const limits = builder.validationLimits;
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. |
344
239
 
345
- console.log(limits);
346
- ```
240
+ ---
347
241
 
348
- Example output shape:
242
+ ## Validation Rules
349
243
 
350
- ```json
351
- {
352
- "maxBlobSizeBytes": 104857600,
353
- "maxFileSizeBytes": 104857600,
354
- "tagLabelMinLength": 1,
355
- "tagLabelMaxLength": 20,
356
- "tagInvalidChars": [",", ":", " ", "\t", "\n", "\r"],
357
- "userNameMinLength": 3,
358
- "userNameMaxLength": 50,
359
- "userBioMaxLength": 160,
360
- "userImageUrlMaxLength": 300,
361
- "userLinksMaxCount": 5,
362
- "userLinkTitleMaxLength": 100,
363
- "userLinkUrlMaxLength": 300,
364
- "userStatusMaxLength": 50,
365
- "postShortContentMaxLength": 2000,
366
- "postLongContentMaxLength": 50000,
367
- "postAttachmentsMaxCount": 3,
368
- "postAttachmentUrlMaxLength": 200,
369
- "postAllowedAttachmentProtocols": ["pubky", "http", "https"],
370
- "fileNameMinLength": 1,
371
- "fileNameMaxLength": 255,
372
- "fileSrcMaxLength": 1024,
373
- "feedTagsMaxCount": 5
374
- }
375
- ```
244
+ ### Common Rules
245
+
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.
376
249
 
377
250
  ---
378
251
 
379
- ## 📄 License
252
+ ## License
380
253
 
381
- MIT
254
+ This specification is released under the MIT License.
package/package.json CHANGED
@@ -1,51 +1,18 @@
1
1
  {
2
2
  "name": "pubky-app-specs",
3
3
  "description": "Pubky.app Data Model Specifications",
4
- "version": "0.4.3",
4
+ "version": "0.5.0",
5
5
  "license": "MIT",
6
- "contributors": [
7
- "SHAcollision",
8
- "tipogi",
9
- "ok300"
10
- ],
11
6
  "repository": {
12
7
  "type": "git",
13
- "url": "git+https://github.com/pubky/pubky-app-specs.git"
14
- },
15
- "bugs": {
16
- "url": "https://github.com/pubky/pubky-app-specs/issues"
8
+ "url": "https://github.com/pubky/pubky-app-specs"
17
9
  },
18
10
  "files": [
19
11
  "pubky_app_specs_bg.wasm",
20
- "pubky_app_specs.d.ts",
21
- "index.cjs",
22
- "index.js",
23
- "example.js"
12
+ "pubky_app_specs.js",
13
+ "pubky_app_specs.d.ts"
24
14
  ],
25
- "type": "module",
26
- "main": "index.cjs",
27
- "module": "index.js",
28
- "types": "pubky_app_specs.d.ts",
29
- "exports": {
30
- ".": {
31
- "types": "./pubky_app_specs.d.ts",
32
- "import": "./index.js",
33
- "require": "./index.cjs"
34
- }
35
- },
15
+ "main": "pubky_app_specs.js",
36
16
  "homepage": "https://pubky.app",
37
- "sideEffects": false,
38
- "devDependencies": {
39
- "mocha": "^10.2.0"
40
- },
41
- "scripts": {
42
- "build": "cargo run --bin bundle_specs_npm",
43
- "example": "node example.js",
44
- "test": "mocha test.js"
45
- },
46
- "keywords": [
47
- "pubky-app",
48
- "pubky-nexus",
49
- "specs"
50
- ]
51
- }
17
+ "types": "pubky_app_specs.d.ts"
18
+ }