@atproto/lex-client 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/client.d.ts +52 -7
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +38 -16
  5. package/dist/client.js.map +1 -1
  6. package/dist/lexicons/com/atproto/repo/applyWrites.d.ts +3 -0
  7. package/dist/lexicons/com/atproto/repo/applyWrites.d.ts.map +1 -0
  8. package/dist/lexicons/com/atproto/repo/applyWrites.defs.d.ts +100 -0
  9. package/dist/lexicons/com/atproto/repo/applyWrites.defs.d.ts.map +1 -0
  10. package/dist/lexicons/com/atproto/repo/applyWrites.defs.js +81 -0
  11. package/dist/lexicons/com/atproto/repo/applyWrites.defs.js.map +1 -0
  12. package/dist/lexicons/com/atproto/repo/applyWrites.js +6 -0
  13. package/dist/lexicons/com/atproto/repo/applyWrites.js.map +1 -0
  14. package/dist/lexicons/com/atproto/repo/createRecord.defs.d.ts +16 -13
  15. package/dist/lexicons/com/atproto/repo/createRecord.defs.d.ts.map +1 -1
  16. package/dist/lexicons/com/atproto/repo/createRecord.defs.js +10 -10
  17. package/dist/lexicons/com/atproto/repo/createRecord.defs.js.map +1 -1
  18. package/dist/lexicons/com/atproto/repo/deleteRecord.defs.d.ts +16 -13
  19. package/dist/lexicons/com/atproto/repo/deleteRecord.defs.d.ts.map +1 -1
  20. package/dist/lexicons/com/atproto/repo/deleteRecord.defs.js +10 -10
  21. package/dist/lexicons/com/atproto/repo/deleteRecord.defs.js.map +1 -1
  22. package/dist/lexicons/com/atproto/repo/getRecord.defs.d.ts +13 -11
  23. package/dist/lexicons/com/atproto/repo/getRecord.defs.d.ts.map +1 -1
  24. package/dist/lexicons/com/atproto/repo/getRecord.defs.js +7 -9
  25. package/dist/lexicons/com/atproto/repo/getRecord.defs.js.map +1 -1
  26. package/dist/lexicons/com/atproto/repo/listRecords.defs.d.ts +13 -11
  27. package/dist/lexicons/com/atproto/repo/listRecords.defs.d.ts.map +1 -1
  28. package/dist/lexicons/com/atproto/repo/listRecords.defs.js +7 -9
  29. package/dist/lexicons/com/atproto/repo/listRecords.defs.js.map +1 -1
  30. package/dist/lexicons/com/atproto/repo/putRecord.defs.d.ts +16 -13
  31. package/dist/lexicons/com/atproto/repo/putRecord.defs.d.ts.map +1 -1
  32. package/dist/lexicons/com/atproto/repo/putRecord.defs.js +10 -10
  33. package/dist/lexicons/com/atproto/repo/putRecord.defs.js.map +1 -1
  34. package/dist/lexicons/com/atproto/repo/uploadBlob.defs.d.ts +6 -3
  35. package/dist/lexicons/com/atproto/repo/uploadBlob.defs.d.ts.map +1 -1
  36. package/dist/lexicons/com/atproto/repo/uploadBlob.defs.js +7 -7
  37. package/dist/lexicons/com/atproto/repo/uploadBlob.defs.js.map +1 -1
  38. package/dist/lexicons/com/atproto/repo.d.ts +2 -1
  39. package/dist/lexicons/com/atproto/repo.d.ts.map +1 -1
  40. package/dist/lexicons/com/atproto/repo.js +2 -1
  41. package/dist/lexicons/com/atproto/repo.js.map +1 -1
  42. package/dist/lexicons/com/atproto/sync/getBlob.defs.d.ts +10 -8
  43. package/dist/lexicons/com/atproto/sync/getBlob.defs.d.ts.map +1 -1
  44. package/dist/lexicons/com/atproto/sync/getBlob.defs.js +6 -8
  45. package/dist/lexicons/com/atproto/sync/getBlob.defs.js.map +1 -1
  46. package/dist/types.d.ts +2 -6
  47. package/dist/types.d.ts.map +1 -1
  48. package/dist/types.js.map +1 -1
  49. package/dist/util.d.ts +9 -0
  50. package/dist/util.d.ts.map +1 -1
  51. package/dist/util.js +23 -0
  52. package/dist/util.js.map +1 -1
  53. package/dist/write-operation-builder.d.ts +19 -0
  54. package/dist/write-operation-builder.d.ts.map +1 -0
  55. package/dist/write-operation-builder.js +35 -0
  56. package/dist/write-operation-builder.js.map +1 -0
  57. package/dist/xrpc.d.ts.map +1 -1
  58. package/dist/xrpc.js +5 -2
  59. package/dist/xrpc.js.map +1 -1
  60. package/package.json +4 -4
  61. package/src/client.ts +88 -45
  62. package/src/lexicons/com/atproto/repo/applyWrites.defs.ts +197 -0
  63. package/src/lexicons/com/atproto/repo/applyWrites.ts +6 -0
  64. package/src/lexicons/com/atproto/repo/createRecord.defs.ts +30 -36
  65. package/src/lexicons/com/atproto/repo/deleteRecord.defs.ts +24 -30
  66. package/src/lexicons/com/atproto/repo/getRecord.defs.ts +14 -21
  67. package/src/lexicons/com/atproto/repo/listRecords.defs.ts +21 -28
  68. package/src/lexicons/com/atproto/repo/putRecord.defs.ts +31 -37
  69. package/src/lexicons/com/atproto/repo/uploadBlob.defs.ts +8 -13
  70. package/src/lexicons/com/atproto/repo.ts +2 -1
  71. package/src/lexicons/com/atproto/sync/getBlob.defs.ts +14 -21
  72. package/src/types.ts +6 -10
  73. package/src/util.ts +48 -1
  74. package/src/write-operation-builder.ts +110 -0
  75. package/src/xrpc.ts +5 -5
package/dist/xrpc.js CHANGED
@@ -4,7 +4,7 @@ import { getMain, } from '@atproto/lex-schema';
4
4
  import { buildAgent } from './agent.js';
5
5
  import { XrpcFetchError, asXrpcFailure } from './errors.js';
6
6
  import { XrpcResponse } from './response.js';
