1
0
Fork 0

feat(backend): Allow loading of patterns as yaml/json

This commit is contained in:
joostdecock 2023-05-30 09:50:46 +02:00
parent cf060c779b
commit e4e808f118
3 changed files with 68 additions and 5 deletions

View file

@ -70,3 +70,14 @@ PatternsController.prototype.clone = async (req, res, tools) => {
return Pattern.sendResponse(res)
}
/*
* Read a public pattern
* See: https://freesewing.dev/reference/backend/api
*/
PatternsController.prototype.readPublic = async (req, res, tools, format = 'json') => {
const Pattern = new PatternModel(tools)
await Pattern.publicRead(req)
return format === 'yaml' ? Pattern.sendYamlResponse(res) : Pattern.sendResponse(res)
}

View file

@ -1,5 +1,6 @@
import { log } from '../utils/log.mjs'
import { setPatternAvatar } from '../utils/sanity.mjs'
import yaml from 'js-yaml'
export function PatternModel(tools) {
this.config = tools.config
@ -119,6 +120,22 @@ PatternModel.prototype.read = async function (where) {
return this.setExists()
}
/*
* Loads a pattern from the database but only if it's public
*
* Stores result in this.record
*/
PatternModel.prototype.publicRead = async function ({ params }) {
await this.read({ id: parseInt(params.id) })
if (this.record.public !== true) {
// Note that we return 404
// because we don't want to reveal that a non-public pattern exists.
return this.setResponse(404)
}
return this.setResponse(200, false, this.asPublicPattern(), true)
}
/*
* Loads a pattern from the database based on the where clause you pass it
* In addition prepares it for returning the pattern data
@ -314,6 +331,8 @@ PatternModel.prototype.revealPattern = function (pattern) {
//console.log(err)
}
}
if (pattern.set) delete pattern.set.measies
if (pattern.cset) delete pattern.cset.measies
return { ...pattern, ...clear }
}
@ -323,13 +342,20 @@ PatternModel.prototype.revealPattern = function (pattern) {
*
* Will be used by this.sendResponse()
*/
PatternModel.prototype.setResponse = function (status = 200, error = false, data = {}) {
PatternModel.prototype.setResponse = function (
status = 200,
error = false,
data = {},
rawData = false
) {
this.response = {
status,
body: {
result: 'success',
...data,
},
body: rawData
? data
: {
result: 'success',
...data,
},
}
if (status > 201) {
this.response.body.error = error
@ -346,3 +372,25 @@ PatternModel.prototype.setResponse = function (status = 200, error = false, data
PatternModel.prototype.sendResponse = async function (res) {
return res.status(this.response.status).send(this.response.body)
}
/*
* Helper method to send response as YAML
*/
PatternModel.prototype.sendYamlResponse = async function (res) {
return res.status(this.response.status).type('yaml').send(yaml.dump(this.response.body))
}
/*
* Returns record data fit for public publishing
*/
PatternModel.prototype.asPublicPattern = function () {
const data = {
author: 'FreeSewing.org',
type: 'pattern',
...this.asPattern(),
}
delete data.userId
delete data.public
return data
}

View file

@ -54,4 +54,8 @@ export function patternsRoutes(tools) {
app.delete('/patterns/:id/key', passport.authenticate(...bsc), (req, res) =>
Patterns.delete(req, res, tools)
)
// Read a public pattern as JSON or YAML (no auth needed, but will only work for public patterns)
app.get('/patterns/:id.json', (req, res) => Patterns.readPublic(req, res, tools, 'json'))
app.get('/patterns/:id.yaml', (req, res) => Patterns.readPublic(req, res, tools, 'yaml'))
}