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.
Files changed (111) hide show
  1. package/dist/.DS_Store +0 -0
  2. package/dist/bin/cli.js +14 -14
  3. package/dist/lib/{chunk-DrSxFLj_.js → _virtual/_rolldown/runtime.js} +1 -1
  4. package/dist/lib/file-matching.js +152 -0
  5. package/dist/lib/index.d.ts +11 -1496
  6. package/dist/lib/index.js +6 -6215
  7. package/dist/lib/log.d.ts +11 -0
  8. package/dist/lib/log.js +20 -0
  9. package/dist/lib/metadata-types.d.ts +151 -0
  10. package/dist/lib/metadata-types.js +30 -0
  11. package/dist/lib/metadata.d.ts +16 -0
  12. package/dist/lib/metadata.js +235 -0
  13. package/dist/lib/package.js +5 -0
  14. package/dist/lib/parsers/configparser-parser.js +43 -0
  15. package/dist/lib/parsers/gemspec-parser.js +256 -0
  16. package/dist/lib/parsers/go-mod-parser.js +153 -0
  17. package/dist/lib/parsers/makefile-config-parser.js +102 -0
  18. package/dist/lib/parsers/properties-parser.js +31 -0
  19. package/dist/lib/parsers/rfc822-header-parser.js +48 -0
  20. package/dist/lib/parsers/setup-py-parser.js +173 -0
  21. package/dist/lib/source.d.ts +17 -0
  22. package/dist/lib/source.js +34 -0
  23. package/dist/lib/sources/arduino-library-properties.d.ts +45 -0
  24. package/dist/lib/sources/arduino-library-properties.js +208 -0
  25. package/dist/lib/sources/cinder-cinderblock-xml.d.ts +21 -0
  26. package/dist/lib/sources/cinder-cinderblock-xml.js +134 -0
  27. package/dist/lib/sources/code-stats.d.ts +14 -0
  28. package/dist/lib/sources/code-stats.js +40 -0
  29. package/dist/lib/sources/codemeta-json.d.ts +117 -0
  30. package/dist/lib/sources/codemeta-json.js +226 -0
  31. package/dist/lib/sources/dependency-updates.d.ts +22 -0
  32. package/dist/lib/sources/dependency-updates.js +132 -0
  33. package/dist/lib/sources/file-stats.d.ts +12 -0
  34. package/dist/lib/sources/file-stats.js +48 -0
  35. package/dist/lib/sources/git-config.d.ts +8 -0
  36. package/dist/lib/sources/git-config.js +21 -0
  37. package/dist/lib/sources/git-stats.d.ts +35 -0
  38. package/dist/lib/sources/git-stats.js +130 -0
  39. package/dist/lib/sources/github.d.ts +94 -0
  40. package/dist/lib/sources/github.js +399 -0
  41. package/dist/lib/sources/go-go-mod.d.ts +19 -0
  42. package/dist/lib/sources/go-go-mod.js +38 -0
  43. package/dist/lib/sources/go-goreleaser-yaml.d.ts +19 -0
  44. package/dist/lib/sources/go-goreleaser-yaml.js +152 -0
  45. package/dist/lib/sources/java-pom-xml.d.ts +52 -0
  46. package/dist/lib/sources/java-pom-xml.js +248 -0
  47. package/dist/lib/sources/license-file.d.ts +10 -0
  48. package/dist/lib/sources/license-file.js +26 -0
  49. package/dist/lib/sources/metadata-file.d.ts +14 -0
  50. package/dist/lib/sources/metadata-file.js +109 -0
  51. package/dist/lib/sources/metascope.d.ts +14 -0
  52. package/dist/lib/sources/metascope.js +35 -0
  53. package/dist/lib/sources/node-npm-registry.d.ts +19 -0
  54. package/dist/lib/sources/node-npm-registry.js +74 -0
  55. package/dist/lib/sources/node-package-json.d.ts +7 -0
  56. package/dist/lib/sources/node-package-json.js +27 -0
  57. package/dist/lib/sources/obsidian-plugin-manifest-json.d.ts +17 -0
  58. package/dist/lib/sources/obsidian-plugin-manifest-json.js +34 -0
  59. package/dist/lib/sources/obsidian-plugin-registry.d.ts +10 -0
  60. package/dist/lib/sources/obsidian-plugin-registry.js +44 -0
  61. package/dist/lib/sources/openframeworks-addon-config-mk.d.ts +17 -0
  62. package/dist/lib/sources/openframeworks-addon-config-mk.js +39 -0
  63. package/dist/lib/sources/openframeworks-install-xml.d.ts +20 -0
  64. package/dist/lib/sources/openframeworks-install-xml.js +153 -0
  65. package/dist/lib/sources/processing-library-properties.d.ts +44 -0
  66. package/dist/lib/sources/processing-library-properties.js +219 -0
  67. package/dist/lib/sources/processing-sketch-properties.d.ts +38 -0
  68. package/dist/lib/sources/processing-sketch-properties.js +185 -0
  69. package/dist/lib/sources/publiccode-yaml.d.ts +73 -0
  70. package/dist/lib/sources/publiccode-yaml.js +256 -0
  71. package/dist/lib/sources/python-pkg-info.d.ts +31 -0
  72. package/dist/lib/sources/python-pkg-info.js +115 -0
  73. package/dist/lib/sources/python-pypi-registry.d.ts +19 -0
  74. package/dist/lib/sources/python-pypi-registry.js +101 -0
  75. package/dist/lib/sources/python-pyproject-toml.d.ts +7 -0
  76. package/dist/lib/sources/python-pyproject-toml.js +30 -0
  77. package/dist/lib/sources/python-setup-cfg.d.ts +28 -0
  78. package/dist/lib/sources/python-setup-cfg.js +106 -0
  79. package/dist/lib/sources/python-setup-py.d.ts +28 -0
  80. package/dist/lib/sources/python-setup-py.js +48 -0
  81. package/dist/lib/sources/readme-file.d.ts +11 -0
  82. package/dist/lib/sources/readme-file.js +55 -0
  83. package/dist/lib/sources/ruby-gemspec.d.ts +44 -0
  84. package/dist/lib/sources/ruby-gemspec.js +62 -0
  85. package/dist/lib/sources/rust-cargo-toml.d.ts +40 -0
  86. package/dist/lib/sources/rust-cargo-toml.js +159 -0
  87. package/dist/lib/sources/xcode-info-plist.d.ts +22 -0
  88. package/dist/lib/sources/xcode-info-plist.js +199 -0
  89. package/dist/lib/sources/xcode-project-pbxproj.d.ts +21 -0
  90. package/dist/lib/sources/xcode-project-pbxproj.js +222 -0
  91. package/dist/lib/templates/codemeta.d.ts +47 -0
  92. package/dist/lib/templates/codemeta.js +494 -0
  93. package/dist/lib/templates/frontmatter.d.ts +87 -0
  94. package/dist/lib/templates/frontmatter.js +111 -0
  95. package/dist/lib/templates/index.d.ts +181 -0
  96. package/dist/lib/templates/index.js +22 -0
  97. package/dist/lib/templates/metadata.d.ts +17 -0
  98. package/dist/lib/templates/metadata.js +35 -0
  99. package/dist/lib/templates/project.d.ts +39 -0
  100. package/dist/lib/templates/project.js +51 -0
  101. package/dist/lib/utilities/codemeta-helpers.d.ts +39 -0
  102. package/dist/lib/utilities/codemeta-helpers.js +83 -0
  103. package/dist/lib/utilities/fetch.js +43 -0
  104. package/dist/lib/utilities/formatting.js +28 -0
  105. package/dist/lib/utilities/license-identification.js +141 -0
  106. package/dist/lib/utilities/schema-primitives.js +47 -0
  107. package/dist/lib/utilities/template-helpers.d.ts +135 -0
  108. package/dist/lib/utilities/template-helpers.js +310 -0
  109. package/dist/lib/utilities/tree-sitter-wasm.js +30 -0
  110. package/package.json +6 -6
  111. package/readme.md +62 -15
