Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/typescript-6-upgrade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@clerk/cli-core": patch
---

Upgrade workspace and e2e fixtures to TypeScript 6
64 changes: 22 additions & 42 deletions bun.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
"scripts": {
"build": "bun run --filter @clerk/cli-core build",
"dev": "bun run --cwd packages/cli-core dev",
"typecheck": "bun run --filter @clerk/cli-core typecheck && tsc --noEmit -p scripts/tsconfig.json",
"test": "bun run scripts/run-tests.ts --pattern 'packages/cli-core/src/**/*.test.ts' --pattern 'scripts/**/*.test.ts'",
"test:e2e": "bun run scripts/run-tests.ts --pattern 'test/e2e/*.test.ts' --retries 1",
"test:e2e:op": "bun run scripts/run-e2e-op.ts",
"e2e:refresh-fixtures": "bun run scripts/refresh-e2e-fixtures.ts",
"typecheck": "bun run --filter @clerk/cli-core typecheck && tsc --noEmit -p scripts/tsconfig.json",
"lint": "bun run --filter @clerk/cli-core lint && oxlint -c .oxlintrc.json scripts/",
"format": "bun run --filter @clerk/cli-core format && oxfmt --write scripts/",
"format:check": "bun run --filter @clerk/cli-core format:check && oxfmt --check scripts/",
Expand Down
5 changes: 3 additions & 2 deletions packages/cli-core/mocks/bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/cli-core/mocks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"dev": "vite"
},
"devDependencies": {
"typescript": "^5",
"typescript": "^6.0.2",
"vite": "^6.3.5"
}
}
4 changes: 2 additions & 2 deletions packages/cli-core/mocks/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ const app = document.getElementById("app")!;
const params = new URLSearchParams(window.location.search);
const callbackPort = params.get("callback_port");

type Screen = "sign-in" | "sign-up" | "select-app" | "success-new" | "success-existing";
type AppScreen = "sign-in" | "sign-up" | "select-app" | "success-new" | "success-existing";

