NextJs: Static export with dynamic routing - azure

I am deploying my Next.js app on Azure and it will throw a 404 on page refresh if I navigate to the module pages e.g www.site.com/overview.
I have followed the guide for deploying on azure here - https://learn.microsoft.com/en-us/azure/static-web-apps/deploy-nextjs.
However it has some conflicting advice, it says to export it using next build && next export and to also dynamically map the routes to avoid the 404 error, however when I do that Next.js throws an error:
Error occurred prerendering page "/modules/emergency-closing". Read more: https://err.sh/next.js/prerender-error
Error:
Error: you provided query values for /modules/emergency-closing which is an auto-exported page. These can not be applied since the page can no longer be re-rendered on the server. To disable auto-export for this page add `getInitialProps`
What is the correct way to export the app and run it on Azure?
next.config.js
const modules = require('./data/modules')
module.exports = {
trailingSlash: true,
async exportPathMap() {
const paths = {
'/': { page: '/' },
}
//
Object.keys(modules).map((module) => {
paths[`/modules/${modules[module].slug}`] = {
page: '/modules/[moduleSlug]',
query: { moduleSlug: modules[module].slug },
}
})
return paths
},
}
modules.js
module.exports = {
overview: {
id: 6,
name: 'overview',
slug: 'overview',
},
'special-features': {
id: 1,
name: 'Special features',
slug: 'special-features',
},
diagnosis: {
id: 3,
name: 'Diagnosis',
slug: 'diagnosis',
},
'emergency-closing': {
id: 4,
name: 'Emergency closing',
slug: 'emergency-closing',
},
'side-window-settings': {
id: 5,
name: 'Side window settings',
slug: 'side-window-settings',
},
}
package.json
"build": "next build && next export",

Related

node-ews Update email to mark as read

I'm using "node-ews" library version 3.5.0, but when I try to update any property I get the following error:
{
"ResponseMessages":{
"UpdateItemResponseMessage":{
"attributes":{
"ResponseClass":"Error"
},
"MessageText":"An internal server error occurred. The operation failed., Object reference not set to an instance of an object.",
"ResponseCode":"ErrorInternalServerError",
"DescriptiveLinkKey":0,
"Items":null
}
}
}
I'm trying to mark email as read using the following code:
const markFolderAsRead = async (ews, id, changeKey) => {
const args = {
attributes: {
MessageDisposition: "SaveOnly",
},
ItemChanges: {
ItemChange: {
ItemId: {
attributes: {
Id: id,
ChangeKey: changeKey,
},
},
Updates: {
SetItemField: {
FieldURI: {
attributes: {
FieldURI: "message:IsRead",
},
Message: {
IsRead: true,
},
},
},
},
},
},
};
await ews.run("UpdateItem", args).then((result) => {
console.log("email read:", JSON.stringify(result));
});
};
I tried several modifications, including trying to update another fields, but none of it worked.
I followed this documentation: https://learn.microsoft.com/pt-br/exchange/client-developer/web-service-reference/updateitem-operation
And the lib doesn't show any example of it, but when I change the json to a wrong "soap" construction the error show different messages, or even if I do not pass any of the parameters required as "ChangeKey".
So, maybe this error is something relate to microsoft ews soap construction that I'm missing parameters, or so.
Got it working!
My JSON was wrong. The FieldURI was finishing after the message attribute, it should be before.
Correct JSON:
const args = {
attributes: {
MessageDisposition: "SaveOnly",
ConflictResolution: "AlwaysOverwrite",
SendMeetingInvitationsOrCancellations: "SendToNone",
},
ItemChanges: {
ItemChange: {
ItemId: {
attributes: {
Id: id,
ChangeKey: changeKey,
},
},
Updates: {
SetItemField: {
FieldURI: {
attributes: {
FieldURI: "message:IsRead",
},
},
Message: {
IsRead: "true",
},
},
},
},
},
};

Recaptcha v3 Invalid Input Response

