Skip to content
Snippets Groups Projects
Verified Commit 68aacbbb authored by Konstantin Tsabolov's avatar Konstantin Tsabolov
Browse files

chore(devtools): get rid of devtools

parent 5cf50d0a
No related branches found
No related tags found
1 merge request!47Tenant manager
Showing
with 1 addition and 398 deletions
......@@ -11,7 +11,6 @@
# ... in these directories
!apps/**/src/*
!devtools/**/src/*
# Explicitly ignore these locations
node_modules
......
......@@ -20,7 +20,7 @@ module.exports = {
},
'import/resolver': {
typescript: {
project: ['apps/*/tsconfig.json', 'devtools/tsconfig.json'],
project: ['apps/*/tsconfig.json'],
alwaysTryTypes: true,
},
},
......@@ -88,12 +88,6 @@ module.exports = {
},
],
},
},
{
files: ['devtools/**/*.ts'],
rules: {
'no-console': 'off',
}
}
],
};
......@@ -12,7 +12,6 @@
# ... in these ones
!apps/**/src/*
!devtools/**/src/*
# Explicitly ignore these locations
node_modules
......
......@@ -14,7 +14,6 @@ FROM base AS dependencies
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml tsconfig*.json .swcrc ./
COPY patches ./patches
COPY apps/shared/package.json ./apps/shared/
COPY devtools/package.json ./devtools/
RUN pnpm install --frozen-lockfile
# Build shared
......@@ -27,33 +26,6 @@ COPY --from=dependencies ${APP_HOME}/apps/shared/node_modules ./apps/shared/node
COPY --from=dependencies ${APP_HOME}/patches ./patches
RUN pnpm --filter shared build
# Build DevTools
FROM base AS build-devtools
COPY --from=dependencies ${APP_HOME}/package.json ${APP_HOME}/pnpm-lock.yaml ${APP_HOME}/pnpm-workspace.yaml ${APP_HOME}/tsconfig*.json ${APP_HOME}/.swcrc ./
COPY --from=dependencies ${APP_HOME}/node_modules ./node_modules
COPY --from=dependencies ${APP_HOME}/devtools/node_modules ./devtools/node_modules
COPY --from=dependencies ${APP_HOME}/patches ./patches
COPY --from=build-shared ${APP_HOME}/apps/shared ./apps/shared
COPY devtools ./devtools
RUN pnpm --filter devtools build && pnpm --filter devtools --prod deploy build
# Final devtools
FROM node:20-slim AS devtools
ARG APP_HOME=/home/node/app
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
WORKDIR ${APP_HOME}
CMD ["node", "dist/server.js"]
COPY --from=build-devtools --chown=node:node ${APP_HOME}/build/dist ./dist
COPY --from=build-devtools --chown=node:node ${APP_HOME}/build/node_modules ./node_modules
COPY --from=build-devtools --chown=node:node ${APP_HOME}/build/package.json .
USER node
# Build service
FROM base AS build-service
......
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src"
}
{
"name": "@ocm/devtools",
"version": "1.0.0",
"description": "Developers tools for OCM",
"contributors": [
"Konstantin Tsabolov <konstantin.tsabolov@spherity.com>"
],
"private": true,
"license": "Apache-2.0",
"type": "module",
"scripts": {
"exec": "nest start --entryFile=cli.js --",
"start": "nest start --entryFile=server.js",
"clean": "rimraf dist *.tsbuildinfo",
"prebuild": "pnpm clean",
"build": "nest build -p tsconfig.production.json"
},
"dependencies": {
"@nestjs/cli": "10.3.2",
"@nestjs/common": "10.3.3",
"@nestjs/config": "3.2.0",
"@nestjs/core": "10.3.3",
"@nestjs/microservices": "10.3.3",
"@ocm/shared": "workspace:*",
"joi": "17.12.1",
"nest-commander": "3.12.5",
"reflect-metadata": "0.2.1",
"rxjs": "7.8.1",
"vite-node": "1.3.1"
},
"devDependencies": {
"rimraf": "5.0.5",
"vite-node": "1.3.1"
}
}
import { CommandFactory } from 'nest-commander';
import { Commander } from './commander.js';
await CommandFactory.run(Commander, ['warn', 'error']);
import { Body, Controller, Get, Post } from '@nestjs/common';
import { CommanderService } from './commander.service.js';
@Controller()
export class CommanderController {
public constructor(private readonly service: CommanderService) {}
@Get('list-tenants')
public listTenants() {
return this.service.listTenants();
}
@Post('create-tenant')
public createTenant(@Body() { label }: { label?: string }) {
return this.service.createTenant(label);
}
@Post('register-endorser-did')
public registerEndorserDID() {
return this.service.registerEndorserDID();
}
@Post('register-did')
public registerDID(
@Body() { tenantId, seed }: { tenantId: string; seed?: string },
) {
return this.service.registerDID(tenantId, seed);
}
@Post('resolve-did')
public resolveDID(
@Body() { tenantId, did }: { tenantId: string; did: string },
) {
return this.service.resolveDID(tenantId, did);
}
@Post('policy/*/*/*/*/evaluation')
public mockPolicyEvaluation() {
return { result: true };
}
}
import { Inject, Injectable } from '@nestjs/common';
import { ClientProxy } from '@nestjs/microservices';
import {
EventDidsRegisterEndorserDid,
EventDidsRegisterIndyFromSeed,
EventDidsResolve,
EventTenantsCreate,
EventTenantsGetAllTenantIds,
} from '@ocm/shared';
import { randomBytes } from 'node:crypto';
import { map } from 'rxjs';
import { NATS_CLIENT_NAME } from './constants.js';
import { requestTimeout } from './utils.js';
@Injectable()
export class CommanderService {
public constructor(
@Inject(NATS_CLIENT_NAME) private readonly client: ClientProxy,
) {}
public listTenants() {
return this.client.send(EventTenantsGetAllTenantIds.token, {}).pipe(
requestTimeout,
map(({ data }) => data),
);
}
public createTenant(label = 'tenant_' + randomBytes(4).toString('hex')) {
return this.client.send(EventTenantsCreate.token, { label }).pipe(
requestTimeout,
map(({ data }) => data),
);
}
public registerEndorserDID() {
return this.client.send(EventDidsRegisterEndorserDid.token, {}).pipe(
requestTimeout,
map(({ data }) => data),
);
}
public resolveDID(tenantId: string, did: string) {
return this.client.send(EventDidsResolve.token, { tenantId, did }).pipe(
requestTimeout,
map(({ data }) => data),
);
}
public registerDID(
tenantId: string,
seed: string = randomBytes(16).toString('hex'),
) {
return this.client
.send(EventDidsRegisterIndyFromSeed.token, {
tenantId,
seed,
})
.pipe(
requestTimeout,
map(({ data }) => data),
);
}
}
import type { ConfigType } from '@nestjs/config';
import { Module } from '@nestjs/common';
import { ConfigModule, registerAs } from '@nestjs/config';
import { ClientsModule, Transport } from '@nestjs/microservices';
import Joi from 'joi';
import { CommanderController } from './commander.controller.js';
import { CommanderService } from './commander.service.js';
import { CreateTenantCommand } from './commands/create-tenant.command.js';
import { ListTenantsCommand } from './commands/list-tenants.command.js';
import { RegisterDIDCommand } from './commands/register-did.command.js';
import { RegisterEndorserDIDCommand } from './commands/register-endorser-did.command.js';
import { ResolveDIDCommand } from './commands/resolve-did.command.js';
import { NATS_CLIENT_NAME } from './constants.js';
export const httpConfig = registerAs('http', () => ({
port: Number(process.env.HTTP_PORT) || 4100,
}));
export const natsConfig = registerAs('nats', () => ({
url: process.env.NATS_URL || 'nats://localhost:4222',
user: process.env.NATS_USER || 'nats_user',
pass: process.env.NATS_PASSWORD || 'nats_password',
}));
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [httpConfig, natsConfig],
validationSchema: Joi.object({
HTTP_PORT: Joi.number(),
NATS_URL: Joi.string(),
NATS_USER: Joi.string(),
NATS_PASSWORD: Joi.string(),
}),
}),
ClientsModule.registerAsync([
{
name: NATS_CLIENT_NAME,
inject: [natsConfig.KEY],
useFactory: ({ url, user, pass }: ConfigType<typeof natsConfig>) => ({
transport: Transport.NATS,
options: { servers: [url], user, pass },
}),
},
]),
],
providers: [
CommanderService,
ListTenantsCommand,
CreateTenantCommand,
RegisterDIDCommand,
RegisterEndorserDIDCommand,
ResolveDIDCommand,
],
controllers: [CommanderController],
})
export class Commander {}
import { Command, CommandRunner } from 'nest-commander';
import { firstValueFrom, tap } from 'rxjs';
import { CommanderService } from '../commander.service.js';
@Command({
name: 'create-tenant',
description: 'Create a new tenant',
arguments: '[label]',
})
export class CreateTenantCommand extends CommandRunner {
public constructor(private readonly service: CommanderService) {
super();
}
public async run([label]: string[]) {
await firstValueFrom(
this.service.createTenant(label).pipe(
tap((data) => {
console.log(`Tenant "${label}" created with id: ${data.id}`);
}),
),
);
}
}
import { Command, CommandRunner } from 'nest-commander';
import { firstValueFrom, tap } from 'rxjs';
import { CommanderService } from '../commander.service.js';
@Command({
name: 'list-tenants',
description: 'List all tenants',
})
export class ListTenantsCommand extends CommandRunner {
public constructor(private readonly service: CommanderService) {
super();
}
public async run(): Promise<void> {
await firstValueFrom(this.service.listTenants().pipe(tap(console.log)));
}
}
import { Command, CommandRunner } from 'nest-commander';
import { firstValueFrom, tap } from 'rxjs';
import { CommanderService } from '../commander.service.js';
@Command({
name: 'register-did',
description: 'Register a new DID for a tenant',
arguments: '<tenantId> [seed]',
})
export class RegisterDIDCommand extends CommandRunner {
public constructor(private readonly service: CommanderService) {
super();
}
public async run([tenantId, seed]: string[]): Promise<void> {
await firstValueFrom(
this.service.registerDID(tenantId, seed).pipe(
tap((data) => {
console.log(`Registered DID "${data[0]}" for tenant "${tenantId}"`);
}),
),
);
}
}
import { Command, CommandRunner } from 'nest-commander';
import { firstValueFrom, tap } from 'rxjs';
import { CommanderService } from '../commander.service.js';
@Command({
name: 'register-endorser-did',
description: 'Register an endorser DID',
})
export class RegisterEndorserDIDCommand extends CommandRunner {
public constructor(private readonly service: CommanderService) {
super();
}
public async run(): Promise<void> {
await firstValueFrom(
this.service.registerEndorserDID().pipe(
tap(() => {
console.log(`Successfully registered an endorser DID`);
}),
),
);
}
}
import { Command, CommandRunner } from 'nest-commander';
import { firstValueFrom, tap } from 'rxjs';
import { CommanderService } from '../commander.service.js';
@Command({
name: 'resolve-did',
arguments: '<tenantId> <did>',
})
export class ResolveDIDCommand extends CommandRunner {
public constructor(private readonly service: CommanderService) {
super();
}
public async run([tenantId, did]: string[]): Promise<void> {
await firstValueFrom(
this.service.resolveDID(tenantId, did).pipe(
tap((data) => {
console.log(JSON.stringify(data, null, 2));
}),
),
);
}
}
export const NATS_CLIENT_NAME = 'DEVTOOLS';
export const REQUEST_TIMEOUT_MS = 10000;
import type { ConfigType } from '@nestjs/config';
import { NestFactory } from '@nestjs/core';
import { Commander, httpConfig } from './commander.js';
const app = await NestFactory.create(Commander);
const { port } = app.get(httpConfig.KEY) as ConfigType<typeof httpConfig>;
await app.listen(port);
import { timeout, throwError } from 'rxjs';
import { REQUEST_TIMEOUT_MS } from './constants.js';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const requestTimeout = timeout<any, any>({
each: REQUEST_TIMEOUT_MS,
with: () => throwError(() => new Error('Request timed out')),
});
{
"extends": "../tsconfig.build.json",
"compilerOptions": {
"baseUrl": ".",
"outDir": "./dist",
"rootDir": "./src"
},
"exclude": ["node_modules", "**/test", "**/dist", "**/*spec.ts"]
}
{
"extends": "../tsconfig.json",
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment