metascope 0.1.0 → 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/dist/.DS_Store +0 -0
- package/dist/bin/cli.js +14 -14
- package/dist/lib/{chunk-DrSxFLj_.js → _virtual/_rolldown/runtime.js} +1 -1
- package/dist/lib/file-matching.js +152 -0
- package/dist/lib/index.d.ts +11 -1496
- package/dist/lib/index.js +6 -6215
- package/dist/lib/log.d.ts +11 -0
- package/dist/lib/log.js +20 -0
- package/dist/lib/metadata-types.d.ts +151 -0
- package/dist/lib/metadata-types.js +30 -0
- package/dist/lib/metadata.d.ts +16 -0
- package/dist/lib/metadata.js +235 -0
- package/dist/lib/package.js +5 -0
- package/dist/lib/parsers/configparser-parser.js +43 -0
- package/dist/lib/parsers/gemspec-parser.js +256 -0
- package/dist/lib/parsers/go-mod-parser.js +153 -0
- package/dist/lib/parsers/makefile-config-parser.js +102 -0
- package/dist/lib/parsers/properties-parser.js +31 -0
- package/dist/lib/parsers/rfc822-header-parser.js +48 -0
- package/dist/lib/parsers/setup-py-parser.js +173 -0
- package/dist/lib/source.d.ts +17 -0
- package/dist/lib/source.js +34 -0
- package/dist/lib/sources/arduino-library-properties.d.ts +45 -0
- package/dist/lib/sources/arduino-library-properties.js +208 -0
- package/dist/lib/sources/cinder-cinderblock-xml.d.ts +21 -0
- package/dist/lib/sources/cinder-cinderblock-xml.js +134 -0
- package/dist/lib/sources/code-stats.d.ts +14 -0
- package/dist/lib/sources/code-stats.js +40 -0
- package/dist/lib/sources/codemeta-json.d.ts +117 -0
- package/dist/lib/sources/codemeta-json.js +226 -0
- package/dist/lib/sources/dependency-updates.d.ts +22 -0
- package/dist/lib/sources/dependency-updates.js +132 -0
- package/dist/lib/sources/file-stats.d.ts +12 -0
- package/dist/lib/sources/file-stats.js +48 -0
- package/dist/lib/sources/git-config.d.ts +8 -0
- package/dist/lib/sources/git-config.js +21 -0
- package/dist/lib/sources/git-stats.d.ts +35 -0
- package/dist/lib/sources/git-stats.js +130 -0
- package/dist/lib/sources/github.d.ts +94 -0
- package/dist/lib/sources/github.js +399 -0
- package/dist/lib/sources/go-go-mod.d.ts +19 -0
- package/dist/lib/sources/go-go-mod.js +38 -0
- package/dist/lib/sources/go-goreleaser-yaml.d.ts +19 -0
- package/dist/lib/sources/go-goreleaser-yaml.js +152 -0
- package/dist/lib/sources/java-pom-xml.d.ts +52 -0
- package/dist/lib/sources/java-pom-xml.js +248 -0
- package/dist/lib/sources/license-file.d.ts +10 -0
- package/dist/lib/sources/license-file.js +26 -0
- package/dist/lib/sources/metadata-file.d.ts +14 -0
- package/dist/lib/sources/metadata-file.js +109 -0
- package/dist/lib/sources/metascope.d.ts +14 -0
- package/dist/lib/sources/metascope.js +35 -0
- package/dist/lib/sources/node-npm-registry.d.ts +19 -0
- package/dist/lib/sources/node-npm-registry.js +74 -0
- package/dist/lib/sources/node-package-json.d.ts +7 -0
- package/dist/lib/sources/node-package-json.js +27 -0
- package/dist/lib/sources/obsidian-plugin-manifest-json.d.ts +17 -0
- package/dist/lib/sources/obsidian-plugin-manifest-json.js +34 -0
- package/dist/lib/sources/obsidian-plugin-registry.d.ts +10 -0
- package/dist/lib/sources/obsidian-plugin-registry.js +44 -0
- package/dist/lib/sources/openframeworks-addon-config-mk.d.ts +17 -0
- package/dist/lib/sources/openframeworks-addon-config-mk.js +39 -0
- package/dist/lib/sources/openframeworks-install-xml.d.ts +20 -0
- package/dist/lib/sources/openframeworks-install-xml.js +153 -0
- package/dist/lib/sources/processing-library-properties.d.ts +44 -0
- package/dist/lib/sources/processing-library-properties.js +219 -0
- package/dist/lib/sources/processing-sketch-properties.d.ts +38 -0
- package/dist/lib/sources/processing-sketch-properties.js +185 -0
- package/dist/lib/sources/publiccode-yaml.d.ts +73 -0
- package/dist/lib/sources/publiccode-yaml.js +256 -0
- package/dist/lib/sources/python-pkg-info.d.ts +31 -0
- package/dist/lib/sources/python-pkg-info.js +115 -0
- package/dist/lib/sources/python-pypi-registry.d.ts +19 -0
- package/dist/lib/sources/python-pypi-registry.js +101 -0
- package/dist/lib/sources/python-pyproject-toml.d.ts +7 -0
- package/dist/lib/sources/python-pyproject-toml.js +30 -0
- package/dist/lib/sources/python-setup-cfg.d.ts +28 -0
- package/dist/lib/sources/python-setup-cfg.js +106 -0
- package/dist/lib/sources/python-setup-py.d.ts +28 -0
- package/dist/lib/sources/python-setup-py.js +48 -0
- package/dist/lib/sources/readme-file.d.ts +11 -0
- package/dist/lib/sources/readme-file.js +55 -0
- package/dist/lib/sources/ruby-gemspec.d.ts +44 -0
- package/dist/lib/sources/ruby-gemspec.js +62 -0
- package/dist/lib/sources/rust-cargo-toml.d.ts +40 -0
- package/dist/lib/sources/rust-cargo-toml.js +159 -0
- package/dist/lib/sources/xcode-info-plist.d.ts +22 -0
- package/dist/lib/sources/xcode-info-plist.js +199 -0
- package/dist/lib/sources/xcode-project-pbxproj.d.ts +21 -0
- package/dist/lib/sources/xcode-project-pbxproj.js +222 -0
- package/dist/lib/templates/codemeta.d.ts +47 -0
- package/dist/lib/templates/codemeta.js +494 -0
- package/dist/lib/templates/frontmatter.d.ts +87 -0
- package/dist/lib/templates/frontmatter.js +111 -0
- package/dist/lib/templates/index.d.ts +181 -0
- package/dist/lib/templates/index.js +22 -0
- package/dist/lib/templates/metadata.d.ts +17 -0
- package/dist/lib/templates/metadata.js +35 -0
- package/dist/lib/templates/project.d.ts +39 -0
- package/dist/lib/templates/project.js +51 -0
- package/dist/lib/utilities/codemeta-helpers.d.ts +39 -0
- package/dist/lib/utilities/codemeta-helpers.js +83 -0
- package/dist/lib/utilities/fetch.js +43 -0
- package/dist/lib/utilities/formatting.js +28 -0
- package/dist/lib/utilities/license-identification.js +141 -0
- package/dist/lib/utilities/schema-primitives.js +47 -0
- package/dist/lib/utilities/template-helpers.d.ts +135 -0
- package/dist/lib/utilities/template-helpers.js +310 -0
- package/dist/lib/utilities/tree-sitter-wasm.js +30 -0
- package/package.json +6 -6
- package/readme.md +62 -15
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { getMatches } from "../file-matching.js";
|
|
2
|
+
import { defineSource } from "../source.js";
|
|
3
|
+
import { nonEmptyString, optionalUrl, stringArray } from "../utilities/schema-primitives.js";
|
|
4
|
+
import { splitCommaSeparated } from "../utilities/template-helpers.js";
|
|
5
|
+
import { parseConfigparser, splitMultiline } from "../parsers/configparser-parser.js";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
//#region src/lib/sources/python-setup-cfg.ts
|
|
10
|
+
const setupCfgDataSchema = z.object({
|
|
11
|
+
author: nonEmptyString,
|
|
12
|
+
author_email: nonEmptyString,
|
|
13
|
+
classifiers: stringArray,
|
|
14
|
+
description: nonEmptyString,
|
|
15
|
+
download_url: optionalUrl,
|
|
16
|
+
extras_require: z.record(z.string(), z.array(z.string())),
|
|
17
|
+
install_requires: stringArray,
|
|
18
|
+
keywords: z.array(z.string()).optional(),
|
|
19
|
+
license: nonEmptyString,
|
|
20
|
+
long_description: nonEmptyString,
|
|
21
|
+
maintainer: nonEmptyString,
|
|
22
|
+
maintainer_email: nonEmptyString,
|
|
23
|
+
name: nonEmptyString,
|
|
24
|
+
project_urls: z.record(z.string(), z.string()),
|
|
25
|
+
python_requires: nonEmptyString,
|
|
26
|
+
url: optionalUrl,
|
|
27
|
+
version: nonEmptyString
|
|
28
|
+
});
|
|
29
|
+
/** Simple string attributes to extract from [metadata]. */
|
|
30
|
+
const STRING_ATTRS = new Set([
|
|
31
|
+
"author",
|
|
32
|
+
"author_email",
|
|
33
|
+
"description",
|
|
34
|
+
"download_url",
|
|
35
|
+
"license",
|
|
36
|
+
"long_description",
|
|
37
|
+
"maintainer",
|
|
38
|
+
"maintainer_email",
|
|
39
|
+
"name",
|
|
40
|
+
"url",
|
|
41
|
+
"version"
|
|
42
|
+
]);
|
|
43
|
+
/**
|
|
44
|
+
* Parse a setup.cfg file and return structured metadata.
|
|
45
|
+
*
|
|
46
|
+
* Extracts fields from the `[metadata]` and `[options]` sections,
|
|
47
|
+
* including multi-line values like classifiers and install_requires.
|
|
48
|
+
*/
|
|
49
|
+
function parse(source) {
|
|
50
|
+
const sections = parseConfigparser(source);
|
|
51
|
+
const metadata = sections.metadata ?? {};
|
|
52
|
+
const options = sections.options ?? {};
|
|
53
|
+
const data = {
|
|
54
|
+
author: void 0,
|
|
55
|
+
author_email: void 0,
|
|
56
|
+
classifiers: [],
|
|
57
|
+
description: void 0,
|
|
58
|
+
download_url: void 0,
|
|
59
|
+
extras_require: {},
|
|
60
|
+
install_requires: [],
|
|
61
|
+
keywords: void 0,
|
|
62
|
+
license: void 0,
|
|
63
|
+
long_description: void 0,
|
|
64
|
+
maintainer: void 0,
|
|
65
|
+
maintainer_email: void 0,
|
|
66
|
+
name: void 0,
|
|
67
|
+
project_urls: {},
|
|
68
|
+
python_requires: void 0,
|
|
69
|
+
url: void 0,
|
|
70
|
+
version: void 0
|
|
71
|
+
};
|
|
72
|
+
for (const key of STRING_ATTRS) {
|
|
73
|
+
const value = metadata[key];
|
|
74
|
+
if (value) Object.assign(data, { [key]: value });
|
|
75
|
+
}
|
|
76
|
+
if (metadata.classifiers) data.classifiers = splitMultiline(metadata.classifiers);
|
|
77
|
+
if (metadata.keywords) data.keywords = splitCommaSeparated(metadata.keywords);
|
|
78
|
+
if (metadata.project_urls) for (const line of splitMultiline(metadata.project_urls)) {
|
|
79
|
+
const eqIndex = line.indexOf("=");
|
|
80
|
+
if (eqIndex > 0) {
|
|
81
|
+
const label = line.slice(0, eqIndex).trim();
|
|
82
|
+
const url = line.slice(eqIndex + 1).trim();
|
|
83
|
+
if (url) data.project_urls[label] = url;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (options.install_requires) data.install_requires = splitMultiline(options.install_requires);
|
|
87
|
+
if (options.python_requires) data.python_requires = options.python_requires;
|
|
88
|
+
const extrasSection = sections["options.extras_require"];
|
|
89
|
+
if (extrasSection) for (const [key, value] of Object.entries(extrasSection)) data.extras_require[key] = splitMultiline(value);
|
|
90
|
+
return setupCfgDataSchema.parse(data);
|
|
91
|
+
}
|
|
92
|
+
const pythonSetupCfgSource = defineSource({
|
|
93
|
+
async discover(context) {
|
|
94
|
+
return getMatches(context.options, ["setup.cfg"]);
|
|
95
|
+
},
|
|
96
|
+
key: "pythonSetupCfg",
|
|
97
|
+
async parse(input, context) {
|
|
98
|
+
return {
|
|
99
|
+
data: parse(await readFile(resolve(context.options.path, input), "utf8")),
|
|
100
|
+
source: input
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
phase: 1
|
|
104
|
+
});
|
|
105
|
+
//#endregion
|
|
106
|
+
export { pythonSetupCfgSource };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { OneOrMany, SourceRecord } from "../source.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/sources/python-setup-py.d.ts
|
|
5
|
+
/** Parsed setup.py metadata */
|
|
6
|
+
declare const setupPyDataSchema: z.ZodObject<{
|
|
7
|
+
author: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
8
|
+
author_email: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
9
|
+
classifiers: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
10
|
+
description: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
11
|
+
download_url: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
12
|
+
extras_require: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>;
|
|
13
|
+
install_requires: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
14
|
+
keywords: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
15
|
+
license: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
16
|
+
long_description: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
17
|
+
maintainer: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
18
|
+
maintainer_email: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
19
|
+
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
20
|
+
project_urls: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
21
|
+
python_requires: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
22
|
+
url: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
23
|
+
version: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
type SetupPyData = z.infer<typeof setupPyDataSchema>;
|
|
26
|
+
type PythonSetupPyData = OneOrMany<SourceRecord<SetupPyData>> | undefined;
|
|
27
|
+
//#endregion
|
|
28
|
+
export { PythonSetupPyData };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { getMatches } from "../file-matching.js";
|
|
2
|
+
import { defineSource } from "../source.js";
|
|
3
|
+
import { nonEmptyString, optionalUrl, stringArray } from "../utilities/schema-primitives.js";
|
|
4
|
+
import { parseSetupPy } from "../parsers/setup-py-parser.js";
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
6
|
+
import { resolve } from "node:path";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
//#region src/lib/sources/python-setup-py.ts
|
|
9
|
+
/** Parsed setup.py metadata */
|
|
10
|
+
const setupPyDataSchema = z.object({
|
|
11
|
+
author: nonEmptyString,
|
|
12
|
+
author_email: nonEmptyString,
|
|
13
|
+
classifiers: stringArray,
|
|
14
|
+
description: nonEmptyString,
|
|
15
|
+
download_url: optionalUrl,
|
|
16
|
+
extras_require: z.record(z.string(), z.array(z.string())),
|
|
17
|
+
install_requires: stringArray,
|
|
18
|
+
keywords: z.array(z.string()).optional(),
|
|
19
|
+
license: nonEmptyString,
|
|
20
|
+
long_description: nonEmptyString,
|
|
21
|
+
maintainer: nonEmptyString,
|
|
22
|
+
maintainer_email: nonEmptyString,
|
|
23
|
+
name: nonEmptyString,
|
|
24
|
+
project_urls: z.record(z.string(), z.string()),
|
|
25
|
+
python_requires: nonEmptyString,
|
|
26
|
+
url: optionalUrl,
|
|
27
|
+
version: nonEmptyString
|
|
28
|
+
});
|
|
29
|
+
/** Parse setup.py content and validate through the Zod schema. */
|
|
30
|
+
async function parse(content) {
|
|
31
|
+
const data = await parseSetupPy(content);
|
|
32
|
+
return setupPyDataSchema.parse(data);
|
|
33
|
+
}
|
|
34
|
+
const pythonSetupPySource = defineSource({
|
|
35
|
+
async discover(context) {
|
|
36
|
+
return getMatches(context.options, ["setup.py"]);
|
|
37
|
+
},
|
|
38
|
+
key: "pythonSetupPy",
|
|
39
|
+
async parse(input, context) {
|
|
40
|
+
return {
|
|
41
|
+
data: await parse(await readFile(resolve(context.options.path, input), "utf8")),
|
|
42
|
+
source: input
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
phase: 1
|
|
46
|
+
});
|
|
47
|
+
//#endregion
|
|
48
|
+
export { pythonSetupPySource };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { OneOrMany, SourceRecord } from "../source.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/sources/readme-file.d.ts
|
|
5
|
+
declare const readmeSchema: z.ZodObject<{
|
|
6
|
+
name: z.ZodString;
|
|
7
|
+
}, z.core.$strip>;
|
|
8
|
+
type Readme = z.infer<typeof readmeSchema>;
|
|
9
|
+
type ReadmeFileData = OneOrMany<SourceRecord<Readme>> | undefined;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { ReadmeFileData };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { getMatches } from "../file-matching.js";
|
|
2
|
+
import { defineSource } from "../source.js";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import remarkParse from "remark-parse";
|
|
7
|
+
import { unified } from "unified";
|
|
8
|
+
//#region src/lib/sources/readme-file.ts
|
|
9
|
+
const readmeSchema = z.object({ name: z.string() });
|
|
10
|
+
/**
|
|
11
|
+
* Recursively extract plain text from mdast phrasing content.
|
|
12
|
+
*/
|
|
13
|
+
function extractText(nodes) {
|
|
14
|
+
return nodes.map((node) => {
|
|
15
|
+
if ("value" in node) return node.value;
|
|
16
|
+
if ("children" in node) return extractText(node.children);
|
|
17
|
+
return "";
|
|
18
|
+
}).join("").trim();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Extract the text content of the first H1 heading from markdown.
|
|
22
|
+
*/
|
|
23
|
+
function extractFirstH1(markdown) {
|
|
24
|
+
const tree = unified().use(remarkParse).parse(markdown);
|
|
25
|
+
for (const node of tree.children) if (node.type === "heading" && node.depth === 1) {
|
|
26
|
+
const text = extractText(node.children);
|
|
27
|
+
if (text.length > 0) return text;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parse a README file's content.
|
|
32
|
+
* @param content - Raw file content (markdown).
|
|
33
|
+
* @returns Parsed metadata, or `undefined` if no H1 heading is found.
|
|
34
|
+
*/
|
|
35
|
+
function parse(content) {
|
|
36
|
+
const name = extractFirstH1(content);
|
|
37
|
+
if (!name) return void 0;
|
|
38
|
+
return readmeSchema.parse({ name });
|
|
39
|
+
}
|
|
40
|
+
const readmeFileSource = defineSource({
|
|
41
|
+
async discover(context) {
|
|
42
|
+
return getMatches(context.options, ["README", "README.*"]);
|
|
43
|
+
},
|
|
44
|
+
key: "readmeFile",
|
|
45
|
+
async parse(input, context) {
|
|
46
|
+
const data = parse(await readFile(resolve(context.options.path, input), "utf8"));
|
|
47
|
+
if (data !== void 0) return {
|
|
48
|
+
data,
|
|
49
|
+
source: input
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
phase: 1
|
|
53
|
+
});
|
|
54
|
+
//#endregion
|
|
55
|
+
export { readmeFileSource };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { OneOrMany, SourceRecord } from "../source.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/sources/ruby-gemspec.d.ts
|
|
5
|
+
/** @public */
|
|
6
|
+
declare const gemSpecSchema: z.ZodObject<{
|
|
7
|
+
authors: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
8
|
+
bindir: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
9
|
+
cert_chain: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
10
|
+
dependencies: z.ZodArray<z.ZodObject<{
|
|
11
|
+
name: z.ZodString;
|
|
12
|
+
requirements: z.ZodArray<z.ZodString>;
|
|
13
|
+
type: z.ZodEnum<{
|
|
14
|
+
development: "development";
|
|
15
|
+
runtime: "runtime";
|
|
16
|
+
}>;
|
|
17
|
+
}, z.core.$strip>>;
|
|
18
|
+
description: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
19
|
+
email: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
20
|
+
executables: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
21
|
+
extensions: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
22
|
+
extra: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
23
|
+
extra_rdoc_files: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
24
|
+
files: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
25
|
+
homepage: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
26
|
+
license: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
27
|
+
licenses: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
28
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
29
|
+
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
30
|
+
platform: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
31
|
+
post_install_message: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
32
|
+
rdoc_options: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
33
|
+
require_paths: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
34
|
+
required_ruby_version: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
35
|
+
required_rubygems_version: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
36
|
+
signing_key: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
37
|
+
summary: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
38
|
+
test_files: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
39
|
+
version: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
40
|
+
}, z.core.$strip>;
|
|
41
|
+
type GemSpec = z.infer<typeof gemSpecSchema>;
|
|
42
|
+
type RubyGemspecData = OneOrMany<SourceRecord<GemSpec>> | undefined;
|
|
43
|
+
//#endregion
|
|
44
|
+
export { RubyGemspecData };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getMatches } from "../file-matching.js";
|
|
2
|
+
import { defineSource } from "../source.js";
|
|
3
|
+
import { nonEmptyString, optionalUrl, stringArray } from "../utilities/schema-primitives.js";
|
|
4
|
+
import { parseGemspec } from "../parsers/gemspec-parser.js";
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
6
|
+
import { resolve } from "node:path";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
//#region src/lib/sources/ruby-gemspec.ts
|
|
9
|
+
const gemSpecDependencySchema = z.object({
|
|
10
|
+
name: z.string(),
|
|
11
|
+
requirements: z.array(z.string()),
|
|
12
|
+
type: z.enum(["development", "runtime"])
|
|
13
|
+
});
|
|
14
|
+
/** @public */
|
|
15
|
+
const gemSpecSchema = z.object({
|
|
16
|
+
authors: stringArray,
|
|
17
|
+
bindir: nonEmptyString,
|
|
18
|
+
cert_chain: stringArray,
|
|
19
|
+
dependencies: z.array(gemSpecDependencySchema),
|
|
20
|
+
description: nonEmptyString,
|
|
21
|
+
email: z.union([z.string(), z.array(z.string())]).optional(),
|
|
22
|
+
executables: stringArray,
|
|
23
|
+
extensions: stringArray,
|
|
24
|
+
extra: z.record(z.string(), z.unknown()),
|
|
25
|
+
extra_rdoc_files: stringArray,
|
|
26
|
+
files: stringArray,
|
|
27
|
+
homepage: optionalUrl,
|
|
28
|
+
license: nonEmptyString,
|
|
29
|
+
licenses: stringArray,
|
|
30
|
+
metadata: z.record(z.string(), z.string()),
|
|
31
|
+
name: nonEmptyString,
|
|
32
|
+
platform: nonEmptyString,
|
|
33
|
+
post_install_message: nonEmptyString,
|
|
34
|
+
rdoc_options: stringArray,
|
|
35
|
+
require_paths: stringArray,
|
|
36
|
+
required_ruby_version: nonEmptyString,
|
|
37
|
+
required_rubygems_version: nonEmptyString,
|
|
38
|
+
signing_key: nonEmptyString,
|
|
39
|
+
summary: nonEmptyString,
|
|
40
|
+
test_files: stringArray,
|
|
41
|
+
version: nonEmptyString
|
|
42
|
+
});
|
|
43
|
+
/** Parse gemspec content and validate through the Zod schema. */
|
|
44
|
+
async function parse(content) {
|
|
45
|
+
const raw = await parseGemspec(content);
|
|
46
|
+
return gemSpecSchema.parse(raw);
|
|
47
|
+
}
|
|
48
|
+
const rubyGemspecSource = defineSource({
|
|
49
|
+
async discover(context) {
|
|
50
|
+
return getMatches(context.options, ["*.gemspec"]);
|
|
51
|
+
},
|
|
52
|
+
key: "rubyGemspec",
|
|
53
|
+
async parse(input, context) {
|
|
54
|
+
return {
|
|
55
|
+
data: await parse(await readFile(resolve(context.options.path, input), "utf8")),
|
|
56
|
+
source: input
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
phase: 1
|
|
60
|
+
});
|
|
61
|
+
//#endregion
|
|
62
|
+
export { rubyGemspecSource };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { OneOrMany, SourceRecord } from "../source.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/sources/rust-cargo-toml.d.ts
|
|
5
|
+
declare const cargoTomlSchema: z.ZodObject<{
|
|
6
|
+
authors: z.ZodArray<z.ZodObject<{
|
|
7
|
+
email: z.ZodOptional<z.ZodString>;
|
|
8
|
+
name: z.ZodString;
|
|
9
|
+
}, z.core.$strip>>;
|
|
10
|
+
buildDependencies: z.ZodArray<z.ZodObject<{
|
|
11
|
+
name: z.ZodString;
|
|
12
|
+
version: z.ZodOptional<z.ZodString>;
|
|
13
|
+
}, z.core.$strip>>;
|
|
14
|
+
categories: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
15
|
+
dependencies: z.ZodArray<z.ZodObject<{
|
|
16
|
+
name: z.ZodString;
|
|
17
|
+
version: z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, z.core.$strip>>;
|
|
19
|
+
description: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
20
|
+
devDependencies: z.ZodArray<z.ZodObject<{
|
|
21
|
+
name: z.ZodString;
|
|
22
|
+
version: z.ZodOptional<z.ZodString>;
|
|
23
|
+
}, z.core.$strip>>;
|
|
24
|
+
documentation: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
25
|
+
edition: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
26
|
+
homepage: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
27
|
+
keywords: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
28
|
+
license: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
29
|
+
licenseFile: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
30
|
+
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
31
|
+
readme: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
32
|
+
repository: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
33
|
+
rustVersion: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
34
|
+
version: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
35
|
+
workspaceMembers: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
type CargoToml = z.infer<typeof cargoTomlSchema>;
|
|
38
|
+
type RustCargoTomlData = OneOrMany<SourceRecord<CargoToml>> | undefined;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { RustCargoTomlData };
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { getMatches } from "../file-matching.js";
|
|
2
|
+
import { defineSource } from "../source.js";
|
|
3
|
+
import { nonEmptyString, optionalUrl, stringArray } from "../utilities/schema-primitives.js";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
import { resolve } from "node:path";
|
|
6
|
+
import is from "@sindresorhus/is";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { parse } from "smol-toml";
|
|
9
|
+
//#region src/lib/sources/rust-cargo-toml.ts
|
|
10
|
+
/**
|
|
11
|
+
* Source for Rust `Cargo.toml` manifest files.
|
|
12
|
+
* These are TOML files used by the Cargo package manager. Metadata lives
|
|
13
|
+
* primarily in the `[package]` table, with dependencies in `[dependencies]`,
|
|
14
|
+
* `[dev-dependencies]`, and `[build-dependencies]`.
|
|
15
|
+
*
|
|
16
|
+
* Uses `smol-toml` for TOML parsing.
|
|
17
|
+
* @see https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
18
|
+
*/
|
|
19
|
+
const cargoTomlAuthorEntrySchema = z.object({
|
|
20
|
+
email: z.string().optional(),
|
|
21
|
+
name: z.string()
|
|
22
|
+
});
|
|
23
|
+
const cargoTomlDependencyEntrySchema = z.object({
|
|
24
|
+
name: z.string(),
|
|
25
|
+
version: z.string().optional()
|
|
26
|
+
});
|
|
27
|
+
const cargoTomlSchema = z.object({
|
|
28
|
+
authors: z.array(cargoTomlAuthorEntrySchema),
|
|
29
|
+
buildDependencies: z.array(cargoTomlDependencyEntrySchema),
|
|
30
|
+
categories: stringArray,
|
|
31
|
+
dependencies: z.array(cargoTomlDependencyEntrySchema),
|
|
32
|
+
description: nonEmptyString,
|
|
33
|
+
devDependencies: z.array(cargoTomlDependencyEntrySchema),
|
|
34
|
+
documentation: optionalUrl,
|
|
35
|
+
edition: nonEmptyString,
|
|
36
|
+
homepage: optionalUrl,
|
|
37
|
+
keywords: stringArray,
|
|
38
|
+
license: nonEmptyString,
|
|
39
|
+
licenseFile: nonEmptyString,
|
|
40
|
+
name: nonEmptyString,
|
|
41
|
+
readme: nonEmptyString,
|
|
42
|
+
repository: optionalUrl,
|
|
43
|
+
rustVersion: nonEmptyString,
|
|
44
|
+
version: nonEmptyString,
|
|
45
|
+
workspaceMembers: stringArray
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* Parse a `Cargo.toml` content string into a structured object.
|
|
49
|
+
* Returns undefined if the TOML is malformed.
|
|
50
|
+
*/
|
|
51
|
+
function parse$1(content) {
|
|
52
|
+
let data;
|
|
53
|
+
try {
|
|
54
|
+
const parsed = parse(content);
|
|
55
|
+
if (!is.plainObject(parsed)) return void 0;
|
|
56
|
+
data = parsed;
|
|
57
|
+
} catch {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const packageData = is.plainObject(data.package) ? data.package : {};
|
|
61
|
+
const workspace = is.plainObject(data.workspace) ? data.workspace : void 0;
|
|
62
|
+
return cargoTomlSchema.parse({
|
|
63
|
+
authors: parseAuthors(packageData.authors),
|
|
64
|
+
buildDependencies: parseDependencies(is.plainObject(data["build-dependencies"]) ? data["build-dependencies"] : {}),
|
|
65
|
+
categories: toStringArray(packageData.categories),
|
|
66
|
+
dependencies: parseDependencies(is.plainObject(data.dependencies) ? data.dependencies : {}),
|
|
67
|
+
description: nonEmpty(packageData.description),
|
|
68
|
+
devDependencies: parseDependencies(is.plainObject(data["dev-dependencies"]) ? data["dev-dependencies"] : {}),
|
|
69
|
+
documentation: nonEmpty(packageData.documentation),
|
|
70
|
+
edition: nonEmpty(packageData.edition),
|
|
71
|
+
homepage: nonEmpty(packageData.homepage),
|
|
72
|
+
keywords: toStringArray(packageData.keywords),
|
|
73
|
+
license: nonEmpty(packageData.license),
|
|
74
|
+
licenseFile: nonEmpty(packageData["license-file"]),
|
|
75
|
+
name: nonEmpty(packageData.name),
|
|
76
|
+
readme: nonEmpty(packageData.readme),
|
|
77
|
+
repository: nonEmpty(packageData.repository),
|
|
78
|
+
rustVersion: nonEmpty(packageData["rust-version"]),
|
|
79
|
+
version: nonEmpty(packageData.version),
|
|
80
|
+
workspaceMembers: toStringArray(workspace?.members)
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/** Return a trimmed string, or undefined if not a non-empty string. */
|
|
84
|
+
function nonEmpty(value) {
|
|
85
|
+
if (typeof value !== "string") return void 0;
|
|
86
|
+
const trimmed = value.trim();
|
|
87
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
88
|
+
}
|
|
89
|
+
/** Convert an unknown value to a string array, filtering non-strings. */
|
|
90
|
+
function toStringArray(value) {
|
|
91
|
+
if (!Array.isArray(value)) return [];
|
|
92
|
+
return value.filter((v) => typeof v === "string" && v.trim().length > 0);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Parse `authors` field entries. Each entry is `"Name <email>"` or `"Name"`.
|
|
96
|
+
*/
|
|
97
|
+
function parseAuthors(value) {
|
|
98
|
+
if (!Array.isArray(value)) return [];
|
|
99
|
+
const results = [];
|
|
100
|
+
for (const entry of value) {
|
|
101
|
+
if (typeof entry !== "string") continue;
|
|
102
|
+
const trimmed = entry.trim();
|
|
103
|
+
if (trimmed.length === 0) continue;
|
|
104
|
+
const bracketIndex = trimmed.indexOf("<");
|
|
105
|
+
if (bracketIndex !== -1) {
|
|
106
|
+
const closeBracket = trimmed.indexOf(">", bracketIndex);
|
|
107
|
+
if (closeBracket !== -1) {
|
|
108
|
+
const name = trimmed.slice(0, bracketIndex).trim();
|
|
109
|
+
const email = trimmed.slice(bracketIndex + 1, closeBracket).trim();
|
|
110
|
+
results.push({
|
|
111
|
+
email: email.length > 0 ? email : void 0,
|
|
112
|
+
name
|
|
113
|
+
});
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
results.push({
|
|
118
|
+
email: void 0,
|
|
119
|
+
name: trimmed
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
return results;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Parse a dependencies table into name/version entries.
|
|
126
|
+
* Handles both `dep = "version"` and `dep = { version = "..." }` forms.
|
|
127
|
+
*/
|
|
128
|
+
function parseDependencies(table) {
|
|
129
|
+
const results = [];
|
|
130
|
+
for (const [name, value] of Object.entries(table)) if (typeof value === "string") results.push({
|
|
131
|
+
name,
|
|
132
|
+
version: value
|
|
133
|
+
});
|
|
134
|
+
else if (is.plainObject(value)) results.push({
|
|
135
|
+
name,
|
|
136
|
+
version: nonEmpty(value.version)
|
|
137
|
+
});
|
|
138
|
+
else results.push({
|
|
139
|
+
name,
|
|
140
|
+
version: void 0
|
|
141
|
+
});
|
|
142
|
+
return results;
|
|
143
|
+
}
|
|
144
|
+
const rustCargoTomlSource = defineSource({
|
|
145
|
+
async discover(context) {
|
|
146
|
+
return getMatches(context.options, ["Cargo.toml"]);
|
|
147
|
+
},
|
|
148
|
+
key: "rustCargoToml",
|
|
149
|
+
async parse(input, context) {
|
|
150
|
+
const data = parse$1(await readFile(resolve(context.options.path, input), "utf8"));
|
|
151
|
+
if (data !== void 0) return {
|
|
152
|
+
data,
|
|
153
|
+
source: input
|
|
154
|
+
};
|
|
155
|
+
},
|
|
156
|
+
phase: 1
|
|
157
|
+
});
|
|
158
|
+
//#endregion
|
|
159
|
+
export { rustCargoTomlSource };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { OneOrMany, SourceRecord } from "../source.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/sources/xcode-info-plist.d.ts
|
|
5
|
+
declare const infoPlistSchema: z.ZodObject<{
|
|
6
|
+
applicationCategory: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
7
|
+
author: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
8
|
+
authorEmail: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
9
|
+
copyrightHolder: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
10
|
+
copyrightYear: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
11
|
+
description: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
12
|
+
identifier: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
13
|
+
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
14
|
+
operatingSystems: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
15
|
+
processorRequirements: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>;
|
|
16
|
+
url: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
17
|
+
version: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
type InfoPlist = z.infer<typeof infoPlistSchema>;
|
|
20
|
+
type XcodeInfoPlistData = OneOrMany<SourceRecord<InfoPlist>> | undefined;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { XcodeInfoPlistData };
|