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
65 changes: 65 additions & 0 deletions src/commands/slice-edit-variation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import type { SharedSlice } from "@prismicio/types-internal/lib/customtypes";

import { getAdapter } from "../adapters";
import { getHost, getToken } from "../auth";
import { getSlices, updateSlice } from "../clients/custom-types";
import { CommandError, createCommand, type CommandConfig } from "../lib/command";
import { UnknownRequestError } from "../lib/request";
import { getRepositoryName } from "../project";

const config = {
name: "prismic slice edit-variation",
description: "Edit a variation of a slice.",
positionals: {
name: { description: "Name of the variation", required: true },
},
options: {
in: { type: "string", required: true, description: "Name of the slice" },
name: { type: "string", short: "n", description: "New name for the variation" },
repo: { type: "string", short: "r", description: "Repository domain" },
},
} satisfies CommandConfig;

export default createCommand(config, async ({ positionals, values }) => {
const [currentName] = positionals;
const { in: sliceName, repo = await getRepositoryName() } = values;

const adapter = await getAdapter();
const token = await getToken();
const host = await getHost();
const slices = await getSlices({ repo, token, host });
const slice = slices.find((s) => s.name === sliceName);

if (!slice) {
throw new CommandError(`Slice not found: ${sliceName}`);
}

const variation = slice.variations.find((v) => v.name === currentName);

if (!variation) {
throw new CommandError(`Variation "${currentName}" not found in slice "${sliceName}".`);
}

if ("name" in values) variation.name = values.name!;

const updatedSlice: SharedSlice = { ...slice };

try {
await updateSlice(updatedSlice, { repo, host, token });
} catch (error) {
if (error instanceof UnknownRequestError) {
const message = await error.text();
throw new CommandError(`Failed to update variation: ${message}`);
}
throw error;
}

try {
await adapter.updateSlice(updatedSlice);
} catch {
await adapter.createSlice(updatedSlice);
}
await adapter.generateTypes();

console.info(`Variation updated: "${variation.name}" in slice "${sliceName}"`);
});
58 changes: 58 additions & 0 deletions src/commands/slice-edit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import type { SharedSlice } from "@prismicio/types-internal/lib/customtypes";

import { getAdapter } from "../adapters";
import { getHost, getToken } from "../auth";
import { getSlices, updateSlice } from "../clients/custom-types";
import { CommandError, createCommand, type CommandConfig } from "../lib/command";
import { UnknownRequestError } from "../lib/request";
import { getRepositoryName } from "../project";

const config = {
name: "prismic slice edit",
description: "Edit a slice.",
positionals: {
name: { description: "Name of the slice", required: true },
},
options: {
name: { type: "string", short: "n", description: "New name for the slice" },
repo: { type: "string", short: "r", description: "Repository domain" },
},
} satisfies CommandConfig;

