Socket
Socket
Sign inDemoInstall

@cyklang/cli

Package Overview
Dependencies
Maintainers
1
Versions
68
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cyklang/cli - npm Package Compare versions

Comparing version 0.5.4 to 0.5.5

build/UninstallCommand.d.ts

24

build/AssetCommand.d.ts
import { Command } from "commander";
import { DBManager, DBRemote } from "@cyklang/core";
export declare class AssetCommand extends Command {
constructor(name: string, description: string);
}
export interface FileDescriptor {
path: string;
mtime: Date;
id?: number;
}
/**
* function uploadDirectory
* @param source
* @param dest
* @param options {yes: no confirmation, auth: basic/token/cookie/undefined}
* @param dbManager
* @param dbRemote
*/
export declare function uploadDirectory(source: string, dest: string, options: any, dbManager: DBManager | undefined, dbRemote: DBRemote | undefined): Promise<void>;
/**
* function uploadAsset
* @param upload
* @param route
* @param dbManager
* @param dbRemote
* @param auth
*/
export declare function uploadAsset(upload: FileDescriptor, route: string, dbManager: DBManager | undefined, dbRemote: DBRemote | undefined, auth?: string): Promise<void>;

385

build/AssetCommand.js

@@ -29,3 +29,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.AssetCommand = void 0;
exports.uploadAsset = exports.uploadDirectory = exports.AssetCommand = void 0;
const commander_1 = require("commander");

@@ -188,6 +188,2 @@ const loglevel_1 = require("loglevel");

super(name);
//----------------------------------------------------------------------------------------------
// file2exclude
//----------------------------------------------------------------------------------------------
this.ignorePatterns = ['.git', 'node_modules'];
this.description(description)

