reflet-sdk 0.4.3 → 0.5.0
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/CHANGELOG.md +15 -0
- package/README.md +64 -0
- package/dist/{client-BYuSKJw5.js → client-BWEBWk1k.js} +3 -3
- package/dist/client-BWEBWk1k.js.map +1 -0
- package/dist/client-w4Rkl10y.d.ts.map +1 -1
- package/dist/devtools-layer-BYGuFmhg.js +3935 -0
- package/dist/devtools-layer-BYGuFmhg.js.map +1 -0
- package/dist/devtools-next.d.ts +19 -0
- package/dist/devtools-next.d.ts.map +1 -0
- package/dist/devtools-next.js +25 -0
- package/dist/devtools-next.js.map +1 -0
- package/dist/devtools-vite.d.ts +8 -0
- package/dist/devtools-vite.d.ts.map +1 -0
- package/dist/devtools-vite.js +75 -0
- package/dist/devtools-vite.js.map +1 -0
- package/dist/feedback.d.ts +5 -0
- package/dist/feedback.d.ts.map +1 -1
- package/dist/feedback.js +54 -1868
- package/dist/feedback.js.map +1 -1
- package/dist/handler-CHP0m7KF.js +713 -0
- package/dist/handler-CHP0m7KF.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/options-7KtQZJj8.d.ts +20 -0
- package/dist/options-7KtQZJj8.d.ts.map +1 -0
- package/dist/picker-DDDpVcfr.js +1918 -0
- package/dist/picker-DDDpVcfr.js.map +1 -0
- package/dist/protocol-Bn6Bg_0r.js +32 -0
- package/dist/protocol-Bn6Bg_0r.js.map +1 -0
- package/dist/react.js +2 -2
- package/dist/{z-index-_Q9PWbfY.js → z-index-CKxBgZTG.js} +3 -2
- package/dist/{z-index-_Q9PWbfY.js.map → z-index-CKxBgZTG.js.map} +1 -1
- package/package.json +15 -2
- package/dist/client-BYuSKJw5.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-CHP0m7KF.js","names":["TRAILING_SLASHES","QUERY_OR_HASH"],"sources":["../src/devtools/server/json-response.ts","../src/devtools/server/options.ts","../src/devtools/server/reflet-proxy.ts","../src/devtools/server/request-guard.ts","../src/devtools/server/source/code-search.ts","../src/devtools/server/source/project-roots.ts","../src/devtools/server/source/jsx-range.ts","../src/devtools/server/source/server-frame.ts","../src/devtools/server/source/source-file.ts","../src/devtools/server/handler.ts"],"sourcesContent":["import type { DevtoolsErrorBody } from \"../protocol\";\n\nexport type DevtoolsOutcome<T> =\n | { ok: true; value: T }\n | { error: string; ok: false; status: number };\n\nconst JSON_RESPONSE_HEADERS = {\n \"cache-control\": \"no-store\",\n \"content-type\": \"application/json; charset=utf-8\",\n \"x-content-type-options\": \"nosniff\",\n};\n\nexport function jsonTextResponse(\n text: string | null,\n status: number\n): Response {\n return new Response(text, { headers: JSON_RESPONSE_HEADERS, status });\n}\n\nexport function jsonResponse(body: unknown, status = 200): Response {\n return jsonTextResponse(JSON.stringify(body), status);\n}\n\nexport function errorResponse(error: string, status: number): Response {\n const body: DevtoolsErrorBody = { error };\n return jsonResponse(body, status);\n}\n\nexport function failure<T>(error: string, status: number): DevtoolsOutcome<T> {\n return { error, ok: false, status };\n}\n","import { resolve } from \"node:path\";\nimport { DEFAULT_API_URL } from \"../../client\";\nimport { EDITORS, type EditorId } from \"../protocol\";\n\nexport interface DevtoolsServerOptions {\n /** Dev hostnames besides localhost, e.g. `app.test`. Falls back to REFLET_DEVTOOLS_HOSTS, comma-separated. */\n allowedHosts?: string[];\n /** Reflet API origin. Falls back to REFLET_API_URL, then the hosted API. */\n apiUrl?: string;\n /** Editor that \"open in editor\" links target. Falls back to REFLET_EDITOR. */\n editor?: EditorId;\n /** App directory source paths resolve against. Defaults to the working directory. */\n root?: string;\n /** Falls back to REFLET_SECRET_KEY. Never sent to the browser. */\n secretKey?: string;\n}\n\nexport type DevtoolsEnv = Readonly<Record<string, string | undefined>>;\n\nexport interface ResolvedDevtoolsOptions {\n allowedHosts: string[];\n apiUrl: string;\n editor: EditorId;\n root: string;\n secretKey: string | null;\n}\n\nconst DEFAULT_EDITOR: EditorId = \"vscode\";\nconst TRAILING_SLASHES = /\\/+$/;\n\nfunction isEditorId(value: string | undefined): value is EditorId {\n return EDITORS.some((editor) => editor === value);\n}\n\nfunction presentValue(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction resolveEditor(\n optionEditor: string | undefined,\n envEditor: string | undefined\n): EditorId {\n if (isEditorId(optionEditor)) {\n return optionEditor;\n }\n const normalizedEnvEditor = presentValue(envEditor)?.toLowerCase();\n return isEditorId(normalizedEnvEditor) ? normalizedEnvEditor : DEFAULT_EDITOR;\n}\n\nexport function resolveDevtoolsOptions(\n options: DevtoolsServerOptions,\n env: DevtoolsEnv\n): ResolvedDevtoolsOptions {\n const apiUrl =\n presentValue(options.apiUrl) ??\n presentValue(env.REFLET_API_URL) ??\n DEFAULT_API_URL;\n\n return {\n allowedHosts: (\n options.allowedHosts ??\n presentValue(env.REFLET_DEVTOOLS_HOSTS)?.split(\",\") ??\n []\n )\n .map((host) => host.trim().toLowerCase())\n .filter(Boolean),\n apiUrl: apiUrl.replace(TRAILING_SLASHES, \"\"),\n editor: resolveEditor(options.editor, env.REFLET_EDITOR),\n root: resolve(presentValue(options.root) ?? process.cwd()),\n secretKey:\n presentValue(options.secretKey) ??\n presentValue(env.REFLET_SECRET_KEY) ??\n null,\n };\n}\n","import { PROXIED_API_PATHS } from \"../protocol\";\nimport { errorResponse, jsonTextResponse } from \"./json-response\";\n\ntype ProxiedApiPath = (typeof PROXIED_API_PATHS)[number];\n\nconst CREATE_FEEDBACK_PATH: ProxiedApiPath = \"/api/v1/feedback/create\";\nconst MISSING_SECRET_KEY_ERROR =\n \"Set REFLET_SECRET_KEY in the dev server environment to reach your Reflet board.\";\nconst BODYLESS_STATUSES = [204, 205, 304];\n\nexport interface RefletProxyTarget {\n apiUrl: string;\n secretKey: string | null;\n}\n\ntype ForwardedBody = { body: string | undefined } | { error: string };\n\nfunction isProxiedApiPath(path: string): path is ProxiedApiPath {\n return PROXIED_API_PATHS.some((proxiedPath) => proxiedPath === path);\n}\n\nfunction isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nasync function readForwardedBody(\n request: Request,\n apiPath: ProxiedApiPath\n): Promise<ForwardedBody> {\n if (request.method !== \"POST\") {\n return { body: undefined };\n }\n const text = await request.text();\n if (apiPath !== CREATE_FEEDBACK_PATH) {\n return { body: text || undefined };\n }\n\n let payload: unknown;\n try {\n payload = JSON.parse(text);\n } catch {\n return { error: \"Feedback must be a JSON object.\" };\n }\n if (!isJsonObject(payload)) {\n return { error: \"Feedback must be a JSON object.\" };\n }\n return { body: JSON.stringify({ ...payload, internal: true }) };\n}\n\n/** Forwards an allowlisted Reflet API call with the secret key; devtools notes are always internal. */\nexport async function proxyToReflet(\n request: Request,\n apiPath: string,\n target: RefletProxyTarget\n): Promise<Response> {\n if (!isProxiedApiPath(apiPath)) {\n return errorResponse(\n `Reflet devtools does not forward ${apiPath || \"/\"}.`,\n 404\n );\n }\n if (!target.secretKey) {\n return errorResponse(MISSING_SECRET_KEY_ERROR, 503);\n }\n if (request.method !== \"GET\" && request.method !== \"POST\") {\n return errorResponse(`${request.method} is not supported here.`, 405);\n }\n\n const forwarded = await readForwardedBody(request, apiPath);\n if (\"error\" in forwarded) {\n return errorResponse(forwarded.error, 400);\n }\n\n const { search } = new URL(request.url);\n let upstream: Response;\n try {\n upstream = await fetch(`${target.apiUrl}${apiPath}${search}`, {\n body: forwarded.body,\n headers: {\n Accept: \"application/json\",\n Authorization: `Bearer ${target.secretKey}`,\n \"Content-Type\": \"application/json\",\n },\n method: request.method,\n });\n } catch {\n return errorResponse(`Could not reach Reflet at ${target.apiUrl}.`, 502);\n }\n\n const text = await upstream.text();\n return jsonTextResponse(\n BODYLESS_STATUSES.includes(upstream.status) ? null : text,\n upstream.status\n );\n}\n","import { DEVTOOLS_REQUEST_HEADER } from \"../protocol\";\nimport { errorResponse } from \"./json-response\";\n\nconst LOOPBACK_HOSTNAMES = [\"localhost\", \"[::1]\"];\nconst LOOPBACK_IPV4 = /^127(?:\\.\\d{1,3}){3}$/;\n\nfunction hostnameOf(host: string): string | null {\n try {\n return new URL(`http://${host}`).hostname.toLowerCase();\n } catch {\n return null;\n }\n}\n\nfunction isAllowedHost(hostname: string, allowedHosts: string[]): boolean {\n return (\n LOOPBACK_HOSTNAMES.includes(hostname) ||\n hostname.endsWith(\".localhost\") ||\n LOOPBACK_IPV4.test(hostname) ||\n allowedHosts.includes(hostname)\n );\n}\n\n/**\n * The Host check stops DNS rebinding: a hostile domain resolved to 127.0.0.1\n * is same-origin with itself, so origin checks alone would let it through.\n */\nexport function rejectUntrustedRequest(\n request: Request,\n allowedHosts: string[]\n): Response | null {\n const hostname = hostnameOf(\n request.headers.get(\"host\") ?? new URL(request.url).host\n );\n if (!(hostname && isAllowedHost(hostname, allowedHosts))) {\n return errorResponse(\n \"Reflet devtools only answers on localhost. Add other dev hostnames to allowedHosts or REFLET_DEVTOOLS_HOSTS.\",\n 403\n );\n }\n\n if (request.headers.get(DEVTOOLS_REQUEST_HEADER) !== \"1\") {\n return errorResponse(\n `Reflet devtools requests must send the ${DEVTOOLS_REQUEST_HEADER} header.`,\n 403\n );\n }\n\n const fetchSite = request.headers.get(\"sec-fetch-site\");\n const isTrustedSite =\n fetchSite === null || fetchSite === \"same-origin\" || fetchSite === \"none\";\n if (!isTrustedSite) {\n return errorResponse(\n \"Reflet devtools only answers requests from the app's own origin.\",\n 403\n );\n }\n\n return null;\n}\n","import { type ExecFileException, execFile } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport type { CodeMatch, CodeSearchResult } from \"../../protocol\";\nimport { type DevtoolsOutcome, failure } from \"../json-response\";\n\nconst MIN_QUERY_LENGTH = 2;\nconst MAX_QUERY_LENGTH = 200;\nconst MAX_MATCHES = 20;\nconst PREVIEW_LENGTH = 160;\nconst PREVIEW_LEAD = 40;\nconst SEARCH_TIMEOUT_MS = 4000;\nconst MAX_OUTPUT_BYTES = 1_048_576;\nconst NO_MATCHES_EXIT_CODE = 1;\nconst NOT_A_REPOSITORY_EXIT_CODE = 128;\nconst SEARCHED_FILES = [\n \"*.tsx\",\n \"*.jsx\",\n \"*.ts\",\n \"*.js\",\n \"*.vue\",\n \"*.svelte\",\n \"*.astro\",\n \"*.mdx\",\n];\nconst LINE_BREAK = /[\\r\\n]/;\n\ninterface GitGrepRun {\n error: ExecFileException | null;\n stdout: string;\n}\n\nfunction runGitGrep(workspaceRoot: string, query: string): Promise<GitGrepRun> {\n const args = [\n \"grep\",\n \"-n\",\n \"-z\",\n \"-I\",\n \"-F\",\n \"--no-color\",\n \"--untracked\",\n \"-e\",\n query,\n \"--\",\n ...SEARCHED_FILES,\n ];\n return new Promise((resolveRun) => {\n execFile(\n \"git\",\n args,\n {\n cwd: workspaceRoot,\n encoding: \"utf8\",\n maxBuffer: MAX_OUTPUT_BYTES,\n timeout: SEARCH_TIMEOUT_MS,\n },\n (error, stdout) => resolveRun({ error, stdout })\n );\n });\n}\n\nfunction previewLine(content: string, query: string): string {\n const text = content.trim();\n if (text.length <= PREVIEW_LENGTH) {\n return text;\n }\n const matchIndex = text.indexOf(query);\n const start = Math.max(\n 0,\n Math.min(matchIndex - PREVIEW_LEAD, text.length - PREVIEW_LENGTH)\n );\n const end = start + PREVIEW_LENGTH;\n const head = start > 0 ? \"…\" : \"\";\n const tail = end < text.length ? \"…\" : \"\";\n return `${head}${text.slice(start, end)}${tail}`;\n}\n\nfunction parseMatches(\n stdout: string,\n workspaceRoot: string,\n query: string\n): CodeMatch[] {\n const matches: CodeMatch[] = [];\n for (const record of stdout.split(\"\\n\")) {\n const [path, lineText, content] = record.split(\"\\0\");\n const line = Number(lineText);\n const isComplete =\n path !== undefined && content !== undefined && Number.isInteger(line);\n if (isComplete && !path.split(\"/\").includes(\"node_modules\")) {\n matches.push({\n absolutePath: join(workspaceRoot, path),\n line,\n path,\n preview: previewLine(content, query),\n });\n if (matches.length === MAX_MATCHES) {\n break;\n }\n }\n }\n return matches;\n}\n\nfunction describeGitFailure(error: ExecFileException): DevtoolsOutcome<never> {\n if (error.code === \"ENOENT\") {\n return failure(\"Code search needs git installed on the dev server.\", 503);\n }\n if (error.code === NOT_A_REPOSITORY_EXIT_CODE) {\n return failure(\n \"Code search needs the app to live in a git repository.\",\n 503\n );\n }\n if (error.killed) {\n return failure(\"Code search timed out.\", 504);\n }\n return failure(`Code search failed: ${error.message}`, 500);\n}\n\nexport async function searchCode(\n workspaceRoot: string,\n rawQuery: string\n): Promise<DevtoolsOutcome<CodeSearchResult>> {\n const query = rawQuery.trim();\n if (query.length < MIN_QUERY_LENGTH || query.length > MAX_QUERY_LENGTH) {\n return failure(\n `Search for ${MIN_QUERY_LENGTH} to ${MAX_QUERY_LENGTH} characters.`,\n 400\n );\n }\n if (LINE_BREAK.test(query)) {\n return failure(\"Search for a single line of text.\", 400);\n }\n\n const { error, stdout } = await runGitGrep(workspaceRoot, query);\n const matches = parseMatches(stdout, workspaceRoot, query);\n const hasNoMatches = error?.code === NO_MATCHES_EXIT_CODE;\n if (!error || hasNoMatches || matches.length > 0) {\n return { ok: true, value: { matches } };\n }\n return describeGitFailure(error);\n}\n","import { existsSync, realpathSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\n\nexport interface ProjectRoots {\n /** The app directory, where the dev server runs. */\n root: string;\n /** Nearest ancestor of the app directory holding `.git`, else the app directory. */\n workspaceRoot: string;\n}\n\nexport function resolveProjectRoots(appRoot: string): ProjectRoots {\n const resolvedRoot = resolve(appRoot);\n const root = existsSync(resolvedRoot)\n ? realpathSync(resolvedRoot)\n : resolvedRoot;\n\n for (let directory = root; ; directory = dirname(directory)) {\n if (existsSync(join(directory, \".git\"))) {\n return { root, workspaceRoot: directory };\n }\n if (dirname(directory) === directory) {\n return { root, workspaceRoot: root };\n }\n }\n}\n","import type { LineRange } from \"../../protocol\";\n\nconst FAILED = -1;\nconst MAX_TAG_LOOKBACK = 2;\nconst TAG_NAME_START = /[A-Za-z_$]/;\nconst TAG_NAME_CHAR = /[\\w$.:-]/;\nconst IDENTIFIER_CHAR = /[\\w$]/;\nconst WHITESPACE = /\\s/;\nconst JSX_EXPRESSION_LEAD = /[([{,;=?:&|!>]/;\nconst JSX_KEYWORD_LEADS = [\"return\", \"yield\", \"default\", \"await\"];\n\ninterface OpeningTag {\n end: number;\n name: string;\n selfClosing: boolean;\n}\n\nfunction isTagStart(code: string, index: number): boolean {\n if (code.charAt(index) !== \"<\") {\n return false;\n }\n const next = code.charAt(index + 1);\n return next === \">\" || TAG_NAME_START.test(next);\n}\n\nfunction startsJsxInExpression(code: string, index: number): boolean {\n let cursor = index - 1;\n while (cursor >= 0 && WHITESPACE.test(code.charAt(cursor))) {\n cursor -= 1;\n }\n if (cursor < 0) {\n return true;\n }\n const previous = code.charAt(cursor);\n if (JSX_EXPRESSION_LEAD.test(previous)) {\n return true;\n }\n let wordStart = cursor;\n while (wordStart > 0 && IDENTIFIER_CHAR.test(code.charAt(wordStart - 1))) {\n wordStart -= 1;\n }\n return JSX_KEYWORD_LEADS.includes(code.slice(wordStart, cursor + 1));\n}\n\nfunction skipJsString(code: string, index: number): number {\n const quote = code.charAt(index);\n let cursor = index + 1;\n while (cursor < code.length) {\n const char = code.charAt(cursor);\n if (char === \"\\\\\") {\n cursor += 2;\n } else if (char === quote) {\n return cursor + 1;\n } else if (char === \"\\n\") {\n return index + 1;\n } else {\n cursor += 1;\n }\n }\n return index + 1;\n}\n\nfunction skipTemplate(code: string, index: number): number {\n let cursor = index + 1;\n while (cursor < code.length) {\n const char = code.charAt(cursor);\n if (char === \"\\\\\") {\n cursor += 2;\n } else if (char === \"`\") {\n return cursor + 1;\n } else if (char === \"$\" && code.charAt(cursor + 1) === \"{\") {\n cursor = skipJsExpression(code, cursor + 1);\n if (cursor === FAILED) {\n return FAILED;\n }\n } else {\n cursor += 1;\n }\n }\n return FAILED;\n}\n\nfunction skipJsToken(code: string, index: number): number {\n const char = code.charAt(index);\n const next = code.charAt(index + 1);\n if (char === '\"' || char === \"'\") {\n return skipJsString(code, index);\n }\n if (char === \"`\") {\n return skipTemplate(code, index);\n }\n if (char === \"/\" && next === \"/\") {\n const lineEnd = code.indexOf(\"\\n\", index);\n return lineEnd === -1 ? code.length : lineEnd;\n }\n if (char === \"/\" && next === \"*\") {\n const commentEnd = code.indexOf(\"*/\", index + 2);\n return commentEnd === -1 ? FAILED : commentEnd + 2;\n }\n if (isTagStart(code, index) && startsJsxInExpression(code, index)) {\n return skipElement(code, index);\n }\n return index + 1;\n}\n\nfunction skipJsExpression(code: string, index: number): number {\n let depth = 0;\n let cursor = index;\n while (cursor < code.length) {\n const char = code.charAt(cursor);\n if (char === \"{\" || char === \"}\") {\n depth += char === \"{\" ? 1 : -1;\n cursor += 1;\n if (depth === 0) {\n return cursor;\n }\n } else {\n cursor = skipJsToken(code, cursor);\n if (cursor === FAILED) {\n return FAILED;\n }\n }\n }\n return FAILED;\n}\n\nfunction skipTypeArguments(code: string, index: number): number {\n let depth = 0;\n for (let cursor = index; cursor < code.length; cursor += 1) {\n const char = code.charAt(cursor);\n if (char === \"<\") {\n depth += 1;\n } else if (char === \">\") {\n depth -= 1;\n if (depth === 0) {\n return cursor + 1;\n }\n }\n }\n return FAILED;\n}\n\nfunction skipAttributeToken(code: string, index: number): number {\n const char = code.charAt(index);\n if (char === \"{\") {\n return skipJsExpression(code, index);\n }\n if (char === '\"' || char === \"'\") {\n const closingQuote = code.indexOf(char, index + 1);\n return closingQuote === -1 ? FAILED : closingQuote + 1;\n }\n return index + 1;\n}\n\nfunction readTagName(code: string, index: number): number {\n let cursor = index;\n while (TAG_NAME_CHAR.test(code.charAt(cursor))) {\n cursor += 1;\n }\n return cursor;\n}\n\nfunction readOpeningTag(code: string, index: number): OpeningTag | null {\n const nameEnd = readTagName(code, index + 1);\n const name = code.slice(index + 1, nameEnd);\n let cursor =\n code.charAt(nameEnd) === \"<\" ? skipTypeArguments(code, nameEnd) : nameEnd;\n\n while (cursor !== FAILED && cursor < code.length) {\n const char = code.charAt(cursor);\n if (char === \">\") {\n return { end: cursor + 1, name, selfClosing: false };\n }\n if (char === \"/\" && code.charAt(cursor + 1) === \">\") {\n return { end: cursor + 2, name, selfClosing: true };\n }\n cursor = skipAttributeToken(code, cursor);\n }\n return null;\n}\n\nfunction readClosingTagEnd(code: string, index: number, name: string): number {\n let cursor = index + 2;\n while (WHITESPACE.test(code.charAt(cursor))) {\n cursor += 1;\n }\n const nameEnd = readTagName(code, cursor);\n if (code.slice(cursor, nameEnd) !== name) {\n return FAILED;\n }\n cursor = nameEnd;\n while (WHITESPACE.test(code.charAt(cursor))) {\n cursor += 1;\n }\n return code.charAt(cursor) === \">\" ? cursor + 1 : FAILED;\n}\n\nfunction skipChildren(code: string, index: number, name: string): number {\n let cursor = index;\n while (cursor !== FAILED && cursor < code.length) {\n const char = code.charAt(cursor);\n if (char === \"<\" && code.charAt(cursor + 1) === \"/\") {\n return readClosingTagEnd(code, cursor, name);\n }\n if (char === \"{\") {\n cursor = skipJsExpression(code, cursor);\n } else if (isTagStart(code, cursor)) {\n cursor = skipElement(code, cursor);\n } else {\n cursor += 1;\n }\n }\n return FAILED;\n}\n\nfunction skipElement(code: string, index: number): number {\n const tag = readOpeningTag(code, index);\n if (!tag) {\n return FAILED;\n }\n return tag.selfClosing ? tag.end : skipChildren(code, tag.end, tag.name);\n}\n\nfunction lineOffset(code: string, line: number): number {\n if (!Number.isInteger(line) || line < 1) {\n return FAILED;\n }\n let offset = 0;\n for (let current = 1; current < line; current += 1) {\n const newline = code.indexOf(\"\\n\", offset);\n if (newline === -1) {\n return FAILED;\n }\n offset = newline + 1;\n }\n return offset;\n}\n\nfunction findTagStart(\n code: string,\n lineStart: number,\n lineEnd: number,\n column: number\n): number {\n const origin = Math.min(lineStart + Math.max(column, 0), lineEnd);\n for (let back = 0; back <= MAX_TAG_LOOKBACK; back += 1) {\n const candidate = origin - back;\n if (candidate >= lineStart && isTagStart(code, candidate)) {\n return candidate;\n }\n }\n for (let candidate = origin + 1; candidate < lineEnd; candidate += 1) {\n if (isTagStart(code, candidate)) {\n return candidate;\n }\n }\n return FAILED;\n}\n\nfunction countNewlines(code: string, from: number, to: number): number {\n let count = 0;\n let newline = code.indexOf(\"\\n\", from);\n while (newline !== -1 && newline < to) {\n count += 1;\n newline = code.indexOf(\"\\n\", newline + 1);\n }\n return count;\n}\n\n/** Lines spanned by the JSX element at a 1-based line and 0-based column. */\nexport function jsxElementLines(\n code: string,\n line: number,\n column: number\n): LineRange | null {\n const lineStart = lineOffset(code, line);\n if (lineStart === FAILED) {\n return null;\n }\n const newline = code.indexOf(\"\\n\", lineStart);\n const lineEnd = newline === -1 ? code.length : newline;\n const tagStart = findTagStart(code, lineStart, lineEnd, column);\n if (tagStart === FAILED) {\n return null;\n }\n const elementEnd = skipElement(code, tagStart);\n if (elementEnd === FAILED) {\n return null;\n }\n return {\n end: line + countNewlines(code, tagStart, elementEnd - 1),\n start: line,\n };\n}\n","import { readFile, realpath, stat } from \"node:fs/promises\";\nimport { SourceMap } from \"node:module\";\nimport { dirname, join, relative, sep } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { type DevtoolsOutcome, failure } from \"../json-response\";\nimport type { SourceRequest } from \"./source-file\";\n\nconst SERVER_FRAME_PREFIX = /^(?:about|rsc):\\/\\/React\\/Server\\//;\nconst QUERY_OR_HASH = /[?#].*$/;\nconst SOURCE_MAPPING_URL = /\\/\\/# sourceMappingURL=(\\S+)\\s*$/;\nconst MAX_MAP_BYTES = 50 * 1_048_576;\n\nconst mapCache = new Map<string, { map: SourceMap; mtimeMs: number }>();\n\nexport function isServerFrame(fileName: string): boolean {\n return SERVER_FRAME_PREFIX.test(fileName);\n}\n\nfunction isInside(path: string, root: string): boolean {\n const fromRoot = relative(root, path);\n return (\n fromRoot !== \"\" &&\n !fromRoot.startsWith(\"..\") &&\n !fromRoot.includes(`..${sep}`)\n );\n}\n\nasync function mapPathFor(chunkPath: string): Promise<string> {\n const code = await readFile(chunkPath, \"utf8\");\n const declared = SOURCE_MAPPING_URL.exec(code)?.[1];\n return declared\n ? join(dirname(chunkPath), decodeURIComponent(declared))\n : `${chunkPath}.map`;\n}\n\nasync function loadMap(mapPath: string): Promise<SourceMap> {\n const { mtimeMs, size } = await stat(mapPath);\n if (size > MAX_MAP_BYTES) {\n throw new Error(\"source map too large\");\n }\n const cached = mapCache.get(mapPath);\n if (cached?.mtimeMs === mtimeMs) {\n return cached.map;\n }\n const map = new SourceMap(JSON.parse(await readFile(mapPath, \"utf8\")));\n mapCache.set(mapPath, { map, mtimeMs });\n return map;\n}\n\n/**\n * Server Components stamp their elements with frames into the dev server's\n * own chunks (`about://React/Server/file:///…/.next/…`); the browser cannot\n * fetch those maps, so they are resolved here from disk.\n */\nexport async function mapServerFrame(\n request: SourceRequest,\n workspaceRoot: string\n): Promise<DevtoolsOutcome<SourceRequest>> {\n const unreadable = failure<SourceRequest>(\n \"This element comes from a Server Component whose source map could not be read.\",\n 404\n );\n if (request.line === null) {\n return unreadable;\n }\n try {\n const chunkUrl = request.fileName\n .replace(SERVER_FRAME_PREFIX, \"\")\n .replace(QUERY_OR_HASH, \"\");\n const chunkPath = await realpath(fileURLToPath(chunkUrl));\n if (!isInside(chunkPath, workspaceRoot)) {\n return failure<SourceRequest>(\n \"Reflet devtools only reads files inside your repository.\",\n 403\n );\n }\n const map = await loadMap(await mapPathFor(chunkPath));\n const origin = map.findOrigin(request.line, (request.column ?? 0) + 1);\n if (!(\"fileName\" in origin)) {\n return unreadable;\n }\n return {\n ok: true,\n value: {\n column: origin.columnNumber - 1,\n fileName: origin.fileName,\n line: origin.lineNumber,\n },\n };\n } catch {\n return unreadable;\n }\n}\n","import { readFile, realpath, stat } from \"node:fs/promises\";\nimport { extname, isAbsolute, join, relative, sep } from \"node:path\";\nimport type { SourceFile } from \"../../protocol\";\nimport { type DevtoolsOutcome, failure } from \"../json-response\";\nimport { jsxElementLines } from \"./jsx-range\";\nimport type { ProjectRoots } from \"./project-roots\";\nimport { isServerFrame, mapServerFrame } from \"./server-frame\";\n\nconst MAX_SOURCE_BYTES = 1_048_576;\nconst MAX_FILE_NAME_LENGTH = 2048;\nconst MAX_NORMALIZE_PASSES = 8;\nconst SOURCE_EXTENSIONS = [\n \".astro\",\n \".cjs\",\n \".js\",\n \".jsx\",\n \".mdx\",\n \".mjs\",\n \".svelte\",\n \".ts\",\n \".tsx\",\n \".vue\",\n];\nconst EXTENSION_REFUSAL = `Reflet devtools only reads source files (${SOURCE_EXTENSIONS.join(\", \")}).`;\nconst OUTSIDE_WORKSPACE_REFUSAL =\n \"Reflet devtools only reads files inside your repository.\";\nconst NODE_MODULES_REFUSAL =\n \"Reflet devtools does not read files inside node_modules.\";\nconst QUERY_OR_HASH = /[?#].*$/;\nconst TURBOPACK_MODULE_SUFFIX = /(?: \\[[\\w-]+\\])+(?: \\([\\w-]+\\))*$/;\nconst URL_PREFIXES = [/^file:\\/\\//, /^https?:\\/\\/[^/]*/];\nconst BUNDLER_PREFIXES = [\n /^rsc:\\/\\/React\\/[^/]+\\//,\n /^webpack-internal:\\/{2,}/,\n /^webpack:\\/\\/[^/]*\\//,\n /^turbopack:\\/{2,}/,\n /^\\[project\\]\\//,\n /^\\(app-pages-browser\\)\\//,\n /^\\([\\w-]+\\)\\/(?=\\.\\/)/,\n /^\\/@fs(?=\\/)/,\n /^\\.\\//,\n];\n\ninterface LocatedFile {\n realPath: string;\n relativePath: string;\n size: number;\n}\n\ntype CandidateCheck =\n | ({ kind: \"found\" } & LocatedFile)\n | { kind: \"missing\" }\n | { kind: \"refused\"; reason: string };\n\nexport interface SourceRequest {\n column: number | null;\n fileName: string;\n line: number | null;\n}\n\nfunction decodePath(path: string): string {\n try {\n return decodeURIComponent(path);\n } catch {\n return path;\n }\n}\n\nfunction stripFirstPrefix(fileName: string, prefixes: RegExp[]): string {\n for (const prefix of prefixes) {\n if (prefix.test(fileName)) {\n return fileName.replace(prefix, \"\");\n }\n }\n return fileName;\n}\n\n/** Turns a file name from a React debug stack into a filesystem path. */\nexport function normalizeSourceFileName(rawFileName: string): string {\n let fileName = rawFileName\n .trim()\n .replace(QUERY_OR_HASH, \"\")\n .replace(TURBOPACK_MODULE_SUFFIX, \"\");\n let isUrlEncoded = false;\n\n for (let pass = 0; pass < MAX_NORMALIZE_PASSES; pass += 1) {\n const withoutUrl = stripFirstPrefix(fileName, URL_PREFIXES);\n isUrlEncoded ||= withoutUrl !== fileName;\n const stripped = stripFirstPrefix(withoutUrl, BUNDLER_PREFIXES);\n if (stripped === fileName) {\n break;\n }\n fileName = stripped;\n }\n\n return isUrlEncoded ? decodePath(fileName) : fileName;\n}\n\nfunction candidatePaths(fileName: string, roots: ProjectRoots): string[] {\n const candidates = [\n join(roots.root, fileName),\n join(roots.workspaceRoot, fileName),\n ];\n if (isAbsolute(fileName)) {\n candidates.unshift(fileName);\n }\n return [...new Set(candidates)];\n}\n\nfunction isSourceExtension(path: string): boolean {\n return SOURCE_EXTENSIONS.includes(extname(path).toLowerCase());\n}\n\nfunction workspaceRelativePath(\n realPath: string,\n workspaceRoot: string\n): string | null {\n const relativePath = relative(workspaceRoot, realPath);\n const escapes =\n relativePath === \"\" ||\n relativePath === \"..\" ||\n relativePath.startsWith(`..${sep}`) ||\n isAbsolute(relativePath);\n return escapes ? null : relativePath.split(sep).join(\"/\");\n}\n\nasync function checkCandidate(\n candidate: string,\n workspaceRoot: string\n): Promise<CandidateCheck> {\n let realPath: string;\n let size: number;\n try {\n realPath = await realpath(candidate);\n const stats = await stat(realPath);\n if (!stats.isFile()) {\n return { kind: \"missing\" };\n }\n size = stats.size;\n } catch {\n return { kind: \"missing\" };\n }\n\n const relativePath = workspaceRelativePath(realPath, workspaceRoot);\n if (relativePath === null) {\n return { kind: \"refused\", reason: OUTSIDE_WORKSPACE_REFUSAL };\n }\n if (relativePath.split(\"/\").includes(\"node_modules\")) {\n return { kind: \"refused\", reason: NODE_MODULES_REFUSAL };\n }\n if (!isSourceExtension(realPath)) {\n return { kind: \"refused\", reason: EXTENSION_REFUSAL };\n }\n return { kind: \"found\", realPath, relativePath, size };\n}\n\nasync function locateSourceFile(\n fileName: string,\n roots: ProjectRoots\n): Promise<DevtoolsOutcome<LocatedFile>> {\n let refusal: string | null = null;\n for (const candidate of candidatePaths(fileName, roots)) {\n const check = await checkCandidate(candidate, roots.workspaceRoot);\n if (check.kind === \"found\") {\n return { ok: true, value: check };\n }\n if (check.kind === \"refused\") {\n refusal ??= check.reason;\n }\n }\n if (refusal) {\n return failure(refusal, 403);\n }\n return failure(`Could not find ${fileName} in ${roots.workspaceRoot}.`, 404);\n}\n\n/** Server-map columns can point past the line; the element then starts at its first tag. */\nfunction columnWithinLine(code: string, line: number, column: number | null) {\n const text = code.split(\"\\n\")[line - 1] ?? \"\";\n return column !== null && column < text.length ? column : null;\n}\n\nexport async function readSourceFile(\n frame: SourceRequest,\n roots: ProjectRoots\n): Promise<DevtoolsOutcome<SourceFile>> {\n if (\n frame.fileName.length > MAX_FILE_NAME_LENGTH ||\n frame.fileName.includes(\"\\0\")\n ) {\n return failure(\"That source file name is not a valid path.\", 400);\n }\n const mapped = isServerFrame(frame.fileName)\n ? await mapServerFrame(frame, roots.workspaceRoot)\n : { ok: true as const, value: frame };\n if (!mapped.ok) {\n return mapped;\n }\n const request = mapped.value;\n const fileName = normalizeSourceFileName(request.fileName);\n if (!fileName) {\n return failure(\"A source file name is required.\", 400);\n }\n if (!isSourceExtension(fileName)) {\n return failure(EXTENSION_REFUSAL, 403);\n }\n\n const located = await locateSourceFile(fileName, roots);\n if (!located.ok) {\n return located;\n }\n const { realPath, relativePath, size } = located.value;\n if (size > MAX_SOURCE_BYTES) {\n return failure(\n `${relativePath} is larger than 1 MB, too big to preview.`,\n 413\n );\n }\n\n const code = await readFile(realPath, \"utf8\");\n const column =\n request.line === null\n ? request.column\n : columnWithinLine(code, request.line, request.column);\n const elementLines =\n request.line === null\n ? null\n : jsxElementLines(code, request.line, column ?? 0);\n\n return {\n ok: true,\n value: {\n absolutePath: realPath,\n code,\n column,\n elementLines,\n line: request.line,\n path: relativePath,\n },\n };\n}\n","import {\n DEVTOOLS_ENDPOINTS,\n DEVTOOLS_ROUTE_BASE,\n DEVTOOLS_STATUS_MARKER,\n type DevtoolsStatus,\n} from \"../protocol\";\nimport {\n type DevtoolsOutcome,\n errorResponse,\n jsonResponse,\n} from \"./json-response\";\nimport {\n type DevtoolsEnv,\n type DevtoolsServerOptions,\n type ResolvedDevtoolsOptions,\n resolveDevtoolsOptions,\n} from \"./options\";\nimport { proxyToReflet } from \"./reflet-proxy\";\nimport { rejectUntrustedRequest } from \"./request-guard\";\nimport { searchCode } from \"./source/code-search\";\nimport { type ProjectRoots, resolveProjectRoots } from \"./source/project-roots\";\nimport { readSourceFile } from \"./source/source-file\";\n\nexport type DevtoolsHandler = (request: Request) => Promise<Response>;\n\nconst TRAILING_SLASHES = /\\/+$/;\n\nfunction outcomeResponse<T>(outcome: DevtoolsOutcome<T>): Response {\n return outcome.ok\n ? jsonResponse(outcome.value)\n : errorResponse(outcome.error, outcome.status);\n}\n\nfunction routeSubPath(pathname: string): string | null {\n const baseIndex = pathname.indexOf(DEVTOOLS_ROUTE_BASE);\n if (baseIndex === -1) {\n return null;\n }\n return pathname\n .slice(baseIndex + DEVTOOLS_ROUTE_BASE.length)\n .replace(TRAILING_SLASHES, \"\");\n}\n\nfunction readInteger(value: string | null, minimum: number): number | null {\n if (value === null || value === \"\") {\n return null;\n }\n const parsed = Number(value);\n return Number.isInteger(parsed) && parsed >= minimum ? parsed : null;\n}\n\nasync function routeRequest(\n request: Request,\n settings: ResolvedDevtoolsOptions,\n projectRoots: () => ProjectRoots\n): Promise<Response> {\n const url = new URL(request.url);\n const subPath = routeSubPath(url.pathname);\n\n if (subPath?.startsWith(`${DEVTOOLS_ENDPOINTS.proxy}/`)) {\n const apiPath = subPath.slice(DEVTOOLS_ENDPOINTS.proxy.length);\n return await proxyToReflet(request, apiPath, settings);\n }\n\n const isReadEndpoint =\n subPath === DEVTOOLS_ENDPOINTS.status ||\n subPath === DEVTOOLS_ENDPOINTS.source ||\n subPath === DEVTOOLS_ENDPOINTS.search;\n if (isReadEndpoint && request.method !== \"GET\") {\n return errorResponse(`${subPath} only answers GET requests.`, 405);\n }\n\n switch (subPath) {\n case DEVTOOLS_ENDPOINTS.status:\n return jsonResponse({\n editor: settings.editor,\n hasSecretKey: settings.secretKey !== null,\n marker: DEVTOOLS_STATUS_MARKER,\n } satisfies DevtoolsStatus);\n case DEVTOOLS_ENDPOINTS.source:\n return outcomeResponse(\n await readSourceFile(\n {\n column: readInteger(url.searchParams.get(\"column\"), 0),\n fileName: url.searchParams.get(\"file\") ?? \"\",\n line: readInteger(url.searchParams.get(\"line\"), 1),\n },\n projectRoots()\n )\n );\n case DEVTOOLS_ENDPOINTS.search:\n return outcomeResponse(\n await searchCode(\n projectRoots().workspaceRoot,\n url.searchParams.get(\"q\") ?? \"\"\n )\n );\n default:\n return errorResponse(\n `No Reflet devtools endpoint at ${url.pathname}.`,\n 404\n );\n }\n}\n\nexport function createDevtoolsHandler(\n options: DevtoolsServerOptions = {},\n env: DevtoolsEnv = process.env\n): DevtoolsHandler {\n const settings = resolveDevtoolsOptions(options, env);\n let roots: ProjectRoots | null = null;\n const projectRoots = (): ProjectRoots => {\n roots ??= resolveProjectRoots(settings.root);\n return roots;\n };\n\n return async (request) => {\n const rejection = rejectUntrustedRequest(request, settings.allowedHosts);\n if (rejection) {\n return rejection;\n }\n try {\n return await routeRequest(request, settings, projectRoots);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return errorResponse(`Reflet devtools route failed: ${reason}`, 500);\n }\n };\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as RefletNotFoundError, i as RefletError, n as Reflet, o as RefletValidationError, r as RefletAuthError } from "./client-BWEBWk1k.js";
|
|
2
2
|
export { Reflet, RefletAuthError, RefletError, RefletNotFoundError, RefletValidationError };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
//#region src/devtools/protocol.d.ts
|
|
2
|
+
declare const EDITORS: readonly ["cursor", "vscode", "webstorm", "windsurf", "zed"];
|
|
3
|
+
type EditorId = (typeof EDITORS)[number];
|
|
4
|
+
//#endregion
|
|
5
|
+
//#region src/devtools/server/options.d.ts
|
|
6
|
+
interface DevtoolsServerOptions {
|
|
7
|
+
/** Dev hostnames besides localhost, e.g. `app.test`. Falls back to REFLET_DEVTOOLS_HOSTS, comma-separated. */
|
|
8
|
+
allowedHosts?: string[];
|
|
9
|
+
/** Reflet API origin. Falls back to REFLET_API_URL, then the hosted API. */
|
|
10
|
+
apiUrl?: string;
|
|
11
|
+
/** Editor that "open in editor" links target. Falls back to REFLET_EDITOR. */
|
|
12
|
+
editor?: EditorId;
|
|
13
|
+
/** App directory source paths resolve against. Defaults to the working directory. */
|
|
14
|
+
root?: string;
|
|
15
|
+
/** Falls back to REFLET_SECRET_KEY. Never sent to the browser. */
|
|
16
|
+
secretKey?: string;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { DevtoolsServerOptions as t };
|
|
20
|
+
//# sourceMappingURL=options-7KtQZJj8.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options-7KtQZJj8.d.ts","names":[],"sources":["../src/devtools/protocol.ts","../src/devtools/server/options.ts"],"mappings":";cAuBa;KAQD,mBAAmB;;;UC3Bd;;EAEf;;EAEA;;EAEA,SAAS;;EAET;;EAEA"}
|