function render(screen: Screen) {
function render(screen: AppScreen) {
switch (screen) {
case "sign-in":
return renderSignIn();
Expand Down
4 changes: 2 additions & 2 deletions packages/cli-core/src/commands/api/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
promptsStubs,
stubFetch,
} from "../../test/lib/stubs.ts";
import { getPlapiBaseUrl } from "../../lib/environment.ts";

let mockStoredToken: string | null = null;
mock.module("../../lib/credential-store.ts", () => ({
Expand Down Expand Up @@ -404,8 +405,7 @@ describe("api command", () => {
});

await runApi("/v1/platform/applications", { platform: true });
expect(capturedUrl).toContain("api.clerk.com");
expect(capturedUrl).not.toContain("api.clerk.dev");
expect(capturedUrl).toStartWith(`${getPlapiBaseUrl()}/`);
expect(capturedHeaders?.get("Authorization")).toBe("Bearer plat_key_123");
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ function ensureRouteImported(source: string): string {
const importMatch = source.match(
/import\s*\{([^}]*)\}\s*from\s*["']@react-router\/dev\/routes["']/,
);
if (!importMatch || /\broute\b/.test(importMatch[1]!)) return source;
const importedNames = importMatch?.[1];
if (!importedNames || /\broute\b/.test(importedNames)) return source;

return source.replace(
/(\bimport\s*\{[^}]*)(\}\s*from\s*["']@react-router\/dev\/routes["'])/,
Expand Down Expand Up @@ -311,7 +312,7 @@ function injectRouteEntries(
const canonicalPattern = /export default \[([^\]]*)\]\s*satisfies\s*RouteConfig\s*;/s;
const canonical = source.match(canonicalPattern);
if (canonical) {
const innerContent = canonical[1]!.trimEnd();
const innerContent = (canonical[1] ?? "").trimEnd();
const separator = innerContent.length > 0 && !innerContent.endsWith(",") ? "," : "";
const newInner = `${innerContent}${separator}\n ${newEntries},\n`;
return source.replace(canonicalPattern, `export default [${newInner}] satisfies RouteConfig;`);
Expand All @@ -321,7 +322,7 @@ function injectRouteEntries(
const simplePattern = /(export\s+default\s+\[)([\s\S]*?)(\]\s*;)/;
const simple = source.match(simplePattern);
if (simple) {
const innerContent = simple[2]!.trimEnd();
const innerContent = (simple[2] ?? "").trimEnd();
const separator = innerContent.length > 0 && !innerContent.endsWith(",") ? "," : "";
const newInner = `${innerContent}${separator}\n ${newEntries},\n`;
return source.replace(simplePattern, `$1${newInner}$3`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export function wrapBodyWithProvider(content: string, provider: string): string
const providerIndent = bodyIndent + " ";
const contentIndent = providerIndent + " ";

const trimmedInner = inner.trim();
const trimmedInner = (inner ?? "").trim();
const reindented = trimmedInner
.split("\n")
.map((line) => {
Expand Down
8 changes: 7 additions & 1 deletion packages/cli-core/src/commands/init/heuristics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ async function runPmInstall(
label: string,
{ fromLockfile = false }: { fromLockfile?: boolean } = {},
): Promise<void> {
const pmBinary = addCmd.split(" ")[0]!;
const manualCmd = `${addCmd} ${packages.join(" ")}`;

// The package manager is detected from lockfiles, which can exist without
// the actual binary being installed (e.g. teammate committed bun.lock, you
// only have npm). Fail fast with a useful message rather than a raw ENOENT.
const pmBinary = addCmd.split(" ")[0];
if (!pmBinary) {
throw new Error(`Invalid package manager install command: ${addCmd}`);
}
if (Bun.which(pmBinary) === null) {
const hint = fromLockfile
? ` (detected from lockfile — install ${pmBinary} or switch package managers)`
Expand Down
4 changes: 2 additions & 2 deletions packages/cli-core/src/commands/init/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ const FAKE_CTX = {
name: "React",
sdk: "@clerk/react",
envVar: "VITE_CLERK_PUBLISHABLE_KEY",
envFile: ".env" as const,
envFile: ".env.local" as const,
},
typescript: true,
srcDir: false,
packageManager: "npm" as const,
existingClerk: true,
deps: { react: "^19.0.0" },
envFile: ".env",
envFile: ".env.local",
};

const FAKE_BOOTSTRAP = {
Expand Down
7 changes: 6 additions & 1 deletion packages/cli-core/src/lib/auth-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,13 @@ export function startAuthServer(expectedState: string): AuthServerResult {
const activeServer = server;
log.debug(`auth-server: listening on 127.0.0.1:${activeServer.port} for ${CALLBACK_PATH}`);

const port = server.port;
if (port === undefined) {
throw new Error("Failed to determine auth server port.");
}

return {
port: activeServer.port!,
port,
waitForCallback: () => callbackPromise,
stop: () => {
clearTimeout(timeout);
Expand Down
8 changes: 5 additions & 3 deletions packages/cli-core/src/lib/dotenv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ export function parseEnvFile(content: string): EnvLine[] {
if (line.trim() === "") return { type: "blank" };
const match = line.match(ENTRY_RE);
if (!match) return { type: "comment", raw: line };
const key = match[2]!;
let value = match[3]!;
const key = match[2];
if (!key) return { type: "comment", raw: line };
let value = match[3] ?? "";
// Strip surrounding quotes
if (
(value.startsWith('"') && value.endsWith('"')) ||
Expand All @@ -59,7 +60,8 @@ export function mergeEnvVars(lines: EnvLine[], vars: Record<string, string>): En
const remaining = { ...vars };
const result = lines.map((line): EnvLine => {
if (line.type !== "entry" || !(line.key in remaining)) return line;
const value = remaining[line.key]!;
const value = remaining[line.key];
if (value === undefined) return line;
delete remaining[line.key];
return { type: "entry", key: line.key, value, raw: `${line.key}=${value}` };
});
Expand Down
11 changes: 6 additions & 5 deletions packages/cli-core/src/lib/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,14 +102,15 @@ export function clerkHelpConfig(): Partial<Help> {
c.argsStr ? c.name.padEnd(maxNameLen + 2) + c.argsStr : c.name,
);
const termWidth = Math.max(...terms.map((t) => helper.displayWidth(t)));
const items = terms.map((term, i) =>
helper.formatItem(
const items = terms.map((term, i) => {
const description = cmdData[i]?.description ?? "";
return helper.formatItem(
helper.styleSubcommandTerm(term),
termWidth,
helper.styleSubcommandDescription(cmdData[i]!.description),
helper.styleSubcommandDescription(description),
helper,
),
);
);
});
output = output.concat(helper.formatItemList("Commands:", items, helper));
}

Expand Down
2 changes: 1 addition & 1 deletion packages/cli-core/src/lib/spinner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function createSpinner() {
}
stream.write("\x1b[?25l"); // hide cursor
timer = setInterval(() => {
const char = cyan(FRAMES[frame++ % FRAMES.length]!);
const char = cyan(FRAMES[frame++ % FRAMES.length] ?? FRAMES[0]!);
stream.write(`\r\x1b[K${char} ${message}`);
}, INTERVAL);
},
Expand Down
1 change: 1 addition & 0 deletions test/e2e/fixtures/nextjs-app-router-next14/css.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
declare module "*.css" {}
2 changes: 1 addition & 1 deletion test/e2e/fixtures/nextjs-app-router-next14/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"typescript": "^5"
"typescript": "^6.0.2"
}
}
2 changes: 1 addition & 1 deletion test/e2e/fixtures/nextjs-app-router/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"typescript": "^5"
"typescript": "^6.0.2"
},
"ignoreScripts": [
"sharp",
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/fixtures/nextjs-pages-router/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@types/node": "^20",
"@types/react": "^19",
"@types/react-dom": "^19",
"typescript": "^5"
"typescript": "^6.0.2"
},
"ignoreScripts": [
"sharp",
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/fixtures/react-router/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3",
"tailwindcss": "^4.1.13",
"typescript": "^5.9.2",
"typescript": "^6.0.2",
"vite": "^7.1.7",
"vite-tsconfig-paths": "^5.1.4"
}
Expand Down
1 change: 0 additions & 1 deletion test/e2e/fixtures/react-router/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"moduleResolution": "bundler",
"jsx": "react-jsx",
"rootDirs": [".", "./.react-router/types"],
"baseUrl": ".",
"paths": {
"~/*": ["./app/*"]
},
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/fixtures/tanstack-start/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@types/react-dom": "^19.2.0",
"@vitejs/plugin-react": "^6.0.1",
"jsdom": "^28.1.0",
"typescript": "^5.7.2",
"typescript": "^6.0.2",
"vite": "^8.0.0",
"vitest": "^3.0.5"
},
Expand Down
1 change: 0 additions & 1 deletion test/e2e/fixtures/tanstack-start/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"target": "ES2022",
"jsx": "react-jsx",
"module": "ESNext",
"baseUrl": ".",
"paths": {
"#/*": ["./src/*"],
"@/*": ["./src/*"]
Expand Down
Loading