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
25 changes: 22 additions & 3 deletions src/adapters/nextjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { relative } from "node:path";
import { fileURLToPath } from "node:url";

import { Adapter } from ".";
import { getHost, getToken } from "../auth";
import { addPreview, getPreviews, getSimulatorUrl, setSimulatorUrl } from "../clients/core";
import { exists, writeFileRecursive } from "../lib/file";
import { addDependencies, findPackageJson, getNpmPackageVersion } from "../lib/packageJson";
import { dedent } from "../lib/string";
import { appendTrailingSlash } from "../lib/url";
import { buildRoutePath } from "../project";
import { buildRoutePath, getRepositoryName } from "../project";
import { checkIsTypeScriptProject, findProjectRoot } from "../project";
import {
pageTemplate,
Expand Down Expand Up @@ -38,7 +40,24 @@ export class NextJsAdapter extends Adapter {
await createRevalidateRoute();
}

onProjectInitialized(): void {}
async onProjectInitialized(): Promise<void> {
const repo = await getRepositoryName();
const token = await getToken();
const host = await getHost();

const simulatorUrl = await getSimulatorUrl({ repo, token, host });
if (!simulatorUrl) {
await setSimulatorUrl("http://localhost:3000/slice-simulator", { repo, token, host });
}

const previews = await getPreviews({ repo, token, host });
if (previews.length === 0) {
await addPreview(
{ name: "Development", websiteURL: "http://localhost:3000", resolverPath: "/api/preview" },
{ repo, token, host },
);
}
}
Comment thread
angeloashmore marked this conversation as resolved.

async onSliceCreated(model: SharedSlice, library: URL): Promise<void> {
const sliceDirectoryName = pascalCase(model.name);
Expand Down Expand Up @@ -102,7 +121,7 @@ export class NextJsAdapter extends Adapter {

async getDefaultCustomTypeLibrary(): Promise<URL> {
const projectRoot = await findProjectRoot();
const defaultCustomTypeLibrary = new URL("customtypes/", projectRoot)
const defaultCustomTypeLibrary = new URL("customtypes/", projectRoot);
return defaultCustomTypeLibrary;
}
}
Expand Down
25 changes: 22 additions & 3 deletions src/adapters/nuxt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import { relative } from "node:path";
import { fileURLToPath } from "node:url";

import { Adapter } from ".";
import { getHost, getToken } from "../auth";
import { addPreview, getPreviews, getSimulatorUrl, setSimulatorUrl } from "../clients/core";
import { exists, writeFileRecursive } from "../lib/file";
import { addDependencies, getNpmPackageVersion } from "../lib/packageJson";
import { dedent } from "../lib/string";
import { appendTrailingSlash } from "../lib/url";
import { buildRoutePath, readConfig, updateConfig } from "../project";
import { buildRoutePath, getRepositoryName, readConfig, updateConfig } from "../project";
import { checkIsTypeScriptProject, findProjectRoot } from "../project";
import { pageTemplate, sliceSimulatorPageTemplate, sliceTemplate } from "./nuxt.templates";

Expand All @@ -31,7 +33,24 @@ export class NuxtAdapter extends Adapter {
await modifySliceLibraryPath(this);
}

onProjectInitialized(): void {}
async onProjectInitialized(): Promise<void> {
const repo = await getRepositoryName();
const token = await getToken();
const host = await getHost();

const simulatorUrl = await getSimulatorUrl({ repo, token, host });
if (!simulatorUrl) {
await setSimulatorUrl("http://localhost:3000/slice-simulator", { repo, token, host });
}

const previews = await getPreviews({ repo, token, host });
if (previews.length === 0) {
await addPreview(
{ name: "Development", websiteURL: "http://localhost:3000", resolverPath: "/preview" },
{ repo, token, host },
);
}
}

async onSliceCreated(model: SharedSlice, library: URL): Promise<void> {
const sliceDirectoryName = pascalCase(model.name);
Expand Down Expand Up @@ -87,7 +106,7 @@ export class NuxtAdapter extends Adapter {

async getDefaultCustomTypeLibrary(): Promise<URL> {
const projectRoot = await findProjectRoot();
const defaultCustomTypeLibrary = new URL("customtypes/", projectRoot)
const defaultCustomTypeLibrary = new URL("customtypes/", projectRoot);
return defaultCustomTypeLibrary;
}
}
Expand Down
25 changes: 22 additions & 3 deletions src/adapters/sveltekit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import { relative } from "node:path";
import { fileURLToPath } from "node:url";

import { Adapter } from ".";
import { getHost, getToken } from "../auth";
import { addPreview, getPreviews, getSimulatorUrl, setSimulatorUrl } from "../clients/core";
import { exists, writeFileRecursive } from "../lib/file";
import { addDependencies, findPackageJson, getNpmPackageVersion } from "../lib/packageJson";
import { dedent } from "../lib/string";
import { appendTrailingSlash } from "../lib/url";
import { buildRoutePath } from "../project";
import { buildRoutePath, getRepositoryName } from "../project";
import { checkIsTypeScriptProject, findProjectRoot } from "../project";
import {
pageServerTemplate,
Expand Down Expand Up @@ -42,7 +44,24 @@ export class SvelteKitAdapter extends Adapter {
await modifyViteConfig();
}

onProjectInitialized(): void {}
async onProjectInitialized(): Promise<void> {
const repo = await getRepositoryName();
const token = await getToken();
const host = await getHost();

const simulatorUrl = await getSimulatorUrl({ repo, token, host });
if (!simulatorUrl) {
await setSimulatorUrl("http://localhost:5173/slice-simulator", { repo, token, host });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 I always wondered why we don’t also use localhost:3000 for SvelteKit. I know 5173 is the default from Vite, but having 3000 everywhere could make things simpler and more consistent I guess.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5173 is 1337 for SITE 🤓

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also VITE since 5 is V in Roman numerals!

@xrutayisire: I always wondered why we don’t also use localhost:3000 for SvelteKit. I know 5173 is the default from Vite, but having 3000 everywhere could make things simpler and more consistent I guess.

It's better to follow each framework's conventions, in my opinion, rather than force our conventions. Developers will be less surprised and will have less to learn if we follow what they expect.

}

const previews = await getPreviews({ repo, token, host });
if (previews.length === 0) {
await addPreview(
{ name: "Development", websiteURL: "http://localhost:5173", resolverPath: "/api/preview" },
{ repo, token, host },
);
}
}

async onSliceCreated(model: SharedSlice, library: URL): Promise<void> {
const sliceDirectoryName = pascalCase(model.name);
Expand Down Expand Up @@ -103,7 +122,7 @@ export class SvelteKitAdapter extends Adapter {

async getDefaultCustomTypeLibrary(): Promise<URL> {
const projectRoot = await findProjectRoot();
const defaultCustomTypeLibrary = new URL("customtypes/", projectRoot)
const defaultCustomTypeLibrary = new URL("customtypes/", projectRoot);
return defaultCustomTypeLibrary;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export default createCommand(config, async ({ values }) => {
}
}

let repo = explicitRepo ?? legacySliceMachineConfig?.repositoryName;
let repo = (explicitRepo ?? legacySliceMachineConfig?.repositoryName)?.toLowerCase();
if (repo) {
const hasRepoAccess = profile.repositories.some((repository) => repository.domain === repo);
if (!hasRepoAccess) {
Expand Down
58 changes: 57 additions & 1 deletion test/init.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { access, readFile, rm, writeFile } from "node:fs/promises";
import { onTestFinished } from "vitest";

import { captureOutput, it } from "./it";
import {
addPreview,
createRepository,
deleteRepository,
getPreviews,
getRepository,
setSimulatorUrl,
} from "./prismic";

it("supports --help", async ({ expect, prismic }) => {
const { stdout, exitCode } = await prismic("init", ["--help"]);
Expand All @@ -18,16 +27,63 @@ it("creates a repo if --repo is not provided and no legacy config exists", async
expect,
project,
prismic,
token,
host,
password,
}) => {
await rm(new URL("prismic.config.json", project));
const { exitCode, stdout } = await prismic("init");
const createdRepositoryMatch = stdout.match(/^Created repository: ([a-z0-9-]+)$/m);
const name = createdRepositoryMatch?.[1];
if (!name) throw new Error(`Could not find created repository name in output:\n${stdout}`);
onTestFinished(() => deleteRepository(name, { token, password, host }));

expect(exitCode).toBe(0);
expect(stdout).toContain("Created repository:");
expect(stdout).toContain("Initialized Prismic for repository");

const configRaw = await readFile(new URL("prismic.config.json", project), "utf-8");
const config = JSON.parse(configRaw);
expect(config.repositoryName).toMatch(/^[a-f0-9]{8}$/);
expect(config.repositoryName).toBe(name);

const repository = await getRepository({ repo: name, token, host });
expect(repository.simulatorUrl).toBe("http://localhost:3000/slice-simulator");

const previews = await getPreviews({ repo: name, token, host });
const dev = previews.find((p) => p.url === "http://localhost:3000/api/preview");
expect(dev?.label).toBe("Development");
Comment thread
cursor[bot] marked this conversation as resolved.
}, 60_000);

it("preserves existing preview config", async ({
expect,
project,
prismic,
token,
password,
host,
}) => {
const rawName = `CLI-Test-${crypto.randomUUID().slice(0, 8)}`;
const name = rawName.toLowerCase();
onTestFinished(() => deleteRepository(name, { token, password, host }));
await createRepository(name, { token, host });

const presetSimulator = "https://staging.example.com/slice-simulator";
await setSimulatorUrl(presetSimulator, { repo: name, token, host });
await addPreview("https://staging.example.com/api/preview", "Staging", {
repo: name,
token,
host,
});

await rm(new URL("prismic.config.json", project));
const { exitCode } = await prismic("init", ["--repo", rawName]);
expect(exitCode).toBe(0);

const repository = await getRepository({ repo: name, token, host });
expect(repository.simulatorUrl).toBe(presetSimulator);

const previews = await getPreviews({ repo: name, token, host });
expect(previews.map((p) => p.label)).toEqual(["Staging"]);
}, 60_000);

it("initializes a project with --repo when logged in", async ({
Expand Down
14 changes: 14 additions & 0 deletions test/prismic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,20 @@ export async function deleteWriteToken(tokenValue: string, config: RepoConfig):
throw new Error(`Failed to delete write token: ${res.status} ${await res.text()}`);
}

export async function setSimulatorUrl(simulatorUrl: string, config: RepoConfig): Promise<void> {
const host = config.host ?? DEFAULT_HOST;
const url = new URL("core/repository", `https://${config.repo}.${host}/`);
const res = await fetch(url, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Cookie: `prismic-auth=${config.token}`,
},
body: JSON.stringify({ simulator_url: simulatorUrl }),
});
if (!res.ok) throw new Error(`Failed to set simulator URL: ${res.status} ${await res.text()}`);
}

export async function getRepository(
config: RepoConfig,
): Promise<{ name: string; framework: string; simulatorUrl?: string }> {
Expand Down