mirror of
https://github.com/BradNut/TofuStack
synced 2025-09-08 17:40:26 +00:00
added redis provider and queueService
This commit is contained in:
parent
4055dcbcf7
commit
6390f8e19a
9 changed files with 182 additions and 25 deletions
20
README.md
20
README.md
|
|
@ -6,7 +6,7 @@ If you forked this repository before May 27th, you'll want to view commit `653e2
|
|||
|
||||
## ❔ What
|
||||
|
||||
A scalable, testable, extensible, template for Sveltekit.
|
||||
A scalable, testable, extensible, template for Sveltekit.
|
||||
|
||||
Sveltekit is awesome, but sometimes you need a bit more capability in the backend than what frameworks like
|
||||
NextJS & Sveltekit can deliver.
|
||||
|
|
@ -25,25 +25,35 @@ export const DELETE: RequestHandler = ({ request }) => app.fetch(request);
|
|||
export const POST: RequestHandler = ({ request }) => app.fetch(request);
|
||||
```
|
||||
|
||||
## Local Setup
|
||||
|
||||
1. Make sure Docker is running
|
||||
2. Copy the `.env.example` file and rename to `.env`
|
||||
3. `pnpm install`
|
||||
4. `pnpm initialize`(this will start the docker-compose and run the initial database migration.)
|
||||
5. `pnpm dev`
|
||||
|
||||
No additional setup is required, zero api keys, zero services to signup for, zero cost.
|
||||
|
||||
## How to Use
|
||||
|
||||
This is **not** supposed to serve as an all batteries included ["production boilerplate"](https://github.com/ixartz/Next-js-Boilerplate) with 200 useless sponsored features that get in your way. Templates that do this are ANYTHING but "production" and "quick start".
|
||||
This is **not** supposed to serve as an all batteries included ["production boilerplate"](https://github.com/ixartz/Next-js-Boilerplate) with 200 useless sponsored features that get in your way. Templates that do this are ANYTHING but "production" and "quick start".
|
||||
|
||||
This is stack is designed to be library agnostic. The philosophy here is to boostrap the concrete, repetitive, and time consuming tasks that every application will need reguardless of what you're building.
|
||||
|
||||
**So - fork this repo, add your favorite libraries, and build out your own "more opinionated" personal template tailored to you**!
|
||||
**So - fork this repo, add your favorite libraries, and build out your own "more opinionated" personal template tailored to you**!
|
||||
|
||||
## Features
|
||||
|
||||
- 🟢 Full E2E typesafety
|
||||
- 🟢 RPC Client for API Requests
|
||||
- 🟢 Custom Fetch Wrapper
|
||||
- 🔴 Deployment Template
|
||||
- 🟢 Deployment Template
|
||||
- 🟠 Authentication
|
||||
- 🟢 Email/Passkey
|
||||
- 🔴 OAuth
|
||||
- 🟢 Email Update/Verifiaction
|
||||
- 🔴 Rate limiter
|
||||
- 🟢 Rate limiter
|
||||
|
||||
## Technologies
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
"@typescript-eslint/parser": "^7.13.1",
|
||||
"arctic": "^1.9.1",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"bullmq": "^5.8.3",
|
||||
"dayjs": "^1.11.11",
|
||||
"dotenv-cli": "^7.4.2",
|
||||
"drizzle-kit": "^0.21.4",
|
||||
|
|
|
|||
130
pnpm-lock.yaml
130
pnpm-lock.yaml
|
|
@ -105,6 +105,9 @@ importers:
|
|||
autoprefixer:
|
||||
specifier: ^10.4.19
|
||||
version: 10.4.19(postcss@8.4.38)
|
||||
bullmq:
|
||||
specifier: ^5.8.3
|
||||
version: 5.8.3
|
||||
dayjs:
|
||||
specifier: ^1.11.11
|
||||
version: 1.11.11
|
||||
|
|
@ -764,6 +767,36 @@ packages:
|
|||
peerDependencies:
|
||||
svelte: '>=3 <5'
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3':
|
||||
resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3':
|
||||
resolution: {integrity: sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3':
|
||||
resolution: {integrity: sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3':
|
||||
resolution: {integrity: sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3':
|
||||
resolution: {integrity: sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3':
|
||||
resolution: {integrity: sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@napi-rs/wasm-runtime@0.2.4':
|
||||
resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==}
|
||||
|
||||
|
|
@ -1507,6 +1540,9 @@ packages:
|
|||
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
bullmq@5.8.3:
|
||||
resolution: {integrity: sha512-RJgQu/vgSZqjOYrZ7F1UJsSAzveNx7FFpR3Tp/1TxOMXXN9TtZMSly5MT+vjzOhQX//3+YWNRbMWpC1mkqBc9w==}
|
||||
|
||||
bytes@3.1.2:
|
||||
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
|
@ -1612,6 +1648,10 @@ packages:
|
|||
resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
cron-parser@4.9.0:
|
||||
resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
cross-spawn@7.0.3:
|
||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||
engines: {node: '>= 8'}
|
||||
|
|
@ -1689,6 +1729,10 @@ packages:
|
|||
resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
detect-libc@2.0.3:
|
||||
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
devalue@5.0.0:
|
||||
resolution: {integrity: sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==}
|
||||
|
||||
|
|
@ -2442,6 +2486,10 @@ packages:
|
|||
peerDependencies:
|
||||
svelte: ^3 || ^4 || ^5.0.0-next.42
|
||||
|
||||
luxon@3.4.4:
|
||||
resolution: {integrity: sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
magic-string@0.30.10:
|
||||
resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==}
|
||||
|
||||
|
|
@ -2552,6 +2600,13 @@ packages:
|
|||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
msgpackr-extract@3.0.3:
|
||||
resolution: {integrity: sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==}
|
||||
hasBin: true
|
||||
|
||||
msgpackr@1.10.2:
|
||||
resolution: {integrity: sha512-L60rsPynBvNE+8BWipKKZ9jHcSGbtyJYIwjRq0VrIvQ08cRjntGXJYW/tmciZ2IHWIY8WEW32Qa2xbh5+SKBZA==}
|
||||
|
||||
mz@2.7.0:
|
||||
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
|
||||
|
||||
|
|
@ -2583,6 +2638,13 @@ packages:
|
|||
next-tick@1.1.0:
|
||||
resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==}
|
||||
|
||||
node-abort-controller@3.1.1:
|
||||
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
|
||||
|
||||
node-gyp-build-optional-packages@5.2.2:
|
||||
resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==}
|
||||
hasBin: true
|
||||
|
||||
node-releases@2.0.14:
|
||||
resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
|
||||
|
||||
|
|
@ -3461,6 +3523,10 @@ packages:
|
|||
resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==}
|
||||
engines: {node: '>= 0.4.0'}
|
||||
|
||||
uuid@9.0.1:
|
||||
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
||||
hasBin: true
|
||||
|
||||
valibot@0.31.1:
|
||||
resolution: {integrity: sha512-2YYIhPrnVSz/gfT2/iXVTrSj92HwchCt9Cga/6hX4B26iCz9zkIsGTS0HjDYTZfTi1Un0X6aRvhBi1cfqs/i0Q==}
|
||||
|
||||
|
|
@ -4006,6 +4072,24 @@ snapshots:
|
|||
nanoid: 5.0.7
|
||||
svelte: 5.0.0-next.164
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3':
|
||||
optional: true
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.3':
|
||||
optional: true
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.3':
|
||||
optional: true
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-linux-arm@3.0.3':
|
||||
optional: true
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-linux-x64@3.0.3':
|
||||
optional: true
|
||||
|
||||
'@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3':
|
||||
optional: true
|
||||
|
||||
'@napi-rs/wasm-runtime@0.2.4':
|
||||
dependencies:
|
||||
'@emnapi/core': 1.2.0
|
||||
|
|
@ -4729,6 +4813,18 @@ snapshots:
|
|||
|
||||
builtin-modules@3.3.0: {}
|
||||
|
||||
bullmq@5.8.3:
|
||||
dependencies:
|
||||
cron-parser: 4.9.0
|
||||
ioredis: 5.4.1
|
||||
msgpackr: 1.10.2
|
||||
node-abort-controller: 3.1.1
|
||||
semver: 7.6.2
|
||||
tslib: 2.6.3
|
||||
uuid: 9.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
bytes@3.1.2: {}
|
||||
|
||||
cac@6.7.14: {}
|
||||
|
|
@ -4832,6 +4928,10 @@ snapshots:
|
|||
|
||||
cookie@0.6.0: {}
|
||||
|
||||
cron-parser@4.9.0:
|
||||
dependencies:
|
||||
luxon: 3.4.4
|
||||
|
||||
cross-spawn@7.0.3:
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
|
|
@ -4883,6 +4983,9 @@ snapshots:
|
|||
|
||||
detect-indent@6.1.0: {}
|
||||
|
||||
detect-libc@2.0.3:
|
||||
optional: true
|
||||
|
||||
devalue@5.0.0: {}
|
||||
|
||||
didyoumean@1.2.2: {}
|
||||
|
|
@ -5729,6 +5832,8 @@ snapshots:
|
|||
dependencies:
|
||||
svelte: 5.0.0-next.164
|
||||
|
||||
luxon@3.4.4: {}
|
||||
|
||||
magic-string@0.30.10:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
|
|
@ -5828,6 +5933,22 @@ snapshots:
|
|||
|
||||
ms@2.1.3: {}
|
||||
|
||||
msgpackr-extract@3.0.3:
|
||||
dependencies:
|
||||
node-gyp-build-optional-packages: 5.2.2
|
||||
optionalDependencies:
|
||||
'@msgpackr-extract/msgpackr-extract-darwin-arm64': 3.0.3
|
||||
'@msgpackr-extract/msgpackr-extract-darwin-x64': 3.0.3
|
||||
'@msgpackr-extract/msgpackr-extract-linux-arm': 3.0.3
|
||||
'@msgpackr-extract/msgpackr-extract-linux-arm64': 3.0.3
|
||||
'@msgpackr-extract/msgpackr-extract-linux-x64': 3.0.3
|
||||
'@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.3
|
||||
optional: true
|
||||
|
||||
msgpackr@1.10.2:
|
||||
optionalDependencies:
|
||||
msgpackr-extract: 3.0.3
|
||||
|
||||
mz@2.7.0:
|
||||
dependencies:
|
||||
any-promise: 1.3.0
|
||||
|
|
@ -5848,6 +5969,13 @@ snapshots:
|
|||
|
||||
next-tick@1.1.0: {}
|
||||
|
||||
node-abort-controller@3.1.1: {}
|
||||
|
||||
node-gyp-build-optional-packages@5.2.2:
|
||||
dependencies:
|
||||
detect-libc: 2.0.3
|
||||
optional: true
|
||||
|
||||
node-releases@2.0.14: {}
|
||||
|
||||
nodemailer@6.9.14: {}
|
||||
|
|
@ -6673,6 +6801,8 @@ snapshots:
|
|||
|
||||
utils-merge@1.0.1: {}
|
||||
|
||||
uuid@9.0.1: {}
|
||||
|
||||
valibot@0.31.1:
|
||||
optional: true
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,6 @@ ensure that the correct data is being passed around.
|
|||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
export const updateEmailDto = z.object({
|
||||
email: z.string()
|
||||
email: z.string().email()
|
||||
});
|
||||
export type UpdateEmailDto = z.infer<typeof updateEmailDto>;
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
export * from './database.provider';
|
||||
export * from './lucia.provider';
|
||||
export * from './redis.provider';
|
||||
|
|
|
|||
14
src/lib/server/api/providers/redis.provider.ts
Normal file
14
src/lib/server/api/providers/redis.provider.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { container } from 'tsyringe';
|
||||
import RedisClient from 'ioredis'
|
||||
import { config } from '../common/config';
|
||||
|
||||
// Symbol
|
||||
export const RedisProvider = Symbol('REDIS_TOKEN');
|
||||
|
||||
// Type
|
||||
export type RedisProvider = RedisClient;
|
||||
|
||||
// Register
|
||||
container.register<RedisProvider>(RedisProvider, {
|
||||
useValue: new RedisClient(config.REDIS_URL)
|
||||
});
|
||||
19
src/lib/server/api/services/queues.service.ts
Normal file
19
src/lib/server/api/services/queues.service.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { injectable } from "tsyringe";
|
||||
import RedisClient from 'ioredis'
|
||||
import { config } from "../common/config";
|
||||
import { Queue, Worker, type Processor } from 'bullmq';
|
||||
|
||||
@injectable()
|
||||
export class QueuesServices {
|
||||
connection = new RedisClient(config.REDIS_URL);
|
||||
|
||||
constructor() { }
|
||||
|
||||
createQueue(name: string) {
|
||||
return new Queue(name, { connection: this.connection })
|
||||
}
|
||||
|
||||
createWorker(name: string, prcoessor: Processor) {
|
||||
return new Worker(name, prcoessor, { connection: this.connection })
|
||||
}
|
||||
}
|
||||
|
|
@ -3,24 +3,6 @@ import { generateRandomString } from "oslo/crypto";
|
|||
import { TimeSpan, createDate, type TimeSpanUnit } from 'oslo';
|
||||
import { HashingService } from './hashing.service';
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Service */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* ---------------------------------- About --------------------------------- */
|
||||
/*
|
||||
Services are responsible for handling business logic and data manipulation.
|
||||
They genreally call on repositories or other services to complete a use-case.
|
||||
*/
|
||||
/* ---------------------------------- Notes --------------------------------- */
|
||||
/*
|
||||
Services should be kept as clean and simple as possible.
|
||||
|
||||
Create private functions to handle complex logic and keep the public methods as
|
||||
simple as possible. This makes the service easier to read, test and understand.
|
||||
*/
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
@injectable()
|
||||
export class TokensService {
|
||||
constructor(@inject(HashingService) private readonly hashingService: HashingService) { }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import 'reflect-metadata';
|
||||
import { LoginRequestsService } from '../services/login-requests.service';
|
||||
import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
|
||||
import { afterAll, beforeAll, describe, expect, it, vi } from 'vitest';
|
||||
import { TokensService } from '../services/tokens.service';
|
||||
import { MailerService } from '../services/mailer.service';
|
||||
import { UsersRepository } from '../repositories/users.repository';
|
||||
|
|
|
|||
Loading…
Reference in a new issue