Skip to content
Open
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
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"dependencies": {
"@clack/prompts": "1.2.0",
"@cloudcannon/gadget": "0.0.32",
"@cloudcannon/sdk": "0.0.2",
"citty": "0.2.2",
"yaml": "2.8.3"
}
Expand Down
56 changes: 56 additions & 0 deletions src/builds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { defineCommand } from 'citty';
import { printJson } from './configure/utility.ts';
import { getSdkClient } from './sdk-client.ts';

export const buildsListCommand = defineCommand({
meta: {
name: 'list',
description: 'List builds for a site.',
},
args: {
site: {
type: 'string',
description: 'The site UUID',
valueHint: 'uuid',
required: true,
},
},
async run(ctx): Promise<void> {
const client = getSdkClient();
const builds = await client.site(ctx.args.site).getBuilds();
printJson(builds);
},
});

export const buildsPrintLogsCommand = defineCommand({
meta: {
name: 'print-logs',
description: 'Prints the logs for a build.',
},
args: {
uuid: {
type: 'positional',
description: 'The build UUID',
required: true,
},
},
async run(ctx): Promise<void> {
const client = getSdkClient();
const resp = await client.build(ctx.args.uuid).get();
const text = await resp.text();
if (text) {
console.log(text);
}
},
});

export const buildsCommand = defineCommand({
meta: {
name: 'builds',
description: 'Manage CloudCannon builds.',
},
subCommands: {
list: buildsListCommand,
'print-logs': buildsPrintLogsCommand,
},
});
119 changes: 119 additions & 0 deletions src/files.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { createWriteStream } from 'node:fs';
import { readFile } from 'node:fs/promises';
import { Writable } from 'node:stream';
import { defineCommand } from 'citty';
import { printJson } from './configure/utility.ts';
import { getSdkClient } from './sdk-client.ts';

export const filesListCommand = defineCommand({
meta: {
name: 'list',
description: 'List files from a site.',
},
args: {
site: {
type: 'string',
description: 'The site UUID',
valueHint: 'uuid',
required: true,
},
},
async run(ctx): Promise<void> {
const client = getSdkClient();
const files = await client.site(ctx.args.site).listFiles();
const output = Object.fromEntries(files.map((file) => [file.sitePath, file.md5]));
printJson(output);
},
});

export const filesGetCommand = defineCommand({
meta: {
name: 'get',
description: 'Get the contents of a file from a site.',
},
args: {
site: {
type: 'string',
description: 'The site UUID',
valueHint: 'uuid',
required: true,
},
output: {
type: 'string',
description: 'Path to save the file to',
valueHint: 'path',
},
path: {
type: 'positional',
description: 'The file path on the site',
required: true,
},
},
async run(ctx): Promise<void> {
const client = getSdkClient();
const resp = await client.site(ctx.args.site).getFile(ctx.args.path);
if (ctx.args.output) {
const stream = createWriteStream(ctx.args.output);
await resp.body?.pipeTo(Writable.toWeb(stream));
} else {
const text = await resp.text();
console.log(text);
}
},
});

export const filesUploadCommand = defineCommand({
meta: {
name: 'upload',
description: 'Upload a file to a site.',
},
args: {
site: {
type: 'string',
description: 'The site UUID',
valueHint: 'uuid',
required: true,
},
localPath: {
type: 'positional',
description: 'The local file path to upload',
required: true,
},
path: {
type: 'positional',
description: 'The destination path on the site',
required: true,
},
type: {
type: 'string',
description: 'MIME type of the file',
valueHint: 'mime',
},
overwrite: {
type: 'boolean',
description: 'Overwrite if the file already exists',
default: false,
},
},
async run(ctx): Promise<void> {
const client = getSdkClient();
const content = await readFile(ctx.args.localPath);
await client.site(ctx.args.site).uploadFile(ctx.args.path, content, {
type: ctx.args.type,
overwriteExistingFile: ctx.args.overwrite,
});
console.log('File uploaded.');
},
});

export const filesCommand = defineCommand({
meta: {
name: 'files',
description: 'Manage files on CloudCannon sites.',
},
subCommands: {
list: filesListCommand,
get: filesGetCommand,
upload: filesUploadCommand,
},
});
6 changes: 6 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

import { defineCommand, runMain } from 'citty';
import pkg from '../package.json' with { type: 'json' };
import { buildsCommand } from './builds.ts';
import { configureCommand } from './configure.ts';
import { orgsCommand } from './orgs.ts';
import { sitesCommand } from './site.ts';

const main = defineCommand({
meta: {
Expand All @@ -11,7 +14,10 @@ const main = defineCommand({
description: 'Work with CloudCannon from the command line.',
},
subCommands: {
builds: buildsCommand,
configure: configureCommand,
orgs: orgsCommand,
sites: sitesCommand,
},
});

Expand Down
45 changes: 45 additions & 0 deletions src/orgs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { defineCommand } from 'citty';
import { printJson } from './configure/utility.ts';
import { getSdkClient } from './sdk-client.ts';

export const orgsListCommand = defineCommand({
meta: {
name: 'list',
description: 'List all organisations.',
},
async run(): Promise<void> {
const client = getSdkClient();
const orgs = await client.orgs();
printJson(orgs);
},
});

export const orgsGetCommand = defineCommand({
meta: {
name: 'get',
description: 'Get an organisation by UUID.',
},
args: {
uuid: {
type: 'positional',
description: 'The organisation UUID',
required: true,
},
},
async run(ctx): Promise<void> {
const client = getSdkClient();
const org = await client.org(ctx.args.uuid).get();
printJson(org);
},
});

export const orgsCommand = defineCommand({
meta: {
name: 'orgs',
description: 'Manage CloudCannon organisations.',
},
subCommands: {
list: orgsListCommand,
get: orgsGetCommand,
},
});
11 changes: 11 additions & 0 deletions src/sdk-client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import CloudCannonClient from '@cloudcannon/sdk';

export function getSdkClient(): CloudCannonClient {
const apiKey = process.env.CLOUDCANNON_API_KEY;
if (!apiKey) {
throw new Error(
'CLOUDCANNON_API_KEY environment variable is required. Set it with: export CLOUDCANNON_API_KEY=your_key'
);
}
return new CloudCannonClient({ key: apiKey });
}
Loading