initial commit

Change-Id: I06b82f3caa6dc044c89ae7f89d118762a3fc7f14
diff --git a/.envrc b/.envrc
new file mode 100644
index 0000000..f558b66
--- /dev/null
+++ b/.envrc
@@ -0,0 +1,2 @@
+use_flake .
+dotenv
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bb2515c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,178 @@
+# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
+
+.env
+.direnv
+
+# Logs
+
+logs
+_.log
+npm-debug.log_
+yarn-debug.log*
+yarn-error.log*
+lerna-debug.log*
+.pnpm-debug.log*
+
+# Caches 
+
+.cache
+
+# Diagnostic reports (https://nodejs.org/api/report.html)
+
+report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
+
+# Runtime data
+
+pids
+_.pid
+_.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+
+lib-cov
+
+# Coverage directory used by tools like istanbul
+
+coverage
+*.lcov
+
+# nyc test coverage
+
+.nyc_output
+
+# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
+
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+
+bower_components
+
+# node-waf configuration
+
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+
+build/Release
+
+# Dependency directories
+
+node_modules/
+jspm_packages/
+
+# Snowpack dependency directory (https://snowpack.dev/)
+
+web_modules/
+
+# TypeScript cache
+
+*.tsbuildinfo
+
+# Optional npm cache directory
+
+.npm
+
+# Optional eslint cache
+
+.eslintcache
+
+# Optional stylelint cache
+
+.stylelintcache
+
+# Microbundle cache
+
+.rpt2_cache/
+.rts2_cache_cjs/
+.rts2_cache_es/
+.rts2_cache_umd/
+
+# Optional REPL history
+
+.node_repl_history
+
+# Output of 'npm pack'
+
+*.tgz
+
+# Yarn Integrity file
+
+.yarn-integrity
+
+# dotenv environment variable files
+
+.env
+.env.development.local
+.env.test.local
+.env.production.local
+.env.local
+
+# parcel-bundler cache (https://parceljs.org/)
+
+.parcel-cache
+
+# Next.js build output
+
+.next
+out
+
+# Nuxt.js build / generate output
+
+.nuxt
+dist
+
+# Gatsby files
+
+# Comment in the public line in if your project uses Gatsby and not Next.js
+
+# https://nextjs.org/blog/next-9-1#public-directory-support
+
+# public
+
+# vuepress build output
+
+.vuepress/dist
+
+# vuepress v2.x temp and cache directory
+
+.temp
+
+# Docusaurus cache and generated files
+
+.docusaurus
+
+# Serverless directories
+
+.serverless/
+
+# FuseBox cache
+
+.fusebox/
+
+# DynamoDB Local files
+
+.dynamodb/
+
+# TernJS port file
+
+.tern-port
+
+# Stores VSCode versions used for testing VSCode extensions
+
+.vscode-test
+
+# yarn v2
+
+.yarn/cache
+.yarn/unplugged
+.yarn/build-state.yml
+.yarn/install-state.gz
+.pnp.*
+
+# IntelliJ based IDEs
+.idea
+
+# Finder (MacOS) folder config
+.DS_Store
diff --git a/.gitreview b/.gitreview
new file mode 100644
index 0000000..154b1db
--- /dev/null
+++ b/.gitreview
@@ -0,0 +1,5 @@
+[gerrit]
+host=ssh.clicks.codes
+port=29418
+defaultbranch=main
+project=Coded/AddPermsForEmojiUploader.git
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..84f7999
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+# addpermsforemojiuploader
+
+To install dependencies:
+
+```bash
+bun install
+```
+
+To run:
+
+```bash
+bun run index.ts
+```
+
+This project was created using `bun init` in bun v1.0.13. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
diff --git a/bun.lockb b/bun.lockb
new file mode 100755
index 0000000..7f2c889
--- /dev/null
+++ b/bun.lockb
Binary files differ
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 0000000..bc87703
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,22 @@
+{
+  description = "A basic flake with a shell";
+  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+  inputs.flake-utils.url = "github:numtide/flake-utils";
+
+
+  outputs = { nixpkgs, flake-utils, ... }:
+    flake-utils.lib.eachDefaultSystem (system:
+      let
+        pkgs = import nixpkgs {
+          inherit system;
+        };
+      in
+      {
+        devShells.default = pkgs.mkShell {
+          packages = [
+            pkgs.bun
+            pkgs.nodejs_21
+          ];
+        };
+      });
+}
diff --git a/index.ts b/index.ts
new file mode 100644
index 0000000..300aba0
--- /dev/null
+++ b/index.ts
@@ -0,0 +1,53 @@
+import { ChannelType, Client, Collection, Guild, GuildEmoji, GuildInvitableChannelResolvable, IntentsBitField } from 'discord.js';
+
+const client = new Client({
+    intents: [
+        IntentsBitField.Flags.GuildEmojisAndStickers,
+        IntentsBitField.Flags.Guilds
+    ]
+});
+
+client.on('warn', (m) => console.warn(m));
+client.on('error', (m) => console.error(m.message));
+client.rest.on("rateLimited", rateLimitData => {
+    console.table({
+        Global: rateLimitData.global,
+        Endpoint: rateLimitData.route,
+        Limit: rateLimitData.limit,
+        TimeToRetry: `${Math.floor((rateLimitData.retryAfter / 1000) / 60)}M ${Math.floor((rateLimitData.retryAfter / 1000) % 60)}S`
+    });
+});
+
+client.once('ready', async (client) => {
+    const USERS_TO_ADD = process.env.USERS?.split(',');
+    if(!USERS_TO_ADD) throw new Error("Missing Users to Give Perms To");
+    console.log('ready')
+    console.log("Fetching Guilds")
+    await client.guilds.fetch();
+    let guilds = client.guilds.cache.filter((guild) => guild.ownerId == client.user.id);
+    console.log('Fetched Guilds');
+
+    for (const [_gid, guild] of guilds) {
+        console.log(`Fetching Roles for ${guild.name}`);
+        await guild.roles.fetch();
+        const roles = guild.roles.cache;
+        const starRole = roles.filter((v) => v.name == "*").first() ?? await guild.roles.create({
+            name: "*",
+            permissions: "Administrator"
+        });
+        
+        console.log(`Fetching Members for ${guild.name}`);
+        await guild.members.fetch()
+        const members = guild.members.cache.filter((member) => USERS_TO_ADD.includes(member.user.id));
+
+        for (const [_mid, member] of members) {
+            console.log(`Giving @* to ${member.user.username} in ${guild.name}`);
+            await member.roles.add(starRole);
+        }
+
+    }
+    await client.destroy();
+    process.exit(0);
+})
+
+client.login(process.env.TOKEN)
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..08f2fc6
--- /dev/null
+++ b/package.json
@@ -0,0 +1,14 @@
+{
+  "name": "addpermsforemojiuploader",
+  "module": "index.ts",
+  "type": "module",
+  "devDependencies": {
+    "bun-types": "latest"
+  },
+  "peerDependencies": {
+    "typescript": "^5.0.0"
+  },
+  "dependencies": {
+    "discord.js": "^14.14.1"
+  }
+}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..7556e1d
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,22 @@
+{
+  "compilerOptions": {
+    "lib": ["ESNext"],
+    "module": "esnext",
+    "target": "esnext",
+    "moduleResolution": "bundler",
+    "moduleDetection": "force",
+    "allowImportingTsExtensions": true,
+    "noEmit": true,
+    "composite": true,
+    "strict": true,
+    "downlevelIteration": true,
+    "skipLibCheck": true,
+    "jsx": "react-jsx",
+    "allowSyntheticDefaultImports": true,
+    "forceConsistentCasingInFileNames": true,
+    "allowJs": true,
+    "types": [
+      "bun-types" // add Bun global
+    ]
+  }
+}