New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@rushstack/typings-generator

Package Overview
Dependencies
Maintainers
2
Versions
318
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rushstack/typings-generator - npm Package Compare versions

Comparing version 0.5.7 to 0.6.0

12

CHANGELOG.json

@@ -5,2 +5,14 @@ {

{
"version": "0.6.0",
"tag": "@rushstack/typings-generator_v0.6.0",
"date": "Fri, 10 Dec 2021 01:09:33 GMT",
"comments": {
"minor": [
{
"comment": "Support additional output files beyond the typings files."
}
]
}
},
{
"version": "0.5.7",

@@ -7,0 +19,0 @@ "tag": "@rushstack/typings-generator_v0.5.7",

9

CHANGELOG.md
# Change Log - @rushstack/typings-generator
This log was last generated on Thu, 09 Dec 2021 20:34:41 GMT and should not be manually modified.
This log was last generated on Fri, 10 Dec 2021 01:09:33 GMT and should not be manually modified.
## 0.6.0
Fri, 10 Dec 2021 01:09:33 GMT
### Minor changes
- Support additional output files beyond the typings files.
## 0.5.7

@@ -6,0 +13,0 @@ Thu, 09 Dec 2021 20:34:41 GMT

2

dist/tsdoc-metadata.json

@@ -8,5 +8,5 @@ // This file is read by tools that parse documentation comments conforming to the TSDoc standard.

"packageName": "@microsoft/api-extractor",
"packageVersion": "7.19.1"
"packageVersion": "7.19.2"
}
]
}

@@ -40,3 +40,4 @@ import { ITerminal } from '@rushstack/node-core-library';

fileExtensions: string[];
parseAndGenerateTypings: (fileContents: string, filePath: string) => TTypingsResult | Promise<TTypingsResult>;
parseAndGenerateTypings: (fileContents: string, filePath: string, relativePath: string) => TTypingsResult | Promise<TTypingsResult>;
getAdditionalOutputFiles?: (relativePath: string) => string[];
terminal?: ITerminal;

@@ -68,5 +69,7 @@ globsToIgnore?: string[];

