Skip to content

Commit

Permalink
SYNC: main branch
Browse files Browse the repository at this point in the history
  • Loading branch information
chhabra1112 committed Nov 10, 2024
2 parents e24488e + 820cdb6 commit 2b63c97
Show file tree
Hide file tree
Showing 47 changed files with 3,141 additions and 1,402 deletions.
6 changes: 3 additions & 3 deletions lib/cache/service.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import { Injectable, OnModuleInit } from '@nestjs/common';
import { IntentConfig } from '../config/service';
import { logTime } from '../utils/helpers';
import { InternalLogger } from '../utils/logger';
import { InMemoryDriver } from './drivers/inMemory';
import { RedisDriver } from './drivers/redis';
import { CacheDriver, CacheOptions } from './interfaces';
import { ConfigService } from '../config';

@Injectable()
export class CacheService implements OnModuleInit {
static driverMap = { redis: RedisDriver, memory: InMemoryDriver };
public static data: CacheOptions;
static stores: Record<string, CacheDriver>;

constructor(config: IntentConfig) {
CacheService.data = config.get('cache');
constructor(config: ConfigService) {
CacheService.data = config.get('cache') as CacheOptions;
}

onModuleInit() {
Expand Down
34 changes: 22 additions & 12 deletions lib/codegen/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ export class CodegenCommand {
_cli.success(`Successfully created ${filePath}`);
} catch (e) {
_cli.error(e['message']);
return;
}

process.exit();
}

@Command('make:controller {name}', { desc: 'Command to create a controller' })
Expand All @@ -50,8 +51,9 @@ export class CodegenCommand {
_cli.success(`Successfully created ${filePath}`);
} catch (e) {
_cli.error(e['message']);
return;
}

process.exit();
}

@Command('make:service {name}', { desc: 'Command to create a service' })
Expand All @@ -67,8 +69,9 @@ export class CodegenCommand {
_cli.success(`Successfully created ${filePath}`);
} catch (e) {
_cli.error(e['message']);
return;
}

process.exit();
}

@Command('make:job {name}', { desc: 'Command to create a job' })
Expand All @@ -90,8 +93,8 @@ export class CodegenCommand {
} catch (e) {
console.log(e);
_cli.error(e['message']);
return;
}
process.exit();
}

@Command('make:model {name}', { desc: 'Command to create a model' })
Expand All @@ -111,8 +114,8 @@ export class CodegenCommand {
_cli.success(`Successfully created ${filePath}`);
} catch (e) {
_cli.error(e['message']);
return;
}
process.exit();
}

