Shopify node api context initalize errors out - node.js

I'm trying to make an app following these directions:
https://github.com/Shopify/shopify-node-api/blob/main/docs/getting_started.md
I have all the code configred and it looks like this:
// src/index.ts
import http from 'http';
import url from 'url';
import querystring from 'querystring';
import Shopify, { ApiVersion } from '#shopify/shopify-api';
require('dotenv').config();
const { API_KEY, API_SECRET_KEY, SCOPES, SHOP, HOST } = process.env
Shopify.Context.initialize({
API_KEY,
API_SECRET_KEY,
SCOPES: [SCOPES],
HOST_NAME: HOST.replace(/https?:\/\//, ""),
HOST_SCHEME: HOST.split("://")[0],
IS_EMBEDDED_APP: {boolean},
API_VERSION: ApiVersion.{version} // all supported versions are available, as well as "unstable" and "unversioned"
});
// Storing the currently active shops in memory will force them to re-login when your server restarts. You should
// persist this object in your app.
const ACTIVE_SHOPIFY_SHOPS: { [key: string]: string | undefined } = {};
async function onRequest(
request: http.IncomingMessage,
response: http.ServerResponse,
): Promise<void> {
const {headers, url: req_url} = request;
const pathName: string | null = url.parse(req_url).pathname;
const queryString: string = String(url.parse(req_url).query);
const query: Record<string, any> = querystring.parse(queryString);
switch (pathName) {
default:
// This shop hasn't been seen yet, go through OAuth to create a session
if (ACTIVE_SHOPIFY_SHOPS[SHOP] === undefined) {
// not logged in, redirect to login
response.writeHead(302, {Location: `/login`});
response.end();
} else {
response.write('Hello world!');
// Load your app skeleton page with App Bridge, and do something amazing!
}
return;
} // end of default path
} // end of onRequest()
http.createServer(onRequest).listen(3000);
Package JSON looks like this:
{
"name": "shopify-checkout-apit",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"#shopify/shopify-api": "^3.1.0"
},
"devDependencies": {
"#types/node": "^17.0.40",
"dotenv": "^16.0.1",
"typescript": "^4.7.3"
},
"scripts": {
"build": "npx tsc",
"prestart": "yarn run build",
"start": "node dist/index.js"
}
}
When I go to run the app with yarn start I get a ton of errors
PS C:\Users\kawnah\shopify-checkout-apit> yarn start yarn run v1.22.18
$ yarn run build $ npx tsc src/index.ts:17:27 - error TS1003:
Identifier expected.
17 API_VERSION: ApiVersion.{version} // all supported versions are
available, as well as "unstable" and "unversioned"
~
src/index.ts:18:1 - error TS1005: ',' expected.
18 }); ~
Found 2 errors in the same file, starting at: src/index.ts:17
error Command failed with exit code 2. info Visit
https://yarnpkg.com/en/docs/cli/run for documentation about this
command. error Command failed with exit code 2. info Visit
https://yarnpkg.com/en/docs/cli/run for documentation about this
command. PS C:\Users\kawnah\shopify-checkout-apit>
I have no idea what any of this means.
Typescript Error TS1003 when attempting to access object properties using bracket notation
Why does this trigger an Identifier Expected error in Typescript?
I tried deleting node modules and reinstalling but it didn't work.
How do you fix this?

