Skip to content

Commit

Permalink
feat(cli): add JSON schema for config file
Browse files Browse the repository at this point in the history
  • Loading branch information
unekinn committed Jan 9, 2025
1 parent bcd50d9 commit c0ad228
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 15 deletions.
11 changes: 11 additions & 0 deletions .changeset/friendly-hotels-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@digdir/designsystemet": minor
---

Add JSON schema for CLI config file, which enables editor hints. To use it, do something like this:
```jsonc
{
"$schema": "node_modules/@digdir/designsystemet/dist/config.schema.json"
// ...config options here...
}
```
54 changes: 41 additions & 13 deletions packages/cli/bin/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,52 @@ export function mapPathToOptionName(path: (string | number)[]) {
return option;
}

const themeSchema = z.object({
colors: z.object({
main: z.record(z.string().transform(convertToHex)),
support: z.record(z.string().transform(convertToHex)),
neutral: z.string().transform(convertToHex),
}),
typography: z.object({
fontFamily: z.string(),
}),
borderRadius: z.number(),
});
const hexPatterns = [
// Hex colors: #000, #0000, #000000, #00000000
`#[0-9a-fA-F]{3}`,
`#[0-9a-fA-F]{4}`,
`#[0-9a-fA-F]{6}`,
`#[0-9a-fA-F]{8}`,
];

export const colorRegex = new RegExp(`^${hexPatterns.join('|')}$`);

const colorSchema = z
.string({ description: 'A hex color, which is used for creating a color scale' })
.regex(colorRegex)
.transform(convertToHex);
const colorCategorySchema = z.record(colorSchema, { description: 'One or more color definitions' });

const themeSchema = z.object(
{
colors: z.object(
{
main: colorCategorySchema,
support: colorCategorySchema,
neutral: colorSchema,
},
{ description: 'Defines the colors for this theme' },
),
typography: z.object(
{
fontFamily: z.string({ description: 'Sets the font-family for this theme' }),
},
{ description: 'Defines the typography for a given theme' },
),
borderRadius: z.number({ description: 'Defines the border-radius for this theme' }),
},
{ description: 'An object defining a theme. The property name holding the object becomes the theme name.' },
);

/**
* This defines the structure of the JSON config file
*/
export const configFileSchema = z.object({
outDir: z.string().optional(),
themes: z.record(themeSchema),
outDir: z.string({ description: 'Path to the output directory for the created design tokens' }).optional(),
themes: z.record(themeSchema, {
description:
'An object with one or more themes. Each property defines a theme, and the property name is used as the theme name.',
}),
});

/**
Expand Down
6 changes: 4 additions & 2 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@
"designsystemet": "tsx ./bin/designsystemet.ts",
"build:tokens": "yarn clean:theme && yarn designsystemet tokens build -p -t ../../design-tokens -o ../../packages/theme/brand",
"build:tokens:debug": "yarn clean:theme && tsx --inspect-brk ./bin/designsystemet.ts tokens build -p -t ../../design-tokens -o ../../packages/theme/brand",
"build": "tsup && yarn build:types",
"build": "tsup && yarn build:types && yarn build:json-schema",
"build:types": "tsc --emitDeclarationOnly --declaration",
"build:json-schema": "tsx ./src/build-scripts/createJsonSchema.ts",
"types": "tsc --noEmit",
"test:tokens-create-options": "yarn designsystemet tokens create -m dominant:#007682 complimentary:#ff0000 -n #003333 -s support1:#12404f support2:#0054a6 support3:#942977 -b 99 -o ./test-tokens-create",
"test:tokens-create-json": "yarn designsystemet tokens create --json ./test-tokens-create-complex.config.json",
Expand Down Expand Up @@ -85,6 +86,7 @@
"tslib": "^2.6.3",
"tsup": "^8.2.4",
"tsx": "^4.16.5",
"typescript": "^5.5.4"
"typescript": "^5.5.4",
"zod-to-json-schema": "^3.24.1"
}
}
19 changes: 19 additions & 0 deletions packages/cli/src/build-scripts/createJsonSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { writeFile } from 'node:fs/promises';
import { resolve } from 'node:path';
import { z } from 'zod';
import { zodToJsonSchema } from 'zod-to-json-schema';
import { configFileSchema } from '../../bin/config.js';

const schema = z
.object({
$schema: z.string().optional(),
})
.extend(configFileSchema.shape);

writeFile(
resolve(import.meta.dirname, '../../dist/config.schema.json'),
JSON.stringify(zodToJsonSchema(schema), undefined, 2),
{
encoding: 'utf-8',
},
);
1 change: 1 addition & 0 deletions packages/cli/test-tokens-create-complex.config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "./dist/config.schema.json",
"outDir": "./test-tokens-create",
"themes": {
"some-org": {
Expand Down
1 change: 1 addition & 0 deletions packages/cli/test-tokens-create.config.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "./dist/config.schema.json",
"outDir": "./test-tokens-create",
"themes": {
"digdir": {
Expand Down
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1785,6 +1785,7 @@ __metadata:
tsx: "npm:^4.16.5"
typescript: "npm:^5.5.4"
zod: "npm:^3.23.8"
zod-to-json-schema: "npm:^3.24.1"
zod-validation-error: "npm:^3.4.0"
bin:
designsystemet: dist/bin/designsystemet.js
Expand Down Expand Up @@ -18526,6 +18527,15 @@ __metadata:
languageName: node
linkType: hard

"zod-to-json-schema@npm:^3.24.1":
version: 3.24.1
resolution: "zod-to-json-schema@npm:3.24.1"
peerDependencies:
zod: ^3.24.1
checksum: 10/d31fd05b67b428d8e0d5ecad2c3e80a1c2fc370e4c22f9111ffd11cbe05cfcab00f3228f84295830952649d15ea4494ef42c2ee1cbe723c865b13f4cf2b80c09
languageName: node
linkType: hard

"zod-validation-error@npm:^3.4.0":
version: 3.4.0
resolution: "zod-validation-error@npm:3.4.0"
Expand Down

0 comments on commit c0ad228

Please sign in to comment.