Multiple Routes in Swagger - express

I'm trying to make two different routes in swagger as but both APIs show me the same endpoints. What I understand from this is somehow different routes don't register. How can I make it so?
import swaggerJSDoc from 'swagger-jsdoc'
export const swaggerPublicSpec = swaggerJSDoc({
definition: {
//***
}
}
},
apis: ['./docs/**/*.yaml', './src/**/openapi-public.yaml']
})
export const swaggerPrivateSpec = swaggerJSDoc({
definition: {
//***
}
}
},
apis: ['./docs/**/*.yaml', './src/**/openapi.yaml']
})
This is their express app
appInstance.use('/docs', swaggerUI.serve, swaggerUI.setup(swaggerPublicSpec, { explorer: true }))
appInstance.use('/private-docs', swaggerUI.serve, swaggerUI.setup(swaggerPrivateSpec, { explorer: true }))

Related

Nuxt 3 - how to access plugin injections from components?

Using Nuxt 3 and vue-gtag, what is the right way to access $gtag from components?
plugins/gtag.client.js:
import VueGtag from 'vue-gtag';
export default defineNuxtPlugin(nuxtApp => {
const router = useRouter();
nuxtApp.vueApp.use(
VueGtag,
{
config: {
id: '...'
}
},
router
);
});
In Nuxt 2, this.$gtag was accessible from component file.
In Nuxt 3, I can't seem to find it:
const nuxtApp = useNuxtApp();
nuxtApp.$gtag //undefined
Looking at the source code, it seems to be defined correctly, so I don't think it's a problem with the plugin itself.
app.config.globalProperties.$gtag = api;
I have same issue when define the domToImage plugin in nuxt 3. I found a solution as follow. Hope to help you.
Return provide in nuxt plugin:
import domtoimage from "dom-to-image-more";
export default defineNuxtPlugin((nuxtApp) => {
// nuxtApp.vueApp.use(domtoimage)
return {
provide: {
domtoimage
}
}
})
Use in component:
const print = () => {
console.log("Print ...")
const { $domtoimage } = useNuxtApp()
$domtoimage.toPng(printMeDiv)
.then((dataUrl) => {
console.log(dataUrl)
})
}
}

How to use fetched api result in other methods or functions in Nuxt3

How to work with fetched data from an API in Nuxt3?
For example, I want to set metatags from the API's results, but it throws an error of undefined. I am unable to access pageData in useHead.
<script setup>
import { ref } from "vue"
const { apiUrl } = useRuntimeConfig()
const route = useRoute()
const { data: pageData } = await useFetch(
`${apiUrl}/misc/cmspage/61785b119b4eb50d8d625621`
)
useHead({
title: this.pageData.seo.metatitle
})
</script>
This is the result of the API.
{
seo: {
metatitle: "SomeTitle",
metadesc: "SomeDescriptions",
metakeywords: "SomeKeywords",
},
pagename: "XXXXX",
faqs: [],
topDestinations: [],
pageId: "61785b119b4eb50d8d625621",
id: "61785b119b4eb50d8d625621",
}
You should use pageData.value.seo.metatitle to print the content of your ref.
More details are available here: https://vuejs.org/guide/essentials/reactivity-fundamentals.html#reactive-variables-with-ref (switch to composition on the top right sidebar API preference)

How to Implement nuxtServerInit Action to load data from server-side on the initial load in Pinia (Nuxt3)