@@ -205,12 +201,2 @@ .option('-i --id <id>', 'asset id or pathname whose properties are updated')

}
mimetypeLookup(filename) {
let result;
if (path_1.default.extname(filename) === '.cyk') {
result = 'application/xml';
}
else {
result = mime_types_1.default.lookup(filename);
}
return result;
}
/**

@@ -280,3 +266,3 @@ * method commandU

if (options.clean) {
await this.cleanDestination(dest);
await cleanDestination(dest, this.dbManager, this.dbRemote);
}

@@ -289,3 +275,3 @@ for (let ind = 0; ind < sources.length; ind++) {

if (filestat.isDirectory() === true) {
await this.uploadDirectory(source, dest, options);
await uploadDirectory(source, dest, options, this.dbManager, this.dbRemote);
}

@@ -295,3 +281,3 @@ else if (filestat.isFile() === true) {

logger.debug('upload file ' + source + ' to ' + dest + base);
await this.uploadAsset({ path: source, mtime: filestat.mtime }, dest + base, options.auth);
await uploadAsset({ path: source, mtime: filestat.mtime }, dest + base, this.dbManager, this.dbRemote, options.auth);
}

@@ -304,178 +290,221 @@ }

}
//----------------------------------------------------------------------------------------------
// cleanDestination
//----------------------------------------------------------------------------------------------
async cleanDestination(dest) {
const remoteList = await scanAssets(this.dbManager);
for (let ind = 0; ind < remoteList.length; ind++) {
const fd = remoteList[ind];
if (fd.path.startsWith(dest)) {
const url = '/api/admin/assets/' + fd.id;
await this.dbRemote?.apiServer.delete(url);
}
}
/**
* function cleanDestination
* @param dest
* @param dbManager
* @param dbRemote
*/
async function cleanDestination(dest, dbManager, dbRemote) {
const remoteList = await scanAssets(dbManager);
for (let ind = 0; ind < remoteList.length; ind++) {
const fd = remoteList[ind];
if (fd.path.startsWith(dest)) {
const url = '/api/admin/assets/' + fd.id;
await dbRemote?.apiServer.delete(url);
}
}
//----------------------------------------------------------------------------------------------
// uploadDirectory
//----------------------------------------------------------------------------------------------
async uploadDirectory(source, dest, options) {
const localList = [];
let dirName;
if (source.substring(source.length - 1) === '/') {
// trailing directory separator
dirName = source;
}
/**
* function uploadDirectory
* @param source
* @param dest
* @param options {yes: no confirmation, auth: basic/token/cookie/undefined}
* @param dbManager
* @param dbRemote
*/
async function uploadDirectory(source, dest, options, dbManager, dbRemote) {
const localList = [];
let dirName;
if (source.substring(source.length - 1) === '/') {
// trailing directory separator
dirName = source;
}
else {
dirName = source + '/';
}
// logger.debug('options', options)
scanDir(dirName, localList);
const remoteList = await scanAssets(dbManager);
const uploadList = buildUploadList(dirName, dest, localList, remoteList);
// logger.info(fileNames.join('\n'))
if (uploadList.length === 0)
throw 'None file to upload';
let uploadConfirmed = (options.yes !== undefined);
if (uploadConfirmed === false) {
const reply = await inquirer_1.default.prompt({ type: 'confirm', name: 'confirm', message: 'Do you want to upload this(these) ' + uploadList.length + ' file(s) ?' });
if (reply.confirm === true)
uploadConfirmed = true;
}
if (uploadConfirmed === true) {
await uploadFiles(dirName, uploadList, dest, dbManager, dbRemote, options.auth);
}
}
exports.uploadDirectory = uploadDirectory;
/**
* function buildUploadList
* @param dirName
* @param dest
* @param localList
* @param remoteList
* @returns
*/
function buildUploadList(dirName, dest, localList, remoteList) {
const result = [];
const remoteMap = new Map();
for (let ind = 0; ind < remoteList.length; ind++) {
const remote = remoteList[ind];
remoteMap.set(remote.path, remote);
}
for (let ind = 0; ind < localList.length; ind++) {
const localDesc = localList[ind];
const route = dest + localDesc.path.substring(dirName.length);
const remoteDesc = remoteMap.get(route);
if (remoteDesc === undefined || remoteDesc.mtime.getTime() + 1000 < localDesc.mtime.getTime()) {
if (remoteDesc === undefined)
logger.debug('remoteDesc undefined');
else
logger.debug('remoteDesc.mtime ' + remoteDesc.mtime.getTime(), 'localDesc.mtime ' + localDesc.mtime.getTime());
logger.info(localDesc.path);
result.push(localDesc);
}
else {
dirName = source + '/';
}
// logger.debug('options', options)
this.scanDir(dirName, localList);
const remoteList = await scanAssets(this.dbManager);
const uploadList = this.buildUploadList(dirName, dest, localList, remoteList);
// logger.info(fileNames.join('\n'))
if (uploadList.length === 0)
throw 'None file to upload';
let uploadConfirmed = (options.yes !== undefined);
if (uploadConfirmed === false) {
const reply = await inquirer_1.default.prompt({ type: 'confirm', name: 'confirm', message: 'Do you want to upload this(these) ' + uploadList.length + ' file(s) ?' });
if (reply.confirm === true)
uploadConfirmed = true;
}
if (uploadConfirmed === true) {
await this.uploadFiles(dirName, uploadList, dest, options.auth);
}
// const rl = readline.createInterface(process.stdin, process.stdout)
// rl.question('Do you want to upload this(these) ' + uploadList.length + ' file(s) (Y/N/y/n) ?', async (reply) => {
// rl.close()
// if (reply !== 'Y' && reply !== 'y') {
// logger.info('upload cancelled')
// return
// }
// await this.uploadFiles(dirName, uploadList, dest)
// })
}
//----------------------------------------------------------------------------------------------
// buildUploadList
//----------------------------------------------------------------------------------------------
buildUploadList(dirName, dest, localList, remoteList) {
const result = [];
const remoteMap = new Map();
for (let ind = 0; ind < remoteList.length; ind++) {
const remote = remoteList[ind];
remoteMap.set(remote.path, remote);
return result;
}
/**
* function scanDir
* @param dirName
* @param result
*/
function scanDir(dirName, result) {
const files = fs.readdirSync(dirName);
for (let ind = 0; ind < files.length; ind++) {
const fileName = files[ind];
if (file2exclude(fileName) === true)
continue;
const fstat = fs.statSync(dirName + fileName);
if (fstat.isDirectory() === true) {
scanDir(dirName + fileName + '/', result);
}
for (let ind = 0; ind < localList.length; ind++) {
const localDesc = localList[ind];
const route = dest + localDesc.path.substring(dirName.length);
const remoteDesc = remoteMap.get(route);
if (remoteDesc === undefined || remoteDesc.mtime.getTime() + 1000 < localDesc.mtime.getTime()) {
if (remoteDesc === undefined)
logger.debug('remoteDesc undefined');
else
logger.debug('remoteDesc.mtime ' + remoteDesc.mtime.getTime(), 'localDesc.mtime ' + localDesc.mtime.getTime());
logger.info(localDesc.path);
result.push(localDesc);
}
}
return result;
}
//----------------------------------------------------------------------------------------------
// scanDir
//----------------------------------------------------------------------------------------------
scanDir(dirName, result) {
const files = fs.readdirSync(dirName);
for (let ind = 0; ind < files.length; ind++) {
const fileName = files[ind];
if (this.file2exclude(fileName) === true)
else {
if (mimetypeLookup(fileName) === false) {
logger.info(fileName + ' file extension is unknown and will not be uploaded');
continue;
const fstat = fs.statSync(dirName + fileName);
if (fstat.isDirectory() === true) {
this.scanDir(dirName + fileName + '/', result);
}
else {
if (this.mimetypeLookup(fileName) === false) {
logger.info(fileName + ' file extension is unknown and will not be uploaded');
continue;
}
//const dbAssetExist = this.dbManager?.dbAssetExist()
result.push({ path: dirName + fileName, mtime: fstat.mtime });
// logger.debug(dirName + '/' + fileName)
}
//const dbAssetExist = this.dbManager?.dbAssetExist()
result.push({ path: dirName + fileName, mtime: fstat.mtime });
// logger.debug(dirName + '/' + fileName)
}
}
file2exclude(fileName) {
let result = false;
this.ignorePatterns.forEach((pattern) => {
if (fileName === pattern)
result = true;
});
return result;
}
const ignorePatterns = ['.git', 'node_modules'];
/**
* function file2exclude
* @param fileName
* @returns
*/
function file2exclude(fileName) {
let result = false;
ignorePatterns.forEach((pattern) => {
if (fileName === pattern)
result = true;
});
return result;
}
/**
* function uploadFiles
* @param dirName
* @param uploadList
* @param dest
* @param dbManager
* @param dbRemote
* @param auth
*/
async function uploadFiles(dirName, uploadList, dest, dbManager, dbRemote, auth) {
for (let ind = 0; ind < uploadList.length; ind++) {
const upload = uploadList[ind];
const route = dest + upload.path.substring(dirName.length);
logger.debug('upload ' + upload.path + ' to ' + route);
await uploadAsset(upload, route, dbManager, dbRemote, auth);
}
//----------------------------------------------------------------------------------------------
// uploadFiles
//----------------------------------------------------------------------------------------------
async uploadFiles(dirName, uploadList, dest, auth) {
for (let ind = 0; ind < uploadList.length; ind++) {
const upload = uploadList[ind];
const route = dest + upload.path.substring(dirName.length);
logger.debug('upload ' + upload.path + ' to ' + route);
await this.uploadAsset(upload, route, auth);
}
/**
* function uploadAsset
* @param upload
* @param route
* @param dbManager
* @param dbRemote
* @param auth
*/
async function uploadAsset(upload, route, dbManager, dbRemote, auth) {
// logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' + this.mimetypeLookup(upload.path) + ', auth : ' + auth)
try {
let dbAsset = await dbManager?.dbAssetExist(route);
if (dbAsset === undefined) {
dbAsset = new core_1.DBAsset();
}
}
//----------------------------------------------------------------------------------------------
// uploadAsset
//----------------------------------------------------------------------------------------------
async uploadAsset(upload, route, auth) {
// logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' + this.mimetypeLookup(upload.path) + ', auth : ' + auth)
try {
let dbAsset = await this.dbManager?.dbAssetExist(route);
if (dbAsset === undefined) {
dbAsset = new core_1.DBAsset();
}
const mimetype = this.mimetypeLookup(upload.path);
if (mimetype === false)
throw 'mimetype false for ' + upload;
dbAsset.mimetype = mimetype;
dbAsset.route = route;
dbAsset.auth = auth;
if (dbAsset.auth === 'none')
dbAsset.auth = undefined;
// const fstat = fs.statSync(fileName)
dbAsset.last_update = upload.mtime;
// const contentBuffer = fs.readFileSync(fileName)
// dbAsset.content = contentBuffer
// logger.debug('dbAsset.content length ' + dbAsset.content.length)
if (dbAsset.id === undefined) {
dbAsset.id = await this.dbManager?.dbAssetInsert(dbAsset);
logger.info('inserted asset ' + dbAsset.id + ' route ' + dbAsset.route);
}
else {
await this.dbManager?.dbAssetUpdate(dbAsset);
logger.info('updated asset ' + dbAsset.route);
}
await this.uploadAssetContent(dbAsset, upload.path);
const mimetype = mimetypeLookup(upload.path);
if (mimetype === false)
throw 'mimetype false for ' + upload;
dbAsset.mimetype = mimetype;
dbAsset.route = route;
dbAsset.auth = auth;
if (dbAsset.auth === 'none')
dbAsset.auth = undefined;
// const fstat = fs.statSync(fileName)
dbAsset.last_update = upload.mtime;
// const contentBuffer = fs.readFileSync(fileName)
// dbAsset.content = contentBuffer
// logger.debug('dbAsset.content length ' + dbAsset.content.length)
if (dbAsset.id === undefined) {
dbAsset.id = await dbManager?.dbAssetInsert(dbAsset);
logger.info('inserted asset ' + dbAsset.id + ' route ' + dbAsset.route);
}
catch (err) {
logger.error(err);
else {
await dbManager?.dbAssetUpdate(dbAsset);
logger.info('updated asset ' + dbAsset.route);
}
await uploadAssetContent(dbAsset, upload.path, dbRemote);
}
//----------------------------------------------------------------------------------------------
// uploadAssetContent
//----------------------------------------------------------------------------------------------
async uploadAssetContent(dbAsset, fileName) {
logger.debug('uploadAssetContent file ' + fileName + ' to path ' + path_1.default);
try {
const file = fs.createReadStream(fileName);
const form = new form_data_1.default();
form.append('uploadFile', file);
const route = '/api/upload/cyk_asset/asset_content?asset_id=' + dbAsset.id;
const resp = await this.dbRemote?.apiServer.post(route, form);
if (resp.status === 200) {
logger.info(fileName + ' uploaded');
}
catch (err) {
logger.error(err);
}
}
exports.uploadAsset = uploadAsset;
/**
* function mimetypeLookup
* @param filename
* @returns
*/
function mimetypeLookup(filename) {
let result;
if (path_1.default.extname(filename) === '.cyk') {
result = 'application/xml';
}
else {
result = mime_types_1.default.lookup(filename);
}
return result;
}
/**
* function uploadAssetContent
* @param dbAsset
* @param fileName
* @param dbRemote
*/
async function uploadAssetContent(dbAsset, fileName, dbRemote) {
logger.debug('uploadAssetContent file ' + fileName + ' to path ' + path_1.default);
try {
const file = fs.createReadStream(fileName);
const form = new form_data_1.default();
form.append('uploadFile', file);
const route = '/api/upload/cyk_asset/asset_content?asset_id=' + dbAsset.id;
const resp = await dbRemote?.apiServer.post(route, form);
if (resp.status === 200) {
logger.info(fileName + ' uploaded');
}
catch (err) {
logger.error(err);
}
}
catch (err) {
logger.error(err);
}
}

@@ -25,14 +25,19 @@ import { DBManager, DBRemote, SigninResponse } from "@cyklang/core";

}>;
/**
* method runShellCommand
* @param command
*/
runShellCommand(command: string, args: string[]): Promise<void>;
/**
*
* @param command
* @param args
* @returns
*/
spawnCommand(command: string, args: string[]): Promise<void>;
}
/**
* method runShellCommand
* @param command
*/
export declare function runShellCommand(command: string, args: string[]): Promise<void>;
/**
* function spawnCommand
* @param command
* @param args
* @returns
*/
export declare function spawnCommand(command: string, args: string[]): Promise<void>;
/**
* function readPackageJson
* @returns
*/
export declare function readPackageJson(): Promise<any>;
"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 __importDefault = (this && this.__importDefault) || function (mod) {

@@ -6,3 +29,3 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

Object.defineProperty(exports, "__esModule", { value: true });
exports.Cmd = void 0;
exports.readPackageJson = exports.spawnCommand = exports.runShellCommand = exports.Cmd = void 0;
const core_1 = require("@cyklang/core");

@@ -16,2 +39,3 @@ const commander_1 = require("commander");

const kolorist_1 = require("kolorist");
const fs = __importStar(require("fs"));
const logger = loglevel_1.default.getLogger('Cmd.ts');

@@ -105,43 +129,62 @@ logger.setLevel('debug');

}
/**
* method runShellCommand
* @param command
*/
async runShellCommand(command, args) {
try {
await this.spawnCommand(command, args);
// console.log(command)
// const result = await this.executeCommand(command);
// console.log(result.stdout);
// if (result.stderr && result.stderr.trim() !== '')
// console.error(result.stderr);
}
catch (error) {
console.error('Error running "' + command + '":', error);
throw error;
}
}
exports.Cmd = Cmd;
/**
* method runShellCommand
* @param command
*/
async function runShellCommand(command, args) {
try {
await spawnCommand(command, args);
// console.log(command)
// const result = await this.executeCommand(command);
// console.log(result.stdout);
// if (result.stderr && result.stderr.trim() !== '')
// console.error(result.stderr);
}
/**
*
* @param command
* @param args
* @returns
*/
spawnCommand(command, args) {
console.log();
console.log([command, ...args, '...'].join(' '));
const child_process = (0, child_process_1.spawn)(command, args, { stdio: 'inherit' });
return new Promise((resolve, reject) => {
child_process.on('close', (code) => {
if (code === 0) {
console.log((0, kolorist_1.green)('*') + ' ' + [command, ...args].join(' '));
resolve();
}
else {
reject(new Error([command, ...args].join(' ') + ' --> Error ' + code));
}
});
catch (error) {
console.error('Error running "' + command + '":', error);
throw error;
}
}
exports.runShellCommand = runShellCommand;
/**
* function spawnCommand
* @param command
* @param args
* @returns
*/
function spawnCommand(command, args) {
console.log();
console.log([command, ...args, '...'].join(' '));
const child_process = (0, child_process_1.spawn)(command, args, { stdio: 'inherit' });
return new Promise((resolve, reject) => {
child_process.on('close', (code) => {
if (code === 0) {
console.log((0, kolorist_1.green)('*') + ' ' + [command, ...args].join(' '));
resolve();
}
else {
reject(new Error([command, ...args].join(' ') + ' --> Error ' + code));
}
});
});
}
exports.spawnCommand = spawnCommand;
/**
* function readPackageJson
* @returns
*/
async function readPackageJson() {
try {
if (!fs.existsSync("package.json"))
throw 'package.json not found';
const fileContent = fs.readFileSync("package.json");
return JSON.parse(fileContent.toString());
}
catch (err) {
console.error(err);
throw err;
}
}
exports.Cmd = Cmd;
exports.readPackageJson = readPackageJson;

@@ -126,2 +126,3 @@ "use strict";

await this.dbManager.dbModuleDelete(dbModule);
logger.info('module ' + dbname + ' (id ' + dbModule.id + ' deleted)');
}

@@ -128,0 +129,0 @@ catch (err) {

@@ -18,2 +18,3 @@ #!/usr/bin/env node

const OpenCommand_1 = require("./OpenCommand");
const UninstallCommand_1 = require("./UninstallCommand");
const logger = loglevel_1.default.getLogger("index.ts");

@@ -23,5 +24,6 @@ logger.setLevel("debug");

program.name('cyk').description('cyklang CLI')
.version('0.5.4');
.version('0.5.5');
program.addCommand(new InstallCommand_1.InstallCommand('install'));
program.addCommand(new InstallCommand_1.InstallCommand('i'));
program.addCommand(new UninstallCommand_1.UninstallCommand('uninstall'));
program.addCommand(new AssetCommand_1.AssetCommand('asset', 'manage assets'));

@@ -28,0 +30,0 @@ program.addCommand(new AssetCommand_1.AssetCommand('a', 'manage assets'));

import { Cmd } from "./Cmd";
import { DBManager, DBRemote } from "@cyklang/core";
export declare class InstallCommand extends Cmd {
constructor(name: string);
install(node_package: string, options: any): Promise<void>;
/**
* method installNodePackage
* @param node_package
* constructor
* @param name
*/
installNodePackage(node_package: string): Promise<void>;
constructor(name: string);
/**
* method lookupInstallScript
* method install
* @param node_package
* @param options
*/
lookupInstallScript(node_package: string): Promise<string | undefined>;
install(node_package: string, options: any): Promise<void>;
}
export declare function installPackage(node_package: string, dbManager: DBManager, dbRemote: DBRemote): Promise<void>;

@@ -29,3 +29,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.InstallCommand = void 0;
exports.installPackage = exports.InstallCommand = void 0;
const Cmd_1 = require("./Cmd");

@@ -37,8 +37,14 @@ const fs = __importStar(require("fs"));

const ModuleCommand_1 = require("./ModuleCommand");
const UninstallCommand_1 = require("./UninstallCommand");
const AssetCommand_1 = require("./AssetCommand");
const logger = loglevel_1.default.getLogger('InstallCommand.ts');
logger.setLevel('debug');
class InstallCommand extends Cmd_1.Cmd {
/**
* constructor
* @param name
*/
constructor(name) {
super(name);
this.description('npm install and upload xml modules to Cyk server')
this.description('npm install and run install script')
.argument('<node_package>', 'Node Package installed as dev dependency')

@@ -49,47 +55,13 @@ .action(async (node_package, options) => {

}
/**
* method install
* @param node_package
* @param options
*/
async install(node_package, options) {
try {
await this.prologue(options);
if (this.dbManager === undefined)
throw 'dbManager undefined';
/**
* install the Node Package
*/
await this.installNodePackage(node_package);
const installScript = await this.lookupInstallScript(node_package);
if (installScript) {
/**
* execute installScript
*/
const installPath = path.join('node_modules', node_package, 'scripts', installScript);
await this.runShellCommand(installPath, []);
}
else {
/**
* default install : upload modules and execute _init.xml
*/
console.log();
console.log('upload modules to server ...');
const xmlFolder = path.join('node_modules', node_package, 'xml');
if (!fs.existsSync(xmlFolder) || !fs.statSync(xmlFolder).isDirectory()) {
throw 'xml folder not found ( ' + xmlFolder + ' )';
}
/**
* upload modules to the server
*/
let initModule;
const files = fs.readdirSync(xmlFolder);
for (let ind = 0; ind < files.length; ind++) {
const file = files[ind];
await (0, ModuleCommand_1.uploadModule)(path.join(xmlFolder, file), this.dbManager);
if (file.endsWith('_init.xml')) {
initModule = file;
}
}
console.log((0, kolorist_1.green)('*') + ' upload modules to server');
if (initModule) {
const initPath = path.join(xmlFolder, initModule);
await this.runShellCommand('npx', ['cyk', 'run', initPath]);
}
}
if (this.dbManager === undefined || !this.dbRemote)
throw 'dbManager or dbRemote undefined';
await installPackage(node_package, this.dbManager, this.dbRemote);
}

@@ -100,39 +72,143 @@ catch (err) {

}
}
exports.InstallCommand = InstallCommand;
async function installPackage(node_package, dbManager, dbRemote) {
/**
* method installNodePackage
* @param node_package
* install the Node Package
*/
async installNodePackage(node_package) {
try {
await this.runShellCommand('npm', ['install', '--save-dev', node_package]);
await installNodePackage(node_package, dbManager);
const installScript = await lookupInstallScript(node_package);
if (installScript) {
/**
* execute installScript
*/
const installPath = path.join('node_modules', node_package, 'scripts', installScript);
await (0, Cmd_1.runShellCommand)(installPath, []);
}
else {
/**
* default install : upload modules and execute _init.xml
*/
await defaultInstallScript(node_package, dbManager, dbRemote);
}
}
exports.installPackage = installPackage;
/**
* method defaultInstallScript
* @param node_package
*/
async function defaultInstallScript(node_package, dbManager, dbRemote) {
console.log();
console.log('Default install script');
/**
* upload package assets
*/
await uploadPackageAssets(node_package, dbManager, dbRemote);
/**
* upload package modules to the server
*/
await uploadPackageModules(node_package, dbManager);
}
/**
* function uploadPackageAssets
* @param node_package
* @param dbManager
*/
async function uploadPackageAssets(node_package, dbManager, dbRemote) {
const assetFolder = path.join('node_modules', node_package, 'asset');
if (!fs.existsSync(assetFolder) || !fs.statSync(assetFolder).isDirectory()) {
return;
}
console.log();
console.log('upload assets to server ...');
if (!dbManager)
throw 'dbManager undefined';
const items = fs.readdirSync(assetFolder);
for (let ind = 0; ind < items.length; ind++) {
const item = items[ind];
const itemPath = path.join(assetFolder, item);
if (fs.statSync(itemPath).isDirectory()) {
const dest = "/" + item + "/";
await (0, AssetCommand_1.uploadDirectory)(itemPath, dest, { yes: true }, dbManager, dbRemote);
}
catch (error) {
console.error('Error installing ' + node_package + ' :', error);
throw error;
else {
const dest = "/" + item;
const fd = { path: path.join(assetFolder, item), mtime: new Date() };
await (0, AssetCommand_1.uploadAsset)(fd, dest, dbManager, dbRemote);
}
}
/**
* method lookupInstallScript
* @param node_package
*/
async lookupInstallScript(node_package) {
let result;
try {
const scriptsFolder = path.join('node_modules', node_package, 'scripts');
if (fs.existsSync(scriptsFolder) && fs.statSync(scriptsFolder).isDirectory()) {
const files = fs.readdirSync(scriptsFolder);
for (let ind = 0; ind < files.length; ind++) {
const file = files[ind];
if (file.startsWith('install.')) {
result = file;
}
console.log((0, kolorist_1.green)('*') + ' upload assets to server');
}
/**
* function uploadModules
* @param node_package
* @param dbManager
*/
async function uploadPackageModules(node_package, dbManager) {
const moduleFolder = path.join('node_modules', node_package, 'module');
if (!fs.existsSync(moduleFolder) || !fs.statSync(moduleFolder).isDirectory()) {
return;
}
console.log();
console.log('upload modules to server ...');
let initModule;
const files = fs.readdirSync(moduleFolder);
for (let ind = 0; ind < files.length; ind++) {
const file = files[ind];
if (!dbManager)
throw 'dbManager undefined';
await (0, ModuleCommand_1.uploadModule)(path.join(moduleFolder, file), dbManager);
if (file.endsWith('_init.xml')) {
initModule = file;
}
}
console.log((0, kolorist_1.green)('*') + ' upload modules to server');
if (initModule) {
const initPath = path.join(moduleFolder, initModule);
await (0, Cmd_1.runShellCommand)('npx', ['cyk', 'run', initPath]);
}
}
/**
* method installNodePackage
* @param node_package
*/
async function installNodePackage(node_package, dbManager) {
try {
const packageJson = await (0, Cmd_1.readPackageJson)();
if (packageJson.devDependencies && packageJson.devDependencies[node_package]
|| packageJson.dependencies && packageJson.dependencies[node_package]) {
console.log(node_package + ' already installed. We uninstall it first');
if (!dbManager)
throw 'dbManager undefined';
await (0, UninstallCommand_1.uninstallPackage)(node_package, dbManager);
}
await (0, Cmd_1.runShellCommand)('npm', ['install', '--save-dev', node_package]);
}
catch (error) {
console.error('Error installing ' + node_package + ' :', error);
throw error;
}
}
/**
* function lookupInstallScript
* @param node_package
*/
async function lookupInstallScript(node_package) {
let result;
try {
const scriptsFolder = path.join('node_modules', node_package, 'scripts');
if (fs.existsSync(scriptsFolder) && fs.statSync(scriptsFolder).isDirectory()) {
const files = fs.readdirSync(scriptsFolder);
for (let ind = 0; ind < files.length; ind++) {
const file = files[ind];
if (file.startsWith('install.')) {
result = file;
}
}
return result;
}
catch (err) {
throw err;
}
return result;
}
catch (err) {
throw err;
}
}
exports.InstallCommand = InstallCommand;

@@ -13,1 +13,7 @@ #!/usr/bin/env ts-node

export declare function uploadModule(file: string, dbManager: DBManager): Promise<void>;
/**
* function deleteModule
* @param dbname
* @param dbManager
*/
export declare function deleteModule(dbname: string, dbManager: DBManager): Promise<void>;

@@ -30,3 +30,3 @@ #!/usr/bin/env ts-node

Object.defineProperty(exports, "__esModule", { value: true });
exports.uploadModule = exports.ModuleCommand = void 0;
exports.deleteModule = exports.uploadModule = exports.ModuleCommand = void 0;
const core_1 = require("@cyklang/core");

@@ -170,2 +170,3 @@ const fs = __importStar(require("fs"));

else {
logger.debug('module exists : ' + dbModuleExist.dbname + ', id ' + dbModuleExist.id);
// update

@@ -285,1 +286,11 @@ dbModuleExist.source = source;

}
/**
* function deleteModule
* @param dbname
* @param dbManager
*/
async function deleteModule(dbname, dbManager) {
const dbClient = new DBClient_1.DBClient(dbManager);
await dbClient.deleteModule(dbname);
}
exports.deleteModule = deleteModule;
{
"name": "@cyklang/cli",
"version": "0.5.4",
"version": "0.5.5",
"description": "cyklang CLI",

@@ -20,3 +20,3 @@ "main": "build/index.js",

"dependencies": {
"@cyklang/core": "^0.5.2",
"@cyklang/core": "^0.5.3",
"commander": "^9.4.0",

@@ -23,0 +23,0 @@ "dotenv": "^16.0.1",

@@ -10,3 +10,3 @@ import { Command } from "commander"

// import readline from 'readline'
import { DBAsset, DBExecuteRequest, DBManager, ObjectData, parseXML, PrimitiveData } from "@cyklang/core"
import { DBAsset, DBExecuteRequest, DBManager, DBRemote, ObjectData, parseXML, PrimitiveData } from "@cyklang/core"
import FormData from 'form-data'

@@ -116,3 +116,3 @@

await this.prologue(options)
if (! this.dbManager) throw 'dbManager undefined'
if (!this.dbManager) throw 'dbManager undefined'
const dbClient = new DBClient(this.dbManager)

@@ -126,5 +126,5 @@ const list = await dbClient.selectFromTable('Assets to delete', 'cyk_asset',

);
const reply = await inquirer.prompt({type: 'confirm', name: 'confirm', message: 'Do you want to delete these ' + list.length + ' file(s)'})
const reply = await inquirer.prompt({ type: 'confirm', name: 'confirm', message: 'Do you want to delete these ' + list.length + ' file(s)' })
if (reply.confirm) {
for(let ind = 0; ind < list.length; ind++) {
for (let ind = 0; ind < list.length; ind++) {
const asset = list[ind]

@@ -174,3 +174,3 @@ logger.info('delete ' + asset.asset_route)

interface FileDescriptor {
export interface FileDescriptor {
path: string

@@ -200,13 +200,4 @@ mtime: Date

mimetypeLookup(filename: string): string | false {
let result: string | false
if (path.extname(filename) === '.cyk') {
result = 'application/xml'
}
else {
result = mime.lookup(filename)
}
return result
}
/**

@@ -279,3 +270,3 @@ * method commandU

if (options.clean) {
await this.cleanDestination(dest)
await cleanDestination(dest, this.dbManager, this.dbRemote)
}

@@ -288,3 +279,3 @@

if (filestat.isDirectory() === true) {
await this.uploadDirectory(source, dest, options)
await uploadDirectory(source, dest, options, this.dbManager, this.dbRemote)
}

@@ -294,3 +285,3 @@ else if (filestat.isFile() === true) {

logger.debug('upload file ' + source + ' to ' + dest + base)
await this.uploadAsset({ path: source, mtime: filestat.mtime }, dest + base, options.auth)
await uploadAsset({ path: source, mtime: filestat.mtime }, dest + base, this.dbManager, this.dbRemote, options.auth)
}

@@ -303,210 +294,234 @@ }

}
}
//----------------------------------------------------------------------------------------------
// cleanDestination
//----------------------------------------------------------------------------------------------
/**
* function cleanDestination
* @param dest
* @param dbManager
* @param dbRemote
*/
async function cleanDestination(dest: string, dbManager: DBManager | undefined, dbRemote: DBRemote | undefined) {
async cleanDestination(dest: string) {
const remoteList = await scanAssets(this.dbManager)
for (let ind = 0; ind < remoteList.length; ind++) {
const fd = remoteList[ind]
if (fd.path.startsWith(dest)) {
const url = '/api/admin/assets/' + fd.id
await this.dbRemote?.apiServer.delete(url)
}
const remoteList = await scanAssets(dbManager)
for (let ind = 0; ind < remoteList.length; ind++) {
const fd = remoteList[ind]
if (fd.path.startsWith(dest)) {
const url = '/api/admin/assets/' + fd.id
await dbRemote?.apiServer.delete(url)
}
}
}
/**
* function uploadDirectory
* @param source
* @param dest
* @param options {yes: no confirmation, auth: basic/token/cookie/undefined}
* @param dbManager
* @param dbRemote
*/
export async function uploadDirectory(source: string, dest: string, options: any,
dbManager: DBManager | undefined, dbRemote: DBRemote | undefined) {
//----------------------------------------------------------------------------------------------
// uploadDirectory
//----------------------------------------------------------------------------------------------
const localList: FileDescriptor[] = []
let dirName: string
if (source.substring(source.length - 1) === '/') {
// trailing directory separator
dirName = source
}
else {
dirName = source + '/'
}
async uploadDirectory(source: string, dest: string, options: any) {
// logger.debug('options', options)
const localList: FileDescriptor[] = []
let dirName: string
if (source.substring(source.length - 1) === '/') {
// trailing directory separator
dirName = source
}
else {
dirName = source + '/'
}
scanDir(dirName, localList)
// logger.debug('options', options)
const remoteList = await scanAssets(dbManager)
this.scanDir(dirName, localList)
const uploadList = buildUploadList(dirName, dest, localList, remoteList)
const remoteList = await scanAssets(this.dbManager)
// logger.info(fileNames.join('\n'))
if (uploadList.length === 0) throw 'None file to upload'
const uploadList = this.buildUploadList(dirName, dest, localList, remoteList)
let uploadConfirmed = (options.yes !== undefined)
// logger.info(fileNames.join('\n'))
if (uploadList.length === 0) throw 'None file to upload'
if (uploadConfirmed === false) {
const reply = await inquirer.prompt({ type: 'confirm', name: 'confirm', message: 'Do you want to upload this(these) ' + uploadList.length + ' file(s) ?' })
if (reply.confirm === true) uploadConfirmed = true
}
let uploadConfirmed = (options.yes !== undefined)
if (uploadConfirmed === true) {
await uploadFiles(dirName, uploadList, dest, dbManager, dbRemote, options.auth)
}
}
/**
* function buildUploadList
* @param dirName
* @param dest
* @param localList
* @param remoteList
* @returns
*/
function buildUploadList(dirName: string, dest: string, localList: FileDescriptor[], remoteList: FileDescriptor[]): FileDescriptor[] {
const result: FileDescriptor[] = []
const remoteMap = new Map<string, FileDescriptor>()
for (let ind = 0; ind < remoteList.length; ind++) {
const remote = remoteList[ind]
remoteMap.set(remote.path, remote)
}
for (let ind = 0; ind < localList.length; ind++) {
const localDesc = localList[ind]
const route = dest + localDesc.path.substring(dirName.length)
const remoteDesc = remoteMap.get(route)
if (uploadConfirmed === false) {
const reply = await inquirer.prompt({ type: 'confirm', name: 'confirm', message: 'Do you want to upload this(these) ' + uploadList.length + ' file(s) ?' })
if (reply.confirm === true) uploadConfirmed = true
if (remoteDesc === undefined || remoteDesc.mtime.getTime() + 1000 < localDesc.mtime.getTime()) {
if (remoteDesc === undefined) logger.debug('remoteDesc undefined')
else logger.debug('remoteDesc.mtime ' + remoteDesc.mtime.getTime(), 'localDesc.mtime ' + localDesc.mtime.getTime())
logger.info(localDesc.path)
result.push(localDesc)
}
if (uploadConfirmed === true) {
await this.uploadFiles(dirName, uploadList, dest, options.auth)
}
// const rl = readline.createInterface(process.stdin, process.stdout)
// rl.question('Do you want to upload this(these) ' + uploadList.length + ' file(s) (Y/N/y/n) ?', async (reply) => {
// rl.close()
// if (reply !== 'Y' && reply !== 'y') {
// logger.info('upload cancelled')
// return
// }
// await this.uploadFiles(dirName, uploadList, dest)
// })
}
//----------------------------------------------------------------------------------------------
// buildUploadList
//----------------------------------------------------------------------------------------------
buildUploadList(dirName: string, dest: string, localList: FileDescriptor[], remoteList: FileDescriptor[]): FileDescriptor[] {
const result: FileDescriptor[] = []
const remoteMap = new Map<string, FileDescriptor>()
for (let ind = 0; ind < remoteList.length; ind++) {
const remote = remoteList[ind]
remoteMap.set(remote.path, remote)
return result
}
/**
* function scanDir
* @param dirName
* @param result
*/
function scanDir(dirName: string, result: FileDescriptor[]) {
const files = fs.readdirSync(dirName)
for (let ind = 0; ind < files.length; ind++) {
const fileName = files[ind]
if (file2exclude(fileName) === true) continue
const fstat = fs.statSync(dirName + fileName)
if (fstat.isDirectory() === true) {
scanDir(dirName + fileName + '/', result)
}
for (let ind = 0; ind < localList.length; ind++) {
const localDesc = localList[ind]
const route = dest + localDesc.path.substring(dirName.length)
const remoteDesc = remoteMap.get(route)
if (remoteDesc === undefined || remoteDesc.mtime.getTime() + 1000 < localDesc.mtime.getTime()) {
if (remoteDesc === undefined) logger.debug('remoteDesc undefined')
else logger.debug('remoteDesc.mtime ' + remoteDesc.mtime.getTime(), 'localDesc.mtime ' + localDesc.mtime.getTime())
logger.info(localDesc.path)
result.push(localDesc)
else {
if (mimetypeLookup(fileName) === false) {
logger.info(fileName + ' file extension is unknown and will not be uploaded')
continue
}
//const dbAssetExist = this.dbManager?.dbAssetExist()
result.push({ path: dirName + fileName, mtime: fstat.mtime })
// logger.debug(dirName + '/' + fileName)
}
return result
}
}
//----------------------------------------------------------------------------------------------
// scanDir
//----------------------------------------------------------------------------------------------
scanDir(dirName: string, result: FileDescriptor[]) {
const files = fs.readdirSync(dirName)
for (let ind = 0; ind < files.length; ind++) {
const fileName = files[ind]
if (this.file2exclude(fileName) === true) continue
const fstat = fs.statSync(dirName + fileName)
if (fstat.isDirectory() === true) {
this.scanDir(dirName + fileName + '/', result)
}
else {
if (this.mimetypeLookup(fileName) === false) {
logger.info(fileName + ' file extension is unknown and will not be uploaded')
continue
}
//const dbAssetExist = this.dbManager?.dbAssetExist()
result.push({ path: dirName + fileName, mtime: fstat.mtime })
// logger.debug(dirName + '/' + fileName)
}
}
const ignorePatterns = ['.git', 'node_modules']
/**
* function file2exclude
* @param fileName
* @returns
*/
function file2exclude(fileName: string): boolean {
let result = false
ignorePatterns.forEach((pattern) => {
if (fileName === pattern) result = true
})
return result
}
/**
* function uploadFiles
* @param dirName
* @param uploadList
* @param dest
* @param dbManager
* @param dbRemote
* @param auth
*/
async function uploadFiles(dirName: string, uploadList: FileDescriptor[], dest: string, dbManager: DBManager | undefined, dbRemote: DBRemote | undefined, auth: string | undefined) {
for (let ind = 0; ind < uploadList.length; ind++) {
const upload = uploadList[ind]
const route = dest + upload.path.substring(dirName.length)
logger.debug('upload ' + upload.path + ' to ' + route)
await uploadAsset(upload, route, dbManager, dbRemote, auth)
}
}
//----------------------------------------------------------------------------------------------
// file2exclude
//----------------------------------------------------------------------------------------------
/**
* function uploadAsset
* @param upload
* @param route
* @param dbManager
* @param dbRemote
* @param auth
*/
export async function uploadAsset(upload: FileDescriptor, route: string, dbManager: DBManager | undefined, dbRemote: DBRemote | undefined, auth?: string) {
// logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' + this.mimetypeLookup(upload.path) + ', auth : ' + auth)
ignorePatterns = ['.git', 'node_modules']
file2exclude(fileName: string): boolean {
let result = false
this.ignorePatterns.forEach((pattern) => {
if (fileName === pattern) result = true
})
return result
}
//----------------------------------------------------------------------------------------------
// uploadFiles
//----------------------------------------------------------------------------------------------
async uploadFiles(dirName: string, uploadList: FileDescriptor[], dest: string, auth: string | undefined) {
for (let ind = 0; ind < uploadList.length; ind++) {
const upload = uploadList[ind]
const route = dest + upload.path.substring(dirName.length)
logger.debug('upload ' + upload.path + ' to ' + route)
await this.uploadAsset(upload, route, auth)
try {
let dbAsset: DBAsset | undefined = await dbManager?.dbAssetExist(route)
if (dbAsset === undefined) {
dbAsset = new DBAsset()
}
}
const mimetype = mimetypeLookup(upload.path)
if (mimetype === false) throw 'mimetype false for ' + upload
dbAsset.mimetype = mimetype
dbAsset.route = route
dbAsset.auth = auth
if (dbAsset.auth === 'none') dbAsset.auth = undefined
//----------------------------------------------------------------------------------------------
// uploadAsset
//----------------------------------------------------------------------------------------------
// const fstat = fs.statSync(fileName)
dbAsset.last_update = upload.mtime
async uploadAsset(upload: FileDescriptor, route: string, auth?: string) {
// logger.debug('uploadAsset ' + upload.path + ' to route ' + route + ' with mimetype ' + this.mimetypeLookup(upload.path) + ', auth : ' + auth)
// const contentBuffer = fs.readFileSync(fileName)
// dbAsset.content = contentBuffer
// logger.debug('dbAsset.content length ' + dbAsset.content.length)
try {
let dbAsset: DBAsset | undefined = await this.dbManager?.dbAssetExist(route)
if (dbAsset === undefined) {
dbAsset = new DBAsset()
}
const mimetype = this.mimetypeLookup(upload.path)
if (mimetype === false) throw 'mimetype false for ' + upload
dbAsset.mimetype = mimetype
dbAsset.route = route
dbAsset.auth = auth
if (dbAsset.auth === 'none') dbAsset.auth = undefined
// const fstat = fs.statSync(fileName)
dbAsset.last_update = upload.mtime
// const contentBuffer = fs.readFileSync(fileName)
// dbAsset.content = contentBuffer
// logger.debug('dbAsset.content length ' + dbAsset.content.length)
if (dbAsset.id === undefined) {
dbAsset.id = await this.dbManager?.dbAssetInsert(dbAsset)
logger.info('inserted asset ' + dbAsset.id + ' route ' + dbAsset.route)
}
else {
await this.dbManager?.dbAssetUpdate(dbAsset)
logger.info('updated asset ' + dbAsset.route)
}
await this.uploadAssetContent(dbAsset, upload.path)
if (dbAsset.id === undefined) {
dbAsset.id = await dbManager?.dbAssetInsert(dbAsset)
logger.info('inserted asset ' + dbAsset.id + ' route ' + dbAsset.route)
}
catch (err) {
logger.error(err)
else {
await dbManager?.dbAssetUpdate(dbAsset)
logger.info('updated asset ' + dbAsset.route)
}
await uploadAssetContent(dbAsset, upload.path, dbRemote)
}
catch (err) {
logger.error(err)
}
}
//----------------------------------------------------------------------------------------------
// uploadAssetContent
//----------------------------------------------------------------------------------------------
/**
* function mimetypeLookup
* @param filename
* @returns
*/
function mimetypeLookup(filename: string): string | false {
let result: string | false
if (path.extname(filename) === '.cyk') {
result = 'application/xml'
}
else {
result = mime.lookup(filename)
}
return result
}
async uploadAssetContent(dbAsset: DBAsset, fileName: string) {
logger.debug('uploadAssetContent file ' + fileName + ' to path ' + path)
try {
const file = fs.createReadStream(fileName)
const form = new FormData()
form.append('uploadFile', file)
/**
* function uploadAssetContent
* @param dbAsset
* @param fileName
* @param dbRemote
*/
async function uploadAssetContent(dbAsset: DBAsset, fileName: string, dbRemote: DBRemote | undefined) {
logger.debug('uploadAssetContent file ' + fileName + ' to path ' + path)
try {
const file = fs.createReadStream(fileName)
const form = new FormData()
form.append('uploadFile', file)
const route = '/api/upload/cyk_asset/asset_content?asset_id=' + dbAsset.id
const resp = await this.dbRemote?.apiServer.post(route, form)
if (resp.status === 200) {
logger.info(fileName + ' uploaded')
}
const route = '/api/upload/cyk_asset/asset_content?asset_id=' + dbAsset.id
const resp = await dbRemote?.apiServer.post(route, form)
if (resp.status === 200) {
logger.info(fileName + ' uploaded')
}
catch (err) {
logger.error(err)
}
}
catch (err) {
logger.error(err)
}
}

@@ -8,3 +8,4 @@ import { DBManager, DBRemote, SigninResponse, Structure } from "@cyklang/core";

import { exec, spawn } from 'child_process';
import {red, green, bold} from 'kolorist'
import { red, green, bold } from 'kolorist'
import * as fs from 'fs'

@@ -119,42 +120,62 @@ const logger = loglevel.getLogger('Cmd.ts')

/**
* method runShellCommand
* @param command
*/
async runShellCommand(command: string, args: string[]) {
try {
await this.spawnCommand(command, args)
// console.log(command)
// const result = await this.executeCommand(command);
// console.log(result.stdout);
// if (result.stderr && result.stderr.trim() !== '')
// console.error(result.stderr);
} catch (error) {
console.error('Error running "' + command + '":', error);
throw error
}
}
/**
* method runShellCommand
* @param command
*/
export async function runShellCommand(command: string, args: string[]) {
try {
await spawnCommand(command, args)
// console.log(command)
// const result = await this.executeCommand(command);
// console.log(result.stdout);
// if (result.stderr && result.stderr.trim() !== '')
// console.error(result.stderr);
} catch (error) {
console.error('Error running "' + command + '":', error);
throw error
}
}
/**
*
* @param command
* @param args
* @returns
*/
spawnCommand(command: string, args: string[]): Promise<void> {
console.log()
console.log([command, ...args, '...'].join(' '))
const child_process = spawn(command, args, { stdio: 'inherit' })
return new Promise((resolve, reject) => {
child_process.on('close', (code) => {
if (code === 0) {
console.log(green('*') + ' ' + [command, ...args].join(' '))
resolve()
}
else {
reject(new Error([command, ...args].join(' ') + ' --> Error ' + code))
}
})
/**
* function spawnCommand
* @param command
* @param args
* @returns
*/
export function spawnCommand(command: string, args: string[]): Promise<void> {
console.log()
console.log([command, ...args, '...'].join(' '))
const child_process = spawn(command, args, { stdio: 'inherit' })
return new Promise((resolve, reject) => {
child_process.on('close', (code) => {
if (code === 0) {
console.log(green('*') + ' ' + [command, ...args].join(' '))
resolve()
}
else {
reject(new Error([command, ...args].join(' ') + ' --> Error ' + code))
}
})
})
}
/**
* function readPackageJson
* @returns
*/
export async function readPackageJson(): Promise<any> {
try {
if (!fs.existsSync("package.json")) throw 'package.json not found'
const fileContent = fs.readFileSync("package.json")
return JSON.parse(fileContent.toString())
}
catch (err) {
console.error(err)
throw err
}
}

@@ -138,2 +138,3 @@ import { BasicType, DBColumn, DBExecuteRequest, DBManager, DBTable, ObjectData, parseXML, PrimitiveData, Script, variable2json, XmlError } from "@cyklang/core";

await this.dbManager.dbModuleDelete(dbModule)
logger.info('module ' + dbname + ' (id ' + dbModule.id + ' deleted)')
}

@@ -140,0 +141,0 @@ catch (err) {

@@ -13,2 +13,3 @@ #!/usr/bin/env node

import { OpenCommand } from './OpenCommand'
import { UninstallCommand } from './UninstallCommand'
const logger = loglevel.getLogger("index.ts")

@@ -19,6 +20,7 @@ logger.setLevel("debug")

program.name('cyk').description('cyklang CLI')
.version('0.5.4')
.version('0.5.5')
program.addCommand(new InstallCommand('install'))
program.addCommand(new InstallCommand('i'))
program.addCommand(new UninstallCommand('uninstall'))
program.addCommand(new AssetCommand('asset', 'manage assets'))

@@ -25,0 +27,0 @@ program.addCommand(new AssetCommand('a', 'manage assets'))

@@ -1,8 +0,11 @@

import { Cmd } from "./Cmd";
import { Cmd, readPackageJson, runShellCommand } from "./Cmd";
import * as fs from "fs"
import * as path from "path"
import {green, red, bold} from 'kolorist'
import { green, red, bold } from 'kolorist'
import loglevel from 'loglevel'
import { uploadModule } from "./ModuleCommand";
import { uninstallPackage } from "./UninstallCommand";
import { DBManager, DBRemote } from "@cyklang/core";
import { FileDescriptor, uploadAsset, uploadDirectory } from "./AssetCommand";
const logger = loglevel.getLogger('InstallCommand.ts')

@@ -12,5 +15,9 @@ logger.setLevel('debug')

export class InstallCommand extends Cmd {
/**
* constructor
* @param name
*/
constructor(name: string) {
super(name)
this.description('npm install and upload xml modules to Cyk server')
this.description('npm install and run install script')
.argument('<node_package>', 'Node Package installed as dev dependency')

@@ -22,50 +29,13 @@ .action(async (node_package: any, options: any) => {

/**
* method install
* @param node_package
* @param options
*/
async install(node_package: string, options: any) {
try {
await this.prologue(options)
if (this.dbManager === undefined) throw 'dbManager undefined'
if (this.dbManager === undefined || !this.dbRemote) throw 'dbManager or dbRemote undefined'
/**
* install the Node Package
*/
await this.installNodePackage(node_package)
const installScript = await this.lookupInstallScript(node_package)
if (installScript) {
/**
* execute installScript
*/
const installPath = path.join('node_modules',node_package,'scripts',installScript)
await this.runShellCommand(installPath, [])
}
else {
/**
* default install : upload modules and execute _init.xml
*/
console.log()
console.log('upload modules to server ...')
const xmlFolder = path.join('node_modules', node_package, 'xml')
if (!fs.existsSync(xmlFolder) || !fs.statSync(xmlFolder).isDirectory()) {
throw 'xml folder not found ( ' + xmlFolder + ' )'
}
/**
* upload modules to the server
*/
let initModule: string | undefined
const files = fs.readdirSync(xmlFolder)
for (let ind = 0; ind < files.length; ind++) {
const file = files[ind]
await uploadModule(path.join(xmlFolder, file), this.dbManager)
if (file.endsWith('_init.xml')) {
initModule = file
}
}
console.log(green('*') + ' upload modules to server' )
if (initModule) {
const initPath = path.join(xmlFolder, initModule)
await this.runShellCommand('npx', ['cyk', 'run', initPath])
}
}
await installPackage(node_package, this.dbManager, this.dbRemote)
}

@@ -76,41 +46,153 @@ catch (err) {

}
}
export async function installPackage(node_package: string, dbManager: DBManager, dbRemote: DBRemote) {
/**
* method installNodePackage
* @param node_package
* install the Node Package
*/
async installNodePackage(node_package: string) {
await installNodePackage(node_package, dbManager)
try {
await this.runShellCommand('npm', ['install', '--save-dev', node_package])
} catch (error) {
console.error('Error installing ' + node_package + ' :', error);
throw error
}
const installScript = await lookupInstallScript(node_package)
if (installScript) {
/**
* execute installScript
*/
const installPath = path.join('node_modules', node_package, 'scripts', installScript)
await runShellCommand(installPath, [])
}
else {
/**
* default install : upload modules and execute _init.xml
*/
await defaultInstallScript(node_package, dbManager, dbRemote)
}
}
/**
* method defaultInstallScript
* @param node_package
*/
async function defaultInstallScript(node_package: string, dbManager: DBManager, dbRemote: DBRemote) {
console.log()
console.log('Default install script')
/**
* method lookupInstallScript
* @param node_package
* upload package assets
*/
async lookupInstallScript(node_package: string): Promise<string | undefined> {
let result: string | undefined
try {
const scriptsFolder = path.join('node_modules', node_package, 'scripts')
if (fs.existsSync(scriptsFolder) && fs.statSync(scriptsFolder).isDirectory()) {
const files = fs.readdirSync(scriptsFolder)
for (let ind = 0; ind < files.length; ind++) {
const file = files[ind]
if (file.startsWith('install.')) {
result = file
}
await uploadPackageAssets(node_package, dbManager, dbRemote)
/**
* upload package modules to the server
*/
await uploadPackageModules(node_package, dbManager)
}
/**
* function uploadPackageAssets
* @param node_package
* @param dbManager
*/
async function uploadPackageAssets(node_package: string, dbManager: DBManager, dbRemote: DBRemote) {
const assetFolder = path.join('node_modules', node_package, 'asset')
if (!fs.existsSync(assetFolder) || !fs.statSync(assetFolder).isDirectory()) {
return
}
console.log()
console.log('upload assets to server ...')
if (!dbManager) throw 'dbManager undefined'
const items = fs.readdirSync(assetFolder)
for (let ind = 0; ind < items.length; ind++) {
const item = items[ind]
const itemPath = path.join(assetFolder, item)
if (fs.statSync(itemPath).isDirectory()) {
const dest = "/" + item + "/"
await uploadDirectory(itemPath, dest, {yes: true}, dbManager, dbRemote)
}
else {
const dest = "/" + item
const fd: FileDescriptor = {path: path.join(assetFolder, item), mtime: new Date()}
await uploadAsset(fd, dest, dbManager, dbRemote)
}
}
console.log(green('*') + ' upload assets to server')
}
/**
* function uploadModules
* @param node_package
* @param dbManager
*/
async function uploadPackageModules(node_package: string, dbManager: DBManager) {
const moduleFolder = path.join('node_modules', node_package, 'module')
if (!fs.existsSync(moduleFolder) || !fs.statSync(moduleFolder).isDirectory()) {
return
}
console.log()
console.log('upload modules to server ...')
let initModule: string | undefined
const files = fs.readdirSync(moduleFolder)
for (let ind = 0; ind < files.length; ind++) {
const file = files[ind]
if (!dbManager) throw 'dbManager undefined'
await uploadModule(path.join(moduleFolder, file), dbManager)
if (file.endsWith('_init.xml')) {
initModule = file
}
}
console.log(green('*') + ' upload modules to server')
if (initModule) {
const initPath = path.join(moduleFolder, initModule)
await runShellCommand('npx', ['cyk', 'run', initPath])
}
}
/**
* method installNodePackage
* @param node_package
*/
async function installNodePackage(node_package: string, dbManager: DBManager) {
try {
const packageJson = await readPackageJson()
if (packageJson.devDependencies && packageJson.devDependencies[node_package]
|| packageJson.dependencies && packageJson.dependencies[node_package]) {
console.log(node_package + ' already installed. We uninstall it first')
if (!dbManager) throw 'dbManager undefined'
await uninstallPackage(node_package, dbManager)
}
await runShellCommand('npm', ['install', '--save-dev', node_package])
} catch (error) {
console.error('Error installing ' + node_package + ' :', error);
throw error
}
}
/**
* function lookupInstallScript
* @param node_package
*/
async function lookupInstallScript(node_package: string): Promise<string | undefined> {
let result: string | undefined
try {
const scriptsFolder = path.join('node_modules', node_package, 'scripts')
if (fs.existsSync(scriptsFolder) && fs.statSync(scriptsFolder).isDirectory()) {
const files = fs.readdirSync(scriptsFolder)
for (let ind = 0; ind < files.length; ind++) {
const file = files[ind]
if (file.startsWith('install.')) {
result = file
}
}
return result
}
catch (err) {
throw err
}
return result
}
catch (err) {
throw err
}
}

@@ -150,2 +150,3 @@ #!/usr/bin/env ts-node

else {
logger.debug('module exists : ' + dbModuleExist.dbname + ', id ' + dbModuleExist.id)
// update

@@ -277,1 +278,12 @@ dbModuleExist.source = source

/**
* function deleteModule
* @param dbname
* @param dbManager
*/
export async function deleteModule(dbname: string, dbManager: DBManager) {
const dbClient = new DBClient(dbManager)
await dbClient.deleteModule(dbname)
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc