From 695d3c12826976cbc36c472a41160f1ed1869313 Mon Sep 17 00:00:00 2001 From: seveibar Date: Sun, 12 Jan 2025 23:19:48 -0800 Subject: [PATCH 1/2] add registry ky types --- lib/registry-api/get-ky.ts | 276 ++++++++++++++++++++++++++++++++++++- 1 file changed, 274 insertions(+), 2 deletions(-) diff --git a/lib/registry-api/get-ky.ts b/lib/registry-api/get-ky.ts index 75a11bb..5cf5c04 100644 --- a/lib/registry-api/get-ky.ts +++ b/lib/registry-api/get-ky.ts @@ -1,5 +1,6 @@ import { getRegistryApiUrl } from "lib/cli-config" import ky, { type AfterResponseHook } from "ky" +import type { TypedKyInstance } from "typed-ky" const prettyResponseErrorHook: AfterResponseHook = async ( _request, @@ -20,11 +21,282 @@ const prettyResponseErrorHook: AfterResponseHook = async ( } } -export const getKy = () => { +export const getKy = (): RegistryKy => { return ky.create({ prefixUrl: getRegistryApiUrl(), hooks: { afterResponse: [prettyResponseErrorHook], }, - }) + }) as any as RegistryKy } + +export type SnippetType = "board" | "package" | "model" | "footprint" + +export type Snippet = { + snippet_id: string + unscoped_name: string + name: string + owner_name: string + code: string + created_at: string + updated_at: string + snippet_type: SnippetType + description?: string + dts?: string + compiled_js?: string + manual_edits_json_content?: string + star_count: number + circuit_json?: any[] | null +} + +export type LiteSnippet = Omit< + Snippet, + "code" | "dts" | "compiled_js" | "circuit_json" +> + +export interface RegistryApi { + "snippets/create": { + POST: { + requestJson: { + unscoped_name?: string + code?: string + snippet_type: SnippetType + description?: string + dts?: string + compiled_js?: string + circuit_json?: any + } + responseJson: { + ok: boolean + snippet: { + snippet_id: string + unscoped_name: string + name: string + owner_name: string + code: string + created_at: string + updated_at: string + snippet_type: SnippetType + description?: string + dts?: string + compiled_js?: string + manual_edits_json_content?: string + star_count: number + circuit_json?: any[] | null + } + } + } + } + "snippets/get": { + GET: { + searchParams: { + snippet_id?: string + name?: string + owner_name?: string + unscoped_name?: string + } + responseJson: { + ok: boolean + snippet: Snippet + } + } + } + "snippets/update": { + POST: { + requestJson: { + snippet_id: string + code?: string + description?: string + unscoped_name?: string + dts?: string + compiled_js?: string + circuit_json?: any + manual_edits_json_content?: string | null + } + responseJson: { + ok: boolean + snippet: Snippet + } + } + } + "snippets/delete": { + POST: { + requestJson: { + snippet_id: string + } + responseJson: { + ok: boolean + } + } + } + "snippets/list": { + GET: { + searchParams: { + owner_name?: string + unscoped_name?: string + } + responseJson: { + ok: boolean + snippets: Array<{ + snippet_id: string + unscoped_name: string + name: string + owner_name: string + created_at: string + updated_at: string + snippet_type: SnippetType + description?: string + manual_edits_json_content?: string + star_count: number + }> + } + } + } + "snippets/list_newest": { + GET: { + searchParams: { + limit?: number + } + responseJson: { + snippets: LiteSnippet[] + lite_snippets: LiteSnippet[] + } + } + } + "snippets/list_trending": { + GET: { + responseJson: { + snippets: Snippet[] + } + } + } + "snippets/search": { + GET: { + searchParams: { + q: string + } + responseJson: { + snippets: Snippet[] + } + } + } + "snippets/add_star": { + POST: { + requestJson: { + snippet_id: string + } + responseJson: { + ok: boolean + } + } + } + "snippets/remove_star": { + POST: { + requestJson: { + snippet_id: string + } + responseJson: { + ok: boolean + } + } + } + + "package_files/create": { + POST: { + requestJson: { + file_path: string + is_release_tarball?: boolean + content_mimetype?: string + content_text?: string + content_base64?: string + package_release_id?: string + package_name_with_version?: string + npm_pack_output?: any + } + responseJson: { + ok: boolean + package_file: { + package_file_id: string + package_release_id: string + file_path: string + content_text?: string | null + created_at: string + } + } + } + } + + "package_files/get": { + POST: { + requestJson: { + package_file_id?: string + package_release_id?: string + file_path?: string + package_id?: string + version?: string + package_name?: string + package_name_with_version?: string + } + responseJson: + | { + ok: boolean + package_file?: { + package_file_id: string + package_release_id: string + file_path: string + content_text?: string | null + created_at: string + } + } + | { + error: { + error_code: string + message: string + [key: string]: any + } + } + } + } + + "package_files/download": { + GET: { + searchParams: { + package_file_id?: string + package_name_with_version?: string + file_path?: string + } + responseJson: string + } + POST: { + searchParams: { + package_file_id?: string + package_name_with_version?: string + file_path?: string + } + responseJson: string + } + } + + "package_files/list": { + POST: { + requestJson: { + package_release_id?: string + package_name?: string + use_latest_version?: boolean + package_name_with_version?: string + } + responseJson: { + ok: boolean + package_files: Array<{ + package_file_id: string + package_release_id: string + file_path: string + content_text?: string | null + created_at: string + }> + } + } + } +} + +export type RegistryKy = TypedKyInstance From fbe21c97a5463a2f7edcbcfa609b0016088fabab Mon Sep 17 00:00:00 2001 From: K Om Senapati Date: Fri, 31 Jan 2025 22:09:02 +0530 Subject: [PATCH 2/2] fix: endpoint types issues (#45) --- cli/auth/login/register.ts | 44 ++++++++++++------------------ cli/clone/register.ts | 33 +++++++++++++--------- lib/registry-api/endpoint-types.ts | 33 +++++++++++++++------- lib/registry-api/get-ky.ts | 10 +++++++ 4 files changed, 70 insertions(+), 50 deletions(-) diff --git a/cli/auth/login/register.ts b/cli/auth/login/register.ts index 21ca6dd..a4d4b99 100644 --- a/cli/auth/login/register.ts +++ b/cli/auth/login/register.ts @@ -2,7 +2,6 @@ import type { Command } from "commander" import { cliConfig } from "lib/cli-config" import delay from "delay" import { getKy } from "lib/registry-api/get-ky" -import type { EndpointResponse } from "lib/registry-api/endpoint-types" export const registerAuthLogin = (program: Command) => { program.commands @@ -13,12 +12,9 @@ export const registerAuthLogin = (program: Command) => { const ky = getKy() const { login_page } = await ky - .post( - "sessions/login_page/create", - { - json: {}, - }, - ) + .post("sessions/login_page/create", { + json: {}, + }) .json() console.log("Please visit the following URL to log in:") @@ -27,17 +23,14 @@ export const registerAuthLogin = (program: Command) => { // Wait until we receive confirmation while (true) { const { login_page: new_login_page } = await ky - .post( - "sessions/login_page/get", - { - json: { - login_page_id: login_page.login_page_id, - }, - headers: { - Authorization: `Bearer ${login_page.login_page_auth_token}`, - }, + .post("sessions/login_page/get", { + json: { + login_page_id: login_page.login_page_id, }, - ) + headers: { + Authorization: `Bearer ${login_page.login_page_auth_token}`, + }, + }) .json() if (new_login_page.was_login_successful) { @@ -53,17 +46,14 @@ export const registerAuthLogin = (program: Command) => { } const { session } = await ky - .post( - "sessions/login_page/exchange_for_cli_session", - { - json: { - login_page_id: login_page.login_page_id, - }, - headers: { - Authorization: `Bearer ${login_page.login_page_auth_token}`, - }, + .post("sessions/login_page/exchange_for_cli_session", { + json: { + login_page_id: login_page.login_page_id, + }, + headers: { + Authorization: `Bearer ${login_page.login_page_auth_token}`, }, - ) + }) .json() cliConfig.set("sessionToken", session.token) diff --git a/cli/clone/register.ts b/cli/clone/register.ts index f4832b4..56df715 100644 --- a/cli/clone/register.ts +++ b/cli/clone/register.ts @@ -33,14 +33,7 @@ export const registerClone = (program: Command) => { console.log(`Cloning ${author}/${snippetName}...`) const packageFileList = await ky - .post<{ - package_files: Array<{ - package_file_id: string - package_release_id: string - file_path: string - created_at: string - }> - }>("package_files/list", { + .post("package_files/list", { json: { package_name: `${author}/${snippetName}`, use_latest_version: true, @@ -63,11 +56,7 @@ export const registerClone = (program: Command) => { if (filePath.startsWith("dist/")) continue const fileContent = await ky - .post<{ - package_file: { - content_text: string - } - }>("package_files/get", { + .post("package_files/get", { json: { package_name: `${author}/${snippetName}`, file_path: fileInfo.file_path, @@ -75,6 +64,18 @@ export const registerClone = (program: Command) => { }) .json() + if ("error" in fileContent) { + throw new Error( + `Failed to get file ${filePath}: ${fileContent.error.message}`, + ) + } + // Check if we have the package file + if (!fileContent.ok || !fileContent.package_file) { + throw new Error( + `Failed to get file ${filePath}: No package file returned`, + ) + } + const fullPath = path.join(dirPath, filePath) const dirName = path.dirname(fullPath) @@ -83,6 +84,12 @@ export const registerClone = (program: Command) => { fs.mkdirSync(dirName, { recursive: true }) } + if (!fileContent.package_file.content_text) { + throw new Error( + `Failed to get file ${filePath}: No content text available`, + ) + } + fs.writeFileSync(fullPath, fileContent.package_file.content_text) } diff --git a/lib/registry-api/endpoint-types.ts b/lib/registry-api/endpoint-types.ts index 2f87f21..93f993e 100644 --- a/lib/registry-api/endpoint-types.ts +++ b/lib/registry-api/endpoint-types.ts @@ -1,20 +1,33 @@ -export interface EndpointResponse { +export interface EndpointTypes { "sessions/login_page/create": { - login_page: { - login_page_id: string - login_page_auth_token: string - url: string + requestJson: Record + responseJson: { + login_page: { + login_page_id: string + login_page_auth_token: string + url: string + } } } "sessions/login_page/get": { - login_page: { - was_login_successful: boolean - is_expired: boolean + requestJson: { + login_page_id: string + } + responseJson: { + login_page: { + was_login_successful: boolean + is_expired: boolean + } } } "sessions/login_page/exchange_for_cli_session": { - session: { - token: string + requestJson: { + login_page_id: string + } + responseJson: { + session: { + token: string + } } } } diff --git a/lib/registry-api/get-ky.ts b/lib/registry-api/get-ky.ts index 5cf5c04..3595f49 100644 --- a/lib/registry-api/get-ky.ts +++ b/lib/registry-api/get-ky.ts @@ -1,6 +1,7 @@ import { getRegistryApiUrl } from "lib/cli-config" import ky, { type AfterResponseHook } from "ky" import type { TypedKyInstance } from "typed-ky" +import type { EndpointTypes } from "./endpoint-types" const prettyResponseErrorHook: AfterResponseHook = async ( _request, @@ -55,6 +56,15 @@ export type LiteSnippet = Omit< > export interface RegistryApi { + "sessions/login_page/create": { + POST: EndpointTypes["sessions/login_page/create"] + } + "sessions/login_page/get": { + POST: EndpointTypes["sessions/login_page/get"] + } + "sessions/login_page/exchange_for_cli_session": { + POST: EndpointTypes["sessions/login_page/exchange_for_cli_session"] + } "snippets/create": { POST: { requestJson: {