feat: add functional authentication
This commit is contained in:
70
api/.tasks/bootstrap.ts
Normal file
70
api/.tasks/bootstrap.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { resolve } from "node:path";
|
||||
|
||||
import { logger } from "~libraries/logger/mod.ts";
|
||||
|
||||
const LIBRARIES_DIR = resolve(import.meta.dirname!, "..", "libraries");
|
||||
const STORES_DIR = resolve(import.meta.dirname!, "..", "stores");
|
||||
|
||||
const log = logger.prefix("Bootstrap");
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
| Database
|
||||
|--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
await import("~libraries/database/.tasks/bootstrap.ts");
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
| Packages
|
||||
|--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
await bootstrap(LIBRARIES_DIR);
|
||||
await bootstrap(STORES_DIR);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
| Helpers
|
||||
|--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Traverse path and look for a `bootstrap.ts` file in each folder found under
|
||||
* the given path. If a `boostrap.ts` file is found it is imported so its content
|
||||
* is executed.
|
||||
*
|
||||
* @param path - Path to resolve `bootstrap.ts` files.
|
||||
*/
|
||||
export async function bootstrap(path: string): Promise<void> {
|
||||
const bootstrap: { name: string; path: string }[] = [];
|
||||
for await (const entry of Deno.readDir(path)) {
|
||||
if (entry.isDirectory === true) {
|
||||
const moduleName = path.split("/").pop();
|
||||
if (moduleName === undefined) {
|
||||
continue;
|
||||
}
|
||||
const filePath = `${path}/${entry.name}/.tasks/bootstrap.ts`;
|
||||
if (await hasFile(filePath)) {
|
||||
bootstrap.push({ name: entry.name, path: filePath });
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const entry of bootstrap) {
|
||||
log.info(entry.name);
|
||||
await import(entry.path);
|
||||
}
|
||||
}
|
||||
|
||||
async function hasFile(filePath: string) {
|
||||
try {
|
||||
await Deno.lstat(filePath);
|
||||
} catch (err) {
|
||||
if (!(err instanceof Deno.errors.NotFound)) {
|
||||
throw err;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
66
api/.tasks/migrate.ts
Normal file
66
api/.tasks/migrate.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { resolve } from "node:path";
|
||||
import process from "node:process";
|
||||
|
||||
import { exists } from "@std/fs";
|
||||
|
||||
import { config } from "~libraries/database/config.ts";
|
||||
import { getMongoClient } from "~libraries/database/connection.ts";
|
||||
import { container } from "~libraries/database/container.ts";
|
||||
import { logger } from "~libraries/logger/mod.ts";
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
| Dependencies
|
||||
|--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const client = getMongoClient(config.mongo);
|
||||
|
||||
container.set("client", client);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
| Migrate
|
||||
|--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const db = client.db("api:migrations");
|
||||
const collection = db.collection<MigrationDocument>("migrations");
|
||||
|
||||
const { default: journal } = await import(resolve(import.meta.dirname!, "migrations", "meta", "_journal.json"), {
|
||||
with: { type: "json" },
|
||||
});
|
||||
|
||||
const migrations =
|
||||
(await collection.findOne({ name: journal.name })) ?? ({ name: journal.name, entries: [] } as MigrationDocument);
|
||||
|
||||
for (const entry of journal.entries) {
|
||||
const migrationFileName = `${String(entry.idx).padStart(4, "0")}_${entry.name}.ts`;
|
||||
if (migrations.entries.includes(migrationFileName)) {
|
||||
continue;
|
||||
}
|
||||
const migrationPath = resolve(import.meta.dirname!, "migrations", migrationFileName);
|
||||
if (await exists(migrationPath)) {
|
||||
await import(migrationPath);
|
||||
await collection.updateOne(
|
||||
{
|
||||
name: journal.name,
|
||||
},
|
||||
{
|
||||
$set: { name: journal.name },
|
||||
$push: { entries: migrationFileName }, // Assuming 'entries' is an array
|
||||
},
|
||||
{
|
||||
upsert: true,
|
||||
},
|
||||
);
|
||||
logger.info(`Migrated ${migrationPath}`);
|
||||
}
|
||||
}
|
||||
|
||||
type MigrationDocument = {
|
||||
name: string;
|
||||
entries: string[];
|
||||
};
|
||||
|
||||
process.exit(0);
|
||||
4
api/.tasks/migrations/meta/_journal.json
Normal file
4
api/.tasks/migrations/meta/_journal.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"name": "api",
|
||||
"entries": []
|
||||
}
|
||||
Reference in New Issue
Block a user