A simple AtProto app to read pet.mewsse.link records on my PDS.

Better lexicon usage with embed

Mewsse 2ab2c9b9 3ac5195c

Changed files
+176 -41
lexicons
src
lexicons
types
pet
+26
lexicons/pet/mewsse/embed/image.json
···
+
{
+
"lexicon": 1,
+
"id": "pet.mewsse.embed.image",
+
"description": "An image to illustrate a link",
+
"defs": {
+
"main": {
+
"type": "object",
+
"required": ["image"],
+
"properties": {
+
"image": {
+
"type": "blob",
+
"description": "An image to illustrate a link",
+
"accept": [
+
"image/*"
+
],
+
"maxSize": 1000000
+
},
+
"alt": {
+
"type": "string",
+
"maxLength": 3000,
+
"description": "A alt text to describe the image."
+
}
+
}
+
}
+
}
+
}
+17
lexicons/pet/mewsse/embed/post.json
···
+
{
+
"lexicon": 1,
+
"id": "pet.mewsse.embed.post",
+
"description": "An embeded bluesky post",
+
"defs": {
+
"main": {
+
"type": "object",
+
"required": ["uri"],
+
"properties": {
+
"uri": {
+
"type": "string",
+
"format": "at-uri"
+
}
+
}
+
}
+
}
+
}
+17
lexicons/pet/mewsse/embed/video.json
···
+
{
+
"lexicon": 1,
+
"id": "pet.mewsse.embed.video",
+
"description": "An video to embed in a link",
+
"defs": {
+
"main": {
+
"type": "object",
+
"required": ["uri"],
+
"properties": {
+
"uri": {
+
"type": "string",
+
"format": "uri"
+
}
+
}
+
}
+
}
+
}
+7 -12
lexicons/pet/mewsse/link.json
···
"type": "string",
"description": "Short description for the content of the link."
},
-
"image": {
-
"type": "blob",
-
"description": "An image to illustrate the link",
-
"accept": [
-
"image/*"
-
],
-
"maxSize": 1000000
-
},
-
"alt": {
-
"type": "string",
-
"maxLength": 3000,
-
"description": "A alt text to describe the image."
+
"embed": {
+
"type": "union",
+
"refs": [
+
"pet.mewsse.embed.image",
+
"pet.mewsse.embed.post",
+
"pet.mewsse.embed.video"
+
]
},
"nsfw": {
"type": "boolean",
+11
package-lock.json
···
"dotenv": "^17.2.3",
"eta": "^4.0.1",
"kysely": "^0.28.7",
+
"kysely-plugin-serialize": "^0.8.2",
"mime": "^4.1.0"
},
"devDependencies": {
···
"resolved": "https://registry.npmjs.org/kysely/-/kysely-0.28.7.tgz",
"integrity": "sha512-u/cAuTL4DRIiO2/g4vNGRgklEKNIj5Q3CG7RoUB5DV5SfEC2hMvPxKi0GWPmnzwL2ryIeud2VTcEEmqzTzEPNw==",
"license": "MIT",
+
"peer": true,
"engines": {
"node": ">=20.0.0"
+
}
+
},
+
"node_modules/kysely-plugin-serialize": {
+
"version": "0.8.2",
+
"resolved": "https://registry.npmjs.org/kysely-plugin-serialize/-/kysely-plugin-serialize-0.8.2.tgz",
+
"integrity": "sha512-81nyTvDPGNHTzs9/Si+GW69YkcQgy2PMlkCieihEyF9EmlGY/TURUZMhVRrLV1k3Hsit+AWCfoEOLJczbK3hDw==",
+
"license": "MIT",
+
"peerDependencies": {
+
"kysely": ">=0.26"
}
},
"node_modules/mime": {
+1
package.json
···
"dotenv": "^17.2.3",
"eta": "^4.0.1",
"kysely": "^0.28.7",
+
"kysely-plugin-serialize": "^0.8.2",
"mime": "^4.1.0"
},
"devDependencies": {
+12 -5
src/db.ts
···
+
import { SerializePlugin } from 'kysely-plugin-serialize'
import { Kysely, Migrator, SqliteDialect } from 'kysely'
import SqliteDb from 'better-sqlite3'
import type { Migration, MigrationProvider } from 'kysely'
-
+
import type { Blob, LegacyBlob } from '@atcute/lexicons'
export type DatabaseSchema = {
links: Link,
revs: Rev
···
link: string,
title: string,
description: string | null,
-
image: string | null,
-
alt: string | null,
+
embed: {
+
'$type': string,
+
image?: Blob | LegacyBlob,
+
alt?: string,
+
uri?: string
+
} | null,
nsfw: number,
big: number,
createdAt: string,
···
.addColumn('link', 'varchar', (col) => col.notNull())
.addColumn('title', 'varchar', (col) => col.notNull())
.addColumn('description', 'varchar')
-
.addColumn('image', 'varchar')
-
.addColumn('alt', 'varchar')
+
.addColumn('embed', 'varchar')
.addColumn('nsfw', 'integer')
.addColumn('big', 'integer')
.addColumn('createdAt', 'varchar', (col) => col.notNull())
···
dialect: new SqliteDialect({
database: new SqliteDb(location)
}),
+
plugins: [
+
new SerializePlugin(),
+
],
})
}
+4 -8
src/ingester.ts
···
link: link.link,
title: link.title,
description: link.description,
-
image: findImage(did, pds, link),
-
alt: link.alt ?? null,
+
embed: link.embed || null,
nsfw: +(link.nsfw || 0),
big: +(link.big || 0),
createdAt: link.createdAt
···
link: link.link,
title: link.title,
description: link.description,
-
image: link.image,
-
alt: link.alt,
+
embed: link.embed || null,
nsfw: +(link.nsfw || 0),
big: +(link.big || 0),
})
···
link: record.link,
title: record.title,
description: record.description ?? null,
-
image: findImage(did, pds, record),
-
alt: record.alt ?? null,
+
embed: record.embed || null,
nsfw: +(record.nsfw || 0),
big: +(record.big || 0),
createdAt: record.createdAt
···
link: record.link,
title: record.title,
description: record.description ?? null,
-
image: findImage(did, pds, record),
-
alt: record.alt ?? null,
+
embed: record.embed,
nsfw: +(record.nsfw || 0),
big: +(record.big || 0),
createdAt: record.createdAt
+4 -1
src/lexicons/index.ts
···
-
export * as PetMewsseLink from "./types/pet/mewsse/link.js";
+
export * as PetMewsseEmbedImage from "./types/pet/mewsse/embed/image.ts";
+
export * as PetMewsseEmbedPost from "./types/pet/mewsse/embed/post.ts";
+
export * as PetMewsseEmbedVideo from "./types/pet/mewsse/embed/video.ts";
+
export * as PetMewsseLink from "./types/pet/mewsse/link.ts";
+31
src/lexicons/types/pet/mewsse/embed/image.ts
···
+
import type {} from "@atcute/lexicons";
+
import * as v from "@atcute/lexicons/validations";
+
+
const _mainSchema = /*#__PURE__*/ v.object({
+
$type: /*#__PURE__*/ v.optional(
+
/*#__PURE__*/ v.literal("pet.mewsse.embed.image"),
+
),
+
/**
+
* A alt text to describe the image.
+
* @maxLength 3000
+
*/
+
alt: /*#__PURE__*/ v.optional(
+
/*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
+
/*#__PURE__*/ v.stringLength(0, 3000),
+
]),
+
),
+
/**
+
* An image to illustrate a link
+
* @accept image/*
+
* @maxSize 1000000
+
*/
+
image: /*#__PURE__*/ v.blob(),
+
});
+
+
type main$schematype = typeof _mainSchema;
+
+
export interface mainSchema extends main$schematype {}
+
+
export const mainSchema = _mainSchema as mainSchema;
+
+
export interface Main extends v.InferInput<typeof mainSchema> {}
+17
src/lexicons/types/pet/mewsse/embed/post.ts
···
+
import type {} from "@atcute/lexicons";
+
import * as v from "@atcute/lexicons/validations";
+
+
const _mainSchema = /*#__PURE__*/ v.object({
+
$type: /*#__PURE__*/ v.optional(
+
/*#__PURE__*/ v.literal("pet.mewsse.embed.post"),
+
),
+
uri: /*#__PURE__*/ v.resourceUriString(),
+
});
+
+
type main$schematype = typeof _mainSchema;
+
+
export interface mainSchema extends main$schematype {}
+
+
export const mainSchema = _mainSchema as mainSchema;
+
+
export interface Main extends v.InferInput<typeof mainSchema> {}
+17
src/lexicons/types/pet/mewsse/embed/video.ts
···
+
import type {} from "@atcute/lexicons";
+
import * as v from "@atcute/lexicons/validations";
+
+
const _mainSchema = /*#__PURE__*/ v.object({
+
$type: /*#__PURE__*/ v.optional(
+
/*#__PURE__*/ v.literal("pet.mewsse.embed.video"),
+
),
+
uri: /*#__PURE__*/ v.genericUriString(),
+
});
+
+
type main$schematype = typeof _mainSchema;
+
+
export interface mainSchema extends main$schematype {}
+
+
export const mainSchema = _mainSchema as mainSchema;
+
+
export interface Main extends v.InferInput<typeof mainSchema> {}
+12 -15
src/lexicons/types/pet/mewsse/link.ts
···
import type {} from "@atcute/lexicons";
import * as v from "@atcute/lexicons/validations";
import type {} from "@atcute/lexicons/ambient";
+
import * as PetMewsseEmbedImage from "./embed/image.ts";
+
import * as PetMewsseEmbedPost from "./embed/post.ts";
+
import * as PetMewsseEmbedVideo from "./embed/video.ts";
const _mainSchema = /*#__PURE__*/ v.record(
/*#__PURE__*/ v.tidString(),
/*#__PURE__*/ v.object({
$type: /*#__PURE__*/ v.literal("pet.mewsse.link"),
/**
-
* A alt text to describe the image.
-
* @maxLength 3000
-
*/
-
alt: /*#__PURE__*/ v.optional(
-
/*#__PURE__*/ v.constrain(/*#__PURE__*/ v.string(), [
-
/*#__PURE__*/ v.stringLength(0, 3000),
-
]),
-
),
-
/**
* Do we need to display the link as large content ?
* @default false
*/
···
* Short description for the content of the link.
*/
description: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.string()),
-
/**
-
* An image to illustrate the link
-
* @accept image/*
-
* @maxSize 1000000
-
*/
-
image: /*#__PURE__*/ v.optional(/*#__PURE__*/ v.blob()),
+
get embed() {
+
return /*#__PURE__*/ v.optional(
+
/*#__PURE__*/ v.variant([
+
PetMewsseEmbedImage.mainSchema,
+
PetMewsseEmbedPost.mainSchema,
+
PetMewsseEmbedVideo.mainSchema,
+
]),
+
);
+
},
/**
* The link to point to.
* @maxLength 3000