export declare class TypingsGenerator {
private _targetMap;
private _dependencyMap;
private readonly _dependenciesOfFile;
private readonly _consumersOfFile;
private readonly _relativePaths;
protected _options: ITypingsGeneratorOptions;
private readonly _fileGlob;
constructor(options: ITypingsGeneratorOptions);

@@ -76,3 +79,3 @@ generateTypingsAsync(): Promise<void>;

/**
* Register file dependencies that may effect the typings of a target file.
* Register file dependencies that may effect the typings of a consumer file.
* Note: This feature is only useful in watch mode.

@@ -82,6 +85,10 @@ * The registerDependency method must be called in the body of parseAndGenerateTypings every

*/
registerDependency(target: string, dependency: string): void;
registerDependency(consumer: string, rawDependency: string): void;
getOutputFilePaths(relativePath: string): string[];
private _reprocessFiles;
private _parseFileAndGenerateTypingsAsync;
/**
* Removes the consumer from all extant dependencies
*/
private _clearDependencies;
private _getDependencyTargets;
private _getTypingsFilePath;

@@ -88,0 +95,0 @@ private _normalizeFileExtensions;

@@ -17,4 +17,4 @@ "use strict";

constructor(options) {
super(Object.assign(Object.assign({}, options), { parseAndGenerateTypings: async (fileContents, filePath) => {
const stringValueTypings = await options.parseAndGenerateTypings(fileContents, filePath);
super(Object.assign(Object.assign({}, options), { parseAndGenerateTypings: async (fileContents, filePath, relativePath) => {
const stringValueTypings = await options.parseAndGenerateTypings(fileContents, filePath, relativePath);
if (stringValueTypings === undefined) {

@@ -21,0 +21,0 @@ return;

@@ -9,3 +9,4 @@ import { ITerminal } from '@rushstack/node-core-library';

fileExtensions: string[];
parseAndGenerateTypings: (fileContents: string, filePath: string) => TTypingsResult | Promise<TTypingsResult>;
parseAndGenerateTypings: (fileContents: string, filePath: string, relativePath: string) => TTypingsResult | Promise<TTypingsResult>;
getAdditionalOutputFiles?: (relativePath: string) => string[];
terminal?: ITerminal;

@@ -26,5 +27,7 @@ globsToIgnore?: string[];

export declare class TypingsGenerator {
private _targetMap;
private _dependencyMap;
private readonly _dependenciesOfFile;
private readonly _consumersOfFile;
private readonly _relativePaths;
protected _options: ITypingsGeneratorOptions;
private readonly _fileGlob;
constructor(options: ITypingsGeneratorOptions);

@@ -34,3 +37,3 @@ generateTypingsAsync(): Promise<void>;

/**
* Register file dependencies that may effect the typings of a target file.
* Register file dependencies that may effect the typings of a consumer file.
* Note: This feature is only useful in watch mode.

@@ -40,6 +43,10 @@ * The registerDependency method must be called in the body of parseAndGenerateTypings every

*/
registerDependency(target: string, dependency: string): void;
registerDependency(consumer: string, rawDependency: string): void;
getOutputFilePaths(relativePath: string): string[];
private _reprocessFiles;
private _parseFileAndGenerateTypingsAsync;
/**
* Removes the consumer from all extant dependencies
*/
private _clearDependencies;
private _getDependencyTargets;
private _getTypingsFilePath;

@@ -46,0 +53,0 @@ private _normalizeFileExtensions;

@@ -66,8 +66,10 @@ "use strict";

this._options.fileExtensions = this._normalizeFileExtensions(this._options.fileExtensions);
this._targetMap = new Map();
this._dependencyMap = new Map();
this._dependenciesOfFile = new Map();
this._consumersOfFile = new Map();
this._relativePaths = new Map();
this._fileGlob = `**/*+(${this._options.fileExtensions.join('|')})`;
}
async generateTypingsAsync() {
await node_core_library_1.FileSystem.ensureEmptyFolderAsync(this._options.generatedTsFolder);
const filePaths = await node_core_library_1.LegacyAdapters.convertCallbackToPromise(glob_1.default, `**/*+(${this._options.fileExtensions.join('|')})`, {
const filePaths = await node_core_library_1.LegacyAdapters.convertCallbackToPromise(glob_1.default, this._fileGlob, {
cwd: this._options.srcFolder,

@@ -79,20 +81,53 @@ absolute: true,

});
await node_core_library_1.Async.forEachAsync(filePaths, async (filePath) => {
filePath = `${this._options.srcFolder}/${filePath}`;
await this._parseFileAndGenerateTypingsAsync(filePath);
}, { concurrency: 50 });
await this._reprocessFiles(filePaths);
}
async runWatcherAsync() {
await node_core_library_1.FileSystem.ensureFolderAsync(this._options.generatedTsFolder);
const globBase = `${this._options.srcFolder}/**`;
await new Promise((resolve, reject) => {
const watcher = chokidar.watch(this._options.fileExtensions.map((fileExtension) => `${globBase}/*${fileExtension}`), {
const watcher = chokidar.watch(this._fileGlob, {
cwd: this._options.srcFolder,
ignored: this._options.globsToIgnore
});
const boundGenerateTypingsFunction = this._parseFileAndGenerateTypingsAsync.bind(this);
watcher.on('add', boundGenerateTypingsFunction);
watcher.on('change', boundGenerateTypingsFunction);
watcher.on('unlink', async (filePath) => {
const generatedTsFilePath = this._getTypingsFilePath(filePath);
await node_core_library_1.FileSystem.deleteFileAsync(generatedTsFilePath);
const queue = new Set();
let timeout;
let processing = false;
let flushAfterCompletion = false;
const flushInternal = () => {
processing = true;
const toProcess = Array.from(queue);
queue.clear();
this._reprocessFiles(toProcess)
.then(() => {
processing = false;
// If the timeout was invoked again, immediately reexecute with the changed files.
if (flushAfterCompletion) {
flushAfterCompletion = false;
flushInternal();
}
})
.catch(reject);
};
const debouncedFlush = () => {
timeout = undefined;
if (processing) {
// If the callback was invoked while processing is ongoing, indicate that we should flush immediately
// upon completion of the current change batch.
flushAfterCompletion = true;
return;
}
flushInternal();
};
const onChange = (relativePath) => {
queue.add(relativePath);
if (timeout) {
clearTimeout(timeout);
}
setTimeout(debouncedFlush, 100);
};
watcher.on('add', onChange);
watcher.on('change', onChange);
watcher.on('unlink', async (relativePath) => {
await Promise.all(this.getOutputFilePaths(relativePath).map(async (outputFile) => {
await node_core_library_1.FileSystem.deleteFileAsync(outputFile);
}));
});

@@ -103,3 +138,3 @@ watcher.on('error', reject);

/**
* Register file dependencies that may effect the typings of a target file.
* Register file dependencies that may effect the typings of a consumer file.
* Note: This feature is only useful in watch mode.

@@ -109,27 +144,57 @@ * The registerDependency method must be called in the body of parseAndGenerateTypings every

*/
registerDependency(target, dependency) {
let targetDependencySet = this._targetMap.get(target);
if (!targetDependencySet) {
targetDependencySet = new Set();
this._targetMap.set(target, targetDependencySet);
registerDependency(consumer, rawDependency) {
// Need to normalize slashes in the dependency path
const dependency = path.resolve(this._options.srcFolder, rawDependency);
let dependencies = this._dependenciesOfFile.get(consumer);
if (!dependencies) {
dependencies = new Set();
this._dependenciesOfFile.set(consumer, dependencies);
}
targetDependencySet.add(dependency);
let dependencyTargetSet = this._dependencyMap.get(dependency);
if (!dependencyTargetSet) {
dependencyTargetSet = new Set();
this._dependencyMap.set(dependency, dependencyTargetSet);
dependencies.add(dependency);
let consumers = this._consumersOfFile.get(dependency);
if (!consumers) {
consumers = new Set();
this._consumersOfFile.set(dependency, consumers);
}
dependencyTargetSet.add(target);
consumers.add(consumer);
}
async _parseFileAndGenerateTypingsAsync(filePath) {
getOutputFilePaths(relativePath) {
var _a, _b;
const typingsFile = this._getTypingsFilePath(relativePath);
const additionalPaths = (_b = (_a = this._options).getAdditionalOutputFiles) === null || _b === void 0 ? void 0 : _b.call(_a, relativePath);
return additionalPaths ? [typingsFile, ...additionalPaths] : [typingsFile];
}
async _reprocessFiles(relativePaths) {
// Build a queue of resolved paths
const toProcess = new Set();
for (const rawPath of relativePaths) {
const relativePath = node_core_library_1.Path.convertToSlashes(rawPath);
const resolvedPath = path.resolve(this._options.srcFolder, rawPath);
this._relativePaths.set(resolvedPath, relativePath);
toProcess.add(resolvedPath);
}
// Expand out all registered consumers, according to the current dependency graph
for (const file of toProcess) {
const consumers = this._consumersOfFile.get(file);
if (consumers) {
for (const consumer of consumers) {
toProcess.add(consumer);
}
}
}
// Map back to the relative paths so that the information is available
await node_core_library_1.Async.forEachAsync(toProcess, async (resolvedPath) => {
const relativePath = this._relativePaths.get(resolvedPath);
if (!relativePath) {
throw new Error(`Missing relative path for file ${resolvedPath}`);
}
await this._parseFileAndGenerateTypingsAsync(relativePath, resolvedPath);
}, { concurrency: 20 });
}
async _parseFileAndGenerateTypingsAsync(relativePath, resolvedPath) {
// Clear registered dependencies prior to reprocessing.
this._clearDependencies(filePath);
// Check for targets that register this file as a dependency, and reprocess them too.
for (const target of this._getDependencyTargets(filePath)) {
await this._parseFileAndGenerateTypingsAsync(target);
}
this._clearDependencies(resolvedPath);
try {
const fileContents = await node_core_library_1.FileSystem.readFileAsync(filePath);
const typingsData = await this._options.parseAndGenerateTypings(fileContents, filePath);
const generatedTsFilePath = this._getTypingsFilePath(filePath);
const fileContents = await node_core_library_1.FileSystem.readFileAsync(resolvedPath);
const typingsData = await this._options.parseAndGenerateTypings(fileContents, resolvedPath, relativePath);
// Typings data will be undefined when no types should be generated for the parsed file.

@@ -144,2 +209,3 @@ if (typingsData === undefined) {

].join(os_1.EOL);
const generatedTsFilePath = this._getTypingsFilePath(relativePath);
await node_core_library_1.FileSystem.writeFileAsync(generatedTsFilePath, prefixedTypingsData, {

@@ -151,33 +217,31 @@ ensureFolderExists: true,

catch (e) {
this._options.terminal.writeError(`Error occurred parsing and generating typings for file "${filePath}": ${e}`);
this._options.terminal.writeError(`Error occurred parsing and generating typings for file "${resolvedPath}": ${e}`);
}
}
_clearDependencies(target) {
const targetDependencySet = this._targetMap.get(target);
if (targetDependencySet) {
for (const dependency of targetDependencySet) {
this._dependencyMap.get(dependency).delete(target);
/**
* Removes the consumer from all extant dependencies
*/
_clearDependencies(consumer) {
const dependencies = this._dependenciesOfFile.get(consumer);
if (dependencies) {
for (const dependency of dependencies) {
this._consumersOfFile.get(dependency).delete(consumer);
}
targetDependencySet.clear();
dependencies.clear();
}
}
_getDependencyTargets(dependency) {
var _a;
return [...(((_a = this._dependencyMap.get(dependency)) === null || _a === void 0 ? void 0 : _a.keys()) || [])];
_getTypingsFilePath(relativePath) {
return path.resolve(this._options.generatedTsFolder, `${relativePath}.d.ts`);
}
_getTypingsFilePath(filePath) {
const relativeSourceFilePath = path.relative(this._options.srcFolder, `${filePath}.d.ts`);
return `${this._options.generatedTsFolder}/${relativeSourceFilePath}`;
}
_normalizeFileExtensions(fileExtensions) {
const result = [];
const result = new Set();
for (const fileExtension of fileExtensions) {
if (!fileExtension.startsWith('.')) {
result.push(`.${fileExtension}`);
result.add(`.${fileExtension}`);
}
else {
result.push(fileExtension);
result.add(fileExtension);
}
}
return result;
return Array.from(result);
}

@@ -184,0 +248,0 @@ }

{
"name": "@rushstack/typings-generator",
"version": "0.5.7",
"version": "0.6.0",
"description": "This library provides functionality for automatically generating typings for non-TS files.",

@@ -5,0 +5,0 @@ "keywords": [

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc