metascope 0.7.0 → 0.7.2
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/bin/chunk-Bdh3yLIe.js +1 -0
- package/dist/bin/cli.js +308 -284
- package/dist/bin/dns-CUigd8AG.js +1 -0
- package/dist/bin/{jiti-D2Njwwqq.js → jiti-BTBDwj9g.js} +2 -2
- package/dist/bin/renovate-DxDKd5Ft.js +1 -0
- package/dist/bin/shared-CTlQdTfh.js +5 -0
- package/dist/lib/file-matching.js +20 -13
- package/dist/lib/log.d.ts +6 -4
- package/dist/lib/log.js +5 -3
- package/dist/lib/metadata-types.d.ts +33 -21
- package/dist/lib/metadata-types.js +8 -9
- package/dist/lib/metadata.js +7 -7
- package/dist/lib/package.js +1 -1
- package/dist/lib/parsers/gemspec-parser.js +16 -14
- package/dist/lib/parsers/go-mod-parser.js +13 -10
- package/dist/lib/parsers/makefile-config-parser.js +20 -17
- package/dist/lib/parsers/properties-parser.js +3 -3
- package/dist/lib/parsers/rfc822-header-parser.js +4 -4
- package/dist/lib/parsers/setup-py-parser.js +3 -4
- package/dist/lib/source.d.ts +1 -0
- package/dist/lib/source.js +5 -4
- package/dist/lib/sources/arduino-library-properties.d.ts +10 -10
- package/dist/lib/sources/arduino-library-properties.js +32 -15
- package/dist/lib/sources/cinder-cinderblock-xml.d.ts +11 -11
- package/dist/lib/sources/cinder-cinderblock-xml.js +21 -9
- package/dist/lib/sources/codemeta-json.d.ts +66 -66
- package/dist/lib/sources/codemeta-json.js +27 -23
- package/dist/lib/sources/git-stats.js +1 -1
- package/dist/lib/sources/github-actions.js +9 -2
- package/dist/lib/sources/github.js +1 -1
- package/dist/lib/sources/go-go-mod.d.ts +4 -4
- package/dist/lib/sources/go-goreleaser-yaml.d.ts +8 -8
- package/dist/lib/sources/go-goreleaser-yaml.js +5 -4
- package/dist/lib/sources/java-pom-xml.d.ts +12 -12
- package/dist/lib/sources/java-pom-xml.js +38 -19
- package/dist/lib/sources/metadata-file.d.ts +4 -4
- package/dist/lib/sources/metadata-file.js +15 -12
- package/dist/lib/sources/node-npm-registry.js +1 -1
- package/dist/lib/sources/openframeworks-addon-config-mk.d.ts +7 -7
- package/dist/lib/sources/openframeworks-addon-config-mk.js +7 -0
- package/dist/lib/sources/openframeworks-install-xml.d.ts +10 -10
- package/dist/lib/sources/openframeworks-install-xml.js +24 -14
- package/dist/lib/sources/processing-library-properties.d.ts +8 -8
- package/dist/lib/sources/processing-library-properties.js +25 -10
- package/dist/lib/sources/processing-sketch-properties.d.ts +16 -16
- package/dist/lib/sources/processing-sketch-properties.js +51 -7
- package/dist/lib/sources/publiccode-yaml.d.ts +23 -23
- package/dist/lib/sources/publiccode-yaml.js +37 -5
- package/dist/lib/sources/python-pkg-info.d.ts +18 -18
- package/dist/lib/sources/python-pkg-info.js +2 -2
- package/dist/lib/sources/python-setup-cfg.d.ts +14 -14
- package/dist/lib/sources/python-setup-cfg.js +2 -2
- package/dist/lib/sources/python-setup-py.d.ts +14 -14
- package/dist/lib/sources/readme-file.js +9 -2
- package/dist/lib/sources/ruby-gemspec.d.ts +22 -22
- package/dist/lib/sources/ruby-gemspec.js +1 -0
- package/dist/lib/sources/rust-cargo-toml.d.ts +14 -14
- package/dist/lib/sources/rust-cargo-toml.js +29 -10
- package/dist/lib/sources/xcode-info-plist.d.ts +12 -12
- package/dist/lib/sources/xcode-info-plist.js +48 -24
- package/dist/lib/sources/xcode-project-pbxproj.d.ts +8 -8
- package/dist/lib/sources/xcode-project-pbxproj.js +22 -12
- package/dist/lib/templates/codemeta-json.d.ts +4 -5
- package/dist/lib/templates/codemeta-json.js +4 -5
- package/dist/lib/templates/codemeta.js +30 -30
- package/dist/lib/templates/metadata.d.ts +2 -2
- package/dist/lib/templates/metadata.js +3 -3
- package/dist/lib/utilities/codemeta-helpers.d.ts +3 -2
- package/dist/lib/utilities/codemeta-helpers.js +14 -12
- package/dist/lib/utilities/fetch.js +2 -2
- package/dist/lib/utilities/formatting.js +4 -3
- package/dist/lib/utilities/github.js +3 -3
- package/dist/lib/utilities/license-identification.d.ts +3 -1
- package/dist/lib/utilities/license-identification.js +21 -25
- package/dist/lib/utilities/schema-primitives.js +16 -13
- package/dist/lib/utilities/template-helpers.js +3 -3
- package/package.json +14 -14
- package/readme.md +7 -3
- package/dist/.DS_Store +0 -0
- package/dist/bin/chunk-BjEoQXZ0.js +0 -1
|
@@ -8,12 +8,13 @@ import { z } from "zod";
|
|
|
8
8
|
import { parse } from "smol-toml";
|
|
9
9
|
//#region src/lib/sources/rust-cargo-toml.ts
|
|
10
10
|
/**
|
|
11
|
-
* Source for Rust `Cargo.toml` manifest files.
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* `[
|
|
11
|
+
* Source for Rust `Cargo.toml` manifest files. These are TOML files used by the
|
|
12
|
+
* Cargo package manager. Metadata lives primarily in the `[package]` table,
|
|
13
|
+
* with dependencies in `[dependencies]`, `[dev-dependencies]`, and
|
|
14
|
+
* `[build-dependencies]`.
|
|
15
15
|
*
|
|
16
16
|
* Uses `smol-toml` for TOML parsing.
|
|
17
|
+
*
|
|
17
18
|
* @see https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
18
19
|
*/
|
|
19
20
|
const cargoTomlAuthorEntrySchema = z.object({
|
|
@@ -25,34 +26,52 @@ const cargoTomlDependencyEntrySchema = z.object({
|
|
|
25
26
|
version: z.string().optional()
|
|
26
27
|
});
|
|
27
28
|
const cargoTomlSchema = z.object({
|
|
29
|
+
/** Parsed author entries from `package.authors`. */
|
|
28
30
|
authors: z.array(cargoTomlAuthorEntrySchema),
|
|
31
|
+
/** Build dependency names and versions from `[build-dependencies]`. */
|
|
29
32
|
buildDependencies: z.array(cargoTomlDependencyEntrySchema),
|
|
33
|
+
/** Category strings from `package.categories`. */
|
|
30
34
|
categories: stringArray,
|
|
35
|
+
/** Dependencies from `[dependencies]`. */
|
|
31
36
|
dependencies: z.array(cargoTomlDependencyEntrySchema),
|
|
37
|
+
/** Description from `package.description`. */
|
|
32
38
|
description: nonEmptyString,
|
|
39
|
+
/** Dev dependency names and versions from `[dev-dependencies]`. */
|
|
33
40
|
devDependencies: z.array(cargoTomlDependencyEntrySchema),
|
|
41
|
+
/** Documentation URL from `package.documentation`. */
|
|
34
42
|
documentation: optionalUrl,
|
|
43
|
+
/** Rust edition from `package.edition`. */
|
|
35
44
|
edition: nonEmptyString,
|
|
45
|
+
/** Homepage URL from `package.homepage`. */
|
|
36
46
|
homepage: optionalUrl,
|
|
47
|
+
/** Keywords from `package.keywords`. */
|
|
37
48
|
keywords: stringArray,
|
|
49
|
+
/** License identifier from `package.license`. */
|
|
38
50
|
license: nonEmptyString,
|
|
51
|
+
/** License file path from `package.license-file`. */
|
|
39
52
|
licenseFile: nonEmptyString,
|
|
53
|
+
/** Package name from `package.name`. */
|
|
40
54
|
name: nonEmptyString,
|
|
55
|
+
/** Readme file path from `package.readme`. */
|
|
41
56
|
readme: nonEmptyString,
|
|
57
|
+
/** Repository URL from `package.repository`. */
|
|
42
58
|
repository: optionalUrl,
|
|
59
|
+
/** Minimum Rust version from `package.rust-version`. */
|
|
43
60
|
rustVersion: nonEmptyString,
|
|
61
|
+
/** Version string from `package.version`. */
|
|
44
62
|
version: nonEmptyString,
|
|
63
|
+
/** Workspace members from `[workspace]`. */
|
|
45
64
|
workspaceMembers: stringArray
|
|
46
65
|
});
|
|
47
66
|
/**
|
|
48
|
-
* Parse a `Cargo.toml` content string into a structured object.
|
|
49
|
-
*
|
|
67
|
+
* Parse a `Cargo.toml` content string into a structured object. Returns
|
|
68
|
+
* undefined if the TOML is malformed.
|
|
50
69
|
*/
|
|
51
70
|
function parse$1(content) {
|
|
52
71
|
let data;
|
|
53
72
|
try {
|
|
54
73
|
const parsed = parse(content);
|
|
55
|
-
if (!is.plainObject(parsed)) return
|
|
74
|
+
if (!is.plainObject(parsed)) return;
|
|
56
75
|
data = parsed;
|
|
57
76
|
} catch {
|
|
58
77
|
return;
|
|
@@ -82,7 +101,7 @@ function parse$1(content) {
|
|
|
82
101
|
}
|
|
83
102
|
/** Return a trimmed string, or undefined if not a non-empty string. */
|
|
84
103
|
function nonEmpty(value) {
|
|
85
|
-
if (typeof value !== "string") return
|
|
104
|
+
if (typeof value !== "string") return;
|
|
86
105
|
const trimmed = value.trim();
|
|
87
106
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
88
107
|
}
|
|
@@ -122,8 +141,8 @@ function parseAuthors(value) {
|
|
|
122
141
|
return results;
|
|
123
142
|
}
|
|
124
143
|
/**
|
|
125
|
-
* Parse a dependencies table into name/version entries.
|
|
126
|
-
*
|
|
144
|
+
* Parse a dependencies table into name/version entries. Handles both `dep =
|
|
145
|
+
* "version"` and `dep = { version = "..." }` forms.
|
|
127
146
|
*/
|
|
128
147
|
function parseDependencies(table) {
|
|
129
148
|
const results = [];
|
|
@@ -3,18 +3,18 @@ import { z } from "zod";
|
|
|
3
3
|
|
|
4
4
|
//#region src/lib/sources/xcode-info-plist.d.ts
|
|
5
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
|
|
6
|
+
applicationCategory: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
7
|
+
author: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
8
|
+
authorEmail: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
9
|
+
copyrightHolder: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
10
|
+
copyrightYear: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
11
|
+
description: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
12
|
+
identifier: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
13
|
+
name: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
14
|
+
operatingSystems: z.ZodDefault<z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>>;
|
|
15
|
+
processorRequirements: z.ZodDefault<z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>>;
|
|
16
|
+
url: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
17
|
+
version: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
18
18
|
}, z.core.$strip>;
|
|
19
19
|
type InfoPlist = z.infer<typeof infoPlistSchema>;
|
|
20
20
|
type XcodeInfoPlistData = OneOrMany<SourceRecord<InfoPlist>> | undefined;
|
|
@@ -11,9 +11,10 @@ import plist from "plist";
|
|
|
11
11
|
* Source and parser for Apple `Info.plist` files.
|
|
12
12
|
*
|
|
13
13
|
* Handles three flavors of Info.plist:
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
*
|
|
15
|
+
* - Standard Apple app/framework bundles (CFBundle* keys)
|
|
16
|
+
* - Alfred workflow plists (name, createdby, bundleid, etc.)
|
|
17
|
+
* - TextMate bundle plists (name, contactName, contactEmailRot13, etc.)
|
|
17
18
|
*
|
|
18
19
|
* Uses the `plist` npm package to parse XML plist format.
|
|
19
20
|
*/
|
|
@@ -23,23 +24,38 @@ const ALL_RIGHTS_RESERVED_REGEX = /\.\s*all\s+rights\s+reserved\.?/i;
|
|
|
23
24
|
const TRAILING_PUNCTUATION_REGEX = /[.,;]+$/;
|
|
24
25
|
const PROCESSOR_ARCH_REGEX = /^(?:arm|x86|i386)/i;
|
|
25
26
|
const infoPlistSchema = z.object({
|
|
27
|
+
/** Application category (humanized from UTI). */
|
|
26
28
|
applicationCategory: nonEmptyString,
|
|
29
|
+
/** Author / creator name. */
|
|
27
30
|
author: nonEmptyString,
|
|
31
|
+
/** Author email (decoded from ROT13 for TextMate bundles). */
|
|
28
32
|
authorEmail: nonEmptyString,
|
|
33
|
+
/** Copyright holder name. */
|
|
29
34
|
copyrightHolder: nonEmptyString,
|
|
35
|
+
/** Copyright year. */
|
|
30
36
|
copyrightYear: nonEmptyString,
|
|
37
|
+
/** Description / readme text. */
|
|
31
38
|
description: nonEmptyString,
|
|
39
|
+
/** Bundle identifier (e.g. "com.example.app"). */
|
|
32
40
|
identifier: nonEmptyString,
|
|
41
|
+
/** Display name of the app or bundle. */
|
|
33
42
|
name: nonEmptyString,
|
|
43
|
+
/** Inferred operating systems. */
|
|
34
44
|
operatingSystems: stringArray,
|
|
45
|
+
/** Processor architecture requirements (e.g. "armv7"). */
|
|
35
46
|
processorRequirements: stringArray,
|
|
47
|
+
/** Homepage URL. */
|
|
36
48
|
url: optionalUrl,
|
|
49
|
+
/** Version string. */
|
|
37
50
|
version: nonEmptyString
|
|
38
51
|
});
|
|
39
52
|
/** Xcode build variable pattern: $(VAR) or ${VAR}. */
|
|
40
53
|
const XCODE_VARIABLE_RE = /\$[({][^)}]+[)}]/;
|
|
54
|
+
/** XML comment, including malformed ones with `--` inside. */
|
|
55
|
+
const XML_COMMENT_RE = /<!--[\s\S]*?-->/g;
|
|
41
56
|
/**
|
|
42
|
-
* Map DTPlatformName / CFBundleSupportedPlatforms values to human-readable OS
|
|
57
|
+
* Map DTPlatformName / CFBundleSupportedPlatforms values to human-readable OS
|
|
58
|
+
* names.
|
|
43
59
|
*/
|
|
44
60
|
const PLATFORM_NAME_MAP = {
|
|
45
61
|
appletvos: "tvOS",
|
|
@@ -52,18 +68,12 @@ const PLATFORM_NAME_MAP = {
|
|
|
52
68
|
xros: "visionOS"
|
|
53
69
|
};
|
|
54
70
|
/**
|
|
55
|
-
* Parse an `Info.plist` content string into a structured object.
|
|
56
|
-
*
|
|
71
|
+
* Parse an `Info.plist` content string into a structured object. Returns
|
|
72
|
+
* undefined if the plist is malformed or not a dictionary.
|
|
57
73
|
*/
|
|
58
74
|
function parse(content) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const parsed = plist.parse(content);
|
|
62
|
-
if (!is.plainObject(parsed)) return;
|
|
63
|
-
data = parsed;
|
|
64
|
-
} catch {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
75
|
+
const data = tryParsePlist(content) ?? tryParsePlist(content.replaceAll(XML_COMMENT_RE, "").trimStart());
|
|
76
|
+
if (!data) return;
|
|
67
77
|
const name = getString(data, "CFBundleDisplayName") ?? getString(data, "CFBundleName") ?? getString(data, "name");
|
|
68
78
|
const description = getString(data, "description");
|
|
69
79
|
const version = getString(data, "CFBundleShortVersionString") ?? getString(data, "version") ?? getString(data, "CFBundleVersion");
|
|
@@ -90,15 +100,27 @@ function parse(content) {
|
|
|
90
100
|
});
|
|
91
101
|
}
|
|
92
102
|
/**
|
|
93
|
-
*
|
|
94
|
-
*
|
|
103
|
+
* Run `plist.parse` and return the result only if it is a plain-object dict.
|
|
104
|
+
* Returns undefined on any throw or non-dict root.
|
|
105
|
+
*/
|
|
106
|
+
function tryParsePlist(content) {
|
|
107
|
+
try {
|
|
108
|
+
const parsed = plist.parse(content);
|
|
109
|
+
return is.plainObject(parsed) ? parsed : void 0;
|
|
110
|
+
} catch {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Get a string value from a plist dict, returning undefined for empty strings,
|
|
116
|
+
* whitespace-only strings, and Xcode variable placeholders.
|
|
95
117
|
*/
|
|
96
118
|
function getString(data, key) {
|
|
97
119
|
const value = data[key];
|
|
98
|
-
if (typeof value !== "string") return
|
|
120
|
+
if (typeof value !== "string") return;
|
|
99
121
|
const trimmed = value.trim();
|
|
100
|
-
if (trimmed.length === 0) return
|
|
101
|
-
if (XCODE_VARIABLE_RE.test(trimmed)) return
|
|
122
|
+
if (trimmed.length === 0) return;
|
|
123
|
+
if (XCODE_VARIABLE_RE.test(trimmed)) return;
|
|
102
124
|
return trimmed;
|
|
103
125
|
}
|
|
104
126
|
/**
|
|
@@ -111,8 +133,8 @@ function rot13(value) {
|
|
|
111
133
|
});
|
|
112
134
|
}
|
|
113
135
|
/**
|
|
114
|
-
* Convert an Apple UTI application category to a human-readable string.
|
|
115
|
-
*
|
|
136
|
+
* Convert an Apple UTI application category to a human-readable string. e.g.
|
|
137
|
+
* "public.app-category.developer-tools" → "Developer Tools"
|
|
116
138
|
*/
|
|
117
139
|
function humanizeCategory(uti) {
|
|
118
140
|
if (!uti.startsWith("public.app-category.")) return uti;
|
|
@@ -123,11 +145,12 @@ function humanizeCategory(uti) {
|
|
|
123
145
|
*/
|
|
124
146
|
function parseApplicationCategory(data) {
|
|
125
147
|
const category = getString(data, "LSApplicationCategoryType");
|
|
126
|
-
if (!category) return
|
|
148
|
+
if (!category) return;
|
|
127
149
|
return humanizeCategory(category);
|
|
128
150
|
}
|
|
129
151
|
/**
|
|
130
|
-
* Parse copyright information from NSHumanReadableCopyright or
|
|
152
|
+
* Parse copyright information from NSHumanReadableCopyright or
|
|
153
|
+
* CFBundleGetInfoString.
|
|
131
154
|
*/
|
|
132
155
|
function parseCopyright(data) {
|
|
133
156
|
const copyrightSource = getString(data, "NSHumanReadableCopyright") ?? getString(data, "CFBundleGetInfoString");
|
|
@@ -177,7 +200,8 @@ function parseOperatingSystems(data) {
|
|
|
177
200
|
return results;
|
|
178
201
|
}
|
|
179
202
|
/**
|
|
180
|
-
* Extract processor architecture requirements from
|
|
203
|
+
* Extract processor architecture requirements from
|
|
204
|
+
* UIRequiredDeviceCapabilities.
|
|
181
205
|
*/
|
|
182
206
|
function parseProcessorRequirements(data) {
|
|
183
207
|
const capabilities = data.UIRequiredDeviceCapabilities;
|
|
@@ -3,17 +3,17 @@ import { z } from "zod";
|
|
|
3
3
|
|
|
4
4
|
//#region src/lib/sources/xcode-project-pbxproj.d.ts
|
|
5
5
|
declare const pbxprojSchema: z.ZodObject<{
|
|
6
|
-
copyrightHolder: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
7
|
-
copyrightYear: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
6
|
+
copyrightHolder: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
7
|
+
copyrightYear: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
8
8
|
dependencies: z.ZodArray<z.ZodObject<{
|
|
9
9
|
url: z.ZodString;
|
|
10
10
|
}, z.core.$strip>>;
|
|
11
|
-
identifier: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
12
|
-
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
13
|
-
operatingSystems: z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString
|
|
14
|
-
organizationName: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
15
|
-
programmingLanguage: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
16
|
-
version: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString
|
|
11
|
+
identifier: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
12
|
+
name: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
13
|
+
operatingSystems: z.ZodDefault<z.ZodPipe<z.ZodTransform<string[], unknown>, z.ZodArray<z.ZodString>>>;
|
|
14
|
+
organizationName: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
15
|
+
programmingLanguage: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
16
|
+
version: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
17
17
|
}, z.core.$strip>;
|
|
18
18
|
type Pbxproj = z.infer<typeof pbxprojSchema>;
|
|
19
19
|
type XcodeProjectPbxprojData = OneOrMany<SourceRecord<Pbxproj>> | undefined;
|
|
@@ -9,13 +9,14 @@ import { PBXNativeTarget, XCRemoteSwiftPackageReference, XcodeProject } from "@b
|
|
|
9
9
|
/**
|
|
10
10
|
* Source and parser for Xcode `.pbxproj` project files.
|
|
11
11
|
*
|
|
12
|
-
* Uses the `@bacons/xcode` package to parse the binary/ASCII plist format
|
|
13
|
-
*
|
|
12
|
+
* Uses the `@bacons/xcode` package to parse the binary/ASCII plist format and
|
|
13
|
+
* navigate the Xcode project object graph.
|
|
14
14
|
*
|
|
15
15
|
* Extracts metadata from:
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
*
|
|
17
|
+
* - Project-level attributes (organizationName)
|
|
18
|
+
* - Build settings on the main app target (Release config preferred)
|
|
19
|
+
* - Swift Package Manager dependencies
|
|
19
20
|
*/
|
|
20
21
|
const COPYRIGHT_YEAR_REGEX = /(?:©|\(c\)|copyright)\s*(\d{4})/i;
|
|
21
22
|
const COPYRIGHT_HOLDER_REGEX = /(?:©|\(c\)|copyright)\s*\d{4}\s*(.+)/i;
|
|
@@ -23,14 +24,23 @@ const ALL_RIGHTS_RESERVED_REGEX = /\.\s*all\s+rights\s+reserved\.?/i;
|
|
|
23
24
|
const TRAILING_PUNCTUATION_REGEX = /[.,;]+$/;
|
|
24
25
|
const pbxprojDependencySchema = z.object({ url: z.string() });
|
|
25
26
|
const pbxprojSchema = z.object({
|
|
27
|
+
/** Copyright holder name. */
|
|
26
28
|
copyrightHolder: nonEmptyString,
|
|
29
|
+
/** Copyright year. */
|
|
27
30
|
copyrightYear: nonEmptyString,
|
|
31
|
+
/** Swift Package Manager dependencies. */
|
|
28
32
|
dependencies: z.array(pbxprojDependencySchema),
|
|
33
|
+
/** Bundle identifier (e.g. "com.example.app"). */
|
|
29
34
|
identifier: nonEmptyString,
|
|
35
|
+
/** Display name of the app or target. */
|
|
30
36
|
name: nonEmptyString,
|
|
37
|
+
/** Inferred operating systems with deployment targets. */
|
|
31
38
|
operatingSystems: stringArray,
|
|
39
|
+
/** Organization name from project attributes. */
|
|
32
40
|
organizationName: nonEmptyString,
|
|
41
|
+
/** Detected programming language (Swift or Objective-C). */
|
|
33
42
|
programmingLanguage: nonEmptyString,
|
|
43
|
+
/** Marketing version string. */
|
|
34
44
|
version: nonEmptyString
|
|
35
45
|
});
|
|
36
46
|
/** Xcode build variable pattern: $(VAR) or ${VAR}. */
|
|
@@ -71,8 +81,8 @@ const DEPLOYMENT_TARGETS = [
|
|
|
71
81
|
}
|
|
72
82
|
];
|
|
73
83
|
/**
|
|
74
|
-
* Parse a `.pbxproj` file into a structured object.
|
|
75
|
-
*
|
|
84
|
+
* Parse a `.pbxproj` file into a structured object. Returns undefined if the
|
|
85
|
+
* file is malformed or cannot be parsed.
|
|
76
86
|
*/
|
|
77
87
|
function parse(filePath) {
|
|
78
88
|
let project;
|
|
@@ -123,15 +133,15 @@ function parse(filePath) {
|
|
|
123
133
|
});
|
|
124
134
|
}
|
|
125
135
|
/**
|
|
126
|
-
* Get a string build setting, filtering out empty strings and unresolved
|
|
127
|
-
*
|
|
136
|
+
* Get a string build setting, filtering out empty strings and unresolved Xcode
|
|
137
|
+
* variable placeholders. Handles both string and numeric values.
|
|
128
138
|
*/
|
|
129
139
|
function cleanString(value) {
|
|
130
140
|
if (typeof value === "number") return String(value);
|
|
131
|
-
if (typeof value !== "string") return
|
|
141
|
+
if (typeof value !== "string") return;
|
|
132
142
|
const trimmed = value.trim();
|
|
133
|
-
if (trimmed.length === 0) return
|
|
134
|
-
if (XCODE_VARIABLE_RE.test(trimmed)) return
|
|
143
|
+
if (trimmed.length === 0) return;
|
|
144
|
+
if (XCODE_VARIABLE_RE.test(trimmed)) return;
|
|
135
145
|
return trimmed;
|
|
136
146
|
}
|
|
137
147
|
/**
|
|
@@ -2,11 +2,10 @@ import { Template } from "../metadata-types.js";
|
|
|
2
2
|
//#region src/lib/templates/codemeta-json.d.ts
|
|
3
3
|
type TemplateDataCodemetaJson = ReturnType<typeof codemetaJson>;
|
|
4
4
|
/**
|
|
5
|
-
* A JSON-friendly derivation of the `codemeta` template.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* JSON-LD.
|
|
5
|
+
* A JSON-friendly derivation of the `codemeta` template. Produces the same
|
|
6
|
+
* aggregated metadata but parses it through a strict schema,stripping JSON-LD
|
|
7
|
+
* artifacts (like `@context` and `@type`) to yield plain JSON suitable for
|
|
8
|
+
* consumption by tools that don't care to understand JSON-LD.
|
|
10
9
|
*
|
|
11
10
|
* This template also provides a handy baseline normalization abstraction for
|
|
12
11
|
* the other templates.
|
|
@@ -3,11 +3,10 @@ import { codeMetaJsonDataSchema } from "../sources/codemeta-json.js";
|
|
|
3
3
|
import { codemeta } from "./codemeta.js";
|
|
4
4
|
//#region src/lib/templates/codemeta-json.ts
|
|
5
5
|
/**
|
|
6
|
-
* A JSON-friendly derivation of the `codemeta` template.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* JSON-LD.
|
|
6
|
+
* A JSON-friendly derivation of the `codemeta` template. Produces the same
|
|
7
|
+
* aggregated metadata but parses it through a strict schema,stripping JSON-LD
|
|
8
|
+
* artifacts (like `@context` and `@type`) to yield plain JSON suitable for
|
|
9
|
+
* consumption by tools that don't care to understand JSON-LD.
|
|
11
10
|
*
|
|
12
11
|
* This template also provides a handy baseline normalization abstraction for
|
|
13
12
|
* the other templates.
|
|
@@ -13,14 +13,14 @@ import is from "@sindresorhus/is";
|
|
|
13
13
|
* ## Cascade strategy
|
|
14
14
|
*
|
|
15
15
|
* For **ecosystem-derived fields** (name, version, description, author,
|
|
16
|
-
* license, dependencies, keywords, …) the ecosystem manifest is canonical.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* license, dependencies, keywords, …) the ecosystem manifest is canonical. This
|
|
17
|
+
* keeps the output fresh when e.g. a new dependency is added to package.json,
|
|
18
|
+
* and makes the round-trip stable: generate → save as codemeta.json →
|
|
19
|
+
* regenerate → identical output.
|
|
20
20
|
*
|
|
21
21
|
* For **codemeta-specific fields** that only exist in codemeta.json
|
|
22
|
-
* (developmentStatus, funding, buildInstructions, …) the existing
|
|
23
|
-
*
|
|
22
|
+
* (developmentStatus, funding, buildInstructions, …) the existing codemeta.json
|
|
23
|
+
* is the source of truth.
|
|
24
24
|
*
|
|
25
25
|
* ## Software type inference
|
|
26
26
|
*
|
|
@@ -287,7 +287,6 @@ const codemeta = defineTemplate(({ arduinoLibraryProperties, cinderCinderblockXm
|
|
|
287
287
|
const releaseNotes = cm?.data.releaseNotes;
|
|
288
288
|
const installUrl = cm?.data.installUrl;
|
|
289
289
|
const relatedLink = cm?.data.relatedLink;
|
|
290
|
-
const targetProduct = void 0;
|
|
291
290
|
return stripUndefined({
|
|
292
291
|
"@context": "https://w3id.org/codemeta/3.0",
|
|
293
292
|
"@type": "SoftwareSourceCode",
|
|
@@ -325,15 +324,14 @@ const codemeta = defineTemplate(({ arduinoLibraryProperties, cinderCinderblockXm
|
|
|
325
324
|
softwareHelp,
|
|
326
325
|
softwareRequirements,
|
|
327
326
|
softwareSuggestions,
|
|
328
|
-
targetProduct,
|
|
327
|
+
targetProduct: void 0,
|
|
329
328
|
url,
|
|
330
329
|
version
|
|
331
330
|
});
|
|
332
331
|
});
|
|
333
332
|
/**
|
|
334
|
-
* Extract authors from a gemspec record.
|
|
335
|
-
*
|
|
336
|
-
* We pair them by index where possible.
|
|
333
|
+
* Extract authors from a gemspec record. Gemspec has `authors: string[]` and a
|
|
334
|
+
* separate `email: string | string[]`. We pair them by index where possible.
|
|
337
335
|
*/
|
|
338
336
|
function gemspecAuthors(gem) {
|
|
339
337
|
if (gem === void 0) return [];
|
|
@@ -344,9 +342,9 @@ function gemspecAuthors(gem) {
|
|
|
344
342
|
}));
|
|
345
343
|
}
|
|
346
344
|
/**
|
|
347
|
-
* Takes ecosystem persons (which may include undefined) and codemeta fallback
|
|
348
|
-
* Uses ecosystem if any are present, otherwise falls back.
|
|
349
|
-
*
|
|
345
|
+
* Takes ecosystem persons (which may include undefined) and codemeta fallback
|
|
346
|
+
* persons. Uses ecosystem if any are present, otherwise falls back. Always
|
|
347
|
+
* deduplicates by name.
|
|
350
348
|
*/
|
|
351
349
|
function resolvePersonsOrOrgs(ecosystemPersons, fallbackPersons) {
|
|
352
350
|
const ecosystem = ecosystemPersons.filter((p) => p !== void 0);
|
|
@@ -389,11 +387,12 @@ function collectDevelopmentDeps(sources) {
|
|
|
389
387
|
* Convert a Record<name, version> dependency map to CodemetaDependencyLd[].
|
|
390
388
|
*/
|
|
391
389
|
function objectEntriesToDeps(deps) {
|
|
392
|
-
if (deps === void 0) return
|
|
390
|
+
if (deps === void 0) return;
|
|
393
391
|
return Object.entries(deps).map(([depName, depVersion]) => toDependencyLd(depName, depVersion));
|
|
394
392
|
}
|
|
395
393
|
/**
|
|
396
|
-
* Parse a PEP 508 dependency string ("package>=1.0") into a
|
|
394
|
+
* Parse a PEP 508 dependency string ("package>=1.0") into a
|
|
395
|
+
* CodemetaDependencyLd.
|
|
397
396
|
*/
|
|
398
397
|
function parsePep508Dep(dep) {
|
|
399
398
|
const trimmed = dep.trim();
|
|
@@ -408,7 +407,7 @@ function parsePep508Dep(dep) {
|
|
|
408
407
|
* Extract URL from package.json repository field (string or {url}).
|
|
409
408
|
*/
|
|
410
409
|
function repositoryUrlFromPackageJson(repository) {
|
|
411
|
-
if (repository === void 0) return
|
|
410
|
+
if (repository === void 0) return;
|
|
412
411
|
if (typeof repository === "string") return repository;
|
|
413
412
|
return repository.url;
|
|
414
413
|
}
|
|
@@ -416,7 +415,7 @@ function repositoryUrlFromPackageJson(repository) {
|
|
|
416
415
|
* Extract URL from package.json bugs field.
|
|
417
416
|
*/
|
|
418
417
|
function bugsUrlFromPackageJson(bugs) {
|
|
419
|
-
if (bugs === void 0) return
|
|
418
|
+
if (bugs === void 0) return;
|
|
420
419
|
return bugs.url;
|
|
421
420
|
}
|
|
422
421
|
/**
|
|
@@ -427,11 +426,11 @@ function firstPomLicense(pom) {
|
|
|
427
426
|
return pomLicense?.name ?? pomLicense?.url;
|
|
428
427
|
}
|
|
429
428
|
/**
|
|
430
|
-
* Resolve Python pyproject.toml license field to a string.
|
|
431
|
-
*
|
|
429
|
+
* Resolve Python pyproject.toml license field to a string. Can be a string
|
|
430
|
+
* (SPDX ID) or `{ spdx?: string; text?: string; file?: string }`.
|
|
432
431
|
*/
|
|
433
432
|
function resolvePythonLicense(pythonLicense) {
|
|
434
|
-
if (pythonLicense === void 0) return
|
|
433
|
+
if (pythonLicense === void 0) return;
|
|
435
434
|
if (typeof pythonLicense === "string") return pythonLicense;
|
|
436
435
|
return pythonLicense.spdx ?? pythonLicense.text;
|
|
437
436
|
}
|
|
@@ -439,7 +438,7 @@ function resolvePythonLicense(pythonLicense) {
|
|
|
439
438
|
* Resolve codemeta license field (string or string[]) to first string.
|
|
440
439
|
*/
|
|
441
440
|
function resolveCmLicense(cmLicense) {
|
|
442
|
-
if (cmLicense === void 0) return
|
|
441
|
+
if (cmLicense === void 0) return;
|
|
443
442
|
return Array.isArray(cmLicense) ? cmLicense[0] : cmLicense;
|
|
444
443
|
}
|
|
445
444
|
/**
|
|
@@ -454,10 +453,11 @@ function deduplicateStrings(strings) {
|
|
|
454
453
|
return [...seen.values()];
|
|
455
454
|
}
|
|
456
455
|
/**
|
|
457
|
-
* Case-insensitive lookup in a string record (e.g. pyproject.toml
|
|
456
|
+
* Case-insensitive lookup in a string record (e.g. pyproject.toml
|
|
457
|
+
* `[project.urls]`).
|
|
458
458
|
*/
|
|
459
459
|
function caseInsensitiveLookup(record, key) {
|
|
460
|
-
if (record === void 0) return
|
|
460
|
+
if (record === void 0) return;
|
|
461
461
|
const lowerKey = key.toLowerCase();
|
|
462
462
|
for (const [k, v] of Object.entries(record)) if (k.toLowerCase() === lowerKey) return v;
|
|
463
463
|
}
|
|
@@ -466,7 +466,7 @@ function caseInsensitiveLookup(record, key) {
|
|
|
466
466
|
* homepage URLs derived from repository URLs.
|
|
467
467
|
*/
|
|
468
468
|
function stripReadmeFragment(url) {
|
|
469
|
-
if (url === void 0) return
|
|
469
|
+
if (url === void 0) return;
|
|
470
470
|
return url.endsWith("#readme") ? url.slice(0, -7) : url;
|
|
471
471
|
}
|
|
472
472
|
/**
|
|
@@ -474,19 +474,19 @@ function stripReadmeFragment(url) {
|
|
|
474
474
|
* CodeMeta dates are `schema:Date`, not `schema:DateTime`.
|
|
475
475
|
*/
|
|
476
476
|
function toDateOnly(value) {
|
|
477
|
-
if (value === void 0) return
|
|
477
|
+
if (value === void 0) return;
|
|
478
478
|
if (DATE_ONLY_REGEX.test(value)) return value;
|
|
479
479
|
const match = DATETIME_DATE_REGEX.exec(value);
|
|
480
480
|
if (match) return match[1];
|
|
481
481
|
return value;
|
|
482
482
|
}
|
|
483
483
|
/**
|
|
484
|
-
* Build a URL for the project's README.
|
|
485
|
-
*
|
|
486
|
-
*
|
|
484
|
+
* Build a URL for the project's README. Prefers a web URL on the remote service
|
|
485
|
+
* (e.g. GitHub blob link) when a code repository URL is available, otherwise
|
|
486
|
+
* falls back to the local source path.
|
|
487
487
|
*/
|
|
488
488
|
function readmeUrl(readmeRecord, repoUrl, defaultBranch, basePath) {
|
|
489
|
-
if (readmeRecord === void 0) return
|
|
489
|
+
if (readmeRecord === void 0) return;
|
|
490
490
|
const repoRelativePath = basePath === void 0 ? basename(readmeRecord.source) : relative(basePath, readmeRecord.source).replaceAll("\\", "/");
|
|
491
491
|
if (is.nonEmptyStringAndNotWhitespace(repoUrl) && repoUrl.includes("github.com")) {
|
|
492
492
|
const branch = defaultBranch ?? "main";
|
|
@@ -2,8 +2,8 @@ import { Template } from "../metadata-types.js";
|
|
|
2
2
|
//#region src/lib/templates/metadata.d.ts
|
|
3
3
|
type TemplateDataMetadata = ReturnType<typeof metadata>;
|
|
4
4
|
/**
|
|
5
|
-
* A minimal metadata template for populating a GitHub repository's
|
|
6
|
-
*
|
|
5
|
+
* A minimal metadata template for populating a GitHub repository's description,
|
|
6
|
+
* homepage, and topics via metadata.json / metadata.yaml.
|
|
7
7
|
*
|
|
8
8
|
* Builds on the codemeta template for baseline values, then lets any
|
|
9
9
|
* metadata.json source fields override the result.
|
|
@@ -6,15 +6,15 @@ import { codemetaJson } from "./codemeta-json.js";
|
|
|
6
6
|
* Strip `git+` prefix and `.git` suffix from a URL.
|
|
7
7
|
*/
|
|
8
8
|
function normalizeGitUrl(url) {
|
|
9
|
-
if (url === void 0) return
|
|
9
|
+
if (url === void 0) return;
|
|
10
10
|
let normalized = url;
|
|
11
11
|
if (normalized.startsWith("git+")) normalized = normalized.slice(4);
|
|
12
12
|
if (normalized.endsWith(".git")) normalized = normalized.slice(0, -4);
|
|
13
13
|
return normalized;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* A minimal metadata template for populating a GitHub repository's
|
|
17
|
-
*
|
|
16
|
+
* A minimal metadata template for populating a GitHub repository's description,
|
|
17
|
+
* homepage, and topics via metadata.json / metadata.yaml.
|
|
18
18
|
*
|
|
19
19
|
* Builds on the codemeta template for baseline values, then lets any
|
|
20
20
|
* metadata.json source fields override the result.
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Helpers for building codemeta JSON-LD objects.
|
|
4
4
|
*
|
|
5
|
-
* Provides type-safe constructors for Person/Organization and
|
|
6
|
-
* dependency nodes, plus deduplication and license URL
|
|
5
|
+
* Provides type-safe constructors for Person/Organization and
|
|
6
|
+
* SoftwareApplication dependency nodes, plus deduplication and license URL
|
|
7
|
+
* normalization.
|
|
7
8
|
*/
|
|
8
9
|
/**
|
|
9
10
|
* An Organization node in codemeta JSON-LD.
|