7
- import { buildXrpcRequestHeaders, isAsyncIterable, isBlobLike, toReadableStream, } from './util.js';
7
+ import { asUint8ArrayArrayBuffer, buildXrpcRequestHeaders, isAsyncIterable, isBlobLike, toReadableStream, } from './util.js';
8
8
  export async function xrpc(agentOpts, ns, options = {}) {
9
9
  const response = await xrpcSafe(agentOpts, ns, options);
10
10
  if (response.success)
@@ -105,13 +105,16 @@ function xrpcProcedureInput(method, options, encodingHint) {
105
105
  if (body === null)
106
106
  break;
107
107
  if (ArrayBuffer.isView(body)) {
108
- return buildPayload(input, body, encodingHint);
108
+ return buildPayload(input, asUint8ArrayArrayBuffer(body), encodingHint);
109
109
  }
110
110
  else if (body instanceof ArrayBuffer ||
111
111
  body instanceof ReadableStream) {
112
112
  return buildPayload(input, body, encodingHint);
113
113
  }
114
114
  else if (isAsyncIterable(body)) {
115
+ // @NOTE While fetch() does not allow SharedArrayBuffer-backed
116
+ // Uint8Arrays as "body", it **does** allow using ReadableStreams made
117
+ // of Uint8Arrays<SharedArrayBuffer> (tested on NodeJS 22) as "body".
115
118
  return buildPayload(input, toReadableStream(body), encodingHint);
116
119
  }
117
120
  else if (isBlobLike(body)) {
package/dist/xrpc.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"xrpc.js","sourceRoot":"","sources":["../src/xrpc.ts"],"names":[],"mappings":"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","sourcesContent":["import { LexValue, isLexScalar, isPlainObject } from '@atproto/lex-data'\nimport { lexStringify } from '@atproto/lex-json'\nimport {\n InferInput,\n InferPayload,\n Main,\n NsidString,\n Params,\n Payload,\n Procedure,\n Query,\n Restricted,\n Subscription,\n getMain,\n} from '@atproto/lex-schema'\nimport { Agent, AgentOptions, buildAgent } from './agent.js'\nimport { XrpcFailure, XrpcFetchError, asXrpcFailure } from './errors.js'\nimport { XrpcResponse, XrpcResponseOptions } from './response.js'\nimport { BinaryBodyInit } from './types.js'\nimport {\n XrpcRequestHeadersOptions,\n buildXrpcRequestHeaders,\n isAsyncIterable,\n isBlobLike,\n toReadableStream,\n} from './util.js'\n\n/**\n * The query/path parameters type for an XRPC method, inferred from its schema.\n *\n * @typeParam M - The XRPC method type (Procedure, Query, or Subscription)\n */\nexport type XrpcRequestParams<M extends Procedure | Query | Subscription> =\n InferInput<M['parameters']>\n\n// If all params are optional, allow omitting the params object\ntype XrpcRequestParamsOptions<P extends Params> =\n NonNullable<unknown> extends P ? { params?: P } : { params: P }\n\ntype XrpcRequestPayload<M extends Procedure | Query> = M extends Procedure\n ? InferPayload<M['input'], BinaryBodyInit>\n : undefined\n\ntype XrpcRequestPayloadOptions<TPayload> = TPayload extends {\n body: infer B\n encoding: infer E\n}\n ? {\n body: B\n\n /**\n * mime type hint for binary bodies\n *\n * Only needed for endpoints that accept binary input (e.g. file uploads)\n * when the body is a Blob-like object without a type (e.g. fetch-blob's\n * Blob). If the body is a Blob-like object with a type, that type will be\n * used as the content-type header instead of this option.\n *\n * @default \"application/octet-stream\"\n */\n encoding?: E\n }\n : { body?: undefined; encoding?: undefined }\n\n/**\n * Options for making an XRPC request, based on the method schema.\n *\n * Combines {@link XrpcRequestOptions} and {@link XrpcResponseOptions} with\n * method-specific params and body requirements. The type system ensures\n * required params/body are provided based on the method schema.\n *\n * @typeParam M - The XRPC method type (Procedure or Query)\n *\n * @example Query with params\n * ```typescript\n * const options: XrpcOptions<typeof app.bsky.feed.getTimeline.main> = {\n * params: { limit: 50 }\n * }\n * ```\n *\n * @example Procedure with body\n * ```typescript\n * const options: XrpcOptions<typeof com.atproto.repo.createRecord.main> = {\n * body: { repo: did, collection: 'app.bsky.feed.post', record: { ... } }\n * }\n * ```\n */\nexport type XrpcOptions<M extends Procedure | Query = Procedure | Query> =\n XrpcRequestOptions<M> & XrpcResponseOptions\n\nexport type XrpcRequestOptions<\n M extends Procedure | Query = Procedure | Query,\n> = XrpcRequestProcessingOptions &\n XrpcRequestHeadersOptions &\n XrpcRequestPayloadOptions<XrpcRequestPayload<M>> &\n XrpcRequestParamsOptions<XrpcRequestParams<M>>\n\nexport type XrpcRequestProcessingOptions = {\n /**\n * AbortSignal to cancel the request.\n */\n signal?: AbortSignal\n\n /**\n * Whether to validate the request against the method's input schema. Enabling\n * this can help catch errors early but may have a performance cost. This\n * would typically only be set to `true` in development or debugging\n * scenarios.\n *\n * @default false\n */\n validateRequest?: boolean\n}\n\n/**\n * Makes an XRPC request and throws on failure.\n *\n * This is the low-level function for making XRPC calls.\n *\n * @param agent - The {@link Agent} to use for making the request\n * @param ns - The lexicon method definition\n * @param options - Request {@link XrpcOptions options} (params, body, headers, etc.)\n * @returns The successful {@link XrpcResponse}\n * @throws {XrpcFailure} When the request fails\n *\n * @example\n * ```typescript\n * const response = await xrpc('https://bsky.network', com.atproto.identity.resolveHandle, {\n * params: { handle: \"atproto.com\" }\n * })\n * ```\n *\n * @example\n * ```typescript\n * const response = await xrpc(agent, app.bsky.feed.getTimeline.main, {\n * params: { limit: 50 }\n * })\n * ```\n */\nexport async function xrpc<const M extends Query | Procedure>(\n agentOpts: Agent | AgentOptions,\n ns: NonNullable<unknown> extends XrpcOptions<M>\n ? Main<M>\n : Restricted<'This XRPC method requires an \"options\" argument'>,\n): Promise<XrpcResponse<M>>\nexport async function xrpc<const M extends Query | Procedure>(\n agentOpts: Agent | AgentOptions,\n ns: Main<M>,\n options: XrpcOptions<M>,\n): Promise<XrpcResponse<M>>\nexport async function xrpc<const M extends Query | Procedure>(\n agentOpts: Agent | AgentOptions,\n ns: Main<M>,\n options: XrpcOptions<M> = {} as XrpcOptions<M>,\n): Promise<XrpcResponse<M>> {\n const response = await xrpcSafe<M>(agentOpts, ns, options)\n if (response.success) return response\n else throw response\n}\n\n/**\n * Union type representing either a successful response or a failure.\n *\n * Both {@link XrpcResponse} and {@link XrpcFailure} have a `success` property\n * that can be used to discriminate between them.\n *\n * @typeParam M - The XRPC method type\n */\nexport type XrpcResult<M extends Procedure | Query> =\n | XrpcResponse<M>\n | XrpcFailure<M>\n\n/**\n * Makes an XRPC request without throwing on failure.\n *\n * Returns a discriminated union that can be checked via the `success` property.\n * This is useful for handling errors without try/catch blocks. This also allow\n * failure results to be typed with the method schema, which can provide better\n * type safety when handling errors (e.g. checking for specific error codes).\n *\n * @param agent - The {@link Agent} to use for making the request\n * @param ns - The lexicon method definition\n * @param options - Request {@link XrpcOptions options} (params, body, headers, etc.)\n * @returns Either a successful {@link XrpcResponse} or an {@link XrpcFailure}\n *\n * @example\n * ```typescript\n * const result = await xrpcSafe('https://example.com', app.bsky.actor.getProfile, {\n * params: { actor: 'alice.bsky.social' }\n * })\n *\n * if (result.success) {\n * console.log(result.body.displayName)\n * } else {\n * console.error('Request failed:', result.error)\n * }\n * ```\n */\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agentOpts: Agent | AgentOptions,\n ns: NonNullable<unknown> extends XrpcOptions<M>\n ? Main<M>\n : Restricted<'This XRPC method requires an \"options\" argument'>,\n): Promise<XrpcResult<M>>\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agentOpts: Agent | AgentOptions,\n ns: Main<M>,\n options: XrpcOptions<M>,\n): Promise<XrpcResult<M>>\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agentOpts: Agent | AgentOptions,\n ns: Main<M>,\n options: XrpcOptions<M> = {} as XrpcOptions<M>,\n): Promise<XrpcResult<M>> {\n options.signal?.throwIfAborted()\n const method: M = getMain(ns)\n try {\n const agent = buildAgent(agentOpts)\n const url = xrpcRequestUrl(method, options)\n const request = xrpcRequestInit(method, options)\n const response = await agent.fetchHandler(url, request).catch((err) => {\n const cause = extractFetchErrorCause(err)\n throw new XrpcFetchError(method, cause)\n })\n return await XrpcResponse.fromFetchResponse<M>(method, response, options)\n } catch (cause) {\n return asXrpcFailure(method, cause)\n }\n}\n\nfunction xrpcRequestUrl<M extends Procedure | Query | Subscription>(\n method: M,\n options: { params?: Params },\n): `/xrpc/${NsidString}${'' | `?${string}`}` {\n const path = `/xrpc/${method.nsid}` as const\n\n // @NOTE param.toURLSearchParams() will always validate the params in order to\n // apply default values, so we can't disable it with options.validateRequest\n\n const queryString = method.parameters\n ?.toURLSearchParams(options.params ?? {})\n .toString()\n\n return queryString ? (`${path}?${queryString}` as const) : path\n}\n\nfunction xrpcRequestInit<T extends Procedure | Query>(\n schema: T,\n options: XrpcRequestProcessingOptions &\n XrpcRequestHeadersOptions &\n XrpcProcedureInputOptions & {\n encoding?: string\n },\n): RequestInit & { duplex?: 'half' } {\n const headers = buildXrpcRequestHeaders(options)\n\n // Tell the server what type of response we're expecting\n if (schema.output.encoding) {\n headers.set('accept', schema.output.encoding)\n }\n\n // Caller should not set content-type header\n if (headers.has('content-type')) {\n const contentType = headers.get('content-type')\n throw new TypeError(`Unexpected content-type header (${contentType})`)\n }\n\n // Requests with body\n if ('input' in schema) {\n const encodingHint = options.encoding\n const input = xrpcProcedureInput(schema, options, encodingHint)\n\n if (input) {\n headers.set('content-type', input.encoding)\n } else if (encodingHint != null) {\n throw new TypeError(`Unexpected encoding hint (${encodingHint})`)\n }\n\n return {\n duplex: 'half',\n redirect: 'follow',\n referrerPolicy: 'strict-origin-when-cross-origin', // (default)\n mode: 'cors', // (default)\n signal: options.signal,\n method: 'POST',\n headers,\n body: input?.body,\n }\n }\n\n // Requests without body\n return {\n duplex: 'half',\n redirect: 'follow',\n referrerPolicy: 'strict-origin-when-cross-origin', // (default)\n mode: 'cors', // (default)\n signal: options.signal,\n method: 'GET',\n headers,\n }\n}\n\ntype XrpcProcedureInputOptions = {\n body?: LexValue | BinaryBodyInit\n validateRequest?: boolean\n}\n\nfunction xrpcProcedureInput(\n method: Procedure,\n options: XrpcProcedureInputOptions,\n encodingHint?: string,\n): null | { body: BodyInit; encoding: string } {\n const { input } = method\n const { body } = options\n\n if (options.validateRequest) {\n input.schema?.check(body)\n }\n\n // Special handling for endpoints expecting application/json input\n if (input.encoding === 'application/json') {\n // @NOTE **NOT** using isLexValue here to avoid deep checks in order to\n // distinguish between LexValue and BinaryBodyInit.\n if (!isLexScalar(body) && !isPlainObject(body) && !Array.isArray(body)) {\n throw new TypeError(`Expected LexValue body, got ${typeof body}`)\n }\n\n return buildPayload(input, lexStringify(body), encodingHint)\n }\n\n // Other encodings will be sent unaltered (ie. as binary data)\n switch (typeof body) {\n case 'undefined':\n case 'string':\n return buildPayload(input, body, encodingHint)\n case 'object': {\n if (body === null) break\n if (ArrayBuffer.isView(body)) {\n return buildPayload(\n input,\n body as Uint8Array<ArrayBuffer>,\n encodingHint,\n )\n } else if (\n body instanceof ArrayBuffer ||\n body instanceof ReadableStream\n ) {\n return buildPayload(input, body, encodingHint)\n } else if (isAsyncIterable(body)) {\n return buildPayload(input, toReadableStream(body), encodingHint)\n } else if (isBlobLike(body)) {\n return buildPayload(input, body, encodingHint || body.type)\n }\n }\n }\n\n throw new TypeError(\n `Invalid ${typeof body} body for ${input.encoding} encoding`,\n )\n}\n\nfunction buildPayload(\n schema: Payload,\n body: undefined | BodyInit,\n encodingHint?: string,\n): null | { body: BodyInit; encoding: string } {\n if (schema.encoding === undefined) {\n if (body !== undefined) {\n throw new TypeError(`Endpoint expects no payload`)\n }\n\n return null\n }\n\n if (body === undefined) {\n // This error would be returned by the server, but we can catch it earlier\n // to avoid un-necessary requests. Note that a content-length of 0 does not\n // necessary mean that the body is \"empty\" (e.g. an empty txt file).\n throw new TypeError(`A request body is expected but none was provided`)\n }\n\n const encoding = buildEncoding(schema, encodingHint)\n return { encoding, body }\n}\n\nfunction buildEncoding(schema: Payload, encodingHint?: string): string {\n // Should never happen (required for type safety)\n if (!schema.encoding) {\n throw new TypeError('Unexpected payload')\n }\n\n if (encodingHint?.length) {\n if (!schema.matchesEncoding(encodingHint)) {\n throw new TypeError(\n `Cannot send a body with content-type \"${encodingHint}\" for \"${schema.encoding}\" encoding`,\n )\n }\n return encodingHint\n }\n\n // Fallback\n\n if (schema.encoding === '*/*') {\n return 'application/octet-stream'\n }\n\n if (schema.encoding.startsWith('text/')) {\n return schema.encoding.includes('*')\n ? 'text/plain; charset=utf-8'\n : `${schema.encoding}; charset=utf-8`\n }\n\n if (!schema.encoding.includes('*')) {\n return schema.encoding\n }\n\n throw new TypeError(\n `Unable to determine payload encoding. Please provide a 'content-type' header matching ${schema.encoding}.`,\n )\n}\n\n/**\n * Extracts the root cause from an error, unwrapping common fetch-related errors\n * such as those from undici (Node's internal fetch implementation).\n *\n * @param err - The error to extract the root cause from\n * @returns The root cause error, or the original error if no specific pattern is matched\n * @remarks This is useful for getting more specific error information from fetch-related failures, especially in Node environments using undici.\n */\nexport function extractFetchErrorCause(err: unknown): unknown {\n // Unwrap the Network error from undici (i.e. Node's internal fetch() implementation)\n // https://github.com/nodejs/undici/blob/04cb77327f7ada95c2e5b67424cddcb22d7bf882/lib/web/fetch/index.js#L234-L239\n if (\n err instanceof TypeError &&\n err.message === 'fetch failed' &&\n err.cause !== undefined\n ) {\n return err.cause\n }\n\n // @TODO Add other unwrap patterns here as needed (e.g. for other fetch\n // implementations or common network libraries, like \"node:http\", or in other\n // environments like React Native, Deno, Bun, Browser, etc.)\n\n return err\n}\n"]}
1
+ {"version":3,"file":"xrpc.js","sourceRoot":"","sources":["../src/xrpc.ts"],"names":[],"mappings":"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","sourcesContent":["import { LexValue, isLexScalar, isPlainObject } from '@atproto/lex-data'\nimport { lexStringify } from '@atproto/lex-json'\nimport {\n InferInput,\n InferPayload,\n Main,\n NsidString,\n Params,\n Payload,\n Procedure,\n Query,\n Restricted,\n Subscription,\n getMain,\n} from '@atproto/lex-schema'\nimport { Agent, AgentOptions, buildAgent } from './agent.js'\nimport { XrpcFailure, XrpcFetchError, asXrpcFailure } from './errors.js'\nimport { XrpcResponse, XrpcResponseOptions } from './response.js'\nimport { BinaryBodyInit } from './types.js'\nimport {\n XrpcRequestHeadersOptions,\n asUint8ArrayArrayBuffer,\n buildXrpcRequestHeaders,\n isAsyncIterable,\n isBlobLike,\n toReadableStream,\n} from './util.js'\n\n/**\n * The query/path parameters type for an XRPC method, inferred from its schema.\n *\n * @typeParam M - The XRPC method type (Procedure, Query, or Subscription)\n */\nexport type XrpcRequestParams<M extends Procedure | Query | Subscription> =\n InferInput<M['parameters']>\n\n// If all params are optional, allow omitting the params object\ntype XrpcRequestParamsOptions<P extends Params> =\n NonNullable<unknown> extends P ? { params?: P } : { params: P }\n\ntype XrpcRequestPayload<M extends Procedure | Query> = M extends Procedure\n ? InferPayload<M['input'], BinaryBodyInit>\n : undefined\n\ntype XrpcRequestPayloadOptions<TPayload> = TPayload extends {\n body: infer B\n encoding: infer E\n}\n ? {\n body: B\n\n /**\n * mime type hint for binary bodies\n *\n * Only needed for endpoints that accept binary input (e.g. file uploads)\n * when the body is a Blob-like object without a type (e.g. fetch-blob's\n * Blob). If the body is a Blob-like object with a type, that type will be\n * used as the content-type header instead of this option.\n *\n * @default \"application/octet-stream\"\n */\n encoding?: E\n }\n : { body?: undefined; encoding?: undefined }\n\n/**\n * Options for making an XRPC request, based on the method schema.\n *\n * Combines {@link XrpcRequestOptions} and {@link XrpcResponseOptions} with\n * method-specific params and body requirements. The type system ensures\n * required params/body are provided based on the method schema.\n *\n * @typeParam M - The XRPC method type (Procedure or Query)\n *\n * @example Query with params\n * ```typescript\n * const options: XrpcOptions<typeof app.bsky.feed.getTimeline.main> = {\n * params: { limit: 50 }\n * }\n * ```\n *\n * @example Procedure with body\n * ```typescript\n * const options: XrpcOptions<typeof com.atproto.repo.createRecord.main> = {\n * body: { repo: did, collection: 'app.bsky.feed.post', record: { ... } }\n * }\n * ```\n */\nexport type XrpcOptions<M extends Procedure | Query = Procedure | Query> =\n XrpcRequestOptions<M> & XrpcResponseOptions\n\nexport type XrpcRequestOptions<\n M extends Procedure | Query = Procedure | Query,\n> = XrpcRequestProcessingOptions &\n XrpcRequestHeadersOptions &\n XrpcRequestPayloadOptions<XrpcRequestPayload<M>> &\n XrpcRequestParamsOptions<XrpcRequestParams<M>>\n\nexport type XrpcRequestProcessingOptions = {\n /**\n * AbortSignal to cancel the request.\n */\n signal?: AbortSignal\n\n /**\n * Whether to validate the request against the method's input schema. Enabling\n * this can help catch errors early but may have a performance cost. This\n * would typically only be set to `true` in development or debugging\n * scenarios.\n *\n * @default false\n */\n validateRequest?: boolean\n}\n\n/**\n * Makes an XRPC request and throws on failure.\n *\n * This is the low-level function for making XRPC calls.\n *\n * @param agent - The {@link Agent} to use for making the request\n * @param ns - The lexicon method definition\n * @param options - Request {@link XrpcOptions options} (params, body, headers, etc.)\n * @returns The successful {@link XrpcResponse}\n * @throws {XrpcFailure} When the request fails\n *\n * @example\n * ```typescript\n * const response = await xrpc('https://bsky.network', com.atproto.identity.resolveHandle, {\n * params: { handle: \"atproto.com\" }\n * })\n * ```\n *\n * @example\n * ```typescript\n * const response = await xrpc(agent, app.bsky.feed.getTimeline.main, {\n * params: { limit: 50 }\n * })\n * ```\n */\nexport async function xrpc<const M extends Query | Procedure>(\n agentOpts: Agent | AgentOptions,\n ns: NonNullable<unknown> extends XrpcOptions<M>\n ? Main<M>\n : Restricted<'This XRPC method requires an \"options\" argument'>,\n): Promise<XrpcResponse<M>>\nexport async function xrpc<const M extends Query | Procedure>(\n agentOpts: Agent | AgentOptions,\n ns: Main<M>,\n options: XrpcOptions<M>,\n): Promise<XrpcResponse<M>>\nexport async function xrpc<const M extends Query | Procedure>(\n agentOpts: Agent | AgentOptions,\n ns: Main<M>,\n options: XrpcOptions<M> = {} as XrpcOptions<M>,\n): Promise<XrpcResponse<M>> {\n const response = await xrpcSafe<M>(agentOpts, ns, options)\n if (response.success) return response\n else throw response\n}\n\n/**\n * Union type representing either a successful response or a failure.\n *\n * Both {@link XrpcResponse} and {@link XrpcFailure} have a `success` property\n * that can be used to discriminate between them.\n *\n * @typeParam M - The XRPC method type\n */\nexport type XrpcResult<M extends Procedure | Query> =\n | XrpcResponse<M>\n | XrpcFailure<M>\n\n/**\n * Makes an XRPC request without throwing on failure.\n *\n * Returns a discriminated union that can be checked via the `success` property.\n * This is useful for handling errors without try/catch blocks. This also allow\n * failure results to be typed with the method schema, which can provide better\n * type safety when handling errors (e.g. checking for specific error codes).\n *\n * @param agent - The {@link Agent} to use for making the request\n * @param ns - The lexicon method definition\n * @param options - Request {@link XrpcOptions options} (params, body, headers, etc.)\n * @returns Either a successful {@link XrpcResponse} or an {@link XrpcFailure}\n *\n * @example\n * ```typescript\n * const result = await xrpcSafe('https://example.com', app.bsky.actor.getProfile, {\n * params: { actor: 'alice.bsky.social' }\n * })\n *\n * if (result.success) {\n * console.log(result.body.displayName)\n * } else {\n * console.error('Request failed:', result.error)\n * }\n * ```\n */\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agentOpts: Agent | AgentOptions,\n ns: NonNullable<unknown> extends XrpcOptions<M>\n ? Main<M>\n : Restricted<'This XRPC method requires an \"options\" argument'>,\n): Promise<XrpcResult<M>>\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agentOpts: Agent | AgentOptions,\n ns: Main<M>,\n options: XrpcOptions<M>,\n): Promise<XrpcResult<M>>\nexport async function xrpcSafe<const M extends Query | Procedure>(\n agentOpts: Agent | AgentOptions,\n ns: Main<M>,\n options: XrpcOptions<M> = {} as XrpcOptions<M>,\n): Promise<XrpcResult<M>> {\n options.signal?.throwIfAborted()\n const method: M = getMain(ns)\n try {\n const agent = buildAgent(agentOpts)\n const url = xrpcRequestUrl(method, options)\n const request = xrpcRequestInit(method, options)\n const response = await agent.fetchHandler(url, request).catch((err) => {\n const cause = extractFetchErrorCause(err)\n throw new XrpcFetchError(method, cause)\n })\n return await XrpcResponse.fromFetchResponse<M>(method, response, options)\n } catch (cause) {\n return asXrpcFailure(method, cause)\n }\n}\n\nfunction xrpcRequestUrl<M extends Procedure | Query | Subscription>(\n method: M,\n options: { params?: Params },\n): `/xrpc/${NsidString}${'' | `?${string}`}` {\n const path = `/xrpc/${method.nsid}` as const\n\n // @NOTE param.toURLSearchParams() will always validate the params in order to\n // apply default values, so we can't disable it with options.validateRequest\n\n const queryString = method.parameters\n ?.toURLSearchParams(options.params ?? {})\n .toString()\n\n return queryString ? (`${path}?${queryString}` as const) : path\n}\n\nfunction xrpcRequestInit<T extends Procedure | Query>(\n schema: T,\n options: XrpcRequestProcessingOptions &\n XrpcRequestHeadersOptions &\n XrpcProcedureInputOptions & {\n encoding?: string\n },\n): RequestInit & { duplex?: 'half' } {\n const headers = buildXrpcRequestHeaders(options)\n\n // Tell the server what type of response we're expecting\n if (schema.output.encoding) {\n headers.set('accept', schema.output.encoding)\n }\n\n // Caller should not set content-type header\n if (headers.has('content-type')) {\n const contentType = headers.get('content-type')\n throw new TypeError(`Unexpected content-type header (${contentType})`)\n }\n\n // Requests with body\n if ('input' in schema) {\n const encodingHint = options.encoding\n const input = xrpcProcedureInput(schema, options, encodingHint)\n\n if (input) {\n headers.set('content-type', input.encoding)\n } else if (encodingHint != null) {\n throw new TypeError(`Unexpected encoding hint (${encodingHint})`)\n }\n\n return {\n duplex: 'half',\n redirect: 'follow',\n referrerPolicy: 'strict-origin-when-cross-origin', // (default)\n mode: 'cors', // (default)\n signal: options.signal,\n method: 'POST',\n headers,\n body: input?.body,\n }\n }\n\n // Requests without body\n return {\n duplex: 'half',\n redirect: 'follow',\n referrerPolicy: 'strict-origin-when-cross-origin', // (default)\n mode: 'cors', // (default)\n signal: options.signal,\n method: 'GET',\n headers,\n }\n}\n\ntype XrpcProcedureInputOptions = {\n body?: LexValue | BinaryBodyInit\n validateRequest?: boolean\n}\n\nfunction xrpcProcedureInput(\n method: Procedure,\n options: XrpcProcedureInputOptions,\n encodingHint?: string,\n): null | { body: BodyInit; encoding: string } {\n const { input } = method\n const { body } = options\n\n if (options.validateRequest) {\n input.schema?.check(body)\n }\n\n // Special handling for endpoints expecting application/json input\n if (input.encoding === 'application/json') {\n // @NOTE **NOT** using isLexValue here to avoid deep checks in order to\n // distinguish between LexValue and BinaryBodyInit.\n if (!isLexScalar(body) && !isPlainObject(body) && !Array.isArray(body)) {\n throw new TypeError(`Expected LexValue body, got ${typeof body}`)\n }\n\n return buildPayload(input, lexStringify(body), encodingHint)\n }\n\n // Other encodings will be sent unaltered (ie. as binary data)\n switch (typeof body) {\n case 'undefined':\n case 'string':\n return buildPayload(input, body, encodingHint)\n case 'object': {\n if (body === null) break\n if (ArrayBuffer.isView(body)) {\n return buildPayload(input, asUint8ArrayArrayBuffer(body), encodingHint)\n } else if (\n body instanceof ArrayBuffer ||\n body instanceof ReadableStream\n ) {\n return buildPayload(input, body, encodingHint)\n } else if (isAsyncIterable(body)) {\n // @NOTE While fetch() does not allow SharedArrayBuffer-backed\n // Uint8Arrays as \"body\", it **does** allow using ReadableStreams made\n // of Uint8Arrays<SharedArrayBuffer> (tested on NodeJS 22) as \"body\".\n return buildPayload(input, toReadableStream(body), encodingHint)\n } else if (isBlobLike(body)) {\n return buildPayload(input, body, encodingHint || body.type)\n }\n }\n }\n\n throw new TypeError(\n `Invalid ${typeof body} body for ${input.encoding} encoding`,\n )\n}\n\nfunction buildPayload(\n schema: Payload,\n body: undefined | BodyInit,\n encodingHint?: string,\n): null | { body: BodyInit; encoding: string } {\n if (schema.encoding === undefined) {\n if (body !== undefined) {\n throw new TypeError(`Endpoint expects no payload`)\n }\n\n return null\n }\n\n if (body === undefined) {\n // This error would be returned by the server, but we can catch it earlier\n // to avoid un-necessary requests. Note that a content-length of 0 does not\n // necessary mean that the body is \"empty\" (e.g. an empty txt file).\n throw new TypeError(`A request body is expected but none was provided`)\n }\n\n const encoding = buildEncoding(schema, encodingHint)\n return { encoding, body }\n}\n\nfunction buildEncoding(schema: Payload, encodingHint?: string): string {\n // Should never happen (required for type safety)\n if (!schema.encoding) {\n throw new TypeError('Unexpected payload')\n }\n\n if (encodingHint?.length) {\n if (!schema.matchesEncoding(encodingHint)) {\n throw new TypeError(\n `Cannot send a body with content-type \"${encodingHint}\" for \"${schema.encoding}\" encoding`,\n )\n }\n return encodingHint\n }\n\n // Fallback\n\n if (schema.encoding === '*/*') {\n return 'application/octet-stream'\n }\n\n if (schema.encoding.startsWith('text/')) {\n return schema.encoding.includes('*')\n ? 'text/plain; charset=utf-8'\n : `${schema.encoding}; charset=utf-8`\n }\n\n if (!schema.encoding.includes('*')) {\n return schema.encoding\n }\n\n throw new TypeError(\n `Unable to determine payload encoding. Please provide a 'content-type' header matching ${schema.encoding}.`,\n )\n}\n\n/**\n * Extracts the root cause from an error, unwrapping common fetch-related errors\n * such as those from undici (Node's internal fetch implementation).\n *\n * @param err - The error to extract the root cause from\n * @returns The root cause error, or the original error if no specific pattern is matched\n * @remarks This is useful for getting more specific error information from fetch-related failures, especially in Node environments using undici.\n */\nexport function extractFetchErrorCause(err: unknown): unknown {\n // Unwrap the Network error from undici (i.e. Node's internal fetch() implementation)\n // https://github.com/nodejs/undici/blob/04cb77327f7ada95c2e5b67424cddcb22d7bf882/lib/web/fetch/index.js#L234-L239\n if (\n err instanceof TypeError &&\n err.message === 'fetch failed' &&\n err.cause !== undefined\n ) {\n return err.cause\n }\n\n // @TODO Add other unwrap patterns here as needed (e.g. for other fetch\n // implementations or common network libraries, like \"node:http\", or in other\n // environments like React Native, Deno, Bun, Browser, etc.)\n\n return err\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto/lex-client",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "engines": {
5
5
  "node": ">=22"
6
6
  },
@@ -36,14 +36,14 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "tslib": "^2.8.1",
39
- "@atproto/lex-data": "^0.1.0",
39
+ "@atproto/lex-data": "^0.1.1",
40
40
  "@atproto/lex-json": "^0.1.0",
41
- "@atproto/lex-schema": "^0.1.0"
41
+ "@atproto/lex-schema": "^0.1.1"
42
42
  },
43
43
  "devDependencies": {
44
44
  "vitest": "^4.0.16",
45
45
  "@atproto/lex-cbor": "^0.1.0",
46
- "@atproto/lex-builder": "^0.1.0"
46
+ "@atproto/lex-builder": "^0.1.1"
47
47
  },
48
48
  "scripts": {
49
49
  "prebuild": "node ./scripts/lex-build.mjs",
package/src/client.ts CHANGED
@@ -27,10 +27,21 @@ import {
27
27
  } from './response.js'
28
28
  import { BinaryBodyInit, Service } from './types.js'
29
29
  import {
30
+ RecordKeyOptions,
30
31
  XrpcRequestHeadersOptions,
31
32
  applyDefaults,
32
33
  buildXrpcRequestHeaders,
34
+ getDefaultRecordKey,
35
+ getLiteralRecordKey,
33
36
  } from './util.js'
37
+ import {
38
+ WriteOperation,
39
+ WriteOperationCreateOptions,
40
+ WriteOperationDeleteOptions,
41
+ WriteOperationHelper,
42
+ WriteOperationUpdateOptions,
43
+ WriteOperationsFactory,
44
+ } from './write-operation-builder.js'
34
45
  import {
35
46
  XrpcOptions,
36
47
  XrpcRequestParams,
@@ -39,25 +50,31 @@ import {
39
50
  xrpcSafe,
40
51
  } from './xrpc.js'
41
52
 
42
- export type {
43
- AtIdentifierString,
44
- CidString,
45
- DidString,
46
- Infer,
47
- InferMethodInputBody,
48
- InferMethodOutputBody,
49
- InferRecordKey,
50
- LexMap,
51
- LexValue,
52
- LexiconRecordKey,
53
- Main,
54
- NsidString,
55
- Params,
53
+ export {
54
+ type AtIdentifierString,
55
+ type CidString,
56
+ type DidString,
57
+ type Infer,
58
+ type InferMethodInputBody,
59
+ type InferMethodOutputBody,
60
+ type InferRecordKey,
61
+ type LexMap,
62
+ type LexValue,
63
+ type LexiconRecordKey,
64
+ type Main,
65
+ type NsidString,
66
+ type Params,
56
67
  Procedure,
57
68
  Query,
58
69
  RecordSchema,
59
- Restricted,
60
- TypedLexMap,
70
+ type Restricted,
71
+ type TypedLexMap,
72
+ type WriteOperation,
73
+ type WriteOperationCreateOptions,
74
+ type WriteOperationDeleteOptions,
75
+ WriteOperationHelper,
76
+ type WriteOperationUpdateOptions,
77
+ type WriteOperationsFactory,
61
78
  }
62
79
 
63
80
  /**
@@ -217,6 +234,23 @@ export type ListRecordsOptions = Omit<
217
234
  reverse?: boolean
218
235
  }
219
236
 
237
+ /**
238
+ * Options for applying a batch of writes (create/update/delete) to an AT Protocol repository.
239
+ *
240
+ * @see {@link Client.applyWrites}
241
+ */
242
+ export type ApplyWritesOptions = Omit<
243
+ XrpcOptions<typeof com.atproto.repo.applyWrites.main>,
244
+ 'body'
245
+ > & {
246
+ /** Repository identifier (DID or handle). Defaults to authenticated user's DID. */
247
+ repo?: AtIdentifierString
248
+ /** Whether the PDS should validate the records against their lexicon schemas. */
249
+ validate?: boolean
250
+ /** Compare-and-swap on the repo commit. If specified, must match current commit. */
251
+ swapCommit?: CidString
252
+ }
253
+
220
254
  export type UploadBlobOptions = Omit<
221
255
  XrpcOptions<typeof com.atproto.repo.uploadBlob.main>,
222
256
  'body'
@@ -227,13 +261,6 @@ export type GetBlobOptions = Omit<
227
261
  'params'
228
262
  >
229
263
 
230
- export type RecordKeyOptions<
231
- T extends RecordSchema,
232
- AlsoOptionalWhenRecordKeyIs extends LexiconRecordKey = never,
233
- > = T['key'] extends `literal:${string}` | AlsoOptionalWhenRecordKeyIs
234
- ? { rkey?: InferRecordKey<T> }
235
- : { rkey: InferRecordKey<T> }
236
-
237
264
  /**
238
265
  * Type-safe options for {@link Client.create}, combining record options with key requirements.
239
266
  * @typeParam T - The record schema type
@@ -699,6 +726,44 @@ export class Client implements Agent {
699
726
  })
700
727
  }
701
728
 
729
+ /**
730
+ * Performs an atomic batch of create, update, and delete operations on records in a repository.
731
+ *
732
+ * @param builder - A function that receives an {@link ApplyWritesOperations} instance to build the operations
733
+ * @param options - ApplyWrites options including repo, validate, swapCommit
734
+ * @returns The XRPC response from the applyWrites call
735
+ *
736
+ * @example
737
+ * ```typescript
738
+ * const response = await client.applyWrites((op) => [
739
+ * op.create(app.bsky.feed.post, { text: 'Hello!' }),
740
+ * op.update(app.bsky.feed.post, { text: 'Updated text' }, { rkey: 'post123' }),
741
+ * op.delete(app.bsky.feed.post, 'post456'),
742
+ * op.update(app.bsky.actor.profile, { displayName: 'Alice' }),
743
+ * ], {
744
+ * validate: true,
745
+ * })
746
+ *
747
+ * for (const result of response.body.results) {
748
+ * console.log(result.uri)
749
+ * }
750
+ * ```
751
+ */
752
+ async applyWrites(
753
+ factory: WriteOperationsFactory,
754
+ options?: ApplyWritesOptions,
755
+ ) {
756
+ return this.xrpc(com.atproto.repo.applyWrites, {
757
+ ...options,
758
+ body: {
759
+ repo: options?.repo ?? this.assertDid,
760
+ writes: WriteOperationHelper.build(factory),
761
+ validate: options?.validate,
762
+ swapCommit: options?.swapCommit,
763
+ },
764
+ })
765
+ }
766
+
702
767
  /**
703
768
  * Uploads a blob to an AT Protocol repository.
704
769
  *
@@ -1002,25 +1067,3 @@ export class Client implements Agent {
1002
1067
  return { ...body, records, invalid }
1003
1068
  }
1004
1069
  }
1005
-
1006
- function getDefaultRecordKey<const T extends RecordSchema>(
1007
- schema: T,
1008
- ): undefined | InferRecordKey<T> {
1009
- // Let the server generate the TID
1010
- if (schema.key === 'tid') return undefined
1011
- if (schema.key === 'any') return undefined
1012
-
1013
- return getLiteralRecordKey(schema)
1014
- }
1015
-
1016
- function getLiteralRecordKey<const T extends RecordSchema>(
1017
- schema: T,
1018
- ): InferRecordKey<T> {
1019
- if (schema.key.startsWith('literal:')) {
1020
- return schema.key.slice(8) as InferRecordKey<T>
1021
- }
1022
-
1023
- throw new TypeError(
1024
- `An "rkey" must be provided for record key type "${schema.key}" (${schema.$type})`,
1025
- )
1026
- }
@@ -0,0 +1,197 @@
1
+ /*
2
+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
3
+ */
4
+
5
+ import { l } from '@atproto/lex-schema'
6
+ import * as RepoDefs from './defs.defs.js'
7
+
8
+ const $nsid = 'com.atproto.repo.applyWrites'
9
+
10
+ export { $nsid }
11
+
12
+ export const $lxm = $nsid
13
+ export const $params = /*#__PURE__*/ l.params()
14
+ export const $input = /*#__PURE__*/ l.jsonPayload({
15
+ repo: /*#__PURE__*/ l.string({ format: 'at-identifier' }),
16
+ validate: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.boolean()),
17
+ writes: /*#__PURE__*/ l.array(
18
+ /*#__PURE__*/ l.typedUnion(
19
+ [
20
+ /*#__PURE__*/ l.typedRef<Create>((() => create) as any),
21
+ /*#__PURE__*/ l.typedRef<Update>((() => update) as any),
22
+ /*#__PURE__*/ l.typedRef<Delete$0>((() => delete$0) as any),
23
+ ],
24
+ true,
25
+ ),
26
+ ),
27
+ swapCommit: /*#__PURE__*/ l.optional(
28
+ /*#__PURE__*/ l.string({ format: 'cid' }),
29
+ ),
30
+ })
31
+ export const $output = /*#__PURE__*/ l.jsonPayload({
32
+ commit: /*#__PURE__*/ l.optional(
33
+ /*#__PURE__*/ l.ref<RepoDefs.CommitMeta>(
34
+ (() => RepoDefs.commitMeta) as any,
35
+ ),
36
+ ),
37
+ results: /*#__PURE__*/ l.optional(
38
+ /*#__PURE__*/ l.array(
39
+ /*#__PURE__*/ l.typedUnion(
40
+ [
41
+ /*#__PURE__*/ l.typedRef<CreateResult>((() => createResult) as any),
42
+ /*#__PURE__*/ l.typedRef<UpdateResult>((() => updateResult) as any),
43
+ /*#__PURE__*/ l.typedRef<DeleteResult>((() => deleteResult) as any),
44
+ ],
45
+ true,
46
+ ),
47
+ ),
48
+ ),
49
+ })
50
+ /** Apply a batch transaction of repository creates, updates, and deletes. Requires auth, implemented by PDS. */
51
+ const main = /*#__PURE__*/ l.procedure($nsid, $params, $input, $output, [
52
+ 'InvalidSwap',
53
+ ])
54
+
55
+ export { main }
56
+
57
+ export type $Params = l.InferMethodParams<typeof main>
58
+ export type $Input<B = l.BinaryData> = l.InferMethodInput<typeof main, B>
59
+ export type $InputBody<B = l.BinaryData> = l.InferMethodInputBody<
60
+ typeof main,
61
+ B
62
+ >
63
+ export type $Output<B = l.BinaryData> = l.InferMethodOutput<typeof main, B>
64
+ export type $OutputBody<B = l.BinaryData> = l.InferMethodOutputBody<
65
+ typeof main,
66
+ B
67
+ >
68
+ /** Operation which creates a new record. */
69
+ type Create = {
70
+ $type?: 'com.atproto.repo.applyWrites#create'
71
+ collection: l.NsidString
72
+
73
+ /**
74
+ * NOTE: maxLength is redundant with record-key format. Keeping it temporarily to ensure backwards compatibility.
75
+ */
76
+ rkey?: l.RecordKeyString
77
+ value: l.LexMap
78
+ }
79
+
80
+ export type { Create }
81
+
82
+ /** Operation which creates a new record. */
83
+ const create = /*#__PURE__*/ l.typedObject<Create>(
84
+ $nsid,
85
+ 'create',
86
+ /*#__PURE__*/ l.object({
87
+ collection: /*#__PURE__*/ l.string({ format: 'nsid' }),
88
+ rkey: /*#__PURE__*/ l.optional(
89
+ /*#__PURE__*/ l.string({ maxLength: 512, format: 'record-key' }),
90
+ ),
91
+ value: /*#__PURE__*/ l.lexMap(),
92
+ }),
93
+ )
94
+
95
+ export { create }
96
+
97
+ /** Operation which updates an existing record. */
98
+ type Update = {
99
+ $type?: 'com.atproto.repo.applyWrites#update'
100
+ collection: l.NsidString
101
+ rkey: l.RecordKeyString
102
+ value: l.LexMap
103
+ }
104
+
105
+ export type { Update }
106
+
107
+ /** Operation which updates an existing record. */
108
+ const update = /*#__PURE__*/ l.typedObject<Update>(
109
+ $nsid,
110
+ 'update',
111
+ /*#__PURE__*/ l.object({
112
+ collection: /*#__PURE__*/ l.string({ format: 'nsid' }),
113
+ rkey: /*#__PURE__*/ l.string({ format: 'record-key' }),
114
+ value: /*#__PURE__*/ l.lexMap(),
115
+ }),
116
+ )
117
+
118
+ export { update }
119
+
120
+ /** Operation which deletes an existing record. */
121
+ type Delete$0 = {
122
+ $type?: 'com.atproto.repo.applyWrites#delete'
123
+ collection: l.NsidString
124
+ rkey: l.RecordKeyString
125
+ }
126
+
127
+ export type { Delete$0 as Delete }
128
+
129
+ /** Operation which deletes an existing record. */
130
+ const delete$0 = /*#__PURE__*/ l.typedObject<Delete$0>(
131
+ $nsid,
132
+ 'delete',
133
+ /*#__PURE__*/ l.object({
134
+ collection: /*#__PURE__*/ l.string({ format: 'nsid' }),
135
+ rkey: /*#__PURE__*/ l.string({ format: 'record-key' }),
136
+ }),
137
+ )
138
+
139
+ export { delete$0 as 'delete' }
140
+
141
+ type CreateResult = {
142
+ $type?: 'com.atproto.repo.applyWrites#createResult'
143
+ uri: l.AtUriString
144
+ cid: l.CidString
145
+ validationStatus?: 'valid' | 'unknown' | l.UnknownString
146
+ }
147
+
148
+ export type { CreateResult }
149
+
150
+ const createResult = /*#__PURE__*/ l.typedObject<CreateResult>(
151
+ $nsid,
152
+ 'createResult',
153
+ /*#__PURE__*/ l.object({
154
+ uri: /*#__PURE__*/ l.string({ format: 'at-uri' }),
155
+ cid: /*#__PURE__*/ l.string({ format: 'cid' }),
156
+ validationStatus: /*#__PURE__*/ l.optional(
157
+ /*#__PURE__*/ l.string<{ knownValues: ['valid', 'unknown'] }>(),
158
+ ),
159
+ }),
160
+ )
161
+
162
+ export { createResult }
163
+
164
+ type UpdateResult = {
165
+ $type?: 'com.atproto.repo.applyWrites#updateResult'
166
+ uri: l.AtUriString
167
+ cid: l.CidString
168
+ validationStatus?: 'valid' | 'unknown' | l.UnknownString
169
+ }
170
+
171
+ export type { UpdateResult }
172
+
173
+ const updateResult = /*#__PURE__*/ l.typedObject<UpdateResult>(
174
+ $nsid,
175
+ 'updateResult',
176
+ /*#__PURE__*/ l.object({
177
+ uri: /*#__PURE__*/ l.string({ format: 'at-uri' }),
178
+ cid: /*#__PURE__*/ l.string({ format: 'cid' }),
179
+ validationStatus: /*#__PURE__*/ l.optional(
180
+ /*#__PURE__*/ l.string<{ knownValues: ['valid', 'unknown'] }>(),
181
+ ),
182
+ }),
183
+ )
184
+
185
+ export { updateResult }
186
+
187
+ type DeleteResult = { $type?: 'com.atproto.repo.applyWrites#deleteResult' }
188
+
189
+ export type { DeleteResult }
190
+
191
+ const deleteResult = /*#__PURE__*/ l.typedObject<DeleteResult>(
192
+ $nsid,
193
+ 'deleteResult',
194
+ /*#__PURE__*/ l.object({}),
195
+ )
196
+
197
+ export { deleteResult }
@@ -0,0 +1,6 @@
1
+ /*
2
+ * THIS FILE WAS GENERATED BY "@atproto/lex". DO NOT EDIT.
3
+ */
4
+
5
+ export * from './applyWrites.defs.js'
6
+ export * as $defs from './applyWrites.defs.js'
@@ -9,38 +9,37 @@ const $nsid = 'com.atproto.repo.createRecord'
9
9
 
10
10
  export { $nsid }
11
11
 
12
+ export const $lxm = $nsid
13
+ export const $params = /*#__PURE__*/ l.params()
14
+ export const $input = /*#__PURE__*/ l.jsonPayload({
15
+ repo: /*#__PURE__*/ l.string({ format: 'at-identifier' }),
16
+ collection: /*#__PURE__*/ l.string({ format: 'nsid' }),
17
+ rkey: /*#__PURE__*/ l.optional(
18
+ /*#__PURE__*/ l.string({ format: 'record-key', maxLength: 512 }),
19
+ ),
20
+ validate: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.boolean()),
21
+ record: /*#__PURE__*/ l.lexMap(),
22
+ swapCommit: /*#__PURE__*/ l.optional(
23
+ /*#__PURE__*/ l.string({ format: 'cid' }),
24
+ ),
25
+ })
26
+ export const $output = /*#__PURE__*/ l.jsonPayload({
27
+ uri: /*#__PURE__*/ l.string({ format: 'at-uri' }),
28
+ cid: /*#__PURE__*/ l.string({ format: 'cid' }),
29
+ commit: /*#__PURE__*/ l.optional(
30
+ /*#__PURE__*/ l.ref<RepoDefs.CommitMeta>(
31
+ (() => RepoDefs.commitMeta) as any,
32
+ ),
33
+ ),
34
+ validationStatus: /*#__PURE__*/ l.optional(
35
+ /*#__PURE__*/ l.string<{ knownValues: ['valid', 'unknown'] }>(),
36
+ ),
37
+ })
12
38
  /** Create a single new repository record. Requires auth, implemented by PDS. */
13
- const main =
14
- /*#__PURE__*/
15
- l.procedure(
16
- $nsid,
17
- /*#__PURE__*/ l.params(),
18
- /*#__PURE__*/ l.jsonPayload({
19
- repo: /*#__PURE__*/ l.string({ format: 'at-identifier' }),
20
- collection: /*#__PURE__*/ l.string({ format: 'nsid' }),
21
- rkey: /*#__PURE__*/ l.optional(
22
- /*#__PURE__*/ l.string({ format: 'record-key', maxLength: 512 }),
23
- ),
24
- validate: /*#__PURE__*/ l.optional(/*#__PURE__*/ l.boolean()),
25
- record: /*#__PURE__*/ l.lexMap(),
26
- swapCommit: /*#__PURE__*/ l.optional(
27
- /*#__PURE__*/ l.string({ format: 'cid' }),
28
- ),
29
- }),
30
- /*#__PURE__*/ l.jsonPayload({
31
- uri: /*#__PURE__*/ l.string({ format: 'at-uri' }),
32
- cid: /*#__PURE__*/ l.string({ format: 'cid' }),
33
- commit: /*#__PURE__*/ l.optional(
34
- /*#__PURE__*/ l.ref<RepoDefs.CommitMeta>(
35
- (() => RepoDefs.commitMeta) as any,
36
- ),
37
- ),
38
- validationStatus: /*#__PURE__*/ l.optional(
39
- /*#__PURE__*/ l.string<{ knownValues: ['valid', 'unknown'] }>(),
40
- ),
41
- }),
42
- ['InvalidSwap'],
43
- )
39
+ const main = /*#__PURE__*/ l.procedure($nsid, $params, $input, $output, [
40
+ 'InvalidSwap',
41
+ ])
42
+
44
43
  export { main }
45
44
 
46
45
  export type $Params = l.InferMethodParams<typeof main>
@@ -54,8 +53,3 @@ export type $OutputBody<B = l.BinaryData> = l.InferMethodOutputBody<
54
53
  typeof main,
55
54
  B
56
55
  >
57
-
58
- export const $lxm = /*#__PURE__*/ main.nsid,
59
- $params = /*#__PURE__*/ main.parameters,
60
- $input = /*#__PURE__*/ main.input,
61
- $output = /*#__PURE__*/ main.output