Socket
Socket
Sign inDemoInstall

typedoc-plugin-missing-exports

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

typedoc-plugin-missing-exports - npm Package Compare versions

Comparing version 1.0.0 to 2.0.0

4

CHANGELOG.md

@@ -0,1 +1,5 @@

### 2.0.0 (2023-04-15)
- BREAKING: Drop support for TypeDoc 0.22 and 0.23
### 1.0.0 (2022-08-12)

@@ -2,0 +6,0 @@

200

index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.discoverMissingExports = exports.load = void 0;
exports.load = void 0;
const assert_1 = require("assert");
const typedoc_1 = require("typedoc");
let hasMonkeyPatched = false;
function load(app) {
app.options.addDeclaration({
name: "internalModule",
help: "Define the name of the module that internal symbols which are not exported should be placed into.",
defaultValue: "<internal>",
});
if (hasMonkeyPatched) {
throw new Error("typedoc-plugin-missing-exports cannot be loaded multiple times");
}
hasMonkeyPatched = true;
let activeReflection;
const referencedSymbols = new Map();
const symbolToActiveRefl = new Map();
const knownPrograms = new Map();
app.converter.on(typedoc_1.Converter.EVENT_CREATE_DECLARATION, (context) => {
if (context.scope.kindOf(typedoc_1.ReflectionKind.Project | typedoc_1.ReflectionKind.Module)) {
knownPrograms.set(context.scope, context.program);
}
});
app.converter.on(typedoc_1.Converter.EVENT_RESOLVE_BEGIN, onResolveBegin.bind(void 0, knownPrograms), void 0, 1e9);
}
exports.load = load;
function onResolveBegin(knownPrograms, context) {
const modules = context.project.getChildrenByKind(typedoc_1.ReflectionKind.Module);
if (modules.length === 0) {
// Single entry point, just target the project.
modules.push(context.project);
}
for (const mod of modules) {
let missing = discoverMissingExports(mod);
if (missing.size === 0)
continue;
// Nasty hack here that will almost certainly break in future TypeDoc versions.
context.setActiveProgram(knownPrograms.get(mod));
const internalNs = context
.withScope(mod)
.createDeclarationReflection(typedoc_1.ReflectionKind.Module, void 0, void 0, context.converter.application.options.getValue("internalModule"));
context.finalizeDeclarationReflection(internalNs);
const internalContext = context.withScope(internalNs);
// Keep track of which symbols we've tried to convert. If they don't get converted
// when calling convertSymbol, then the user has excluded them somehow, don't go into
// an infinite loop when converting.
const tried = new Set();
do {
for (const s of missing) {
if (shouldConvertSymbol(s, context.checker)) {
internalContext.converter.convertSymbol(internalContext, s);
}
tried.add(s);
function discoverMissingExports(context, program) {
// An export is missing if if was referenced
// Is not contained in the documented
// And is "owned" by the active reflection
const referenced = referencedSymbols.get(program) || new Set();
const ownedByOther = new Set();
referencedSymbols.set(program, ownedByOther);
for (const s of [...referenced]) {
if (context.project.getReflectionFromSymbol(s)) {
referenced.delete(s);
}
missing = discoverMissingExports(internalNs);
for (const s of tried) {
missing.delete(s);
else if (symbolToActiveRefl.get(s) !== activeReflection) {
referenced.delete(s);
ownedByOther.add(s);
}
} while (missing.size > 0);
// All the missing symbols were excluded, so get rid of our namespace.
if (!internalNs.children?.length) {
context.project.removeReflection(internalNs);
}
context.setActiveProgram(void 0);
return referenced;
}
knownPrograms.clear();
}
function discoverMissingExports(root) {
const missing = new Set();
const queue = [];
let current = root;
const visitor = (0, typedoc_1.makeRecursiveVisitor)({
reference(type) {
if (!type.reflection) {
const symbol = type.getSymbol();
if (symbol) {
missing.add(symbol);
}
}
},
reflection(type) {
queue.push(type.declaration);
},
});
const add = (item) => {
if (!item)
return;
if (item instanceof typedoc_1.Reflection) {
queue.push(item);
// Monkey patch the constructor for references so that we can get every
const origCreateSymbolReference = typedoc_1.ReferenceType.createSymbolReference;
typedoc_1.ReferenceType.createSymbolReference = function (symbol, context, name) {
(0, assert_1.ok)(activeReflection, "active reflection has not been set");
const set = referencedSymbols.get(context.program);
symbolToActiveRefl.set(symbol, activeReflection);
if (set) {
set.add(symbol);
}
else {
queue.push(...item);
referencedSymbols.set(context.program, new Set([symbol]));
}
return origCreateSymbolReference.call(this, symbol, context, name);
};
do {
// Ugly? Yeah, it is. TypeDoc doesn't have a "visit all types" function,
// so we have to build our own. This is modeled after the one in
// https://github.com/TypeStrong/typedoc/blob/beta/src/lib/validation/exports.ts
if (current instanceof typedoc_1.ContainerReflection) {
add(current.children);
app.options.addDeclaration({
name: "internalModule",
help: "Define the name of the module that internal symbols which are not exported should be placed into.",
defaultValue: "<internal>",
});
app.converter.on(typedoc_1.Converter.EVENT_CREATE_DECLARATION, (context, refl) => {
if (refl.kindOf(typedoc_1.ReflectionKind.Project | typedoc_1.ReflectionKind.Module)) {
knownPrograms.set(refl, context.program);
activeReflection = refl;
}
if (current instanceof typedoc_1.DeclarationReflection) {
current.type?.visit(visitor);
add(current.typeParameters);
add(current.signatures);
add(current.indexSignature);
add(current.getSignature);
add(current.setSignature);
current.overwrites?.visit(visitor);
current.inheritedFrom?.visit(visitor);
current.implementationOf?.visit(visitor);
current.extendedTypes?.forEach((type) => type.visit(visitor));
// do not validate extendedBy, guaranteed to all be in the documentation.
current.implementedTypes?.forEach((type) => type.visit(visitor));
// do not validate implementedBy, guaranteed to all be in the documentation.
});
app.converter.on(typedoc_1.Converter.EVENT_RESOLVE_BEGIN, function onResolveBegin(context) {
const modules = context.project.getChildrenByKind(typedoc_1.ReflectionKind.Module);
if (modules.length === 0) {
// Single entry point, just target the project.
modules.push(context.project);
}
if (current instanceof typedoc_1.SignatureReflection) {
add(current.parameters);
add(current.typeParameters);
current.type?.visit(visitor);
current.overwrites?.visit(visitor);
current.inheritedFrom?.visit(visitor);
current.implementationOf?.visit(visitor);
for (const mod of modules) {
activeReflection = mod;
const program = knownPrograms.get(mod);
if (!program)
continue;
let missing = discoverMissingExports(context, program);
if (!missing || !missing.size)
continue;
// Nasty hack here that will almost certainly break in future TypeDoc versions.
context.setActiveProgram(program);
const internalNs = context
.withScope(mod)
.createDeclarationReflection(typedoc_1.ReflectionKind.Module, void 0, void 0, context.converter.application.options.getValue("internalModule"));
context.finalizeDeclarationReflection(internalNs);
const internalContext = context.withScope(internalNs);
// Keep track of which symbols we've tried to convert. If they don't get converted
// when calling convertSymbol, then the user has excluded them somehow, don't go into
// an infinite loop when converting.
const tried = new Set();
do {
for (const s of missing) {
if (shouldConvertSymbol(s, context.checker)) {
internalContext.converter.convertSymbol(internalContext, s);
}
tried.add(s);
}
missing = discoverMissingExports(context, program);
for (const s of tried) {
missing.delete(s);
}
} while (missing.size > 0);
// All the missing symbols were excluded, so get rid of our namespace.
if (!internalNs.children?.length) {
context.project.removeReflection(internalNs);
}
context.setActiveProgram(void 0);
}
if (current instanceof typedoc_1.ParameterReflection) {
current.type?.visit(visitor);
}
if (current instanceof typedoc_1.TypeParameterReflection) {
current.type?.visit(visitor);
current.default?.visit(visitor);
}
} while ((current = queue.shift()));
return missing;
knownPrograms.clear();
referencedSymbols.clear();
}, void 0, 1e9);
}
exports.discoverMissingExports = discoverMissingExports;
exports.load = load;
function shouldConvertSymbol(symbol, checker) {

@@ -130,0 +108,0 @@ while (symbol.flags & typedoc_1.TypeScript.SymbolFlags.Alias) {

{
"name": "typedoc-plugin-missing-exports",
"version": "1.0.0",
"version": "2.0.0",
"description": "Include non-exported types in TypeDoc documentation",

@@ -11,6 +11,6 @@ "main": "./index.js",

"@types/node": "^16.11.10",
"ava": "^4.3.0",
"prettier": "^2.7.1",
"typedoc": "^0.23.1",
"typescript": "^4.7.4"
"prettier": "^2.8.7",
"typedoc": "^0.24.2",
"typescript": "^5.0.4",
"vitest": "^0.30.1"
},

@@ -28,14 +28,8 @@ "repository": {

"peerDependencies": {
"typedoc": "0.22.x || 0.23.x"
"typedoc": "0.24.x"
},
"scripts": {
"pretest": "node scripts/copy_test_files.js",
"test": "ava",
"test": "vitest run test/packages.test.ts",
"build": "tsc"
},
"ava": {
"files": [
"test/**/*.test.js"
]
}
}

@@ -5,3 +5,3 @@ # typedoc-plugin-missing-exports

> Supports TypeDoc 0.22.x and 0.23.x
> Supports TypeDoc 0.24.x

@@ -16,6 +16,7 @@ TypeDoc 0.20 switched from documenting each file individually to documenting based on entry points. TypeDoc looks at each provided entry point and documents all exports from that entry point.

`npm install typedoc-plugin-missing-exports`
```bash
npm install typedoc-plugin-missing-exports
npx typedoc --plugin typedoc-plugin-missing-exports
```
TypeDoc will automatically use this plugin when present.
### Options

@@ -22,0 +23,0 @@

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