generated from nhcarrigan/template
feat: add npm audit script, crowdin helpers now write data to disk
Node.js CI / Lint and Test (push) Failing after 34s
Node.js CI / Lint and Test (push) Failing after 34s
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* @copyright NHCarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import { readFile, appendFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { getLanguages } from "./utils/getLanguages.js";
|
||||
import type { String } from "./interfaces/string.js";
|
||||
|
||||
const projectId = process.env.CROWDIN_PROJECT_ID;
|
||||
const apiUrl = process.env.CROWDIN_API_URL;
|
||||
const token = process.env.CROWDIN_TOKEN;
|
||||
|
||||
if (
|
||||
projectId === undefined
|
||||
|| projectId === ""
|
||||
|| apiUrl === undefined
|
||||
|| apiUrl === ""
|
||||
|| token === undefined
|
||||
|| token === ""
|
||||
) {
|
||||
throw new Error(`Project ID or API URL is missing! Did you run this script with 'op run'?`);
|
||||
}
|
||||
|
||||
const logPath
|
||||
= join(import.meta.dirname, "..", "..", "data", "crowdin-strings-hidden.txt");
|
||||
|
||||
const languages = await getLanguages(projectId, apiUrl, token);
|
||||
console.log(`Found ${languages.length.toString()} active languages.`);
|
||||
const rawStrings = await readFile(
|
||||
join(import.meta.dirname, "..", "..", "data", "crowdin-strings.json"),
|
||||
"utf-8",
|
||||
);
|
||||
const strings: Array<String["data"][0]["data"]> = JSON.parse(rawStrings);
|
||||
console.log(`Found ${strings.length.toString()} strings.`);
|
||||
|
||||
const log = await readFile(
|
||||
logPath,
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const processedIds = log.split("\n");
|
||||
|
||||
const unprocessedStrings = strings.filter((string) => {
|
||||
return !processedIds.includes(string.id.toString());
|
||||
});
|
||||
|
||||
const hidden = unprocessedStrings.filter((string) => {
|
||||
return string.isHidden;
|
||||
});
|
||||
|
||||
console.log(`Processing ${hidden.length.toString()} hidden strings.`);
|
||||
|
||||
for (const string of hidden) {
|
||||
console.log(`Deleting translations for ${string.id.toString()}`);
|
||||
await Promise.all(languages.map(async(language) => {
|
||||
await fetch(`${apiUrl}/projects/${projectId}/translations`, {
|
||||
body: JSON.stringify({
|
||||
languageId: language,
|
||||
stringId: string.id,
|
||||
}),
|
||||
headers: {
|
||||
"authorization": `Bearer ${token}`,
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention -- header.
|
||||
"content-type": "application/json",
|
||||
},
|
||||
method: "DELETE",
|
||||
});
|
||||
}));
|
||||
await appendFile(logPath, `${string.id.toString()}\n`);
|
||||
}
|
||||
|
||||
console.log("Completed!");
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @copyright NHCarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
export interface String {
|
||||
data: Array<{
|
||||
data: {
|
||||
id: number;
|
||||
projectId: number;
|
||||
branchId: number;
|
||||
identifier: string;
|
||||
text: string;
|
||||
type: string;
|
||||
context: string;
|
||||
maxLength: number;
|
||||
isHidden: boolean;
|
||||
isDuplicate: boolean;
|
||||
masterStringId: number;
|
||||
hasPlurals: boolean;
|
||||
isIcu: boolean;
|
||||
labelIds: Array<number>;
|
||||
webUrl: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
fileId: number;
|
||||
directoryId: number;
|
||||
revision: number;
|
||||
};
|
||||
}>;
|
||||
pagination: {
|
||||
offset: number;
|
||||
limit: number;
|
||||
};
|
||||
}
|
||||
@@ -18,10 +18,10 @@ export const getFiles
|
||||
projectId: string,
|
||||
apiUrl: string,
|
||||
token: string,
|
||||
): Promise<Array<number>> => {
|
||||
): Promise<Array<File["data"][0]>> => {
|
||||
const url = `${apiUrl}/projects/${projectId}/files?limit=500`;
|
||||
let offset = 0;
|
||||
const ids: Array<number> = [];
|
||||
const files: Array<File["data"][0]> = [];
|
||||
|
||||
console.log(`Requesting files ${offset.toString()} to ${(offset + 500).toString()}`);
|
||||
let request = await fetch(url, {
|
||||
@@ -30,9 +30,7 @@ export const getFiles
|
||||
},
|
||||
});
|
||||
let response: File = await request.json();
|
||||
ids.push(...response.data.map((datum) => {
|
||||
return datum.data.id;
|
||||
}));
|
||||
files.push(...response.data);
|
||||
while (response.data.length >= 500) {
|
||||
offset = offset + 500;
|
||||
console.log(`Requesting files ${offset.toString()} to ${(offset + 500).toString()}`);
|
||||
@@ -42,9 +40,7 @@ export const getFiles
|
||||
},
|
||||
});
|
||||
response = await request.json();
|
||||
ids.push(...response.data.map((datum) => {
|
||||
return datum.data.id;
|
||||
}));
|
||||
files.push(...response.data);
|
||||
}
|
||||
return ids;
|
||||
return files;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* @copyright NHCarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import type { String } from "../interfaces/string.js";
|
||||
|
||||
/**
|
||||
* Gets a list of all strings from a project.
|
||||
* @param projectId - The project ID (a numeric string).
|
||||
* @param apiUrl - The base URL for the API.
|
||||
* @param token - The API key.
|
||||
* @returns An array of string objects.
|
||||
*/
|
||||
export const getStrings
|
||||
= async(
|
||||
projectId: string,
|
||||
apiUrl: string,
|
||||
token: string,
|
||||
): Promise<Array<String["data"][0]["data"]>> => {
|
||||
const url = `${apiUrl}/projects/${projectId}/strings?limit=500`;
|
||||
let offset = 0;
|
||||
const strings: Array<String["data"][0]["data"]> = [];
|
||||
|
||||
console.log(`Requesting strings ${offset.toString()} to ${(offset + 500).toString()}`);
|
||||
let request = await fetch(url, {
|
||||
headers: {
|
||||
authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
let response: String = await request.json();
|
||||
strings.push(...response.data.map((datum) => {
|
||||
return datum.data;
|
||||
}));
|
||||
while (response.data.length >= 500) {
|
||||
offset = offset + 500;
|
||||
console.log(`Requesting strings ${offset.toString()} to ${(offset + 500).toString()}`);
|
||||
request = await fetch(`${url}&offset=${offset.toString()}`, {
|
||||
headers: {
|
||||
authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
response = await request.json();
|
||||
strings.push(...response.data.map((datum) => {
|
||||
return datum.data;
|
||||
}));
|
||||
}
|
||||
return strings;
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @copyright NHCarrigan
|
||||
* @license Naomi's Public License
|
||||
* @author Naomi Carrigan
|
||||
*/
|
||||
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { getFiles } from "./utils/getFiles.js";
|
||||
import { getStrings } from "./utils/getStrings.js";
|
||||
|
||||
const projectId = process.env.CROWDIN_PROJECT_ID;
|
||||
const apiUrl = process.env.CROWDIN_API_URL;
|
||||
const token = process.env.CROWDIN_TOKEN;
|
||||
|
||||
if (
|
||||
projectId === undefined
|
||||
|| projectId === ""
|
||||
|| apiUrl === undefined
|
||||
|| apiUrl === ""
|
||||
|| token === undefined
|
||||
|| token === ""
|
||||
) {
|
||||
throw new Error(`Project ID or API URL is missing! Did you run this script with 'op run'?`);
|
||||
}
|
||||
|
||||
const files = await getFiles(projectId, apiUrl, token);
|
||||
const strings = await getStrings(projectId, apiUrl, token);
|
||||
|
||||
await writeFile(
|
||||
join(import.meta.dirname, "..", "..", "data", "crowdin-files.json"),
|
||||
JSON.stringify(files, null, 2),
|
||||
"utf-8",
|
||||
);
|
||||
await writeFile(
|
||||
join(import.meta.dirname, "..", "..", "data", "crowdin-strings.json"),
|
||||
JSON.stringify(strings, null, 2),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
console.log("Loaded files and strings!");
|
||||
Reference in New Issue
Block a user