@solidxai/solidctl 0.1.23-beta.0 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,81 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { CommandFactory } from "nest-commander";
|
|
6
|
-
import { resolve } from "path";
|
|
7
|
-
import { AppModule } from "./app.module";
|
|
8
|
-
import { configurePgInt8TypeParser } from "./database.utils";
|
|
9
|
-
import "./suppress-warnings";
|
|
3
|
+
import { bootstrapSolidCli } from '@solidxai/core';
|
|
4
|
+
import { AppModule } from './app.module';
|
|
10
5
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// ---- Global safety nets (must be first) ----
|
|
14
|
-
process.on('unhandledRejection', (reason, promise) => {
|
|
15
|
-
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
16
|
-
});
|
|
17
|
-
process.on('uncaughtException', (err) => {
|
|
18
|
-
console.error('Uncaught Exception:', err);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
// Suppress pg deprecation warning caused by TypeORM's internal query scheduling
|
|
22
|
-
process.on('warning', (warning) => {
|
|
23
|
-
if (warning.name === 'DeprecationWarning' && warning.message.includes('client.query()')) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
console.warn(warning);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
async function bootstrap() {
|
|
30
|
-
// setup log levels...
|
|
31
|
-
const showLogs = process.argv.includes('--verbose') || process.argv.includes('-v');
|
|
32
|
-
// strip before nest-commander runs...
|
|
33
|
-
stripArg('--verbose');
|
|
34
|
-
stripArg('-v');
|
|
35
|
-
|
|
36
|
-
// validate project existence
|
|
37
|
-
validateProjectRootPath();
|
|
38
|
-
|
|
39
|
-
// Define log levels based on the flag
|
|
40
|
-
const logLevels = showLogs ? ['debug', 'error', 'fatal', 'log', 'verbose', 'warn'] : ['error', 'fatal'];
|
|
41
|
-
|
|
42
|
-
const appModule = await AppModule.forRoot();
|
|
43
|
-
// const app = await NestFactory.create(appModule);
|
|
44
|
-
|
|
45
|
-
// Create an instance of the application, capture the application context so we can inject it into a service in itself.
|
|
46
|
-
// @ts-ignore
|
|
47
|
-
const app = await CommandFactory.createWithoutRunning(appModule, logLevels);
|
|
48
|
-
// const app = await CommandFactory.createWithoutRunning(AppModule, ['debug', 'error', 'fatal', 'log', 'verbose', 'warn']);
|
|
49
|
-
// const app = await CommandFactory.createWithoutRunning(AppModule, ['error', 'fatal']);
|
|
50
|
-
|
|
51
|
-
// Configure pg type parser before running the app
|
|
52
|
-
configurePgInt8TypeParser();
|
|
53
|
-
|
|
54
|
-
// Now run the command factory.
|
|
55
|
-
try {
|
|
56
|
-
await CommandFactory.runApplication(app);
|
|
57
|
-
}
|
|
58
|
-
catch (e) {
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Exit explicitly, make sure that any commands you have created and are using Promises, you do not keep them orphan/dangling.
|
|
63
|
-
process.exit(0);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
bootstrap();
|
|
67
|
-
|
|
68
|
-
// Check if the current directory is a valid Solid API project
|
|
69
|
-
function validateProjectRootPath() {
|
|
70
|
-
const packageJsonPath = resolve(process.cwd(), "package.json");
|
|
71
|
-
if (!existsSync(packageJsonPath)) {
|
|
72
|
-
logger.log("Does not seem to be a valid solid-api project.");
|
|
73
|
-
process.exit(1);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Utility function to strip a specific argument from process.argv
|
|
78
|
-
function stripArg(flag: string) {
|
|
79
|
-
const idx = process.argv.indexOf(flag);
|
|
80
|
-
if (idx !== -1) process.argv.splice(idx, 1);
|
|
81
|
-
}
|
|
6
|
+
bootstrapSolidCli(() => AppModule.forRoot());
|
|
@@ -1,130 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
// import { AppModule } from './app.module';
|
|
3
|
-
|
|
4
|
-
// async function bootstrap() {
|
|
5
|
-
// const app = await NestFactory.create(AppModule);
|
|
6
|
-
// await app.listen(3000);
|
|
7
|
-
// }
|
|
8
|
-
// bootstrap();
|
|
9
|
-
import { ValidationPipe } from '@nestjs/common';
|
|
10
|
-
import { NestFactory } from '@nestjs/core';
|
|
11
|
-
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
12
|
-
import { buildDefaultCorsOptions, buildDefaultSecurityHeaderOptions, buildPermissionsPolicyHeader, WrapResponseInterceptor } from '@solidxai/core';
|
|
13
|
-
import { NextFunction, Request, Response } from 'express';
|
|
14
|
-
import helmet from 'helmet';
|
|
15
|
-
import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
|
|
1
|
+
import { bootstrapSolidApp } from '@solidxai/core';
|
|
16
2
|
import { AppModule } from './app.module';
|
|
17
|
-
import { configurePgInt8TypeParser } from './database.utils';
|
|
18
|
-
import './suppress-warnings';
|
|
19
|
-
|
|
20
|
-
import qs from 'qs';
|
|
21
|
-
|
|
22
|
-
// ---- Global safety nets (must be first) ----
|
|
23
|
-
process.on('unhandledRejection', (reason, promise) => {
|
|
24
|
-
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
25
|
-
});
|
|
26
|
-
process.on('uncaughtException', (err) => {
|
|
27
|
-
console.error('Uncaught Exception:', err);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
// Suppress pg deprecation warning caused by TypeORM's internal query scheduling
|
|
31
|
-
process.on('warning', (warning) => {
|
|
32
|
-
if (warning.name === 'DeprecationWarning' && warning.message.includes('client.query()')) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
console.warn(warning);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
async function bootstrap() {
|
|
39
|
-
const appModule = await AppModule.forRoot();
|
|
40
|
-
const app = await NestFactory.create(appModule);
|
|
41
|
-
|
|
42
|
-
// Add a simple health check endpoint at the root path
|
|
43
|
-
const server = app.getHttpAdapter().getInstance();
|
|
44
|
-
server.get("/", (_req, res) => {
|
|
45
|
-
res.status(200).send("SOLID OK");
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// Enable Helmet middleware for security
|
|
49
|
-
app.use(helmet(buildDefaultSecurityHeaderOptions()));
|
|
50
|
-
|
|
51
|
-
// Enable Permission policy header
|
|
52
|
-
app.use((req: Request, _res: Response, next: NextFunction) => {
|
|
53
|
-
_res.setHeader('Permissions-Policy', buildPermissionsPolicyHeader({
|
|
54
|
-
// Example overrides:
|
|
55
|
-
// "autoplay": ['self', 'https://player.example.com'],
|
|
56
|
-
// "camera": 'none',
|
|
57
|
-
}));
|
|
58
|
-
next();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
// setup winston as the default logger.
|
|
62
|
-
app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER));
|
|
63
|
-
|
|
64
|
-
// Making the port dynamic
|
|
65
|
-
const port = process.env.PORT || 3000;
|
|
66
|
-
|
|
67
|
-
app.setGlobalPrefix('api');
|
|
68
|
-
// Middleware to parse deeply nested queries
|
|
69
|
-
app.use((req: Request, _res: Response, next: NextFunction) => {
|
|
70
|
-
if (req.query) {
|
|
71
|
-
req.query = qs.parse(req.url.split('?')[1], {
|
|
72
|
-
allowDots: true, // Allows dot notation ($eq, $or, etc.)
|
|
73
|
-
depth: 20, // Supports deeply nested structures
|
|
74
|
-
arrayLimit: 100, // Prevents indexed arrays from becoming objects
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
next();
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// Apply the ValidationPipe globally in our main.ts file
|
|
81
|
-
app.useGlobalPipes(new ValidationPipe({
|
|
82
|
-
// This attribute makes that the system throws an error if a property non existent on our DTO is sent in the payload.
|
|
83
|
-
// forbidNonWhitelisted: true,
|
|
84
|
-
|
|
85
|
-
// This removes the un-necessary fields in the payload.
|
|
86
|
-
// whitelist: true,
|
|
87
|
-
|
|
88
|
-
// Converts the payload to an actual instance of the DTO type.
|
|
89
|
-
transform: true,
|
|
90
|
-
|
|
91
|
-
transformOptions: {
|
|
92
|
-
enableImplicitConversion: true,
|
|
93
|
-
}
|
|
94
|
-
}));
|
|
95
|
-
|
|
96
|
-
// Setting up Swagger document
|
|
97
|
-
const options = new DocumentBuilder()
|
|
98
|
-
.setTitle('Solid Starters')
|
|
99
|
-
.setDescription('Solid starters starter')
|
|
100
|
-
.setVersion('1.0')
|
|
101
|
-
.setExternalDoc('Postman Collection', '/docs-json')
|
|
102
|
-
.addBearerAuth(
|
|
103
|
-
{
|
|
104
|
-
// I was also testing it without prefix 'Bearer ' before the JWT
|
|
105
|
-
description: `Please enter token in following format: Bearer <JWT>`,
|
|
106
|
-
name: 'Authorization',
|
|
107
|
-
bearerFormat: 'Bearer', // I`ve tested not to use this field, but the result was the same
|
|
108
|
-
scheme: 'Bearer',
|
|
109
|
-
type: 'http', // I`ve attempted type: 'apiKey' too
|
|
110
|
-
in: 'Header'
|
|
111
|
-
},
|
|
112
|
-
'jwt'
|
|
113
|
-
)
|
|
114
|
-
.build();
|
|
115
|
-
|
|
116
|
-
const document = SwaggerModule.createDocument(app, options);
|
|
117
|
-
SwaggerModule.setup('/docs', app, document);
|
|
118
|
-
|
|
119
|
-
// Apply interceptor...
|
|
120
|
-
app.useGlobalInterceptors(
|
|
121
|
-
new WrapResponseInterceptor(),
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
app.enableCors(buildDefaultCorsOptions());
|
|
125
|
-
|
|
126
|
-
configurePgInt8TypeParser();
|
|
127
3
|
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
bootstrap();
|
|
4
|
+
bootstrapSolidApp(() => AppModule.forRoot());
|