metascope 0.6.3 → 0.7.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.
Files changed (66) hide show
  1. package/dist/bin/chunk-Bdh3yLIe.js +1 -0
  2. package/dist/bin/cli.js +282 -281
  3. package/dist/bin/dns-CUigd8AG.js +1 -0
  4. package/dist/bin/{jiti-D2Njwwqq.js → jiti-BTBDwj9g.js} +2 -2
  5. package/dist/bin/renovate-DecR7mby.js +1 -0
  6. package/dist/bin/shared-C_yS1qGF.js +5 -0
  7. package/dist/lib/file-matching.js +20 -13
  8. package/dist/lib/log.d.ts +6 -4
  9. package/dist/lib/log.js +5 -3
  10. package/dist/lib/metadata-types.d.ts +33 -21
  11. package/dist/lib/metadata-types.js +8 -9
  12. package/dist/lib/metadata.js +7 -7
  13. package/dist/lib/package.js +1 -1
  14. package/dist/lib/parsers/gemspec-parser.js +16 -14
  15. package/dist/lib/parsers/go-mod-parser.js +13 -10
  16. package/dist/lib/parsers/makefile-config-parser.js +20 -17
  17. package/dist/lib/parsers/properties-parser.js +3 -3
  18. package/dist/lib/parsers/rfc822-header-parser.js +4 -4
  19. package/dist/lib/parsers/setup-py-parser.js +3 -4
  20. package/dist/lib/source.d.ts +1 -0
  21. package/dist/lib/source.js +5 -4
  22. package/dist/lib/sources/arduino-library-properties.js +32 -15
  23. package/dist/lib/sources/cinder-cinderblock-xml.js +21 -9
  24. package/dist/lib/sources/codemeta-json.js +24 -20
  25. package/dist/lib/sources/dependency-updates.js +12 -23
  26. package/dist/lib/sources/git-stats.js +1 -1
  27. package/dist/lib/sources/github-actions.js +9 -2
  28. package/dist/lib/sources/github.js +1 -1
  29. package/dist/lib/sources/go-goreleaser-yaml.js +5 -4
  30. package/dist/lib/sources/java-pom-xml.js +38 -19
  31. package/dist/lib/sources/license-file.d.ts +1 -4
  32. package/dist/lib/sources/license-file.js +1 -4
  33. package/dist/lib/sources/metadata-file.js +15 -12
  34. package/dist/lib/sources/node-npm-registry.js +1 -1
  35. package/dist/lib/sources/openframeworks-addon-config-mk.js +7 -0
  36. package/dist/lib/sources/openframeworks-install-xml.js +24 -14
  37. package/dist/lib/sources/processing-library-properties.js +25 -10
  38. package/dist/lib/sources/processing-sketch-properties.js +51 -7
  39. package/dist/lib/sources/publiccode-yaml.js +37 -5
  40. package/dist/lib/sources/python-pkg-info.js +2 -2
  41. package/dist/lib/sources/python-setup-cfg.js +2 -2
  42. package/dist/lib/sources/readme-file.js +9 -2
  43. package/dist/lib/sources/ruby-gemspec.js +1 -0
  44. package/dist/lib/sources/rust-cargo-toml.js +29 -10
  45. package/dist/lib/sources/xcode-info-plist.js +48 -24
  46. package/dist/lib/sources/xcode-project-pbxproj.js +22 -12
  47. package/dist/lib/templates/codemeta-json.d.ts +4 -5
  48. package/dist/lib/templates/codemeta-json.js +4 -5
  49. package/dist/lib/templates/codemeta.js +30 -30
  50. package/dist/lib/templates/frontmatter.d.ts +1 -1
  51. package/dist/lib/templates/index.d.ts +1 -1
  52. package/dist/lib/templates/metadata.d.ts +2 -2
  53. package/dist/lib/templates/metadata.js +3 -3
  54. package/dist/lib/utilities/codemeta-helpers.d.ts +3 -2
  55. package/dist/lib/utilities/codemeta-helpers.js +14 -12
  56. package/dist/lib/utilities/fetch.js +2 -2
  57. package/dist/lib/utilities/formatting.js +4 -3
  58. package/dist/lib/utilities/github.js +3 -3
  59. package/dist/lib/utilities/license-identification.d.ts +25 -0
  60. package/dist/lib/utilities/license-identification.js +132 -29
  61. package/dist/lib/utilities/schema-primitives.js +11 -10
  62. package/dist/lib/utilities/template-helpers.js +3 -3
  63. package/package.json +19 -18
  64. package/readme.md +23 -19
  65. package/dist/.DS_Store +0 -0
  66. package/dist/bin/chunk-BjEoQXZ0.js +0 -1
