xshell 0.0.9 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/extension.js +12 -12
- package/extension.js.map +1 -1
- package/file.d.ts +39 -17
- package/file.js +57 -53
- package/file.js.map +1 -1
- package/index.js +5 -5
- package/index.js.map +1 -1
- package/net.d.ts +28 -19
- package/net.js +80 -70
- package/net.js.map +1 -1
- package/package.json +18 -24
- package/process.d.ts +17 -17
- package/process.js +61 -67
- package/process.js.map +1 -1
- package/prototype.d.ts +33 -22
- package/prototype.js +129 -107
- package/prototype.js.map +1 -1
- package/repl.d.ts +2 -5
- package/repl.js +86 -73
- package/repl.js.map +1 -1
- package/server.d.ts +11 -7
- package/server.js +116 -112
- package/server.js.map +1 -1
- package/tsconfig.json +18 -6
- package/ufs.d.ts +21 -0
- package/ufs.js +153 -0
- package/ufs.js.map +1 -0
- package/utils.d.ts +17 -10
- package/utils.js +87 -44
- package/utils.js.map +1 -1
- package/xshell.js +1 -1
- package/xshell.js.map +1 -1
package/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["server.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer as create_server } from 'http'\nimport type { Server as HttpServer, IncomingHttpHeaders } from 'http'\n\nimport zlib from 'zlib'\n\n// --- 3-rd party\nimport invoke from 'lodash/invoke'\nimport qs from 'qs'\n\n\n// --- Koa & Koa Middleware\nimport Koa from 'koa'\nimport type { Context, Next } from 'koa'\n\nimport KoaCors from '@koa/cors'\nimport KoaCompress from 'koa-compress'\nimport { userAgent as KoaUserAgent } from 'koa-useragent'\n\n\ndeclare module 'koa' {\n interface Request {\n _path: string\n body: any\n }\n \n interface Context {\n compress: boolean\n }\n}\n\n// --- My Lib\nimport { request as _request } from './net'\nimport { stream_to_buffer, delay, log_section, inspect } from './utils'\n\n\ndeclare module 'http' {\n interface IncomingMessage {\n tunnel?: boolean\n id?: string\n body?: Buffer\n }\n \n interface ServerResponse {\n body?: Buffer\n }\n}\n\ninterface Message {\n id: string\n headers: IncomingHttpHeaders\n body: {\n buffer: Buffer\n }\n}\n\n// ------------ CONSTs\nexport const LOCALHOST_IPS = new Set(['127.0.0.1', '::ffff:127.0.0.1', '::1'])\nexport const ROUTER_IP = '192.168.1.1'\nexport const PHONE_IP = '192.168.1.113'\nexport const KNOWN_IPS = new Set([...LOCALHOST_IPS, ROUTER_IP, PHONE_IP])\n\n\n// ------------ MyServer\nexport const server = {\n app: null as Koa,\n \n handler: null as ReturnType<Koa['callback']>,\n \n server_80: null as HttpServer,\n \n \n /** start http server and listen */\n async start () {\n let app = new Koa()\n app.on('error', (error, ctx) => {\n console.error(error)\n console.log(ctx)\n })\n \n app.use(this.entry.bind(this))\n \n app.use(KoaCompress({\n br: {\n // https://nodejs.org/api/zlib.html#zlib_class_brotlioptions\n params: {\n [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT,\n [zlib.constants.BROTLI_PARAM_QUALITY]: 6 // default 11 (maximized compression), may lead to news/get generated 14MB JSON taking 24s\n },\n },\n threshold: 512\n }))\n \n app.use(KoaCors({ credentials: true }))\n app.use(KoaUserAgent)\n \n app.use(this.router.bind(this))\n \n this.app = app\n \n await this.listen()\n },\n \n \n async listen () {\n this.handler = this.app.callback()\n this.server_80 = create_server(this.handler)\n \n await Promise.all([\n new Promise<void>( resolve => { this.server_80.listen(8421, resolve) }),\n ])\n },\n \n \n stop () {\n this.server_80.close()\n },\n \n \n async entry (ctx: Context, next: Next) {\n const { req: { tunnel, id }, res } = ctx\n let { req, request } = ctx\n \n if (!tunnel) {\n const buf = await stream_to_buffer(req)\n if (buf.length)\n req.body = buf\n }\n \n // ------------ parse req.body to request.body\n if (req.body)\n if (ctx.is('application/json') || ctx.is('text/plain'))\n request.body = JSON.parse(req.body.toString())\n else if (ctx.is('application/x-www-form-urlencoded'))\n request.body = qs.parse(req.body.toString())\n else if (ctx.is('multipart/form-data')) {\n throw new Error('multipart/form-data is not supported')\n } else\n request.body = req.body\n \n \n // ------------ parse request.ip\n request.ip = (request.headers['x-real-ip'] as string || request.ip).replace(/^::ffff:/, '')\n \n \n // ------------ next\n await next()\n // ------------ post processing\n },\n \n \n \n async router (ctx: Context, next: Next) {\n let { request, response } = ctx\n request.path\n request._path = decodeURIComponent(request.path)\n Object.defineProperty(request, 'path', {\n value: request._path,\n configurable: true,\n enumerable: true,\n writable: true\n })\n \n const { path } = request\n \n // ------------ RPC\n if (path === '/api/rpc') {\n await this.rpc(ctx)\n return\n }\n \n \n // ------------ log\n this.logger(ctx)\n \n await next?.()\n },\n \n \n /** args are array http://127.0.0.1/repl/rpc?func=to_json&args=aaa&args=bbb \n should use POST when arg is number, otherwise type will be string \n queries:\n - func: function name\n - args?: `[]` args array\n - async?: `false` don't wait\n - ignore?: `false` don't serialize result into response\n */\n async rpc (ctx: Context) {\n const { request: { query, body }, response } = ctx\n \n let { func, args = [], ignore = false, async: _async = false }: { func: string, args: any[] | string, ignore: boolean | string, async: boolean | string } = { ...query, ...body }\n \n if (!func) throw new Error('rpc no func')\n \n if (!Array.isArray(args))\n args = [args]\n \n // ?async=1 or ?async=0 or ?async=false\n if (typeof ignore === 'string')\n ignore = ignore.to_bool()\n \n if (typeof _async === 'string')\n _async = _async.to_bool()\n \n try {\n const presult = invoke(global, func, ...args)\n \n if (_async) {\n response.body = ''\n return\n }\n \n const result = await presult\n \n if (ignore) {\n response.body = ''\n return\n }\n \n response.body = JSON.stringify(result) || ''\n } catch (error) {\n response.status = 500\n response.body = error\n throw error\n }\n },\n \n \n logger (ctx: Context) {\n const { request } = ctx\n const { query, body, path, method, req: { httpVersion, tunnel }, ip } = request\n \n const known = KNOWN_IPS.has(ip)\n const ua = ctx.userAgent\n \n let s = ''\n \n // --- time\n s += new Date().to_time_str() + ' '\n \n \n let t: string\n // --- IP 50\n if (known)\n if (LOCALHOST_IPS.has(ip))\n t = ''\n else if (ip === ROUTER_IP)\n t = 'Router'.grey\n else if (ip === PHONE_IP)\n t = 'Phone'\n else\n t = ip\n else\n t = ip\n \n s += t.pad(50) + ' '\n \n \n // --- UA\n t = ''\n if (!known) {\n if (ua.isMobile)\n t += ' Mobile'.magenta\n if (ua.isBot)\n t += ' Robot'.blue\n if (ua.isDesktop)\n t += ' Desktop'\n if (ua.platform !== 'unknown' && !ua.os.startsWith('Windows'))\n t += '/' + ua.platform\n if (ua.os !== 'unknown' && ua.platform !== 'Android')\n t += '/' + ua.os\n if (ua.browser !== 'unknown')\n t += '/' + ua.browser\n if (ua.version !== 'unknown')\n t += '/' + ua.version\n }\n s += t.pad(50) + ' '\n \n \n // --- Tunnel/HTTP version\n s += tunnel ? \n ('Tunnel/' + httpVersion).pad(10).cyan\n :\n ('HTTP/' + httpVersion).pad(10)\n \n s += ' '\n \n \n // --- Method 8\n if (method === 'GET')\n t = method\n else\n t = method.red\n \n s += t.pad(8)\n \n \n // --- Path 60\n if (path.toLowerCase() !== request._path.toLowerCase())\n t = request._path.blue + ' → ' + path\n else\n if (!path.includes('.'))\n t = path.yellow\n else\n t = path\n \n s += t.pad(60) + ' '\n \n \n // --- Query\n if (query && Object.keys(query).length) {\n t = ` ${inspect(query, { compact: true }).replace('[Object: null prototype] ', '')}`\n if ((s + t).width > global.WIDTH)\n s += '\\n'\n s += t\n }\n \n \n // --- Body\n if (body && Object.keys(body).length)\n s += '\\n' + inspect(body).replace('[Object: null prototype] ', '')\n \n \n console.log(s)\n },\n}\n\n\nexport default server\n\nexport type Server = typeof server\n"]}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["server.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer as http_create_server } from 'http'\nimport type { Server as HttpServer, IncomingHttpHeaders } from 'http'\n\nimport zlib from 'zlib'\n\n// --- 3rd party\nimport invoke from 'lodash/invoke'\nimport qs from 'qs'\n\n\n// --- koa & koa middleware\nimport Koa from 'koa'\nimport type { Context, Next } from 'koa'\n\nimport KoaCors from '@koa/cors'\nimport KoaCompress from 'koa-compress'\nimport { userAgent as KoaUserAgent } from 'koa-useragent'\nimport type { UserAgentContext } from 'koa-useragent'\n\n\ndeclare module 'koa' {\n interface Request {\n _path: string\n body: any\n }\n \n interface Context {\n compress: boolean\n userAgent: UserAgentContext['userAgent'] & { isWechat: boolean }\n }\n}\n\n// --- my libs\nimport { request as _request } from './net'\nimport { stream_to_buffer, inspect } from './utils'\nimport { output_width } from './utils'\n\n\ndeclare module 'http' {\n interface IncomingMessage {\n tunnel?: boolean\n id?: string\n body?: Buffer\n }\n \n interface ServerResponse {\n body?: Buffer\n }\n}\n\ninterface Message {\n id: string\n headers: IncomingHttpHeaders\n body: {\n buffer: Buffer\n }\n}\n\n// ------------ my server\nexport const server = {\n app: null as Koa,\n \n handler: null as ReturnType<Koa['callback']>,\n \n server_80: null as HttpServer,\n \n \n /** start http server and listen */\n async start () {\n // --- init koa app\n let app = new Koa()\n \n app.on('error', (error, ctx) => {\n console.error(error)\n console.log(ctx)\n })\n \n app.use(\n this.entry.bind(this)\n )\n \n app.use(KoaCompress({\n br: {\n // https://nodejs.org/api/zlib.html#zlib_class_brotlioptions\n params: {\n [zlib.constants.BROTLI_PARAM_MODE]: zlib.constants.BROTLI_MODE_TEXT,\n [zlib.constants.BROTLI_PARAM_QUALITY]: 6 // default 11 (maximized compression), may lead to news/get generated 14mb json taking 24s\n },\n },\n threshold: 512\n }))\n \n app.use(\n KoaCors({ credentials: true })\n )\n app.use(KoaUserAgent)\n \n app.use(this.router.bind(this))\n \n this.app = app\n \n this.handler = this.app.callback()\n \n this.server_80 = http_create_server(this.handler)\n \n await new Promise<void>(resolve => {\n this.server_80.listen(8421, resolve)\n })\n },\n \n \n stop () {\n this.server_80.close()\n },\n \n \n async entry (ctx: Context, next: Next) {\n let { response } = ctx\n \n await this.parse(ctx)\n \n // ------------ next\n try {\n await next()\n } catch (error) {\n if (error.status !== 404)\n console.error(error)\n response.status = error.status || 500\n response.body = inspect(error, { colors: false })\n response.type = 'text/plain'\n }\n },\n \n \n /** \n parse req.body to request.body \n process request.ip\n */\n async parse (ctx: Context) {\n const {\n request,\n req,\n req: { tunnel },\n } = ctx\n \n if (!tunnel) {\n const buf = await stream_to_buffer(req)\n if (buf.length)\n req.body = buf\n }\n \n // --- parse request.ip\n request.ip = (request.headers['x-real-ip'] as string || request.ip).replace(/^::ffff:/, '')\n \n \n // --- parse body\n if (!req.body) return\n \n if (ctx.is('application/json') || ctx.is('text/plain'))\n request.body = JSON.parse(req.body.toString())\n else if (ctx.is('application/x-www-form-urlencoded'))\n request.body = qs.parse(req.body.toString())\n else if (ctx.is('multipart/form-data')) {\n throw new Error('multipart/form-data is not supported')\n } else\n request.body = req.body\n },\n \n \n async router (ctx: Context, next: Next) {\n let { request } = ctx\n const _path = request._path = decodeURIComponent(request.path)\n Object.defineProperty(request, 'path', {\n value: _path,\n configurable: true,\n enumerable: true,\n writable: true\n })\n \n const { path } = request\n \n // ------------ /repl/rpc\n if (path === '/api/rpc') {\n await this.rpc(ctx)\n return\n }\n \n \n // ------------ log\n this.logger(ctx)\n \n // ------------ repl_router hook\n if (await global.repl_router?.(ctx))\n return\n \n await next?.()\n },\n \n \n /** args are array http://localhost/repl/rpc?func=to_json&args=aaa&args=bbb \n should use POST when arg is number, otherwise type will be string \n queries:\n - func: function name\n - args?: `[]` args array\n - ignore?: `false` don't serialize result into response\n - async?: `false` don't wait\n */\n async rpc (ctx: Context) {\n const { request: { query, body }, response } = ctx\n \n let { func, args = [], ignore = false, async: _async = false }: { func: string, args: any[] | string, ignore: boolean | string, async: boolean | string } = { ...query, ...body }\n \n if (!func) {\n let error = new Error('rpc no func')\n ;(error as any).status = 400\n throw error\n }\n \n if (!Array.isArray(args))\n args = [args]\n \n // ?async=1 or ?async=0 or ?async=false\n if (typeof ignore === 'string')\n ignore = ignore.to_bool()\n \n if (typeof _async === 'string')\n _async = _async.to_bool()\n \n try {\n const presult = invoke(global, func, ...args)\n \n if (_async) {\n response.body = ''\n return\n }\n \n const result = await presult\n \n if (ignore) {\n response.body = ''\n return\n }\n \n response.body = JSON.stringify(result) || ''\n } catch (error) {\n error.status = 500\n throw error\n }\n },\n \n \n logger (ctx: Context) {\n const { request } = ctx\n const {\n query, \n body, \n path, _path, \n protocol,\n host,\n req: { httpVersion: http_version },\n ip,\n } = request\n \n let { method } = request\n \n const ua = ctx.userAgent\n \n \n let s = ''\n \n // --- time\n s += `${new Date().to_time_str()} `\n \n \n // --- ip\n s += (ip || '').pad(40) + ' '\n \n \n // --- ua\n s += (() => {\n let t = ''\n if (ua.isMobile)\n t += 'mobile'\n if (ua.isDesktop)\n t += 'desktop'\n if (ua.isBot)\n t += `${ t ? ' ' : '' }${'robot'.blue}`\n if (ua.platform !== 'unknown' && !ua.os.startsWith('Windows'))\n t += '/' + ua.platform.toLowerCase().replace('apple mac', 'mac')\n if (ua.os !== 'unknown' && ua.platform !== 'Android')\n t += '/' + ua.os.toLowerCase()\n if (ua.browser !== 'unknown')\n t += '/' + ua.browser.toLowerCase()\n if (ua.isWechat)\n t += '/weixin'\n if (ua.version !== 'unknown')\n t += '/' + ua.version.split('.').slice(0, 2).join('.')\n return t\n })().pad(40) + ' '\n \n \n // --- https/2.0\n // if (req.tunnel) `tunnel/${http_version}`.pad(10).cyan\n s += `${`${protocol.pad(5)}/${http_version}`.pad(10)} `\n \n \n // --- method\n method = method.toLowerCase()\n s += method === 'get' ? method.pad(10) : method.pad(10).yellow\n \n \n // --- host\n s += `${host.pad(20)} `\n \n \n // --- path\n s += (() => {\n if (path.toLowerCase() !== _path.toLowerCase())\n return `${_path.blue} → ${path}`\n if (!path.includes('.'))\n return path.yellow\n return path\n })()\n \n \n // --- query\n if (Object.keys(query).length) {\n let t = inspect(query, { compact: true })\n .replace('[Object: null prototype] ', '')\n \n if (t.endsWith('\\n'))\n t = t.slice(0, -1)\n \n s += (s + t).width > output_width ? '\\n' : ' '\n \n s += t\n }\n \n \n // --- body\n if (body && Object.keys(body).length)\n s += '\\n' + inspect(body).replace('[Object: null prototype] ', '')\n \n \n // --- print log\n console.log(s)\n },\n}\n\n\nexport default server\n\nexport type Server = typeof server\n"]}
|
package/tsconfig.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
-
// ---
|
|
3
|
+
// --- module
|
|
4
4
|
"module": "CommonJS", // none, CommonJS, amd, system, umd, es6, es2015, ESNext
|
|
5
5
|
"moduleResolution": "Node",
|
|
6
6
|
"allowSyntheticDefaultImports": true,
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"resolveJsonModule": true,
|
|
9
9
|
"isolatedModules": true,
|
|
10
10
|
|
|
11
|
-
// ---
|
|
11
|
+
// --- build
|
|
12
12
|
"target": "ES2019",
|
|
13
13
|
"allowJs": false,
|
|
14
14
|
"checkJs": false,
|
|
@@ -16,22 +16,23 @@
|
|
|
16
16
|
"newLine": "lf",
|
|
17
17
|
"lib": ["ESNext", "DOM"],
|
|
18
18
|
"importHelpers": true,
|
|
19
|
+
// "watch": false
|
|
19
20
|
"incremental": true,
|
|
20
21
|
"tsBuildInfoFile": "./node_modules/.tsbuildinfo",
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
// ---
|
|
24
|
+
// --- emit
|
|
24
25
|
"declaration": true,
|
|
25
26
|
"emitDeclarationOnly": false,
|
|
26
27
|
"noEmitOnError": false,
|
|
27
28
|
"listEmittedFiles": true,
|
|
28
29
|
|
|
29
|
-
// ---
|
|
30
|
+
// --- source maps
|
|
30
31
|
"sourceMap": true,
|
|
31
32
|
"inlineSourceMap": false,
|
|
32
33
|
"inlineSources": true,
|
|
33
34
|
|
|
34
|
-
// ---
|
|
35
|
+
// --- features
|
|
35
36
|
"experimentalDecorators": true,
|
|
36
37
|
"emitDecoratorMetadata": true,
|
|
37
38
|
"preserveSymlinks": true,
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
"forceConsistentCasingInFileNames": true,
|
|
42
43
|
|
|
43
44
|
|
|
44
|
-
// ---
|
|
45
|
+
// --- type checking
|
|
45
46
|
"strict": false,
|
|
46
47
|
"alwaysStrict": false,
|
|
47
48
|
"noImplicitAny": false,
|
|
@@ -51,6 +52,17 @@
|
|
|
51
52
|
"noUnusedLocals": false,
|
|
52
53
|
"noUnusedParameters": false,
|
|
53
54
|
"skipLibCheck": true,
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
"watchOptions": {
|
|
58
|
+
"excludeDirectories": [
|
|
59
|
+
"**/node_modules",
|
|
60
|
+
],
|
|
61
|
+
|
|
62
|
+
"watchFile": "useFsEvents",
|
|
63
|
+
"watchDirectory": "useFsEvents",
|
|
64
|
+
|
|
65
|
+
"fallbackPolling": "dynamicPriority"
|
|
54
66
|
}
|
|
55
67
|
}
|
|
56
68
|
|
package/ufs.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import type fs from 'fs';
|
|
3
|
+
import './prototype.js';
|
|
4
|
+
declare type FS = typeof fs;
|
|
5
|
+
export interface UFS extends FS {
|
|
6
|
+
}
|
|
7
|
+
export declare class UFS {
|
|
8
|
+
fss: FS[];
|
|
9
|
+
constructor(fss: any[]);
|
|
10
|
+
use(fs: any): this;
|
|
11
|
+
existsSync(path: string): boolean;
|
|
12
|
+
readdir(...args: any[]): any;
|
|
13
|
+
readdirSync(...args: any[]): unknown[];
|
|
14
|
+
createReadStream(path: string, options?: any): any;
|
|
15
|
+
createWriteStream(path: string, options?: any): any;
|
|
16
|
+
static sync_method_wrapper(this: UFS, method: string, ...args: any[]): any;
|
|
17
|
+
static async_method_wrapper(this: UFS, method: string, ...args: any[]): any;
|
|
18
|
+
}
|
|
19
|
+
export declare let ufs: UFS;
|
|
20
|
+
export declare function set_ufs(_ufs: UFS): void;
|
|
21
|
+
export default UFS;
|
package/ufs.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.set_ufs = exports.ufs = exports.UFS = void 0;
|
|
4
|
+
const lists_js_1 = require("fs-monkey/lib/util/lists.js");
|
|
5
|
+
require("./prototype.js");
|
|
6
|
+
class UFS {
|
|
7
|
+
constructor(fss) {
|
|
8
|
+
this.fss = fss || [];
|
|
9
|
+
const overriden_methods = Object.getOwnPropertyNames(UFS.prototype);
|
|
10
|
+
const filter_out_overriden_methods = (method) => !overriden_methods.includes(method);
|
|
11
|
+
lists_js_1.fsSyncMethods.filter(filter_out_overriden_methods).forEach(method => {
|
|
12
|
+
this[method] = UFS.sync_method_wrapper.bind(this, method);
|
|
13
|
+
}, this);
|
|
14
|
+
lists_js_1.fsAsyncMethods.filter(filter_out_overriden_methods).forEach(method => {
|
|
15
|
+
this[method] = UFS.async_method_wrapper.bind(this, method);
|
|
16
|
+
}, this);
|
|
17
|
+
}
|
|
18
|
+
use(fs) {
|
|
19
|
+
this.fss = [fs, ...this.fss];
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
existsSync(path) {
|
|
23
|
+
for (let fs of this.fss)
|
|
24
|
+
if (fs.existsSync(path))
|
|
25
|
+
return true;
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
readdir(...args) {
|
|
29
|
+
const method = 'readdir';
|
|
30
|
+
let callback = args.last;
|
|
31
|
+
if (typeof callback !== 'function')
|
|
32
|
+
callback = null;
|
|
33
|
+
else
|
|
34
|
+
args.pop();
|
|
35
|
+
let files = new Set();
|
|
36
|
+
const iterate = (i, error) => {
|
|
37
|
+
if (i >= this.fss.length)
|
|
38
|
+
return callback === null || callback === void 0 ? void 0 : callback(error, [...files].sort());
|
|
39
|
+
const fs = this.fss[i];
|
|
40
|
+
if (!fs[method])
|
|
41
|
+
return iterate(i + 1, new Error(`fs no method: ${method}, args: ${args}`));
|
|
42
|
+
fs[method](...args, (fsError, _files) => {
|
|
43
|
+
if (!fsError) {
|
|
44
|
+
files = new Set([...files, ..._files]);
|
|
45
|
+
return iterate(i + 1, null);
|
|
46
|
+
}
|
|
47
|
+
fsError.prev = error;
|
|
48
|
+
return iterate(i + 1, fsError);
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
return iterate(0, null);
|
|
52
|
+
}
|
|
53
|
+
readdirSync(...args) {
|
|
54
|
+
const method = 'readdirSync';
|
|
55
|
+
let last_error = null;
|
|
56
|
+
let files = new Set();
|
|
57
|
+
this.fss.forEach(fs => {
|
|
58
|
+
try {
|
|
59
|
+
if (!fs[method])
|
|
60
|
+
throw new Error(`fs no method: ${method}, args: ${args}`);
|
|
61
|
+
files = new Set([...files, ...fs[method].apply(fs, args)]);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
error.prev = last_error;
|
|
65
|
+
last_error = error;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
if (last_error)
|
|
69
|
+
throw last_error;
|
|
70
|
+
return [...files].sort();
|
|
71
|
+
}
|
|
72
|
+
createReadStream(path, options) {
|
|
73
|
+
let last_error = null;
|
|
74
|
+
for (let fs of this.fss)
|
|
75
|
+
try {
|
|
76
|
+
if (!fs.createReadStream)
|
|
77
|
+
throw new Error('method not supported: "createReadStream"');
|
|
78
|
+
if (!fs.existsSync)
|
|
79
|
+
throw new Error('method not supported: "existsSync"');
|
|
80
|
+
if (!fs.existsSync(path))
|
|
81
|
+
throw new Error(`文件不存在:${path}`);
|
|
82
|
+
const read_stream = fs.createReadStream.apply(fs, arguments);
|
|
83
|
+
if (!read_stream)
|
|
84
|
+
throw new Error('no valid read stream');
|
|
85
|
+
return read_stream;
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
error.prev = last_error;
|
|
89
|
+
last_error = error;
|
|
90
|
+
}
|
|
91
|
+
throw last_error;
|
|
92
|
+
}
|
|
93
|
+
createWriteStream(path, options) {
|
|
94
|
+
let last_error = null;
|
|
95
|
+
for (let fs of this.fss)
|
|
96
|
+
try {
|
|
97
|
+
if (!fs.createWriteStream)
|
|
98
|
+
throw new Error('Method not supported: "createWriteStream"');
|
|
99
|
+
fs.statSync(path);
|
|
100
|
+
const write_stream = fs.createWriteStream.apply(fs, arguments);
|
|
101
|
+
if (!write_stream)
|
|
102
|
+
throw new Error('no valid write stream');
|
|
103
|
+
return write_stream;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
error.prev = last_error;
|
|
107
|
+
last_error = error;
|
|
108
|
+
}
|
|
109
|
+
throw last_error;
|
|
110
|
+
}
|
|
111
|
+
static sync_method_wrapper(method, ...args) {
|
|
112
|
+
let last_error = null;
|
|
113
|
+
for (let fs of this.fss)
|
|
114
|
+
try {
|
|
115
|
+
if (!fs[method])
|
|
116
|
+
throw new Error(`fs no method: ${method}, args: ${args}`);
|
|
117
|
+
return fs[method].apply(fs, args);
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
error.prev = last_error;
|
|
121
|
+
last_error = error;
|
|
122
|
+
}
|
|
123
|
+
throw last_error;
|
|
124
|
+
}
|
|
125
|
+
static async_method_wrapper(method, ...args) {
|
|
126
|
+
let callback = args.last;
|
|
127
|
+
if (typeof callback !== 'function')
|
|
128
|
+
callback = null;
|
|
129
|
+
else
|
|
130
|
+
args.pop();
|
|
131
|
+
const iterate = (i, error) => {
|
|
132
|
+
if (i >= this.fss.length)
|
|
133
|
+
return callback === null || callback === void 0 ? void 0 : callback(error);
|
|
134
|
+
const fs = this.fss[i];
|
|
135
|
+
if (!fs[method])
|
|
136
|
+
return iterate(i + 1, new Error(`fs no method: ${method}, args: ${args}`));
|
|
137
|
+
return fs[method](...args, (fs_error, ...results) => {
|
|
138
|
+
if (!fs_error)
|
|
139
|
+
return callback === null || callback === void 0 ? void 0 : callback.call(fs, null, ...results);
|
|
140
|
+
fs_error.prev = error;
|
|
141
|
+
return iterate(i + 1, fs_error);
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
return iterate(0, null);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
exports.UFS = UFS;
|
|
148
|
+
function set_ufs(_ufs) {
|
|
149
|
+
exports.ufs = _ufs;
|
|
150
|
+
}
|
|
151
|
+
exports.set_ufs = set_ufs;
|
|
152
|
+
exports.default = UFS;
|
|
153
|
+
//# sourceMappingURL=ufs.js.map
|
package/ufs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ufs.js","sourceRoot":"","sources":["ufs.ts"],"names":[],"mappings":"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","sourcesContent":["import { fsAsyncMethods as fs_async_methods, fsSyncMethods as fs_sync_methods } from 'fs-monkey/lib/util/lists.js'\n\nimport type fs from 'fs'\n\n\nimport './prototype.js'\n\n\ntype FS = typeof fs\n\n// @ts-ignore\nexport interface UFS extends FS { }\n\nexport class UFS {\n fss: FS[]\n \n constructor (fss: any[]) {\n this.fss = fss || []\n \n const overriden_methods = Object.getOwnPropertyNames(UFS.prototype)\n \n const filter_out_overriden_methods = (method: string) => \n !overriden_methods.includes(method)\n \n fs_sync_methods.filter(filter_out_overriden_methods).forEach( method => {\n this[method] = UFS.sync_method_wrapper.bind(this, method)\n }, this)\n \n fs_async_methods.filter(filter_out_overriden_methods).forEach( method => {\n this[method] = UFS.async_method_wrapper.bind(this, method)\n }, this)\n }\n \n \n use (fs: any) {\n this.fss = [fs, ...this.fss]\n return this\n }\n \n \n existsSync (path: string) {\n for (let fs of this.fss)\n if (fs.existsSync(path)) return true\n return false\n }\n \n \n readdir (...args) {\n const method = 'readdir'\n \n let callback = args.last\n \n if (typeof callback !== 'function')\n callback = null\n else\n args.pop()\n \n let files = new Set()\n \n const iterate = (i: number, error: Error) => {\n if (i >= this.fss.length) return callback?.(error, [...files].sort())\n \n const fs = this.fss[i]\n \n if (!fs[method]) return iterate(i+1, new Error(`fs no method: ${method}, args: ${args}`))\n \n fs[method as string](...args, (fsError: Error & { prev: Error }, _files: string[]) => {\n if (!fsError) {\n files = new Set([...files, ..._files])\n return iterate(i+1, null)\n }\n fsError.prev = error\n return iterate(i+1, fsError)\n })\n }\n \n return iterate(0, null)\n }\n \n \n readdirSync (...args) {\n const method = 'readdirSync'\n \n let last_error = null\n let files = new Set()\n \n this.fss.forEach( fs => {\n try {\n if (!fs[method]) throw new Error(`fs no method: ${method}, args: ${args}`)\n \n files = new Set([...files, ...fs[method].apply(fs, args)])\n } catch (error) {\n error.prev = last_error\n last_error = error\n }\n })\n \n if (last_error) throw last_error\n \n return [...files].sort()\n }\n \n \n createReadStream (path: string, options?: any) {\n let last_error = null\n \n for (let fs of this.fss)\n try {\n if (!fs.createReadStream) throw new Error('method not supported: \"createReadStream\"')\n if (!fs.existsSync) throw new Error('method not supported: \"existsSync\"')\n if (!fs.existsSync(path)) throw new Error(`文件不存在:${path}`)\n const read_stream = fs.createReadStream.apply(fs, arguments)\n if (!read_stream) throw new Error('no valid read stream')\n return read_stream\n } catch (error) {\n error.prev = last_error\n last_error = error\n }\n \n throw last_error\n }\n \n \n createWriteStream (path: string, options?: any) {\n let last_error = null\n \n for (let fs of this.fss)\n try {\n if (!fs.createWriteStream) throw new Error('Method not supported: \"createWriteStream\"')\n fs.statSync(path)\n const write_stream = fs.createWriteStream.apply(fs, arguments)\n if (!write_stream) throw new Error('no valid write stream')\n return write_stream\n } catch (error) {\n error.prev = last_error\n last_error = error\n }\n \n \n throw last_error\n }\n \n \n static sync_method_wrapper (this: UFS, method: string, ...args: any[]) {\n let last_error: Error = null\n for (let fs of this.fss)\n try {\n if (!fs[method]) throw new Error(`fs no method: ${method}, args: ${args}`)\n return fs[method].apply(fs, args)\n } catch (error) {\n error.prev = last_error\n last_error = error\n }\n throw last_error\n }\n \n \n static async_method_wrapper (this: UFS, method: string, ...args: any[]) {\n let callback = args.last\n \n if (typeof callback !== 'function')\n callback = null\n else\n args.pop()\n \n const iterate = (i: number, error: Error) => {\n if (i >= this.fss.length) return callback?.(error)\n \n const fs = this.fss[i]\n \n if (!fs[method]) return iterate(i+1, new Error(`fs no method: ${method}, args: ${args}`))\n \n return fs[method](...args, (fs_error: Error & { prev: Error }, ...results: any[]) => {\n if (!fs_error) return callback?.call(fs, null, ...results)\n fs_error.prev = error\n return iterate(i+1, fs_error)\n })\n }\n \n return iterate(0, null)\n }\n}\n\nexport let ufs: UFS\n\nexport function set_ufs (_ufs: UFS) {\n ufs = _ufs\n}\n\nexport default UFS\n"]}
|
package/utils.d.ts
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import { Readable } from 'stream';
|
|
3
3
|
import util from 'util';
|
|
4
|
-
|
|
4
|
+
import './prototype';
|
|
5
|
+
export declare const output_width = 230;
|
|
5
6
|
export declare function dedent(templ: TemplateStringsArray | string, ...values: any[]): string;
|
|
6
|
-
|
|
7
|
+
/** unique iterable or array (by selector)
|
|
8
|
+
- selector?: 可以是 key (string) 或 (obj: any) => any
|
|
9
|
+
*/
|
|
10
|
+
export declare function unique<T>(iterable: T[] | Iterable<T>, selector?: string | ((obj: T) => any)): any[];
|
|
11
|
+
/** sort keys in object and returns new object */
|
|
7
12
|
export declare function sort_keys<T>(obj: T): T;
|
|
8
|
-
|
|
9
|
-
export declare function
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
/** string compare in lexicographic order */
|
|
14
|
+
export declare function strcmp(l: string, r: string): 0 | 1 | -1;
|
|
15
|
+
/** 拼接 TypedArrays 生成一个完整的 Uint8Array */
|
|
16
|
+
export declare function concat(views: ArrayBufferView[]): Uint8Array;
|
|
17
|
+
export declare function typed_array_to_buffer(view: ArrayBufferView): Buffer;
|
|
18
|
+
export declare function log_section(message: string, { time, timestamp, color, }?: {
|
|
19
|
+
time?: boolean;
|
|
20
|
+
timestamp?: boolean | Date;
|
|
12
21
|
color?: 'green' | 'red' | 'yellow';
|
|
13
|
-
left_width?: number;
|
|
14
|
-
full_width?: number;
|
|
15
22
|
}): void;
|
|
16
|
-
|
|
17
|
-
export declare function log_line(width?: number): void;
|
|
23
|
+
export declare function log_line(): void;
|
|
18
24
|
export declare function delay(milliseconds: number): Promise<unknown>;
|
|
19
25
|
export declare function has_chinese(str: string): boolean;
|
|
20
26
|
export declare function escape_line_feed(str: string): string;
|
|
@@ -30,3 +36,4 @@ export declare namespace inspect {
|
|
|
30
36
|
const custom: typeof util.inspect.custom;
|
|
31
37
|
}
|
|
32
38
|
export declare function stream_to_buffer(stream: Readable): Promise<Buffer>;
|
|
39
|
+
export declare function stream_to_lines(stream: Readable): AsyncGenerator<string, void, unknown>;
|
package/utils.js
CHANGED
|
@@ -1,38 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.stream_to_buffer = exports.inspect = exports.escape_line_feed = exports.has_chinese = exports.delay = exports.log_line = exports.log_section = exports.
|
|
3
|
+
exports.stream_to_lines = exports.stream_to_buffer = exports.inspect = exports.escape_line_feed = exports.has_chinese = exports.delay = exports.log_line = exports.log_section = exports.typed_array_to_buffer = exports.concat = exports.strcmp = exports.sort_keys = exports.unique = exports.dedent = exports.output_width = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const prototype_1 = require("./prototype");
|
|
10
|
-
function assert(shoud_be_true_expr) {
|
|
11
|
-
if (!shoud_be_true_expr) {
|
|
12
|
-
debugger;
|
|
13
|
-
throw new Error(`Assertion Failed: ${inspect(shoud_be_true_expr)}`);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
exports.assert = assert;
|
|
5
|
+
const util_1 = (0, tslib_1.__importDefault)(require("util"));
|
|
6
|
+
const omit_1 = (0, tslib_1.__importDefault)(require("lodash/omit"));
|
|
7
|
+
require("./prototype");
|
|
8
|
+
exports.output_width = 230;
|
|
17
9
|
function dedent(templ, ...values) {
|
|
18
10
|
let strings = Array.from(typeof templ === 'string' ? [templ] : templ.raw);
|
|
19
|
-
// 1.
|
|
11
|
+
// 1. remove trailing whitespace
|
|
20
12
|
strings[strings.length - 1] = strings[strings.length - 1].replace(/\r?\n([\t ]*)$/, '');
|
|
21
|
-
// 2.
|
|
22
|
-
const
|
|
13
|
+
// 2. find all line breaks to determine the highest common indentation level
|
|
14
|
+
const indent_lengths = strings.reduce((arr, str) => {
|
|
23
15
|
const matches = str.match(/\n[\t ]+/g);
|
|
24
16
|
if (matches)
|
|
25
17
|
return arr.concat(matches.map(match => match.length - 1));
|
|
26
18
|
return arr;
|
|
27
19
|
}, []);
|
|
28
|
-
// 3.
|
|
29
|
-
if (
|
|
30
|
-
const pattern = new RegExp(`\n[\t ]{${Math.min(...
|
|
20
|
+
// 3. remove the common indentation from all strings
|
|
21
|
+
if (indent_lengths.length) {
|
|
22
|
+
const pattern = new RegExp(`\n[\t ]{${Math.min(...indent_lengths)}}`, 'g');
|
|
31
23
|
strings = strings.map(str => str.replace(pattern, '\n'));
|
|
32
24
|
}
|
|
33
|
-
// 4.
|
|
25
|
+
// 4. remove leading whitespace
|
|
34
26
|
strings[0] = strings[0].replace(/^\r?\n/, '');
|
|
35
|
-
// 5.
|
|
27
|
+
// 5. perform interpolation
|
|
36
28
|
let string = strings[0];
|
|
37
29
|
values.forEach((value, i) => {
|
|
38
30
|
string += value + strings[i + 1];
|
|
@@ -41,40 +33,76 @@ function dedent(templ, ...values) {
|
|
|
41
33
|
return string;
|
|
42
34
|
}
|
|
43
35
|
exports.dedent = dedent;
|
|
44
|
-
|
|
45
|
-
|
|
36
|
+
/** unique iterable or array (by selector)
|
|
37
|
+
- selector?: 可以是 key (string) 或 (obj: any) => any
|
|
38
|
+
*/
|
|
39
|
+
function unique(iterable, selector) {
|
|
40
|
+
if (!selector)
|
|
41
|
+
return [...new Set(iterable)];
|
|
42
|
+
let map = new Map();
|
|
43
|
+
if (typeof selector === 'string')
|
|
44
|
+
for (const x of iterable)
|
|
45
|
+
map.set(x[selector], x);
|
|
46
|
+
else
|
|
47
|
+
for (const x of iterable)
|
|
48
|
+
map.set(selector(x), x);
|
|
49
|
+
return [...map.values()];
|
|
46
50
|
}
|
|
47
51
|
exports.unique = unique;
|
|
52
|
+
/** sort keys in object and returns new object */
|
|
48
53
|
function sort_keys(obj) {
|
|
49
|
-
return Object.fromEntries(
|
|
54
|
+
return Object.fromEntries(Object.entries(obj)
|
|
55
|
+
.sort(([key_l], [key_r]) => strcmp(key_l, key_r)));
|
|
50
56
|
}
|
|
51
57
|
exports.sort_keys = sort_keys;
|
|
52
|
-
|
|
53
|
-
function
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
/** string compare in lexicographic order */
|
|
59
|
+
function strcmp(l, r) {
|
|
60
|
+
if (l === r)
|
|
61
|
+
return 0;
|
|
62
|
+
if (l < r)
|
|
63
|
+
return -1;
|
|
64
|
+
return 1;
|
|
65
|
+
}
|
|
66
|
+
exports.strcmp = strcmp;
|
|
67
|
+
/** 拼接 TypedArrays 生成一个完整的 Uint8Array */
|
|
68
|
+
function concat(views) {
|
|
69
|
+
let length = 0;
|
|
70
|
+
for (const v of views)
|
|
71
|
+
length += v.byteLength;
|
|
72
|
+
let buf = new Uint8Array(length);
|
|
73
|
+
let offset = 0;
|
|
74
|
+
for (const v of views) {
|
|
75
|
+
const uint8view = new Uint8Array(v.buffer, v.byteOffset, v.byteLength);
|
|
76
|
+
buf.set(uint8view, offset);
|
|
77
|
+
offset += uint8view.byteLength;
|
|
78
|
+
}
|
|
79
|
+
return buf;
|
|
56
80
|
}
|
|
57
|
-
exports.
|
|
58
|
-
function
|
|
81
|
+
exports.concat = concat;
|
|
82
|
+
function typed_array_to_buffer(view) {
|
|
83
|
+
return Buffer.from(view.buffer, view.byteOffset, view.byteLength);
|
|
84
|
+
}
|
|
85
|
+
exports.typed_array_to_buffer = typed_array_to_buffer;
|
|
86
|
+
// ------------------------------------ log: module loaded, section, line
|
|
87
|
+
function log_section(message, { time = false, timestamp = false, color = undefined, } = {}) {
|
|
59
88
|
const stime = (() => {
|
|
60
|
-
if (timestamp)
|
|
61
|
-
return ` [${String(new Date().getTime() - global.started_at.getTime()).pad(4, { position: 'left' })} ms]`;
|
|
62
89
|
if (time)
|
|
63
|
-
|
|
64
|
-
|
|
90
|
+
return `[${String(new Date().getTime() - global.started_at.getTime()).pad(4, { position: 'left' })} ms]`;
|
|
91
|
+
if (timestamp)
|
|
92
|
+
if (typeof timestamp === 'object')
|
|
93
|
+
return `[${timestamp.to_str()}]`;
|
|
65
94
|
else
|
|
66
|
-
return `
|
|
95
|
+
return `[${new Date().to_str()}]`;
|
|
67
96
|
return '';
|
|
68
97
|
})();
|
|
69
|
-
message = `${
|
|
98
|
+
message = `${stime.pad(20)}${message}`;
|
|
70
99
|
if (color)
|
|
71
|
-
message =
|
|
100
|
+
message = message[color];
|
|
72
101
|
console.log(message);
|
|
73
102
|
}
|
|
74
103
|
exports.log_section = log_section;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
console.log('─'.repeat(width / 2));
|
|
104
|
+
function log_line() {
|
|
105
|
+
console.log('---');
|
|
78
106
|
}
|
|
79
107
|
exports.log_line = log_line;
|
|
80
108
|
async function delay(milliseconds) {
|
|
@@ -83,7 +111,7 @@ async function delay(milliseconds) {
|
|
|
83
111
|
});
|
|
84
112
|
}
|
|
85
113
|
exports.delay = delay;
|
|
86
|
-
// ------------
|
|
114
|
+
// ------------ text
|
|
87
115
|
function has_chinese(str) {
|
|
88
116
|
return /[\u4E00-\u9FA5]/.test(str);
|
|
89
117
|
}
|
|
@@ -98,10 +126,8 @@ exports.escape_line_feed = escape_line_feed;
|
|
|
98
126
|
*/
|
|
99
127
|
function inspect(obj, options = {}) {
|
|
100
128
|
if (options.omit)
|
|
101
|
-
obj = omit_1.default(obj, [inspect.custom, ...(options.omit || [])]);
|
|
129
|
+
obj = (0, omit_1.default)(obj, [inspect.custom, ...(options.omit || [])]);
|
|
102
130
|
let text = util_1.default.inspect(obj, options);
|
|
103
|
-
if (obj && typeof obj === 'object')
|
|
104
|
-
text = text.split_lines().indent2to4().join_lines();
|
|
105
131
|
if (!('limit' in options))
|
|
106
132
|
options.limit = 10000;
|
|
107
133
|
if (options.limit && text.length > options.limit)
|
|
@@ -121,4 +147,21 @@ async function stream_to_buffer(stream) {
|
|
|
121
147
|
return Buffer.concat(chunks);
|
|
122
148
|
}
|
|
123
149
|
exports.stream_to_buffer = stream_to_buffer;
|
|
150
|
+
async function* stream_to_lines(stream) {
|
|
151
|
+
let buf = '';
|
|
152
|
+
for await (const chunk of stream) {
|
|
153
|
+
let i = 0, j = 0;
|
|
154
|
+
for (; (i = chunk.indexOf('\n', j)) >= 0;) {
|
|
155
|
+
let line = chunk.slice(j, i);
|
|
156
|
+
if (buf) {
|
|
157
|
+
line = buf + line;
|
|
158
|
+
buf = '';
|
|
159
|
+
}
|
|
160
|
+
j = i + 1;
|
|
161
|
+
yield line;
|
|
162
|
+
}
|
|
163
|
+
buf = chunk.slice(j);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
exports.stream_to_lines = stream_to_lines;
|
|
124
167
|
//# sourceMappingURL=utils.js.map
|
package/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Readable } from 'stream'\n\nimport path from 'upath'\nimport util from 'util'\nimport omit from 'lodash/omit'\nimport sort_by from 'lodash/sortBy'\n\nimport { colors } from './prototype'\n\n\nexport function assert (shoud_be_true_expr: any): never | void {\n if (!shoud_be_true_expr) {\n debugger\n throw new Error(`Assertion Failed: ${inspect(shoud_be_true_expr)}`)\n }\n}\n\n\nexport function dedent (\n templ: TemplateStringsArray | string,\n ...values: any[]\n): string {\n let strings = Array.from(typeof templ === 'string' ? [templ] : templ.raw)\n \n // 1. Remove trailing whitespace.\n strings[strings.length - 1] = strings[strings.length - 1].replace(\n /\\r?\\n([\\t ]*)$/,\n '',\n )\n \n // 2. Find all line breaks to determine the highest common indentation level.\n const indentLengths = strings.reduce<number[]>(\n (arr, str) => {\n const matches = str.match(/\\n[\\t ]+/g)\n if (matches) \n return arr.concat(matches.map(match => match.length - 1))\n \n return arr\n },\n [],\n )\n \n // 3. Remove the common indentation from all strings.\n if (indentLengths.length) {\n const pattern = new RegExp(`\\n[\\t ]{${Math.min(...indentLengths)}}`, 'g')\n \n strings = strings.map(str => str.replace(pattern, '\\n'))\n }\n \n // 4. Remove leading whitespace.\n strings[0] = strings[0].replace(/^\\r?\\n/, '')\n \n // 5. Perform interpolation.\n let string = strings[0]\n \n values.forEach((value, i) => {\n string += value + strings[i + 1]\n })\n \n string += '\\n'\n \n return string\n}\n\n\nexport function unique (iterable: any[] | Set<any>) {\n return [... new Set(iterable)]\n}\n\n\nexport function sort_keys <T> (obj: T) {\n return Object.fromEntries(\n sort_by(\n Object.entries(obj),\n ([key, ]) => key\n )\n ) as T\n}\n\n\n// ------------------------------------ Log: module loaded, section, line\nexport function log_module_loaded (id: string) {\n const fname = path.basename(id).replace(/\\.(coffee|ts)$/, '')\n console.log(`${ fname }${ ' '.repeat(20 - fname.length) }loaded`)\n}\n\n\nexport function log_section (\n message: string, \n {\n timestamp = false,\n time = false,\n color = undefined,\n left_width = 30,\n full_width = 110\n }: {\n timestamp?: boolean\n time?: boolean | Date\n color?: 'green' | 'red' | 'yellow'\n left_width?: number\n full_width?: number\n } = { }\n) {\n const stime = (() => {\n if (timestamp)\n return ` [${String(new Date().getTime() - global.started_at.getTime()).pad(4, { position: 'left' })} ms]`\n if (time)\n if (typeof time === 'object')\n return ` [${time.to_str()}]`\n else\n return ` [${new Date().to_str()}]`\n return ''\n })()\n \n message = `${'-'.repeat(left_width)}${stime} ${message} `.pad(full_width, { character: '-' })\n \n if (color)\n message = colors[color](message)\n \n console.log(message)\n}\n\n\n/** '─' === '\\u2500' */\nexport function log_line (width: number = global.WIDTH || 240) {\n console.log('─'.repeat(width / 2))\n}\n\n\nexport async function delay (milliseconds: number) {\n return new Promise( resolve => {\n setTimeout(resolve, milliseconds)\n })\n}\n\n\n// ------------ Text\nexport function has_chinese (str: string) {\n return /[\\u4E00-\\u9FA5]/.test(str)\n}\n\n\nexport function escape_line_feed (str: string) {\n return str.replace(/\\n/g, '\\\\n')\n}\n\n/** util.inspect(obj) \n - options\n - limit?: `10000`\n*/\nexport function inspect (\n obj: any, \n options: util.InspectOptions & {\n limit?: number\n omit?: string[]\n } = { }\n) {\n if (options.omit)\n obj = omit(obj, [inspect.custom, ...(options.omit || [])])\n \n let text = util.inspect(obj, options)\n \n if (obj && typeof obj === 'object')\n text = text.split_lines().indent2to4().join_lines()\n\n if (!('limit' in options))\n options.limit = 10000\n if (options.limit && text.length > options.limit)\n return `${text.slice(0, options.limit)}……'\\u001b[39m\\n`\n else\n return text\n}\n\nexport namespace inspect {\n export const custom: typeof util.inspect.custom = util.inspect.custom\n}\n\n\n// ------------------------------------ Steam\nexport async function stream_to_buffer (stream: Readable) {\n let chunks = [ ]\n for await (const chunk of stream)\n chunks.push(chunk)\n return Buffer.concat(chunks)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["utils.ts"],"names":[],"mappings":";;;;AAEA,6DAAuB;AACvB,oEAA8B;AAE9B,uBAAoB;AAEP,QAAA,YAAY,GAAG,GAAG,CAAA;AAG/B,SAAgB,MAAM,CAClB,KAAoC,EACpC,GAAG,MAAa;IAEhB,IAAI,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAEzE,gCAAgC;IAChC,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,OAAO,CAC7D,gBAAgB,EAChB,EAAE,CACL,CAAA;IAED,4EAA4E;IAC5E,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CACjC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACT,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QACtC,IAAI,OAAO;YACP,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAA;QAE7D,OAAO,GAAG,CAAA;IACd,CAAC,EACD,EAAE,CACL,CAAA;IAED,oDAAoD;IACpD,IAAI,cAAc,CAAC,MAAM,EAAE;QACvB,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QAE1E,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAA;KAC3D;IAED,+BAA+B;IAC/B,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAA;IAE7C,2BAA2B;IAC3B,IAAI,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IAEvB,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;QACxB,MAAM,IAAI,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;IAEF,MAAM,IAAI,IAAI,CAAA;IAEd,OAAO,MAAM,CAAA;AACjB,CAAC;AA5CD,wBA4CC;AAGD;;EAEE;AACF,SAAgB,MAAM,CAAM,QAA2B,EAAE,QAAqC;IAC1F,IAAI,CAAC,QAAQ;QACT,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;IAEjC,IAAI,GAAG,GAAG,IAAI,GAAG,EAAE,CAAA;IACnB,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAC5B,KAAK,MAAM,CAAC,IAAI,QAAQ;YACpB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAA;;QAE3B,KAAK,MAAM,CAAC,IAAI,QAAQ;YACpB,GAAG,CAAC,GAAG,CACH,QAAQ,CAAC,CAAC,CAAC,EACX,CAAC,CACJ,CAAA;IAET,OAAO,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,CAAA;AAC5B,CAAC;AAhBD,wBAgBC;AAGD,iDAAiD;AACjD,SAAgB,SAAS,CAAM,GAAM;IACjC,OAAO,MAAM,CAAC,WAAW,CACrB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;SACd,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CACvB,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAC3B,CAAA;AACV,CAAC;AAND,8BAMC;AAGD,4CAA4C;AAC5C,SAAgB,MAAM,CAAE,CAAS,EAAE,CAAS;IACxC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAA;IACrB,IAAI,CAAC,GAAG,CAAC;QAAI,OAAO,CAAC,CAAC,CAAA;IACtB,OAAO,CAAC,CAAA;AACZ,CAAC;AAJD,wBAIC;AAGD,wCAAwC;AACxC,SAAgB,MAAM,CAAE,KAAwB;IAC5C,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,KAAK,MAAM,CAAC,IAAI,KAAK;QACjB,MAAM,IAAI,CAAC,CAAC,UAAU,CAAA;IAE1B,IAAI,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAA;IAChC,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE;QACnB,MAAM,SAAS,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,CAAA;QACtE,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;QAC1B,MAAM,IAAI,SAAS,CAAC,UAAU,CAAA;KACjC;IAED,OAAO,GAAG,CAAA;AACd,CAAC;AAdD,wBAcC;AAGD,SAAgB,qBAAqB,CAAE,IAAqB;IACxD,OAAO,MAAM,CAAC,IAAI,CACd,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,UAAU,CAClB,CAAA;AACL,CAAC;AAND,sDAMC;AAGD,yEAAyE;AACzE,SAAgB,WAAW,CACvB,OAAe,EACf,EACI,IAAI,GAAG,KAAK,EACZ,SAAS,GAAG,KAAK,EACjB,KAAK,GAAG,SAAS,MAKjB,EAAG;IAEP,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE;QAChB,IAAI,IAAI;YACJ,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,MAAM,CAAA;QAC5G,IAAI,SAAS;YACT,IAAI,OAAO,SAAS,KAAK,QAAQ;gBAC7B,OAAO,IAAI,SAAS,CAAC,MAAM,EAAE,GAAG,CAAA;;gBAEhC,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC,MAAM,EAAE,GAAG,CAAA;QACzC,OAAO,EAAE,CAAA;IACb,CAAC,CAAC,EAAE,CAAA;IAEJ,OAAO,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,EAAE,CAAA;IAEtC,IAAI,KAAK;QACL,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAA;IAE5B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;AACxB,CAAC;AA7BD,kCA6BC;AAGD,SAAgB,QAAQ;IACpB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AACtB,CAAC;AAFD,4BAEC;AAGM,KAAK,UAAU,KAAK,CAAE,YAAoB;IAC7C,OAAO,IAAI,OAAO,CAAE,OAAO,CAAC,EAAE;QAC1B,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;AACN,CAAC;AAJD,sBAIC;AAGD,oBAAoB;AACpB,SAAgB,WAAW,CAAE,GAAW;IACpC,OAAO,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACtC,CAAC;AAFD,kCAEC;AAGD,SAAgB,gBAAgB,CAAE,GAAW;IACzC,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AACpC,CAAC;AAFD,4CAEC;AAED;;;EAGE;AACF,SAAgB,OAAO,CACnB,GAAQ,EACR,UAGI,EAAG;IAEP,IAAI,OAAO,CAAC,IAAI;QACZ,GAAG,GAAG,IAAA,cAAI,EAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAE9D,IAAI,IAAI,GAAG,cAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAErC,IAAI,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC;QACrB,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;IACzB,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK;QAC5C,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAA;;QAEvD,OAAO,IAAI,CAAA;AACnB,CAAC;AAlBD,0BAkBC;AAED,WAAiB,OAAO;IACP,cAAM,GAA+B,cAAI,CAAC,OAAO,CAAC,MAAM,CAAA;AACzE,CAAC,EAFgB,OAAO,GAAP,eAAO,KAAP,eAAO,QAEvB;AAGD,6CAA6C;AACtC,KAAK,UAAU,gBAAgB,CAAE,MAAgB;IACpD,IAAI,MAAM,GAAG,EAAG,CAAA;IAChB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAA+B;QACrD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACtB,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;AAChC,CAAC;AALD,4CAKC;AAGM,KAAK,SAAU,CAAC,CAAC,eAAe,CAAE,MAAgB;IACrD,IAAI,GAAG,GAAG,EAAE,CAAA;IACZ,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAA+B,EAAE;QACvD,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;QAChB,OAAQ,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAK;YAC1C,IAAI,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YAC5B,IAAI,GAAG,EAAE;gBACL,IAAI,GAAG,GAAG,GAAG,IAAI,CAAA;gBACjB,GAAG,GAAG,EAAE,CAAA;aACX;YACD,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACT,MAAM,IAAI,CAAA;SACb;QACD,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;KACvB;AACL,CAAC;AAfD,0CAeC","sourcesContent":["import { Readable } from 'stream'\n\nimport util from 'util'\nimport omit from 'lodash/omit'\n\nimport './prototype'\n\nexport const output_width = 230\n\n\nexport function dedent (\n templ: TemplateStringsArray | string,\n ...values: any[]\n): string {\n let strings = Array.from(typeof templ === 'string' ? [templ] : templ.raw)\n \n // 1. remove trailing whitespace\n strings[strings.length - 1] = strings[strings.length - 1].replace(\n /\\r?\\n([\\t ]*)$/,\n '',\n )\n \n // 2. find all line breaks to determine the highest common indentation level\n const indent_lengths = strings.reduce<number[]>(\n (arr, str) => {\n const matches = str.match(/\\n[\\t ]+/g)\n if (matches) \n return arr.concat(matches.map(match => match.length - 1))\n \n return arr\n },\n [],\n )\n \n // 3. remove the common indentation from all strings\n if (indent_lengths.length) {\n const pattern = new RegExp(`\\n[\\t ]{${Math.min(...indent_lengths)}}`, 'g')\n \n strings = strings.map(str => str.replace(pattern, '\\n'))\n }\n \n // 4. remove leading whitespace\n strings[0] = strings[0].replace(/^\\r?\\n/, '')\n \n // 5. perform interpolation\n let string = strings[0]\n \n values.forEach((value, i) => {\n string += value + strings[i + 1]\n })\n \n string += '\\n'\n \n return string\n}\n\n\n/** unique iterable or array (by selector) \n - selector?: 可以是 key (string) 或 (obj: any) => any\n*/\nexport function unique <T> (iterable: T[] | Iterable<T>, selector?: string | ((obj: T) => any)) {\n if (!selector)\n return [...new Set(iterable)]\n \n let map = new Map()\n if (typeof selector === 'string')\n for (const x of iterable)\n map.set(x[selector], x)\n else\n for (const x of iterable)\n map.set(\n selector(x),\n x\n )\n \n return [...map.values()]\n}\n\n\n/** sort keys in object and returns new object */\nexport function sort_keys <T> (obj: T) {\n return Object.fromEntries(\n Object.entries(obj)\n .sort(([key_l], [key_r]) => \n strcmp(key_l, key_r))\n ) as T\n}\n\n\n/** string compare in lexicographic order */\nexport function strcmp (l: string, r: string) {\n if (l === r) return 0\n if (l < r) return -1\n return 1\n}\n\n\n/** 拼接 TypedArrays 生成一个完整的 Uint8Array */\nexport function concat (views: ArrayBufferView[]) {\n let length = 0\n for (const v of views)\n length += v.byteLength\n \n let buf = new Uint8Array(length)\n let offset = 0\n for (const v of views) {\n const uint8view = new Uint8Array(v.buffer, v.byteOffset, v.byteLength)\n buf.set(uint8view, offset)\n offset += uint8view.byteLength\n }\n \n return buf\n}\n\n\nexport function typed_array_to_buffer (view: ArrayBufferView) {\n return Buffer.from(\n view.buffer,\n view.byteOffset,\n view.byteLength\n )\n}\n\n\n// ------------------------------------ log: module loaded, section, line\nexport function log_section (\n message: string, \n {\n time = false,\n timestamp = false,\n color = undefined,\n }: {\n time?: boolean\n timestamp?: boolean | Date\n color?: 'green' | 'red' | 'yellow'\n } = { }\n) {\n const stime = (() => {\n if (time)\n return `[${String(new Date().getTime() - global.started_at.getTime()).pad(4, { position: 'left' })} ms]`\n if (timestamp)\n if (typeof timestamp === 'object')\n return `[${timestamp.to_str()}]`\n else\n return `[${new Date().to_str()}]`\n return ''\n })()\n \n message = `${stime.pad(20)}${message}`\n \n if (color)\n message = message[color]\n \n console.log(message)\n}\n\n\nexport function log_line () {\n console.log('---')\n}\n\n\nexport async function delay (milliseconds: number) {\n return new Promise( resolve => {\n setTimeout(resolve, milliseconds)\n })\n}\n\n\n// ------------ text\nexport function has_chinese (str: string) {\n return /[\\u4E00-\\u9FA5]/.test(str)\n}\n\n\nexport function escape_line_feed (str: string) {\n return str.replace(/\\n/g, '\\\\n')\n}\n\n/** util.inspect(obj) \n - options\n - limit?: `10000`\n*/\nexport function inspect (\n obj: any, \n options: util.InspectOptions & {\n limit?: number\n omit?: string[]\n } = { }\n) {\n if (options.omit)\n obj = omit(obj, [inspect.custom, ...(options.omit || [])])\n \n let text = util.inspect(obj, options)\n \n if (!('limit' in options))\n options.limit = 10000\n if (options.limit && text.length > options.limit)\n return `${text.slice(0, options.limit)}……'\\u001b[39m\\n`\n else\n return text\n}\n\nexport namespace inspect {\n export const custom: typeof util.inspect.custom = util.inspect.custom\n}\n\n\n// ------------------------------------ Steam\nexport async function stream_to_buffer (stream: Readable) {\n let chunks = [ ]\n for await (const chunk of stream as AsyncIterable<Buffer>)\n chunks.push(chunk)\n return Buffer.concat(chunks)\n}\n\n\nexport async function * stream_to_lines (stream: Readable) {\n let buf = ''\n for await (const chunk of stream as AsyncIterable<string>) {\n let i = 0, j = 0\n for (; (i = chunk.indexOf('\\n', j)) >= 0; ) {\n let line = chunk.slice(j, i)\n if (buf) {\n line = buf + line\n buf = ''\n }\n j = i + 1\n yield line\n }\n buf = chunk.slice(j)\n }\n}\n\n"]}
|