I'm having a problem when trying to apply recaptcha into my web app.
Basically, it's returning the error message: "invalid-input-response"
What could I be doing wrong?
Stack:
#nuxtjs/recaptcha 1.1.1
express-recaptcha 5.1.0
nuxt 2.15.8
node 16.15.9
Here is my configuration on front, I don't have certain about the recaptcha mode, if I should use base or enterprise.
nuxt.config.js
modules: [
'#nuxtjs/recaptcha',
],
recaptcha: {
hideBadge: true,
mode: 'base',
siteKey: 'MY_SITE_KEY',
version: 3,
size: 'normal',
},
On index I don't know if has any problem here
Based on docs, it's only do that
On my action I'm sending the token alongside my data on that format
{
token: 'asdadsadadasdas',
review: {...}
}
index.vue
async mounted() {
try {
await this.$recaptcha.init()
} catch (e) {
console.log(e);
}
},
methods: {
...mapActions({
getProduct: "getProduct",
postReview: "postReview",
}),
async submit() {
const postReviewToken = await this.$recaptcha.execute('postReview')
try {
await this.postReview({
token: postReviewToken,
productId: this.$route.params.productId,
review: {
title: this.review.title,
content: this.review.content,
},
});
this.getProduct({ productId: this.$route.params.productId });
this.review = {
title: "",
content: "",
};
} catch (error) {}
},
},
Node
And on my api I just added the middleware as docs require
import { RecaptchaV3 } from 'express-recaptcha/dist'
const recaptcha = new RecaptchaV3(
'MY_SITE_KEY',
'MY_SECRET_KEY'
)
routes.post('/product/:id/review', recaptcha.middleware.verify, async (request: Request, response: Response) => {
if (request.recaptcha?.error) {
return response.status(400).json({ message: request.recaptcha.error })
}
const review = await prisma.review.create({
data: {
productId: request.params.id,
title: request.body.review.title,
content: request.body.review.content,
},
select: {
id: true,
title: true,
content: true,
}
})
response.json({review});
});

(this.internalValue || []).findIndex is not a function when enabling multiple selection on v-select

I am using Vue.js with Vuetify.
Following is my minimal reproducible example:
<template>
<v-app>
<v-select v-model="site" :items="sites" item-value="_id" item-text="name"></v-select>
<v-btn #click="showSelections">Show Selections</v-btn>
</v-app>
</template>
<script>
export default {
name: 'App',
data: () => ({
site: [],
sites: [
{
name: 'Vancouver',
_id: '5d9c276784e00100699281e2',
},
{
name: 'LA',
_id: '5d9c276784e00100699281e5',
},
{
name: 'Montreal',
_id: '5d9c276784e00100699281e3',
},
],
}),
methods: {
showSelections: function() {
console.log(this.site);
}
}
};
</script>
This example works perfect until you want to enable multiple selection on the v-select component.
<v-select v-model="site" :items="sites" multiple item-value="_id" item-text="name"></v-select>
As soon as you click the combobox, you'd get this:
vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in v-on handler: "TypeError: (this.internalValue || []).findIndex is not a function"
found in
---> <VSelectList>
<VThemeProvider>
<VMenu>
<VSelect>
<VMain>
<VApp>
<App> at src/App.vue
<Root>
TypeError: (this.internalValue || []).findIndex is not a function
at VueComponent.findExistingIndex (VSelect.ts?1576:338)
at VueComponent.selectItem (VSelect.ts?1576:816)
at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1854)
at VueComponent.invoker (vue.runtime.esm.js?2b0e:2179)
at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1854)
at VueComponent.Vue.$emit (vue.runtime.esm.js?2b0e:3888)
at click (VSelectList.ts?7bd1:169)
at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1854)
at VueComponent.invoker (vue.runtime.esm.js?2b0e:2179)
at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1854)
This seems to be an issue caused by Vue CLI 4.5.11 transpiling Vuetify. If you remove vuetify from transpileDependencies, your example works properly:
// vue.config.js
module.exports = {
// transpileDependencies: [
// 'vuetify'
// ]
}
Interestingly, this isn't a problem at all (no config changes needed) with Vue CLI 5.0.0-alpha.4, so consider upgrading.
I had the same problem. I leave you here as I have it in case it works for you:
<!-- VueJS Template -->
<v-select :items="arrayItems" v-model="arrayItemsSelected" label="Items" item-text="text" outlined multiple chips attach dark></v-select>
// VueJS Data
export default {
data: () => ({
arrayItemsSelected: [],
arrayItems: [
{ value: "Item1", text: "Item1" },
{ value: "Item2", text: "Item2" },
{ value: "Item3", text: "Item3" },
{ value: "Item4", text: "Item4" },
{ value: "Item5", text: "Item5" },
],
}),
}
I had the same issue when I was toggling the multiple property of the v-select. See the reproduction link: https://codepen.io/kkojot/pen/MWOpYqZ
To avoid this error you have to clear the property bound to v-model and change it empty object {} or empty array [] accordingly.
computed: {
isMultiple() {
//comment the if statment below to see the 'TypeError: (this.internalValue || []).findIndex is not a function'
if (this.multiple) this.site = [];
else this.site = {};
return this.multiple;
},
},

nodejs systray: SysTray is not a constructor

