@player-tools/cli 0.0.2-next.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.
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validationRenderer = exports.getTaskSymbol = exports.formatDiagnosticResults = exports.getSummary = void 0;
7
+ const vscode_languageserver_types_1 = require("vscode-languageserver-types");
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const log_symbols_1 = __importDefault(require("log-symbols"));
10
+ const elegant_spinner_1 = __importDefault(require("elegant-spinner"));
11
+ const fs_1 = require("./fs");
12
+ /** Compare the ranges and return the one that starts of finishes first */
13
+ function rangeComparator(first, second) {
14
+ if (first.start.line < second.start.line) {
15
+ return -1;
16
+ }
17
+ if (first.start.line > second.start.line) {
18
+ return 1;
19
+ }
20
+ if (first.start.character < second.start.character) {
21
+ return -1;
22
+ }
23
+ if (first.start.character > second.start.character) {
24
+ return 1;
25
+ }
26
+ return 0;
27
+ }
28
+ /** Sort a list of digs by position */
29
+ const sortDiagnostics = (validations) => {
30
+ // Sort the validations by line/char number
31
+ return validations.sort((a, b) => {
32
+ return rangeComparator(a.range, b.range);
33
+ });
34
+ };
35
+ /** Get the text representing the line range */
36
+ function getLineRange(range) {
37
+ return `${range.start.line + 1}:${range.start.character + 1}`;
38
+ }
39
+ /** Fix the plurality of a word */
40
+ function maybePlural(word, count) {
41
+ return count > 1 ? `${word}s` : word;
42
+ }
43
+ /** Get the lines representing the summary of the results */
44
+ function getSummary({ errors, warnings, skipped, fileCount, duration, }) {
45
+ return [
46
+ '\n',
47
+ (errors > 0 || warnings === 0) &&
48
+ chalk_1.default.red(`${errors} ${maybePlural('error', errors)}`),
49
+ warnings > 0 &&
50
+ chalk_1.default.yellow(`${warnings} ${maybePlural('warning', warnings)}`),
51
+ skipped !== undefined &&
52
+ skipped > 0 &&
53
+ chalk_1.default.gray(`${skipped} ${maybePlural('skipped', skipped)}`),
54
+ chalk_1.default.gray(`in ${fileCount} ${maybePlural('file', fileCount)}`),
55
+ chalk_1.default.gray(`took ${duration}ms`),
56
+ ]
57
+ .filter(Boolean)
58
+ .join(' ');
59
+ }
60
+ exports.getSummary = getSummary;
61
+ /** Format a diag for printing on the console */
62
+ function formatDiagnostic(diag, longestLine, fName) {
63
+ const type = diag.severity === vscode_languageserver_types_1.DiagnosticSeverity.Error
64
+ ? chalk_1.default.red(`${log_symbols_1.default.error} `)
65
+ : chalk_1.default.yellow(`${log_symbols_1.default.warning} `);
66
+ const msg = chalk_1.default.bold(diag.message);
67
+ const range = getLineRange(diag.range);
68
+ return [
69
+ `${type}`,
70
+ range.padEnd(longestLine),
71
+ msg,
72
+ `${fName}:${range.padEnd(longestLine)}`,
73
+ ].join(' ');
74
+ }
75
+ /** Format the results for printing on the console */
76
+ function formatDiagnosticResults(filePath, results, verbose = false) {
77
+ const count = {
78
+ errors: 0,
79
+ warnings: 0,
80
+ };
81
+ const linePrefix = ' ';
82
+ const longestLine = Math.max(...results.map((r) => getLineRange(r.range).length));
83
+ let lines = results
84
+ .map((diag) => {
85
+ if (diag.severity === vscode_languageserver_types_1.DiagnosticSeverity.Error) {
86
+ count.errors += 1;
87
+ }
88
+ else if (diag.severity === vscode_languageserver_types_1.DiagnosticSeverity.Warning) {
89
+ count.warnings += 1;
90
+ }
91
+ if (diag.severity === vscode_languageserver_types_1.DiagnosticSeverity.Error || verbose) {
92
+ return linePrefix + formatDiagnostic(diag, longestLine + 1, filePath);
93
+ }
94
+ return '';
95
+ })
96
+ .filter((line) => line !== '');
97
+ if (count.errors > 0) {
98
+ lines = ['', `${chalk_1.default.red(log_symbols_1.default.error)} ${filePath}`, ...lines, ''];
99
+ }
100
+ else if (verbose) {
101
+ if (count.warnings > 0) {
102
+ lines = [
103
+ '',
104
+ `${chalk_1.default.yellow(log_symbols_1.default.warning)} ${filePath}`,
105
+ ...lines,
106
+ '',
107
+ ];
108
+ }
109
+ else {
110
+ lines = [`${chalk_1.default.green(log_symbols_1.default.success)} ${filePath}`, ...lines];
111
+ }
112
+ }
113
+ return Object.assign(Object.assign({}, count), { lines });
114
+ }
115
+ exports.formatDiagnosticResults = formatDiagnosticResults;
116
+ const spinnerState = new WeakMap();
117
+ /** Get the symbol for a given task */
118
+ const getTaskSymbol = (task) => {
119
+ var _a;
120
+ if (task.state === 'pending' || task.state === 'idle') {
121
+ const spinner = (_a = spinnerState.get(task)) !== null && _a !== void 0 ? _a : (0, elegant_spinner_1.default)();
122
+ spinnerState.set(task, spinner);
123
+ return chalk_1.default.yellow(spinner());
124
+ }
125
+ if (task.state === 'completed' && task.error) {
126
+ return log_symbols_1.default.error;
127
+ }
128
+ if (task.state === 'completed') {
129
+ return chalk_1.default.yellow(log_symbols_1.default.success);
130
+ }
131
+ return ' ';
132
+ };
133
+ exports.getTaskSymbol = getTaskSymbol;
134
+ exports.validationRenderer = {
135
+ onUpdate(ctx) {
136
+ const { tasks } = ctx;
137
+ const output = ['Validating content'];
138
+ tasks.forEach((task) => {
139
+ var _a, _b;
140
+ if (task.state === 'completed' && task.output) {
141
+ const formattedDiags = formatDiagnosticResults(((_a = task.data) === null || _a === void 0 ? void 0 : _a.file) ? (0, fs_1.normalizePath)(task.data.file) : '', sortDiagnostics(task.output), true);
142
+ output.push(...formattedDiags.lines);
143
+ }
144
+ else {
145
+ output.push(`${(0, exports.getTaskSymbol)(task)} ${((_b = task.data) === null || _b === void 0 ? void 0 : _b.file) ? (0, fs_1.normalizePath)(task.data.file) : ''}`);
146
+ }
147
+ });
148
+ return output.join('\n');
149
+ },
150
+ onEnd(ctx) {
151
+ const count = {
152
+ errors: 0,
153
+ warnings: 0,
154
+ skipped: 0,
155
+ fileCount: ctx.tasks.length,
156
+ duration: ctx.duration,
157
+ };
158
+ ctx.tasks.forEach((t) => {
159
+ var _a, _b;
160
+ if (t.state === 'completed' && t.output) {
161
+ const formattedDiags = formatDiagnosticResults((_b = (_a = t.data) === null || _a === void 0 ? void 0 : _a.file) !== null && _b !== void 0 ? _b : '', t.output, true);
162
+ count.errors += formattedDiags.errors;
163
+ count.warnings += formattedDiags.warnings;
164
+ }
165
+ });
166
+ return [exports.validationRenderer.onUpdate(ctx), getSummary(count)].join('\n');
167
+ },
168
+ };
@@ -0,0 +1,5 @@
1
+ /** Check if an input is a directory, if it is, then swap it to a globbed path */
2
+ export declare const convertToFileGlob: (input: string[], glob: string) => string[];
3
+ /** Normalize a path for display */
4
+ export declare const normalizePath: (p: string) => string;
5
+ //# sourceMappingURL=fs.d.ts.map
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.normalizePath = exports.convertToFileGlob = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const fs_1 = __importDefault(require("fs"));
9
+ /** Check if an input is a directory, if it is, then swap it to a globbed path */
10
+ const convertToFileGlob = (input, glob) => {
11
+ return input.map((i) => {
12
+ try {
13
+ if (fs_1.default.statSync(i).isDirectory()) {
14
+ return path_1.default.join(i, glob);
15
+ }
16
+ }
17
+ catch (e) { }
18
+ return i;
19
+ });
20
+ };
21
+ exports.convertToFileGlob = convertToFileGlob;
22
+ /** Normalize a path for display */
23
+ const normalizePath = (p) => {
24
+ return path_1.default.relative(process.cwd(), p);
25
+ };
26
+ exports.normalizePath = normalizePath;
@@ -0,0 +1,52 @@
1
+ interface BaseTask<Results, Data> {
2
+ /** The state of the task */
3
+ state: 'idle' | 'pending';
4
+ /** A function to run */
5
+ run: () => Promise<Results>;
6
+ /** other metadata about the task */
7
+ data?: Data;
8
+ }
9
+ export declare type CompletedTask<Results, Data> = Omit<BaseTask<Results, Data>, 'state'> & {
10
+ /** The state of the task */
11
+ state: 'completed';
12
+ } & ({
13
+ /** The results */
14
+ output: Results;
15
+ /** An error if any */
16
+ error?: never;
17
+ } | {
18
+ /** The error if any */
19
+ error: Error;
20
+ /** No output on error */
21
+ output?: never;
22
+ });
23
+ export declare type Task<ResultsType, Data> = BaseTask<ResultsType, Data> | CompletedTask<ResultsType, Data>;
24
+ export interface TaskProgressRenderer<ResultType, Data = unknown> {
25
+ /** Call back to paint update on the page */
26
+ onUpdate: (ctx: {
27
+ /** The tasks that are running */
28
+ tasks: Array<Task<ResultType, Data>>;
29
+ }) => string;
30
+ /** Called for a summary */
31
+ onEnd: (ctx: {
32
+ /** The completed tasks */
33
+ tasks: Array<CompletedTask<ResultType, Data>>;
34
+ /** Number of ms it took to run */
35
+ duration: number;
36
+ }) => string;
37
+ }
38
+ interface TaskRunner<R, Data> {
39
+ /** The list of tasks */
40
+ tasks: Array<Task<R, Data>>;
41
+ /** A trigger to start it */
42
+ run: () => Promise<Array<CompletedTask<R, Data>>>;
43
+ }
44
+ /** Create a runner to kick off tasks in parallel */
45
+ export declare const createTaskRunner: <R, D>({ tasks, renderer, }: {
46
+ /** A list of tasks to run */
47
+ tasks: Pick<BaseTask<R, D>, "run" | "data">[];
48
+ /** How to report progress */
49
+ renderer: TaskProgressRenderer<R, D>;
50
+ }) => TaskRunner<R, D>;
51
+ export {};
52
+ //# sourceMappingURL=task-runner.d.ts.map
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.createTaskRunner = void 0;
16
+ const log_update_1 = __importDefault(require("log-update"));
17
+ /** Create a runner to kick off tasks in parallel */
18
+ const createTaskRunner = ({ tasks, renderer, }) => {
19
+ const statefulTasks = tasks.map((t) => {
20
+ return Object.assign(Object.assign({}, t), { state: 'idle' });
21
+ });
22
+ /** Kick off the task list */
23
+ const run = () => __awaiter(void 0, void 0, void 0, function* () {
24
+ const startTime = Date.now();
25
+ let ended = false;
26
+ const paintInterval = setInterval(() => {
27
+ if (ended) {
28
+ return;
29
+ }
30
+ const output = renderer.onUpdate({ tasks: statefulTasks });
31
+ if (process.stdout.isTTY) {
32
+ (0, log_update_1.default)(output);
33
+ }
34
+ }, 10);
35
+ yield Promise.all(statefulTasks.map((t) => __awaiter(void 0, void 0, void 0, function* () {
36
+ t.state = 'pending';
37
+ try {
38
+ const r = yield t.run();
39
+ t.state = 'completed';
40
+ t.output = r;
41
+ }
42
+ catch (e) {
43
+ if (e instanceof Error) {
44
+ t.state = 'completed';
45
+ t.error = e;
46
+ }
47
+ }
48
+ })));
49
+ ended = true;
50
+ clearInterval(paintInterval);
51
+ const duration = Date.now() - startTime;
52
+ const output = renderer.onEnd({
53
+ duration,
54
+ tasks: statefulTasks,
55
+ });
56
+ console.log(output);
57
+ log_update_1.default.done();
58
+ return statefulTasks;
59
+ });
60
+ return {
61
+ tasks: statefulTasks,
62
+ run,
63
+ };
64
+ };
65
+ exports.createTaskRunner = createTaskRunner;
@@ -0,0 +1 @@
1
+ {"version":"0.0.2-next.0","commands":{"dsl:compile":{"id":"dsl:compile","description":"Compile Player DSL files into JSON","strict":true,"pluginName":"@player-tools/cli","pluginAlias":"@player-tools/cli","pluginType":"core","aliases":[],"flags":{"config":{"name":"config","type":"option","char":"c","description":"Path to a specific config file to load.\nBy default, will automatically search for an rc or config file to load","multiple":false},"input":{"name":"input","type":"option","char":"i","description":"An input directory to compile.\nAny jsx/ts/tsx files will be loaded via babel-require automatically.","multiple":false},"output":{"name":"output","type":"option","char":"o","description":"Output directory to write results to.","multiple":false},"skip-validation":{"name":"skip-validation","type":"boolean","description":"Option to skip validating the generated JSON","allowNo":false},"exp":{"name":"exp","type":"boolean","description":"Use experimental language features","allowNo":false}},"args":[],"_globalFlags":{}},"json:validate":{"id":"json:validate","description":"Validate Player JSON content","strict":true,"pluginName":"@player-tools/cli","pluginAlias":"@player-tools/cli","pluginType":"core","aliases":[],"flags":{"config":{"name":"config","type":"option","char":"c","description":"Path to a specific config file to load.\nBy default, will automatically search for an rc or config file to load","multiple":false},"files":{"name":"files","type":"option","char":"f","description":"A list of files or globs to validate","multiple":true},"exp":{"name":"exp","type":"boolean","description":"Use experimental language features","allowNo":false}},"args":[],"_globalFlags":{}},"xlr:compile":{"id":"xlr:compile","description":"Compiles typescript files to XLRs format","strict":true,"pluginName":"@player-tools/cli","pluginAlias":"@player-tools/cli","pluginType":"core","aliases":[],"flags":{"config":{"name":"config","type":"option","char":"c","description":"Path to a specific config file to load.\nBy default, will automatically search for an rc or config file to load","multiple":false},"input":{"name":"input","type":"option","char":"i","description":"An input directory to search for types to export","multiple":false,"default":"./src"},"output":{"name":"output","type":"option","char":"o","description":"Output directory to write results to.","multiple":false,"default":"./dist"},"mode":{"name":"mode","type":"option","char":"m","description":"Search strategy for types to export: plugin (default, looks for exported EnchancedPlayerPlugin classes) or type (all exported types)","helpValue":"(plugin|types)","multiple":false,"options":["plugin","types"],"default":"plugin"}},"args":[],"_globalFlags":{}},"xlr:convert":{"id":"xlr:convert","description":"Exports XLRs files to a specific language","strict":true,"pluginName":"@player-tools/cli","pluginAlias":"@player-tools/cli","pluginType":"core","aliases":[],"flags":{"config":{"name":"config","type":"option","char":"c","description":"Path to a specific config file to load.\nBy default, will automatically search for an rc or config file to load","multiple":false},"input":{"name":"input","type":"option","char":"i","description":"An input directory to search for types to export","multiple":false,"default":"./dist"},"output":{"name":"output","type":"option","char":"o","description":"Output directory to write results to.","multiple":false},"lang":{"name":"lang","type":"option","char":"l","description":"Search strategy for types to export: plugin (default, looks for exported EnchancedPlayerPlugin classes) or type (all exported types)","helpValue":"(TypeScript)","multiple":false,"options":["TypeScript"]}},"args":[],"_globalFlags":{}}}}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@player-tools/cli",
3
+ "version": "0.0.2-next.0",
4
+ "private": false,
5
+ "publishConfig": {
6
+ "registry": "https://registry.npmjs.org"
7
+ },
8
+ "peerDependencies": {},
9
+ "dependencies": {
10
+ "@babel/core": "^7.15.5",
11
+ "@babel/preset-env": "^7.15.6",
12
+ "@babel/preset-react": "^7.14.5",
13
+ "@babel/preset-typescript": "^7.15.0",
14
+ "@babel/plugin-transform-react-jsx-source": "^7.18.6",
15
+ "@babel/register": "^7.17.7",
16
+ "@types/babel__register": "^7.17.0",
17
+ "@oclif/core": "1.9.0",
18
+ "@oclif/plugin-legacy": "^1.2.7",
19
+ "chalk": "^4.0.1",
20
+ "cosmiconfig": "^7.0.1",
21
+ "cross-fetch": "^3.0.5",
22
+ "elegant-spinner": "^2.0.0",
23
+ "figures": "^3.0.0",
24
+ "globby": "^11.0.1",
25
+ "log-symbols": "^4.0.0",
26
+ "log-update": "^4.0.0",
27
+ "mkdirp": "^1.0.4",
28
+ "vscode-languageserver-textdocument": "^1.0.1",
29
+ "vscode-languageserver-types": "^3.15.1",
30
+ "@player-tools/dsl": "0.0.2-next.0",
31
+ "@player-tools/language-service": "0.0.2-next.0",
32
+ "@player-tools/xlr-sdk": "0.0.2-next.0",
33
+ "@player-tools/xlr-utils": "0.0.2-next.0",
34
+ "@player-tools/xlr-converters": "0.0.2-next.0"
35
+ },
36
+ "main": "./dist/index.js",
37
+ "module": "dist/index.esm.js",
38
+ "typings": "dist/index.d.ts",
39
+ "files": [
40
+ "bin",
41
+ "dist",
42
+ "oclif.manifest.json"
43
+ ],
44
+ "oclif": {
45
+ "bin": "player",
46
+ "dirname": "player",
47
+ "topicSeparator": " ",
48
+ "commands": "./dist/commands"
49
+ },
50
+ "bin": {
51
+ "player": "bin/run"
52
+ }
53
+ }