diff --git a/src/lib/module-info.ts b/src/lib/module-info.ts index e2fadb45..17e2c9cc 100644 --- a/src/lib/module-info.ts +++ b/src/lib/module-info.ts @@ -63,7 +63,7 @@ export default async function getModuleInfo(packageName: string, directory: stri const nameKind = (node as ts.ModuleDeclaration).name.kind; if (nameKind === ts.SyntaxKind.StringLiteral) { // If we're in an external module, this is an augmentation, not a declaration. - if (!isExternalModule(src)) { + if (!ts.isExternalModule(src)) { const name = stripQuotes((node as ts.ModuleDeclaration).name.getText()); noWindowsSlashes(packageName, name); diff --git a/src/lib/packages.ts b/src/lib/packages.ts index 40199c3b..0c960d99 100644 --- a/src/lib/packages.ts +++ b/src/lib/packages.ts @@ -423,11 +423,11 @@ export namespace TypeScriptVersion { case "2.0": // A 2.0-compatible package is assumed compatible with TypeScript 2.1 // We want the "2.1" tag to always exist. - return [tags.latest, tags.v2_0, tags.v2_1]; + return [tags.latest, tags.v2_0, tags.v2_1, tags.v2_2]; case "2.1": // Eventually this will change to include "latest", too. // And obviously we shouldn't advance the "2.0" tag if the package is now 2.1-specific. - return [tags.latest, tags.v2_1]; + return [tags.latest, tags.v2_1, tags.v2_2]; } } @@ -435,5 +435,9 @@ export namespace TypeScriptVersion { export const latest = "latest"; export const v2_0 = "ts2.0"; export const v2_1 = "ts2.1"; + export const v2_2 = "ts2.2"; } + + export type VersionTag = "ts2.0" | "ts2.1" | "ts2.2"; + export const allVersionTags: VersionTag[] = [tags.v2_0, tags.v2_1, tags.v2_2]; } diff --git a/src/lib/versions.ts b/src/lib/versions.ts index 9a3c7e36..dcf57a27 100644 --- a/src/lib/versions.ts +++ b/src/lib/versions.ts @@ -243,7 +243,7 @@ function latestPatchMatchingMajorAndMinor( } const { major, minor, patch } = semver; return major === newMajor && minor === newMinor ? patch : undefined; - }).filter(x => x !== undefined); + }).filter(x => x !== undefined) as number[]; return best(versionsWithTypings, (a, b) => a > b); } diff --git a/src/publish-registry.ts b/src/publish-registry.ts index 026e09d4..ac39ca17 100644 --- a/src/publish-registry.ts +++ b/src/publish-registry.ts @@ -1,13 +1,14 @@ import { clearOutputPath } from "./lib/package-generator"; import * as yargs from "yargs"; -import { AllPackages, TypingsData } from "./lib/packages"; +import { Options } from "./lib/common"; +import { AllPackages, TypeScriptVersion, TypingsData } from "./lib/packages"; import NpmClient from "./lib/npm-client"; -import { outputPath } from "./lib/settings"; +import { npmRegistry, outputPath } from "./lib/settings"; import { fetchLastPatchNumber, readAdditions } from "./lib/versions"; -import { writeJson } from "./util/io"; +import { fetchJson, writeJson } from "./util/io"; import { Logger, logger, writeLog } from "./util/logging"; -import { done, joinPaths } from "./util/util"; +import { done, joinPaths, nAtATime } from "./util/util"; const packageName = "types-registry"; const registryOutputPath = joinPaths(outputPath, packageName); @@ -28,7 +29,7 @@ export default async function main(dry = false) { const added = await readAdditions(); if (added.length) { log(`New packages have been added: ${JSON.stringify(added)}, so publishing a new registry`); - await generateAndPublishRegistry(log, dry); + await generateAndPublishRegistry(log, Options.defaults, dry); } else { log("No new packages published, so no need to publish new registry."); } @@ -36,21 +37,21 @@ export default async function main(dry = false) { await writeLog("publish-registry.md", logResult()); } -async function generateAndPublishRegistry(log: Logger, dry: boolean) { +async function generateAndPublishRegistry(log: Logger, options: Options, dry: boolean) { // Don't include not-needed packages in the registry. const typings = await AllPackages.readTypings(); const last = await fetchLastPatchNumber(packageName); const packageJson = generatePackageJson(last + 1); - await generate(typings, packageJson, log); + await generate(typings, packageJson, log, options); await publish(packageJson, dry); } -async function generate(typings: TypingsData[], packageJson: {}, log: Logger): Promise { +async function generate(typings: TypingsData[], packageJson: {}, log: Logger, options: Options): Promise { await clearOutputPath(registryOutputPath, log); await writeOutputFile("package.json", packageJson); - await writeOutputFile("index.json", generateRegistry(typings)); + await writeOutputFile("index.json", await generateRegistry(typings, options)); await writeOutputFile("README.md", readme); function writeOutputFile(filename: string, content: {}): Promise { @@ -84,10 +85,38 @@ function generatePackageJson(patch: number): {} { }; } -function generateRegistry(typings: TypingsData[]): {} { - const entries: { [packageName: string]: 1 } = {}; - for (const { name } of typings) { - entries[name] = 1; - } +interface Registry { + entries: Entries +} +interface Entries { + [key: string]: Versions; +} +type Versions = Partial>; + +async function generateRegistry(typings: TypingsData[], options: Options): Promise { + const entries: Entries = {}; + await nAtATime(25, typings, addEntry, { name: "Generating registry...", flavor: t => t.name, options }); return { entries }; + + async function addEntry(typing: TypingsData): Promise { + const versions = await getVersions(typing.fullEscapedNpmName); + entries[typing.name] = versions; + } +} + +async function getVersions(escapedPackageName: string): Promise { + const uri = npmRegistry + escapedPackageName; + const info = await fetchJson(uri, { retries: true }); + const tags = info["dist-tags"]; + return pick(tags, TypeScriptVersion.allVersionTags); +} + +function pick(obj: T, keys: K[]): Pick { + const out = {} as Pick; + for (const key in obj) { + if (keys.includes(key as K)) { + out[key] = obj[key]; + } + } + return out; }