myjsbook 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +263 -0
- package/package.json +38 -0
- package/public/app.js +6686 -0
- package/public/components/constants.js +421 -0
- package/public/components/elements.js +118 -0
- package/public/components/state.js +53 -0
- package/public/icons/audio.svg +1 -0
- package/public/icons/azure.svg +1 -0
- package/public/icons/babel.svg +1 -0
- package/public/icons/bun.svg +1 -0
- package/public/icons/bun_light.svg +1 -0
- package/public/icons/c.svg +1 -0
- package/public/icons/chrome.svg +1 -0
- package/public/icons/citation.svg +1 -0
- package/public/icons/claude.svg +1 -0
- package/public/icons/console.svg +1 -0
- package/public/icons/cpp.svg +1 -0
- package/public/icons/css-map.svg +1 -0
- package/public/icons/css.svg +1 -0
- package/public/icons/database.svg +1 -0
- package/public/icons/docker.svg +1 -0
- package/public/icons/document.svg +1 -0
- package/public/icons/ejs.svg +1 -0
- package/public/icons/exe.svg +1 -0
- package/public/icons/favicon.svg +1 -0
- package/public/icons/figma.svg +1 -0
- package/public/icons/firebase.svg +1 -0
- package/public/icons/folder-admin-open.svg +1 -0
- package/public/icons/folder-admin.svg +1 -0
- package/public/icons/folder-api-open.svg +1 -0
- package/public/icons/folder-api.svg +1 -0
- package/public/icons/folder-app-open.svg +1 -0
- package/public/icons/folder-app.svg +1 -0
- package/public/icons/folder-archive-open.svg +1 -0
- package/public/icons/folder-archive.svg +1 -0
- package/public/icons/folder-attachment-open.svg +1 -0
- package/public/icons/folder-attachment.svg +1 -0
- package/public/icons/folder-aws-open.svg +1 -0
- package/public/icons/folder-aws.svg +1 -0
- package/public/icons/folder-backup-open.svg +1 -0
- package/public/icons/folder-backup.svg +1 -0
- package/public/icons/folder-class-open.svg +1 -0
- package/public/icons/folder-class.svg +1 -0
- package/public/icons/folder-claude-open.svg +1 -0
- package/public/icons/folder-claude.svg +1 -0
- package/public/icons/folder-client-open.svg +1 -0
- package/public/icons/folder-client.svg +1 -0
- package/public/icons/folder-command-open.svg +1 -0
- package/public/icons/folder-command.svg +1 -0
- package/public/icons/folder-components-open.svg +1 -0
- package/public/icons/folder-components.svg +1 -0
- package/public/icons/folder-config-open.svg +1 -0
- package/public/icons/folder-config.svg +1 -0
- package/public/icons/folder-connection-open.svg +1 -0
- package/public/icons/folder-connection.svg +1 -0
- package/public/icons/folder-console-open.svg +1 -0
- package/public/icons/folder-console.svg +1 -0
- package/public/icons/folder-container-open.svg +1 -0
- package/public/icons/folder-container.svg +1 -0
- package/public/icons/folder-content-open.svg +1 -0
- package/public/icons/folder-content.svg +1 -0
- package/public/icons/folder-context-open.svg +1 -0
- package/public/icons/folder-context.svg +1 -0
- package/public/icons/folder-controller-open.svg +1 -0
- package/public/icons/folder-controller.svg +1 -0
- package/public/icons/folder-core-open.svg +1 -0
- package/public/icons/folder-core.svg +1 -0
- package/public/icons/folder-css-open.svg +1 -0
- package/public/icons/folder-css.svg +1 -0
- package/public/icons/folder-custom-open.svg +1 -0
- package/public/icons/folder-custom.svg +1 -0
- package/public/icons/folder-database-open.svg +1 -0
- package/public/icons/folder-database.svg +1 -0
- package/public/icons/folder-decorators-open.svg +1 -0
- package/public/icons/folder-decorators.svg +1 -0
- package/public/icons/folder-desktop-open.svg +1 -0
- package/public/icons/folder-desktop.svg +1 -0
- package/public/icons/folder-dist-open.svg +1 -0
- package/public/icons/folder-dist.svg +1 -0
- package/public/icons/folder-docs-open.svg +1 -0
- package/public/icons/folder-docs.svg +1 -0
- package/public/icons/folder-download-open.svg +1 -0
- package/public/icons/folder-download.svg +1 -0
- package/public/icons/folder-dtos-open.svg +1 -0
- package/public/icons/folder-dtos.svg +1 -0
- package/public/icons/folder-element-open.svg +1 -0
- package/public/icons/folder-element.svg +1 -0
- package/public/icons/folder-environment-open.svg +1 -0
- package/public/icons/folder-environment.svg +1 -0
- package/public/icons/folder-error-open.svg +1 -0
- package/public/icons/folder-error.svg +1 -0
- package/public/icons/folder-event-open.svg +1 -0
- package/public/icons/folder-event.svg +1 -0
- package/public/icons/folder-examples-open.svg +1 -0
- package/public/icons/folder-examples.svg +1 -0
- package/public/icons/folder-expo-open.svg +1 -0
- package/public/icons/folder-expo.svg +1 -0
- package/public/icons/folder-export-open.svg +1 -0
- package/public/icons/folder-export.svg +1 -0
- package/public/icons/folder-features-open.svg +1 -0
- package/public/icons/folder-features.svg +1 -0
- package/public/icons/folder-filter-open.svg +1 -0
- package/public/icons/folder-filter.svg +1 -0
- package/public/icons/folder-firebase-open.svg +1 -0
- package/public/icons/folder-firebase.svg +1 -0
- package/public/icons/folder-firestore-open.svg +1 -0
- package/public/icons/folder-firestore.svg +1 -0
- package/public/icons/folder-font-open.svg +1 -0
- package/public/icons/folder-font.svg +1 -0
- package/public/icons/folder-functions-open.svg +1 -0
- package/public/icons/folder-functions.svg +1 -0
- package/public/icons/folder-gemini-ai-open.svg +1 -0
- package/public/icons/folder-gemini-ai.svg +1 -0
- package/public/icons/folder-git-open.svg +1 -0
- package/public/icons/folder-git.svg +1 -0
- package/public/icons/folder-github-open.svg +1 -0
- package/public/icons/folder-github.svg +1 -0
- package/public/icons/folder-helper-open.svg +1 -0
- package/public/icons/folder-helper.svg +1 -0
- package/public/icons/folder-home-open.svg +1 -0
- package/public/icons/folder-home.svg +1 -0
- package/public/icons/folder-icons-open.svg +1 -0
- package/public/icons/folder-icons.svg +1 -0
- package/public/icons/folder-images-open.svg +1 -0
- package/public/icons/folder-images.svg +1 -0
- package/public/icons/folder-interface-open.svg +1 -0
- package/public/icons/folder-interface.svg +1 -0
- package/public/icons/folder-ios-open.svg +1 -0
- package/public/icons/folder-ios.svg +1 -0
- package/public/icons/folder-java-open.svg +1 -0
- package/public/icons/folder-java.svg +1 -0
- package/public/icons/folder-javascript-open.svg +1 -0
- package/public/icons/folder-javascript.svg +1 -0
- package/public/icons/folder-middleware-open.svg +1 -0
- package/public/icons/folder-middleware.svg +1 -0
- package/public/icons/folder-migrations-open.svg +1 -0
- package/public/icons/folder-migrations.svg +1 -0
- package/public/icons/folder-other-open.svg +1 -0
- package/public/icons/folder-other.svg +1 -0
- package/public/icons/folder-packages-open.svg +1 -0
- package/public/icons/folder-packages.svg +1 -0
- package/public/icons/folder-pdf-open.svg +1 -0
- package/public/icons/folder-pdf.svg +1 -0
- package/public/icons/folder-plugin-open.svg +1 -0
- package/public/icons/folder-plugin.svg +1 -0
- package/public/icons/folder-project-open.svg +1 -0
- package/public/icons/folder-project.svg +1 -0
- package/public/icons/folder-public-open.svg +1 -0
- package/public/icons/folder-public.svg +1 -0
- package/public/icons/folder-python-open.svg +1 -0
- package/public/icons/folder-python.svg +1 -0
- package/public/icons/folder-repository-open.svg +1 -0
- package/public/icons/folder-repository.svg +1 -0
- package/public/icons/folder-routes-open.svg +1 -0
- package/public/icons/folder-routes.svg +1 -0
- package/public/icons/folder-rules-open.svg +1 -0
- package/public/icons/folder-rules.svg +1 -0
- package/public/icons/folder-sass-open.svg +1 -0
- package/public/icons/folder-sass.svg +1 -0
- package/public/icons/folder-scripts-open.svg +1 -0
- package/public/icons/folder-scripts.svg +1 -0
- package/public/icons/folder-server-open.svg +1 -0
- package/public/icons/folder-server.svg +1 -0
- package/public/icons/folder-serverless-open.svg +1 -0
- package/public/icons/folder-serverless.svg +1 -0
- package/public/icons/folder-skills-open.svg +1 -0
- package/public/icons/folder-skills.svg +1 -0
- package/public/icons/folder-src-open.svg +1 -0
- package/public/icons/folder-src.svg +1 -0
- package/public/icons/folder-stack-open.svg +1 -0
- package/public/icons/folder-stack.svg +1 -0
- package/public/icons/folder-store-open.svg +1 -0
- package/public/icons/folder-store.svg +1 -0
- package/public/icons/folder-supabase-open.svg +1 -0
- package/public/icons/folder-supabase.svg +1 -0
- package/public/icons/folder-svg-open.svg +1 -0
- package/public/icons/folder-svg.svg +1 -0
- package/public/icons/folder-target-open.svg +1 -0
- package/public/icons/folder-target.svg +1 -0
- package/public/icons/folder-tasks-open.svg +1 -0
- package/public/icons/folder-tasks.svg +1 -0
- package/public/icons/folder-temp-open.svg +1 -0
- package/public/icons/folder-temp.svg +1 -0
- package/public/icons/folder-template-open.svg +1 -0
- package/public/icons/folder-template.svg +1 -0
- package/public/icons/folder-test-open.svg +1 -0
- package/public/icons/folder-test.svg +1 -0
- package/public/icons/folder-tools-open.svg +1 -0
- package/public/icons/folder-tools.svg +1 -0
- package/public/icons/folder-typescript-open.svg +1 -0
- package/public/icons/folder-typescript.svg +1 -0
- package/public/icons/folder-ui-open.svg +1 -0
- package/public/icons/folder-ui.svg +1 -0
- package/public/icons/folder-upload-open.svg +1 -0
- package/public/icons/folder-upload.svg +1 -0
- package/public/icons/folder-utils-open.svg +1 -0
- package/public/icons/folder-utils.svg +1 -0
- package/public/icons/folder-video-open.svg +1 -0
- package/public/icons/folder-video.svg +1 -0
- package/public/icons/folder-views-open.svg +1 -0
- package/public/icons/folder-views.svg +1 -0
- package/public/icons/font.svg +1 -0
- package/public/icons/gemini-ai.svg +1 -0
- package/public/icons/gemini.svg +1 -0
- package/public/icons/git.svg +1 -0
- package/public/icons/google.svg +1 -0
- package/public/icons/graphql.svg +1 -0
- package/public/icons/html.svg +1 -0
- package/public/icons/image.svg +1 -0
- package/public/icons/java.svg +1 -0
- package/public/icons/javaclass.svg +1 -0
- package/public/icons/javascript.svg +1 -0
- package/public/icons/jsconfig.svg +1 -0
- package/public/icons/json.svg +1 -0
- package/public/icons/markdown.svg +1 -0
- package/public/icons/nodejs.svg +1 -0
- package/public/icons/nodejs_alt.svg +1 -0
- package/public/icons/nodemon.svg +1 -0
- package/public/icons/npm.svg +1 -0
- package/public/icons/pdf.svg +1 -0
- package/public/icons/prettier.svg +1 -0
- package/public/icons/prisma.svg +1 -0
- package/public/icons/python.svg +1 -0
- package/public/icons/react.svg +1 -0
- package/public/icons/react_ts.svg +1 -0
- package/public/icons/readme.svg +1 -0
- package/public/icons/remark.svg +1 -0
- package/public/icons/sass.svg +1 -0
- package/public/icons/svg.svg +1 -0
- package/public/icons/tailwindcss.svg +1 -0
- package/public/icons/typescript-def.svg +1 -0
- package/public/icons/typescript.svg +1 -0
- package/public/icons/zip.svg +1 -0
- package/public/index.html +1342 -0
- package/public/styles.css +4736 -0
- package/src/cli.js +175 -0
- package/src/lib/files.js +143 -0
- package/src/lib/notebook.js +141 -0
- package/src/lib/package-exports.js +331 -0
- package/src/lib/session.js +1003 -0
- package/src/server.js +2232 -0
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import ts from "typescript";
|
|
5
|
+
|
|
6
|
+
function createNotebookRequire(notebookPath) {
|
|
7
|
+
const anchor = path.join(path.dirname(notebookPath), "__nodebook__.mjs");
|
|
8
|
+
return createRequire(anchor);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function findPackageRootFromEntry(entryPath) {
|
|
12
|
+
let currentPath = path.dirname(entryPath);
|
|
13
|
+
|
|
14
|
+
while (currentPath !== path.dirname(currentPath)) {
|
|
15
|
+
if (fs.existsSync(path.join(currentPath, "package.json"))) {
|
|
16
|
+
return currentPath;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
currentPath = path.dirname(currentPath);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function resolvePackageRoot(notebookPath, moduleName) {
|
|
26
|
+
try {
|
|
27
|
+
const notebookRequire = createNotebookRequire(notebookPath);
|
|
28
|
+
const entryPath = notebookRequire.resolve(moduleName);
|
|
29
|
+
return findPackageRootFromEntry(entryPath);
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function resolveDeclarationEntry(packageRoot, packageJson) {
|
|
36
|
+
const candidates = [];
|
|
37
|
+
const rootExport = packageJson.exports?.["."];
|
|
38
|
+
|
|
39
|
+
if (typeof rootExport === "object" && rootExport !== null) {
|
|
40
|
+
if (typeof rootExport.types === "string") {
|
|
41
|
+
candidates.push(rootExport.types);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (typeof rootExport.import === "object" && rootExport.import !== null && typeof rootExport.import.types === "string") {
|
|
45
|
+
candidates.push(rootExport.import.types);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (typeof rootExport.require === "object" && rootExport.require !== null && typeof rootExport.require.types === "string") {
|
|
49
|
+
candidates.push(rootExport.require.types);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (typeof packageJson.types === "string") {
|
|
54
|
+
candidates.push(packageJson.types);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (typeof packageJson.typings === "string") {
|
|
58
|
+
candidates.push(packageJson.typings);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (typeof packageJson.module === "string") {
|
|
62
|
+
candidates.push(packageJson.module.replace(/\.js$/, ".d.ts"));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (typeof packageJson.main === "string") {
|
|
66
|
+
candidates.push(packageJson.main.replace(/\.cjs$/, ".d.cts").replace(/\.js$/, ".d.ts"));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
candidates.push("index.d.ts", "index.d.cts", "index.d.mts");
|
|
70
|
+
|
|
71
|
+
for (const candidate of candidates) {
|
|
72
|
+
const absolutePath = path.resolve(packageRoot, candidate);
|
|
73
|
+
|
|
74
|
+
if (fs.existsSync(absolutePath)) {
|
|
75
|
+
return absolutePath;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Find the root directory of an @types/ package by walking up the directory tree.
|
|
84
|
+
*
|
|
85
|
+
* `@types/*` packages contain ONLY `.d.ts` declaration files — they have no
|
|
86
|
+
* JavaScript entry point, so `require.resolve('@types/express')` always throws
|
|
87
|
+
* MODULE_NOT_FOUND. We locate them by scanning the filesystem directly instead.
|
|
88
|
+
*
|
|
89
|
+
* @param {string} notebookPath – absolute path to the .ijsnb file
|
|
90
|
+
* @param {string} atTypesName – full scoped name, e.g. "@types/express"
|
|
91
|
+
* @returns {string|null} absolute path to the @types/<name> root, or null
|
|
92
|
+
*/
|
|
93
|
+
function findAtTypesRoot(notebookPath, atTypesName) {
|
|
94
|
+
const suffix = atTypesName.startsWith("@types/")
|
|
95
|
+
? atTypesName.slice("@types/".length)
|
|
96
|
+
: atTypesName;
|
|
97
|
+
|
|
98
|
+
let dir = path.dirname(notebookPath);
|
|
99
|
+
const root = path.parse(dir).root;
|
|
100
|
+
|
|
101
|
+
while (dir !== root) {
|
|
102
|
+
const candidate = path.join(dir, "node_modules", "@types", suffix);
|
|
103
|
+
if (fs.existsSync(path.join(candidate, "package.json"))) {
|
|
104
|
+
return candidate;
|
|
105
|
+
}
|
|
106
|
+
dir = path.dirname(dir);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function isRelativeSpecifier(specifier) {
|
|
113
|
+
return specifier.startsWith("./") || specifier.startsWith("../");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function resolveDeclarationFile(fromFile, specifier) {
|
|
117
|
+
const basePath = path.resolve(path.dirname(fromFile), specifier);
|
|
118
|
+
const candidates = [
|
|
119
|
+
basePath,
|
|
120
|
+
`${basePath}.d.ts`,
|
|
121
|
+
`${basePath}.d.cts`,
|
|
122
|
+
`${basePath}.d.mts`,
|
|
123
|
+
path.join(basePath, "index.d.ts"),
|
|
124
|
+
path.join(basePath, "index.d.cts"),
|
|
125
|
+
path.join(basePath, "index.d.mts")
|
|
126
|
+
];
|
|
127
|
+
|
|
128
|
+
for (const candidate of candidates) {
|
|
129
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
|
|
130
|
+
return candidate;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function hasModifier(node, kind) {
|
|
138
|
+
return Boolean(node.modifiers?.some((modifier) => modifier.kind === kind));
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function classifyNode(node) {
|
|
142
|
+
if (ts.isClassDeclaration(node)) return "class";
|
|
143
|
+
if (ts.isFunctionDeclaration(node)) return "function";
|
|
144
|
+
if (ts.isInterfaceDeclaration(node)) return "interface";
|
|
145
|
+
if (ts.isTypeAliasDeclaration(node)) return "type";
|
|
146
|
+
if (ts.isEnumDeclaration(node)) return "enum";
|
|
147
|
+
if (ts.isVariableStatement(node)) return "variable";
|
|
148
|
+
return "symbol";
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function deriveDefaultImportName(moduleName) {
|
|
152
|
+
const baseName = moduleName.includes("/")
|
|
153
|
+
? moduleName.split("/").at(-1)
|
|
154
|
+
: moduleName;
|
|
155
|
+
|
|
156
|
+
const normalized = String(baseName ?? "pkg")
|
|
157
|
+
.replace(/[^a-zA-Z0-9_$]+/g, " ")
|
|
158
|
+
.trim()
|
|
159
|
+
.split(/\s+/)
|
|
160
|
+
.filter(Boolean)
|
|
161
|
+
.map((part, index) => {
|
|
162
|
+
if (index === 0) return part.toLowerCase();
|
|
163
|
+
return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
|
|
164
|
+
})
|
|
165
|
+
.join("");
|
|
166
|
+
|
|
167
|
+
return normalized || "pkg";
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function addExportSymbol(store, moduleName, name, kind, options = {}) {
|
|
171
|
+
if (!name || name === "default" || name === "__esModule") {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(name)) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const key = `${moduleName}:${name}`;
|
|
180
|
+
if (store.has(key)) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
store.set(key, {
|
|
185
|
+
moduleName,
|
|
186
|
+
exportName: name,
|
|
187
|
+
importName: name,
|
|
188
|
+
kind,
|
|
189
|
+
isDefault: Boolean(options.isDefault)
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function collectPackageSymbols(moduleName, entryFile) {
|
|
194
|
+
const visitedFiles = new Set();
|
|
195
|
+
const exportsMap = new Map();
|
|
196
|
+
|
|
197
|
+
function visit(filePath) {
|
|
198
|
+
if (!filePath || visitedFiles.has(filePath) || !fs.existsSync(filePath)) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
visitedFiles.add(filePath);
|
|
203
|
+
|
|
204
|
+
let sourceText = "";
|
|
205
|
+
try {
|
|
206
|
+
sourceText = fs.readFileSync(filePath, "utf8");
|
|
207
|
+
} catch {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const sourceFile = ts.createSourceFile(filePath, sourceText, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
212
|
+
|
|
213
|
+
for (const statement of sourceFile.statements) {
|
|
214
|
+
if (ts.isExportAssignment(statement)) {
|
|
215
|
+
const localName = deriveDefaultImportName(moduleName);
|
|
216
|
+
addExportSymbol(exportsMap, moduleName, localName, "default", { isDefault: true });
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (ts.isExportDeclaration(statement)) {
|
|
221
|
+
const moduleSpecifier = statement.moduleSpecifier && ts.isStringLiteral(statement.moduleSpecifier)
|
|
222
|
+
? statement.moduleSpecifier.text
|
|
223
|
+
: null;
|
|
224
|
+
|
|
225
|
+
if (statement.exportClause && ts.isNamedExports(statement.exportClause)) {
|
|
226
|
+
for (const element of statement.exportClause.elements) {
|
|
227
|
+
const exportName = element.name.text;
|
|
228
|
+
addExportSymbol(exportsMap, moduleName, exportName, "symbol");
|
|
229
|
+
}
|
|
230
|
+
} else if (!statement.exportClause && moduleSpecifier && isRelativeSpecifier(moduleSpecifier)) {
|
|
231
|
+
visit(resolveDeclarationFile(filePath, moduleSpecifier));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (!hasModifier(statement, ts.SyntaxKind.ExportKeyword)) {
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const kind = classifyNode(statement);
|
|
242
|
+
const isDefault = hasModifier(statement, ts.SyntaxKind.DefaultKeyword);
|
|
243
|
+
|
|
244
|
+
if (ts.isVariableStatement(statement)) {
|
|
245
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
246
|
+
if (ts.isIdentifier(declaration.name)) {
|
|
247
|
+
addExportSymbol(exportsMap, moduleName, declaration.name.text, kind);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if ("name" in statement && statement.name && ts.isIdentifier(statement.name)) {
|
|
255
|
+
addExportSymbol(exportsMap, moduleName, statement.name.text, kind);
|
|
256
|
+
} else if (isDefault) {
|
|
257
|
+
addExportSymbol(exportsMap, moduleName, deriveDefaultImportName(moduleName), "default", { isDefault: true });
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
visit(entryFile);
|
|
263
|
+
|
|
264
|
+
return Array.from(exportsMap.values())
|
|
265
|
+
.sort((left, right) => left.exportName.localeCompare(right.exportName));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export async function collectDeclaredPackageExports(notebookPath, moduleNames) {
|
|
269
|
+
const exportEntries = [];
|
|
270
|
+
|
|
271
|
+
for (const moduleName of moduleNames) {
|
|
272
|
+
// Skip @types/ packages themselves — they are type companions, not importable modules.
|
|
273
|
+
// Their symbols are collected via the @types fallback path below when the main
|
|
274
|
+
// package (e.g. "express") has no bundled declarations.
|
|
275
|
+
if (moduleName.startsWith("@types/")) continue;
|
|
276
|
+
|
|
277
|
+
const packageRoot = resolvePackageRoot(notebookPath, moduleName);
|
|
278
|
+
if (!packageRoot) {
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const packageJsonPath = path.join(packageRoot, "package.json");
|
|
283
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
let packageJson = {};
|
|
288
|
+
try {
|
|
289
|
+
packageJson = JSON.parse(await fs.promises.readFile(packageJsonPath, "utf8"));
|
|
290
|
+
} catch {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
let declarationEntry = resolveDeclarationEntry(packageRoot, packageJson);
|
|
295
|
+
|
|
296
|
+
// Many popular packages (express, axios, lodash, etc.) ship NO bundled .d.ts
|
|
297
|
+
// files and rely on a companion "@types/<name>" package from DefinitelyTyped.
|
|
298
|
+
// When the package itself has no declaration entry, try that companion package
|
|
299
|
+
// so we still get named-export auto-complete for the original module name.
|
|
300
|
+
//
|
|
301
|
+
// IMPORTANT: we use findAtTypesRoot() NOT resolvePackageRoot() here because
|
|
302
|
+
// @types/* packages have no JavaScript entry point, so require.resolve() always
|
|
303
|
+
// throws MODULE_NOT_FOUND for them.
|
|
304
|
+
if (!declarationEntry) {
|
|
305
|
+
const atTypesName = moduleName.startsWith("@")
|
|
306
|
+
? `@types/${moduleName.slice(1).replace("/", "__")}` // @scope/pkg → @types/scope__pkg
|
|
307
|
+
: `@types/${moduleName}`;
|
|
308
|
+
|
|
309
|
+
const atTypesRoot = findAtTypesRoot(notebookPath, atTypesName);
|
|
310
|
+
if (atTypesRoot) {
|
|
311
|
+
try {
|
|
312
|
+
const atTypesPkgJsonPath = path.join(atTypesRoot, "package.json");
|
|
313
|
+
const atTypesPkgJson = JSON.parse(
|
|
314
|
+
await fs.promises.readFile(atTypesPkgJsonPath, "utf8")
|
|
315
|
+
);
|
|
316
|
+
declarationEntry = resolveDeclarationEntry(atTypesRoot, atTypesPkgJson);
|
|
317
|
+
} catch {
|
|
318
|
+
// ignore — fall through to the next module
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (!declarationEntry) {
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
exportEntries.push(...collectPackageSymbols(moduleName, declarationEntry));
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
return exportEntries;
|
|
331
|
+
}
|