I'm trying to combine express-session with a typeorm storage within NestJS framework. Therefore I wrote a NestMiddleware as wrapper for express-session (see below). When I start node, NestJS logs the following
Error message:
UnhandledPromiseRejectionWarning: Unhandled promise rejection
(rejection id: 1): Error: Nest can't resolve dependencies of the
SessionMiddleware (?). Please verify whether [0] argument is available
in the current context.
Express is not started (connection refused), but the Sqlite DB (where the sessions should be stored) is created (also a session table, but not the columns).
To me it looks like there is a special problem in resolving dependencies with #InjectRepository from nestjs/typorm-Module. Does anyone have a hint?
Code:
import { Middleware, NestMiddleware, ExpressMiddleware } from '#nestjs/common';
import * as expressSession from 'express-session';
import { InjectRepository } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
import { TypeormStore } from 'connect-typeorm';
import { Session } from './session.entity';
#Middleware()
export class SessionMiddleware implements NestMiddleware {
constructor(
#InjectRepository(Session)
private readonly sessionRepository: Repository<Session>
) {}
resolve(): ExpressMiddleware {
return expressSession({
store: new TypeormStore({ ttl: 86400 }).connect(this.sessionRepository),
secret: 'secret'
});
}
}
It was my fault. Had the middleware in a module, but was configuring the session middleware at the app module level. On that level the following import statement was missing:
TypeOrmModule.forFeature([Session])
Moved now everything to non-app module including middleware configuration. That solved the problem.
Related
The issue I'm facing is with running migrations using #nestjs/typeorm ^9.0.1 and typeorm ^0.3.12. Despite being able to build the project and create migrations, when I try to run them, typeorm can't find the migration files (No migrations are pending).
I have noticed that the version 0.3.x of typeorm requires Datasource object and that in the version 9.x of #nestjs/typeorm, TypeOrmModuleOptions does not have the cli : {migrationsDir : string} attribute.
Here's a link to the project that reproduces the problem, and an example directory structure :
src\configs\database\dataSource.config.ts
src\configs\database\postgres.config.ts
src\configs\database\migrations\1676252827402-Chat.ts
postgres.config.ts
import { DataSourceOptions } from "typeorm";
import { join } from "path";
import { config } from "dotenv";
import CustomNamingStrategy from "./customNamingStrategy";
import { registerAs } from "#nestjs/config";
import { TypeOrmModuleOptions } from "#nestjs/typeorm";
config();
export const databaseConfig: DataSourceOptions = {
name: "default",
type: "postgres",
url: process.env.DATABASE_URL,
ssl:
process.env.DATABASE_ENABLE_SSL === "true"
? {
rejectUnauthorized: false,
}
: false,
logging: process.env.DATABASE_ENABLE_LOGGING === "true",
entities: [join(__dirname, "../../models/*/", "*.entity.{ts,js}")],
migrations: [join(__dirname, "migrations/*.{ts,js}")],
synchronize: false,
migrationsRun: false,
namingStrategy: new CustomNamingStrategy(),
};
export default registerAs(
"database",
() =>
({
...databaseConfig,
keepConnectionAlive: true,
} as TypeOrmModuleOptions)
);
dataSource.config.ts
import { DataSource } from "typeorm";
import { databaseConfig } from "./postgres.config";
export const AppDataSource = new DataSource(databaseConfig);
package.json
"typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli"
"migration:create": "yarn run typeorm migration:create"
"migration:run": "yarn run typeorm migration:run -d src/configs/database/dataSource.config.ts"
Although I can use the create command successfully, when I use the run command, it only displays the message "No migrations are pending". I attempted to resolve the issue by changing migrations path to the DataSourceOptions.migrations list, but it did not work. I also tried replacing the cli parameter datasource with the dist datasource, as well as adjusting the migration paths, but these changes did not fix the issue.
I'm facing a similar issue using the same version of typeorm (^0.3.12), so there might be a bug in this version.
It seems that the migrations are not found anymore if the DataSourceOptions.migrations property is set with the path to the migrations folder.
The ^0.3.12 version seems to be working fine only if the migration classes are directly referenced in DataSourceOptions.migrations, similar to the following:
import { Chat1676252827402 } from './migrations/1676252827402-Chat.ts';
export const databaseConfig: DataSourceOptions = {
...
migrations: [Chat1676252827402],
...
};
I have a config file that exports some info for my app.
export const config: Config = {
isProd: process.env.NODE_ENV == 'production',
connection: {
port: parseInt(process.env.APP_PORT) || 2000,
},
};
And I want to import it and use inside my e2e jest test.
import {Test, TestingModule} from "#nestjs/testing";
import {INestApplication} from "#nestjs/common";
import * as request from "supertest";
import {AppModule} from "./../src/app.module";
import * as dotenv from "dotenv";
dotenv.config({path: ".env"});
import {config} from "../src/infrastructure/config/config"
console.log(process.env); // available here
console.log(config); // will return default values, not from .env
// ...
How can i make jest use env inside imported module?
Nestjs has great configuration modules that support .env:
https://docs.nestjs.com/techniques/configuration#custom-env-file-path
Makes it really easy to ref your configuration in all of your services as opposed to having to import.
I have a cloud function that is meant to delete a post with its subcollection of comments. It properly deletes the post in the emulator. However, when I try to deploy the cloud function to Firebase the following error occurs:
i functions: updating Node.js 16 function
recursiveDelete(us-central1)...
Function failed on loading user code. This is likely due to a bug in
the user code. Error message:
Error: please examine your function logs to see the error cause:
https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs.
Additional troubleshooting documentation can be found at
https://cloud.google.com/functions/docs/troubleshooting#logging.
Functions deploy had errors with the following functions:
recursiveDelete(us-central1)
As instructed, I checked the error in the log in Google Cloud I found:
SyntaxError: Unexpected token p in JSON at position 1
at .JSON.parse
at .parse (
/layers/google.nodejs.functions-framework/functions-framework/node_modules/body-parser/lib/types/json.js:89
)
This is the function:
const functions = require("firebase-functions");
const firebase_tools = require('firebase-tools');
const admin = require('firebase-admin');
admin.initializeApp();
/**
* Initiate a recursive delete of documents at a given path.
* #param {string} data.path the document or collection path to delete.
*/
exports.recursiveDelete = functions
.runWith({
timeoutSeconds: 540,
memory: '2GB'
})
.https.onCall(async (data, context) => {
const path = data[0].path;
console.log(`Running cloud function recursiveDelete on ${path}`);
await firebase_tools.firestore
.delete(path, {
project: process.env.GCP_PROJECT,
recursive: true,
yes: true,
token: '...',
force: true
});
return {
path: path
};
});
This is how I'm calling it:
static Future<void> delete(String ref) async {
if (FirebaseAuth.instance.currentUser == null) {
throw Exception('Must be logged in');
}
await FirebaseFunctions.instance
.httpsCallable('recursiveDelete')
.call([{'path': 'posts/$ref'}])
.then((value) => logger("Post deleted: ${value.data}"))
.catchError((error) => logger.error("Failed to delete post: $error"));
}
In the emulator, deletion works fine and the output is:
I/flutter (26907): [Post] [INFO] Post deleted: {path:
posts/Gk4TeWEgZmm0QUcaqTrk}
So, what's wrong with it?
Full stack-trace:
=== Deploying to 'sightings-dev'...
i deploying functions
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
✔ functions: required API cloudfunctions.googleapis.com is enabled
✔ functions: required API cloudbuild.googleapis.com is enabled
✔ artifactregistry: required API artifactregistry.googleapis.com is enabled
i functions: preparing codebase default for deployment
i functions: preparing functions directory for uploading...
i functions: packaged /Users/strijdhaftig/sightings/frontend/flutter/sightings/functions (55.13 KB) for uploading
✔ functions: functions folder uploaded successfully
i functions: updating Node.js 16 function recursiveDelete(us-central1)...
Function failed on loading user code. This is likely due to a bug in the user code. Error message: Error: please examine your function logs to see the error cause: https://cloud.google.com/functions/docs/monitoring/logging#viewing_logs. Additional troubleshooting documentation can be found at https://cloud.google.com/functions/docs/troubleshooting#logging. Please visit https://cloud.google.com/functions/docs/troubleshooting for in-depth troubleshooting documentation.
Functions deploy had errors with the following functions:
recursiveDelete(us-central1)
i functions: cleaning up build files...
Error: There was an error deploying functions
Having trouble? Try again or contact support with contents of firebase-debug.log
is there a way to get data from a database in postgres using wasm?. I'd tried to get it using a library in rust but I got some errore when I build the package using "wasm-pack building--target web". The idea is to build a function in lib.rs file that return data from a db. I have the below code inside lib.rs:
use postgres::{Client, Error, NoTls};
use wasm_bindgen::prelude::*;
...
struct Author {
_id: i32,
name: String,
}
#[wasm_bindgen]
pub fn select_name(name: &String) -> Result<(), Error> {
let mut client = Client::connect("postgresql://user:1234#localhost:5432/db", NoTls)?;
for row in client.query(
"SELECT id, name FROM author WHERE name = $1",
&[&name],
)? {
let author = Author {
_id: row.get(0),
name: row.get(1),
};
println!(
"Select_Name => Author {} :",
author.name
);
}
Ok(())
}
but I get some errors:
error[E0432]: unresolved import `crate::sys::IoSourceState`
error[E0432]: unresolved import `crate::sys`
...
It is not possible directly (as Njuguna Mureithi rightly wrote) but it can be circumvented.
We can use the project: https://github.com/PostgREST/postgrest
and expose the API to our sql server.
We download the latest version of postgrest
https://github.com/PostgREST/postgrest/releases/tag/v9.0.0
in case of Linux we unpack
tar -xf postgrest-v9.0.0-linux-static-x64.tar.xz
then run help
./postgrest -h
create a configuration file for ./postgrest
postgrest -e > cfg.psqlrest
change the user and password for the database in the configuration file.
e.g. with
db-uri = "postgres://user:pasword#localhost:5432/dbname"
to your dbname database access user:pasword configuration
db-uri = "postgres://postgres:zaqwsxc#localhost:5432/dbname"
and run the server which will issue the api to our postgres
./postgrest cfg.psqlrest
The address http://localhost:3000 will start accessing the database dbname, which must be created in the database server beforehand.
Here is a description of the libraries needed to call the query using the API.
https://rustwasm.github.io/wasm-bindgen/examples/fetch.html
examples of API
https://postgrest.org/en/stable/api.html
I'm trying to build a simple CRUD API with the MongoDB Rust driver but I'm failing to insert anything into the DB. I'm using Mlab to host my database.
The code that I'm running:
#[macro_use(bson, doc)]
extern crate bson;
extern crate mongodb;
use mongodb::db::ThreadedDatabase;
use mongodb::{Client, ThreadedClient};
fn main() {
let client = Client::with_uri(
"mongodb://<my_db_username>:<my_db_password>#ds235711.mlab.com:35711/rustcrud",
)
.expect("Failed to initialize client");
let coll = client.db("rustcrud").collection("test");
coll.insert_one(doc! { "title": "Back to the Future" }, None)
.unwrap();
}
And the error that I get:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: OperationError("not authorized on rustcrud to execute command { insert: \"test\", $db: \"rustcrud\" }")', libcore/result.rs:1009:5
What am I doing wrong?
From the project's GitHub repository, issue 256: Add auth to base examples
user-password authentication occurs at the database-level. The user, password, and database are parsed from the URI, but I don't believe we have it set up to automatically authenticate when you create the database object
let client = Client::with_uri("mongodb://x:y#localhost:27017")?;
client.auth("x", "y");