@x12i/npm-core 0.0.0-stage → 0.2.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/README.md +14 -3
- package/dist/http.d.ts +21 -0
- package/dist/http.js +59 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/registry.d.ts +86 -0
- package/dist/registry.js +231 -0
- package/dist/registry.js.map +1 -0
- package/package.json +52 -6
package/README.md
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# @x12i/npm-core
|
|
2
|
+
|
|
3
|
+
Read the public npm registry: list every package in an org, and read one package's README and metadata.
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
import { listOrgPackages, getReadme } from "@x12i/npm-core";
|
|
7
|
+
|
|
8
|
+
const names = await listOrgPackages("x12i");
|
|
9
|
+
const readme = await getReadme("@x12i/sdk");
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
`listOrgPackages` uses `GET https://registry.npmjs.org/-/org/{org}/package`. Search is only the fallback when that listing is empty or fails. `listOrgCatalog` returns that same set, including unscoped names the org owns, and adds the latest publish time from the maintainer search when npm has one. Both always include the org's `UNSCOPED_PACKAGES` (for x12i, names such as `devops-agent`), so unscoped packages stay tracked when npm falls back to scoped search. Add a new unscoped package to that list in `src/registry.ts`. `getReadme` and `getPackage` read the packument. `getLastMonthDownloads` reads the npm downloads API.
|
|
13
|
+
|
|
14
|
+
This package does not crawl daily download history and it does not store reviews. Pass `fetch`, `userAgent`, `maxRetries`, `deadline`, and `beforeFetch` when the caller has to count or stub HTTP requests.
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare class RateLimitedError extends Error {
|
|
2
|
+
readonly status = 429;
|
|
3
|
+
retryAfterMs?: number;
|
|
4
|
+
constructor(message: string);
|
|
5
|
+
}
|
|
6
|
+
export type RequestError = Error & {
|
|
7
|
+
status?: number;
|
|
8
|
+
retryAfterMs?: number;
|
|
9
|
+
};
|
|
10
|
+
export type RequestOptions = {
|
|
11
|
+
fetch?: typeof fetch;
|
|
12
|
+
userAgent?: string;
|
|
13
|
+
/** Retries after the first attempt for network errors, 5xx, and 429. */
|
|
14
|
+
maxRetries?: number;
|
|
15
|
+
/** Epoch ms. A 429 whose wait would pass this deadline is thrown immediately. */
|
|
16
|
+
deadline?: number;
|
|
17
|
+
/** Called once per HTTP attempt. Throw to stop, for example when a fetch budget is spent. */
|
|
18
|
+
beforeFetch?: () => void;
|
|
19
|
+
};
|
|
20
|
+
/** GET JSON from the npm registry or downloads API. */
|
|
21
|
+
export declare function fetchJson<T>(url: string, options?: RequestOptions): Promise<T>;
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export class RateLimitedError extends Error {
|
|
2
|
+
status = 429;
|
|
3
|
+
retryAfterMs;
|
|
4
|
+
constructor(message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "RateLimitedError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
function delay(milliseconds) {
|
|
10
|
+
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
11
|
+
}
|
|
12
|
+
/** GET JSON from the npm registry or downloads API. */
|
|
13
|
+
export async function fetchJson(url, options = {}) {
|
|
14
|
+
const maxRetries = options.maxRetries ?? 2;
|
|
15
|
+
const doFetch = options.fetch ?? fetch;
|
|
16
|
+
let lastError = new Error("npm request failed");
|
|
17
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
18
|
+
options.beforeFetch?.();
|
|
19
|
+
try {
|
|
20
|
+
const response = await doFetch(url, {
|
|
21
|
+
headers: {
|
|
22
|
+
Accept: "application/json",
|
|
23
|
+
"User-Agent": options.userAgent ?? "@x12i/npm-core",
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
if (response.ok)
|
|
27
|
+
return (await response.json());
|
|
28
|
+
const retryAfter = Number(response.headers.get("retry-after"));
|
|
29
|
+
const error = new Error(`npm API returned status ${response.status} for ${url}`);
|
|
30
|
+
error.status = response.status;
|
|
31
|
+
error.retryAfterMs = Number.isFinite(retryAfter) ? retryAfter * 1000 : 0;
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
if (error instanceof RateLimitedError)
|
|
36
|
+
throw error;
|
|
37
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
38
|
+
if (lastError.name === "FetchBudgetExhausted")
|
|
39
|
+
throw lastError;
|
|
40
|
+
const status = lastError.status ?? 0;
|
|
41
|
+
const rateLimited = status === 429;
|
|
42
|
+
if (status >= 400 && status < 500 && !rateLimited)
|
|
43
|
+
break;
|
|
44
|
+
if (attempt >= maxRetries) {
|
|
45
|
+
if (rateLimited)
|
|
46
|
+
throw new RateLimitedError(lastError.message);
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
const backoff = rateLimited ? Math.min(30_000, 3_000 * 2 ** attempt) : (attempt + 1) * 1_500;
|
|
50
|
+
const wait = Math.max(lastError.retryAfterMs ?? 0, backoff) + Math.floor(Math.random() * 400);
|
|
51
|
+
if (rateLimited && options.deadline && Date.now() + wait > options.deadline) {
|
|
52
|
+
throw new RateLimitedError(lastError.message);
|
|
53
|
+
}
|
|
54
|
+
await delay(wait);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
throw lastError;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { RateLimitedError, fetchJson, type RequestOptions } from "./http.js";
|
|
2
|
+
export { getLastMonthDownloads, getPackage, getReadme, listOrgCatalog, listOrgPackages, normalizeOrg, packageInfo, readmeHeadings, searchPackages, UNSCOPED_PACKAGES, unscopedPackages, type OrgPackageRecord, type PackageInfo, } from "./registry.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { RateLimitedError, fetchJson } from "./http.js";
|
|
2
|
+
export { getLastMonthDownloads, getPackage, getReadme, listOrgCatalog, listOrgPackages, normalizeOrg, packageInfo, readmeHeadings, searchPackages, UNSCOPED_PACKAGES, unscopedPackages, } from "./registry.js";
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAuB,MAAM,WAAW,CAAC;AAC7E,OAAO,EACL,qBAAqB,EACrB,UAAU,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,YAAY,EACZ,WAAW,EACX,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GAGjB,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { type RequestOptions } from "./http.js";
|
|
2
|
+
export type PackageInfo = {
|
|
3
|
+
name: string;
|
|
4
|
+
version: string | null;
|
|
5
|
+
description: string;
|
|
6
|
+
keywords: string[];
|
|
7
|
+
homepage: string | null;
|
|
8
|
+
repository: string | null;
|
|
9
|
+
readme: string;
|
|
10
|
+
publishedAt: string | null;
|
|
11
|
+
modifiedAt: string | null;
|
|
12
|
+
license: string | null;
|
|
13
|
+
};
|
|
14
|
+
type Packument = {
|
|
15
|
+
name?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
readme?: string;
|
|
18
|
+
license?: string | {
|
|
19
|
+
type?: string;
|
|
20
|
+
};
|
|
21
|
+
keywords?: unknown;
|
|
22
|
+
homepage?: string;
|
|
23
|
+
repository?: unknown;
|
|
24
|
+
"dist-tags"?: {
|
|
25
|
+
latest?: string;
|
|
26
|
+
};
|
|
27
|
+
versions?: Record<string, VersionDoc>;
|
|
28
|
+
time?: Record<string, string>;
|
|
29
|
+
};
|
|
30
|
+
type VersionDoc = {
|
|
31
|
+
description?: string;
|
|
32
|
+
keywords?: unknown;
|
|
33
|
+
homepage?: string;
|
|
34
|
+
repository?: unknown;
|
|
35
|
+
license?: string | {
|
|
36
|
+
type?: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export type OrgPackageRecord = {
|
|
40
|
+
name: string;
|
|
41
|
+
version: string | null;
|
|
42
|
+
description: string;
|
|
43
|
+
keywords: string[];
|
|
44
|
+
homepage: string | null;
|
|
45
|
+
repository: string | null;
|
|
46
|
+
license: string | null;
|
|
47
|
+
/** Latest publish time from npm search. Null when search has not seen this package yet. */
|
|
48
|
+
modifiedAt: string | null;
|
|
49
|
+
};
|
|
50
|
+
/** `x12i`, `@x12i`, and `@x12i/` all name the org `x12i`. */
|
|
51
|
+
export declare function normalizeOrg(org: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* Org packages published without the `@org/` scope. Scoped search cannot find them,
|
|
54
|
+
* so they are always tracked even when the org listing is unavailable.
|
|
55
|
+
*/
|
|
56
|
+
export declare const UNSCOPED_PACKAGES: Readonly<Record<string, readonly string[]>>;
|
|
57
|
+
export declare function unscopedPackages(org: string): readonly string[];
|
|
58
|
+
export declare function readmeHeadings(markdown: string): string[];
|
|
59
|
+
export declare function packageInfo(doc: Packument, fallbackName?: string): PackageInfo;
|
|
60
|
+
/**
|
|
61
|
+
* Every package the org listing returns, including unscoped names the org owns,
|
|
62
|
+
* plus the known unscoped packages for the org.
|
|
63
|
+
* npm search is only the fallback: it drops packages and repeats others.
|
|
64
|
+
*/
|
|
65
|
+
export declare function listOrgPackages(org: string, options?: RequestOptions): Promise<string[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Every package the org owns, including unscoped names, with the latest publish
|
|
68
|
+
* time when the maintainer search knows it. Membership comes from the org listing.
|
|
69
|
+
* Search only supplies dates and short metadata, and a search failure still returns the names.
|
|
70
|
+
*/
|
|
71
|
+
export declare function listOrgCatalog(org: string, options?: RequestOptions): Promise<{
|
|
72
|
+
packages: OrgPackageRecord[];
|
|
73
|
+
fromOrgListing: boolean;
|
|
74
|
+
}>;
|
|
75
|
+
/** Registry search filtered to one scope, used when the catalog service is unreachable. */
|
|
76
|
+
export declare function searchPackages(text: string, options?: RequestOptions & {
|
|
77
|
+
size?: number;
|
|
78
|
+
scope?: string;
|
|
79
|
+
}): Promise<PackageInfo[]>;
|
|
80
|
+
/** Full packument summary for one package. */
|
|
81
|
+
export declare function getPackage(name: string, options?: RequestOptions): Promise<PackageInfo>;
|
|
82
|
+
/** README plus the description, keywords, version, repository, and homepage from the same packument. */
|
|
83
|
+
export declare function getReadme(name: string, options?: RequestOptions): Promise<PackageInfo>;
|
|
84
|
+
/** Download count for the last month. A package npm has not counted yet is 0. */
|
|
85
|
+
export declare function getLastMonthDownloads(name: string, options?: RequestOptions): Promise<number>;
|
|
86
|
+
export {};
|
package/dist/registry.js
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { fetchJson } from "./http.js";
|
|
2
|
+
const SEARCH_PAGE_SIZE = 250;
|
|
3
|
+
/** `x12i`, `@x12i`, and `@x12i/` all name the org `x12i`. */
|
|
4
|
+
export function normalizeOrg(org) {
|
|
5
|
+
const name = org.trim().replace(/^@/, "").replace(/\/$/, "");
|
|
6
|
+
if (!/^[a-z0-9][a-z0-9-]*$/i.test(name))
|
|
7
|
+
throw new Error(`Invalid npm org: ${org}`);
|
|
8
|
+
return name;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Org packages published without the `@org/` scope. Scoped search cannot find them,
|
|
12
|
+
* so they are always tracked even when the org listing is unavailable.
|
|
13
|
+
*/
|
|
14
|
+
export const UNSCOPED_PACKAGES = {
|
|
15
|
+
x12i: [
|
|
16
|
+
"aimlapi-models",
|
|
17
|
+
"apimart-models",
|
|
18
|
+
"aws-ai-availability",
|
|
19
|
+
"azure-ai-availability",
|
|
20
|
+
"catalog-explorer-ui",
|
|
21
|
+
"catalog-model-convert",
|
|
22
|
+
"catalox-ui",
|
|
23
|
+
"cloudflare-ai-availability",
|
|
24
|
+
"decision-models",
|
|
25
|
+
"devops-agent",
|
|
26
|
+
"doctor-mongo",
|
|
27
|
+
"haimaker-models",
|
|
28
|
+
"ofoxai-models",
|
|
29
|
+
"openrouter-models",
|
|
30
|
+
"x12i-downloads",
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
export function unscopedPackages(org) {
|
|
34
|
+
return UNSCOPED_PACKAGES[normalizeOrg(org)] ?? [];
|
|
35
|
+
}
|
|
36
|
+
function withUnscoped(org, names) {
|
|
37
|
+
return [...new Set([...names, ...unscopedPackages(org)])].sort();
|
|
38
|
+
}
|
|
39
|
+
function strings(value) {
|
|
40
|
+
if (!Array.isArray(value))
|
|
41
|
+
return [];
|
|
42
|
+
return value.filter((item) => typeof item === "string" && item.trim().length > 0);
|
|
43
|
+
}
|
|
44
|
+
function cleanRepository(value) {
|
|
45
|
+
const raw = typeof value === "string" ? value : value && typeof value === "object" && typeof value.url === "string" ? value.url : "";
|
|
46
|
+
const cleaned = raw.replace(/^git\+/, "").replace(/\.git$/, "").trim();
|
|
47
|
+
return cleaned || null;
|
|
48
|
+
}
|
|
49
|
+
function licenseOf(value) {
|
|
50
|
+
if (typeof value === "string" && value.trim())
|
|
51
|
+
return value.trim();
|
|
52
|
+
if (value && typeof value === "object" && typeof value.type === "string")
|
|
53
|
+
return value.type;
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
export function readmeHeadings(markdown) {
|
|
57
|
+
return markdown
|
|
58
|
+
.split(/\r?\n/)
|
|
59
|
+
.map((line) => /^#{1,3}\s+(.+?)\s*#*$/.exec(line)?.[1]?.trim() ?? "")
|
|
60
|
+
.filter((heading) => heading.length > 0);
|
|
61
|
+
}
|
|
62
|
+
export function packageInfo(doc, fallbackName = "") {
|
|
63
|
+
const version = doc["dist-tags"]?.latest ?? null;
|
|
64
|
+
const latest = version && doc.versions ? doc.versions[version] : undefined;
|
|
65
|
+
const name = doc.name || fallbackName;
|
|
66
|
+
if (!name)
|
|
67
|
+
throw new Error("npm packument has no package name");
|
|
68
|
+
return {
|
|
69
|
+
name,
|
|
70
|
+
version,
|
|
71
|
+
description: (doc.description || latest?.description || "").trim(),
|
|
72
|
+
keywords: strings(latest?.keywords ?? doc.keywords),
|
|
73
|
+
homepage: (typeof latest?.homepage === "string" && latest.homepage) || (typeof doc.homepage === "string" && doc.homepage) || null,
|
|
74
|
+
repository: cleanRepository(latest?.repository ?? doc.repository),
|
|
75
|
+
readme: typeof doc.readme === "string" ? doc.readme : "",
|
|
76
|
+
publishedAt: doc.time?.created ?? null,
|
|
77
|
+
modifiedAt: doc.time?.modified ?? (version ? doc.time?.[version] ?? null : null),
|
|
78
|
+
license: licenseOf(latest?.license ?? doc.license),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Every package the org listing returns, including unscoped names the org owns,
|
|
83
|
+
* plus the known unscoped packages for the org.
|
|
84
|
+
* npm search is only the fallback: it drops packages and repeats others.
|
|
85
|
+
*/
|
|
86
|
+
export async function listOrgPackages(org, options = {}) {
|
|
87
|
+
const name = normalizeOrg(org);
|
|
88
|
+
try {
|
|
89
|
+
const listing = await fetchJson(`https://registry.npmjs.org/-/org/${encodeURIComponent(name)}/package`, options);
|
|
90
|
+
if (listing && typeof listing === "object" && !Array.isArray(listing)) {
|
|
91
|
+
const names = Object.keys(listing);
|
|
92
|
+
if (names.length > 0)
|
|
93
|
+
return withUnscoped(name, names);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
if (error instanceof Error && error.name === "FetchBudgetExhausted")
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
return withUnscoped(name, await discoverViaSearch(name, options));
|
|
101
|
+
}
|
|
102
|
+
async function discoverViaSearch(org, options) {
|
|
103
|
+
const prefix = `@${org}/`;
|
|
104
|
+
const names = new Set();
|
|
105
|
+
let offset = 0;
|
|
106
|
+
let total = Infinity;
|
|
107
|
+
while (offset < total && offset <= 10_000) {
|
|
108
|
+
const data = await fetchJson(`https://registry.npmjs.org/-/v1/search?text=${encodeURIComponent(prefix)}&size=${SEARCH_PAGE_SIZE}&from=${offset}`, options);
|
|
109
|
+
total = Number.isFinite(data.total) ? data.total : 0;
|
|
110
|
+
const objects = data.objects ?? [];
|
|
111
|
+
if (objects.length === 0)
|
|
112
|
+
break;
|
|
113
|
+
for (const item of objects) {
|
|
114
|
+
const packageName = item.package?.name;
|
|
115
|
+
if (typeof packageName === "string" && packageName.startsWith(prefix))
|
|
116
|
+
names.add(packageName);
|
|
117
|
+
}
|
|
118
|
+
offset += SEARCH_PAGE_SIZE;
|
|
119
|
+
}
|
|
120
|
+
return [...names].sort();
|
|
121
|
+
}
|
|
122
|
+
const MAINTAINER_PAGE_SIZE = 250;
|
|
123
|
+
const MAINTAINER_PAGE_CAP = 20;
|
|
124
|
+
function blankOrgPackage(name) {
|
|
125
|
+
return { name, version: null, description: "", keywords: [], homepage: null, repository: null, license: null, modifiedAt: null };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Every package the org owns, including unscoped names, with the latest publish
|
|
129
|
+
* time when the maintainer search knows it. Membership comes from the org listing.
|
|
130
|
+
* Search only supplies dates and short metadata, and a search failure still returns the names.
|
|
131
|
+
*/
|
|
132
|
+
export async function listOrgCatalog(org, options = {}) {
|
|
133
|
+
const orgName = normalizeOrg(org);
|
|
134
|
+
let names = [];
|
|
135
|
+
let fromOrgListing = false;
|
|
136
|
+
try {
|
|
137
|
+
const listing = await fetchJson(`https://registry.npmjs.org/-/org/${encodeURIComponent(orgName)}/package`, options);
|
|
138
|
+
if (listing && typeof listing === "object" && !Array.isArray(listing)) {
|
|
139
|
+
names = Object.keys(listing);
|
|
140
|
+
fromOrgListing = names.length > 0;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
if (error instanceof Error && error.name === "FetchBudgetExhausted")
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
147
|
+
names = fromOrgListing ? withUnscoped(orgName, names) : await listOrgPackages(orgName, options);
|
|
148
|
+
const wanted = new Set(names);
|
|
149
|
+
const found = new Map();
|
|
150
|
+
try {
|
|
151
|
+
let offset = 0;
|
|
152
|
+
let total = Infinity;
|
|
153
|
+
for (let page = 0; page < MAINTAINER_PAGE_CAP && offset < total; page++) {
|
|
154
|
+
const data = await fetchJson(`https://registry.npmjs.org/-/v1/search?text=${encodeURIComponent(`maintainer:${orgName}`)}&size=${MAINTAINER_PAGE_SIZE}&from=${offset}`, options);
|
|
155
|
+
total = Number.isFinite(data.total) ? data.total : 0;
|
|
156
|
+
const objects = data.objects ?? [];
|
|
157
|
+
if (objects.length === 0)
|
|
158
|
+
break;
|
|
159
|
+
for (const item of objects) {
|
|
160
|
+
const pkg = item.package;
|
|
161
|
+
if (!pkg?.name || !wanted.has(pkg.name))
|
|
162
|
+
continue;
|
|
163
|
+
found.set(pkg.name, {
|
|
164
|
+
name: pkg.name,
|
|
165
|
+
version: pkg.version ?? null,
|
|
166
|
+
description: (pkg.description ?? "").trim(),
|
|
167
|
+
keywords: strings(pkg.keywords),
|
|
168
|
+
homepage: pkg.links?.homepage ?? null,
|
|
169
|
+
repository: pkg.links?.repository ?? null,
|
|
170
|
+
license: typeof pkg.license === "string" && pkg.license.trim() ? pkg.license.trim() : null,
|
|
171
|
+
modifiedAt: typeof pkg.date === "string" && pkg.date ? pkg.date : null,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
offset += MAINTAINER_PAGE_SIZE;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// Dates are best-effort. The org listing is still the catalog membership.
|
|
179
|
+
}
|
|
180
|
+
return { packages: names.map((name) => found.get(name) ?? blankOrgPackage(name)), fromOrgListing };
|
|
181
|
+
}
|
|
182
|
+
/** Registry search filtered to one scope, used when the catalog service is unreachable. */
|
|
183
|
+
export async function searchPackages(text, options = {}) {
|
|
184
|
+
const scope = options.scope ?? "@x12i/";
|
|
185
|
+
const size = Math.min(250, Math.max(1, options.size ?? 20));
|
|
186
|
+
const query = `${text} ${scope}`.trim();
|
|
187
|
+
const data = await fetchJson(`https://registry.npmjs.org/-/v1/search?text=${encodeURIComponent(query)}&size=${size}`, options);
|
|
188
|
+
const found = [];
|
|
189
|
+
for (const item of data.objects ?? []) {
|
|
190
|
+
const pkg = item.package;
|
|
191
|
+
if (!pkg?.name || !pkg.name.startsWith(scope))
|
|
192
|
+
continue;
|
|
193
|
+
found.push({
|
|
194
|
+
name: pkg.name,
|
|
195
|
+
version: pkg.version ?? null,
|
|
196
|
+
description: (pkg.description ?? "").trim(),
|
|
197
|
+
keywords: strings(pkg.keywords),
|
|
198
|
+
homepage: pkg.links?.homepage ?? null,
|
|
199
|
+
repository: pkg.links?.repository ?? null,
|
|
200
|
+
license: typeof pkg.license === "string" && pkg.license.trim() ? pkg.license.trim() : null,
|
|
201
|
+
readme: "",
|
|
202
|
+
publishedAt: null,
|
|
203
|
+
modifiedAt: null,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
return found;
|
|
207
|
+
}
|
|
208
|
+
/** Full packument summary for one package. */
|
|
209
|
+
export async function getPackage(name, options = {}) {
|
|
210
|
+
const doc = await fetchJson(`https://registry.npmjs.org/${encodeURIComponent(name).replace("%40", "@")}`, options);
|
|
211
|
+
return packageInfo(doc, name);
|
|
212
|
+
}
|
|
213
|
+
/** README plus the description, keywords, version, repository, and homepage from the same packument. */
|
|
214
|
+
export async function getReadme(name, options = {}) {
|
|
215
|
+
return getPackage(name, options);
|
|
216
|
+
}
|
|
217
|
+
/** Download count for the last month. A package npm has not counted yet is 0. */
|
|
218
|
+
export async function getLastMonthDownloads(name, options = {}) {
|
|
219
|
+
try {
|
|
220
|
+
const data = await fetchJson(`https://api.npmjs.org/downloads/point/last-month/${encodeURIComponent(name)}`, options);
|
|
221
|
+
const count = Number(data.downloads);
|
|
222
|
+
return Number.isFinite(count) && count > 0 ? Math.floor(count) : 0;
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
const status = error.status;
|
|
226
|
+
if (status === 404)
|
|
227
|
+
return 0;
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,52 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@x12i/npm-core",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@x12i/npm-core",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "List packages in an npm org and read a package README from the registry.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"npm",
|
|
7
|
+
"registry",
|
|
8
|
+
"npm-org",
|
|
9
|
+
"packument",
|
|
10
|
+
"readme",
|
|
11
|
+
"x12i"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"type": "module",
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=22.18.0"
|
|
18
|
+
},
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+ssh://git@github.com/x12i/x12i-stats.git",
|
|
36
|
+
"directory": "packages/npm-core"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/x12i/x12i-stats/tree/main/packages/npm-core#readme",
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/x12i/x12i-stats/issues"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc -p tsconfig.json",
|
|
44
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
45
|
+
"test": "tsc -p tsconfig.json && node --test test/registry.test.mjs",
|
|
46
|
+
"prepublishOnly": "npm run typecheck && npm test"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/node": "22.19.19",
|
|
50
|
+
"typescript": "5.9.3"
|
|
51
|
+
}
|
|
52
|
+
}
|