cssprobe-cli 0.1.0
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/AGENTS.md +77 -0
- package/LICENSE +21 -0
- package/README.md +218 -0
- package/bin/cssprobe-cli.js +6 -0
- package/dist/browser/launcher.d.ts +25 -0
- package/dist/browser/launcher.js +213 -0
- package/dist/cli/command.d.ts +27 -0
- package/dist/cli/command.js +84 -0
- package/dist/cli/commands.d.ts +42 -0
- package/dist/cli/commands.js +166 -0
- package/dist/cli/minimist.d.ts +9 -0
- package/dist/cli/minimist.js +120 -0
- package/dist/cli/output.d.ts +26 -0
- package/dist/cli/output.js +80 -0
- package/dist/cli/program.d.ts +1 -0
- package/dist/cli/program.js +381 -0
- package/dist/collector-bundle.js +342 -0
- package/dist/config/config.d.ts +23 -0
- package/dist/config/config.js +128 -0
- package/dist/config/helpGenerator.d.ts +10 -0
- package/dist/config/helpGenerator.js +156 -0
- package/dist/engine/analyzer.d.ts +2 -0
- package/dist/engine/analyzer.js +385 -0
- package/dist/engine/collector.d.ts +3 -0
- package/dist/engine/collector.js +291 -0
- package/dist/engine/renderer.d.ts +3 -0
- package/dist/engine/renderer.js +159 -0
- package/dist/engine/types.d.ts +130 -0
- package/dist/engine/types.js +4 -0
- package/dist/help.json +107 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -0
- package/dist/installer/index.d.ts +3 -0
- package/dist/installer/index.js +12 -0
- package/dist/installer/skill-template.d.ts +9 -0
- package/dist/installer/skill-template.js +274 -0
- package/dist/installer/targets/registry.d.ts +9 -0
- package/dist/installer/targets/registry.js +121 -0
- package/dist/installer/targets/shared.d.ts +9 -0
- package/dist/installer/targets/shared.js +112 -0
- package/dist/installer/targets/types.d.ts +22 -0
- package/dist/installer/targets/types.js +3 -0
- package/docs/guide/installation.md +230 -0
- package/package.json +51 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as z from 'zod';
|
|
2
|
+
import type { AnyCommandSchema } from './command';
|
|
3
|
+
export declare const commands: {
|
|
4
|
+
[k: string]: AnyCommandSchema;
|
|
5
|
+
};
|
|
6
|
+
export declare const inspectCommand: import("./command").CommandSchema<z.ZodObject<{
|
|
7
|
+
url: z.ZodString;
|
|
8
|
+
selector: z.ZodOptional<z.ZodString>;
|
|
9
|
+
}, "strip", z.ZodTypeAny, {
|
|
10
|
+
url: string;
|
|
11
|
+
selector?: string | undefined;
|
|
12
|
+
}, {
|
|
13
|
+
url: string;
|
|
14
|
+
selector?: string | undefined;
|
|
15
|
+
}>, z.ZodObject<{
|
|
16
|
+
json: z.ZodOptional<z.ZodBoolean>;
|
|
17
|
+
headed: z.ZodOptional<z.ZodBoolean>;
|
|
18
|
+
browser: z.ZodOptional<z.ZodEnum<["chromium", "firefox", "webkit"]>>;
|
|
19
|
+
zoom: z.ZodOptional<z.ZodBoolean>;
|
|
20
|
+
depth: z.ZodOptional<z.ZodEffects<z.ZodNumber, number, unknown>>;
|
|
21
|
+
'max-nodes': z.ZodOptional<z.ZodEffects<z.ZodNumber, number, unknown>>;
|
|
22
|
+
'up-to': z.ZodOptional<z.ZodString>;
|
|
23
|
+
state: z.ZodOptional<z.ZodString>;
|
|
24
|
+
}, "strip", z.ZodTypeAny, {
|
|
25
|
+
json?: boolean | undefined;
|
|
26
|
+
headed?: boolean | undefined;
|
|
27
|
+
browser?: "chromium" | "firefox" | "webkit" | undefined;
|
|
28
|
+
zoom?: boolean | undefined;
|
|
29
|
+
depth?: number | undefined;
|
|
30
|
+
'max-nodes'?: number | undefined;
|
|
31
|
+
'up-to'?: string | undefined;
|
|
32
|
+
state?: string | undefined;
|
|
33
|
+
}, {
|
|
34
|
+
json?: boolean | undefined;
|
|
35
|
+
headed?: boolean | undefined;
|
|
36
|
+
browser?: "chromium" | "firefox" | "webkit" | undefined;
|
|
37
|
+
zoom?: boolean | undefined;
|
|
38
|
+
depth?: unknown;
|
|
39
|
+
'max-nodes'?: unknown;
|
|
40
|
+
'up-to'?: string | undefined;
|
|
41
|
+
state?: string | undefined;
|
|
42
|
+
}>>;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.inspectCommand = exports.commands = void 0;
|
|
37
|
+
const z = __importStar(require("zod"));
|
|
38
|
+
const command_1 = require("./command");
|
|
39
|
+
const numberArg = z.preprocess((val, ctx) => {
|
|
40
|
+
const number = Number(val);
|
|
41
|
+
if (Number.isNaN(number)) {
|
|
42
|
+
ctx.addIssue({ code: 'custom', message: `expected number, received '${val}'` });
|
|
43
|
+
}
|
|
44
|
+
return number;
|
|
45
|
+
}, z.number());
|
|
46
|
+
const urlArg = z.string().describe('URL, file:// path, or local HTML file path');
|
|
47
|
+
// ── core ──
|
|
48
|
+
const inspect = (0, command_1.declareCommand)({
|
|
49
|
+
name: 'inspect',
|
|
50
|
+
category: 'core',
|
|
51
|
+
description: 'Inspect the runtime CSS of a page (layout, scroll, colors, fonts, backgrounds)',
|
|
52
|
+
args: z.object({
|
|
53
|
+
url: urlArg,
|
|
54
|
+
selector: z.string().optional().describe('CSS selector for the root element (auto-detected if omitted)'),
|
|
55
|
+
}),
|
|
56
|
+
options: z.object({
|
|
57
|
+
json: z.boolean().optional().describe('output structured JSON instead of Markdown'),
|
|
58
|
+
headed: z.boolean().optional().describe('show the browser window'),
|
|
59
|
+
browser: z.enum(['chromium', 'firefox', 'webkit']).optional().describe('browser engine (default chromium)'),
|
|
60
|
+
zoom: z.boolean().optional().describe('run 1x/0.5x viewport diagnosis'),
|
|
61
|
+
depth: numberArg.optional().describe('DOM tree depth (default 6)'),
|
|
62
|
+
'max-nodes': numberArg.optional().describe('node count cap (default 60)'),
|
|
63
|
+
'up-to': z.string().optional().describe('ancestor stop tag (default html)'),
|
|
64
|
+
state: z.string().optional().describe('path to saved state file (cookies + localStorage)'),
|
|
65
|
+
}),
|
|
66
|
+
});
|
|
67
|
+
const login = (0, command_1.declareCommand)({
|
|
68
|
+
name: 'login',
|
|
69
|
+
category: 'core',
|
|
70
|
+
description: 'Open browser for interactive login, then save state for later use',
|
|
71
|
+
args: z.object({
|
|
72
|
+
url: urlArg,
|
|
73
|
+
}),
|
|
74
|
+
options: z.object({
|
|
75
|
+
browser: z.enum(['chromium', 'firefox', 'webkit']).optional().describe('browser engine (default chromium)'),
|
|
76
|
+
out: z.string().optional().describe('output state file path (default: ~/.cssprobe-cli/states/<domain>.json)'),
|
|
77
|
+
}),
|
|
78
|
+
});
|
|
79
|
+
// ── config ──
|
|
80
|
+
const configShow = (0, command_1.declareCommand)({
|
|
81
|
+
name: 'config-show',
|
|
82
|
+
category: 'config',
|
|
83
|
+
description: 'Show current configuration',
|
|
84
|
+
options: z.object({
|
|
85
|
+
profile: z.string().optional().describe('profile name'),
|
|
86
|
+
}),
|
|
87
|
+
});
|
|
88
|
+
const configSet = (0, command_1.declareCommand)({
|
|
89
|
+
name: 'config-set',
|
|
90
|
+
category: 'config',
|
|
91
|
+
description: 'Set a configuration value',
|
|
92
|
+
args: z.object({
|
|
93
|
+
key: z.string().describe('Config key (browser, depth, headed)'),
|
|
94
|
+
value: z.string().describe('Config value'),
|
|
95
|
+
}),
|
|
96
|
+
options: z.object({
|
|
97
|
+
profile: z.string().optional().describe('profile name'),
|
|
98
|
+
}),
|
|
99
|
+
});
|
|
100
|
+
const configList = (0, command_1.declareCommand)({
|
|
101
|
+
name: 'config-list',
|
|
102
|
+
category: 'config',
|
|
103
|
+
description: 'List all profiles',
|
|
104
|
+
});
|
|
105
|
+
const configUse = (0, command_1.declareCommand)({
|
|
106
|
+
name: 'config-use',
|
|
107
|
+
category: 'config',
|
|
108
|
+
description: 'Switch active profile',
|
|
109
|
+
args: z.object({
|
|
110
|
+
name: z.string().describe('Profile name'),
|
|
111
|
+
}),
|
|
112
|
+
});
|
|
113
|
+
const configNew = (0, command_1.declareCommand)({
|
|
114
|
+
name: 'config-new',
|
|
115
|
+
category: 'config',
|
|
116
|
+
description: 'Create a new profile',
|
|
117
|
+
args: z.object({
|
|
118
|
+
name: z.string().describe('Profile name'),
|
|
119
|
+
}),
|
|
120
|
+
});
|
|
121
|
+
const configPath = (0, command_1.declareCommand)({
|
|
122
|
+
name: 'config-path',
|
|
123
|
+
category: 'config',
|
|
124
|
+
description: 'Show configuration file path',
|
|
125
|
+
});
|
|
126
|
+
// ── skill ──
|
|
127
|
+
const skillInstall = (0, command_1.declareCommand)({
|
|
128
|
+
name: 'skill-install',
|
|
129
|
+
category: 'skill',
|
|
130
|
+
description: 'Install Agent Skill for cssprobe-cli (teaches agents how to use the CLI)',
|
|
131
|
+
options: z.object({
|
|
132
|
+
target: z.string().optional().describe('agent target: auto, all, opencode, claude, codex, cursor, hermes, gemini (default: auto)'),
|
|
133
|
+
local: z.boolean().optional().describe('install to current directory instead of home'),
|
|
134
|
+
path: z.string().optional().describe('custom base directory (overrides home/current)'),
|
|
135
|
+
}),
|
|
136
|
+
});
|
|
137
|
+
const skillUninstall = (0, command_1.declareCommand)({
|
|
138
|
+
name: 'skill-uninstall',
|
|
139
|
+
category: 'skill',
|
|
140
|
+
description: 'Remove Agent Skill for cssprobe-cli',
|
|
141
|
+
options: z.object({
|
|
142
|
+
target: z.string().optional().describe('agent target: auto, all, opencode, claude, codex, cursor, hermes, gemini (default: auto)'),
|
|
143
|
+
local: z.boolean().optional().describe('remove from current directory instead of home'),
|
|
144
|
+
path: z.string().optional().describe('custom base directory'),
|
|
145
|
+
}),
|
|
146
|
+
});
|
|
147
|
+
const stateImport = (0, command_1.declareCommand)({
|
|
148
|
+
name: 'state-import',
|
|
149
|
+
category: 'core',
|
|
150
|
+
description: 'Import cookies from Netscape format file into a Playwright state file',
|
|
151
|
+
args: z.object({
|
|
152
|
+
file: z.string().optional().describe('Netscape cookie file path (reads from stdin if omitted)'),
|
|
153
|
+
}),
|
|
154
|
+
options: z.object({
|
|
155
|
+
out: z.string().optional().describe('output state file path (default: ~/.cssprobe-cli/states/imported.json)'),
|
|
156
|
+
merge: z.string().optional().describe('existing state file to merge into'),
|
|
157
|
+
}),
|
|
158
|
+
});
|
|
159
|
+
const commandsArray = [
|
|
160
|
+
inspect, login, stateImport,
|
|
161
|
+
configShow, configSet, configList, configUse, configNew, configPath,
|
|
162
|
+
skillInstall, skillUninstall,
|
|
163
|
+
];
|
|
164
|
+
exports.commands = Object.fromEntries(commandsArray.map(cmd => [cmd.name, cmd]));
|
|
165
|
+
exports.inspectCommand = inspect;
|
|
166
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface MinimistOptions {
|
|
2
|
+
string?: string | string[];
|
|
3
|
+
boolean?: string | string[];
|
|
4
|
+
}
|
|
5
|
+
export interface MinimistArgs {
|
|
6
|
+
_: string[];
|
|
7
|
+
[key: string]: string | boolean | string[] | undefined;
|
|
8
|
+
}
|
|
9
|
+
export declare function minimist(args: string[], opts?: MinimistOptions): MinimistArgs;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Arguments parser — minimal minimist fork (same as playwright-cli / glitchtip-cli).
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.minimist = minimist;
|
|
5
|
+
function minimist(args, opts) {
|
|
6
|
+
if (!opts)
|
|
7
|
+
opts = {};
|
|
8
|
+
const bools = {};
|
|
9
|
+
const strings = {};
|
|
10
|
+
for (const key of toArray(opts.boolean))
|
|
11
|
+
bools[key] = true;
|
|
12
|
+
for (const key of toArray(opts.string))
|
|
13
|
+
strings[key] = true;
|
|
14
|
+
const argv = { _: [] };
|
|
15
|
+
function setArg(key, val) {
|
|
16
|
+
if (argv[key] === undefined || bools[key] || typeof argv[key] === 'boolean')
|
|
17
|
+
argv[key] = val;
|
|
18
|
+
else if (Array.isArray(argv[key]))
|
|
19
|
+
argv[key].push(val);
|
|
20
|
+
else
|
|
21
|
+
argv[key] = [argv[key], val];
|
|
22
|
+
}
|
|
23
|
+
let notFlags = [];
|
|
24
|
+
const doubleDashIndex = args.indexOf('--');
|
|
25
|
+
if (doubleDashIndex !== -1) {
|
|
26
|
+
notFlags = args.slice(doubleDashIndex + 1);
|
|
27
|
+
args = args.slice(0, doubleDashIndex);
|
|
28
|
+
}
|
|
29
|
+
for (let i = 0; i < args.length; i++) {
|
|
30
|
+
const arg = args[i];
|
|
31
|
+
let key;
|
|
32
|
+
let next;
|
|
33
|
+
if ((/^--.+=/).test(arg)) {
|
|
34
|
+
const m = arg.match(/^--([^=]+)=([\s\S]*)$/);
|
|
35
|
+
key = m[1];
|
|
36
|
+
if (bools[key])
|
|
37
|
+
throw new Error(`boolean option '--${key}' should not be passed with '=value', use '--${key}' or '--no-${key}' instead`);
|
|
38
|
+
setArg(key, m[2]);
|
|
39
|
+
}
|
|
40
|
+
else if ((/^--no-.+/).test(arg)) {
|
|
41
|
+
key = arg.match(/^--no-(.+)/)[1];
|
|
42
|
+
setArg(key, false);
|
|
43
|
+
}
|
|
44
|
+
else if ((/^--.+/).test(arg)) {
|
|
45
|
+
key = arg.match(/^--(.+)/)[1];
|
|
46
|
+
next = args[i + 1];
|
|
47
|
+
if (next !== undefined
|
|
48
|
+
&& !(/^(-|--)[^-]/).test(next)
|
|
49
|
+
&& !bools[key]) {
|
|
50
|
+
setArg(key, next);
|
|
51
|
+
i += 1;
|
|
52
|
+
}
|
|
53
|
+
else if ((/^(true|false)$/).test(next)) {
|
|
54
|
+
setArg(key, next === 'true');
|
|
55
|
+
i += 1;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
setArg(key, strings[key] ? '' : true);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else if ((/^-[^-]+/).test(arg)) {
|
|
62
|
+
const letters = arg.slice(1, -1).split('');
|
|
63
|
+
let broken = false;
|
|
64
|
+
for (let j = 0; j < letters.length; j++) {
|
|
65
|
+
next = arg.slice(j + 2);
|
|
66
|
+
if (next === '-') {
|
|
67
|
+
setArg(letters[j], next);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if ((/[A-Za-z]/).test(letters[j]) && next[0] === '=') {
|
|
71
|
+
setArg(letters[j], next.slice(1));
|
|
72
|
+
broken = true;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
if ((/[A-Za-z]/).test(letters[j])
|
|
76
|
+
&& (/-?\d+(\.\d*)?(e-?\d+)?$/).test(next)) {
|
|
77
|
+
setArg(letters[j], next);
|
|
78
|
+
broken = true;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
if (letters[j + 1] && letters[j + 1].match(/\W/)) {
|
|
82
|
+
setArg(letters[j], arg.slice(j + 2));
|
|
83
|
+
broken = true;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
setArg(letters[j], strings[letters[j]] ? '' : true);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
key = arg.slice(-1)[0];
|
|
91
|
+
if (!broken && key !== '-') {
|
|
92
|
+
if (args[i + 1]
|
|
93
|
+
&& !(/^(-|--)[^-]/).test(args[i + 1])
|
|
94
|
+
&& !bools[key]) {
|
|
95
|
+
setArg(key, args[i + 1]);
|
|
96
|
+
i += 1;
|
|
97
|
+
}
|
|
98
|
+
else if (args[i + 1] && (/^(true|false)$/).test(args[i + 1])) {
|
|
99
|
+
setArg(key, args[i + 1] === 'true');
|
|
100
|
+
i += 1;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
setArg(key, strings[key] ? '' : true);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
argv._.push(arg);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
for (const k of notFlags)
|
|
112
|
+
argv._.push(k);
|
|
113
|
+
return argv;
|
|
114
|
+
}
|
|
115
|
+
function toArray(value) {
|
|
116
|
+
if (!value)
|
|
117
|
+
return [];
|
|
118
|
+
return Array.isArray(value) ? value : [value];
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=minimist.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface Output {
|
|
2
|
+
readonly json: boolean;
|
|
3
|
+
readonly raw: boolean;
|
|
4
|
+
format(data: any): string;
|
|
5
|
+
error(message: string): never;
|
|
6
|
+
help(text: string): void;
|
|
7
|
+
version(version: string): void;
|
|
8
|
+
}
|
|
9
|
+
export declare class TextOutput implements Output {
|
|
10
|
+
readonly json = false;
|
|
11
|
+
readonly raw: boolean;
|
|
12
|
+
constructor(raw?: boolean);
|
|
13
|
+
format(data: any): string;
|
|
14
|
+
private _formatTable;
|
|
15
|
+
error(message: string): never;
|
|
16
|
+
help(text: string): void;
|
|
17
|
+
version(version: string): void;
|
|
18
|
+
}
|
|
19
|
+
export declare class JsonOutput implements Output {
|
|
20
|
+
readonly json = true;
|
|
21
|
+
readonly raw = false;
|
|
22
|
+
format(data: any): string;
|
|
23
|
+
error(message: string): never;
|
|
24
|
+
help(text: string): void;
|
|
25
|
+
version(version: string): void;
|
|
26
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JsonOutput = exports.TextOutput = void 0;
|
|
4
|
+
class TextOutput {
|
|
5
|
+
json = false;
|
|
6
|
+
raw;
|
|
7
|
+
constructor(raw = false) {
|
|
8
|
+
this.raw = raw;
|
|
9
|
+
}
|
|
10
|
+
format(data) {
|
|
11
|
+
if (this.raw)
|
|
12
|
+
return typeof data === 'string' ? data : JSON.stringify(data);
|
|
13
|
+
if (data === null || data === undefined)
|
|
14
|
+
return '(empty)';
|
|
15
|
+
if (Array.isArray(data))
|
|
16
|
+
return this._formatTable(data);
|
|
17
|
+
if (typeof data === 'object')
|
|
18
|
+
return JSON.stringify(data, null, 2);
|
|
19
|
+
return String(data);
|
|
20
|
+
}
|
|
21
|
+
_formatTable(rows) {
|
|
22
|
+
if (rows.length === 0)
|
|
23
|
+
return '(empty list)';
|
|
24
|
+
const allColumns = Object.keys(rows[0] || {});
|
|
25
|
+
const columns = allColumns.filter(col => {
|
|
26
|
+
const val = rows[0][col];
|
|
27
|
+
return val === null || val === undefined || typeof val !== 'object';
|
|
28
|
+
});
|
|
29
|
+
if (columns.length === 0)
|
|
30
|
+
return JSON.stringify(rows, null, 2);
|
|
31
|
+
const cells = rows.map((item) => columns.map((col) => {
|
|
32
|
+
const v = item[col];
|
|
33
|
+
if (v === null || v === undefined)
|
|
34
|
+
return '';
|
|
35
|
+
if (typeof v === 'object')
|
|
36
|
+
return JSON.stringify(v);
|
|
37
|
+
return String(v);
|
|
38
|
+
}));
|
|
39
|
+
cells.unshift(columns);
|
|
40
|
+
const widths = columns.map((_, ci) => Math.max(...cells.map((r) => String(r[ci]).length)));
|
|
41
|
+
return cells
|
|
42
|
+
.map((row, ri) => {
|
|
43
|
+
const line = row.map((cell, ci) => String(cell).padEnd(widths[ci])).join(' ');
|
|
44
|
+
if (ri === 0)
|
|
45
|
+
return line + '\n' + widths.map((w) => '-'.repeat(w)).join(' ');
|
|
46
|
+
return line;
|
|
47
|
+
})
|
|
48
|
+
.join('\n');
|
|
49
|
+
}
|
|
50
|
+
error(message) {
|
|
51
|
+
console.error(`Error: ${message}`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
help(text) {
|
|
55
|
+
console.log(text);
|
|
56
|
+
}
|
|
57
|
+
version(version) {
|
|
58
|
+
console.log(version);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.TextOutput = TextOutput;
|
|
62
|
+
class JsonOutput {
|
|
63
|
+
json = true;
|
|
64
|
+
raw = false;
|
|
65
|
+
format(data) {
|
|
66
|
+
return JSON.stringify(data, null, 2);
|
|
67
|
+
}
|
|
68
|
+
error(message) {
|
|
69
|
+
console.log(JSON.stringify({ isError: true, error: message }));
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
help(text) {
|
|
73
|
+
console.log(JSON.stringify({ help: text }));
|
|
74
|
+
}
|
|
75
|
+
version(version) {
|
|
76
|
+
console.log(JSON.stringify({ version }));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.JsonOutput = JsonOutput;
|
|
80
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function program(): Promise<void>;
|