datagrok-tools 4.8.3 → 4.9.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/README.md CHANGED
@@ -118,4 +118,4 @@ Read more about package development in [Datagrok's documentation](https://datagr
118
118
  save a test run result, add the `--csv` flag (the report will be saved in a
119
119
  CSV file in the package folder). You can find more details in [local package testing
120
120
  instructions](https://datagrok.ai/help/develop/how-to/test-packages#local-testing).
121
- - `link` / `unlink` commands are used for public plugins development to (un)link `datagrok-api` and libraries.
121
+ - `link` command is used for public plugins development to link `datagrok-api` and libraries.
@@ -132,7 +132,7 @@ function createDirectoryContents(name, config, templateDir, packageDir) {
132
132
  dependencies.push("".concat(module, "@").concat(tag));
133
133
  }
134
134
 
135
- contents = JSON.stringify(_package, null, '\t');
135
+ contents = JSON.stringify(_package, null, 2);
136
136
  }
137
137
 
138
138
  if (file === 'package.js' && ts) copyFilePath = _path["default"].join(packageDir, 'package.ts');
@@ -148,7 +148,7 @@ function createDirectoryContents(name, config, templateDir, packageDir) {
148
148
  var eslintConf = JSON.parse(contents);
149
149
  eslintConf.parser = '@typescript-eslint/parser';
150
150
  eslintConf.plugins = ['@typescript-eslint'];
151
- contents = JSON.stringify(eslintConf, null, '\t');
151
+ contents = JSON.stringify(eslintConf, null, 2);
152
152
  }
153
153
  }
154
154
 
@@ -248,7 +248,7 @@ function create(args) {
248
248
  var p = JSON.parse(_fs["default"].readFileSync(packagePath, 'utf-8'));
249
249
  p.repository = repositoryInfo;
250
250
 
251
- _fs["default"].writeFileSync(packagePath, JSON.stringify(p, null, '\t'), 'utf-8');
251
+ _fs["default"].writeFileSync(packagePath, JSON.stringify(p, null, 2), 'utf-8');
252
252
  }
253
253
 
254
254
  process.exit();
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.help = void 0;
7
- var HELP = "\nUsage: grok <command>\n\nDatagrok's package management tool\n\nCommands:\n add Add an object template\n api Create wrapper functions\n check Check package content (function signatures, etc.)\n config Create and manage config files\n create Create a package\n init Modify a package template\n link Link `datagrok-api` and libraries for local development\n unlink Revert `grok link`\n publish Upload a package\n test Run package tests\n\nTo get help on a particular command, use:\n grok <command> --help\n\nRead more about the package development workflow:\nhttps://datagrok.ai/help/develop/develop\n";
7
+ var HELP = "\nUsage: grok <command>\n\nDatagrok's package management tool\n\nCommands:\n add Add an object template\n api Create wrapper functions\n check Check package content (function signatures, etc.)\n config Create and manage config files\n create Create a package\n init Modify a package template\n link Link `datagrok-api` and libraries for local development\n publish Upload a package\n test Run package tests\n\nTo get help on a particular command, use:\n grok <command> --help\n\nRead more about the package development workflow:\nhttps://datagrok.ai/help/develop/develop\n";
8
8
  var HELP_ADD = "\nUsage: grok add <entity> <name>\n\nAdd an object template to your package:\n\ngrok add app <name>\ngrok add connection <name>\ngrok add detector <semantic-type-name>\ngrok add function [tag] <name>\ngrok add query <name>\ngrok add script [tag] <language> <name>\ngrok add view <name>\ngrok add viewer <name>\ngrok add tests\n\nPlease note that entity names may only include letters and numbers\n\nSupported languages for scripts:\njavascript, julia, node, octave, python, r\n\nAvailable tags:\npanel, init\n";
