Skip to content

Commit

Permalink
feat: basic setup
Browse files Browse the repository at this point in the history
  • Loading branch information
chavda-bhavik committed Sep 23, 2022
1 parent b403503 commit 05cf126
Show file tree
Hide file tree
Showing 31 changed files with 3,978 additions and 0 deletions.
28 changes: 28 additions & 0 deletions .commitlintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"extends": ["@commitlint/config-conventional"],
"rules": {
"subject-case": [
2,
"always",
["sentence-case", "start-case", "pascal-case", "upper-case", "lower-case"]
],
"type-enum": [
2,
"always",
[
"build",
"chore",
"ci",
"docs",
"feat",
"fix",
"perf",
"refactor",
"revert",
"style",
"test",
"sample"
]
]
}
}
11 changes: 11 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
12 changes: 12 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules

# OSX
.DS_Store
94 changes: 94 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
module.exports = {
root: true,
extends: [
'airbnb-typescript',
'plugin:import/typescript',
'plugin:@typescript-eslint/recommended',
'prettier',
'plugin:prettier/recommended',
'plugin:promise/recommended',
],
ignorePatterns: ['.eslintrc.js', '*.json', 'jest.config.js'],
plugins: ['import', 'promise', '@typescript-eslint', 'prettier'],
parser: '@typescript-eslint/parser',
settings: {
'import/parsers': {
'@typescript-eslint/parser': ['.ts', '.tsx'],
},
},
parserOptions: {
project: './tsconfig.json',
ecmaVersion: 2020,
sourceType: 'module',
},
rules: {
'@typescript-eslint/space-before-blocks': 'off',
'@typescript-eslint/lines-between-class-members': 'off',
'react/jsx-wrap-multilines': 'off',
'react/jsx-filename-extension': 'off',
'multiline-comment-style': ['error', 'starred-block'],
'promise/catch-or-return': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-unused-expressions': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'react/jsx-closing-bracket-location': 'off',
'@typescript-eslint/no-var-requires': 'off',
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': ['off'],
'mocha/no-mocha-arrows': 'off',
'@typescript-eslint/default-param-last': 'off',
'no-return-await': 'off',
'no-await-in-loop': 'off',
'no-continue': 'off',
'no-console': 'warn',
'no-prototype-builtins': 'off',
'import/no-cycle': 'off',
'class-methods-use-this': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/no-explicit-any': 1,
'no-restricted-syntax': 'off',
'@typescript-eslint/interface-name-prefix': 'off',
'no-underscore-dangle': 'off',
'import/prefer-default-export': 'off',
// A temporary hack related to IDE not resolving correct package.json
'import/no-extraneous-dependencies': 'off',
'react/jsx-one-expression-per-line': 'off',
'react/jsx-no-bind': 'off',
'lines-between-class-members': 'off',
'max-classes-per-file': 'off',
'react/react-in-jsx-scope': 'off',
'max-len': ['warn', { code: 140 }],
'@typescript-eslint/return-await': 'off',
'no-restricted-imports': [
'error',
{
patterns: ['@novu/shared/*', '@novu/dal/*', '!import2/good'],
},
],
'padding-line-between-statements': [
'error',
{ blankLine: 'any', prev: ['const', 'let', 'var'], next: ['if', 'for'] },
{ blankLine: 'any', prev: ['const', 'let', 'var'], next: ['const', 'let', 'var'] },
{ blankLine: 'always', prev: '*', next: 'return' },
],
'id-length': ['error', { min: 2, exceptions: ['i', 'e', 'a', 'b', '_', 't'], properties: 'never' }],
'@typescript-eslint/naming-convention': [
'error',

{ selector: 'enumMember', format: ['UPPER_CASE'] },
{ selector: 'enum', format: ['PascalCase'], suffix: ['Enum'] },
{ selector: 'class', format: ['PascalCase'] },
{ selector: 'variableLike', format: ['camelCase', 'UPPER_CASE', 'PascalCase'], leadingUnderscore: 'allow' },
{
selector: 'interface',
format: ['PascalCase'],
prefix: ['I'],
},
{
selector: ['function'],
format: ['camelCase'],
leadingUnderscore: 'allow',
},
],
},
};
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
dist
build

.env
4 changes: 4 additions & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx --no -- commitlint --edit "$1"
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

