ts-ag 1.1.0 → 1.1.2
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.
- package/dist/browser.js +1 -1
- package/dist/browser.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
package/dist/browser.js
CHANGED
|
@@ -24,7 +24,7 @@ const queryMethods = ["GET", "DELETE"];
|
|
|
24
24
|
async function _apiRequest(path, method, input, schema, environment, apiUrl, headers) {
|
|
25
25
|
if (schema) if (schema.async === true) v.parseAsync(schema, input);
|
|
26
26
|
else v.parse(schema, input);
|
|
27
|
-
let url = `${apiUrl}${path}`;
|
|
27
|
+
let url = `${apiUrl}${apiUrl.endsWith("/") ? "" : "/"}${path}`;
|
|
28
28
|
if (queryMethods.includes(method)) {
|
|
29
29
|
const params = input ?? {};
|
|
30
30
|
const queryString = new URLSearchParams(Object.entries(params).reduce((acc, [key, value]) => {
|
package/dist/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","names":[],"sources":["../src/lambda/client-types.ts","../src/lambda/client.ts","../src/lambda/handlerUtils.ts","../src/rehype/flat-toc.ts","../src/utils/valibot.ts","../src/utils/object.ts"],"sourcesContent":["import type { ErrorBody, SuccessCode, ErrorCode } from './handlerUtils.js';\n\n// ----------------- Helpers ----------------------\n// Used to easily extract types from ApiEndpoints types\n\n/**\n * Extracts the requestInput type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiInput<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n E,\n { path: P; method: M }\n>['requestInput'];\n\n/**\n * Extracts the requestOutput type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiOutput<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n E,\n { path: P; method: M }\n>['requestOutput'];\n\n/**\n * Extracts the response type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiResponse<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n E,\n { path: P; method: M }\n>['response'];\n\n/**\n * Extracts the sucessful body type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiSuccessBody<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n Extract<E, { path: P; method: M }>['response'],\n { status: SuccessCode }\n>['json'] extends () => Promise<infer R>\n ? R\n : unknown;\n\n/**\n * Extracts the sucessful body type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiErrorBody<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n Extract<E, { path: P; method: M }>['response'],\n { status: ErrorCode }\n>['json'] extends () => Promise<infer R>\n ? R\n : unknown;\n\n/**\n * Converts a RawApiGatewayHandler response type to a fetch like response type.\n */\ntype ConvertToFetch<T> = T extends { statusCode: number; body: object; headers: object }\n ? { ok: T['statusCode'] extends SuccessCode ? true : false; json: () => Promise<T['body']>; status: T['statusCode'] }\n : T;\n\nexport type CleanResponse = Omit<Response, 'status' | 'ok' | 'json'>;\nexport type FetchResponse<T extends (...args: any) => any> = ConvertToFetch<Awaited<ReturnType<T>>> & CleanResponse;\n\n// ------------------------ Proper types ------------------\n// This is used by createApiRequest and createFormFunction\n\nexport const HTTPMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'] as const;\nexport type HTTPMethod = (typeof HTTPMethods)[number];\n\nexport type ApiEndpoints = {\n path: string;\n method: HTTPMethod;\n requestInput: Record<string, any> | null;\n requestOutput: object | null;\n response: FetchResponse<\n // This means we get better types\n () => Promise<\n | { headers: object; statusCode: SuccessCode; body: any }\n | { headers: object; statusCode: ErrorCode; body: ErrorBody }\n >\n >;\n};\n","// import { deserialize } from './deserializer.js';\nimport { parse } from 'devalue';\nimport * as v from 'valibot';\n\nimport type { ApiEndpoints, ApiInput, ApiResponse } from './client-types.js';\n\nconst bodyMethods = ['POST', 'PUT', 'PATCH'] as const;\nconst queryMethods = ['GET', 'DELETE'] as const;\n\nasync function _apiRequest<T = Response>(\n path: string,\n method: 'GET' | 'POST' | 'DELETE',\n input: object | null,\n schema: ApiSchema,\n // This was here because of the deserializer being different in prod\n environment: string | 'production',\n apiUrl: string,\n headers?: HeadersInit\n): Promise<T> {\n if (schema) {\n if (schema.async === true) v.parseAsync(schema, input);\n else v.parse(schema, input);\n }\n\n let url = `${apiUrl}${path}`;\n\n if (queryMethods.includes(method as any)) {\n const params = input ?? {};\n const queryString = new URLSearchParams(\n Object.entries(params).reduce(\n (acc, [key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((v) => (acc[key] = String(v)));\n } else {\n acc[key] = String(value);\n }\n return acc;\n },\n {} as Record<string, string>\n )\n ).toString();\n if (queryString) url += `?${queryString}`;\n }\n\n headers = { 'Content-Type': 'application/json', ...headers };\n const response = await fetch(url, {\n method,\n headers,\n // oxlint-disable-next-line\n body: bodyMethods.includes(method as any) ? JSON.stringify(input) : undefined,\n credentials: 'include'\n });\n const contentType = response.headers.get('content-type') ?? '';\n\n let retrieved: Promise<string> | false = false;\n response.json = async () => {\n if (retrieved === false) {\n retrieved = response.text();\n }\n\n if (contentType === 'application/devalue') {\n return await parse(await retrieved);\n } else {\n return JSON.parse(await retrieved);\n }\n };\n return response as unknown as T;\n}\n\nconst HTTPMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'] as const;\ntype HTTPMethod = (typeof HTTPMethods)[number];\n\nexport type ApiRequestFunction<API extends ApiEndpoints> = <\n Path extends API['path'],\n Method extends Extract<API, { path: Path }>['method']\n>(\n path: Path,\n method: Method,\n input: ApiInput<API, Path, Method>,\n headers?: HeadersInit\n) => Promise<ApiResponse<API, Path, Method>>;\n\nexport type ApiSchema = v.GenericSchema | v.GenericSchemaAsync;\n\n/**\n * @returns A function that can be used to make API requests with type safety\n * @example const clientApiRequest = createApiRequest<ApiEndpoints>();\n */\nexport function createApiRequest<API extends ApiEndpoints>(\n schemas: Partial<Record<API['path'], Partial<Record<HTTPMethod, ApiSchema>>>>,\n apiUrl: string,\n env: string\n): ApiRequestFunction<API> {\n return async function apiRequest(path, method, input, headers) {\n const schema = schemas[path]?.[method];\n if (schema === undefined) throw new Error('Schema is undefined in api request');\n\n // if (typeof schema === 'function') {\n // schema = schema();\n // }\n\n return _apiRequest<ApiResponse<API, typeof path, typeof method>>(\n path as string,\n method as 'GET' | 'POST',\n input,\n schema,\n env,\n apiUrl,\n headers\n );\n };\n}\n","import type { APIGatewayProxyResultV2, Context, APIGatewayProxyEventV2WithLambdaAuthorizer } from 'aws-lambda';\nimport { stringify } from 'devalue';\n\nexport type SuccessCode = 200 | 201 | 204;\nexport type ErrorCode = 400 | 401 | 403 | 404 | 409 | 500;\n\nexport type ErrorBody = { message: string; field?: { name: string; value: string } };\n\n/**\n * The error response for the lambda functions to return\n */\nexport type ErrorRawProxyResultV2 = {\n statusCode: ErrorCode;\n headers?: { [header: string]: string } | undefined;\n body?: ErrorBody;\n isBase64Encoded?: boolean | undefined;\n cookies?: string[] | undefined;\n};\n\nexport type OkRawProxyResultV2 = {\n statusCode: SuccessCode;\n headers?: { [header: string]: string } | undefined;\n body?: object | undefined;\n isBase64Encoded?: boolean | undefined;\n cookies?: string[] | undefined;\n};\n/**\n * A type for the raw proxy result - just using an object not a stirng for the body\n */\nexport type RawProxyResultV2 = ErrorRawProxyResultV2 | OkRawProxyResultV2;\n\n// The type of the handler returned from wrapHandler\nexport type APIGatewayHandler<E> = (event: E, context: Context) => Promise<APIGatewayProxyResultV2>;\n\n// The type of the handler passed into wrapHandler\nexport type RawApiGatewayHandler<E extends APIGatewayProxyEventV2WithLambdaAuthorizer<any>> = (\n event: E,\n context: Context\n) => Promise<RawProxyResultV2>;\n\n/**\n * Wraps a handler that returns the body as an object rather than a string.\n *\n * This means you can achieve proper type inference on your handler and have standardised serialisation\n *\n * @example\n```ts\nexport type AuthorizerContext = {\n details: JWTPayload;\n} | null;\n\nexport const wrapHandler = baseWrapHandler<APIGatewayProxyEventV2WithLambdaAuthorizer<AuthorizerContext>>\n\n*/\nexport function wrapHandler<E extends APIGatewayProxyEventV2WithLambdaAuthorizer<any>>(\n handler: RawApiGatewayHandler<E>\n): APIGatewayHandler<E> {\n return async (event: E, context: Context): Promise<APIGatewayProxyResultV2> => {\n const result = await handler(event, context);\n\n if (result.body) {\n const headers = new Headers(result.headers);\n headers.set('Content-Type', 'application/devalue');\n\n return { ...result, headers: Object.fromEntries(headers), body: stringify(result.body) };\n } else {\n return { ...result, body: undefined };\n }\n };\n}\n","import type { Root, RootContent, Element } from 'hast';\nimport rehypeParse from 'rehype-parse';\nimport type { Plugin } from 'unified';\nimport { unified } from 'unified';\nimport type { VFile } from 'vfile';\n\n/**\n * This rehype plugin extracts the headings from the markdown elements but also the raw elements.\n * So we get html headings in the TOC as well\n *\n * It sets the file.data.fm.toc to a flat map of the toc\n */\nexport const extractToc: Plugin<[], Root> = () => {\n return (tree: Root, file: VFile) => {\n const details = tree.children.flatMap(extractDetails);\n if (file.data.fm === undefined) file.data.fm = {};\n // @ts-expect-error its untyped but for svmdex it is there\n file.data.fm.toc = details;\n };\n};\nexport type Toc = TocEntry[];\nexport type TocEntry = { level: number; id: string; value: string };\n\nfunction extractDetails(content: RootContent | { type: 'raw'; value: string }): TocEntry[] {\n if (content.type === 'element' && content.tagName.startsWith('h') && 'id' in content.properties) {\n const value =\n content.children.length === 1 && content.children[0].type === 'text'\n ? content.children[0].value\n : (content.properties.id as string);\n\n return [{ level: parseInt(content.tagName.slice(1)), id: content.properties.id as string, value }];\n } else if (content.type === 'raw') {\n const parsed = parseRaw(content.value);\n return parsed.flatMap(extractDetails);\n }\n return [];\n}\n\n/**\n * Parses raw HTML and returns a flat array of all heading (h1-h6) elements as HAST nodes.\n */\nexport function parseRaw(raw: string): Element[] {\n // Parse the HTML string into a HAST Root node\n const tree = unified()\n .use(rehypeParse, { fragment: true }) // allow parsing HTML fragments\n .parse(raw) as Root;\n\n // Helper function to recursively find heading elements\n function collectHeadings(node: RootContent): Element[] {\n if (node.type === 'element' && /^h[1-6]$/.test(node.tagName)) {\n return [node];\n }\n // Check children recursively\n if ('children' in node && Array.isArray(node.children)) {\n return node.children.flatMap(collectHeadings);\n }\n return [];\n }\n\n // Flatten all headings found in the tree\n return tree.children.flatMap(collectHeadings);\n}\n","import type { GenericSchema, GenericSchemaAsync } from 'valibot';\n\nexport function isSchema(x: unknown): x is GenericSchema {\n return !!x && typeof x === 'object' && 'kind' in x && x['kind'] === 'schema';\n}\n\nexport function unwrap(schema: GenericSchema): GenericSchema {\n // Unwrap common wrappers that simply contain another schema under `wrapped`\n // optional | exactOptional | undefinedable | nullable | nullish | nonNullable | nonNullish | readonly | brand | description | metadata | title | flavor\n // Most of these share `{ type: string; wrapped: GenericSchema }`\n // Guarded unwrap to avoid infinite loops.\n let curr: any = schema as any;\n const seen = new Set<any>();\n while (curr && typeof curr === 'object' && !seen.has(curr) && 'wrapped' in curr && isSchema((curr as any).wrapped)) {\n seen.add(curr);\n curr = (curr as any).wrapped;\n }\n return curr as GenericSchema;\n}\n\nfunction isIntegerKey(s: string): boolean {\n // allow \"0\", \"01\" etc. to index tuples/arrays consistently\n return /^-?\\d+$/.test(s);\n}\n\nexport type GetSchemaByPathOptions = {\n /**\n * When a union/variant cannot be narrowed by the path segment,\n * choose index `preferOption` (default 0). Set to -1 to return undefined instead.\n */\n preferOption?: number;\n};\n\nexport function getSchemaByPath(\n root: GenericSchema | GenericSchemaAsync,\n path: string,\n opts: GetSchemaByPathOptions = {}\n): GenericSchema | undefined {\n if (!isSchema(root)) return undefined;\n if (!path) return root;\n\n const keys = path.split('.');\n let curr: GenericSchema | undefined = root;\n\n for (let i = 0; i < keys.length; i++) {\n if (!curr) return undefined;\n curr = unwrap(curr);\n const seg = keys[i];\n\n // Narrow by schema \"type\"\n const type = (curr as any).type as string | undefined;\n\n switch (type) {\n case 'object': {\n // ObjectSchema has `.entries`\n const entries = (curr as any).entries as Record<string, GenericSchema> | undefined;\n if (!entries) return undefined;\n curr = entries[seg];\n break;\n }\n\n case 'record': {\n // RecordSchema has `.value` for any key\n const value = (curr as any).value as GenericSchema | undefined;\n curr = value;\n break;\n }\n\n case 'array': {\n // ArraySchema has `.item`\n if (!isIntegerKey(seg)) return undefined;\n const item = (curr as any).item as GenericSchema | undefined;\n curr = item;\n break;\n }\n\n case 'tuple': {\n // TupleSchema has `.items` and possibly `.rest`\n if (!isIntegerKey(seg)) return undefined;\n const idx = Number(seg);\n const items = (curr as any).items as GenericSchema[] | undefined;\n const rest = (curr as any).rest as GenericSchema | undefined;\n if (!items) return undefined;\n curr = idx < items.length ? items[idx] : rest;\n break;\n }\n\n case 'union': {\n // UnionSchema has `.options` (array of schemas)\n const options = (curr as any).options as GenericSchema[] | undefined;\n if (!options?.length) return undefined;\n\n // Try to narrow by segment:\n // - if numeric seg: prefer array/tuple options\n // - if string seg: prefer object/record options that contain seg\n const numeric = isIntegerKey(seg);\n\n let next: GenericSchema | undefined;\n\n if (numeric) {\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n return u?.type === 'array' || u?.type === 'tuple';\n }) ?? options[opts.preferOption ?? 0];\n } else {\n // Prefer object/record with matching key\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n if (u?.type === 'object') {\n const ent = u.entries as Record<string, GenericSchema> | undefined;\n return !!ent && seg in ent;\n }\n return u?.type === 'record';\n }) ?? options[opts.preferOption ?? 0];\n }\n\n curr = next;\n // Loop continues to use seg against selected option\n i--; // reprocess this segment against the chosen branch\n break;\n }\n\n case 'variant': {\n // Variant (discriminated union) has `.options` too\n const options = (curr as any).options as GenericSchema[] | undefined;\n if (!options?.length) return undefined;\n // Same narrowing as union\n const numeric = isIntegerKey(seg);\n let next: GenericSchema | undefined;\n if (numeric) {\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n return u?.type === 'array' || u?.type === 'tuple';\n }) ?? options[opts.preferOption ?? 0];\n } else {\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n if (u?.type === 'object') {\n const ent = u.entries as Record<string, GenericSchema> | undefined;\n return !!ent && seg in ent;\n }\n return u?.type === 'record';\n }) ?? options[opts.preferOption ?? 0];\n }\n curr = next;\n i--;\n break;\n }\n\n default: {\n // If it’s a pipeline schema (`pipe`) or similar wrapper, many expose `.wrapped` and are handled by unwrap.\n // If we end up at a primitive or unknown structure while keys remain, fail.\n return undefined;\n }\n }\n }\n\n return curr ? unwrap(curr) : undefined;\n}\n","import { isEqual, isObject } from 'radash';\n\nimport type { DeepPartial } from '../types/deep.js';\n\n/**\n * Sets the value for an object by its dot path\n * @param obj - any object\n * @param path - the dot path eg. key1.0.1.key2\n * @param value - any value\n * @returns - the modified object\n */\nexport function setByPath<T extends object>(obj: T, path: string, value: any): T {\n const keys = path.split('.');\n let curr: any = obj;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const k = keys[i];\n const next = keys[i + 1];\n // handle array indices like '0'\n if (Number.isInteger(Number(next))) {\n curr[k] ??= [];\n } else {\n curr[k] ??= {};\n }\n curr = curr[k];\n }\n\n curr[keys[keys.length - 1]] = value;\n return obj;\n}\n\n/**\n * Gets the value from an object by its dot path\n * @param obj - any object\n * @param path - the dot path eg. key1.0.1.key2\n * @returns - the value at the given path or undefined\n */\nexport function getByPath<T extends object>(obj: T, path: string): any {\n if (!obj || typeof obj !== 'object') return undefined;\n const keys = path.split('.');\n let curr: any = obj;\n\n for (const k of keys) {\n if (curr == null) return undefined;\n curr = curr[k];\n }\n\n return curr;\n}\n\nconst isPlainRecord = (v: unknown): v is Record<string, unknown> => isObject(v) && !Array.isArray(v);\n\n/**\n * Returns a deep \"patch\" object containing only the fields from `b`\n * that are different from `a`.\n *\n * Behavior:\n * - Only keys from `b` can appear in the result.\n * - New keys in `b` are included.\n * - Changed primitive/array values are included as the value from `b`.\n * - For nested plain objects, it recurses and returns only the differing nested fields.\n * - Arrays are treated as atomic (if different, the whole array from `b` is returned).\n *\n * Typing:\n * - Output is `DeepPartial<B>` because only a subset of `b`'s shape is returned.\n *\n * @template A\n * @template B\n * @param {A} a - Base/original object (can be a different shape than `b`).\n * @param {B} b - Updated object; output keys come from this object.\n * @returns {DeepPartial<B>} Deep partial of `b` containing only differences vs `a`.\n */\nexport const deepDiff = <A extends object, B extends object>(a: A, b: B): DeepPartial<B> => {\n const out: Record<string, unknown> = {};\n\n for (const key of Object.keys(b) as Array<keyof B>) {\n const aVal = (a as any)?.[key];\n const bVal = (b as any)[key];\n\n if (!((key as any) in (a as any))) {\n out[key as any] = bVal;\n continue;\n }\n\n if (isPlainRecord(aVal) && isPlainRecord(bVal)) {\n const nested = deepDiff(aVal, bVal);\n if (Object.keys(nested as any).length) out[key as any] = nested;\n continue;\n }\n\n if (!isEqual(aVal, bVal)) out[key as any] = bVal;\n }\n\n return out as DeepPartial<B>;\n};\n\n/**\n * Deeply prunes `source` to match the *shape* of `shape`.\n *\n * Rules:\n * - Only keys that exist on `shape` are kept.\n * - Pruning is deep for nested plain objects.\n * - Arrays are supported by using the first element of `shape` as the element-shape.\n * - If `shape` is `[]`, returns `[]` (drops all elements).\n * - Primitive values are kept as-is (no type coercion) if the key exists in `shape`.\n * - If `shape` expects an object/array but `source` is not compatible, returns an empty object/array of that shape.\n *\n * @typeParam S - Source object type.\n * @typeParam Sh - Shape object type.\n * @param source - The object to prune.\n * @param shape - The object whose keys/structure are the allowlist.\n * @returns A new value derived from `source`, containing only fields present in `shape`, pruned deeply.\n *\n * @example\n * const source = { a: 1, b: { c: 2, d: 3 }, e: [ { x: 1, y: 2 }, { x: 3, y: 4 } ], z: 9 };\n * const shape = { a: 0, b: { c: 0 }, e: [ { x: 0 } ] };\n * // => { a: 1, b: { c: 2 }, e: [ { x: 1 }, { x: 3 } ] }\n * const out = pruneToShape(source, shape);\n */\nexport function pruneToShape<S, Sh>(source: S, shape: Sh): Sh {\n return pruneAny(source as unknown, shape as unknown) as Sh;\n\n function pruneAny(src: unknown, sh: unknown): unknown {\n // Arrays: use first element as the \"element shape\"\n if (Array.isArray(sh)) {\n if (!Array.isArray(src)) return [];\n if (sh.length === 0) return [];\n const elemShape = sh[0];\n return src.map((v) => pruneAny(v, elemShape));\n }\n\n // Plain objects: keep only keys present on shape, recursively.\n if (isPlainObject(sh)) {\n const out: Record<string, unknown> = {};\n const srcObj = isPlainObject(src) ? (src as Record<string, unknown>) : undefined;\n\n for (const key of Object.keys(sh as Record<string, unknown>)) {\n const shVal = (sh as Record<string, unknown>)[key];\n const srcVal = srcObj ? srcObj[key] : undefined;\n\n if (Array.isArray(shVal) || isPlainObject(shVal)) {\n out[key] = pruneAny(srcVal, shVal);\n } else {\n // Primitive (or function/date/etc in shape): key exists => keep source value as-is\n out[key] = srcVal;\n }\n }\n return out;\n }\n\n // Non-object shape => allowed leaf; just return source leaf as-is.\n return src;\n }\n\n function isPlainObject(v: unknown): v is Record<string, unknown> {\n if (v === null || typeof v !== 'object') return false;\n const proto = Object.getPrototypeOf(v);\n return proto === Object.prototype || proto === null;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"browser.js","names":[],"sources":["../src/lambda/client-types.ts","../src/lambda/client.ts","../src/lambda/handlerUtils.ts","../src/rehype/flat-toc.ts","../src/utils/valibot.ts","../src/utils/object.ts"],"sourcesContent":["import type { ErrorBody, SuccessCode, ErrorCode } from './handlerUtils.js';\n\n// ----------------- Helpers ----------------------\n// Used to easily extract types from ApiEndpoints types\n\n/**\n * Extracts the requestInput type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiInput<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n E,\n { path: P; method: M }\n>['requestInput'];\n\n/**\n * Extracts the requestOutput type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiOutput<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n E,\n { path: P; method: M }\n>['requestOutput'];\n\n/**\n * Extracts the response type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiResponse<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n E,\n { path: P; method: M }\n>['response'];\n\n/**\n * Extracts the sucessful body type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiSuccessBody<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n Extract<E, { path: P; method: M }>['response'],\n { status: SuccessCode }\n>['json'] extends () => Promise<infer R>\n ? R\n : unknown;\n\n/**\n * Extracts the sucessful body type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiErrorBody<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n Extract<E, { path: P; method: M }>['response'],\n { status: ErrorCode }\n>['json'] extends () => Promise<infer R>\n ? R\n : unknown;\n\n/**\n * Converts a RawApiGatewayHandler response type to a fetch like response type.\n */\ntype ConvertToFetch<T> = T extends { statusCode: number; body: object; headers: object }\n ? { ok: T['statusCode'] extends SuccessCode ? true : false; json: () => Promise<T['body']>; status: T['statusCode'] }\n : T;\n\nexport type CleanResponse = Omit<Response, 'status' | 'ok' | 'json'>;\nexport type FetchResponse<T extends (...args: any) => any> = ConvertToFetch<Awaited<ReturnType<T>>> & CleanResponse;\n\n// ------------------------ Proper types ------------------\n// This is used by createApiRequest and createFormFunction\n\nexport const HTTPMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'] as const;\nexport type HTTPMethod = (typeof HTTPMethods)[number];\n\nexport type ApiEndpoints = {\n path: string;\n method: HTTPMethod;\n requestInput: Record<string, any> | null;\n requestOutput: object | null;\n response: FetchResponse<\n // This means we get better types\n () => Promise<\n | { headers: object; statusCode: SuccessCode; body: any }\n | { headers: object; statusCode: ErrorCode; body: ErrorBody }\n >\n >;\n};\n","// import { deserialize } from './deserializer.js';\nimport { parse } from 'devalue';\nimport * as v from 'valibot';\n\nimport type { ApiEndpoints, ApiInput, ApiResponse } from './client-types.js';\n\nconst bodyMethods = ['POST', 'PUT', 'PATCH'] as const;\nconst queryMethods = ['GET', 'DELETE'] as const;\n\nasync function _apiRequest<T = Response>(\n path: string,\n method: 'GET' | 'POST' | 'DELETE',\n input: object | null,\n schema: ApiSchema,\n // This was here because of the deserializer being different in prod\n environment: string | 'production',\n apiUrl: string,\n headers?: HeadersInit\n): Promise<T> {\n if (schema) {\n if (schema.async === true) v.parseAsync(schema, input);\n else v.parse(schema, input);\n }\n\n let url = `${apiUrl}${apiUrl.endsWith('/') ? '' : '/'}${path}`;\n\n if (queryMethods.includes(method as any)) {\n const params = input ?? {};\n const queryString = new URLSearchParams(\n Object.entries(params).reduce(\n (acc, [key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((v) => (acc[key] = String(v)));\n } else {\n acc[key] = String(value);\n }\n return acc;\n },\n {} as Record<string, string>\n )\n ).toString();\n if (queryString) url += `?${queryString}`;\n }\n\n headers = { 'Content-Type': 'application/json', ...headers };\n const response = await fetch(url, {\n method,\n headers,\n // oxlint-disable-next-line\n body: bodyMethods.includes(method as any) ? JSON.stringify(input) : undefined,\n credentials: 'include'\n });\n const contentType = response.headers.get('content-type') ?? '';\n\n let retrieved: Promise<string> | false = false;\n response.json = async () => {\n if (retrieved === false) {\n retrieved = response.text();\n }\n\n if (contentType === 'application/devalue') {\n return await parse(await retrieved);\n } else {\n return JSON.parse(await retrieved);\n }\n };\n return response as unknown as T;\n}\n\nconst HTTPMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'] as const;\ntype HTTPMethod = (typeof HTTPMethods)[number];\n\nexport type ApiRequestFunction<API extends ApiEndpoints> = <\n Path extends API['path'],\n Method extends Extract<API, { path: Path }>['method']\n>(\n path: Path,\n method: Method,\n input: ApiInput<API, Path, Method>,\n headers?: HeadersInit\n) => Promise<ApiResponse<API, Path, Method>>;\n\nexport type ApiSchema = v.GenericSchema | v.GenericSchemaAsync;\n\n/**\n * @returns A function that can be used to make API requests with type safety\n * @example const clientApiRequest = createApiRequest<ApiEndpoints>();\n */\nexport function createApiRequest<API extends ApiEndpoints>(\n schemas: Partial<Record<API['path'], Partial<Record<HTTPMethod, ApiSchema>>>>,\n apiUrl: string,\n env: string\n): ApiRequestFunction<API> {\n return async function apiRequest(path, method, input, headers) {\n const schema = schemas[path]?.[method];\n if (schema === undefined) throw new Error('Schema is undefined in api request');\n\n // if (typeof schema === 'function') {\n // schema = schema();\n // }\n\n return _apiRequest<ApiResponse<API, typeof path, typeof method>>(\n path as string,\n method as 'GET' | 'POST',\n input,\n schema,\n env,\n apiUrl,\n headers\n );\n };\n}\n","import type { APIGatewayProxyResultV2, Context, APIGatewayProxyEventV2WithLambdaAuthorizer } from 'aws-lambda';\nimport { stringify } from 'devalue';\n\nexport type SuccessCode = 200 | 201 | 204;\nexport type ErrorCode = 400 | 401 | 403 | 404 | 409 | 500;\n\nexport type ErrorBody = { message: string; field?: { name: string; value: string } };\n\n/**\n * The error response for the lambda functions to return\n */\nexport type ErrorRawProxyResultV2 = {\n statusCode: ErrorCode;\n headers?: { [header: string]: string } | undefined;\n body?: ErrorBody;\n isBase64Encoded?: boolean | undefined;\n cookies?: string[] | undefined;\n};\n\nexport type OkRawProxyResultV2 = {\n statusCode: SuccessCode;\n headers?: { [header: string]: string } | undefined;\n body?: object | undefined;\n isBase64Encoded?: boolean | undefined;\n cookies?: string[] | undefined;\n};\n/**\n * A type for the raw proxy result - just using an object not a stirng for the body\n */\nexport type RawProxyResultV2 = ErrorRawProxyResultV2 | OkRawProxyResultV2;\n\n// The type of the handler returned from wrapHandler\nexport type APIGatewayHandler<E> = (event: E, context: Context) => Promise<APIGatewayProxyResultV2>;\n\n// The type of the handler passed into wrapHandler\nexport type RawApiGatewayHandler<E extends APIGatewayProxyEventV2WithLambdaAuthorizer<any>> = (\n event: E,\n context: Context\n) => Promise<RawProxyResultV2>;\n\n/**\n * Wraps a handler that returns the body as an object rather than a string.\n *\n * This means you can achieve proper type inference on your handler and have standardised serialisation\n *\n * @example\n```ts\nexport type AuthorizerContext = {\n details: JWTPayload;\n} | null;\n\nexport const wrapHandler = baseWrapHandler<APIGatewayProxyEventV2WithLambdaAuthorizer<AuthorizerContext>>\n\n*/\nexport function wrapHandler<E extends APIGatewayProxyEventV2WithLambdaAuthorizer<any>>(\n handler: RawApiGatewayHandler<E>\n): APIGatewayHandler<E> {\n return async (event: E, context: Context): Promise<APIGatewayProxyResultV2> => {\n const result = await handler(event, context);\n\n if (result.body) {\n const headers = new Headers(result.headers);\n headers.set('Content-Type', 'application/devalue');\n\n return { ...result, headers: Object.fromEntries(headers), body: stringify(result.body) };\n } else {\n return { ...result, body: undefined };\n }\n };\n}\n","import type { Root, RootContent, Element } from 'hast';\nimport rehypeParse from 'rehype-parse';\nimport type { Plugin } from 'unified';\nimport { unified } from 'unified';\nimport type { VFile } from 'vfile';\n\n/**\n * This rehype plugin extracts the headings from the markdown elements but also the raw elements.\n * So we get html headings in the TOC as well\n *\n * It sets the file.data.fm.toc to a flat map of the toc\n */\nexport const extractToc: Plugin<[], Root> = () => {\n return (tree: Root, file: VFile) => {\n const details = tree.children.flatMap(extractDetails);\n if (file.data.fm === undefined) file.data.fm = {};\n // @ts-expect-error its untyped but for svmdex it is there\n file.data.fm.toc = details;\n };\n};\nexport type Toc = TocEntry[];\nexport type TocEntry = { level: number; id: string; value: string };\n\nfunction extractDetails(content: RootContent | { type: 'raw'; value: string }): TocEntry[] {\n if (content.type === 'element' && content.tagName.startsWith('h') && 'id' in content.properties) {\n const value =\n content.children.length === 1 && content.children[0].type === 'text'\n ? content.children[0].value\n : (content.properties.id as string);\n\n return [{ level: parseInt(content.tagName.slice(1)), id: content.properties.id as string, value }];\n } else if (content.type === 'raw') {\n const parsed = parseRaw(content.value);\n return parsed.flatMap(extractDetails);\n }\n return [];\n}\n\n/**\n * Parses raw HTML and returns a flat array of all heading (h1-h6) elements as HAST nodes.\n */\nexport function parseRaw(raw: string): Element[] {\n // Parse the HTML string into a HAST Root node\n const tree = unified()\n .use(rehypeParse, { fragment: true }) // allow parsing HTML fragments\n .parse(raw) as Root;\n\n // Helper function to recursively find heading elements\n function collectHeadings(node: RootContent): Element[] {\n if (node.type === 'element' && /^h[1-6]$/.test(node.tagName)) {\n return [node];\n }\n // Check children recursively\n if ('children' in node && Array.isArray(node.children)) {\n return node.children.flatMap(collectHeadings);\n }\n return [];\n }\n\n // Flatten all headings found in the tree\n return tree.children.flatMap(collectHeadings);\n}\n","import type { GenericSchema, GenericSchemaAsync } from 'valibot';\n\nexport function isSchema(x: unknown): x is GenericSchema {\n return !!x && typeof x === 'object' && 'kind' in x && x['kind'] === 'schema';\n}\n\nexport function unwrap(schema: GenericSchema): GenericSchema {\n // Unwrap common wrappers that simply contain another schema under `wrapped`\n // optional | exactOptional | undefinedable | nullable | nullish | nonNullable | nonNullish | readonly | brand | description | metadata | title | flavor\n // Most of these share `{ type: string; wrapped: GenericSchema }`\n // Guarded unwrap to avoid infinite loops.\n let curr: any = schema as any;\n const seen = new Set<any>();\n while (curr && typeof curr === 'object' && !seen.has(curr) && 'wrapped' in curr && isSchema((curr as any).wrapped)) {\n seen.add(curr);\n curr = (curr as any).wrapped;\n }\n return curr as GenericSchema;\n}\n\nfunction isIntegerKey(s: string): boolean {\n // allow \"0\", \"01\" etc. to index tuples/arrays consistently\n return /^-?\\d+$/.test(s);\n}\n\nexport type GetSchemaByPathOptions = {\n /**\n * When a union/variant cannot be narrowed by the path segment,\n * choose index `preferOption` (default 0). Set to -1 to return undefined instead.\n */\n preferOption?: number;\n};\n\nexport function getSchemaByPath(\n root: GenericSchema | GenericSchemaAsync,\n path: string,\n opts: GetSchemaByPathOptions = {}\n): GenericSchema | undefined {\n if (!isSchema(root)) return undefined;\n if (!path) return root;\n\n const keys = path.split('.');\n let curr: GenericSchema | undefined = root;\n\n for (let i = 0; i < keys.length; i++) {\n if (!curr) return undefined;\n curr = unwrap(curr);\n const seg = keys[i];\n\n // Narrow by schema \"type\"\n const type = (curr as any).type as string | undefined;\n\n switch (type) {\n case 'object': {\n // ObjectSchema has `.entries`\n const entries = (curr as any).entries as Record<string, GenericSchema> | undefined;\n if (!entries) return undefined;\n curr = entries[seg];\n break;\n }\n\n case 'record': {\n // RecordSchema has `.value` for any key\n const value = (curr as any).value as GenericSchema | undefined;\n curr = value;\n break;\n }\n\n case 'array': {\n // ArraySchema has `.item`\n if (!isIntegerKey(seg)) return undefined;\n const item = (curr as any).item as GenericSchema | undefined;\n curr = item;\n break;\n }\n\n case 'tuple': {\n // TupleSchema has `.items` and possibly `.rest`\n if (!isIntegerKey(seg)) return undefined;\n const idx = Number(seg);\n const items = (curr as any).items as GenericSchema[] | undefined;\n const rest = (curr as any).rest as GenericSchema | undefined;\n if (!items) return undefined;\n curr = idx < items.length ? items[idx] : rest;\n break;\n }\n\n case 'union': {\n // UnionSchema has `.options` (array of schemas)\n const options = (curr as any).options as GenericSchema[] | undefined;\n if (!options?.length) return undefined;\n\n // Try to narrow by segment:\n // - if numeric seg: prefer array/tuple options\n // - if string seg: prefer object/record options that contain seg\n const numeric = isIntegerKey(seg);\n\n let next: GenericSchema | undefined;\n\n if (numeric) {\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n return u?.type === 'array' || u?.type === 'tuple';\n }) ?? options[opts.preferOption ?? 0];\n } else {\n // Prefer object/record with matching key\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n if (u?.type === 'object') {\n const ent = u.entries as Record<string, GenericSchema> | undefined;\n return !!ent && seg in ent;\n }\n return u?.type === 'record';\n }) ?? options[opts.preferOption ?? 0];\n }\n\n curr = next;\n // Loop continues to use seg against selected option\n i--; // reprocess this segment against the chosen branch\n break;\n }\n\n case 'variant': {\n // Variant (discriminated union) has `.options` too\n const options = (curr as any).options as GenericSchema[] | undefined;\n if (!options?.length) return undefined;\n // Same narrowing as union\n const numeric = isIntegerKey(seg);\n let next: GenericSchema | undefined;\n if (numeric) {\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n return u?.type === 'array' || u?.type === 'tuple';\n }) ?? options[opts.preferOption ?? 0];\n } else {\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n if (u?.type === 'object') {\n const ent = u.entries as Record<string, GenericSchema> | undefined;\n return !!ent && seg in ent;\n }\n return u?.type === 'record';\n }) ?? options[opts.preferOption ?? 0];\n }\n curr = next;\n i--;\n break;\n }\n\n default: {\n // If it’s a pipeline schema (`pipe`) or similar wrapper, many expose `.wrapped` and are handled by unwrap.\n // If we end up at a primitive or unknown structure while keys remain, fail.\n return undefined;\n }\n }\n }\n\n return curr ? unwrap(curr) : undefined;\n}\n","import { isEqual, isObject } from 'radash';\n\nimport type { DeepPartial } from '../types/deep.js';\n\n/**\n * Sets the value for an object by its dot path\n * @param obj - any object\n * @param path - the dot path eg. key1.0.1.key2\n * @param value - any value\n * @returns - the modified object\n */\nexport function setByPath<T extends object>(obj: T, path: string, value: any): T {\n const keys = path.split('.');\n let curr: any = obj;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const k = keys[i];\n const next = keys[i + 1];\n // handle array indices like '0'\n if (Number.isInteger(Number(next))) {\n curr[k] ??= [];\n } else {\n curr[k] ??= {};\n }\n curr = curr[k];\n }\n\n curr[keys[keys.length - 1]] = value;\n return obj;\n}\n\n/**\n * Gets the value from an object by its dot path\n * @param obj - any object\n * @param path - the dot path eg. key1.0.1.key2\n * @returns - the value at the given path or undefined\n */\nexport function getByPath<T extends object>(obj: T, path: string): any {\n if (!obj || typeof obj !== 'object') return undefined;\n const keys = path.split('.');\n let curr: any = obj;\n\n for (const k of keys) {\n if (curr == null) return undefined;\n curr = curr[k];\n }\n\n return curr;\n}\n\nconst isPlainRecord = (v: unknown): v is Record<string, unknown> => isObject(v) && !Array.isArray(v);\n\n/**\n * Returns a deep \"patch\" object containing only the fields from `b`\n * that are different from `a`.\n *\n * Behavior:\n * - Only keys from `b` can appear in the result.\n * - New keys in `b` are included.\n * - Changed primitive/array values are included as the value from `b`.\n * - For nested plain objects, it recurses and returns only the differing nested fields.\n * - Arrays are treated as atomic (if different, the whole array from `b` is returned).\n *\n * Typing:\n * - Output is `DeepPartial<B>` because only a subset of `b`'s shape is returned.\n *\n * @template A\n * @template B\n * @param {A} a - Base/original object (can be a different shape than `b`).\n * @param {B} b - Updated object; output keys come from this object.\n * @returns {DeepPartial<B>} Deep partial of `b` containing only differences vs `a`.\n */\nexport const deepDiff = <A extends object, B extends object>(a: A, b: B): DeepPartial<B> => {\n const out: Record<string, unknown> = {};\n\n for (const key of Object.keys(b) as Array<keyof B>) {\n const aVal = (a as any)?.[key];\n const bVal = (b as any)[key];\n\n if (!((key as any) in (a as any))) {\n out[key as any] = bVal;\n continue;\n }\n\n if (isPlainRecord(aVal) && isPlainRecord(bVal)) {\n const nested = deepDiff(aVal, bVal);\n if (Object.keys(nested as any).length) out[key as any] = nested;\n continue;\n }\n\n if (!isEqual(aVal, bVal)) out[key as any] = bVal;\n }\n\n return out as DeepPartial<B>;\n};\n\n/**\n * Deeply prunes `source` to match the *shape* of `shape`.\n *\n * Rules:\n * - Only keys that exist on `shape` are kept.\n * - Pruning is deep for nested plain objects.\n * - Arrays are supported by using the first element of `shape` as the element-shape.\n * - If `shape` is `[]`, returns `[]` (drops all elements).\n * - Primitive values are kept as-is (no type coercion) if the key exists in `shape`.\n * - If `shape` expects an object/array but `source` is not compatible, returns an empty object/array of that shape.\n *\n * @typeParam S - Source object type.\n * @typeParam Sh - Shape object type.\n * @param source - The object to prune.\n * @param shape - The object whose keys/structure are the allowlist.\n * @returns A new value derived from `source`, containing only fields present in `shape`, pruned deeply.\n *\n * @example\n * const source = { a: 1, b: { c: 2, d: 3 }, e: [ { x: 1, y: 2 }, { x: 3, y: 4 } ], z: 9 };\n * const shape = { a: 0, b: { c: 0 }, e: [ { x: 0 } ] };\n * // => { a: 1, b: { c: 2 }, e: [ { x: 1 }, { x: 3 } ] }\n * const out = pruneToShape(source, shape);\n */\nexport function pruneToShape<S, Sh>(source: S, shape: Sh): Sh {\n return pruneAny(source as unknown, shape as unknown) as Sh;\n\n function pruneAny(src: unknown, sh: unknown): unknown {\n // Arrays: use first element as the \"element shape\"\n if (Array.isArray(sh)) {\n if (!Array.isArray(src)) return [];\n if (sh.length === 0) return [];\n const elemShape = sh[0];\n return src.map((v) => pruneAny(v, elemShape));\n }\n\n // Plain objects: keep only keys present on shape, recursively.\n if (isPlainObject(sh)) {\n const out: Record<string, unknown> = {};\n const srcObj = isPlainObject(src) ? (src as Record<string, unknown>) : undefined;\n\n for (const key of Object.keys(sh as Record<string, unknown>)) {\n const shVal = (sh as Record<string, unknown>)[key];\n const srcVal = srcObj ? srcObj[key] : undefined;\n\n if (Array.isArray(shVal) || isPlainObject(shVal)) {\n out[key] = pruneAny(srcVal, shVal);\n } else {\n // Primitive (or function/date/etc in shape): key exists => keep source value as-is\n out[key] = srcVal;\n }\n }\n return out;\n }\n\n // Non-object shape => allowed leaf; just return source leaf as-is.\n return src;\n }\n\n function isPlainObject(v: unknown): v is Record<string, unknown> {\n if (v === null || typeof v !== 'object') return false;\n const proto = Object.getPrototypeOf(v);\n return proto === Object.prototype || proto === null;\n }\n}\n"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -34,7 +34,7 @@ const queryMethods = ["GET", "DELETE"];
|
|
|
34
34
|
async function _apiRequest(path, method, input, schema, environment, apiUrl, headers) {
|
|
35
35
|
if (schema) if (schema.async === true) v.parseAsync(schema, input);
|
|
36
36
|
else v.parse(schema, input);
|
|
37
|
-
let url = `${apiUrl}${path}`;
|
|
37
|
+
let url = `${apiUrl}${apiUrl.endsWith("/") ? "" : "/"}${path}`;
|
|
38
38
|
if (queryMethods.includes(method)) {
|
|
39
39
|
const params = input ?? {};
|
|
40
40
|
const queryString = new URLSearchParams(Object.entries(params).reduce((acc, [key, value]) => {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["parse","baseGetSignedUrl"],"sources":["../src/lambda/client-types.ts","../src/lambda/client.ts","../src/lambda/handlerUtils.ts","../src/lambda/errors.ts","../src/lambda/response.ts","../src/lambda/server/authentication.ts","../src/cognito/client.ts","../src/cognito/errors.ts","../src/cognito/user.ts","../src/cognito/password.ts","../src/s3/client.ts","../src/s3/errors.ts","../src/s3/signedUrl.ts","../src/s3/object.ts","../src/dynamo/errors.ts","../src/ses/errors.ts","../src/rehype/flat-toc.ts","../src/utils/valibot.ts","../src/utils/object.ts","../src/utils/fs.ts"],"sourcesContent":["import type { ErrorBody, SuccessCode, ErrorCode } from './handlerUtils.js';\n\n// ----------------- Helpers ----------------------\n// Used to easily extract types from ApiEndpoints types\n\n/**\n * Extracts the requestInput type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiInput<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n E,\n { path: P; method: M }\n>['requestInput'];\n\n/**\n * Extracts the requestOutput type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiOutput<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n E,\n { path: P; method: M }\n>['requestOutput'];\n\n/**\n * Extracts the response type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiResponse<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n E,\n { path: P; method: M }\n>['response'];\n\n/**\n * Extracts the sucessful body type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiSuccessBody<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n Extract<E, { path: P; method: M }>['response'],\n { status: SuccessCode }\n>['json'] extends () => Promise<infer R>\n ? R\n : unknown;\n\n/**\n * Extracts the sucessful body type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiErrorBody<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n Extract<E, { path: P; method: M }>['response'],\n { status: ErrorCode }\n>['json'] extends () => Promise<infer R>\n ? R\n : unknown;\n\n/**\n * Converts a RawApiGatewayHandler response type to a fetch like response type.\n */\ntype ConvertToFetch<T> = T extends { statusCode: number; body: object; headers: object }\n ? { ok: T['statusCode'] extends SuccessCode ? true : false; json: () => Promise<T['body']>; status: T['statusCode'] }\n : T;\n\nexport type CleanResponse = Omit<Response, 'status' | 'ok' | 'json'>;\nexport type FetchResponse<T extends (...args: any) => any> = ConvertToFetch<Awaited<ReturnType<T>>> & CleanResponse;\n\n// ------------------------ Proper types ------------------\n// This is used by createApiRequest and createFormFunction\n\nexport const HTTPMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'] as const;\nexport type HTTPMethod = (typeof HTTPMethods)[number];\n\nexport type ApiEndpoints = {\n path: string;\n method: HTTPMethod;\n requestInput: Record<string, any> | null;\n requestOutput: object | null;\n response: FetchResponse<\n // This means we get better types\n () => Promise<\n | { headers: object; statusCode: SuccessCode; body: any }\n | { headers: object; statusCode: ErrorCode; body: ErrorBody }\n >\n >;\n};\n","// import { deserialize } from './deserializer.js';\nimport { parse } from 'devalue';\nimport * as v from 'valibot';\n\nimport type { ApiEndpoints, ApiInput, ApiResponse } from './client-types.js';\n\nconst bodyMethods = ['POST', 'PUT', 'PATCH'] as const;\nconst queryMethods = ['GET', 'DELETE'] as const;\n\nasync function _apiRequest<T = Response>(\n path: string,\n method: 'GET' | 'POST' | 'DELETE',\n input: object | null,\n schema: ApiSchema,\n // This was here because of the deserializer being different in prod\n environment: string | 'production',\n apiUrl: string,\n headers?: HeadersInit\n): Promise<T> {\n if (schema) {\n if (schema.async === true) v.parseAsync(schema, input);\n else v.parse(schema, input);\n }\n\n let url = `${apiUrl}${path}`;\n\n if (queryMethods.includes(method as any)) {\n const params = input ?? {};\n const queryString = new URLSearchParams(\n Object.entries(params).reduce(\n (acc, [key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((v) => (acc[key] = String(v)));\n } else {\n acc[key] = String(value);\n }\n return acc;\n },\n {} as Record<string, string>\n )\n ).toString();\n if (queryString) url += `?${queryString}`;\n }\n\n headers = { 'Content-Type': 'application/json', ...headers };\n const response = await fetch(url, {\n method,\n headers,\n // oxlint-disable-next-line\n body: bodyMethods.includes(method as any) ? JSON.stringify(input) : undefined,\n credentials: 'include'\n });\n const contentType = response.headers.get('content-type') ?? '';\n\n let retrieved: Promise<string> | false = false;\n response.json = async () => {\n if (retrieved === false) {\n retrieved = response.text();\n }\n\n if (contentType === 'application/devalue') {\n return await parse(await retrieved);\n } else {\n return JSON.parse(await retrieved);\n }\n };\n return response as unknown as T;\n}\n\nconst HTTPMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'] as const;\ntype HTTPMethod = (typeof HTTPMethods)[number];\n\nexport type ApiRequestFunction<API extends ApiEndpoints> = <\n Path extends API['path'],\n Method extends Extract<API, { path: Path }>['method']\n>(\n path: Path,\n method: Method,\n input: ApiInput<API, Path, Method>,\n headers?: HeadersInit\n) => Promise<ApiResponse<API, Path, Method>>;\n\nexport type ApiSchema = v.GenericSchema | v.GenericSchemaAsync;\n\n/**\n * @returns A function that can be used to make API requests with type safety\n * @example const clientApiRequest = createApiRequest<ApiEndpoints>();\n */\nexport function createApiRequest<API extends ApiEndpoints>(\n schemas: Partial<Record<API['path'], Partial<Record<HTTPMethod, ApiSchema>>>>,\n apiUrl: string,\n env: string\n): ApiRequestFunction<API> {\n return async function apiRequest(path, method, input, headers) {\n const schema = schemas[path]?.[method];\n if (schema === undefined) throw new Error('Schema is undefined in api request');\n\n // if (typeof schema === 'function') {\n // schema = schema();\n // }\n\n return _apiRequest<ApiResponse<API, typeof path, typeof method>>(\n path as string,\n method as 'GET' | 'POST',\n input,\n schema,\n env,\n apiUrl,\n headers\n );\n };\n}\n","import type { APIGatewayProxyResultV2, Context, APIGatewayProxyEventV2WithLambdaAuthorizer } from 'aws-lambda';\nimport { stringify } from 'devalue';\n\nexport type SuccessCode = 200 | 201 | 204;\nexport type ErrorCode = 400 | 401 | 403 | 404 | 409 | 500;\n\nexport type ErrorBody = { message: string; field?: { name: string; value: string } };\n\n/**\n * The error response for the lambda functions to return\n */\nexport type ErrorRawProxyResultV2 = {\n statusCode: ErrorCode;\n headers?: { [header: string]: string } | undefined;\n body?: ErrorBody;\n isBase64Encoded?: boolean | undefined;\n cookies?: string[] | undefined;\n};\n\nexport type OkRawProxyResultV2 = {\n statusCode: SuccessCode;\n headers?: { [header: string]: string } | undefined;\n body?: object | undefined;\n isBase64Encoded?: boolean | undefined;\n cookies?: string[] | undefined;\n};\n/**\n * A type for the raw proxy result - just using an object not a stirng for the body\n */\nexport type RawProxyResultV2 = ErrorRawProxyResultV2 | OkRawProxyResultV2;\n\n// The type of the handler returned from wrapHandler\nexport type APIGatewayHandler<E> = (event: E, context: Context) => Promise<APIGatewayProxyResultV2>;\n\n// The type of the handler passed into wrapHandler\nexport type RawApiGatewayHandler<E extends APIGatewayProxyEventV2WithLambdaAuthorizer<any>> = (\n event: E,\n context: Context\n) => Promise<RawProxyResultV2>;\n\n/**\n * Wraps a handler that returns the body as an object rather than a string.\n *\n * This means you can achieve proper type inference on your handler and have standardised serialisation\n *\n * @example\n```ts\nexport type AuthorizerContext = {\n details: JWTPayload;\n} | null;\n\nexport const wrapHandler = baseWrapHandler<APIGatewayProxyEventV2WithLambdaAuthorizer<AuthorizerContext>>\n\n*/\nexport function wrapHandler<E extends APIGatewayProxyEventV2WithLambdaAuthorizer<any>>(\n handler: RawApiGatewayHandler<E>\n): APIGatewayHandler<E> {\n return async (event: E, context: Context): Promise<APIGatewayProxyResultV2> => {\n const result = await handler(event, context);\n\n if (result.body) {\n const headers = new Headers(result.headers);\n headers.set('Content-Type', 'application/devalue');\n\n return { ...result, headers: Object.fromEntries(headers), body: stringify(result.body) };\n } else {\n return { ...result, body: undefined };\n }\n };\n}\n","/**\n * These are the various errors that should be returned from anything called by a lambda function.\n *\n * Pass a lambda error to the errorResponse function to get a suitable response to return from the lambda handler.\n *\n * The separation means that they can be returned from functions that are certainly run inside a lambda fucntion but theyre not the actual return of the lambda.\n * Im not sure it this is optimal behaviour and if not we will migrate to only using the errorResponse function\n */\n\nexport const error_lambda_badRequest = (message: string, fieldName?: string, fieldValue?: string) => ({\n type: 'lambda_badRequest' as const,\n message,\n fieldName,\n fieldValue\n});\nexport const error_lambda_unauthorized = (message: string) => ({ type: 'lambda_unauthorized' as const, message });\n\nexport const error_lambda_forbidden = (message: string) => ({ type: 'lambda_forbidden' as const, message });\n\nexport const error_lambda_notFound = (message: string, fieldName?: string, fieldValue?: string) => ({\n type: 'lambda_notFound' as const,\n message,\n fieldName,\n fieldValue\n});\n\nexport const error_lambda_conflict = (message: string, fieldName?: string, fieldValue?: string) => ({\n type: 'lambda_conflict' as const,\n message,\n fieldName,\n fieldValue\n});\n\nexport const error_lambda_internal = (message: string) => ({ type: 'lambda_internal' as const, message });\n\nexport type type_error_lambda_badRequest = ReturnType<typeof error_lambda_badRequest>;\nexport type type_error_lambda_unauthorized = ReturnType<typeof error_lambda_unauthorized>;\nexport type type_error_lambda_forbidden = ReturnType<typeof error_lambda_forbidden>;\nexport type type_error_lambda_notFound = ReturnType<typeof error_lambda_notFound>;\nexport type type_error_lambda_conflict = ReturnType<typeof error_lambda_conflict>;\nexport type type_error_lambda_internal = ReturnType<typeof error_lambda_internal>;\n\nexport type type_error_lambda =\n | type_error_lambda_badRequest\n | type_error_lambda_unauthorized\n | type_error_lambda_forbidden\n | type_error_lambda_notFound\n | type_error_lambda_conflict\n | type_error_lambda_internal;\n","import type { BaseIssue, SafeParseResult } from 'valibot';\n\nimport { error_lambda_badRequest, type type_error_lambda } from './errors.js';\nimport type { ErrorRawProxyResultV2, OkRawProxyResultV2 } from './handlerUtils.js';\n\nfunction field(obj: { fieldName?: string; fieldValue?: string }) {\n return obj.fieldName === undefined || obj.fieldValue === undefined\n ? {}\n : { field: { name: obj.fieldName, value: obj.fieldValue } };\n}\n\nexport type type_error_response = Omit<ErrorRawProxyResultV2, 'headers' | 'body'> & {\n headers: NonNullable<ErrorRawProxyResultV2['headers']>;\n body: NonNullable<ErrorRawProxyResultV2['body']>;\n};\n\nexport type LambdaErrorResponse<Type extends string = '', Extras extends object = {}> =\n | {\n headers: Record<string, string>;\n statusCode: 400;\n body: { message: string; type: Type } & ReturnType<typeof field> & Extras;\n }\n | { headers: Record<string, string>; statusCode: 401; body: { message: string; type: Type } & Extras }\n | { headers: Record<string, string>; statusCode: 403; body: { message: string; type: Type } & Extras }\n | {\n headers: Record<string, string>;\n statusCode: 404;\n body: { message: string; type: Type } & ReturnType<typeof field> & Extras;\n }\n | {\n headers: Record<string, string>;\n statusCode: 409;\n body: { message: string; type: Type } & ReturnType<typeof field> & Extras;\n }\n | { headers: Record<string, string>; statusCode: 500; body: { message: string; type: Type } & Extras };\n\nexport function response_error<Type extends string = '', Extras extends object = {}>(\n e: type_error_lambda,\n headers: Record<string, string>,\n type: Type = '' as Type,\n extras: Extras = {} as Extras\n): LambdaErrorResponse<Type, Extras> {\n switch (e.type) {\n case 'lambda_badRequest':\n return { headers, statusCode: 400, body: { message: e.message, type: type, ...field(e), ...extras } };\n\n case 'lambda_unauthorized':\n return { headers, statusCode: 401, body: { message: e.message, type: type, ...extras } };\n\n case 'lambda_forbidden':\n return { headers, statusCode: 403, body: { message: e.message, type: type, ...extras } };\n\n case 'lambda_notFound':\n return { headers, statusCode: 404, body: { message: e.message, type: type, ...field(e), ...extras } };\n\n case 'lambda_conflict':\n return { headers, statusCode: 409, body: { message: e.message, type: type, ...field(e), ...extras } };\n\n default:\n return { headers, statusCode: 500, body: { message: 'Unknown error', type: type, ...extras } };\n }\n}\n\n/**\n * Helper function to get a reasonable default error response from a valibot parse result\n * @param res - The output from calling safeParse on the input\n * @param headers - The headers to return in the response\n */\nexport function response_valibotError(res: Extract<SafeParseResult<any>, { success: false }>, headers: any) {\n const issue = res.issues[0] as BaseIssue<any>;\n\n if (issue.path && issue.path[0] && typeof issue.path[0].key === 'string') {\n return response_error(error_lambda_badRequest('Invalid input', issue.path[0].key, issue.message), headers);\n } else {\n return response_error(error_lambda_badRequest(`Invalid input: ${issue.message}`), headers);\n }\n}\n\nexport function response_ok<Body extends { message: string }>(\n body: Body,\n headers: any,\n cookies?: string[] | undefined\n) {\n return { headers, cookies, statusCode: 200 as const, body } satisfies OkRawProxyResultV2;\n}\n","import { error_lambda_unauthorized } from '$lambda/errors.js';\nimport type { APIGatewayProxyEventV2WithLambdaAuthorizer, APIGatewayRequestAuthorizerEventV2 } from 'aws-lambda';\nimport { parse } from 'cookie';\nimport { Result } from 'neverthrow';\n\n/**\n * Wraps cookies parse along with the api gateway event with neverthrow\n */\nexport const getCookies = Result.fromThrowable(\n (event: APIGatewayProxyEventV2WithLambdaAuthorizer<any> | APIGatewayRequestAuthorizerEventV2) => {\n if (!('headers' in event) || !event.headers) {\n throw new Error('No headers in event');\n }\n\n // First try to get cookies from the cookies array (API Gateway v2 format)\n const cookieString =\n Array.isArray(event.cookies) && event.cookies.length > 0\n ? event.cookies.join('; ')\n : event.headers.Cookie || event.headers.cookie;\n\n if (!cookieString) {\n throw new Error('No cookies found in event');\n }\n\n const res = parse(cookieString);\n return res;\n },\n (e) => {\n if (e instanceof Error) return error_lambda_unauthorized(e.message);\n return error_lambda_unauthorized('Invalid Cookies');\n }\n);\n","import { CognitoIdentityProviderClient } from '@aws-sdk/client-cognito-identity-provider';\n\n/**\n * Convenience function if process.env.AWS_REGION is set\n */\nexport function getCognitoClient() {\n return new CognitoIdentityProviderClient({\n // region: process.env.AWS_REGION\n // endpoint: `https://cognito-idp.${process.env.REGION}.amazonaws.com`\n });\n}\n","import {\n error_lambda_badRequest,\n error_lambda_conflict,\n error_lambda_internal,\n error_lambda_unauthorized,\n error_lambda_forbidden,\n error_lambda_notFound\n} from '$lambda/errors.js';\n\nexport const error_cognito_forbidden = { group: 'cognito' as const, type: 'cognito_forbidden' as const };\nexport const error_cognito_internal = { group: 'cognito' as const, type: 'cognito_internal' as const };\nexport const error_cognito_role = { group: 'cognito' as const, type: 'cognito_role' as const };\nexport const error_cognito_input = { group: 'cognito' as const, type: 'cognito_input' as const };\nexport const error_cognito_auth = { group: 'cognito' as const, type: 'cognito_auth' as const };\nexport const error_cognito_notFound = { group: 'cognito' as const, type: 'cognito_notFound' as const };\nexport const error_cognito_userNotFound = { group: 'cognito' as const, type: 'cognito_userNotFound' as const };\nexport const error_cognito_tooManyRequests = { group: 'cognito' as const, type: 'cognito_tooManyRequests' as const };\nexport const error_cognito_passwordPolicy = { group: 'cognito' as const, type: 'cognito_passwordPolicy' as const };\nexport const error_cognito_passwordHistory = { group: 'cognito' as const, type: 'cognito_passwordHistory' as const };\nexport const error_cognito_passwordResetRequired = {\n group: 'cognito' as const,\n type: 'cognito_passwordResetRequired' as const\n};\n\n// Confirm forgot password\nexport const error_cognito_codeExpired = { group: 'cognito' as const, type: 'cognito_codeExpired' as const };\nexport const error_cognito_codeMismatch = { group: 'cognito' as const, type: 'cognito_codeMismatch' as const };\n\n// Forgot password\nexport const error_cognito_delivery = { group: 'cognito' as const, type: 'cognito_delivery' as const };\n// Confirm signup\nexport const error_cognito_userExists = { group: 'cognito' as const, type: 'cognito_userExists' as const };\n\nexport type type_error_cognito_forbidden = typeof error_cognito_forbidden;\nexport type type_error_cognito_internal = typeof error_cognito_internal;\nexport type type_error_cognito_role = typeof error_cognito_role;\nexport type type_error_cognito_input = typeof error_cognito_input;\nexport type type_error_cognito_auth = typeof error_cognito_auth;\nexport type type_error_cognito_notFound = typeof error_cognito_notFound;\nexport type type_error_cognito_userNotFound = typeof error_cognito_userNotFound;\nexport type type_error_cognito_tooManyRequests = typeof error_cognito_tooManyRequests;\nexport type type_error_cognito_passwordPolicy = typeof error_cognito_passwordPolicy;\nexport type type_error_cognito_passwordHistory = typeof error_cognito_passwordHistory;\nexport type type_error_cognito_passwordResetRequired = typeof error_cognito_passwordResetRequired;\nexport type type_error_cognito_codeExpired = typeof error_cognito_codeExpired;\nexport type type_error_cognito_codeMismatch = typeof error_cognito_codeMismatch;\nexport type type_error_cognito_delivery = typeof error_cognito_delivery;\nexport type type_error_cognito_userExists = typeof error_cognito_userExists;\n\nexport type type_error_cognito =\n | type_error_cognito_forbidden\n | type_error_cognito_internal\n | type_error_cognito_role\n | type_error_cognito_input\n | type_error_cognito_auth\n | type_error_cognito_notFound\n | type_error_cognito_userNotFound\n | type_error_cognito_tooManyRequests\n | type_error_cognito_passwordPolicy\n | type_error_cognito_passwordHistory\n | type_error_cognito_passwordResetRequired\n | type_error_cognito_codeExpired\n | type_error_cognito_codeMismatch\n | type_error_cognito_delivery\n | type_error_cognito_userExists;\n\nconst awsToCognitoErrorMap = {\n ForbiddenException: error_cognito_forbidden,\n NotAuthorizedException: error_cognito_auth,\n UserNotConfirmedException: error_cognito_auth,\n UserNotFoundException: error_cognito_userNotFound,\n ResourceNotFoundException: error_cognito_notFound,\n InvalidParameterException: error_cognito_input,\n InvalidPasswordException: error_cognito_passwordPolicy,\n PasswordHistoryPolicyViolationException: error_cognito_passwordHistory,\n PasswordResetRequiredException: error_cognito_passwordResetRequired,\n LimitExceededException: error_cognito_tooManyRequests,\n TooManyRequestsException: error_cognito_tooManyRequests,\n InternalErrorException: error_cognito_internal,\n // Confirm forgot password\n CodeMismatchException: error_cognito_codeMismatch,\n ExpiredCodeException: error_cognito_codeExpired,\n TooManyFailedAttemptsException: error_cognito_tooManyRequests,\n UnexpectedLambdaException: error_cognito_internal,\n InvalidLambdaResponseException: error_cognito_internal,\n UserLambdaValidationException: error_cognito_internal,\n // Forgot password\n InvalidEmailRoleAccessPolicyException: error_cognito_role,\n InvalidSmsRoleAccessPolicyException: error_cognito_role,\n InvalidSmsRoleTrustRelationshipException: error_cognito_role,\n CodeDelliveryFailureException: error_cognito_delivery,\n // Confirm signup\n AliasExistsException: error_cognito_userExists,\n // Login\n InvalidUserPoolConfigurationException: error_cognito_internal,\n MFAMethodNotFoundException: error_cognito_notFound,\n UnsupportedOperationException: error_cognito_internal,\n // Reset password\n SoftwareTokenMFANotFoundException: error_cognito_notFound,\n // Sign up\n UsernameExistsException: error_cognito_userExists\n} as const;\n\n/**\n * Gets a generic error from the name of the aws error\n */\nexport function error_cognito(error: Error): type_error_cognito {\n const type = error.name as keyof typeof awsToCognitoErrorMap;\n if (awsToCognitoErrorMap[type] === undefined) console.warn(`${type} is not present in the cognito error map`);\n\n console.error(`Cognito error: ${type}`, error);\n\n return awsToCognitoErrorMap[type] || error_cognito_internal;\n}\n\n/**\n * Converts a cognito error to a lambda error.\n * Basically just for narrowing it down a bit\n */\nexport function error_lambda_fromCognito(e: type_error_cognito) {\n switch (e.type) {\n case 'cognito_auth':\n return error_lambda_unauthorized('Not authorized');\n case 'cognito_forbidden':\n return error_lambda_forbidden('Forbidden');\n case 'cognito_internal':\n case 'cognito_role':\n return error_lambda_internal('Internal server error');\n case 'cognito_input':\n return error_lambda_badRequest('There is an issue with your request');\n case 'cognito_notFound':\n return error_lambda_notFound('Resource not found');\n case 'cognito_userNotFound':\n return error_lambda_notFound('User not found');\n case 'cognito_tooManyRequests':\n return error_lambda_badRequest('Too many requests');\n case 'cognito_passwordPolicy':\n return error_lambda_badRequest('Password does not meet policy requirements');\n case 'cognito_passwordHistory':\n return error_lambda_conflict('Password was used recently');\n case 'cognito_passwordResetRequired':\n return error_lambda_badRequest('Password reset required');\n case 'cognito_delivery':\n return error_lambda_internal('Delivery failed for the provided email or phone number');\n default:\n return error_lambda_internal('Unknown error');\n }\n}\n","import type {\n AdminGetUserCommandOutput,\n AttributeType,\n CognitoIdentityProviderServiceException\n} from '@aws-sdk/client-cognito-identity-provider';\nimport { AdminGetUserCommand, AdminListGroupsForUserCommand } from '@aws-sdk/client-cognito-identity-provider';\nimport { ResultAsync } from 'neverthrow';\n\nimport { getCognitoClient } from './client.js';\nimport { error_cognito } from './errors.js';\n\nexport type type_userResponse = Omit<AdminGetUserCommandOutput, 'UserAttributes'> & {\n UserAttributes: Record<string, string>;\n};\n\n/**\n * Performs an AdminGetUserCommand and extracts the user attributes into an object\n */\nexport const getUserDetails = ResultAsync.fromThrowable(\n async (a: { username: string; userPoolId: string }) => {\n console.log('getUserDetails: Getting details for user: ', a.username);\n const cognitoClient = getCognitoClient();\n const res = await cognitoClient.send(new AdminGetUserCommand({ UserPoolId: a.userPoolId, Username: a.username }));\n return { ...res, UserAttributes: extractAttributes(res.UserAttributes) } as type_userResponse;\n },\n (e) => {\n console.error('getUserDetails:error:', e);\n return error_cognito(e as CognitoIdentityProviderServiceException);\n }\n);\n\n/**\n * @returns An object of attributes with their names as keys and values as values.\n */\nexport function extractAttributes(attrs: AttributeType[] | undefined) {\n const attributes: Record<string, string> = {};\n if (attrs) {\n for (const attr of attrs) {\n if (attr.Name && attr.Value) {\n attributes[attr.Name] = attr.Value;\n }\n }\n }\n return attributes;\n}\n\n/**\n * Performs an AdminGetUserCommand and extracts the user attributes into an object\n */\nexport const getUserGroups = ResultAsync.fromThrowable(\n async (a: { username: string; userPoolId: string }) => {\n console.log('getUserGroups: Getting groups for user: ', a.username);\n const cognitoClient = getCognitoClient();\n const res = await cognitoClient.send(\n new AdminListGroupsForUserCommand({ UserPoolId: a.userPoolId, Username: a.username })\n );\n return res;\n },\n (e) => {\n console.error('getUserGroups:error:', e);\n return error_cognito(e as CognitoIdentityProviderServiceException);\n }\n);\n","import { createHmac } from 'crypto';\n\nimport {\n AdminInitiateAuthCommand,\n ChangePasswordCommand,\n ConfirmForgotPasswordCommand,\n ConfirmSignUpCommand,\n ForgotPasswordCommand,\n GlobalSignOutCommand,\n RespondToAuthChallengeCommand,\n SignUpCommand\n} from '@aws-sdk/client-cognito-identity-provider';\nimport { ResultAsync } from 'neverthrow';\n\nimport { getCognitoClient } from './client.js';\nimport type { type_error_cognito } from './errors.js';\nimport { error_cognito, error_cognito_auth } from './errors.js';\n\n/**\n * Computes Cognito secret hash used for client-side authentication flows.\n *\n * @param username - Cognito username or alias.\n * @param clientId - Cognito app client ID.\n * @param clientSecret - Cognito app client secret.\n */\nexport function computeSecretHash(username: string, clientId: string, clientSecret: string): string {\n console.log('computeSecretHash: ', username, clientId, clientSecret);\n return createHmac('SHA256', clientSecret)\n .update(username + clientId)\n .digest('base64');\n}\n\n// ---- Change password ---- //\n\n/**\n * Changes a user's password given a valid access token.\n *\n * @param accessToken - Access token for the authenticated user.\n * @param oldPassword - Current password.\n * @param newPassword - New password to set.\n */\nexport const changePassword = ResultAsync.fromThrowable(\n async (accessToken: string, oldPassword: string, newPassword: string) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new ChangePasswordCommand({\n AccessToken: accessToken,\n PreviousPassword: oldPassword,\n ProposedPassword: newPassword\n })\n );\n },\n (e) => {\n console.error('ChangePasswordCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Confirm Forgot password ---- //\n\n/**\n * Completes a forgot-password flow by submitting the confirmation code and new password.\n *\n * @param a.username - Cognito username or alias.\n * @param a.confirmationCode - Code sent by Cognito to the user.\n * @param a.newPassword - New password to set.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n */\nexport const confirmForgotPassword = ResultAsync.fromThrowable(\n (a: { username: string; confirmationCode: string; newPassword: string; clientId: string; clientSecret: string }) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new ConfirmForgotPasswordCommand({\n ClientId: a.clientId,\n Username: a.username,\n ConfirmationCode: a.confirmationCode,\n Password: a.newPassword,\n SecretHash: computeSecretHash(a.username, a.clientId, a.clientSecret)\n })\n );\n },\n (e) => {\n console.error('ConfirmForgotPasswordCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Confirm Signup ---- //\n\n/**\n * Confirms a user's signup using the confirmation code sent by Cognito.\n *\n * @param a.username - Cognito username or alias.\n * @param a.confirmationCode - Code sent to the user after signup.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n */\nexport const confirmSignup = ResultAsync.fromThrowable(\n (a: { username: string; confirmationCode: string; clientId: string; clientSecret: string }) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new ConfirmSignUpCommand({\n ClientId: a.clientId,\n Username: a.username,\n ConfirmationCode: a.confirmationCode,\n SecretHash: computeSecretHash(a.username, a.clientId, a.clientSecret)\n })\n );\n },\n (e) => {\n console.error('ConfirmSignUpCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Forgot password ---- //\n\n/**\n * Starts a forgot-password flow by sending a reset code to the user.\n *\n * @param a.username - Cognito username or alias.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n */\nexport const forgotPassword = ResultAsync.fromThrowable(\n (a: { username: string; clientId: string; clientSecret: string }) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new ForgotPasswordCommand({\n ClientId: a.clientId,\n Username: a.username,\n SecretHash: computeSecretHash(a.username, a.clientId, a.clientSecret)\n })\n );\n },\n (e) => {\n console.error('ForgotPasswordCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Login ---- //\n\n/**\n * Signs a user in with ADMIN_USER_PASSWORD_AUTH.\n *\n * @param a.username - Cognito username or alias.\n * @param a.password - User password.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n * @param a.userPoolId - Cognito user pool ID.\n */\nexport const login = ResultAsync.fromThrowable(\n (a: { username: string; password: string; clientId: string; clientSecret: string; userPoolId: string }) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new AdminInitiateAuthCommand({\n AuthFlow: 'ADMIN_USER_PASSWORD_AUTH',\n ClientId: a.clientId,\n UserPoolId: a.userPoolId,\n AuthParameters: {\n USERNAME: a.username,\n PASSWORD: a.password,\n SECRET_HASH: computeSecretHash(a.username, a.clientId, a.clientSecret)\n }\n })\n );\n },\n (e) => {\n console.error('AdminInitiateAuthCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Refresh token ---- //\n\n/**\n * Exchanges a refresh token for new tokens.\n *\n * @param a.username - Cognito username or alias used to compute secret hash.\n * @param a.refreshToken - Refresh token to exchange.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n * @param a.userPoolId - Cognito user pool ID.\n */\nexport const refreshTokens = ResultAsync.fromThrowable(\n (a: { username: string; refreshToken: string; clientId: string; clientSecret: string; userPoolId: string }) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new AdminInitiateAuthCommand({\n AuthFlow: 'REFRESH_TOKEN_AUTH',\n ClientId: a.clientId,\n UserPoolId: a.userPoolId,\n AuthParameters: {\n REFRESH_TOKEN: a.refreshToken,\n SECRET_HASH: computeSecretHash(a.username, a.clientId, a.clientSecret)\n }\n })\n );\n },\n (e) => {\n console.error('refreshTokens: AdminInitiateAuthCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Logout ---- //\n/**\n * Globally signs out a user by invalidating all refresh tokens.\n *\n * @param accessToken - Access token for the authenticated user.\n */\nexport const logout = ResultAsync.fromThrowable(\n (accessToken: string) => {\n const cognitoClient = getCognitoClient();\n // GlobalSignOut invalidates all refresh tokens associated with user\n return cognitoClient.send(new GlobalSignOutCommand({ AccessToken: accessToken }));\n },\n (e) => {\n console.error('GlobalSignOutCommand error', e);\n return error_cognito(e as Error);\n }\n);\n\n// ---- Reset password ---- //\n/**\n * Completes a NEW_PASSWORD_REQUIRED challenge for users who must set a new password.\n *\n * @param a.session - Session returned from the auth challenge.\n * @param a.newPassword - New password to set.\n * @param a.username - Cognito username or alias.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n */\nexport const resetPassword = ResultAsync.fromThrowable(\n (a: { session: string; newPassword: string; username: string; clientId: string; clientSecret: string }) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new RespondToAuthChallengeCommand({\n ChallengeName: 'NEW_PASSWORD_REQUIRED',\n ClientId: a.clientId,\n Session: a.session,\n ChallengeResponses: {\n SECRET_HASH: computeSecretHash(a.username, a.clientId, a.clientSecret),\n NEW_PASSWORD: a.newPassword,\n USERNAME: a.username\n }\n })\n );\n },\n (e) => {\n console.error('RespondToAuthChallengeCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Sign up ---- //\n/**\n * Registers a new user with Cognito and optional custom attributes.\n *\n * @param a.username - Cognito username.\n * @param a.password - User password.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n * @param a.<attribute> - Any additional user attributes to set.\n */\nexport const signUp = ResultAsync.fromThrowable(\n (a: { username: string; password: string; clientId: string; clientSecret: string } & Record<string, unknown>) => {\n const cognitoClient = getCognitoClient();\n const secretHash = computeSecretHash(a.username, a.clientId, a.clientSecret);\n\n return cognitoClient.send(\n new SignUpCommand({\n ClientId: a.clientId,\n Username: a.username,\n Password: a.password,\n SecretHash: secretHash,\n UserAttributes: Object.entries(a)\n .filter(([key]) => !['username', 'password', 'clientId', 'clientSecret'].includes(key))\n .map(([key, value]) => ({ Name: key, Value: value as string }))\n })\n );\n },\n (e) => {\n console.error('SignUpCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Federated ---- //\n/**\n * Exchanges an OAuth2 authorization code for Cognito tokens using the token endpoint.\n * See https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html for request/response fields and grant details.\n *\n * @param a.code - Authorization code returned by the hosted UI.\n * @param a.redirectUri - Redirect URI registered with the app client.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret used for Basic Auth.\n * @param a.cognitoDomain - Cognito domain URL (e.g., your-domain.auth.region.amazoncognito.com).\n * @returns Parsed token payload containing `access_token`, `id_token`, `refresh_token`, token type, and expiry.\n */\nexport const verifyOAuthToken = ResultAsync.fromThrowable(\n async (a: { code: string; redirectUri: string; clientId: string; clientSecret: string; cognitoDomain: string }) => {\n const basicAuth = Buffer.from(`${a.clientId}:${a.clientSecret}`).toString('base64');\n\n const params = new URLSearchParams();\n params.append('grant_type', 'authorization_code');\n params.append('code', a.code);\n params.append('redirect_uri', a.redirectUri);\n\n // params.append('client_id', a.clientId);\n\n console.log('verifyOAuthToken: params', params.toString());\n\n const tokenRes = await fetch(`https://${a.cognitoDomain}/oauth2/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded', Authorization: `Basic ${basicAuth}` },\n body: params.toString()\n });\n if (!tokenRes.ok) {\n console.error('verifyOAuthToken: token exchange failed', await tokenRes.text());\n throw new Error('');\n }\n\n return (await tokenRes.json()) as {\n access_token: string;\n id_token: string;\n refresh_token: string;\n token_type: string;\n expires_in: number;\n };\n },\n (e) => {\n console.error('verifyOAuthToken:error', e);\n return error_cognito_auth;\n }\n);\n\n/**\n * Exchanges an OAuth2 refresh token for Cognito tokens using the oauth token endpoint.\n * See https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html for request/response fields and grant details.\n *\n * @param a.redirectUri - Redirect URI registered with the app client.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret used for Basic Auth.\n * @param a.cognitoDomain - Cognito domain URL (e.g., your-domain.auth.region.amazoncognito.com).\n * @returns Parsed token payload containing `access_token`, `id_token`, `refresh_token`, token type, and expiry.\n */\nexport const refreshOAuthToken = ResultAsync.fromThrowable(\n async (a: { clientId: string; clientSecret: string; cognitoDomain: string; refreshToken: string }) => {\n const basicAuth = Buffer.from(`${a.clientId}:${a.clientSecret}`).toString('base64');\n\n const params = new URLSearchParams();\n params.append('grant_type', 'refresh_token');\n params.append('refresh_token', a.refreshToken);\n\n console.log('refreshOAuthToken: params', params.toString());\n\n const tokenRes = await fetch(`https://${a.cognitoDomain}/oauth2/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded', Authorization: `Basic ${basicAuth}` },\n body: params.toString()\n });\n if (!tokenRes.ok) {\n console.error('refreshOAuthToken: token exchange failed', await tokenRes.text());\n throw new Error('');\n }\n\n return (await tokenRes.json()) as {\n access_token: string;\n id_token: string;\n refresh_token: string | undefined;\n token_type: string;\n expires_in: number;\n };\n },\n (e) => {\n console.error('refreshOAuthToken:error', e);\n return error_cognito_auth;\n }\n);\n","import { S3Client } from '@aws-sdk/client-s3';\n\n/**\n * Convenience function for S3Client when process.env.REGION is set\n */\nexport function getS3() {\n return new S3Client({\n // endpoint: `https://s3.${process.env.REGION}.amazonaws.com`,\n // region: process.env.REGION\n });\n}\n","export const error_s3_internal = { type: 's3_internal' as const };\nexport const error_s3_get = { type: 's3_get' as const };\n\nexport type type_error_s3_internal = typeof error_s3_internal;\nexport type type_error_s3_get = typeof error_s3_get;\n","import { getSignedUrl as baseGetSignedUrl } from '@aws-sdk/s3-request-presigner';\nimport { ResultAsync } from 'neverthrow';\n\nexport const getSignedUrl = ResultAsync.fromThrowable(baseGetSignedUrl, (e) => e);\n","import { HeadObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';\nimport { ResultAsync } from 'neverthrow';\n\nimport { getS3 } from './client.js';\nimport { error_s3_get } from './errors.js';\n\n/**\n * Retrieves an object from an S3 bucket.\n *\n * @param {string} bucketName - The name of the S3 bucket.\n * @param {string} key - The key of the object to retrieve.\n * @returns {Promise<Buffer>} A promise that resolves to the object data as a Buffer.\n */\nexport const getObject = ResultAsync.fromThrowable(\n async (bucketName: string, key: string) => {\n const s3 = getS3();\n const cmd = new GetObjectCommand({ Bucket: bucketName, Key: key });\n const res = await s3.send(cmd);\n const stream = res.Body as any;\n return new Promise<Buffer>((resolve, reject) => {\n const chunks: Buffer[] = [];\n stream.on('data', (chunk: Buffer) => chunks.push(chunk));\n stream.on('end', () => resolve(Buffer.concat(chunks)));\n stream.on('error', reject);\n });\n },\n (e) => {\n console.error(`Error getting object from S3: ${e}`);\n return error_s3_get;\n }\n);\n\n/**\n * Convenience function to get an object from S3 and return it as a string.\n */\nexport function getObjectString(bucketName: string, key: string): ResultAsync<string, typeof error_s3_get> {\n return getObject(bucketName, key).map((buffer) => buffer.toString('utf-8'));\n}\n\n/**\n * Checks if an object exists in an s3 bucket by retrieving the HEAD data\n *\n * @param {string} bucketName - The name of the S3 bucket.\n * @param {string} key - The key of the object to retrieve.\n * @returns {Promise<Buffer>} A promise that resolves to a boolean.\n */\nexport const objectExists = ResultAsync.fromThrowable(\n async (bucketName: string, key: string) => {\n const s3 = getS3();\n\n try {\n const cmd = new HeadObjectCommand({ Bucket: bucketName, Key: key });\n const res = await s3.send(cmd);\n return res.$metadata.httpStatusCode === 200;\n } catch (e) {\n if ((e as any).$metadata.httpStatusCode === 404) {\n return false;\n } else throw e;\n }\n },\n (e) => {\n console.error(`Error getting object head from S3: ${e}`);\n return error_s3_get;\n }\n);\n","import { error_lambda_internal } from '$lambda/errors.js';\n\nexport const error_dynamo = { type: 'dynamo' as const };\n\nexport type type_error_dynamo = typeof error_dynamo;\n\nexport function error_lambda_fromDynamo(_e: type_error_dynamo) {\n return error_lambda_internal('Internal server error');\n}\n","export const error_ses = { type: 'ses' as const };\n","import type { Root, RootContent, Element } from 'hast';\nimport rehypeParse from 'rehype-parse';\nimport type { Plugin } from 'unified';\nimport { unified } from 'unified';\nimport type { VFile } from 'vfile';\n\n/**\n * This rehype plugin extracts the headings from the markdown elements but also the raw elements.\n * So we get html headings in the TOC as well\n *\n * It sets the file.data.fm.toc to a flat map of the toc\n */\nexport const extractToc: Plugin<[], Root> = () => {\n return (tree: Root, file: VFile) => {\n const details = tree.children.flatMap(extractDetails);\n if (file.data.fm === undefined) file.data.fm = {};\n // @ts-expect-error its untyped but for svmdex it is there\n file.data.fm.toc = details;\n };\n};\nexport type Toc = TocEntry[];\nexport type TocEntry = { level: number; id: string; value: string };\n\nfunction extractDetails(content: RootContent | { type: 'raw'; value: string }): TocEntry[] {\n if (content.type === 'element' && content.tagName.startsWith('h') && 'id' in content.properties) {\n const value =\n content.children.length === 1 && content.children[0].type === 'text'\n ? content.children[0].value\n : (content.properties.id as string);\n\n return [{ level: parseInt(content.tagName.slice(1)), id: content.properties.id as string, value }];\n } else if (content.type === 'raw') {\n const parsed = parseRaw(content.value);\n return parsed.flatMap(extractDetails);\n }\n return [];\n}\n\n/**\n * Parses raw HTML and returns a flat array of all heading (h1-h6) elements as HAST nodes.\n */\nexport function parseRaw(raw: string): Element[] {\n // Parse the HTML string into a HAST Root node\n const tree = unified()\n .use(rehypeParse, { fragment: true }) // allow parsing HTML fragments\n .parse(raw) as Root;\n\n // Helper function to recursively find heading elements\n function collectHeadings(node: RootContent): Element[] {\n if (node.type === 'element' && /^h[1-6]$/.test(node.tagName)) {\n return [node];\n }\n // Check children recursively\n if ('children' in node && Array.isArray(node.children)) {\n return node.children.flatMap(collectHeadings);\n }\n return [];\n }\n\n // Flatten all headings found in the tree\n return tree.children.flatMap(collectHeadings);\n}\n","import type { GenericSchema, GenericSchemaAsync } from 'valibot';\n\nexport function isSchema(x: unknown): x is GenericSchema {\n return !!x && typeof x === 'object' && 'kind' in x && x['kind'] === 'schema';\n}\n\nexport function unwrap(schema: GenericSchema): GenericSchema {\n // Unwrap common wrappers that simply contain another schema under `wrapped`\n // optional | exactOptional | undefinedable | nullable | nullish | nonNullable | nonNullish | readonly | brand | description | metadata | title | flavor\n // Most of these share `{ type: string; wrapped: GenericSchema }`\n // Guarded unwrap to avoid infinite loops.\n let curr: any = schema as any;\n const seen = new Set<any>();\n while (curr && typeof curr === 'object' && !seen.has(curr) && 'wrapped' in curr && isSchema((curr as any).wrapped)) {\n seen.add(curr);\n curr = (curr as any).wrapped;\n }\n return curr as GenericSchema;\n}\n\nfunction isIntegerKey(s: string): boolean {\n // allow \"0\", \"01\" etc. to index tuples/arrays consistently\n return /^-?\\d+$/.test(s);\n}\n\nexport type GetSchemaByPathOptions = {\n /**\n * When a union/variant cannot be narrowed by the path segment,\n * choose index `preferOption` (default 0). Set to -1 to return undefined instead.\n */\n preferOption?: number;\n};\n\nexport function getSchemaByPath(\n root: GenericSchema | GenericSchemaAsync,\n path: string,\n opts: GetSchemaByPathOptions = {}\n): GenericSchema | undefined {\n if (!isSchema(root)) return undefined;\n if (!path) return root;\n\n const keys = path.split('.');\n let curr: GenericSchema | undefined = root;\n\n for (let i = 0; i < keys.length; i++) {\n if (!curr) return undefined;\n curr = unwrap(curr);\n const seg = keys[i];\n\n // Narrow by schema \"type\"\n const type = (curr as any).type as string | undefined;\n\n switch (type) {\n case 'object': {\n // ObjectSchema has `.entries`\n const entries = (curr as any).entries as Record<string, GenericSchema> | undefined;\n if (!entries) return undefined;\n curr = entries[seg];\n break;\n }\n\n case 'record': {\n // RecordSchema has `.value` for any key\n const value = (curr as any).value as GenericSchema | undefined;\n curr = value;\n break;\n }\n\n case 'array': {\n // ArraySchema has `.item`\n if (!isIntegerKey(seg)) return undefined;\n const item = (curr as any).item as GenericSchema | undefined;\n curr = item;\n break;\n }\n\n case 'tuple': {\n // TupleSchema has `.items` and possibly `.rest`\n if (!isIntegerKey(seg)) return undefined;\n const idx = Number(seg);\n const items = (curr as any).items as GenericSchema[] | undefined;\n const rest = (curr as any).rest as GenericSchema | undefined;\n if (!items) return undefined;\n curr = idx < items.length ? items[idx] : rest;\n break;\n }\n\n case 'union': {\n // UnionSchema has `.options` (array of schemas)\n const options = (curr as any).options as GenericSchema[] | undefined;\n if (!options?.length) return undefined;\n\n // Try to narrow by segment:\n // - if numeric seg: prefer array/tuple options\n // - if string seg: prefer object/record options that contain seg\n const numeric = isIntegerKey(seg);\n\n let next: GenericSchema | undefined;\n\n if (numeric) {\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n return u?.type === 'array' || u?.type === 'tuple';\n }) ?? options[opts.preferOption ?? 0];\n } else {\n // Prefer object/record with matching key\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n if (u?.type === 'object') {\n const ent = u.entries as Record<string, GenericSchema> | undefined;\n return !!ent && seg in ent;\n }\n return u?.type === 'record';\n }) ?? options[opts.preferOption ?? 0];\n }\n\n curr = next;\n // Loop continues to use seg against selected option\n i--; // reprocess this segment against the chosen branch\n break;\n }\n\n case 'variant': {\n // Variant (discriminated union) has `.options` too\n const options = (curr as any).options as GenericSchema[] | undefined;\n if (!options?.length) return undefined;\n // Same narrowing as union\n const numeric = isIntegerKey(seg);\n let next: GenericSchema | undefined;\n if (numeric) {\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n return u?.type === 'array' || u?.type === 'tuple';\n }) ?? options[opts.preferOption ?? 0];\n } else {\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n if (u?.type === 'object') {\n const ent = u.entries as Record<string, GenericSchema> | undefined;\n return !!ent && seg in ent;\n }\n return u?.type === 'record';\n }) ?? options[opts.preferOption ?? 0];\n }\n curr = next;\n i--;\n break;\n }\n\n default: {\n // If it’s a pipeline schema (`pipe`) or similar wrapper, many expose `.wrapped` and are handled by unwrap.\n // If we end up at a primitive or unknown structure while keys remain, fail.\n return undefined;\n }\n }\n }\n\n return curr ? unwrap(curr) : undefined;\n}\n","import { isEqual, isObject } from 'radash';\n\nimport type { DeepPartial } from '../types/deep.js';\n\n/**\n * Sets the value for an object by its dot path\n * @param obj - any object\n * @param path - the dot path eg. key1.0.1.key2\n * @param value - any value\n * @returns - the modified object\n */\nexport function setByPath<T extends object>(obj: T, path: string, value: any): T {\n const keys = path.split('.');\n let curr: any = obj;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const k = keys[i];\n const next = keys[i + 1];\n // handle array indices like '0'\n if (Number.isInteger(Number(next))) {\n curr[k] ??= [];\n } else {\n curr[k] ??= {};\n }\n curr = curr[k];\n }\n\n curr[keys[keys.length - 1]] = value;\n return obj;\n}\n\n/**\n * Gets the value from an object by its dot path\n * @param obj - any object\n * @param path - the dot path eg. key1.0.1.key2\n * @returns - the value at the given path or undefined\n */\nexport function getByPath<T extends object>(obj: T, path: string): any {\n if (!obj || typeof obj !== 'object') return undefined;\n const keys = path.split('.');\n let curr: any = obj;\n\n for (const k of keys) {\n if (curr == null) return undefined;\n curr = curr[k];\n }\n\n return curr;\n}\n\nconst isPlainRecord = (v: unknown): v is Record<string, unknown> => isObject(v) && !Array.isArray(v);\n\n/**\n * Returns a deep \"patch\" object containing only the fields from `b`\n * that are different from `a`.\n *\n * Behavior:\n * - Only keys from `b` can appear in the result.\n * - New keys in `b` are included.\n * - Changed primitive/array values are included as the value from `b`.\n * - For nested plain objects, it recurses and returns only the differing nested fields.\n * - Arrays are treated as atomic (if different, the whole array from `b` is returned).\n *\n * Typing:\n * - Output is `DeepPartial<B>` because only a subset of `b`'s shape is returned.\n *\n * @template A\n * @template B\n * @param {A} a - Base/original object (can be a different shape than `b`).\n * @param {B} b - Updated object; output keys come from this object.\n * @returns {DeepPartial<B>} Deep partial of `b` containing only differences vs `a`.\n */\nexport const deepDiff = <A extends object, B extends object>(a: A, b: B): DeepPartial<B> => {\n const out: Record<string, unknown> = {};\n\n for (const key of Object.keys(b) as Array<keyof B>) {\n const aVal = (a as any)?.[key];\n const bVal = (b as any)[key];\n\n if (!((key as any) in (a as any))) {\n out[key as any] = bVal;\n continue;\n }\n\n if (isPlainRecord(aVal) && isPlainRecord(bVal)) {\n const nested = deepDiff(aVal, bVal);\n if (Object.keys(nested as any).length) out[key as any] = nested;\n continue;\n }\n\n if (!isEqual(aVal, bVal)) out[key as any] = bVal;\n }\n\n return out as DeepPartial<B>;\n};\n\n/**\n * Deeply prunes `source` to match the *shape* of `shape`.\n *\n * Rules:\n * - Only keys that exist on `shape` are kept.\n * - Pruning is deep for nested plain objects.\n * - Arrays are supported by using the first element of `shape` as the element-shape.\n * - If `shape` is `[]`, returns `[]` (drops all elements).\n * - Primitive values are kept as-is (no type coercion) if the key exists in `shape`.\n * - If `shape` expects an object/array but `source` is not compatible, returns an empty object/array of that shape.\n *\n * @typeParam S - Source object type.\n * @typeParam Sh - Shape object type.\n * @param source - The object to prune.\n * @param shape - The object whose keys/structure are the allowlist.\n * @returns A new value derived from `source`, containing only fields present in `shape`, pruned deeply.\n *\n * @example\n * const source = { a: 1, b: { c: 2, d: 3 }, e: [ { x: 1, y: 2 }, { x: 3, y: 4 } ], z: 9 };\n * const shape = { a: 0, b: { c: 0 }, e: [ { x: 0 } ] };\n * // => { a: 1, b: { c: 2 }, e: [ { x: 1 }, { x: 3 } ] }\n * const out = pruneToShape(source, shape);\n */\nexport function pruneToShape<S, Sh>(source: S, shape: Sh): Sh {\n return pruneAny(source as unknown, shape as unknown) as Sh;\n\n function pruneAny(src: unknown, sh: unknown): unknown {\n // Arrays: use first element as the \"element shape\"\n if (Array.isArray(sh)) {\n if (!Array.isArray(src)) return [];\n if (sh.length === 0) return [];\n const elemShape = sh[0];\n return src.map((v) => pruneAny(v, elemShape));\n }\n\n // Plain objects: keep only keys present on shape, recursively.\n if (isPlainObject(sh)) {\n const out: Record<string, unknown> = {};\n const srcObj = isPlainObject(src) ? (src as Record<string, unknown>) : undefined;\n\n for (const key of Object.keys(sh as Record<string, unknown>)) {\n const shVal = (sh as Record<string, unknown>)[key];\n const srcVal = srcObj ? srcObj[key] : undefined;\n\n if (Array.isArray(shVal) || isPlainObject(shVal)) {\n out[key] = pruneAny(srcVal, shVal);\n } else {\n // Primitive (or function/date/etc in shape): key exists => keep source value as-is\n out[key] = srcVal;\n }\n }\n return out;\n }\n\n // Non-object shape => allowed leaf; just return source leaf as-is.\n return src;\n }\n\n function isPlainObject(v: unknown): v is Record<string, unknown> {\n if (v === null || typeof v !== 'object') return false;\n const proto = Object.getPrototypeOf(v);\n return proto === Object.prototype || proto === null;\n }\n}\n","import { lstat, mkdir, readFile, writeFile } from 'fs/promises';\nimport { dirname } from 'path';\n\nimport chalk from 'chalk';\nimport type { PackageJson } from 'type-fest';\n\n/**\n * @returns true if a filepath exists\n */\nexport async function exists(filePath: string): Promise<boolean> {\n try {\n await lstat(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Writes data to a filepath if it is different\n * @returns true if the file is written to\n */\nexport async function writeIfDifferent(filePath: string, newData: string): Promise<boolean> {\n // Ensure the directory exists\n const directory = dirname(filePath);\n if (!(await exists(directory))) {\n await mkdir(directory, { recursive: true });\n }\n\n // Check if the file exists\n if (await exists(filePath)) {\n // Read the existing file content\n const existingData = await readFile(filePath, 'utf8');\n\n // Compare the existing data with the new data\n if (existingData === newData) {\n // console.log('File contents are identical. No write needed.');\n return false;\n }\n }\n\n // Write the new data if it's different or the file doesn't exist\n await writeFile(filePath, newData, 'utf8');\n console.log(chalk.green('Writing to'), filePath);\n return true;\n}\n\n/**\n * @returns the json object packageJson or undefined if it doesnt exist\n */\nexport async function readPackageJson(filePath: string): Promise<PackageJson | undefined> {\n if (!(await exists(filePath))) return undefined;\n return JSON.parse(await readFile(filePath, { encoding: 'utf-8' })) as PackageJson;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["parse","baseGetSignedUrl"],"sources":["../src/lambda/client-types.ts","../src/lambda/client.ts","../src/lambda/handlerUtils.ts","../src/lambda/errors.ts","../src/lambda/response.ts","../src/lambda/server/authentication.ts","../src/cognito/client.ts","../src/cognito/errors.ts","../src/cognito/user.ts","../src/cognito/password.ts","../src/s3/client.ts","../src/s3/errors.ts","../src/s3/signedUrl.ts","../src/s3/object.ts","../src/dynamo/errors.ts","../src/ses/errors.ts","../src/rehype/flat-toc.ts","../src/utils/valibot.ts","../src/utils/object.ts","../src/utils/fs.ts"],"sourcesContent":["import type { ErrorBody, SuccessCode, ErrorCode } from './handlerUtils.js';\n\n// ----------------- Helpers ----------------------\n// Used to easily extract types from ApiEndpoints types\n\n/**\n * Extracts the requestInput type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiInput<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n E,\n { path: P; method: M }\n>['requestInput'];\n\n/**\n * Extracts the requestOutput type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiOutput<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n E,\n { path: P; method: M }\n>['requestOutput'];\n\n/**\n * Extracts the response type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiResponse<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n E,\n { path: P; method: M }\n>['response'];\n\n/**\n * Extracts the sucessful body type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiSuccessBody<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n Extract<E, { path: P; method: M }>['response'],\n { status: SuccessCode }\n>['json'] extends () => Promise<infer R>\n ? R\n : unknown;\n\n/**\n * Extracts the sucessful body type from an API endpoint definition\n * @template E - Union type of all API endpoints\n * @template P - Path string literal type (e.g. 'payments/account')\n * @template M - HTTP method string literal type (e.g. 'GET', 'POST')\n */\nexport type ApiErrorBody<E extends ApiEndpoints, P extends E['path'], M extends E['method']> = Extract<\n Extract<E, { path: P; method: M }>['response'],\n { status: ErrorCode }\n>['json'] extends () => Promise<infer R>\n ? R\n : unknown;\n\n/**\n * Converts a RawApiGatewayHandler response type to a fetch like response type.\n */\ntype ConvertToFetch<T> = T extends { statusCode: number; body: object; headers: object }\n ? { ok: T['statusCode'] extends SuccessCode ? true : false; json: () => Promise<T['body']>; status: T['statusCode'] }\n : T;\n\nexport type CleanResponse = Omit<Response, 'status' | 'ok' | 'json'>;\nexport type FetchResponse<T extends (...args: any) => any> = ConvertToFetch<Awaited<ReturnType<T>>> & CleanResponse;\n\n// ------------------------ Proper types ------------------\n// This is used by createApiRequest and createFormFunction\n\nexport const HTTPMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'] as const;\nexport type HTTPMethod = (typeof HTTPMethods)[number];\n\nexport type ApiEndpoints = {\n path: string;\n method: HTTPMethod;\n requestInput: Record<string, any> | null;\n requestOutput: object | null;\n response: FetchResponse<\n // This means we get better types\n () => Promise<\n | { headers: object; statusCode: SuccessCode; body: any }\n | { headers: object; statusCode: ErrorCode; body: ErrorBody }\n >\n >;\n};\n","// import { deserialize } from './deserializer.js';\nimport { parse } from 'devalue';\nimport * as v from 'valibot';\n\nimport type { ApiEndpoints, ApiInput, ApiResponse } from './client-types.js';\n\nconst bodyMethods = ['POST', 'PUT', 'PATCH'] as const;\nconst queryMethods = ['GET', 'DELETE'] as const;\n\nasync function _apiRequest<T = Response>(\n path: string,\n method: 'GET' | 'POST' | 'DELETE',\n input: object | null,\n schema: ApiSchema,\n // This was here because of the deserializer being different in prod\n environment: string | 'production',\n apiUrl: string,\n headers?: HeadersInit\n): Promise<T> {\n if (schema) {\n if (schema.async === true) v.parseAsync(schema, input);\n else v.parse(schema, input);\n }\n\n let url = `${apiUrl}${apiUrl.endsWith('/') ? '' : '/'}${path}`;\n\n if (queryMethods.includes(method as any)) {\n const params = input ?? {};\n const queryString = new URLSearchParams(\n Object.entries(params).reduce(\n (acc, [key, value]) => {\n if (Array.isArray(value)) {\n value.forEach((v) => (acc[key] = String(v)));\n } else {\n acc[key] = String(value);\n }\n return acc;\n },\n {} as Record<string, string>\n )\n ).toString();\n if (queryString) url += `?${queryString}`;\n }\n\n headers = { 'Content-Type': 'application/json', ...headers };\n const response = await fetch(url, {\n method,\n headers,\n // oxlint-disable-next-line\n body: bodyMethods.includes(method as any) ? JSON.stringify(input) : undefined,\n credentials: 'include'\n });\n const contentType = response.headers.get('content-type') ?? '';\n\n let retrieved: Promise<string> | false = false;\n response.json = async () => {\n if (retrieved === false) {\n retrieved = response.text();\n }\n\n if (contentType === 'application/devalue') {\n return await parse(await retrieved);\n } else {\n return JSON.parse(await retrieved);\n }\n };\n return response as unknown as T;\n}\n\nconst HTTPMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'] as const;\ntype HTTPMethod = (typeof HTTPMethods)[number];\n\nexport type ApiRequestFunction<API extends ApiEndpoints> = <\n Path extends API['path'],\n Method extends Extract<API, { path: Path }>['method']\n>(\n path: Path,\n method: Method,\n input: ApiInput<API, Path, Method>,\n headers?: HeadersInit\n) => Promise<ApiResponse<API, Path, Method>>;\n\nexport type ApiSchema = v.GenericSchema | v.GenericSchemaAsync;\n\n/**\n * @returns A function that can be used to make API requests with type safety\n * @example const clientApiRequest = createApiRequest<ApiEndpoints>();\n */\nexport function createApiRequest<API extends ApiEndpoints>(\n schemas: Partial<Record<API['path'], Partial<Record<HTTPMethod, ApiSchema>>>>,\n apiUrl: string,\n env: string\n): ApiRequestFunction<API> {\n return async function apiRequest(path, method, input, headers) {\n const schema = schemas[path]?.[method];\n if (schema === undefined) throw new Error('Schema is undefined in api request');\n\n // if (typeof schema === 'function') {\n // schema = schema();\n // }\n\n return _apiRequest<ApiResponse<API, typeof path, typeof method>>(\n path as string,\n method as 'GET' | 'POST',\n input,\n schema,\n env,\n apiUrl,\n headers\n );\n };\n}\n","import type { APIGatewayProxyResultV2, Context, APIGatewayProxyEventV2WithLambdaAuthorizer } from 'aws-lambda';\nimport { stringify } from 'devalue';\n\nexport type SuccessCode = 200 | 201 | 204;\nexport type ErrorCode = 400 | 401 | 403 | 404 | 409 | 500;\n\nexport type ErrorBody = { message: string; field?: { name: string; value: string } };\n\n/**\n * The error response for the lambda functions to return\n */\nexport type ErrorRawProxyResultV2 = {\n statusCode: ErrorCode;\n headers?: { [header: string]: string } | undefined;\n body?: ErrorBody;\n isBase64Encoded?: boolean | undefined;\n cookies?: string[] | undefined;\n};\n\nexport type OkRawProxyResultV2 = {\n statusCode: SuccessCode;\n headers?: { [header: string]: string } | undefined;\n body?: object | undefined;\n isBase64Encoded?: boolean | undefined;\n cookies?: string[] | undefined;\n};\n/**\n * A type for the raw proxy result - just using an object not a stirng for the body\n */\nexport type RawProxyResultV2 = ErrorRawProxyResultV2 | OkRawProxyResultV2;\n\n// The type of the handler returned from wrapHandler\nexport type APIGatewayHandler<E> = (event: E, context: Context) => Promise<APIGatewayProxyResultV2>;\n\n// The type of the handler passed into wrapHandler\nexport type RawApiGatewayHandler<E extends APIGatewayProxyEventV2WithLambdaAuthorizer<any>> = (\n event: E,\n context: Context\n) => Promise<RawProxyResultV2>;\n\n/**\n * Wraps a handler that returns the body as an object rather than a string.\n *\n * This means you can achieve proper type inference on your handler and have standardised serialisation\n *\n * @example\n```ts\nexport type AuthorizerContext = {\n details: JWTPayload;\n} | null;\n\nexport const wrapHandler = baseWrapHandler<APIGatewayProxyEventV2WithLambdaAuthorizer<AuthorizerContext>>\n\n*/\nexport function wrapHandler<E extends APIGatewayProxyEventV2WithLambdaAuthorizer<any>>(\n handler: RawApiGatewayHandler<E>\n): APIGatewayHandler<E> {\n return async (event: E, context: Context): Promise<APIGatewayProxyResultV2> => {\n const result = await handler(event, context);\n\n if (result.body) {\n const headers = new Headers(result.headers);\n headers.set('Content-Type', 'application/devalue');\n\n return { ...result, headers: Object.fromEntries(headers), body: stringify(result.body) };\n } else {\n return { ...result, body: undefined };\n }\n };\n}\n","/**\n * These are the various errors that should be returned from anything called by a lambda function.\n *\n * Pass a lambda error to the errorResponse function to get a suitable response to return from the lambda handler.\n *\n * The separation means that they can be returned from functions that are certainly run inside a lambda fucntion but theyre not the actual return of the lambda.\n * Im not sure it this is optimal behaviour and if not we will migrate to only using the errorResponse function\n */\n\nexport const error_lambda_badRequest = (message: string, fieldName?: string, fieldValue?: string) => ({\n type: 'lambda_badRequest' as const,\n message,\n fieldName,\n fieldValue\n});\nexport const error_lambda_unauthorized = (message: string) => ({ type: 'lambda_unauthorized' as const, message });\n\nexport const error_lambda_forbidden = (message: string) => ({ type: 'lambda_forbidden' as const, message });\n\nexport const error_lambda_notFound = (message: string, fieldName?: string, fieldValue?: string) => ({\n type: 'lambda_notFound' as const,\n message,\n fieldName,\n fieldValue\n});\n\nexport const error_lambda_conflict = (message: string, fieldName?: string, fieldValue?: string) => ({\n type: 'lambda_conflict' as const,\n message,\n fieldName,\n fieldValue\n});\n\nexport const error_lambda_internal = (message: string) => ({ type: 'lambda_internal' as const, message });\n\nexport type type_error_lambda_badRequest = ReturnType<typeof error_lambda_badRequest>;\nexport type type_error_lambda_unauthorized = ReturnType<typeof error_lambda_unauthorized>;\nexport type type_error_lambda_forbidden = ReturnType<typeof error_lambda_forbidden>;\nexport type type_error_lambda_notFound = ReturnType<typeof error_lambda_notFound>;\nexport type type_error_lambda_conflict = ReturnType<typeof error_lambda_conflict>;\nexport type type_error_lambda_internal = ReturnType<typeof error_lambda_internal>;\n\nexport type type_error_lambda =\n | type_error_lambda_badRequest\n | type_error_lambda_unauthorized\n | type_error_lambda_forbidden\n | type_error_lambda_notFound\n | type_error_lambda_conflict\n | type_error_lambda_internal;\n","import type { BaseIssue, SafeParseResult } from 'valibot';\n\nimport { error_lambda_badRequest, type type_error_lambda } from './errors.js';\nimport type { ErrorRawProxyResultV2, OkRawProxyResultV2 } from './handlerUtils.js';\n\nfunction field(obj: { fieldName?: string; fieldValue?: string }) {\n return obj.fieldName === undefined || obj.fieldValue === undefined\n ? {}\n : { field: { name: obj.fieldName, value: obj.fieldValue } };\n}\n\nexport type type_error_response = Omit<ErrorRawProxyResultV2, 'headers' | 'body'> & {\n headers: NonNullable<ErrorRawProxyResultV2['headers']>;\n body: NonNullable<ErrorRawProxyResultV2['body']>;\n};\n\nexport type LambdaErrorResponse<Type extends string = '', Extras extends object = {}> =\n | {\n headers: Record<string, string>;\n statusCode: 400;\n body: { message: string; type: Type } & ReturnType<typeof field> & Extras;\n }\n | { headers: Record<string, string>; statusCode: 401; body: { message: string; type: Type } & Extras }\n | { headers: Record<string, string>; statusCode: 403; body: { message: string; type: Type } & Extras }\n | {\n headers: Record<string, string>;\n statusCode: 404;\n body: { message: string; type: Type } & ReturnType<typeof field> & Extras;\n }\n | {\n headers: Record<string, string>;\n statusCode: 409;\n body: { message: string; type: Type } & ReturnType<typeof field> & Extras;\n }\n | { headers: Record<string, string>; statusCode: 500; body: { message: string; type: Type } & Extras };\n\nexport function response_error<Type extends string = '', Extras extends object = {}>(\n e: type_error_lambda,\n headers: Record<string, string>,\n type: Type = '' as Type,\n extras: Extras = {} as Extras\n): LambdaErrorResponse<Type, Extras> {\n switch (e.type) {\n case 'lambda_badRequest':\n return { headers, statusCode: 400, body: { message: e.message, type: type, ...field(e), ...extras } };\n\n case 'lambda_unauthorized':\n return { headers, statusCode: 401, body: { message: e.message, type: type, ...extras } };\n\n case 'lambda_forbidden':\n return { headers, statusCode: 403, body: { message: e.message, type: type, ...extras } };\n\n case 'lambda_notFound':\n return { headers, statusCode: 404, body: { message: e.message, type: type, ...field(e), ...extras } };\n\n case 'lambda_conflict':\n return { headers, statusCode: 409, body: { message: e.message, type: type, ...field(e), ...extras } };\n\n default:\n return { headers, statusCode: 500, body: { message: 'Unknown error', type: type, ...extras } };\n }\n}\n\n/**\n * Helper function to get a reasonable default error response from a valibot parse result\n * @param res - The output from calling safeParse on the input\n * @param headers - The headers to return in the response\n */\nexport function response_valibotError(res: Extract<SafeParseResult<any>, { success: false }>, headers: any) {\n const issue = res.issues[0] as BaseIssue<any>;\n\n if (issue.path && issue.path[0] && typeof issue.path[0].key === 'string') {\n return response_error(error_lambda_badRequest('Invalid input', issue.path[0].key, issue.message), headers);\n } else {\n return response_error(error_lambda_badRequest(`Invalid input: ${issue.message}`), headers);\n }\n}\n\nexport function response_ok<Body extends { message: string }>(\n body: Body,\n headers: any,\n cookies?: string[] | undefined\n) {\n return { headers, cookies, statusCode: 200 as const, body } satisfies OkRawProxyResultV2;\n}\n","import { error_lambda_unauthorized } from '$lambda/errors.js';\nimport type { APIGatewayProxyEventV2WithLambdaAuthorizer, APIGatewayRequestAuthorizerEventV2 } from 'aws-lambda';\nimport { parse } from 'cookie';\nimport { Result } from 'neverthrow';\n\n/**\n * Wraps cookies parse along with the api gateway event with neverthrow\n */\nexport const getCookies = Result.fromThrowable(\n (event: APIGatewayProxyEventV2WithLambdaAuthorizer<any> | APIGatewayRequestAuthorizerEventV2) => {\n if (!('headers' in event) || !event.headers) {\n throw new Error('No headers in event');\n }\n\n // First try to get cookies from the cookies array (API Gateway v2 format)\n const cookieString =\n Array.isArray(event.cookies) && event.cookies.length > 0\n ? event.cookies.join('; ')\n : event.headers.Cookie || event.headers.cookie;\n\n if (!cookieString) {\n throw new Error('No cookies found in event');\n }\n\n const res = parse(cookieString);\n return res;\n },\n (e) => {\n if (e instanceof Error) return error_lambda_unauthorized(e.message);\n return error_lambda_unauthorized('Invalid Cookies');\n }\n);\n","import { CognitoIdentityProviderClient } from '@aws-sdk/client-cognito-identity-provider';\n\n/**\n * Convenience function if process.env.AWS_REGION is set\n */\nexport function getCognitoClient() {\n return new CognitoIdentityProviderClient({\n // region: process.env.AWS_REGION\n // endpoint: `https://cognito-idp.${process.env.REGION}.amazonaws.com`\n });\n}\n","import {\n error_lambda_badRequest,\n error_lambda_conflict,\n error_lambda_internal,\n error_lambda_unauthorized,\n error_lambda_forbidden,\n error_lambda_notFound\n} from '$lambda/errors.js';\n\nexport const error_cognito_forbidden = { group: 'cognito' as const, type: 'cognito_forbidden' as const };\nexport const error_cognito_internal = { group: 'cognito' as const, type: 'cognito_internal' as const };\nexport const error_cognito_role = { group: 'cognito' as const, type: 'cognito_role' as const };\nexport const error_cognito_input = { group: 'cognito' as const, type: 'cognito_input' as const };\nexport const error_cognito_auth = { group: 'cognito' as const, type: 'cognito_auth' as const };\nexport const error_cognito_notFound = { group: 'cognito' as const, type: 'cognito_notFound' as const };\nexport const error_cognito_userNotFound = { group: 'cognito' as const, type: 'cognito_userNotFound' as const };\nexport const error_cognito_tooManyRequests = { group: 'cognito' as const, type: 'cognito_tooManyRequests' as const };\nexport const error_cognito_passwordPolicy = { group: 'cognito' as const, type: 'cognito_passwordPolicy' as const };\nexport const error_cognito_passwordHistory = { group: 'cognito' as const, type: 'cognito_passwordHistory' as const };\nexport const error_cognito_passwordResetRequired = {\n group: 'cognito' as const,\n type: 'cognito_passwordResetRequired' as const\n};\n\n// Confirm forgot password\nexport const error_cognito_codeExpired = { group: 'cognito' as const, type: 'cognito_codeExpired' as const };\nexport const error_cognito_codeMismatch = { group: 'cognito' as const, type: 'cognito_codeMismatch' as const };\n\n// Forgot password\nexport const error_cognito_delivery = { group: 'cognito' as const, type: 'cognito_delivery' as const };\n// Confirm signup\nexport const error_cognito_userExists = { group: 'cognito' as const, type: 'cognito_userExists' as const };\n\nexport type type_error_cognito_forbidden = typeof error_cognito_forbidden;\nexport type type_error_cognito_internal = typeof error_cognito_internal;\nexport type type_error_cognito_role = typeof error_cognito_role;\nexport type type_error_cognito_input = typeof error_cognito_input;\nexport type type_error_cognito_auth = typeof error_cognito_auth;\nexport type type_error_cognito_notFound = typeof error_cognito_notFound;\nexport type type_error_cognito_userNotFound = typeof error_cognito_userNotFound;\nexport type type_error_cognito_tooManyRequests = typeof error_cognito_tooManyRequests;\nexport type type_error_cognito_passwordPolicy = typeof error_cognito_passwordPolicy;\nexport type type_error_cognito_passwordHistory = typeof error_cognito_passwordHistory;\nexport type type_error_cognito_passwordResetRequired = typeof error_cognito_passwordResetRequired;\nexport type type_error_cognito_codeExpired = typeof error_cognito_codeExpired;\nexport type type_error_cognito_codeMismatch = typeof error_cognito_codeMismatch;\nexport type type_error_cognito_delivery = typeof error_cognito_delivery;\nexport type type_error_cognito_userExists = typeof error_cognito_userExists;\n\nexport type type_error_cognito =\n | type_error_cognito_forbidden\n | type_error_cognito_internal\n | type_error_cognito_role\n | type_error_cognito_input\n | type_error_cognito_auth\n | type_error_cognito_notFound\n | type_error_cognito_userNotFound\n | type_error_cognito_tooManyRequests\n | type_error_cognito_passwordPolicy\n | type_error_cognito_passwordHistory\n | type_error_cognito_passwordResetRequired\n | type_error_cognito_codeExpired\n | type_error_cognito_codeMismatch\n | type_error_cognito_delivery\n | type_error_cognito_userExists;\n\nconst awsToCognitoErrorMap = {\n ForbiddenException: error_cognito_forbidden,\n NotAuthorizedException: error_cognito_auth,\n UserNotConfirmedException: error_cognito_auth,\n UserNotFoundException: error_cognito_userNotFound,\n ResourceNotFoundException: error_cognito_notFound,\n InvalidParameterException: error_cognito_input,\n InvalidPasswordException: error_cognito_passwordPolicy,\n PasswordHistoryPolicyViolationException: error_cognito_passwordHistory,\n PasswordResetRequiredException: error_cognito_passwordResetRequired,\n LimitExceededException: error_cognito_tooManyRequests,\n TooManyRequestsException: error_cognito_tooManyRequests,\n InternalErrorException: error_cognito_internal,\n // Confirm forgot password\n CodeMismatchException: error_cognito_codeMismatch,\n ExpiredCodeException: error_cognito_codeExpired,\n TooManyFailedAttemptsException: error_cognito_tooManyRequests,\n UnexpectedLambdaException: error_cognito_internal,\n InvalidLambdaResponseException: error_cognito_internal,\n UserLambdaValidationException: error_cognito_internal,\n // Forgot password\n InvalidEmailRoleAccessPolicyException: error_cognito_role,\n InvalidSmsRoleAccessPolicyException: error_cognito_role,\n InvalidSmsRoleTrustRelationshipException: error_cognito_role,\n CodeDelliveryFailureException: error_cognito_delivery,\n // Confirm signup\n AliasExistsException: error_cognito_userExists,\n // Login\n InvalidUserPoolConfigurationException: error_cognito_internal,\n MFAMethodNotFoundException: error_cognito_notFound,\n UnsupportedOperationException: error_cognito_internal,\n // Reset password\n SoftwareTokenMFANotFoundException: error_cognito_notFound,\n // Sign up\n UsernameExistsException: error_cognito_userExists\n} as const;\n\n/**\n * Gets a generic error from the name of the aws error\n */\nexport function error_cognito(error: Error): type_error_cognito {\n const type = error.name as keyof typeof awsToCognitoErrorMap;\n if (awsToCognitoErrorMap[type] === undefined) console.warn(`${type} is not present in the cognito error map`);\n\n console.error(`Cognito error: ${type}`, error);\n\n return awsToCognitoErrorMap[type] || error_cognito_internal;\n}\n\n/**\n * Converts a cognito error to a lambda error.\n * Basically just for narrowing it down a bit\n */\nexport function error_lambda_fromCognito(e: type_error_cognito) {\n switch (e.type) {\n case 'cognito_auth':\n return error_lambda_unauthorized('Not authorized');\n case 'cognito_forbidden':\n return error_lambda_forbidden('Forbidden');\n case 'cognito_internal':\n case 'cognito_role':\n return error_lambda_internal('Internal server error');\n case 'cognito_input':\n return error_lambda_badRequest('There is an issue with your request');\n case 'cognito_notFound':\n return error_lambda_notFound('Resource not found');\n case 'cognito_userNotFound':\n return error_lambda_notFound('User not found');\n case 'cognito_tooManyRequests':\n return error_lambda_badRequest('Too many requests');\n case 'cognito_passwordPolicy':\n return error_lambda_badRequest('Password does not meet policy requirements');\n case 'cognito_passwordHistory':\n return error_lambda_conflict('Password was used recently');\n case 'cognito_passwordResetRequired':\n return error_lambda_badRequest('Password reset required');\n case 'cognito_delivery':\n return error_lambda_internal('Delivery failed for the provided email or phone number');\n default:\n return error_lambda_internal('Unknown error');\n }\n}\n","import type {\n AdminGetUserCommandOutput,\n AttributeType,\n CognitoIdentityProviderServiceException\n} from '@aws-sdk/client-cognito-identity-provider';\nimport { AdminGetUserCommand, AdminListGroupsForUserCommand } from '@aws-sdk/client-cognito-identity-provider';\nimport { ResultAsync } from 'neverthrow';\n\nimport { getCognitoClient } from './client.js';\nimport { error_cognito } from './errors.js';\n\nexport type type_userResponse = Omit<AdminGetUserCommandOutput, 'UserAttributes'> & {\n UserAttributes: Record<string, string>;\n};\n\n/**\n * Performs an AdminGetUserCommand and extracts the user attributes into an object\n */\nexport const getUserDetails = ResultAsync.fromThrowable(\n async (a: { username: string; userPoolId: string }) => {\n console.log('getUserDetails: Getting details for user: ', a.username);\n const cognitoClient = getCognitoClient();\n const res = await cognitoClient.send(new AdminGetUserCommand({ UserPoolId: a.userPoolId, Username: a.username }));\n return { ...res, UserAttributes: extractAttributes(res.UserAttributes) } as type_userResponse;\n },\n (e) => {\n console.error('getUserDetails:error:', e);\n return error_cognito(e as CognitoIdentityProviderServiceException);\n }\n);\n\n/**\n * @returns An object of attributes with their names as keys and values as values.\n */\nexport function extractAttributes(attrs: AttributeType[] | undefined) {\n const attributes: Record<string, string> = {};\n if (attrs) {\n for (const attr of attrs) {\n if (attr.Name && attr.Value) {\n attributes[attr.Name] = attr.Value;\n }\n }\n }\n return attributes;\n}\n\n/**\n * Performs an AdminGetUserCommand and extracts the user attributes into an object\n */\nexport const getUserGroups = ResultAsync.fromThrowable(\n async (a: { username: string; userPoolId: string }) => {\n console.log('getUserGroups: Getting groups for user: ', a.username);\n const cognitoClient = getCognitoClient();\n const res = await cognitoClient.send(\n new AdminListGroupsForUserCommand({ UserPoolId: a.userPoolId, Username: a.username })\n );\n return res;\n },\n (e) => {\n console.error('getUserGroups:error:', e);\n return error_cognito(e as CognitoIdentityProviderServiceException);\n }\n);\n","import { createHmac } from 'crypto';\n\nimport {\n AdminInitiateAuthCommand,\n ChangePasswordCommand,\n ConfirmForgotPasswordCommand,\n ConfirmSignUpCommand,\n ForgotPasswordCommand,\n GlobalSignOutCommand,\n RespondToAuthChallengeCommand,\n SignUpCommand\n} from '@aws-sdk/client-cognito-identity-provider';\nimport { ResultAsync } from 'neverthrow';\n\nimport { getCognitoClient } from './client.js';\nimport type { type_error_cognito } from './errors.js';\nimport { error_cognito, error_cognito_auth } from './errors.js';\n\n/**\n * Computes Cognito secret hash used for client-side authentication flows.\n *\n * @param username - Cognito username or alias.\n * @param clientId - Cognito app client ID.\n * @param clientSecret - Cognito app client secret.\n */\nexport function computeSecretHash(username: string, clientId: string, clientSecret: string): string {\n console.log('computeSecretHash: ', username, clientId, clientSecret);\n return createHmac('SHA256', clientSecret)\n .update(username + clientId)\n .digest('base64');\n}\n\n// ---- Change password ---- //\n\n/**\n * Changes a user's password given a valid access token.\n *\n * @param accessToken - Access token for the authenticated user.\n * @param oldPassword - Current password.\n * @param newPassword - New password to set.\n */\nexport const changePassword = ResultAsync.fromThrowable(\n async (accessToken: string, oldPassword: string, newPassword: string) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new ChangePasswordCommand({\n AccessToken: accessToken,\n PreviousPassword: oldPassword,\n ProposedPassword: newPassword\n })\n );\n },\n (e) => {\n console.error('ChangePasswordCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Confirm Forgot password ---- //\n\n/**\n * Completes a forgot-password flow by submitting the confirmation code and new password.\n *\n * @param a.username - Cognito username or alias.\n * @param a.confirmationCode - Code sent by Cognito to the user.\n * @param a.newPassword - New password to set.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n */\nexport const confirmForgotPassword = ResultAsync.fromThrowable(\n (a: { username: string; confirmationCode: string; newPassword: string; clientId: string; clientSecret: string }) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new ConfirmForgotPasswordCommand({\n ClientId: a.clientId,\n Username: a.username,\n ConfirmationCode: a.confirmationCode,\n Password: a.newPassword,\n SecretHash: computeSecretHash(a.username, a.clientId, a.clientSecret)\n })\n );\n },\n (e) => {\n console.error('ConfirmForgotPasswordCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Confirm Signup ---- //\n\n/**\n * Confirms a user's signup using the confirmation code sent by Cognito.\n *\n * @param a.username - Cognito username or alias.\n * @param a.confirmationCode - Code sent to the user after signup.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n */\nexport const confirmSignup = ResultAsync.fromThrowable(\n (a: { username: string; confirmationCode: string; clientId: string; clientSecret: string }) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new ConfirmSignUpCommand({\n ClientId: a.clientId,\n Username: a.username,\n ConfirmationCode: a.confirmationCode,\n SecretHash: computeSecretHash(a.username, a.clientId, a.clientSecret)\n })\n );\n },\n (e) => {\n console.error('ConfirmSignUpCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Forgot password ---- //\n\n/**\n * Starts a forgot-password flow by sending a reset code to the user.\n *\n * @param a.username - Cognito username or alias.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n */\nexport const forgotPassword = ResultAsync.fromThrowable(\n (a: { username: string; clientId: string; clientSecret: string }) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new ForgotPasswordCommand({\n ClientId: a.clientId,\n Username: a.username,\n SecretHash: computeSecretHash(a.username, a.clientId, a.clientSecret)\n })\n );\n },\n (e) => {\n console.error('ForgotPasswordCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Login ---- //\n\n/**\n * Signs a user in with ADMIN_USER_PASSWORD_AUTH.\n *\n * @param a.username - Cognito username or alias.\n * @param a.password - User password.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n * @param a.userPoolId - Cognito user pool ID.\n */\nexport const login = ResultAsync.fromThrowable(\n (a: { username: string; password: string; clientId: string; clientSecret: string; userPoolId: string }) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new AdminInitiateAuthCommand({\n AuthFlow: 'ADMIN_USER_PASSWORD_AUTH',\n ClientId: a.clientId,\n UserPoolId: a.userPoolId,\n AuthParameters: {\n USERNAME: a.username,\n PASSWORD: a.password,\n SECRET_HASH: computeSecretHash(a.username, a.clientId, a.clientSecret)\n }\n })\n );\n },\n (e) => {\n console.error('AdminInitiateAuthCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Refresh token ---- //\n\n/**\n * Exchanges a refresh token for new tokens.\n *\n * @param a.username - Cognito username or alias used to compute secret hash.\n * @param a.refreshToken - Refresh token to exchange.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n * @param a.userPoolId - Cognito user pool ID.\n */\nexport const refreshTokens = ResultAsync.fromThrowable(\n (a: { username: string; refreshToken: string; clientId: string; clientSecret: string; userPoolId: string }) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new AdminInitiateAuthCommand({\n AuthFlow: 'REFRESH_TOKEN_AUTH',\n ClientId: a.clientId,\n UserPoolId: a.userPoolId,\n AuthParameters: {\n REFRESH_TOKEN: a.refreshToken,\n SECRET_HASH: computeSecretHash(a.username, a.clientId, a.clientSecret)\n }\n })\n );\n },\n (e) => {\n console.error('refreshTokens: AdminInitiateAuthCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Logout ---- //\n/**\n * Globally signs out a user by invalidating all refresh tokens.\n *\n * @param accessToken - Access token for the authenticated user.\n */\nexport const logout = ResultAsync.fromThrowable(\n (accessToken: string) => {\n const cognitoClient = getCognitoClient();\n // GlobalSignOut invalidates all refresh tokens associated with user\n return cognitoClient.send(new GlobalSignOutCommand({ AccessToken: accessToken }));\n },\n (e) => {\n console.error('GlobalSignOutCommand error', e);\n return error_cognito(e as Error);\n }\n);\n\n// ---- Reset password ---- //\n/**\n * Completes a NEW_PASSWORD_REQUIRED challenge for users who must set a new password.\n *\n * @param a.session - Session returned from the auth challenge.\n * @param a.newPassword - New password to set.\n * @param a.username - Cognito username or alias.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n */\nexport const resetPassword = ResultAsync.fromThrowable(\n (a: { session: string; newPassword: string; username: string; clientId: string; clientSecret: string }) => {\n const cognitoClient = getCognitoClient();\n return cognitoClient.send(\n new RespondToAuthChallengeCommand({\n ChallengeName: 'NEW_PASSWORD_REQUIRED',\n ClientId: a.clientId,\n Session: a.session,\n ChallengeResponses: {\n SECRET_HASH: computeSecretHash(a.username, a.clientId, a.clientSecret),\n NEW_PASSWORD: a.newPassword,\n USERNAME: a.username\n }\n })\n );\n },\n (e) => {\n console.error('RespondToAuthChallengeCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Sign up ---- //\n/**\n * Registers a new user with Cognito and optional custom attributes.\n *\n * @param a.username - Cognito username.\n * @param a.password - User password.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret.\n * @param a.<attribute> - Any additional user attributes to set.\n */\nexport const signUp = ResultAsync.fromThrowable(\n (a: { username: string; password: string; clientId: string; clientSecret: string } & Record<string, unknown>) => {\n const cognitoClient = getCognitoClient();\n const secretHash = computeSecretHash(a.username, a.clientId, a.clientSecret);\n\n return cognitoClient.send(\n new SignUpCommand({\n ClientId: a.clientId,\n Username: a.username,\n Password: a.password,\n SecretHash: secretHash,\n UserAttributes: Object.entries(a)\n .filter(([key]) => !['username', 'password', 'clientId', 'clientSecret'].includes(key))\n .map(([key, value]) => ({ Name: key, Value: value as string }))\n })\n );\n },\n (e) => {\n console.error('SignUpCommand error', e);\n return error_cognito(e as Error) as type_error_cognito;\n }\n);\n\n// ---- Federated ---- //\n/**\n * Exchanges an OAuth2 authorization code for Cognito tokens using the token endpoint.\n * See https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html for request/response fields and grant details.\n *\n * @param a.code - Authorization code returned by the hosted UI.\n * @param a.redirectUri - Redirect URI registered with the app client.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret used for Basic Auth.\n * @param a.cognitoDomain - Cognito domain URL (e.g., your-domain.auth.region.amazoncognito.com).\n * @returns Parsed token payload containing `access_token`, `id_token`, `refresh_token`, token type, and expiry.\n */\nexport const verifyOAuthToken = ResultAsync.fromThrowable(\n async (a: { code: string; redirectUri: string; clientId: string; clientSecret: string; cognitoDomain: string }) => {\n const basicAuth = Buffer.from(`${a.clientId}:${a.clientSecret}`).toString('base64');\n\n const params = new URLSearchParams();\n params.append('grant_type', 'authorization_code');\n params.append('code', a.code);\n params.append('redirect_uri', a.redirectUri);\n\n // params.append('client_id', a.clientId);\n\n console.log('verifyOAuthToken: params', params.toString());\n\n const tokenRes = await fetch(`https://${a.cognitoDomain}/oauth2/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded', Authorization: `Basic ${basicAuth}` },\n body: params.toString()\n });\n if (!tokenRes.ok) {\n console.error('verifyOAuthToken: token exchange failed', await tokenRes.text());\n throw new Error('');\n }\n\n return (await tokenRes.json()) as {\n access_token: string;\n id_token: string;\n refresh_token: string;\n token_type: string;\n expires_in: number;\n };\n },\n (e) => {\n console.error('verifyOAuthToken:error', e);\n return error_cognito_auth;\n }\n);\n\n/**\n * Exchanges an OAuth2 refresh token for Cognito tokens using the oauth token endpoint.\n * See https://docs.aws.amazon.com/cognito/latest/developerguide/token-endpoint.html for request/response fields and grant details.\n *\n * @param a.redirectUri - Redirect URI registered with the app client.\n * @param a.clientId - Cognito app client ID.\n * @param a.clientSecret - Cognito app client secret used for Basic Auth.\n * @param a.cognitoDomain - Cognito domain URL (e.g., your-domain.auth.region.amazoncognito.com).\n * @returns Parsed token payload containing `access_token`, `id_token`, `refresh_token`, token type, and expiry.\n */\nexport const refreshOAuthToken = ResultAsync.fromThrowable(\n async (a: { clientId: string; clientSecret: string; cognitoDomain: string; refreshToken: string }) => {\n const basicAuth = Buffer.from(`${a.clientId}:${a.clientSecret}`).toString('base64');\n\n const params = new URLSearchParams();\n params.append('grant_type', 'refresh_token');\n params.append('refresh_token', a.refreshToken);\n\n console.log('refreshOAuthToken: params', params.toString());\n\n const tokenRes = await fetch(`https://${a.cognitoDomain}/oauth2/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded', Authorization: `Basic ${basicAuth}` },\n body: params.toString()\n });\n if (!tokenRes.ok) {\n console.error('refreshOAuthToken: token exchange failed', await tokenRes.text());\n throw new Error('');\n }\n\n return (await tokenRes.json()) as {\n access_token: string;\n id_token: string;\n refresh_token: string | undefined;\n token_type: string;\n expires_in: number;\n };\n },\n (e) => {\n console.error('refreshOAuthToken:error', e);\n return error_cognito_auth;\n }\n);\n","import { S3Client } from '@aws-sdk/client-s3';\n\n/**\n * Convenience function for S3Client when process.env.REGION is set\n */\nexport function getS3() {\n return new S3Client({\n // endpoint: `https://s3.${process.env.REGION}.amazonaws.com`,\n // region: process.env.REGION\n });\n}\n","export const error_s3_internal = { type: 's3_internal' as const };\nexport const error_s3_get = { type: 's3_get' as const };\n\nexport type type_error_s3_internal = typeof error_s3_internal;\nexport type type_error_s3_get = typeof error_s3_get;\n","import { getSignedUrl as baseGetSignedUrl } from '@aws-sdk/s3-request-presigner';\nimport { ResultAsync } from 'neverthrow';\n\nexport const getSignedUrl = ResultAsync.fromThrowable(baseGetSignedUrl, (e) => e);\n","import { HeadObjectCommand, GetObjectCommand } from '@aws-sdk/client-s3';\nimport { ResultAsync } from 'neverthrow';\n\nimport { getS3 } from './client.js';\nimport { error_s3_get } from './errors.js';\n\n/**\n * Retrieves an object from an S3 bucket.\n *\n * @param {string} bucketName - The name of the S3 bucket.\n * @param {string} key - The key of the object to retrieve.\n * @returns {Promise<Buffer>} A promise that resolves to the object data as a Buffer.\n */\nexport const getObject = ResultAsync.fromThrowable(\n async (bucketName: string, key: string) => {\n const s3 = getS3();\n const cmd = new GetObjectCommand({ Bucket: bucketName, Key: key });\n const res = await s3.send(cmd);\n const stream = res.Body as any;\n return new Promise<Buffer>((resolve, reject) => {\n const chunks: Buffer[] = [];\n stream.on('data', (chunk: Buffer) => chunks.push(chunk));\n stream.on('end', () => resolve(Buffer.concat(chunks)));\n stream.on('error', reject);\n });\n },\n (e) => {\n console.error(`Error getting object from S3: ${e}`);\n return error_s3_get;\n }\n);\n\n/**\n * Convenience function to get an object from S3 and return it as a string.\n */\nexport function getObjectString(bucketName: string, key: string): ResultAsync<string, typeof error_s3_get> {\n return getObject(bucketName, key).map((buffer) => buffer.toString('utf-8'));\n}\n\n/**\n * Checks if an object exists in an s3 bucket by retrieving the HEAD data\n *\n * @param {string} bucketName - The name of the S3 bucket.\n * @param {string} key - The key of the object to retrieve.\n * @returns {Promise<Buffer>} A promise that resolves to a boolean.\n */\nexport const objectExists = ResultAsync.fromThrowable(\n async (bucketName: string, key: string) => {\n const s3 = getS3();\n\n try {\n const cmd = new HeadObjectCommand({ Bucket: bucketName, Key: key });\n const res = await s3.send(cmd);\n return res.$metadata.httpStatusCode === 200;\n } catch (e) {\n if ((e as any).$metadata.httpStatusCode === 404) {\n return false;\n } else throw e;\n }\n },\n (e) => {\n console.error(`Error getting object head from S3: ${e}`);\n return error_s3_get;\n }\n);\n","import { error_lambda_internal } from '$lambda/errors.js';\n\nexport const error_dynamo = { type: 'dynamo' as const };\n\nexport type type_error_dynamo = typeof error_dynamo;\n\nexport function error_lambda_fromDynamo(_e: type_error_dynamo) {\n return error_lambda_internal('Internal server error');\n}\n","export const error_ses = { type: 'ses' as const };\n","import type { Root, RootContent, Element } from 'hast';\nimport rehypeParse from 'rehype-parse';\nimport type { Plugin } from 'unified';\nimport { unified } from 'unified';\nimport type { VFile } from 'vfile';\n\n/**\n * This rehype plugin extracts the headings from the markdown elements but also the raw elements.\n * So we get html headings in the TOC as well\n *\n * It sets the file.data.fm.toc to a flat map of the toc\n */\nexport const extractToc: Plugin<[], Root> = () => {\n return (tree: Root, file: VFile) => {\n const details = tree.children.flatMap(extractDetails);\n if (file.data.fm === undefined) file.data.fm = {};\n // @ts-expect-error its untyped but for svmdex it is there\n file.data.fm.toc = details;\n };\n};\nexport type Toc = TocEntry[];\nexport type TocEntry = { level: number; id: string; value: string };\n\nfunction extractDetails(content: RootContent | { type: 'raw'; value: string }): TocEntry[] {\n if (content.type === 'element' && content.tagName.startsWith('h') && 'id' in content.properties) {\n const value =\n content.children.length === 1 && content.children[0].type === 'text'\n ? content.children[0].value\n : (content.properties.id as string);\n\n return [{ level: parseInt(content.tagName.slice(1)), id: content.properties.id as string, value }];\n } else if (content.type === 'raw') {\n const parsed = parseRaw(content.value);\n return parsed.flatMap(extractDetails);\n }\n return [];\n}\n\n/**\n * Parses raw HTML and returns a flat array of all heading (h1-h6) elements as HAST nodes.\n */\nexport function parseRaw(raw: string): Element[] {\n // Parse the HTML string into a HAST Root node\n const tree = unified()\n .use(rehypeParse, { fragment: true }) // allow parsing HTML fragments\n .parse(raw) as Root;\n\n // Helper function to recursively find heading elements\n function collectHeadings(node: RootContent): Element[] {\n if (node.type === 'element' && /^h[1-6]$/.test(node.tagName)) {\n return [node];\n }\n // Check children recursively\n if ('children' in node && Array.isArray(node.children)) {\n return node.children.flatMap(collectHeadings);\n }\n return [];\n }\n\n // Flatten all headings found in the tree\n return tree.children.flatMap(collectHeadings);\n}\n","import type { GenericSchema, GenericSchemaAsync } from 'valibot';\n\nexport function isSchema(x: unknown): x is GenericSchema {\n return !!x && typeof x === 'object' && 'kind' in x && x['kind'] === 'schema';\n}\n\nexport function unwrap(schema: GenericSchema): GenericSchema {\n // Unwrap common wrappers that simply contain another schema under `wrapped`\n // optional | exactOptional | undefinedable | nullable | nullish | nonNullable | nonNullish | readonly | brand | description | metadata | title | flavor\n // Most of these share `{ type: string; wrapped: GenericSchema }`\n // Guarded unwrap to avoid infinite loops.\n let curr: any = schema as any;\n const seen = new Set<any>();\n while (curr && typeof curr === 'object' && !seen.has(curr) && 'wrapped' in curr && isSchema((curr as any).wrapped)) {\n seen.add(curr);\n curr = (curr as any).wrapped;\n }\n return curr as GenericSchema;\n}\n\nfunction isIntegerKey(s: string): boolean {\n // allow \"0\", \"01\" etc. to index tuples/arrays consistently\n return /^-?\\d+$/.test(s);\n}\n\nexport type GetSchemaByPathOptions = {\n /**\n * When a union/variant cannot be narrowed by the path segment,\n * choose index `preferOption` (default 0). Set to -1 to return undefined instead.\n */\n preferOption?: number;\n};\n\nexport function getSchemaByPath(\n root: GenericSchema | GenericSchemaAsync,\n path: string,\n opts: GetSchemaByPathOptions = {}\n): GenericSchema | undefined {\n if (!isSchema(root)) return undefined;\n if (!path) return root;\n\n const keys = path.split('.');\n let curr: GenericSchema | undefined = root;\n\n for (let i = 0; i < keys.length; i++) {\n if (!curr) return undefined;\n curr = unwrap(curr);\n const seg = keys[i];\n\n // Narrow by schema \"type\"\n const type = (curr as any).type as string | undefined;\n\n switch (type) {\n case 'object': {\n // ObjectSchema has `.entries`\n const entries = (curr as any).entries as Record<string, GenericSchema> | undefined;\n if (!entries) return undefined;\n curr = entries[seg];\n break;\n }\n\n case 'record': {\n // RecordSchema has `.value` for any key\n const value = (curr as any).value as GenericSchema | undefined;\n curr = value;\n break;\n }\n\n case 'array': {\n // ArraySchema has `.item`\n if (!isIntegerKey(seg)) return undefined;\n const item = (curr as any).item as GenericSchema | undefined;\n curr = item;\n break;\n }\n\n case 'tuple': {\n // TupleSchema has `.items` and possibly `.rest`\n if (!isIntegerKey(seg)) return undefined;\n const idx = Number(seg);\n const items = (curr as any).items as GenericSchema[] | undefined;\n const rest = (curr as any).rest as GenericSchema | undefined;\n if (!items) return undefined;\n curr = idx < items.length ? items[idx] : rest;\n break;\n }\n\n case 'union': {\n // UnionSchema has `.options` (array of schemas)\n const options = (curr as any).options as GenericSchema[] | undefined;\n if (!options?.length) return undefined;\n\n // Try to narrow by segment:\n // - if numeric seg: prefer array/tuple options\n // - if string seg: prefer object/record options that contain seg\n const numeric = isIntegerKey(seg);\n\n let next: GenericSchema | undefined;\n\n if (numeric) {\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n return u?.type === 'array' || u?.type === 'tuple';\n }) ?? options[opts.preferOption ?? 0];\n } else {\n // Prefer object/record with matching key\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n if (u?.type === 'object') {\n const ent = u.entries as Record<string, GenericSchema> | undefined;\n return !!ent && seg in ent;\n }\n return u?.type === 'record';\n }) ?? options[opts.preferOption ?? 0];\n }\n\n curr = next;\n // Loop continues to use seg against selected option\n i--; // reprocess this segment against the chosen branch\n break;\n }\n\n case 'variant': {\n // Variant (discriminated union) has `.options` too\n const options = (curr as any).options as GenericSchema[] | undefined;\n if (!options?.length) return undefined;\n // Same narrowing as union\n const numeric = isIntegerKey(seg);\n let next: GenericSchema | undefined;\n if (numeric) {\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n return u?.type === 'array' || u?.type === 'tuple';\n }) ?? options[opts.preferOption ?? 0];\n } else {\n next =\n options.find((o) => {\n const u = unwrap(o) as any;\n if (u?.type === 'object') {\n const ent = u.entries as Record<string, GenericSchema> | undefined;\n return !!ent && seg in ent;\n }\n return u?.type === 'record';\n }) ?? options[opts.preferOption ?? 0];\n }\n curr = next;\n i--;\n break;\n }\n\n default: {\n // If it’s a pipeline schema (`pipe`) or similar wrapper, many expose `.wrapped` and are handled by unwrap.\n // If we end up at a primitive or unknown structure while keys remain, fail.\n return undefined;\n }\n }\n }\n\n return curr ? unwrap(curr) : undefined;\n}\n","import { isEqual, isObject } from 'radash';\n\nimport type { DeepPartial } from '../types/deep.js';\n\n/**\n * Sets the value for an object by its dot path\n * @param obj - any object\n * @param path - the dot path eg. key1.0.1.key2\n * @param value - any value\n * @returns - the modified object\n */\nexport function setByPath<T extends object>(obj: T, path: string, value: any): T {\n const keys = path.split('.');\n let curr: any = obj;\n\n for (let i = 0; i < keys.length - 1; i++) {\n const k = keys[i];\n const next = keys[i + 1];\n // handle array indices like '0'\n if (Number.isInteger(Number(next))) {\n curr[k] ??= [];\n } else {\n curr[k] ??= {};\n }\n curr = curr[k];\n }\n\n curr[keys[keys.length - 1]] = value;\n return obj;\n}\n\n/**\n * Gets the value from an object by its dot path\n * @param obj - any object\n * @param path - the dot path eg. key1.0.1.key2\n * @returns - the value at the given path or undefined\n */\nexport function getByPath<T extends object>(obj: T, path: string): any {\n if (!obj || typeof obj !== 'object') return undefined;\n const keys = path.split('.');\n let curr: any = obj;\n\n for (const k of keys) {\n if (curr == null) return undefined;\n curr = curr[k];\n }\n\n return curr;\n}\n\nconst isPlainRecord = (v: unknown): v is Record<string, unknown> => isObject(v) && !Array.isArray(v);\n\n/**\n * Returns a deep \"patch\" object containing only the fields from `b`\n * that are different from `a`.\n *\n * Behavior:\n * - Only keys from `b` can appear in the result.\n * - New keys in `b` are included.\n * - Changed primitive/array values are included as the value from `b`.\n * - For nested plain objects, it recurses and returns only the differing nested fields.\n * - Arrays are treated as atomic (if different, the whole array from `b` is returned).\n *\n * Typing:\n * - Output is `DeepPartial<B>` because only a subset of `b`'s shape is returned.\n *\n * @template A\n * @template B\n * @param {A} a - Base/original object (can be a different shape than `b`).\n * @param {B} b - Updated object; output keys come from this object.\n * @returns {DeepPartial<B>} Deep partial of `b` containing only differences vs `a`.\n */\nexport const deepDiff = <A extends object, B extends object>(a: A, b: B): DeepPartial<B> => {\n const out: Record<string, unknown> = {};\n\n for (const key of Object.keys(b) as Array<keyof B>) {\n const aVal = (a as any)?.[key];\n const bVal = (b as any)[key];\n\n if (!((key as any) in (a as any))) {\n out[key as any] = bVal;\n continue;\n }\n\n if (isPlainRecord(aVal) && isPlainRecord(bVal)) {\n const nested = deepDiff(aVal, bVal);\n if (Object.keys(nested as any).length) out[key as any] = nested;\n continue;\n }\n\n if (!isEqual(aVal, bVal)) out[key as any] = bVal;\n }\n\n return out as DeepPartial<B>;\n};\n\n/**\n * Deeply prunes `source` to match the *shape* of `shape`.\n *\n * Rules:\n * - Only keys that exist on `shape` are kept.\n * - Pruning is deep for nested plain objects.\n * - Arrays are supported by using the first element of `shape` as the element-shape.\n * - If `shape` is `[]`, returns `[]` (drops all elements).\n * - Primitive values are kept as-is (no type coercion) if the key exists in `shape`.\n * - If `shape` expects an object/array but `source` is not compatible, returns an empty object/array of that shape.\n *\n * @typeParam S - Source object type.\n * @typeParam Sh - Shape object type.\n * @param source - The object to prune.\n * @param shape - The object whose keys/structure are the allowlist.\n * @returns A new value derived from `source`, containing only fields present in `shape`, pruned deeply.\n *\n * @example\n * const source = { a: 1, b: { c: 2, d: 3 }, e: [ { x: 1, y: 2 }, { x: 3, y: 4 } ], z: 9 };\n * const shape = { a: 0, b: { c: 0 }, e: [ { x: 0 } ] };\n * // => { a: 1, b: { c: 2 }, e: [ { x: 1 }, { x: 3 } ] }\n * const out = pruneToShape(source, shape);\n */\nexport function pruneToShape<S, Sh>(source: S, shape: Sh): Sh {\n return pruneAny(source as unknown, shape as unknown) as Sh;\n\n function pruneAny(src: unknown, sh: unknown): unknown {\n // Arrays: use first element as the \"element shape\"\n if (Array.isArray(sh)) {\n if (!Array.isArray(src)) return [];\n if (sh.length === 0) return [];\n const elemShape = sh[0];\n return src.map((v) => pruneAny(v, elemShape));\n }\n\n // Plain objects: keep only keys present on shape, recursively.\n if (isPlainObject(sh)) {\n const out: Record<string, unknown> = {};\n const srcObj = isPlainObject(src) ? (src as Record<string, unknown>) : undefined;\n\n for (const key of Object.keys(sh as Record<string, unknown>)) {\n const shVal = (sh as Record<string, unknown>)[key];\n const srcVal = srcObj ? srcObj[key] : undefined;\n\n if (Array.isArray(shVal) || isPlainObject(shVal)) {\n out[key] = pruneAny(srcVal, shVal);\n } else {\n // Primitive (or function/date/etc in shape): key exists => keep source value as-is\n out[key] = srcVal;\n }\n }\n return out;\n }\n\n // Non-object shape => allowed leaf; just return source leaf as-is.\n return src;\n }\n\n function isPlainObject(v: unknown): v is Record<string, unknown> {\n if (v === null || typeof v !== 'object') return false;\n const proto = Object.getPrototypeOf(v);\n return proto === Object.prototype || proto === null;\n }\n}\n","import { lstat, mkdir, readFile, writeFile } from 'fs/promises';\nimport { dirname } from 'path';\n\nimport chalk from 'chalk';\nimport type { PackageJson } from 'type-fest';\n\n/**\n * @returns true if a filepath exists\n */\nexport async function exists(filePath: string): Promise<boolean> {\n try {\n await lstat(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Writes data to a filepath if it is different\n * @returns true if the file is written to\n */\nexport async function writeIfDifferent(filePath: string, newData: string): Promise<boolean> {\n // Ensure the directory exists\n const directory = dirname(filePath);\n if (!(await exists(directory))) {\n await mkdir(directory, { recursive: true });\n }\n\n // Check if the file exists\n if (await exists(filePath)) {\n // Read the existing file content\n const existingData = await readFile(filePath, 'utf8');\n\n // Compare the existing data with the new data\n if (existingData === newData) {\n // console.log('File contents are identical. No write needed.');\n return false;\n }\n }\n\n // Write the new data if it's different or the file doesn't exist\n await writeFile(filePath, newData, 'utf8');\n console.log(chalk.green('Writing to'), filePath);\n return true;\n}\n\n/**\n * @returns the json object packageJson or undefined if it doesnt exist\n */\nexport async function readPackageJson(filePath: string): Promise<PackageJson | undefined> {\n if (!(await exists(filePath))) return undefined;\n return JSON.parse(await readFile(filePath, { encoding: 'utf-8' })) as PackageJson;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-ag",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Useful TS stuff",
|
|
5
5
|
"bugs": "https://github.com/ageorgeh/ts-ag/issues",
|
|
6
6
|
"author": "Alexander Hornung",
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
"cookie": "1.1.1",
|
|
51
51
|
"cycle": "1.0.3",
|
|
52
52
|
"dequal": "^2.0.3",
|
|
53
|
-
"devalue": "^5.6.
|
|
53
|
+
"devalue": "^5.6.4",
|
|
54
54
|
"get-tsconfig": "^4.13.6",
|
|
55
55
|
"glob": "^13.0.6",
|
|
56
|
-
"jose": "6.2.
|
|
56
|
+
"jose": "6.2.1",
|
|
57
57
|
"neverthrow": "8.2.0",
|
|
58
58
|
"oxfmt": "^0.36.0",
|
|
59
59
|
"radash": "^12.1.1",
|
|
@@ -65,24 +65,24 @@
|
|
|
65
65
|
"vfile": "6.0.3"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@actions/languageserver": "^0.3.
|
|
68
|
+
"@actions/languageserver": "^0.3.47",
|
|
69
69
|
"@types/aws-lambda": "8.10.161",
|
|
70
70
|
"@types/hast": "3.0.4",
|
|
71
71
|
"@types/node": "^24.12.0",
|
|
72
72
|
"@types/ungap__structured-clone": "1.2.0",
|
|
73
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
73
|
+
"@typescript/native-preview": "7.0.0-dev.20260314.1",
|
|
74
74
|
"concurrently": "^9.2.1",
|
|
75
75
|
"globals": "^17.4.0",
|
|
76
76
|
"husky": "^9.1.7",
|
|
77
77
|
"jiti": "2.6.1",
|
|
78
|
-
"lint-staged": "^16.
|
|
78
|
+
"lint-staged": "^16.4.0",
|
|
79
79
|
"oxlint": "^1.51.0",
|
|
80
80
|
"semantic-release": "^25.0.3",
|
|
81
81
|
"tsdown": "^0.21.2",
|
|
82
82
|
"typescript": "^5.9.3",
|
|
83
83
|
"typescript-svelte-plugin": "0.3.50",
|
|
84
84
|
"vite-tsconfig-paths": "^6.1.1",
|
|
85
|
-
"vitest": "^4.0
|
|
85
|
+
"vitest": "^4.1.0"
|
|
86
86
|
},
|
|
87
87
|
"peerDependencies": {
|
|
88
88
|
"@types/aws-lambda": "8.10.161",
|