I am trying to use npm module for nodejs called systray, when I try to run the example given on the npm page it throws
TypeError: SysTray is not a constructor
systray seems to be a popular module for a crossplatform system tray but it lacks in examples, below is the sample code that I am trying to run
var SysTray = require("systray")
const systray = new SysTray({
menu: {
// you should using .png icon in macOS/Linux, but .ico format in windows
icon: "",
title: "My Systray",
tooltip: "Tips",
items: [{
title: "aa",
tooltip: "bb",
// checked is implement by plain text in linux
checked: true,
enabled: true
}, {
title: "aa2",
tooltip: "bb",
checked: false,
enabled: true
}, {
title: "Exit",
tooltip: "bb",
checked: false,
enabled: true
}]
},
debug: false,
copyDir: true, // copy go tray binary to outside directory, useful for packing tool like pkg.
})
systray.onClick(action => {
if (action.seq_id === 0) {
systray.sendAction({
type: 'update-item',
item: {
...action.item,
checked: !action.item.checked,
},
seq_id: action.seq_id,
})
} else if (action.seq_id === 1) {
// open the url
console.log('open the url', action)
} else if (action.seq_id === 2) {
systray.kill()
}
})
Require it in this way:
const SysTray = require('systray').default;
But probably it is better to use import constructions and babel (https://babeljs.io/docs/en/babel-preset-typescript)
Seems that the npm package you are trying to use is meant to be used with typescript.

Unable to fetch list in react relay

I am following schema same as mentioned here
I want to fetch all users so I updated my schema like this
var Root = new GraphQLObjectType({
name: 'Root',
fields: () => ({
user: {
type: userType,
resolve: (rootValue, _) => {
return getUser(rootValue)
}
},
post: {
type: postType,
args: {
...connectionArgs,
postID: {type: GraphQLString}
},
resolve: (rootValue, args) => {
return getPost(args.postID).then(function(data){
return data[0];
}).then(null,function(err){
return err;
});
}
},
users:{
type: new GraphQLList(userType),
resolve: (root) =>getUsers(),
},
})
});
And in database.js
export function getUsers(params) {
console.log("getUsers",params)
return new Promise((resolve, reject) => {
User.find({}).exec({}, function(err, users) {
if (err) {
resolve({})
} else {
resolve(users)
}
});
})
}
I am getting results in /graphql as
{
users {
id,
fullName
}
}
and results as
{
"data": {
"users": [
{
"id": "VXNlcjo1Nzk4NWQxNmIwYWYxYWY2MTc3MGJlNTA=",
"fullName": "Akshay"
},
{
"id": "VXNlcjo1Nzk4YTRkNTBjMWJlZTg1MzFmN2IzMzI=",
"fullName": "jitendra"
},
{
"id": "VXNlcjo1NzliNjcyMmRlNjRlZTI2MTFkMWEyMTk=",
"fullName": "akshay1"
},
{
"id": "VXNlcjo1NzliNjgwMDc4YTYwMTZjMTM0ZmMxZWM=",
"fullName": "Akshay2"
},
{
"id": "VXNlcjo1NzlmMTNkYjMzNTNkODQ0MmJjOWQzZDU=",
"fullName": "test"
}
]
}
}
but If I try to fetch this in view as
export default Relay.createContainer(UserList, {
fragments: {
userslist: () => Relay.QL`
fragment on User #relay(plural: true) {
fullName,
local{
email
},
images{
full
},
currentPostCount,
isPremium,
}
`,
},
});
I am getting error Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.
Please tell me what I am missing .
I tried a lot with and without #relay(plural: true).
Also tried to update schema with arguments as
users:{
type: new GraphQLList(userType),
args: {
names: {
type: GraphQLString,
},
...connectionArgs,
},
resolve: (root, {names}) =>connectionFromArray(getUsers(names)),
},
but I got error Cannot read property 'after' of undefined in implementing react-relay
Thanks in Advance.
Relay currently only supports three types of root fields (see facebook/relay#112):
Root field without arguments, returning a single node:
e.g. { user { id } } returning {"id": "123"}
Root field with one argument, returning a single node:
e.g. { post(id: "456") { id } } returning {"id": "456"}
Root field with one array argument returning an array of nodes with the same size as the argument array (also known as "a plural identifying root field"):
e.g. { users(ids: ["123", "321"]) { id } } returning [{"id": "123"}, {"id": "321"}]
A workaround is to create a root field (often called viewer) returning a node that has those fields. When nested inside the Viewer (or any other node), fields are allowed to have any return type, including a list or connection. When you've wrapped the fields in this object in your GraphQL server, you can query them like this:
{
viewer {
users {
id,
fullName,
}
}
}
The Viewer type is a node type, and since there will just be one instance of it, its id should be a constant. You can use the globalIdField helper to define the id field, and add any other fields you want to query with Relay:
const viewerType = new GraphQLObjectType({
name: 'Viewer',
interfaces: [nodeInterface],
fields: {
id: globalIdField('Viewer', () => 'VIEWER_ID'),
users:{
type: new GraphQLList(userType),
resolve: (viewer) => getUsers(),
},
},
});
On the client you'll need to change the root query in your route to { viewer } and define the fragment on Viewer:
export default Relay.createContainer(UserList, {
fragments: {
viewer: () => Relay.QL`
fragment on Viewer {
users {
fullName,
local {
email,
},
images {
full,
},
currentPostCount,
isPremium,
}
}
`,
},
});

Resources