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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ Avatar URL: 'https://app.box.com/api/avatar/large/77777'
* [`box retention-policies`](docs/retention-policies.md) - List all retention policies for your enterprise
* [`box search`](docs/search.md) - Search for files and folders in your Enterprise
* [`box shared-links`](docs/shared-links.md) - Manage shared links
* [`box shuttle`](docs/shuttle.md) - Manage Box Shuttle migrations (systems, jobs, mappings, runs, reports)
* [`box sign-requests`](docs/sign-requests.md) - List sign requests
* [`box sign-templates`](docs/sign-templates.md) - List sign templates
* [`box storage-policies`](docs/storage-policies.md) - List storage policies
Expand Down
2,288 changes: 2,288 additions & 0 deletions docs/shuttle.md

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions package-lock.json

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

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"@oclif/table": "0.5.4",
"@octokit/rest": "^22.0.0",
"archiver": "^8.0.0",
"box-node-sdk": "^4.11.1",
"box-node-sdk": "^4.19.0",
"chalk": "^2.4.1",
"cli-progress": "^2.1.0",
"csv": "^6.3.3",
Expand Down Expand Up @@ -145,6 +145,9 @@
"shared-links": {
"description": "Manage shared links"
},
"shuttle": {
"description": "Manage Box Shuttle migrations (systems, jobs, mappings, runs, reports)"
},
"tasks": {
"description": "Manage tasks"
},
Expand Down
40 changes: 40 additions & 0 deletions src/commands/shuttle/discovered-subjects/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
'use strict';

const BoxCommand = require('../../../box-command');
const { SHUTTLE_PERMISSIONS } = require('../../../modules/shuttle');
const { Flags } = require('@oclif/core');
const PaginationUtilities = require('../../../pagination-utils');

class ShuttleDiscoveredSubjectsListCommand extends BoxCommand {
async run() {
const { flags } = await this.parse(ShuttleDiscoveredSubjectsListCommand);
const subjects = await this.markerPagination(
(pageQueryParams) =>
this.tsClient.shuttle.getShuttleDiscoveredSubjectsV2026R0(pageQueryParams),
{ jobId: flags['job-id'] }
);
await this.output(subjects);
}
}

ShuttleDiscoveredSubjectsListCommand.aliases = [
'shuttle:discovered-subjects:list',
];
ShuttleDiscoveredSubjectsListCommand.description =
`List discovered subjects for shuttle jobs ${SHUTTLE_PERMISSIONS}`;
ShuttleDiscoveredSubjectsListCommand.examples = [
'box shuttle:discovered-subjects --job-id 6a315c0754833bfc5df067bf',
];
ShuttleDiscoveredSubjectsListCommand._endpoint =
'get_shuttle_discovered_subjects';

ShuttleDiscoveredSubjectsListCommand.flags = {
...BoxCommand.flags,
...PaginationUtilities.flags,
'job-id': Flags.string({
description: 'Shuttle job ID whose discovered subjects to list',
required: true,
}),
};

module.exports = ShuttleDiscoveredSubjectsListCommand;
73 changes: 73 additions & 0 deletions src/commands/shuttle/job-schedules/create.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
'use strict';

const BoxCommand = require('../../../box-command');
const { Flags } = require('@oclif/core');
const {
resolveBody,
bodyFlags,
scheduleTriggerFlags,
buildScheduleTrigger,
SHUTTLE_PERMISSIONS,
} = require('../../../modules/shuttle');

class ShuttleJobSchedulesCreateCommand extends BoxCommand {
async run() {
const { flags } = await this.parse(ShuttleJobSchedulesCreateCommand);
const requestBody = resolveBody(flags, () => {
if (!flags['job-id'] || !flags['run-mode']) {
this.error(
'--job-id and --run-mode are required unless --body / --body-file is set.'
);
}
const body = {
jobId: flags['job-id'],
runMode: flags['run-mode'],
trigger: buildScheduleTrigger(flags, {
required: true,
command: this,
}),
};
if (flags.state !== undefined) {
body.state = flags.state;
}
if (flags.description !== undefined) {
body.description = flags.description;
}
return body;
});

const schedule =
await this.tsClient.shuttle.createShuttleJobScheduleV2026R0(requestBody);
await this.output(schedule.rawData ?? schedule);
}
}

