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
|
||||
FROM base
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile --prod
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "morphus",
|
||||
"version": "0.1.0",
|
||||
"version": "1.0.0-rc.2",
|
||||
"description": "",
|
||||
"author": "Niccolo Borgioli",
|
||||
"license": "MIT",
|
||||
|
@ -30,6 +30,7 @@ const Schema = yaml.DEFAULT_SCHEMA.extend([RegExpTag])
|
||||
export type NullableStringOrRegexpArray = (string | RegExp)[] | null
|
||||
|
||||
function formatNullableStringOrRegexpArray(values: any) {
|
||||
if (values === null) return
|
||||
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')
|
||||
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 }) })
|
||||
|
||||
export const config = convict({
|
||||
@ -101,6 +114,19 @@ export const config = convict({
|
||||
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: {
|
||||
assets: {
|
||||
|
@ -61,6 +61,11 @@ export class ComplexParameter<N = string, T extends object = {}> {
|
||||
@IsObject()
|
||||
options: T
|
||||
|
||||
/**
|
||||
* parses a parameter value from a string
|
||||
*
|
||||
* @param parameter parameter to parse
|
||||
*/
|
||||
constructor(parameter: string) {
|
||||
const [name, optionsRaw] = parameter.split('|')
|
||||
if (!name) throw new Error('Invalid parameter')
|
||||
@ -115,8 +120,33 @@ export class TransformQueryBase {
|
||||
@ValidateNested()
|
||||
op: ComplexParameter[] = []
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
preset?: string
|
||||
|
||||
constructor(data: any, options: { headers: IncomingHttpHeaders }) {
|
||||
Object.assign(this, data)
|
||||
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)
|
||||
}
|
||||
|
||||
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.height) this.height = parseInt(this.height as any)
|
||||
@ -127,8 +157,7 @@ export class TransformQueryBase {
|
||||
// @ts-ignore
|
||||
this.format = new ComplexParameter((this.format as any) || '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)
|
||||
}
|
||||
|
||||
@ -152,13 +181,7 @@ export class TransformQueryBase {
|
||||
}
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
const data = flatten(this) as Record<string, any>
|
||||
return new URLSearchParams(sortObjectByKeys(data)).toString()
|
||||
}
|
||||
|
||||
autoFormat(headers: IncomingHttpHeaders) {
|
||||
const ua = headers['user-agent']
|
||||
private autoFormat(headers: IncomingHttpHeaders) {
|
||||
const accept = headers['accept'] // Accept: image/avif,image/webp,*/*
|
||||
if (accept) {
|
||||
const acceptTypes = accept.split(',')
|
||||
@ -173,6 +196,11 @@ export class TransformQueryBase {
|
||||
this.format!.name = 'jpeg'
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
const data = flatten(this) as Record<string, any>
|
||||
return new URLSearchParams(sortObjectByKeys(data)).toString()
|
||||
}
|
||||
|
||||
get hash(): string {
|
||||
return sha3(this.toString())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user