baqend
Version:
Baqend JavaScript SDK
106 lines (92 loc) • 3.65 kB
text/typescript
import { join as pathJoin } from 'path';
import { EntityManager, message, util } from 'baqend';
import inquirer from 'inquirer';
import * as account from './account';
import { AccountArgs } from './account';
import {
ensureDir, isNativeClassNamespace, readDir, readFile, writeFile,
} from './helper';
type JsonMap = util.JsonMap;
const SCHEMA_FILE_PATH = './baqend/schema/';
export type SchemaArgs = {
command: 'upload' | 'download' | 'deploy'
force?: boolean,
};
export async function uploadSchema(db: EntityManager, force: boolean = false): Promise<boolean> {
let fileNames;
try {
fileNames = await readDir(SCHEMA_FILE_PATH);
} catch (e) {
throw new Error('Your schema folder baqend is empty, no schema changes were deployed.');
}
const schemas: JsonMap[] = await Promise.all(
fileNames.map(async (fileName) => {
const file = await readFile(pathJoin(SCHEMA_FILE_PATH, fileName), 'utf-8');
return JSON.parse(file) as JsonMap;
}),
);
if (force) {
const { answer } = await inquirer.prompt([
{ type: 'confirm', name: 'answer', message: 'This will delete ALL your App data. Are you sure you want to continue?' },
]);
if (!answer) {
return false;
}
schemas.forEach((schemaDescriptor: JsonMap) => {
console.log(`Replacing ${(schemaDescriptor.class as string).replace('/db/', '')} Schema`);
});
await db.send(new message.ReplaceAllSchemas(schemas));
return true;
}
const acls = schemas.map((schemaDescriptor) => {
console.log(`Updating ${(schemaDescriptor.class as string).replace('/db/', '')} Schema`);
return { operation: 'updateClassAcl', bucket: schemaDescriptor.class, acl: schemaDescriptor.acl };
});
try {
// We need to update acls separately, since they are not changed by an additive update
// Deploy schemas first to ensure all schemas exists
await db.send(new message.UpdateAllSchemas(schemas));
await db.send(new message.UpdateAllSchemas(acls));
return true;
} catch (e: any) {
console.error(`Schema update failed with error: ${e.message}`);
return false;
}
}
export function downloadSchema(db: EntityManager) {
return db.send(new message.GetAllSchemas()).then((res) => Promise.all(
res.entity.map((schemaDescriptor: JsonMap) => {
const classname = (schemaDescriptor.class as string).replace('/db/', '');
const filename = `baqend/schema/${classname}.json`;
if (!isNativeClassNamespace(classname) && classname !== 'Object') {
return writeFile(filename, JSON.stringify(schemaDescriptor, null, 2), 'utf-8').then(() => {
console.log(`Downloaded ${classname} Schema`);
});
}
return Promise.resolve();
}),
));
}
export function schema(args: SchemaArgs & AccountArgs) {
return account.login(args).then((db) => ensureDir(SCHEMA_FILE_PATH).then(() => {
switch (args.command) {
case 'upload':
case 'deploy':
return uploadSchema(db, args.force).then((deployed) => {
console.log('---------------------------------------');
if (deployed) {
console.log(`The schema was successfully ${args.force ? 'replaced' : 'updated'}`);
} else {
console.log('The schema update was aborted');
}
});
case 'download':
return downloadSchema(db).then(() => {
console.log('---------------------------------------');
console.log('Your schema was successfully downloaded');
});
default:
throw new Error(`Invalid command: "${args.command}". Please use one of ["deploy", "download"].`);
}
}));
}