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
2,129 changes: 1,085 additions & 1,044 deletions api/openapi.ts

Large diffs are not rendered by default.

14 changes: 9 additions & 5 deletions api/templates.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { client } from "./client.ts";

export const templates = {
create: client("/templates").post,
get: client("/templates/{id}").get,
list: client("/templates").get,
delete: client("/templates/{id}").delete,
export const customTemplates = {
create: client("/custom-templates").post,
get: client("/custom-templates/{id}").get,
list: client("/custom-templates").get,
delete: client("/custom-templates/{id}").delete,
};

export const osTemplates = {
list: client("/os-templates").get,
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { command, flag, flags } from "../../../zcli.ts";
import { dataTable } from "../../../lib/data-table.ts";
import { fields } from "../../../flags.ts";
import { pickJson } from "../../../lib/pick-json.ts";
import { templates } from "../../../api/templates.ts";
import { customTemplates } from "../../../api/templates.ts";
import { defaultFields } from "../mod.ts";

/**
Expand All @@ -14,21 +14,21 @@ import { defaultFields } from "../mod.ts";
const subCommands: ReturnType<typeof command>[] = [];

export const create = command("create", {
short: "Create a template",
short: "Create a custom template",
long: `
Create a template from a machine.
Create a custom template from a machine.
`,
commands: subCommands,
flags: flags({
fields,
}).merge(flags({
"name": flag({
aliases: ["n"],
short: "The name of the template",
short: "The name of the custom template",
}).string(),
"machine-id": flag({
aliases: ["m"],
short: "The ID of the machine to create a template from",
short: "The ID of the machine to create a custom template from",
}).string(),
})),
// We use command metadata in the `persistentPreRun` function to check if a
Expand All @@ -41,7 +41,7 @@ export const create = command("create", {
}).run(
async function* ({ flags }) {
const response = await loading(
templates.create({
customTemplates.create({
name: flags.name,
machineId: flags["machine-id"],
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { args, command, flags, z } from "../../../zcli.ts";
import { dataTable } from "../../../lib/data-table.ts";
import { fields } from "../../../flags.ts";
import { pickJson } from "../../../lib/pick-json.ts";
import { templates } from "../../../api/templates.ts";
import { customTemplates } from "../../../api/templates.ts";
import { defaultFields } from "../mod.ts";

/**
Expand All @@ -15,13 +15,13 @@ import { defaultFields } from "../mod.ts";
const subCommands: ReturnType<typeof command>[] = [];

export const del = command("delete", {
short: "Delete a template",
short: "Delete a custom template",
long: `
Delete a template from a team.
Delete a custom template from a team.
`,
commands: subCommands,
args: args().tuple([
z.string().describe("The ID of the template to delete"),
z.string().describe("The ID of the custom template to delete"),
]).optional(),
flags: flags({
fields,
Expand All @@ -40,11 +40,11 @@ export const del = command("delete", {
id = await input("ID:", {
filter: (v) => !!v.sequence.match(/[a-zA-Z0-9_-]/),
});
asserts(id, "A template ID is required");
asserts(id, "A custom template ID is required");
}

const response = await loading(
templates.delete({ id }),
customTemplates.delete({ id }),
);

asserts(response.ok, response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { args, command, flags, z } from "../../../zcli.ts";
import { dataTable } from "../../../lib/data-table.ts";
import { fields } from "../../../flags.ts";
import { pickJson } from "../../../lib/pick-json.ts";
import { templates } from "../../../api/templates.ts";
import { customTemplates } from "../../../api/templates.ts";
import { defaultFields } from "../mod.ts";

/**
Expand All @@ -15,13 +15,13 @@ import { defaultFields } from "../mod.ts";
const subCommands: ReturnType<typeof command>[] = [];

export const get = command("get", {
short: "Get a template",
short: "Get a custom template",
long: `
Get a template from a team.
Get a custom template from a team.
`,
commands: subCommands,
args: args().tuple([
z.string().describe("The ID of the template to get"),
z.string().describe("The ID of the custom template to get"),
]).optional(),
flags: flags({
fields,
Expand All @@ -40,11 +40,11 @@ export const get = command("get", {
id = await input("ID:", {
filter: (v) => !!v.sequence.match(/[a-zA-Z0-9_-]/),
});
asserts(id, "A template ID is required");
asserts(id, "A custom template ID is required");
}

const response = await loading(
templates.get({ id }),
customTemplates.get({ id }),
);

asserts(response.ok, response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { loading } from "../../../lib/loading.ts";
import * as psFlags from "../../../flags.ts";
import { pickJson } from "../../../lib/pick-json.ts";
import { config } from "../../../config.ts";
import { templates } from "../../../api/templates.ts";
import { customTemplates } from "../../../api/templates.ts";
import { defaultFields } from "../mod.ts";

/**
Expand All @@ -15,13 +15,13 @@ import { defaultFields } from "../mod.ts";
const subCommands: ReturnType<typeof command>[] = [];

export const list = command("list", {
short: "List templates.",
short: "List custom templates.",
long: ({ root }) => `
List templates in your team.
List custom templates in your team.

Pick a subset of fields to display:
\`\`\`
${root.name} template list -F name -F dtModified
${root.name} custom-template list -F name -F dtModified
\`\`\`
`,
commands: subCommands,
Expand All @@ -48,9 +48,9 @@ export const list = command("list", {
}).run(
async function* ({ flags }) {
const team = await config.get("team");
asserts(team, "You must be in a team to list templates.");
asserts(team, "You must be in a team to list custom templates.");
const result = await loading(
templates.list({
customTemplates.list({
limit: flags.limit,
after: flags.after,
orderBy: "dtCreated",
Expand Down
12 changes: 6 additions & 6 deletions commands/template/mod.ts → commands/custom-template/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ const subCommands: ReturnType<typeof command>[] = [
del,
];

export const template = command("template", {
short: "Manage your templates",
export const customTemplate = command("custom-template", {
short: "Manage your custom templates",
long: `
Manage your templates. Templates are a backup of your machine's disk.
They can be used to create additional machines. You can use them to
prepopulate a machine with your desired software stack.
Manage your custom templates. Custom templates are a backup of your
machine's disk. They can be used to create additional machines. You
can use them to prepopulate a machine with your desired software stack.

For more information, see ${new URL(
"/compute/custom-templates",
Expand All @@ -38,7 +38,7 @@ export const template = command("template", {
`,
commands: subCommands,
}).run(function* ({ ctx }) {
for (const line of template.help(ctx)) {
for (const line of customTemplate.help(ctx)) {
yield line;
}
});
6 changes: 4 additions & 2 deletions commands/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ import { signup } from "./signup/mod.ts";
import { snapshot } from "./snapshot/mod.ts";
import { startupScript } from "./startup-script/mod.ts";
import { storageProvider } from "./storage-provider/mod.ts";
import { template } from "./template/mod.ts";
import { customTemplate } from "./custom-template/mod.ts";
import { up } from "./up/mod.ts";
import { getLatestVersion, upgrade } from "./upgrade/mod.ts";
import { osTemplate } from "./os-template/mod.ts";

/**
* This variable is automatically generated by `zcli add`. Do not remove this
Expand All @@ -41,6 +42,7 @@ export const commands = [
autoscalingGroup,
config,
console,
customTemplate,
dataset,
deployment,
docs,
Expand All @@ -49,6 +51,7 @@ export const commands = [
logout,
machine,
machineEvent,
osTemplate,
privateNetwork,
project,
publicIp,
Expand All @@ -58,7 +61,6 @@ export const commands = [
sharedDrive,
startupScript,
storageProvider,
template,
up,
upgrade,
model,
Expand Down
67 changes: 67 additions & 0 deletions commands/os-template/list/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { command, flag, flags } from "../../../zcli.ts";
import { asserts } from "../../../lib/asserts.ts";
import { dataTable } from "../../../lib/data-table.ts";
import { loading } from "../../../lib/loading.ts";
import * as psFlags from "../../../flags.ts";
import { pickJson } from "../../../lib/pick-json.ts";
import { osTemplates } from "../../../api/templates.ts";
import { defaultFields } from "../mod.ts";

/**
* This variable is automatically generated by `zcli add`. Do not remove this
* or change its name unless you're no longer using `zcli add`.
*/
const subCommands: ReturnType<typeof command>[] = [];

export const list = command("list", {
short: "List OS templates.",
long: ({ root }) => `
List OS templates.

Pick a subset of fields to display:
\`\`\`
${root.name} os-template list -F name
\`\`\`
`,
commands: subCommands,
flags: psFlags.paginator.merge(flags({
"name": flag({
aliases: ["n"],
short: "Filter by name.",
}).ostring(),
})),
// We use command metadata in the `persistentPreRun` function to check if a
// command requires an API key. If it does, we'll check to see if one is
// set. If not, we'll throw an error.
meta: {
requireApiKey: true,
},
}).run(
async function* ({ flags }) {
const result = await loading(
osTemplates.list({
limit: flags.limit,
after: flags.after,
orderBy: "name",
order: flags.asc ? "asc" : undefined,
name: flags.name,
}),
{ enabled: !flags.json },
);

asserts(result.ok, result);

if (!flags.json) {
for await (
const line of dataTable(
result.data.items,
flags.fields ?? defaultFields,
)
) {
yield line;
}
} else {
yield pickJson(result.data, flags.fields);
}
},
);
36 changes: 36 additions & 0 deletions commands/os-template/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { command } from "../../zcli.ts";
import { list } from "./list/mod.ts";
import { env } from "../../env.ts";

export const defaultFields = [
"id",
"name",
"operatingSystemLabel",
"defaultSizeGb",
];

/**
* This variable is automatically generated by `zcli add`. Do not remove this
* or change its name unless you're no longer using `zcli add`.
*/
const subCommands: ReturnType<typeof command>[] = [
list,
];

export const osTemplate = command("os-template", {
short: "List OS templates",
long: `
List OS templates. OS templates are pre-configured virtual machines that
you can use to create a new machine.

For more information, see ${new URL(
"/compute/os-templates",
env.get("PAPERSPACE_DOCS_URL"),
)}.
`,
commands: subCommands,
}).run(function* ({ ctx }) {
for (const line of osTemplate.help(ctx)) {
yield line;
}
});
8 changes: 4 additions & 4 deletions errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,13 @@ export class DegitError extends AppError {
export class ApiClientError extends AppError {
readonly name = "ApiClientError";
readonly code: ApiClientErrorCode;
readonly issues:
components["responses"]["error"]["content"]["application/json"]["issues"];
readonly details:
components["responses"]["error"]["content"]["application/json"]["details"];

constructor({
message,
code,
issues,
details,
}:
& Omit<
components["responses"]["error"]["content"]["application/json"],
Expand All @@ -88,7 +88,7 @@ export class ApiClientError extends AppError {
}) {
super({ message, exitCode: 1 });
this.code = code;
this.issues = issues;
this.details = details;
}
}

Expand Down