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,117 @@
|
|
|
1
|
+
import { OneOrMany, SourceRecord } from "../source.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/sources/codemeta-json.d.ts
|
|
5
|
+
declare const codeMetaJsonDataSchema: z.ZodObject<{
|
|
6
|
+
applicationCategory: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
7
|
+
applicationSubCategory: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
8
|
+
author: z.ZodOptional<z.ZodPipe<z.ZodTransform<Record<string, unknown>[] | undefined, unknown>, z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
9
|
+
affiliation: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
10
|
+
email: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
11
|
+
familyName: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
12
|
+
givenName: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
13
|
+
id: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
14
|
+
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
15
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
16
|
+
Organization: "Organization";
|
|
17
|
+
Person: "Person";
|
|
18
|
+
}>>;
|
|
19
|
+
url: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
20
|
+
}, z.core.$strip>>>>>;
|
|
21
|
+
buildInstructions: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
22
|
+
codeRepository: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
23
|
+
continuousIntegration: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
24
|
+
contributor: z.ZodOptional<z.ZodPipe<z.ZodTransform<Record<string, unknown>[] | undefined, unknown>, z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
25
|
+
affiliation: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
26
|
+
email: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
27
|
+
familyName: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
28
|
+
givenName: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
29
|
+
id: 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
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
32
|
+
Organization: "Organization";
|
|
33
|
+
Person: "Person";
|
|
34
|
+
}>>;
|
|
35
|
+
url: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
36
|
+
}, z.core.$strip>>>>>;
|
|
37
|
+
copyrightHolder: z.ZodOptional<z.ZodPipe<z.ZodTransform<Record<string, unknown>[] | undefined, unknown>, z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
38
|
+
affiliation: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
39
|
+
email: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
40
|
+
familyName: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
41
|
+
givenName: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
42
|
+
id: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
43
|
+
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
44
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
45
|
+
Organization: "Organization";
|
|
46
|
+
Person: "Person";
|
|
47
|
+
}>>;
|
|
48
|
+
url: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
49
|
+
}, z.core.$strip>>>>>;
|
|
50
|
+
copyrightYear: z.ZodPipe<z.ZodTransform<number | undefined, unknown>, z.ZodOptional<z.ZodNumber>>;
|
|
51
|
+
dateCreated: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
52
|
+
dateModified: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
53
|
+
datePublished: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
54
|
+
description: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
55
|
+
developmentStatus: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
56
|
+
downloadUrl: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
57
|
+
funder: z.ZodOptional<z.ZodPipe<z.ZodTransform<Record<string, unknown>[] | undefined, unknown>, z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
58
|
+
affiliation: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
59
|
+
email: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
60
|
+
familyName: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
61
|
+
givenName: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
62
|
+
id: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
63
|
+
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
64
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
65
|
+
Organization: "Organization";
|
|
66
|
+
Person: "Person";
|
|
67
|
+
}>>;
|
|
68
|
+
url: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
69
|
+
}, z.core.$strip>>>>>;
|
|
70
|
+
funding: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
71
|
+
identifier: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
72
|
+
installUrl: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
73
|
+
isAccessibleForFree: z.ZodOptional<z.ZodBoolean>;
|
|
74
|
+
issueTracker: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
75
|
+
keywords: z.ZodOptional<z.ZodPipe<z.ZodTransform<string[] | undefined, unknown>, z.ZodOptional<z.ZodArray<z.ZodString>>>>;
|
|
76
|
+
license: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | string[] | undefined, unknown>, z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>>;
|
|
77
|
+
maintainer: z.ZodOptional<z.ZodPipe<z.ZodTransform<Record<string, unknown>[] | undefined, unknown>, z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
78
|
+
affiliation: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
79
|
+
email: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
80
|
+
familyName: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
81
|
+
givenName: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
82
|
+
id: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
83
|
+
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
84
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
85
|
+
Organization: "Organization";
|
|
86
|
+
Person: "Person";
|
|
87
|
+
}>>;
|
|
88
|
+
url: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
89
|
+
}, z.core.$strip>>>>>;
|
|
90
|
+
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
91
|
+
operatingSystem: z.ZodOptional<z.ZodPipe<z.ZodTransform<string[] | undefined, unknown>, z.ZodOptional<z.ZodArray<z.ZodString>>>>;
|
|
92
|
+
programmingLanguage: z.ZodOptional<z.ZodPipe<z.ZodTransform<string[] | undefined, unknown>, z.ZodOptional<z.ZodArray<z.ZodString>>>>;
|
|
93
|
+
readme: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
94
|
+
relatedLink: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | string[] | undefined, unknown>, z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>>>;
|
|
95
|
+
releaseNotes: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
96
|
+
runtimePlatform: z.ZodOptional<z.ZodPipe<z.ZodTransform<string[] | undefined, unknown>, z.ZodOptional<z.ZodArray<z.ZodString>>>>;
|
|
97
|
+
softwareHelp: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
98
|
+
softwareRequirements: z.ZodOptional<z.ZodPipe<z.ZodTransform<Record<string, unknown>[] | undefined, unknown>, z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
99
|
+
identifier: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
100
|
+
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
101
|
+
runtimePlatform: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
102
|
+
version: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
103
|
+
}, z.core.$strip>>>>>;
|
|
104
|
+
softwareSuggestions: z.ZodOptional<z.ZodPipe<z.ZodTransform<Record<string, unknown>[] | undefined, unknown>, z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
105
|
+
identifier: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
106
|
+
name: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
107
|
+
runtimePlatform: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
108
|
+
version: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>;
|
|
109
|
+
}, z.core.$strip>>>>>;
|
|
110
|
+
softwareVersion: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
111
|
+
url: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
112
|
+
version: z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodPipe<z.ZodTransform<string | undefined, unknown>, z.ZodOptional<z.ZodString>>>;
|
|
113
|
+
}, z.core.$strip>;
|
|
114
|
+
type CodeMetaJson = z.infer<typeof codeMetaJsonDataSchema>;
|
|
115
|
+
type CodeMetaJsonData = OneOrMany<SourceRecord<CodeMetaJson>> | undefined;
|
|
116
|
+
//#endregion
|
|
117
|
+
export { CodeMetaJson, CodeMetaJsonData };
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { log } from "../log.js";
|
|
2
|
+
import { getMatches } from "../file-matching.js";
|
|
3
|
+
import { defineSource } from "../source.js";
|
|
4
|
+
import { nonEmptyString, optionalUrl, parseJsonRecord } from "../utilities/schema-primitives.js";
|
|
5
|
+
import { splitCommaSeparated } from "../utilities/template-helpers.js";
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
import { resolve } from "node:path";
|
|
8
|
+
import is from "@sindresorhus/is";
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
//#region src/lib/sources/codemeta-json.ts
|
|
11
|
+
/**
|
|
12
|
+
* CodeMeta JSON metadata source.
|
|
13
|
+
*
|
|
14
|
+
* Reads a codemeta.json file (v1, v2, or v3) and normalizes it into a
|
|
15
|
+
* consistent shape with predictable types. No enrichment, no JSON-LD
|
|
16
|
+
* expansion — just an honest representation of what's in the file.
|
|
17
|
+
*
|
|
18
|
+
* Uses Zod preprocess schemas to handle v1/v2/v3 normalization:
|
|
19
|
+
* - `@`-prefixed JSON-LD keys stripped, v1 property names remapped
|
|
20
|
+
* - `{"@type": "xsd:anyURI", "@value": "..."}` unwrapped to plain strings
|
|
21
|
+
* - Person/org objects normalized (`@type`→`type`, `@id`→`id`, affiliation-as-object)
|
|
22
|
+
* - Comma-separated strings split to arrays, `{"name":"..."}` objects unwrapped
|
|
23
|
+
* - Dependencies normalized (string → `{name: string}`)
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* A string that also unwraps `{"@value": "..."}` JSON-LD typed values.
|
|
27
|
+
* Empty/whitespace strings become undefined via `nonEmptyString`.
|
|
28
|
+
*/
|
|
29
|
+
const codeMetaString = z.preprocess((value) => {
|
|
30
|
+
if (typeof value === "string") return value;
|
|
31
|
+
if (is.plainObject(value) && typeof value["@value"] === "string") return value["@value"];
|
|
32
|
+
}, nonEmptyString);
|
|
33
|
+
/** Same as codeMetaString but semantically a URL field. */
|
|
34
|
+
const codeMetaUrl = z.preprocess((value) => {
|
|
35
|
+
if (typeof value === "string") return value;
|
|
36
|
+
if (is.plainObject(value) && typeof value["@value"] === "string") return value["@value"];
|
|
37
|
+
}, optionalUrl);
|
|
38
|
+
/**
|
|
39
|
+
* A string array that handles CodeMeta's polymorphic inputs:
|
|
40
|
+
* - Single comma-separated string → split to array (common in v1)
|
|
41
|
+
* - Array of strings → pass through
|
|
42
|
+
* - Array of `{"name":"..."}` objects → extract name strings (e.g. programmingLanguage)
|
|
43
|
+
*/
|
|
44
|
+
const codeMetaStringArray = z.preprocess((value) => {
|
|
45
|
+
if (value === void 0 || value === null) return;
|
|
46
|
+
if (typeof value === "string") return value.includes(",") ? splitCommaSeparated(value) : [value];
|
|
47
|
+
if (Array.isArray(value)) return value.map((item) => {
|
|
48
|
+
if (typeof item === "string") return item.trim();
|
|
49
|
+
if (is.plainObject(item)) return typeof item.name === "string" ? item.name.trim() : "";
|
|
50
|
+
log.warn("Invalid type found in codemeta json parser");
|
|
51
|
+
return "";
|
|
52
|
+
}).filter((s) => s.length > 0);
|
|
53
|
+
}, z.array(z.string()).optional()).optional();
|
|
54
|
+
/**
|
|
55
|
+
* License field — preserve as string or string[].
|
|
56
|
+
*/
|
|
57
|
+
const codeMetaLicense = z.preprocess((value) => {
|
|
58
|
+
if (typeof value === "string") return value;
|
|
59
|
+
if (Array.isArray(value)) {
|
|
60
|
+
const filtered = value.filter((l) => typeof l === "string");
|
|
61
|
+
return filtered.length > 0 ? filtered : void 0;
|
|
62
|
+
}
|
|
63
|
+
}, z.union([z.string(), z.array(z.string())]).optional()).optional();
|
|
64
|
+
const codeMetaPersonOrOrgSchema = z.object({
|
|
65
|
+
affiliation: nonEmptyString,
|
|
66
|
+
email: nonEmptyString,
|
|
67
|
+
familyName: nonEmptyString,
|
|
68
|
+
givenName: nonEmptyString,
|
|
69
|
+
id: nonEmptyString,
|
|
70
|
+
name: nonEmptyString,
|
|
71
|
+
type: z.enum(["Organization", "Person"]).optional(),
|
|
72
|
+
url: optionalUrl
|
|
73
|
+
});
|
|
74
|
+
/**
|
|
75
|
+
* Preprocess a raw person/org value into a normalized shape.
|
|
76
|
+
* Handles: plain string → {name: string}, `@type`→`type`, `@id`→`id`,
|
|
77
|
+
* affiliation-as-object → affiliation string.
|
|
78
|
+
*/
|
|
79
|
+
function preprocessPersonOrOrg(value) {
|
|
80
|
+
if (typeof value === "string") return { name: value };
|
|
81
|
+
if (!is.plainObject(value)) return;
|
|
82
|
+
const result = {};
|
|
83
|
+
if (typeof value["@type"] === "string") {
|
|
84
|
+
const rawType = value["@type"].toLowerCase();
|
|
85
|
+
if (rawType === "person") result.type = "Person";
|
|
86
|
+
else if (rawType === "organization") result.type = "Organization";
|
|
87
|
+
}
|
|
88
|
+
if (typeof value["@id"] === "string") result.id = value["@id"];
|
|
89
|
+
if (typeof value.name === "string") result.name = value.name;
|
|
90
|
+
if (typeof value.givenName === "string") result.givenName = value.givenName;
|
|
91
|
+
if (typeof value.familyName === "string") result.familyName = value.familyName;
|
|
92
|
+
if (typeof value.email === "string") result.email = value.email;
|
|
93
|
+
if (typeof value.url === "string") result.url = value.url;
|
|
94
|
+
if (typeof value.affiliation === "string") result.affiliation = value.affiliation;
|
|
95
|
+
else if (is.plainObject(value.affiliation) && typeof value.affiliation.name === "string") result.affiliation = value.affiliation.name;
|
|
96
|
+
if (result.name ?? result.givenName ?? result.familyName ?? result.email) return result;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* A person/org array that normalizes single values to arrays,
|
|
100
|
+
* and each element through `preprocessPersonOrOrg`.
|
|
101
|
+
*/
|
|
102
|
+
const codeMetaPersonArray = z.preprocess((value) => {
|
|
103
|
+
if (value === void 0 || value === null) return;
|
|
104
|
+
const normalized = (Array.isArray(value) ? value : [value]).map((item) => preprocessPersonOrOrg(item)).filter((p) => p !== void 0);
|
|
105
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
106
|
+
}, z.array(codeMetaPersonOrOrgSchema).optional()).optional();
|
|
107
|
+
const codeMetaDependencySchema = z.object({
|
|
108
|
+
identifier: nonEmptyString,
|
|
109
|
+
name: nonEmptyString,
|
|
110
|
+
runtimePlatform: nonEmptyString,
|
|
111
|
+
version: nonEmptyString
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* Preprocess a raw dependency value into a normalized shape.
|
|
115
|
+
* Handles: plain string → {name: string}.
|
|
116
|
+
*/
|
|
117
|
+
function preprocessDependency(value) {
|
|
118
|
+
if (typeof value === "string") return { name: value };
|
|
119
|
+
if (!is.plainObject(value)) return;
|
|
120
|
+
const dep = {};
|
|
121
|
+
if (typeof value.name === "string") dep.name = value.name;
|
|
122
|
+
if (typeof value.identifier === "string") dep.identifier = value.identifier;
|
|
123
|
+
if (typeof value.version === "string") dep.version = value.version;
|
|
124
|
+
if (typeof value.runtimePlatform === "string") dep.runtimePlatform = value.runtimePlatform;
|
|
125
|
+
if (dep.name ?? dep.identifier) return dep;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* A dependency array that normalizes single values to arrays,
|
|
129
|
+
* and each element through `preprocessDependency`.
|
|
130
|
+
*/
|
|
131
|
+
const codeMetaDependencyArray = z.preprocess((value) => {
|
|
132
|
+
if (value === void 0 || value === null) return;
|
|
133
|
+
const normalized = (Array.isArray(value) ? value : [value]).map((item) => preprocessDependency(item)).filter((d) => d !== void 0);
|
|
134
|
+
return normalized.length > 0 ? normalized : void 0;
|
|
135
|
+
}, z.array(codeMetaDependencySchema).optional()).optional();
|
|
136
|
+
const codeMetaJsonDataSchema = z.object({
|
|
137
|
+
applicationCategory: codeMetaString,
|
|
138
|
+
applicationSubCategory: codeMetaString,
|
|
139
|
+
author: codeMetaPersonArray,
|
|
140
|
+
buildInstructions: codeMetaUrl,
|
|
141
|
+
codeRepository: codeMetaUrl,
|
|
142
|
+
continuousIntegration: codeMetaUrl,
|
|
143
|
+
contributor: codeMetaPersonArray,
|
|
144
|
+
copyrightHolder: codeMetaPersonArray,
|
|
145
|
+
copyrightYear: z.preprocess((v) => {
|
|
146
|
+
if (typeof v === "number") return v;
|
|
147
|
+
if (typeof v === "string") {
|
|
148
|
+
const parsed = Number.parseInt(v, 10);
|
|
149
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
150
|
+
}
|
|
151
|
+
}, z.number().optional()),
|
|
152
|
+
dateCreated: codeMetaString,
|
|
153
|
+
dateModified: codeMetaString,
|
|
154
|
+
datePublished: codeMetaString,
|
|
155
|
+
description: codeMetaString,
|
|
156
|
+
developmentStatus: codeMetaString,
|
|
157
|
+
downloadUrl: codeMetaUrl,
|
|
158
|
+
funder: codeMetaPersonArray,
|
|
159
|
+
funding: codeMetaString,
|
|
160
|
+
identifier: codeMetaString,
|
|
161
|
+
installUrl: codeMetaUrl,
|
|
162
|
+
isAccessibleForFree: z.boolean().optional(),
|
|
163
|
+
issueTracker: codeMetaUrl,
|
|
164
|
+
keywords: codeMetaStringArray,
|
|
165
|
+
license: codeMetaLicense,
|
|
166
|
+
maintainer: codeMetaPersonArray,
|
|
167
|
+
name: codeMetaString,
|
|
168
|
+
operatingSystem: codeMetaStringArray,
|
|
169
|
+
programmingLanguage: codeMetaStringArray,
|
|
170
|
+
readme: codeMetaUrl,
|
|
171
|
+
relatedLink: codeMetaLicense,
|
|
172
|
+
releaseNotes: codeMetaString,
|
|
173
|
+
runtimePlatform: codeMetaStringArray,
|
|
174
|
+
softwareHelp: codeMetaUrl,
|
|
175
|
+
softwareRequirements: codeMetaDependencyArray,
|
|
176
|
+
softwareSuggestions: codeMetaDependencyArray,
|
|
177
|
+
softwareVersion: codeMetaString,
|
|
178
|
+
url: codeMetaUrl,
|
|
179
|
+
version: codeMetaString
|
|
180
|
+
});
|
|
181
|
+
/** Map v1 property names to their v2/v3 equivalents. */
|
|
182
|
+
const v1PropertyMap = {
|
|
183
|
+
agents: "author",
|
|
184
|
+
contIntegration: "continuousIntegration",
|
|
185
|
+
depends: "softwareRequirements",
|
|
186
|
+
suggests: "softwareSuggestions",
|
|
187
|
+
title: "name"
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* Parse a codemeta.json file, normalizing v1/v2/v3 into a consistent shape.
|
|
191
|
+
*/
|
|
192
|
+
function parse(content) {
|
|
193
|
+
const raw = parseJsonRecord(content);
|
|
194
|
+
if (!raw) return void 0;
|
|
195
|
+
const migrated = migrateV1Properties(raw);
|
|
196
|
+
if (migrated.datePublished === void 0 && typeof migrated.dateReleased === "string") migrated.datePublished = migrated.dateReleased;
|
|
197
|
+
return codeMetaJsonDataSchema.parse(migrated);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Strip `@`-prefixed JSON-LD keys and remap v1 property names.
|
|
201
|
+
*/
|
|
202
|
+
function migrateV1Properties(raw) {
|
|
203
|
+
const result = {};
|
|
204
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
205
|
+
if (key.startsWith("@")) continue;
|
|
206
|
+
const mappedKey = v1PropertyMap[key] ?? key;
|
|
207
|
+
if (!(mappedKey in result)) result[mappedKey] = value;
|
|
208
|
+
}
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
const codemetaJsonSource = defineSource({
|
|
212
|
+
async discover(context) {
|
|
213
|
+
return getMatches(context.options, ["codemeta.json"]);
|
|
214
|
+
},
|
|
215
|
+
key: "codemetaJson",
|
|
216
|
+
async parse(input, context) {
|
|
217
|
+
const data = parse(await readFile(resolve(context.options.path, input), "utf8"));
|
|
218
|
+
if (data !== void 0) return {
|
|
219
|
+
data,
|
|
220
|
+
source: input
|
|
221
|
+
};
|
|
222
|
+
},
|
|
223
|
+
phase: 1
|
|
224
|
+
});
|
|
225
|
+
//#endregion
|
|
226
|
+
export { codeMetaJsonDataSchema, codemetaJsonSource };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { OneOrMany, SourceRecord } from "../source.js";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/sources/dependency-updates.d.ts
|
|
4
|
+
type DependencyUpdatesPackage = {
|
|
5
|
+
/** Human-readable age of the update (e.g. "3 months"). */age?: string; /** Additional info about the update (e.g. deprecation notice). */
|
|
6
|
+
info?: string; /** Package name. */
|
|
7
|
+
name: string; /** Latest available version. */
|
|
8
|
+
new: string; /** Currently installed version. */
|
|
9
|
+
old: string;
|
|
10
|
+
};
|
|
11
|
+
type DependencyUpdatesFields = {
|
|
12
|
+
/** Packages with available major version updates. */major?: DependencyUpdatesPackage[]; /** Packages with available minor version updates. */
|
|
13
|
+
minor?: DependencyUpdatesPackage[]; /** Packages with available patch version updates. */
|
|
14
|
+
patch?: DependencyUpdatesPackage[];
|
|
15
|
+
};
|
|
16
|
+
type DependencyUpdatesExtra = {
|
|
17
|
+
/** Total dependency staleness in libyears. */libyears?: number; /** Total number of outdated packages. */
|
|
18
|
+
total?: number;
|
|
19
|
+
};
|
|
20
|
+
type DependencyUpdatesData = OneOrMany<SourceRecord<DependencyUpdatesFields, DependencyUpdatesExtra>> | undefined;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { DependencyUpdatesData };
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { log } from "../log.js";
|
|
2
|
+
import { defineSource } from "../source.js";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { exec } from "tinyexec";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { coerce, diff } from "semver";
|
|
8
|
+
//#region src/lib/sources/dependency-updates.ts
|
|
9
|
+
const depSchema = z.object({
|
|
10
|
+
age: z.string().optional(),
|
|
11
|
+
info: z.string().optional(),
|
|
12
|
+
new: z.string(),
|
|
13
|
+
old: z.string()
|
|
14
|
+
});
|
|
15
|
+
const updatesOutputSchema = z.object({ results: z.record(z.string(), z.record(z.string(), z.record(z.string(), depSchema))) });
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the path to the `updates` CLI binary from its installed package.
|
|
18
|
+
*/
|
|
19
|
+
function resolveUpdatesBinary() {
|
|
20
|
+
const require = createRequire(import.meta.url);
|
|
21
|
+
const packageJsonPath = require.resolve("updates/package.json");
|
|
22
|
+
const packageJson = require(packageJsonPath);
|
|
23
|
+
const bin = typeof packageJson === "object" && packageJson !== null && "bin" in packageJson && typeof packageJson.bin === "string" ? packageJson.bin : void 0;
|
|
24
|
+
if (!bin) throw new Error("Could not resolve updates binary path");
|
|
25
|
+
return join(dirname(packageJsonPath), bin);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Parse an age string from the `updates` CLI (via the `timerel` library) into fractional years.
|
|
29
|
+
*
|
|
30
|
+
* Possible formats: "now", "<n> sec(s)", "<n> min(s)", "<n> hour(s)",
|
|
31
|
+
* "<n> day(s)", "<n> week(s)", "<n> month(s)", "<n> year(s)"
|
|
32
|
+
*/
|
|
33
|
+
function parseAgeToYears(age) {
|
|
34
|
+
if (age === "now") return 0;
|
|
35
|
+
const match = /^(\d+)\s+(\w+)$/.exec(age.trim());
|
|
36
|
+
if (!match) return 0;
|
|
37
|
+
const value = Number(match[1]);
|
|
38
|
+
switch (match[2]) {
|
|
39
|
+
case "day":
|
|
40
|
+
case "days": return value / 365.25;
|
|
41
|
+
case "hour":
|
|
42
|
+
case "hours": return value / (365.25 * 24);
|
|
43
|
+
case "min":
|
|
44
|
+
case "mins": return value / (365.25 * 24 * 60);
|
|
45
|
+
case "month":
|
|
46
|
+
case "months": return value / 12;
|
|
47
|
+
case "sec":
|
|
48
|
+
case "secs": return value / (365.25 * 24 * 60 * 60);
|
|
49
|
+
case "week":
|
|
50
|
+
case "weeks": return value * 7 / 365.25;
|
|
51
|
+
case "year":
|
|
52
|
+
case "years": return value;
|
|
53
|
+
default: return 0;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Classify a version bump as major, minor, or patch using semver.
|
|
58
|
+
* Falls back to 'major' for non-semver versions (e.g. GitHub Actions tags).
|
|
59
|
+
*/
|
|
60
|
+
function classifyBump(oldVersion, newVersion) {
|
|
61
|
+
const oldSemver = coerce(oldVersion);
|
|
62
|
+
const newSemver = coerce(newVersion);
|
|
63
|
+
if (!oldSemver || !newSemver) return "major";
|
|
64
|
+
const result = diff(oldSemver, newSemver);
|
|
65
|
+
if (!result) return "major";
|
|
66
|
+
if (result.startsWith("major") || result === "premajor") return "major";
|
|
67
|
+
if (result.startsWith("minor") || result === "preminor") return "minor";
|
|
68
|
+
return "patch";
|
|
69
|
+
}
|
|
70
|
+
const dependencyUpdatesSource = defineSource({
|
|
71
|
+
async discover(context) {
|
|
72
|
+
return [context.options.path];
|
|
73
|
+
},
|
|
74
|
+
key: "dependencyUpdates",
|
|
75
|
+
async parse(input) {
|
|
76
|
+
log.debug("Extracting dependency update information via updates...");
|
|
77
|
+
const result = await exec("node", [
|
|
78
|
+
resolveUpdatesBinary(),
|
|
79
|
+
"--file",
|
|
80
|
+
input,
|
|
81
|
+
"--json"
|
|
82
|
+
]);
|
|
83
|
+
let parsed;
|
|
84
|
+
try {
|
|
85
|
+
parsed = updatesOutputSchema.parse(JSON.parse(result.stdout));
|
|
86
|
+
} catch {
|
|
87
|
+
log.debug("No dependency files found for updates analysis.");
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const major = [];
|
|
91
|
+
const minor = [];
|
|
92
|
+
const patch = [];
|
|
93
|
+
let libyears = 0;
|
|
94
|
+
for (const mode of Object.values(parsed.results)) for (const depGroup of Object.values(mode)) for (const [name, dep] of Object.entries(depGroup)) {
|
|
95
|
+
if (name === "@types/node") continue;
|
|
96
|
+
if (dep.age) libyears += parseAgeToYears(dep.age);
|
|
97
|
+
const packageStatus = {
|
|
98
|
+
name,
|
|
99
|
+
new: dep.new,
|
|
100
|
+
old: dep.old
|
|
101
|
+
};
|
|
102
|
+
if (dep.age) packageStatus.age = dep.age;
|
|
103
|
+
if (dep.info) packageStatus.info = dep.info;
|
|
104
|
+
switch (classifyBump(dep.old, dep.new)) {
|
|
105
|
+
case "major":
|
|
106
|
+
major.push(packageStatus);
|
|
107
|
+
break;
|
|
108
|
+
case "minor":
|
|
109
|
+
minor.push(packageStatus);
|
|
110
|
+
break;
|
|
111
|
+
case "patch":
|
|
112
|
+
patch.push(packageStatus);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
data: {
|
|
118
|
+
major,
|
|
119
|
+
minor,
|
|
120
|
+
patch
|
|
121
|
+
},
|
|
122
|
+
extra: {
|
|
123
|
+
libyears: Math.round(libyears * 10) / 10,
|
|
124
|
+
total: major.length + minor.length + patch.length
|
|
125
|
+
},
|
|
126
|
+
source: input
|
|
127
|
+
};
|
|
128
|
+
},
|
|
129
|
+
phase: 1
|
|
130
|
+
});
|
|
131
|
+
//#endregion
|
|
132
|
+
export { dependencyUpdatesSource };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { OneOrMany, SourceRecord } from "../source.js";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/sources/file-stats.d.ts
|
|
4
|
+
type FileStats = {
|
|
5
|
+
/** Name of repo folder, possibly useful as a name fallback */folderName?: string; /** Total number of directories (recursive). */
|
|
6
|
+
totalDirectoryCount?: number; /** Total number of files (recursive). */
|
|
7
|
+
totalFileCount?: number; /** Total size of all files in bytes. */
|
|
8
|
+
totalSizeBytes?: number;
|
|
9
|
+
};
|
|
10
|
+
type FileStatsData = OneOrMany<SourceRecord<FileStats>> | undefined;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { FileStatsData };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { log } from "../log.js";
|
|
2
|
+
import { getMatches, getWorkspaces } from "../file-matching.js";
|
|
3
|
+
import { batchMap } from "../utilities/formatting.js";
|
|
4
|
+
import { defineSource } from "../source.js";
|
|
5
|
+
import { stat } from "node:fs/promises";
|
|
6
|
+
import path, { dirname } from "node:path";
|
|
7
|
+
//#region src/lib/sources/file-stats.ts
|
|
8
|
+
const fileStatsSource = defineSource({
|
|
9
|
+
async discover(context) {
|
|
10
|
+
return [context.options.path, ...getWorkspaces(context.options.path, context.options.workspaces)];
|
|
11
|
+
},
|
|
12
|
+
key: "fileStats",
|
|
13
|
+
async parse(input, context) {
|
|
14
|
+
log.debug("Extracting file statistics metadata...");
|
|
15
|
+
const allFiles = await getMatches({
|
|
16
|
+
...context.options,
|
|
17
|
+
path: input,
|
|
18
|
+
recursive: false,
|
|
19
|
+
workspaces: false
|
|
20
|
+
}, ["**"]);
|
|
21
|
+
const totalFileCount = allFiles.length;
|
|
22
|
+
const uniqueDirectories = /* @__PURE__ */ new Set();
|
|
23
|
+
for (const file of allFiles) {
|
|
24
|
+
const directory = dirname(file);
|
|
25
|
+
if (directory !== input) uniqueDirectories.add(directory);
|
|
26
|
+
}
|
|
27
|
+
const totalDirectoryCount = uniqueDirectories.size;
|
|
28
|
+
const totalSizeBytes = (await batchMap(allFiles, async (file) => {
|
|
29
|
+
try {
|
|
30
|
+
return (await stat(file)).size;
|
|
31
|
+
} catch {
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
}, 100)).reduce((sum, size) => sum + size, 0);
|
|
35
|
+
return {
|
|
36
|
+
data: {
|
|
37
|
+
folderName: input.split(path.sep).at(-1),
|
|
38
|
+
totalDirectoryCount,
|
|
39
|
+
totalFileCount,
|
|
40
|
+
totalSizeBytes
|
|
41
|
+
},
|
|
42
|
+
source: input
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
phase: 1
|
|
46
|
+
});
|
|
47
|
+
//#endregion
|
|
48
|
+
export { fileStatsSource };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { OneOrMany, SourceRecord } from "../source.js";
|
|
2
|
+
import { GitConfig } from "pkg-types";
|
|
3
|
+
|
|
4
|
+
//#region src/lib/sources/git-config.d.ts
|
|
5
|
+
type GitConfigInfo = GitConfig;
|
|
6
|
+
type GitConfigData = OneOrMany<SourceRecord<GitConfigInfo>> | undefined;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { GitConfigData };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { log } from "../log.js";
|
|
2
|
+
import { getMatches } from "../file-matching.js";
|
|
3
|
+
import { defineSource } from "../source.js";
|
|
4
|
+
import { readGitConfig } from "pkg-types";
|
|
5
|
+
//#region src/lib/sources/git-config.ts
|
|
6
|
+
const gitConfigSource = defineSource({
|
|
7
|
+
async discover(context) {
|
|
8
|
+
return getMatches(context.options, [".git/config"]);
|
|
9
|
+
},
|
|
10
|
+
key: "gitConfig",
|
|
11
|
+
async parse(input) {
|
|
12
|
+
log.debug("Extracting git config metadata...");
|
|
13
|
+
return {
|
|
14
|
+
data: { ...await readGitConfig(input) },
|
|
15
|
+
source: input
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
phase: 1
|
|
19
|
+
});
|
|
20
|
+
//#endregion
|
|
21
|
+
export { gitConfigSource };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { OneOrMany, SourceRecord } from "../source.js";
|
|
2
|
+
|
|
3
|
+
//#region src/lib/sources/git-stats.d.ts
|
|
4
|
+
type GitStatsInfo = {
|
|
5
|
+
/** Total number of local branches. */branchCount?: number; /** Name of the currently checked-out branch. */
|
|
6
|
+
branchCurrent?: string; /** Total number of commits in the current branch. */
|
|
7
|
+
commitCount?: number; /** ISO 8601 date of the repository's first commit. */
|
|
8
|
+
commitDateFirst?: string; /** ISO 8601 date of the most recent commit. */
|
|
9
|
+
commitDateLast?: string; /** Number of unique commit author emails. */
|
|
10
|
+
contributorCount?: number; /** Whether the repo uses Git LFS. */
|
|
11
|
+
hasLfs?: boolean; /** Whether the working tree has no uncommitted changes. */
|
|
12
|
+
isClean?: boolean; /** Whether the working tree has uncommitted changes. */
|
|
13
|
+
isDirty?: boolean; /** Whether any remote is ahead of the local branch. */
|
|
14
|
+
isRemoteAhead?: boolean; /** Number of configured remotes. */
|
|
15
|
+
remoteCount?: number; /** Per-remote ahead/behind commit counts relative to HEAD. */
|
|
16
|
+
remoteStatus?: Record<string, {
|
|
17
|
+
ahead: number;
|
|
18
|
+
behind: number;
|
|
19
|
+
}>; /** Number of registered git submodules. */
|
|
20
|
+
submoduleCount?: number; /** Total number of tags. */
|
|
21
|
+
tagCount?: number; /** ISO 8601 date of the most recent tag. */
|
|
22
|
+
tagDateLatest?: string; /** Name of the most recent tag. */
|
|
23
|
+
tagNameLatest?: string; /** Number of tags matching a version pattern (e.g. v1.2.3). */
|
|
24
|
+
tagReleaseCount?: number; /** ISO 8601 date of the most recent version tag. */
|
|
25
|
+
tagVersionDateLatest?: string; /** Most recent version tag, without the leading "v". */
|
|
26
|
+
tagVersionLatest?: string; /** Total commits ahead of all remotes combined. */
|
|
27
|
+
totalAhead?: number; /** Total commits behind all remotes combined. */
|
|
28
|
+
totalBehind?: number; /** Number of files tracked by git. */
|
|
29
|
+
trackedFileCount?: number; /** Total size in bytes of all tracked files. */
|
|
30
|
+
trackedSizeBytes?: number; /** Number of files with staged or unstaged changes. */
|
|
31
|
+
uncommittedFileCount?: number;
|
|
32
|
+
};
|
|
33
|
+
type GitStatsData = OneOrMany<SourceRecord<GitStatsInfo>> | undefined;
|
|
34
|
+
//#endregion
|
|
35
|
+
export { GitStatsData };
|