Change JavaScript in TypeScript - javascript

I would like to translate this code into actual TypeScript. Could you help me there?
import mongoose, { Promise } from 'mongoose';
Promise = global.Promise;
const db = {};
db.mongoose = mongoose;
db.user = require("./user.model");
db.role = require("./role.model");
db.ROLES = ["user", "admin", "moderator"];
export default db;

It would be great if you'd provide us with what you have tried and achieved so that it is easier to modify your code.
A way to do this would be to type this in a TypeScript file in an editor that provides linting for TypeScript like Visual Studio Code. Then check all the errors and fix them.

Related

YAML validation using JSON schema

I am having a CI service that validates YAML files using JSON schema. The solution works by firstly converting the YAML to JSON using js-yaml and then by checking the schema using ajv
sample code:
import { load } from 'js-yaml';
import { default as Ajv } from 'ajv';
import schema from '../../schema.json';
const ajv = new Ajv({
strict: false
});
export const validate = (file: { content: string }) => {
const parsed = load(file.content) as unknown;
const valid = ajv.validate(schema, parsed);
if (!valid) throw new Error(ajv.errorsText());
}
I would like to extend this solution to report back with the error Line and Column.
Do you know if there is a solution for this out there already? My GoogleFu let me down this time. The closest I got is vscode XML plugin vscode YAML plugin which seems to be tightly coupled with VS code :(

What is exports.local used for in node.js

Exports.local Node js sample code
I am using passport-local-mongoose in my node js Application and I come across exports.local for passport authentication. I couldn't understand it function. Please check the image above
In your case here there is nothing special about local keyword, it is just the name of the variable that is used to export the passport local authentication strategy configuration, so you can call it in other files using require, so here in your example, you have this logic written in authenticate.js, so to use it in any other file you will have to call it using the following:
const { local } = require('./authenticate'); // identify the right path to authenticate.js
enter code here
The CommonJS (CJS) format is used in Node.js and uses require and module.exports to define dependencies and modules. The npm ecosystem is built upon this format. In your case exports.local creates a new module and export it for the use elsewhere.
Example
user.js
const getName = () => {
return 'Jim';
};
exports.getName = getName;
index.js
const user = require('./user');
console.log(`User: ${user.getName()}`);
Output
User: Jim

Implement Joi in Typescript

Simple joi validation snippet in javascript.It will simply return an error object when validation fails.
validate.js
const Joi =require("joi");
function validateObject (input) {
const schema = {
key: Joi.string().required(),
};
return Joi.validate(input, schema);
};
let {error} = validateObject({key:5})
console.log(error)
Now I am learning typescript and like to do the exact functionality in TS.I am aware that Joi is a javascript library but can we make use of it in Typescript.When exploring I came across some alternatives like https://github.com/joiful-ts/joiful.
I am curious to know if there is any straightforward approach using Joi directly in typescript. Or little bit of changes to make the Joi work exactly like in Javascript.
WHAT I TRIED
validate.ts
import * as Joi from "joi";
export const validateObject = (input: object) => {
const schema = {
home: Joi.string().required(),
};
return Joi.validate(input, schema);
};
validateObject({key:5})
While compiling, I got the error
Cannot find name 'Iterable'.
703 map(iterable: Iterable<[string | number | boolean | symbol,
symbol]> | { [key: string]: symbol }): this;
UPDATE
I have installed #types/joi as suggested in the answer but still the same error
I am basically looking for validating string,boolean,number,array and object keys as it can be done easily with Joi in Javascript
Please change your import
-const Joi =require("joi");
+import Joi from "joi";
And make sure you've installed the types by using
npm install --save-dev #types/joi
Type definitions for Joi exists: #types/joi or #types/hapi__joi (for joi version 17).
Add those to your package.json, and you should be able to use Joi with Typescript. Generally speaking you should not be downloading seperate libraries to make a package work in Typescript, some definitions should do
Try to use this code instead.
import * as Joi from "joi";
export const validateObject = (input: object) => {
const schema = Joi.object().keys({
home: Joi.string().required(),
});
return schema.validate(input);
};
validateObject({key:5})
I hope you will manage to make it work.
I doubt that import * as Joi from "joi" is going to give you much joy. You are importing all exported members with that.
Is there an individual export you are wanting? Use import { IndividualExport } from "joi"
Is there a default export you are wanting? Use import Joi from "joi"
Also is there a reason you are calling Joi in the second example but not the first?
Zod seems to be a popular Joi alternative for TypeScrip:
https://www.npmjs.com/package/zod

Inline import by ES6 modules in Node.js

In an "old way" of managing modules in Node.JS (CommonJS modules) you can do something like this:
Example of Express.js route: app.use('/user', require("./user"));
How to do this when I am using ES6 Modules (import, export) and transcribing by Node.JS server by babel?
I can't just do: app.use('/user', import {user} from './user');
Try separating it out into multiple expressions - import (as well as export) are not available at the same lexical level as you are trying to use it the example:
import { user } from './user'
...
app.use('/user', user)
There is a way to do dynamic inline imports in node, detailed here:
https://javascript.info/modules-dynamic-imports
This code has worked for me:
let {default: foo} = await import('./foo.js');
Here is a working example of a function I wrote as part of a db migration tool in node.
const getMigrations = async (path) => {
const migrateDir = await fs.readdirSync(path);
const migrations = await Promise.all(migrateDir.map(async (filename) => {
let {default: migration} = await import(`${path}/${filename}`);
return migration;
}));
migrations.sort((a, b) => {
return a.seq - b.seq;
});
return migrations;
};
Where an example migration is like:
export default {
seq: 1.1,
label: 'create user table',
sql: `
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
...
);
`
};
I am using node v12.18.4 with "type": "module" in my package.json. When I run the script, I get a warning that the ESM module loader is experimental, but it works. However, there is a note on the page linked to above that says:
Dynamic imports work in regular scripts, they don’t require script type="module".
I hope this helps. I believe you should be able to apply this to your problem.

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