ShuttleJobSchedulesCreateCommand.description = `Create a shuttle job schedule ${SHUTTLE_PERMISSIONS}`;
ShuttleJobSchedulesCreateCommand.examples = [
'box shuttle:job-schedules:create --job-id 6a315c0754833bfc5df067bf --run-mode transfer --trigger-type by_time --start-at 2026-03-16T09:00:00 --time-zone America/Los_Angeles --repeat daily',
'box shuttle:job-schedules:create --job-id 6a315c0754833bfc5df067bf --run-mode simulation --trigger-type by_job --triggered-by-job-id 8d2ca68e810d9156194530c3 --last-run-condition on_success',
];
ShuttleJobSchedulesCreateCommand._endpoint = 'post_shuttle_job_schedules';

ShuttleJobSchedulesCreateCommand.flags = {
...BoxCommand.flags,
...bodyFlags,
'job-id': Flags.string({
description: 'Shuttle job ID (required unless --body / --body-file)',
}),
'run-mode': Flags.string({
description:
'Schedule run mode (required unless --body / --body-file). Accepted values: transfer, simulation, analysis',
options: ['transfer', 'simulation', 'analysis'],
}),
state: Flags.string({
description: 'Schedule state. Accepted values: enabled, paused',
options: ['enabled', 'paused'],
}),
description: Flags.string({
description: 'Optional schedule description',
}),
...scheduleTriggerFlags,
};

module.exports = ShuttleJobSchedulesCreateCommand;
34 changes: 34 additions & 0 deletions src/commands/shuttle/job-schedules/delete.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict';

const { Args } = require('@oclif/core');
const BoxCommand = require('../../../box-command');
const { SHUTTLE_PERMISSIONS } = require('../../../modules/shuttle');

class ShuttleJobSchedulesDeleteCommand extends BoxCommand {
async run() {
const { args } = await this.parse(ShuttleJobSchedulesDeleteCommand);
await this.tsClient.shuttle.deleteShuttleJobScheduleByIdV2026R0(args.id);
this.info(`Deleted shuttle job schedule ${args.id}`);
}
}

ShuttleJobSchedulesDeleteCommand.description = `Delete a shuttle job schedule ${SHUTTLE_PERMISSIONS}`;
ShuttleJobSchedulesDeleteCommand.examples = [
'box shuttle:job-schedules:delete 6a315c0754833bfc5df067bf',
];
ShuttleJobSchedulesDeleteCommand._endpoint = 'delete_shuttle_job_schedules_id';

ShuttleJobSchedulesDeleteCommand.flags = {
...BoxCommand.flags,
};

ShuttleJobSchedulesDeleteCommand.args = {
id: Args.string({
name: 'id',
required: true,
hidden: false,
description: 'ID of the shuttle job schedule to delete',
}),
};

module.exports = ShuttleJobSchedulesDeleteCommand;
36 changes: 36 additions & 0 deletions src/commands/shuttle/job-schedules/get.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use strict';

const { Args } = require('@oclif/core');
const BoxCommand = require('../../../box-command');
const { SHUTTLE_PERMISSIONS } = require('../../../modules/shuttle');

class ShuttleJobSchedulesGetCommand extends BoxCommand {
async run() {
const { args } = await this.parse(ShuttleJobSchedulesGetCommand);
const schedule = await this.tsClient.shuttle.getShuttleJobScheduleByIdV2026R0(
args.id
);
await this.output(schedule.rawData ?? schedule);
}
}

ShuttleJobSchedulesGetCommand.description = `Get a shuttle job schedule by ID ${SHUTTLE_PERMISSIONS}`;
ShuttleJobSchedulesGetCommand.examples = [
'box shuttle:job-schedules:get 6a315c0754833bfc5df067bf',
];
ShuttleJobSchedulesGetCommand._endpoint = 'get_shuttle_job_schedules_id';

ShuttleJobSchedulesGetCommand.flags = {
...BoxCommand.flags,
};

ShuttleJobSchedulesGetCommand.args = {
id: Args.string({
name: 'id',
required: true,
hidden: false,
description: 'ID of the shuttle job schedule',
}),
};