@@ -7,12 +7,19 @@ import { resolve } from "node:path";
7
7
  import { z } from "zod";
8
8
  //#region src/lib/sources/openframeworks-addon-config-mk.ts
9
9
  const openframeworksAddonConfigSchema = z.object({
10
+ /** `ADDON_AUTHOR` from `meta:` section. */
10
11
  author: nonEmptyString,
12
+ /** `ADDON_DEPENDENCIES` from `common:` section (space-separated addon names). */
11
13
  dependencies: stringArray,
14
+ /** `ADDON_DESCRIPTION` from `meta:` section. */
12
15
  description: nonEmptyString,
16
+ /** `ADDON_NAME` from `meta:` section. */
13
17
  name: nonEmptyString,
18
+ /** Platform section names that contain at least one variable assignment. */
14
19
  platformSections: stringArray,
20
+ /** `ADDON_TAGS` from `meta:` section (quote-aware tokenized). */
15
21
  tags: stringArray,
22
+ /** `ADDON_URL` from `meta:` section. */
16
23
  url: optionalUrl
17
24
  });
18
25
  /**
@@ -19,19 +19,29 @@ import { XMLParser } from "fast-xml-parser";
19
19
  * content is actually an openFrameworks addon by checking for the `<install>`
20
20
  * root element and the presence of "addons" in the file content.
21
21
  *
22
- * Uses `fast-xml-parser` with attribute parsing enabled to read `<lib os="...">`
23
- * attributes for operating system inference.
22
+ * Uses `fast-xml-parser` with attribute parsing enabled to read `<lib
23
+ * os="...">` attributes for operating system inference.
24
24
  */
25
25
  const openframeworksInstallXmlSchema = z.object({
26
+ /** Addon author name. */
26
27
  author: nonEmptyString,
28
+ /** Source code repository URL. */
27
29
  codeUrl: optionalUrl,
30
+ /** Description of the addon. */
28
31
  description: nonEmptyString,
32
+ /** Download URL. */
29
33
  downloadUrl: optionalUrl,
34
+ /** Addon display name. */
30
35
  name: nonEmptyString,
36
+ /** Supported operating systems from `<lib os="...">` attributes. */
31
37
  operatingSystems: stringArray,
38
+ /** Software dependencies from `<requires>` elements. */
32
39
  requirements: stringArray,
40
+ /** Website URL. */
33
41
  siteUrl: optionalUrl,
42
+ /** Generic URL (used when no code_url / site_url provided). */
34
43
  url: optionalUrl,
44
+ /** Version string. */
35
45
  version: nonEmptyString
36
46
  });
37
47
  /**
@@ -43,9 +53,9 @@ const LIB_OS_MAP = {
43
53
  win32: "Windows"
44
54
  };
45
55
  /**
46
- * Parse a legacy openFrameworks `install.xml` content string into a structured object.
47
- * Returns undefined if the XML is malformed, missing the `<install>` root element,
48
- * or does not appear to be an openFrameworks addon.
56
+ * Parse a legacy openFrameworks `install.xml` content string into a structured
57
+ * object. Returns undefined if the XML is malformed, missing the `<install>`
58
+ * root element, or does not appear to be an openFrameworks addon.
49
59
  */