9
9
  var HELP_INIT = "\nUsage: grok init\n\nModify a package template by adding config files for linters, IDE, etc.\n\nOptions:\n[--eslint] [--ide] [--test] [--ts]\n\n--eslint Add a configuration for eslint\n--ide Add an IDE-specific configuration for debugging (vscode)\n--test Add tests support (TypeScript packages only)\n--ts Convert a JavaScript package to TypeScript\n";
10
10
  var HELP_API = "\nUsage: grok api\n\nCreate wrapper functions for package scripts and queries\n";
@@ -13,8 +13,7 @@ var HELP_CREATE = "\nUsage: grok create [name]\n\nCreate a package:\n\ngrok crea
13
13
  var HELP_PUBLISH = "\nUsage: grok publish [host]\n\nUpload a package\n\nOptions:\n[--build|--rebuild] [--debug|--release] [-k | --key] [--suffix]\n\nRunning `grok publish` is the same as running `grok publish defaultHost --build --debug`\n";
14
14
  var HELP_CHECK = "\nUsage: grok check\n\nOptions:\n[-r | --recursive]\n\n--recursive Check all packages in the current directory\n\nCheck package content (function signatures, import statements of external modules, etc.)\n";
15
15
  var HELP_TEST = "\nUsage: grok test\n\nOptions:\n[--host] [--csv]\n\n--host Host alias as in the config file\n--csv Save the test report in a CSV file\n--gui Launch graphical interface (non-headless mode)\n--skip-build Skip the package build step\n--skip-publish Skip the package publication step\n\nRun package tests\n\nSee instructions:\nhttps://datagrok.ai/help/develop/how-to/test-packages#local-testing\n";
16
- var HELP_LINK = "\nUsage: grok link\n\nLink `datagrok-api` and libraries for local development\n";
17
- var HELP_UNLINK = "\nUsage: grok unlink\n\nRevert `grok link`\n";
16
+ var HELP_LINK = "\nUsage: grok link\n\nLink `datagrok-api` and libraries for local development\n\nOptions:\n[--local | --npm]\n\n--local Default. Links libraries and updates package scripts (\"link-all\", \"build-all\")\n--npm Unlinks local packages and runs `npm i`\n";
18
17
  var HELP_MIGRATE = "\nUsage: grok migrate\n\nSwitch to `grok` tools by copying your keys to the config\nfile and converting your scripts in the `package.json` file\n";
