Error: "Missing initializer in const declaration" plaid api create link token - node.js

I'm trying to setup the plaid api in my node.js code and I need to be able to make a request for the create_link_token. The sample code from their docs is as follows:
const request: LinkTokenCreateRequest = {
user: {
client_user_id: 'user-id',
},
client_name: 'Plaid Test App',
products: ['auth', 'transactions'],
country_codes: ['US'],
language: 'en',
webhook: 'https://sample-web-hook.com',
redirect_uri: 'https://domainname.com/oauth-page.html',
account_filters: {
depository: {
account_subtypes: ['DepositoryAccountSubtype.Checking, DepositoryAccountSubtype.Savings'],
},
},
};
try {
const response = await plaidClient.linkTokenCreate(request);
const linkToken = response.data.link_token;
} catch (error) {
// handle error
}
my code is:
app.post('/api/create_link_token', async (req, res, next) => {
const request: LinkTokenCreateRequest = {
user: {
client_user_id: 'user-id',
},
client_name: 'Plaid Test App',
products: ['auth', 'transactions'],
country_codes: ['US'],
language: 'en',
webhook: 'https://sample-web-hook.com',
redirect_uri: 'https://domainname.com/oauth-page.html',
account_filters: {
depository: {
account_subtypes: ['DepositoryAccountSubtype.Checking, DepositoryAccountSubtype.Savings'],
},
},
};
try {
const response = await plaidClient.linkTokenCreate(request);
const linkToken = response.data.link_token;
} catch(e) {
handleError(e);
}
});
Right off the bat I get the error: 'LinkTokenCreateRequest' refers to a value, but is being used as a type here. Did you mean 'typeof LinkTokenCreateRequest'?ts(2749) as a red underline underneath LinkTokenCreateRequest. Side note I've never used TS before this, but I believe I have to use it on this project because some of their components require it. If I do as they suggest and change it to typeof LinkTokenCreateRequest = {... then the red underline error goes away, however upon starting the server I get the error:
const request: typeof LinkTokenCreateRequest = {
^^^^^^^
SyntaxError: Missing initializer in const declaration
I've very confused as to how I can make this work so any suggestions would be much appreciated.

Related

How to create a Plaid LinkToken using Node JS?

I believe Plaid updated its createLinkToken documentation, but I can't seem to figure out what I'm doing wrong here. I'm taking a course, and here is the old code that worked in using a FirebaseFunction to create a link token with Plaid:
exports.createPlaidLinkToken = functions.https.onCall(async (data, context) => {
const customerId = context.auth.id;
const plaidClient = new plaid.Client({
clientID: functions.config().plaid.client_id,
secret: functions.config().plaid.secret,
env: plaid.environments.sandbox,
options: {
version: '2019-05-29',
},
});
return plaidClient.createLinkToken({
user: {
client_user_id: customerId,
},
client_name: "Bon Voyage",
products: ["auth"],
country_codes: ["US"],
language: "en"
}).then((apiResponse) => {
const linkToken = apiResponse.link_token;
return linkToken;
}).catch((err) => {
console.log(err);
throw new functions.https.HttpsError("internal", "Unable to create plaid link token: " + err);
});
});
I've tried a number of things. I know plaid.Client is now new.Configuration but I can't seem to figure out the rest. Any helpers?
You can see in the comments below what I've tried. I've modified the code as follows, and now receive Error status code 400.
const plaid = require('plaid');
const { Configuration, PlaidEnvironments, PlaidApi } = require("plaid");
exports.createPlaidLinkToken = functions.https.onCall(async (data, context) => {
const customerId = context.auth.uid;
const configuration = new Configuration({
basePath: PlaidEnvironments.sandbox,
baseOptions: {
headers: {
plaid_client_id: functions.config().plaid.client_id,
plaid_secret: functions.config().plaid.secret,
plaid_version: '2021-05-20'
},
},
});
const plaidClient = new PlaidApi(configuration);
return plaidClient.linkTokenCreate({
user: {
client_user_id: customerId,
},
client_name: "Bon Voyage",
products: ["auth"],
country_codes: ["US"],
language: "en"
})
.then((apiResponse) => {
const linkToken = apiResponse.data.link_token;
// const linkToken = response.link_token
return linkToken;
})
.catch((err) => {
console.log(err);
throw new functions.https.HttpsError(
"internal",
" Unable to create plaid link token: " + err
);
});
});
It's difficult to answer this question as you haven't mentioned what you've tried or what error you are experiencing. Have you reviewed the sample implementations in the docs that show how to do this, including the sample code in the Quickstart and Tiny Quickstart?
Off the top of my head, I do see that this sample code specifies an API version of 2019-05-29, which is not compatible with the latest version of the Node client library that uses new.Configuration.

How to make kuzzle-device-manager plugin API actions works?

I successfully installed and loaded kuzzle-device-manager in the backend file:
import { Backend } from 'kuzzle';
import { DeviceManagerPlugin } from 'kuzzle-device-manager';
const app = new Backend('playground');
console.log(app.config);
const deviceManager = new DeviceManagerPlugin();
const mappings = {
updatedAt: { type: 'date' },
payloadUuid: { type: 'keyword' },
value: { type: 'float' }
}
deviceManager.devices.registerMeasure('humidity', mappings)
app.plugin.use(deviceManager)
app.start()
.then(async () => {
// Interact with Kuzzle API to create a new index if it does not already exist
console.log(' started!');
})
.catch(console.error);
But when i try to use controllers from that plugin for example device-manager/device with create action i get an error output.
Here is my "client" code in js:
const { Kuzzle, WebSocket } = require("kuzzle-sdk")
const kuzzle = new Kuzzle(
new WebSocket('KUZZLE_IP')
)
kuzzle.on('networkError', error => {
console.error('Network Error: ', error);
})
const run = async () => {
try {
// Connects to the Kuzzle server
await kuzzle.connect();
// Creates an index
const result = await kuzzle.query({
index: "nyc-open-data",
controller: "device-manager/device",
action: "create",
body: {
model: "model-1234",
reference: "reference-1234"
}
}, {
queuable: false
})
console.log(result)
} catch (error) {
console.error(error.message);
} finally {
kuzzle.disconnect();
}
};
run();
And the result log:
API action "device-manager/device":"create" not found
Note: The nyc-open-data index exists and is empty.
We apologize for this mistake in the documentation, the device-manager/device:create method is not available because the plugin is using auto-provisioning until the v2.
You should send a payload to your decoder, the plugin will automatically provision the device if it does not exists https://docs.kuzzle.io/official-plugins/device-manager/1/guides/decoders/#receive-payloads

How to test files and json data at the same time with jest?

I have a post request with express that upload a file and some data to the mongodb:
// Routes
Router.post('/api/training', validator(createVideoSchema, 'body'), uploadVideo, createVideoHandler);
// Route Handlers
async function createVideoHandler (req: Request, res: Response, next: NextFunction) {
try {
const dataToCreate = {
...req.body,
url: req.file?.path,
mimetype: req.file?.mimetype
};
const data = await service.create(dataToCreate);
response(req, res, data, 201);
} catch (error) {
next(error);
}
}
the body must be validate by joi using the following schema:
import Joi from 'joi';
const title = Joi.string().email().min(5).max(255);
const description = Joi.string().min(5).max(255);
const thumbnail = Joi.string().min(5).max(255);
const tags = Joi.array().items(Joi.string().min(5).max(100));
const createVideoSchema = Joi.object({
title: title.required(),
description: description.required(),
thumbnail: thumbnail.required(),
tags: tags.required(),
});
export { createVideoSchema };
Then I am creating a test to verify I am receiving a 201 status code:
it('should have a 201 status code', async () => {
const response = await request(app).post(route)
.set('Accept', 'application/json')
.field('title', data.title)
.field('description', data.description)
.field('thumbnail', data.thumbnail)
.field('tags', data.tags)
.attach('video', Buffer.from('video'), { filename: 'video.mp4' });
expect(response.status).toBe(201);
});
For some reason the validation middleware throws me a 400 error saying that the data is missing:
Error: "title" is required. "description" is required. "thumbnail" is required. "tags" is required
I tried to send the data using .set('Accept', 'multipart/form-data') but it throws me the same error.
I guess this error has to do with the way I send the data, but I don't fully understand.
You typically should not call a live API from a test. Instead you should mock the different possibly API response scenarios and be sure your code handles the different possibilities correctly. Ideally you'll also have a client class of some kind to place direct calls to your API inside a class that can easily be mocked.
For example, you could mock the endpoint response for valid data with something like:
export class VideoClient {
async createVideo(data) {
const response = await request(app).post(route) // Whatever url points to your API endpoint
.set('Accept', 'application/json')
.field('title', data.title)
.field('description', data.description)
.field('thumbnail', data.thumbnail)
.field('tags', data.tags)
.attach('video', Buffer.from('video'), { filename: 'video.mp4' });
if (response.status.ok) {
return { response, message: 'someGoodResponseMessage'};
}
return { response, message: 'someErrorOccurred' };
}
}
Then in your test you can mock your client call:
import { VideoClient } from './clients/VideoClient.js'; // or whatever path you saved your client to
const goodData = { someValidData: 'test' };
const badData = {someBadData: 'test' };
const goodResponse = {
response: { status: 201 },
message: 'someGoodResponseMessage'
}
const badResponse = {
response: { status: 400 },
message: 'someErrorOccurred'
}
it('should have a 201 status code', async () => {
VideoClient.createVideo = jest.fn().mockReturnValue(goodResponse);
const results = await VideoClient.createVideo(goodData);
expect(results.response.status).toBe(201);
expect(results.message).toEqual('someGoodResponseMessage');
});
it('should have a 400 status code', async () => {
VideoClient.createVideo = jest.fn().mockReturnValue(badResponse);
const results = await VideoClient.createVideo(badData);
expect(results.response.status).toBe(400);
expect(results.message).toEqual('someErrorOccurred');
});
This is by no means a working test or exhaustive example, but demonstrating the idea that you really should not call your API in your tests, but instead call mock implementations of your API to handle how your client code responds in different situations.

I am getting a 500 response. Is the way I am trying this wrong? Or is there something I'm missing?

I'm making a game project. I have everything working to where you can create a character, and it posts okay to the database, and I can see the characters I've created on an endpoint with all the details included.
Where it doesn't work anywhere else is where I have things shifted from a context state to a separate context state for a 'character sheet' state. All the data successfully goes to my character sheet, and console.logs support everything is properly showing up, but it won't post to my url.
My model:
const mongoose = require("mongoose"),
Schema = mongoose.Schema;
const characterSheetSchema = new Schema({
characterPowers: {},
characterInventory: {},
characterArmor: {},
characterShield: {},
characterWeapon: {},
characterCoin: {},
characterHp: {},
characterStats: {},
characterExperience: { type: Number },
characterRace: {},
characterClass: {},
characterAge: {
type: Number,
},
characterName: {
type: String,
},
characterDescription: {
type: String,
},
characterLevel: { type: Number },
});
module.exports = CharacterSheet = mongoose.model(
"charactersheet",
characterSheetSchema
);
My routes:
const router = require('express').Router()
const CharacterSheet = require('../../models/chracterSheet/characterSheet.model')
router.post("/createcharactersheet", (req, res) => {
try {
let {
characterPowers,
characterInventory,
characterArmor,
characterShield,
characterWeapon,
characterCoin,
characterHp,
characterStats,
characterExperience,
characterRace,
characterClass,
characterAge,
characterName,
characterDescription,
characterLevel
} = req.body
const newCharacterSheet = new CharacterSheet({
characterPowers,
characterInventory,
characterArmor,
characterShield,
characterWeapon,
characterCoin,
characterHp,
characterStats,
characterExperience,
characterRace,
characterClass,
characterAge,
characterName,
characterDescription,
characterLevel
})
const savedCharacterSheet = newCharacterSheet.save()
res.json(savedCharacterSheet)
} catch (err) {
res.status(500).json({err: err.message})
}
})
router.get('/viewcharactersheets', (req, res) => {
CharacterSheet.find({}, function(err, charactersheets) {
if (err) {
console.log(err)
} else {
return res.json({charactersheets: charactersheets})
}
})
})
module.exports = router
My post request:
Axios.post("http://localhost:5000/characters/createcharactersheet", {
characterPowers: characterSheet.characterPowers,
characterInventory: characterSheet.characterInventory,
characterArmor: characterSheet.characterArmor,
characterShield: characterSheet.characterShield,
characterWeapon: characterSheet.characterWeapon,
chacterCoin: characterSheet.characterCoin,
characterHp: characterSheet.characterHp,
characterStats: characterSheet.characterStats,
characterExperience: characterSheet.characterExperience,
characterRace: characterSheet.characterRace,
characterClass: characterSheet.characterClass,
characterAge: characterSheet.characterAge,
characterName: characterSheet.characterName,
characterDescription: characterSheet.characterDescription,
characterLevel: characterSheet.characterLevel,
});
My Terminal
My error
POST error
Uncaught in promise error
Everything else works and goes into my restful api, but for a reason unknown to me, it won't post to my createcharactersheet document or api.
Any insight would be appreciated.
Mongoose Model.save() returns an Promise to try to use async/await
async/await way:
router.post("/createcharactersheet", async(req, res) => {
...
try {
const newCharacterSheet = new CharacterSheet({
...
})
await newCharacterSheet.save()
res.status(201).json(newCharacterSheet)
} catch (error) {
res.status(500).send(e.message)
{
})
or (im not sure)
const savedCharacterSheet = newCharacterSheet.save()
savedCharacterSheet
.then(saved =>
res.json(saved)
)
.catch(e =>
res.status(500).send(e.message)
)
Edit
Aslo log you errors
catch (e) {
console.error(e)
}

Mock multiple api call inside one function using Moxios

I am writing a test case for my service class. I want to mock multiple calls inside one function as I am making two API calls from one function. I tried following but it is not working
it('should get store info', async done => {
const store: any = DealersAPIFixture.generateStoreInfo();
moxios.wait(() => {
const request = moxios.requests.mostRecent();
request.respondWith({
status: 200,
response: store
});
const nextRequest = moxios.requests.at(1);
nextRequest.respondWith({
status: 200,
response: DealersAPIFixture.generateLocation()
});
});
const params = {
dealerId: store.dealerId,
storeId: store.storeId,
uid: 'h0pw1p20'
};
return DealerServices.retrieveStoreInfo(params).then((data: IStore) => {
const expectedOutput = DealersFixture.generateStoreInfo(data);
expect(data).toMatchObject(expectedOutput);
});
});
const nextRequest is always undefined
it throw error TypeError: Cannot read property 'respondWith' of undefined
here is my service class
static async retrieveStoreInfo(
queryParam: IStoreQueryString
): Promise<IStore> {
const res = await request(getDealerStoreParams(queryParam));
try {
const locationResponse = await graphQlRequest({
query: locationQuery,
variables: { storeId: res.data.storeId }
});
res.data['inventoryLocationCode'] =
locationResponse.data?.location?.inventoryLocationCode;
} catch (e) {
res.data['inventoryLocationCode'] = 'N/A';
}
return res.data;
}
Late for the party, but I had to resolve this same problem just today.
My (not ideal) solution is to use moxios.stubRequest for each request except for the last one. This solution is based on the fact that moxios.stubRequest pushes requests to moxios.requests, so, you'll be able to analyze all requests after responding to the last call.
The code will look something like this (considering you have 3 requests to do):
moxios.stubRequest("get-dealer-store-params", {
status: 200,
response: {
name: "Audi",
location: "Berlin",
}
});
moxios.stubRequest("graph-ql-request", {
status: 204,
});
moxios.wait(() => {
const lastRequest = moxios.requests.mostRecent();
lastRequest.respondWith({
status: 200,
response: {
isEverythingWentFine: true,
},
});
// Here you can analyze any request you want
// Assert getDealerStoreParams's request
const dealerStoreParamsRequest = moxios.requests.first();
expect(dealerStoreParamsRequest.config.headers.Accept).toBe("application/x-www-form-urlencoded");
// Assert graphQlRequest
const graphQlRequest = moxios.requests.get("POST", "graph-ql-request");
...
// Assert last request
expect(lastRequest.config.url).toBe("status");
});

Resources