datagrok-tools 4.14.5 → 4.14.7
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/CHANGELOG.md +8 -0
- package/bin/commands/check.js +22 -13
- package/bin/utils/utils.js +6 -6
- package/package.json +1 -1
- package/plugins/func-gen-plugin.js +43 -18
package/CHANGELOG.md
CHANGED
package/bin/commands/check.js
CHANGED
|
@@ -21,20 +21,21 @@ var testUtils = _interopRequireWildcard(require("../utils/test-utils"));
|
|
|
21
21
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
22
22
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
23
23
|
const warns = ['Latest package version', 'Datagrok API version should contain'];
|
|
24
|
-
const
|
|
24
|
+
const forbiddenNames = ['function', 'class', 'export'];
|
|
25
|
+
const namesInFiles = new Map();
|
|
25
26
|
function check(args) {
|
|
26
27
|
const nOptions = Object.keys(args).length - 1;
|
|
27
28
|
if (args['_'].length !== 1 || nOptions > 2 || nOptions > 0 && !args.r && !args.recursive) return false;
|
|
28
29
|
const curDir = process.cwd();
|
|
29
|
-
if (args.recursive) return runChecksRec(curDir);else {
|
|
30
|
+
if (args.recursive) return runChecksRec(curDir, args.soft ?? false);else {
|
|
30
31
|
if (!utils.isPackageDir(curDir)) {
|
|
31
32
|
color.error('File `package.json` not found. Run the command from the package directory');
|
|
32
33
|
return false;
|
|
33
34
|
}
|
|
34
|
-
return runChecks(curDir);
|
|
35
|
+
return runChecks(curDir, args.soft ?? false);
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
|
-
function runChecks(packagePath) {
|
|
38
|
+
function runChecks(packagePath, soft = false) {
|
|
38
39
|
const files = _ignoreWalk.default.sync({
|
|
39
40
|
path: packagePath,
|
|
40
41
|
ignoreFiles: ['.npmignore', '.gitignore']
|
|
@@ -77,20 +78,20 @@ function runChecks(packagePath) {
|
|
|
77
78
|
if (errors.length) {
|
|
78
79
|
console.log(`Checking package ${_path.default.basename(packagePath)}...`);
|
|
79
80
|
showError(errors);
|
|
80
|
-
if (json.version.startsWith('0') || errors.every(w => warns.some(ww => w.includes(ww)))) return true;
|
|
81
|
+
if (soft || json.version.startsWith('0') || errors.every(w => warns.some(ww => w.includes(ww)))) return true;
|
|
81
82
|
testUtils.exitWithCode(1);
|
|
82
83
|
}
|
|
83
84
|
console.log(`Checking package ${_path.default.basename(packagePath)}...\t\t\t\u2713 OK`);
|
|
84
85
|
return true;
|
|
85
86
|
}
|
|
86
|
-
function runChecksRec(dir) {
|
|
87
|
+
function runChecksRec(dir, soft = false) {
|
|
87
88
|
const files = _fs.default.readdirSync(dir);
|
|
88
89
|
for (const file of files) {
|
|
89
90
|
const filepath = _path.default.join(dir, file);
|
|
90
91
|
const stats = _fs.default.statSync(filepath);
|
|
91
92
|
if (stats.isDirectory()) {
|
|
92
|
-
if (utils.isPackageDir(filepath)) return runChecks(filepath);else {
|
|
93
|
-
if (file !== 'node_modules' && !file.startsWith('.')) runChecksRec(_path.default.join(dir, file));
|
|
93
|
+
if (utils.isPackageDir(filepath)) return runChecks(filepath, soft);else {
|
|
94
|
+
if (file !== 'node_modules' && !file.startsWith('.')) runChecksRec(_path.default.join(dir, file), soft);
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
}
|
|
@@ -315,13 +316,20 @@ function checkFuncSignatures(packagePath, files) {
|
|
|
315
316
|
warnings.push(`File ${file}, function ${f.name}:\n${vr.message}`);
|
|
316
317
|
}
|
|
317
318
|
}
|
|
318
|
-
let wrongInputNames = f.inputs.filter(e =>
|
|
319
|
+
let wrongInputNames = f.inputs.filter(e => forbiddenNames.includes(e?.name ?? ''));
|
|
320
|
+
if (f.name) {
|
|
321
|
+
console.log(f);
|
|
322
|
+
if (namesInFiles.has(f.name)) namesInFiles.get(f.name)?.push(file);else namesInFiles.set(f.name, [file]);
|
|
323
|
+
}
|
|
319
324
|
if (wrongInputNames.length > 0) warnings.push(`File ${file}, function ${f.name}: Wrong input names: (${wrongInputNames.map(e => e.name).join(', ')})`);
|
|
320
325
|
if (f.isInvalidateOnWithoutCache) warnings.push(`File ${file}, function ${f.name}: Can't use invalidateOn without cache, please follow this example: 'meta.cache.invalidateOn'`);
|
|
321
|
-
if (f.cache) if (!utils.
|
|
326
|
+
if (f.cache) if (!utils.cacheValues.includes(f.cache)) warnings.push(`File ${file}, function ${f.name}: unsupposed variable for cache : ${f.cache}`);
|
|
322
327
|
if (f.invalidateOn) if (!utils.isValidCron(f.invalidateOn)) warnings.push(`File ${file}, function ${f.name}: unsupposed variable for invalidateOn : ${f.invalidateOn}`);
|
|
323
328
|
}
|
|
324
329
|
}
|
|
330
|
+
for (const [name, files] of namesInFiles) {
|
|
331
|
+
if (files.length > 1) warnings.push(`Duplicate names ('${name}'): \n ${files.join('\n ')}`);
|
|
332
|
+
}
|
|
325
333
|
return warnings;
|
|
326
334
|
}
|
|
327
335
|
const sharedLibExternals = {
|
|
@@ -519,7 +527,8 @@ function getFuncMetadata(script, fileExtention) {
|
|
|
519
527
|
if (match) {
|
|
520
528
|
if (!isHeader) isHeader = true;
|
|
521
529
|
const param = match[1];
|
|
522
|
-
|
|
530
|
+
console.log(param);
|
|
531
|
+
if (param === 'name') data.name = line.match(utils.nameAnnRegex)?.[2]?.toLocaleLowerCase();else if (param === 'description') data.description = match[2];else if (param === 'input') {
|
|
523
532
|
data.inputs.push({
|
|
524
533
|
type: match[2],
|
|
525
534
|
name: match[3]
|
|
@@ -539,8 +548,8 @@ function getFuncMetadata(script, fileExtention) {
|
|
|
539
548
|
}
|
|
540
549
|
if (isHeader) {
|
|
541
550
|
const nm = line.match(utils.nameRegex);
|
|
542
|
-
if (nm
|
|
543
|
-
|
|
551
|
+
if (nm) data.name = nm[1]?.toLocaleLowerCase();
|
|
552
|
+
if (data.name && !match) {
|
|
544
553
|
funcData.push(data);
|
|
545
554
|
data = {
|
|
546
555
|
name: '',
|
package/bin/utils/utils.js
CHANGED
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.
|
|
7
|
+
exports.cacheValues = exports.absUrlRegex = exports.TemplateBuilder = void 0;
|
|
8
8
|
exports.camelCaseToKebab = camelCaseToKebab;
|
|
9
9
|
exports.checkScriptLocation = checkScriptLocation;
|
|
10
10
|
exports.commentMap = void 0;
|
|
@@ -165,7 +165,7 @@ function getParam(name, script, comment = '#') {
|
|
|
165
165
|
return match ? match[1]?.trim() : null;
|
|
166
166
|
}
|
|
167
167
|
;
|
|
168
|
-
const
|
|
168
|
+
const cacheValues = exports.cacheValues = ['all', 'server', 'client', 'true'];
|
|
169
169
|
function isValidCron(cronExpression) {
|
|
170
170
|
const cronRegex = /^(\*|([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])|\*\/([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])) (\*|([0-9]|1[0-9]|2[0-3])|\*\/([0-9]|1[0-9]|2[0-3])) (\*|([1-9]|1[0-9]|2[0-9]|3[0-1])|\*\/([1-9]|1[0-9]|2[0-9]|3[0-1])) (\*|([1-9]|1[0-2])|\*\/([1-9]|1[0-2])) (\*|([0-6])|\*\/([0-6]))$/;
|
|
171
171
|
return cronRegex.test(cronExpression);
|
|
@@ -183,15 +183,15 @@ const dgToTsTypeMap = exports.dgToTsTypeMap = {
|
|
|
183
183
|
view: 'DG.View'
|
|
184
184
|
};
|
|
185
185
|
const propertyTypes = exports.propertyTypes = ['bool', 'int', 'double', 'string', 'datetime', 'object', 'column', 'dataframe', 'bitset', 'cell', 'string_list', 'map'];
|
|
186
|
-
const headerTags = exports.headerTags = ['name', 'description', 'help-url', 'input', 'output', 'tags', 'sample', 'language', 'returns', 'test', 'sidebar', 'condition', 'top-menu', 'environment', 'require', 'editor-for', 'schedule', 'reference', 'editor', 'meta'];
|
|
186
|
+
const headerTags = exports.headerTags = ['name', 'description', 'help-url', 'input', 'output', 'tags', 'sample', 'language', 'returns', 'test', 'sidebar', 'condition', 'top-menu', 'environment', 'require', 'editor-for', 'schedule', 'reference', 'editor', 'meta', 'connection', 'friendlyName'];
|
|
187
187
|
const fileParamRegex = exports.fileParamRegex = {
|
|
188
188
|
py: new RegExp(`^\#\\s*((?:${headerTags.join('|')})[^:]*): *([^\\s\\[\\{]+) ?([^\\s\\[\\{]+)?[^\\n]*$`),
|
|
189
189
|
ts: new RegExp(`^\/\/\\s*((?:${headerTags.join('|')})[^:]*): *([^\\s\\[\\{]+) ?([^\\s\\[\\{]+)?[^\\n]*$`),
|
|
190
190
|
js: new RegExp(`^\/\/\\s*((?:${headerTags.join('|')})[^:]*): *([^\\s\\[\\{]+) ?([^\\s\\[\\{]+)?[^\\n]*$`),
|
|
191
191
|
sql: new RegExp(`^--\\s*((?:${headerTags.join('|')})[^:]*): *([^\\s\\[\\{]+) ?([^\\s\\[\\{]+)?[^\\n]*$`)
|
|
192
192
|
};
|
|
193
|
-
const nameAnnRegex = exports.nameAnnRegex =
|
|
194
|
-
const nameRegex = exports.nameRegex = /(?:|(?:static)(?:export )(?:async )
|
|
193
|
+
const nameAnnRegex = exports.nameAnnRegex = /\s*(name[^:]*): ([^\n\r\[\{]+)/;
|
|
194
|
+
const nameRegex = exports.nameRegex = /(?:|(?:static)(?:export )(?:async ))\s+function\s+([a-zA-Z_][a-zA-Z0-9_$]*)\s*\((.*?).*/;
|
|
195
195
|
const absUrlRegex = exports.absUrlRegex = new RegExp('^(?:[a-z+]+:)?//', 'i');
|
|
196
196
|
function getScriptOutputType(script, comment = '#') {
|
|
197
197
|
const regex = new RegExp(`${comment}\\s*output:\\s?([a-z_]+)\\s*`);
|
|
@@ -245,7 +245,7 @@ async function runScript(script, path, verbose = false) {
|
|
|
245
245
|
}
|
|
246
246
|
} catch (error) {
|
|
247
247
|
console.error(`Execution failed: ${error.message}`);
|
|
248
|
-
throw new Error(`
|
|
248
|
+
throw new Error(`Error executing '${script}'. Error message: ${error.message}`);
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
251
|
function setHost(host, configFile) {
|
package/package.json
CHANGED
|
@@ -125,12 +125,7 @@ class FuncGeneratorPlugin {
|
|
|
125
125
|
]);
|
|
126
126
|
const functionParams =
|
|
127
127
|
node?.type === "MethodDefinition" ? this._readMethodParamas(node) : [];
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
const annotationByReturnTypeObj = {
|
|
131
|
-
name: "result",
|
|
132
|
-
type: annotationByReturnType,
|
|
133
|
-
};
|
|
128
|
+
const annotationByReturnObj = node?.type === "MethodDefinition" ? this._readOutputsFromReturnType(node) : undefined;
|
|
134
129
|
const isMethodAsync = this._isMethodAsync(node);
|
|
135
130
|
let importString = generateImport(
|
|
136
131
|
node?.type === "MethodDefinition" ? className : identifierName,
|
|
@@ -142,8 +137,8 @@ class FuncGeneratorPlugin {
|
|
|
142
137
|
}${identifierName}`;
|
|
143
138
|
const funcAnnotaionOptions = {
|
|
144
139
|
...reservedDecorators[name]["metadata"],
|
|
145
|
-
...(
|
|
146
|
-
? { outputs:
|
|
140
|
+
...(annotationByReturnObj
|
|
141
|
+
? { outputs: annotationByReturnObj ?? [] }
|
|
147
142
|
: {}),
|
|
148
143
|
...Object.fromEntries(decoratorOptions),
|
|
149
144
|
...{ inputs: functionParams },
|
|
@@ -345,21 +340,14 @@ class FuncGeneratorPlugin {
|
|
|
345
340
|
}
|
|
346
341
|
}
|
|
347
342
|
|
|
348
|
-
_readReturnType(
|
|
343
|
+
_readReturnType(annotation) {
|
|
349
344
|
let resultType = "dynamic";
|
|
350
|
-
let isArray = false;
|
|
351
|
-
let annotation = node.value?.returnType?.typeAnnotation;
|
|
345
|
+
let isArray = false;
|
|
352
346
|
if (
|
|
353
347
|
annotation &&
|
|
354
348
|
annotation.type !== "TSUnionType" &&
|
|
355
349
|
annotation.type !== "TSIntersectionType"
|
|
356
350
|
) {
|
|
357
|
-
// if (annotation?.typeName?.name === "Promise") {
|
|
358
|
-
// const argumnets = annotation.typeArguments?.params;
|
|
359
|
-
// if (argumnets && argumnets.length === 1) {
|
|
360
|
-
// annotation = argumnets[0];
|
|
361
|
-
// } else annotation = {};
|
|
362
|
-
// }
|
|
363
351
|
|
|
364
352
|
if (annotation.typeName || annotation.type === "TSTypeReference")
|
|
365
353
|
resultType =
|
|
@@ -377,12 +365,49 @@ class FuncGeneratorPlugin {
|
|
|
377
365
|
annotation?.elementType?.typeName?.right?.name;
|
|
378
366
|
}
|
|
379
367
|
}
|
|
380
|
-
|
|
381
368
|
resultType = typesToAnnotation[resultType];
|
|
382
369
|
if (isArray && resultType) resultType = `list`;
|
|
383
370
|
return resultType ?? 'dynamic';
|
|
384
371
|
}
|
|
385
372
|
|
|
373
|
+
_readOutputsFromReturnType(node) {
|
|
374
|
+
let results = [];
|
|
375
|
+
let annotation = node.value?.returnType?.typeAnnotation;
|
|
376
|
+
|
|
377
|
+
if (node?.type === 'ClassDeclaration')
|
|
378
|
+
return [];
|
|
379
|
+
|
|
380
|
+
if (annotation?.typeName?.name === "Promise") {
|
|
381
|
+
const argumnets = annotation.typeArguments?.params;
|
|
382
|
+
if (argumnets && argumnets.length === 1) {
|
|
383
|
+
annotation = argumnets[0];
|
|
384
|
+
} else annotation = {};
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
if (annotation?.type === "TSTypeLiteral"){
|
|
388
|
+
results = this._readOutputsFromReturnTypeObject(annotation);
|
|
389
|
+
}
|
|
390
|
+
else{
|
|
391
|
+
let resultType = this._readReturnType(annotation);
|
|
392
|
+
results.push({name: 'result', type: resultType});
|
|
393
|
+
if (resultType === 'void')
|
|
394
|
+
results = [];
|
|
395
|
+
}
|
|
396
|
+
return results;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
_readOutputsFromReturnTypeObject(node) {
|
|
400
|
+
let i = 0;
|
|
401
|
+
let results = [];
|
|
402
|
+
for (let member of node.members) {
|
|
403
|
+
results.push({
|
|
404
|
+
name: member?.key?.name ?? `result${i}`,
|
|
405
|
+
type: this._readReturnType(member.typeAnnotation.typeAnnotation),
|
|
406
|
+
});
|
|
407
|
+
i++;
|
|
408
|
+
}
|
|
409
|
+
return results;
|
|
410
|
+
}
|
|
386
411
|
|
|
387
412
|
_getTypeNameFromNode(typeNode) {
|
|
388
413
|
if (typeNode.type === "TSTypeReference") {
|