Skip to content
This repository has been archived by the owner on Jun 11, 2020. It is now read-only.

Store TypeScript version tags in typings registry #294

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/lib/module-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
8 changes: 6 additions & 2 deletions src/lib/packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,17 +423,21 @@ 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];
}
}

namespace tags {
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];
}
2 changes: 1 addition & 1 deletion src/lib/versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
57 changes: 43 additions & 14 deletions src/publish-registry.ts
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -28,29 +29,29 @@ 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.");
}

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<void> {
async function generate(typings: TypingsData[], packageJson: {}, log: Logger, options: Options): Promise<void> {
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<void> {
Expand Down Expand Up @@ -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<Record<TypeScriptVersion.VersionTag, string>>;

async function generateRegistry(typings: TypingsData[], options: Options): Promise<Registry> {
const entries: Entries = {};
await nAtATime(25, typings, addEntry, { name: "Generating registry...", flavor: t => t.name, options });
return { entries };

async function addEntry(typing: TypingsData): Promise<void> {
const versions = await getVersions(typing.fullEscapedNpmName);
entries[typing.name] = versions;
}
}

async function getVersions(escapedPackageName: string): Promise<Versions> {
const uri = npmRegistry + escapedPackageName;
const info = await fetchJson(uri, { retries: true });
const tags = info["dist-tags"];
return pick(tags, TypeScriptVersion.allVersionTags);
}

function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
const out = {} as Pick<T, K>;
for (const key in obj) {
if (keys.includes(key as K)) {
out[key] = obj[key];
}
}
return out;
}