baqend
Version:
Baqend JavaScript SDK
214 lines • 18 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.deploy = void 0;
/* eslint-disable no-await-in-loop, no-return-await, @typescript-eslint/return-await */
const fs_1 = __importDefault(require("fs"));
const glob_1 = require("glob");
const mime_types_1 = require("mime-types");
const path_1 = require("path");
const readline_1 = __importDefault(require("readline"));
const baqend_1 = require("baqend");
const account = __importStar(require("./account"));
const schema_1 = require("./schema");
const helper_1 = require("./helper");
const handlerTypes = ['update', 'insert', 'delete', 'validate'];
function deploy(args) {
return account.login(args).then((db) => {
const promises = [];
if ((!args.code && !args.files) || (args.code && args.files)) {
promises.push(deployFiles(db, args.bucketPath, args.fileDir, args.fileGlob, args.createBucket));
promises.push(deployCode(db, args.codeDir));
}
else if (args.code) {
promises.push(deployCode(db, args.codeDir));
}
else if (args.files) {
promises.push(deployFiles(db, args.bucketPath, args.fileDir, args.fileGlob, args.createBucket));
}
if (args.schema) {
promises.push((0, schema_1.uploadSchema)(db));
}
return Promise.all(promises);
});
}
exports.deploy = deploy;
function deployFiles(db, path, cwd, pattern, createBucket) {
return __awaiter(this, void 0, void 0, function* () {
let bucket = path;
while (bucket.length && bucket.charAt(0) === '/')
bucket = bucket.substring(1);
while (bucket.length && bucket.charAt(bucket.length - 1) === '/')
bucket = bucket.substring(0, bucket.length - 1);
if (!bucket.length) {
throw new Error(`Invalid bucket-path ${bucket}`);
}
if (createBucket) {
yield ensureRootBucket(db, bucket);
}
const files = yield (0, glob_1.glob)(pattern, { nodir: true, cwd });
const result = yield uploadFiles(db, bucket, files, cwd);
if (result && result.length > 0) {
console.log('File deployment completed.');
}
else {
console.warn('Your specified upload folder is empty, no files were uploaded.');
}
});
}
function deployCode(db, codePath) {
return (0, helper_1.readDir)(codePath)
.catch(() => {
throw new Error(`Your specified backend code folder ${codePath} is empty, no backend code was deployed.`);
})
.then((fileNames) => Promise.all(fileNames
.map((fileName) => (0, helper_1.stat)((0, path_1.join)(codePath, fileName))
.then((st) => {
if (st.isDirectory()) {
return uploadHandler(db, fileName, codePath);
}
return uploadCode(db, fileName, codePath);
})))
.then(() => {
console.log('Code deployment completed.');
})
.catch((e) => {
throw new Error(`Failed to deploy code: ${e.message}`);
}));
}
function uploadHandler(db, directoryName, codePath) {
const bucket = directoryName;
if (!db[bucket])
return Promise.resolve();
return (0, helper_1.readDir)((0, path_1.join)(codePath, directoryName)).then((fileNames) => Promise.all(fileNames
.filter((fileName) => !fileName.startsWith('.'))
.map((fileName) => {
const handlerType = fileName.replace(/\.(js|es\d*)$/, '');
if (handlerTypes.indexOf(handlerType) === -1)
return Promise.resolve();
return (0, helper_1.readFile)((0, path_1.join)(codePath, directoryName, fileName), 'utf-8')
.then((file) => db.code.saveCode(bucket, handlerType, file))
.then(() => console.log(`${handlerType} handler for ${bucket} deployed.`));
})));
}
function uploadCode(db, name, codePath) {
if (name.startsWith('.'))
return Promise.resolve();
const moduleName = name.replace(/\.(js|es\d*)$/, '');
return (0, helper_1.readFile)((0, path_1.join)(codePath, name), 'utf-8').then((file) => db.code.saveCode(moduleName, 'module', file)).then(() => {
console.log(`Module ${moduleName} deployed.`);
});
}
function uploadFiles(db, bucket, files, cwd) {
const isTty = process.stdout.isTTY;
let index = 0;
const uploads = [];
for (let i = 0; i < 10 && i < files.length; i += 1) {
uploads.push(upload());
}
if (!isTty) {
console.log(`Uploading ${files.length} files.`);
}
return Promise.all(uploads);
function upload() {
return __awaiter(this, void 0, void 0, function* () {
while (index < files.length) {
if (isTty) {
if (index > 0) {
readline_1.default.clearLine(process.stdout, 0);
readline_1.default.cursorTo(process.stdout, 0);
}
process.stdout.write(`Uploading file ${(index + 1)} of ${files.length}`);
}
const file = files[index];
index += 1;
if (isTty && index === files.length) {
console.log(''); // add a final linebreak
}
yield uploadFile(db, bucket, file, cwd);
}
});
}
}
function uploadFile(db, bucket, filePath, cwd) {
return __awaiter(this, void 0, void 0, function* () {
const fullFilePath = (0, path_1.join)(cwd, filePath);
const st = yield (0, helper_1.stat)(fullFilePath);
if (!st || st.isDirectory()) {
return null;
}
for (let retires = 3;; retires -= 1) {
try {
const file = new db.File({
path: `/${bucket}/${filePath}`,
data: fs_1.default.createReadStream(fullFilePath),
size: st.size,
type: 'stream',
mimeType: (0, mime_types_1.lookup)(filePath) || 'application/octet-stream',
});
return yield file.upload({ force: true });
}
catch (e) {
if (retires <= 0) {
console.warn(`Failed to upload file ${filePath}. ${retires} retries left.`);
throw new Error(`Failed to upload file ${filePath}: ${e.message}`);
}
}
}
});
}
function ensureRootBucket(db, name) {
return __awaiter(this, void 0, void 0, function* () {
try {
yield db.File.loadMetadata(name);
return;
}
catch (e) {
// ignored
}
const adminPermission = new baqend_1.intersection.Permission().allowAccess('/db/Role/1');
const publicPermission = new baqend_1.intersection.Permission();
yield db.File.saveMetadata(name, {
load: publicPermission,
insert: adminPermission,
update: adminPermission,
delete: adminPermission,
query: adminPermission,
});
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGVwbG95LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsdUZBQXVGO0FBQ3ZGLDRDQUFvQjtBQUNwQiwrQkFBNEI7QUFDNUIsMkNBQXNEO0FBQ3RELCtCQUF3QztBQUN4Qyx3REFBZ0M7QUFDaEMsbUNBQXFEO0FBQ3JELG1EQUFxQztBQUNyQyxxQ0FBd0M7QUFFeEMscUNBQW1EO0FBRW5ELE1BQU0sWUFBWSxHQUFHLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUM7QUFhaEUsU0FBZ0IsTUFBTSxDQUFDLElBQThCO0lBQ25ELE9BQU8sT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTtRQUNyQyxNQUFNLFFBQVEsR0FBbUIsRUFBRSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUM1RCxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7WUFDaEcsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1NBQzdDO2FBQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ3BCLFFBQVEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsT0FBTyxD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