-
Notifications
You must be signed in to change notification settings - Fork 254
Expand file tree
/
Copy pathsync.ts
More file actions
71 lines (61 loc) · 2.99 KB
/
sync.ts
File metadata and controls
71 lines (61 loc) · 2.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import fs from "fs";
import {FetchingJSONSchemaStore, InputData, JSONSchemaInput, quicktype} from "quicktype-core";
const ECOSYSTEM_DATA_URL = "https://thunderstore.io/api/experimental/schema/dev/latest/";
const ECOSYSTEM_JSON_SCHEMA_URL = "https://thunderstore.io/api/experimental/schema/ecosystem-json-schema/latest/";
const ECOSYSTEM_DATA_PATH = "./src/assets/data/ecosystem.json";
const ECOSYSTEM_JSON_SCHEMA_PATH = "./src/assets/data/ecosystemJsonSchema.json";
const ECOSYSTEM_DATA_TYPES_PATH = "./src/assets/data/ecosystemTypes.ts";
/**
* This script synchronizes the in-repo ecosystem schema JSON to the latest
* version and generates matching TypeScript types.
*
* To only generate the TypeScript types without syncing with the
* Thunderstore API, use `yarn sync -- --types-only`
*/
async function updateSchema() {
let schema: Buffer;
if (process.argv.includes('--types-only')) {
console.log("Skipping API update, reading JSON schema from disk...");
schema = fs.readFileSync(ECOSYSTEM_JSON_SCHEMA_PATH);
} else {
console.log("Updating ecosystem.json...");
const response = await fetch(ECOSYSTEM_DATA_URL);
if (response.status !== 200) {
throw new Error(`Received non-200 status from schema API: ${response.status}`);
}
const data = Buffer.from(await response.arrayBuffer());
fs.writeFileSync(ECOSYSTEM_DATA_PATH, data);
console.log("Updating ecosystemJsonSchema.json...");
const schemaResponse = await fetch(ECOSYSTEM_JSON_SCHEMA_URL);
if (schemaResponse.status !== 200) {
throw new Error(`Received non-200 status from schema API: ${schemaResponse.status}`);
}
schema = Buffer.from(await schemaResponse.arrayBuffer());
fs.writeFileSync(ECOSYSTEM_JSON_SCHEMA_PATH, schema);
}
console.log("Updating ecosystemTypes.ts...");
const schemaInput = new JSONSchemaInput(new FetchingJSONSchemaStore());
await schemaInput.addSource({name: "ThunderstoreEcosystem", schema: schema.toString()});
const inputData = new InputData();
inputData.addInput(schemaInput);
const types = await quicktype({
inputData,
lang: "typescript",
leadingComments: [{descriptionBlock: [
"This file is automatically generated by the sync.ts script.",
"Do not edit it manually.",
]}],
});
const finalTypes = enumKeysToUpperSnakeCase(types.lines.join("\n"));
fs.writeFileSync(ECOSYSTEM_DATA_TYPES_PATH, finalTypes);
}
updateSchema();
function enumKeysToUpperSnakeCase(tsCode: string): string {
const enumRegex = /export enum (\w+) \{([\s\S]*?)\}/g;
const enumKeyValueRegex = /(\w+) = "(.*?)"/g;
const enumKeyValueReplacer = (_: string, enumKey: string, enumValue: string) =>
`${enumValue.replace(/-/g, "_").toUpperCase()} = "${enumValue}"`;
return tsCode.replace(enumRegex, (_, enumName, enumBody) =>
`export enum ${enumName} {${enumBody.replace(enumKeyValueRegex, enumKeyValueReplacer)}}`
);
}