19
18
  var help = {
20
19
  add: HELP_ADD,
@@ -24,7 +23,6 @@ var help = {
24
23
  create: HELP_CREATE,
25
24
  init: HELP_INIT,
26
25
  link: HELP_LINK,
27
- unlink: HELP_UNLINK,
28
26
  publish: HELP_PUBLISH,
29
27
  test: HELP_TEST,
30
28
  help: HELP
@@ -8,7 +8,6 @@ Object.defineProperty(exports, "__esModule", {
8
8
  value: true
9
9
  });
10
10
  exports.link = link;
11
- exports.unlink = unlink;
12
11
 
13
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
14
13
 
@@ -34,197 +33,210 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
34
33
 
35
34
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
36
35
 
37
- /**
38
- * Link: api > utils > other libs - npm install, npm run build, npm link
39
- * Unlink: npm install in the package and its dependencies, npm unlink
40
- */
36
+ var curDir = process.cwd();
37
+
38
+ var repositoryDir = _path["default"].dirname(_path["default"].dirname(curDir));
39
+
41
40
  var apiPackageName = 'datagrok-api';
42
41
  var libScope = '@datagrok-libraries';
43
- var paths = (_paths = {}, (0, _defineProperty2["default"])(_paths, apiPackageName, _path["default"].join(_path["default"].dirname(_path["default"].dirname(_path["default"].dirname(__dirname))), 'js-api')), (0, _defineProperty2["default"])(_paths, libScope, _path["default"].join(_path["default"].dirname(_path["default"].dirname(_path["default"].dirname(__dirname))), 'libraries')), _paths);
42
+ var paths = (_paths = {}, (0, _defineProperty2["default"])(_paths, apiPackageName, _path["default"].join(repositoryDir, 'js-api')), (0, _defineProperty2["default"])(_paths, libScope, _path["default"].join(repositoryDir, 'libraries')), _paths);
43
+ var packageDependencies = {};
44
44
  /** Links local packages. */
45
45
 
46
46
  function link(args) {
47
47
  var nOptions = Object.keys(args).length - 1;
48
- if (nOptions > 0 || args['_'].length > 1) return false;
49
- var curDir = process.cwd();
50
-
51
- var packageDir = _path["default"].join(curDir, 'package.json');
48
+ if (nOptions > 1 || args['_'].length > 1 || nOptions === 1 && !args.local && !args.npm) return false;
49
+ var local = args.npm ? false : true; // args.local is default
52
50
 
53
51
  if (!utils.isPackageDir(curDir)) {
54
52
  color.error('File `package.json` not found. Run the command from the package directory');
55
53
  return false;
56
54
  }
57
55
 
58
- var dependencies = readDependencies(JSON.parse(_fs["default"].readFileSync(packageDir, 'utf-8')));
59
-
60
- var modulesDir = _path["default"].join(curDir, 'node_modules');
61
-
62
- if (!_fs["default"].existsSync(modulesDir)) {
63
- console.log('Running `npm install` to get the required dependencies...\n');
64
- (0, _child_process.exec)('npm install', function (err, stdout, stderr) {
65
- if (err) throw err;else console.log(stderr, stdout);
66
- });
67
- } // The order should start with js-api, then libraries/utils, then other libraries
68
-
69
-
70
- var apiModule = null;
71
- var hasUtils = false;
72
- var libs = [];
73
-
74
- var allModules = _fs["default"].readdirSync(modulesDir, {
75
- encoding: 'utf-8',
76
- withFileTypes: true
77
- });
78
-
79
- var _iterator = _createForOfIteratorHelper(allModules),
80
- _step;
81
-
82
- try {
83
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
84
- var m = _step.value;
85
- if (m.name === apiPackageName) apiModule = m;else if (m.name === libScope) {
86
- libs = _fs["default"].readdirSync(_path["default"].join(modulesDir, m.name), {
87
- encoding: 'utf-8',
88
- withFileTypes: true
89
- });
56
+ for (var _i = 0, _Object$values = Object.values(paths); _i < _Object$values.length; _i++) {
57
+ var p = _Object$values[_i];
90
58
 
91
- var _iterator3 = _createForOfIteratorHelper(libs),
92
- _step3;
93
-
94
- try {
95
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
96
- var lib = _step3.value;
97
- if (lib.name === 'utils') hasUtils = true;
98
- }
99
- } catch (err) {
100
- _iterator3.e(err);
101
- } finally {
102
- _iterator3.f();
103
- }
104
- }
59
+ if (!_fs["default"].existsSync(p)) {
60
+ color.error("Directory ".concat(p, " not found. Run the command from the public package repository"));
61
+ return false;
105
62
  }
106
- } catch (err) {
107
- _iterator.e(err);
108
- } finally {
109
- _iterator.f();
110
63
  }
111
64
 
112
- function installLibs(libs) {
113
- if (!libs.length) return;
65
+ var dependencies = readDependencies(curDir);
114
66
 
115
- var f = function f() {
116
- var _iterator2 = _createForOfIteratorHelper(libs),
117
- _step2;
67
+ if (local) {
68
+ var _link = function _link(packagePath) {
69
+ var packageJsonPath = _path["default"].join(packagePath, 'package.json');
118
70
 
119
- try {
120
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
121
- var lib = _step2.value;
71
+ var json = JSON.parse(_fs["default"].readFileSync(packageJsonPath, 'utf-8'));
72
+ json.scripts['link-all'] = generateLinkScript(packagePath, packageHierarchy);
73
+ json.scripts['build-all'] = generateBuildScript(packagePath, packageHierarchy);
122
74
 
123
- if ("".concat(libScope, "/").concat(lib.name) in dependencies) {
124
- var libPath = _path["default"].join(paths[libScope], lib.name);
75
+ _fs["default"].writeFileSync(packageJsonPath, JSON.stringify(json, null, 2), 'utf-8');
125
76
 
126
- var isLinked = lib.isSymbolicLink();
127
- console.log(isLinked ? "Package \"".concat(lib.name, "\" is linked. Updating dependencies and running the build script...") : "Linking \"".concat(lib.name, "\"..."));
128
- (0, _child_process.exec)(isLinked ? 'npm update && npm run build' : 'npm install && npm run link-all && npm run build && npm link', {
129
- cwd: libPath
130
- }, function (err, stdout, stderr) {
131
- if (err) throw err;else console.log(stderr, stdout);
132
- });
133
- }
134
- }
135
- } catch (err) {
136
- _iterator2.e(err);
137
- } finally {
138
- _iterator2.f();
139
- }
140
- };
141
-
142
- if (hasUtils) {
143
- var utilsModule = libs.splice(libs.findIndex(function (m) {
144
- return m.name === 'utils';
145
- }), 1)[0];
146
-
147
- var libPath = _path["default"].join(paths[libScope], 'utils');
148
-
149
- var isLinked = utilsModule.isSymbolicLink();
150
- console.log(isLinked ? "Package \"".concat(utilsModule.name, "\" is linked. Updating dependencies and running the build script...") : "Linking \"".concat(utilsModule.name, "\"..."));
151
- (0, _child_process.exec)(isLinked ? 'npm update && npm run build' : 'npm install && npm run link-all && npm run build && npm link', {
152
- cwd: libPath
77
+ (0, _child_process.exec)('npm install && npm link && npm run link-all', {
78
+ cwd: packagePath
153
79
  }, function (err, stdout, stderr) {
154
- if (err) throw err;else {
155
- console.log(stderr, stdout);
156
- f();
157
- }
80
+ if (err) throw err;else console.log(stderr, stdout);
158
81
  });
159
- } else {
160
- f();
161
- }
162
- }
82
+ };
163
83
 
164
- if (apiModule != null) {
165
- var isLinked = apiModule.isSymbolicLink();
166
- console.log(isLinked ? "Package \"".concat(apiModule.name, "\" is linked. Updating dependencies and running the build script...") : "Linking \"".concat(apiModule.name, "\"..."));
167
- (0, _child_process.exec)(isLinked ? "npm update && npm run build" : "npm install && npm run build && npm link", {
168
- cwd: paths[apiPackageName]
169
- }, function (err, stdout, stderr) {
170
- if (err) throw err;else {
171
- console.log(stderr, stdout);
172
- installLibs(libs);
173
- var packageNames = Object.keys(dependencies).join(' ');
174
- (0, _child_process.exec)("npm link ".concat(packageNames));
175
- }
84
+ var packageHierarchy = getHierarchy(curDir);
85
+ packageHierarchy.forEach(function (packageName) {
86
+ return _link(getPackagePath(packageName));
87
+ });
88
+
89
+ _link(curDir);
90
+ } else {
91
+ runScript(curDir, 'npm install', dependencies, {
92
+ dirMessage: 'Unlinking local packages in ',
93
+ successMessage: 'Local packages have been successfully unlinked.'
176
94
  });
177
95
  }
178
96
 
179
97
  return true;
180
98
  }
181
- /** Unlinks local packages and runs `npm i`. */
182
99
 
100
+ function readDependencies(packagePath) {
101
+ if (packagePath in packageDependencies) return packageDependencies[packagePath];
183
102
 
184
- function unlink(args) {
185
- var nOptions = Object.keys(args).length - 1;
186
- if (nOptions > 0 || args['_'].length > 1) return false;
187
- var curDir = process.cwd();
103
+ var fileContent = _fs["default"].readFileSync(_path["default"].join(packagePath, 'package.json'), 'utf-8');
188
104
 
189
- var packageDir = _path["default"].join(curDir, 'package.json');
105
+ var json = JSON.parse(fileContent);
106
+ var libs = {};
190
107
 
191
- if (!utils.isPackageDir(curDir)) {
192
- color.error('File `package.json` not found. Run the command from the package directory');
193
- return false;
108
+ for (var dep in json.dependencies) {
109
+ if (dep === apiPackageName || dep.startsWith("".concat(libScope, "/"))) libs[dep] = json.dependencies[dep];
110
+ }
111
+
112
+ packageDependencies[packagePath] = libs;
113
+ return libs;
114
+ }
115
+
116
+ function getPackagePath(packageName) {
117
+ return packageName === apiPackageName ? paths[packageName] : _path["default"].join(paths[libScope], packageName.split('/')[1]);
118
+ }
119
+ /** Forms a hierarchy to understand in which order packages should be linked. */
120
+
121
+
122
+ function getHierarchy(packageDir) {
123
+ var hierarchy = [];
124
+ var dependencies = Object.keys(readDependencies(packageDir));
125
+ var cachedHierarchy = {};
126
+
127
+ for (var _i2 = 0, _dependencies = dependencies; _i2 < _dependencies.length; _i2++) {
128
+ var _cachedHierarchy$depP;
129
+
130
+ var dep = _dependencies[_i2];
131
+ var idx = hierarchy.indexOf(dep);
132
+ if (idx === -1) idx = hierarchy.push(dep) - 1;
133
+ var depPath = getPackagePath(dep);
134
+ var internalHierarchy = (_cachedHierarchy$depP = cachedHierarchy[depPath]) !== null && _cachedHierarchy$depP !== void 0 ? _cachedHierarchy$depP : getHierarchy(depPath);
135
+ if (!(depPath in cachedHierarchy)) cachedHierarchy[depPath] = internalHierarchy;
136
+
137
+ var _iterator = _createForOfIteratorHelper(internalHierarchy),
138
+ _step;
139
+
140
+ try {
141
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
142
+ var internalDep = _step.value;
143
+ var depIdx = hierarchy.indexOf(internalDep);
144
+
145
+ if (depIdx === -1) {
146
+ // Insert the internal dependency before the main package
147
+ hierarchy.splice(idx, 0, internalDep);
148
+ idx++;
149
+ } else if (depIdx > idx) {
150
+ // Remove the internal dependency from the list and place it before the main package
151
+ // (doesn't affect the order of same-level libraries, their order is arbitrary)
152
+ hierarchy.splice(depIdx, 1);
153
+ idx = hierarchy.indexOf(dep);
154
+ hierarchy.splice(idx, 0, internalDep);
155
+ idx++;
156
+ }
157
+ }
158
+ } catch (err) {
159
+ _iterator.e(err);
160
+ } finally {
161
+ _iterator.f();
162
+ }
194
163
  }
195
164
 
196
- var dependencies = readDependencies(JSON.parse(_fs["default"].readFileSync(packageDir, 'utf-8')));
197
- var packageNames = Object.keys(dependencies).join(' '); // npm unlink ${packageNames}
165
+ return hierarchy;
166
+ }
167
+ /** Executes a script for a package and its dependencies with messages on the current progress. */
168
+
198
169
 
199
- (0, _child_process.exec)("npm install", function (err, stdout, stderr) {
200
- console.log("Unlinking local packages in ".concat(_path["default"].basename(curDir)));
170
+ function runScript(packageDir, script, dependencies) {
171
+ var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
172
+ (0, _child_process.exec)(script, {
173
+ cwd: packageDir
174
+ }, function (err, stdout, stderr) {
175
+ if (options.dirMessage) console.log("".concat(options.dirMessage).concat(_path["default"].basename(packageDir)));
176
+ if (options.callback) options.callback(packageDir);
201
177
  if (err) throw err;else {
202
178
  console.log(stderr, stdout);
203
179
 
204
180
  var _loop = function _loop(dep) {
205
- var depPath = dep === apiPackageName ? paths[dep] : _path["default"].join(paths[libScope], dep.split('/')[1]);
206
- (0, _child_process.exec)("npm install", {
181
+ var depPath = getPackagePath(dep);
182
+ (0, _child_process.exec)(script, {
207
183
  cwd: depPath
208
184
  }, function (err, stdout, stderr) {
209
- console.log("Unlinking local packages in ".concat(_path["default"].basename(depPath)));
185
+ if (options.dirMessage) console.log("".concat(options.dirMessage).concat(_path["default"].basename(depPath)));
186
+ if (options.callback) options.callback(depPath);
210
187
  if (err) throw err;else console.log(stderr, stdout);
211
188
  });
212
189
  };
213
190
 
214
191
  for (var dep in dependencies) {
215
192
  _loop(dep);
216
- }
193
+ } // if (options.successMessage)
194
+ // setTimeout(() => color.success(options.successMessage!), 5000);
195
+
217
196
  }
218
197
  });
219
- return true;
220
198
  }
199
+ /** Generates a package script to build all dependencies using the provided hierarchy. */
221
200
 
222
- function readDependencies(json) {
223
- var libs = {};
224
201
 
225
- for (var dep in json.dependencies) {
226
- if (dep === apiPackageName || dep.startsWith("".concat(libScope, "/"))) libs[dep] = json.dependencies[dep];
202
+ function generateBuildScript(packagePath, hierarchy) {
203
+ var dependencies = Object.keys(readDependencies(packagePath));
204
+ var packageNames = hierarchy.filter(function (p) {
205
+ return dependencies.includes(p);
206
+ });
207
+ var prefix = "./".concat(_path["default"].relative(packagePath, repositoryDir).split(_path["default"].sep).join('/'), "/");
208
+ var script = '';
209
+
210
+ var _iterator2 = _createForOfIteratorHelper(packageNames),
211
+ _step2;
212
+
213
+ try {
214
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
215
+ var packageName = _step2.value;
216
+ script += "npm --prefix ".concat(prefix).concat(packageName === apiPackageName ? 'js-api' : "libraries/".concat(packageName.split('/')[1]), " run build && ");
217
+ }
218
+ } catch (err) {
219
+ _iterator2.e(err);
220
+ } finally {
221
+ _iterator2.f();
227
222
  }
228
223
 
229
- return libs;
224
+ return "".concat(script ? script : '', "npm run build");
225
+ }
226
+ /** Generates a package script to link all dependencies using the provided hierarchy. */
227
+
228
+
229
+ function generateLinkScript(packagePath, hierarchy) {
230
+ var dependencies = Object.keys(readDependencies(packagePath));
231
+ var packageNames = hierarchy.filter(function (p) {
232
+ return dependencies.includes(p);
233
+ });
234
+
235
+ for (var _i3 = 0, _dependencies2 = dependencies; _i3 < _dependencies2.length; _i3++) {
236
+ var dep = _dependencies2[_i3];
237
+ if (!packageNames.includes(dep)) color.error("Hierarchy does not include package ".concat(dep));
238
+ }
239
+
240
+ var script = "npm link".concat(packageNames.length ? ' ' + packageNames.join(' ') : '');
241
+ return script;
230
242
  }
package/bin/grok.js CHANGED
@@ -12,7 +12,6 @@ const commands = {
12
12
  create: require('./commands/create').create,
13
13
  init: require('./commands/init').init,
14
14
  link: require('./commands/link').link,
15
- unlink: require('./commands/link').unlink,
16
15
  publish: require('./commands/publish').publish,
17
16
  test: require('./commands/test').test,
18
17
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datagrok-tools",
3
- "version": "4.8.3",
3
+ "version": "4.9.0",
4
4
  "description": "Utility to upload and publish packages to Datagrok",
5
5
  "homepage": "https://github.com/datagrok-ai/public/tree/master/tools#readme",
6
6
  "dependencies": {