My Code:
export const useMenuStore = defineStore("menuStore", {
state: () => ({
menus: [],
}),
actions: {
async nuxtServerInit() {
const { body } = await fetch("https://jsonplaceholder.typicode.com/posts/1").then((response) => response.json());
console.log(body);
this.menus = body;
resolve();
},
},
});
NuxtServerInit is not working on initial page render on nuxt js vuex module mode.Anyone know this error please help me.
NuxtServerInit is not implemented in Pinia, but exists a workaround.
Using Pinia alongside Vuex
// nuxt.config.js
export default {
buildModules: [
'#nuxtjs/composition-api/module',
['#pinia/nuxt', { disableVuex: false }],
],
// ... other options
}
then Include an index.js file inside /stores with a nuxtServerInit action which will be called from the server-side on the initial load.
// store/index.js
import { useSessionStore } from '~/stores/session'
export const actions = {
async nuxtServerInit ({ dispatch }, { req, redirect, $pinia }) {
if (!req.url.includes('/auth/')) {
const store = useSessionStore($pinia)
try {
await store.me() // load user information from the server-side before rendering on client-side
} catch (e) {
redirect('/auth/login') // redirects to login if user is not logged in
}
}
}
}
In Nuxt2, the Nuxt will run the code in nuxtServerInit() of store/index.js on the server-side to boot the app.
However, in Nuxt3, there is no specific place to write the boot code, you can write the boot code anywhere instead of in nuxtServerInit() of store/index.js.
It might be helpful, especially when you need to send a request before boosting the app.
your pinia file may define like following:
store/menu.js
import { defineStore } from 'pinia';
export const useMenuStore = defineStore('menuStore', {
state: () => ({
_menus: [],
}),
getters: {
menus() {
return this._menus;
}
},
actions: {
async boot() {
const { data } = await useFetch('https://jsonplaceholder.typicode.com/posts/1');
this._menus = data;
}
}
});
Then, create a plugin which named as *.server.[ts|js], for example init.server.js
(.sever.js tail will let the file only run in server side)
plugins/init.server.js
import { defineNuxtPlugin } from '#app';
import { useMenuStore } from '~/store/menu.js';
export default defineNuxtPlugin(async (nuxtApp) => {
const menu = useMenuStore(nuxtApp.$pinia);
await menu.boot();
});
nuxt.config.js
modules: [
'#pinia/nuxt',
],
There is an entire example of SSR Nuxt3 with authorization that may help

How to use Google Map API in Nuxt Js?

