@microsoft/rayfin-docs 1.35.0-alpha.1315 → 1.35.0-alpha.1331
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/dist/discovery.d.ts +21 -0
- package/dist/discovery.js +62 -34
- package/dist/site-cjs/discovery.js +63 -34
- package/package.json +1 -1
package/dist/discovery.d.ts
CHANGED
|
@@ -107,4 +107,25 @@ export declare function validateRayfinDocsManifest(pkgJson: unknown, packageName
|
|
|
107
107
|
* docs" for end users.
|
|
108
108
|
*/
|
|
109
109
|
export declare function docKindToModule(kind: DocKind): 'guide' | 'host' | 'ts-sdk';
|
|
110
|
+
/** One package and its actual installed manifest version. */
|
|
111
|
+
export interface InstalledPackageVersion {
|
|
112
|
+
name: string;
|
|
113
|
+
version: string;
|
|
114
|
+
}
|
|
115
|
+
/** Installed package versions plus candidates that could not be resolved. */
|
|
116
|
+
export interface InstalledPackageVersionResolution {
|
|
117
|
+
packages: InstalledPackageVersion[];
|
|
118
|
+
unresolvedPackageNames: string[];
|
|
119
|
+
}
|
|
120
|
+
/** Optional policy applied to installed manifest versions. */
|
|
121
|
+
export interface InstalledPackageVersionResolutionOptions {
|
|
122
|
+
isVersionAllowed?: (version: string) => boolean;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Resolve actual installed versions for a bounded candidate set.
|
|
126
|
+
*
|
|
127
|
+
* Candidates are deduplicated and sorted. Missing, malformed, or mismatched
|
|
128
|
+
* manifests are omitted so telemetry collection remains best-effort.
|
|
129
|
+
*/
|
|
130
|
+
export declare function resolveInstalledPackageVersions(packageNames: readonly string[], from: string, options?: InstalledPackageVersionResolutionOptions): InstalledPackageVersionResolution;
|
|
110
131
|
//# sourceMappingURL=discovery.d.ts.map
|
package/dist/discovery.js
CHANGED
|
@@ -318,38 +318,71 @@ function buildNodeModulesChain(fromDir) {
|
|
|
318
318
|
return chain;
|
|
319
319
|
}
|
|
320
320
|
/**
|
|
321
|
-
*
|
|
322
|
-
* `exports` field doesn't expose it as a subpath OR when the package
|
|
323
|
-
* is ESM-only (`exports."."` is `{ "import": ... }` without a CJS
|
|
324
|
-
* `default`/`require` branch).
|
|
321
|
+
* Resolve actual installed versions for a bounded candidate set.
|
|
325
322
|
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
323
|
+
* Candidates are deduplicated and sorted. Missing, malformed, or mismatched
|
|
324
|
+
* manifests are omitted so telemetry collection remains best-effort.
|
|
325
|
+
*/
|
|
326
|
+
export function resolveInstalledPackageVersions(packageNames, from, options = {}) {
|
|
327
|
+
const fromDir = from.startsWith('file:') || from.includes('://')
|
|
328
|
+
? dirname(fileURLToPath(from))
|
|
329
|
+
: resolveExistingDir(from);
|
|
330
|
+
const requireFromBase = createRequire(join(fromDir, 'noop.js'));
|
|
331
|
+
const nodeModulesChain = buildNodeModulesChain(fromDir);
|
|
332
|
+
const packages = [];
|
|
333
|
+
const unresolvedPackageNames = [];
|
|
334
|
+
for (const packageName of [...new Set(packageNames)].sort()) {
|
|
335
|
+
if (!isValidPackageName(packageName)) {
|
|
336
|
+
unresolvedPackageNames.push(packageName);
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
const packageJsonPath = resolvePackageJson(requireFromBase, packageName, nodeModulesChain);
|
|
340
|
+
if (!packageJsonPath) {
|
|
341
|
+
unresolvedPackageNames.push(packageName);
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
try {
|
|
345
|
+
const manifest = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
346
|
+
if (manifest.name === packageName &&
|
|
347
|
+
typeof manifest.version === 'string' &&
|
|
348
|
+
manifest.version.length > 0 &&
|
|
349
|
+
(options.isVersionAllowed?.(manifest.version) ?? true)) {
|
|
350
|
+
packages.push({ name: packageName, version: manifest.version });
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
unresolvedPackageNames.push(packageName);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
unresolvedPackageNames.push(packageName);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
return { packages, unresolvedPackageNames };
|
|
361
|
+
}
|
|
362
|
+
function isValidPackageName(packageName) {
|
|
363
|
+
return (packageName.length <= 214 &&
|
|
364
|
+
/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/.test(packageName));
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Find a package's `package.json` even when exports hide it, the package is
|
|
368
|
+
* ESM-only, or the install is hoisted above the resolution root.
|
|
333
369
|
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
370
|
+
* Packages with restricted exports often omit `./package.json`, causing direct
|
|
371
|
+
* subpath resolution to fail. ESM-only packages may also hide their main entry
|
|
372
|
+
* from CommonJS resolution, so the final tier searches the cached ancestor
|
|
373
|
+
* `node_modules` chain used by npm, pnpm, and Yarn-style installs.
|
|
336
374
|
*/
|
|
337
375
|
function resolvePackageJson(req, packageName, nodeModulesChain) {
|
|
338
|
-
//
|
|
339
|
-
// includes `./package.json` in it.
|
|
376
|
+
// Tier 1: direct manifest resolution when exports allow the subpath.
|
|
340
377
|
try {
|
|
341
378
|
return req.resolve(`${packageName}/package.json`);
|
|
342
379
|
}
|
|
343
|
-
catch
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
return undefined;
|
|
348
|
-
}
|
|
349
|
-
// ERR_PACKAGE_PATH_NOT_EXPORTED or similar: keep going.
|
|
380
|
+
catch {
|
|
381
|
+
// MODULE_NOT_FOUND means only this subpath failed to resolve, not that the
|
|
382
|
+
// package is absent. Restricted exports and alternate layouts require the
|
|
383
|
+
// remaining tiers.
|
|
350
384
|
}
|
|
351
|
-
//
|
|
352
|
-
// searching for a package.json whose name matches.
|
|
385
|
+
// Tier 2: resolve the package entry, then walk upward to its named manifest.
|
|
353
386
|
try {
|
|
354
387
|
const entry = req.resolve(packageName);
|
|
355
388
|
let dir = dirname(entry);
|
|
@@ -358,12 +391,11 @@ function resolvePackageJson(req, packageName, nodeModulesChain) {
|
|
|
358
391
|
if (existsSync(candidate)) {
|
|
359
392
|
try {
|
|
360
393
|
const parsed = JSON.parse(readFileSync(candidate, 'utf8'));
|
|
361
|
-
if (parsed.name === packageName)
|
|
394
|
+
if (parsed.name === packageName)
|
|
362
395
|
return candidate;
|
|
363
|
-
}
|
|
364
396
|
}
|
|
365
397
|
catch {
|
|
366
|
-
//
|
|
398
|
+
// Keep walking toward the package root.
|
|
367
399
|
}
|
|
368
400
|
}
|
|
369
401
|
const parent = dirname(dir);
|
|
@@ -373,17 +405,13 @@ function resolvePackageJson(req, packageName, nodeModulesChain) {
|
|
|
373
405
|
}
|
|
374
406
|
}
|
|
375
407
|
catch {
|
|
376
|
-
// ESM-only package or similar: fall through to
|
|
408
|
+
// ESM-only package or similar: fall through to node_modules lookup.
|
|
377
409
|
}
|
|
378
|
-
//
|
|
379
|
-
// chain looking for `<ancestor>/node_modules/<packageName>/package.json`.
|
|
380
|
-
// This is what npm/pnpm/yarn tooling does internally and works
|
|
381
|
-
// regardless of how the package's `exports` are configured.
|
|
410
|
+
// Tier 3: search cached ancestor node_modules roots, independent of exports.
|
|
382
411
|
for (const dir of nodeModulesChain) {
|
|
383
412
|
const candidate = join(dir, 'node_modules', packageName, 'package.json');
|
|
384
|
-
if (existsSync(candidate))
|
|
413
|
+
if (existsSync(candidate))
|
|
385
414
|
return candidate;
|
|
386
|
-
}
|
|
387
415
|
}
|
|
388
416
|
return undefined;
|
|
389
417
|
}
|
|
@@ -5,6 +5,7 @@ exports.hasExplicitDiscoverySource = hasExplicitDiscoverySource;
|
|
|
5
5
|
exports.discoverRayfinDocsPackages = discoverRayfinDocsPackages;
|
|
6
6
|
exports.validateRayfinDocsManifest = validateRayfinDocsManifest;
|
|
7
7
|
exports.docKindToModule = docKindToModule;
|
|
8
|
+
exports.resolveInstalledPackageVersions = resolveInstalledPackageVersions;
|
|
8
9
|
/**
|
|
9
10
|
* Per-package docs discovery - Phase 2 of `docs-package-architecture`.
|
|
10
11
|
*
|
|
@@ -326,38 +327,71 @@ function buildNodeModulesChain(fromDir) {
|
|
|
326
327
|
return chain;
|
|
327
328
|
}
|
|
328
329
|
/**
|
|
329
|
-
*
|
|
330
|
-
* `exports` field doesn't expose it as a subpath OR when the package
|
|
331
|
-
* is ESM-only (`exports."."` is `{ "import": ... }` without a CJS
|
|
332
|
-
* `default`/`require` branch).
|
|
330
|
+
* Resolve actual installed versions for a bounded candidate set.
|
|
333
331
|
*
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
332
|
+
* Candidates are deduplicated and sorted. Missing, malformed, or mismatched
|
|
333
|
+
* manifests are omitted so telemetry collection remains best-effort.
|
|
334
|
+
*/
|
|
335
|
+
function resolveInstalledPackageVersions(packageNames, from, options = {}) {
|
|
336
|
+
const fromDir = from.startsWith('file:') || from.includes('://')
|
|
337
|
+
? (0, path_1.dirname)((0, url_1.fileURLToPath)(from))
|
|
338
|
+
: resolveExistingDir(from);
|
|
339
|
+
const requireFromBase = (0, module_1.createRequire)((0, path_1.join)(fromDir, 'noop.js'));
|
|
340
|
+
const nodeModulesChain = buildNodeModulesChain(fromDir);
|
|
341
|
+
const packages = [];
|
|
342
|
+
const unresolvedPackageNames = [];
|
|
343
|
+
for (const packageName of [...new Set(packageNames)].sort()) {
|
|
344
|
+
if (!isValidPackageName(packageName)) {
|
|
345
|
+
unresolvedPackageNames.push(packageName);
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
const packageJsonPath = resolvePackageJson(requireFromBase, packageName, nodeModulesChain);
|
|
349
|
+
if (!packageJsonPath) {
|
|
350
|
+
unresolvedPackageNames.push(packageName);
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
try {
|
|
354
|
+
const manifest = JSON.parse((0, fs_1.readFileSync)(packageJsonPath, 'utf8'));
|
|
355
|
+
if (manifest.name === packageName &&
|
|
356
|
+
typeof manifest.version === 'string' &&
|
|
357
|
+
manifest.version.length > 0 &&
|
|
358
|
+
(options.isVersionAllowed?.(manifest.version) ?? true)) {
|
|
359
|
+
packages.push({ name: packageName, version: manifest.version });
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
unresolvedPackageNames.push(packageName);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
unresolvedPackageNames.push(packageName);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return { packages, unresolvedPackageNames };
|
|
370
|
+
}
|
|
371
|
+
function isValidPackageName(packageName) {
|
|
372
|
+
return (packageName.length <= 214 &&
|
|
373
|
+
/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/.test(packageName));
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Find a package's `package.json` even when exports hide it, the package is
|
|
377
|
+
* ESM-only, or the install is hoisted above the resolution root.
|
|
341
378
|
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
379
|
+
* Packages with restricted exports often omit `./package.json`, causing direct
|
|
380
|
+
* subpath resolution to fail. ESM-only packages may also hide their main entry
|
|
381
|
+
* from CommonJS resolution, so the final tier searches the cached ancestor
|
|
382
|
+
* `node_modules` chain used by npm, pnpm, and Yarn-style installs.
|
|
344
383
|
*/
|
|
345
384
|
function resolvePackageJson(req, packageName, nodeModulesChain) {
|
|
346
|
-
//
|
|
347
|
-
// includes `./package.json` in it.
|
|
385
|
+
// Tier 1: direct manifest resolution when exports allow the subpath.
|
|
348
386
|
try {
|
|
349
387
|
return req.resolve(`${packageName}/package.json`);
|
|
350
388
|
}
|
|
351
|
-
catch
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
return undefined;
|
|
356
|
-
}
|
|
357
|
-
// ERR_PACKAGE_PATH_NOT_EXPORTED or similar: keep going.
|
|
389
|
+
catch {
|
|
390
|
+
// MODULE_NOT_FOUND means only this subpath failed to resolve, not that the
|
|
391
|
+
// package is absent. Restricted exports and alternate layouts require the
|
|
392
|
+
// remaining tiers.
|
|
358
393
|
}
|
|
359
|
-
//
|
|
360
|
-
// searching for a package.json whose name matches.
|
|
394
|
+
// Tier 2: resolve the package entry, then walk upward to its named manifest.
|
|
361
395
|
try {
|
|
362
396
|
const entry = req.resolve(packageName);
|
|
363
397
|
let dir = (0, path_1.dirname)(entry);
|
|
@@ -366,12 +400,11 @@ function resolvePackageJson(req, packageName, nodeModulesChain) {
|
|
|
366
400
|
if ((0, fs_1.existsSync)(candidate)) {
|
|
367
401
|
try {
|
|
368
402
|
const parsed = JSON.parse((0, fs_1.readFileSync)(candidate, 'utf8'));
|
|
369
|
-
if (parsed.name === packageName)
|
|
403
|
+
if (parsed.name === packageName)
|
|
370
404
|
return candidate;
|
|
371
|
-
}
|
|
372
405
|
}
|
|
373
406
|
catch {
|
|
374
|
-
//
|
|
407
|
+
// Keep walking toward the package root.
|
|
375
408
|
}
|
|
376
409
|
}
|
|
377
410
|
const parent = (0, path_1.dirname)(dir);
|
|
@@ -381,17 +414,13 @@ function resolvePackageJson(req, packageName, nodeModulesChain) {
|
|
|
381
414
|
}
|
|
382
415
|
}
|
|
383
416
|
catch {
|
|
384
|
-
// ESM-only package or similar: fall through to
|
|
417
|
+
// ESM-only package or similar: fall through to node_modules lookup.
|
|
385
418
|
}
|
|
386
|
-
//
|
|
387
|
-
// chain looking for `<ancestor>/node_modules/<packageName>/package.json`.
|
|
388
|
-
// This is what npm/pnpm/yarn tooling does internally and works
|
|
389
|
-
// regardless of how the package's `exports` are configured.
|
|
419
|
+
// Tier 3: search cached ancestor node_modules roots, independent of exports.
|
|
390
420
|
for (const dir of nodeModulesChain) {
|
|
391
421
|
const candidate = (0, path_1.join)(dir, 'node_modules', packageName, 'package.json');
|
|
392
|
-
if ((0, fs_1.existsSync)(candidate))
|
|
422
|
+
if ((0, fs_1.existsSync)(candidate))
|
|
393
423
|
return candidate;
|
|
394
|
-
}
|
|
395
424
|
}
|
|
396
425
|
return undefined;
|
|
397
426
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microsoft/rayfin-docs",
|
|
3
|
-
"version": "1.35.0-alpha.
|
|
3
|
+
"version": "1.35.0-alpha.1331",
|
|
4
4
|
"description": "Rayfin docs indexing and search library — used by the MCP server, CLI, and other doc-facing surfaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|