I have an azure function running locally in dev mode. I am trying to import node-fetch:
import { fetch } from "node-fetch";
module.exports = async function (context, req) {
context.log("JavaScript HTTP trigger function processed a request.");
const res = await fetch("https://www.swyx.io/api/rss.xml");
const responseMessage = "res:" + res.ok;
context.res = {
// status: 200, /* Defaults to 200 */
body: responseMessage,
};
};
I get the following error:
Worker was unable to load function HttpTrigger1: 'Cannot use import statement outside a module'
What I've tried:
I added type: 'module' to package.json.
I named the file index.cjs
But it still throws same error.
For reference, here is my package.json:
{
"name": "cors-test",
"version": "1.0.0",
"description": "",
"type": "module",
"scripts": {
"start": "func start",
"test": "echo \"No tests yet...\""
},
"dependencies": {
"node-fetch": "^3.3.0"
},
"devDependencies": {}
}
And here is the file structure:
.
├── host.json
├── HttpTrigger1
│ ├── function.json
│ ├── index.cjs
│ └── sample.dat
├── local.settings.json
├── package.json
├── package-lock.json
└── yarn.lock
I found the solution
renamed the file to index.mjs
removed module.exports and used export default instead:
import fetch from "node-fetch";
export default async function (context, req) {
context.log("JavaScript HTTP trigger function processed a request.");
const res = await fetch("https://www.swyx.io/api/rss.xml");
const responseMessage = "res:" + res.ok;
context.res = {
// status: 200, /* Defaults to 200 */
body: responseMessage,
};
}
Related
I am trying to deploy my NestJS project to AWS lambda with serverless framework, I followed official documentation
I created a file serverless.ts in src directory along with main.ts file.
When I run sls offline, it successfull runs and gives following output:
Running "serverless" from node_modules
Starting Offline at stage dev (us-east-1)
Offline [http for lambda] listening on http://localhost:3002
Function names exposed for local invocation by aws-sdk:
* main: projectName-dev-main
┌────────────────────────────────────────────────────────────────────────┐
│ │
│ ANY | http://localhost:4000/ │
│ POST | http://localhost:4000/2015-03-31/functions/main/invocations │
│ ANY | http://localhost:4000/{proxy*} │
│ POST | http://localhost:4000/2015-03-31/functions/main/invocations │
│ │
└────────────────────────────────────────────────────────────────────────┘
Server ready: http://localhost:4000 🚀
But when I open the localhost URL http://localhost:4000, I get 502 Bad gateway and
following error.
ANY / (λ: main)
✖ Unhandled exception in handler 'main'.
✖ Error: Cannot find module 'main'
Require stack:
- /home/my-PC/Desktop/projectName/node_modules/serverless-offline/src/lambda/handler-runner/in-process-runner/aws-lambda-ric/UserFunction.js
✖ Runtime.ImportModuleError: Error: Cannot find module 'main'
Require stack:
- /home/my-PC/Desktop/projectName/node_modules/serverless-offline/src/lambda/handler-runner/in-process-runner/aws-lambda-ric/UserFunction.js
at _loadUserApp (/home/my-PC/Desktop/projectName/node_modules/serverless-offline/src/lambda/handler-runner/in-process-runner/aws-lambda-ric/UserFunction.js:310:15)
at async module.exports.load (/home/my-PC/Desktop/projectName/node_modules/serverless-offline/src/lambda/handler-runner/in-process-runner/aws-lambda-ric/UserFunction.js:341:21)
at async InProcessRunner.run (file:///home/my-PC/Desktop/projectName/node_modules/serverless-offline/src/lambda/handler-runner/in-process-runner/InProcessRunner.js:41:21)
at async MessagePort.<anonymous> (file:///home/my-PC/Desktop/projectName/node_modules/serverless-offline/src/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js:25:14)
Here is code:
main.ts
import { NestFactory } from '#nestjs/core';
import { ValidationPipe } from '#nestjs/common';
import { AppModule } from './app.module';
async function bootstrap() {
process.env.TZ = 'Asia/Calcutta';
const app = await NestFactory.create(AppModule);
const port = process.env.PORT || 3000;
app.useGlobalPipes(new ValidationPipe({ whitelist: true }));
await app.listen(port);
}
bootstrap();
serverless.ts
import { NestFactory } from '#nestjs/core';
import serverlessExpress from '#vendia/serverless-express';
import { Callback, Context, Handler } from 'aws-lambda';
import { AppModule } from './app.module';
let server: Handler;
async function bootstrap(): Promise<Handler> {
const app = await NestFactory.create(AppModule);
await app.init();
const expressApp = app.getHttpAdapter().getInstance();
return serverlessExpress({ app: expressApp });
}
export const handler: Handler = async (
event: any,
context: Context,
callback: Callback,
) => {
server = server ?? (await bootstrap());
return server(event, context, callback);
};
serverless.yaml
service: myProject
useDotenv: true
plugins:
- serverless-offline
# - serverless-plugin-optimize
provider:
name: aws
runtime: nodejs16.x
region: us-east-1
profile: default
memorySize: 128
stage: dev
environment:
TZ: ${env:TZ}
functions:
main:
handler: dist/main.handler
events:
- http:
method: ANY
path: /
- http:
method: ANY
path: '{proxy+}'
custom:
serverless-offline:
noPrependStageInUrl: true
httpPort: 4000
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"
});
Setting up an AWS Lambda Layer in NodeJS.
The steps are clear.
Setup the following directory structure:
-layer
utils.js
-nodejs
package.json
package-lock.json
-node_modules
The utils file has a simple piece of code in it, like this:
export function get_exchange_rate(curr1, curr2){
return 100.00;
}
The package.json file contains this:
{
"name": "layer",
"version": "1.0.0",
"description": "",
"type": "module",
"main": "utils.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
}}
I zip up everything inside the layers folder and upload to Lambda Layers.
I attach the layer to the Lambda and my Lambda handler looks like this:
'use strict';
const opps = require('/opt/utils');
exports.handler = function(event, context) {
console.log("EXCHANGE RATE: ", opps.get_exchange_rate(1,2).toString())
};
I run it and it works fine.
But then I add an NPM module to the layer. I run npm install request, this adds request and dependencies to the node_modules folder and updates the packages.json file with the request dependency.
"dependencies": {
"request": "^2.88.2"
}
And in the utils.js file I add the following code:
import request from 'request'
export function get_status(){
request("http://www.google.com", (error, response, body) => {
console.log("error:", error);
console.log("statusCode:", response && response.statusCode);
console.log("body:", body);
});
}
I zip this all up and add to Lambda Layers, then call the get_status() function from Lambda, I receive this error:
SyntaxError: Cannot use import statement outside a module
I am currently working on an application running on Electron (former atom-shell), and trying to design a way to alert the user when a new update is available. To do this, I am using electron-updater in the way described in electron-updater-sample. I also configured Sinopia to be listening on http://localhost:4873/ (default behavior) and ran this commande line:
npm config set registry "http://localhost:4873"
I checked in the .npmrc file, the registry is properly set with the new value.
The problem I have is when I try to check for the update, I get this error message in console:
{ [HTTPError: Response code 404 (Not Found)]
message: 'Response code 404 (Not Found)',
code: undefined,
host: 'registry.npmjs.org',
hostname: 'registry.npmjs.org',
method: 'GET',
path: '/hacker-keyboard-electron',
statusCode: 404,
statusMessage: 'Not Found' }
So I believe I forgot something in the configuration of npm that makes the application listen to the regular path for npm rather than the Sinopia server. The question is what?
Please find below the code I am using:
foobar-generator
├── app
├── bower components
├── bower.json
├── index.html
├── index. js
├── main. js
├── nbproject
├── node modules
├── npm-debug.log
├── package.json
├── readme. md
└── sinopia
package.json
{
"name": "foobar-generator",
"version": "0.0.1",
"description": "A generator for foobar",
"main": "main.js",
"dependencies": {
"angular": "^1.4.7",
"bootstrap": "^3.3.5",
"chokidar": "^1.2.0",
"electron-debug": "^0.2.1",
"electron-packager": "^5.1.0",
"electron-plugins": "^0.0.4",
"electron-prebuilt": "^0.33.6",
"electron-rebuild": "^1.0.2",
"electron-updater": "^0.2.0",
"grunt": "^0.4.5",
"jquery": "^2.1.4"
},
"devDependencies": {},
"publishConfig": {
"registry": "http://localhost:4873/"
},
"registry": "http://localhost:4873/"
}
main.js
var appli = require('app');
var BrowserWindow = require('browser-window');
var updater = require('electron-updater');
var util = require('util');
// Report crashes to our server.
require('crash-reporter').start();
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
var mainWindow = null;
var loaded = false;
// Quit when all windows are closed.
appli.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') {
appli.quit();
}
});
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
appli.on('ready', function () {
updater.on('ready', function () {
// Create the browser window.
mainWindow = new BrowserWindow({width: 800, height: 600});
// and load the index.html of the app.
mainWindow.loadUrl('file://' + __dirname + '/index.html');
mainWindow.openDevTools({detach: true});
mainWindow.on('closed', function () {
mainWindow = null;
});
});
updater.on('updateRequired', function () {
appli.quit();
});
updater.on('updateAvailable', function () {
if (mainWindow) {
mainWindow.webContents.send('update-available');
}
});
updater.start();
updater.check(function (err, results) {
if (err) {
return console.error(util.inspect(err));
}
console.log(results);
});
});
Do you guys see anything I could have forgotten/done wrong?
By reading the manual for npmrc (npm help npmrc), I have discovered the the .npmrc file is not unique. By configuring the registry the way I did, I only changed the per-user .npmrc. But there also should be such a file in your project root directory! It is in this one that you should configure the registry you want to use. Adding this file in project root directory solved the problem I was facing.
You should listen to error event.
Try this
updater.on('error', function (err) {
console.log(err);
});
I am trying to configure the grunt connect such a way that
For static pages it serves pages from src directory
web service calls are intercepted by middle-ware and static json is served.
While the web service calls are being mocked correctly the connect.static call ends up giving an error
TypeError: undefined is not a function
While I realize that the connect.static was provided in later versions of this module, I have already upgraded to a version later than that
Here is my package.json file
{
"name": "my-angular-seed-project",
"version": "1.0.0",
"description": "angular seed with only bower and grunt",
"main": "index.js",
"dependencies": {
},
"devDependencies": {
"bower": "^1.4.1",
"grunt": "^0.4.5",
"grunt-cli": "^0.1.13",
"grunt-contrib-connect": ">=0.10.0",
"grunt-contrib-jshint": "latest",
"grunt-contrib-uglify": "latest",
"grunt-contrib-watch": "latest",
"jshint-stylish": "^2.0.1"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Here is the gruntfile.js
// Gruntfile.js
// our wrapper function (required by grunt and its plugins)
// all configuration goes inside this function
module.exports = function(grunt) {
var restEndPoints = {
"/restapi/users": {"GET":"json-files/users.get.json"},
"/restapi/users/login": {"GET":"json-files/users.get.json"},
"/restapi/users/john#gmail.com": {"GET":"json-files/users.get.john.json"},
"/restapi/nodes": {"GET":"json-files/nodes.get.json","PUT":"json-files/nodes.put.json","POST":"json-files/nodes.put.json"},
"/restapi/nodes/Node1": {"GET":"json-files/nodes.get.node1.json","DELETE":"json-files/nodes.delete.node1.json"},
"/restapi/services": {"GET":"json-files/services.get.json","PUT":"json-files/services.put.json","POST":"json-files/services.put.json"},
"/restapi/services/nginx": {"GET":"json-files/services.get.nginx.json","DELETE":"json-files/services.delete.nginx.json"},
"/restapi/commands": {"GET":"json-files/commands.get.json","PUT":"json-files/commands.put.json","POST":"json-files/commands.put.json"},
"/restapi/commands/pwd": {"GET":"json-files/commands.get.pwd.json","DELETE":"json-files/commands.delete.pwd.json"}
};
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;};
// ===========================================================================
// CONFIGURE GRUNT ===========================================================
// ===========================================================================
grunt.initConfig({
// get the configuration info from package.json ----------------------------
// this way we can use things like name and version (pkg.name)
pkg: grunt.file.readJSON('package.json'),
// all of our configuration will go here
watch: {
},
// configure jshint to validate js files -----------------------------------
jshint: {
options: {
reporter: require('jshint-stylish') // use jshint-stylish to make our errors look and read good
},
// when this task is run, lint the Gruntfile and all js files in src
build: ['Gruntfile.js', 'src/**/*.js']
},
// configure connect to run server (on test/serve or example)
connect: {
server: {
options: {
port : 8000,
hostname : 'localhost',
base : 'src',
middleware: function (connect,options){return [
//Middleware #1 - for rest api calls
function restapiMiddleware(req, res, next) {
if (req.url.indexOf('restapi') > 0){
console.log(req.method+' request received for webservice api ['+req.url+']');
var match = false;
var json_file_to_serve = "";
var keys = Object.keys(restEndPoints);
keys.forEach(function(urlAsKey) {
if (req.url.endsWith(urlAsKey)) {
Object.keys(restEndPoints[urlAsKey]).forEach(function(httpMethodsAsKey) {
if (req.method == httpMethodsAsKey){
match = true;
json_file_to_serve = restEndPoints[urlAsKey][httpMethodsAsKey];
}
}); //forEach ends
}
}); //forEach ends
//no match with the url, move along
if (match == false) {
return next();
}
if (req.url.endsWith('/login')){
res.writeHead(200, { 'user-auth-token':'56f7997504b352cbf6ba6210409e423f5fdac49a','user-enc-email':'lJUXityStsKko/lPr9eJUc5fLFCV5kFm' });
}
//Finalize this response with json file
res.end(grunt.file.read(json_file_to_serve));
// if not restapi call then goto next middleware
// can we serve static right here ?
}else{
return next();
}
} // element/middleware one ends so comma just json objects this is awesome
,
//Middleware #2 for static page calls
function staticMiddleware(connect,options) {
connect.static(options.base);
//connect.static('src');
}
] // array ends
}
}
}
}
});
// ===========================================================================
// LOAD GRUNT PLUGINS ========================================================
// ===========================================================================
// we can only load these if they are in our package.json
// make sure you have run npm install so our app can find these
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-watch');
//register the task
grunt.registerTask('serve', ['connect', 'watch']);
};
Am I missing something trivial here ?
Thanks #R4c00n & #Christian Fritz, I was going through the gruntfile of the grunt-contrib-connect and it uses the serveStatic call instead of connect.static and yes the module serve-static is part of grunt contrib connect's node_modules. So now a serveStatic(base.options) does wire the static files as well.
Here is the updated grunt file section (the serve static call has to be first though)
middleware: function (connect,options){return [
//statically serve pages from src directory
serveStatic('src'),
//Middleware #1 - for rest api calls
function restapiMiddleware(req, res, next) {
// middleware code
}];}