@vercel/python-analysis 0.1.1
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 +202 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +107 -0
- package/dist/manifest/package.d.ts +166 -0
- package/dist/manifest/package.js +422 -0
- package/dist/manifest/pep440.d.ts +6 -0
- package/dist/manifest/pep440.js +63 -0
- package/dist/manifest/pep508.d.ts +64 -0
- package/dist/manifest/pep508.js +70 -0
- package/dist/manifest/pipfile/schema.d.ts +40 -0
- package/dist/manifest/pipfile/schema.js +44 -0
- package/dist/manifest/pipfile/schema.zod.d.ts +606 -0
- package/dist/manifest/pipfile/schema.zod.js +97 -0
- package/dist/manifest/pipfile/types.d.ts +77 -0
- package/dist/manifest/pipfile/types.js +16 -0
- package/dist/manifest/pipfile-parser.d.ts +35 -0
- package/dist/manifest/pipfile-parser.js +262 -0
- package/dist/manifest/pyproject/schema.d.ts +50 -0
- package/dist/manifest/pyproject/schema.js +56 -0
- package/dist/manifest/pyproject/schema.zod.d.ts +767 -0
- package/dist/manifest/pyproject/schema.zod.js +94 -0
- package/dist/manifest/pyproject/types.d.ts +93 -0
- package/dist/manifest/pyproject/types.js +16 -0
- package/dist/manifest/python-selector.d.ts +123 -0
- package/dist/manifest/python-selector.js +185 -0
- package/dist/manifest/python-specifiers.d.ts +76 -0
- package/dist/manifest/python-specifiers.js +156 -0
- package/dist/manifest/requirement/schema.d.ts +28 -0
- package/dist/manifest/requirement/schema.js +35 -0
- package/dist/manifest/requirement/schema.zod.d.ts +76 -0
- package/dist/manifest/requirement/schema.zod.js +49 -0
- package/dist/manifest/requirement/types.d.ts +50 -0
- package/dist/manifest/requirement/types.js +16 -0
- package/dist/manifest/requirements-txt-parser.d.ts +55 -0
- package/dist/manifest/requirements-txt-parser.js +400 -0
- package/dist/manifest/uv-config/schema.d.ts +22 -0
- package/dist/manifest/uv-config/schema.js +35 -0
- package/dist/manifest/uv-config/schema.zod.d.ts +140 -0
- package/dist/manifest/uv-config/schema.zod.js +48 -0
- package/dist/manifest/uv-config/types.d.ts +48 -0
- package/dist/manifest/uv-config/types.js +16 -0
- package/dist/manifest/uv-python-version-parser.d.ts +28 -0
- package/dist/manifest/uv-python-version-parser.js +268 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.js +16 -0
- package/dist/util/config.d.ts +20 -0
- package/dist/util/config.js +100 -0
- package/dist/util/error.d.ts +39 -0
- package/dist/util/error.js +54 -0
- package/dist/util/fs.d.ts +25 -0
- package/dist/util/fs.js +75 -0
- package/dist/util/type.d.ts +7 -0
- package/dist/util/type.js +30 -0
- package/package.json +43 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var types_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(types_exports);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Pep440Constraint } from './pep440';
|
|
2
|
+
import type { PythonRequest } from './python-specifiers';
|
|
3
|
+
/**
|
|
4
|
+
* uv supports these request formats in --python and .python-version:
|
|
5
|
+
* - <version> (e.g. 3, 3.12, 3.12.3)
|
|
6
|
+
* - <version-specifier> (e.g. >=3.12,<3.13)
|
|
7
|
+
* - <version><short-variant> (e.g. 3.13t, 3.12.0d)
|
|
8
|
+
* - <version>+<variant> (e.g. 3.13+freethreaded, 3.12.0+debug, 3.14+gil)
|
|
9
|
+
* - <implementation> (e.g. cpython or cp)
|
|
10
|
+
* - <implementation>@<version>
|
|
11
|
+
* - <implementation><version> (e.g. cpython3.12 or cp312)
|
|
12
|
+
* - <implementation><version-specifier> (e.g. cpython>=3.12,<3.13)
|
|
13
|
+
* - <implementation>-<version>-<os>-<arch>-<libc> (e.g. cpython-3.12.3-macos-aarch64-none)
|
|
14
|
+
*
|
|
15
|
+
* plus local interpreter requests, which we obviously cannot support
|
|
16
|
+
* - <executable-path> (e.g. /opt/homebrew/bin/python3)
|
|
17
|
+
* - <executable-name> (e.g. mypython3)
|
|
18
|
+
* - <install-dir> (e.g. /some/environment/)
|
|
19
|
+
*/
|
|
20
|
+
export declare function pythonRequestFromConstraint(constraint: Pep440Constraint[]): PythonRequest;
|
|
21
|
+
/**
|
|
22
|
+
* Parse the contents of a `.python-version` file.
|
|
23
|
+
*/
|
|
24
|
+
export declare function parsePythonVersionFile(content: string): PythonRequest[] | null;
|
|
25
|
+
/**
|
|
26
|
+
* Parse a single uv python request (as in `--python ...` or `.python-version` contents).
|
|
27
|
+
*/
|
|
28
|
+
export declare function parseUvPythonRequest(input: string): PythonRequest | null;
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var uv_python_version_parser_exports = {};
|
|
20
|
+
__export(uv_python_version_parser_exports, {
|
|
21
|
+
parsePythonVersionFile: () => parsePythonVersionFile,
|
|
22
|
+
parseUvPythonRequest: () => parseUvPythonRequest,
|
|
23
|
+
pythonRequestFromConstraint: () => pythonRequestFromConstraint
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(uv_python_version_parser_exports);
|
|
26
|
+
var import_pep440 = require("./pep440");
|
|
27
|
+
var import_python_specifiers = require("./python-specifiers");
|
|
28
|
+
function pythonRequestFromConstraint(constraint) {
|
|
29
|
+
return {
|
|
30
|
+
implementation: "cpython",
|
|
31
|
+
version: {
|
|
32
|
+
constraint,
|
|
33
|
+
variant: "default"
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function parsePythonVersionFile(content) {
|
|
38
|
+
const lines = content.split(/\r?\n/);
|
|
39
|
+
const requests = [];
|
|
40
|
+
for (let i = 0; i < lines.length; i++) {
|
|
41
|
+
const raw = lines[i] ?? "";
|
|
42
|
+
const trimmed = raw.trim();
|
|
43
|
+
if (!trimmed)
|
|
44
|
+
continue;
|
|
45
|
+
if (trimmed.startsWith("#"))
|
|
46
|
+
continue;
|
|
47
|
+
const parsed = parseUvPythonRequest(trimmed);
|
|
48
|
+
if (parsed != null) {
|
|
49
|
+
requests.push(parsed);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (requests.length === 0) {
|
|
53
|
+
return null;
|
|
54
|
+
} else {
|
|
55
|
+
return requests;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function parseUvPythonRequest(input) {
|
|
59
|
+
const raw = input.trim();
|
|
60
|
+
if (!raw) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
const lowercase = raw.toLowerCase();
|
|
64
|
+
if (lowercase === "any" || lowercase === "default") {
|
|
65
|
+
return {};
|
|
66
|
+
}
|
|
67
|
+
for (const [implName, implementation] of Object.entries(
|
|
68
|
+
import_python_specifiers.PythonImplementation.knownNames()
|
|
69
|
+
)) {
|
|
70
|
+
if (lowercase.startsWith(implName)) {
|
|
71
|
+
let rest = lowercase.substring(implName.length);
|
|
72
|
+
if (rest.length === 0) {
|
|
73
|
+
return {
|
|
74
|
+
implementation
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (rest[0] === "@") {
|
|
78
|
+
rest = rest.substring(1);
|
|
79
|
+
}
|
|
80
|
+
const version2 = parseVersionRequest(rest);
|
|
81
|
+
if (version2 != null) {
|
|
82
|
+
return {
|
|
83
|
+
implementation,
|
|
84
|
+
version: version2
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const version = parseVersionRequest(lowercase);
|
|
90
|
+
if (version != null) {
|
|
91
|
+
return {
|
|
92
|
+
implementation: "cpython",
|
|
93
|
+
version
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return tryParsePlatformRequest(lowercase);
|
|
97
|
+
}
|
|
98
|
+
function parseVersionRequest(input) {
|
|
99
|
+
const [version, variant] = parseVariantSuffix(input);
|
|
100
|
+
let parsedVer = (0, import_pep440.parsePep440Version)(version);
|
|
101
|
+
if (parsedVer != null) {
|
|
102
|
+
if (parsedVer.release.length === 1) {
|
|
103
|
+
const converted = splitWheelTagVersion(version);
|
|
104
|
+
if (converted != null) {
|
|
105
|
+
const convertedVer = (0, import_pep440.parsePep440Version)(converted);
|
|
106
|
+
if (convertedVer != null) {
|
|
107
|
+
parsedVer = convertedVer;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
constraint: (0, import_pep440.pep440ConstraintFromVersion)(parsedVer),
|
|
113
|
+
variant
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
const parsedConstr = (0, import_pep440.parsePep440Constraint)(version);
|
|
117
|
+
if (parsedConstr?.length) {
|
|
118
|
+
return {
|
|
119
|
+
constraint: parsedConstr,
|
|
120
|
+
variant
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
function splitWheelTagVersion(version) {
|
|
126
|
+
if (!/^\d+$/.test(version)) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
if (version.length < 2) {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const major = version[0];
|
|
133
|
+
const minorStr = version.substring(1);
|
|
134
|
+
const minor = parseInt(minorStr, 10);
|
|
135
|
+
if (isNaN(minor) || minor > 255) {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
return `${major}.${minor}`;
|
|
139
|
+
}
|
|
140
|
+
function rfindNumericChar(s) {
|
|
141
|
+
for (let i = s.length - 1; i >= 0; i--) {
|
|
142
|
+
const code = s.charCodeAt(i);
|
|
143
|
+
if (code >= 48 && code <= 57)
|
|
144
|
+
return i;
|
|
145
|
+
}
|
|
146
|
+
return -1;
|
|
147
|
+
}
|
|
148
|
+
function parseVariantSuffix(vrs) {
|
|
149
|
+
let pos = rfindNumericChar(vrs);
|
|
150
|
+
if (pos < 0) {
|
|
151
|
+
return [vrs, "default"];
|
|
152
|
+
}
|
|
153
|
+
pos += 1;
|
|
154
|
+
if (pos + 1 > vrs.length) {
|
|
155
|
+
return [vrs, "default"];
|
|
156
|
+
}
|
|
157
|
+
let variant = vrs.substring(pos);
|
|
158
|
+
if (variant[0] === "+") {
|
|
159
|
+
variant = variant.substring(1);
|
|
160
|
+
}
|
|
161
|
+
const prefix = vrs.substring(0, pos);
|
|
162
|
+
return [prefix, import_python_specifiers.PythonVariant.parse(variant)];
|
|
163
|
+
}
|
|
164
|
+
function tryParsePlatformRequest(raw) {
|
|
165
|
+
const parts = raw.split("-");
|
|
166
|
+
let partIdx = 0;
|
|
167
|
+
const state = ["implementation", "version", "os", "arch", "libc", "end"];
|
|
168
|
+
let stateIdx = 0;
|
|
169
|
+
let implementation;
|
|
170
|
+
let version;
|
|
171
|
+
let os;
|
|
172
|
+
let arch;
|
|
173
|
+
let libc;
|
|
174
|
+
let implOrVersionFailed = false;
|
|
175
|
+
for (; ; ) {
|
|
176
|
+
if (partIdx >= parts.length || state[stateIdx] === "end") {
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
const part = parts[partIdx].toLowerCase();
|
|
180
|
+
if (part.length === 0) {
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
switch (state[stateIdx]) {
|
|
184
|
+
case "implementation":
|
|
185
|
+
if (part === "any") {
|
|
186
|
+
partIdx += 1;
|
|
187
|
+
stateIdx += 1;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
implementation = import_python_specifiers.PythonImplementation.parse(part);
|
|
191
|
+
if (import_python_specifiers.PythonImplementation.isUnknown(implementation)) {
|
|
192
|
+
implementation = void 0;
|
|
193
|
+
stateIdx += 1;
|
|
194
|
+
implOrVersionFailed = true;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
stateIdx += 1;
|
|
198
|
+
partIdx += 1;
|
|
199
|
+
break;
|
|
200
|
+
case "version":
|
|
201
|
+
if (part === "any") {
|
|
202
|
+
partIdx += 1;
|
|
203
|
+
stateIdx += 1;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
version = parseVersionRequest(part);
|
|
207
|
+
if (version == null) {
|
|
208
|
+
version = void 0;
|
|
209
|
+
stateIdx += 1;
|
|
210
|
+
implOrVersionFailed = true;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
stateIdx += 1;
|
|
214
|
+
partIdx += 1;
|
|
215
|
+
break;
|
|
216
|
+
case "os":
|
|
217
|
+
if (part === "any") {
|
|
218
|
+
partIdx += 1;
|
|
219
|
+
stateIdx += 1;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
os = part;
|
|
223
|
+
stateIdx += 1;
|
|
224
|
+
partIdx += 1;
|
|
225
|
+
break;
|
|
226
|
+
case "arch":
|
|
227
|
+
if (part === "any") {
|
|
228
|
+
partIdx += 1;
|
|
229
|
+
stateIdx += 1;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
arch = part;
|
|
233
|
+
stateIdx += 1;
|
|
234
|
+
partIdx += 1;
|
|
235
|
+
break;
|
|
236
|
+
case "libc":
|
|
237
|
+
if (part === "any") {
|
|
238
|
+
partIdx += 1;
|
|
239
|
+
stateIdx += 1;
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
libc = part;
|
|
243
|
+
stateIdx += 1;
|
|
244
|
+
partIdx += 1;
|
|
245
|
+
break;
|
|
246
|
+
default:
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (implOrVersionFailed && implementation === void 0 && version === void 0) {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
let platform;
|
|
254
|
+
if (os !== void 0 || arch !== void 0 || libc !== void 0) {
|
|
255
|
+
platform = {
|
|
256
|
+
os,
|
|
257
|
+
arch,
|
|
258
|
+
libc
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
return { implementation, version, platform };
|
|
262
|
+
}
|
|
263
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
264
|
+
0 && (module.exports = {
|
|
265
|
+
parsePythonVersionFile,
|
|
266
|
+
parseUvPythonRequest,
|
|
267
|
+
pythonRequestFromConstraint
|
|
268
|
+
});
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types-only entrypoint for @vercel/python-analysis.
|
|
3
|
+
*
|
|
4
|
+
* Import from this module to avoid pulling in Zod and other runtime dependencies.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* import type { PyProjectToml, UvConfig } from '@vercel/python-analysis/types';
|
|
8
|
+
*
|
|
9
|
+
* @module types
|
|
10
|
+
*/
|
|
11
|
+
export type { License, LicenseObject, Person, PyProjectBuildSystem, PyProjectDependencyGroups, PyProjectProject, PyProjectToml, PyProjectToolSection, Readme, ReadmeObject, } from './manifest/pyproject/types';
|
|
12
|
+
export type { UvConfig, UvConfigWorkspace, UvIndexEntry, } from './manifest/uv-config/types';
|
|
13
|
+
export type { PipfileDependency, PipfileDependencyDetail, PipfileLike, PipfileLockLike, PipfileLockMeta, PipfileSource, } from './manifest/pipfile/types';
|
|
14
|
+
export type { DependencySource, HashDigest, NormalizedRequirement, } from './manifest/requirement/types';
|
|
15
|
+
export type { PythonBuild, PythonConstraint, PythonImplementation, PythonPlatformRequest, PythonRequest, PythonVariant, PythonVersion, PythonVersionRequest, UnknownPythonImplementation, } from './manifest/python-specifiers';
|
|
16
|
+
export type { PythonConfig, PythonConfigs, PythonManifest, PythonManifestOrigin, PythonPackage, PythonVersionConfig, } from './manifest/package';
|
|
17
|
+
export type { PythonSelectionResult } from './manifest/python-selector';
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var types_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(types_exports);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Parse config content and validate it against a zod schema.
|
|
4
|
+
*
|
|
5
|
+
* @param content - Raw file content
|
|
6
|
+
* @param filename - File path (used for error messages and format detection)
|
|
7
|
+
* @param schema - Zod schema to validate against
|
|
8
|
+
* @param filetype - Optional file type override (e.g., '.toml', '.json')
|
|
9
|
+
* @returns Validated and typed config object
|
|
10
|
+
*/
|
|
11
|
+
export declare function parseConfig<T>(content: string, filename: string, schema: z.ZodType<T>, filetype?: string | undefined): T;
|
|
12
|
+
/**
|
|
13
|
+
* Read a config file if it exists and validate it against a zod schema.
|
|
14
|
+
*
|
|
15
|
+
* @param filename - Path to the config file
|
|
16
|
+
* @param schema - Zod schema to validate against
|
|
17
|
+
* @param filetype - Optional file type override (e.g., '.toml', '.json')
|
|
18
|
+
* @returns Validated config object, or null if file doesn't exist
|
|
19
|
+
*/
|
|
20
|
+
export declare function readConfigIfExists<T>(filename: string, schema: z.ZodType<T>, filetype?: string | undefined): Promise<T | null>;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var config_exports = {};
|
|
30
|
+
__export(config_exports, {
|
|
31
|
+
parseConfig: () => parseConfig,
|
|
32
|
+
readConfigIfExists: () => readConfigIfExists
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(config_exports);
|
|
35
|
+
var import_node_path = __toESM(require("node:path"));
|
|
36
|
+
var import_js_yaml = __toESM(require("js-yaml"));
|
|
37
|
+
var import_smol_toml = __toESM(require("smol-toml"));
|
|
38
|
+
var import_fs = require("./fs");
|
|
39
|
+
var import_error = require("./error");
|
|
40
|
+
function parseRawConfig(content, filename, filetype = void 0) {
|
|
41
|
+
if (filetype === void 0) {
|
|
42
|
+
filetype = import_node_path.default.extname(filename.toLowerCase());
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
if (filetype === ".json") {
|
|
46
|
+
return JSON.parse(content);
|
|
47
|
+
} else if (filetype === ".toml") {
|
|
48
|
+
return import_smol_toml.default.parse(content);
|
|
49
|
+
} else if (filetype === ".yaml" || filetype === ".yml") {
|
|
50
|
+
return import_js_yaml.default.load(content, { filename });
|
|
51
|
+
} else {
|
|
52
|
+
throw new import_error.PythonAnalysisError({
|
|
53
|
+
message: `Could not parse config file "${filename}": unrecognized config format`,
|
|
54
|
+
code: "PYTHON_CONFIG_UNKNOWN_FORMAT",
|
|
55
|
+
path: filename
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
} catch (error) {
|
|
59
|
+
if (error instanceof import_error.PythonAnalysisError) {
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
if (error instanceof Error) {
|
|
63
|
+
throw new import_error.PythonAnalysisError({
|
|
64
|
+
message: `Could not parse config file "${filename}": ${error.message}`,
|
|
65
|
+
code: "PYTHON_CONFIG_PARSE_ERROR",
|
|
66
|
+
path: filename
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function parseConfig(content, filename, schema, filetype = void 0) {
|
|
73
|
+
const raw = parseRawConfig(content, filename, filetype);
|
|
74
|
+
const result = schema.safeParse(raw);
|
|
75
|
+
if (!result.success) {
|
|
76
|
+
const issues = result.error.issues.map((issue) => {
|
|
77
|
+
const path2 = issue.path.length > 0 ? issue.path.join(".") : "(root)";
|
|
78
|
+
return ` - ${path2}: ${issue.message}`;
|
|
79
|
+
}).join("\n");
|
|
80
|
+
throw new import_error.PythonAnalysisError({
|
|
81
|
+
message: `Invalid config in "${filename}":
|
|
82
|
+
${issues}`,
|
|
83
|
+
code: "PYTHON_CONFIG_VALIDATION_ERROR",
|
|
84
|
+
path: filename
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return result.data;
|
|
88
|
+
}
|
|
89
|
+
async function readConfigIfExists(filename, schema, filetype = void 0) {
|
|
90
|
+
const content = await (0, import_fs.readFileTextIfExists)(filename);
|
|
91
|
+
if (content == null) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
return parseConfig(content, filename, schema, filetype);
|
|
95
|
+
}
|
|
96
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
97
|
+
0 && (module.exports = {
|
|
98
|
+
parseConfig,
|
|
99
|
+
readConfigIfExists
|
|
100
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare const isErrnoException: (error: unknown, code?: string | undefined) => error is NodeJS.ErrnoException;
|
|
2
|
+
interface PythonAnalysisErrorProps {
|
|
3
|
+
/**
|
|
4
|
+
* The error message to display to the end-user.
|
|
5
|
+
* Should be short yet descriptive of what went wrong.
|
|
6
|
+
*/
|
|
7
|
+
message: string;
|
|
8
|
+
/**
|
|
9
|
+
* A unique error code for this particular error.
|
|
10
|
+
* Should start with `PYTHON_` prefix.
|
|
11
|
+
*/
|
|
12
|
+
code: string;
|
|
13
|
+
/**
|
|
14
|
+
* The path to the file that caused the error, if applicable.
|
|
15
|
+
*/
|
|
16
|
+
path?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Optional hyperlink to documentation with more information about this error.
|
|
19
|
+
*/
|
|
20
|
+
link?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Optional "action" to display before the `link`, such as "Learn More".
|
|
23
|
+
*/
|
|
24
|
+
action?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* This error should be thrown from Python analysis functions
|
|
28
|
+
* when encountering configuration or manifest parsing errors.
|
|
29
|
+
* This is necessary to provide clear error messages without stack traces.
|
|
30
|
+
*/
|
|
31
|
+
export declare class PythonAnalysisError extends Error {
|
|
32
|
+
hideStackTrace: boolean;
|
|
33
|
+
code: string;
|
|
34
|
+
path?: string;
|
|
35
|
+
link?: string;
|
|
36
|
+
action?: string;
|
|
37
|
+
constructor({ message, code, path, link, action }: PythonAnalysisErrorProps);
|
|
38
|
+
}
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var error_exports = {};
|
|
30
|
+
__export(error_exports, {
|
|
31
|
+
PythonAnalysisError: () => PythonAnalysisError,
|
|
32
|
+
isErrnoException: () => isErrnoException
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(error_exports);
|
|
35
|
+
var import_node_util = __toESM(require("node:util"));
|
|
36
|
+
const isErrnoException = (error, code = void 0) => {
|
|
37
|
+
return import_node_util.default.types.isNativeError(error) && "code" in error && (code === void 0 || error.code === code);
|
|
38
|
+
};
|
|
39
|
+
class PythonAnalysisError extends Error {
|
|
40
|
+
constructor({ message, code, path, link, action }) {
|
|
41
|
+
super(message);
|
|
42
|
+
this.hideStackTrace = true;
|
|
43
|
+
this.name = "PythonAnalysisError";
|
|
44
|
+
this.code = code;
|
|
45
|
+
this.path = path;
|
|
46
|
+
this.link = link;
|
|
47
|
+
this.action = action;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
51
|
+
0 && (module.exports = {
|
|
52
|
+
PythonAnalysisError,
|
|
53
|
+
isErrnoException
|
|
54
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/** Absolute filesystem path. */
|
|
3
|
+
export type AbsPath = string;
|
|
4
|
+
/** Relative filesystem path. */
|
|
5
|
+
export type RelPath = string;
|
|
6
|
+
/** Any filesystem path */
|
|
7
|
+
export type Path = AbsPath | RelPath;
|
|
8
|
+
export declare function readFileIfExists(file: Path): Promise<Buffer | null>;
|
|
9
|
+
export declare function readFileTextIfExists(file: Path, encoding?: BufferEncoding): Promise<string | null>;
|
|
10
|
+
export declare function normalizePath(p: Path): AbsPath;
|
|
11
|
+
/**
|
|
12
|
+
* Check if a path is at or below a parent path in the directory tree.
|
|
13
|
+
*
|
|
14
|
+
* @param somePath - The path to check
|
|
15
|
+
* @param parentPath - The potential parent/ancestor path
|
|
16
|
+
* @returns True if `somePath` is equal to `parentPath` or is a subdirectory
|
|
17
|
+
* of `parentPath`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* isSubpath('/a/b/c', '/a/b') // true - c is under b
|
|
21
|
+
* isSubpath('/a/b', '/a/b') // true - same path
|
|
22
|
+
* isSubpath('/a/b', '/a/b/c') // false - b is above c
|
|
23
|
+
* isSubpath('/a/x', '/a/b') // false - x is not under b
|
|
24
|
+
*/
|
|
25
|
+
export declare function isSubpath(somePath: Path, parentPath: Path): boolean;
|
package/dist/util/fs.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var fs_exports = {};
|
|
30
|
+
__export(fs_exports, {
|
|
31
|
+
isSubpath: () => isSubpath,
|
|
32
|
+
normalizePath: () => normalizePath,
|
|
33
|
+
readFileIfExists: () => readFileIfExists,
|
|
34
|
+
readFileTextIfExists: () => readFileTextIfExists
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(fs_exports);
|
|
37
|
+
var import_node_path = __toESM(require("node:path"));
|
|
38
|
+
var import_fs_extra = require("fs-extra");
|
|
39
|
+
var import_error = require("./error");
|
|
40
|
+
async function readFileIfExists(file) {
|
|
41
|
+
try {
|
|
42
|
+
return await (0, import_fs_extra.readFile)(file);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (!(0, import_error.isErrnoException)(error, "ENOENT")) {
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
async function readFileTextIfExists(file, encoding = "utf8") {
|
|
51
|
+
const data = await readFileIfExists(file);
|
|
52
|
+
if (data == null) {
|
|
53
|
+
return null;
|
|
54
|
+
} else {
|
|
55
|
+
return data.toString(encoding);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function normalizePath(p) {
|
|
59
|
+
let np = import_node_path.default.normalize(p);
|
|
60
|
+
if (np.endsWith(import_node_path.default.sep)) {
|
|
61
|
+
np = np.slice(0, -1);
|
|
62
|
+
}
|
|
63
|
+
return np;
|
|
64
|
+
}
|
|
65
|
+
function isSubpath(somePath, parentPath) {
|
|
66
|
+
const rel = import_node_path.default.relative(parentPath, somePath);
|
|
67
|
+
return rel === "" || !rel.startsWith("..") && !import_node_path.default.isAbsolute(rel);
|
|
68
|
+
}
|
|
69
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
70
|
+
0 && (module.exports = {
|
|
71
|
+
isSubpath,
|
|
72
|
+
normalizePath,
|
|
73
|
+
readFileIfExists,
|
|
74
|
+
readFileTextIfExists
|
|
75
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type guard to check if a value is a plain object (not null, array, or primitive).
|
|
3
|
+
*
|
|
4
|
+
* @param value - Value to check
|
|
5
|
+
* @returns True if value is a plain object
|
|
6
|
+
*/
|
|
7
|
+
export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|