this repo has no description
0
fork

Configure Feed

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

Rename createLabel method to internal saveLabel, expose new createLabel with simpler API

futur 69c3dbd4 203f0fab

+61 -37
+23 -19
src/LabelerServer.ts
··· 22 22 import type { WebSocket } from "ws"; 23 23 import { formatLabel, labelIsSigned, signLabel } from "./util/labels.js"; 24 24 import type { 25 + CreateLabelData, 25 26 ProcedureHandler, 26 27 QueryHandler, 27 28 SavedLabel, 28 29 SubscriptionHandler, 29 30 } from "./util/types.js"; 31 + import { excludeUndefined } from "./util/util.js"; 30 32 31 33 /** 32 34 * Options for the {@link LabelerServer} class. ··· 132 134 } 133 135 134 136 /** 135 - * Create and insert a label into the database, emitting it to subscribers. 136 - * @param label The label to create. 137 - * @returns The created label. 137 + * Insert a label into the database, emitting it to subscribers. 138 + * @param label The label to insert. 139 + * @returns The inserted label. 138 140 */ 139 - async createLabel(label: ComAtprotoLabelDefs.Label): Promise<SavedLabel> { 141 + private async saveLabel(label: ComAtprotoLabelDefs.Label): Promise<SavedLabel> { 140 142 const signed = labelIsSigned(label) ? label : await signLabel(label, this.signingKey); 141 143 142 144 const stmt = this.db.prepare(` ··· 155 157 } 156 158 157 159 /** 160 + * Create and insert a label into the database, emitting it to subscribers. 161 + * @param label The label to create. 162 + * @returns The created label. 163 + */ 164 + async createLabel(label: CreateLabelData): Promise<SavedLabel> { 165 + return this.saveLabel( 166 + excludeUndefined({ 167 + ...label, 168 + src: label.src ?? this.did, 169 + cts: label.cts ?? new Date().toISOString(), 170 + }), 171 + ); 172 + } 173 + 174 + /** 158 175 * Create and insert labels into the database, emitting them to subscribers. 159 176 * @param subject The subject of the labels. 160 177 * @param labels The labels to create. ··· 170 187 const createdLabels: Array<SavedLabel> = []; 171 188 if (create) { 172 189 for (const val of create) { 173 - const created = await this.createLabel({ 174 - src: this.did, 175 - uri, 176 - ...(cid ? { cid } : {}), 177 - val, 178 - cts: new Date().toISOString(), 179 - }); 190 + const created = await this.createLabel({ uri, cid, val }); 180 191 createdLabels.push(created); 181 192 } 182 193 } 183 194 if (negate) { 184 195 for (const val of negate) { 185 - const negated = await this.createLabel({ 186 - src: this.did, 187 - uri, 188 - ...(cid ? { cid } : {}), 189 - val, 190 - neg: true, 191 - cts: new Date().toISOString(), 192 - }); 196 + const negated = await this.createLabel({ uri, cid, val, neg: true }); 193 197 createdLabels.push(negated); 194 198 } 195 199 }
+1
src/index.ts
··· 1 1 export { type LabelerOptions, LabelerServer } from "./LabelerServer.js"; 2 2 export { formatLabel, labelIsSigned, signLabel } from "./util/labels.js"; 3 3 export type { 4 + CreateLabelData, 4 5 ProcedureHandler, 5 6 QueryHandler, 6 7 SavedLabel,
+4 -16
src/util/labels.ts
··· 1 1 import { encode as cborEncode } from "@atcute/cbor"; 2 2 import type { ComAtprotoLabelDefs } from "@atproto/api"; 3 3 import type { Keypair } from "@atproto/crypto"; 4 - import type { SignedLabel, StrictPartial } from "./types.js"; 4 + import type { SignedLabel } from "./types.js"; 5 + import { excludeUndefined } from "./util.js"; 5 6 6 7 const LABEL_VERSION = 1; 7 8 8 - export function formatLabel( 9 - label: ComAtprotoLabelDefs.Label, 10 - ): StrictPartial<ComAtprotoLabelDefs.Label> { 11 - const { src, uri, cid, val, neg, cts, exp, sig } = label; 12 - return { 13 - ver: LABEL_VERSION, 14 - src, 15 - uri, 16 - ...(cid ? { cid } : {}), 17 - val, 18 - neg: !!neg, 19 - cts, 20 - ...(exp ? { exp } : {}), 21 - ...(sig ? { sig } : {}), 22 - } as never; 9 + export function formatLabel(label: ComAtprotoLabelDefs.Label): ComAtprotoLabelDefs.Label { 10 + return excludeUndefined({ ...label, ver: LABEL_VERSION, neg: !!label.neg }); 23 11 } 24 12 25 13 export async function signLabel(
+23 -2
src/util/types.ts
··· 9 9 RouteHandlerMethod, 10 10 } from "fastify"; 11 11 12 + type OptionalOrUndefinedKeys<T> = { [K in keyof T]: undefined extends T[K] ? K : never }[keyof T]; 13 + type RequiredDefinedKeys<T> = Exclude<keyof T, OptionalOrUndefinedKeys<T>>; 12 14 export type StrictPartial<T> = 13 - & { [K in keyof T as undefined extends T[K] ? never : K]: T[K] } 14 - & { [K in keyof T as undefined extends T[K] ? K : never]?: T[K] }; 15 + & { [K in OptionalOrUndefinedKeys<T>]+?: Exclude<T[K], undefined> } 16 + & { [K in RequiredDefinedKeys<T>]-?: T[K] }; 15 17 18 + /** 19 + * Data required to create a label. 20 + */ 21 + export interface CreateLabelData { 22 + /** The label value. */ 23 + val: string; 24 + /** The subject of the label. If labeling an account, this should be a string beginning with `did:`. */ 25 + uri: string; 26 + /** Optionally, a CID specifying the version of `uri` to label. */ 27 + cid?: string | undefined; 28 + /** Whether this label is negating a previous instance of this label applied to the same subject. */ 29 + neg?: boolean | undefined; 30 + /** The DID of the actor who created this label, if different from the labeler. */ 31 + src?: string | undefined; 32 + /** The creation date of the label. Must be in ISO 8601 format. */ 33 + cts?: string | undefined; 34 + /** The expiration date of the label, if any. Must be in ISO 8601 format. */ 35 + exp?: string | undefined; 36 + } 16 37 export type SignedLabel = ComAtprotoLabelDefs.Label & { sig: Uint8Array }; 17 38 export type SavedLabel = SignedLabel & { id: number }; 18 39
+10
src/util/util.ts
··· 1 + import { StrictPartial } from "./types.js"; 2 + 3 + export function excludeUndefined<T extends Record<PropertyKey, unknown>>(obj: T): StrictPartial<T> { 4 + return Object.entries(obj).reduce<Record<string, unknown>>((acc, [key, value]) => { 5 + if (value !== undefined) { 6 + acc[key] = value; 7 + } 8 + return acc; 9 + }, {}) as never; 10 + }