50
60
  function parse(content) {
51
61
  if (!content.toLowerCase().includes("addons")) return;
@@ -58,12 +68,12 @@ function parse(content) {
58
68
  let data;
59
69
  try {
60
70
  const parsed = parser.parse(fixedContent);
61
- if (!is.plainObject(parsed)) return void 0;
71
+ if (!is.plainObject(parsed)) return;
62
72
  data = parsed;
63
73
  } catch {
64
74
  return;
65
75
  }
66
- if (!is.plainObject(data.install)) return void 0;
76
+ if (!is.plainObject(data.install)) return;
67
77
  const { install } = data;
68
78
  return openframeworksInstallXmlSchema.parse({
69
79
  author: getString(install.author),
@@ -79,17 +89,17 @@ function parse(content) {
79
89
  });
80
90
  }
81
91
  /**
82
- * Get a trimmed non-empty string from a parsed XML value.
83
- * Returns undefined for empty strings, non-strings, or whitespace-only values.
92
+ * Get a trimmed non-empty string from a parsed XML value. Returns undefined for
93
+ * empty strings, non-strings, or whitespace-only values.
84
94
  */
85
95
  function getString(value) {
86
- if (typeof value !== "string") return void 0;
96
+ if (typeof value !== "string") return;
87
97
  const trimmed = value.trim();
88
98
  return trimmed.length > 0 ? trimmed : void 0;
89
99
  }
90
100
  /**
91
- * Extract software requirements from `<requires>`.
92
- * Handles three variants:
101
+ * Extract software requirements from `<requires>`. Handles three variants:
102
+ *
93
103
  * 1. Empty — skip
94
104
  * 2. Free text — emit as-is
95
105
  * 3. Structured `<addon>` children — emit each separately
@@ -112,8 +122,8 @@ function parseRequirements(install) {
112
122
  return [];
113
123
  }
114
124
  /**
115
- * Extract operating system information from `<lib os="...">` attributes
116
- * found within `<add><link>` sections.
125
+ * Extract operating system information from `<lib os="...">` attributes found
126
+ * within `<add><link>` sections.
117
127
  */
118
128
  function parseOperatingSystems(install) {
119
129
  if (!is.plainObject(install.add)) return [];
@@ -35,23 +35,38 @@ const CANONICAL_CATEGORIES = [
35
35
  const CATEGORY_MAP = new Map(CANONICAL_CATEGORIES.map((cat) => [cat.replaceAll(/[^a-z]/gi, "").toLowerCase(), cat]));
36
36
  CATEGORY_MAP.set("3d", "3D");
37
37
  const processingLibraryPropertiesSchema = z.object({
38
+ /** Parsed author entries with optional URLs. */
38
39
  authors: z.array(processingLibraryPropertiesAuthorEntrySchema),
40
+ /** Normalized categories. */
39
41
  categories: z.array(z.enum(CANONICAL_CATEGORIES)),
42
+ /** Direct download URL for the .zip distribution. */
40
43
  download: optionalUrl,
44
+ /** Numeric identifier assigned by Processing contribution manager. */
41
45
  id: nonEmptyString,
46
+ /** Maximum Processing revision, or 0 for no upper constraint. */
42
47
  maxRevision: z.number(),
48
+ /** Minimum Processing revision, or 0 for no lower constraint. */
43
49
  minRevision: z.number(),
50
+ /** Library name. */
44
51
  name: nonEmptyString,
52
+ /** Extended description paragraph. */
45
53
  paragraph: nonEmptyString,
54
+ /** Human-readable version string. */
46
55
  prettyVersion: nonEmptyString,
56
+ /** Raw key-value pairs. */
47
57
  raw: z.record(z.string(), z.string()),
58
+ /** One-sentence description. */
48
59
  sentence: nonEmptyString,
60
+ /** Contribution type (library, tool, mode, examples). */
49
61
  type: nonEmptyString,
62
+ /** Project URL. */
50
63
  url: optionalUrl,
64
+ /** Integer release counter. */
51
65
  version: z.number()
52
66
  });
53
67
  /**
54
- * Parse a Processing `library.properties` content string into a structured object.
68
+ * Parse a Processing `library.properties` content string into a structured
69
+ * object.
55
70
  */
56
71
  function parse(content) {
57
72
  const raw = parseProperties(content);
@@ -86,28 +101,28 @@ function get(raw, key) {
86
101
  }
87
102
  /** Return a trimmed string, or undefined if empty/whitespace-only. */
88
103
  function nonEmpty(value) {
89
- if (value === void 0) return void 0;
104
+ if (value === void 0) return;
90
105
  const trimmed = value.trim();
91
106
  return trimmed.length > 0 ? trimmed : void 0;
92
107
  }
93
108
  /**
94
- * Strip trailing inline comments from a value.
95
- * Matches the pattern ` # comment text` (space-hash-space).
109
+ * Strip trailing inline comments from a value. Matches the pattern ` # comment
110
+ * text` (space-hash-space).
96
111
  */
97
112
  function stripInlineComment(value) {
98
113
  const index = value.indexOf(" # ");
99
114
  return index === -1 ? value : value.slice(0, index).trim();
100
115
  }
101
116
  /**
102
- * Unescape backslash-escaped colons in URLs.
103
- * Some Processing fixtures use `https\://` instead of `https://`.
117
+ * Unescape backslash-escaped colons in URLs. Some Processing fixtures use
118
+ * `https\://` instead of `https://`.
104
119
  */
105
120
  function unescapeUrl(value) {
106
121
  return value.replaceAll(String.raw`\:`, ":");
107
122
  }
108
123
  /**
109
- * Parse a Processing authors/authorList value into AuthorEntry[].
110
- * Preserves original order of appearance.
124
+ * Parse a Processing authors/authorList value into AuthorEntry[]. Preserves
125
+ * original order of appearance.
111
126
  */
112
127
  function parseAuthors(value) {
113
128
  const trimmed = value.trim();
@@ -149,8 +164,8 @@ function parseAuthors(value) {
149
164
  return results;
150
165
  }
151
166
  /**
152
- * Split plain text on ` and `, `,`, `&` to extract author names.
153
- * Filters out bare "others" entries.
167
+ * Split plain text on `and`, `,`, `&` to extract author names. Filters out bare
168
+ * "others" entries.
154
169
  */
155
170
  function addPlainAuthors(text, results) {
156
171
  const parts = text.split(AUTHOR_SEPARATOR_REGEX).map((s) => s.trim()).filter((s) => s.length > 0 && s.toLowerCase() !== "others");
@@ -13,34 +13,78 @@ const processingSketchPropertiesAuthorEntrySchema = z.object({
13
13
  url: z.string().optional()
14
14
  });
15
15
  const processingSketchPropertiesSchema = z.object({
16
+ /**
17
+ * Parsed author entries with optional URLs. _Unofficial: borrowed from
18
+ * library.properties_
19
+ */
16
20
  authors: z.array(processingSketchPropertiesAuthorEntrySchema),
21
+ /** Contributed component type. */
17
22
  component: nonEmptyString,
23
+ /** Direct download URL. _Unofficial: borrowed from library.properties_ */
18
24
  download: optionalUrl,
25
+ /** Primary .pde filename for the sketch. */
19
26
  main: nonEmptyString,
27
+ /** Android app label. From `manifest.label`. */
20
28
  manifestLabel: nonEmptyString,
29
+ /**
30
+ * Android screen orientation, e.g. "unspecified". From
31
+ * `manifest.orientation`.
32
+ */
21
33
  manifestOrientation: nonEmptyString,
34
+ /** Android package name. From `manifest.package`. */
22
35
  manifestPackage: nonEmptyString,
36
+ /** Android permission list. From `manifest.permissions`. */
23
37
  manifestPermissions: z.array(z.string()),
38
+ /** Android minimum SDK level. From `manifest.sdk.min`. */
24
39
  manifestSdkMin: z.number().optional(),
40
+ /** Android target SDK level. From `manifest.sdk.target`. */
25
41
  manifestSdkTarget: z.number().optional(),
42
+ /** Android version code integer. From `manifest.version.code`. */
26
43
  manifestVersionCode: z.number().optional(),
44
+ /** Android version name string. From `manifest.version.name`. */
27
45
  manifestVersionName: nonEmptyString,
46
+ /**
47
+ * Maximum Processing revision, or 0 for no upper constraint. _Unofficial:
48
+ * borrowed from library.properties_
49
+ */
28
50
  maxRevision: z.number(),
51
+ /**
52
+ * Minimum Processing revision, or 0 for no lower constraint. _Unofficial:
53
+ * borrowed from library.properties_
54
+ */
29
55
  minRevision: z.number(),
56
+ /** Mode display name, e.g. "Java", "REPL Mode". */
30
57
  mode: nonEmptyString,
58
+ /** Mode identifier, e.g. "processing.mode.java.JavaMode". From `mode.id`. */
31
59
  modeId: nonEmptyString,
60
+ /** Sketch name. _Unofficial: borrowed from library.properties_ */
32
61
  name: nonEmptyString,
62
+ /**
63
+ * Extended description paragraph. _Unofficial: borrowed from
64
+ * library.properties_
65
+ */
33
66
  paragraph: nonEmptyString,
67
+ /**
68
+ * Human-readable version string. _Unofficial: borrowed from
69
+ * library.properties_
70
+ */
34
71
  prettyVersion: nonEmptyString,
72
+ /** Raw key-value pairs. */
35
73
  raw: z.record(z.string(), z.string()),
74
+ /** One-sentence description. _Unofficial: borrowed from library.properties_ */
36
75
  sentence: nonEmptyString,
76
+ /** Templates string. */
37
77
  templates: nonEmptyString,
78
+ /** Project URL. _Unofficial: borrowed from library.properties_ */
38
79
  url: optionalUrl,
80
+ /** Integer release counter. _Unofficial: borrowed from library.properties_ */
39
81
  version: z.number(),
82
+ /** Zip file name for contributed content. */
40
83
  zipfilename: nonEmptyString
41
84
  });
42
85
  /**
43
- * Parse a Processing `sketch.properties` content string into a structured object.
86
+ * Parse a Processing `sketch.properties` content string into a structured
87
+ * object.
44
88
  */
45
89
  function parse(content) {
46
90
  const raw = parseProperties(content);
@@ -89,13 +133,13 @@ function parse(content) {
89
133
  }
90
134
  /** Return a trimmed string, or undefined if empty/whitespace-only. */
91
135
  function nonEmpty(value) {
92
- if (value === void 0) return void 0;
136
+ if (value === void 0) return;
93
137
  const trimmed = value.trim();
94
138
  return trimmed.length > 0 ? trimmed : void 0;
95
139
  }
96
140
  /**
97
- * Strip trailing inline comments from a value.
98
- * Matches the pattern ` # comment text` (space-hash-space).
141
+ * Strip trailing inline comments from a value. Matches the pattern ` # comment
142
+ * text` (space-hash-space).
99
143
  */
100
144
  function stripInlineComment(value) {
101
145
  const index = value.indexOf(" # ");
@@ -150,7 +194,7 @@ function parseAuthors(value) {
150
194
  return results;
151
195
  }
152
196
  /**
153
- * Split plain text on ` and `, `,`, `&` to extract author names.
197
+ * Split plain text on `and`, `,`, `&` to extract author names.
154
198
  */
155
199
  function addPlainAuthors(text, results) {
156
200
  const parts = text.split(AUTHOR_SEPARATOR_REGEX).map((s) => s.trim()).filter((s) => s.length > 0 && s.toLowerCase() !== "others");
@@ -160,8 +204,8 @@ function addPlainAuthors(text, results) {
160
204
  });
161
205
  }
162
206
  /**
163
- * Validate that a sketch.properties file is a Processing sketch.
164
- * Checks for at least one known Processing sketch key.
207
+ * Validate that a sketch.properties file is a Processing sketch. Checks for at
208
+ * least one known Processing sketch key.
165
209
  */
166
210
  function isProcessingSketchProperties(content) {
167
211
  const raw = parseProperties(content);
@@ -10,8 +10,8 @@ import { parse } from "yaml";
10
10
  * Source and parser for `publiccode.yml` / `publiccode.yaml` files.
11
11
  *
12
12
  * Publiccode.yml is a metadata standard for public software repositories,
13
- * primarily used in Europe (Italy, Netherlands, etc.).
14
- * See: https://yml.publiccode.tools/
13
+ * primarily used in Europe (Italy, Netherlands, etc.). See:
14
+ * https://yml.publiccode.tools/
15
15
  *
16
16
  * Extracts project metadata including name, version, license, contacts,
17
17
  * multi-language descriptions, dependencies, and categorization.
@@ -48,34 +48,63 @@ const publiccodeDescriptionSchema = z.object({
48
48
  shortDescription: z.string().optional()
49
49
  });
50
50
  const publiccodeSchema = z.object({
51
+ /** Application suite this software belongs to. */
51
52
  applicationSuite: nonEmptyString,
53
+ /** Available localization languages (BCP 47). */
52
54
  availableLanguages: stringArray,
55
+ /** Software categories (e.g. "it-security", "cloud-management"). */
53
56
  categories: stringArray,
57
+ /** Maintenance contacts. */
54
58
  contacts: z.array(publiccodeContactEntrySchema),
59
+ /** Maintenance contractors. */
55
60
  contractors: z.array(publiccodeContractorEntrySchema),
61
+ /** Software dependencies (open, proprietary, hardware). */
56
62
  dependencies: z.array(publiccodeDependencyEntrySchema),
63
+ /** Preferred description (English if available, else first language). */
57
64
  description: publiccodeDescriptionSchema.optional(),
65
+ /** All localized descriptions keyed by language code. */
58
66
  descriptions: z.record(z.string(), publiccodeDescriptionSchema),
67
+ /** Development status (concept, development, beta, stable, obsolete). */
59
68
  developmentStatus: nonEmptyString,
69
+ /** Supported input MIME types. */
60
70
  inputTypes: stringArray,
71
+ /** URL of upstream software this is based on. */
61
72
  isBasedOn: optionalUrl,
73
+ /** Landing page URL. */
62
74
  landingUrl: optionalUrl,
75
+ /** SPDX license expression. */
63
76
  license: nonEmptyString,
77
+ /** Whether the software supports localization. */
64
78
  localisationReady: z.boolean().optional(),
79
+ /** Path or URL to logo image. */
65
80
  logo: optionalUrl,
81
+ /** Main copyright holder. */
66
82
  mainCopyrightOwner: nonEmptyString,
83
+ /** Maintenance type (internal, community, contract, none). */
67
84
  maintenanceType: nonEmptyString,
85
+ /** Path or URL to monochrome logo image. */
68
86
  monochromeLogo: optionalUrl,
87
+ /** Software name. */
69
88
  name: nonEmptyString,
89
+ /** Supported output MIME types. */
70
90
  outputTypes: stringArray,
91
+ /** Supported platforms (e.g. "web", "linux", "mac"). */
71
92
  platforms: stringArray,
93
+ /** The publiccode.yml schema version. */
72
94
  publiccodeYmlVersion: nonEmptyString,
95
+ /** Release date (YYYY-MM-DD). */
73
96
  releaseDate: nonEmptyString,
97
+ /** Repository owner name. */
74
98
  repoOwner: nonEmptyString,
99
+ /** Roadmap URL. */
75
100
  roadmap: optionalUrl,
101
+ /** Software type (e.g. "standalone/web", "standalone/other"). */
76
102
  softwareType: nonEmptyString,
103
+ /** Software version string. */
77
104
  softwareVersion: nonEmptyString,
105
+ /** Repository URL. */
78
106
  url: optionalUrl,
107
+ /** Organizations using this software. */
79
108
  usedBy: stringArray
80
109
  });
81
110
  /** Coerce YAML values that may be parsed as non-strings back to strings. */
@@ -115,8 +144,11 @@ function parseDescription(data) {
115
144
  }
116
145
  /**
117
146
  * Parse a publiccode.yml / publiccode.yaml file content.
147
+ *
118
148
  * @param content - Raw YAML file content.
119
- * @returns Parsed publiccode metadata, or `undefined` if the content is invalid.
149
+ *
150
+ * @returns Parsed publiccode metadata, or `undefined` if the content is
151
+ * invalid.
120
152
  */
121
153
  function parse$1(content) {
122
154
  let data;
@@ -125,8 +157,8 @@ function parse$1(content) {
125
157
  } catch {
126
158
  return;
127
159
  }
128
- if (!isPlainObject(data)) return void 0;
129
- if (!isNonEmptyString(data.name) && !isNonEmptyString(data.url)) return void 0;
160
+ if (!isPlainObject(data)) return;
161
+ if (!isNonEmptyString(data.name) && !isNonEmptyString(data.url)) return;
130
162
  const descriptions = {};
131
163
  let description;
132
164
  if (isPlainObject(data.description)) {
@@ -51,8 +51,8 @@ const HEADER_MAP = {
51
51
  * Parse a PKG-INFO or METADATA file and return structured metadata.
52
52
  *
53
53
  * Handles RFC 822-style headers with multi-value fields (Classifier,
54
- * Requires-Dist, Project-URL, Platform), continuation lines, and
55
- * the body section as long_description.
54
+ * Requires-Dist, Project-URL, Platform), continuation lines, and the body
55
+ * section as long_description.
56
56
  */
57
57
  function parse(source) {
58
58
  const headers = parseRfc822Headers(source);
@@ -43,8 +43,8 @@ const STRING_ATTRS = new Set([
43
43
  /**
44
44
  * Parse a setup.cfg file and return structured metadata.
45
45
  *
46
- * Extracts fields from the `[metadata]` and `[options]` sections,
47
- * including multi-line values like classifiers and install_requires.
46
+ * Extracts fields from the `[metadata]` and `[options]` sections, including
47
+ * multi-line values like classifiers and install_requires.
48
48
  */
49
49
  function parse(source) {
50
50
  const sections = parseConfigparser(source);
@@ -8,7 +8,9 @@ import remarkParse from "remark-parse";
8
8
  import { unified } from "unified";
9
9
  //#region src/lib/sources/readme-file.ts
10
10
  const readmeSchema = z.object({
11
+ /** YAML frontmatter key-value pairs, if present. */
11
12
  frontmatter: z.record(z.string(), z.unknown()).optional(),
13
+ /** Project name extracted from the first H1 heading. */
12
14
  name: z.string()
13
15
  });
14
16
  /**
@@ -21,7 +23,10 @@ function extractText(nodes) {
21
23
  return "";
22
24
  }).join("").trim();
23
25
  }
24
- /** Reusable markdown parser — processor config is stateless, only the AST is per-call. */
26
+ /**
27
+ * Reusable markdown parser — processor config is stateless, only the AST is
28
+ * per-call.
29
+ */
25
30
  const markdownParser = unified().use(remarkParse);
26
31
  /**
27
32
  * Extract the text content of the first H1 heading from markdown.
@@ -35,13 +40,15 @@ function extractFirstH1(markdown) {
35
40
  }
36
41
  /**
37
42
  * Parse a README file's content.
43
+ *
38
44
  * @param content - Raw file content (markdown).
45
+ *
39
46
  * @returns Parsed metadata, or `undefined` if no H1 heading is found.
40
47
  */
41
48
  function parse(content) {
42
49
  const { content: markdown, data } = matter(content);
43
50
  const name = extractFirstH1(markdown);
44
- if (!name) return void 0;
51
+ if (!name) return;
45
52
  return readmeSchema.parse({
46
53
  frontmatter: Object.keys(data).length > 0 ? data : void 0,
47
54
  name
@@ -21,6 +21,7 @@ const gemSpecSchema = z.object({
21
21
  email: z.union([z.string(), z.array(z.string())]).optional(),
22
22
  executables: stringArray,
23
23
  extensions: stringArray,
24
+ /** Any attributes not explicitly modeled above */
24
25
  extra: z.record(z.string(), z.unknown()),
25
26
  extra_rdoc_files: stringArray,
26
27
  files: stringArray,
@@ -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
- * 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]`.
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
- * Returns undefined if the TOML is malformed.
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 void 0;
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 void 0;
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
- * Handles both `dep = "version"` and `dep = { version = "..." }` forms.
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 = [];