Octokit Express Middleware with Next.js - node.js

I am just practicing creating a GitHub app. Part of the Octokit it says that I can use the createNodeMiddleware. Now that might not necessarily be as simple with next.js; however, the problem that I am having is actually a compiler error (it seems) where it says that it cannot read properties of undefined (reading 'substr') when I am trying to just create a new instance of the App object.
Here is my code
import { Octokit, App } from "octokit";
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
// This function can be marked `async` if using `await` inside
export function middleware(request: NextRequest) {
const myApp = new App({
appId: 123,
privateKey: "",
});
return NextResponse.redirect(new URL('/about-2', request.url))
}
// See "Matching Paths" below to learn more
export const config = {
matcher: '/about/:path*',
}
When it executes the line for const myApp = new App({... it throws this error. Any ideas on where to start with this? I realize that I may need to manually make the routes that it creates with the middleware in the end. But I was hoping to at least be able to create an instance of the App with Octokit as it seems like that will be necessary no matter what functionality that I want from octokit. This is a nextjs app bootstraped with create-next-app and the typescript template.
Server Error
TypeError: Cannot read properties of undefined (reading 'substr')
This error happened while generating the page. Any console logs will be displayed in the terminal window.
Call Stack
<unknown>
node_modules\universal-user-agent\dist-web\index.js (6:0)
getUserAgent
node_modules\universal-user-agent\dist-web\index.js (6:26)
eval
node_modules\#octokit\endpoint\dist-web\index.js (359:64)
(middleware)/./node_modules/#octokit/endpoint/dist-web/index.js
evalmachine.<anonymous> (138:1)
__webpack_require__
evalmachine.<anonymous> (37:33)
fn
evalmachine.<anonymous> (269:21)
eval
webpack-internal:///(middleware)/./node_modules/#octokit/request/dist-web/index.js (5:75)
(middleware)/./node_modules/#octokit/request/dist-web/index.js
evalmachine.<anonymous> (248:1)
__webpack_require__
evalmachine.<anonymous> (37:33)
fn
evalmachine.<anonymous> (269:21)
eval
webpack-internal:///(middleware)/./node_modules/#octokit/core/dist-web/index.js (8:74)

Related

Using serverless deployment to lambda with ES6 /Node.js v16

Newbie question....
I have a locally working node.js application which I am now trying to deploy express to AWS lambda. I have used this guide to deploy a test version (which worked).
I now am trying to implement my application which uses ES6 (and has type: module in package.json).
In my application I have added
import serverless from 'serverless-http'
but I cannot figure out the appropriate syntax for the export - the original was...
module.exports.handler = serverless(app);
I have tried:
const handler = async (app) =\> {
return serverless(app)
}
export default handler
Error message received:
2022-11-05T15:50:25.962Z undefined ERROR Uncaught Exception
"errorType": "Runtime.HandlerNotFound",
"errorMessage": "app.handler is undefined or not exported",
"stack": [
"Runtime.HandlerNotFound: app.handler is undefined or not exported",
" at Object.UserFunction.js.module.exports.load (file:///var/runtime/index.mjs:979:15)",
" at async start (file:///var/runtime/index.mjs:1137:23)",
" at async file:///var/runtime/index.mjs:1143:1"
]
I strongly suspect I am missing some fundamental understanding - truly appreciate some guidance.
The reason for the error is that you are sending a default export when AWS Lambda is expecting a named export.
The issue is the same as with all ES6 imports/exports:
// export.js
export default const defaultExport = "foo"
export const namedExport = "bar"
// import.js
import { defaultExport } from "./export.js" // error, cannot find defaultExport
import { namedExport } from "./export.js" // success, found namedExport
import defaultExport from "./export.js" // success, found defaultExport
So, it's like the case above where you're sending the defaultExport, but AWS Lambda wants the { namedExport }. You just need to remove default from your export, and make sure you're building the handler properly. Here is a suggestion to do that:
const lambda = serverless(app)
export async function handler(event, context) {
return lambda(event, context)
}
I've tested and it's working with serverless-offline using Node18.x. You can read more about exports on MDN.

worker-loader cannot work with wasm-loader and typescript in react project

I've tried:
// Worker.ts
// #ts-ignore
// eslint-disable-next-line no-restricted-globals
const ctx: Worker = self as any;
// Post data to parent thread
// ctx.postMessage({ foo: "foo" });
// Respond to message from parent thread
ctx.addEventListener('message', async ({ data }) => {
const {
href,
width,
height
} = data;
const { qrcode } = await import('uranus-qrcode');
const qr = qrcode(href, width, height);
ctx.postMessage({ href, qr });
});
in which uranus-qrcode is a Rust-Wasm module I created. I use wasm-loader to load it, and it works when I load it into the main thread, but when I tried it with worker-loader it says:
Uncaught (in promise) TypeError: Cannot read property './modules/uranus_qrcode/uranus_qrcode_bg.wasm' of undefined
at Object../modules/uranus_qrcode/uranus_qrcode_bg.wasm (http://localhost:3334/0.34621aa454b5fe6ea3b4.worker.js:145:40)
at __webpack_require__ (http://localhost:3334/34621aa454b5fe6ea3b4.worker.js:34:30)
at Module../modules/uranus_qrcode/uranus_qrcode.js (http://localhost:3334/0.34621aa454b5fe6ea3b4.worker.js:12:80)
at __webpack_require__ (http://localhost:3334/34621aa454b5fe6ea3b4.worker.js:34:30)
at async http://localhost:3334/34621aa454b5fe6ea3b4.worker.js:139:7
Now the workerize method works!
I've originally tried workerize-loader + wasm-loader, and it works pretty well in the dev mode but once it is compiled, the prototype will not be added to the worker (suspecting it's a bug in workerize-loader because all workerized modules behave the same). This indeed turns out to be a bug in workerize-loader (see workerize-loader failed to work after compiling and Version 1.2.0 does not export function on worker instance in production mode). After upgrading to the workerize-loader 1.2.1, it works in both dev and prod code.
I have updated the Master repo: https://github.com/aeroxy/react-typescript-webassembly-starter.git

How to remove or replace all console.log in Angular SSR

I've built an angular project with CLI. when I run the project It shows all console.log that I used in development mode. Then I googled and found a solution. Replaced with empty function in the production mode by adding two lines of code in main.ts file:
if (environment.production) {
enableProdMode();
if (window) {
window.console.log = window.console.warn = window.console.info = window.console.debug = function () {/* no log */ };
}
}
It helps me to get rid out of that problem in production mode and saves a lot of time of removing all console.log lines manually. So, I added those lines in main.server.ts file also to solve the problem in SSR.
But, the problem is when I build with angular SSR and run the project it returns errors:
ReferenceError: window is not defined
at Object.K011 (C:\xampp\htdocs\10MS\10-minute-school-3.0\dist\server\main.js:1:176367)
at __webpack_require__ (C:\xampp\htdocs\10MS\10-minute-school-3.0\dist\server\main.js:1:295)
at Object.0 (C:\xampp\htdocs\10MS\10-minute-school-3.0\dist\server\main.js:1:5525)
at __webpack_require__ (C:\xampp\htdocs\10MS\10-minute-school-3.0\dist\server\main.js:1:295)
at +JNS (C:\xampp\htdocs\10MS\10-minute-school-3.0\dist\server\main.js:1:1624)
at Object.<anonymous> (C:\xampp\htdocs\10MS\10-minute-school-3.0\dist\server\main.js:1:1669)
at Module._compile (internal/modules/cjs/loader.js:956:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:973:10)
at Module.load (internal/modules/cjs/loader.js:812:32)
at Function.Module._load (internal/modules/cjs/loader.js:724:14)
I understand the problem that there is no global window variable in nodejs. But, I need to remove all console.log lines. How can I able to remove all console.log lines in SSR build.
Instead of doing it in the main.ts file, you can override the console methods (log, warn, error, etc) in the app.module.ts file just before the app is initialized. This can be done using the APP_INITIALIZER injector token that allows you run some custom initialization logic needed for your app.
The PLATFORM_ID is another injector token that is provided by the Angular once the platform is initialized (platform can be server, browser or web worker) and it is available before application initialization. Using this token we can determine the platform using the isPlatformBrowser(platformId) method which returns true if the platform is a browser.
We can combine the above 2 strategies to override the console methods as below.
app.module.ts
import {
NgModule,
Injector,
APP_INITIALIZER,
PLATFORM_ID
} from "#angular/core";
import { isPlatformBrowser, isPlatformServer } from "#angular/common";
import { environment } from '../environments/environment';
...
/**
* Factory method to override the console methods
* during app initialization
*/
function silenceConsoleMethods(injector: Injector) {
return () => {
const platformId = injector.get(PLATFORM_ID);
if (isPlatformBrowser(platformId) && environment.production) {
window.console.log = window.console.debug = window.console.warn = window.console.error = () => {};
} else if (isPlatformServer(platformId)) {
console.log = console.debug = console.warn = console.error = () => {};
}
};
}
#NgModule({
...
providers: [
{
provide: APP_INITIALIZER,
useFactory: silenceConsoleMethods,
deps: [Injector],
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule {}
You can find a working version of the above example in Stackbliz here. To demonstrate the solution works, I have overriden all console logging methods except error to show the error messages on console.
P.S:
You can use isPlatformServer(platformId) to determine if the platform is server and perform any initialization logic related to server side rendering.
Edit:
Updated silenceConsoleMethods() in the app.module.ts file to override the console object when the app is rendered using Nodejs runtime. Now you should not face any problem when the app is rendered on server side.

Syntax error when I access the "process.env" on Vue.js

I got a problem when I try to access the variable:process.env. It told me I got a syntax error and I'm 100% sure that my code is correct.
I want to know what problem with it
I tried check my codes over and over again. I can't find any syntax error.By the way, it's ok when I access the proceess varible. But when I try to access the process.env, it started to execute eval, which raised the error I mentioned before.
My code goes that :
src/global.vue
console.log(process.env);
The error I got:
Uncaught SyntaxError: Unexpected token :
at Object../node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/App.vue (app.js:1170)
at __webpack_require__ (app.js:679)
at fn (app.js:89)
at eval (App.vue?9e04:1)
at Object../src/App.vue (app.js:5245)
at __webpack_require__ (app.js:679)
at fn (app.js:89)
at eval (main.js:5)
at Object../src/main.js (app.js:5357)
at __webpack_require__ (app.js:679)
The app.js:1170 goes that:
eval("/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__components_headers__ = __webpack_require__(\"./src/components/headers.vue\");\n/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__components_blogfooter__ = __webpack_require__(\"./src/components/blogfooter.vue\");\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n// import axios from 'axios'\n\n\n/* harmony default export */ __webpack_exports__[\"a\"] = ({\n name: 'App',\n components: { 'headers': __WEBPACK_IMPORTED_MODULE_0__components_headers__[\"a\" /* default */],\n 'blog-footer': __WEBPACK_IMPORTED_MODULE_1__components_blogfooter__[\"a\" /* default */]\n },\n created: function created() {\n this.$store.dispatch('GET_BASIC');\n console.log(Object({\"NODE_ENV\":\"development\",\"SERVER\":http://localhost:8000}));\n }\n});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYmFiZWwtbG9hZGVyL2xpYi9pbmRleC5qcyEuL25vZGVfbW9kdWxlcy92dWUtbG9hZGVyL2xpYi9zZWxlY3Rvci5qcz90eXBlPXNjcmlwdCZpbmRleD0wIS4vc3JjL0FwcC52dWUuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vQXBwLnZ1ZT8yNmNkIl0sInNvdXJjZXNDb250ZW50IjpbIjx0ZW1wbGF0ZT5cbiAgPGRpdj5cbiAgICA8ZGl2IGNsYXNzPVwid3JhcFwiPlxuICAgICAgPGhlYWRlcnM+PC9oZWFkZXJzPlxuICAgICAgPHRyYW5zaXRpb24+XG4gICAgICAgIDxyb3V0ZXItdmlldz48L3JvdXRlci12aWV3PlxuICAgICAgPC90cmFuc2l0aW9uPlxuICAgICAgPGJsb2ctZm9vdGVyPjwvYmxvZy1mb290ZXI+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC90ZW1wbGF0ZT5cblxuPHNjcmlwdD5cbiAgLy8gaW1wb3J0IGF4aW9zIGZyb20gJ2F4aW9zJ1xuICBpbXBvcnQgSGVhZGVycyBmcm9tICdAL2NvbXBvbmVudHMvaGVhZGVycydcbiAgaW1wb3J0IEZvb3RlciBmcm9tICdAL2NvbXBvbmVudHMvYmxvZ2Zvb3RlcidcbiAgZXhwb3J0IGRlZmF1bHQge1xuICAgIG5hbWU6ICdBcHAnLFxuICAgIGNvbXBvbmVudHM6eydoZWFkZXJzJzpIZWFkZXJzLFxuICAgICAgICAgICAgICAgICdibG9nLWZvb3Rlcic6Rm9vdGVyXG4gICAgfSxcbiAgICBjcmVhdGVkICgpIHtcbiAgICAgIHRoaXMuJHN0b3JlLmRpc3BhdGNoKCdHRVRfQkFTSUMnKTtcbiAgICAgIGNvbnNvbGUubG9nKHByb2Nlc3MuZW52KVxuICAgIH0sXG4gIH1cblxuPC9zY3JpcHQ+XG5cbjxzdHlsZT5cblxuPC9zdHlsZT5cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyBBcHAudnVlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFhQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQURBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFSQSIsInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/App.vue\n");
I solve it by adding double quotes on the value of the variable SERVER:
Old code
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
SERVER: 'http://localhost:8000'
})
New code
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
SERVER: '"http://localhost:8000"'
})
I don't know why it has no hint to tell me that thing. The grammar of config file is so weird that you need to put a quote outside an existed quote.
Can anyone tell me why?
After instpecting the error in app.js:1170 one can see that your process.env.serversomehow misses " - why that is no clue but i think this should be fixable now^^
currently:
{server: http://localhost:8000}
but should be
{server:"http://localhost:8000"}
I had a similar problem when working in a project with webpack, I made a configuration of the .env to node and to the test environment, but when running in the web environment, this same error message, as if the process. envdid not exist. In my case I was using the dotenv lib, so it was pretty simple to solve, I just saw that theJSON.stringifysetting inDefinePlugin` was missing.
Resolved configuring it this way:
new webpack.DefinePlugin({
"process.env": JSON.stringify(dotenv.parsed),
})

Unable to create a Pool instance with constructor in jest test

When I run a jest test, creating a Pool instance when I require the pool, it returns a _pg.Pool is not a constructor error.
I have tried looking at the StackOverflow: pg.Pool is not a constructor
And this still does not work.
However, I am able to create a pool instance when I run the code, the error only shows up in Jest.
Node code:
import { Pool } from 'pg'
const pool = new Pool({configs})
export default pool
Error log:
● Test suite failed to run
TypeError: _pg.Pool is not a constructor
> 6 | const pool = new Pool({
|
at Object.<anonymous> (src/resources/connection.js:6:14)
at Object.require (src/routes/api.js:2:20)
at Object.<anonymous> (src/__tests__/integration/user.test.js:8:1)
sidenote: the code is a copy of the documentation in https://node-postgres.com/api/pool
I don't expect an error to occur, since pg.Pool is a class with a constructor.
In case anyone comes across the same problem, I solved it by installing pg-pool, which has been merged into main pg package, and then importing pg-pool's Pool instead of pg's.
Reference: https://github.com/brianc/node-postgres/tree/master/packages/pg-pool
I wanted to add an alternate answer because for me the issue was very subtle and simple to fix.
I have a wrapper module that leverages pg and which historically has imported it via:
import * as postgresql from 'pg';
I've always used this.pool = new postgresql.Pool( { ...bits } );
This of course led to the following error today when updating my module to be pure ESM:
TypeError: postgresql.Pool is not a constructor
at new PostgreSQLDriver (file:///home/rik/workspaces/kwaeri/node-kit/postgresql-database-driver/dist/src/postgresql-database-driver.mjs:35:278)
at file:///home/rik/workspaces/kwaeri/node-kit/postgresql-database-driver/dist/test/postgresql-database-driver.mjs:23:559
at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:528:24)
at async importModuleDynamicallyWrapper (node:internal/vm/module:438:15)
at async formattedImport (/home/rik/workspaces/kwaeri/node-kit/postgresql-database-driver/node_modules/mocha/lib/nodejs/esm-utils.js:7:14)
at async exports.loadFilesAsync (/home/rik/workspaces/kwaeri/node-kit/postgresql-database-driver/node_modules/mocha/lib/nodejs/esm-utils.js:91:20)
at async singleRun (/home/rik/workspaces/kwaeri/node-kit/postgresql-database-driver/node_modules/mocha/lib/cli/run-helpers.js:125:3)
at async exports.handler (/home/rik/workspaces/kwaeri/node-kit/postgresql-database-driver/node_modules/mocha/lib/cli/run.js:370:5)
I tried using named exports as the documentation seems to suggest in the Check, use, return section, but that got me:
file:///home/rik/workspaces/kwaeri/node-kit/postgresql-database-driver/dist/src/postgresql-database-driver.mjs:23
cov_1u3o9s5ali=function(){return actualCoverage;};}return actualCoverage;}cov_1u3o9s5ali();import{Pool}from'pg';import{DatabaseDriver}from'#kwaeri/database-driver';// You'll need this line and the method definitions below
^^^^
SyntaxError: Named export 'Pool' not found. The requested module 'pg' 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 'pg';
const {return actualCoverage;};}return actualCoverage;}cov_1u3o9s5ali();import{Pool}from'pg';import{DatabaseDriver} = pkg;
... As I had actually expected it would.
Anyways, the fix is hinted to by typescript in the syntax error above - doh:
import Postgres from `pg`;
// ...
this.pool = new Postgres.Pool( { ...bits } );
That resolves the issue.

Resources