I'm using ESLINT to analyze my code. The code runs fine. It's highlighting "Datastore". This is sample code from Google Cloud Platform Datastore examples.
[eslint] A function with a name starting with an uppercase letter should only be used as a constructor. (new-cap)
// Instantiates a client
const datastore = Datastore({
projectId: projectId,
});
Here's .eslintrc.js
module.exports = { extends: 'google', parserOptions: {
ecmaVersion: 6, }, };
You can configuration the rules in your .eslintrc, It looks like this:
module.exports = {
// "extends": "airbnb"
"extends": "google",
"parserOptions": {
"ecmaVersion": 8,
},
"rules": {
"new-cap": 0,
}
};
level 0 — disables the rule
level 1 — makes it a warning
level 2 — makes it an error.
This is unrelated to Google Cloud. It's related to your eslint configs. To remove this you can do either of the following:
while importing datastore use this method:
var gcloud = require('google-cloud');
var datastore = gcloud.datastore({
projectId: 'grape-spaceship-123',
keyFilename: '/path/to/keyfile.json'
});
or update your options for eslint. You can do this by adding it on top of the file
/*eslint new-cap: ["error", { "newIsCap": false }]*/
Related
I am trying to deploy NextJs and NextAuth.js to AWS using CDK (Cloud Development Kit). I have cloned the NextAuth.js example project (https://github.com/nextauthjs/next-auth-example) and
installed "serverless-http" for handling the binding from Lambda to NextJs. I attempted to follow this guide https://remaster.com/blog/nextjs-lambda-serverless-framework but using AWS CDK instead of the serverless.yml file as I am integrating it with existing infrastructure.
next.config.js:
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
images: {
unoptimized: true
},
output: 'standalone'
}
module.exports = nextConfig
[...nextauth].ts (From the example but using a simple credentials provider that always resolves):
import NextAuth, { NextAuthOptions } from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials";
export const authOptions: NextAuthOptions = {
providers: [
CredentialsProvider({
name: "Credentials",
credentials: {
username: { label: "Username", type: "text", placeholder: "jsmith" },
password: { label: "Password", type: "password" }
},
async authorize(credentials, req) {
return { id: "1", name: "J Smith", email: "jsmith#example.com" }
}
})
],
theme: {
colorScheme: "light",
},
callbacks: {
async jwt({ token }) {
token.userRole = "admin"
return token
},
},
}
export default NextAuth(authOptions)
server.ts:
import { NextConfig } from "next";
import NextServer from "next/dist/server/next-server";
import serverless from "serverless-http";
// #ts-ignore
import { config } from "./.next/required-server-files.json";
const nextServer = new NextServer({
hostname: "localhost",
port: 3000,
dir: __dirname,
dev: false,
conf: {
...(config as NextConfig),
},
});
export const handler = serverless(nextServer.getRequestHandler());
It is being built using the following script:
#!/bin/bash
BUILD_FOLDER=.dist
yarn build
rm -rf $BUILD_FOLDER
mv .next/standalone/ $BUILD_FOLDER/
cp -r .next/static $BUILD_FOLDER/.next
rm $BUILD_FOLDER/server.js
cp -r next.config.js $BUILD_FOLDER/
cp -r node_modules/serverless-http $BUILD_FOLDER/node_modules/serverless-http
tsc server.ts --outDir .dist --esModuleInterop true
cp -r public $BUILD_FOLDER/
This is deployed using AWS written in CDK C#. Primarily using a HttpApi and a single Lambda. Each configured as shown below:
Lambda:
var function = new Function(this, "nextjs-function", new FunctionProps
{
Code = Code.FromAsset(...".dist"),
Handler = "server.handler",
Runtime = Runtime.NODEJS_16_X,
...
Environment = new Dictionary<string, string>
{
{ "NEXTAUTH_URL", "https://myDomainName.com" },
{ "NEXTAUTH_SECRET", portalSecret },
}
});
HttpApi:
var httpApi = new HttpApi(this, "http-api", new HttpApiProps
{
DisableExecuteApiEndpoint = true,
DefaultIntegration = new HttpLambdaIntegration("nextjs-route", function),
DefaultDomainMapping = new DomainMappingOptions
{
DomainName = "myDomainName.com"
}
});
Opening the deployed webpage and clicking the "Sign In" button at the top, I get taken to /api/auth/signin?callbackUrl=%2F with a form. Without touching the credentials I click "Sign in with credentials". This results in the page reloading and nothing happening. Expected behaviour should be a session and a redirect back to the home page (/) as is happening when running it locally using either yarn dev or yarn build && yarn start.
I get no errors client/server-side thus leaving me in the dark.
I suspect that it has to do with domain configuration but I am unable to find the problem. I tested with another NextJs/NextAuth project using a AWS Cognito provider. This also had problems as when I clicked the sign in button I got an "Unexpected token" error due to the underlying signIn(...) function (from the NextAuth library) trying to parse the fetched page as JSON, which turned out to be the sign-in-page. Thus my suspicion of something domain-related.
Using Firebase Dynamic Links in a Managed Workflow Expo app directs to the correct deep link in the app on Android, but on iOS only opens the app in either whatever page was last open or the homepage.
app.config.js
ios: {
associatedDomains: [
'applinks:*.myapp.web.app',
'applinks:myapp.web.app',
'applinks:*.myapp.page.link',
'applinks:myapp.page.link',
],
},
AppNavigation.js
const linking = {
prefixes: [
prefix,
'https://myapp.web.app',
'https://*.myapp.web.app',
],
The apple-app-site-association file stored on myapp.web.app
{
"applinks": {
"apps": [],
"details": [
{
"appID": "1234567890.com.my.app",
"paths": [ "*" ]
}
]
}
}
The Dynamic Link is generated using REST API with the following payload:
const payload = {
dynamicLinkInfo: {
domainUriPrefix: 'https://myapp.page.link',
link: `https://myapp.web.app/${deepLink}`,
androidInfo: {
androidPackageName: com.my.app,
},
iosInfo: {
iosBundleId: com.my.app,
iosAppStoreId: 1234567890,
},
The generated Dynamic Link opens the app and directs to the ${deepLink} on Android as expected, but not on iOS. This was tested in an app built with EAS built.
Ended up solving this myself. Dynamic Links get resolved (converted from short link to full link) automatically on Android, but on iOS this has to be done manually with dynamicLinks().resolveLink(url);
After resolving, the link gets picked up by React Native Navigation and works like a normal deep link.
Full code for Dynamic Links:
const linking = {
prefixes: [
'https://myapp.page.link',
'https://myapp.web.app',
],
async getInitialURL() {
// If the app was opened with a Firebase Dynamic Link
const dynamicLink = await dynamicLinks().getInitialLink();
if (dynamicLink) {
const { url } = dynamicLink;
const resolvedLink = await dynamicLinks().resolveLink(url);
return resolvedLink.url;
}
// If the app was opened with any other link (sometimes the Dynamic Link also ends up here, so it needs to be resolved
const initialUrl = await Linking.getInitialURL();
if (initialUrl) {
const resolvedLink = await dynamicLinks().resolveLink(initialUrl);
return (resolvedLink) ? resolvedLink.url : initialUrl;
}
},
subscribe(listener) {
const handleDynamicLink = (dynamicLink) => {
listener(dynamicLink.url);
};
// Listen to incoming links from deep linking
const unsubscribeToDynamicLinks = dynamicLinks().onLink(handleDynamicLink);
return () => {
// Clean up the event listeners
unsubscribeToDynamicLinks();
};
},
};
In my case I also had to install all 3 of the following libraries:
"#react-native-firebase/analytics": "16.4.3",
"#react-native-firebase/app": "16.4.3",
"#react-native-firebase/dynamic-links": "16.4.3",
Is there a way to disable transpilation of es5 code (such as async functions) while in next dev?
Setting the babel preset-env does not work, and this previous answer no longer works either.
Setting the browserlist target within package.json still transpiles the code as well
As of Jan 2023 I found a few flags that help get you most of the way there.
const isProd = process.env.NODE_ENV === "production";
const nextConfig = {
webpack: (config, { dev }) => {
if (dev && Array.isArray(config.target) && config.target.includes('web')) {
config.optimization.minimize = false;
delete config.optimization.minimizer;
config.target = ["web", "es2020"];
}
return config;
}
};
if (!isProd) {
nextConfig.experimental = {
legacyBrowsers: false,
};
}
module.exports = nextConfig;
This will disable legacy browser support and use your browser list for swc, and then also changes the targets for webpack. Doesn't completely remove transpilation but it's way better than the default
Also, nextjs now supports browserslist in your package.json - source
Adding the following key to your package.json will enable most features by default:
{
"browserslist": [
"chrome 109"
]
}
I am trying to deploy a next.js (ssr) application in AWS' Amplify using the CDK but Amplify fails to identify the app as next.js ssr. When I do it manually though, using AWS UI, app is identified as SSR and works as expected.
This is generated by aws-cdk/aws-amplify v118 as:
import * as cdk from '#aws-cdk/core';
import * as amplify from '#aws-cdk/aws-amplify';
import codebuild = require('#aws-cdk/aws-codebuild');
export class AmplifyStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props: cdk.StackProps) {
super(scope, id, props);
const sourceCodeProvider = new amplify.GitHubSourceCodeProvider({
owner: '.....',
repository: '....',
oauthToken: cdk.SecretValue.secretsManager('github-token'),
});
const buildSpec = codebuild.BuildSpec.fromObjectToYaml(
{
version: 1,
applications: [
{
frontend: {
phases: {
preBuild: {
commands: [
"npm install"
]
},
build: {
commands: [
"npm run build"
]
}
},
artifacts: {
baseDirectory: ".next",
files: [
"**/*"
]
},
cache: {
paths: [
"node_modules/**/*"
]
}
}
}
]
}
);
const amplifyApp = new amplify.App(this, "cdk-nf-web-app", {
sourceCodeProvider: sourceCodeProvider,
buildSpec: buildSpec
});
amplifyApp.addBranch('develop', {
basicAuth: amplify.BasicAuth.fromGeneratedPassword('dev')
});
amplifyApp.addCustomRule({
source: "</^[^.]+$|\\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf|map|json)$)([^.]+$)/>",
target: "/index.html",
status: amplify.RedirectStatus.REWRITE
});
}
}
Which is identical to what AWS has generated when I do it manually from UI. The difference here is the lack of Framework identification as shown in picture. Any ideas?
To answer my own question, I was missing the role as without it aws won't create the necessary resources. (role: https://docs.aws.amazon.com/cdk/api/latest/docs/aws-iam-readme.html)
Edit to elaborate on how i fixed it:
Added a new role that can be used by amplify
const role = new iam.Role(this, 'amplify-role-webapp-'+props.environment, {
assumedBy: new iam.ServicePrincipal('amplify.amazonaws.com'),
description: 'Custom role permitting resources creation from Amplify',
});
and assigned a policy (AdministratorAccess) that role
let iManagedPolicy = iam.ManagedPolicy.fromAwsManagedPolicyName(
'AdministratorAccess',
);
role.addManagedPolicy(iManagedPolicy)
Then upon creating the app, i assigned the role to the app:
const amplifyApp = new amplify.App(this, "cdk-nf-web-app", {
sourceCodeProvider: sourceCodeProvider,
buildSpec: buildSpec,
role: role <--- this line here
});
The amplify app requires authorisation to create the relevant resources:
// This is for demonstrations purposes only; Do not give full access for production usage!
amplifyApp.grantPrincipal.addToPrincipalPolicy(new iam.PolicyStatement({
resources: ["*"],
actions: ['*'],
}))
Source Code Showcase
In my emberjs - i am implementing the firebase data base. for that I have changed the environment settings like this: ( please see my comments )
module.exports = function(environment) {
var ENV = {
modulePrefix: 'ember-simple-blog-eee6c',
environment: environment,
rootURL: '/',
contentSecurityPolicy: {
'script-src': "'self' 'unsafe-eval' apis.google.com",
'frame-src': "'self' https://*.firebaseapp.com",
'connect-src': "'self' wss://*.firebaseio.com https://*.googleapis.com"
},
firebase: {
authDomain: 'ember-simple-blog-eee6c.firebaseapp.com',
databaseURL: 'https://ember-simple-blog-eee6c.firebaseio.com/',
projectId: "ember-simple-blog-eee6c",
storageBucket: "",
messagingSenderId: "731960884482" //note sure taken from previous app
},
locationType: 'auto',
EmberENV: {
FEATURES: {
// Here you can enable experimental features on an ember canary build
// e.g. 'with-controller': true
},
EXTEND_PROTOTYPES: {
// Prevent Ember Data from overriding Date.parse.
Date: false
}
},
APP: {
// Here you can pass flags/options to your application instance
// when it is created
},
contentSecurityPolicy: {
'font-src': "'self' data: fonts.gstatic.com",
'style-src': "'self' 'unsafe-inline' fonts.googleapis.com"
}
};
if (environment === 'development') {
// ENV.APP.LOG_RESOLVER = true;
// ENV.APP.LOG_ACTIVE_GENERATION = true;
// ENV.APP.LOG_TRANSITIONS = true;
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
// ENV.APP.LOG_VIEW_LOOKUPS = true;
}
if (environment === 'test') {
// Testem prefers this...
ENV.locationType = 'none';
// keep test console output quieter
ENV.APP.LOG_ACTIVE_GENERATION = false;
ENV.APP.LOG_VIEW_LOOKUPS = false;
ENV.APP.rootElement = '#ember-testing';
}
if (environment === 'production') {
}
return ENV;
};
After implemented this config, I am getting error as :
Uncaught Error: Could not find module `ember-simple-blog-eee6c/app` imported from `(require)`
What is wrong here? how to solve this? any one please help me .
Thanks in advance.
I suspect that your firebase has nothing to do with your error. I'm able to recreate your error on my own app by giving module-prefix an incorrect name. Is it possible you are naming your module-prefix after your firebase project instead of your ember Project? If so, I think that might be the reason. I think you need your modulePrefix to have the same name as the folder your Ember project is inside of.