Using Sequelize with Typscript result in error - javascript

After some time I try to re-develop my NodeJs app to TypeScript and I run with Sequelize into problems.
After trying to use the code from the website, I get an error:
This expression is not constructable.
Type 'typeof import("/home/developer/devel/metricsutilities/WorklogMetrics/node_modules/sequelize/types/index")' has no construct signatures.ts(2351)
The code is a simple database connector
import * as Sequelize from 'sequelize'
export const sequelize = new Sequelize("xx", "xxx", "xxx", {
host: "xxx",
dialect: "postgres",
pool: {
max: 15,
min: 0,
idle: 10000,
},
logging: false,
timezone: "+01:00",
});
sequelize.authenticate()
Inside a common JavaScript NodeJS app this is working. Sequelize 6.21.3
Inside my new NodeJS app not. And I think it is exact the Sequelize website says.
My new server has:
Node 16.10.0 on Linux Ubuntu
Sequelize 6.28.0
#types/sequelize: 4.28.14
Do I miss something inside the constructor?

You import the whole module and tried to use it as a class. Just import separated classes/functions/enums/interfaces enumerating them inside {} in the import statement:
import { Sequelize, Op } from 'sequelize'

Related

How to correct: SyntaxError: Named export 'mongo' not found

Trying to run a simple script to create a user with mongoose using nodejs. So basically just running node my_script.js which is the official way as per Run Node.js scripts from the command line
I have tried importing in the following ways:
import Connection from 'mongoose';
const { mongo } = Connection;
import mongoose from "mongoose"
import mongoose from "node_modules/mongoose/index.js"
const mongoose = require("mongoose")
Also tried adding the following lines to package.json:
"type": "module",
"esModuleInterop": true,
Complete error seen below for most of the import cases above:
import mongoose, { mongo } from "mongoose";
^^^^^
SyntaxError: Named export 'mongo' not found. The requested module 'mongoose' is a CommonJS module, which may not support all module.exports as named exports.CommonJS modules can always be imported via the default export, for example using:
import pkg from 'mongoose';
const { mongo } = pkg;
at ModuleJob._instantiate (internal/modules/esm/module_job.js:98:21)
at async ModuleJob.run (internal/modules/esm/module_job.js:143:5)
at async Loader.import (internal/modules/esm/loader.js:165:24)
at async Object.loadESM (internal/process/esm_loader.js:68:5)
From mongoose index.js file I do not see any other export besides:
const mongoose = module.exports = exports = new Mongoose({
[defaultMongooseSymbol]: true
});
Found this github issue Misleading error that module does not provide export
#32137 but still not sure how to make this import to work.
This "appears" to be the fix which is the only thing that happened after I took a break.
I had 2 files: B.js and A.js
from A.js:
import foo from "./B.js";
import mongoose from "mongoose";
I decided to run B.js on it's own to see if it would give me the same error(it had a mongoose import as well), it turn's out there was another different error:
foo.pre(save, function(next) {
^ ReferenceError: save is not defined
Ok nothing biggy, corrected it and node B.js worked fine when running it, hence decided to test with node A.js, which worked just fine to my surprise!
This turned out to be completely counterintuitive, as the error mentioned initially was not pointing to this.

How can I break apart a GraphQL Schema into multiple files in graphql-yoga

I'm new to GraphQL. I'm trying to break apart a schema.sql file into multiple files.
First question, is this a standard way of doing things with GraphQL (for example, Query.graphql, Mutation.graphql, TypeA.graphql, etc.)
Second, I thought the parameter in typeDefs (for graphql-yoga) allows me to pass an array of locations for all the schema files, but it's not working for me (See below after the code for the error I'm geting.
Here is my code in my main index.js file:
import { graphQLServer, GraphQLServer } from 'graphql-yoga';
import db from '../database/db';
import Query from './resolvers/Query';
import Mutation from './resolvers/Mutation';
import Post from './resolvers/Post';
import User from './resolvers/User';
import Comment from './resolvers/Comment';
const typeDefs = [
'./schemas/query.graphql',
'./schemas/mutation.graphql',
'./schemas/user.graphql'
];
const server = new GraphQLServer({
typeDefs: typeDefs,
context: { db },
resolvers: { Query, Mutation, Post, User, Comment }
});
server.start(()=> {
console.log("Server started on localhost:4000!");
});
Here is the error I'm getting:
Error: Field createUser: Couldn't find type User in any of the schemas.
at collectNode (C:\Websites\Learning-GraphQL - Local Copy\graphql-bootcamp\graphql-basics\node_modules\graphql-import\src\definition.ts:154:15)
at C:\Websites\Learning-GraphQL - Local Copy\graphql-bootcamp\graphql-basics\node_modules\graphql-import\src\definition.ts:135:7
at Array.forEach (<anonymous>)
at collectNewTypeDefinitions (C:\Websites\Learning-GraphQL - Local Copy\graphql-bootcamp\graphql-basics\node_modules\graphql-import\src\definition.ts:134:26)
at Object.completeDefinitionPool (C:\Websites\Learning-GraphQL - Local Copy\graphql-bootcamp\graphql-basics\node_modules\graphql-import\src\definition.ts:49:39)
at Object.importSchema (C:\Websites\Learning-GraphQL - Local Copy\graphql-bootcamp\graphql-basics\node_modules\graphql-import\src\index.ts:127:18)
at mergeTypeDefs (C:\Websites\Learning-GraphQL - Local Copy\graphql-bootcamp\graphql-basics\node_modules\graphql-yoga\src\index.ts:456:14)
at C:\Websites\Learning-GraphQL - Local Copy\graphql-bootcamp\graphql-basics\node_modules\graphql-yoga\src\index.ts:472:32
at Array.reduce (<anonymous>)
at mergeTypeDefs (C:\Websites\Learning-GraphQL - Local Copy\graphql-bootcamp\graphql-basics\node_modules\graphql-yoga\src\index.ts:471:21)
As you can see, it says it can't find one of my types (User), but I do have it in the User.graphql schema file. When I have everything in just one file and pass that file only as the typeDefs, it works fine. Thanks in advance for your help!
const typeDefs = [
'./schemas/query.graphql',
'./schemas/mutation.graphql',
'./schemas/user.graphql'
];
this is only an array of strings
from docs:
typeDefs - String or Function or DocumentNode or array of previous
you can make something like:
import Query from './schemas/query.graphql'
import Mutation from './schemas/mutation.graphql'
import User from './schemas/user.graphql'
const typeDefs = [Query, Mutation, User];
config required: https://github.com/apollographql/graphql-tag#webpack-preprocessing-with-graphql-tagloader

Node.js use mssql for accessing database

I'm making the Meteor.js app and I have to get data from mssql database. I use Meteor 1.8 and a npm package - mssql(version 5.1.0). That's my code:
const sql = require('mssql')
const config = {something}
export default function fetch(query) {
const config = {something}
sql.connect(config, err => {
if (err) {
console.error(err)
return
}
// create Request object
var request = new sql.Request()
// query to the database and get the records
request.query(query, (err, recordset) => {
if (err) {
console.error(err)
return
}
return recordset
})
})
}
And I have such error
TypeError: sql.connect is not a function
I don't know what's going on, I tried to do it in many ways and I failed. When I use ConnectionPool I see an error saying that ConnectionPool is not a constructor.
What is the proper way to do this?
In my config file I have: user, password, server, database, port.
It appears to be because you're mixing your module systems, you're using require (which is CommonJS-like) but in something that's apparently an ECMAScript module (ESM) (from the export default ...). Node.js itself won't let you do that, but if you're using some kind of bundler or transpiler, perhaps it might...
Changing your require to:
import sql from "mssql";
...and making sure Node.js is using ESM¹, I don't get any error with sql.connect not being a function.
¹ In my case, since I'm using Node.js v12, I do that by having "type": "module" in my package.json and running it via node --experimental-modules filename.js, more here.

How to use Phoenix Channels / Sockets in an Angular 2 app?

I have a backend built with Elixir / Phoenix and a frontend built with Angular 2 (Typescript, Brunch,io for building, ES6). I now want to use Phoenix Channels. And I'm a bit desperate trying to use the Phoenix Javascript Client in my frontend.
When I install https://www.npmjs.com/package/phoenix-js via npm install phoenix-js and then try to inject it into a service in angular like this:
import { Socket } from "phoenix-js";
I always get the error Cannot find module phoenix-js during compilation.
I'm a bit stuck and every hint on how to get this to work would be greatly appreciated.
Thanks
Edit: I'm going to leave the old answer below - even though it is a bit emberassing. Getting everything to work and using the most recent version of the Phoenix JS Client with Angular 2 was even easier than I thought and I was just terribly confused.
The Phoenix JS client has been extracted as an npm package and can be found here. Install it with npm install --save phoenix. Then load it as additional dependency. In my setup with SystemJS it was just a matter of adding the necessary configuration:
import { join } from 'path';
import { SeedConfig } from './seed.config';
import { InjectableDependency } from './seed.config.interfaces';
export class ProjectConfig extends SeedConfig {
PROJECT_TASKS_DIR = join(process.cwd(), this.TOOLS_DIR, 'tasks', 'project');
constructor() {
super();
// this.APP_TITLE = 'Put name of your app here';
let additional_deps: InjectableDependency[] = [
// {src: 'jquery/dist/jquery.min.js', inject: 'libs'},
// {src: 'lodash/lodash.min.js', inject: 'libs'},
{src: 'phoenix/priv/static/phoenix.js', inject: 'libs'}
];
const seedDependencies = this.NPM_DEPENDENCIES;
this.NPM_DEPENDENCIES = seedDependencies.concat(additional_deps);
}
}
Now we have it in the global scope and just need to use declare var in the Angular 2 service typescript file where we want to use it. Here was where I made a crucial mistake. I tried to access Socket directly and therefor used declare var Socket: any. Which always led to the error Socket is undefined. But this issue got me in the right direction: If you use the transpiled ES5 version (and not ES6) you have to use Phoenix.Socket (because of namespacing I guess).
So this is how my service looks like now:
import { Injectable } from '#angular/core';
declare var Phoenix: any;
#Injectable()
export class PhoenixChannelService {
socket: any;
constructor() {
this.socket = new Phoenix.Socket("ws://localhost:4000/socket", {
logger: ((kind, msg, data) => { console.log(`${kind}: ${msg}`, data) }),
transport: WebSocket
});
this.socket.connect();
}
}
Now everything works like a charm.
If you don't want to install the client via npm, there is a more basic way: Just get the latest version of the JS Client from GitHub from /priv/static, store it in the folder where you keep your static assets and include it directly in your index.html:
<script src="/path/to/static/js/phoenix.js"></script>
The rest stays the same.
Note: If you want to use it with typescript type definitions, this npm package might be a good starting point - even though it is a bit old.
Old and embarrassing answer: So I think I figured it out. Writing my own definition file wasn't an option. And since all the documented code on how to use the phoenix client is in ES6 I got stuck including the transpiled ES5 version directly in my index.html. But the first clue was this article.
I then found this issue on GitHub which is about extracting the Phoenix Client. Via this I then found this npm package, which is a bit outdated but seems to work. I install it with npm insall --save phoenix-js and then load the dependency in my project. Since my Angular App is based on this seed it goes into my project definition (and make sure to load the Globals version of the phoenix client:
import { join } from 'path';
import { SeedConfig } from './seed.config';
import { InjectableDependency } from './seed.config.interfaces';
export class ProjectConfig extends SeedConfig {
PROJECT_TASKS_DIR = join(process.cwd(), this.TOOLS_DIR, 'tasks', 'project');
constructor() {
super();
// this.APP_TITLE = 'Put name of your app here';
let additional_deps: InjectableDependency[] = [
// {src: 'jquery/dist/jquery.min.js', inject: 'libs'},
// {src: 'lodash/lodash.min.js', inject: 'libs'},
{src: 'phoenix-js/dist/glob/main.js', inject: 'libs'}
];
const seedDependencies = this.NPM_DEPENDENCIES;
this.NPM_DEPENDENCIES = seedDependencies.concat(additional_deps);
}
}
Now I can use it in my angular 2 service:
import { Injectable } from '#angular/core';
declare var Socket: any;
declare var Channel: any;
#Injectable()
export class PhoenixChannelService {
socket: any;
channel: any;
constructor() {
this.socket = new Socket("/socket", {
logger: ((kind, msg, data) => { console.log(`${kind}: ${msg}`, data) })
});
this.socket.connect({user_id: "123"});
}
}
Depending on your build process (I use gulp) and other factors you might have to adapt. But I hope this provides some help to other people stuck with this issue.
Edit: This is the official extracted JS client for Phoenix. But I didn't get it to work in my setup, probably because of Typescript.

How to import MongoDB using es6 style imports?

Hopefully this is a simple question. I am trying to import MongoDB using the es6 import-from style. If I import using node require it works fine.
let mongo = require('mongodb');
let MongoClient = mongo.MongoClient;
But if I import it the es6 way it breaks without errors or logs.
import {MongoClient} from 'mongodb';
But it doesn't break when compiling/running it only breaks when I try to do anything with MongoClient.
Here is my Db Manager class-
import {MongoClient} from 'mongodb';
export class DbManager {
constructor() {
console.log('Constructing DB Connection');
}
}
When I run my server I get several logs from other managers and events.
mycomputer myuser$ ./start.sh
Server Constructing
Route Manager Constructing
Initializing Route: Static
Constructing DB Connection
http server started on port: 8000
But if I do a console.log of the MongoClient there is simply no output.
import {MongoClient} from 'mongodb';
export class DbManager {
constructor() {
console.log('Constructing DB Connection');
console.log(MongoClient);
}
}
And the output looks like this-
mycomputer myuser$ ./start.sh
mycomputer myuser$
There are no compile errors so I don't understand why this isn't working. Furthermore, I don't understand why there aren't any logs! This is one of the last things that happens, there should at least be logs up until that point I'd think. If you'd like to see my start.sh script here it is (quick and dirty, don't judge me):
tsc
echo "var System = require('systemjs');" > dist/final.js
babel dist/typescript.js >> dist/final.js
echo "System.import('main');" >> dist/final.js
node dist/final.js
EDIT
Continuing to search for the answer while waiting (hoping) for a response. I'm taking a look at the resulting final.js and if MongoClient is used anywhere in the file the System.register function call looks like this-
System.register("db/db.manager", ["mongodb"] ...
And if I don't use it (even if I import it) it does not show mongodb.
System.register("db/db.manager", [] ...
That would explain why nothing would happen. Something is wrong with trying to import mongodb. Not sure yet what to do.
EDIT EDIT
Found a solution. One i'm not thrilled with but maybe it's just the way it has to be.
I don't think I can rely on es6 imports. It looks like I can use it to import the typedefs but not the actual module. How I got around this is like this-
import {Db as MongoDb, MongoClient} from 'mongodb';
let mongodb = require('mongodb');
let mongoClient: MongoClient = mongodb.MongoClient;
A lot of extra work. If there's another way please let me know.
Listen, I know there are more than a handful of cracks at this solution here. Some may work for you, but for me, none solved me but the one below.
2021 UPDATE:
BORING BACKSTORY ALERT
We're using Node v14.16.0 and our package.json has "type": "module" set. So, our code is ES6+ and commonjs imports are a deal-breaker in most cases, especially when it comes to the MongoDB Native 3.6 NodeJS Driver.
Lucky for us, MongoDB Native ^4.0.0-beta.3 is written in TypeScript, and works as expected. Prepare your shattered sprits for liftoff. ;) Oh, and rather than store your secret sauce (user:pass and uri) in your source code, check out node-config and be safe.
THE SOLUTION
# This version will keep changing after this posts, so take heed.
$ cd path/to/your/project
$ npm i -s mongodb#4.0.0-beta.3
Inside your project:
import config from 'config'
// MongoDB
import { MongoClient } from 'mongodb'
const client = new MongoClient(config.get('mongodb.uri'))
await client.connect()
const db = client.db()
const stuff = db.collection('AllTheStuff')
const record = {
type: "ThisAndThat",
lastUpdated: new Date().getTime()
}
const query = { type: "ThisAndThat" }
const options = { upsert: true }
const result = await stuff.replaceOne(query, record, options)
And now all your cats are sleep silent tonight. Hopefully this lowers the level of unchallenged insanity in the world, or helps you in your quest, whichever suits your taste in achievement. :)
import { MongoClient } from 'mongodb';
just imports type definition from node_modules/#types/mongodb/index.d.ts
import * as mongodb from 'mongodb';
imports everything from node_modules/mongodb/index.js and its the same as
let mongodb = require('mongodb');
Try this:
import { default as mongodb } from 'mongodb';
let MongoClient = mongodb.MongoClient;
Edit
As Elihu pointed out in the comment below, the additional integration of #types/mongo is now deprecated and is no longer needed as the mongo-package now comes with types per default.
npm install --save mongodb is therefore sufficient.
Original Answer
As mkalmo suggested you can import the mongodb types:
Step 1: Install via the npm mongodb types package
npm install --save #types/mongodb
Step 2: Use it!
import mongodb from "mongodb";
const MongoClient = mongodb.MongoClient;
This works for me:
import mongodb from 'mongodb'
const { MongoClient } = mongodb

Categories

Resources