Skip to content

Commit

Permalink
vn(feat) gitflow(3:46): got it working in an least optimal way. need …
Browse files Browse the repository at this point in the history
…to clean up and refactor. long flow, hungry.
varsnothing committed Jan 24, 2024
1 parent a271c9e commit 35db20a
Showing 8 changed files with 204 additions and 67 deletions.
3 changes: 3 additions & 0 deletions .env.public
Original file line number Diff line number Diff line change
@@ -12,6 +12,9 @@ GITHUB_SECRET=
EMAIL_SERVER=
EMAIL_FROM=

# modes: "full" (feats: enable-multi-tenancy,;)
NEXUS_MODE=

# env agnostic
MONGODB_URI=

10 changes: 8 additions & 2 deletions lib/model/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
// index.ts TS-Doc?

/* mdb */
import clientPromise from "./mdb-connector";
import clientPromise, { _setDb } from "./mdb-connector";
export const MongoConnector = clientPromise;
export { DATABASE_STRING } from "./interfaces";
export const setDb = _setDb;

export {
DATABASE_STRING,
DATABASE_USERS_STRING,
DATABASE_ORGS_STRING
} from "./interfaces";

/* rm-decorators */
export { decorateRMCharacters } from "./decorators";
10 changes: 7 additions & 3 deletions lib/model/interfaces/constants.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// constants.ts
let nexusDatabase = "test";
let orgsDatabase, usersDatabase;
let DATABASE_USERS_STRING, DATABASE_ORGS_STRING;


/* lean */
if (process.env.NEXUS_MODE !== 'full') {
console.log("DEFAULT DB IS", process.env.MONGODB_DATABASE)
nexusDatabase = process.env.MONGODB_DATABASE;
} else {
/* full-model */
@@ -28,11 +30,13 @@ if (process.env.MONGODB_USERS_DATABASE) {
// krnDatabase = process.env.MONGODB_KRN_DATABASE;
// }

}

/* __backwards-compatible: should fallback to nexus */
const DATABASE_USERS_STRING = usersDatabase || nexusDatabase;
const DATABASE_ORGS_STRING = orgsDatabase || nexusDatabase;
DATABASE_USERS_STRING = usersDatabase || nexusDatabase;
DATABASE_ORGS_STRING = orgsDatabase || nexusDatabase;

}
console.log(" CONST IS ", DATABASE_USERS_STRING)