the config needs to look like this
Shopify.Context.initialize({
API_KEY,
API_SECRET_KEY,
SCOPES: [SCOPES],
HOST_NAME: HOST.replace(/https?:\/\//, ""),
HOST_SCHEME: HOST.split("://")[0],
IS_EMBEDDED_APP: true,
API_VERSION: ApiVersion.October21 // all supported versions are available, as well as "unstable" and "unversioned"
});

Related

React-Native Server Error When making a simple API request

I have a frontend in react-native that makes an API call using the axios library; its shown below:
function addItem(item) {
if (!item) {
Alert.alert('Error', 'Please enter a valid item.', [{text: 'Ok'}]);
} else {
axios.get('/additem', {
Id: items[items.length - 1].id + 1,
Text: item
})
.then((res) => {
setItems([...items, {id: res.id, text: res.text}])
})
.catch((err) => {
console.log(err);
})
}
}
As you can see, I am making a GET request to an endpoint, and using the response data.
Here is what my backend endpoint looks like in Node.js (using Express.js):
app.get('/additem', (req, res) => {
const item = new Item({
id: req.body.Id,
text: req.body.Text
});
item.save()
.then((result) => {
res.send(result)
})
.catch((err) => {
console.log(err)
})
})
The save() function and Item object are just specific to MongoDB, so don't worry too much about that.
I am using a proxy to "connect" the backend and frontend, meaning, I have added this to my package.json file in my frontend:
{
"name": "firstProj",
"version": "0.0.1",
"private": true,
"proxy": "https://localhost:5000",
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
localhost:5000 is where my node.js backend is running
Now when I try to access the endpoint via my frontend, react-native yells at me saying this:
LOG [Error: Network Error]
Zero clue why this is happening. Any help is appreciated. :) Let me know if you need more information from my end.
Thanks a ton.
EDIT:
this is the full error when not caught by my code:
Possible Unhandled Promise Rejection (id: 0):
Error: Network Error
createError#http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:99656:26
handleError#http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:99560:27
dispatchEvent#http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:32348:31
setReadyState#http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:31432:33
__didCompleteResponse#http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:31248:29
emit#http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:3537:42
__callFunction#http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:2765:36
http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:2497:31
__guard#http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:2719:15
callFunctionReturnFlushedQueue#http://10.0.2.2:8081/index.bundle?platform=android&dev=true&minify=false:2496:21
callFunctionReturnFlushedQueue#[native code]
just Remember to not put http://localhost:PORT into API Address because it will not work in that way
the way you should do it is first find your internet IP address on your machine like :
108.67.122.124
and then you change setting in your backend Service and replace localhost with this :
108.67.122.124:PORT
and then Address it like that to your AXIOS or whatever library you use
So lets wrap it again :
DONT address your react native like http:localhost:5000 instead do it like 108.67.122.124:5000 In that way it will fully work

Unhandled error while running jest-puppeteer test

I am trying to set up testing for my puppeteer project. I was following a basic guide and the test passes but there is 2 console errors in the terminal.
The error doesn't show up when using https://google.com or https://youtube.com. So it looks like it could be a thing with the specific site?
console.error
Unhandled error
at process.uncaught (node_modules/jest-jasmine2/build/jasmine/Env.js:248:21)
at handler (node_modules/jest-environment-puppeteer/lib/PuppeteerEnvironment.js:17:11)
at map (node_modules/mitt/src/index.ts:74:75)
at Array.map (<anonymous>)
at Object.emit (node_modules/mitt/src/index.ts:74:56)
at Page.emit (node_modules/puppeteer/lib/EventEmitter.js:72:22)
console.error
at process.uncaught (node_modules/jest-jasmine2/build/jasmine/Env.js:249:21)
at handler (node_modules/jest-environment-puppeteer/lib/PuppeteerEnvironment.js:17:11)
at map (node_modules/mitt/src/index.ts:74:75)
at Array.map (<anonymous>)
at Object.emit (node_modules/mitt/src/index.ts:74:56)
at Page.emit (node_modules/puppeteer/lib/EventEmitter.js:72:22)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 5.613 s
Ran all test suites.
Here is my code
describe('NCAA Home', () => {
beforeAll(async () => {
await page.goto('http://stats.ncaa.org/rankings/change_sport_year_div');
});
it('should be titled "NCAA Statistics"', async () => {
await expect(page.title()).resolves.toMatch('NCAA Statistics');
});
});
Here is my jest.config.js
module.exports = {
preset: "jest-puppeteer",
testMatch: [
"**/test/**/*.test.js"
],
verbose: true
}
package.json
{
"name": "stackoverflow",
"version": "1.0.0",
"description": "",
"main": "index.js",
"jest": {
"preset": "jest-puppeteer"
},
"scripts": {
"test": "jest"
},
"author": "",
"license": "ISC",
"devDependencies": {
"jest": "^26.1.0",
"jest-puppeteer": "^4.4.0"
},
"dependencies": {
"puppeteer": "^5.1.0"
}
}
All of the things I have come across have mentioned an issue with async/await but anything I have tried produces the same, if not, more errors. I have made a new project with these files and I am getting the same error
The error is from the website itself. Check the console of the website. Hence for a websites like google.com or youtube.com, it works without any errors.
I have created clean repo which reproduces issue.
https://github.com/sergtimosh/jest-puppeteer-issue-reproduction.git
clone repository
npm i
npm test test.spec.js
or
HEADLESS=false npm test test.spec.js
A workaround is to create incognito browser context in jest-environment.js.
Just uncomment two lines in this file and tests are passing with no issues. But problem is still here if you need to share browser context between test suites(files).
const PuppeteerEnvironment = require('jest-environment-puppeteer');
class JestEnvironment extends PuppeteerEnvironment {
async setup() {
await super.setup()
//to fix issue uncomment next two lines
// const incognitoContext = await this.global.browser.createIncognitoBrowserContext()
// this.global.page = await incognitoContext.newPage()
}
async teardown() {
await super.teardown()
}
}
module.exports = JestEnvironment;

Deploy Express server and test GraphQL API via CircleCI

I wish to test that my Express server launches properly and that my endpoint retrieves the correct information. I wish to do this in CI so that I can monitor when my application is no longer working, if I make any changes in the future.
It's a very simple application, my server looks like this:
server.js
import express from 'express';
import graphqlHTTP from 'express-graphql';
import { GraphQLObjectType, GraphQLString, GraphQLSchema } from 'graphql';
import cors from 'cors';
const QueryRoot = new GraphQLObjectType({
name: 'Query',
fields: () => ({
hello: {
type: GraphQLString,
resolve: () => "Hello world!"
}
})
});
const schema = new GraphQLSchema({ query: QueryRoot });
const app = express();
app.use(cors()); // enable cors
app.use('/api', graphqlHTTP({
schema: schema,
graphiql: true,
}));
app.listen(1337, () => {
console.log('Server running on port: 1337');
});
basicTest.test.js:
const chai = require('chai');
const expect = chai.expect;
const url = `http://localhost:1337`;
const request = require('supertest')(url);
describe('GraphQL', () => {
it('Response returns hello world', (done) => {
request.post('/api')
.send({ query: ' { hello }' })
.expect(200)
.end((err, res) => {
if (err) return done(err);
expect(res.body.data.hello).to.contain('Hello world!');
done();
});
});
});
My .circleci/config.yml looks like this:
# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/node:10.16.0
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/mongo:3.4.4
working_directory: ~/repo
steps:
- checkout
# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run: npm install
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
- run:
npm start &
npm test
and package.json:
{
"name": "graphql-express-server",
"repository": {
"url": "myURL"
},
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "nodemon -r esm server.js",
"test": "mocha test/*.test.js"
},
"author": "AuthorName",
"license": "ISC",
"dependencies": {
"cors": "^2.8.5",
"esm": "^3.2.25",
"express": "^4.17.1",
"express-graphql": "^0.9.0",
"graphql": "^14.4.2",
"nodemon": "^1.19.1",
"supertest": "^4.0.2"
},
"devDependencies": {
"chai": "^4.2.0",
"mocha": "^6.2.0"
}
}
I tried adding & to the end of my npm start command but that just skips the entire process as far as I can see. The issue I'm getting is 'Error: ECONNREFUSED: Connection refused' when the test gets executed.
Do I need to host the server elsewhere? I'm unsure what I'm supposed to do. I've never really tested the back end in CI before.
EDIT:
My commands are as follows:
- run:
npm start &
- run:
sleep 5
- run:
npm test
And my output in CI is as follows:
--------------------------------
***npm start &***
#!/bin/bash -eo pipefail
npm start &
--------------------------------
***sleep 5***
#!/bin/bash -eo pipefail
sleep 5
--------------------------------
***npm test***
#!/bin/bash -eo pipefail
npm test
> graphql-express-server#1.0.0 test /home/circleci/repo
> mocha test/*.test.js
GraphQL
1) Response returns hello world
0 passing (14ms)
1 failing
1) GraphQL
Response returns hello world:
Error: ECONNREFUSED: Connection refused
at Test.assert (node_modules/supertest/lib/test.js:165:15)
at localAssert (node_modules/supertest/lib/test.js:131:12)
at /home/circleci/repo/node_modules/supertest/lib/test.js:128:5
at Test.Request.callback (node_modules/superagent/lib/node/index.js:728:3)
at ClientRequest.req.once.err (node_modules/superagent/lib/node/index.js:647:10)
at Socket.socketErrorListener (_http_client.js:392:9)
at emitErrorNT (internal/streams/destroy.js:91:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
at process._tickCallback (internal/process/next_tick.js:63:19)
npm ERR! Test failed. See above for more details.
Exited with code 1
--------------------------------
As you can see, the message Server running on port: 1337 does not show up in my npm start & step console section.
Any suggestions? Am I doing something wrong?
npm start & won't wait for server to start, are you sure your server is listening on the port by the time your test makes a request? I.e. do you have 'Server running on port: 1337' in your console on CI? If not then try running sleep 3 before starting tests

What is the most simplest way of implementing a DELETE request using axios?

I have been unsuccessful in trying to figure out how to solve the following errors, (1st error:)'OPTIONS http://localhost:3000/lists/5a9dca48cebb5a4e5fc1bfe9 404 (Not Found)' and (2nd error:)'Failed to load http://localhost:3000/lists/5a9dca48cebb5a4e5fc1bfe9: Response for preflight has invalid HTTP status code 404.'.
Initially I defined my code along the same lines as the following: https://github.com/20chix/Hotel_System_Vue.js_Frontend/blob/master/src/components/Hello.vue
Seen quite a number of posts similar to my problem, but neither of their suggested solutions have worked for me.
I'm using Vue.js, Axios and Node.js in the back, my collection is defined as follows in MongoDb:
List: {_id:'', name:'', items:
[ {
title: '',
category: ''
}
]
}
GetList.vue:
methods: {
fetchLists(){
let uri = 'http://localhost:3000/lists';
axios.get(uri).then((response) => {
this.List = response.data;
console.log(this.List[3].items[0]);
console.log(this.List);
});
},
DELETE(a_list, id){
$("#myModal").modal('show');
this.list = a_list;
this._id = id;
},
deleteList : function(_id){
// let uri = 'http://localhost:3000/lists/'+_id;
// this.List.splice(_id, 1);
axios.delete('http://localhost:3000/lists/'+_id)
.then((response) => {
this.fetchLists();
//refreshes Application
// window.location.reload();
})
.catch((error) => {
console.log(error);
});
}
ListController:
exports.delete_a_list = function(req, res)=>{
console.log(req.params);
List.deleteOne({req.params.listId}, function(err, list){
if(err){res.json(err);};
else
{res.json({list: 'List successfully deleted'});}
};
});
UPDATE:
Upon running 'npm install cors --save', it was stored in my package.json .
server/package.json:
{
"name": "api",
"version": "1.0.0",
"description": ":)",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"keywords": [
":)"
],
"license": "ISC",
"devDependencies": {
"nodemon": "^1.17.1"
},
"dependencies": {
"cors": "^2.8.4",
"express": "^4.16.2",
"mongoose": "^5.0.8",
"npm": "^5.7.1"
}
}
UPDATE:
I tried the following too:
ObjectID = require('mongodb').ObjectID;
exports.delete_a_list = function(req, res){
// console.log(req.params);
List.deleteOne({
_id: ObjectID(req.params.listId)}, function(err, list){
if(err)
res.json(err);
res.json({list: 'List successfully deleted'});
});
};'
This returns the same error including:
xhr.js?ec6c:178 OPTIONS http://localhost:3000/lists/undefined 404 (Not Found)
dispatchXhrRequest # xhr.js?ec6c:178
xhrAdapter # xhr.js?ec6c:12
dispatchRequest # dispatchRequest.js?c4bb:59
Promise.then (async)
request # Axios.js?5e65:51
Axios.(anonymous function) # Axios.js?5e65:61
wrap # bind.js?24ff:9
deleteList # GetList.vue?c877:131
boundFn # vue.esm.js?efeb:190
click # GetList.vue?d584:124
invoker # vue.esm.js?efeb:2004
fn._withTask.fn._withTask # vue.esm.js?efeb:1802
:1 Failed to load http://localhost:3000/lists/undefined: Response for preflight has invalid HTTP status code 404.
createError.js?16d0:16 Uncaught (in promise) Error: Network Error
at createError (createError.js?16d0:16)
at XMLHttpRequest.handleError (xhr.js?ec6c:87)
Thank you guys for all your suggestions.
I found the following video: https://www.youtube.com/watch?v=NEFfbK323Ok, from The Net Ninja, and was able to get it to finally work upon changing my code to reflect his particular method:
listRoutes.js:
app.route('/lists/:_id')
.get(lists.read_a_list)
// .update(lists.update_a_list)
.delete(lists.delete_a_list);
listController.js:
exports.delete_a_list = function(req, res){
// console.log(req.params);
List.findByIdAndRemove({_id: req.params._id}).then(function(list){
res.send(list);
});
};
GetList.vue:
deleteList : function(_id, List){
axios.delete('http://localhost:3000/lists/'+_id, List)
.then(response => {
this.List.splice(index, 1);
//refreshes Application
// window.location.reload();
})
}
Your problem ist related to CORS (cross-origin-resource-sharing).
If you are using node with express then just include this middleware:
https://www.npmjs.com/package/cors
This query seems wrong:
List.deleteOne({req.params.listId}, ...
Can you try modifying it like this?:
List.deleteOne({_id: ObjectID(req.params.listId}), ...
(You need to have ObjectID declared somewhere up: ObjectID = require('mongodb').ObjectID)

Using passport-google-oauth with react-native

I'm trying to use passport-google-oauth in my react-native application. When I run the app it throws the error: requiring unknown module util . I've installed the package using npm install .. and I've also tried npm install ... --save
App/Components/Login.js
'use strict';
var React = require('react-native');
var GoogleStrategy = require('passport-google-oauth').OAuthStrategy;
...
package.json
{
"name": "NativeApp",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node_modules/react-native/packager/packager.sh"
},
"dependencies": {
"passport": ">= 0.0.0",
"passport-google-oauth": "^0.2.0",
"react-native": "^0.4.4"
},
"devDependencies": {}
}
index.ios.js
'use strict';
var React = require('react-native');
var Login = require('./App/Components/login');
var {
AppRegistry,
StyleSheet,
Text,
View,
NavigatorIOS,
} = React;
class AppStoreIOS extends React.Component{
render() {
return (
<NavigatorIOS
titleTextColor = '#0073A0'
// barTintColor = '#183E63'
initialRoute={{
component: Login,
title: 'AppStore v2.0',
passProps: { myProp: 'foo' },
}}
/>
);
}
};
Don't think this going to work for you. Passport expects to be run in an node.js (express based) environment, and will at least require some work to port it to using a webview for the Oauth flow, realistically it will be a lot of work.
Have a look at https://medium.com/#jtremback/oauth-2-with-react-native-c3c7c64cbb6d for an example of how to support oauth in react-native. I haven't tried this, but it looks pretty straight forward.

Resources