Browse Source

Convert scripts to typescript

Steven Silvester 7 years ago
parent
commit
ed8ce57c87

+ 1 - 0
lerna.json

@@ -8,6 +8,7 @@
     "packages/services/examples/node",
     "packages/services/examples/browser",
     "packages/services/examples/typescript-browser-with-output",
+    "scripts",
     "test"
   ],
   "version": "independent"

+ 7 - 7
package.json

@@ -1,12 +1,13 @@
 {
   "private": true,
   "scripts": {
-    "addsibling": "node scripts/add-sibling.js",
-    "build": "npm run build:packages && cd jupyterlab && npm run build",
+    "install": "lerna bootstrap --hoist",
+    "build": "npm run build:scripts && npm run build:packages && cd jupyterlab && npm run build",
     "build:examples": "lerna run build --scope \"@jupyterlab/example-*\"",
     "build:main": "npm run build",
     "build:main:prod": "npm run build:packages && cd jupyterlab && npm run build:prod",
     "build:packages": "cd packages/all-packages && npm run build",
+    "build:scripts": "cd scripts && npm run build",
     "build:src": "lerna run build --scope \"@jupyterlab/!(test-|example-)*\"",
     "build:static": "cd jupyterlab && npm run build:static",
     "build:test": "lerna run build:test",
@@ -19,23 +20,22 @@
     "coverage": "lerna run coverage --stream",
     "docs": "lerna run docs",
     "get:dependency": "node scripts/get-dependency.js",
-    "install": "lerna bootstrap --hoist",
     "integrity": "node scripts/ensure-integrity.js",
     "publish": "npm run clean:slate && lerna publish --force-publish=* -m \"Publish\"",
-    "remove:dependency": "node scripts/remove-dependency.js",
-    "removesibling": "node scripts/remove-sibling.js",
+    "remove:dependency": "node scripts/lib/remove-dependency.js",
+    "removesibling": "node scripts/lib/remove-sibling.js",
     "test": "cd test && npm test",
     "test:chrome": "lerna run test:chrome --stream",
     "test:firefox": "lerna run test:firefox --stream",
     "test:ie": "lerna run test:ie --concurrency 1 --stream",
     "test:services": "cd packages/services && npm test && npm run test:integration && cd examples/node && python main.py",
     "update:core": "npm run integrity && cd jupyterlab && node update-core.js",
+    "update:dependency": "node scripts/lib/update-dependency.js",
     "watch:main": "cd jupyterlab && npm run watch",
     "watch:packages": "cd packages/all-packages && npm run watch",
     "watch": "run-p watch:*",
     "addsibling": "node scripts/add-sibling.js",
-    "removesibling": "node scripts/remove-sibling.js",
-    "update:dependency": "node scripts/update-dependency.js"
+    "removesibling": "node scripts/remove-sibling.js"
   },
   "dependencies": {},
   "devDependencies": {

+ 0 - 58
scripts/clean-packages.js

@@ -1,58 +0,0 @@
-#!/usr/bin/env node
-var fs = require('fs');
-var path = require('path');
-var glob = require('glob');
-var childProcess = require('child_process');
-
-
-// Get all of the packages.
-var basePath = path.resolve('.');
-var lernaConfig = require(path.join(basePath, 'lerna.json'));
-var packageConfig = lernaConfig.packages;
-var skipSource = process.argv.indexOf('packages') === -1;
-var skipExamples = process.argv.indexOf('examples') === -1;
-
-
-// Handle the packages
-for (var i = 0; i < packageConfig.length; i++) {
-  if (skipSource && packageConfig[i] === 'packages/*') {
-    continue;
-  }
-  if (skipExamples && packageConfig[i] === 'examples/*') {
-    continue;
-  }
-  var files = glob.sync(path.join(basePath, packageConfig[i]));
-  for (var j = 0; j < files.length; j++) {
-    try {
-      handlePackage(files[j]);
-    } catch (e) {
-      console.error(e);
-    }
-  }
-}
-
-
-/**
- * Handle an individual package on the path - update the dependency.
- */
-function handlePackage(packagePath) {
-  // Read in the package.json.
-  var packagePath = path.join(packagePath, 'package.json');
-  try {
-    var package = require(packagePath);
-  } catch (e) {
-    console.log('skipping', packagePath);
-    return
-  }
-  if (!package.scripts || !package.scripts.clean) {
-    return;
-  }
-  var targets = package.scripts.clean.split('&&');
-  for (var i = 0; i < targets.length; i++) {
-    var target = targets[i].replace('rimraf', '').trim();
-    target = path.join(packagePath, target);
-    if (fs.existsSync(target)) {
-      fs.removeSync(target);
-    }
-  }
-}

+ 0 - 75
scripts/get-dependency.js

@@ -1,75 +0,0 @@
-// Get the appropriate dependency for a package.
-var path = require('path');
-var glob = require('glob');
-var utils = require('./utils');
-var childProcess = require('child_process');
-
-var allDeps = [];
-var allDevDeps = [];
-var hatVersions = [/@phosphor\/*/]
-
-/**
- * Get the appropriate dependency for a given package name.
- */
-function getDependency(name) {
-  var version = null;
-
-  try {
-    var data = require(path.join(name, 'package.json'));
-    var spec = '~';
-    for (var hat of hatVersions) {
-      if (hat.test(data.name)) {
-        spec = '^'
-      }
-    }
-    version = spec + data.version;
-  } catch (e) {
-    // ignore
-  }
-
-  utils.getCorePaths().forEach(function (pkgRoot) {
-  // Read in the package.json.
-    var packagePath = path.join(pkgRoot, 'package.json');
-    try {
-      var package = require(packagePath);
-    } catch (e) {
-      console.log('Skipping package ' + packagePath);
-      return;
-    }
-
-    if (package.name === name) {
-      version = '^' + package.version;
-    }
-
-    var deps = package.dependencies || {};
-    var devDeps = package.devDependencies || {};
-    if (deps[name]) {
-      allDeps.push(package.name);
-    }
-    if (devDeps[name]) {
-      allDevDeps.push(package.name);
-    }
-  });
-
-  if (!version) {
-    var cmd = 'npm view ' + name + ' version';
-    version = '~' + String(childProcess.execSync(cmd)).trim();
-  }
-
-  return version;
-}
-
-module.exports = getDependency;
-
-if (require.main === module) {
-  // Make sure we have required command line arguments.
-  if (process.argv.length < 3) {
-      var msg = '** Must supply a target library name\n';
-      process.stderr.write(msg);
-      process.exit(1);
-  }
-  var version = getDependency(process.argv[2]);
-  console.log('deps: ', allDeps);
-  console.log('devDeps:', allDevDeps);
-  console.log('\n    ' + '"' + name + '": "' + version + '"');
-}

+ 25 - 0
scripts/package.json

@@ -0,0 +1,25 @@
+{
+  "name": "@jupyterlab/scripts",
+  "private": true,
+  "version": "0.1.0",
+  "description": "JupyterLab - Scripts",
+  "license": "BSD-3-Clause",
+  "author": "Project Jupyter",
+  "scripts": {
+    "build": "tsc",
+    "clean": "rimraf lib",
+    "watch": "tsc -w"
+  },
+  "dependencies": {
+    "fs-extra": "~4.0.2",
+    "glob": "~7.1.2",
+    "sort-package-json": "~1.7.1"
+  },
+  "devDependencies": {
+    "@types/fs-extra": "~4.0.3",
+    "@types/glob": "~5.0.33",
+    "@types/node": "~8.0.47",
+    "rimraf": "~2.6.2",
+    "typescript": "~2.4.2"
+  }
+}

+ 0 - 39
scripts/patch-release.js

@@ -1,39 +0,0 @@
-#!/usr/bin/env node
-var fs = require('fs');
-var path = require('path');
-var childProcess = require('child_process');
-
-
-// Make sure we have required command line arguments.
-if (process.argv.length < 3) {
-  var msg = '** Must supply a target package';
-  process.stderr.write(msg);
-  process.exit(1);
-}
-
-// Extract the desired package target.
-var target = process.argv[2];
-
-var packagePath = path.resolve(path.join('packages', target));
-
-if (!fs.existsSync(packagePath)) {
-  console.log('Invalid package path', packagePath);
-  process.exit(1);
-}
-
-// Perform the patch operations.
-console.log('Patching', target, '...');
-run('npm run build:packages');
-run('npm version patch', { cwd: packagePath });
-run('npm publish', { cwd: packagePath});
-
-// Extract the new package info.
-var data = require(path.join(packagePath, 'package.json'));
-var name = data.name;
-var version = data.version;
-
-run('npm run integrity');
-run('git commit -a -m "Release ' + name + '@' + version + '"');
-run('git tag ' + name + '@' + version);
-
-console.log('\n\nFinished, make sure to push the commit and the tag.')

+ 19 - 15
scripts/add-sibling.js → scripts/src/add-sibling.ts

@@ -1,7 +1,8 @@
 #!/usr/bin/env node
-var fs = require('fs-extra');
-var path = require('path');
-var utils = require('./utils');
+import fs = require('fs-extra');
+import path = require('path');
+import utils = require('./utils');
+import childProcess = require('child_process');
 
 /**
  * Add an extension to the source tree of JupyterLab.
@@ -16,34 +17,34 @@ var utils = require('./utils');
 
 // Make sure we have required command line arguments.
 if (process.argv.length < 3) {
-    var msg = '** Must supply a target extension';
+    let msg = '** Must supply a target extension';
     process.stderr.write(msg);
     process.exit(1);
 }
 
 // Extract the desired git repository and repository name.
-var target = process.argv[2];
-var basePath = path.resolve('.');
-var packageDirName;
+let target = process.argv[2];
+let basePath = path.resolve('.');
+let packageDirName;
 
-var packagePath = '';
+let packagePath = '';
 if (target[0] === '.' || target[0] === '/') {
   // If the target starts with a '.' or a '/', treat it as a local path.
   packagePath = path.resolve(target);
   // Possibly remove a trailing slash.
-  if (packagePath[packagePath.length-1] === '/') {
+  if (packagePath[packagePath.length - 1] === '/') {
     packagePath = packagePath.slice(0, -1);
   }
   packageDirName = packagePath.split('/').pop();
   // Copy the package directory contents to the sibling package.
-  var newPackagePath = path.join(basePath, 'packages', packageDirName);
+  let newPackagePath = path.join(basePath, 'packages', packageDirName);
   fs.copySync(packagePath, newPackagePath);
 } else {
   // Otherwise treat it as a git reposotory and try to add it.
   packageDirName = target.split('/').pop().split('.')[0];
-  var packagePath = path.join(basePath, 'packages', packageDirName);
+  let packagePath = path.join(basePath, 'packages', packageDirName);
   // Add the repository as a submodule.
-  childProcess.execSync('git clone '+ target + ' ' + packagePath);
+  childProcess.execSync('git clone ' + target + ' ' + packagePath);
 }
 
 // Remove any existing node_modules in the extension.
@@ -51,10 +52,13 @@ if (fs.existsSync(path.join(packagePath, 'node_modules'))) {
   fs.removeSync(path.join(packagePath, 'node_modules'));
 }
 
+// Get the package.json of the extension.
+let data = require(path.join(packagePath, 'package.json'));
+
 // Add the extension path to packages/all-packages/tsconfig.json
-var tsconfigPath = path.join(basePath, 'packages', 'all-packages', 'tsconfig.json');
-var tsconfig = require(tsconfigPath);
-tsconfig.compilerOptions.paths[package.name] = [path.join('..', packageDirName, 'src')];
+let tsconfigPath = path.join(basePath, 'packages', 'all-packages', 'tsconfig.json');
+let tsconfig = require(tsconfigPath);
+tsconfig.compilerOptions.paths[data.name] = [path.join('..', packageDirName, 'src')];
 fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\n');
 
 // Update the core jupyterlab build dependencies.

+ 58 - 0
scripts/src/clean-packages.ts

@@ -0,0 +1,58 @@
+#!/usr/bin/env node
+import fs = require('fs-extra');
+import path = require('path');
+import glob = require('glob');
+
+
+// Get all of the packages.
+let basePath = path.resolve('.');
+let lernaConfig = require(path.join(basePath, 'lerna.json'));
+let packageConfig = lernaConfig.packages;
+let skipSource = process.argv.indexOf('packages') === -1;
+let skipExamples = process.argv.indexOf('examples') === -1;
+
+
+// Handle the packages
+for (let i = 0; i < packageConfig.length; i++) {
+  if (skipSource && packageConfig[i] === 'packages/*') {
+    continue;
+  }
+  if (skipExamples && packageConfig[i] === 'examples/*') {
+    continue;
+  }
+  let files = glob.sync(path.join(basePath, packageConfig[i]));
+  for (let j = 0; j < files.length; j++) {
+    try {
+      handlePackage(files[j]);
+    } catch (e) {
+      console.error(e);
+    }
+  }
+}
+
+
+/**
+ * Handle an individual package on the path - update the dependency.
+ */
+function handlePackage(packagePath: string): void {
+  // Read in the package.json.
+  packagePath = path.join(packagePath, 'package.json');
+  let data: any;
+  try {
+    data = require(packagePath);
+  } catch (e) {
+    console.log('skipping', packagePath);
+    return;
+  }
+  if (!data.scripts || !data.scripts.clean) {
+    return;
+  }
+  let targets = data.scripts.clean.split('&&');
+  for (let i = 0; i < targets.length; i++) {
+    let target = targets[i].replace('rimraf', '').trim();
+    target = path.join(packagePath, target);
+    if (fs.existsSync(target)) {
+      fs.removeSync(target);
+    }
+  }
+}

+ 82 - 74
scripts/ensure-integrity.js → scripts/src/ensure-integrity.ts

@@ -5,112 +5,113 @@
  * Ensure imports match dependencies for TypeScript packages.
  * Manage the all-packages meta package.
  */
-var path = require('path');
-var glob = require('glob');
-var ts = require("typescript");
-var fs = require('fs-extra');
-var getDependency = require('./get-dependency');
-var utils = require('./utils');
+import path = require('path');
+import glob = require('glob');
+import ts = require('typescript');
+import fs = require('fs-extra');
+import getDependency = require('./get-dependency');
+import utils = require('./utils');
 
 
 // Data to ignore.
-var MISSING = {
-  "@jupyterlab/buildutils": ["path"]
-}
+let MISSING: { [key: string]: string[] } = {
+  '@jupyterlab/buildutils': ['path']
+};
 
-var UNUSED = {
-  "@jupyterlab/apputils-extension": ["es6-promise"],
-  "@jupyterlab/theme-dark-extension": ["font-awesome"],
-  "@jupyterlab/theme-light-extension": ["font-awesome"],
-  "@jupyterlab/vega2-extension": ["d3","vega","vega-lite"]
-}
+let UNUSED: { [key: string]: string[] } = {
+  '@jupyterlab/apputils-extension': ['es6-promise'],
+  '@jupyterlab/theme-dark-extension': ['font-awesome'],
+  '@jupyterlab/theme-light-extension': ['font-awesome'],
+  '@jupyterlab/vega2-extension': ['d3', 'vega', 'vega-lite']
+};
 
-var pkgData = {};
-var pkgPaths = {};
-var pkgNames = {};
-var seenDeps = {};
+let pkgData: { [key: string]: any } = {};
+let pkgPaths: { [key: string]: string } = {};
+let pkgNames: { [key: string]: string } = {};
+let seenDeps: { [key: string]: string } = {};
 
 
 /**
  * Ensure the integrity of a package.
  */
-function ensurePackage(pkgName) {
-  var dname = pkgPaths[pkgName];
-  var data = pkgData[pkgName];
-  var deps = data.dependencies;
-  var devDeps = data.devDependencies;
-  var messages = [];
+function ensurePackage(pkgName: string): string[] {
+  let dname = pkgPaths[pkgName];
+  let data = pkgData[pkgName];
+  let deps: { [key: string]: string } = data.dependencies;
+  let devDeps: { [key: string]: string } = data.devDependencies;
+  let messages: string[] = [];
 
   // Verify dependencies are consistent.
-  Object.keys(deps).forEach(function(name) {
+  Object.keys(deps).forEach(name => {
     if (!(name in seenDeps)) {
-      seenDeps[name] = getDependency(name);
+      seenDeps[name] = getDependency.getDependency(name);
     }
     deps[name] = seenDeps[name];
   });
 
   // Verify devDependencies are consistent.
-  Object.keys(devDeps).forEach(function(name) {
+  Object.keys(devDeps).forEach(name => {
     if (!(name in seenDeps)) {
-      seenDeps[name] = getDependency(name);
+      seenDeps[name] = getDependency.getDependency(name);
     }
     devDeps[name] = seenDeps[name];
   });
 
   // For TypeScript files, verify imports match dependencies.
+  let filenames: string[] = [];
   filenames = glob.sync(path.join(dname, 'src/*.ts*'));
   filenames = filenames.concat(glob.sync(path.join(dname, 'src/**/*.ts*')));
 
-  if (filenames.length == 0) {
+  if (filenames.length === 0) {
     if (utils.ensurePackageData(data, path.join(dname, 'package.json'))) {
       messages.push('Package data changed');
     }
     return messages;
   }
 
-  var imports = [];
+  let imports: string[] = [];
 
   // Extract all of the imports from the TypeScript files.
   filenames.forEach(fileName => {
-    var sourceFile = ts.createSourceFile(fileName,
-        fs.readFileSync(fileName).toString(), ts.ScriptTarget.ES6,
+    let sourceFile = ts.createSourceFile(fileName,
+        fs.readFileSync(fileName).toString(), (ts.ScriptTarget as any).ES6,
         /*setParentNodes */ true);
     imports = imports.concat(getImports(sourceFile));
   });
-  var names = Array.from(new Set(imports)).sort();
+  let names: string[] = Array.from(new Set(imports)).sort();
   names = names.map(function(name) {
-    var parts = name.split('/');
+    let parts = name.split('/');
     if (name.indexOf('@') === 0) {
       return parts[0] + '/' + parts[1];
     }
     return parts[0];
-  })
+  });
 
   // Look for imports with no dependencies.
-  names.forEach(function(name) {
+  names.forEach(name => {
     if (MISSING[pkgName] && MISSING[pkgName].indexOf(name) !== -1) {
       return;
     }
-    if (name == '.' || name == '..') {
+    if (name === '.' || name === '..') {
       return;
     }
     if (!deps[name]) {
       messages.push('Missing dependency: ' + name);
       if (!(name in seenDeps)) {
-        seenDeps[name] = getDependency(name);
+        seenDeps[name] = getDependency.getDependency(name);
       }
       deps[name] = seenDeps[name];
     }
   });
 
   // Look for unused packages
-  Object.keys(deps).forEach(function(name) {
+  Object.keys(deps).forEach(name => {
     if (UNUSED[pkgName] && UNUSED[pkgName].indexOf(name) !== -1) {
       return;
     }
     if (names.indexOf(name) === -1) {
       messages.push('Unused dependency: ' + name);
-      delete data.dependencies[name]
+      delete data.dependencies[name];
     }
   });
 
@@ -123,12 +124,16 @@ function ensurePackage(pkgName) {
 
 /**
  * Extract the module imports from a TypeScript source file.
+ *
+ * @param sourceFile - The path to the source file.
+ *
+ * @returns An array of package names.
  */
-function getImports(sourceFile) {
-  var imports = [];
+function getImports(sourceFile: ts.SourceFile): string[] {
+  let imports: string[] = [];
   handleNode(sourceFile);
 
-  function handleNode(node) {
+  function handleNode(node: any): void {
     switch (node.kind) {
       case ts.SyntaxKind.ImportDeclaration:
         imports.push(node.moduleSpecifier.text);
@@ -136,6 +141,8 @@ function getImports(sourceFile) {
       case ts.SyntaxKind.ImportEqualsDeclaration:
         imports.push(node.moduleReference.expression.text);
         break;
+      default:
+        // no-op
     }
     ts.forEachChild(node, handleNode);
   }
@@ -145,26 +152,26 @@ function getImports(sourceFile) {
 
 /**
  * Ensure the all-packages package.
+ *
+ * @returns An array of messages for changes.
  */
-function ensureAllPackages() {
-  var basePath = path.resolve('.');
-  var allPackagesPath = path.join(basePath, 'packages', 'all-packages');
-  var allPackageJson = path.join(allPackagesPath, 'package.json');
-  var allPackageData = require(allPackageJson);
-  var tsconfigPath = path.join(allPackagesPath, 'tsconfig.json');
-  var tsconfig = require(tsconfigPath);
-  var indexPath = path.join(allPackagesPath, 'src', 'index.ts');
-  var index = fs.readFileSync(indexPath, 'utf8');
-  var lines = index.split('\n').slice(0, 3);
-  var messages = [];
-
-  utils.getCorePaths().forEach(function (pkgPath) {
+function ensureAllPackages(): string[] {
+  let basePath = path.resolve('.');
+  let allPackagesPath = path.join(basePath, 'packages', 'all-packages');
+  let allPackageJson = path.join(allPackagesPath, 'package.json');
+  let allPackageData = require(allPackageJson);
+  let indexPath = path.join(allPackagesPath, 'src', 'index.ts');
+  let index = fs.readFileSync(indexPath, 'utf8');
+  let lines = index.split('\n').slice(0, 3);
+  let messages: string[] = [];
+
+  utils.getCorePaths().forEach(pkgPath => {
     if (pkgPath === allPackagesPath) {
       return;
     }
-    var name = pkgNames[pkgPath];
-    var data = pkgData[name];
-    var valid = true;
+    let name = pkgNames[pkgPath];
+    let data = pkgData[name];
+    let valid = true;
 
     // Ensure it is a dependency.
     if (!allPackageData.dependencies[name]) {
@@ -187,8 +194,8 @@ function ensureAllPackages() {
   if (utils.ensurePackageData(allPackageData, allPackageJson)) {
     messages.push('Package data changed');
   }
-  var newIndex = lines.join('\n');
-  if (newIndex != index) {
+  let newIndex = lines.join('\n');
+  if (newIndex !== index) {
     messages.push('Index changed');
     fs.writeFileSync(indexPath, lines.join('\n'));
   }
@@ -200,35 +207,36 @@ function ensureAllPackages() {
 /**
  * Ensure the repo integrity.
  */
-function ensureIntegrity() {
-  var messages = {};
+function ensureIntegrity(): void {
+  let messages: { [key: string]: string[] } = {};
 
   // Pick up all the package versions.
-  utils.getLernaPaths().forEach(function(pkgPath) {
+  utils.getLernaPaths().forEach(pkgPath => {
     // Read in the package.json.
+    let data: any;
     try {
-      var package = require(path.join(pkgPath, 'package.json'));
+      data = require(path.join(pkgPath, 'package.json'));
     } catch (e) {
       return;
     }
 
-    pkgData[package.name] = package;
-    pkgPaths[package.name] = pkgPath;
-    pkgNames[pkgPath] = package.name;
+    pkgData[data.name] = data;
+    pkgPaths[data.name] = pkgPath;
+    pkgNames[pkgPath] = data.name;
   });
 
   // Validate each package.
   for (let name in pkgData) {
-    var pkgMessages = ensurePackage(name);
+    let pkgMessages = ensurePackage(name);
     if (pkgMessages.length > 0) {
       messages[name] = pkgMessages;
     }
-  };
+  }
 
   // Handle the all-packages metapackage.
-  var pkgMessages = ensureAllPackages();
+  let pkgMessages = ensureAllPackages();
   if (pkgMessages.length > 0) {
-    var allName ='@jupyterlab/all-packages';
+    let allName ='@jupyterlab/all-packages';
     if (!messages[allName]) {
       messages[allName] = [];
     }
@@ -242,7 +250,7 @@ function ensureIntegrity() {
       console.log('\n\nPlease run `npm run integrity` locally and commit the changes');
     } else {
       console.log('\n\nPlease commit the changes by running:');
-      console.log('git commit -a -m "Package integrity updates"')
+      console.log('git commit -a -m "Package integrity updates"');
     }
     process.exit(1);
   } else {

+ 79 - 0
scripts/src/get-dependency.ts

@@ -0,0 +1,79 @@
+// Get the appropriate dependency for a package.
+import path = require('path');
+import utils = require('./utils');
+import childProcess = require('child_process');
+
+let allDeps: string[] = [];
+let allDevDeps: string[] = [];
+let hatVersions: ReadonlyArray<string | RegExp> = [/@phosphor\/*/];
+
+
+/**
+ * Get the appropriate dependency for a given package name.
+ *
+ * @param name - The name of the package.
+ *
+ * @returns The dependency version specifier.
+ */
+export
+function getDependency(name: string): string {
+  let version = null;
+
+  try {
+    let data = require(path.join(name, 'package.json'));
+    let spec = '~';
+    for (let hat of hatVersions) {
+      if (RegExp(hat).test(data.name)) {
+        spec = '^';
+      }
+    }
+    version = spec + data.version;
+  } catch (e) {
+    // ignore
+  }
+
+  utils.getCorePaths().forEach(pkgRoot => {
+  // Read in the package.json.
+    let packagePath = path.join(pkgRoot, 'package.json');
+    let data: any;
+    try {
+      data = require(packagePath);
+    } catch (e) {
+      console.log('Skipping package ' + packagePath);
+      return;
+    }
+
+    if (data.name === name) {
+      version = '^' + data.version;
+    }
+
+    let deps = data.dependencies || {};
+    let devDeps = data.devDependencies || {};
+    if (deps[name]) {
+      allDeps.push(data.name);
+    }
+    if (devDeps[name]) {
+      allDevDeps.push(data.name);
+    }
+  });
+
+  if (!version) {
+    let cmd = 'npm view ' + name + ' version';
+    version = '~' + String(childProcess.execSync(cmd)).trim();
+  }
+
+  return version;
+}
+
+if (require.main === module) {
+  // Make sure we have required command line arguments.
+  if (process.argv.length < 3) {
+      let msg = '** Must supply a target library name\n';
+      process.stderr.write(msg);
+      process.exit(1);
+  }
+  let version = getDependency(process.argv[2]);
+  console.log('deps: ', allDeps);
+  console.log('devDeps:', allDevDeps);
+  console.log('\n    ' + '"' + name + '": "' + version + '"');
+}

+ 39 - 0
scripts/src/patch-release.ts

@@ -0,0 +1,39 @@
+#!/usr/bin/env node
+import fs = require('fs');
+import path = require('path');
+import utils = require('./utils');
+
+
+// Make sure we have required command line arguments.
+if (process.argv.length < 3) {
+  let msg = '** Must supply a target package';
+  process.stderr.write(msg);
+  process.exit(1);
+}
+
+// Extract the desired package target.
+let target = process.argv[2];
+
+let packagePath = path.resolve(path.join('packages', target));
+
+if (!fs.existsSync(packagePath)) {
+  console.log('Invalid package path', packagePath);
+  process.exit(1);
+}
+
+// Perform the patch operations.
+console.log('Patching', target, '...');
+utils.run('npm run build:packages');
+utils.run('npm version patch', { cwd: packagePath });
+utils.run('npm publish', { cwd: packagePath});
+
+// Extract the new package info.
+let data = require(path.join(packagePath, 'package.json'));
+let name = data.name;
+let version = data.version;
+
+utils.run('npm run integrity');
+utils.run('git commit -a -m "Release ' + name + '@' + version + '"');
+utils.run('git tag ' + name + '@' + version);
+
+console.log('\n\nFinished, make sure to push the commit and the tag.');

+ 4 - 0
scripts/src/read-package-json.d.ts

@@ -0,0 +1,4 @@
+declare module 'sort-package-json' {
+    function sort(value: any): any;
+    export = sort;
+}

+ 8 - 10
scripts/remove-dependency.js → scripts/src/remove-dependency.ts

@@ -1,19 +1,16 @@
-#!/usr/bin/env node
-var fs = require('fs');
-var path = require('path');
-var glob = require('glob');
-var utils = require('./utils');
+import path = require('path');
+import utils = require('./utils');
 
 
 // Make sure we have required command line arguments.
 if (process.argv.length !== 3) {
-  var msg = '** Must supply a library name\n';
+  let msg = '** Must supply a library name\n';
   process.stderr.write(msg);
   process.exit(1);
 }
 
 
-var name = process.argv[2];
+let name = process.argv[2];
 
 // Handle the packages
 utils.getLernaPaths().forEach(function (pkgPath) {
@@ -25,11 +22,12 @@ handlePackage(path.resolve('.'));
 /**
  * Handle an individual package on the path - update the dependency.
  */
-function handlePackage(packagePath) {
+function handlePackage(packagePath: string): void {
   // Read in the package.json.
-  var packagePath = path.join(packagePath, 'package.json');
+  packagePath = path.join(packagePath, 'package.json');
+  let data: any;
   try {
-    var data = require(packagePath);
+    data = require(packagePath);
   } catch (e) {
     console.log('Skipping package ' + packagePath);
     return;

+ 11 - 11
scripts/remove-sibling.js → scripts/src/remove-sibling.ts

@@ -8,32 +8,32 @@
  * branches of JupyterLab.
  */
 
-var fs = require('fs-extra');
-var path = require('path');
-var utils = require('./utils');
+import fs = require('fs-extra');
+import path = require('path');
+import utils = require('./utils');
 
 // Make sure we have required command line arguments.
 if (process.argv.length < 3) {
-    var msg = '** Must supply a target extension name';
+    let msg = '** Must supply a target extension name';
     process.stderr.write(msg);
     process.exit(1);
 }
 
 // Get the package name or path.
-var target = process.argv[2];
-var basePath = path.resolve('.');
+let target = process.argv[2];
+let basePath = path.resolve('.');
 
 // Get the package.json of the extension.
-var packagePath = path.join(basePath, 'packages', target, 'package.json');
+let packagePath = path.join(basePath, 'packages', target, 'package.json');
 if (!fs.existsSync(packagePath)) {
     packagePath = require.resolve(path.join(target, 'package.json'));
 }
-var package = require(packagePath);
+let data = require(packagePath);
 
 // Remove the extension path from packages/all-packages/tsconfig.json
-var tsconfigPath = path.join(basePath, 'packages', 'all-packages', 'tsconfig.json');
-var tsconfig = require(tsconfigPath);
-tsconfig.compilerOptions.paths[package.name] = undefined;
+let tsconfigPath = path.join(basePath, 'packages', 'all-packages', 'tsconfig.json');
+let tsconfig = require(tsconfigPath);
+tsconfig.compilerOptions.paths[data.name] = undefined;
 fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2) + '\n');
 
 // Remove the package from the local tree.

+ 55 - 0
scripts/src/update-dependency.ts

@@ -0,0 +1,55 @@
+import path = require('path');
+import childProcess = require('child_process');
+import utils = require('./utils');
+
+
+// Make sure we have required command line arguments.
+if (process.argv.length !== 3) {
+  let msg = '** Must supply an update specifier\n';
+  process.stderr.write(msg);
+  process.exit(1);
+}
+
+// Extract the desired library target and specifier.
+let parts = process.argv[2].split('@');
+
+// Translate @latest to a concrete version.
+if (parts.length === 1 || parts[1] === 'latest') {
+  let cmd = 'npm view ' + parts[0] + ' version';
+  parts.push('~' + String(childProcess.execSync(cmd)).trim());
+}
+let name = parts[0];
+let specifier = parts[1];
+
+
+// Handle the packages
+utils.getLernaPaths().forEach(pkgPath => {
+  handlePackage(pkgPath);
+});
+handlePackage(path.resolve('.'));
+
+
+/**
+ * Handle an individual package on the path - update the dependency.
+ */
+function handlePackage(packagePath: string): void {
+  // Read in the package.json.
+  packagePath = path.join(packagePath, 'package.json');
+  let data: any;
+  try {
+    data = require(packagePath);
+  } catch (e) {
+    console.log('Skipping package ' + packagePath);
+    return;
+  }
+
+  // Update dependencies as appropriate.
+  if (name in data['dependencies']) {
+    data['dependencies'][name] = specifier;
+  } else if (name in data['devDependencies']) {
+    data['devDependencies'][name] = specifier;
+  }
+
+  // Write the file back to disk.
+  utils.ensurePackageData(data, packagePath);
+}

+ 63 - 0
scripts/src/utils.ts

@@ -0,0 +1,63 @@
+import path = require('path');
+import glob = require('glob');
+import fs = require('fs-extra');
+import childProcess = require('child_process');
+import sortPackageJson = require('sort-package-json');
+
+
+/**
+ * Get all of the lerna package paths.
+ */
+export
+function getLernaPaths(): string[] {
+  let basePath = path.resolve('.');
+  let lernaConfig = require(path.join(basePath, 'lerna.json'));
+  let paths: string[] = [];
+  for (let config of lernaConfig.packages) {
+    paths = paths.concat(glob.sync(path.join(basePath, config)));
+  }
+  return paths;
+}
+
+/**
+ * Get all of the core package paths.
+ */
+export
+function getCorePaths(): string[] {
+  let spec = path.resolve(path.join('.', 'packages', '*'));
+  return glob.sync(spec);
+}
+
+
+/**
+ * Write a package.json if necessary.
+ *
+ * @param data - The package data.
+ *
+ * @oaram pkgJsonPath - The path to the package.json file.
+ *
+ * @returns Whether the file has changed.
+ */
+export
+function ensurePackageData(data: any, pkgJsonPath: string): boolean {
+  let text = JSON.stringify(sortPackageJson(data), null, 2) + '\n';
+  let orig = fs.readFileSync(pkgJsonPath).toString();
+  if (text !== orig) {
+    fs.writeFileSync(pkgJsonPath, text);
+    return true;
+  }
+  return false;
+}
+
+/**
+ * Run a command with terminal output.
+ *
+ * @param cmd - The command to run.
+ */
+export
+function run(cmd: string, options: childProcess.ExecSyncOptions = {}): void {
+  options = options || {};
+  options['stdio'] = [1, 2, 3];
+  console.log('>', cmd);
+  childProcess.execSync(cmd, options);
+}

+ 16 - 0
scripts/tsconfig.json

@@ -0,0 +1,16 @@
+{
+  "compilerOptions": {
+    "declaration": true,
+    "noImplicitAny": true,
+    "noEmitOnError": true,
+    "noUnusedLocals": true,
+    "module": "commonjs",
+    "moduleResolution": "node",
+    "target": "ES5",
+    "outDir": "./lib",
+    "lib": [
+      "ES5", "ES2015.Promise", "DOM", "ES2015.Collection", "ES2016", "ES6"
+    ]
+  },
+  "include": ["src/*"]
+}

+ 0 - 57
scripts/update-dependency.js

@@ -1,57 +0,0 @@
-#!/usr/bin/env node
-var fs = require('fs');
-var path = require('path');
-var glob = require('glob');
-var childProcess = require('child_process');
-var utils = requier('./utils');
-
-
-// Make sure we have required command line arguments.
-if (process.argv.length !== 3) {
-  var msg = '** Must supply an update specifier\n';
-  process.stderr.write(msg);
-  process.exit(1);
-}
-
-// Extract the desired library target and specifier.
-var parts = process.argv[2].split('@');
-
-// Translate @latest to a concrete version.
-if (parts.length == 1 || parts[1] == 'latest') {
-  var cmd = 'npm view ' + target + ' version';
-  parts.push('~' + String(childProcess.execSync(cmd)).trim());
-}
-var name = parts[0];
-var specifier = parts[1];
-
-
-// Handle the packages
-utils.getLernaPaths().forEach(function (pkgPath) {
-  handlePackage(pkgPath);
-});
-handlePackage(path.resolve('.'));
-
-
-/**
- * Handle an individual package on the path - update the dependency.
- */
-function handlePackage(packagePath) {
-  // Read in the package.json.
-  var packagePath = path.join(packagePath, 'package.json');
-  try {
-    var data = require(packagePath);
-  } catch (e) {
-    console.log('Skipping package ' + packagePath);
-    return;
-  }
-
-  // Update dependencies as appropriate.
-  if (target in data['dependencies']) {
-    data['dependencies'][target] = specifier;
-  } else if (target in data['devDependencies']) {
-    data['devDependencies'][target] = specifier;
-  }
-
-  // Write the file back to disk.
-  utils.ensurePackageData(data, packagePath);
-}

+ 0 - 59
scripts/utils.js

@@ -1,59 +0,0 @@
-var path = require('path');
-var glob = require('glob');
-var fs = require('fs-extra');
-var childProcess = require('child_process');
-var sortPackageJson = require('sort-package-json');
-
-
-/**
- * Get all of the lerna package paths.
- */
-function getLernaPaths() {
-  var basePath = path.resolve('.');
-  var lernaConfig = require(path.join(basePath, 'lerna.json'));
-  var paths = [];
-  for (var config of lernaConfig.packages) {
-    paths = paths.concat(glob.sync(path.join(basePath, config)));
-  }
-  return paths;
-}
-
-/**
- * Get all of the core package paths.
- */
-function getCorePaths() {
-  var spec = path.resolve(path.join('.', 'packages', '*'));
-  return glob.sync(spec);
-}
-
-
-/**
- * Write a package.json if necessary.
- */
-function ensurePackageData(data, pkgJsonPath) {
-  var text = JSON.stringify(sortPackageJson(data), null, 2) + '\n';
-  var orig = fs.readFileSync(pkgJsonPath).toString();
-  if (text !== orig) {
-    fs.writeFileSync(pkgJsonPath, text);
-    return true;
-  }
-  return false;
-}
-
-/**
- * Run a command with terminal output.
- */
-function run(cmd, options) {
-  options = options || {};
-  options['stdio'] = [1,2,3];
-  console.log('>', cmd);
-  childProcess.execSync(cmd, options);
-}
-
-
-module.exports = {
-  getLernaPaths: getLernaPaths,
-  getCorePaths: getCorePaths,
-  ensurePackageData: ensurePackageData,
-  run: run
-};