@@ -71,12 +71,12 @@ async function createUser(pubkyId) {
7171 const specs = new PubkySpecsBuilder (pubkyId);
7272
7373 // Create user object with minimal fields
74- const {user , meta } = specs .createUser (
74+ const { user , meta } = specs .createUser (
7575 " Alice" , // Name
7676 " Hello from WASM" , // Bio
7777 null , // Image URL or File
7878 null , // Links
79- " active" // Status
79+ " active" , // Status
8080 );
8181
8282 // meta contains { id, path, url }.
@@ -112,12 +112,12 @@ async function createPost(pubkyId, content) {
112112 const specs = new PubkySpecsBuilder (pubkyId);
113113
114114 // Create the Post object
115- const {post , meta } = specs .createPost (
115+ const { post , meta } = specs .createPost (
116116 content,
117117 PubkyAppPostKind .Short ,
118118 null , // parent post URI (for replies)
119119 null , // embed object (for reposts)
120- null // attachments (array of file URLs, max 3)
120+ null , // attachments (array of file URLs, max 3)
121121 );
122122
123123 // Store the post
@@ -128,7 +128,7 @@ async function createPost(pubkyId, content) {
128128 });
129129
130130 console .log (" Post stored at:" , meta .url );
131- return {post, meta};
131+ return { post, meta };
132132}
133133```
134134
@@ -143,12 +143,12 @@ async function createPostWithAttachments(pubkyId, content, fileUrls) {
143143 const specs = new PubkySpecsBuilder (pubkyId);
144144
145145 // Create post with attachments (max 3 allowed)
146- const {post , meta } = specs .createPost (
146+ const { post , meta } = specs .createPost (
147147 content,
148148 PubkyAppPostKind .Image ,
149149 null , // parent
150150 null , // embed
151- fileUrls // e.g. ["pubky://user/pub/pubky.app/files/abc123"]
151+ fileUrls, // e.g. ["pubky://user/pub/pubky.app/files/abc123"]
152152 );
153153
154154 const postJson = post .toJson ();
@@ -160,7 +160,7 @@ async function createPostWithAttachments(pubkyId, content, fileUrls) {
160160 });
161161
162162 console .log (" Post with attachments stored at:" , meta .url );
163- return {post, meta};
163+ return { post, meta };
164164}
165165```
166166
@@ -174,7 +174,7 @@ async function followUser(myPubkyId, userToFollow) {
174174 const client = new Client ();
175175 const specs = new PubkySpecsBuilder (myPubkyId);
176176
177- const {follow , meta } = specs .createFollow (userToFollow);
177+ const { follow , meta } = specs .createFollow (userToFollow);
178178
179179 // We only need to store the JSON in the homeserver
180180 await client .fetch (meta .url , {
@@ -215,18 +215,18 @@ async function uploadFile(pubkyId, fileData, fileName, contentType, fileSize) {
215215
216216 // First, create and store the blob (raw binary data)
217217 const { blob , meta: blobMeta } = specs .createBlob (fileData);
218-
218+
219219 await client .fetch (blobMeta .url , {
220220 method: " PUT" ,
221221 body: JSON .stringify (blob .toJson ()),
222222 });
223223
224224 // Then create the file metadata pointing to the blob
225225 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
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
230230 );
231231
232232 await client .fetch (fileMeta .url , {
@@ -287,16 +287,16 @@ const userId = "8kkppkmiubfq4pxn6f73nqrhhhgkb5xyfprntc9si3np9ydbotto";
287287const targetUserId = " dzswkfy7ek3bqnoc89jxuqqfbzhjrj6mi8qthgbxxcqkdugm3rio" ;
288288
289289// 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}
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}
300300```
301301
302302---
@@ -330,6 +330,52 @@ A `ParsedUriResult` object with:
330330
331331---
332332
333+ ## Validation limits
334+
335+ The WASM builder exposes validation limits as a JSON object so UIs can reuse
336+ the canonical rules without duplicating magic numbers.
337+
338+ ``` js
339+ import init , { PubkySpecsBuilder } from " pubky-app-specs" ;
340+
341+ await init ();
342+ const builder = new PubkySpecsBuilder (" pubky_id_here" );
343+ const limits = builder .validationLimits ;
344+
345+ console .log (limits);
346+ ```
347+
348+ Example output shape:
349+
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+ ```
376+
377+ ---
378+
333379## 📄 License
334380
335381MIT
0 commit comments