diff --git a/src/adapters/nextjs.ts b/src/adapters/nextjs.ts index c456fbc..4d67ed4 100644 --- a/src/adapters/nextjs.ts +++ b/src/adapters/nextjs.ts @@ -15,7 +15,7 @@ import { getSimulatorUrl, setSimulatorUrl, } from "../lib/prismic/clients/core"; -import { dedent } from "../lib/string"; +import { dedent, formatObjectKey } from "../lib/string"; import { appendTrailingSlash } from "../lib/url"; import { buildRoutePath, getRepositoryName } from "../project"; import { checkIsTypeScriptProject, findProjectRoot } from "../project"; @@ -104,7 +104,7 @@ export class NextJsAdapter extends Adapter { }); const componentLines = slices.map((slice) => { const componentName = pascalCase(slice.model.name); - return `${slice.model.id}: ${componentName}`; + return `${formatObjectKey(slice.model.id)}: ${componentName}`; }); const contents = dedent` // Code generated by Prismic. DO NOT EDIT. diff --git a/src/adapters/nuxt.ts b/src/adapters/nuxt.ts index 84fa4f5..1d9ac66 100644 --- a/src/adapters/nuxt.ts +++ b/src/adapters/nuxt.ts @@ -16,7 +16,7 @@ import { getSimulatorUrl, setSimulatorUrl, } from "../lib/prismic/clients/core"; -import { dedent } from "../lib/string"; +import { dedent, formatObjectKey } from "../lib/string"; import { appendTrailingSlash } from "../lib/url"; import { buildRoutePath, getRepositoryName, readConfig, updateConfig } from "../project"; import { checkIsTypeScriptProject, findProjectRoot } from "../project"; @@ -90,7 +90,7 @@ export class NuxtAdapter extends Adapter { const slices = allSlices.filter((slice) => slice.library.href === library.href); const componentLines = slices.map((slice) => { const relativeDirectory = relative(fileURLToPath(library), fileURLToPath(slice.directory)); - return `${slice.model.id}: defineAsyncComponent(() => import("./${relativeDirectory}/index.vue"))`; + return `${formatObjectKey(slice.model.id)}: defineAsyncComponent(() => import("./${relativeDirectory}/index.vue"))`; }); const contents = dedent` // Code generated by Prismic. DO NOT EDIT. diff --git a/src/adapters/sveltekit.ts b/src/adapters/sveltekit.ts index 7d62d06..2594e53 100644 --- a/src/adapters/sveltekit.ts +++ b/src/adapters/sveltekit.ts @@ -17,7 +17,7 @@ import { getSimulatorUrl, setSimulatorUrl, } from "../lib/prismic/clients/core"; -import { dedent } from "../lib/string"; +import { dedent, formatObjectKey } from "../lib/string"; import { appendTrailingSlash } from "../lib/url"; import { buildRoutePath, getRepositoryName } from "../project"; import { checkIsTypeScriptProject, findProjectRoot } from "../project"; @@ -107,7 +107,7 @@ export class SvelteKitAdapter extends Adapter { }); const componentLines = slices.map((slice) => { const componentName = pascalCase(slice.model.name); - return `${slice.model.id}: ${componentName}`; + return `${formatObjectKey(slice.model.id)}: ${componentName}`; }); const contents = dedent` // Code generated by Prismic. DO NOT EDIT. diff --git a/src/lib/string.ts b/src/lib/string.ts index b4bb75b..71ae245 100644 --- a/src/lib/string.ts +++ b/src/lib/string.ts @@ -15,6 +15,10 @@ export function dedent(strings: TemplateStringsArray | string, ...values: unknow return baseDedentWithOptions(Object.assign(resolved, { raw: resolved }), ...values); } +export function formatObjectKey(key: string): string { + return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? key : JSON.stringify(key); +} + export function formatTable( rows: string[][], config?: { headers?: string[]; separator?: string }, diff --git a/test/setup.ts b/test/setup.ts index c453fd0..ba6c3dd 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -64,7 +64,7 @@ expect.extend({ const sliceIndexPath = new URL("../index.js", sliceDirectory); try { const sliceIndex = await readFile(sliceIndexPath, "utf8"); - if (!new RegExp(`\\b${slice.id}: `).test(sliceIndex)) { + if (!new RegExp(`(?:"|\\b)${slice.id}"?: `).test(sliceIndex)) { problems.push( `slice "${slice.id}" not found in slice library index (${sliceIndexPath.href})`, ); diff --git a/test/slice-create.test.ts b/test/slice-create.test.ts index 9475b66..c49fc35 100644 --- a/test/slice-create.test.ts +++ b/test/slice-create.test.ts @@ -34,6 +34,16 @@ it("creates a slice with a custom id", async ({ expect, prismic, project }) => { expect(created).toBeDefined(); }); +it("quotes the slice ID in the slice index file", async ({ expect, prismic, project }) => { + const { name, id: baseId } = buildSlice(); + const id = `with-dash-${baseId}`; + + const { stderr, exitCode } = await prismic("slice", ["create", name, "--id", id]); + expect(exitCode, stderr).toBe(0); + + await expect(project).toHaveFile("slices/index.js", { contains: `"${id}": ${name}` }); +}); + it("creates a slice in the first configured library", async ({ expect, prismic,