@Command('make:repo {repoName} {modelFileName} {--without-interface}', {
Expand Down Expand Up @@ -147,8 +150,9 @@ export class CodegenCommand {
_cli.success(`Successfully created ${filePath}`);
} catch (e) {
_cli.error(e['message']);
return;
}

process.exit();
}

@Command('make:exception {name}', {
Expand All @@ -166,8 +170,9 @@ export class CodegenCommand {
_cli.success(`Successfully created ${filePath}`);
} catch (e) {
_cli.error(e['message']);
return;
}

process.exit();
}

@Command('make:resource {name}', { desc: 'Command to create a service' })
Expand All @@ -183,8 +188,9 @@ export class CodegenCommand {
await CommandRunner.run(`make:service ${name}`, { silent: true });
} catch (e) {
_cli.error(e['message']);
return;
}

process.exit();
}

@Command('make:event {name}', {
Expand All @@ -206,8 +212,9 @@ export class CodegenCommand {
_cli.success(`Successfully created ${filePath}`);
} catch (e) {
_cli.error(e['message']);
return;
}

process.exit();
}

@Command(
Expand All @@ -232,8 +239,9 @@ export class CodegenCommand {
_cli.success(`Successfully created ${filePath}`);
} catch (e) {
_cli.error(e['message']);
return;
}

process.exit();
}

@Command(
Expand All @@ -256,8 +264,9 @@ export class CodegenCommand {
_cli.success(`Successfully created ${filePath}`);
} catch (e) {
_cli.error(e['message']);
return;
}

process.exit();
}

@Command('make:mail {name}', {
Expand All @@ -278,7 +287,8 @@ export class CodegenCommand {
_cli.success(`Successfully created ${filePath}`);
} catch (e) {
_cli.error(e['message']);
return;
}

process.exit();
}
}
26 changes: 26 additions & 0 deletions lib/config/builder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {
NamespacedConfigMapKeys,
NamespacedConfigMapValues,
RegisterNamespaceReturnType,
} from './options';

export class ConfigBuilder {
static async build(
namespaceObjects: RegisterNamespaceReturnType<string, any>[],
): Promise<Map<string, any>> {
const configMap = new Map();

for (const namespacedConfig of namespaceObjects) {
const namespacedMap = new Map<
NamespacedConfigMapKeys,
NamespacedConfigMapValues
>();
namespacedMap.set('factory', namespacedConfig._.factory);
namespacedMap.set('static', await namespacedConfig._.factory());
namespacedMap.set('encrypt', namespacedConfig._.options.encrypt);
configMap.set(namespacedConfig._.namespace, namespacedMap);
}

return configMap;
}
}
49 changes: 25 additions & 24 deletions lib/config/command.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
import { Injectable } from '@nestjs/common';
import pc from 'picocolors';
import { Command, ConsoleIO } from '../console';
import { Obj } from '../utils';
import { Arr } from '../utils/array';
import { columnify } from '../utils/columnify';
import { IntentConfig } from './service';
import { ConfigMap } from './options';
import { CONFIG_FACTORY } from './constant';
import pc from 'picocolors';
import archy from 'archy';
import { Inject } from '../foundation';
import { jsonToArchy } from '../utils/console-helpers';

@Injectable()
@Command('config:view {--ns : Namespace of a particular config}', {
desc: 'Command to view config for a given namespace',
})
export class ViewConfigCommand {
constructor(private config: IntentConfig) {}
constructor(@Inject(CONFIG_FACTORY) private config: ConfigMap) {}

@Command('config:view {namespace}', {
desc: 'Command to view config for a given namespace',
})
async handle(_cli: ConsoleIO): Promise<void> {
const namespace = _cli.argument<string>('namespace');
const config = this.config.get(namespace);
if (!config) {
_cli.error(`config with ${namespace} namespace not found`);
const nsFlag = _cli.option<string>('ns');
const printNsToConsole = (namespace, obj) => {
const values = obj.get('static') as Record<string, any>;
console.log(
archy(jsonToArchy(values, pc.bgGreen(pc.black(` ${namespace} `)))),
);
};

if (nsFlag) {
const ns = this.config.get(nsFlag);
printNsToConsole(nsFlag, ns);
return;
}
const columnifiedConfig = columnify(
Arr.toObj(Obj.entries(config), ['key', 'value']),
);
const printRows = [];
for (const row of columnifiedConfig) {
printRows.push([pc.green(row[0]), pc.yellow(row[1])].join(' '));
}

// eslint-disable-next-line no-console
console.log(printRows.join('\n'));
// Example usage
for (const [namespace, obj] of this.config.entries()) {
printNsToConsole(namespace, obj);
}
}
}
1 change: 1 addition & 0 deletions lib/config/constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const CONFIG_FACTORY = '@intentjs/config_factory';
6 changes: 6 additions & 0 deletions lib/config/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export * from './builder';
export * from './register-namespace';
export * from './options';
export * from './service';
export * from './command';
export * from './constant';
36 changes: 36 additions & 0 deletions lib/config/options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export type RegisterNamespaceOptions = {
encrypt?: boolean;
};

export type BuildConfigFromNS<
T extends RegisterNamespaceReturnType<any, any>[],
> = {
[N in T[number]['_']['namespace']]: Extract<
T[number],
{ _: { namespace: N } }
>['$inferConfig'];
};

export type RegisterNamespaceReturnType<
N extends string,
T extends Record<string, any>,
> = {
_: {
namespace: N;
options: RegisterNamespaceOptions;
factory: () => T | Promise<T>;
};
$inferConfig: T;
};

export type NamespacedConfigMapKeys = 'factory' | 'static' | 'encrypt';

export type NamespacedConfigMapValues =
// eslint-disable-next-line @typescript-eslint/ban-types
Function | object | boolean | string | number;

export type NamespacedConfigMap = Map<
NamespacedConfigMapKeys,
NamespacedConfigMapValues
>;
export type ConfigMap = Map<string, NamespacedConfigMap>;
25 changes: 25 additions & 0 deletions lib/config/register-namespace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { LiteralString } from '../type-helpers';
import {
RegisterNamespaceOptions,
RegisterNamespaceReturnType,
} from './options';

// eslint-disable-next-line @typescript-eslint/no-var-requires
require('dotenv').config();

export const registerNamespace = <N extends string, T>(
namespace: LiteralString<N>,
factory: () => T | Promise<T>,
options?: RegisterNamespaceOptions,
): RegisterNamespaceReturnType<LiteralString<N>, T> => {
return {
_: {
namespace,
options: {
encrypt: options?.encrypt ?? false,
},
factory,
},
$inferConfig: {} as T,
};
};
61 changes: 42 additions & 19 deletions lib/config/service.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,51 @@
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Inject, Injectable } from '../foundation';
import { DotNotation, GetNestedPropertyType } from '../type-helpers';
import { Obj } from '../utils';
import { CONFIG_FACTORY } from './constant';
import { ConfigMap, NamespacedConfigMapValues } from './options';

type ConfigPaths<T> = DotNotation<T>;

@Injectable()
export class IntentConfig {
private static cachedConfig: Map<string, any>;
private static config: ConfigService;
export class ConfigService<G = undefined> {
private static cachedConfig = new Map<string, any>();
private static config: ConfigMap;

constructor(private config: ConfigService) {
IntentConfig.cachedConfig = new Map<string, any>();
IntentConfig.config = config;
constructor(@Inject(CONFIG_FACTORY) private config: ConfigMap) {
ConfigService.cachedConfig = new Map<ConfigPaths<G>, any>();
ConfigService.config = this.config;
}

get<T = any>(key: string): T {
if (IntentConfig.cachedConfig.has(key))
return IntentConfig.cachedConfig.get(key);
const value = this.config.get<T>(key);
IntentConfig.cachedConfig.set(key, value);
return value;
get<P extends string = ConfigPaths<G>, F = any>(
key: P,
): GetNestedPropertyType<G, P, F> | Promise<GetNestedPropertyType<G, P, F>> {
return ConfigService.get<G, P>(key);
}

static get<T = any>(key: string): T {
if (this.cachedConfig.has(key)) return this.cachedConfig.get(key);
const value = this.config.get<T>(key);
this.cachedConfig.set(key, value);
return value;
static get<C = undefined, P extends string = ConfigPaths<C>, F = any>(
key: P,
): GetNestedPropertyType<C, P, F> | Promise<GetNestedPropertyType<C, P, F>> {
const cachedValue = ConfigService.cachedConfig.get(key);
if (cachedValue) return cachedValue;

const [namespace, ...paths] = (key as string).split('.');
const nsConfig = this.config.get(namespace);
/**
* Returns a null value if the namespace doesn't exist.
*/
if (!nsConfig) return null;

if (!paths.length) return nsConfig.get('static') as any;

const staticValues = nsConfig.get('static') as Omit<
NamespacedConfigMapValues,
'function'
>;

const valueOnPath = Obj.get<any>(staticValues, paths.join('.'));
if (valueOnPath) {
this.cachedConfig.set(key as string, valueOnPath);
}
return valueOnPath;
}
}
Loading

0 comments on commit 2b63c97

Please sign in to comment.