Suite of AT Protocol TypeScript libraries built on web standards
20
fork

Configure Feed

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

fix: param array parsing for single item

+76 -8
+1 -1
common/deno.json
··· 1 1 { 2 2 "name": "@atp/common", 3 - "version": "0.1.0-alpha.11", 3 + "version": "0.1.0-alpha.12", 4 4 "exports": { 5 5 ".": "./mod.ts", 6 6 "./server": "./server.ts"
+1 -1
lex-gen/deno.json
··· 1 1 { 2 2 "name": "@atp/lex-gen", 3 - "version": "0.1.0-alpha.6", 3 + "version": "0.1.0-alpha.7", 4 4 "exports": "./mod.ts", 5 5 "license": "MIT", 6 6 "imports": {
+1 -1
lex/deno.json
··· 1 1 { 2 2 "name": "@atp/lex", 3 - "version": "0.1.0-alpha.10", 3 + "version": "0.1.0-alpha.11", 4 4 "exports": { 5 5 ".": "./mod.ts", 6 6 "./cbor": "./cbor/mod.ts",
+18 -1
lex/schema/params.ts
··· 1 1 import { isPlainObject } from "../data/object.ts"; 2 2 import type { WithOptionalProperties } from "../core/types.ts"; 3 3 import { lazyProperty } from "../util/lazy-property.ts"; 4 + import { ArraySchema } from "./array.ts"; 5 + import { OptionalSchema } from "./optional.ts"; 4 6 import { 5 7 type Infer, 6 8 Schema, ··· 90 92 const params: Record<string, Param> = {}; 91 93 92 94 for (const [key, value] of urlSearchParams.entries()) { 95 + const validator = unwrapParamValidator(this.validatorsMap.get(key)); 96 + const expectsArray = validator instanceof ArraySchema; 97 + 93 98 if (params[key] === undefined) { 94 - params[key] = value; 99 + params[key] = expectsArray ? [value] : value; 95 100 } else if (Array.isArray(params[key])) { 96 101 (params[key] as ParamScalar[]).push(value); 97 102 } else { ··· 117 122 118 123 return urlSearchParams; 119 124 } 125 + } 126 + 127 + function unwrapParamValidator( 128 + validator: Validator<Param | undefined> | undefined, 129 + ): Validator<Param | undefined> | undefined { 130 + if (validator instanceof OptionalSchema) { 131 + return unwrapParamValidator( 132 + validator.schema as Validator<Param | undefined>, 133 + ); 134 + } 135 + 136 + return validator; 120 137 } 121 138 122 139 function normalizeParamValue(
+19
lex/tests/params_test.ts
··· 20 20 ); 21 21 }); 22 22 23 + Deno.test("parses single URLSearchParams value for declared array param", () => { 24 + const params = l.params({ 25 + feeds: l.array(l.string({ format: "at-uri" })), 26 + }); 27 + 28 + assertEquals( 29 + params.fromURLSearchParams( 30 + new URLSearchParams( 31 + "feeds=at%3A%2F%2Fdid%3Aplc%3Acveom2iroj3mt747sd4qqnr2%2Fso.sprk.feed.generator%2Fdiscover", 32 + ), 33 + ), 34 + { 35 + feeds: [ 36 + "at://did:plc:cveom2iroj3mt747sd4qqnr2/so.sprk.feed.generator/discover", 37 + ], 38 + }, 39 + ); 40 + }); 41 + 23 42 Deno.test("serializes transformed params to URLSearchParams", () => { 24 43 const params = l.params({ 25 44 since: l.optional(l.string({ format: "datetime" })),
+1 -1
repo/deno.json
··· 1 1 { 2 2 "name": "@atp/repo", 3 - "version": "0.1.0-alpha.6", 3 + "version": "0.1.0-alpha.7", 4 4 "exports": "./mod.ts", 5 5 "license": "MIT", 6 6 "imports": {
+1 -1
sync/deno.json
··· 1 1 { 2 2 "name": "@atp/sync", 3 - "version": "0.1.0-alpha.11", 3 + "version": "0.1.0-alpha.12", 4 4 "exports": "./mod.ts", 5 5 "license": "MIT", 6 6 "imports": {
+1 -1
xrpc-server/deno.json
··· 1 1 { 2 2 "name": "@atp/xrpc-server", 3 - "version": "0.1.0-alpha.11", 3 + "version": "0.1.0-alpha.12", 4 4 "exports": "./mod.ts", 5 5 "license": "MIT", 6 6 "imports": {
+32
xrpc-server/tests/lex_compat_test.ts
··· 26 26 }), 27 27 ); 28 28 29 + const feedGeneratorsQuery = l.query( 30 + "io.example.feedGeneratorsQuery", 31 + l.params({ 32 + feeds: l.array(l.string({ format: "at-uri" })), 33 + }), 34 + l.jsonPayload({ 35 + feeds: l.array(l.string({ format: "at-uri" })), 36 + }), 37 + ); 38 + 29 39 const echoProcedure = l.procedure( 30 40 "io.example.echoProcedure", 31 41 l.params(), ··· 205 215 }), 206 216 }); 207 217 218 + server.add(feedGeneratorsQuery, { 219 + handler: ({ params }) => ({ 220 + encoding: "application/json", 221 + body: { feeds: params.feeds }, 222 + }), 223 + }); 224 + 208 225 httpServer = await createServer(server); 209 226 const port = (httpServer as Deno.HttpServer & { port: number }).port; 210 227 baseUrl = `http://localhost:${port}`; ··· 238 255 message: "hello", 239 256 extra: "world", 240 257 }); 258 + }); 259 + 260 + Deno.test("coerces single URL query value for lex sdk array params", { 261 + sanitizeOps: false, 262 + sanitizeResources: false, 263 + }, async () => { 264 + const feed = 265 + "at://did:plc:cveom2iroj3mt747sd4qqnr2/so.sprk.feed.generator/discover"; 266 + const response = await fetch( 267 + `${baseUrl}/xrpc/${feedGeneratorsQuery.nsid}?feeds=${ 268 + encodeURIComponent(feed) 269 + }`, 270 + ); 271 + 272 + assertEquals(await response.json(), { feeds: [feed] }); 241 273 }); 242 274 243 275 Deno.test("registers procedures from lex sdk methods", {
+1 -1
xrpc/deno.json
··· 1 1 { 2 2 "name": "@atp/xrpc", 3 - "version": "0.1.0-alpha.6", 3 + "version": "0.1.0-alpha.7", 4 4 "exports": "./mod.ts", 5 5 "license": "MIT", 6 6 "imports": {