diff --git a/scripts/genIndex.js b/scripts/genIndex.js
index c1b68227..e4601f3e 100644
--- a/scripts/genIndex.js
+++ b/scripts/genIndex.js
@@ -41,29 +41,29 @@ let content = `/*
// node scripts/genIndex.js /path/to/dir
const targetDir = process.argv[2];
if (!targetDir) {
- console.error("Please provide a target directory.");
- process.exit(1);
+ console.error("Please provide a target directory.");
+ process.exit(1);
}
if (fs.existsSync(path.join(targetDir, "index.js")) || fs.existsSync(path.join(targetDir, "index.ts"))) {
- console.error("index.js or index.ts already exists in the target directory.");
- process.exit(1);
+ console.error("index.js or index.ts already exists in the target directory.");
+ process.exit(1);
}
const dirs = fs.readdirSync(targetDir).filter((f) => fs.statSync(path.join(targetDir, f)).isDirectory());
for (const dir of dirs) {
- content += `export * from "./${dir}";\n`;
+ content += `export * from "./${dir}";\n`;
}
const files = fs.readdirSync(targetDir).filter((f) => f.endsWith(".js") || f.endsWith(".ts"));
for (const file of files) {
- const filePath = path.join(targetDir, file);
- const stat = fs.statSync(filePath);
- if (stat.isFile()) {
- const ext = path.extname(file);
- const base = path.basename(file, ext);
- content += `export * from "./${base}";\n`;
- }
+ const filePath = path.join(targetDir, file);
+ const stat = fs.statSync(filePath);
+ if (stat.isFile()) {
+ const ext = path.extname(file);
+ const base = path.basename(file, ext);
+ content += `export * from "./${base}";\n`;
+ }
}
fs.writeFileSync(path.join(targetDir, "index.ts"), content);
diff --git a/scripts/license.js b/scripts/license.js
index 380a3ed6..0cc9b094 100644
--- a/scripts/license.js
+++ b/scripts/license.js
@@ -12,43 +12,43 @@ const walk = require("./util/walk");
const SPACEBAR_SOURCE_DIR = Path.join(__dirname, "..", "src");
const SPACEBAR_SCRIPTS_DIR = Path.join(__dirname);
const SPACEBAR_LICENSE_PREAMBLE = fs
- .readFileSync(Path.join(__dirname, "util", "licensePreamble.txt"))
- .toString()
- .split("\r") // remove windows bs
- .join("") // ^
- .split("\n")
- .map((x) => `\t${x}`)
- .join("\n");
+ .readFileSync(Path.join(__dirname, "util", "licensePreamble.txt"))
+ .toString()
+ .split("\r") // remove windows bs
+ .join("") // ^
+ .split("\n")
+ .map((x) => `\t${x}`)
+ .join("\n");
const languageCommentStrings = {
- js: ["/*", "*/"],
- ts: ["/*", "*/"],
+ js: ["/*", "*/"],
+ ts: ["/*", "*/"],
};
const addToDir = (dir) => {
- const files = walk(dir, Object.keys(languageCommentStrings));
+ const files = walk(dir, Object.keys(languageCommentStrings));
- for (let path of files) {
- const file = fs.readFileSync(path).toString().split("\r").join("");
- const fileType = path.slice(path.lastIndexOf(".") + 1);
- const commentStrings = languageCommentStrings[fileType];
- if (!commentStrings) continue;
+ for (let path of files) {
+ const file = fs.readFileSync(path).toString().split("\r").join("");
+ const fileType = path.slice(path.lastIndexOf(".") + 1);
+ const commentStrings = languageCommentStrings[fileType];
+ if (!commentStrings) continue;
- const preamble = commentStrings[0] + "\n" + SPACEBAR_LICENSE_PREAMBLE + "\n" + commentStrings[1];
+ const preamble = commentStrings[0] + "\n" + SPACEBAR_LICENSE_PREAMBLE + "\n" + commentStrings[1];
- if (file.startsWith(preamble)) {
- continue;
- }
+ if (file.startsWith(preamble)) {
+ continue;
+ }
- // This is kind of lame.
- if (file.includes("@fc-license-skip") && path != __filename) {
- console.log(`skipping ${path} as it has a different license.`);
- continue;
- }
+ // This is kind of lame.
+ if (file.includes("@fc-license-skip") && path != __filename) {
+ console.log(`skipping ${path} as it has a different license.`);
+ continue;
+ }
- console.log(`writing to ${path}`);
- fs.writeFileSync(path, preamble + "\n\n" + file);
- }
+ console.log(`writing to ${path}`);
+ fs.writeFileSync(path, preamble + "\n\n" + file);
+ }
};
addToDir(SPACEBAR_SOURCE_DIR);
diff --git a/scripts/openapi.js b/scripts/openapi.js
index 39396d8d..5afee152 100644
--- a/scripts/openapi.js
+++ b/scripts/openapi.js
@@ -32,227 +32,227 @@ const SchemaPath = path.join(__dirname, "..", "assets", "schemas.json");
const schemas = JSON.parse(fs.readFileSync(SchemaPath, { encoding: "utf8" }));
let specification = {
- openapi: "3.1.0",
- info: {
- title: "Spacebar Server",
- description:
- "Spacebar is a Discord.com server implementation and extension, with the goal of complete feature parity with Discord.com, all while adding some additional goodies, security, privacy, and configuration options.",
- license: {
- name: "AGPLV3",
- url: "https://www.gnu.org/licenses/agpl-3.0.en.html",
- },
- version: "1.0.0",
- },
- externalDocs: {
- description: "Spacebar Docs",
- url: "https://docs.spacebar.chat",
- },
- servers: [
- {
- url: "https://old.server.spacebar.chat/api/",
- description: "Official Spacebar Instance",
- },
- ],
- components: {
- securitySchemes: {
- bearer: {
- type: "http",
- scheme: "bearer",
- description: "Bearer/Bot prefixes are not required.",
- bearerFormat: "JWT",
- in: "header",
- },
- },
- },
- tags: [],
- paths: {},
+ openapi: "3.1.0",
+ info: {
+ title: "Spacebar Server",
+ description:
+ "Spacebar is a Discord.com server implementation and extension, with the goal of complete feature parity with Discord.com, all while adding some additional goodies, security, privacy, and configuration options.",
+ license: {
+ name: "AGPLV3",
+ url: "https://www.gnu.org/licenses/agpl-3.0.en.html",
+ },
+ version: "1.0.0",
+ },
+ externalDocs: {
+ description: "Spacebar Docs",
+ url: "https://docs.spacebar.chat",
+ },
+ servers: [
+ {
+ url: "https://old.server.spacebar.chat/api/",
+ description: "Official Spacebar Instance",
+ },
+ ],
+ components: {
+ securitySchemes: {
+ bearer: {
+ type: "http",
+ scheme: "bearer",
+ description: "Bearer/Bot prefixes are not required.",
+ bearerFormat: "JWT",
+ in: "header",
+ },
+ },
+ },
+ tags: [],
+ paths: {},
};
const schemaRegEx = new RegExp(/^[\w.]+$/);
function combineSchemas(schemas) {
- let definitions = {};
+ let definitions = {};
- for (const name in schemas) {
- definitions = {
- ...definitions,
- ...schemas[name].definitions,
- [name]: {
- ...schemas[name],
- definitions: undefined,
- $schema: undefined,
- },
- };
- }
+ for (const name in schemas) {
+ definitions = {
+ ...definitions,
+ ...schemas[name].definitions,
+ [name]: {
+ ...schemas[name],
+ definitions: undefined,
+ $schema: undefined,
+ },
+ };
+ }
- for (const key in definitions) {
- if (!schemaRegEx.test(key)) {
- console.error(` \x1b[5m${bgRedBright("ERROR")}\x1b[25m Invalid schema name: ${key}, context:`, definitions[key]);
- continue;
- }
- specification.components = specification.components || {};
- specification.components.schemas = specification.components.schemas || {};
- specification.components.schemas[key] = definitions[key];
- delete definitions[key].additionalProperties;
- delete definitions[key].$schema;
- const definition = definitions[key];
+ for (const key in definitions) {
+ if (!schemaRegEx.test(key)) {
+ console.error(` \x1b[5m${bgRedBright("ERROR")}\x1b[25m Invalid schema name: ${key}, context:`, definitions[key]);
+ continue;
+ }
+ specification.components = specification.components || {};
+ specification.components.schemas = specification.components.schemas || {};
+ specification.components.schemas[key] = definitions[key];
+ delete definitions[key].additionalProperties;
+ delete definitions[key].$schema;
+ const definition = definitions[key];
- if (typeof definition.properties === "object") {
- for (const property of Object.values(definition.properties)) {
- if (Array.isArray(property.type)) {
- if (property.type.includes("null")) {
- property.type = property.type.find((x) => x !== "null");
- property.nullable = true;
- }
- }
- }
- }
- }
+ if (typeof definition.properties === "object") {
+ for (const property of Object.values(definition.properties)) {
+ if (Array.isArray(property.type)) {
+ if (property.type.includes("null")) {
+ property.type = property.type.find((x) => x !== "null");
+ property.nullable = true;
+ }
+ }
+ }
+ }
+ }
- return definitions;
+ return definitions;
}
function getTag(key) {
- return key.match(/\/([\w-]+)/)[1];
+ return key.match(/\/([\w-]+)/)[1];
}
function apiRoutes(missingRoutes) {
- const routes = getRouteDescriptions();
+ const routes = getRouteDescriptions();
- // populate tags
- const tags = Array.from(routes.keys())
- .map((x) => getTag(x))
- .sort((a, b) => a.localeCompare(b));
- specification.tags = [...new Set(tags)].map((x) => ({ name: x }));
+ // populate tags
+ const tags = Array.from(routes.keys())
+ .map((x) => getTag(x))
+ .sort((a, b) => a.localeCompare(b));
+ specification.tags = [...new Set(tags)].map((x) => ({ name: x }));
- routes.forEach((route, pathAndMethod) => {
- const [p, method] = pathAndMethod.split("|");
- const path = p.replace(/:(\w+)/g, "{$1}");
+ routes.forEach((route, pathAndMethod) => {
+ const [p, method] = pathAndMethod.split("|");
+ const path = p.replace(/:(\w+)/g, "{$1}");
- let obj = specification.paths[path]?.[method] || {};
- obj["x-right-required"] = route.right;
- obj["x-permission-required"] = route.permission;
- obj["x-fires-event"] = route.event;
+ let obj = specification.paths[path]?.[method] || {};
+ obj["x-right-required"] = route.right;
+ obj["x-permission-required"] = route.permission;
+ obj["x-fires-event"] = route.event;
- if (
- !NO_AUTHORIZATION_ROUTES.some((x) => {
- if (typeof x === "string") return (method.toUpperCase() + " " + path).startsWith(x);
- return x.test(method.toUpperCase() + " " + path);
- })
- ) {
- obj.security = [{ bearer: [] }];
- }
+ if (
+ !NO_AUTHORIZATION_ROUTES.some((x) => {
+ if (typeof x === "string") return (method.toUpperCase() + " " + path).startsWith(x);
+ return x.test(method.toUpperCase() + " " + path);
+ })
+ ) {
+ obj.security = [{ bearer: [] }];
+ }
- if (route.description) obj.description = route.description;
- if (route.summary) obj.summary = route.summary;
- if (route.deprecated) obj.deprecated = route.deprecated;
+ if (route.description) obj.description = route.description;
+ if (route.summary) obj.summary = route.summary;
+ if (route.deprecated) obj.deprecated = route.deprecated;
- if (route.requestBody) {
- obj.requestBody = {
- required: true,
- content: {
- "application/json": {
- schema: {
- $ref: `#/components/schemas/${route.requestBody}`,
- },
- },
- },
- };
- }
+ if (route.requestBody) {
+ obj.requestBody = {
+ required: true,
+ content: {
+ "application/json": {
+ schema: {
+ $ref: `#/components/schemas/${route.requestBody}`,
+ },
+ },
+ },
+ };
+ }
- if (route.responses) {
- obj.responses = {};
+ if (route.responses) {
+ obj.responses = {};
- for (const [k, v] of Object.entries(route.responses)) {
- if (v.body)
- obj.responses[k] = {
- description: obj?.responses?.[k]?.description || "",
- content: {
- "application/json": {
- schema: {
- $ref: `#/components/schemas/${v.body}`,
- },
- },
- },
- };
- else
- obj.responses[k] = {
- description: obj?.responses?.[k]?.description || "No description available",
- };
- }
- } else {
- obj.responses = {
- default: {
- description: "No description available",
- },
- };
- }
+ for (const [k, v] of Object.entries(route.responses)) {
+ if (v.body)
+ obj.responses[k] = {
+ description: obj?.responses?.[k]?.description || "",
+ content: {
+ "application/json": {
+ schema: {
+ $ref: `#/components/schemas/${v.body}`,
+ },
+ },
+ },
+ };
+ else
+ obj.responses[k] = {
+ description: obj?.responses?.[k]?.description || "No description available",
+ };
+ }
+ } else {
+ obj.responses = {
+ default: {
+ description: "No description available",
+ },
+ };
+ }
- // handles path parameters
- if (p.includes(":")) {
- obj.parameters = p.match(/:\w+/g)?.map((x) => ({
- name: x.replace(":", ""),
- in: "path",
- required: true,
- schema: { type: "string" },
- description: x.replace(":", ""),
- }));
- }
+ // handles path parameters
+ if (p.includes(":")) {
+ obj.parameters = p.match(/:\w+/g)?.map((x) => ({
+ name: x.replace(":", ""),
+ in: "path",
+ required: true,
+ schema: { type: "string" },
+ description: x.replace(":", ""),
+ }));
+ }
- if (route.query) {
- // map to array
- const query = Object.entries(route.query).map(([k, v]) => ({
- name: k,
- in: "query",
- required: v.required,
- schema: { type: v.type },
- description: v.description,
- }));
+ if (route.query) {
+ // map to array
+ const query = Object.entries(route.query).map(([k, v]) => ({
+ name: k,
+ in: "query",
+ required: v.required,
+ schema: { type: v.type },
+ description: v.description,
+ }));
- obj.parameters = [...(obj.parameters || []), ...query];
- }
+ obj.parameters = [...(obj.parameters || []), ...query];
+ }
- obj.tags = [...new Set([...(obj.tags || []), getTag(p)])];
+ obj.tags = [...new Set([...(obj.tags || []), getTag(p)])];
- if (missingRoutes.additional.includes(path.replace(/\/$/, ""))) {
- obj["x-badges"] = [
- {
- label: "Spacebar-only",
- color: "red",
- },
- ];
- }
+ if (missingRoutes.additional.includes(path.replace(/\/$/, ""))) {
+ obj["x-badges"] = [
+ {
+ label: "Spacebar-only",
+ color: "red",
+ },
+ ];
+ }
- specification.paths[path] = Object.assign(specification.paths[path] || {}, {
- [method]: obj,
- });
- });
+ specification.paths[path] = Object.assign(specification.paths[path] || {}, {
+ [method]: obj,
+ });
+ });
}
async function main() {
- console.log("Generating OpenAPI Specification...");
+ console.log("Generating OpenAPI Specification...");
- const routesRes = await fetch("https://github.com/spacebarchat/missing-routes/raw/main/missing.json", {
- headers: {
- Accept: "application/json",
- },
- });
- const missingRoutes = await routesRes.json();
+ const routesRes = await fetch("https://github.com/spacebarchat/missing-routes/raw/main/missing.json", {
+ headers: {
+ Accept: "application/json",
+ },
+ });
+ const missingRoutes = await routesRes.json();
- combineSchemas(schemas);
- apiRoutes(missingRoutes);
+ combineSchemas(schemas);
+ apiRoutes(missingRoutes);
- fs.writeFileSync(openapiPath, JSON.stringify(specification, null, 4).replaceAll("#/definitions", "#/components/schemas").replaceAll("bigint", "number"));
- console.log("Wrote OpenAPI specification to", openapiPath);
- const elapsedMs = Number(totalSw.elapsed().totalMilliseconds + "." + totalSw.elapsed().microseconds);
- console.log(
- "Specification contains",
- Object.keys(specification.paths).length,
- "paths and",
- Object.keys(specification.components.schemas).length,
- "schemas in",
- elapsedMs,
- "ms.",
- );
+ fs.writeFileSync(openapiPath, JSON.stringify(specification, null, 4).replaceAll("#/definitions", "#/components/schemas").replaceAll("bigint", "number"));
+ console.log("Wrote OpenAPI specification to", openapiPath);
+ const elapsedMs = Number(totalSw.elapsed().totalMilliseconds + "." + totalSw.elapsed().microseconds);
+ console.log(
+ "Specification contains",
+ Object.keys(specification.paths).length,
+ "paths and",
+ Object.keys(specification.components.schemas).length,
+ "schemas in",
+ elapsedMs,
+ "ms.",
+ );
}
main();
diff --git a/scripts/schema.js b/scripts/schema.js
index 1779c8d6..67c5563c 100644
--- a/scripts/schema.js
+++ b/scripts/schema.js
@@ -24,10 +24,10 @@ const totalSw = Stopwatch.startNew();
const conWarn = console.warn;
console.warn = (...args) => {
- // silence some expected warnings
- if (args[0] === "initializer is expression for property id") return;
- if (args[0].startsWith("unknown initializer for property ") && args[0].endsWith("[object Object]")) return;
- conWarn(...args);
+ // silence some expected warnings
+ if (args[0] === "initializer is expression for property id") return;
+ if (args[0].startsWith("unknown initializer for property ") && args[0].endsWith("[object Object]")) return;
+ conWarn(...args);
};
const path = require("path");
@@ -41,27 +41,27 @@ const exclusionList = JSON.parse(fs.readFileSync(path.join(__dirname, "schemaExc
// @type {TJS.PartialArgs}
const settings = {
- required: true,
- ignoreErrors: true,
- excludePrivate: true,
- defaultNumberType: "integer",
- noExtraProps: true,
- defaultProps: false,
- useTypeOfKeyword: true, // should help catch functions?
+ required: true,
+ ignoreErrors: true,
+ excludePrivate: true,
+ defaultNumberType: "integer",
+ noExtraProps: true,
+ defaultProps: false,
+ useTypeOfKeyword: true, // should help catch functions?
};
const baseClassProperties = [
- // BaseClass methods
- "toJSON",
- "hasId",
- "save",
- "remove",
- "softRemove",
- "recover",
- "reload",
- "assign",
- "_do_validate", // ?
- "hasId", // ?
+ // BaseClass methods
+ "toJSON",
+ "hasId",
+ "save",
+ "remove",
+ "softRemove",
+ "recover",
+ "reload",
+ "assign",
+ "_do_validate", // ?
+ "hasId", // ?
];
const ExcludeAndWarn = [...exclusionList.manualWarn, ...exclusionList.manualWarnRe.map((r) => new RegExp(r))];
@@ -69,315 +69,315 @@ const Excluded = [...exclusionList.manual, ...exclusionList.manualRe.map((r) =>
const Included = [...exclusionList.include, ...exclusionList.includeRe.map((r) => new RegExp(r))];
const excludedLambdas = [
- (n, s) => {
- // attempt to import
- if (JSON.stringify(s).includes(`#/definitions/import(`)) {
- console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as it attempted to use import().`);
- exclusionList.auto.push({ value: n, reason: "Uses import()" });
- return true;
- }
- },
- (n, s) => {
- if (JSON.stringify(s).includes(process.cwd())) {
- console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as it leaked $PWD.`);
- exclusionList.auto.push({ value: n, reason: "Leaked $PWD" });
- return true;
- }
- },
- (n, s) => {
- if (JSON.stringify(s).includes(process.env.HOME)) {
- console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as it leaked a $HOME path.`);
- exclusionList.auto.push({ value: n, reason: "Leaked $HOME" });
- return true;
- }
- },
- (n, s) => {
- if (s["$ref"] === `#/definitions/${n}`) {
- console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as it is a self-reference only schema.`);
- exclusionList.auto.push({ value: n, reason: "Self-reference only schema" });
- // fs.writeFileSync(`fucked/${n}.json`, JSON.stringify(s, null, 4));
- return true;
- }
- },
- (n, s) => {
- if (s.description?.match(/Smithy/)) {
- console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as it appears to be an AWS Smithy schema.`);
- exclusionList.auto.push({ value: n, reason: "AWS Smithy schema" });
- return true;
- }
- },
- (n, s) => {
- if (s.description?.startsWith("<p>")) {
- console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as we don't use HTML paragraphs for descriptions.`);
- exclusionList.auto.push({ value: n, reason: "HTML paragraph in description" });
- return true;
- }
- },
- (n, s) => {
- if (s.properties && Object.keys(s.properties).every((x) => x[0] === x[0].toUpperCase())) {
- console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as all its properties have uppercase characters.`);
- exclusionList.auto.push({ value: n, reason: "Schema with only uppercase properties" });
- return true;
- }
- },
- // (n, s) => {
- // if (JSON.stringify(s).length <= 300) {
- // console.log({n, s});
- // }
- // }
+ (n, s) => {
+ // attempt to import
+ if (JSON.stringify(s).includes(`#/definitions/import(`)) {
+ console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as it attempted to use import().`);
+ exclusionList.auto.push({ value: n, reason: "Uses import()" });
+ return true;
+ }
+ },
+ (n, s) => {
+ if (JSON.stringify(s).includes(process.cwd())) {
+ console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as it leaked $PWD.`);
+ exclusionList.auto.push({ value: n, reason: "Leaked $PWD" });
+ return true;
+ }
+ },
+ (n, s) => {
+ if (JSON.stringify(s).includes(process.env.HOME)) {
+ console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as it leaked a $HOME path.`);
+ exclusionList.auto.push({ value: n, reason: "Leaked $HOME" });
+ return true;
+ }
+ },
+ (n, s) => {
+ if (s["$ref"] === `#/definitions/${n}`) {
+ console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as it is a self-reference only schema.`);
+ exclusionList.auto.push({ value: n, reason: "Self-reference only schema" });
+ // fs.writeFileSync(`fucked/${n}.json`, JSON.stringify(s, null, 4));
+ return true;
+ }
+ },
+ (n, s) => {
+ if (s.description?.match(/Smithy/)) {
+ console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as it appears to be an AWS Smithy schema.`);
+ exclusionList.auto.push({ value: n, reason: "AWS Smithy schema" });
+ return true;
+ }
+ },
+ (n, s) => {
+ if (s.description?.startsWith("<p>")) {
+ console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as we don't use HTML paragraphs for descriptions.`);
+ exclusionList.auto.push({ value: n, reason: "HTML paragraph in description" });
+ return true;
+ }
+ },
+ (n, s) => {
+ if (s.properties && Object.keys(s.properties).every((x) => x[0] === x[0].toUpperCase())) {
+ console.log(`\r${redBright("[WARN]")} Omitting schema ${n} as all its properties have uppercase characters.`);
+ exclusionList.auto.push({ value: n, reason: "Schema with only uppercase properties" });
+ return true;
+ }
+ },
+ // (n, s) => {
+ // if (JSON.stringify(s).length <= 300) {
+ // console.log({n, s});
+ // }
+ // }
];
function includesMatch(haystack, needles, log = false) {
- for (const needle of needles) {
- const match = needle instanceof RegExp ? needle.test(haystack) : haystack === needle;
- if (match) {
- if (log) console.warn(redBright("[WARN]:"), "Excluding schema", haystack, "due to match with", needle);
- return needle;
- }
- }
- return null;
+ for (const needle of needles) {
+ const match = needle instanceof RegExp ? needle.test(haystack) : haystack === needle;
+ if (match) {
+ if (log) console.warn(redBright("[WARN]:"), "Excluding schema", haystack, "due to match with", needle);
+ return needle;
+ }
+ }
+ return null;
}
async function main() {
- const stepSw = Stopwatch.startNew();
+ const stepSw = Stopwatch.startNew();
- process.stdout.write("Loading program... ");
- const program = TJS.programFromConfig(path.join(__dirname, "..", "tsconfig.json"), walk(path.join(__dirname, "..", "src", "schemas")));
- const generator = TJS.buildGenerator(program, settings);
- if (!generator || !program) {
- console.log(redBright("Failed to create schema generator."));
- return;
- }
+ process.stdout.write("Loading program... ");
+ const program = TJS.programFromConfig(path.join(__dirname, "..", "tsconfig.json"), walk(path.join(__dirname, "..", "src", "schemas")));
+ const generator = TJS.buildGenerator(program, settings);
+ if (!generator || !program) {
+ console.log(redBright("Failed to create schema generator."));
+ return;
+ }
- const elapsedLoad = stepSw.getElapsedAndReset();
- process.stdout.write("Done in " + yellowBright(elapsedLoad.totalMilliseconds + "." + elapsedLoad.microseconds) + " ms\n");
+ const elapsedLoad = stepSw.getElapsedAndReset();
+ process.stdout.write("Done in " + yellowBright(elapsedLoad.totalMilliseconds + "." + elapsedLoad.microseconds) + " ms\n");
- process.stdout.write("Generating schema list... ");
- let schemas = generator.getUserSymbols().filter((x) => {
- return (
- (x.endsWith("Schema") || x.endsWith("Response") || x.startsWith("API")) &&
- // !ExcludeAndWarn.some((exc) => {
- // const match = exc instanceof RegExp ? exc.test(x) : x === exc;
- // if (match) console.warn("Warning: Excluding schema", x);
- // return match;
- // }) &&
- // !Excluded.some((exc) => (exc instanceof RegExp ? exc.test(x) : x === exc))
- (includesMatch(x, Included) || (!includesMatch(x, ExcludeAndWarn, true) && !includesMatch(x, Excluded)))
- );
- });
- //.sort((a,b) => a.localeCompare(b));
+ process.stdout.write("Generating schema list... ");
+ let schemas = generator.getUserSymbols().filter((x) => {
+ return (
+ (x.endsWith("Schema") || x.endsWith("Response") || x.startsWith("API")) &&
+ // !ExcludeAndWarn.some((exc) => {
+ // const match = exc instanceof RegExp ? exc.test(x) : x === exc;
+ // if (match) console.warn("Warning: Excluding schema", x);
+ // return match;
+ // }) &&
+ // !Excluded.some((exc) => (exc instanceof RegExp ? exc.test(x) : x === exc))
+ (includesMatch(x, Included) || (!includesMatch(x, ExcludeAndWarn, true) && !includesMatch(x, Excluded)))
+ );
+ });
+ //.sort((a,b) => a.localeCompare(b));
- const elapsedList = stepSw.getElapsedAndReset();
- process.stdout.write("Done in " + yellowBright(elapsedList.totalMilliseconds + "." + elapsedList.microseconds) + " ms\n");
- console.log("Found", yellowBright(schemas.length), "schemas to process.");
+ const elapsedList = stepSw.getElapsedAndReset();
+ process.stdout.write("Done in " + yellowBright(elapsedList.totalMilliseconds + "." + elapsedList.microseconds) + " ms\n");
+ console.log("Found", yellowBright(schemas.length), "schemas to process.");
- let definitions = {};
- let nestedDefinitions = {};
- let writePromises = [];
+ let definitions = {};
+ let nestedDefinitions = {};
+ let writePromises = [];
- if (process.env.WRITE_SCHEMA_DIR === "true") {
- fs.rmSync("schemas_orig", { recursive: true, force: true });
- fs.mkdirSync("schemas_orig");
+ if (process.env.WRITE_SCHEMA_DIR === "true") {
+ fs.rmSync("schemas_orig", { recursive: true, force: true });
+ fs.mkdirSync("schemas_orig");
- fs.rmSync("schemas_nested", { recursive: true, force: true });
- fs.mkdirSync("schemas_nested");
+ fs.rmSync("schemas_nested", { recursive: true, force: true });
+ fs.mkdirSync("schemas_nested");
- fs.rmSync("schemas_final", { recursive: true, force: true });
- fs.mkdirSync("schemas_final");
- }
+ fs.rmSync("schemas_final", { recursive: true, force: true });
+ fs.mkdirSync("schemas_final");
+ }
- const schemaSw = Stopwatch.startNew();
- for (const name of schemas) {
- process.stdout.write(`Processing schema ${name}... `);
- const part = TJS.generateSchema(program, name, settings, [], generator);
- if (!part) continue;
+ const schemaSw = Stopwatch.startNew();
+ for (const name of schemas) {
+ process.stdout.write(`Processing schema ${name}... `);
+ const part = TJS.generateSchema(program, name, settings, [], generator);
+ if (!part) continue;
- if (definitions[name]) {
- process.stdout.write(yellow(` [ERROR] Duplicate schema name detected: ${name}. Overwriting previous schema.`));
- }
+ if (definitions[name]) {
+ process.stdout.write(yellow(` [ERROR] Duplicate schema name detected: ${name}. Overwriting previous schema.`));
+ }
- if (!includesMatch(name, Included) && excludedLambdas.some((fn) => fn(name, part))) {
- continue;
- }
+ if (!includesMatch(name, Included) && excludedLambdas.some((fn) => fn(name, part))) {
+ continue;
+ }
- if (process.env.WRITE_SCHEMA_DIR === "true") writePromises.push(async () => await fsp.writeFile(path.join("schemas_orig", `${name}.json`), JSON.stringify(part, null, 4)));
+ if (process.env.WRITE_SCHEMA_DIR === "true") writePromises.push(async () => await fsp.writeFile(path.join("schemas_orig", `${name}.json`), JSON.stringify(part, null, 4)));
- // testing:
- function mergeDefs(schemaName, schema) {
- if (schema.definitions) {
- // schema["x-sb-defs"] = Object.keys(schema.definitions);
- process.stdout.write(cyanBright("Processing nested... "));
- for (const defKey in schema.definitions) {
- if (definitions[defKey] && deepEqual(definitions[defKey], schema.definitions[defKey])) {
- // console.log("Definition", defKey, "from schema", schemaName, "is identical to existing definition, skipping.");
- schema.definitions = Object.fromEntries(Object.entries(schema.definitions).filter(([k, v]) => k !== defKey));
- process.stdout.write(greenBright("T"));
- } else if (!nestedDefinitions[defKey]) {
- nestedDefinitions[defKey] = schema.definitions[defKey];
- schema.definitions = Object.fromEntries(Object.entries(schema.definitions).filter(([k, v]) => k !== defKey));
- // console.log("Tracking sub-definition", defKey, "from schema", schemaName);
- process.stdout.write(green("N"));
- } else if (!deepEqual(nestedDefinitions[defKey], schema.definitions[defKey])) {
- console.log(redBright("[ERROR]"), "Conflicting nested definition for", defKey, "found in schema", schemaName);
- console.log(columnizedObjectDiff(nestedDefinitions[defKey], schema.definitions[defKey], true));
- } else {
- // console.log("Definition", defKey, "from schema", schemaName, "is identical to existing definition, skipping.");
- schema.definitions = Object.fromEntries(Object.entries(schema.definitions).filter(([k, v]) => k !== defKey));
- process.stdout.write(greenBright("M"));
- }
- }
- if (Object.keys(schema.definitions).length === 0) {
- process.stdout.write(greenBright("✓ "));
- delete schema.definitions;
- } else {
- console.log("Remaining definitions in schema", schemaName, "after merge:", Object.keys(schema.definitions));
- }
- }
- }
- mergeDefs(name, part);
+ // testing:
+ function mergeDefs(schemaName, schema) {
+ if (schema.definitions) {
+ // schema["x-sb-defs"] = Object.keys(schema.definitions);
+ process.stdout.write(cyanBright("Processing nested... "));
+ for (const defKey in schema.definitions) {
+ if (definitions[defKey] && deepEqual(definitions[defKey], schema.definitions[defKey])) {
+ // console.log("Definition", defKey, "from schema", schemaName, "is identical to existing definition, skipping.");
+ schema.definitions = Object.fromEntries(Object.entries(schema.definitions).filter(([k, v]) => k !== defKey));
+ process.stdout.write(greenBright("T"));
+ } else if (!nestedDefinitions[defKey]) {
+ nestedDefinitions[defKey] = schema.definitions[defKey];
+ schema.definitions = Object.fromEntries(Object.entries(schema.definitions).filter(([k, v]) => k !== defKey));
+ // console.log("Tracking sub-definition", defKey, "from schema", schemaName);
+ process.stdout.write(green("N"));
+ } else if (!deepEqual(nestedDefinitions[defKey], schema.definitions[defKey])) {
+ console.log(redBright("[ERROR]"), "Conflicting nested definition for", defKey, "found in schema", schemaName);
+ console.log(columnizedObjectDiff(nestedDefinitions[defKey], schema.definitions[defKey], true));
+ } else {
+ // console.log("Definition", defKey, "from schema", schemaName, "is identical to existing definition, skipping.");
+ schema.definitions = Object.fromEntries(Object.entries(schema.definitions).filter(([k, v]) => k !== defKey));
+ process.stdout.write(greenBright("M"));
+ }
+ }
+ if (Object.keys(schema.definitions).length === 0) {
+ process.stdout.write(greenBright("✓ "));
+ delete schema.definitions;
+ } else {
+ console.log("Remaining definitions in schema", schemaName, "after merge:", Object.keys(schema.definitions));
+ }
+ }
+ }
+ mergeDefs(name, part);
- const elapsed = schemaSw.getElapsedAndReset();
- process.stdout.write(
- "Done in " + yellowBright(elapsed.totalMilliseconds + "." + elapsed.microseconds) + " ms, " + yellowBright(JSON.stringify(part).length) + " bytes (unformatted) ",
- );
- if (elapsed.totalMilliseconds >= 20) console.log(bgRedBright("\x1b[5m[SLOW]\x1b[25m"));
- else console.log();
+ const elapsed = schemaSw.getElapsedAndReset();
+ process.stdout.write(
+ "Done in " + yellowBright(elapsed.totalMilliseconds + "." + elapsed.microseconds) + " ms, " + yellowBright(JSON.stringify(part).length) + " bytes (unformatted) ",
+ );
+ if (elapsed.totalMilliseconds >= 20) console.log(bgRedBright("\x1b[5m[SLOW]\x1b[25m"));
+ else console.log();
- definitions = { ...definitions, [name]: { ...part } };
- }
- console.log("Processed", Object.keys(definitions).length, "schemas in", Number(stepSw.elapsed().totalMilliseconds + "." + stepSw.elapsed().microseconds), "ms.");
+ definitions = { ...definitions, [name]: { ...part } };
+ }
+ console.log("Processed", Object.keys(definitions).length, "schemas in", Number(stepSw.elapsed().totalMilliseconds + "." + stepSw.elapsed().microseconds), "ms.");
- console.log("Merging nested definitions into main definitions...");
- let isNewLine = true;
- for (const defKey in nestedDefinitions) {
- if (!includesMatch(defKey, Included, false)) {
- const bannedMatch = includesMatch(defKey, ExcludeAndWarn, false) ?? includesMatch(defKey, Excluded, false);
- if (bannedMatch !== null) {
- // console.log(yellowBright("\n[WARN]"), "Skipping nested definition", defKey, "as it matched a banned format.");
- console.log((isNewLine ? "" : "\n") + redBright("WARNING") + " Excluding schema " + yellowBright(defKey) + " due to match with " + redBright(bannedMatch));
- isNewLine = true;
- continue;
- }
- }
+ console.log("Merging nested definitions into main definitions...");
+ let isNewLine = true;
+ for (const defKey in nestedDefinitions) {
+ if (!includesMatch(defKey, Included, false)) {
+ const bannedMatch = includesMatch(defKey, ExcludeAndWarn, false) ?? includesMatch(defKey, Excluded, false);
+ if (bannedMatch !== null) {
+ // console.log(yellowBright("\n[WARN]"), "Skipping nested definition", defKey, "as it matched a banned format.");
+ console.log((isNewLine ? "" : "\n") + redBright("WARNING") + " Excluding schema " + yellowBright(defKey) + " due to match with " + redBright(bannedMatch));
+ isNewLine = true;
+ continue;
+ }
+ }
- nestedDefinitions[defKey]["$schema"] = "http://json-schema.org/draft-07/schema#";
- if (definitions[defKey]) {
- if (!deepEqual(definitions[defKey], nestedDefinitions[defKey])) {
- if (Object.keys(definitions[defKey]).every((k) => k === "$ref" || k === "$schema")) {
- definitions[defKey] = nestedDefinitions[defKey];
- console.log(yellowBright("\nWARNING"), "Overwriting definition for", defKey, "with nested definition (ref/schema only).");
- isNewLine = true;
- } else {
- console.log(redBright("\nERROR"), "Conflicting definition for", defKey, "found in main definitions.");
- console.log(columnizedObjectDiff(definitions[defKey], nestedDefinitions[defKey], true));
- console.log("Keys:", Object.keys(definitions[defKey]), Object.keys(nestedDefinitions[defKey]));
- isNewLine = true;
- }
- } else {
- // console.log("Definition", defKey, "is identical to existing definition, skipping.");
- }
- } else {
- definitions[defKey] = nestedDefinitions[defKey];
- if (isNewLine) {
- process.stdout.write("Adding nested definitions to main definitions: ");
- isNewLine = false;
- } else process.stdout.write("\x1b[4D, ");
- process.stdout.write(yellowBright(defKey) + "... ");
- }
- }
+ nestedDefinitions[defKey]["$schema"] = "http://json-schema.org/draft-07/schema#";
+ if (definitions[defKey]) {
+ if (!deepEqual(definitions[defKey], nestedDefinitions[defKey])) {
+ if (Object.keys(definitions[defKey]).every((k) => k === "$ref" || k === "$schema")) {
+ definitions[defKey] = nestedDefinitions[defKey];
+ console.log(yellowBright("\nWARNING"), "Overwriting definition for", defKey, "with nested definition (ref/schema only).");
+ isNewLine = true;
+ } else {
+ console.log(redBright("\nERROR"), "Conflicting definition for", defKey, "found in main definitions.");
+ console.log(columnizedObjectDiff(definitions[defKey], nestedDefinitions[defKey], true));
+ console.log("Keys:", Object.keys(definitions[defKey]), Object.keys(nestedDefinitions[defKey]));
+ isNewLine = true;
+ }
+ } else {
+ // console.log("Definition", defKey, "is identical to existing definition, skipping.");
+ }
+ } else {
+ definitions[defKey] = nestedDefinitions[defKey];
+ if (isNewLine) {
+ process.stdout.write("Adding nested definitions to main definitions: ");
+ isNewLine = false;
+ } else process.stdout.write("\x1b[4D, ");
+ process.stdout.write(yellowBright(defKey) + "... ");
+ }
+ }
- deleteOneOfKindUndefinedRecursive(definitions, "$");
- for (const defKey in definitions) {
- filterSchema(definitions[defKey]);
- }
+ deleteOneOfKindUndefinedRecursive(definitions, "$");
+ for (const defKey in definitions) {
+ filterSchema(definitions[defKey]);
+ }
- if (process.env.WRITE_SCHEMA_DIR === "true") {
- await Promise.all(writePromises);
- await Promise.all(
- Object.keys(definitions).map(async (name) => {
- await fsp.writeFile(path.join("schemas_final", `${name}.json`), JSON.stringify(definitions[name], null, 4));
- // console.log("Wrote schema", name, "to schemas/");
- }),
- );
- await Promise.all(
- Object.keys(nestedDefinitions).map(async (name) => {
- await fsp.writeFile(path.join("schemas_nested", `${name}.json`), JSON.stringify(nestedDefinitions[name], null, 4));
- // console.log("Wrote schema", name, "to schemas_nested/");
- }),
- );
- }
+ if (process.env.WRITE_SCHEMA_DIR === "true") {
+ await Promise.all(writePromises);
+ await Promise.all(
+ Object.keys(definitions).map(async (name) => {
+ await fsp.writeFile(path.join("schemas_final", `${name}.json`), JSON.stringify(definitions[name], null, 4));
+ // console.log("Wrote schema", name, "to schemas/");
+ }),
+ );
+ await Promise.all(
+ Object.keys(nestedDefinitions).map(async (name) => {
+ await fsp.writeFile(path.join("schemas_nested", `${name}.json`), JSON.stringify(nestedDefinitions[name], null, 4));
+ // console.log("Wrote schema", name, "to schemas_nested/");
+ }),
+ );
+ }
- fs.writeFileSync(schemaPath, JSON.stringify(definitions, null, 4));
- fs.writeFileSync(__dirname + "/schemaExclusions.json", JSON.stringify(exclusionList, null, 4));
- const elapsedMs = Number(totalSw.elapsed().totalMilliseconds + "." + totalSw.elapsed().microseconds);
- console.log("\nSuccessfully wrote", Object.keys(definitions).length, "schemas to", schemaPath, "in", elapsedMs, "ms,", fs.statSync(schemaPath).size, "bytes.");
+ fs.writeFileSync(schemaPath, JSON.stringify(definitions, null, 4));
+ fs.writeFileSync(__dirname + "/schemaExclusions.json", JSON.stringify(exclusionList, null, 4));
+ const elapsedMs = Number(totalSw.elapsed().totalMilliseconds + "." + totalSw.elapsed().microseconds);
+ console.log("\nSuccessfully wrote", Object.keys(definitions).length, "schemas to", schemaPath, "in", elapsedMs, "ms,", fs.statSync(schemaPath).size, "bytes.");
}
function deleteOneOfKindUndefinedRecursive(obj, path) {
- if (obj?.type === "object" && obj?.properties?.oneofKind?.type === "undefined") return true;
+ if (obj?.type === "object" && obj?.properties?.oneofKind?.type === "undefined") return true;
- for (const key in obj) {
- if (typeof obj[key] === "object" && deleteOneOfKindUndefinedRecursive(obj[key], path + "." + key)) {
- console.log("Deleting", path, key);
- delete obj[key];
- }
- }
+ for (const key in obj) {
+ if (typeof obj[key] === "object" && deleteOneOfKindUndefinedRecursive(obj[key], path + "." + key)) {
+ console.log("Deleting", path, key);
+ delete obj[key];
+ }
+ }
- return false;
+ return false;
}
function filterSchema(schema) {
- // this is a hack. we may want to check if its a @column instead
- if (schema.properties) {
- for (let key in schema.properties) {
- if (baseClassProperties.includes(key)) {
- delete schema.properties[key];
- }
- }
- }
+ // this is a hack. we may want to check if its a @column instead
+ if (schema.properties) {
+ for (let key in schema.properties) {
+ if (baseClassProperties.includes(key)) {
+ delete schema.properties[key];
+ }
+ }
+ }
- if (schema.required) schema.required = schema.required.filter((x) => !baseClassProperties.includes(x));
+ if (schema.required) schema.required = schema.required.filter((x) => !baseClassProperties.includes(x));
- // recurse into own definitions
- if (schema.definitions) {
- console.log(redBright("WARNING"), "Schema has own definitions, recursing into them to filter base class properties:", Object.keys(schema.definitions));
- for (const defKey in schema.definitions) {
- filterSchema(schema.definitions[defKey]);
- }
- }
+ // recurse into own definitions
+ if (schema.definitions) {
+ console.log(redBright("WARNING"), "Schema has own definitions, recursing into them to filter base class properties:", Object.keys(schema.definitions));
+ for (const defKey in schema.definitions) {
+ filterSchema(schema.definitions[defKey]);
+ }
+ }
}
function deepEqual(a, b) {
- if (a === b) return true;
+ if (a === b) return true;
- if (typeof a !== "object" || typeof b !== "object" || a == null || b == null) {
- return false;
- }
+ if (typeof a !== "object" || typeof b !== "object" || a == null || b == null) {
+ return false;
+ }
- const keysA = Object.keys(a);
- const keysB = Object.keys(b);
+ const keysA = Object.keys(a);
+ const keysB = Object.keys(b);
- if (keysA.length !== keysB.length) return false;
+ if (keysA.length !== keysB.length) return false;
- for (const key of keysA) {
- if (!keysB.includes(key) || (typeof a[key] === typeof b[key] && !deepEqual(a[key], b[key]))) {
- return false;
- }
- }
+ for (const key of keysA) {
+ if (!keysB.includes(key) || (typeof a[key] === typeof b[key] && !deepEqual(a[key], b[key]))) {
+ return false;
+ }
+ }
- return true;
+ return true;
}
function columnizedObjectDiff(a, b, trackEqual = false) {
- const diffs = { left: {}, right: {}, ...(trackEqual ? { equal: {} } : {}) };
- const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
- for (const key of keys) {
- if (!deepEqual(a[key], b[key])) {
- diffs.left[key] = a[key];
- diffs.right[key] = b[key];
- } else if (trackEqual) diffs.equal[key] = a[key];
- }
- return diffs;
+ const diffs = { left: {}, right: {}, ...(trackEqual ? { equal: {} } : {}) };
+ const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
+ for (const key of keys) {
+ if (!deepEqual(a[key], b[key])) {
+ diffs.left[key] = a[key];
+ diffs.right[key] = b[key];
+ } else if (trackEqual) diffs.equal[key] = a[key];
+ }
+ return diffs;
}
main();
diff --git a/scripts/schemaExclusions.json b/scripts/schemaExclusions.json
index 389cb4f5..64e2bbf0 100644
--- a/scripts/schemaExclusions.json
+++ b/scripts/schemaExclusions.json
@@ -1,409 +1,415 @@
{
- "include": ["MessageInteractionSchema"],
- "includeRe": ["^MessageComponentType\\..*"],
- "manual": [
- "DefaultSchema",
- "Schema",
- "EntitySchema",
- "ReadableStream<any>",
- "SomeJSONSchema",
- "UncheckedPartialSchema",
- "PartialSchema",
- "UncheckedPropertiesSchema",
- "PropertiesSchema",
- "AsyncSchema",
- "AnySchema",
- "SMTPConnection.CustomAuthenticationResponse",
- "TransportMakeRequestResponse",
- "StaticSchema",
- "CSVImportResponse",
- "NewMultipleMembersResponse",
- "EventsResponse",
- "NotificationAPIResponse",
- "MetricsAPIResponse",
- "ValidationResponse",
- "MultipleValidationJobsListResponse",
- "UpdateRouteResponse",
- "MessagesSendAPIResponse",
- "APIWebhook",
- "WebhookResponse",
- "WebhookValidationResponse",
- "MessageResponse",
- "ConnectionSettingsResponse",
- "UpdatedDKIMSelectorResponse",
- "UpdatedWebPrefixResponse",
- "APIResponse",
- "APIErrorOptions",
- "APIErrorType",
- "ListTagsForResourceResponse",
- "GetContactResponse",
- "LibraryResponse",
- "LibraryLocalResponse",
- "SchemaTraits",
- "TraitsSchema",
- "AbuseIpDbCheckResponse",
- "IpDataIpLookupResponse"
- ],
- "manualRe": [
- ".*\\.Response$",
- "^(Http2Server|Server|Express|(Resolved|)Http|Client|_|)Response$",
- ".*\\..*",
- "^Axios.*",
- "^Internal",
- "^Record<",
- "^Omit<",
- "^ListContact(s|Lists)Response$",
- "^APIKeyConfiguration\\..*",
- "^AccountSetting\\..*",
- "^BulkContactManagement\\..*",
- "^Campaign.*",
- "^Contact.*",
- "^DNS\\..*",
- "^Delete.*",
- "^Destroy.*",
- "^Template\\..*",
- "^Webhook\\..*",
- "^(BigDecimal|BigInteger|Blob|Boolean|Document|Error|LazyRequest|List|Map|Normalized|Numeric|StreamingBlob|TimestampDateTime|TimestampHttpDate|TimestampEpochSeconds|Simple)Schema",
- "^((Create|Update)Contact(|List))Response$",
- "^(T|Unt)agResourceResponse$",
- "^Put",
- "^Inbox",
- "^Seed",
- "^DomainTag",
- "^IpPool",
- "DomainTemplate",
- "^\\$",
- "^Suppression",
- "^Mail(|ing)List",
- "DomainTracking",
- "UpdatedDomain",
- "ConfigurationSet",
- "ContactList",
- "^IPR",
- "^Job"
- ],
- "manualWarn": [],
- "manualWarnRe": [".*<.*>$"],
- "auto": [
- {
- "value": "StringSchema",
- "reason": "AWS Smithy schema"
- },
- {
- "value": "TimestampDefaultSchema",
- "reason": "AWS Smithy schema"
- },
- {
- "value": "StaticSimpleSchema",
- "reason": "Self-reference only schema"
- },
- {
- "value": "StaticListSchema",
- "reason": "Self-reference only schema"
- },
- {
- "value": "StaticMapSchema",
- "reason": "Self-reference only schema"
- },
- {
- "value": "StaticStructureSchema",
- "reason": "Self-reference only schema"
- },
- {
- "value": "StaticErrorSchema",
- "reason": "Self-reference only schema"
- },
- {
- "value": "StaticOperationSchema",
- "reason": "Self-reference only schema"
- },
- {
- "value": "UnitSchema",
- "reason": "AWS Smithy schema"
- },
- {
- "value": "MemberSchema",
- "reason": "Self-reference only schema"
- },
- {
- "value": "StructureSchema",
- "reason": "Self-reference only schema"
- },
- {
- "value": "OperationSchema",
- "reason": "Self-reference only schema"
- },
- {
- "value": "BatchGetMetricDataResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "CancelExportJobResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "CreateCustomVerificationEmailTemplateResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "CreateDedicatedIpPoolResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "CreateDeliverabilityTestReportResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "CreateEmailIdentityResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "CreateEmailIdentityPolicyResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "CreateEmailTemplateResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "CreateExportJobResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "CreateImportJobResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "CreateMultiRegionEndpointResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "CreateTenantResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "CreateTenantResourceAssociationResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetAccountResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetBlacklistReportsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetCustomVerificationEmailTemplateResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetDedicatedIpResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetDedicatedIpPoolResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetDedicatedIpsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetDeliverabilityDashboardOptionsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetDeliverabilityTestReportResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetDomainDeliverabilityCampaignResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetDomainStatisticsReportResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetEmailIdentityResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetEmailIdentityPoliciesResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetEmailTemplateResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetExportJobResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetImportJobResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetMessageInsightsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetMultiRegionEndpointResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetReputationEntityResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetSuppressedDestinationResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "GetTenantResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListCustomVerificationEmailTemplatesResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListDedicatedIpPoolsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListDeliverabilityTestReportsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListDomainDeliverabilityCampaignsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListEmailIdentitiesResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListEmailTemplatesResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListExportJobsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListImportJobsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListMultiRegionEndpointsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListRecommendationsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListReputationEntitiesResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListResourceTenantsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListSuppressedDestinationsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListTenantResourcesResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "ListTenantsResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "SendBulkEmailResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "SendCustomVerificationEmailResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "SendEmailResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "TestRenderEmailTemplateResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "UpdateCustomVerificationEmailTemplateResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "UpdateEmailIdentityPolicyResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "UpdateEmailTemplateResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "UpdateReputationEntityCustomerManagedStatusResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "UpdateReputationEntityPolicyResponse",
- "reason": "HTML paragraph in description"
- },
- {
- "value": "UpdatedDKIMAuthorityResponse",
- "reason": "Uses import()"
- },
- {
- "value": "ListRecipientResponse",
- "reason": "Schema with only uppercase properties"
- },
- {
- "value": "TemplateResponse",
- "reason": "Schema with only uppercase properties"
- },
- {
- "value": "TemplateDetailContentResponse",
- "reason": "Schema with only uppercase properties"
- },
- {
- "value": "EventCallbackUrlResponse",
- "reason": "Schema with only uppercase properties"
- },
- {
- "value": "ParseRouteResponse",
- "reason": "Schema with only uppercase properties"
- },
- {
- "value": "SenderResponse",
- "reason": "Schema with only uppercase properties"
- },
- {
- "value": "MetaSenderResponse",
- "reason": "Schema with only uppercase properties"
- },
- {
- "value": "ApiKeyResponse",
- "reason": "Schema with only uppercase properties"
- },
- {
- "value": "MyProfileResponse",
- "reason": "Schema with only uppercase properties"
- },
- {
- "value": "UserResponse",
- "reason": "Schema with only uppercase properties"
- }
- ]
-}
+ "include": [
+ "MessageInteractionSchema"
+ ],
+ "includeRe": [
+ "^MessageComponentType\\..*"
+ ],
+ "manual": [
+ "DefaultSchema",
+ "Schema",
+ "EntitySchema",
+ "ReadableStream<any>",
+ "SomeJSONSchema",
+ "UncheckedPartialSchema",
+ "PartialSchema",
+ "UncheckedPropertiesSchema",
+ "PropertiesSchema",
+ "AsyncSchema",
+ "AnySchema",
+ "SMTPConnection.CustomAuthenticationResponse",
+ "TransportMakeRequestResponse",
+ "StaticSchema",
+ "CSVImportResponse",
+ "NewMultipleMembersResponse",
+ "EventsResponse",
+ "NotificationAPIResponse",
+ "MetricsAPIResponse",
+ "ValidationResponse",
+ "MultipleValidationJobsListResponse",
+ "UpdateRouteResponse",
+ "MessagesSendAPIResponse",
+ "APIWebhook",
+ "WebhookResponse",
+ "WebhookValidationResponse",
+ "MessageResponse",
+ "ConnectionSettingsResponse",
+ "UpdatedDKIMSelectorResponse",
+ "UpdatedWebPrefixResponse",
+ "APIResponse",
+ "APIErrorOptions",
+ "APIErrorType",
+ "ListTagsForResourceResponse",
+ "GetContactResponse",
+ "LibraryResponse",
+ "LibraryLocalResponse",
+ "SchemaTraits",
+ "TraitsSchema",
+ "AbuseIpDbCheckResponse",
+ "IpDataIpLookupResponse"
+ ],
+ "manualRe": [
+ ".*\\.Response$",
+ "^(Http2Server|Server|Express|(Resolved|)Http|Client|_|)Response$",
+ ".*\\..*",
+ "^Axios.*",
+ "^Internal",
+ "^Record<",
+ "^Omit<",
+ "^ListContact(s|Lists)Response$",
+ "^APIKeyConfiguration\\..*",
+ "^AccountSetting\\..*",
+ "^BulkContactManagement\\..*",
+ "^Campaign.*",
+ "^Contact.*",
+ "^DNS\\..*",
+ "^Delete.*",
+ "^Destroy.*",
+ "^Template\\..*",
+ "^Webhook\\..*",
+ "^(BigDecimal|BigInteger|Blob|Boolean|Document|Error|LazyRequest|List|Map|Normalized|Numeric|StreamingBlob|TimestampDateTime|TimestampHttpDate|TimestampEpochSeconds|Simple)Schema",
+ "^((Create|Update)Contact(|List))Response$",
+ "^(T|Unt)agResourceResponse$",
+ "^Put",
+ "^Inbox",
+ "^Seed",
+ "^DomainTag",
+ "^IpPool",
+ "DomainTemplate",
+ "^\\$",
+ "^Suppression",
+ "^Mail(|ing)List",
+ "DomainTracking",
+ "UpdatedDomain",
+ "ConfigurationSet",
+ "ContactList",
+ "^IPR",
+ "^Job"
+ ],
+ "manualWarn": [],
+ "manualWarnRe": [
+ ".*<.*>$"
+ ],
+ "auto": [
+ {
+ "value": "StringSchema",
+ "reason": "AWS Smithy schema"
+ },
+ {
+ "value": "TimestampDefaultSchema",
+ "reason": "AWS Smithy schema"
+ },
+ {
+ "value": "StaticSimpleSchema",
+ "reason": "Self-reference only schema"
+ },
+ {
+ "value": "StaticListSchema",
+ "reason": "Self-reference only schema"
+ },
+ {
+ "value": "StaticMapSchema",
+ "reason": "Self-reference only schema"
+ },
+ {
+ "value": "StaticStructureSchema",
+ "reason": "Self-reference only schema"
+ },
+ {
+ "value": "StaticErrorSchema",
+ "reason": "Self-reference only schema"
+ },
+ {
+ "value": "StaticOperationSchema",
+ "reason": "Self-reference only schema"
+ },
+ {
+ "value": "UnitSchema",
+ "reason": "AWS Smithy schema"
+ },
+ {
+ "value": "MemberSchema",
+ "reason": "Self-reference only schema"
+ },
+ {
+ "value": "StructureSchema",
+ "reason": "Self-reference only schema"
+ },
+ {
+ "value": "OperationSchema",
+ "reason": "Self-reference only schema"
+ },
+ {
+ "value": "BatchGetMetricDataResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "CancelExportJobResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "CreateCustomVerificationEmailTemplateResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "CreateDedicatedIpPoolResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "CreateDeliverabilityTestReportResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "CreateEmailIdentityResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "CreateEmailIdentityPolicyResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "CreateEmailTemplateResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "CreateExportJobResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "CreateImportJobResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "CreateMultiRegionEndpointResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "CreateTenantResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "CreateTenantResourceAssociationResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetAccountResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetBlacklistReportsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetCustomVerificationEmailTemplateResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetDedicatedIpResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetDedicatedIpPoolResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetDedicatedIpsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetDeliverabilityDashboardOptionsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetDeliverabilityTestReportResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetDomainDeliverabilityCampaignResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetDomainStatisticsReportResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetEmailIdentityResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetEmailIdentityPoliciesResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetEmailTemplateResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetExportJobResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetImportJobResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetMessageInsightsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetMultiRegionEndpointResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetReputationEntityResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetSuppressedDestinationResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "GetTenantResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListCustomVerificationEmailTemplatesResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListDedicatedIpPoolsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListDeliverabilityTestReportsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListDomainDeliverabilityCampaignsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListEmailIdentitiesResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListEmailTemplatesResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListExportJobsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListImportJobsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListMultiRegionEndpointsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListRecommendationsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListReputationEntitiesResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListResourceTenantsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListSuppressedDestinationsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListTenantResourcesResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "ListTenantsResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "SendBulkEmailResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "SendCustomVerificationEmailResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "SendEmailResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "TestRenderEmailTemplateResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "UpdateCustomVerificationEmailTemplateResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "UpdateEmailIdentityPolicyResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "UpdateEmailTemplateResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "UpdateReputationEntityCustomerManagedStatusResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "UpdateReputationEntityPolicyResponse",
+ "reason": "HTML paragraph in description"
+ },
+ {
+ "value": "UpdatedDKIMAuthorityResponse",
+ "reason": "Uses import()"
+ },
+ {
+ "value": "ListRecipientResponse",
+ "reason": "Schema with only uppercase properties"
+ },
+ {
+ "value": "TemplateResponse",
+ "reason": "Schema with only uppercase properties"
+ },
+ {
+ "value": "TemplateDetailContentResponse",
+ "reason": "Schema with only uppercase properties"
+ },
+ {
+ "value": "EventCallbackUrlResponse",
+ "reason": "Schema with only uppercase properties"
+ },
+ {
+ "value": "ParseRouteResponse",
+ "reason": "Schema with only uppercase properties"
+ },
+ {
+ "value": "SenderResponse",
+ "reason": "Schema with only uppercase properties"
+ },
+ {
+ "value": "MetaSenderResponse",
+ "reason": "Schema with only uppercase properties"
+ },
+ {
+ "value": "ApiKeyResponse",
+ "reason": "Schema with only uppercase properties"
+ },
+ {
+ "value": "MyProfileResponse",
+ "reason": "Schema with only uppercase properties"
+ },
+ {
+ "value": "UserResponse",
+ "reason": "Schema with only uppercase properties"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/scripts/stress/identify.js b/scripts/stress/identify.js
index 478643f5..08d8d5db 100644
--- a/scripts/stress/identify.js
+++ b/scripts/stress/identify.js
@@ -8,45 +8,45 @@ const TOKEN = process.env.TOKEN;
const TOTAL_ITERATIONS = process.env.ITER ? parseInt(process.env.ITER) : 500;
const doTimedIdentify = () =>
- new Promise((resolve) => {
- let start;
- const ws = new WebSocket(ENDPOINT);
- ws.on("message", (data) => {
- const parsed = JSON.parse(data);
+ new Promise((resolve) => {
+ let start;
+ const ws = new WebSocket(ENDPOINT);
+ ws.on("message", (data) => {
+ const parsed = JSON.parse(data);
- switch (parsed.op) {
- case OPCODES.Hello:
- // send identify
- start = performance.now();
- ws.send(
- JSON.stringify({
- op: OPCODES.Identify,
- d: {
- token: TOKEN,
- properties: {},
- },
- }),
- );
- break;
- case OPCODES.Dispatch:
- if (parsed.t == "READY") {
- ws.close();
- return resolve(performance.now() - start);
- }
+ switch (parsed.op) {
+ case OPCODES.Hello:
+ // send identify
+ start = performance.now();
+ ws.send(
+ JSON.stringify({
+ op: OPCODES.Identify,
+ d: {
+ token: TOKEN,
+ properties: {},
+ },
+ }),
+ );
+ break;
+ case OPCODES.Dispatch:
+ if (parsed.t == "READY") {
+ ws.close();
+ return resolve(performance.now() - start);
+ }
- break;
- }
- });
- });
+ break;
+ }
+ });
+ });
(async () => {
- const perfs = [];
- while (perfs.length < TOTAL_ITERATIONS) {
- const ret = await doTimedIdentify();
- perfs.push(ret);
- // console.log(`${perfs.length}/${TOTAL_ITERATIONS} - this: ${Math.floor(ret)}ms`)
- }
+ const perfs = [];
+ while (perfs.length < TOTAL_ITERATIONS) {
+ const ret = await doTimedIdentify();
+ perfs.push(ret);
+ // console.log(`${perfs.length}/${TOTAL_ITERATIONS} - this: ${Math.floor(ret)}ms`)
+ }
- const avg = perfs.reduce((prev, curr) => prev + curr) / (perfs.length - 1);
- console.log(`Average identify time: ${Math.floor(avg * 100) / 100}ms`);
+ const avg = perfs.reduce((prev, curr) => prev + curr) / (perfs.length - 1);
+ console.log(`Average identify time: ${Math.floor(avg * 100) / 100}ms`);
})();
diff --git a/scripts/stress/login.js b/scripts/stress/login.js
index 5cb254d1..830d6a48 100644
--- a/scripts/stress/login.js
+++ b/scripts/stress/login.js
@@ -1,16 +1,16 @@
const ENDPOINT = process.env.API || "http://localhost:3001";
async function main() {
- const ret = await fetch(`${ENDPOINT}/api/auth/login`, {
- method: "POST",
- body: JSON.stringify({
- login: process.argv[2],
- password: process.argv[3],
- }),
- headers: { "content-type": "application/json " },
- });
+ const ret = await fetch(`${ENDPOINT}/api/auth/login`, {
+ method: "POST",
+ body: JSON.stringify({
+ login: process.argv[2],
+ password: process.argv[3],
+ }),
+ headers: { "content-type": "application/json " },
+ });
- console.log((await ret.json()).token);
+ console.log((await ret.json()).token);
}
main();
diff --git a/scripts/stress/users.js b/scripts/stress/users.js
index 67fa3ec8..2fc41eae 100644
--- a/scripts/stress/users.js
+++ b/scripts/stress/users.js
@@ -21,22 +21,22 @@ const count = Number(process.env.COUNT) || 50;
const endpoint = process.env.API || "http://localhost:3001";
async function main() {
- for (let i = 0; i < count; i++) {
- fetch(`${endpoint}/api/auth/register`, {
- method: "POST",
- body: JSON.stringify({
- fingerprint: `${i}.wR8vi8lGlFBJerErO9LG5NViJFw`,
- username: `test${i}`,
- invite: null,
- consent: true,
- date_of_birth: "2000-01-01",
- gift_code_sku_id: null,
- captcha_key: null,
- }),
- headers: { "content-type": "application/json" },
- });
- console.log(i);
- }
+ for (let i = 0; i < count; i++) {
+ fetch(`${endpoint}/api/auth/register`, {
+ method: "POST",
+ body: JSON.stringify({
+ fingerprint: `${i}.wR8vi8lGlFBJerErO9LG5NViJFw`,
+ username: `test${i}`,
+ invite: null,
+ consent: true,
+ date_of_birth: "2000-01-01",
+ gift_code_sku_id: null,
+ captcha_key: null,
+ }),
+ headers: { "content-type": "application/json" },
+ });
+ console.log(i);
+ }
}
main();
diff --git a/scripts/syncronise.js b/scripts/syncronise.js
index 1f3ed112..58c18029 100644
--- a/scripts/syncronise.js
+++ b/scripts/syncronise.js
@@ -30,9 +30,9 @@ require("dotenv").config({ quiet: true });
const { initDatabase } = require("..");
(async () => {
- const db = await initDatabase();
- console.log("synchronising");
- await db.synchronize();
- console.log("done");
- db.destroy();
+ const db = await initDatabase();
+ console.log("synchronising");
+ await db.synchronize();
+ console.log("done");
+ db.destroy();
})();
diff --git a/scripts/test.js b/scripts/test.js
index c79e336f..3f944138 100644
--- a/scripts/test.js
+++ b/scripts/test.js
@@ -29,34 +29,34 @@ const cfgFile = path.join(__dirname, "test_config.json");
process.env.CONFIG_PATH = cfgFile;
fs.writeFileSync(
- cfgFile,
- JSON.stringify({
- api: { endpointPublic: "http://localhost:3001/api/v9/" },
- cdn: { endpointPublic: "http://localhost:3001/", endpointPrivate: "http://localhost:3001/" },
- gateway: { endpointPublic: "ws://localhost:3001/" },
- }),
+ cfgFile,
+ JSON.stringify({
+ api: { endpointPublic: "http://localhost:3001/api/v9/" },
+ cdn: { endpointPublic: "http://localhost:3001/", endpointPrivate: "http://localhost:3001/" },
+ gateway: { endpointPublic: "ws://localhost:3001/" },
+ }),
);
const server = spawn("node", [path.join(__dirname, "..", "dist", "bundle", "start.js")]);
server.stdout.on("data", (data) => {
- process.stdout.write(data);
+ process.stdout.write(data);
- if (data.toString().toLowerCase().includes("listening")) {
- // we good :)
- console.log("we good");
- server.kill();
- process.exit();
- }
+ if (data.toString().toLowerCase().includes("listening")) {
+ // we good :)
+ console.log("we good");
+ server.kill();
+ process.exit();
+ }
});
server.stderr.on("data", (err) => {
- process.stdout.write(err);
- // we bad :(
- process.kill(1);
+ process.stdout.write(err);
+ // we bad :(
+ process.kill(1);
});
server.on("close", (code) => {
- console.log("closed with code", code);
- process.exit(code);
+ console.log("closed with code", code);
+ process.exit(code);
});
diff --git a/scripts/util/getRouteDescriptions.js b/scripts/util/getRouteDescriptions.js
index 1f27141e..87f1d4eb 100644
--- a/scripts/util/getRouteDescriptions.js
+++ b/scripts/util/getRouteDescriptions.js
@@ -15,24 +15,24 @@ let currentPath = "";
*/
function colorizeMethod(method) {
- switch (method.toLowerCase()) {
- case "get":
- return greenBright(method.toUpperCase());
- case "post":
- return yellowBright(method.toUpperCase());
- case "put":
- return blueBright(method.toUpperCase());
- case "delete":
- return redBright(method.toUpperCase());
- case "patch":
- return yellowBright(method.toUpperCase());
- default:
- return method.toUpperCase();
- }
+ switch (method.toLowerCase()) {
+ case "get":
+ return greenBright(method.toUpperCase());
+ case "post":
+ return yellowBright(method.toUpperCase());
+ case "put":
+ return blueBright(method.toUpperCase());
+ case "delete":
+ return redBright(method.toUpperCase());
+ case "patch":
+ return yellowBright(method.toUpperCase());
+ default:
+ return method.toUpperCase();
+ }
}
function formatPath(path) {
- return path.replace(/:(\w+)/g, underline(":$1")).replace(/#(\w+)/g, underline("#$1"));
+ return path.replace(/:(\w+)/g, underline(":$1")).replace(/#(\w+)/g, underline("#$1"));
}
/**
@@ -43,45 +43,45 @@ function formatPath(path) {
* @param args
*/
function proxy(file, apiMethod, apiPathPrefix, apiPath, ...args) {
- const opts = args.find((x) => x?.prototype?.OPTS_MARKER == true);
- if (!opts)
- return console.error(
- ` \x1b[5m${bgRedBright("ERROR")}\x1b[25m ${file.replace(path.resolve(__dirname, "..", "..", "dist"), "/src")} has route without route() description middleware: ${colorizeMethod(apiMethod)} ${formatPath(apiPath)}`,
- );
+ const opts = args.find((x) => x?.prototype?.OPTS_MARKER == true);
+ if (!opts)
+ return console.error(
+ ` \x1b[5m${bgRedBright("ERROR")}\x1b[25m ${file.replace(path.resolve(__dirname, "..", "..", "dist"), "/src")} has route without route() description middleware: ${colorizeMethod(apiMethod)} ${formatPath(apiPath)}`,
+ );
- console.log(`${colorizeMethod(apiMethod).padStart("DELETE".length + 10)} ${formatPath(apiPathPrefix + apiPath)}`);
- opts.file = file.replace("/dist/", "/src/").replace(".js", ".ts");
- routes.set(apiPathPrefix + apiPath + "|" + apiMethod, opts());
+ console.log(`${colorizeMethod(apiMethod).padStart("DELETE".length + 10)} ${formatPath(apiPathPrefix + apiPath)}`);
+ opts.file = file.replace("/dist/", "/src/").replace(".js", ".ts");
+ routes.set(apiPathPrefix + apiPath + "|" + apiMethod, opts());
}
express.Router = () => {
- return Object.fromEntries(methods.map((method) => [method, proxy.bind(null, currentFile, method, currentPath)]));
+ return Object.fromEntries(methods.map((method) => [method, proxy.bind(null, currentFile, method, currentPath)]));
};
RouteUtility.route = (opts) => {
- const func = function () {
- return opts;
- };
- func.prototype.OPTS_MARKER = true;
- return func;
+ const func = function () {
+ return opts;
+ };
+ func.prototype.OPTS_MARKER = true;
+ return func;
};
module.exports = function getRouteDescriptions() {
- const root = path.join(__dirname, "..", "..", "dist", "api", "routes", "/");
- traverseDirectory({ dirname: root, recursive: true }, (file) => {
- currentFile = file;
+ const root = path.join(__dirname, "..", "..", "dist", "api", "routes", "/");
+ traverseDirectory({ dirname: root, recursive: true }, (file) => {
+ currentFile = file;
- currentPath = file.replace(root.slice(0, -1), "");
- currentPath = currentPath.split(".").slice(0, -1).join("."); // truncate .js/.ts file extension of path
- currentPath = currentPath.replaceAll("#", ":").replaceAll("\\", "/"); // replace # with : for path parameters and windows paths with slashes
- if (currentPath.endsWith("/index")) currentPath = currentPath.slice(0, "/index".length * -1); // delete index from path
+ currentPath = file.replace(root.slice(0, -1), "");
+ currentPath = currentPath.split(".").slice(0, -1).join("."); // truncate .js/.ts file extension of path
+ currentPath = currentPath.replaceAll("#", ":").replaceAll("\\", "/"); // replace # with : for path parameters and windows paths with slashes
+ if (currentPath.endsWith("/index")) currentPath = currentPath.slice(0, "/index".length * -1); // delete index from path
- try {
- require(file);
- } catch (e) {
- console.error(e);
- }
- });
+ try {
+ require(file);
+ } catch (e) {
+ console.error(e);
+ }
+ });
- return routes;
+ return routes;
};
diff --git a/scripts/util/walk.js b/scripts/util/walk.js
index be59023d..06543315 100644
--- a/scripts/util/walk.js
+++ b/scripts/util/walk.js
@@ -20,18 +20,18 @@ const fs = require("fs");
/** dir: string. types: string[] ( file types ) */
module.exports = function walk(dir, types = ["ts"]) {
- var results = [];
- var list = fs.readdirSync(dir);
- list.forEach(function (file) {
- file = dir + "/" + file;
- var stat = fs.statSync(file);
- if (stat && stat.isDirectory()) {
- /* Recurse into a subdirectory */
- results = results.concat(walk(file, types));
- } else {
- if (!types.find((x) => file.endsWith(x))) return;
- results.push(file);
- }
- });
- return results;
+ var results = [];
+ var list = fs.readdirSync(dir);
+ list.forEach(function (file) {
+ file = dir + "/" + file;
+ var stat = fs.statSync(file);
+ if (stat && stat.isDirectory()) {
+ /* Recurse into a subdirectory */
+ results = results.concat(walk(file, types));
+ } else {
+ if (!types.find((x) => file.endsWith(x))) return;
+ results.push(file);
+ }
+ });
+ return results;
};
|