@player-cli/cli 0.0.2--canary.6.49

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.
Files changed (56) hide show
  1. package/README.md +82 -0
  2. package/bin/dev +17 -0
  3. package/bin/run +11 -0
  4. package/dist/commands/dependency-versions/check.d.ts +19 -0
  5. package/dist/commands/dependency-versions/check.js +270 -0
  6. package/dist/commands/dsl/compile.d.ts +20 -0
  7. package/dist/commands/dsl/compile.js +173 -0
  8. package/dist/commands/dsl/validate.d.ts +15 -0
  9. package/dist/commands/dsl/validate.js +142 -0
  10. package/dist/commands/json/validate.d.ts +18 -0
  11. package/dist/commands/json/validate.js +91 -0
  12. package/dist/commands/xlr/compile.d.ts +24 -0
  13. package/dist/commands/xlr/compile.js +153 -0
  14. package/dist/commands/xlr/convert.d.ts +20 -0
  15. package/dist/commands/xlr/convert.js +77 -0
  16. package/dist/config.d.ts +39 -0
  17. package/dist/config.js +3 -0
  18. package/dist/index.d.ts +7 -0
  19. package/dist/index.js +12 -0
  20. package/dist/plugins/LSPAssetsPlugin.d.ts +50 -0
  21. package/dist/plugins/LSPAssetsPlugin.js +47 -0
  22. package/dist/plugins/LSPPluginPlugin.d.ts +11 -0
  23. package/dist/plugins/LSPPluginPlugin.js +22 -0
  24. package/dist/plugins/LSPTransformsPlugin.d.ts +12 -0
  25. package/dist/plugins/LSPTransformsPlugin.js +17 -0
  26. package/dist/plugins/index.d.ts +33 -0
  27. package/dist/plugins/index.js +7 -0
  28. package/dist/utils/babel-register.d.ts +3 -0
  29. package/dist/utils/babel-register.js +19 -0
  30. package/dist/utils/base-command.d.ts +26 -0
  31. package/dist/utils/base-command.js +155 -0
  32. package/dist/utils/compilation-context.d.ts +53 -0
  33. package/dist/utils/compilation-context.js +57 -0
  34. package/dist/utils/compile-renderer.d.ts +13 -0
  35. package/dist/utils/compile-renderer.js +42 -0
  36. package/dist/utils/compiler-options.d.ts +3 -0
  37. package/dist/utils/compiler-options.js +16 -0
  38. package/dist/utils/diag-renderer.d.ts +31 -0
  39. package/dist/utils/diag-renderer.js +224 -0
  40. package/dist/utils/fs.d.ts +9 -0
  41. package/dist/utils/fs.js +39 -0
  42. package/dist/utils/log-levels.d.ts +11 -0
  43. package/dist/utils/log-levels.js +21 -0
  44. package/dist/utils/task-runner.d.ts +59 -0
  45. package/dist/utils/task-runner.js +59 -0
  46. package/dist/utils/xlr/consts.d.ts +7 -0
  47. package/dist/utils/xlr/consts.js +18 -0
  48. package/dist/utils/xlr/visitors/file.d.ts +5 -0
  49. package/dist/utils/xlr/visitors/file.js +25 -0
  50. package/dist/utils/xlr/visitors/index.d.ts +4 -0
  51. package/dist/utils/xlr/visitors/index.js +7 -0
  52. package/dist/utils/xlr/visitors/plugin.d.ts +5 -0
  53. package/dist/utils/xlr/visitors/plugin.js +167 -0
  54. package/dist/utils/xlr/visitors/types.d.ts +13 -0
  55. package/dist/utils/xlr/visitors/types.js +3 -0
  56. package/package.json +58 -0
