I'm using joi-to-swagger and swagger-ui-express and I'm really struggling to find out how to get this schema to show up correctly. It's getting ignored in all scenarios and I can't find the documentation I need to correctly use the schema.
My file:
import j2s from 'joi-to-swagger'
import joi from 'joi'
import swaggerUi from 'swagger-ui-express'
const myJoiSchema = joi
.object({
text: joi.string().max(100).required(),
})
.required()
const schema = j2s(myJoiSchema).swagger
const swaggerDoc = {
swagger: '2.0',
info: {
title: 'title',
version: '1.0',
},
paths: {
'/my-url': {
post: {
summary: 'my api',
// consumes: 'application/json',
// parameters: mySchema, didn't work
requestBody: {
required: true,
schema: {
$ref: '#/components/schemas/mySchema',
},
},
},
},
},
components: {
schemas: {
mySchema: schema,
},
},
}
router.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDoc))
the schema that is produced for value schema is:
{
type: 'object',
properties: {
text: { type: 'string', maxLength: 100 },
},
required: [ 'text' ],
additionalProperties: false
}
How is the schema supposed to be properly used in the swagger doc? It might be special with swagger-ui-express but I can't confirm I've tested it correctly.
I am trying out to write the swagger using fastify and fastify-swagger in localhost. However my real server is running somewhere else which has the backend logic. I am trying to proxy my localhost API call to the remote upstream using fastify-http-proxy.
So in essence, the swagger I want to serve from localhost and and all the actual API call I want to proxy to remote upstream.
My fastify-http-proxy configuration:
fastify.register(require('fastify-http-proxy'), {
upstream: "https://mystaging.com/notifications",
prefix: '/notifications',
replyOptions: {
rewriteRequestHeaders: (originalRequest, headers) => {
return {
...headers,
};
},
},
async preHandler (request, reply) {
console.log('Request URL: ', request.url);
if (request?.url?.includes('api-docs')) {
console.log('Request contains api-docs. Ignore the request...');
return;
}
},
});
Basically my intention is that any upcoming request coming to http://127.0.0.1:8092/notifications should be proxied to and served by the https://mystaging.com/notifications. E.g. POST http://127.0.0.1:8092/notifications/agent-notifications should be actually forwarded to https://mystaging.com/notifications/agent-notification. That's why I configured the fastify-http-proxy as the above way.
My fastify-swagger configuration:
fastify.register(require('fastify-swagger'), swaggerConfig);
const swaggerConfig = {
openapi: {
info: {
title: `foo bar`,
description: `API forwarded for notifications service`,
version: '1.0.0'
},
servers: [
{ url: `${server}` },
],
tags: [
{ name: 'notifications', description: "Notifications"},
],
components: {
securitySchemes: {
authorization: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
description: 'JWT access token to authorize the request, sent on the request header.'
}
}
}
},
exposeRoute: true,
routePrefix: `localhost:8092/notifications/external/api-docs`,
};
Once I opened the swagger in the browser using URL http://localhost:8092/notifications/external/api-docs/static/index.html, I am seeing other than the notifications tag, there are very REST verb of /notifications/ is coming up as the attached picture.
Once I turn of the fastify-http-proxy, everything works fine.
What am I missing/messing up here.
Screenshot of spurious default routes:
Versions used:
"fastify": "^3.21.6",
"fastify-auth0-verify": "^0.5.2",
"fastify-swagger": "^4.8.4",
"fastify-cors": "^6.0.2",
"fastify-http-proxy": "^6.2.1",
Notes added further:
The route specification looks like:
module.exports = async function (fastify, opts) {
fastify.route({
method: 'POST',
url: `${url}/agent-notifications`,
schema: {
description: 'Something',
tags: ['notifications'],
params:{
$ref: 'agent-notifications-proxy-request#',
},
},
handler: async (request, reply) => {
}
});
}
And here is the agent-notifications-proxy-request:
module.exports = function (fastify) {
fastify.addSchema({
$id: 'agent-notifications-proxy-request',
title: "AgentNotificationRequest",
description:'Trying out',
type: 'object',
example: 'Just pass the same stuff as-is',
properties: {
'accountId': {
type: 'string'
},
'templateName': {
type: 'string'
},
"bodyParams": {
type: "object",
},
"includeAdmin": {
type: 'boolean'
},
"serviceName": {
type: 'string'
},
},
});
};
I followed this tutorial for adding social media cards to my site: https://www.gatsbyjs.com/tutorial/seo-and-social-sharing-cards-tutorial/
However, my url https://www.peregrinastro.com/articles/jupiter-saturn-conjunction-in-aquarius-part-1-fresh-air still returns this in twitter card validator:
INFO: Page fetched successfully
INFO: 5 metatags were found
ERROR: No card found (Card error)
I can see that I have all the metatags, so what can be the issue?
SEO component :
import React from "react"
import PropTypes from "prop-types"
import { Helmet } from "react-helmet"
import { useStaticQuery, graphql } from "gatsby"
function SEO({ description, lang, meta, image: metaImage, title }) {
const { site } = useStaticQuery(
graphql`
query {
site {
siteMetadata {
title
description
keywords
author
url
twitter
facebook
}
}
}
`
)
const metaDescription = description || site.siteMetadata.description
const image =
metaImage && metaImage.src
? `${site.siteMetadata.url}${metaImage.src}`
: null
return (
<Helmet
htmlAttributes={{
lang,
}}
title={title}
titleTemplate={`%s | ${site.siteMetadata.title}`}
meta={[
{
name: `description`,
content: metaDescription,
},
{
name: "keywords",
content: site.siteMetadata.keywords.join(","),
},
{
property: `og:title`,
content: title,
},
{
property: `og:description`,
content: metaDescription,
},
{
property: `og:type`,
content: `website`,
},
{
property: `og:site_name`,
content: title,
},
{
property: `og:url`,
content: site.siteMetadata.url,
},
]
.concat(
metaImage
? [
{
property: "og:image",
content: image,
},
{
property: "og:image:width",
content: metaImage.width,
},
{
property: "og:image:height",
content: metaImage.height,
},
{
name: "twitter:card",
content: "summary_large_image",
},
{
name: "twitter:image:src",
content: image,
},
]
: [
{
name: "twitter:card",
content: "summary",
},
]
)
.concat([
{
name: `twitter:creator`,
content: site.siteMetadata.twitter,
},
{
name: `twitter:title`,
content: title,
},
{
name: `twitter:description`,
content: metaDescription,
},
{
name: `twitter:site`,
content: site.siteMetadata.twitter,
},
])
.concat(meta)}
/>
)
}
SEO.defaultProps = {
lang: `en`,
meta: [],
description: ``,
}
SEO.propTypes = {
description: PropTypes.string,
lang: PropTypes.string,
meta: PropTypes.arrayOf(PropTypes.object),
title: PropTypes.string.isRequired,
image: PropTypes.shape({
src: PropTypes.string.isRequired,
height: PropTypes.number.isRequired,
width: PropTypes.number.isRequired,
}),
}
export default SEO
gatsby-config.js
const { isNil } = require("lodash")
const mapPagesUrls = {
index: "/",
}
module.exports = {
siteMetadata: {
title: `Peregrin Astrology`,
description: `astrology blog, horoscopes, mundane, historical astrology, birth chart consultations.`,
keywords: [
"astrology",
"astrologer",
"zodiac",
"signs",
"aries",
"taurus",
"gemini",
"cancer",
"leo",
"virgo",
"libra",
"scorpio",
"sagittarius",
"capricorn",
"aquarius",
"pisces",
"horoscope",
"forecast",
"mundane",
"birth chart",
],
author: `Pedro Coelho`,
url: "https://www.peregrinastro.com",
siteLanguage: "english",
twitter: "#peregrinastro",
facebook: "peregrinastro",
},
plugins: [
`gatsby-plugin-react-helmet`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `gatsby-starter-default`,
short_name: `starter`,
start_url: `/`,
background_color: `#663399`,
theme_color: `#663399`,
display: `minimal-ui`,
icon: `src/images/favicon.png`, // This path is relative to the root of the site.
},
},
{
resolve: `gatsby-source-strapi`,
options: {
apiURL: `https://astrobeats-cms.herokuapp.com`,
queryLimit: 10000, // Default to 100
contentTypes: [`article`, `category`, `author`],
//If using single types place them in this array.
},
},
{
resolve: "gatsby-source-filesystem",
options: {
name: "fonts",
path: `${__dirname}/src/fonts/`,
},
},
{
resolve: "gatsby-plugin-web-font-loader",
options: {
google: {
families: ["Merriweather", "Montserrat", "Lato:100,300,400,700,900"],
},
},
},
{
resolve: "gatsby-plugin-react-svg",
options: {
rule: {
include: /assets/,
},
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images/`,
},
},
],
}
Is it possible to customize/extend the h1-h6 tags in the sw-text-editor with custom classes like “.headline-1” for example?
const { Component } = Shopware;
Component.override('sw-text-editor', {
props: {
buttonConfig: {
type: Array,
required: false,
default() {
return [
{
type: 'paragraph',
title: this.$tc('sw-text-editor-toolbar.title.format'),
icon: 'default-text-editor-style',
children: [
...
{
type: 'formatBlock',
name: this.$tc('sw-text-editor-toolbar.title.h1'),
value: 'h1',
tag: 'h1'
},
...
]
},
...
];
}
}
}
});
Any idea how i can add custom headline tags with specific css classes. Maybe something like this:
{
type: 'formatBlock',
name: this.$tc('sw-text-editor-toolbar.title.h1'),
value: 'h1',
tag: 'h1',
classes: 'test-class'
},
this is my configuration in apostrophe-assets. did i miss something?
// This configures the apostrophe-assets module to push a 'site.less'
// stylesheet by default, and to use jQuery 3.x
module.exports = {
jQuery: 3,
stylesheets: [
{
name: 'bootstrap.min',
minify: true
},
{
name:'font-awesome.min',
path: 'fonts/css',
minify:true
},
{
name: 'style',
minify: false
},
{
name: 'site'
}
],
scripts: [
{
name: 'jquery-3.2.1.min',
minify:true
},{
name: 'popper'
},{
name: 'bootstrap.min'
},
{
name: 'custom'
},
{
name: 'site'
}
]
};
i have referred https://apostrophecms.org/docs/tutorials/getting-started/pushing-assets.html. also i have overwrite the existing module in apostrophe.
It would be interesting to know if its necessary to add jQuery: 3
look at my code:
lib/modules/apostrophe-assets/index.js
module.exports = {
stylesheets: [
{
name: 'site'
}
],
scripts: [
{
name: 'site'
},
{
name: 'lethargy.min'
},
{
name: 'smartscroll.min'
}
]
};
my js files are located in the default path like that:
lib/modules/apostrophe-assets/public/js/lethargy.min.js
You can push assets as well from every widget here for example in index js of :
lib/modules/example-widget/index.js
//Create functions for pushing assets to browser
afterConstruct: function(self) {
self.pushAssets();
},
//load third party styles and scripts
//init has all settings for fullpage
construct: function(self, options) {
self.pushAssets = function() {
self.pushAsset('stylesheet', 'vendor/materialize.min', { when: 'always' });
self.pushAsset('stylesheet', 'overrides', { when: 'always' });
self.pushAsset('script', 'vendor/materialize', { when: 'always' });
self.pushAsset('script', 'init', { when: 'always' });
};
}