Comparing version 3.0.2 to 3.1.0
@@ -5,2 +5,16 @@ # Changelog | ||
## [3.1.0](https://github.com/nonara/ts-patch/compare/v3.0.2...v3.1.0) (2023-12-05) | ||
### Features | ||
* Added Plugin Package Configuration + parseAllJsDoc (closes [#134](https://github.com/nonara/ts-patch/issues/134) closes [#133](https://github.com/nonara/ts-patch/issues/133)) ([15570d0](https://github.com/nonara/ts-patch/commit/15570d05e422dd02635eb3c63dc6b3a036cb543a)) | ||
* Added support for chaining transformers in single factory (closes [#122](https://github.com/nonara/ts-patch/issues/122) closes [#120](https://github.com/nonara/ts-patch/issues/120)) ([aabf389](https://github.com/nonara/ts-patch/commit/aabf3894a610047fade6d2d9fb9949f17afe09df)) | ||
### Bug Fixes | ||
* TsExtras 'ts' type registering as 'any' (fixes [#127](https://github.com/nonara/ts-patch/issues/127)) ([069411e](https://github.com/nonara/ts-patch/commit/069411e49819aa87c880c7c5ff2ab04ecb68eea3)) | ||
* tsp.currentLibrary was not set (detail) ([24d8031](https://github.com/nonara/ts-patch/commit/24d8031bafcd6483fa762ed9ad8437c4a4070093)) | ||
### [3.0.2](https://github.com/nonara/ts-patch/compare/v3.0.1...v3.0.2) (2023-07-20) | ||
@@ -7,0 +21,0 @@ |
{ | ||
"name": "ts-patch", | ||
"version": "3.0.2", | ||
"version": "3.1.0", | ||
"description": "Patch typescript to support custom transformers in tsconfig.json", | ||
@@ -33,3 +33,3 @@ "main": "./index.js", | ||
"resolve": "^1.22.2", | ||
"semver": "^7.3.8", | ||
"semver": "^7.5.4", | ||
"strip-ansi": "^6.0.1" | ||
@@ -36,0 +36,0 @@ }, |
@@ -93,5 +93,7 @@ "use strict"; | ||
/* Get JS */ | ||
const libraryName = tsModule.moduleName.replace(/\.js$/, ''); | ||
const patchDetail = patch_detail_1.PatchDetail.fromModule(tsModule, printedJs); | ||
const js = patchDetail.toHeader() + '\n' + | ||
jsPatchSrc + '\n' + | ||
`tsp.currentLibrary = '${libraryName}';\n` + | ||
printedJs; | ||
@@ -98,0 +100,0 @@ return { dts, js }; |
/** | ||
* NOTE: This file is used during the build process for patch as well | ||
*/ | ||
import type ts from 'typescript'; | ||
import type * as ts from 'typescript'; | ||
export interface PluginConfig { | ||
@@ -54,5 +54,5 @@ [x: string]: any; | ||
export interface TransformerBasePlugin { | ||
before?: ts.TransformerFactory<ts.SourceFile>; | ||
after?: ts.TransformerFactory<ts.SourceFile>; | ||
afterDeclarations?: ts.TransformerFactory<ts.SourceFile | ts.Bundle>; | ||
before?: ts.TransformerFactory<ts.SourceFile> | ts.TransformerFactory<ts.SourceFile>[]; | ||
after?: ts.TransformerFactory<ts.SourceFile> | ts.TransformerFactory<ts.SourceFile>[]; | ||
afterDeclarations?: ts.TransformerFactory<ts.SourceFile | ts.Bundle> | ts.TransformerFactory<ts.SourceFile | ts.Bundle>[]; | ||
} | ||
@@ -86,1 +86,12 @@ export type DiagnosticMap = WeakMap<ts.Program, ts.Diagnostic[]>; | ||
export type RawPattern = (context: ts.TransformationContext, program: ts.Program, config: {}) => ts.Transformer<ts.SourceFile>; | ||
export interface PluginPackageConfig { | ||
tscOptions?: { | ||
/** | ||
* Sets the JSDocParsingMode to ParseAll | ||
* | ||
* @see https://devblogs.microsoft.com/typescript/announcing-typescript-5-3/#optimizations-by-skipping-jsdoc-parsing | ||
* @default false | ||
*/ | ||
parseAllJsDoc?: boolean; | ||
}; | ||
} |
@@ -43,3 +43,5 @@ [![npm version](https://badge.fury.io/js/ts-patch.svg)](https://badge.fury.io/js/ts-patch) | ||
* [Configuring Program Transformers](#configuring-program-transformers) | ||
* [Example Program Transformer](#example-program-transformer) | ||
* [Program Transformer Example](#program-transformer-example) | ||
* [Plugin Package Configuration](#plugin-package-configuration) | ||
* [Example](#example) | ||
* [Resources](#resources) | ||
@@ -109,3 +111,3 @@ * [Recommended Reading](#recommended-reading) | ||
{ "transform": "trans-with-mapping", "resolvePathAliases": true }, | ||
{ "transform": "esm-transformer, "isEsm": true }, | ||
{ "transform": "esm-transformer", "isEsm": true }, | ||
@@ -138,2 +140,4 @@ // Program Transformer | ||
For an overview of the typescript compiler (such as what a `SourceFile` and `Program` is) see: [Typescript Compiler Notes](https://github.com/microsoft/TypeScript-Compiler-Notes). | ||
## Source Transformers | ||
@@ -188,4 +192,6 @@ | ||
[`{ transform: "typia/lib/transform" }`](https://github.com/samchon/typia) | ||
[`{ transform: "typia/lib/transform" }`](https://github.com/samchon/typia) ([💻playground](https://typia.io/playground)) | ||
[`{ transform: "@nestia/core/lib/transform" }`](https://github.com/samchon/nestia) | ||
### Altering Diagnostics | ||
@@ -234,3 +240,3 @@ | ||
### Example Program Transformer | ||
### Program Transformer Example | ||
```TypeScript | ||
@@ -263,2 +269,29 @@ /** | ||
**Live Examples**: | ||
[`{ transform: "@typescript-virtual-barrel/compiler-plugin", transformProgram: true }`](https://github.com/zaguiini/typescript-virtual-barrel) | ||
## Plugin Package Configuration | ||
The plugin package configuration allows you to specify custom options for your TypeScript plugin. | ||
This configuration is defined in the `package.json` of your plugin under the `tsp` property. | ||
An example use case is enabling `parseAllJsDoc` if you require full JSDoc parsing in tsc for your transformer in TS v5.3+. (see: [5.3 JSDoc parsing changes](https://devblogs.microsoft.com/typescript/announcing-typescript-5-3/#optimizations-by-skipping-jsdoc-parsing)) | ||
For all available options, see the `PluginPackageConfig` type in [plugin-types.ts](https://github.com/nonara/ts-patch/blob/master/projects/core/shared/plugin-types.ts) | ||
### Example | ||
```jsonc | ||
{ | ||
"name": "your-plugin-name", | ||
"version": "1.0.0", | ||
"tsp": { | ||
"tscOptions": { | ||
"parseAllJsDoc": true | ||
} | ||
} | ||
} | ||
``` | ||
## Resources | ||
@@ -315,3 +348,3 @@ | ||
If you're interested in helping and have a _high level_ of skill with the TS compiler API, please reach out! | ||
If you're interested in helping and are knowledgeable with the TS compiler codebase, feel free to reach out! | ||
@@ -318,0 +351,0 @@ # License |
@@ -20,5 +20,5 @@ declare namespace ts { | ||
interface TransformerBasePlugin { | ||
before?: ts.TransformerFactory<ts.SourceFile>; | ||
after?: ts.TransformerFactory<ts.SourceFile>; | ||
afterDeclarations?: ts.TransformerFactory<ts.SourceFile | ts.Bundle>; | ||
before?: ts.TransformerFactory<ts.SourceFile> | ts.TransformerFactory<ts.SourceFile>[]; | ||
after?: ts.TransformerFactory<ts.SourceFile> | ts.TransformerFactory<ts.SourceFile>[]; | ||
afterDeclarations?: ts.TransformerFactory<ts.SourceFile | ts.Bundle> | ts.TransformerFactory<ts.SourceFile | ts.Bundle>[]; | ||
} | ||
@@ -43,2 +43,7 @@ type DiagnosticMap = WeakMap<ts.Program, ts.Diagnostic[]>; | ||
type RawPattern = (context: ts.TransformationContext, program: ts.Program, config: {}) => ts.Transformer<ts.SourceFile>; | ||
interface PluginPackageConfig { | ||
tscOptions?: { | ||
parseAllJsDoc?: boolean; | ||
}; | ||
} | ||
} | ||
@@ -45,0 +50,0 @@ declare namespace ts { |
@@ -127,8 +127,3 @@ var tsp = (function () { | ||
const crypto = require("crypto"); | ||
function validateConfigs(configs) { | ||
for (const config of configs) | ||
if (!config.name && !config.transform) | ||
throw new tsp.TsPatchError("tsconfig.json plugins error: transform must be present"); | ||
} | ||
function createTransformerFromPattern(opt) { | ||
function createTransformersFromPattern(opt) { | ||
const { factory, config, program, ls, registerConfig } = opt; | ||
@@ -138,3 +133,5 @@ const { transform, after, afterDeclarations, name, type, transformProgram, ...cleanConfig } = config; | ||
throw new tsp.TsPatchError("Not a valid config entry: \"transform\" key not found"); | ||
const transformerKind = after ? "after" : afterDeclarations ? "afterDeclarations" : "before"; | ||
const transformerKind = after ? "after" : | ||
afterDeclarations ? "afterDeclarations" : | ||
"before"; | ||
let pluginFactoryResult; | ||
@@ -173,20 +170,33 @@ switch (config.type) { | ||
} | ||
let transformerFactory; | ||
let transformerFactories; | ||
switch (typeof pluginFactoryResult) { | ||
case "function": | ||
transformerFactory = pluginFactoryResult; | ||
transformerFactories = [pluginFactoryResult]; | ||
break; | ||
case "object": | ||
transformerFactory = pluginFactoryResult[transformerKind]; | ||
break; | ||
const factoryOrFactories = pluginFactoryResult[transformerKind]; | ||
if (typeof factoryOrFactories === "function") { | ||
transformerFactories = [pluginFactoryResult[transformerKind]]; | ||
break; | ||
} | ||
else if (Array.isArray(factoryOrFactories)) { | ||
transformerFactories = [...factoryOrFactories]; | ||
break; | ||
} | ||
default: | ||
throw new tsp.TsPatchError(`Invalid plugin result: expected a function or an object with a '${transformerKind}' property`); | ||
} | ||
if (!transformerFactory || typeof transformerFactory !== "function") | ||
throw new tsp.TsPatchError(`Invalid plugin entry point! Expected a transformer factory function or an object with a '${transformerKind}' property`); | ||
const wrapper = wrapTransformer(transformerFactory, registerConfig, true); | ||
const wrappedFactories = []; | ||
for (const transformerFactory of transformerFactories) { | ||
if (!transformerFactory || typeof transformerFactory !== "function") | ||
throw new tsp.TsPatchError(`Invalid plugin entry point! Expected a transformer factory function or an object with a '${transformerKind}' property`); | ||
const wrapper = wrapTransformerFactory(transformerFactory, registerConfig, true); | ||
wrappedFactories.push(wrapper); | ||
} | ||
const res = { | ||
[transformerKind]: wrapper | ||
[transformerKind]: wrappedFactories | ||
}; | ||
return res; | ||
} | ||
function wrapTransformer(transformerFn, requireConfig, wrapInnerFunction) { | ||
function wrapTransformerFactory(transformerFn, requireConfig, wrapInnerFunction) { | ||
const wrapper = function tspWrappedFactory(...args) { | ||
@@ -203,3 +213,3 @@ let res; | ||
throw new tsp.TsPatchError("Invalid plugin: expected a function"); | ||
res = wrapTransformer(resFn, requireConfig, false); | ||
res = wrapTransformerFactory(resFn, requireConfig, false); | ||
} | ||
@@ -215,6 +225,9 @@ } | ||
class PluginCreator { | ||
constructor(configs, resolveBaseDir = process.cwd()) { | ||
constructor(configs, options) { | ||
this.plugins = []; | ||
this.configs = configs; | ||
this.resolveBaseDir = resolveBaseDir; | ||
validateConfigs(configs); | ||
this.options = options; | ||
const { resolveBaseDir } = options; | ||
this.plugins = configs.map(config => new tsp.TspPlugin(config, { resolveBaseDir })); | ||
this.needsTscJsDocParsing = this.plugins.some(plugin => plugin.packageConfig?.tscOptions?.parseAllJsDoc === true); | ||
} | ||
@@ -231,13 +244,14 @@ mergeTransformers(into, source) { | ||
} | ||
createTransformers(params, customTransformers) { | ||
createSourceTransformers(params, customTransformers) { | ||
const transformers = { before: [], after: [], afterDeclarations: [] }; | ||
const [ls, program] = ("ls" in params) ? [params.ls, params.ls.getProgram()] : [void 0, params.program]; | ||
for (const config of this.configs) { | ||
if (!config.transform || config.transformProgram) | ||
for (const plugin of this.plugins) { | ||
if (plugin.kind !== "SourceTransformer") | ||
continue; | ||
const resolvedFactory = tsp.resolveFactory(this, config); | ||
if (!resolvedFactory) | ||
const { config } = plugin; | ||
const createFactoryResult = plugin.createFactory(); | ||
if (!createFactoryResult) | ||
continue; | ||
const { factory, registerConfig } = resolvedFactory; | ||
this.mergeTransformers(transformers, createTransformerFromPattern({ | ||
const { factory, registerConfig } = createFactoryResult; | ||
this.mergeTransformers(transformers, createTransformersFromPattern({ | ||
factory: factory, | ||
@@ -254,12 +268,13 @@ registerConfig, | ||
} | ||
getProgramTransformers() { | ||
createProgramTransformers() { | ||
const res = new Map(); | ||
for (const config of this.configs) { | ||
if (!config.transform || !config.transformProgram) | ||
for (const plugin of this.plugins) { | ||
if (plugin.kind !== "ProgramTransformer") | ||
continue; | ||
const resolvedFactory = tsp.resolveFactory(this, config); | ||
if (resolvedFactory === undefined) | ||
const { config } = plugin; | ||
const createFactoryResult = plugin.createFactory(); | ||
if (createFactoryResult === undefined) | ||
continue; | ||
const { registerConfig } = resolvedFactory; | ||
const factory = wrapTransformer(resolvedFactory.factory, registerConfig, false); | ||
const { registerConfig, factory: unwrappedFactory } = createFactoryResult; | ||
const factory = wrapTransformerFactory(unwrappedFactory, registerConfig, false); | ||
const transformerKey = crypto | ||
@@ -279,2 +294,118 @@ .createHash("md5") | ||
const path = require("path"); | ||
const fs = require("fs"); | ||
const requireStack = []; | ||
function getPackagePath(entryFilePath) { | ||
let currentDir = path.dirname(entryFilePath); | ||
const seenPaths = new Set(); | ||
while (currentDir !== path.parse(currentDir).root) { | ||
if (seenPaths.has(currentDir)) | ||
return undefined; | ||
seenPaths.add(currentDir); | ||
const potentialPkgPath = path.join(currentDir, "package.json"); | ||
if (fs.existsSync(potentialPkgPath)) | ||
return potentialPkgPath; | ||
currentDir = path.resolve(currentDir, ".."); | ||
} | ||
return undefined; | ||
} | ||
class TspPlugin { | ||
constructor(config, createOptions) { | ||
this.config = { ...config }; | ||
this.validateConfig(); | ||
this._createOptions = createOptions; | ||
this.importKey = config.import || "default"; | ||
this.kind = config.transformProgram === true ? "ProgramTransformer" : "SourceTransformer"; | ||
const { resolveBaseDir } = createOptions; | ||
const configTransformValue = config.transform; | ||
this.tsConfigPath = config.tsConfig && path.resolve(resolveBaseDir, config.tsConfig); | ||
const entryFilePath = require.resolve(configTransformValue, { paths: [resolveBaseDir] }); | ||
this.entryFilePath = entryFilePath; | ||
let pluginPackageConfig; | ||
const modulePackagePath = getPackagePath(entryFilePath); | ||
if (modulePackagePath) { | ||
const modulePkgJsonContent = fs.readFileSync(modulePackagePath, "utf8"); | ||
const modulePkgJson = JSON.parse(modulePkgJsonContent); | ||
pluginPackageConfig = modulePkgJson.tsp; | ||
if (pluginPackageConfig === null || typeof pluginPackageConfig !== "object") | ||
pluginPackageConfig = undefined; | ||
} | ||
this.packageConfig = pluginPackageConfig; | ||
} | ||
validateConfig() { | ||
const { config } = this; | ||
const configTransformValue = config.transform; | ||
if (!configTransformValue) | ||
throw new tsp.TsPatchError(`Invalid plugin config: missing "transform" value`); | ||
if (config.resolvePathAliases && !config.tsConfig) { | ||
console.warn(`[ts-patch] Warning: resolvePathAliases needs a tsConfig value pointing to a tsconfig.json for transformer" ${configTransformValue}.`); | ||
} | ||
} | ||
createFactory() { | ||
const { entryFilePath, config, tsConfigPath, importKey } = this; | ||
const configTransformValue = config.transform; | ||
if (requireStack.includes(entryFilePath)) | ||
return; | ||
requireStack.push(entryFilePath); | ||
let isEsm = config.isEsm; | ||
if (isEsm == null) { | ||
const impliedModuleFormat = tsp.tsShim.getImpliedNodeFormatForFile(entryFilePath, undefined, tsp.tsShim.sys, { moduleResolution: tsp.tsShim.ModuleResolutionKind.Node16 }); | ||
isEsm = impliedModuleFormat === tsp.tsShim.ModuleKind.ESNext; | ||
} | ||
const isTs = configTransformValue.match(/\.[mc]?ts$/) != null; | ||
const registerConfig = { | ||
isTs, | ||
isEsm, | ||
tsConfig: tsConfigPath, | ||
pluginConfig: config | ||
}; | ||
tsp.registerPlugin(registerConfig); | ||
try { | ||
const commonjsModule = loadEntryFile(); | ||
const factoryModule = (typeof commonjsModule === "function") ? { default: commonjsModule } : commonjsModule; | ||
const factory = factoryModule[importKey]; | ||
if (!factory) | ||
throw new tsp.TsPatchError(`tsconfig.json > plugins: "${configTransformValue}" does not have an export "${importKey}": ` + | ||
require("util").inspect(factoryModule)); | ||
if (typeof factory !== "function") { | ||
throw new tsp.TsPatchError(`tsconfig.json > plugins: "${configTransformValue}" export "${importKey}" is not a plugin: ` + | ||
require("util").inspect(factory)); | ||
} | ||
return { | ||
factory, | ||
registerConfig: registerConfig | ||
}; | ||
} | ||
finally { | ||
requireStack.pop(); | ||
tsp.unregisterPlugin(); | ||
} | ||
function loadEntryFile() { | ||
let res; | ||
try { | ||
res = require(entryFilePath); | ||
} | ||
catch (e) { | ||
if (e.code === "ERR_REQUIRE_ESM") { | ||
if (!registerConfig.isEsm) { | ||
tsp.unregisterPlugin(); | ||
registerConfig.isEsm = true; | ||
tsp.registerPlugin(registerConfig); | ||
return loadEntryFile(); | ||
} | ||
else { | ||
throw new tsp.TsPatchError(`Cannot load ESM transformer "${configTransformValue}" from "${entryFilePath}". Please file a bug report`); | ||
} | ||
} | ||
else | ||
throw e; | ||
} | ||
return res; | ||
} | ||
} | ||
} | ||
tsp.TspPlugin = TspPlugin; | ||
})(tsp || (tsp = {})); | ||
var tsp; | ||
(function (tsp) { | ||
const path = require("path"); | ||
let configStack = []; | ||
@@ -367,75 +498,2 @@ function getTsNode() { | ||
(function (tsp) { | ||
const path = require("path"); | ||
const requireStack = []; | ||
function resolveFactory(pluginCreator, pluginConfig) { | ||
const tsConfig = pluginConfig.tsConfig && path.resolve(pluginCreator.resolveBaseDir, pluginConfig.tsConfig); | ||
const transform = pluginConfig.transform; | ||
const importKey = pluginConfig.import || "default"; | ||
const transformerPath = require.resolve(transform, { paths: [pluginCreator.resolveBaseDir] }); | ||
if (pluginConfig.resolvePathAliases && !tsConfig) { | ||
console.warn(`[ts-patch] Warning: resolvePathAliases needs a tsConfig value pointing to a tsconfig.json for transformer" ${transform}.`); | ||
} | ||
if (requireStack.includes(transformerPath)) | ||
return; | ||
requireStack.push(transformerPath); | ||
let isEsm = pluginConfig.isEsm; | ||
if (isEsm == null) { | ||
const impliedModuleFormat = tsp.tsShim.getImpliedNodeFormatForFile(transformerPath, undefined, tsp.tsShim.sys, { moduleResolution: tsp.tsShim.ModuleResolutionKind.Node16 }); | ||
isEsm = impliedModuleFormat === tsp.tsShim.ModuleKind.ESNext; | ||
} | ||
const isTs = transform.match(/\.[mc]?ts$/) != null; | ||
const registerConfig = { | ||
isTs, | ||
isEsm, | ||
tsConfig: tsConfig, | ||
pluginConfig | ||
}; | ||
tsp.registerPlugin(registerConfig); | ||
try { | ||
const commonjsModule = loadPlugin(); | ||
const factoryModule = (typeof commonjsModule === "function") ? { default: commonjsModule } : commonjsModule; | ||
const factory = factoryModule[importKey]; | ||
if (!factory) | ||
throw new tsp.TsPatchError(`tsconfig.json > plugins: "${transform}" does not have an export "${importKey}": ` + | ||
require("util").inspect(factoryModule)); | ||
if (typeof factory !== "function") { | ||
throw new tsp.TsPatchError(`tsconfig.json > plugins: "${transform}" export "${importKey}" is not a plugin: ` + | ||
require("util").inspect(factory)); | ||
} | ||
return { | ||
factory, | ||
registerConfig: registerConfig, | ||
}; | ||
} | ||
finally { | ||
requireStack.pop(); | ||
tsp.unregisterPlugin(); | ||
} | ||
function loadPlugin() { | ||
let res; | ||
try { | ||
res = require(transformerPath); | ||
} | ||
catch (e) { | ||
if (e.code === "ERR_REQUIRE_ESM") { | ||
if (!registerConfig.isEsm) { | ||
tsp.unregisterPlugin(); | ||
registerConfig.isEsm = true; | ||
tsp.registerPlugin(registerConfig); | ||
return loadPlugin(); | ||
} | ||
else { | ||
throw new tsp.TsPatchError(`Cannot load ESM transformer "${transform}" from "${transformerPath}". Please file a bug report`); | ||
} | ||
} | ||
else | ||
throw e; | ||
} | ||
return res; | ||
} | ||
} | ||
tsp.resolveFactory = resolveFactory; | ||
})(tsp || (tsp = {})); | ||
var tsp; | ||
(function (tsp) { | ||
const activeProgramTransformers = new Set(); | ||
@@ -499,8 +557,11 @@ const { dirname } = require("path"); | ||
} | ||
const plugins = preparePluginsFromCompilerOptions(options.plugins); | ||
const pluginCreator = new tsp.PluginCreator(plugins, { resolveBaseDir: projectConfig.projectDir ?? process.cwd() }); | ||
if (tsp.currentLibrary === "tsc" && pluginCreator.needsTscJsDocParsing) { | ||
host.jsDocParsingMode = tsp.tsShim.JSDocParsingMode.ParseAll; | ||
} | ||
let program = createOpts ? | ||
tsp.tsShim.originalCreateProgram(createOpts) : | ||
tsp.tsShim.originalCreateProgram(rootNames, options, host, oldProgram, configFileParsingDiagnostics); | ||
const plugins = preparePluginsFromCompilerOptions(options.plugins); | ||
const pluginCreator = new tsp.PluginCreator(plugins, projectConfig.projectDir ?? process.cwd()); | ||
const programTransformers = pluginCreator.getProgramTransformers(); | ||
const programTransformers = pluginCreator.createProgramTransformers(); | ||
for (const [transformerKey, [programTransformer, config]] of programTransformers) { | ||
@@ -520,3 +581,3 @@ if (activeProgramTransformers.has(transformerKey)) | ||
function newEmit(targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers, ...additionalArgs) { | ||
const transformers = pluginCreator.createTransformers({ program }, customTransformers); | ||
const transformers = pluginCreator.createSourceTransformers({ program }, customTransformers); | ||
const result = program.originalEmit(targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, transformers, ...additionalArgs); | ||
@@ -523,0 +584,0 @@ for (const diagnostic of tsp.diagnosticMap.get(program) || []) |
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
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
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
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
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
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
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
288727
3421
347
1
31
Updatedsemver@^7.5.4