export default createCommand(config, async ({ positionals, values }) => {
const [currentName] = positionals;
const { repo = await getRepositoryName() } = values;

const adapter = await getAdapter();
const token = await getToken();
const host = await getHost();
const slices = await getSlices({ repo, token, host });
const slice = slices.find((s) => s.name === currentName);

if (!slice) {
throw new CommandError(`Slice not found: ${currentName}`);
}

const updatedSlice: SharedSlice = { ...slice };

if ("name" in values) updatedSlice.name = values.name!;

try {
await updateSlice(updatedSlice, { repo, host, token });
} catch (error) {
if (error instanceof UnknownRequestError) {
const message = await error.text();
throw new CommandError(`Failed to update slice: ${message}`);
}
throw error;
}

try {
await adapter.updateSlice(updatedSlice);
} catch {
await adapter.createSlice(updatedSlice);
}
await adapter.generateTypes();

console.info(`Slice updated: "${updatedSlice.name}" (id: ${updatedSlice.id})`);
});
10 changes: 10 additions & 0 deletions src/commands/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import sliceAddVariation from "./slice-add-variation";
import sliceConnect from "./slice-connect";
import sliceCreate from "./slice-create";
import sliceDisconnect from "./slice-disconnect";
import sliceEdit from "./slice-edit";
import sliceEditVariation from "./slice-edit-variation";
import sliceList from "./slice-list";
import sliceRemove from "./slice-remove";
import sliceRemoveVariation from "./slice-remove-variation";
Expand All @@ -16,6 +18,10 @@ export default createCommandRouter({
handler: sliceCreate,
description: "Create a new slice",
},
edit: {
handler: sliceEdit,
description: "Edit a slice",
},
remove: {
handler: sliceRemove,
description: "Remove a slice",
Expand All @@ -40,6 +46,10 @@ export default createCommandRouter({
handler: sliceAddVariation,
description: "Add a variation to a slice",
},
"edit-variation": {
handler: sliceEditVariation,
description: "Edit a variation of a slice",
},
"remove-variation": {
handler: sliceRemoveVariation,
description: "Remove a variation from a slice",
Expand Down
14 changes: 5 additions & 9 deletions src/commands/type-edit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ const config = {
options: {
name: { type: "string", short: "n", description: "New name for the type" },
format: { type: "string", short: "f", description: 'Type format: "custom" or "page"' },
repeatable: { type: "boolean", description: "Allow multiple documents of this type" },
single: { type: "boolean", short: "s", description: "Restrict to a single document" },
repo: { type: "string", short: "r", description: "Repository domain" },
},
} satisfies CommandConfig;
Expand All @@ -24,10 +22,6 @@ export default createCommand(config, async ({ positionals, values }) => {
const [currentName] = positionals;
const { repo = await getRepositoryName() } = values;

if ("repeatable" in values && "single" in values) {
throw new CommandError("Cannot use both --repeatable and --single");
}

if ("format" in values && values.format !== "custom" && values.format !== "page") {
throw new CommandError(`Invalid format: "${values.format}". Use "custom" or "page".`);
}
Expand All @@ -44,8 +38,6 @@ export default createCommand(config, async ({ positionals, values }) => {

if ("name" in values) type.label = values.name;
if ("format" in values) type.format = values.format as "custom" | "page";
if ("repeatable" in values) type.repeatable = true;
if ("single" in values) type.repeatable = false;

try {
await updateCustomType(type, { repo, host, token });
Expand All @@ -57,7 +49,11 @@ export default createCommand(config, async ({ positionals, values }) => {
throw error;
}

await adapter.updateCustomType(type);
try {
await adapter.updateCustomType(type);
} catch {
await adapter.createCustomType(type);
}
await adapter.generateTypes();

console.info(`Type updated: "${type.label}" (id: ${type.id})`);
Expand Down
48 changes: 48 additions & 0 deletions test/slice-edit-variation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { buildSlice, it } from "./it";
import { getSlices, insertSlice } from "./prismic";

it("supports --help", async ({ expect, prismic }) => {
const { stdout, exitCode } = await prismic("slice", ["edit-variation", "--help"]);
expect(exitCode).toBe(0);
expect(stdout).toContain("prismic slice edit-variation <name> [options]");
});

it("edits a variation name", async ({ expect, prismic, repo, token, host }) => {
const variationName = `Variation${crypto.randomUUID().split("-")[0]}`;
const variationId = `variation${crypto.randomUUID().split("-")[0]}`;
const slice = buildSlice();
const sliceWithVariation = {
...slice,
variations: [
...slice.variations,
{
id: variationId,
name: variationName,
description: variationName,
docURL: "",
imageUrl: "",
version: "",
},
],
};

await insertSlice(sliceWithVariation, { repo, token, host });

const newName = `Variation${crypto.randomUUID().split("-")[0]}`;

const { stdout, exitCode } = await prismic("slice", [
"edit-variation",
variationName,
"--in",
slice.name,
"--name",
newName,
]);
expect(exitCode).toBe(0);
expect(stdout).toContain(`Variation updated: "${newName}" in slice "${slice.name}"`);

const slices = await getSlices({ repo, token, host });
const updated = slices.find((s) => s.id === slice.id);
const variation = updated?.variations.find((v) => v.id === variationId);
expect(variation?.name).toBe(newName);
});
23 changes: 23 additions & 0 deletions test/slice-edit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { buildSlice, it } from "./it";
import { getSlices, insertSlice } from "./prismic";

it("supports --help", async ({ expect, prismic }) => {
const { stdout, exitCode } = await prismic("slice", ["edit", "--help"]);
expect(exitCode).toBe(0);
expect(stdout).toContain("prismic slice edit <name> [options]");
});

it("edits a slice name", async ({ expect, prismic, repo, token, host }) => {
const slice = buildSlice();
await insertSlice(slice, { repo, token, host });

const newName = `SliceS${crypto.randomUUID().split("-")[0]}`;

const { stdout, exitCode } = await prismic("slice", ["edit", slice.name, "--name", newName]);
expect(exitCode).toBe(0);
expect(stdout).toContain(`Slice updated: "${newName}"`);

const slices = await getSlices({ repo, token, host });
const updated = slices.find((s) => s.id === slice.id);
expect(updated?.name).toBe(newName);
});
37 changes: 37 additions & 0 deletions test/type-edit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { buildCustomType, it } from "./it";
import { getCustomTypes, insertCustomType } from "./prismic";

it("supports --help", async ({ expect, prismic }) => {
const { stdout, exitCode } = await prismic("type", ["edit", "--help"]);
expect(exitCode).toBe(0);
expect(stdout).toContain("prismic type edit <name> [options]");
});

it("edits a type name", async ({ expect, prismic, repo, token, host }) => {
const customType = buildCustomType({ format: "custom" });
await insertCustomType(customType, { repo, token, host });

const newName = `TypeT${crypto.randomUUID().split("-")[0]}`;

const { stdout, stderr, exitCode } = await prismic("type", ["edit", customType.label!, "--name", newName]);
expect(stderr).toBe("");
expect(exitCode).toBe(0);
expect(stdout).toContain(`Type updated: "${newName}"`);

const customTypes = await getCustomTypes({ repo, token, host });
const updated = customTypes.find((ct) => ct.id === customType.id);
expect(updated?.label).toBe(newName);
});

it("edits a type format", async ({ expect, prismic, repo, token, host }) => {
const customType = buildCustomType({ format: "custom" });
await insertCustomType(customType, { repo, token, host });

const { stderr, exitCode } = await prismic("type", ["edit", customType.label!, "--format", "page"]);
expect(stderr).toBe("");
expect(exitCode).toBe(0);

const customTypes = await getCustomTypes({ repo, token, host });
const updated = customTypes.find((ct) => ct.id === customType.id);
expect(updated?.format).toBe("page");
});