Move to some etension methods
This commit is contained in:
parent
0d907af72f
commit
bd9a75f919
@ -18,7 +18,6 @@
|
||||
|
||||
// process.env.MONGOMS_DEBUG = "true";
|
||||
import moduleAlias from "module-alias";
|
||||
|
||||
moduleAlias(__dirname + "../../../package.json");
|
||||
|
||||
import "reflect-metadata";
|
||||
|
||||
@ -566,7 +566,7 @@ export class Channel extends BaseClass {
|
||||
let userPerms = new Permissions(new BitField(0).add(roles.map(r => r.permissions)));
|
||||
|
||||
// TODO: do we want to have an instance-wide opt out of this behavior? It would just be an extra if statement here
|
||||
if (userPerms.has(Permissions.FLAGS.ADMINISTRATOR)) return true;
|
||||
if (userPerms.has(Permissions.FLAGS.ADMINISTRATOR)) return userPerms;
|
||||
|
||||
// apply channel overrides
|
||||
if (this.permission_overwrites) {
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2023 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// TODO: remove this function.
|
||||
|
||||
export function containsAll(arr: unknown[], target: unknown[]) {
|
||||
return target.every((v) => arr.includes(v));
|
||||
}
|
||||
|
||||
/* https://stackoverflow.com/a/50636286 */
|
||||
export function partition<T>(array: T[], filter: (elem: T) => boolean) {
|
||||
const pass: T[] = [],
|
||||
fail: T[] = [];
|
||||
array.forEach((e) => (filter(e) ? pass : fail).push(e));
|
||||
return [pass, fail];
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
/**
|
||||
* Normalize a URL by:
|
||||
* - Removing trailing slashes (except root path)
|
||||
* - Sorting query params alphabetically
|
||||
* - Removing empty query strings
|
||||
* - Removing fragments
|
||||
*/
|
||||
export function normalizeUrl(input: string): string {
|
||||
try {
|
||||
const u = new URL(input);
|
||||
// Remove fragment
|
||||
u.hash = "";
|
||||
// Normalize pathname - remove trailing slash except for root "/"
|
||||
if (u.pathname !== "/" && u.pathname.endsWith("/")) {
|
||||
u.pathname = u.pathname.slice(0, -1);
|
||||
}
|
||||
// Normalize query params: sort by key
|
||||
if (u.search) {
|
||||
const params = Array.from(u.searchParams.entries());
|
||||
params.sort(([a], [b]) => a.localeCompare(b));
|
||||
u.search = params.length
|
||||
? "?" + params.map(([k, v]) => `${k}=${v}`).join("&")
|
||||
: "";
|
||||
} else {
|
||||
// Ensure no empty search string
|
||||
u.search = "";
|
||||
}
|
||||
return u.toString();
|
||||
} catch (e) {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
58
src/util/util/extensions/Array.ts
Normal file
58
src/util/util/extensions/Array.ts
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2025 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare global {
|
||||
interface Array<T> {
|
||||
containsAll(target: T[]): boolean;
|
||||
partition(filter: (elem: T) => boolean): [T[], T[]];
|
||||
single(filter: (elem: T) => boolean): T | null;
|
||||
}
|
||||
}
|
||||
|
||||
export function containsAll<T>(arr: T[], target: T[]) {
|
||||
return target.every((v) => arr.includes(v));
|
||||
}
|
||||
|
||||
/* https://stackoverflow.com/a/50636286 */
|
||||
export function partition<T>(array: T[], filter: (elem: T) => boolean): [T[], T[]] {
|
||||
const pass: T[] = [],
|
||||
fail: T[] = [];
|
||||
array.forEach((e) => (filter(e) ? pass : fail).push(e));
|
||||
return [pass, fail];
|
||||
}
|
||||
|
||||
export function single<T>(array: T[], filter: (elem: T) => boolean): T | null {
|
||||
const results = array.filter(filter);
|
||||
if (results.length > 1) throw new Error("Array contains more than one matching element");
|
||||
if (results.length === 0) return null;
|
||||
return results[0];
|
||||
}
|
||||
|
||||
// register extensions
|
||||
if (!Array.prototype.containsAll)
|
||||
Array.prototype.containsAll = function <T>(this: T[], target: T[]) {
|
||||
return containsAll(this, target);
|
||||
};
|
||||
if (!Array.prototype.partition)
|
||||
Array.prototype.partition = function <T>(this: T[], filter: (elem: T) => boolean) {
|
||||
return partition(this, filter);
|
||||
};
|
||||
if (!Array.prototype.single)
|
||||
Array.prototype.single = function <T>(this: T[], filter: (elem: T) => boolean) {
|
||||
return single(this, filter);
|
||||
};
|
||||
0
src/util/util/extensions/Url.d.ts
vendored
Normal file
0
src/util/util/extensions/Url.d.ts
vendored
Normal file
60
src/util/util/extensions/Url.ts
Normal file
60
src/util/util/extensions/Url.ts
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2025 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare module "url" {
|
||||
interface URL {
|
||||
normalize(): string;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a URL by:
|
||||
* - Removing trailing slashes (except root path)
|
||||
* - Sorting query params alphabetically
|
||||
* - Removing empty query strings
|
||||
* - Removing fragments
|
||||
*/
|
||||
export function normalizeUrl(input: string): string {
|
||||
try {
|
||||
const u = new URL(input);
|
||||
// Remove fragment
|
||||
u.hash = "";
|
||||
// Normalize pathname - remove trailing slash except for root "/"
|
||||
if (u.pathname !== "/" && u.pathname.endsWith("/")) {
|
||||
u.pathname = u.pathname.slice(0, -1);
|
||||
}
|
||||
// Normalize query params: sort by key
|
||||
if (u.search) {
|
||||
const params = Array.from(u.searchParams.entries());
|
||||
params.sort(([a], [b]) => a.localeCompare(b));
|
||||
u.search = params.length ? "?" + params.map(([k, v]) => `${k}=${v}`).join("&") : "";
|
||||
} else {
|
||||
// Ensure no empty search string
|
||||
u.search = "";
|
||||
}
|
||||
return u.toString();
|
||||
} catch (e) {
|
||||
return input;
|
||||
}
|
||||
}
|
||||
|
||||
// register extensions
|
||||
if (!URL.prototype.normalize)
|
||||
URL.prototype.normalize = function () {
|
||||
return normalizeUrl(this.toString());
|
||||
};
|
||||
2
src/util/util/extensions/index.ts
Normal file
2
src/util/util/extensions/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from "./Array";
|
||||
export * from "./Url";
|
||||
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
export * from "./ApiError";
|
||||
export * from "./Array";
|
||||
export * from "./extensions/Array";
|
||||
export * from "./BitField";
|
||||
//export * from "./Categories";
|
||||
export * from "./cdn";
|
||||
@ -44,8 +44,8 @@ export * from "./String";
|
||||
export * from "./Token";
|
||||
export * from "./TraverseDirectory";
|
||||
export * from "./WebAuthn";
|
||||
export * from "./Url";
|
||||
export * from "./Gifs";
|
||||
export * from "./Application";
|
||||
export * from "./NameValidation";
|
||||
export * from "./HelperTypes";
|
||||
export * from "./extensions";
|
||||
|
||||
@ -55,8 +55,8 @@
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||
|
||||
/* Emit */
|
||||
"declaration": false /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
|
||||
"declarationMap": false /* Create sourcemaps for d.ts files. */,
|
||||
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
|
||||
"declarationMap": true /* Create sourcemaps for d.ts files. */,
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
"sourceMap": true /* Create source map files for emitted JavaScript files. */,
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||
|
||||
Reference in New Issue
Block a user