server.ts: migrate to TypeScript

This commit is contained in:
liushuyu 2022-11-27 01:34:14 -07:00
parent d98c7c01e0
commit f4c18e0844
No known key found for this signature in database
GPG Key ID: 23D1CE4534419437
4 changed files with 64 additions and 18 deletions

View File

@ -9,5 +9,5 @@ You will need Deno, which is a more modern alternative to Node.js. You can insta
When it's installed, just run the following command: When it's installed, just run the following command:
```bash ```bash
deno run --allow-env=PATH --allow-read --allow-write=/citra/nginx/,temp --allow-net=api.github.com --allow-run server.js deno run --allow-env=PATH --allow-read --allow-write=/citra/nginx/,temp --allow-net=api.github.com --allow-run server.ts
``` ```

View File

@ -1,5 +1,5 @@
{ {
"tasks": { "tasks": {
"bundle": "deno bundle server.js -- server.bundle.js" "bundle": "deno bundle server.ts -- server.bundle.js"
} }
} }

14
deno.lock Normal file
View File

@ -0,0 +1,14 @@
{
"version": "2",
"remote": {
"https://deno.land/x/which@0.2.1/mod.ts": "2e076cb85aea9798662b355fb613d27eebcc78dfc8934ece4ae932f6303f6ca8",
"https://deno.land/x/xml@2.0.4/mod.ts": "e0f63d82d3bb4c082e009956a34a2b3a31006dbdc28b25d27c5089feb8e9fa4f",
"https://deno.land/x/xml@2.0.4/parse.ts": "db7c16f4bcb0d47fc704e2d7e11e54716d195e4ba9f8fd8a28aa09007c02749d",
"https://deno.land/x/xml@2.0.4/stringify.ts": "67989ecd99f25a1c4730f8eb45ea3d9ca8c17ed083851593053a9198e0ca9fff",
"https://deno.land/x/xml@2.0.4/utils/parser.ts": "b2dd27d70e0ff5e9a4f28b7b3e6e4e6ea54714b4695c628fc37050f20e5ee3a5",
"https://deno.land/x/xml@2.0.4/utils/stream.ts": "f7a5b219e8c1981b8f48353167fb7eb116a8c0f84a375068d036a1ba848e0673",
"https://deno.land/x/xml@2.0.4/utils/streamable.ts": "d6429add37e740b0a4f1970d8d55ae9798309805c5126e03963533872a20d81d",
"https://deno.land/x/xml@2.0.4/utils/stringifier.ts": "094d4353b3f71b64dded80ed50e98c994b6da89957c91152f24d320f0082d67e",
"https://deno.land/x/xml@2.0.4/utils/types.ts": "290c064b2b6bd9497bb67835488a2a9546437e06e54b295b214668a1b947e3e5"
}
}

View File

