npmeta 0.0.0 → 0.1.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 +21 -0
- package/dist/index.d.mts +60 -0
- package/dist/index.mjs +174 -0
- package/package.json +36 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Roman A
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
type ModuleFormat = "esm" | "cjs" | "dual" | "wasm" | "binary" | "empty" | "unknown";
|
|
2
|
+
/**
|
|
3
|
+
* Extended package.json fields
|
|
4
|
+
*/
|
|
5
|
+
interface ExtendedPackageJson {
|
|
6
|
+
name?: string;
|
|
7
|
+
version?: string;
|
|
8
|
+
type?: "module" | "commonjs";
|
|
9
|
+
main?: string;
|
|
10
|
+
module?: string;
|
|
11
|
+
types?: string;
|
|
12
|
+
typings?: string;
|
|
13
|
+
exports?: PackageExports;
|
|
14
|
+
bin?: string | Record<string, string>;
|
|
15
|
+
engines?: Record<string, string>;
|
|
16
|
+
dependencies?: Record<string, string>;
|
|
17
|
+
devDependencies?: Record<string, string>;
|
|
18
|
+
peerDependencies?: Record<string, string>;
|
|
19
|
+
}
|
|
20
|
+
type PackageExports = string | null | {
|
|
21
|
+
[key: string]: PackageExports;
|
|
22
|
+
} | PackageExports[];
|
|
23
|
+
/**
|
|
24
|
+
* Detect the module format of a package based on package.json fields
|
|
25
|
+
*/
|
|
26
|
+
declare function detectModuleFormat(pkg: ExtendedPackageJson): ModuleFormat;
|
|
27
|
+
declare function hasBuiltInTypes(pkg: ExtendedPackageJson): boolean;
|
|
28
|
+
interface PackageMetadata {
|
|
29
|
+
name: string;
|
|
30
|
+
bin?: string | Record<string, string>;
|
|
31
|
+
main?: string;
|
|
32
|
+
module?: unknown;
|
|
33
|
+
exports?: unknown;
|
|
34
|
+
}
|
|
35
|
+
declare function isBinaryOnlyPackage(pkg: PackageMetadata): boolean;
|
|
36
|
+
declare function isCreatePackage(packageName: string): boolean;
|
|
37
|
+
declare function getCreatePackageName(packageName: string): string;
|
|
38
|
+
declare function getCreateShortName(createPackageName: string): string;
|
|
39
|
+
/** Parsed result of an npm dependency version value */
|
|
40
|
+
interface ParsedDependencyVersion {
|
|
41
|
+
/** The real package name (different from the dependency key only for aliases) */
|
|
42
|
+
name: string | null;
|
|
43
|
+
/** The semver range or version, null for non-resolvable values (file:, git, etc.) */
|
|
44
|
+
range: string | null;
|
|
45
|
+
}
|
|
46
|
+
declare function parseDependencyVersion(value: string): ParsedDependencyVersion;
|
|
47
|
+
declare function normalizeLicense(license?: string | {
|
|
48
|
+
type: string;
|
|
49
|
+
}): string | undefined;
|
|
50
|
+
declare function splitPackageName(packageName: string): {
|
|
51
|
+
org: string;
|
|
52
|
+
name: string;
|
|
53
|
+
};
|
|
54
|
+
declare function getTypesPackageName(packageName: string): string;
|
|
55
|
+
declare function encodePackageName(name: string): string;
|
|
56
|
+
declare function parsePackageSpec(input: string): {
|
|
57
|
+
name: string;
|
|
58
|
+
version?: string;
|
|
59
|
+
};
|
|
60
|
+
export { detectModuleFormat, encodePackageName, getCreatePackageName, getCreateShortName, getTypesPackageName, hasBuiltInTypes, isBinaryOnlyPackage, isCreatePackage, normalizeLicense, parseDependencyVersion, parsePackageSpec, splitPackageName };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// src/create-package.ts
|
|
2
|
+
function isCreatePackage(packageName) {
|
|
3
|
+
return (packageName.startsWith("@") ? packageName.split("/")[1] : packageName)?.startsWith("create-") || packageName.includes("/create-") || false;
|
|
4
|
+
}
|
|
5
|
+
function getCreatePackageName(packageName) {
|
|
6
|
+
if (!packageName.startsWith("@")) return `create-${packageName}`;
|
|
7
|
+
const slashIndex = packageName.indexOf("/");
|
|
8
|
+
return `${packageName.slice(0, slashIndex)}/create-${packageName.slice(slashIndex + 1)}`;
|
|
9
|
+
}
|
|
10
|
+
function getCreateShortName(createPackageName) {
|
|
11
|
+
if (createPackageName.startsWith("create-")) return createPackageName.slice(7);
|
|
12
|
+
if (!createPackageName.startsWith("@")) return createPackageName;
|
|
13
|
+
const slashIndex = createPackageName.indexOf("/");
|
|
14
|
+
const scope = createPackageName.slice(0, slashIndex);
|
|
15
|
+
const name = createPackageName.slice(slashIndex + 1);
|
|
16
|
+
if (name === "create") return scope;
|
|
17
|
+
if (name.startsWith("create-")) return `${scope}/${name.slice(7)}`;
|
|
18
|
+
return createPackageName;
|
|
19
|
+
}
|
|
20
|
+
// src/binary-detection.ts
|
|
21
|
+
function hasBin(pkg) {
|
|
22
|
+
return pkg.bin != null && (typeof pkg.bin === "string" || Object.keys(pkg.bin).length > 0);
|
|
23
|
+
}
|
|
24
|
+
function isBinaryOnlyPackage(pkg) {
|
|
25
|
+
if (isCreatePackage(pkg.name)) return true;
|
|
26
|
+
const hasEntryPoint = !!pkg.main || !!pkg.module || pkg.exports != null;
|
|
27
|
+
return hasBin(pkg) && !hasEntryPoint;
|
|
28
|
+
}
|
|
29
|
+
// src/analysis.ts
|
|
30
|
+
function analyzeExports(exports, isTypeModule, depth = 0) {
|
|
31
|
+
const result = {
|
|
32
|
+
hasImport: false,
|
|
33
|
+
hasRequire: false,
|
|
34
|
+
hasModule: false,
|
|
35
|
+
hasTypes: false
|
|
36
|
+
};
|
|
37
|
+
if (depth > 10) return result;
|
|
38
|
+
if (exports == null) return result;
|
|
39
|
+
if (typeof exports === "string") {
|
|
40
|
+
if (exports === "./package.json") return result;
|
|
41
|
+
if (exports.endsWith(".mjs") || exports.endsWith(".mts") || exports.endsWith(".json")) result.hasImport = true;
|
|
42
|
+
else if (exports.endsWith(".cjs") || exports.endsWith(".cts")) result.hasRequire = true;
|
|
43
|
+
else if (exports.endsWith(".js")) {
|
|
44
|
+
if (isTypeModule) result.hasImport = true;
|
|
45
|
+
else result.hasRequire = true;
|
|
46
|
+
}
|
|
47
|
+
if (exports.endsWith(".d.ts") || exports.endsWith(".d.mts") || exports.endsWith(".d.cts")) result.hasTypes = true;
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
if (Array.isArray(exports)) {
|
|
51
|
+
for (const item of exports) mergeExportsAnalysis(result, analyzeExports(item, isTypeModule, depth + 1));
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
if (typeof exports === "object") for (const [key, value] of Object.entries(exports)) {
|
|
55
|
+
if (key === "import") result.hasImport = true;
|
|
56
|
+
else if (key === "require") result.hasRequire = true;
|
|
57
|
+
else if (key === "module") result.hasModule = true;
|
|
58
|
+
else if (key === "types") result.hasTypes = true;
|
|
59
|
+
mergeExportsAnalysis(result, analyzeExports(value, isTypeModule, depth + 1));
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
function mergeExportsAnalysis(target, source) {
|
|
64
|
+
target.hasImport ||= source.hasImport;
|
|
65
|
+
target.hasRequire ||= source.hasRequire;
|
|
66
|
+
target.hasModule ||= source.hasModule;
|
|
67
|
+
target.hasTypes ||= source.hasTypes;
|
|
68
|
+
}
|
|
69
|
+
function detectModuleFormat(pkg) {
|
|
70
|
+
const hasExports = pkg.exports != null;
|
|
71
|
+
const hasModule = !!pkg.module;
|
|
72
|
+
const hasMain = !!pkg.main;
|
|
73
|
+
if (!hasExports && !hasModule && !hasMain) {
|
|
74
|
+
if (hasBin(pkg)) return "binary";
|
|
75
|
+
return "empty";
|
|
76
|
+
}
|
|
77
|
+
const isTypeModule = pkg.type === "module";
|
|
78
|
+
const isTypeCommonjs = pkg.type === "commonjs" || !pkg.type;
|
|
79
|
+
if (hasExports && pkg.exports) {
|
|
80
|
+
const exportInfo = analyzeExports(pkg.exports, isTypeModule);
|
|
81
|
+
if (exportInfo.hasImport && exportInfo.hasRequire) return "dual";
|
|
82
|
+
if (exportInfo.hasImport || exportInfo.hasModule) {
|
|
83
|
+
if (hasMain && !isTypeModule) return "dual";
|
|
84
|
+
return "esm";
|
|
85
|
+
}
|
|
86
|
+
if (exportInfo.hasRequire) {
|
|
87
|
+
if (hasModule) return "dual";
|
|
88
|
+
return "cjs";
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (hasModule && hasMain) return pkg.main?.endsWith(".cjs") || pkg.main?.endsWith(".js") && !isTypeModule ? "dual" : "esm";
|
|
92
|
+
if (pkg.main?.endsWith(".wasm")) return "wasm";
|
|
93
|
+
if (hasModule || isTypeModule) return "esm";
|
|
94
|
+
if (hasMain || isTypeCommonjs) return "cjs";
|
|
95
|
+
return "unknown";
|
|
96
|
+
}
|
|
97
|
+
function hasBuiltInTypes(pkg) {
|
|
98
|
+
if (pkg.types || pkg.typings) return true;
|
|
99
|
+
if (pkg.exports) {
|
|
100
|
+
if (analyzeExports(pkg.exports, pkg.type === "module").hasTypes) return true;
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
// src/dependency-version.ts
|
|
105
|
+
const GIT_REFERENCE_RE = /^(?:git(?:\+(?:ssh|https?|file))?:|github:)/;
|
|
106
|
+
const HTTP_REFERENCE_RE = /^https?:\/\//;
|
|
107
|
+
function isNonSemverConstraint(constraint) {
|
|
108
|
+
return GIT_REFERENCE_RE.test(constraint) || HTTP_REFERENCE_RE.test(constraint) || constraint.startsWith("file:") || constraint.startsWith("link:") || constraint.startsWith("workspace:") || constraint.includes("/");
|
|
109
|
+
}
|
|
110
|
+
function parseDependencyVersion(value) {
|
|
111
|
+
if (value.startsWith("npm:")) {
|
|
112
|
+
const aliasBody = value.slice(4);
|
|
113
|
+
if (aliasBody.startsWith("@")) {
|
|
114
|
+
const secondAt = aliasBody.indexOf("@", 1);
|
|
115
|
+
if (secondAt !== -1) return {
|
|
116
|
+
name: aliasBody.slice(0, secondAt),
|
|
117
|
+
range: aliasBody.slice(secondAt + 1)
|
|
118
|
+
};
|
|
119
|
+
return {
|
|
120
|
+
name: aliasBody,
|
|
121
|
+
range: null
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
const atIndex = aliasBody.indexOf("@");
|
|
125
|
+
if (atIndex !== -1) return {
|
|
126
|
+
name: aliasBody.slice(0, atIndex),
|
|
127
|
+
range: aliasBody.slice(atIndex + 1)
|
|
128
|
+
};
|
|
129
|
+
return {
|
|
130
|
+
name: aliasBody,
|
|
131
|
+
range: null
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
if (isNonSemverConstraint(value)) return {
|
|
135
|
+
name: null,
|
|
136
|
+
range: null
|
|
137
|
+
};
|
|
138
|
+
return {
|
|
139
|
+
name: null,
|
|
140
|
+
range: value
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// src/normalize.ts
|
|
144
|
+
function normalizeLicense(license) {
|
|
145
|
+
if (!license) return void 0;
|
|
146
|
+
if (typeof license === "string") return license;
|
|
147
|
+
if (typeof license.type === "string") return license.type;
|
|
148
|
+
}
|
|
149
|
+
// src/package-name.ts
|
|
150
|
+
function splitPackageName(packageName) {
|
|
151
|
+
const [org = "", name = ""] = packageName.startsWith("@") ? packageName.split("/") : ["", packageName];
|
|
152
|
+
return {
|
|
153
|
+
org,
|
|
154
|
+
name
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function getTypesPackageName(packageName) {
|
|
158
|
+
if (packageName.startsWith("@")) return `@types/${packageName.slice(1).replace("/", "__")}`;
|
|
159
|
+
return `@types/${packageName}`;
|
|
160
|
+
}
|
|
161
|
+
function encodePackageName(name) {
|
|
162
|
+
return name.replace("/", "%2F");
|
|
163
|
+
}
|
|
164
|
+
// src/package-spec.ts
|
|
165
|
+
function parsePackageSpec(input) {
|
|
166
|
+
const trimmedInput = input.trim();
|
|
167
|
+
const atPos = trimmedInput.lastIndexOf("@");
|
|
168
|
+
if (atPos <= 0) return { name: trimmedInput };
|
|
169
|
+
return {
|
|
170
|
+
name: trimmedInput.slice(0, atPos).trim(),
|
|
171
|
+
version: trimmedInput.slice(atPos + 1).trim()
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
export { detectModuleFormat, encodePackageName, getCreatePackageName, getCreateShortName, getTypesPackageName, hasBuiltInTypes, isBinaryOnlyPackage, isCreatePackage, normalizeLicense, parseDependencyVersion, parsePackageSpec, splitPackageName };
|
package/package.json
CHANGED
|
@@ -1,4 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "npmeta",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"author": "gameroman",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/gameroman-npm/npmeta.git"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"type": "module",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": "./dist/index.mjs",
|
|
16
|
+
"./package.json": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"u": "bun --sequential format build test:bun test",
|
|
20
|
+
"test": "node --test",
|
|
21
|
+
"test:bun": "bun test --dots",
|
|
22
|
+
"lint": "oxlint",
|
|
23
|
+
"format": "oxfmt",
|
|
24
|
+
"build": "tsdown",
|
|
25
|
+
"prepublishOnly": "bun run build"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@gameroman/config": "0.3.0",
|
|
29
|
+
"@types/node": "26.6.6",
|
|
30
|
+
"oxfmt": "0.75.0",
|
|
31
|
+
"oxlint": "1.90.0",
|
|
32
|
+
"oxlint-tsgolint": "7.0.2005",
|
|
33
|
+
"tsdown": "0.23.3",
|
|
34
|
+
"typescript": "7.0.2"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=22"
|
|
38
|
+
}
|
|
4
39
|
}
|