mirror of
https://github.com/cupcakearmy/morphus.git
synced 2024-12-22 08:06:30 +00:00
add presets
This commit is contained in:
parent
08470ba820
commit
38d35f40aa
@ -17,6 +17,8 @@ RUN ls -hal
|
|||||||
# RUNNER
|
# RUNNER
|
||||||
FROM base
|
FROM base
|
||||||
|
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
COPY package.json pnpm-lock.yaml ./
|
COPY package.json pnpm-lock.yaml ./
|
||||||
RUN pnpm install --frozen-lockfile --prod
|
RUN pnpm install --frozen-lockfile --prod
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "morphus",
|
"name": "morphus",
|
||||||
"version": "0.1.0",
|
"version": "1.0.0-rc.2",
|
||||||
"description": "",
|
"description": "",
|
||||||
"author": "Niccolo Borgioli",
|
"author": "Niccolo Borgioli",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@ -30,6 +30,7 @@ const Schema = yaml.DEFAULT_SCHEMA.extend([RegExpTag])
|
|||||||
export type NullableStringOrRegexpArray = (string | RegExp)[] | null
|
export type NullableStringOrRegexpArray = (string | RegExp)[] | null
|
||||||
|
|
||||||
function formatNullableStringOrRegexpArray(values: any) {
|
function formatNullableStringOrRegexpArray(values: any) {
|
||||||
|
if (values === null) return
|
||||||
if (!Array.isArray(values)) throw new Error('must be an array')
|
if (!Array.isArray(values)) throw new Error('must be an array')
|
||||||
if (values.length === 0) throw new Error('must be an array with at least one element')
|
if (values.length === 0) throw new Error('must be an array with at least one element')
|
||||||
for (const value of values) {
|
for (const value of values) {
|
||||||
@ -39,6 +40,18 @@ function formatNullableStringOrRegexpArray(values: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PresetsConfig = Record<string, string> | null
|
||||||
|
function formatPresets(values: any) {
|
||||||
|
if (values === null) return
|
||||||
|
if (typeof values === 'object') {
|
||||||
|
for (const key in values) {
|
||||||
|
if (typeof values[key] !== 'string') throw new Error('entries for presets must be strings')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error('presets must be an object or null')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
convict.addParser({ extension: ['yml', 'yaml'], parse: (s) => yaml.load(s, { schema: Schema }) })
|
convict.addParser({ extension: ['yml', 'yaml'], parse: (s) => yaml.load(s, { schema: Schema }) })
|
||||||
|
|
||||||
export const config = convict({
|
export const config = convict({
|
||||||
@ -101,6 +114,19 @@ export const config = convict({
|
|||||||
env: 'STORAGE',
|
env: 'STORAGE',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Presets
|
||||||
|
presets: {
|
||||||
|
doc: 'The presets to use',
|
||||||
|
format: formatPresets,
|
||||||
|
nullable: true,
|
||||||
|
default: null as PresetsConfig,
|
||||||
|
},
|
||||||
|
onlyAllowPresets: {
|
||||||
|
doc: 'Whether to allow only presets',
|
||||||
|
format: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
// Local storage
|
// Local storage
|
||||||
local: {
|
local: {
|
||||||
assets: {
|
assets: {
|
||||||
|
@ -61,6 +61,11 @@ export class ComplexParameter<N = string, T extends object = {}> {
|
|||||||
@IsObject()
|
@IsObject()
|
||||||
options: T
|
options: T
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parses a parameter value from a string
|
||||||
|
*
|
||||||
|
* @param parameter parameter to parse
|
||||||
|
*/
|
||||||
constructor(parameter: string) {
|
constructor(parameter: string) {
|
||||||
const [name, optionsRaw] = parameter.split('|')
|
const [name, optionsRaw] = parameter.split('|')
|
||||||
if (!name) throw new Error('Invalid parameter')
|
if (!name) throw new Error('Invalid parameter')
|
||||||
@ -115,8 +120,33 @@ export class TransformQueryBase {
|
|||||||
@ValidateNested()
|
@ValidateNested()
|
||||||
op: ComplexParameter[] = []
|
op: ComplexParameter[] = []
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
preset?: string
|
||||||
|
|
||||||
constructor(data: any, options: { headers: IncomingHttpHeaders }) {
|
constructor(data: any, options: { headers: IncomingHttpHeaders }) {
|
||||||
|
if (Config.onlyAllowPresets) {
|
||||||
|
const { url, preset, ...rest } = data
|
||||||
|
if (!preset) {
|
||||||
|
throw new Error('Preset is required')
|
||||||
|
}
|
||||||
|
if (Object.keys(rest).length > 0) {
|
||||||
|
throw new Error('only preset parameter is allowed')
|
||||||
|
}
|
||||||
|
this.url = url
|
||||||
|
this.preset = data.preset
|
||||||
|
} else {
|
||||||
Object.assign(this, data)
|
Object.assign(this, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.preset) {
|
||||||
|
const preset = Config.presets[this.preset]
|
||||||
|
if (!preset) {
|
||||||
|
throw new Error('preset not found')
|
||||||
|
}
|
||||||
|
const params = Object.fromEntries(new URLSearchParams(preset).entries())
|
||||||
|
Object.assign(this, params)
|
||||||
|
}
|
||||||
|
|
||||||
if (this.width) this.width = parseInt(this.width as any)
|
if (this.width) this.width = parseInt(this.width as any)
|
||||||
if (this.height) this.height = parseInt(this.height as any)
|
if (this.height) this.height = parseInt(this.height as any)
|
||||||
@ -127,8 +157,7 @@ export class TransformQueryBase {
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.format = new ComplexParameter((this.format as any) || 'auto')
|
this.format = new ComplexParameter((this.format as any) || 'auto')
|
||||||
if ((this.format.name as string) === 'auto') {
|
if ((this.format.name as string) === 'auto') {
|
||||||
if (!options.headers) throw new Error('cannot use auto format without user agent')
|
if (!options.headers) throw new Error('cannot use auto format without headers')
|
||||||
|
|
||||||
this.autoFormat(options.headers)
|
this.autoFormat(options.headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,13 +181,7 @@ export class TransformQueryBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toString(): string {
|
private autoFormat(headers: IncomingHttpHeaders) {
|
||||||
const data = flatten(this) as Record<string, any>
|
|
||||||
return new URLSearchParams(sortObjectByKeys(data)).toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
autoFormat(headers: IncomingHttpHeaders) {
|
|
||||||
const ua = headers['user-agent']
|
|
||||||
const accept = headers['accept'] // Accept: image/avif,image/webp,*/*
|
const accept = headers['accept'] // Accept: image/avif,image/webp,*/*
|
||||||
if (accept) {
|
if (accept) {
|
||||||
const acceptTypes = accept.split(',')
|
const acceptTypes = accept.split(',')
|
||||||
@ -173,6 +196,11 @@ export class TransformQueryBase {
|
|||||||
this.format!.name = 'jpeg'
|
this.format!.name = 'jpeg'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toString(): string {
|
||||||
|
const data = flatten(this) as Record<string, any>
|
||||||
|
return new URLSearchParams(sortObjectByKeys(data)).toString()
|
||||||
|
}
|
||||||
|
|
||||||
get hash(): string {
|
get hash(): string {
|
||||||
return sha3(this.toString())
|
return sha3(this.toString())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user