diff --git a/packages/core/src/lib/config/index.ts b/packages/core/src/lib/config/index.ts index 772f1a8..23f8a18 100644 --- a/packages/core/src/lib/config/index.ts +++ b/packages/core/src/lib/config/index.ts @@ -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, diff --git a/packages/core/src/lib/config/types.ts b/packages/core/src/lib/config/types.ts index 94ea3c2..cf6ac4f 100644 --- a/packages/core/src/lib/config/types.ts +++ b/packages/core/src/lib/config/types.ts @@ -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 +export type TypographiesConfig = z.infer +export type PagesConfig = z.infer + +export type UserFileConfig = z.infer +export type UserConfig = z.infer 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) diff --git a/packages/core/src/lib/config/validator.ts b/packages/core/src/lib/config/validator.ts deleted file mode 100644 index 6d04916..0000000 --- a/packages/core/src/lib/config/validator.ts +++ /dev/null @@ -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) diff --git a/packages/core/src/lib/types.ts b/packages/core/src/lib/types.ts index 03c44fb..e45a63e 100644 --- a/packages/core/src/lib/types.ts +++ b/packages/core/src/lib/types.ts @@ -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