@player-tools/cli 0.3.0-next.2 → 0.3.1-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.
- package/dist/commands/xlr/compile.d.ts +1 -1
- package/dist/commands/xlr/compile.js +31 -132
- package/dist/utils/xlr/consts.d.ts +7 -0
- package/dist/utils/xlr/consts.js +17 -0
- package/dist/utils/xlr/visitors/file.d.ts +5 -0
- package/dist/utils/xlr/visitors/file.js +27 -0
- package/dist/utils/xlr/visitors/index.d.ts +4 -0
- package/dist/utils/xlr/visitors/index.js +19 -0
- package/dist/utils/xlr/visitors/plugin.d.ts +5 -0
- package/dist/utils/xlr/visitors/plugin.js +177 -0
- package/dist/utils/xlr/visitors/types.d.ts +13 -0
- package/dist/utils/xlr/visitors/types.js +2 -0
- package/oclif.manifest.json +1 -1
- package/package.json +6 -6
|
@@ -18,6 +18,6 @@ export default class XLRCompile extends BaseCommand {
|
|
|
18
18
|
/** Serializes ES6 Maps */
|
|
19
19
|
private replacer;
|
|
20
20
|
/** Generate extension manifest/description files from an Enhanced Player Plugin */
|
|
21
|
-
private
|
|
21
|
+
private processTypes;
|
|
22
22
|
}
|
|
23
23
|
//# sourceMappingURL=compile.d.ts.map
|
|
@@ -19,23 +19,10 @@ const path_1 = __importDefault(require("path"));
|
|
|
19
19
|
const globby_1 = __importDefault(require("globby"));
|
|
20
20
|
const log_symbols_1 = __importDefault(require("log-symbols"));
|
|
21
21
|
const xlr_converters_1 = require("@player-tools/xlr-converters");
|
|
22
|
-
const xlr_utils_1 = require("@player-tools/xlr-utils");
|
|
23
22
|
const chalk_1 = __importDefault(require("chalk"));
|
|
24
23
|
const base_command_1 = require("../../utils/base-command");
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
'Expression',
|
|
28
|
-
'Asset',
|
|
29
|
-
'Binding',
|
|
30
|
-
'AssetWrapper',
|
|
31
|
-
'Schema.DataType',
|
|
32
|
-
'ExpressionHandler',
|
|
33
|
-
];
|
|
34
|
-
var Mode;
|
|
35
|
-
(function (Mode) {
|
|
36
|
-
Mode["PLUGIN"] = "plugin";
|
|
37
|
-
Mode["TYPES"] = "types";
|
|
38
|
-
})(Mode || (Mode = {}));
|
|
24
|
+
const visitors_1 = require("../../utils/xlr/visitors");
|
|
25
|
+
const consts_1 = require("../../utils/xlr/consts");
|
|
39
26
|
/**
|
|
40
27
|
* Exports TS Interfaces/Types to XLR format
|
|
41
28
|
*/
|
|
@@ -51,7 +38,7 @@ class XLRCompile extends base_command_1.BaseCommand {
|
|
|
51
38
|
return {
|
|
52
39
|
inputPath: input,
|
|
53
40
|
outputDir: path_1.default.join(output, 'xlr'),
|
|
54
|
-
mode: modeValue === 'plugin' ? Mode.PLUGIN : Mode.TYPES,
|
|
41
|
+
mode: modeValue === 'plugin' ? consts_1.Mode.PLUGIN : consts_1.Mode.TYPES,
|
|
55
42
|
};
|
|
56
43
|
});
|
|
57
44
|
}
|
|
@@ -63,7 +50,7 @@ class XLRCompile extends base_command_1.BaseCommand {
|
|
|
63
50
|
`${inputPath}/**/*.tsx`,
|
|
64
51
|
]);
|
|
65
52
|
try {
|
|
66
|
-
this.
|
|
53
|
+
this.processTypes(inputFiles, outputDir, {}, mode);
|
|
67
54
|
}
|
|
68
55
|
catch (e) {
|
|
69
56
|
console.log('');
|
|
@@ -84,138 +71,50 @@ class XLRCompile extends base_command_1.BaseCommand {
|
|
|
84
71
|
return value;
|
|
85
72
|
}
|
|
86
73
|
/** Generate extension manifest/description files from an Enhanced Player Plugin */
|
|
87
|
-
|
|
74
|
+
processTypes(fileNames, outputDirectory, options, mode = consts_1.Mode.PLUGIN) {
|
|
88
75
|
var _a, _b, _c, _d;
|
|
89
76
|
// Build a program using the set of root file names in fileNames
|
|
90
77
|
const program = typescript_1.default.createProgram(fileNames, options);
|
|
91
|
-
fs_1.default.mkdirSync(
|
|
78
|
+
fs_1.default.mkdirSync(outputDirectory, { recursive: true });
|
|
92
79
|
// Get the checker, we will use it to find more about classes
|
|
93
80
|
const checker = program.getTypeChecker();
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
};
|
|
97
|
-
const converter = new xlr_converters_1.TsConverter(checker, customPrimitives);
|
|
98
|
-
/** visit nodes finding exported classes */
|
|
99
|
-
function pluginVisitor(node) {
|
|
100
|
-
var _a;
|
|
101
|
-
// Only consider exported nodes
|
|
102
|
-
if (!(0, xlr_utils_1.isNodeExported)(node)) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
// Plugins are classes so filter those
|
|
106
|
-
if (typescript_1.default.isClassDeclaration(node) && node.name) {
|
|
107
|
-
const symbol = checker.getSymbolAtLocation(node.name);
|
|
108
|
-
if (symbol) {
|
|
109
|
-
// look at what they implement
|
|
110
|
-
(_a = node.heritageClauses) === null || _a === void 0 ? void 0 : _a.forEach((heritage) => {
|
|
111
|
-
heritage.types.forEach((hInterface) => {
|
|
112
|
-
var _a, _b, _c, _d;
|
|
113
|
-
// check if heritage is right one
|
|
114
|
-
if (hInterface.expression.getText() !== PLAYER_PLUGIN_INTERFACE_NAME) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
// Get registration name of plugin
|
|
118
|
-
const nameProperty = node.members.find((member) => {
|
|
119
|
-
var _a;
|
|
120
|
-
return typescript_1.default.isPropertyDeclaration(member) &&
|
|
121
|
-
((_a = member.name) === null || _a === void 0 ? void 0 : _a.getText()) === 'name';
|
|
122
|
-
});
|
|
123
|
-
if (nameProperty && nameProperty.initializer) {
|
|
124
|
-
capabilities.pluginName = (_a = nameProperty.initializer) === null || _a === void 0 ? void 0 : _a.getText().replace(/['"]+/g, '');
|
|
125
|
-
}
|
|
126
|
-
const provides = new Map();
|
|
127
|
-
const typeArgs = hInterface.typeArguments;
|
|
128
|
-
const pluginDec = (_c = (_b = checker.getTypeAtLocation(hInterface).symbol) === null || _b === void 0 ? void 0 : _b.declarations) === null || _c === void 0 ? void 0 : _c[0];
|
|
129
|
-
// process type parameters to figure out what capabilities are provided
|
|
130
|
-
(_d = pluginDec === null || pluginDec === void 0 ? void 0 : pluginDec.typeParameters) === null || _d === void 0 ? void 0 : _d.forEach((param, index) => {
|
|
131
|
-
var _a;
|
|
132
|
-
const capabilityType = param.name.getText();
|
|
133
|
-
if (index < ((_a = typeArgs === null || typeArgs === void 0 ? void 0 : typeArgs.length) !== null && _a !== void 0 ? _a : 0)) {
|
|
134
|
-
const exportedCapabilities = typeArgs === null || typeArgs === void 0 ? void 0 : typeArgs[index];
|
|
135
|
-
// if its an array process each type
|
|
136
|
-
if (typescript_1.default.isTupleTypeNode(exportedCapabilities)) {
|
|
137
|
-
const capabilityNames = exportedCapabilities.elements.map((element) => {
|
|
138
|
-
var _a, _b, _c;
|
|
139
|
-
if (typescript_1.default.isTypeReferenceNode(element) ||
|
|
140
|
-
typescript_1.default.isTypeQueryNode(element)) {
|
|
141
|
-
let referencedSymbol;
|
|
142
|
-
if (typescript_1.default.isTypeReferenceNode(element)) {
|
|
143
|
-
referencedSymbol = checker.getSymbolAtLocation(element.typeName);
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
referencedSymbol = checker.getSymbolAtLocation(element.exprName);
|
|
147
|
-
}
|
|
148
|
-
const alias = referencedSymbol
|
|
149
|
-
? checker.getAliasedSymbol(referencedSymbol)
|
|
150
|
-
: undefined;
|
|
151
|
-
let varDecl;
|
|
152
|
-
/**
|
|
153
|
-
* The TypeChecker will return the interface/type declaration or the variable statement
|
|
154
|
-
* so if we are getting a variable, we need to grab the variable declaration
|
|
155
|
-
*/
|
|
156
|
-
if (typescript_1.default.isTypeReferenceNode(element)) {
|
|
157
|
-
varDecl = (_a = alias === null || alias === void 0 ? void 0 : alias.declarations) === null || _a === void 0 ? void 0 : _a[0];
|
|
158
|
-
}
|
|
159
|
-
else {
|
|
160
|
-
varDecl = (_b = alias === null || alias === void 0 ? void 0 : alias.declarations) === null || _b === void 0 ? void 0 : _b[0].parent.parent;
|
|
161
|
-
}
|
|
162
|
-
if (varDecl && (0, xlr_utils_1.isTopLevelNode)(varDecl)) {
|
|
163
|
-
const capabilityDescription = converter.convertTopLevelNode(varDecl);
|
|
164
|
-
const capabilityName = (_c = capabilityDescription === null || capabilityDescription === void 0 ? void 0 : capabilityDescription.name) !== null && _c !== void 0 ? _c : 'error';
|
|
165
|
-
fs_1.default.writeFileSync(path_1.default.join(outputDir, `${capabilityName}.json`), JSON.stringify(capabilityDescription, undefined, 4));
|
|
166
|
-
return capabilityName;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
throw new Error(`Can't export non reference type ${element.getText()}`);
|
|
170
|
-
});
|
|
171
|
-
provides.set(capabilityType, capabilityNames);
|
|
172
|
-
}
|
|
173
|
-
else if (typescript_1.default.isTypeReferenceNode(exportedCapabilities)) {
|
|
174
|
-
const capabilityName = exportedCapabilities.typeName.getText();
|
|
175
|
-
const capabilityDescription = converter.convertTsTypeNode(exportedCapabilities);
|
|
176
|
-
fs_1.default.writeFileSync(path_1.default.join(outputDir, `${capabilityName}.json`), JSON.stringify(capabilityDescription, undefined, 4));
|
|
177
|
-
provides.set(capabilityType, [capabilityName]);
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
throw new Error(`Can't figure out type ${capabilityType}`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
capabilities.capabilities = provides;
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
/** export all exported types in the file */
|
|
191
|
-
function fileVisitor(file) {
|
|
192
|
-
const convertedTypes = converter.convertSourceFile(file);
|
|
193
|
-
convertedTypes.data.types.forEach((type) => {
|
|
194
|
-
fs_1.default.writeFileSync(path_1.default.join(outputDir, `${type.name}.json`), JSON.stringify(type, undefined, 4));
|
|
195
|
-
});
|
|
196
|
-
capabilities.capabilities = new Map([
|
|
197
|
-
['Types', convertedTypes.convertedTypes],
|
|
198
|
-
]);
|
|
199
|
-
}
|
|
81
|
+
const converter = new xlr_converters_1.TsConverter(checker, consts_1.customPrimitives);
|
|
82
|
+
let capabilities;
|
|
200
83
|
// Visit every sourceFile in the program
|
|
201
84
|
program.getSourceFiles().forEach((sourceFile) => {
|
|
202
85
|
if (!sourceFile.isDeclarationFile) {
|
|
203
86
|
// Walk the tree to search for classes
|
|
204
|
-
|
|
205
|
-
|
|
87
|
+
let generatedCapabilites;
|
|
88
|
+
if (mode === consts_1.Mode.PLUGIN) {
|
|
89
|
+
generatedCapabilites = (0, visitors_1.pluginVisitor)({
|
|
90
|
+
sourceFile,
|
|
91
|
+
converter,
|
|
92
|
+
checker,
|
|
93
|
+
outputDirectory,
|
|
94
|
+
});
|
|
206
95
|
}
|
|
207
|
-
else if (mode === Mode.TYPES) {
|
|
208
|
-
|
|
209
|
-
|
|
96
|
+
else if (mode === consts_1.Mode.TYPES) {
|
|
97
|
+
generatedCapabilites = (0, visitors_1.fileVisitor)({
|
|
98
|
+
sourceFile,
|
|
99
|
+
converter,
|
|
100
|
+
checker,
|
|
101
|
+
outputDirectory,
|
|
102
|
+
});
|
|
210
103
|
}
|
|
211
104
|
else {
|
|
212
105
|
throw new Error(`Error: Option ${mode} not recognized. Valid options are: plugin or type`);
|
|
213
106
|
}
|
|
107
|
+
if (generatedCapabilites) {
|
|
108
|
+
capabilities = generatedCapabilites;
|
|
109
|
+
}
|
|
214
110
|
}
|
|
215
111
|
});
|
|
112
|
+
if (!capabilities) {
|
|
113
|
+
throw new Error('Error: Unable to parse any XLRs in package');
|
|
114
|
+
}
|
|
216
115
|
// print out the manifest files
|
|
217
116
|
const jsonManifest = JSON.stringify(capabilities, this.replacer, 4);
|
|
218
|
-
fs_1.default.writeFileSync(path_1.default.join(
|
|
117
|
+
fs_1.default.writeFileSync(path_1.default.join(outputDirectory, 'manifest.json'), jsonManifest);
|
|
219
118
|
const tsManifestFile = `${[...((_b = (_a = capabilities.capabilities) === null || _a === void 0 ? void 0 : _a.values()) !== null && _b !== void 0 ? _b : [])]
|
|
220
119
|
.flat(2)
|
|
221
120
|
.map((capability) => {
|
|
@@ -234,7 +133,7 @@ module.exports = {
|
|
|
234
133
|
}
|
|
235
134
|
}
|
|
236
135
|
`;
|
|
237
|
-
fs_1.default.writeFileSync(path_1.default.join(
|
|
136
|
+
fs_1.default.writeFileSync(path_1.default.join(outputDirectory, 'manifest.js'), tsManifestFile);
|
|
238
137
|
}
|
|
239
138
|
}
|
|
240
139
|
exports.default = XLRCompile;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Mode = exports.customPrimitives = exports.PLAYER_PLUGIN_INTERFACE_NAME = void 0;
|
|
4
|
+
exports.PLAYER_PLUGIN_INTERFACE_NAME = 'ExtendedPlayerPlugin';
|
|
5
|
+
exports.customPrimitives = [
|
|
6
|
+
'Expression',
|
|
7
|
+
'Asset',
|
|
8
|
+
'Binding',
|
|
9
|
+
'AssetWrapper',
|
|
10
|
+
'Schema.DataType',
|
|
11
|
+
'ExpressionHandler',
|
|
12
|
+
];
|
|
13
|
+
var Mode;
|
|
14
|
+
(function (Mode) {
|
|
15
|
+
Mode["PLUGIN"] = "plugin";
|
|
16
|
+
Mode["TYPES"] = "types";
|
|
17
|
+
})(Mode = exports.Mode || (exports.Mode = {}));
|
|
@@ -0,0 +1,27 @@
|
|
|
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.fileVisitor = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
/** export all exported types in the file */
|
|
10
|
+
function fileVisitor(args) {
|
|
11
|
+
const { sourceFile, converter, outputDirectory } = args;
|
|
12
|
+
const convertedTypes = converter.convertSourceFile(sourceFile);
|
|
13
|
+
if (convertedTypes.data.types.length === 0) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
const capabilities = {
|
|
17
|
+
pluginName: 'Types',
|
|
18
|
+
};
|
|
19
|
+
convertedTypes.data.types.forEach((type) => {
|
|
20
|
+
fs_1.default.writeFileSync(path_1.default.join(outputDirectory, `${type.name}.json`), JSON.stringify(type, undefined, 4));
|
|
21
|
+
});
|
|
22
|
+
capabilities.capabilities = new Map([
|
|
23
|
+
['Types', convertedTypes.convertedTypes],
|
|
24
|
+
]);
|
|
25
|
+
return capabilities;
|
|
26
|
+
}
|
|
27
|
+
exports.fileVisitor = fileVisitor;
|
|
@@ -0,0 +1,19 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./file"), exports);
|
|
18
|
+
__exportStar(require("./plugin"), exports);
|
|
19
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1,177 @@
|
|
|
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.pluginVisitor = void 0;
|
|
7
|
+
const xlr_utils_1 = require("@player-tools/xlr-utils");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const consts_1 = require("../consts");
|
|
12
|
+
/**
|
|
13
|
+
* Follows references to get the actual underlying declaration
|
|
14
|
+
*/
|
|
15
|
+
function getUnderlyingNode(element, checker) {
|
|
16
|
+
var _a, _b;
|
|
17
|
+
let referencedSymbol;
|
|
18
|
+
if (typescript_1.default.isTypeReferenceNode(element)) {
|
|
19
|
+
referencedSymbol = checker.getSymbolAtLocation(element.typeName);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
referencedSymbol = checker.getSymbolAtLocation(element.exprName);
|
|
23
|
+
}
|
|
24
|
+
const alias = referencedSymbol
|
|
25
|
+
? checker.getAliasedSymbol(referencedSymbol)
|
|
26
|
+
: undefined;
|
|
27
|
+
let varDecl;
|
|
28
|
+
/**
|
|
29
|
+
* The TypeChecker will return the interface/type declaration or the variable statement
|
|
30
|
+
* so if we are getting a variable, we need to grab the variable declaration
|
|
31
|
+
*/
|
|
32
|
+
if (typescript_1.default.isTypeReferenceNode(element)) {
|
|
33
|
+
varDecl = (_a = alias === null || alias === void 0 ? void 0 : alias.declarations) === null || _a === void 0 ? void 0 : _a[0];
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
varDecl = (_b = alias === null || alias === void 0 ? void 0 : alias.declarations) === null || _b === void 0 ? void 0 : _b[0].parent.parent;
|
|
37
|
+
}
|
|
38
|
+
if (varDecl && (0, xlr_utils_1.isTopLevelNode)(varDecl)) {
|
|
39
|
+
return varDecl;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Fixes ExpressionHandler ref nodes that don't have argument names because some way of writing ExpressionHandler prevent the ts compiler from inferring them
|
|
44
|
+
*/
|
|
45
|
+
function fixExpressionArgNames(sourceNode, generatedTypeRef, checker) {
|
|
46
|
+
var _a, _b, _c;
|
|
47
|
+
const typeRefCopy = Object.assign({}, generatedTypeRef);
|
|
48
|
+
const { initializer } = sourceNode.declarationList.declarations[0];
|
|
49
|
+
let offset;
|
|
50
|
+
let arrowFunction;
|
|
51
|
+
if (initializer &&
|
|
52
|
+
typescript_1.default.isCallExpression(initializer) &&
|
|
53
|
+
typescript_1.default.isArrowFunction(initializer.arguments[0])) {
|
|
54
|
+
// handles the case of `withoutContext` expression where the types are provided by the generic
|
|
55
|
+
offset = 0;
|
|
56
|
+
arrowFunction = initializer.arguments[0];
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// handles the case of a direct `ExpressionHandler` where the types are provided by the generic
|
|
60
|
+
offset = 1;
|
|
61
|
+
arrowFunction = initializer;
|
|
62
|
+
}
|
|
63
|
+
const paramsNode = (_a = typeRefCopy.genericArguments) === null || _a === void 0 ? void 0 : _a[0];
|
|
64
|
+
if (paramsNode && paramsNode.type === 'array') {
|
|
65
|
+
const functionArg = (_b = arrowFunction.parameters) === null || _b === void 0 ? void 0 : _b[offset];
|
|
66
|
+
if (!paramsNode.name && functionArg) {
|
|
67
|
+
paramsNode.name = functionArg.name.getText();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else if (paramsNode && paramsNode.type === 'tuple') {
|
|
71
|
+
(_c = paramsNode.elementTypes) === null || _c === void 0 ? void 0 : _c.forEach((gArg, index) => {
|
|
72
|
+
var _a;
|
|
73
|
+
const functionArg = (_a = arrowFunction.parameters) === null || _a === void 0 ? void 0 : _a[index + offset];
|
|
74
|
+
if (!gArg.name && functionArg) {
|
|
75
|
+
// eslint-disable-next-line no-param-reassign
|
|
76
|
+
gArg.name = functionArg.name.getText();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return typeRefCopy;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Player specific modifications that we need to do to massage generic XLR conversion because of our weird types
|
|
84
|
+
* Most of this is _definitely not_ best practice.
|
|
85
|
+
*/
|
|
86
|
+
function runPlayerPostProcessing(node, xlr, checker) {
|
|
87
|
+
if (xlr.type === 'ref' &&
|
|
88
|
+
xlr.ref.includes('ExpressionHandler') &&
|
|
89
|
+
typescript_1.default.isVariableStatement(node)) {
|
|
90
|
+
return fixExpressionArgNames(node, xlr, checker);
|
|
91
|
+
}
|
|
92
|
+
return xlr;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Generated the XLR for a Capability, writes it to the specified path, and returns the name
|
|
96
|
+
*/
|
|
97
|
+
function generateXLR(node, checker, converter, outputDirectory) {
|
|
98
|
+
var _a;
|
|
99
|
+
if (typescript_1.default.isTypeReferenceNode(node) || typescript_1.default.isTypeQueryNode(node)) {
|
|
100
|
+
const varDecl = getUnderlyingNode(node, checker);
|
|
101
|
+
if (varDecl) {
|
|
102
|
+
let capabilityDescription = converter.convertTopLevelNode(varDecl);
|
|
103
|
+
capabilityDescription = runPlayerPostProcessing(varDecl, capabilityDescription, checker);
|
|
104
|
+
const capabilityName = (_a = capabilityDescription === null || capabilityDescription === void 0 ? void 0 : capabilityDescription.name) !== null && _a !== void 0 ? _a : 'error';
|
|
105
|
+
fs_1.default.writeFileSync(path_1.default.join(outputDirectory, `${capabilityName}.json`), JSON.stringify(capabilityDescription, undefined, 4));
|
|
106
|
+
return capabilityName;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
throw new Error(`Can't export non reference type ${node.getText()}`);
|
|
110
|
+
}
|
|
111
|
+
/** visit nodes finding exported classes */
|
|
112
|
+
function pluginVisitor(args) {
|
|
113
|
+
const { sourceFile, checker, converter, outputDirectory } = args;
|
|
114
|
+
let capabilities;
|
|
115
|
+
typescript_1.default.forEachChild(sourceFile, (node) => {
|
|
116
|
+
var _a;
|
|
117
|
+
// Only consider exported nodes
|
|
118
|
+
if (!(0, xlr_utils_1.isNodeExported)(node)) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
// Plugins are classes so filter those
|
|
122
|
+
if (typescript_1.default.isClassDeclaration(node) && node.name) {
|
|
123
|
+
const symbol = checker.getSymbolAtLocation(node.name);
|
|
124
|
+
if (symbol) {
|
|
125
|
+
// look at what they implement
|
|
126
|
+
(_a = node.heritageClauses) === null || _a === void 0 ? void 0 : _a.forEach((heritage) => {
|
|
127
|
+
heritage.types.forEach((hInterface) => {
|
|
128
|
+
var _a, _b, _c, _d;
|
|
129
|
+
// check if heritage is right one
|
|
130
|
+
if (hInterface.expression.getText() !== consts_1.PLAYER_PLUGIN_INTERFACE_NAME) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
capabilities = {
|
|
134
|
+
pluginName: 'Unknown Plugin',
|
|
135
|
+
};
|
|
136
|
+
// Get registration name of plugin
|
|
137
|
+
const nameProperty = node.members.find((member) => {
|
|
138
|
+
var _a;
|
|
139
|
+
return typescript_1.default.isPropertyDeclaration(member) &&
|
|
140
|
+
((_a = member.name) === null || _a === void 0 ? void 0 : _a.getText()) === 'name';
|
|
141
|
+
});
|
|
142
|
+
if (nameProperty && nameProperty.initializer) {
|
|
143
|
+
capabilities.pluginName = (_a = nameProperty.initializer) === null || _a === void 0 ? void 0 : _a.getText().replace(/['"]+/g, '');
|
|
144
|
+
}
|
|
145
|
+
const provides = new Map();
|
|
146
|
+
const typeArgs = hInterface.typeArguments;
|
|
147
|
+
const pluginDec = (_c = (_b = checker.getTypeAtLocation(hInterface).symbol) === null || _b === void 0 ? void 0 : _b.declarations) === null || _c === void 0 ? void 0 : _c[0];
|
|
148
|
+
// process type parameters to figure out what capabilities are provided
|
|
149
|
+
(_d = pluginDec === null || pluginDec === void 0 ? void 0 : pluginDec.typeParameters) === null || _d === void 0 ? void 0 : _d.forEach((param, index) => {
|
|
150
|
+
var _a;
|
|
151
|
+
const capabilityType = param.name.getText();
|
|
152
|
+
if (index < ((_a = typeArgs === null || typeArgs === void 0 ? void 0 : typeArgs.length) !== null && _a !== void 0 ? _a : 0)) {
|
|
153
|
+
const exportedCapabilities = typeArgs === null || typeArgs === void 0 ? void 0 : typeArgs[index];
|
|
154
|
+
// if its an array process each type
|
|
155
|
+
if (typescript_1.default.isTupleTypeNode(exportedCapabilities)) {
|
|
156
|
+
const capabilityNames = exportedCapabilities.elements.map((element) => generateXLR(element, checker, converter, outputDirectory));
|
|
157
|
+
provides.set(capabilityType, capabilityNames);
|
|
158
|
+
}
|
|
159
|
+
else if (typescript_1.default.isTypeReferenceNode(exportedCapabilities) ||
|
|
160
|
+
typescript_1.default.isTypeQueryNode(exportedCapabilities)) {
|
|
161
|
+
const capabilityName = generateXLR(exportedCapabilities, checker, converter, outputDirectory);
|
|
162
|
+
provides.set(capabilityType, [capabilityName]);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
throw new Error(`Can't figure out type ${capabilityType}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
capabilities.capabilities = provides;
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
return capabilities;
|
|
176
|
+
}
|
|
177
|
+
exports.pluginVisitor = pluginVisitor;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TsConverter } from '@player-tools/xlr-converters';
|
|
2
|
+
import type ts from 'typescript';
|
|
3
|
+
export interface VisitorProps {
|
|
4
|
+
/** The source file to process */
|
|
5
|
+
sourceFile: ts.SourceFile;
|
|
6
|
+
/** An instance of a typescript type checker */
|
|
7
|
+
checker: ts.TypeChecker;
|
|
8
|
+
/** An instance of a XLR converter */
|
|
9
|
+
converter: TsConverter;
|
|
10
|
+
/** Where to write converted XLRs to */
|
|
11
|
+
outputDirectory: string;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=types.d.ts.map
|
package/oclif.manifest.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.3.
|
|
1
|
+
{"version":"0.3.1-next.0","commands":{"dsl:compile":{"id":"dsl:compile","description":"Compile Player DSL files into JSON","strict":false,"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":false,"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":false,"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":false,"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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@player-tools/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1-next.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org"
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"vscode-languageserver-textdocument": "^1.0.1",
|
|
29
29
|
"vscode-languageserver-types": "^3.15.1",
|
|
30
30
|
"typescript": "4.8.4",
|
|
31
|
-
"@player-tools/dsl": "0.3.
|
|
32
|
-
"@player-tools/language-service": "0.3.
|
|
33
|
-
"@player-tools/xlr-sdk": "0.3.
|
|
34
|
-
"@player-tools/xlr-utils": "0.3.
|
|
35
|
-
"@player-tools/xlr-converters": "0.3.
|
|
31
|
+
"@player-tools/dsl": "0.3.1-next.0",
|
|
32
|
+
"@player-tools/language-service": "0.3.1-next.0",
|
|
33
|
+
"@player-tools/xlr-sdk": "0.3.1-next.0",
|
|
34
|
+
"@player-tools/xlr-utils": "0.3.1-next.0",
|
|
35
|
+
"@player-tools/xlr-converters": "0.3.1-next.0"
|
|
36
36
|
},
|
|
37
37
|
"main": "./dist/index.js",
|
|
38
38
|
"module": "dist/index.esm.js",
|