@@ -0,0 +1,199 @@
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 plist from "plist";
9
+ //#region src/lib/sources/xcode-info-plist.ts
10
+ /**
11
+ * Source and parser for Apple `Info.plist` files.
12
+ *
13
+ * Handles three flavors of Info.plist:
14
+ * - Standard Apple app/framework bundles (CFBundle* keys)
15
+ * - Alfred workflow plists (name, createdby, bundleid, etc.)
16
+ * - TextMate bundle plists (name, contactName, contactEmailRot13, etc.)
17
+ *
18
+ * Uses the `plist` npm package to parse XML plist format.
19
+ */
20
+ const infoPlistSchema = z.object({
21
+ applicationCategory: nonEmptyString,
22
+ author: nonEmptyString,
23
+ authorEmail: nonEmptyString,
24
+ copyrightHolder: nonEmptyString,
25
+ copyrightYear: nonEmptyString,
26
+ description: nonEmptyString,
27
+ identifier: nonEmptyString,
28
+ name: nonEmptyString,
29
+ operatingSystems: stringArray,
30
+ processorRequirements: stringArray,
31
+ url: optionalUrl,
32
+ version: nonEmptyString
33
+ });
34
+ /** Xcode build variable pattern: $(VAR) or ${VAR}. */
35
+ const XCODE_VARIABLE_RE = /\$[({][^)}]+[)}]/;
36
+ /**
37
+ * Map DTPlatformName / CFBundleSupportedPlatforms values to human-readable OS names.
38
+ */
39
+ const PLATFORM_NAME_MAP = {
40
+ appletvos: "tvOS",
41
+ appletvsimulator: "tvOS",
42
+ iphoneos: "iOS",
43
+ iphonesimulator: "iOS",
44
+ macosx: "macOS",
45
+ watchos: "watchOS",
46
+ watchsimulator: "watchOS",
47
+ xros: "visionOS"
48
+ };
49
+ /**
50
+ * Parse an `Info.plist` content string into a structured object.
51
+ * Returns undefined if the plist is malformed or not a dictionary.
52
+ */
53
+ function parse(content) {
54
+ let data;
55
+ try {
56
+ const parsed = plist.parse(content);
57
+ if (!is.plainObject(parsed)) return;
58
+ data = parsed;
59
+ } catch {
60
+ return;
61
+ }
62
+ const name = getString(data, "CFBundleDisplayName") ?? getString(data, "CFBundleName") ?? getString(data, "name");
63
+ const description = getString(data, "description");
64
+ const version = getString(data, "CFBundleShortVersionString") ?? getString(data, "version") ?? getString(data, "CFBundleVersion");
65
+ const identifier = getString(data, "CFBundleIdentifier") ?? getString(data, "bundleid");
66
+ const { copyrightHolder, copyrightYear } = parseCopyright(data);
67
+ const authorName = getString(data, "createdby") ?? getString(data, "contactName");
68
+ const authorEmailRot13 = getString(data, "contactEmailRot13");
69
+ const authorEmail = authorEmailRot13 ? rot13(authorEmailRot13) : void 0;
70
+ const url = getString(data, "webaddress");
71
+ const applicationCategory = parseApplicationCategory(data);
72
+ return infoPlistSchema.parse({
73
+ applicationCategory,
74
+ author: authorName,
75
+ authorEmail,
76
+ copyrightHolder,
77
+ copyrightYear,
78
+ description,
79
+ identifier,
80
+ name,
81
+ operatingSystems: parseOperatingSystems(data),
82
+ processorRequirements: parseProcessorRequirements(data),
83
+ url,
84
+ version
85
+ });
86
+ }
87
+ /**
88
+ * Get a string value from a plist dict, returning undefined for
89
+ * empty strings, whitespace-only strings, and Xcode variable placeholders.
90
+ */
91
+ function getString(data, key) {
92
+ const value = data[key];
93
+ if (typeof value !== "string") return void 0;
94
+ const trimmed = value.trim();
95
+ if (trimmed.length === 0) return void 0;
96
+ if (XCODE_VARIABLE_RE.test(trimmed)) return void 0;
97
+ return trimmed;
98
+ }
99
+ /**
100
+ * ROT13-decode a string (used by TextMate bundles for obfuscated emails).
101
+ */
102
+ function rot13(value) {
103
+ return value.replaceAll(/[a-z]/gi, (c) => {
104
+ const base = c <= "Z" ? 65 : 97;
105
+ return String.fromCodePoint((c.codePointAt(0) - base + 13) % 26 + base);
106
+ });
107
+ }
108
+ /**
109
+ * Convert an Apple UTI application category to a human-readable string.
110
+ * e.g. "public.app-category.developer-tools" → "Developer Tools"
111
+ */
112
+ function humanizeCategory(uti) {
113
+ if (!uti.startsWith("public.app-category.")) return uti;
114
+ return uti.slice(20).split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
115
+ }
116
+ /**
117
+ * Parse application category from LSApplicationCategoryType.
118
+ */
119
+ function parseApplicationCategory(data) {
120
+ const category = getString(data, "LSApplicationCategoryType");
121
+ if (!category) return void 0;
122
+ return humanizeCategory(category);
123
+ }
124
+ /**
125
+ * Parse copyright information from NSHumanReadableCopyright or CFBundleGetInfoString.
126
+ */
127
+ function parseCopyright(data) {
128
+ const copyrightSource = getString(data, "NSHumanReadableCopyright") ?? getString(data, "CFBundleGetInfoString");
129
+ if (!copyrightSource) return {};
130
+ const copyrightYear = /(?:©|\(c\)|copyright)\s*(\d{4})/i.exec(copyrightSource)?.[1];
131
+ const holderMatch = /(?:©|\(c\)|copyright)\s*\d{4}\s*(.+)/i.exec(copyrightSource);
132
+ let copyrightHolder;
133
+ if (holderMatch) {
134
+ copyrightHolder = holderMatch[1].replace(/\.\s*all\s+rights\s+reserved\.?/i, "").replace(/[.,;]+$/, "").trim();
135
+ if (copyrightHolder.length === 0) copyrightHolder = void 0;
136
+ }
137
+ return {
138
+ copyrightHolder,
139
+ copyrightYear
140
+ };
141
+ }
142
+ /**
143
+ * Infer operating systems from various plist keys.
144
+ */
145
+ function parseOperatingSystems(data) {
146
+ const results = [];
147
+ const seen = /* @__PURE__ */ new Set();
148
+ function add(value) {
149
+ if (!seen.has(value)) {
150
+ seen.add(value);
151
+ results.push(value);
152
+ }
153
+ }
154
+ const minMacOS = getString(data, "LSMinimumSystemVersion");
155
+ if (minMacOS) add(`macOS >= ${minMacOS}`);
156
+ const minIOS = getString(data, "MinimumOSVersion");
157
+ if (minIOS) add(`iOS >= ${minIOS}`);
158
+ if (results.length > 0) return results;
159
+ const platformName = getString(data, "DTPlatformName");
160
+ if (platformName) {
161
+ const os = PLATFORM_NAME_MAP[platformName.toLowerCase()];
162
+ if (os) add(os);
163
+ }
164
+ const supportedPlatforms = data.CFBundleSupportedPlatforms;
165
+ if (Array.isArray(supportedPlatforms)) {
166
+ for (const p of supportedPlatforms) if (typeof p === "string") {
167
+ const os = PLATFORM_NAME_MAP[p.toLowerCase()];
168
+ if (os) add(os);
169
+ }
170
+ }
171
+ if (data.LSRequiresIPhoneOS === true && !seen.has("iOS")) add("iOS");
172
+ return results;
173
+ }
174
+ /**
175
+ * Extract processor architecture requirements from UIRequiredDeviceCapabilities.
176
+ */
177
+ function parseProcessorRequirements(data) {
178
+ const capabilities = data.UIRequiredDeviceCapabilities;
179
+ if (!Array.isArray(capabilities)) return [];
180
+ const results = [];
181
+ for (const c of capabilities) if (typeof c === "string" && /^(?:arm|x86|i386)/i.test(c)) results.push(c);
182
+ return results;
183
+ }
184
+ const xcodeInfoPlistSource = defineSource({
185
+ async discover(context) {
186
+ return getMatches(context.options, ["Info.plist"]);
187
+ },
188
+ key: "xcodeInfoPlist",
189
+ async parse(input, context) {
190
+ const data = parse(await readFile(resolve(context.options.path, input), "utf8"));
191
+ if (data !== void 0) return {
192
+ data,
193
+ source: input
194
+ };
195
+ },
196
+ phase: 1
197
+ });
198
+ //#endregion
199
+ export { xcodeInfoPlistSource };
@@ -0,0 +1,21 @@
1
+ import { OneOrMany, SourceRecord } from "../source.js";
2
+ import { z } from "zod";
3
+
4
+ //#region src/lib/sources/xcode-project-pbxproj.d.ts
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>>;
8
+ dependencies: z.ZodArray<z.ZodObject<{
9
+ url: z.ZodString;
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>>;
17
+ }, z.core.$strip>;
18
+ type Pbxproj = z.infer<typeof pbxprojSchema>;
19
+ type XcodeProjectPbxprojData = OneOrMany<SourceRecord<Pbxproj>> | undefined;
20
+ //#endregion
21
+ export { XcodeProjectPbxprojData };
@@ -0,0 +1,222 @@
1
+ import { getMatches } from "../file-matching.js";
2
+ import { defineSource } from "../source.js";
3
+ import { nonEmptyString, stringArray } from "../utilities/schema-primitives.js";
4
+ import { resolve } from "node:path";
5
+ import is from "@sindresorhus/is";
6
+ import { z } from "zod";
7
+ import { PBXNativeTarget, XCRemoteSwiftPackageReference, XcodeProject } from "@bacons/xcode";
8
+ //#region src/lib/sources/xcode-project-pbxproj.ts
9
+ /**
10
+ * Source and parser for Xcode `.pbxproj` project files.
11
+ *
12
+ * Uses the `@bacons/xcode` package to parse the binary/ASCII plist format
13
+ * and navigate the Xcode project object graph.
14
+ *
15
+ * Extracts metadata from:
16
+ * - Project-level attributes (organizationName)
17
+ * - Build settings on the main app target (Release config preferred)
18
+ * - Swift Package Manager dependencies
19
+ */
20
+ const pbxprojDependencySchema = z.object({ url: z.string() });
21
+ const pbxprojSchema = z.object({
22
+ copyrightHolder: nonEmptyString,
23
+ copyrightYear: nonEmptyString,
24
+ dependencies: z.array(pbxprojDependencySchema),
25
+ identifier: nonEmptyString,
26
+ name: nonEmptyString,
27
+ operatingSystems: stringArray,
28
+ organizationName: nonEmptyString,
29
+ programmingLanguage: nonEmptyString,
30
+ version: nonEmptyString
31
+ });
32
+ /** Xcode build variable pattern: $(VAR) or ${VAR}. */
33
+ const XCODE_VARIABLE_RE = /\$[({][^)}]+[)}]/;
34
+ /**
35
+ * Map SDKROOT values to human-readable OS names.
36
+ */
37
+ const SDKROOT_MAP = {
38
+ appletvos: "tvOS",
39
+ iphoneos: "iOS",
40
+ macosx: "macOS",
41
+ watchos: "watchOS",
42
+ xros: "visionOS"
43
+ };
44
+ /**
45
+ * Deployment target build setting keys and their OS label.
46
+ */
47
+ const DEPLOYMENT_TARGETS = [
48
+ {
49
+ key: "IPHONEOS_DEPLOYMENT_TARGET",
50
+ os: "iOS"
51
+ },
52
+ {
53
+ key: "MACOSX_DEPLOYMENT_TARGET",
54
+ os: "macOS"
55
+ },
56
+ {
57
+ key: "TVOS_DEPLOYMENT_TARGET",
58
+ os: "tvOS"
59
+ },
60
+ {
61
+ key: "WATCHOS_DEPLOYMENT_TARGET",
62
+ os: "watchOS"
63
+ },
64
+ {
65
+ key: "XROS_DEPLOYMENT_TARGET",
66
+ os: "visionOS"
67
+ }
68
+ ];
69
+ /**
70
+ * Parse a `.pbxproj` file into a structured object.
71
+ * Returns undefined if the file is malformed or cannot be parsed.
72
+ */
73
+ function parse(filePath) {
74
+ let project;
75
+ try {
76
+ project = XcodeProject.open(filePath);
77
+ } catch {
78
+ return;
79
+ }
80
+ const root = project.rootObject;
81
+ const target = root.props.targets.find((t) => PBXNativeTarget.is(t));
82
+ let appTarget;
83
+ try {
84
+ appTarget = root.getMainAppTarget() ?? void 0;
85
+ } catch {}
86
+ appTarget ??= target;
87
+ let targetConfig;
88
+ let targetSettings;
89
+ if (appTarget) try {
90
+ const config = appTarget.getDefaultConfiguration();
91
+ targetConfig = config;
92
+ const bs = config.props.buildSettings;
93
+ targetSettings = is.plainObject(bs) ? bs : void 0;
94
+ } catch {}
95
+ let projectSettings;
96
+ try {
97
+ const pbs = (root.props.buildConfigurationList.props.buildConfigurations.find((c) => c.props.name === "Release") ?? root.props.buildConfigurationList.getDefaultConfiguration()).props.buildSettings;
98
+ projectSettings = is.plainObject(pbs) ? pbs : void 0;
99
+ } catch {}
100
+ const displayName = getSetting(targetSettings, projectSettings, "INFOPLIST_KEY_CFBundleDisplayName");
101
+ const productName = getResolvedSetting(targetConfig, targetSettings, projectSettings, "PRODUCT_NAME");
102
+ const targetName = appTarget ? cleanString(appTarget.props.name) : void 0;
103
+ const organizationName = cleanString(root.props.attributes.ORGANIZATIONNAME);
104
+ const { copyrightHolder, copyrightYear } = parseCopyrightString(getSetting(targetSettings, projectSettings, "INFOPLIST_KEY_NSHumanReadableCopyright"));
105
+ const swiftVersion = getSetting(targetSettings, projectSettings, "SWIFT_VERSION");
106
+ let programmingLanguage;
107
+ if (swiftVersion) programmingLanguage = "Swift";
108
+ else if (getSetting(targetSettings, projectSettings, "GCC_C_LANGUAGE_STANDARD")) programmingLanguage = "Objective-C";
109
+ return pbxprojSchema.parse({
110
+ copyrightHolder,
111
+ copyrightYear,
112
+ dependencies: parseDependencies(root),
113
+ identifier: getResolvedSetting(targetConfig, targetSettings, projectSettings, "PRODUCT_BUNDLE_IDENTIFIER"),
114
+ name: displayName ?? productName ?? targetName,
115
+ operatingSystems: parseOperatingSystems(targetSettings, projectSettings),
116
+ organizationName,
117
+ programmingLanguage,
118
+ version: getSetting(targetSettings, projectSettings, "MARKETING_VERSION")
119
+ });
120
+ }
121
+ /**
122
+ * Get a string build setting, filtering out empty strings and unresolved
123
+ * Xcode variable placeholders. Handles both string and numeric values.
124
+ */
125
+ function cleanString(value) {
126
+ if (typeof value === "number") return String(value);
127
+ if (typeof value !== "string") return void 0;
128
+ const trimmed = value.trim();
129
+ if (trimmed.length === 0) return void 0;
130
+ if (XCODE_VARIABLE_RE.test(trimmed)) return void 0;
131
+ return trimmed;
132
+ }
133
+ /**
134
+ * Get a build setting from a target, cascading to project-level if not found.
135
+ */
136
+ function getSetting(targetSettings, projectSettings, key) {
137
+ const targetValue = cleanString(targetSettings?.[key]);
138
+ if (targetValue !== void 0) return targetValue;
139
+ return cleanString(projectSettings?.[key]);
140
+ }
141
+ /**
142
+ * Try to resolve a build setting using `@bacons/xcode`'s variable resolution,
143
+ * then fall back to raw value.
144
+ */
145
+ function getResolvedSetting(config, targetSettings, projectSettings, key) {
146
+ if (config) try {
147
+ const cleaned = cleanString(config.resolveBuildSetting(key));
148
+ if (cleaned !== void 0) return cleaned;
149
+ } catch {}
150
+ return getSetting(targetSettings, projectSettings, key);
151
+ }
152
+ /**
153
+ * Parse copyright information from a copyright string.
154
+ */
155
+ function parseCopyrightString(copyrightSource) {
156
+ if (!copyrightSource) return {};
157
+ const copyrightYear = /(?:©|\(c\)|copyright)\s*(\d{4})/i.exec(copyrightSource)?.[1];
158
+ const holderMatch = /(?:©|\(c\)|copyright)\s*\d{4}\s*(.+)/i.exec(copyrightSource);
159
+ let copyrightHolder;
160
+ if (holderMatch) {
161
+ copyrightHolder = holderMatch[1].replace(/\.\s*all\s+rights\s+reserved\.?/i, "").replace(/[.,;]+$/, "").trim();
162
+ if (copyrightHolder.length === 0) copyrightHolder = void 0;
163
+ }
164
+ return {
165
+ copyrightHolder,
166
+ copyrightYear
167
+ };
168
+ }
169
+ /**
170
+ * Infer operating systems from deployment target build settings.
171
+ */
172
+ function parseOperatingSystems(targetSettings, projectSettings) {
173
+ const results = [];
174
+ const seen = /* @__PURE__ */ new Set();
175
+ for (const { key, os } of DEPLOYMENT_TARGETS) {
176
+ const version = getSetting(targetSettings, projectSettings, key);
177
+ if (version) {
178
+ const value = `${os} >= ${version}`;
179
+ if (!seen.has(value)) {
180
+ seen.add(value);
181
+ results.push(value);
182
+ }
183
+ }
184
+ }
185
+ if (results.length === 0) {
186
+ const sdkroot = getSetting(targetSettings, projectSettings, "SDKROOT");
187
+ if (sdkroot && sdkroot !== "auto") {
188
+ const os = SDKROOT_MAP[sdkroot];
189
+ if (os) results.push(os);
190
+ }
191
+ }
192
+ return results;
193
+ }
194
+ /**
195
+ * Extract Swift Package Manager dependencies.
196
+ */
197
+ function parseDependencies(root) {
198
+ const packageReferences = root.props.packageReferences ?? [];
199
+ const results = [];
200
+ for (const packageReference of packageReferences) {
201
+ if (!XCRemoteSwiftPackageReference.is(packageReference)) continue;
202
+ const url = cleanString(packageReference.props.repositoryURL);
203
+ if (url) results.push({ url });
204
+ }
205
+ return results;
206
+ }
207
+ const xcodeProjectPbxprojSource = defineSource({
208
+ async discover(context) {
209
+ return getMatches(context.options, ["*.xcodeproj/project.pbxproj"], ["**/*.xcodeproj/project.pbxproj"]);
210
+ },
211
+ key: "xcodeProjectPbxproj",
212
+ async parse(input, context) {
213
+ const data = parse(resolve(context.options.path, input));
214
+ if (data !== void 0) return {
215
+ data,
216
+ source: input
217
+ };
218
+ },
219
+ phase: 1
220
+ });
221
+ //#endregion
222
+ export { xcodeProjectPbxprojSource };
@@ -0,0 +1,47 @@
1
+ import { Template } from "../metadata-types.js";
2
+ import { CodemetaDependencyLd, CodemetaPersonOrOrgLd } from "../utilities/codemeta-helpers.js";
3
+ //#region src/lib/templates/codemeta.d.ts
4
+ type TemplateDataCodemeta = ReturnType<typeof codemeta>;
5
+ declare const codemeta: Template<{
6
+ '@context': string;
7
+ '@type': string;
8
+ applicationCategory: string | undefined;
9
+ applicationSubCategory: string | undefined;
10
+ author: CodemetaPersonOrOrgLd[] | undefined;
11
+ buildInstructions: string | undefined;
12
+ codeRepository: string | undefined;
13
+ continuousIntegration: string | undefined;
14
+ contributor: CodemetaPersonOrOrgLd[] | undefined;
15
+ copyrightHolder: CodemetaPersonOrOrgLd[] | undefined;
16
+ copyrightYear: number | undefined;
17
+ dateCreated: string | undefined;
18
+ dateModified: string | undefined;
19
+ datePublished: string | undefined;
20
+ description: string | undefined;
21
+ developmentStatus: string | undefined;
22
+ downloadUrl: string | undefined;
23
+ funder: CodemetaPersonOrOrgLd[] | undefined;
24
+ funding: string | undefined;
25
+ identifier: string | undefined;
26
+ installUrl: string | undefined;
27
+ isAccessibleForFree: boolean | undefined;
28
+ issueTracker: string | undefined;
29
+ keywords: string[] | undefined;
30
+ license: string | undefined;
31
+ maintainer: CodemetaPersonOrOrgLd[] | undefined;
32
+ name: string | undefined;
33
+ operatingSystem: string[] | undefined;
34
+ programmingLanguage: string[] | undefined;
35
+ readme: string | undefined;
36
+ relatedLink: string | string[] | undefined;
37
+ releaseNotes: string | undefined;
38
+ runtimePlatform: string[] | undefined;
39
+ softwareHelp: string | undefined;
40
+ softwareRequirements: CodemetaDependencyLd[] | undefined;
41
+ softwareSuggestions: CodemetaDependencyLd[] | undefined;
42
+ targetProduct: Record<string, string> | undefined;
43
+ url: string | undefined;
44
+ version: string | undefined;
45
+ }>;
46
+ //#endregion
47
+ export { TemplateDataCodemeta };