export {
/* __default__ */
6 changes: 5 additions & 1 deletion lib/model/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -3,7 +3,11 @@
/* mdb-ifaces */

/* const */
export { DATABASE_STRING } from "./constants";
export { DATABASE_STRING, DATABASE_USERS_STRING, DATABASE_ORGS_STRING } from "./constants";

// default methods
export { getUserCollection } from "./mdb-init-interface";


// read
export { getUserMeta } from "./mdb-get-interface";
8 changes: 1 addition & 7 deletions lib/model/interfaces/mdb-get-interface.ts
Original file line number Diff line number Diff line change
@@ -3,15 +3,9 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import type { UserSchema, INCharacter, UserDecoration } from "@types";
import { MongoConnector } from "@model";
import { getUserCollection } from "@controller"
import { DATABASE_STRING as databaseName } from "./constants";

const getUserCollection = async () => {
const col = await getCollection(databaseName);
const _col = await col("users");
_init[databaseName].collections["users"] = _col;
return _col;
};

/* public */
export const getUserMeta = async ({
email = "",
112 changes: 64 additions & 48 deletions lib/model/interfaces/mdb-init-interface.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
// mdb-init-interface.ts
import type { UserSchema, INCharacter, UserDecoration } from "@types";
import { MongoConnector } from "@model";
import { DATABASE_STRING as databaseName } from "./constants";
import { MongoConnector, setDb } from "@model";
import {
DATABASE_STRING as databaseName,
DATABASE_USERS_STRING as userDatabaseName,
DATABASE_ORGS_STRING as orgsDatabaseName,
} from "./constants";

console.log("---- USER DATABASE IS : ", userDatabaseName)

type Tdbs = "nexus" | "organizations" | "test";

@@ -25,7 +31,7 @@ const _UserSchema: UserDecoration = {
};

const _OrgSchema: UserDecoration = {
rickmorty: {
rickmorty_org: {
favorites: {
characters: [] as INCharacter["id"][],
},
@@ -34,37 +40,76 @@ const _OrgSchema: UserDecoration = {

/* private */
const getDB = (name: Tdbs | unknown) => async () => {
console.log("---- USER DATABASE IS : ", userDatabaseName)
console.log(`---- db init:connecting-to:${name} ----`, setDb)
const conn = await MongoConnector;
const db = await conn.db(name);
const db_conn = await setDb(name);
const db = await db_conn.db(name)
return db;
};

const init =
(db: Tdbs): (() => Promise<Db>) =>
async (): TModelSingleton => {
console.log("init to ", db)
const _getDB = getDB(db);
const _db = await _getDB();
// console.log({ _db })
console.log(`---- db init:create/load:${db} success ----`, { _db })
return _db;
};

// to-do: singleton + mutex
const __init = {
const _init = {
[userDatabaseName || databaseName]: init(userDatabaseName || databaseName),
};

const _init = !orgsDatabaseName ? __init : {
...__init,
[orgsDatabaseName]: init(orgsDatabaseName),
};
if (!process.env.NEXUS_MODE !== 'full') {
_init[orgsDatabaseName] = init(orgsDatabaseName)
}

// _init[databaseName] = init(databaseName);

const getCollection =
async (_db = databaseName) =>
async (_collection = "users") => {
console.log("DB NAME IS SET TO: ", databaseName)
if (!_init[_db].db) {
const db = await _init[_db]();
_init[_db].db = db;
}
const collection = await _init[_db].db.collection(_collection);
if (!_init[_db].db) return new Error("db not reachable");

/* init-collections */
_init[_db].collections = { ..._init[_db].collections };
_init[_db].collections[_collection] = collection;


return collection;
};

/* public methods */

const getUserCollection = async () => {
const col = await getCollection(userDatabaseName);
const _col = await col("users");
_init[userDatabaseName].collections["users"] = _col;
return _col;
};

const getOrgCollection = async () => {
console.log(" ORGS DB IS :", orgsDatabaseName)
const col = await getCollection(orgsDatabaseName);
const _col = await col("organizations");
_init[orgsDatabaseName].collections["organizations"] = _col;
return _col;
};

/** ORM **/
const defineSchema =
({ schema }) =>
({ schema }, getOneCollection) =>
async () => {
const collection = await getUserCollection();
const collection = await getOneCollection();
const result = collection.updateMany(
{},
{ $set: schema },
@@ -79,55 +124,26 @@ const defineUserSchema = defineSchema({
db: userDatabaseName || databaseName,
collection: "users",
schema: _UserSchema,
});
}, getUserCollection);

const defineOrgSchema = defineSchema({
db: orgsDatabaseName || databaseName,
collection: "orgs",
collection: "organizations",
schema: _OrgSchema,
});
}, getOrgCollection);

const _initSchemas = async () => {
await defineUserSchema();
// to-do: write org schema enforcement logic
// await defineOrgSchema();
await defineOrgSchema();
};

// migrations: uncomment this line to enforce schemas
if (process.env.NEXUS_SCHEMA === 'true') {
// migrations: add this env var and set it to 'true' to enforce schemas
// or run yarn dev:schema (local), start:schema (CI)
if (true || process.env.NEXUS_SCHEMA === 'true') {
_initSchemas();
}

const getCollection =
async (_db = databaseName) =>
async (_collection = "users") => {
if (!_init[_db].db) {
const db = await _init[_db]();
_init[_db].db = db;
}
const collection = await _init[_db].db.collection(_collection);
if (!_init[_db].db) return new Error("db not reachable");
_init[databaseName].collections = { ..._init[databaseName].collections };
_init[databaseName].collections[_collection] = collection;
return collection;
};

/* public methods */

const getUserCollection = async () => {
const col = await getCollection(databaseName);
const _col = await col("users");
_init[databaseName].collections["users"] = _col;
return _col;
};

const getOrgCollection = async () => {
const col = await getCollection(databaseName);
const _col = await col("organizations");
_init[databaseName].collections["organizations"] = _col;
return _col;
};

/* to-do: services, projects, billing, krn cols interfaces.
(check respective dbs, maybe split init for each db) */

116 changes: 112 additions & 4 deletions lib/model/mdb-connector.ts
Original file line number Diff line number Diff line change
@@ -7,26 +7,134 @@ if (!process.env.MONGODB_URI) {
throw new Error('Invalid/Missing environment variable: "MONGODB_URI"');
}

const uri = process.env.MONGODB_URI;
const full_uri = process.env.MONGODB_URI
const uri_arr = full_uri.split("?")
const uri = uri_arr[0]
const params = "?" + uri_arr[1]

const options = {};

let client;
let clientPromise: Promise<MongoClient>;

if (process.env.NODE_ENV === "development") {
// let NexusMongoClient = Object.assign({}, new MongoClient(uri, options))
// Object.setPrototypeOf(NexusMongoClient, {})
//NexusMongoClient.prototype = MongoClient.prototype

//MongoClient.prototype = NexusMongoClient.prototype


// NexusMongoClient.loadDB = async (db) => {
// console.log(`---- db:init:reconnect:load:${db} ----`)
// const _options = {
// ..._options,
// authSource: db
// }
// _client = new this.contructor(uri, _options)
// return await _client.connect()
// }

// class MyProtoype {
// constructor() {
// console.log(" body as constructor ")
// }
// }

//MyProtoype.prototype.constructor = function contructor() { console.log("whatever") }

// function MyAugProto(init) {
// console.log("2", init, this)
// }

// MyProtoype.prototype.myMethod = () => "whatever"

// MyAugProto.prototype = MyProtoype.prototype

//MyAugProto.constructor = (init) => { console.log("2", init) }


//MyProtoype = function MyProtoype(init) { console.log("1", init) }
// //MyProtoype.prototype
// //MyProtoype.prototype.constructor = (init) => { console.log("2", init) }

//new MyAugProto("hello")


// const logProto = MyProtoype

//console.log("ORIG CONN", logProto, logProto.myMethod, new logProto.prototype.constructor, logProto.__constructor)
//console.log("CONN DEC", NexusMongoClient.constructor, typeof MongoClient.constructor)


// NexusMongoClient.prototype.constructor = function constructor(uri, options) {
// console.log(`---- db:init:decorate:constucutor ----`)
// // console.log("const this", this)
// // const _MongoClient = MongoClient
// // this.loadDB = async (db) => {
// // console.log(`---- db:init:reconnect:load:${db} ----`)
// // const _options = {
// // ..._options,
// // authSource: db
// // }
// // _client = new MongoClient(uri, _options)
// // return await _client.connect()
// // }

// // return _MongoClient.prototype.__constructor
// }

//new NexusMongoClient()



//console.log({ origCons: JSON.stringify(MongoClient.constructor), decCons: JSON.stringify(NexusMongoClient.constructor)})


// const NexusMongoClient: MongoClient = (uri, options) => {
// console.log(`---- db:init:first-connect:load:${db} ----`)
// let _client = MongoClient;
// _client.connect.loadDB =
// return _client
// }



const genPromise = (name = "") =>
{
const dest = uri + name + params

console.log("! will connect to ", dest)
if (process.env.NODE_ENV === "development") {
// In development mode, use a global variable so that the value
// is preserved across module reloads caused by HMR (Hot Module Replacement).
if (!global._mongoClientPromise) {
client = new MongoClient(uri, options);
client = new MongoClient(dest, options);
// _client = new MongoClient(uri, options);

//console.log("CONN INSTANCE", client, client.loadDB)
// const _promise = await _client.connect();
// _promise.setDb = _client.connect ;

// console.log({ _promise })
global._mongoClientPromise = client.connect();
}
clientPromise = global._mongoClientPromise;
} else {
// In production mode, it's best to not use a global variable.
client = new MongoClient(uri, options);
client = new MongoClient(dest, options);
//console.log("CONN INSTANCE", client, client.loadDB)
console.log("CONN INSTANCE", client)
clientPromise = client.connect();
}

return clientPromise
}

genPromise()

// Export a module-scoped MongoClient promise. By doing this in a
// separate module, the client can be shared across functions.
export const _setDb = async (db) => {
return genPromise(db)
}
export default clientPromise;
6 changes: 4 additions & 2 deletions src/app/api/auth/[...nextauth]/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
// index.ts

import { MongoDBAdapter } from "@next-auth/mongodb-adapter";
import { MongoConnector, DATABASE_STRING } from "@model";
import { MongoConnector, DATABASE_USERS_STRING } from "@model";
import { authOptions } from "@auth";

// For more information on each option (and a full list of options) go to
// https://authjs.dev/reference/providers/oauth

console.log(" FINAL AUTH IS ", DATABASE_USERS_STRING)

const finalAuth = {
adapter: MongoDBAdapter(MongoConnector, {
databaseName: DATABASE_STRING,
databaseName: DATABASE_USERS_STRING,
}),
...authOptions,
};

0 comments on commit 35db20a

Please sign in to comment.