This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
// The handlers of the branding procedures: each resolves its ports and calls one use case.
|
||||
|
||||
import { type Container, implement, validationFailed } from "@conusai-kit/core"
|
||||
import { DATA_SOURCE, OBJECT_STORE } from "@conusai-kit/data"
|
||||
import { brandGet, brandSet, logoClear, logoGet, logoSet } from "../contract/index.js"
|
||||
import { type BrandingDeps, clearLogo, getBrand, readLogo, setBrand, setLogo } from "../core/brand.js"
|
||||
|
||||
export const brandingDeps = (container: Container): BrandingDeps => ({
|
||||
data: container.resolve(DATA_SOURCE),
|
||||
store: container.resolve(OBJECT_STORE),
|
||||
})
|
||||
|
||||
/** Standard base64 to bytes, refusing anything else as a 422 that names the field. */
|
||||
function bytesOf(body: string): Uint8Array {
|
||||
if (!/^[A-Za-z0-9+/]*={0,2}$/.test(body) || body.length % 4 !== 0) {
|
||||
throw validationFailed([{ path: "body", message: "is not standard base64" }])
|
||||
}
|
||||
return Uint8Array.from(atob(body), (char) => char.charCodeAt(0))
|
||||
}
|
||||
|
||||
const toBase64 = (bytes: Uint8Array): string => {
|
||||
let binary = ""
|
||||
for (const byte of bytes) binary += String.fromCharCode(byte)
|
||||
return btoa(binary)
|
||||
}
|
||||
|
||||
export const brandGetImpl = implement(brandGet, async ({ ctx }) =>
|
||||
getBrand(brandingDeps(ctx.container).data, ctx.scope),
|
||||
)
|
||||
|
||||
export const brandSetImpl = implement(brandSet, async ({ input, ctx }) =>
|
||||
setBrand(brandingDeps(ctx.container).data, ctx.scope, {
|
||||
displayName: input.displayName,
|
||||
primary: input.primary,
|
||||
accent: input.accent,
|
||||
}),
|
||||
)
|
||||
|
||||
export const logoSetImpl = implement(logoSet, async ({ input, ctx }) =>
|
||||
setLogo(brandingDeps(ctx.container), ctx.scope, {
|
||||
variant: input.variant,
|
||||
contentType: input.contentType,
|
||||
bytes: bytesOf(input.body),
|
||||
}),
|
||||
)
|
||||
|
||||
export const logoClearImpl = implement(logoClear, async ({ input, ctx }) =>
|
||||
clearLogo(brandingDeps(ctx.container), ctx.scope, input.variant),
|
||||
)
|
||||
|
||||
export const logoGetImpl = implement(logoGet, async ({ input, ctx }) => {
|
||||
const logo = await readLogo(brandingDeps(ctx.container), ctx.scope, input.variant, input.size)
|
||||
return { contentType: logo.contentType, body: toBase64(logo.bytes) }
|
||||
})
|
||||
|
||||
export const BRANDING_PROCEDURES = [brandGetImpl, brandSetImpl, logoSetImpl, logoClearImpl, logoGetImpl]
|
||||
Reference in New Issue
Block a user