feat: full database clone feature in api-cli

This commit is contained in:
2023-10-20 15:07:52 +02:00
parent 06b8ca109e
commit f618725598
3 changed files with 45 additions and 28 deletions

View File

@@ -0,0 +1,5 @@
---
'@openstapps/api-cli': minor
---
Add "\*" option to copy command that allows for a full database clone

View File

@@ -20,6 +20,12 @@ npm run build
node ./lib/cli.js e2e http://localhost:3000
```
Example to clone the full database
```shell
node app.js copy "*" https://mobile.app.uni-frankfurt.de http://localhost:3000 100
```
### Program arguments
```shell

View File

@@ -15,12 +15,11 @@
import {SCThingType} from '@openstapps/core';
import {Logger} from '@openstapps/logger';
import {Command} from 'commander';
import {readFileSync} from 'fs';
import path from 'path';
import {fileURLToPath, URL} from 'url';
import {URL} from 'url';
import waitOn from 'wait-on';
import {HttpClient} from '@openstapps/api';
import {copy} from './copy.js';
import {version} from '../package.json';
// eslint-disable-next-line unicorn/prevent-abbreviations
import {e2eRun} from './e2e.js';
@@ -28,11 +27,6 @@ process.on('unhandledRejection', async error => {
await Logger.error('unhandledRejection', error);
});
// eslint-disable-next-line unicorn/prefer-module
const packageJson = JSON.parse(
readFileSync(path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'package.json')).toString(),
);
const client = new HttpClient();
const commander = new Command();
const helpAndExit = (help: string) => {
@@ -43,7 +37,7 @@ const helpAndExit = (help: string) => {
commander
.command('e2e <to>')
.version(packageJson.version)
.version(version)
.description(
'Run in end to end test mode. Indexing and afterwards retrieving all test files from @openstapp/core to the backend',
)
@@ -87,15 +81,14 @@ commander
commander
.command('copy <type> <from> <to> <batchSize>')
.version(packageJson.version)
.version(version)
.description('Copy data from one instance to another')
.option(
'-s, --bulkSource <bulkSource>',
'The source identifier for the bulk to use with the target instance [copy]',
'copy',
)
// TODO: remove
.option('-a, --appVersion <version>', 'The App version to use [unset by default]')
.option('-a, --appVersion <version>', 'The App version to use [unset by default]', version)
.allowUnknownOption(false)
.action(async (type, from, to, batchSize, copyCommand) => {
// validate type
@@ -123,23 +116,36 @@ commander
helpAndExit(copyCommand.helpInformation());
}
Logger.info(`Copying ${type} objects from ${fromURL} to ${toURL}`);
/**
* Copy a single type from one backend to another
*/
async function copySingleType(type: string) {
Logger.info(`Copying ${type} objects from ${fromURL} to ${toURL}`);
copy(client, {
batchSize: Number.parseInt(batchSize, 10),
from: fromURL,
source: copyCommand.bulkSource,
to: toURL,
type: type as SCThingType,
version: copyCommand.appVersion,
}).then(
() => {
Logger.ok('Done');
},
error => {
throw error;
},
);
await copy(client, {
batchSize: Number.parseInt(batchSize, 10),
from: fromURL,
source: copyCommand.bulkSource,
to: toURL,
type: type as SCThingType,
version: copyCommand.appVersion,
});
Logger.ok('done');
}
if (type === '*') {
const types = Object.values(SCThingType);
for (const [i, type] of types.entries()) {
Logger.info(`Copying ${type} (${i + 1} / ${types.length})`);
try {
await copySingleType(type);
} catch (error) {
await Logger.error(error);
}
}
} else {
await copySingleType(type);
}
});
commander.parse(process.argv);