mirror of
https://github.com/penpot/penpot-export.git
synced 2025-01-19 21:22:28 -05:00
refactor(core): colocate schemas, types and validators
This commit is contained in:
parent
f7b972e032
commit
924d5bec7b
4 changed files with 99 additions and 120 deletions
|
@ -1,7 +1,6 @@
|
|||
import { UserConfig, UserFileConfig } from '../types'
|
||||
import { UserConfig, UserFileConfig, Config, FileConfig } from './types'
|
||||
|
||||
import { Config, FileConfig } from './types'
|
||||
export { validateUserConfig } from './validator'
|
||||
export { validateUserConfig } from './types'
|
||||
|
||||
function normalizePenpotExportUserFileConfig(
|
||||
userConfig: UserFileConfig,
|
||||
|
|
|
@ -1,15 +1,97 @@
|
|||
export interface PagesConfig {
|
||||
output: string
|
||||
pageId: string
|
||||
}
|
||||
import { z } from 'zod'
|
||||
|
||||
export interface TypographiesConfig {
|
||||
output: string
|
||||
}
|
||||
// Schemas
|
||||
const accessTokenSchema = z.string({
|
||||
required_error: '.accessToken is required',
|
||||
invalid_type_error: '.accessToken must be a string',
|
||||
})
|
||||
const instanceSchema = z
|
||||
.string({
|
||||
required_error: '.instance is required',
|
||||
invalid_type_error: '.instance must be a string',
|
||||
})
|
||||
.url({
|
||||
message: '.instance must be a valid URL',
|
||||
})
|
||||
const fileIdSchema = z
|
||||
.string({
|
||||
required_error: '.fileId is required',
|
||||
invalid_type_error: '.fileId must be a string',
|
||||
})
|
||||
.uuid({
|
||||
message: '.fileId must be a valid UUID',
|
||||
})
|
||||
const pageIdSchema = z
|
||||
.string({
|
||||
required_error: '.pageId is required',
|
||||
invalid_type_error: '.pageId must be a string',
|
||||
})
|
||||
.uuid({
|
||||
message: '.pageId must be a valid UUID',
|
||||
})
|
||||
const outputSchema = z.string({
|
||||
required_error: '.output is required',
|
||||
invalid_type_error: '.output must be a string',
|
||||
})
|
||||
|
||||
export interface ColorsConfig {
|
||||
output: string
|
||||
}
|
||||
const colorsConfigSchema = z.object({
|
||||
output: outputSchema,
|
||||
})
|
||||
const typographiesConfigSchema = z.object({
|
||||
output: outputSchema,
|
||||
})
|
||||
const pagesConfigSchema = z.object({
|
||||
output: outputSchema,
|
||||
pageId: pageIdSchema,
|
||||
})
|
||||
|
||||
const userFileConfigSchema = z
|
||||
.object({
|
||||
fileId: fileIdSchema,
|
||||
colors: z.optional(
|
||||
z
|
||||
.array(colorsConfigSchema)
|
||||
.nonempty({ message: '.colors is required to have at least one item' }),
|
||||
),
|
||||
typographies: z.optional(
|
||||
z.array(typographiesConfigSchema).nonempty({
|
||||
message: '.typographies is required to have at least one item',
|
||||
}),
|
||||
),
|
||||
pages: z.optional(
|
||||
z
|
||||
.array(pagesConfigSchema)
|
||||
.nonempty({ message: '.pages is required to have at least one item' }),
|
||||
),
|
||||
})
|
||||
.refine(
|
||||
(object) => {
|
||||
if ('colors' in object) return true
|
||||
if ('typographies' in object) return true
|
||||
if ('pages' in object) return true
|
||||
return false
|
||||
},
|
||||
{
|
||||
message:
|
||||
'Each file in .files is required to have at least one of .colors, .typographies or .pages properties',
|
||||
},
|
||||
)
|
||||
|
||||
const userConfigSchema = z.object({
|
||||
accessToken: accessTokenSchema,
|
||||
instance: z.optional(instanceSchema),
|
||||
files: z
|
||||
.array(userFileConfigSchema)
|
||||
.nonempty({ message: '.files is required to have at least one item' }),
|
||||
})
|
||||
|
||||
// Types
|
||||
export type ColorsConfig = z.infer<typeof colorsConfigSchema>
|
||||
export type TypographiesConfig = z.infer<typeof typographiesConfigSchema>
|
||||
export type PagesConfig = z.infer<typeof pagesConfigSchema>
|
||||
|
||||
export type UserFileConfig = z.infer<typeof userFileConfigSchema>
|
||||
export type UserConfig = z.infer<typeof userConfigSchema>
|
||||
|
||||
export interface FileConfig {
|
||||
fileId: string
|
||||
|
@ -23,3 +105,7 @@ export interface Config {
|
|||
accessToken: string
|
||||
files: FileConfig[]
|
||||
}
|
||||
|
||||
// Validators
|
||||
export const validateUserConfig = (userConfig: object): UserConfig =>
|
||||
userConfigSchema.parse(userConfig)
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
import { z } from 'zod'
|
||||
|
||||
import { UserConfig } from '../types'
|
||||
|
||||
const accessTokenSchema = z.string({
|
||||
required_error: '.accessToken is required',
|
||||
invalid_type_error: '.accessToken must be a string',
|
||||
})
|
||||
const instanceSchema = z
|
||||
.string({
|
||||
required_error: '.instance is required',
|
||||
invalid_type_error: '.instance must be a string',
|
||||
})
|
||||
.url({
|
||||
message: '.instance must be a valid URL',
|
||||
})
|
||||
const fileIdSchema = z
|
||||
.string({
|
||||
required_error: '.fileId is required',
|
||||
invalid_type_error: '.fileId must be a string',
|
||||
})
|
||||
.uuid({
|
||||
message: '.fileId must be a valid UUID',
|
||||
})
|
||||
const pageIdSchema = z
|
||||
.string({
|
||||
required_error: '.pageId is required',
|
||||
invalid_type_error: '.pageId must be a string',
|
||||
})
|
||||
.uuid({
|
||||
message: '.pageId must be a valid UUID',
|
||||
})
|
||||
const outputSchema = z.string({
|
||||
required_error: '.output is required',
|
||||
invalid_type_error: '.output must be a string',
|
||||
})
|
||||
|
||||
const userColorsConfigSchema = z.object({
|
||||
output: outputSchema,
|
||||
})
|
||||
const userTypographiesConfigSchema = z.object({
|
||||
output: outputSchema,
|
||||
})
|
||||
const userPagesConfigSchema = z.object({
|
||||
output: outputSchema,
|
||||
pageId: pageIdSchema,
|
||||
})
|
||||
|
||||
const userFileConfigSchema = z
|
||||
.object({
|
||||
fileId: fileIdSchema,
|
||||
colors: z.optional(
|
||||
z
|
||||
.array(userColorsConfigSchema)
|
||||
.nonempty({ message: '.colors is required to have at least one item' }),
|
||||
),
|
||||
typographies: z.optional(
|
||||
z.array(userTypographiesConfigSchema).nonempty({
|
||||
message: '.typographies is required to have at least one item',
|
||||
}),
|
||||
),
|
||||
pages: z.optional(
|
||||
z
|
||||
.array(userPagesConfigSchema)
|
||||
.nonempty({ message: '.pages is required to have at least one item' }),
|
||||
),
|
||||
})
|
||||
.refine(
|
||||
(object) => {
|
||||
if ('colors' in object) return true
|
||||
if ('typographies' in object) return true
|
||||
if ('pages' in object) return true
|
||||
return false
|
||||
},
|
||||
{
|
||||
message:
|
||||
'Each file in .files is required to have at least one of .colors, .typographies or .pages properties',
|
||||
},
|
||||
)
|
||||
|
||||
const userConfigSchema = z.object({
|
||||
accessToken: accessTokenSchema,
|
||||
instance: z.optional(instanceSchema),
|
||||
files: z
|
||||
.array(userFileConfigSchema)
|
||||
.nonempty({ message: '.files is required to have at least one item' }),
|
||||
})
|
||||
|
||||
export const validateUserConfig = (userConfig: object): UserConfig =>
|
||||
userConfigSchema.parse(userConfig)
|
|
@ -3,24 +3,8 @@ import type {
|
|||
PenpotApiTypography,
|
||||
PenpotApiColor,
|
||||
} from './api/types'
|
||||
import type {
|
||||
ColorsConfig,
|
||||
PagesConfig,
|
||||
TypographiesConfig,
|
||||
} from './config/types'
|
||||
|
||||
export type UserFileConfig = {
|
||||
fileId: string
|
||||
colors?: ColorsConfig[]
|
||||
typographies?: TypographiesConfig[]
|
||||
pages?: PagesConfig[]
|
||||
}
|
||||
|
||||
export interface UserConfig {
|
||||
instance?: string
|
||||
accessToken: string
|
||||
files: UserFileConfig[]
|
||||
}
|
||||
export type { UserConfig } from './config/types'
|
||||
|
||||
export interface PenpotExportFile {
|
||||
fileName: string
|
||||
|
|
Loading…
Add table
Reference in a new issue