@ -1,10 +1,42 @@
import * as xml from "https://deno.land/x/xml@2.0.4/mod.ts"; import * as xml from "https://deno.land/x/xml@2.0.4/mod.ts";
import { which } from "https://deno.land/x/which@0.2.1/mod.ts"; import { which } from "https://deno.land/x/which@0.2.1/mod.ts";
interface ITargetLicense {
License: { [index: string]: string };
}
interface ITargetSource {
Name: string;
DisplayName: string;
Description: string;
Repo: string;
ScriptName: string;
Default: string;
Licenses: ITargetLicense[];
}
interface IOutputTarget {
Name: string;
DisplayName: string;
Version: string;
DownloadableArchives: string;
UpdateFile: {
"@UncompressedSize": number;
"@CompressedSize": number;
"@OS": string;
};
ReleaseDate: string;
Description: string;
Default: string;
Licenses: ITargetLicense[];
Script: string;
SHA: string;
}
const tempDir = "./temp"; const tempDir = "./temp";
const distDir = "/citra/nginx/citra_repo"; const distDir = "/citra/nginx/citra_repo";
async function getReleases(repo) { async function getReleases(repo: string) {
const result = await fetch(`https://api.github.com/repos/${repo}/releases`, { const result = await fetch(`https://api.github.com/repos/${repo}/releases`, {
headers: { headers: {
Accept: "application/vnd.github.v3+json", Accept: "application/vnd.github.v3+json",
@ -14,7 +46,7 @@ async function getReleases(repo) {
return result.json(); return result.json();
} }
async function checkExists(directory) { async function checkExists(directory: string) {
try { try {
await Deno.stat(directory); await Deno.stat(directory);
return true; return true;
@ -31,13 +63,13 @@ async function check7z() {
throw new Error("7-zip is not available!"); throw new Error("7-zip is not available!");
} }
function bufferToHex(buffer) { function bufferToHex(buffer: ArrayBuffer) {
return [...new Uint8Array(buffer)] return [...new Uint8Array(buffer)]
.map((b) => b.toString(16).padStart(2, "0")) .map((b) => b.toString(16).padStart(2, "0"))
.join(""); .join("");
} }
function getTopResultFor(jsonData, platform) { function getTopResultFor(jsonData: any, platform: string) {
for (const releaseKey in jsonData) { for (const releaseKey in jsonData) {
const release = jsonData[releaseKey]; const release = jsonData[releaseKey];
for (const assetKey in release.assets) { for (const assetKey in release.assets) {
@ -59,7 +91,7 @@ function getTopResultFor(jsonData, platform) {
// The Qt Installer Framework is a pain to build or download. // The Qt Installer Framework is a pain to build or download.
// Because all we need are a few 7-zipped + xml files, we might as well generate them for ourselves. // Because all we need are a few 7-zipped + xml files, we might as well generate them for ourselves.
const targets = [ const targets: ITargetSource[] = [
{ {
Name: "org.citra.nightly.%platform%", Name: "org.citra.nightly.%platform%",
DisplayName: "Citra Nightly", DisplayName: "Citra Nightly",
@ -124,13 +156,13 @@ async function execute() {
ApplicationName: "{AnyApplication}", ApplicationName: "{AnyApplication}",
ApplicationVersion: "1.0.0", // Separate from nightly / canary versions ApplicationVersion: "1.0.0", // Separate from nightly / canary versions
Checksum: false, // As they are pulled straight from Github Checksum: false, // As they are pulled straight from Github
PackageUpdate: [], PackageUpdate: new Array<IOutputTarget>(),
}; };
async function generate(targetSource, platform) { async function generate(targetSource: ITargetSource, platform: string) {
// Get Git metadata // Get Git metadata
const releaseData = getTopResultFor(targetSource.Repo, platform); const releaseData = getTopResultFor(targetSource.Repo, platform);
const name = targetSource.Name.replace("%platform%", platform); const name: string = targetSource.Name.replace("%platform%", platform);
if (releaseData.notFound === true) { if (releaseData.notFound === true) {
console.error(`Release information not found for ${name}!`); console.error(`Release information not found for ${name}!`);
@ -143,7 +175,7 @@ async function execute() {
const targetMetadataFilePath = `${distDir}/${name}/${version}meta.7z`; const targetMetadataFilePath = `${distDir}/${name}/${version}meta.7z`;
if (await checkExists(targetMetadataFilePath)) { if (await checkExists(targetMetadataFilePath)) {
console.debug( console.debug(
`Metadata information already exists for ${name} ${version}, skipping.`, `Metadata information already exists for ${name} ${version}, skipping.`
); );
} else { } else {
console.info(`Building release information for ${name} ${version}.`); console.info(`Building release information for ${name} ${version}.`);
@ -157,7 +189,7 @@ async function execute() {
await Deno.copyFile("license.txt", `${workingDirectoryPath}/license.txt`); await Deno.copyFile("license.txt", `${workingDirectoryPath}/license.txt`);
await Deno.copyFile( await Deno.copyFile(
`scripts/${scriptName}.qs`, `scripts/${scriptName}.qs`,
`${workingDirectoryPath}/installscript.qs`, `${workingDirectoryPath}/installscript.qs`
); );
// Create 7zip archive // Create 7zip archive
@ -169,13 +201,13 @@ async function execute() {
const status = (await proc.status()).code; const status = (await proc.status()).code;
if (status !== 0) { if (status !== 0) {
throw new Error( throw new Error(
`Error when creating ${name} archive. Exited with ${status}.`, `Error when creating ${name} archive. Exited with ${status}.`
); );
} }
// Copy the metadata file into the target path. // Copy the metadata file into the target path.
console.debug( console.debug(
`Creating target metadata for ${name} at ${targetMetadataFilePath}`, `Creating target metadata for ${name} at ${targetMetadataFilePath}`
); );
await Deno.mkdir(`${distDir}/${name}`, { recursive: true }); await Deno.mkdir(`${distDir}/${name}`, { recursive: true });
await Deno.rename(`${tempDir}/${fileName}`, `${targetMetadataFilePath}`); await Deno.rename(`${tempDir}/${fileName}`, `${targetMetadataFilePath}`);
@ -187,7 +219,7 @@ async function execute() {
// Create metadata for the Update.xml // Create metadata for the Update.xml
const metaHash = await crypto.subtle.digest( const metaHash = await crypto.subtle.digest(
"SHA-1", "SHA-1",
await Deno.readFile(targetMetadataFilePath), await Deno.readFile(targetMetadataFilePath)
); );
const target = { const target = {
@ -220,9 +252,9 @@ async function execute() {
await Promise.all( await Promise.all(
["mingw", "osx", "linux"].map((platform) => { ["mingw", "osx", "linux"].map((platform) => {
return Promise.all( return Promise.all(
targets.map((targetSource) => generate(targetSource, platform)), targets.map((targetSource) => generate(targetSource, platform))
); );
}), })
); );
if (updatesAvailable) { if (updatesAvailable) {
@ -233,7 +265,7 @@ async function execute() {
console.info("Wrote a new Updates.xml file -- updates available."); console.info("Wrote a new Updates.xml file -- updates available.");
} else { } else {
console.info( console.info(
"No Citra binary release updates are available for the Updates.xml -- nothing to do.", "No Citra binary release updates are available for the Updates.xml -- nothing to do."
); );
} }