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
11 changes: 11 additions & 0 deletions src/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from "../config";
import { getFramework } from "../frameworks";
import { openBrowser } from "../lib/browser";
import { generateAndWriteTypes } from "../lib/codegen";
import { ForbiddenRequestError, UnauthorizedRequestError } from "../lib/request";
import { syncCustomTypes, syncSlices } from "./sync";

Expand Down Expand Up @@ -154,6 +155,16 @@ export async function init(): Promise<void> {
await syncSlices(repo, framework);
await syncCustomTypes(repo, framework);

// Generate TypeScript types from synced models
const slices = await framework.getSlices();
const customTypes = await framework.getCustomTypes();
const projectRoot = await framework.getProjectRoot();
await generateAndWriteTypes({
customTypes: customTypes.map((customType) => customType.model),
slices: slices.map((slice) => slice.model),
projectRoot,
});
Copy link

Choose a reason for hiding this comment

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

Duplicated type regeneration logic across two files

Low Severity

The inline code in init.ts that calls framework.getSlices(), framework.getCustomTypes(), framework.getProjectRoot(), and then generateAndWriteTypes() is an exact duplicate of the regenerateTypes function in sync.ts. If the codegen behavior ever needs to change (e.g., different options, added error handling), both locations need updating, and forgetting one would introduce a bug. The regenerateTypes helper could live in codegen.ts and be shared.

Additional Locations (1)
Fix in Cursor Fix in Web


console.info(
`Initialized Prismic for repository "${repo}". Run \`npm install\` to install new dependencies.`,
);
Expand Down
16 changes: 16 additions & 0 deletions src/commands/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getHost, getToken } from "../auth";
import { getCustomTypes, getSlices } from "../clients/custom-types";
import { safeGetRepositoryFromConfig } from "../config";
import { type FrameworkAdapter, NoSupportedFrameworkError, requireFramework } from "../frameworks";
import { generateAndWriteTypes } from "../lib/codegen";
import { segmentSetRepository, segmentTrackEnd, segmentTrackStart } from "../lib/segment";
import { sentrySetContext, sentrySetTag } from "../lib/sentry";
import { dedent } from "../lib/string";
Expand Down Expand Up @@ -80,6 +81,7 @@ export async function sync(): Promise<void> {
} else {
await syncSlices(repo, framework);
await syncCustomTypes(repo, framework);
await regenerateTypes(framework);
segmentTrackEnd("sync", true, undefined, { watch: false });

console.info("Sync complete");
Expand All @@ -95,6 +97,7 @@ async function watchForChanges(repo: string, framework: FrameworkAdapter) {

await syncSlices(repo, framework);
await syncCustomTypes(repo, framework);
await regenerateTypes(framework);

console.info(dedent`
Initial sync completed!
Expand Down Expand Up @@ -143,6 +146,8 @@ async function watchForChanges(repo: string, framework: FrameworkAdapter) {
changed.push("custom types");
}

await regenerateTypes(framework);
Copy link

Choose a reason for hiding this comment

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

Hash updates before codegen prevents retry on failure

Medium Severity

In the watch loop, lastRemoteSlicesHash and lastRemoteCustomTypesHash are updated (lines 140, 145) before regenerateTypes runs (line 149). If regenerateTypes throws, the error is caught by the outer catch, but the hashes are already committed. On the next poll, remote hashes match the stored hashes, so no changes are detected — the codegen is never retried for those changes. The prismicio-types.d.ts file remains stale until an entirely new remote change occurs.

Fix in Cursor Fix in Web


const timestamp = new Date().toLocaleTimeString();
console.info(`[${timestamp}] Changes detected in ${changed.join(" and ")}`);
}
Expand Down Expand Up @@ -254,3 +259,14 @@ function exponentialMs(base: number): number {
function hash(data: unknown): string {
return createHash("sha256").update(JSON.stringify(data)).digest("hex");
}

async function regenerateTypes(framework: FrameworkAdapter): Promise<void> {
const slices = await framework.getSlices();
const customTypes = await framework.getCustomTypes();
const projectRoot = await framework.getProjectRoot();
await generateAndWriteTypes({
customTypes: customTypes.map((customType) => customType.model),
slices: slices.map((slice) => slice.model),
projectRoot,
});
}
23 changes: 23 additions & 0 deletions src/lib/codegen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { CustomType, SharedSlice } from "@prismicio/types-internal/lib/customtypes";

import { writeFile } from "node:fs/promises";
import { generateTypes } from "prismic-ts-codegen";

export async function generateAndWriteTypes(args: {
customTypes: CustomType[];
slices: SharedSlice[];
projectRoot: URL;
}): Promise<void> {
const types = generateTypes({
customTypeModels: args.customTypes,
sharedSliceModels: args.slices,
clientIntegration: {
includeContentNamespace: true,
includeCreateClientInterface: true,
},
cache: true,
typesProvider: "@prismicio/client",
});
const outputPath = new URL("prismicio-types.d.ts", args.projectRoot);
await writeFile(outputPath, types);
}