This is my code below to fetch API in Nuxt.Js. I have written the code that should be used to call an API, but I am not getting the results. I am not getting any resources regarding this as well.
async created(){
const config = {
headers : {
Accept : "application/json"
}
};
try{
const result = await axios.get(`https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap`, config);
console.warn(result);
//this.users = result.data;
}
catch (err){
console.warn(err);
}
},
Official GM NPM loader + diy Nuxt plugin
There's an official npm loader for the Google Maps JS API:
https://developers.google.com/maps/documentation/javascript/overview#Loading_the_Maps_API
https://www.npmjs.com/package/#googlemaps/js-api-loader
Below is how I have it implemented in Nuxt (2.15.7).
Side note: Yes, this places your API key client side, which in some contexts (e.g. internal team tools) is fine. For public production deployment, you probably want to protect the API key behind a proxy server, and keep any communication with Google occurring only on your server. A proxy server works great for things like Google search and geolocation services, however for map tiles you may never have a map tile server as fast as Google, so you may have to keep an API key on client-side to ensure smooth performance.
1. Install
npm i #googlemaps/js-api-loader
2. Make your own Nuxt plugin
plugins/mapGoogle.client.js
This keeps the Google Map API as a global so you can make use of it in various components (i.e. non-map contexts, like searching Google Places in a form).
import Vue from 'vue'
import { Loader } from '#googlemaps/js-api-loader'
// Store GM_instance as a window object (outside of the Vue context) to satisfy the GM plugin.
window.GM_instance = new Loader({
apiKey: process.env.GOOGLEMAPSAPIKEY, // This must be set in nuxt.config.js
version: "weekly",
libraries: ["places", "drawing", "geometry"] // Optional GM libraries to load
})
Vue.mixin({
data() {
return {
GM_loaded: false, // Tracks whether already GM loaded
GM_instance: null // Holds the GM instance in the context of Vue; much more convenient to use *anywhere* (Vue templates or scripts) whereas directly accessing the window object within Vue can be problematic.
GM_placeService: null, // Optional - Holds the GM Places service
}
},
methods: {
GM_load() {
return new Promise( async (resolve, reject) => {
// Need to do this only once
if (!this.GM_loaded) {
// Load the GM instance
window.GM_instance.load()
.then((response) => {
this.GM_loaded = true
// this.GM_instance is what we use to interact with GM throughout the Nuxt app
this.GM_instance = response
resolve()
})
.catch(e => {
reject(e)
})
} else {
resolve()
}
})
},
// OPTIONAL FUNCTIONS:
GM_loadPlaceService(map) {
this.GM_placeService = new this.GM_instance.maps.places.PlacesService(map)
},
GM_getPlaceDetails(placeRequest) {
return new Promise((resolve, reject) => {
this.GM_placeService.getDetails(placeRequest, (response) => {
resolve(response)
})
})
}
}
})
3. Set env and plugin in nuxt config
nuxt.config.js
Pass your GM key from your .env file and register your new plugin.
export default {
// ...
// It's best to keep your GM key where all other keys are: your .env file; however this is inaccessible client-side.
// Here, we tell Nuxt the specific env's we want to make available client-side.
env: {
GOOGLEMAPSAPIKEY: process.env.GOOGLEMAPSAPIKEY
},
// Register your new plugin
plugins: [
'#/plugins/mapGoogle.client.js',
],
// ...
}
4. Now use the GM plugin anywhere
components/map.vue
Make a map and process clicks on Google Places
<template>
<div id="map" class="map"></div>
</template>
<script>
export default {
name: "MapGoogle",
data() {
return {
map: null
}
},
mounted() {
// This is the actual trigger that loads GM dynamically.
// Here we run our global GM func: GM_load.
// Side note; annoyance: As you see, using Vue mixin's, you have functions available from out-of-nowhere. Research alternative to mixin's, especially in Vue3/Nuxt3.
this.GM_load()
.then( () => {
this.initMap()
})
},
methods: {
initMap() {
this.map = new this.GM_instance.maps.Map(document.getElementById("map"), {
center: { lat: 43.682284, lng: -79.401603 },
zoom: 8,
})
this.GM_loadPlaceService(this.map)
this.map.addListener("click", (e) => {
this.processClick(e)
})
}
},
async processClick(e) {
// If clicked target has a placeId, user has clicked a GM place
if (e.placeId) {
let placeRequest = {
placeId: e.placeId,
//fields: ['name', 'rating', 'formatted_phone_number', 'geometry']
}
// Get place details
let googlePlace = await this.GM_getPlaceDetails(placeRequest)
console.log("googlePlace %O", googlePlace)
}
}
}
</script>

How to call mirage server before application starts in StencilJS

I am working on a StencilJS project where I have to use MirageJS to make fake API data.
How to call server before StencilJS application loads.
In react we can call makeServer() in the index.ts file, but in the stencil, we don't have such a file.
How can we call this to start the mirage server, Please can someone suggest the correct way.
Below is my server.ts file
mirage/server.ts
import { createServer, Model } from 'miragejs';
import { auditFactory } from './factories';
import { processCollectionRequest } from './utils';
export const makeServer = async ({ environment = 'development' } = {}) => {
console.log('started server');
return createServer({
environment,
factories: {
people: auditFactory,
},
models: {
people: Model,
},
routes() {
this.namespace = '/api/v1';
this.get('/peoples', function (schema, request) {
let res = processCollectionRequest(schema, request, 'peoples', this);
// remove factory properties not in spec
res.items.forEach(e => ['associatedResourceId', 'associatedResourceName', 'associatedResourceType'].forEach(p => delete e[p]));
return res;
});
},
seeds(server) {
server.createList('audit', 20);
},
});
};
I'm not familiar with MirageJS so I might be off, but can you use globalScript (https://stenciljs.com/docs/config) and then run your Mirage server there?