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
38 changes: 30 additions & 8 deletions src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import {
removePreview,
setSimulatorUrl,
} from "../lib/prismic/clients/core";
import { getRepository, type Repository } from "../lib/prismic/clients/repository";
import {
enableTypeBuilder,
getRepository,
type Repository,
} from "../lib/prismic/clients/repository";
import { getProfile } from "../lib/prismic/clients/user";
import { diffModels, getLegacySlices, getRemoteModels } from "../lib/prismic/models";
import { completeOnboardingSteps } from "../lib/prismic/onboarding";
Expand All @@ -36,7 +40,6 @@ import {
MissingPrismicConfigError,
readConfig,
readLegacySliceMachineConfig,
TypeBuilderRequiredError,
UnknownProjectRootError,
updateConfig,
} from "../project";
Expand Down Expand Up @@ -155,12 +158,6 @@ export default createCommand(config, async ({ values }) => {
`Repository "${repo}" not found in your account. Check the name or request access to the repository.`,
);
});

const isTypeBuilderEnabled =
env.PRISMIC_TYPE_BUILDER_ENABLED ?? connectedRepository.quotas?.sliceMachineEnabled === true;
if (!isTypeBuilderEnabled) {
throw new TypeBuilderRequiredError(repo);
}
}

let adapter: Adapter;
Expand All @@ -181,6 +178,31 @@ export default createCommand(config, async ({ values }) => {
`);
}

// The editor shows code snippets for the repository's framework.
const isTypeBuilderEnabled =
env.PRISMIC_TYPE_BUILDER_ENABLED ?? connectedRepository?.quotas?.sliceMachineEnabled;
if (
repo &&
connectedRepository &&
(!isTypeBuilderEnabled || connectedRepository.framework !== adapter.id)
) {
try {
await enableTypeBuilder(adapter.id, { repo, token, host });
if (!isTypeBuilderEnabled)
console.info(`Turned on the Type Builder for repository "${repo}".`);
} catch (error) {
if (!(error instanceof ForbiddenRequestError)) throw error;
if (!isTypeBuilderEnabled) {
throw new CommandError(
`Repository "${repo}" uses the Legacy Builder. Only a repository administrator can turn on the Type Builder. Ask an administrator to run \`prismic init\`.`,
);
}
console.warn(
`Could not set the repository's framework to ${adapter.id}. Ask a repository administrator to run \`prismic init\`.`,
);
}
}

if (!repo) {
repo = await createRepo({
name: values["repo-name"],
Expand Down
4 changes: 1 addition & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import {
InvalidPrismicConfigError,
MissingPrismicConfigError,
getRepositoryName,
TypeBuilderRequiredError,
UnknownProjectRootError,
} from "./project";
import {
Expand Down Expand Up @@ -74,15 +73,14 @@ const KNOWN_ERRORS = [
InvalidLegacySliceMachineConfigError,
MissingPackageJson,
UnknownProjectRootError,
TypeBuilderRequiredError,
NotFoundRequestError,
UnauthorizedRequestError,
ForbiddenRequestError,
BadRequestError,
UnknownRequestError,
];

const REPORTED_KNOWN_ERRORS = [BadRequestError, UnknownRequestError, TypeBuilderRequiredError];
const REPORTED_KNOWN_ERRORS = [BadRequestError, UnknownRequestError];

await main();

Expand Down
9 changes: 9 additions & 0 deletions src/lib/prismic/clients/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const RepositoryStarterSchema = z.object({
const RepositorySchema = z.object({
name: z.optional(z.string()),
starter: z.nullish(RepositoryStarterSchema),
framework: z.optional(z.string()),
quotas: z.optional(
z.object({
sliceMachineEnabled: z.boolean(),
Expand All @@ -32,6 +33,14 @@ export function getRepository(config: RepositoryConfig): Promise<Repository> {
return repositoryServiceRequest(url, config, { schema: RepositorySchema });
}

export async function enableTypeBuilder(
framework: string,
config: RepositoryConfig,
): Promise<void> {
const url = new URL("type-builder", getRepositoryServiceUrl(config.host));
await repositoryServiceRequest(url, config, { method: "PATCH", json: { framework } });
}

const OnboardingStateSchema = z.object({
completedSteps: z.array(z.string()),
});
Expand Down
14 changes: 0 additions & 14 deletions src/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import * as z from "zod/mini";
import { exists, findUpward, readJsonFile } from "./lib/file";
import { stringify } from "./lib/json";
import { findPackageJson, MissingPackageJson } from "./lib/packageJson";
import { dedent } from "./lib/string";
import { appendTrailingSlash } from "./lib/url";

const CONFIG_FILENAME = "prismic.config.json";
Expand Down Expand Up @@ -216,16 +215,3 @@ export async function checkIsTypeScriptProject(): Promise<boolean> {
const projectRoot = await findProjectRoot();
return exists(new URL("tsconfig.json", projectRoot));
}

export class TypeBuilderRequiredError extends Error {
name = "TypeBuilderRequired";
constructor(repo: string) {
super(dedent`
This command requires the Type Builder, but repository "${repo}" uses the Legacy Builder.

Contact Prismic support to enable the Type Builder: https://prismic.io/docs/help-center

Learn more at https://prismic.io/docs/type-builder
`);
}
}
13 changes: 9 additions & 4 deletions test/init.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,13 +314,18 @@ it("fails with next steps when no supported framework is found", async ({
expect(stderr).toContain("prismic repo create --framework");
});

it("fails when Type Builder is not enabled", async ({ expect, project, prismic, repo }) => {
it("turns on the Type Builder when it is not enabled", async ({
expect,
project,
prismic,
repo,
}) => {
await rm(new URL("prismic.config.json", project));
const { exitCode, stderr } = await prismic("init", ["--repo", repo], {
const { exitCode, stdout, stderr } = await prismic("init", ["--repo", repo, "--no-setup"], {
nodeOptions: { env: { PRISMIC_TYPE_BUILDER_ENABLED: "false" } },
});
expect(exitCode).toBe(1);
expect(stderr).toContain("Type Builder");
expect(exitCode, stderr).toBe(0);
expect(stdout).toContain(`Turned on the Type Builder for repository "${repo}".`);
});

it("installs dependencies", { timeout: 30_000 }, async ({ expect, project, prismic, repo }) => {
Expand Down
Loading