pnpm lint-staged
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
auto-install-peers=true
strict-peer-dependencies=false
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# package.json is formatted by package managers, so we ignore it here
package.json
11 changes: 11 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"printWidth": 120,
"trailingComma": "es5",
"singleQuote": true,
"semi": true,
"tabWidth": 2,
"quoteProps": "as-needed",
"jsxSingleQuote": false,
"arrowParens": "always",
"endOfLine": "lf"
}
11 changes: 11 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"npm.packageManager": "pnpm",
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"editor.formatOnSave": true,
"eslint.format.enable": true,
"editor.codeActionsOnSave": {
"source.fixAll": true
},
}

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# impler.io
8 changes: 8 additions & 0 deletions apps/api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "api",
"version": "1.0.0",
"main": "index.js",
"author": "knovator",
"license": "MIT",
"private": false
}
3 changes: 3 additions & 0 deletions libs/dal/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
extends: ['../../.eslintrc.js'],
};
32 changes: 32 additions & 0 deletions libs/dal/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@impler/dal",
"version": "1.0.0",
"description": "",
"private": true,
"scripts": {
"start": "npm run start:dev",
"afterinstall": "pnpm build",
"prebuild": "rimraf dist",
"build": "cross-env node_modules/.bin/tsc -p tsconfig.build.json",
"build:watch": "cross-env node_modules/.bin/tsc -p tsconfig.build.json -w --preserveWatchOutput",
"lint": "eslint src",
"lint:fix": "eslint src --fix",
"test": ""
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"class-transformer": "^0.5.1",
"mongoose": "^6.6.1",
"rimraf": "^3.0.2"
},
"devDependencies": {
"@types/node": "^18.7.18",
"eslint-plugin-prettier": "^4.2.1",
"nodemon": "^2.0.20",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.1.0",
"typescript": "^4.8.3"
}
}
28 changes: 28 additions & 0 deletions libs/dal/src/dal.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Connection, ConnectOptions } from 'mongoose';
import * as mongoose from 'mongoose';

export class DalService {
connection: Connection;

async connect(url: string, config: ConnectOptions = {}) {
const instance = await mongoose.connect(url, config);

this.connection = instance.connection;

return this.connection;
}

isConnected(): boolean {
return this.connection && this.connection.readyState === 1;
}

async disconnect() {
await mongoose.disconnect();
}

async destroy() {
if (process.env.NODE_ENV !== 'test') throw new Error('Allowed only in test mode');

await mongoose.connection.dropDatabase();
}
}
2 changes: 2 additions & 0 deletions libs/dal/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './dal.service';
export * from './repositories/project';
115 changes: 115 additions & 0 deletions libs/dal/src/repositories/base-repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ClassConstructor, plainToClass } from 'class-transformer';
import { Document, FilterQuery, Model, Types } from 'mongoose';

export class BaseRepository<T> {
public _model: Model<any & Document>;

constructor(protected MongooseModel: Model<any & Document>, protected entity: ClassConstructor<T>) {
this._model = MongooseModel;
}

public static createObjectId() {
return new Types.ObjectId().toString();
}

async count(query: FilterQuery<T & Document>): Promise<number> {
return await this.MongooseModel.countDocuments(query);
}

async aggregate(query: any[]): Promise<any> {
return await this.MongooseModel.aggregate(query);
}

async findById(id: string, select?: string): Promise<T | null> {
const data = await this.MongooseModel.findById(id, select);
if (!data) return null;

return this.mapEntity(data.toObject());
}

async findOne(query: FilterQuery<T & Document>, select?: string) {
const data = await this.MongooseModel.findOne(query, select);
if (!data) return null;

return this.mapEntity(data.toObject());
}

async delete(query: FilterQuery<T & Document>) {
const data = await this.MongooseModel.remove(query);

return data;
}

async find(
query: FilterQuery<T & Document>,
select = '',
options: { limit?: number; sort?: any; skip?: number } = {}
): Promise<T[]> {
const data = await this.MongooseModel.find(query, select, {
sort: options.sort || null,
})
.skip(options.skip)
.limit(options.limit)
.lean()
.exec();

return this.mapEntities(data);
}

async *findBatch(
query: FilterQuery<T & Document>,
select = '',
options: { limit?: number; sort?: any; skip?: number } = {},
batchSize = 500
) {
for await (const doc of this._model
.find(query, select, {
sort: options.sort || null,
})
.batchSize(batchSize)
.cursor()) {
yield this.mapEntities(doc);
}
}

async create(data: Partial<T>): Promise<T> {
const newEntity = new this.MongooseModel(data);
const saved = await newEntity.save();

return this.mapEntity(saved);
}

async createMany(data: T[]) {
await new Promise((resolve) => {
this.MongooseModel.collection.insertMany(data, (err, response) => {
resolve(response);
});
});
}

async update(
query: FilterQuery<T & Document>,
updateBody: any
): Promise<{
matched: number;
modified: number;
}> {
const saved = await this.MongooseModel.updateMany(query, updateBody, {
multi: true,
});

return {
matched: saved.matchedCount,
modified: saved.modifiedCount,
};
}

protected mapEntity(data: any): T {
return plainToClass<T, T>(this.entity, JSON.parse(JSON.stringify(data))) as any;
}

protected mapEntities(data: any): T[] {
return plainToClass<T, T[]>(this.entity, JSON.parse(JSON.stringify(data)));
}
}
3 changes: 3 additions & 0 deletions libs/dal/src/repositories/project/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './project.entity';
export * from './project.repository';
export * from './project.schema';
Loading

0 comments on commit 05cf126

Please sign in to comment.