a cache for slack profile pictures and emojis

feat: add inital elysia config

+303
+44
.gitignore
··· 1 + # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 + 3 + # dependencies 4 + /node_modules 5 + /.pnp 6 + .pnp.js 7 + 8 + # testing 9 + /coverage 10 + 11 + # next.js 12 + /.next/ 13 + /out/ 14 + 15 + # production 16 + /build 17 + 18 + # misc 19 + .DS_Store 20 + *.pem 21 + 22 + # debug 23 + npm-debug.log* 24 + yarn-debug.log* 25 + yarn-error.log* 26 + 27 + # local env files 28 + .env.local 29 + .env.development.local 30 + .env.test.local 31 + .env.production.local 32 + 33 + # vercel 34 + .vercel 35 + 36 + **/*.trace 37 + **/*.zip 38 + **/*.tar.gz 39 + **/*.tgz 40 + **/*.log 41 + package-lock.json 42 + **/*.bun 43 + 44 + .env*
bun.lockb

This is a binary file and will not be displayed.

+17
manifest.yaml
··· 1 + display_information: 2 + name: Cachet 3 + description: Cache / Proxy for emojis and profile images 4 + background_color: "#051f3d" 5 + features: 6 + bot_user: 7 + display_name: Cachet 8 + always_online: false 9 + oauth_config: 10 + scopes: 11 + bot: 12 + - users.profile:read 13 + - emoji:read 14 + settings: 15 + org_deploy_enabled: false 16 + socket_mode_enabled: false 17 + token_rotation_enabled: false
+17
package.json
··· 1 + { 2 + "name": "cachet", 3 + "version": "0.0.1", 4 + "scripts": { 5 + "test": "echo \"Error: no test specified\" && exit 1", 6 + "dev": "bun run --watch src/index.ts" 7 + }, 8 + "dependencies": { 9 + "@elysiajs/swagger": "^1.1.6", 10 + "elysia": "latest", 11 + "slack-edge": "^1.3.5" 12 + }, 13 + "devDependencies": { 14 + "bun-types": "latest" 15 + }, 16 + "module": "src/index.js" 17 + }
+120
src/index.ts
··· 1 + import { Elysia, t } from "elysia"; 2 + import { swagger } from "@elysiajs/swagger"; 3 + import { version } from "../package.json"; 4 + import { SlackApp } from "slack-edge"; 5 + 6 + if (!process.env.SLACK_BOT_TOKEN || !process.env.SLACK_SIGNING_SECRET) { 7 + const missingEnvVars = [ 8 + !process.env.SLACK_BOT_TOKEN && "SLACK_BOT_TOKEN", 9 + !process.env.SLACK_SIGNING_SECRET && "SLACK_SIGNING_SECRET", 10 + !process.env.SLACK_USER_TOKEN && "SLACK_USER_TOKEN", 11 + !process.env.ADMINS && "ADMINS", 12 + ].filter(Boolean); 13 + 14 + throw new Error( 15 + `Missing required environment variables: ${missingEnvVars.join(", ")}`, 16 + ); 17 + } 18 + 19 + const slackApp = new SlackApp({ 20 + env: { 21 + SLACK_BOT_TOKEN: process.env.SLACK_BOT_TOKEN, 22 + SLACK_SIGNING_SECRET: process.env.SLACK_SIGNING_SECRET, 23 + SLACK_LOGGING_LEVEL: "INFO", 24 + }, 25 + startLazyListenerAfterAck: true, 26 + }); 27 + 28 + const app = new Elysia() 29 + .use( 30 + swagger({ 31 + documentation: { 32 + info: { 33 + version: version, 34 + title: "Cachet", 35 + description: "Cachet API Documentation", 36 + contact: { 37 + name: "Kieran Klukas", 38 + email: "me@dunkirk.sh", 39 + }, 40 + license: { 41 + name: "AGPL 3.0", 42 + url: "https://github.com/taciturnaxoltol/cachet/blob/master/LICENSE.md", 43 + }, 44 + }, 45 + tags: [ 46 + { 47 + name: "Auth", 48 + description: "Authentication routes", 49 + }, 50 + { 51 + name: "Slack", 52 + description: "Slack routes", 53 + }, 54 + { 55 + name: "Status", 56 + description: "Status routes", 57 + }, 58 + ], 59 + }, 60 + }), 61 + ) 62 + .get( 63 + "/", 64 + () => "Hello World from Cachet 😊\n\n---\nSee /swagger for docs\n---", 65 + { 66 + tags: ["Status"], 67 + response: { 68 + 200: t.String({ 69 + default: 70 + "Hello World from Cachet 😊\n\n---\nSee /swagger for docs\n---", 71 + }), 72 + }, 73 + }, 74 + ) 75 + .get( 76 + "/health", 77 + async ({ error }) => { 78 + // TODO: Check slack connection and database connection 79 + const slackConnection = await slackApp.client.auth.test(); 80 + 81 + if (!slackConnection.ok) 82 + error(500, { 83 + http: false, 84 + slack: slackConnection.ok, 85 + database: false, 86 + }); 87 + 88 + return { 89 + http: true, 90 + slack: true, 91 + database: true, 92 + }; 93 + }, 94 + { 95 + tags: ["Status"], 96 + response: { 97 + 200: t.Object({ 98 + http: t.Boolean(), 99 + slack: t.Boolean(), 100 + database: t.Boolean(), 101 + }), 102 + 500: t.Object({ 103 + http: t.Boolean({ 104 + default: false, 105 + }), 106 + slack: t.Boolean({ 107 + default: false, 108 + }), 109 + database: t.Boolean({ 110 + default: false, 111 + }), 112 + }), 113 + }, 114 + }, 115 + ) 116 + .listen(3000); 117 + 118 + console.log( 119 + `🦊 Elysia is running at ${app.server?.hostname}:${app.server?.port} at ${version}`, 120 + );
+105
tsconfig.json
··· 1 + { 2 + "compilerOptions": { 3 + /* Visit https://aka.ms/tsconfig to read more about this file */ 4 + 5 + /* Projects */ 6 + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 7 + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 9 + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 10 + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 + 13 + /* Language and Environment */ 14 + "target": "ES2021" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 15 + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 + // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 20 + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 22 + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 23 + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 26 + 27 + /* Modules */ 28 + "module": "ES2022" /* Specify what module code is generated. */, 29 + // "rootDir": "./", /* Specify the root folder within your source files. */ 30 + "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, 31 + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 32 + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 33 + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 34 + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 35 + "types": [ 36 + "bun-types" 37 + ] /* Specify type package names to be included without being referenced in a source file. */, 38 + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 39 + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 40 + "resolveJsonModule": true /* Enable importing .json files. */, 41 + // "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */ 42 + 43 + /* JavaScript Support */ 44 + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 45 + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 46 + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 47 + 48 + /* Emit */ 49 + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 50 + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 51 + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 52 + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 53 + // "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. */ 54 + // "outDir": "./", /* Specify an output folder for all emitted files. */ 55 + // "removeComments": true, /* Disable emitting comments. */ 56 + // "noEmit": true, /* Disable emitting files from a compilation. */ 57 + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 58 + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 59 + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 60 + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 61 + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 62 + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 63 + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 64 + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 65 + // "newLine": "crlf", /* Set the newline character for emitting files. */ 66 + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 67 + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 68 + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 69 + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 70 + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 71 + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 72 + 73 + /* Interop Constraints */ 74 + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 75 + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 76 + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, 77 + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 78 + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 79 + 80 + /* Type Checking */ 81 + "strict": true /* Enable all strict type-checking options. */, 82 + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ 83 + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ 84 + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 85 + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ 86 + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 87 + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ 88 + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 89 + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 90 + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 91 + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 92 + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 93 + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 94 + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 95 + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 96 + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 97 + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 98 + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 99 + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 100 + 101 + /* Completeness */ 102 + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 103 + "skipLibCheck": true /* Skip type checking all .d.ts files. */ 104 + } 105 + }