module.exports = ShuttleJobSchedulesGetCommand;
36 changes: 36 additions & 0 deletions src/commands/shuttle/job-schedules/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
'use strict';

const BoxCommand = require('../../../box-command');
const { SHUTTLE_PERMISSIONS } = require('../../../modules/shuttle');
const { Flags } = require('@oclif/core');
const PaginationUtilities = require('../../../pagination-utils');

class ShuttleJobSchedulesListCommand extends BoxCommand {
async run() {
const { flags } = await this.parse(ShuttleJobSchedulesListCommand);
const schedules = await this.markerPagination(
(pageQueryParams) =>
this.tsClient.shuttle.getShuttleJobSchedulesV2026R0(pageQueryParams),
{ jobId: flags['job-id'] }
);
await this.output(schedules);
}
}

ShuttleJobSchedulesListCommand.aliases = ['shuttle:job-schedules:list'];
ShuttleJobSchedulesListCommand.description = `List shuttle job schedules ${SHUTTLE_PERMISSIONS}`;
ShuttleJobSchedulesListCommand.examples = [
'box shuttle:job-schedules --job-id 6a315c0754833bfc5df067bf',
];
ShuttleJobSchedulesListCommand._endpoint = 'get_shuttle_job_schedules';

ShuttleJobSchedulesListCommand.flags = {
...BoxCommand.flags,
...PaginationUtilities.flags,
'job-id': Flags.string({
description: 'Shuttle job ID whose schedules to list',
required: true,
}),
};

module.exports = ShuttleJobSchedulesListCommand;
81 changes: 81 additions & 0 deletions src/commands/shuttle/job-schedules/update.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
'use strict';

const BoxCommand = require('../../../box-command');
const { Flags, Args } = require('@oclif/core');
const {
resolveBody,
bodyFlags,
scheduleTriggerFlags,
buildScheduleTrigger,
SHUTTLE_PERMISSIONS,
} = require('../../../modules/shuttle');

class ShuttleJobSchedulesUpdateCommand extends BoxCommand {
async run() {
const { flags, args } = await this.parse(ShuttleJobSchedulesUpdateCommand);
const requestBody = resolveBody(flags, () => {
const body = {};
if (Object.hasOwn(flags, 'state')) {
body.state = flags.state;
}
if (Object.hasOwn(flags, 'run-mode')) {
body.runMode = flags['run-mode'];
}
if (Object.hasOwn(flags, 'description')) {
body.description = flags.description;
}
const trigger = buildScheduleTrigger(flags, { command: this });
if (trigger !== undefined) {
body.trigger = trigger;
}
if (Object.keys(body).length === 0) {
this.error(
'Provide at least one update flag, or use --body / --body-file.'
);
}
return body;
});

const schedule = await this.tsClient.shuttle.updateShuttleJobScheduleByIdV2026R0(
args.id,
requestBody
);
await this.output(schedule.rawData ?? schedule);
}
}

ShuttleJobSchedulesUpdateCommand.description = `Update a shuttle job schedule ${SHUTTLE_PERMISSIONS}`;
ShuttleJobSchedulesUpdateCommand.examples = [
'box shuttle:job-schedules:update 6a315c0754833bfc5df067bf --state paused',
'box shuttle:job-schedules:update 6a315c0754833bfc5df067bf --trigger-type by_time --start-at 2026-03-16T09:00:00 --time-zone America/Los_Angeles --repeat weekdays',
];
ShuttleJobSchedulesUpdateCommand._endpoint = 'put_shuttle_job_schedules_id';

ShuttleJobSchedulesUpdateCommand.flags = {
...BoxCommand.flags,
...bodyFlags,
state: Flags.string({
description: 'Schedule state. Accepted values: enabled, paused',
options: ['enabled', 'paused'],
}),
'run-mode': Flags.string({
description:
'Schedule run mode. Accepted values: transfer, simulation, analysis',
options: ['transfer', 'simulation', 'analysis'],
}),
description: Flags.string({
description: 'Updated description',
}),
...scheduleTriggerFlags,
};

ShuttleJobSchedulesUpdateCommand.args = {
id: Args.string({
name: 'id',
required: true,
hidden: false,
description: 'ID of the shuttle job schedule to update',
}),
};

module.exports = ShuttleJobSchedulesUpdateCommand;
Loading
Loading