Skip to content
Merged
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/verify-contributor-guidance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"seamless-cli": patch
---

`seamless verify` run without a seamless-auth-api checkout now says it is a contributor tool, where to clone the API, and that `seamless check` is the command for a scaffolded project. From an npx or global install it no longer prints a path inside the npm cache, and `seamless verify --help` says the same up front.
5 changes: 4 additions & 1 deletion src/commands/helpTopics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,10 @@ The code replaces any code sent before and expires in 5 minutes.
sections: [
{
heading: "verify [--local] [--api-only] [--dev] [--filter=<flow>] [--keep-up]",
body: `Stand up the auth stack and run the conformance suite across the API and
body: `For Seamless contributors: to check a project made by init, use
seamless check instead.

Stand up the auth stack and run the conformance suite across the API and
the cookie (adapter) paths. Requires Docker. Builds the auth server from
a sibling seamless-auth-api checkout (override with SEAMLESS_API_DIR).

Expand Down
26 changes: 25 additions & 1 deletion src/commands/verify.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { execSync } from "child_process";
import fs from "fs";

import { runCommand } from "../core/exec.js";
import { runVerify } from "./verify.js";
import { resolveApiDir, runVerify } from "./verify.js";

// Every browser profile, as a clean, a log dump, or a teardown passes them.
const ALL_PROFILES = [
Expand Down Expand Up @@ -694,6 +694,30 @@ describe("runVerify: setup failures (thrown before the run)", () => {
await expect(runVerify([])).rejects.toThrow(/seamless-auth-api/);
});

it("says what verify is for and points at check when the source is missing", async () => {
vi.mocked(fs.existsSync).mockImplementation((p: never) => !String(p).includes("/fake/api"));
await expect(runVerify([])).rejects.toThrow(/contributors[\s\S]*seamless check/);
});

it("names no npx cache path when run from an npm install", () => {
delete process.env.SEAMLESS_API_DIR;
const npxRoot = "/home/me/.npm/_npx/abc123/node_modules/seamless-cli";
expect(() => resolveApiDir(npxRoot)).toThrow(/^No seamless-auth-api source to build/);
expect(() => resolveApiDir(npxRoot)).not.toThrow(/_npx/);
expect(fs.existsSync).not.toHaveBeenCalled();
});

it("uses SEAMLESS_API_DIR even from an npm install", () => {
expect(resolveApiDir("/home/me/.npm/_npx/abc123/node_modules/seamless-cli")).toBe(
"/fake/api",
);
});

it("defaults to a sibling checkout for a linked CLI", () => {
delete process.env.SEAMLESS_API_DIR;
expect(resolveApiDir("/home/me/git/seamless-cli")).toBe("/home/me/git/seamless-auth-api");
});

it("aborts when the templates registry is missing", async () => {
vi.mocked(fs.existsSync).mockImplementation((p: never) => !String(p).endsWith("registry.json"));
await expect(runVerify([])).rejects.toThrow(/templates registry/);
Expand Down
23 changes: 17 additions & 6 deletions src/commands/verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,26 @@ function ensureDocker(): void {
}
}

const API_SOURCE_HELP =
" `seamless verify` is the conformance suite for Seamless contributors. It builds\n" +
" the auth server from a clone of https://github.com/fells-code/seamless-auth-api:\n" +
" clone it and set SEAMLESS_API_DIR to that folder.\n" +
" To check a project made by `seamless init`, run: seamless check";

// The auth API is built from local source. Defaults to a sibling checkout so a
// linked CLI works without extra config; override with SEAMLESS_API_DIR.
function resolveApiDir(): string {
const candidate =
process.env.SEAMLESS_API_DIR ?? path.resolve(REPO_ROOT, "..", "seamless-auth-api");
// linked CLI works without extra config; override with SEAMLESS_API_DIR. An npm
// install (npx, global) has no sibling worth guessing: it would sit in the package
// cache, and naming that path only confuses someone who ran verify by mistake.
export function resolveApiDir(cliRoot: string = REPO_ROOT): string {
const fromEnv = process.env.SEAMLESS_API_DIR;
const installedFromNpm = cliRoot.split(path.sep).includes("node_modules");
if (!fromEnv && installedFromNpm) {
throw new Error(`No seamless-auth-api source to build.\n${API_SOURCE_HELP}`);
}
const candidate = fromEnv ?? path.resolve(cliRoot, "..", "seamless-auth-api");
if (!fs.existsSync(path.join(candidate, "package.json"))) {
throw new Error(
`Could not find the seamless-auth-api source at ${candidate}.\n` +
" Set SEAMLESS_API_DIR to its local checkout.",
`Could not find the seamless-auth-api source at ${candidate}.\n${API_SOURCE_HELP}`,
);
}
return candidate;
Expand Down
Loading