npm
This commit is contained in:
+95
-23
@@ -83,30 +83,30 @@ export type FSStatus = SharedStatus & {
|
|||||||
export abstract class FSExtension<Status extends FSStatus> extends Extension<Status>{
|
export abstract class FSExtension<Status extends FSStatus> extends Extension<Status>{
|
||||||
constructor(
|
constructor(
|
||||||
name: string,
|
name: string,
|
||||||
protected readonly prefix: string){
|
protected readonly path: string){
|
||||||
super(name)
|
super(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
public async status(): Promise<Status>{
|
public async status(): Promise<Status>{
|
||||||
const shdStatus = await super.status()
|
const shdStatus = await super.status()
|
||||||
const empty = await this.isEmpty()
|
const empty = await this.isEmpty()
|
||||||
return <Status>{...shdStatus, prefix: this.prefix, empty: empty}
|
return {...shdStatus, prefix: this.path, empty: empty}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async install():Promise<boolean>{
|
public async install():Promise<boolean>{
|
||||||
const installed = await this.isInstalled()
|
const installed = await this.isInstalled()
|
||||||
if (!installed) {
|
if (!installed) {
|
||||||
logger.info('Installing extension to', path.resolve(this.prefix, this.name))
|
logger.info('Installing extension to', path.resolve(this.path, this.name))
|
||||||
await fs.mkdir(path.resolve(this.prefix, this.name), {recursive: true})
|
await fs.mkdir(path.resolve(this.path, this.name), {recursive: true})
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
logger.warn('Extension already installed at', path.resolve(this.prefix, this.name))
|
logger.error('Extension already installed at', path.resolve(this.path, this.name))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
public async uninstall(): Promise<void>{
|
public async uninstall(): Promise<void>{
|
||||||
logger.info('Uninstalling extension from', path.resolve(this.prefix, this.name))
|
logger.info('Uninstalling extension from', path.resolve(this.path, this.name))
|
||||||
return await trash(path.resolve(this.prefix, this.name))
|
return await trash(path.resolve(this.path, this.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
public async update(force?: boolean): Promise<boolean | undefined>{
|
public async update(force?: boolean): Promise<boolean | undefined>{
|
||||||
@@ -117,17 +117,17 @@ export abstract class FSExtension<Status extends FSStatus> extends Extension<Sta
|
|||||||
public async isEmpty(): Promise<boolean | undefined>{
|
public async isEmpty(): Promise<boolean | undefined>{
|
||||||
if (!this.isInstalled()) return true
|
if (!this.isInstalled()) return true
|
||||||
try {
|
try {
|
||||||
const files = await fs.readdir(path.resolve(this.prefix, this.name))
|
const files = await fs.readdir(path.resolve(this.path, this.name))
|
||||||
return files.length === 0
|
return files.length === 0
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.warn('TODO')
|
logger.error("fs read error", error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async isInstalled(): Promise<boolean>{
|
public async isInstalled(): Promise<boolean>{
|
||||||
try {
|
try {
|
||||||
await fs.access(path.resolve(this.prefix, this.name))
|
await fs.access(path.resolve(this.path, this.name))
|
||||||
return true
|
return true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return false
|
return false
|
||||||
@@ -139,14 +139,18 @@ type NPMStatus = FSStatus & {
|
|||||||
latest?: string,
|
latest?: string,
|
||||||
current?: string,
|
current?: string,
|
||||||
author?: string
|
author?: string
|
||||||
|
license?: string,
|
||||||
|
description?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NPMExtension extends FSExtension<NPMStatus>{
|
export class NPMExtension extends FSExtension<NPMStatus>{
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
pkgName: string,
|
pkgName: string,
|
||||||
prefix: string){
|
private version: string,
|
||||||
super(pkgName, prefix)
|
private prefix: string
|
||||||
|
){
|
||||||
|
super(pkgName, path.resolve(prefix, "node_modules"))
|
||||||
}
|
}
|
||||||
|
|
||||||
public async status(): Promise<NPMStatus> {
|
public async status(): Promise<NPMStatus> {
|
||||||
@@ -155,23 +159,28 @@ export class NPMExtension extends FSExtension<NPMStatus>{
|
|||||||
const latest = await this.getLatestVersion()
|
const latest = await this.getLatestVersion()
|
||||||
const author = await this.getAuthor()
|
const author = await this.getAuthor()
|
||||||
const current = await this.getCurrentVersion()
|
const current = await this.getCurrentVersion()
|
||||||
|
const license = await this.getLicense()
|
||||||
|
const description = await this.getDescription()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...fsStatus,
|
...fsStatus,
|
||||||
latest: latest,
|
latest: latest,
|
||||||
author: author,
|
author: author,
|
||||||
current: current
|
current: current,
|
||||||
|
license: license,
|
||||||
|
description: description
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async install(): Promise<boolean> {
|
public async install(): Promise<boolean> {
|
||||||
super.install()
|
super.install()
|
||||||
logger.info("npm install", this.name, 'to', path.resolve(this.prefix, this.name))
|
logger.info("npm install", this.name, 'to', path.resolve(this.prefix, this.name))
|
||||||
const { error, stdout, stderr } = await exec('npm install --prefix '+ this.prefix + ' ' + this.name)
|
const { error, stdout, stderr } = await exec('npm install --prefix '+ this.prefix + ' ' + this.name+"@"+this.version)
|
||||||
if (error !== null) {
|
if (error) {
|
||||||
logger.warn('npm install', this.name, 'from prefix', this.prefix, 'stderr:', stderr)
|
logger.error('npm install', this.name, "@", this.version, ' from prefix', this.prefix, 'stderr:', stderr)
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
logger.info('npm install', this.name, 'from prefix', this.prefix, 'stdout:', stdout)
|
logger.info('npm install', this.name, "@", this.version, 'from prefix', this.prefix, 'stdout:', stdout)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,7 +190,7 @@ export class NPMExtension extends FSExtension<NPMStatus>{
|
|||||||
logger.info("npm uninstall", this.name, 'from', path.resolve(this.prefix, this.name))
|
logger.info("npm uninstall", this.name, 'from', path.resolve(this.prefix, this.name))
|
||||||
const { error, stdout, stderr } = await exec('npm uninstall --prefix '+ this.prefix + ' ' + this.name)
|
const { error, stdout, stderr } = await exec('npm uninstall --prefix '+ this.prefix + ' ' + this.name)
|
||||||
if (error) {
|
if (error) {
|
||||||
logger.warn('npm uninstall', this.name, 'from prefix', this.prefix, 'stderr:', stderr)
|
logger.error('npm uninstall', this.name, 'from prefix', this.prefix, 'stderr:', stderr)
|
||||||
} else {
|
} else {
|
||||||
logger.info('npm uninstall', this.name, 'from prefix', this.prefix, 'stdout:', stdout)
|
logger.info('npm uninstall', this.name, 'from prefix', this.prefix, 'stdout:', stdout)
|
||||||
}
|
}
|
||||||
@@ -192,7 +201,7 @@ export class NPMExtension extends FSExtension<NPMStatus>{
|
|||||||
logger.info("npm update", path.resolve(this.prefix, this.name))
|
logger.info("npm update", path.resolve(this.prefix, this.name))
|
||||||
const { error, stdout, stderr } = await exec('npm update --prefix '+ this.prefix + ' ' + this.name)
|
const { error, stdout, stderr } = await exec('npm update --prefix '+ this.prefix + ' ' + this.name)
|
||||||
if (error) {
|
if (error) {
|
||||||
logger.warn('npm update', this.name, 'from prefix', this.prefix, 'stderr:', stderr)
|
logger.error('npm update', this.name, 'from prefix', this.prefix, 'stderr:', stderr)
|
||||||
return false
|
return false
|
||||||
} else {
|
} else {
|
||||||
logger.info('npm update', this.name, 'from prefix', this.prefix, 'stdout:', stdout)
|
logger.info('npm update', this.name, 'from prefix', this.prefix, 'stdout:', stdout)
|
||||||
@@ -210,7 +219,7 @@ export class NPMExtension extends FSExtension<NPMStatus>{
|
|||||||
if (Object.keys(JSON.parse(stdout)).length > 0) return true
|
if (Object.keys(JSON.parse(stdout)).length > 0) return true
|
||||||
else return false
|
else return false
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.warn('npm outdated', this.name, 'from prefix', this.prefix, 'stderr:', error)
|
logger.error('npm outdated', this.name, 'from prefix', this.prefix, 'stderr:', error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -222,7 +231,7 @@ export class NPMExtension extends FSExtension<NPMStatus>{
|
|||||||
stderr } = await exec('npm author ls --prefix ' + this.prefix + ' ' + this.name)
|
stderr } = await exec('npm author ls --prefix ' + this.prefix + ' ' + this.name)
|
||||||
|
|
||||||
if(error){
|
if(error){
|
||||||
logger.warn(stderr)
|
logger.error(stderr)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
logger.info(stdout)
|
logger.info(stdout)
|
||||||
@@ -231,22 +240,84 @@ export class NPMExtension extends FSExtension<NPMStatus>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async getLatestVersion(): Promise<string | undefined>{
|
private async getLatestVersion(): Promise<string | undefined>{
|
||||||
|
try{
|
||||||
const {
|
const {
|
||||||
error,
|
error,
|
||||||
stdout,
|
stdout,
|
||||||
stderr } = await exec('npm view --prefix ' + this.prefix + ' ' + this.name + " version")
|
stderr } = await exec('npm view --prefix ' + this.prefix + ' ' + this.name + " version")
|
||||||
|
|
||||||
if(error){
|
if(error){
|
||||||
logger.warn(stderr)
|
logger.error(stderr)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
logger.info(stdout)
|
logger.info(stdout)
|
||||||
return stdout
|
return stdout
|
||||||
}
|
}
|
||||||
|
}catch(error){
|
||||||
|
logger.error(error)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getCurrentVersion(): Promise<string | undefined>{
|
private async getCurrentVersion(): Promise<string | undefined>{
|
||||||
return //TODO
|
try{
|
||||||
|
const {
|
||||||
|
error,
|
||||||
|
stdout,
|
||||||
|
stderr } = await exec('npm list --json --prefix ' + this.prefix + ' ' + this.name)
|
||||||
|
|
||||||
|
if(error){
|
||||||
|
logger.error(stderr)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
logger.info(stdout)
|
||||||
|
return JSON.parse(stdout)['dependencies'][this.name]['version']
|
||||||
|
}
|
||||||
|
}catch(error){
|
||||||
|
logger.error(error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getDescription(): Promise<string | undefined>{
|
||||||
|
try{
|
||||||
|
const {
|
||||||
|
error,
|
||||||
|
stdout,
|
||||||
|
stderr } = await exec('npm show --prefix ' + this.prefix + ' ' + this.name+" description")
|
||||||
|
|
||||||
|
if(error){
|
||||||
|
logger.error(stderr)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
logger.info(stdout)
|
||||||
|
return stdout
|
||||||
|
}
|
||||||
|
}catch(error){
|
||||||
|
logger.error(error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getLicense(): Promise<string | undefined>{
|
||||||
|
try{
|
||||||
|
|
||||||
|
const {
|
||||||
|
error,
|
||||||
|
stdout,
|
||||||
|
stderr } = await exec('npm show --prefix ' + this.prefix + ' ' + this.name+" license")
|
||||||
|
|
||||||
|
if(error){
|
||||||
|
logger.error(stderr)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
logger.info(stdout)
|
||||||
|
return stdout
|
||||||
|
}
|
||||||
|
}catch(error){
|
||||||
|
logger.error(error)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,6 +359,7 @@ export class GitExtension<Status extends GitStatus> extends FSExtension<Status>{
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import * as Logger from 'log4js'
|
import * as Logger from 'log4js'
|
||||||
import * as Knex from 'knex'
|
import * as Knex from 'knex'
|
||||||
import { FrontblockApiClient } from 'frontblock';
|
import { FrontblockApiClient, FrontblockApiConf } from 'frontblock';
|
||||||
import { socketioRPC, rpcHooker, ExtendedRpcInfo } from 'frontblock-generic/RPC';
|
import { socketioRPC, rpcHooker, ExtendedRpcInfo } from 'frontblock-generic/RPC';
|
||||||
import { ApiClientBase, AdminBase } from 'frontblock-generic/Admin';
|
import { ApiClientBase, AdminBase } from 'frontblock-generic/Admin';
|
||||||
import express = require('express');
|
import express = require('express');
|
||||||
@@ -11,7 +11,7 @@ import bsock = require('bsock');
|
|||||||
import { promises as fs } from "fs"
|
import { promises as fs } from "fs"
|
||||||
import * as path from "path"
|
import * as path from "path"
|
||||||
import { UpdateManager } from './UpdateManger';
|
import { UpdateManager } from './UpdateManger';
|
||||||
import { FrontblockApiConf, FrontblockApi } from 'frontblock-generic/Api';
|
import { FrontblockApi } from 'frontblock-generic/Api';
|
||||||
import { Plugin } from 'frontblock-generic/Plugin';
|
import { Plugin } from 'frontblock-generic/Plugin';
|
||||||
var exec = require('child-process-promise').exec;
|
var exec = require('child-process-promise').exec;
|
||||||
|
|
||||||
|
|||||||
+15
-12
@@ -3,15 +3,9 @@ import { socketioRPC } from "frontblock-generic/RPC";
|
|||||||
import { GitUpdater, RepoFolderStatus } from "./GitUpdater";
|
import { GitUpdater, RepoFolderStatus } from "./GitUpdater";
|
||||||
import { FrontblockCherryPicker } from "git-cherrypicker";
|
import { FrontblockCherryPicker } from "git-cherrypicker";
|
||||||
import * as Logger from 'log4js'
|
import * as Logger from 'log4js'
|
||||||
import * as path from "path";
|
|
||||||
import * as rmrf from "rimraf"
|
|
||||||
import { FrontblockAdmin } from "./FrontblockAdmin";
|
import { FrontblockAdmin } from "./FrontblockAdmin";
|
||||||
|
import { NPMExtension } from "./Extension";
|
||||||
import { TableDefiniton } from "frontblock-generic/Admin";
|
import { TableDefiniton } from "frontblock-generic/Admin";
|
||||||
import { promises as fs, mkdirSync as mkdir } from "fs"
|
|
||||||
import { version } from "punycode";
|
|
||||||
import * as git from "simple-git/promise"
|
|
||||||
import * as trash from "trash"
|
|
||||||
import { type } from "os";
|
|
||||||
|
|
||||||
var exec = require('child-process-promise').exec;
|
var exec = require('child-process-promise').exec;
|
||||||
|
|
||||||
@@ -30,6 +24,7 @@ const logger = Logger.getLogger("admin/updatemanager")
|
|||||||
|
|
||||||
export class UpdateManager extends Plugin{
|
export class UpdateManager extends Plugin{
|
||||||
|
|
||||||
|
|
||||||
private loadedPlugins:{[name in string]:Plugin} = {}
|
private loadedPlugins:{[name in string]:Plugin} = {}
|
||||||
private dashboardUpdater:GitUpdater
|
private dashboardUpdater:GitUpdater
|
||||||
private adminUpdater:GitUpdater
|
private adminUpdater:GitUpdater
|
||||||
@@ -46,7 +41,7 @@ export class UpdateManager extends Plugin{
|
|||||||
exportRPCs(): socketioRPC[] {
|
exportRPCs(): socketioRPC[] {
|
||||||
return [{
|
return [{
|
||||||
name: 'installPlugin',
|
name: 'installPlugin',
|
||||||
func: async (name:string, force = false) => {return await this.installPlugin(name, force)},
|
func: async (name:string, force = false) => { },
|
||||||
type: 'call',
|
type: 'call',
|
||||||
visibility: 'private'
|
visibility: 'private'
|
||||||
},{
|
},{
|
||||||
@@ -90,10 +85,18 @@ export class UpdateManager extends Plugin{
|
|||||||
logger.warn(res.stderr)
|
logger.warn(res.stderr)
|
||||||
logger.info(res.stdout)
|
logger.info(res.stdout)
|
||||||
*/
|
*/
|
||||||
await Promise.all([
|
|
||||||
new NPMExtension("knex@0.19.2", "./plugins").install(),
|
const extensions = [
|
||||||
new NPMExtension("sqlite3@4.1.0", "./plugins").install()
|
new NPMExtension("knex", "0.19.2", "./plugins"),
|
||||||
])
|
new NPMExtension("sqlite3", "4.1.0", "./plugins"),
|
||||||
|
new NPMExtension("frontblock", "latest", "./plugins")
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
await Promise.all(extensions.map(e => e.install()))
|
||||||
|
const status = await Promise.all(extensions.map(e => e.status()))
|
||||||
|
console.log(status)
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateAdmin(force:boolean = false){
|
async updateAdmin(force:boolean = false){
|
||||||
|
|||||||
Reference in New Issue
Block a user