mirror of
https://github.com/lxsang/antos-frontend.git
synced 2024-12-26 17:38:20 +01:00
Improvement on core API:
- improvement performance of some VFS utility API - Allow compress/extract zip file in Files - CodePad/Files/MarketPlace use some common system APIs instead of defining in-package functions
This commit is contained in:
parent
e657c98688
commit
fd4474d598
Binary file not shown.
507
src/core/vfs.ts
507
src/core/vfs.ts
@ -1770,9 +1770,7 @@ namespace OS {
|
|||||||
* - array: the result will be an Array of bytes (numbers between 0 and 255).
|
* - array: the result will be an Array of bytes (numbers between 0 and 255).
|
||||||
* - uint8array : the result will be a Uint8Array. This requires a compatible browser.
|
* - uint8array : the result will be a Uint8Array. This requires a compatible browser.
|
||||||
* - arraybuffer : the result will be a ArrayBuffer. This requires a compatible browser.
|
* - arraybuffer : the result will be a ArrayBuffer. This requires a compatible browser.
|
||||||
* - blob : the result will be a Blob. This requires a compatible browser.
|
* - blob : the result will be a Blob. This requires a compatible browser. *
|
||||||
* - nodebuffer : the result will be a nodejs Buffer. This requires nodejs.
|
|
||||||
*
|
|
||||||
* If file_name is not specified, the first file_name in the zip archive will be read
|
* If file_name is not specified, the first file_name in the zip archive will be read
|
||||||
* @export
|
* @export
|
||||||
* @param {string} file zip file
|
* @param {string} file zip file
|
||||||
@ -1784,91 +1782,65 @@ namespace OS {
|
|||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
await API.requires("os://scripts/jszip.min.js");
|
await API.requires("os://scripts/jszip.min.js");
|
||||||
try {
|
const data = await file.asFileHandle().read("binary");
|
||||||
const data = await file.asFileHandle().read("binary");
|
const zip = await JSZip.loadAsync(data);
|
||||||
try {
|
if (!file_name) {
|
||||||
const zip = await JSZip.loadAsync(data);
|
for (let name in zip.files) {
|
||||||
if (!file_name) {
|
file_name = name;
|
||||||
for (let name in zip.files) {
|
break;
|
||||||
file_name = name;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const udata = await zip.file(file_name).async(type);
|
|
||||||
resolve(udata);
|
|
||||||
} catch (e_2) {
|
|
||||||
return reject(__e(e_2));
|
|
||||||
}
|
|
||||||
} catch (e_1) {
|
|
||||||
return reject(__e(e_1));
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
return reject(__e(e));
|
|
||||||
}
|
}
|
||||||
} catch (e_3) {
|
const udata = await zip.file(file_name).async(type);
|
||||||
return reject(__e(e_3));
|
resolve(udata);
|
||||||
|
} catch (e) {
|
||||||
|
return reject(__e(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cat al file to a single out-put
|
* Cat all files to a single out-put
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
* @param {string[]} list list of VFS files
|
* @param {string[]} list list of VFS files
|
||||||
* @param {string} data input data string that will be cat to the files content
|
* @param {string} data input data string that will be cat to the files content
|
||||||
|
* @param {string} join_by join on files content by this string
|
||||||
* @return {*} {Promise<string>}
|
* @return {*} {Promise<string>}
|
||||||
*/
|
*/
|
||||||
export function cat(list: string[], data: string): Promise<string> {
|
export function cat(list: string[], data: string, join_by: string = "\n"): Promise<string> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
if (list.length === 0) {
|
if (list.length === 0) {
|
||||||
return resolve(data);
|
return resolve(data);
|
||||||
}
|
}
|
||||||
const file = list.splice(0, 1)[0].asFileHandle();
|
const promises = [];
|
||||||
return file
|
for (const file of list) {
|
||||||
.read()
|
promises.push(file.asFileHandle().read("text"));
|
||||||
.then((text: string) => {
|
}
|
||||||
data = data + "\n" + text;
|
try {
|
||||||
return cat(list, data)
|
const results = await Promise.all(promises);
|
||||||
.then((d) => resolve(d))
|
resolve(`${data}${join_by}${results.join(join_by)}`);
|
||||||
.catch((e) => reject(__e(e)));
|
} catch (error) {
|
||||||
})
|
reject(__e(error));
|
||||||
.catch((e: Error) => reject(__e(e)));
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read all files content to on the list
|
* Read all files content on the list
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
* @param {string[]} list list of VFS files
|
* @param {string[]} list list of VFS files
|
||||||
* @param {GenericObject<string>[]} contents content array
|
* @param {GenericObject<string>[]} contents content array
|
||||||
* @return {*} {Promise<GenericObject<string>[]>}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
export function read_files(list: string[], contents: GenericObject<string>[]): Promise<GenericObject<string>[]> {
|
export function read_files(list: string[]): Promise<GenericObject<string>[]> {
|
||||||
return new Promise((resolve, reject) => {
|
const promises = [];
|
||||||
if (list.length === 0) {
|
for (const file of list) {
|
||||||
return resolve(contents);
|
promises.push(file.asFileHandle().read("text"));
|
||||||
}
|
}
|
||||||
const file = list.splice(0, 1)[0].asFileHandle();
|
return Promise.all(promises);
|
||||||
return file
|
|
||||||
.read()
|
|
||||||
.then((text: string) => {
|
|
||||||
contents.push({
|
|
||||||
path: file.path,
|
|
||||||
content: text
|
|
||||||
});
|
|
||||||
return read_files(list, contents)
|
|
||||||
.then((d) => resolve(d))
|
|
||||||
.catch((e) => reject(__e(e)));
|
|
||||||
})
|
|
||||||
.catch((e: Error) => reject(__e(e)));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1878,71 +1850,45 @@ namespace OS {
|
|||||||
* @export
|
* @export
|
||||||
* @param {string[]} files list of files
|
* @param {string[]} files list of files
|
||||||
* @param {string} to destination folder
|
* @param {string} to destination folder
|
||||||
* @return {*} {Promise<void>}
|
* @return {*} {Promise<any[]>}
|
||||||
*/
|
*/
|
||||||
export function copy(files: string[], to: string): Promise<void> {
|
export function copy(files: string[], to: string): Promise<any[]> {
|
||||||
return new Promise((resolve, reject) => {
|
const promises = [];
|
||||||
if (files.length === 0) {
|
for (const path of files) {
|
||||||
return resolve();
|
promises.push(new Promise(async (resolve, reject) => {
|
||||||
}
|
try {
|
||||||
const file = files.splice(0, 1)[0].asFileHandle();
|
const file = path.asFileHandle();
|
||||||
const tof = `${to}/${file.basename}`.asFileHandle();
|
const tof = `${to}/${file.basename}`.asFileHandle();
|
||||||
return file
|
const meta = await file.onready();
|
||||||
.onready()
|
|
||||||
.then((meta: { type: string }) => {
|
|
||||||
if (meta.type === "dir") {
|
if (meta.type === "dir") {
|
||||||
// copy directory
|
|
||||||
const desdir = to.asFileHandle();
|
const desdir = to.asFileHandle();
|
||||||
return desdir
|
await desdir.mk(file.basename);
|
||||||
.mk(file.basename)
|
const ret = await file.read();
|
||||||
.then(() => {
|
const files = ret.result.map((v: API.FileInfoType) => v.path);
|
||||||
// read the dir content
|
if (files.length > 0) {
|
||||||
return file
|
await copy(files, `${desdir.path}/${file.basename}`);
|
||||||
.read()
|
resolve(undefined);
|
||||||
.then((data: API.RequestResult) => {
|
}
|
||||||
const list = (data.result as API.FileInfoType[]).map(
|
else {
|
||||||
(v) => v.path
|
resolve(undefined);
|
||||||
);
|
}
|
||||||
return copy(
|
|
||||||
list,
|
|
||||||
`${desdir.path}/${file.basename}`
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
return copy(files, to)
|
|
||||||
.then(() => resolve())
|
|
||||||
.catch((e) =>
|
|
||||||
reject(__e(e))
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.catch((e) => reject(__e(e)));
|
|
||||||
})
|
|
||||||
.catch((e: Error) => reject(__e(e)));
|
|
||||||
})
|
|
||||||
.catch((e: Error) => reject(__e(e)));
|
|
||||||
} else {
|
|
||||||
// copy file
|
|
||||||
return file
|
|
||||||
.read("binary")
|
|
||||||
.then(async (data: ArrayBuffer) => {
|
|
||||||
const d = await tof
|
|
||||||
.setCache(
|
|
||||||
new Blob([data], {
|
|
||||||
type: file.info.mime,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
.write(file.info.mime);
|
|
||||||
try {
|
|
||||||
await copy(files, to);
|
|
||||||
return resolve();
|
|
||||||
} catch (e) {
|
|
||||||
return reject(__e(e));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((e: Error) => reject(__e(e)));
|
|
||||||
}
|
}
|
||||||
})
|
else {
|
||||||
.catch((e: Error) => reject(__e(e)));
|
const content = await file.read("binary");
|
||||||
});
|
await tof
|
||||||
|
.setCache(
|
||||||
|
new Blob([content], {
|
||||||
|
type: file.info.mime,
|
||||||
|
}))
|
||||||
|
.write(file.info.mime);
|
||||||
|
resolve(undefined);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
reject(__e(error));
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1954,69 +1900,38 @@ namespace OS {
|
|||||||
* @return {*} {Promise<any>}
|
* @return {*} {Promise<any>}
|
||||||
*/
|
*/
|
||||||
function aradd(list: string[], zip: any, base: string): Promise<any> {
|
function aradd(list: string[], zip: any, base: string): Promise<any> {
|
||||||
return new Promise((resolve, reject) => {
|
const promises = [];
|
||||||
if (list.length === 0) {
|
for (const path of list) {
|
||||||
return resolve(zip);
|
promises.push(new Promise(async (resolve, reject) => {
|
||||||
}
|
const file = path.asFileHandle();
|
||||||
const path = list.splice(0, 1)[0];
|
try {
|
||||||
const file = path.asFileHandle();
|
const meta = await file.asFileHandle().onready();
|
||||||
return file
|
if (meta.type == "dir") {
|
||||||
.onready()
|
const ret = await file.read();
|
||||||
.then((meta: { type: string }) => {
|
const dirs: string[] = ret.result.map((v: API.FileInfoType) => v.path);
|
||||||
if (meta.type === "dir") {
|
if (dirs.length > 0) {
|
||||||
return file
|
await aradd(dirs, zip, `${base}${file.basename}/`);
|
||||||
.read()
|
resolve(undefined);
|
||||||
.then(
|
}
|
||||||
(d: {
|
else {
|
||||||
result:
|
resolve(undefined);
|
||||||
| Iterable<unknown>
|
}
|
||||||
| ArrayLike<unknown>;
|
|
||||||
}) => {
|
|
||||||
const l = (d.result as API.FileInfoType[]).map(
|
|
||||||
(v) => v.path
|
|
||||||
);
|
|
||||||
return aradd(
|
|
||||||
l,
|
|
||||||
zip,
|
|
||||||
`${base}${file.basename}/`
|
|
||||||
)
|
|
||||||
.then(() => {
|
|
||||||
return aradd(
|
|
||||||
list,
|
|
||||||
zip,
|
|
||||||
base
|
|
||||||
)
|
|
||||||
.then(() => resolve(zip))
|
|
||||||
.catch((e) =>
|
|
||||||
reject(__e(e))
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.catch((e) => reject(__e(e)));
|
|
||||||
}
|
|
||||||
)
|
|
||||||
.catch((e: Error) => reject(__e(e)));
|
|
||||||
} else {
|
|
||||||
return file
|
|
||||||
.read("binary")
|
|
||||||
.then(async (d: any) => {
|
|
||||||
const zpath = `${base}${file.basename}`.replace(
|
|
||||||
/^\/+|\/+$/g,
|
|
||||||
""
|
|
||||||
);
|
|
||||||
zip.file(zpath, d, { binary: true });
|
|
||||||
try {
|
|
||||||
await aradd(list, zip, base);
|
|
||||||
return resolve(zip);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return reject(__e(e));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((e: Error) => reject(__e(e)));
|
|
||||||
}
|
}
|
||||||
})
|
else {
|
||||||
.catch((e: Error) => reject(__e(e)));
|
const u_data = await file.read("binary");
|
||||||
});
|
const z_path = `${base}${file.basename}`.replace(
|
||||||
|
/^\/+|\/+$/g,
|
||||||
|
""
|
||||||
|
);
|
||||||
|
zip.file(z_path, u_data, { binary: true });
|
||||||
|
resolve(undefined);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
reject(__e(error));
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2024,57 +1939,36 @@ namespace OS {
|
|||||||
* Create a zip archive from a folder
|
* Create a zip archive from a folder
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
* @param {string} src source folder
|
* @param {string} src source file/folder
|
||||||
* @param {string} dest destination archive
|
* @param {string} dest destination archive
|
||||||
* @return {*} {Promise<void>}
|
* @return {*} {Promise<void>}
|
||||||
*/
|
*/
|
||||||
export function mkar(src: string, dest: string): Promise<void> {
|
export function mkar(src: string, dest: string): Promise<void> {
|
||||||
return new Promise((resolve, reject) => {
|
console.log(src, dest);
|
||||||
return new Promise(async (r, e) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
await API.requires("os://scripts/jszip.min.js");
|
await API.requires("os://scripts/jszip.min.js");
|
||||||
try {
|
const zip = new JSZip();
|
||||||
const d = await src.asFileHandle().read();
|
const fhd = src.asFileHandle();
|
||||||
return r(d.result);
|
const meta = await fhd.onready();
|
||||||
} catch (ex) {
|
if(meta.type === "file")
|
||||||
return e(__e(ex));
|
{
|
||||||
}
|
await aradd([src], zip, "/");
|
||||||
} catch (ex_1) {
|
|
||||||
return e(__e(ex_1));
|
|
||||||
}
|
}
|
||||||
})
|
else
|
||||||
.then((files: API.FileInfoType[]) => {
|
{
|
||||||
return new Promise(async (r, e) => {
|
const ret = await fhd.read();
|
||||||
const zip = new JSZip();
|
await aradd(
|
||||||
try {
|
ret.result.map((v: API.FileInfoType) => v.path), zip, "/");
|
||||||
const z = await aradd(
|
}
|
||||||
files.map((v: { path: any }) => v.path),
|
const z_data = await zip.generateAsync({ type: "base64" });
|
||||||
zip,
|
await dest.asFileHandle()
|
||||||
"/"
|
.setCache("data:application/zip;base64," + z_data)
|
||||||
);
|
.write("base64");
|
||||||
return r(z);
|
resolve();
|
||||||
} catch (ex) {
|
} catch (error) {
|
||||||
return e(__e(ex));
|
reject(__e(error));
|
||||||
}
|
}
|
||||||
});
|
|
||||||
})
|
|
||||||
.then((zip: any) => {
|
|
||||||
return zip
|
|
||||||
.generateAsync({ type: "base64" })
|
|
||||||
.then((data: string) => {
|
|
||||||
return dest
|
|
||||||
.asFileHandle()
|
|
||||||
.setCache(
|
|
||||||
"data:application/zip;base64," + data
|
|
||||||
)
|
|
||||||
.write("base64")
|
|
||||||
.then((r: any) => {
|
|
||||||
resolve();
|
|
||||||
})
|
|
||||||
.catch((e: Error) => reject(__e(e)));
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((e) => reject(__e(e)));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2083,35 +1977,105 @@ namespace OS {
|
|||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
* @param {string[]} list of directories to be created
|
* @param {string[]} list of directories to be created
|
||||||
* @return {*} {Promise<void>}
|
* @param {boolen} sync sync/async of directory creation
|
||||||
|
* @return {*} {Promise<any>}
|
||||||
*/
|
*/
|
||||||
export function mkdirAll(list: string[]): Promise<void> {
|
export function mkdirAll(list: string[], sync?: boolean): Promise<any> {
|
||||||
return new Promise((resolve, reject) => {
|
if (!sync) {
|
||||||
if (list.length === 0) {
|
const promises = [];
|
||||||
return resolve();
|
for (const dir of list) {
|
||||||
|
const path = dir.asFileHandle()
|
||||||
|
promises.push(path.parent().mk(path.basename));
|
||||||
}
|
}
|
||||||
const path = list.splice(0, 1)[0].asFileHandle();
|
return Promise.all(promises);
|
||||||
return path
|
}
|
||||||
.parent()
|
else {
|
||||||
.mk(path.basename)
|
return new Promise(async (resolve, reject) => {
|
||||||
.then((d: any) => {
|
try {
|
||||||
return mkdirAll(list)
|
if (list.length === 0) {
|
||||||
.then(() => resolve())
|
return resolve(true);
|
||||||
.catch((e) => reject(__e(e)));
|
}
|
||||||
})
|
const dir = list.splice(0, 1)[0].asFileHandle();
|
||||||
.catch((e: Error) => reject(__e(e)));
|
const path = dir.parent();
|
||||||
});
|
const dname = dir.basename;
|
||||||
|
const r = await path.asFileHandle().mk(dname);
|
||||||
|
if (r.error) {
|
||||||
|
return reject(
|
||||||
|
this._api.throwe(
|
||||||
|
__(
|
||||||
|
"Cannot create {0}",
|
||||||
|
`${path}/${dir}`
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await mkdirAll(list, sync);
|
||||||
|
resolve(true);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
reject(__e(e));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
*
|
*
|
||||||
* @export
|
*
|
||||||
* @param {Array<string[]>} list of templates mapping files
|
* @export Extract a zip fle
|
||||||
* @param {string} path path stored create files
|
* @param {string} zfile zip file to extract
|
||||||
* @param {string} name
|
* @param {(zip:any) => Promise<string>} [dest_callback] a callback to get extraction destination
|
||||||
* @return {*} {Promise<void>}
|
* @return {*} {Promise<void>}
|
||||||
*/
|
*/
|
||||||
|
export function extractZip(zfile: string | API.VFS.BaseFileHandle, dest_callback: (zip: any) => Promise<string>): Promise<void> {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
try {
|
||||||
|
await API.requires("os://scripts/jszip.min.js");
|
||||||
|
const data = await zfile.asFileHandle().read("binary");
|
||||||
|
const zip = await JSZip.loadAsync(data);
|
||||||
|
const to = await dest_callback(zip);
|
||||||
|
const dirs = [];
|
||||||
|
const files = [];
|
||||||
|
for (const name in zip.files) {
|
||||||
|
const file = zip.files[name];
|
||||||
|
if (file.dir) {
|
||||||
|
dirs.push(to + "/" + name);
|
||||||
|
} else {
|
||||||
|
files.push(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await mkdirAll(dirs, true);
|
||||||
|
const promises = [];
|
||||||
|
for (const file of files) {
|
||||||
|
promises.push(new Promise(async (res, rej) => {
|
||||||
|
try {
|
||||||
|
const data = await zip.file(file).async("uint8array");
|
||||||
|
const path = `${to}/${file}`;
|
||||||
|
const fp = path.asFileHandle();
|
||||||
|
fp.cache = new Blob([data], { type: "octet/stream" });
|
||||||
|
const r = await fp.write("text/plain");
|
||||||
|
if (r.error) {
|
||||||
|
return rej(
|
||||||
|
API.throwe(
|
||||||
|
__("Cannot extract file to {0}", path)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return resolve(res(path));
|
||||||
|
} catch (error) {
|
||||||
|
rej(__e(error));
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
await Promise.all(promises);
|
||||||
|
resolve();
|
||||||
|
} catch (e) {
|
||||||
|
return reject(__e(e));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make files from a set of template files
|
* Make files from a set of template files
|
||||||
@ -2120,35 +2084,28 @@ namespace OS {
|
|||||||
* @param {Array<string[]>} list mapping paths between templates files and created files
|
* @param {Array<string[]>} list mapping paths between templates files and created files
|
||||||
* @param {string} path files destination
|
* @param {string} path files destination
|
||||||
* @param {(data: string) => string} callback: pre-processing files content before writing to destination files
|
* @param {(data: string) => string} callback: pre-processing files content before writing to destination files
|
||||||
* @return {*} {Promise<void>}
|
* @return {*} {Promise<any[]>}
|
||||||
*/
|
*/
|
||||||
export function mktpl(
|
export function mktpl(
|
||||||
list: Array<string[]>,
|
list: Array<string[]>,
|
||||||
path: string,
|
path: string,
|
||||||
callback: (data: string) => string
|
callback: (data: string) => string
|
||||||
): Promise<void> {
|
): Promise<any[]> {
|
||||||
return new Promise((resolve, reject) => {
|
const promises = [];
|
||||||
if (list.length === 0) {
|
for (const tpl of list) {
|
||||||
return resolve();
|
promises.push(new Promise(async (resolve, reject) => {
|
||||||
}
|
try {
|
||||||
const item = list.splice(0, 1)[0];
|
const data = await `${path}/${tpl[0]}`.asFileHandle().read();
|
||||||
return `${path}/${item[0]}`
|
const file = tpl[1].asFileHandle();
|
||||||
.asFileHandle()
|
file.setCache(callback(data));
|
||||||
.read()
|
await file.write("text/plain");
|
||||||
.then((data) => {
|
resolve(undefined);
|
||||||
const file = item[1].asFileHandle();
|
} catch (error) {
|
||||||
return file
|
reject(__e(error));
|
||||||
.setCache(callback(data))
|
}
|
||||||
.write("text/plain")
|
}));
|
||||||
.then(() => {
|
}
|
||||||
return mktpl(list, path, callback)
|
return Promise.all(promises);
|
||||||
.then(() => resolve())
|
|
||||||
.catch((e) => reject(__e(e)));
|
|
||||||
})
|
|
||||||
.catch((e: Error) => reject(__e(e)));
|
|
||||||
})
|
|
||||||
.catch((e) => reject(__e(e)));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,13 +89,9 @@ namespace OS {
|
|||||||
.then(async (meta) => {
|
.then(async (meta) => {
|
||||||
try {
|
try {
|
||||||
await this.build(meta, true);
|
await this.build(meta, true);
|
||||||
try {
|
await this.run(meta);
|
||||||
return this.run(meta);
|
|
||||||
} catch (e) {
|
|
||||||
return this.logger().error(__("Unable to run project: {0}", e.stack));
|
|
||||||
}
|
|
||||||
} catch (e_1) {
|
} catch (e_1) {
|
||||||
return this.logger().error(__("Unable to build project: {0}", e_1.stack));
|
return this.logger().error(__("Unable to build and run project: {0}", e_1.stack));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((e) => this.logger().error(__("Unable to read meta-data: {0}", e.stack)));
|
.catch((e) => this.logger().error(__("Unable to read meta-data: {0}", e.stack)));
|
||||||
@ -112,19 +108,13 @@ namespace OS {
|
|||||||
.then(async (meta) => {
|
.then(async (meta) => {
|
||||||
try {
|
try {
|
||||||
await this.build(meta, false);
|
await this.build(meta, false);
|
||||||
try {
|
await API.VFS.mkar(
|
||||||
return API.VFS.mkar(
|
`${meta.root}/build/debug`,
|
||||||
`${meta.root}/build/debug`,
|
`${meta.root}/build/release/${meta.name}.zip`
|
||||||
`${meta.root}/build/release/${meta.name}.zip`
|
);
|
||||||
);
|
this.logger().info(__("Archive generate at: {0}", `${meta.root}/build/release/${meta.name}.zip`));
|
||||||
} catch (e) {
|
|
||||||
return this.logger().error(
|
|
||||||
__("Unable to create package archive: {0}",
|
|
||||||
e.stack)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} catch (e_1) {
|
} catch (e_1) {
|
||||||
return this.logger().error(__("Unable to build project: {0}", e_1.stack));
|
return this.logger().error(__("Unable to release project: {0}", e_1.stack));
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((e) => this.logger().error(__("Unable to read meta-data: {0}", e.stack)));
|
.catch((e) => this.logger().error(__("Unable to read meta-data: {0}", e.stack)));
|
||||||
@ -253,54 +243,54 @@ namespace OS {
|
|||||||
const core_lib = "os://packages/CodePad/libs/corelib.d.ts";
|
const core_lib = "os://packages/CodePad/libs/corelib.d.ts";
|
||||||
try {
|
try {
|
||||||
await this.load_corelib(core_lib);
|
await this.load_corelib(core_lib);
|
||||||
const arr = [];
|
const arr = await API.VFS.read_files(files);
|
||||||
API.VFS.read_files(files, arr).then((_result) => {
|
const libs: string[] = files.map((e) => e)
|
||||||
const libs: string[] = arr.map((e) => e.path)
|
libs.unshift(core_lib);
|
||||||
libs.unshift(core_lib);
|
const src_files: GenericObject<any> = {};
|
||||||
const src_files: GenericObject<any> = {};
|
src_files[core_lib] = AntOSDK.corelib["ts"];
|
||||||
src_files[core_lib] = AntOSDK.corelib["ts"];
|
for (const i in arr) {
|
||||||
for (const el of arr) {
|
src_files[files[i]] = ts.createSourceFile(files[i], arr[i], ts.ScriptTarget.Latest);
|
||||||
src_files[el.path] = ts.createSourceFile(el.path, el.content, ts.ScriptTarget.Latest);
|
}
|
||||||
}
|
let js_code = "";
|
||||||
let js_code = "";
|
const host = {
|
||||||
const host = {
|
fileExists: (path: string) => {
|
||||||
fileExists: (path: string) => {
|
return src_files[path] != undefined;
|
||||||
return src_files[path] != undefined;
|
},
|
||||||
},
|
directoryExists: (path: string) => {
|
||||||
directoryExists: (path: string) => {
|
return true;
|
||||||
return true;
|
},
|
||||||
},
|
getCurrentDirectory: () => "/",
|
||||||
getCurrentDirectory: () => "/",
|
getDirectories: () => [],
|
||||||
getDirectories: () => [],
|
getCanonicalFileName: (path: string) => path,
|
||||||
getCanonicalFileName: (path: string) => path,
|
getNewLine: () => "\n",
|
||||||
getNewLine: () => "\n",
|
getDefaultLibFileName: () => "",
|
||||||
getDefaultLibFileName: () => "",
|
getSourceFile: (path: string) => src_files[path],
|
||||||
getSourceFile: (path: string) => src_files[path],
|
readFile: (path: string) => undefined,
|
||||||
readFile: (path: string) => undefined,
|
useCaseSensitiveFileNames: () => true,
|
||||||
useCaseSensitiveFileNames: () => true,
|
writeFile: (path: string, data: string) => js_code = `${js_code}\n${data}`,
|
||||||
writeFile: (path: string, data: string) => js_code = `${js_code}\n${data}`,
|
};
|
||||||
};
|
const program = ts.createProgram(libs, {
|
||||||
const program = ts.createProgram(libs, {
|
"target": "es6",
|
||||||
"target": "es6",
|
"skipLibCheck": true,
|
||||||
"skipLibCheck": true,
|
}, host);
|
||||||
}, host);
|
const result = program.emit();
|
||||||
const result = program.emit();
|
const diagnostics = result.diagnostics.concat((ts.getPreEmitDiagnostics(program)));
|
||||||
const diagnostics = result.diagnostics.concat((ts.getPreEmitDiagnostics(program)));
|
if (diagnostics.length > 0) {
|
||||||
if (diagnostics.length > 0) {
|
diagnostics.forEach(diagnostic => {
|
||||||
diagnostics.forEach(diagnostic => {
|
if (diagnostic.file) {
|
||||||
if (diagnostic.file) {
|
let { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start!);
|
||||||
let { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start!);
|
let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
||||||
let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
this.logger().error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
||||||
this.logger().error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`);
|
} else {
|
||||||
} else {
|
this.logger().error(ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"));
|
||||||
this.logger().error(ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"));
|
}
|
||||||
}
|
});
|
||||||
});
|
return reject(API.throwe(__("Typescript compile error")));
|
||||||
return reject(API.throwe(__("Typescript compile error")));
|
}
|
||||||
}
|
for (const file of files) {
|
||||||
resolve(js_code);
|
this.logger().info(__("Compiled: {0}", file));
|
||||||
})
|
}
|
||||||
.catch((e) => { reject(__e(e)) });
|
resolve(js_code);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return reject(__e(e));
|
return reject(__e(e));
|
||||||
}
|
}
|
||||||
@ -331,12 +321,12 @@ namespace OS {
|
|||||||
const ts_list = meta.ts.map(
|
const ts_list = meta.ts.map(
|
||||||
(v: string) => `${meta.root.trimBy("/")}/${v}`
|
(v: string) => `${meta.root.trimBy("/")}/${v}`
|
||||||
);
|
);
|
||||||
Promise.all([
|
const results = await Promise.all([
|
||||||
this.compile_ts(ts_list),
|
this.compile_ts(ts_list),
|
||||||
this.compile_coffee(coffee_list)
|
this.compile_coffee(coffee_list)
|
||||||
]).then((js_codes: string[]) => {
|
]);
|
||||||
resolve(js_codes.join("\n"));
|
|
||||||
}).catch((e_1) => reject(__e(e_1)));
|
resolve(results.join("\n"));
|
||||||
} catch (e_2) {
|
} catch (e_2) {
|
||||||
return reject(__e(e_2));
|
return reject(__e(e_2));
|
||||||
}
|
}
|
||||||
@ -358,14 +348,12 @@ namespace OS {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await this.verify_coffee(list.map((x: string) => x));
|
await this.verify_coffee(list.map((x: string) => x));
|
||||||
try {
|
const code = await API.VFS.cat(list, "");
|
||||||
const code = await API.VFS.cat(list, "");
|
const jsrc = CoffeeScript.compile(code);
|
||||||
const jsrc = CoffeeScript.compile(code);
|
for (const file of list) {
|
||||||
this.logger().info(__("Compiled successful"));
|
this.logger().info(__("Compiled: {0}", file));
|
||||||
return resolve(jsrc);
|
|
||||||
} catch (e) {
|
|
||||||
return reject(__e(e));
|
|
||||||
}
|
}
|
||||||
|
return resolve(jsrc);
|
||||||
} catch (e_1) {
|
} catch (e_1) {
|
||||||
return reject(__e(e_1));
|
return reject(__e(e_1));
|
||||||
}
|
}
|
||||||
@ -382,109 +370,54 @@ namespace OS {
|
|||||||
* @memberof AntOSDK
|
* @memberof AntOSDK
|
||||||
*/
|
*/
|
||||||
private build(meta: GenericObject<any>, debug: boolean): Promise<void> {
|
private build(meta: GenericObject<any>, debug: boolean): Promise<void> {
|
||||||
const dirs = [
|
|
||||||
`${meta.root}/build`,
|
|
||||||
`${meta.root}/build/debug`,
|
|
||||||
`${meta.root}/build/release`,
|
|
||||||
];
|
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
await API.VFS.mkdirAll(dirs);
|
this.logger().info(__("Building the package", meta.name));
|
||||||
try {
|
await API.VFS.mkdirAll([`${meta.root}/build`,]);
|
||||||
const src = await this.compile(meta);
|
await API.VFS.mkdirAll([`${meta.root}/build/debug`, `${meta.root}/build/release`]);
|
||||||
let v: string;
|
const src = await this.compile(meta);
|
||||||
try {
|
let code = await API.VFS.cat(meta.javascripts.map(v => `${meta.root}/${v}`), src);
|
||||||
let jsrc = await API.VFS.cat(
|
if (!debug) {
|
||||||
(() => {
|
const options = {
|
||||||
const result = [];
|
toplevel: true,
|
||||||
for (v of meta.javascripts) {
|
compress: {
|
||||||
result.push(`${meta.root}/${v}`);
|
passes: 3,
|
||||||
}
|
},
|
||||||
return result;
|
mangle: true,
|
||||||
})(),
|
output: {
|
||||||
src
|
//beautify: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const result = Terser.minify(code, options);
|
||||||
|
if (result.error) {
|
||||||
|
this.logger().error(
|
||||||
|
__(
|
||||||
|
"Unable to minify code: {0}",
|
||||||
|
result.error
|
||||||
|
)
|
||||||
);
|
);
|
||||||
await new Promise<void>(async function (r, e) {
|
} else {
|
||||||
let code = jsrc;
|
code = result.code;
|
||||||
if (!debug) {
|
|
||||||
const options = {
|
|
||||||
toplevel: true,
|
|
||||||
compress: {
|
|
||||||
passes: 3,
|
|
||||||
},
|
|
||||||
mangle: true,
|
|
||||||
output: {
|
|
||||||
//beautify: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const result_1 = Terser.minify(
|
|
||||||
jsrc,
|
|
||||||
options
|
|
||||||
);
|
|
||||||
if (result_1.error) {
|
|
||||||
this.logger().error(
|
|
||||||
__(
|
|
||||||
"Unable to minify code: {0}",
|
|
||||||
result_1.error
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
({ code } = result_1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const d = await `${meta.root}/build/debug/main.js`
|
|
||||||
.asFileHandle()
|
|
||||||
.setCache(code)
|
|
||||||
.write("text/plain");
|
|
||||||
return r();
|
|
||||||
} catch (ex) {
|
|
||||||
return e(__e(ex));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
await new Promise<void>(async (r, e) => {
|
|
||||||
const txt = await API.VFS.cat(
|
|
||||||
(() => {
|
|
||||||
const result1 = [];
|
|
||||||
for (v of meta.css) {
|
|
||||||
result1.push(`${meta.root}/${v}`);
|
|
||||||
}
|
|
||||||
return result1;
|
|
||||||
})(),
|
|
||||||
""
|
|
||||||
);
|
|
||||||
if (txt === "") {
|
|
||||||
return r();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const d_1 = await `${meta.root}/build/debug/main.css`
|
|
||||||
.asFileHandle()
|
|
||||||
.setCache(txt)
|
|
||||||
.write("text/plain");
|
|
||||||
return r();
|
|
||||||
} catch (ex_1) {
|
|
||||||
return e(__e(ex_1));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
await API.VFS.copy(
|
|
||||||
(() => {
|
|
||||||
const result1_1 = [];
|
|
||||||
for (v of meta.copies) {
|
|
||||||
result1_1.push(`${meta.root}/${v}`);
|
|
||||||
}
|
|
||||||
return result1_1;
|
|
||||||
})(),
|
|
||||||
`${meta.root}/build/debug`
|
|
||||||
);
|
|
||||||
return resolve();
|
|
||||||
} catch (e) {
|
|
||||||
return reject(__e(e));
|
|
||||||
}
|
}
|
||||||
} catch (e_1) {
|
|
||||||
return reject(__e(e_1));
|
|
||||||
}
|
}
|
||||||
} catch (e_2) {
|
if (code != "")
|
||||||
return reject(__e(e_2));
|
await `${meta.root}/build/debug/main.js`
|
||||||
|
.asFileHandle()
|
||||||
|
.setCache(code)
|
||||||
|
.write("text/plain");
|
||||||
|
const txt = await API.VFS.cat(meta.css.map(v => `${meta.root}/${v}`), "");
|
||||||
|
if (txt != "")
|
||||||
|
await `${meta.root}/build/debug/main.css`
|
||||||
|
.asFileHandle()
|
||||||
|
.setCache(txt)
|
||||||
|
.write("text/plain");
|
||||||
|
await API.VFS.copy(
|
||||||
|
meta.copies.map(v => `${meta.root}/${v}`),
|
||||||
|
`${meta.root}/build/debug`
|
||||||
|
);
|
||||||
|
resolve();
|
||||||
|
} catch (e) {
|
||||||
|
return reject(__e(e));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -87,8 +87,7 @@ namespace OS {
|
|||||||
iconclass: v.iconclass,
|
iconclass: v.iconclass,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
let ctx_menu = [
|
||||||
m.items = [
|
|
||||||
{
|
{
|
||||||
text: "__(Open with)",
|
text: "__(Open with)",
|
||||||
nodes: apps,
|
nodes: apps,
|
||||||
@ -103,6 +102,75 @@ namespace OS {
|
|||||||
this.mnFile(),
|
this.mnFile(),
|
||||||
this.mnEdit(),
|
this.mnEdit(),
|
||||||
];
|
];
|
||||||
|
if(file.mime === "application/zip")
|
||||||
|
{
|
||||||
|
ctx_menu = ctx_menu.concat([
|
||||||
|
{
|
||||||
|
text: "__(Extract Here)",
|
||||||
|
onmenuselect: (e: GUI.TagEventType<GUI.tag.MenuEventData>) => {
|
||||||
|
if (!e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
API.VFS.extractZip(file.path,
|
||||||
|
(z) => new Promise((r,e) => r(file.path.asFileHandle().parent().path)))
|
||||||
|
.catch((err) => this.error(__("Unable to extract file"), err));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "__(Extract to)",
|
||||||
|
onmenuselect: async (e: GUI.TagEventType<GUI.tag.MenuEventData>) => {
|
||||||
|
if (!e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
OS.GUI.dialogs.FileDialog.last_opened = this.currdir.path;
|
||||||
|
const d = await this.openDialog("FileDialog", {
|
||||||
|
title: __("Select extract destination"),
|
||||||
|
type: "dir",
|
||||||
|
file: file.path.replace(".zip","").asFileHandle()
|
||||||
|
});
|
||||||
|
const path = `${d.file.path}/${d.name}`;
|
||||||
|
await API.VFS.mkdirAll([path]);
|
||||||
|
await API.VFS.extractZip(file.path,
|
||||||
|
(z) => new Promise((r,e) => r(path)));
|
||||||
|
} catch (error) {
|
||||||
|
this.error(__("Unable to extract file"), error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ctx_menu.push(
|
||||||
|
{
|
||||||
|
text: "__(Compress)",
|
||||||
|
onmenuselect: async (e: GUI.TagEventType<GUI.tag.MenuEventData>) => {
|
||||||
|
if (!e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
OS.GUI.dialogs.FileDialog.last_opened = this.currdir.path;
|
||||||
|
const d = await this.openDialog("FileDialog", {
|
||||||
|
title: __("Save compressed file to"),
|
||||||
|
type: "dir",
|
||||||
|
file: `${this.currdir.path}/${file.name}.zip`.asFileHandle()
|
||||||
|
});
|
||||||
|
if(d.name.trim() === "")
|
||||||
|
{
|
||||||
|
return this.error(__("Invalid file name"));
|
||||||
|
}
|
||||||
|
const path = `${d.file.path}/${d.name}`;
|
||||||
|
await API.VFS.mkar(file.path, path);
|
||||||
|
this.notify(__("Archive file created: {0}",path ));
|
||||||
|
} catch (error) {
|
||||||
|
this.error(__("Unable to compress file, folder"), error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
m.items = ctx_menu;
|
||||||
m.show(e);
|
m.show(e);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -546,7 +614,7 @@ namespace OS {
|
|||||||
return this.notify(__("File {0} cut", file.filename));
|
return this.notify(__("File {0} cut", file.filename));
|
||||||
|
|
||||||
case `${this.name}-copy`:
|
case `${this.name}-copy`:
|
||||||
if (!file && file.type !== "dir") {
|
if (!file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.clipboard = {
|
this.clipboard = {
|
||||||
@ -579,30 +647,12 @@ namespace OS {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.clipboard.file
|
API.VFS.copy([this.clipboard.file.path],this.currdir.path)
|
||||||
.read("binary")
|
.then(() => {
|
||||||
.then(async (d) => {
|
return (this.clipboard = undefined);
|
||||||
const blob = new Blob([d], {
|
|
||||||
type: this.clipboard.file.info.mime,
|
|
||||||
});
|
|
||||||
const fp = `${this.currdir.path}/${this.clipboard.file.basename}`.asFileHandle();
|
|
||||||
fp.cache = blob;
|
|
||||||
try {
|
|
||||||
const r = await fp.write(this.clipboard.file.info.mime);
|
|
||||||
return (this.clipboard = undefined);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return this.error(__("Fail to paste: {0}", this.clipboard.file.path), e);
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
return this.error(
|
return this.error(__("Fail to paste: {0}", this.clipboard.file.path), e);
|
||||||
__(
|
|
||||||
"Fail to read: {0}",
|
|
||||||
this.clipboard.file.path
|
|
||||||
),
|
|
||||||
e
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
"author": "Xuan Sang LE",
|
"author": "Xuan Sang LE",
|
||||||
"email": "xsang.le@gmail.com"
|
"email": "xsang.le@gmail.com"
|
||||||
},
|
},
|
||||||
"version":"0.1.2-a",
|
"version":"0.1.3-a",
|
||||||
"category":"System",
|
"category":"System",
|
||||||
"iconclass":"fa fa-hdd-o",
|
"iconclass":"fa fa-hdd-o",
|
||||||
"mimes":["dir"],
|
"mimes":["dir"],
|
||||||
|
@ -68,19 +68,15 @@ namespace OS {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.btinstall.onbtclick = async () => {
|
this.btinstall.onbtclick = async () => {
|
||||||
if (this.btinstall.data.dirty) {
|
try {
|
||||||
try {
|
if (this.btinstall.data.dirty) {
|
||||||
await this.updatePackage();
|
await this.updatePackage();
|
||||||
return this.notify(__("Package updated"));
|
return this.notify(__("Package updated"));
|
||||||
} catch (e) {
|
|
||||||
return this.error(e.toString(), e);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
try {
|
|
||||||
const n = await this.remoteInstall();
|
const n = await this.remoteInstall();
|
||||||
return this.notify(__("Package installed: {0}", n));
|
return this.notify(__("Package installed: {0}", n));
|
||||||
} catch (e_1) {
|
} catch (error) {
|
||||||
return this.error(e_1.toString(), e_1);
|
return this.error(error.toString(), error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -466,40 +462,19 @@ namespace OS {
|
|||||||
return reject(this._api.throwe(__("Unable to find package: {0}", pkgname)));
|
return reject(this._api.throwe(__("Unable to find package: {0}", pkgname)));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const data = await this._api.blob(
|
const n = await this.install(meta.download + "?_=" + new Date().getTime(), meta);
|
||||||
meta.download + "?_=" + new Date().getTime()
|
return resolve(meta);
|
||||||
);
|
|
||||||
try {
|
|
||||||
const n = await this.install(data, meta);
|
|
||||||
return resolve(meta);
|
|
||||||
} catch (e) {
|
|
||||||
return reject(__e(e));
|
|
||||||
}
|
|
||||||
} catch (e_1) {
|
} catch (e_1) {
|
||||||
return reject(__e(e_1));
|
return reject(__e(e_1));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
private bulkInstall(list: string[]): Promise<any> {
|
private bulkInstall(list: string[]): Promise<any> {
|
||||||
return new Promise((resolve, reject) => {
|
const promises = [];
|
||||||
if (list.length == 0) {
|
for (let pkgname of list) {
|
||||||
return resolve(true);
|
promises.push(this.installPkg(pkgname));
|
||||||
}
|
}
|
||||||
const pkgname = list.splice(0, 1)[0];
|
return Promise.all(promises);
|
||||||
this.installPkg(pkgname)
|
|
||||||
.then((_meta) => {
|
|
||||||
this.bulkInstall(list)
|
|
||||||
.then((b) => {
|
|
||||||
resolve(b);
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
reject(e);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
reject(err);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
private remoteInstall(): Promise<string> {
|
private remoteInstall(): Promise<string> {
|
||||||
const el = this.applist.selectedItem;
|
const el = this.applist.selectedItem;
|
||||||
@ -512,175 +487,130 @@ namespace OS {
|
|||||||
}
|
}
|
||||||
// get blob file
|
// get blob file
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
let pkgname = `${el.data.pkgname}@${el.data.version}`;
|
try {
|
||||||
const dep = this.checkDependencies(pkgname);
|
let pkgname = `${el.data.pkgname}@${el.data.version}`;
|
||||||
if (dep.notfound.size != 0) {
|
const dep = this.checkDependencies(pkgname);
|
||||||
return this.openDialog("TextDialog", {
|
if (dep.notfound.size != 0) {
|
||||||
disable: true,
|
this.openDialog("TextDialog", {
|
||||||
title: __("Unresolved dependencies"),
|
disable: true,
|
||||||
value: __(
|
title: __("Unresolved dependencies"),
|
||||||
"Unable to install: The package `{0}` depends on these packages, but they are not found:\n{1}",
|
value: __(
|
||||||
pkgname,
|
"Unable to install: The package `{0}` depends on these packages, but they are not found:\n{1}",
|
||||||
[...dep.notfound].join("\n")
|
pkgname,
|
||||||
)
|
[...dep.notfound].join("\n")
|
||||||
})
|
)
|
||||||
.then((_v) => {
|
|
||||||
reject(__("Unresolved dependencies on: {0}", pkgname))
|
|
||||||
});
|
});
|
||||||
|
return reject(__("Unresolved dependencies on: {0}", pkgname));
|
||||||
|
}
|
||||||
|
const t = await this.openDialog("TextDialog", {
|
||||||
|
title: __("Confirm install"),
|
||||||
|
disable: true,
|
||||||
|
value: __(
|
||||||
|
"Please confirm the following operation:\n\n{0} packages will be removed:\n\n{1}\n\n{2} packages will be installed:\n\n{3}",
|
||||||
|
dep.uninstall.size.toString(),
|
||||||
|
[...dep.uninstall].join("\n"),
|
||||||
|
dep.install.size.toString(),
|
||||||
|
[...dep.install].join("\n")
|
||||||
|
)
|
||||||
|
});
|
||||||
|
if (!t) return;
|
||||||
|
await this.bulkUninstall([...dep.uninstall]);
|
||||||
|
const metas = await this.bulkInstall([...dep.install]);
|
||||||
|
this.appDetail(metas.pop());
|
||||||
|
resolve(pkgname);
|
||||||
|
} catch (error) {
|
||||||
|
reject(__e(error));
|
||||||
}
|
}
|
||||||
this.openDialog("TextDialog", {
|
|
||||||
title: __("Confirm install"),
|
|
||||||
disable: true,
|
|
||||||
value: __(
|
|
||||||
"Please confirm the following operation:\n\n{0} packages will be removed:\n\n{1}\n\n{2} packages will be installed:\n\n{3}",
|
|
||||||
dep.uninstall.size.toString(),
|
|
||||||
[...dep.uninstall].join("\n"),
|
|
||||||
dep.install.size.toString(),
|
|
||||||
[...dep.install].join("\n")
|
|
||||||
)
|
|
||||||
}).then((_v) => {
|
|
||||||
this.bulkUninstall([...dep.uninstall])
|
|
||||||
.then((_b) => {
|
|
||||||
this.bulkInstall([...dep.install])
|
|
||||||
.then((_b1) => {
|
|
||||||
resolve(pkgname);
|
|
||||||
})
|
|
||||||
.catch((e1) => {
|
|
||||||
reject(e1);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch((e2) => {
|
|
||||||
reject(e2);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private localInstall(): Promise<string> {
|
private localInstall(): Promise<string> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
return this.openDialog("FileDialog", {
|
try {
|
||||||
title: "__(Select package archive)",
|
const d = await this.openDialog("FileDialog", {
|
||||||
mimes: [".*/zip"],
|
title: "__(Select package archive)",
|
||||||
}).then((d) => {
|
mimes: [".*/zip"],
|
||||||
return d.file.path
|
});
|
||||||
.asFileHandle()
|
const n = await this.install(d.file.path);
|
||||||
.read("binary")
|
const apps = this.applist.data.map(
|
||||||
.then((data: Uint8Array) => {
|
(v) => v.pkgname
|
||||||
return this.install(data)
|
);
|
||||||
.then((n) => {
|
const idx = apps.indexOf(n);
|
||||||
const apps = this.applist.data.map(
|
if (idx >= 0) {
|
||||||
(v) => v.pkgname
|
this.applist.selected = idx;
|
||||||
);
|
}
|
||||||
const idx = apps.indexOf(n);
|
return resolve(n.name);
|
||||||
if (idx >= 0) {
|
} catch (error) {
|
||||||
this.applist.selected = idx;
|
reject(__e(error));
|
||||||
}
|
}
|
||||||
return resolve(n);
|
|
||||||
})
|
|
||||||
.catch((e: Error) => reject(__e(e)))
|
|
||||||
.catch((e: Error) => reject(__e(e)));
|
|
||||||
})
|
|
||||||
.catch((e: Error) => reject(__e(e)));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private install(
|
private install(
|
||||||
data: ArrayBuffer,
|
zfile: string,
|
||||||
meta?: GenericObject<any>
|
meta?: GenericObject<any>
|
||||||
): Promise<string> {
|
): Promise<GenericObject<any>> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
return JSZip.loadAsync(data)
|
try {
|
||||||
.then((zip: any) => {
|
let v: API.PackageMetaType;
|
||||||
return zip
|
let pth: string = "";
|
||||||
.file("package.json")
|
await API.VFS.extractZip(zfile, (zip) => {
|
||||||
.async("string")
|
return new Promise(async (res, rej) => {
|
||||||
.then((d: string) => {
|
try {
|
||||||
let name: string;
|
const d = await zip.file("package.json").async("string");
|
||||||
const v = JSON.parse(d);
|
v = JSON.parse(d);
|
||||||
const pth = `${this.installdir}/${v.pkgname ? v.pkgname : v.app}`;
|
pth = `${this.installdir}/${v.pkgname ? v.pkgname : v.app}`;
|
||||||
const dir = [pth];
|
await API.VFS.mkdirAll([pth]);
|
||||||
const files = [];
|
res(pth);
|
||||||
for (name in zip.files) {
|
} catch (error) {
|
||||||
const file = zip.files[name];
|
rej(__e(error))
|
||||||
if (file.dir) {
|
}
|
||||||
dir.push(pth + "/" + name);
|
});
|
||||||
} else {
|
|
||||||
files.push(name);
|
});
|
||||||
}
|
const app_meta = {
|
||||||
}
|
pkgname: v.pkgname ? v.pkgname : v.app,
|
||||||
// create all directory
|
name: v.name,
|
||||||
return this.mkdirs(dir)
|
text: v.name,
|
||||||
.then(() => {
|
icon: v.icon,
|
||||||
return this.installFile(
|
iconclass: v.iconclass,
|
||||||
v.pkgname ? v.pkgname : v.app,
|
category: v.category,
|
||||||
zip,
|
author: v.info.author,
|
||||||
files
|
version: v.version,
|
||||||
)
|
description: meta
|
||||||
.then(() => {
|
? meta.description
|
||||||
const app_meta = {
|
: undefined,
|
||||||
pkgname: v.pkgname ? v.pkgname : v.app,
|
download: meta
|
||||||
name: v.name,
|
? meta.download
|
||||||
text: v.name,
|
: undefined,
|
||||||
icon: v.icon,
|
};
|
||||||
iconclass: v.iconclass,
|
v.text = v.name;
|
||||||
category: v.category,
|
v.filename = v.pkgname ? v.pkgname : v.app;
|
||||||
author: v.info.author,
|
v.type = "app";
|
||||||
version: v.version,
|
v.mime = "antos/app";
|
||||||
description: meta
|
if (
|
||||||
? meta.description
|
!v.iconclass &&
|
||||||
: undefined,
|
!v.icon
|
||||||
download: meta
|
) {
|
||||||
? meta.download
|
v.iconclass =
|
||||||
: undefined,
|
"fa fa-adn";
|
||||||
};
|
}
|
||||||
v.text = v.name;
|
v.path = pth;
|
||||||
v.filename = v.pkgname ? v.pkgname : v.app;
|
this.systemsetting.system.packages[
|
||||||
v.type = "app";
|
v.pkgname ? v.pkgname : v.app
|
||||||
v.mime = "antos/app";
|
] = v;
|
||||||
if (
|
return resolve(app_meta);
|
||||||
!v.iconclass &&
|
} catch (error) {
|
||||||
!v.icon
|
reject(__e(error));
|
||||||
) {
|
}
|
||||||
v.iconclass =
|
|
||||||
"fa fa-adn";
|
|
||||||
}
|
|
||||||
v.path = pth;
|
|
||||||
this.systemsetting.system.packages[
|
|
||||||
v.pkgname ? v.pkgname : v.app
|
|
||||||
] = v;
|
|
||||||
this.appDetail(app_meta);
|
|
||||||
return resolve(v.name);
|
|
||||||
})
|
|
||||||
.catch((e) => reject(__e(e)));
|
|
||||||
})
|
|
||||||
.catch((e) => reject(__e(e)));
|
|
||||||
})
|
|
||||||
.catch((err: Error) => reject(__e(err)));
|
|
||||||
})
|
|
||||||
.catch((e: Error) => reject(__e(e)));
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
private bulkUninstall(list: string[]): Promise<any> {
|
private bulkUninstall(list: string[]): Promise<any> {
|
||||||
return new Promise(async (resolve, reject) => {
|
const promises = [];
|
||||||
if (list.length == 0) {
|
for (let pkgname of list) {
|
||||||
return resolve(true);
|
promises.push(this.uninstallPkg(pkgname));
|
||||||
}
|
}
|
||||||
const pkgname = list.splice(0, 1)[0];
|
return Promise.all(promises);
|
||||||
this.uninstallPkg(pkgname)
|
|
||||||
.then((_meta) => {
|
|
||||||
this.bulkUninstall(list)
|
|
||||||
.then((b) => {
|
|
||||||
resolve(b);
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
reject(e);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
reject(err);
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
private uninstallPkg(pkgname: string): Promise<any> {
|
private uninstallPkg(pkgname: string): Promise<any> {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
@ -782,90 +712,20 @@ namespace OS {
|
|||||||
}
|
}
|
||||||
const meta = this.apps_meta[`${sel.pkgname}@${app.version}`];
|
const meta = this.apps_meta[`${sel.pkgname}@${app.version}`];
|
||||||
await this.remoteInstall();
|
await this.remoteInstall();
|
||||||
try {
|
if (meta) {
|
||||||
if (meta) {
|
if (meta.domel)
|
||||||
if (meta.domel)
|
this.applist.delete(meta.domel);
|
||||||
this.applist.delete(meta.domel);
|
|
||||||
}
|
|
||||||
return resolve(true);
|
|
||||||
}
|
}
|
||||||
catch (e) {
|
return resolve(true);
|
||||||
return reject(__e(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (e_1) {
|
catch (e_1) {
|
||||||
return reject(__e(e_1));
|
return reject(__e(e_1));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private mkdirs(list: string[]): Promise<any> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (list.length === 0) {
|
|
||||||
return resolve(true);
|
|
||||||
}
|
|
||||||
const dir = list.splice(0, 1)[0].asFileHandle();
|
|
||||||
const path = dir.parent();
|
|
||||||
const dname = dir.basename;
|
|
||||||
return path
|
|
||||||
.asFileHandle()
|
|
||||||
.mk(dname)
|
|
||||||
.then((r) => {
|
|
||||||
if (r.error) {
|
|
||||||
return reject(
|
|
||||||
this._api.throwe(
|
|
||||||
__(
|
|
||||||
"Cannot create {0}",
|
|
||||||
`${path}/${dir}`
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return this.mkdirs(list)
|
|
||||||
.then(() => resolve(true))
|
|
||||||
.catch((e) => reject(__e(e)));
|
|
||||||
})
|
|
||||||
.catch((e) => reject(__e(e)));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private installFile(n: string, zip: any, files: string[]): Promise<any> {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
if (files.length === 0) {
|
|
||||||
return resolve(true);
|
|
||||||
}
|
|
||||||
const file = files.splice(0, 1)[0];
|
|
||||||
const path = `${this.installdir}/${n}/${file}`;
|
|
||||||
return zip
|
|
||||||
.file(file)
|
|
||||||
.async("uint8array")
|
|
||||||
.then((d: Uint8Array) => {
|
|
||||||
const fp = path.asFileHandle();
|
|
||||||
fp.cache = new Blob([d], { type: "octet/stream" });
|
|
||||||
return fp
|
|
||||||
.write("text/plain")
|
|
||||||
.then((r) => {
|
|
||||||
if (r.error) {
|
|
||||||
return reject(
|
|
||||||
this._api.throwe(
|
|
||||||
__("Cannot install {0}", path)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return this.installFile(n, zip, files)
|
|
||||||
.then(() => resolve(true))
|
|
||||||
.catch((e) => reject(__e(e)));
|
|
||||||
})
|
|
||||||
.catch((e) => reject(__e(e)));
|
|
||||||
})
|
|
||||||
.catch((e: Error) => reject(__e(e)));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MarketPlace.dependencies = [
|
MarketPlace.dependencies = [
|
||||||
"os://scripts/jszip.min.js",
|
|
||||||
"os://scripts/showdown.min.js",
|
"os://scripts/showdown.min.js",
|
||||||
];
|
];
|
||||||
MarketPlace.singleton = true;
|
MarketPlace.singleton = true;
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"app":"MarketPlace",
|
"app":"MarketPlace",
|
||||||
"name":"Application store",
|
"name":"AntOS Application store",
|
||||||
"description":"Application store",
|
"description":"Application store",
|
||||||
"info":{
|
"info":{
|
||||||
"author": "Xuan Sang LE",
|
"author": "Xuan Sang LE",
|
||||||
"email": "xsang.le@gmail.com"
|
"email": "xsang.le@gmail.com"
|
||||||
},
|
},
|
||||||
"version":"0.2.2-a",
|
"version":"0.2.3-a",
|
||||||
"category":"System",
|
"category":"System",
|
||||||
"iconclass":"fa fa-shopping-bag",
|
"iconclass":"fa fa-shopping-bag",
|
||||||
"mimes":["none"],
|
"mimes":["none"],
|
||||||
|
Loading…
Reference in New Issue
Block a user