@naesofteak/naeso 0.0.0-stage → 1.0.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.
@@ -0,0 +1,284 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const {
5
+ resolvePackage
6
+ } = require("./package-resolver");
7
+
8
+ const {
9
+ downloadFile
10
+ } = require("./downloader");
11
+
12
+ const {
13
+ calculateSHA256
14
+ } = require("./checksum");
15
+
16
+ const {
17
+ ensurePackageCache,
18
+ getCachedFile
19
+ } = require("./cache");
20
+
21
+ async function verifyArtifact(
22
+ artifact,
23
+ archivePath,
24
+ packageName
25
+ ) {
26
+ /*
27
+ * If the registry provides an official SHA-256 URL,
28
+ * download and verify it.
29
+ */
30
+ if (artifact.sha256Url) {
31
+ const archiveName =
32
+ path.basename(
33
+ new URL(artifact.url).pathname
34
+ );
35
+
36
+ const checksumName =
37
+ `${archiveName}.sha256`;
38
+
39
+ const checksumPath =
40
+ getCachedFile(
41
+ packageName,
42
+ checksumName
43
+ );
44
+
45
+ if (fs.existsSync(checksumPath)) {
46
+ console.log(
47
+ `Checksum file already exists: ${checksumPath}`
48
+ );
49
+ } else {
50
+ console.log(
51
+ "Downloading official SHA-256 checksum..."
52
+ );
53
+
54
+ await downloadFile(
55
+ artifact.sha256Url,
56
+ checksumPath
57
+ );
58
+
59
+ console.log(
60
+ `Downloaded: ${checksumPath}`
61
+ );
62
+ }
63
+
64
+ const checksumText =
65
+ fs.readFileSync(
66
+ checksumPath,
67
+ "utf8"
68
+ ).trim();
69
+
70
+ const expectedHash =
71
+ checksumText
72
+ .split(/\s+/)[0]
73
+ .toLowerCase();
74
+
75
+ if (!/^[a-f0-9]{64}$/.test(expectedHash)) {
76
+ throw new Error(
77
+ `Invalid SHA-256 checksum for ${artifact.name}.`
78
+ );
79
+ }
80
+
81
+ console.log(
82
+ `Expected SHA-256: ${expectedHash}`
83
+ );
84
+
85
+ console.log(
86
+ "Calculating downloaded archive SHA-256..."
87
+ );
88
+
89
+ const actualHash =
90
+ (
91
+ await calculateSHA256(
92
+ archivePath
93
+ )
94
+ ).toLowerCase();
95
+
96
+ console.log(
97
+ `Actual SHA-256: ${actualHash}`
98
+ );
99
+
100
+ if (actualHash !== expectedHash) {
101
+ fs.unlinkSync(archivePath);
102
+
103
+ throw new Error(
104
+ `${artifact.name} failed SHA-256 verification.`
105
+ );
106
+ }
107
+
108
+ console.log(
109
+ `${artifact.name} SHA-256 verification PASSED.`
110
+ );
111
+
112
+ return {
113
+ verified: true,
114
+ checksum: expectedHash
115
+ };
116
+ }
117
+
118
+ /*
119
+ * No official checksum URL is registered yet.
120
+ *
121
+ * We still calculate the local SHA-256 so that the
122
+ * artifact gets a deterministic fingerprint.
123
+ */
124
+ console.log(
125
+ `No official SHA-256 URL registered for ${artifact.name}.`
126
+ );
127
+
128
+ const actualHash =
129
+ (
130
+ await calculateSHA256(
131
+ archivePath
132
+ )
133
+ ).toLowerCase();
134
+
135
+ console.log(
136
+ `SHA-256: ${actualHash}`
137
+ );
138
+
139
+ return {
140
+ verified: false,
141
+ checksum: actualHash
142
+ };
143
+ }
144
+
145
+ async function downloadArtifact(
146
+ packageName,
147
+ artifact
148
+ ) {
149
+ const cacheDirectory =
150
+ ensurePackageCache(
151
+ packageName
152
+ );
153
+
154
+ const archiveName =
155
+ path.basename(
156
+ new URL(artifact.url).pathname
157
+ );
158
+
159
+ const archivePath =
160
+ getCachedFile(
161
+ packageName,
162
+ archiveName
163
+ );
164
+
165
+ console.log("");
166
+ console.log(
167
+ `Artifact: ${artifact.name}`
168
+ );
169
+ console.log(
170
+ `Type: ${artifact.type}`
171
+ );
172
+ console.log(
173
+ `Version: ${artifact.version}`
174
+ );
175
+ console.log(
176
+ `URL: ${artifact.url}`
177
+ );
178
+ console.log("");
179
+
180
+ if (fs.existsSync(archivePath)) {
181
+ console.log(
182
+ `Archive already exists: ${archivePath}`
183
+ );
184
+ } else {
185
+ console.log(
186
+ `Downloading ${archiveName}...`
187
+ );
188
+
189
+ await downloadFile(
190
+ artifact.url,
191
+ archivePath
192
+ );
193
+
194
+ console.log(
195
+ `Downloaded: ${archivePath}`
196
+ );
197
+ }
198
+
199
+ const verification =
200
+ await verifyArtifact(
201
+ artifact,
202
+ archivePath,
203
+ packageName
204
+ );
205
+
206
+ return {
207
+ ...artifact,
208
+ archive: archivePath,
209
+ checksum: verification.checksum,
210
+ verified: verification.verified
211
+ };
212
+ }
213
+
214
+ async function downloadPackage(
215
+ packageName,
216
+ requestedVersion = null
217
+ ) {
218
+ const resolved =
219
+ resolvePackage(
220
+ packageName,
221
+ requestedVersion
222
+ );
223
+
224
+ const {
225
+ package: pkg,
226
+ version,
227
+ target,
228
+ artifacts
229
+ } = resolved;
230
+
231
+ console.log("");
232
+ console.log(
233
+ "Naeso Package Download"
234
+ );
235
+ console.log(
236
+ "----------------------"
237
+ );
238
+ console.log(
239
+ `Package: ${pkg.name}`
240
+ );
241
+ console.log(
242
+ `Version: ${version}`
243
+ );
244
+ console.log(
245
+ `Target: ${target}`
246
+ );
247
+ console.log("");
248
+
249
+ const downloaded = {};
250
+
251
+ for (
252
+ const [artifactName, artifact]
253
+ of Object.entries(artifacts)
254
+ ) {
255
+ const artifactWithName = {
256
+ ...artifact,
257
+ name: artifactName
258
+ };
259
+
260
+ downloaded[artifactName] =
261
+ await downloadArtifact(
262
+ packageName,
263
+ artifactWithName
264
+ );
265
+ }
266
+
267
+ console.log("");
268
+ console.log(
269
+ "All MongoDB artifacts downloaded."
270
+ );
271
+ console.log("");
272
+
273
+ return {
274
+ package: pkg.name,
275
+ version,
276
+ target,
277
+ artifacts: downloaded
278
+ };
279
+ }
280
+
281
+ module.exports = {
282
+ downloadPackage,
283
+ downloadArtifact
284
+ };
File without changes
@@ -0,0 +1,125 @@
1
+ const { getPackage } = require("./registry");
2
+ const { getTarget } = require("./target");
3
+
4
+ const {
5
+ getLatestVersion,
6
+ getVersionConfig,
7
+ isPackageSupported
8
+ } = require("./compatibility");
9
+
10
+ function resolvePackage(packageName, requestedVersion = null) {
11
+ const pkg = getPackage(packageName);
12
+
13
+ if (!pkg) {
14
+ throw new Error(
15
+ `Package '${packageName}' not found.`
16
+ );
17
+ }
18
+
19
+ const target = getTarget();
20
+
21
+ const version =
22
+ requestedVersion ||
23
+ getLatestVersion(pkg);
24
+
25
+ if (!version) {
26
+ throw new Error(
27
+ `No versions available for '${packageName}'.`
28
+ );
29
+ }
30
+
31
+ const versionConfig =
32
+ getVersionConfig(pkg, version);
33
+
34
+ if (!versionConfig) {
35
+ throw new Error(
36
+ `Version '${version}' not found for '${packageName}'.`
37
+ );
38
+ }
39
+
40
+ if (
41
+ !isPackageSupported(
42
+ pkg,
43
+ target.target,
44
+ version
45
+ )
46
+ ) {
47
+ throw new Error(
48
+ `${packageName} ${version} does not support ${target.target}.`
49
+ );
50
+ }
51
+
52
+ const targetConfig =
53
+ versionConfig.config.targets[target.target];
54
+
55
+ if (!targetConfig) {
56
+ throw new Error(
57
+ `${packageName} ${version} does not support ${target.target}.`
58
+ );
59
+ }
60
+
61
+ /*
62
+ * New multi-artifact package format
63
+ */
64
+ if (targetConfig.artifacts) {
65
+ const artifacts = {};
66
+
67
+ for (
68
+ const [artifactName, artifactConfig]
69
+ of Object.entries(targetConfig.artifacts)
70
+ ) {
71
+ if (!artifactConfig.url) {
72
+ throw new Error(
73
+ `Artifact '${artifactName}' has no download URL.`
74
+ );
75
+ }
76
+
77
+ artifacts[artifactName] = {
78
+ name: artifactName,
79
+ type: artifactConfig.type,
80
+ version: artifactConfig.version || version,
81
+ url: artifactConfig.url,
82
+ sha256Url:
83
+ artifactConfig.sha256Url || null
84
+ };
85
+ }
86
+
87
+ return {
88
+ package: pkg,
89
+ version,
90
+ target: target.target,
91
+ artifacts
92
+ };
93
+ }
94
+
95
+ /*
96
+ * Backward compatibility with the old
97
+ * single-artifact package format.
98
+ */
99
+ if (targetConfig.url) {
100
+ return {
101
+ package: pkg,
102
+ version,
103
+ target: target.target,
104
+
105
+ artifacts: {
106
+ default: {
107
+ name: "default",
108
+ type: "tarball",
109
+ version,
110
+ url: targetConfig.url,
111
+ sha256Url:
112
+ targetConfig.sha256Url || null
113
+ }
114
+ }
115
+ };
116
+ }
117
+
118
+ throw new Error(
119
+ `No artifacts defined for ${packageName} ${version} on ${target.target}.`
120
+ );
121
+ }
122
+
123
+ module.exports = {
124
+ resolvePackage
125
+ };
@@ -0,0 +1,41 @@
1
+ const os = require("os");
2
+ const { execSync } = require("child_process");
3
+
4
+ function getPlatform() {
5
+ return process.platform;
6
+ }
7
+
8
+ function getArchitecture() {
9
+ return process.arch;
10
+ }
11
+
12
+ function getMacOSVersion() {
13
+ if (process.platform !== "darwin") {
14
+ return null;
15
+ }
16
+
17
+ try {
18
+ return execSync("sw_vers -productVersion")
19
+ .toString()
20
+ .trim();
21
+ } catch (error) {
22
+ return null;
23
+ }
24
+ }
25
+
26
+ function getPlatformInfo() {
27
+ return {
28
+ platform: getPlatform(),
29
+ architecture: getArchitecture(),
30
+ macosVersion: getMacOSVersion(),
31
+ hostname: os.hostname(),
32
+ cpuCount: os.cpus().length
33
+ };
34
+ }
35
+
36
+ module.exports = {
37
+ getPlatform,
38
+ getArchitecture,
39
+ getMacOSVersion,
40
+ getPlatformInfo
41
+ };
@@ -0,0 +1,70 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const REGISTRY_PATH = path.join(
5
+ __dirname,
6
+ "..",
7
+ "registry",
8
+ "packages"
9
+ );
10
+
11
+ function getPackagePath(packageName) {
12
+ return path.join(
13
+ REGISTRY_PATH,
14
+ packageName,
15
+ "package.json"
16
+ );
17
+ }
18
+
19
+ function getPackage(packageName) {
20
+ const packagePath = getPackagePath(packageName);
21
+
22
+ if (!fs.existsSync(packagePath)) {
23
+ return null;
24
+ }
25
+
26
+ try {
27
+ const data = fs.readFileSync(packagePath, "utf8");
28
+ return JSON.parse(data);
29
+ } catch (error) {
30
+ throw new Error(
31
+ `Invalid package definition: ${packageName}`
32
+ );
33
+ }
34
+ }
35
+
36
+ function packageExists(packageName) {
37
+ return fs.existsSync(getPackagePath(packageName));
38
+ }
39
+
40
+ function listPackages() {
41
+ if (!fs.existsSync(REGISTRY_PATH)) {
42
+ return [];
43
+ }
44
+
45
+ return fs
46
+ .readdirSync(REGISTRY_PATH, { withFileTypes: true })
47
+ .filter((entry) => entry.isDirectory())
48
+ .map((entry) => entry.name);
49
+ }
50
+
51
+ function searchPackages(keyword) {
52
+ const packages = listPackages();
53
+
54
+ if (!keyword) {
55
+ return packages;
56
+ }
57
+
58
+ const search = keyword.toLowerCase();
59
+
60
+ return packages.filter((packageName) =>
61
+ packageName.toLowerCase().includes(search)
62
+ );
63
+ }
64
+
65
+ module.exports = {
66
+ getPackage,
67
+ packageExists,
68
+ listPackages,
69
+ searchPackages
70
+ };
@@ -0,0 +1,56 @@
1
+ const {
2
+ getPlatformInfo
3
+ } = require("./platform");
4
+
5
+ function getTarget() {
6
+ const system = getPlatformInfo();
7
+
8
+ let platform;
9
+
10
+ switch (system.platform) {
11
+ case "darwin":
12
+ platform = "macos";
13
+ break;
14
+
15
+ case "linux":
16
+ platform = "linux";
17
+ break;
18
+
19
+ case "win32":
20
+ platform = "windows";
21
+ break;
22
+
23
+ default:
24
+ platform = system.platform;
25
+ }
26
+
27
+ let architecture;
28
+
29
+ switch (system.architecture) {
30
+ case "x64":
31
+ architecture = "x86_64";
32
+ break;
33
+
34
+ case "arm64":
35
+ architecture = "arm64";
36
+ break;
37
+
38
+ case "ia32":
39
+ architecture = "x86";
40
+ break;
41
+
42
+ default:
43
+ architecture = system.architecture;
44
+ }
45
+
46
+ return {
47
+ platform,
48
+ architecture,
49
+ target: `${platform}-${architecture}`,
50
+ version: system.macosVersion
51
+ };
52
+ }
53
+
54
+ module.exports = {
55
+ getTarget
56
+ };