package/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # Player CLI
2
+
3
+ ## Config
4
+
5
+ Config files are able to customize the behavior of the CLI commands without requiring args. Behavior specific to execution can leverage `plugins`, which can be composed together using `presets`. Full configs can also be shared using `extensions`.
6
+
7
+ To resolve a full configuration, the `extension` is taken as the base, the `presets` are applied in order, then local `plugins`.
8
+ The format is similar to `eslint`, `babel` and other .rc/json/js based approaches.
9
+
10
+ Config files are searched using cosmiconfig, which will look for:
11
+
12
+ - a `player` property in package.json
13
+ - a `.playerrc` file in JSON or YAML format
14
+ - a `.player.json`, `.playerrc.yaml`, `.playerrc.yml`, `.playerrc.js`, or `.playerrc.cjs` file
15
+ - a `player.config.js` or `player.config.cjs` CommonJS module exporting an object
16
+
17
+ Example:
18
+
19
+ ```js
20
+ module.exports = {
21
+ extends: '@my-scope/base',
22
+ plugins: [
23
+ 'plugin-npm-package',
24
+ ['some-plugin-with-config', { config: true }],
25
+ {
26
+ // Plugins can also be defined inline
27
+ handler: () => {},
28
+ },
29
+ ],
30
+ };
31
+ ```
32
+
33
+ Options defined via the CLI arguments will take precedence over the config files (for things that overlap).
34
+
35
+ ## Plugins
36
+
37
+ Plugins are the way to change runtime behavior of the CLI actions. This includes augmenting the behavior of the DSL compiler, language-service, and more.
38
+
39
+ # Commands
40
+
41
+ <!-- commands -->
42
+
43
+ - [`player dsl compile`](#player-dsl-compile)
44
+
45
+ ## `player dsl compile`
46
+
47
+ Compile Player DSL files into JSON
48
+
49
+ ```
50
+ USAGE
51
+ $ player dsl compile -i <value> [-c <value>] [-o <value>] [--skip-validation]
52
+
53
+ FLAGS
54
+ -c, --config=<value> Path to a specific config file to load.
55
+ By default, will automatically search for an rc or config file to load
56
+ -i, --input=<value> (required) An input directory to compile.
57
+ Any jsx/ts/tsx files will be loaded via babel-require automatically.
58
+ -o, --output=<value> [default: _out] Output directory to write results to
59
+ --skip-validation Option to skip validating the generated JSON
60
+
61
+ DESCRIPTION
62
+ Compile Player DSL files into JSON
63
+ ```
64
+
65
+ ## `player dsl validate`
66
+
67
+ Runs isolated TSC type-checking instance on authored Player DSL Typescript files.
68
+
69
+ ```
70
+ USAGE
71
+ $ player dsl validate [-f <value>] [-c <value>]
72
+
73
+ FLAGS
74
+ -c, --config=<value> Path to a specific config file to load.
75
+ By default, will automatically search for an rc or config file to load
76
+ -f, --files=<value>... A list of files or globs to validate
77
+
78
+ DESCRIPTION
79
+ Runs isolated TSC type-checking instance on authored Player DSL Typescript files.
80
+ ```
81
+
82
+ <!-- commandsstop -->
package/bin/dev ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+
3
+ const oclif = require("@oclif/core");
4
+
5
+ const path = require("path");
6
+ const project = path.join(__dirname, "..", "tsconfig.json");
7
+
8
+ // In dev mode -> use ts-node and dev plugins
9
+ process.env.NODE_ENV = "development";
10
+
11
+ require("ts-node").register({ project });
12
+
13
+ // In dev mode, always show stack traces
14
+ oclif.settings.debug = true;
15
+
16
+ // Start the CLI
17
+ oclif.run().then(oclif.flush).catch(oclif.Errors.handle);
package/bin/run ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+
3
+ const oclif = require("@oclif/core");
4
+
5
+ // Setting this to production break source-map generation for dsl content
6
+ process.env.NODE_ENV = "development";
7
+
8
+ oclif
9
+ .run()
10
+ .then(require("@oclif/core/flush"))
11
+ .catch(require("@oclif/core/handle"));
@@ -0,0 +1,19 @@
1
+ import { BaseCommand } from "../../utils/base-command";
2
+ /** A command to get @player-ui/@player-tools dependency versions and issue warnings/recommendations based on them */
3
+ export default class DependencyVersionsCheck extends BaseCommand {
4
+ static summary: string;
5
+ static description: string;
6
+ static flags: {
7
+ verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
8
+ path: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ ignore: import("@oclif/core/lib/interfaces").OptionFlag<string[]>;
10
+ config: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
11
+ loglevel: import("@oclif/core/lib/interfaces").OptionFlag<string>;
12
+ };
13
+ private getOptions;
14
+ run(): Promise<{
15
+ /** the status code */
16
+ exitCode: number;
17
+ }>;
18
+ }
19
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1,270 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const globby_1 = tslib_1.__importDefault(require("globby"));
5
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
6
+ const fs_extra_1 = tslib_1.__importDefault(require("fs-extra")); // fse rather than fs makes unit testing easier with mocking
7
+ const easy_table_1 = tslib_1.__importDefault(require("easy-table"));
8
+ const child_process_1 = tslib_1.__importDefault(require("child_process"));
9
+ const core_1 = require("@oclif/core");
10
+ const base_command_1 = require("../../utils/base-command");
11
+ /** A command to get @player-ui/@player-tools dependency versions and issue warnings/recommendations based on them */
12
+ class DependencyVersionsCheck extends base_command_1.BaseCommand {
13
+ static summary = "Checks for @player-ui/@player-tools dependency version mismatches and issues warnings/solutions accordingly";
14
+ static description = `Consider the following:
15
+ - The interpretation of TOP-LEVEL and NESTED dependencies is as follows:
16
+ a. TOP-LEVEL dependencies only have one 'node_modules' in their path
17
+ b. NESTED dependencies have more than one 'node_modules' in their path
18
+ - @player-ui/@player-tools dependencies are fetched not only from inside the 'node_modules' at the top of the repository in which it is run but also from 'node_modules' in sub-directories.
19
+ For example, if you have some 'node_modules' inside of a 'packages' folder that contains @player-ui/@player-tools dependencies, then these will also be fetched.
20
+ The display of such dependencies also depends on the first bullet point.
21
+ `;
22
+ static flags = {
23
+ ...base_command_1.BaseCommand.flags,
24
+ verbose: core_1.Flags.boolean({
25
+ char: "v",
26
+ description: "Give verbose description",
27
+ }),
28
+ path: core_1.Flags.boolean({
29
+ char: "p",
30
+ description: "Outputs full path to dependency",
31
+ }),
32
+ ignore: core_1.Flags.string({
33
+ char: "i",
34
+ description: "Ignore the specified pattern(s) when outputting results. Note multiple patterns can be passed",
35
+ multiple: true,
36
+ }),
37
+ };
38
+ async getOptions() {
39
+ const { flags } = await this.parse(DependencyVersionsCheck);
40
+ return {
41
+ verbose: flags.verbose,
42
+ path: flags.path,
43
+ ignore: flags.ignore,
44
+ };
45
+ }
46
+ async run() {
47
+ const results = {
48
+ exitCode: 0,
49
+ };
50
+ // Note: please do not easily change these exit codes, they are used for exit code detection in Jenkins pipeline(s)
51
+ const WARNING_EXIT_CODE = 1;
52
+ const NOT_RUN_AT_REPO_ROOT_EXIT_CODE = 2;
53
+ const chalkNegative = chalk_1.default.bgRed.white;
54
+ const chalkPositive = chalk_1.default.bgGreen;
55
+ const localGithubRepoRoot = child_process_1.default
56
+ .execSync("git rev-parse --show-toplevel")
57
+ .toString()
58
+ .trimEnd();
59
+ const currentDirectory = process.cwd();
60
+ if (localGithubRepoRoot !== currentDirectory) {
61
+ console.log(`${chalkNegative("ERROR:")} cannot run the CLI in ${currentDirectory}`);
62
+ console.log(`Please run the CLI in the root of the repository, ${localGithubRepoRoot}`);
63
+ results.exitCode = NOT_RUN_AT_REPO_ROOT_EXIT_CODE;
64
+ this.exit(results.exitCode);
65
+ return results;
66
+ }
67
+ const { verbose, path, ignore } = await this.getOptions();
68
+ console.log("Consider using the --help flag for more information about this command.");
69
+ if (!verbose) {
70
+ console.log("For more comprehensive logging, consider adding the -v flag.");
71
+ }
72
+ if (!path) {
73
+ console.log("For logging with full path to the dependency rather than with '➡', consider adding the -p flag.");
74
+ }
75
+ if (ignore) {
76
+ console.log("All output based on the versions/dependencies yielded after eliminating the patterns specified by the -i flag.");
77
+ }
78
+ else {
79
+ console.log("To add string pattern(s) for files to exclude, consider adding them after the -i flag.");
80
+ }
81
+ console.log("Inspecting the @player-ui/@player-tools dependencies in the current repository...");
82
+ let packageJsons = globby_1.default.sync("**/node_modules/{@player,@player-language,@web-player}/*/package.json");
83
+ if (ignore) {
84
+ // It is necessary to filter here rather than to pass extra options to globSync.
85
+ // This is because we need want to filter based on partial matches of the file path string
86
+ // whereas any filtering of globSync itself is heavily based on the file path as part of the system
87
+ // and not the file as a simple string.
88
+ packageJsons = packageJsons.filter((packageJson) => {
89
+ return !ignore.some((patternToIgnore) => packageJson.includes(patternToIgnore));
90
+ });
91
+ }
92
+ // Initialize the maps storing the dependency versions mapping to the packages with that version
93
+ const versionToTopLevelDependencyMap = {};
94
+ const versionToNestedDependencyMap = {};
95
+ // Populate the dependency maps
96
+ for (const packageJsonFile of packageJsons) {
97
+ const { version } = JSON.parse(fs_extra_1.default.readFileSync(packageJsonFile, "utf8"));
98
+ // top-level dependencies only have `node_modules` occurring once in their path
99
+ const isTopLevelDependency = (packageJsonFile.match(/node_modules/g) || []).length === 1;
100
+ const mapToUpdate = isTopLevelDependency
101
+ ? versionToTopLevelDependencyMap
102
+ : versionToNestedDependencyMap;
103
+ if (version in mapToUpdate) {
104
+ mapToUpdate[version].push(packageJsonFile);
105
+ }
106
+ else {
107
+ mapToUpdate[version] = [packageJsonFile];
108
+ }
109
+ }
110
+ const topLevelVersions = Object.keys(versionToTopLevelDependencyMap);
111
+ const nestedVersions = Object.keys(versionToNestedDependencyMap);
112
+ /**
113
+ * copied from https://www.npmjs.com/package/semver-compare?activeTab=code
114
+ * rather than yarn-installed since its short.
115
+ *
116
+ * @returns the result of comparison
117
+ */
118
+ function cmp(a, b) {
119
+ const pa = a.split(".");
120
+ const pb = b.split(".");
121
+ for (let i = 0; i < 3; i++) {
122
+ const na = Number(pa[i]);
123
+ const nb = Number(pb[i]);
124
+ if (na > nb)
125
+ return 1;
126
+ if (nb > na)
127
+ return -1;
128
+ if (!isNaN(na) && isNaN(nb))
129
+ return 1;
130
+ if (isNaN(na) && !isNaN(nb))
131
+ return -1;
132
+ }
133
+ return 0;
134
+ }
135
+ const sortedTopLevelVersions = topLevelVersions.sort(cmp);
136
+ const sortedNestedVersions = nestedVersions.sort(cmp);
137
+ const topLevelDependenciesTable = new easy_table_1.default();
138
+ const nestedDependenciesTable = new easy_table_1.default();
139
+ const highestTopLevelVersion = sortedTopLevelVersions[sortedTopLevelVersions.length - 1];
140
+ const highestNestedVersion = sortedNestedVersions[sortedNestedVersions.length - 1];
141
+ const singleVersionsExist = topLevelVersions.length === 1 && nestedVersions.length === 1;
142
+ const singleVersionsMatch = singleVersionsExist && topLevelVersions[0] === nestedVersions[0];
143
+ const singleVersionsMismatch = singleVersionsExist && topLevelVersions[0] !== nestedVersions[0];
144
+ const topLevelVersionsExist = topLevelVersions.length > 0;
145
+ const nestedVersionsExist = nestedVersions.length > 0;
146
+ const multipleTopLevelVersionsDetected = topLevelVersions.length > 1;
147
+ const multipleNestedVersionsDetected = nestedVersions.length > 1;
148
+ /**
149
+ * Formats the path to the dependency
150
+ *
151
+ * @param fullPath
152
+ * @returns the formatted path with ➡ arrows for the CLI user to follow
153
+ */
154
+ function formatDependencyPath(fullPath) {
155
+ const pathArrayWithoutNodeModules = fullPath.split("node_modules/");
156
+ let formattedPath = "";
157
+ for (let i = 0; i < pathArrayWithoutNodeModules.length; i++) {
158
+ if (pathArrayWithoutNodeModules[i] !== "") {
159
+ formattedPath += ` ➡ ${pathArrayWithoutNodeModules[i]}`;
160
+ }
161
+ }
162
+ formattedPath = formattedPath.replace("/package.json", ""); // remove /package.json at the end
163
+ return formattedPath;
164
+ }
165
+ /**
166
+ * Prints the formatted dependencyTable
167
+ *
168
+ * @param printsTopLevelTable - whether to print the top-level table or not
169
+ */
170
+ function printTable(versionToDependencyMap, sortedVersions, table) {
171
+ sortedVersions.forEach(function (version) {
172
+ const dependencies = versionToDependencyMap[version];
173
+ const msg = path
174
+ ? "Path to dependency's package.json"
175
+ : "How to find dependency";
176
+ const firstDependency = path
177
+ ? dependencies[0]
178
+ : formatDependencyPath(dependencies[0]);
179
+ table.cell("Version", version);
180
+ table.cell(msg, firstDependency);
181
+ table.newRow();
182
+ const maxNumberOfDepsToPrint = verbose
183
+ ? dependencies.length
184
+ : Math.min(3, dependencies.length); // in non-verbose, print out at most 3 dependencies
185
+ const numberOfDepsNotPrintedInNonVerbose = dependencies.length - maxNumberOfDepsToPrint;
186
+ for (let i = 1; i < maxNumberOfDepsToPrint; i++) {
187
+ table.cell("Version", "");
188
+ const dependency = path
189
+ ? dependencies[i]
190
+ : formatDependencyPath(dependencies[i]);
191
+ table.cell(msg, dependency);
192
+ table.newRow();
193
+ }
194
+ if (numberOfDepsNotPrintedInNonVerbose > 0) {
195
+ table.cell("Version", "");
196
+ const notPrintedMsg = `... ${numberOfDepsNotPrintedInNonVerbose} other dependencies not printed in non-verbose mode.`;
197
+ table.cell(msg, notPrintedMsg);
198
+ table.newRow();
199
+ }
200
+ });
201
+ console.log(table.toString());
202
+ }
203
+ if (topLevelVersionsExist) {
204
+ console.log("\nTOP-LEVEL @player-ui/@player-tools DEPENDENCIES:");
205
+ printTable(versionToTopLevelDependencyMap, sortedTopLevelVersions, topLevelDependenciesTable);
206
+ }
207
+ if (nestedVersionsExist) {
208
+ console.log("\nNESTED @player-ui/@player-tools DEPENDENCIES:");
209
+ printTable(versionToNestedDependencyMap, sortedNestedVersions, nestedDependenciesTable);
210
+ }
211
+ if ((!topLevelVersionsExist && nestedVersions.length === 1) ||
212
+ (!nestedVersionsExist && topLevelVersions.length === 1) ||
213
+ (!nestedVersionsExist && !topLevelVersionsExist) ||
214
+ singleVersionsMatch) {
215
+ if (singleVersionsMatch) {
216
+ console.log("Unique top-level and nested @player-ui/@player-tools versions match. ");
217
+ }
218
+ if (!topLevelVersionsExist && nestedVersions.length === 1) {
219
+ console.log(`No top-level @player-ui/@player-tools dependencies exist. Only a single nested @player-ui/@player-tools version exists, ${nestedVersions[0]}`);
220
+ }
221
+ if (!nestedVersionsExist && topLevelVersions.length === 1) {
222
+ console.log(`No nested @player-ui/@player-tools dependencies exist. Only a single top-level @player-ui/@player-tools version exists, ${topLevelVersions[0]}`);
223
+ }
224
+ if (!nestedVersionsExist && !topLevelVersionsExist) {
225
+ console.log("No @player-ui/@player-tools dependencies exist.");
226
+ }
227
+ console.log("There are no issues related to @player-ui/@player-tools dependency versioning. You are good to go! ");
228
+ this.exit(results.exitCode);
229
+ return results;
230
+ }
231
+ console.log(chalkNegative("WARNINGS:"));
232
+ if (multipleTopLevelVersionsDetected) {
233
+ console.log("- There are multiple top-level @player-ui/@player-tools dependency versions.");
234
+ }
235
+ if (multipleNestedVersionsDetected) {
236
+ console.log("- There are multiple nested @player-ui/@player-tools dependency versions.");
237
+ }
238
+ if (singleVersionsMismatch) {
239
+ console.log("- Mismatch between the top-level and the nested @player-ui/@player-tools dependency.");
240
+ }
241
+ console.log(chalkPositive("RECOMMENDATIONS:"));
242
+ if (multipleTopLevelVersionsDetected) {
243
+ console.log(`- Resolve all top-level @player-ui/@player-tools dependencies to the same version. Consider updating them to the latest player version you have, ${highestTopLevelVersion}. When all top-level @player-ui/@player-tools dependencies are resolved, run the current CLI again to obtain recommendations about nested @player-ui/@player-tools dependencies.`);
244
+ }
245
+ else if (highestTopLevelVersion && highestNestedVersion) {
246
+ // highestTopLevelVersion && highestNestedVersion defined means: single top-level version, one or more nested versions
247
+ if (cmp(highestTopLevelVersion, highestNestedVersion) >= 1) {
248
+ // when only a single top-level version is detected, it is simply the highest
249
+ console.log(`- The highest @player-ui/@player-tools version is ${highestTopLevelVersion} at the top level. Please add resolutions for all nested @player-ui/@player-tools versions to this version or bump the nested versions to it.`);
250
+ }
251
+ else {
252
+ console.log(`- The highest @player-ui/@player-tools version is ${highestNestedVersion} at the nested level. Please bump the top-level version, ${highestTopLevelVersion}, to ${highestNestedVersion}.`);
253
+ if (multipleNestedVersionsDetected) {
254
+ console.log(`- Also, please add resolutions or bump the versions for nested @player-ui/@player-tools dependencies whose version is not ${highestNestedVersion}.`);
255
+ }
256
+ }
257
+ }
258
+ else if (highestNestedVersion && multipleNestedVersionsDetected) {
259
+ // no top-level version defined, multiple nested versions
260
+ console.log(`- The highest @player-ui/@player-tools version is ${highestNestedVersion} at the nested level. Please add resolutions for all nested @player-ui/@player-tools versions to this version or bump the nested versions to it.`);
261
+ }
262
+ // Although no errors have occurred when the code reaches here, a non-zero exit code of WARNING_EXIT_CODE = 1 is still used to indicate
263
+ // the idea of "warnings" being issued due to dependency version discrepancies
264
+ results.exitCode = WARNING_EXIT_CODE;
265
+ this.exit(results.exitCode);
266
+ return results;
267
+ }
268
+ }
269
+ exports.default = DependencyVersionsCheck;
270
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1,20 @@
1
+ import { BaseCommand } from "../../utils/base-command";
2
+ /** A command to compile player DSL content into JSON */
3
+ export default class DSLCompile extends BaseCommand {
4
+ static description: string;
5
+ static flags: {
6
+ input: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
7
+ output: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
8
+ "skip-validation": import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ exp: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ severity: import("@oclif/core/lib/interfaces").OptionFlag<string>;
11
+ config: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
12
+ loglevel: import("@oclif/core/lib/interfaces").OptionFlag<string>;
13
+ };
14
+ private getOptions;
15
+ run(): Promise<{
16
+ /** the status code */
17
+ exitCode: number;
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const core_1 = require("@oclif/core");
5
+ const globby_1 = tslib_1.__importDefault(require("globby"));
6
+ const path_1 = tslib_1.__importDefault(require("path"));
7
+ const fs_1 = require("fs");
8
+ const mkdirp_1 = tslib_1.__importDefault(require("mkdirp"));
9
+ const log_symbols_1 = tslib_1.__importDefault(require("log-symbols"));
10
+ const figures_1 = tslib_1.__importDefault(require("figures"));
11
+ const chalk_1 = tslib_1.__importDefault(require("chalk"));
12
+ const dsl_1 = require("@player-tools/dsl");
13
+ const base_command_1 = require("../../utils/base-command");
14
+ const fs_2 = require("../../utils/fs");
15
+ const babel_register_1 = require("../../utils/babel-register");
16
+ const validate_1 = tslib_1.__importDefault(require("../json/validate"));
17
+ const validate_2 = tslib_1.__importDefault(require("./validate"));
18
+ /** A command to compile player DSL content into JSON */
19
+ class DSLCompile extends base_command_1.BaseCommand {
20
+ static description = "Compile Player DSL files into JSON";
21
+ static flags = {
22
+ ...base_command_1.BaseCommand.flags,
23
+ input: core_1.Flags.string({
24
+ char: "i",
25
+ description: "An input directory to compile.\nAny jsx/ts/tsx files will be loaded via babel-require automatically.",
26
+ }),
27
+ output: core_1.Flags.string({
28
+ char: "o",
29
+ description: "Output directory to write results to.",
30
+ }),
31
+ "skip-validation": core_1.Flags.boolean({
32
+ description: "Option to skip validating the generated JSON",
33
+ }),
34
+ exp: core_1.Flags.boolean({
35
+ description: "Use experimental language features",
36
+ default: false,
37
+ }),
38
+ severity: core_1.Flags.string({
39
+ char: "s",
40
+ description: "The severity of validation issues",
41
+ options: ["error", "warn"],
42
+ default: "error",
43
+ }),
44
+ };
45
+ async getOptions() {
46
+ const { flags } = await this.parse(DSLCompile);
47
+ const config = await this.getPlayerConfig();
48
+ const input = flags.input ?? config.dsl?.src;
49
+ const { exp } = flags;
50
+ if (!input) {
51
+ throw new Error(`Input files are required for DSL compilation`);
52
+ }
53
+ return {
54
+ input,
55
+ output: flags.output ?? config.dsl?.outDir ?? "_out",
56
+ skipValidation: flags["skip-validation"] ?? config.dsl?.skipValidation ?? false,
57
+ exp,
58
+ severity: flags.severity,
59
+ loglevel: flags.loglevel,
60
+ };
61
+ }
62
+ async run() {
63
+ const { input, output, skipValidation, exp, severity, loglevel } = await this.getOptions();
64
+ const files = await (0, globby_1.default)((0, fs_2.convertToFileGlob)([input], "**/*.(tsx|jsx|js|ts)"), {
65
+ expandDirectories: true,
66
+ });
67
+ const results = {
68
+ exitCode: 0,
69
+ };
70
+ (0, babel_register_1.registerForPaths)();
71
+ this.debug("Found %i files to process", files.length);
72
+ if (!skipValidation) {
73
+ await validate_2.default.run(["-f", input, "-s", severity]);
74
+ }
75
+ const context = await this.createCompilerContext();
76
+ /** Compile a file from the DSL format into JSON */
77
+ const compileFile = async (file) => {
78
+ // Check if any plugin wants to skip this file
79
+ const shouldSkipCompilation = await context.hooks.skipCompilation.call(file);
80
+ if (shouldSkipCompilation) {
81
+ this.log(`${log_symbols_1.default.info} Skipping compilation for %s`, (0, fs_2.normalizePath)(file));
82
+ return;
83
+ }
84
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
85
+ const requiredModule = require(path_1.default.resolve(file));
86
+ const defaultExport = requiredModule.default;
87
+ if (!defaultExport) {
88
+ return;
89
+ }
90
+ const preProcessedValue = await context.dslCompiler.hooks.preProcessFlow.call(defaultExport);
91
+ const { type: contentType, extension: ext } = (await context.hooks.identifyContentType.call(file, preProcessedValue)) || {
92
+ type: (0, dsl_1.fingerprintContent)(preProcessedValue, file) || "unknown",
93
+ extension: ".json",
94
+ };
95
+ let relativePath = path_1.default.relative(input, file);
96
+ if (!relativePath) {
97
+ relativePath = path_1.default.basename(file);
98
+ }
99
+ const outputFile = path_1.default.join(output, path_1.default.format({
100
+ ...path_1.default.parse(relativePath),
101
+ base: undefined,
102
+ ext,
103
+ }));
104
+ this.log(`${log_symbols_1.default.info} Compiling %s ${figures_1.default.arrowRight} %s as type %s`, (0, fs_2.normalizePath)(file), (0, fs_2.normalizePath)(outputFile), contentType);
105
+ const compileResult = await context.hooks.compileContent.call({ type: contentType }, preProcessedValue, file);
106
+ if (compileResult) {
107
+ await (0, mkdirp_1.default)(path_1.default.dirname(outputFile));
108
+ await fs_1.promises.writeFile(outputFile, compileResult.value);
109
+ if (compileResult.sourceMap) {
110
+ await fs_1.promises.writeFile(`${outputFile}.map`, compileResult.sourceMap);
111
+ }
112
+ return {
113
+ contentType,
114
+ outputFile,
115
+ inputFile: file,
116
+ };
117
+ }
118
+ else {
119
+ this.log(`${log_symbols_1.default.error} Error compiling %s, no result was returned by compiler`, (0, fs_2.normalizePath)(file));
120
+ throw new Error(`Error compiling file ${(0, fs_2.normalizePath)(file)}`);
121
+ }
122
+ };
123
+ const compilerResults = [];
124
+ // This has to be done serially b/c of the way React logs messages to console.error
125
+ // Otherwise the errors in console will be randomly interspersed between update messages
126
+ for (let fIndex = 0; fIndex < files.length; fIndex += 1) {
127
+ const file = files[fIndex];
128
+ try {
129
+ const result = await compileFile(file);
130
+ compilerResults.push({
131
+ output: result,
132
+ state: "completed",
133
+ });
134
+ }
135
+ catch (e) {
136
+ results.exitCode = 100;
137
+ this.log("");
138
+ this.log(chalk_1.default.red(`${log_symbols_1.default.error} Error compiling ${file}: ${e.stack}`));
139
+ compilerResults.push({
140
+ state: "completed",
141
+ error: e,
142
+ });
143
+ }
144
+ }
145
+ await context.dslCompiler.hooks.onEnd.call({ output });
146
+ if (!skipValidation) {
147
+ console.log("");
148
+ const hasOutput = compilerResults.some((r) => r.output?.contentType === "flow");
149
+ if (hasOutput) {
150
+ await validate_1.default.run([
151
+ "-f",
152
+ ...compilerResults
153
+ .filter((r) => r.output?.contentType === "flow")
154
+ .map((result) => {
155
+ return result.output?.outputFile ?? "";
156
+ }),
157
+ ...(exp ? ["--exp"] : []),
158
+ "-s",
159
+ severity,
160
+ "-v",
161
+ loglevel,
162
+ ]);
163
+ }
164
+ else {
165
+ console.log("No output to validate");
166
+ }
167
+ }
168
+ this.exit(results.exitCode);
169
+ return results;
170
+ }
171
+ }
172
+ exports.default = DSLCompile;
173
+ //# sourceMappingURL=compile.js.map
@@ -0,0 +1,15 @@
1
+ import { BaseCommand } from "../../utils/base-command";
2
+ /** A command thay runs TS typechecker against source ts and tsx files */
3
+ export default class Validate extends BaseCommand {
4
+ static description: string;
5
+ static flags: {
6
+ files: import("@oclif/core/lib/interfaces").OptionFlag<string[]>;
7
+ severity: import("@oclif/core/lib/interfaces").OptionFlag<string>;
8
+ config: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined>;
9
+ loglevel: import("@oclif/core/lib/interfaces").OptionFlag<string>;
10
+ };
11
+ private getOptions;
12
+ private getTSConfig;
13
+ run(): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=validate.d.ts.map