a collection of lightweight TypeScript packages for AT Protocol, the protocol powering Bluesky
atproto bluesky typescript npm
105
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(frontpage): initial commit

mary.my.id c005c218 56834f2e

verified
+433
+1
README.md
··· 48 48 | [`atproto`](./packages/definitions/atproto): `com.atproto.*` schema definitions | 49 49 | [`bluemoji`](./packages/definitions/bluemoji): `blue.moji.*` schema definitions | 50 50 | [`bluesky`](./packages/definitions/bluesky): `app.bsky.*` and `chat.bsky.*` schema definitions | 51 + | [`frontpage`](./packages/definitions/frontpage): `fyi.unravel.frontpage.*` schema definitions | 51 52 | [`ozone`](./packages/definitions/ozone): `tools.ozone.*` schema definitions | 52 53 | [`whitewind`](./packages/definitions/whitewind): `com.whtwnd.*` schema definitions | 53 54 | **Utility packages** |
+1
lexicons-frontpage/README.md
··· 1 + https://github.com/likeandscribe/frontpage/tree/ad5d8e1a76ed8353afb3ccc0ef83a64ecd67c676/lexicons/fyi/unravel/frontpage
+30
lexicons-frontpage/comment.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "fyi.unravel.frontpage.comment", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "Record containing a Frontpage comment.", 8 + "key": "tid", 9 + "record": { 10 + "type": "object", 11 + "required": ["content", "createdAt", "post"], 12 + "properties": { 13 + "content": { 14 + "type": "string", 15 + "maxLength": 100000, 16 + "maxGraphemes": 10000, 17 + "description": "The content of the comment." 18 + }, 19 + "createdAt": { 20 + "type": "string", 21 + "format": "datetime", 22 + "description": "Client-declared timestamp when this comment was originally created." 23 + }, 24 + "parent": { "type": "ref", "ref": "com.atproto.repo.strongRef" }, 25 + "post": { "type": "ref", "ref": "com.atproto.repo.strongRef" } 26 + } 27 + } 28 + } 29 + } 30 + }
+33
lexicons-frontpage/post.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "fyi.unravel.frontpage.post", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "Record containing a Frontpage post.", 8 + "key": "tid", 9 + "record": { 10 + "type": "object", 11 + "required": ["title", "url", "createdAt"], 12 + "properties": { 13 + "title": { 14 + "type": "string", 15 + "maxLength": 3000, 16 + "maxGraphemes": 300, 17 + "description": "The title of the post." 18 + }, 19 + "url": { 20 + "type": "string", 21 + "format": "uri", 22 + "description": "The URL of the post." 23 + }, 24 + "createdAt": { 25 + "type": "string", 26 + "format": "datetime", 27 + "description": "Client-declared timestamp when this post was originally created." 28 + } 29 + } 30 + } 31 + } 32 + } 33 + }
+23
lexicons-frontpage/vote.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "fyi.unravel.frontpage.vote", 4 + "defs": { 5 + "main": { 6 + "type": "record", 7 + "description": "Record containing a Frontpage vote.", 8 + "key": "tid", 9 + "record": { 10 + "type": "object", 11 + "required": ["subject", "createdAt"], 12 + "properties": { 13 + "subject": { "type": "ref", "ref": "com.atproto.repo.strongRef" }, 14 + "createdAt": { 15 + "type": "string", 16 + "format": "datetime", 17 + "description": "Client-declared timestamp when this vote was originally created." 18 + } 19 + } 20 + } 21 + } 22 + } 23 + }
+1
package.json
··· 4 4 "scripts": { 5 5 "pull": "node ./scripts/pull-lexicons.js", 6 6 "pull:bluemoji": "node ./scripts/pull-bluemoji-lexicons.js", 7 + "pull:frontpage": "node ./scripts/pull-frontpage-lexicons.js", 7 8 "pull:whtwnd": "node ./scripts/pull-whtwnd-lexicons.js", 8 9 "fmt": "prettier --cache --write ." 9 10 },
+45
packages/definitions/frontpage/README.md
··· 1 + # @atcute/frontpage 2 + 3 + [Frontpage](https://frontpage.fyi/) (fyi.unravel.frontpage.\*) schema definitions 4 + 5 + ## usage 6 + 7 + ```ts 8 + import { FyiUnravelFrontpagePost } from '@atcute/frontpage'; 9 + import { is } from '@atcute/lexicons'; 10 + 11 + const post: FyiUnravelFrontpagePost.Main = { 12 + $type: 'fyi.unravel.frontpage.post', 13 + url: 'https://github.com/mary-ext/atcute', 14 + title: 'collection of lightweight TypeScript packages for dealing with AT Protocol', 15 + createdAt: '2024-10-16T16:12:01.599Z', 16 + }; 17 + 18 + is(FyiUnravelFrontpagePost.mainSchema, post); 19 + // -> true 20 + ``` 21 + 22 + ### with `@atcute/client` 23 + 24 + pick either one of these 3 options to register the ambient declarations 25 + 26 + ```jsonc 27 + // tsconfig.json 28 + { 29 + "compilerOptions": { 30 + "types": ["@atcute/frontpage"], 31 + }, 32 + } 33 + ``` 34 + 35 + ```ts 36 + // env.d.ts 37 + /// <reference types="@atcute/frontpage" /> 38 + ``` 39 + 40 + ```ts 41 + // index.ts 42 + import type {} from '@atcute/frontpage'; 43 + ``` 44 + 45 + now all the XRPC operations should be visible in the client
+15
packages/definitions/frontpage/lex.config.js
··· 1 + import { defineLexiconConfig } from '@atcute/lex-cli'; 2 + 3 + export default defineLexiconConfig({ 4 + files: ['../../../lexicons-frontpage/**/*.json'], 5 + outdir: 'lib/lexicons/', 6 + mappings: [ 7 + { 8 + nsid: ['com.atproto.*'], 9 + imports: (nsid) => { 10 + const specifier = nsid.slice('com.atproto.'.length).replaceAll('.', '/'); 11 + return { type: 'namespace', from: `@atcute/atproto/types/${specifier}` }; 12 + }, 13 + }, 14 + ], 15 + });
+1
packages/definitions/frontpage/lib/index.ts
··· 1 + export * from './lexicons/index.js';
+3
packages/definitions/frontpage/lib/lexicons/index.ts
··· 1 + export * as FyiUnravelFrontpageComment from './types/fyi/unravel/frontpage/comment.js'; 2 + export * as FyiUnravelFrontpagePost from './types/fyi/unravel/frontpage/post.js'; 3 + export * as FyiUnravelFrontpageVote from './types/fyi/unravel/frontpage/vote.js';
+36
packages/definitions/frontpage/lib/lexicons/types/fyi/unravel/frontpage/comment.ts
··· 1 + import type {} from '@atcute/lexicons'; 2 + import * as v from '@atcute/lexicons/validations'; 3 + import type {} from '@atcute/lexicons/ambient'; 4 + import * as ComAtprotoRepoStrongRef from '@atcute/atproto/types/repo/strongRef'; 5 + 6 + const _mainSchema = /*#__PURE__*/ v.record( 7 + /*#__PURE__*/ v.tidString(), 8 + /*#__PURE__*/ v.object({ 9 + $type: /*#__PURE__*/ v.literal('fyi.unravel.frontpage.comment'), 10 + content: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 11 + /*#__PURE__*/ v.stringLength(0, 100000), 12 + /*#__PURE__*/ v.stringGraphemes(0, 10000), 13 + ]), 14 + createdAt: /*#__PURE__*/ v.datetimeString(), 15 + get parent() { 16 + return /*#__PURE__*/ v.optional(ComAtprotoRepoStrongRef.mainSchema); 17 + }, 18 + get post() { 19 + return ComAtprotoRepoStrongRef.mainSchema; 20 + }, 21 + }), 22 + ); 23 + 24 + type main$schematype = typeof _mainSchema; 25 + 26 + export interface mainSchema extends main$schematype {} 27 + 28 + export const mainSchema = _mainSchema as mainSchema; 29 + 30 + export interface Main extends v.InferInput<typeof mainSchema> {} 31 + 32 + declare module '@atcute/lexicons/ambient' { 33 + interface Records { 34 + 'fyi.unravel.frontpage.comment': mainSchema; 35 + } 36 + }
+30
packages/definitions/frontpage/lib/lexicons/types/fyi/unravel/frontpage/post.ts
··· 1 + import type {} from '@atcute/lexicons'; 2 + import * as v from '@atcute/lexicons/validations'; 3 + import type {} from '@atcute/lexicons/ambient'; 4 + 5 + const _mainSchema = /*#__PURE__*/ v.record( 6 + /*#__PURE__*/ v.tidString(), 7 + /*#__PURE__*/ v.object({ 8 + $type: /*#__PURE__*/ v.literal('fyi.unravel.frontpage.post'), 9 + title: /*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [ 10 + /*#__PURE__*/ v.stringLength(0, 3000), 11 + /*#__PURE__*/ v.stringGraphemes(0, 300), 12 + ]), 13 + url: /*#__PURE__*/ v.genericUriString(), 14 + createdAt: /*#__PURE__*/ v.datetimeString(), 15 + }), 16 + ); 17 + 18 + type main$schematype = typeof _mainSchema; 19 + 20 + export interface mainSchema extends main$schematype {} 21 + 22 + export const mainSchema = _mainSchema as mainSchema; 23 + 24 + export interface Main extends v.InferInput<typeof mainSchema> {} 25 + 26 + declare module '@atcute/lexicons/ambient' { 27 + interface Records { 28 + 'fyi.unravel.frontpage.post': mainSchema; 29 + } 30 + }
+29
packages/definitions/frontpage/lib/lexicons/types/fyi/unravel/frontpage/vote.ts
··· 1 + import type {} from '@atcute/lexicons'; 2 + import * as v from '@atcute/lexicons/validations'; 3 + import type {} from '@atcute/lexicons/ambient'; 4 + import * as ComAtprotoRepoStrongRef from '@atcute/atproto/types/repo/strongRef'; 5 + 6 + const _mainSchema = /*#__PURE__*/ v.record( 7 + /*#__PURE__*/ v.tidString(), 8 + /*#__PURE__*/ v.object({ 9 + $type: /*#__PURE__*/ v.literal('fyi.unravel.frontpage.vote'), 10 + get subject() { 11 + return ComAtprotoRepoStrongRef.mainSchema; 12 + }, 13 + createdAt: /*#__PURE__*/ v.datetimeString(), 14 + }), 15 + ); 16 + 17 + type main$schematype = typeof _mainSchema; 18 + 19 + export interface mainSchema extends main$schematype {} 20 + 21 + export const mainSchema = _mainSchema as mainSchema; 22 + 23 + export interface Main extends v.InferInput<typeof mainSchema> {} 24 + 25 + declare module '@atcute/lexicons/ambient' { 26 + interface Records { 27 + 'fyi.unravel.frontpage.vote': mainSchema; 28 + } 29 + }
+41
packages/definitions/frontpage/package.json
··· 1 + { 2 + "type": "module", 3 + "name": "@atcute/frontpage", 4 + "version": "1.0.0", 5 + "description": "Frontpage (fyi.unravel.frontpage.*) schema definitions", 6 + "keywords": [ 7 + "atcute", 8 + "atproto", 9 + "frontpage" 10 + ], 11 + "license": "MIT", 12 + "repository": { 13 + "url": "https://github.com/mary-ext/atcute", 14 + "directory": "packages/definitions/frontpage" 15 + }, 16 + "files": [ 17 + "dist/", 18 + "lib/", 19 + "!lib/**/*.bench.ts", 20 + "!lib/**/*.test.ts" 21 + ], 22 + "exports": { 23 + ".": "./dist/index.js", 24 + "./types/*": "./dist/lexicons/types/fyi/unravel/frontpage/*.js" 25 + }, 26 + "scripts": { 27 + "build": "tsc", 28 + "test": "vitest", 29 + "generate": "rm -r ./lib/lexicons/; lex-cli generate -c ./lex.config.js", 30 + "prepublish": "rm -rf dist; pnpm run build" 31 + }, 32 + "dependencies": { 33 + "@atcute/atproto": "workspace:^", 34 + "@atcute/lexicons": "workspace:^" 35 + }, 36 + "devDependencies": { 37 + "@atcute/frontpage": "file:", 38 + "@atcute/lex-cli": "workspace:^", 39 + "vitest": "^3.1.3" 40 + } 41 + }
+22
packages/definitions/frontpage/tsconfig.json
··· 1 + { 2 + "compilerOptions": { 3 + "outDir": "dist/", 4 + "esModuleInterop": true, 5 + "skipLibCheck": true, 6 + "target": "ESNext", 7 + "allowJs": true, 8 + "resolveJsonModule": true, 9 + "moduleDetection": "force", 10 + "isolatedModules": true, 11 + "verbatimModuleSyntax": true, 12 + "strict": true, 13 + "noImplicitOverride": true, 14 + "noUnusedLocals": true, 15 + "noUnusedParameters": true, 16 + "noFallthroughCasesInSwitch": true, 17 + "module": "NodeNext", 18 + "sourceMap": true, 19 + "declaration": true, 20 + }, 21 + "include": ["lib"], 22 + }
+27
pnpm-lock.yaml
··· 259 259 specifier: ^3.1.3 260 260 version: 3.1.3(@types/node@22.15.17) 261 261 262 + packages/definitions/frontpage: 263 + dependencies: 264 + '@atcute/atproto': 265 + specifier: workspace:^ 266 + version: link:../atproto 267 + '@atcute/lexicons': 268 + specifier: workspace:^ 269 + version: link:../../core/lexicons 270 + devDependencies: 271 + '@atcute/frontpage': 272 + specifier: 'file:' 273 + version: file:packages/definitions/frontpage 274 + '@atcute/lex-cli': 275 + specifier: workspace:^ 276 + version: link:../../core/lex-cli 277 + vitest: 278 + specifier: ^3.1.3 279 + version: 3.1.3(@types/node@22.15.17) 280 + 262 281 packages/definitions/ozone: 263 282 dependencies: 264 283 '@atcute/atproto': ··· 560 579 561 580 '@atcute/bluesky@file:packages/definitions/bluesky': 562 581 resolution: {directory: packages/definitions/bluesky, type: directory} 582 + 583 + '@atcute/frontpage@file:packages/definitions/frontpage': 584 + resolution: {directory: packages/definitions/frontpage, type: directory} 563 585 564 586 '@atcute/ozone@file:packages/definitions/ozone': 565 587 resolution: {directory: packages/definitions/ozone, type: directory} ··· 3281 3303 '@atcute/lexicons': link:packages/core/lexicons 3282 3304 3283 3305 '@atcute/bluesky@file:packages/definitions/bluesky': 3306 + dependencies: 3307 + '@atcute/atproto': link:packages/definitions/atproto 3308 + '@atcute/lexicons': link:packages/core/lexicons 3309 + 3310 + '@atcute/frontpage@file:packages/definitions/frontpage': 3284 3311 dependencies: 3285 3312 '@atcute/atproto': link:packages/definitions/atproto 3286 3313 '@atcute/lexicons': link:packages/core/lexicons
+95
scripts/pull-frontpage-lexicons.js
··· 1 + import * as path from 'node:path'; 2 + import * as fs from 'node:fs/promises'; 3 + 4 + import { untar } from '@mary/tar'; 5 + import prettier from 'prettier'; 6 + 7 + const repo = `likeandscribe/frontpage`; 8 + 9 + async function main() { 10 + const config = await prettier.resolveConfig(process.cwd() + '/foo', { editorconfig: true }); 11 + 12 + let sha; 13 + { 14 + console.log(`retrieving latest commit`); 15 + const response = await fetch( 16 + `https://api.github.com/repos/${repo}/commits?path=lexicons/fyi/unravel/frontpage/`, 17 + ); 18 + 19 + if (!response.ok) { 20 + console.log(` response error ${response.status}`); 21 + return; 22 + } 23 + 24 + const json = await response.json(); 25 + const latest = json[0]; 26 + 27 + if (!latest) { 28 + console.log(` latest commit missing?`); 29 + return; 30 + } 31 + 32 + sha = latest.sha; 33 + console.log(` got ${sha}`); 34 + } 35 + 36 + const tmpdir = `lexicons-tmp/`; 37 + 38 + { 39 + console.log(`retrieving zip file`); 40 + const response = await fetch(`https://github.com/${repo}/archive/${sha}.tar.gz`); 41 + 42 + if (!response.ok) { 43 + console.log(` response error ${response.status}`); 44 + return; 45 + } 46 + 47 + const basename = `frontpage-${sha}/lexicons/fyi/unravel/frontpage/`; 48 + 49 + const ds = new DecompressionStream('gzip'); 50 + const stream = response.body.pipeThrough(ds); 51 + 52 + const promises = []; 53 + 54 + console.log(` reading`); 55 + for await (const entry of untar(stream)) { 56 + if (entry.type === 'file' && entry.name.startsWith(basename) && entry.name.endsWith('.json')) { 57 + const name = entry.name.slice(basename.length); 58 + const basedir = tmpdir + path.dirname(name); 59 + 60 + const code = await entry.text(); 61 + 62 + const promise = (async () => { 63 + const formatted = await prettier.format(code, { ...config, parser: 'json' }); 64 + 65 + await fs.mkdir(basedir, { recursive: true }); 66 + await fs.writeFile(tmpdir + name, formatted); 67 + })(); 68 + 69 + promises.push(promise); 70 + } 71 + } 72 + 73 + console.log(` flushing writes`); 74 + await Promise.all(promises); 75 + } 76 + 77 + { 78 + const source = `https://github.com/${repo}/tree/${sha}/lexicons/fyi/unravel/frontpage\n`; 79 + 80 + console.log(`writing readme file`); 81 + 82 + await fs.writeFile(tmpdir + `README.md`, source); 83 + } 84 + 85 + { 86 + const dest = `lexicons-frontpage/`; 87 + 88 + console.log(`moving folder`); 89 + 90 + await fs.rm(dest, { recursive: true, force: true }); 91 + await fs.rename(tmpdir, dest); 92 + } 93 + } 94 + 95 + await main();