UNPKG

baqend

Version:

Baqend JavaScript SDK

214 lines 18 kB
"use strict"; 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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