@digdir/designsystemet 1.0.0-next.46 → 1.0.0-next.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,10 +6,11 @@ export declare const colorRegex: RegExp;
6
6
  */
7
7
  export declare const configFileSchema: z.ZodObject<{
8
8
  outDir: z.ZodOptional<z.ZodString>;
9
+ clean: z.ZodOptional<z.ZodBoolean>;
9
10
  themes: z.ZodRecord<z.ZodString, z.ZodObject<{
10
11
  colors: z.ZodObject<{
11
12
  main: z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodString, `#${string}` | `rgb(${number} ${number} ${number})` | `hsl(${number}deg ${number}% ${number}%)` | `hsv(${number}deg ${number}% ${number}%)` | `hsluv(${number} ${number} ${number})` | `lab(${number}% ${number} ${number})` | `lch(${number}% ${number} ${number}deg)` | `oklab(${number}% ${number} ${number})` | `oklch(${number}% ${number} ${number}deg)` | `jab(${number}% ${number} ${number})` | `jch(${number}% ${number} ${number}deg)`, string>>;
12
- support: z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodString, `#${string}` | `rgb(${number} ${number} ${number})` | `hsl(${number}deg ${number}% ${number}%)` | `hsv(${number}deg ${number}% ${number}%)` | `hsluv(${number} ${number} ${number})` | `lab(${number}% ${number} ${number})` | `lch(${number}% ${number} ${number}deg)` | `oklab(${number}% ${number} ${number})` | `oklch(${number}% ${number} ${number}deg)` | `jab(${number}% ${number} ${number})` | `jch(${number}% ${number} ${number}deg)`, string>>;
13
+ support: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodString, `#${string}` | `rgb(${number} ${number} ${number})` | `hsl(${number}deg ${number}% ${number}%)` | `hsv(${number}deg ${number}% ${number}%)` | `hsluv(${number} ${number} ${number})` | `lab(${number}% ${number} ${number})` | `lch(${number}% ${number} ${number}deg)` | `oklab(${number}% ${number} ${number})` | `oklch(${number}% ${number} ${number}deg)` | `jab(${number}% ${number} ${number})` | `jch(${number}% ${number} ${number}deg)`, string>>>>;
13
14
  neutral: z.ZodEffects<z.ZodString, `#${string}` | `rgb(${number} ${number} ${number})` | `hsl(${number}deg ${number}% ${number}%)` | `hsv(${number}deg ${number}% ${number}%)` | `hsluv(${number} ${number} ${number})` | `lab(${number}% ${number} ${number})` | `lch(${number}% ${number} ${number}deg)` | `oklab(${number}% ${number} ${number})` | `oklch(${number}% ${number} ${number}deg)` | `jab(${number}% ${number} ${number})` | `jch(${number}% ${number} ${number}deg)`, string>;
14
15
  }, "strip", z.ZodTypeAny, {
15
16
  main: Record<string, `#${string}` | `rgb(${number} ${number} ${number})` | `hsl(${number}deg ${number}% ${number}%)` | `hsv(${number}deg ${number}% ${number}%)` | `hsluv(${number} ${number} ${number})` | `lab(${number}% ${number} ${number})` | `lch(${number}% ${number} ${number}deg)` | `oklab(${number}% ${number} ${number})` | `oklch(${number}% ${number} ${number}deg)` | `jab(${number}% ${number} ${number})` | `jch(${number}% ${number} ${number}deg)`>;
@@ -18,7 +19,7 @@ export declare const configFileSchema: z.ZodObject<{
18
19
  }, {
19
20
  main: Record<string, string>;
20
21
  neutral: string;
21
- support: Record<string, string>;
22
+ support?: Record<string, string> | undefined;
22
23
  }>;
23
24
  typography: z.ZodObject<{
24
25
  fontFamily: z.ZodString;
@@ -42,7 +43,7 @@ export declare const configFileSchema: z.ZodObject<{
42
43
  colors: {
43
44
  main: Record<string, string>;
44
45
  neutral: string;
45
- support: Record<string, string>;
46
+ support?: Record<string, string> | undefined;
46
47
  };
47
48
  typography: {
48
49
  fontFamily: string;
@@ -61,19 +62,21 @@ export declare const configFileSchema: z.ZodObject<{
61
62
  };
62
63
  borderRadius: number;
63
64
  }>;
65
+ clean?: boolean | undefined;
64
66
  outDir?: string | undefined;
65
67
  }, {
66
68
  themes: Record<string, {
67
69
  colors: {
68
70
  main: Record<string, string>;
69
71
  neutral: string;
70
- support: Record<string, string>;
72
+ support?: Record<string, string> | undefined;
71
73
  };
72
74
  typography: {
73
75
  fontFamily: string;
74
76
  };
75
77
  borderRadius: number;
76
78
  }>;
79
+ clean?: boolean | undefined;
77
80
  outDir?: string | undefined;
78
81
  }>;
79
82
  /**
@@ -82,10 +85,11 @@ export declare const configFileSchema: z.ZodObject<{
82
85
  */
83
86
  export declare const combinedConfigSchema: z.ZodObject<{
84
87
  outDir: z.ZodString;
88
+ clean: z.ZodBoolean;
85
89
  themes: z.ZodRecord<z.ZodString, z.ZodObject<{
86
90
  colors: z.ZodObject<{
87
91
  main: z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodString, `#${string}` | `rgb(${number} ${number} ${number})` | `hsl(${number}deg ${number}% ${number}%)` | `hsv(${number}deg ${number}% ${number}%)` | `hsluv(${number} ${number} ${number})` | `lab(${number}% ${number} ${number})` | `lch(${number}% ${number} ${number}deg)` | `oklab(${number}% ${number} ${number})` | `oklch(${number}% ${number} ${number}deg)` | `jab(${number}% ${number} ${number})` | `jch(${number}% ${number} ${number}deg)`, string>>;
88
- support: z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodString, `#${string}` | `rgb(${number} ${number} ${number})` | `hsl(${number}deg ${number}% ${number}%)` | `hsv(${number}deg ${number}% ${number}%)` | `hsluv(${number} ${number} ${number})` | `lab(${number}% ${number} ${number})` | `lch(${number}% ${number} ${number}deg)` | `oklab(${number}% ${number} ${number})` | `oklch(${number}% ${number} ${number}deg)` | `jab(${number}% ${number} ${number})` | `jch(${number}% ${number} ${number}deg)`, string>>;
92
+ support: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEffects<z.ZodString, `#${string}` | `rgb(${number} ${number} ${number})` | `hsl(${number}deg ${number}% ${number}%)` | `hsv(${number}deg ${number}% ${number}%)` | `hsluv(${number} ${number} ${number})` | `lab(${number}% ${number} ${number})` | `lch(${number}% ${number} ${number}deg)` | `oklab(${number}% ${number} ${number})` | `oklch(${number}% ${number} ${number}deg)` | `jab(${number}% ${number} ${number})` | `jch(${number}% ${number} ${number}deg)`, string>>>>;
89
93
  neutral: z.ZodEffects<z.ZodString, `#${string}` | `rgb(${number} ${number} ${number})` | `hsl(${number}deg ${number}% ${number}%)` | `hsv(${number}deg ${number}% ${number}%)` | `hsluv(${number} ${number} ${number})` | `lab(${number}% ${number} ${number})` | `lch(${number}% ${number} ${number}deg)` | `oklab(${number}% ${number} ${number})` | `oklch(${number}% ${number} ${number}deg)` | `jab(${number}% ${number} ${number})` | `jch(${number}% ${number} ${number}deg)`, string>;
90
94
  }, "strip", z.ZodTypeAny, {
91
95
  main: Record<string, `#${string}` | `rgb(${number} ${number} ${number})` | `hsl(${number}deg ${number}% ${number}%)` | `hsv(${number}deg ${number}% ${number}%)` | `hsluv(${number} ${number} ${number})` | `lab(${number}% ${number} ${number})` | `lch(${number}% ${number} ${number}deg)` | `oklab(${number}% ${number} ${number})` | `oklch(${number}% ${number} ${number}deg)` | `jab(${number}% ${number} ${number})` | `jch(${number}% ${number} ${number}deg)`>;
@@ -94,7 +98,7 @@ export declare const combinedConfigSchema: z.ZodObject<{
94
98
  }, {
95
99
  main: Record<string, string>;
96
100
  neutral: string;
97
- support: Record<string, string>;
101
+ support?: Record<string, string> | undefined;
98
102
  }>;
99
103
  typography: z.ZodObject<{
100
104
  fontFamily: z.ZodString;
@@ -118,7 +122,7 @@ export declare const combinedConfigSchema: z.ZodObject<{
118
122
  colors: {
119
123
  main: Record<string, string>;
120
124
  neutral: string;
121
- support: Record<string, string>;
125
+ support?: Record<string, string> | undefined;
122
126
  };
123
127
  typography: {
124
128
  fontFamily: string;
@@ -126,6 +130,7 @@ export declare const combinedConfigSchema: z.ZodObject<{
126
130
  borderRadius: number;
127
131
  }>>;
128
132
  }, "strip", z.ZodTypeAny, {
133
+ clean: boolean;
129
134
  themes: Record<string, {
130
135
  colors: {
131
136
  main: Record<string, `#${string}` | `rgb(${number} ${number} ${number})` | `hsl(${number}deg ${number}% ${number}%)` | `hsv(${number}deg ${number}% ${number}%)` | `hsluv(${number} ${number} ${number})` | `lab(${number}% ${number} ${number})` | `lch(${number}% ${number} ${number}deg)` | `oklab(${number}% ${number} ${number})` | `oklch(${number}% ${number} ${number}deg)` | `jab(${number}% ${number} ${number})` | `jch(${number}% ${number} ${number}deg)`>;
@@ -139,11 +144,12 @@ export declare const combinedConfigSchema: z.ZodObject<{
139
144
  }>;
140
145
  outDir: string;
141
146
  }, {
147
+ clean: boolean;
142
148
  themes: Record<string, {
143
149
  colors: {
144
150
  main: Record<string, string>;
145
151
  neutral: string;
146
- support: Record<string, string>;
152
+ support?: Record<string, string> | undefined;
147
153
  };
148
154
  typography: {
149
155
  fontFamily: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../bin/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,sBAQ5D;AAUD,eAAO,MAAM,UAAU,QAA2C,CAAC;AA6BnE;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAM3B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA8B,CAAC;AAChE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../bin/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,sBAQ5D;AAUD,eAAO,MAAM,UAAU,QAA2C,CAAC;AA6BnE;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAO3B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAA8B,CAAC;AAChE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
@@ -0,0 +1,56 @@
1
+ import * as R from "ramda";
2
+ import { z } from "zod";
3
+ import { convertToHex } from "../src/colors/index.js";
4
+ import { cliOptions } from "../src/tokens/create.js";
5
+ function mapPathToOptionName(path) {
6
+ const normalisedPath = path[0] === "themes" ? ["theme", ...R.drop(2, path)] : path;
7
+ const option = R.path(normalisedPath, cliOptions);
8
+ if (typeof option !== "string") {
9
+ return;
10
+ }
11
+ return option;
12
+ }
13
+ const hexPatterns = [
14
+ // Hex colors: #000, #0000, #000000, #00000000
15
+ `#[0-9a-fA-F]{3}`,
16
+ `#[0-9a-fA-F]{4}`,
17
+ `#[0-9a-fA-F]{6}`,
18
+ `#[0-9a-fA-F]{8}`
19
+ ];
20
+ const colorRegex = new RegExp(`^${hexPatterns.join("|")}$`);
21
+ const colorSchema = z.string({ description: "A hex color, which is used for creating a color scale" }).regex(colorRegex).transform(convertToHex);
22
+ const colorCategorySchema = z.record(colorSchema, { description: "One or more color definitions" });
23
+ const themeSchema = z.object(
24
+ {
25
+ colors: z.object(
26
+ {
27
+ main: colorCategorySchema,
28
+ support: colorCategorySchema.optional().default({}),
29
+ neutral: colorSchema
30
+ },
31
+ { description: "Defines the colors for this theme" }
32
+ ),
33
+ typography: z.object(
34
+ {
35
+ fontFamily: z.string({ description: "Sets the font-family for this theme" })
36
+ },
37
+ { description: "Defines the typography for a given theme" }
38
+ ),
39
+ borderRadius: z.number({ description: "Defines the border-radius for this theme" })
40
+ },
41
+ { description: "An object defining a theme. The property name holding the object becomes the theme name." }
42
+ );
43
+ const configFileSchema = z.object({
44
+ outDir: z.string({ description: "Path to the output directory for the created design tokens" }).optional(),
45
+ clean: z.boolean({ description: "Delete the output directory before building or creating tokens" }).optional(),
46
+ themes: z.record(themeSchema, {
47
+ description: "An object with one or more themes. Each property defines a theme, and the property name is used as the theme name."
48
+ })
49
+ });
50
+ const combinedConfigSchema = configFileSchema.required();
51
+ export {
52
+ colorRegex,
53
+ combinedConfigSchema,
54
+ configFileSchema,
55
+ mapPathToOptionName
56
+ };
@@ -15,41 +15,43 @@ import { getDefaultOrExplicitOption, getExplicitOptionOnly } from "./options.js"
15
15
  program.name("designsystemet").description("CLI for working with Designsystemet").showHelpAfterError();
16
16
  function makeTokenCommands() {
17
17
  const tokenCmd = createCommand("tokens");
18
- const DEFAULT_TOKENS_DIR = "./design-tokens";
19
- const DEFAULT_BUILD_DIR = "./design-tokens-build";
18
+ const DEFAULT_TOKENS_CREATE_DIR = "./design-tokens";
19
+ const DEFAULT_TOKENS_BUILD_DIR = "./design-tokens-build";
20
20
  const DEFAULT_FONT = "Inter";
21
21
  const DEFAULT_THEME_NAME = "theme";
22
22
  const DEFAULT_CONFIG_FILE = "designsystemet.config.json";
23
- tokenCmd.command("build").description("Build Designsystemet tokens").option("-t, --tokens <string>", `Path to ${chalk.blue("design-tokens")}`, DEFAULT_TOKENS_DIR).option("-o, --out-dir <string>", `Output directory for built ${chalk.blue("design-tokens")}`, DEFAULT_BUILD_DIR).option("--dry [boolean]", `Dry run for built ${chalk.blue("design-tokens")}`, false).option("-p, --preview", "Generate preview token.ts files", false).option("--verbose", "Enable verbose output", false).action((opts) => {
24
- const { preview, verbose } = opts;
25
- const tokens = typeof opts.tokens === "string" ? opts.tokens : DEFAULT_TOKENS_DIR;
23
+ tokenCmd.command("build").description("Build Designsystemet tokens").option("-t, --tokens <string>", `Path to ${chalk.blue("design-tokens")}`, DEFAULT_TOKENS_CREATE_DIR).option(
24
+ "-o, --out-dir <string>",
25
+ `Output directory for built ${chalk.blue("design-tokens")}`,
26
+ DEFAULT_TOKENS_BUILD_DIR
27
+ ).option(`--${cliOptions.clean} [boolean]`, "Clean output directory before building tokens", parseBoolean, false).option("--dry [boolean]", `Dry run for built ${chalk.blue("design-tokens")}`, parseBoolean, false).option("-p, --preview", "Generate preview token.ts files", false).option("--verbose", "Enable verbose output", false).action((opts) => {
28
+ const { preview, verbose, clean, dry } = opts;
29
+ const tokens = typeof opts.tokens === "string" ? opts.tokens : DEFAULT_TOKENS_CREATE_DIR;
26
30
  const outDir = typeof opts.outDir === "string" ? opts.outDir : "./dist/tokens";
27
- const dry = Boolean(opts.dry);
28
31
  console.log(`Building tokens in ${chalk.green(tokens)}`);
29
32
  if (dry) {
30
33
  console.log(`Performing dry run, no files will be written`);
31
34
  }
32
- return buildTokens({ tokens, outDir, preview, verbose, dry });
35
+ return buildTokens({ tokens, outDir, preview, verbose, dry, clean });
33
36
  });
34
37
  tokenCmd.command("create").description("Create Designsystemet tokens").option(`-m, --${cliOptions.theme.colors.main} <name:hex...>`, `Main colors`, parseColorValues).option(`-s, --${cliOptions.theme.colors.support} <name:hex...>`, `Support colors`, parseColorValues).option(`-n, --${cliOptions.theme.colors.neutral} <hex>`, `Neutral hex color`, convertToHex).option(
35
38
  `-o, --${cliOptions.outDir} <string>`,
36
39
  `Output directory for created ${chalk.blue("design-tokens")}`,
37
- DEFAULT_TOKENS_DIR
38
- ).option("--dry [boolean]", `Dry run for created ${chalk.blue("design-tokens")}`, false).option(`-f, --${cliOptions.theme.typography.fontFamily} <string>`, `Font family`, DEFAULT_FONT).option(
40
+ DEFAULT_TOKENS_CREATE_DIR
41
+ ).option(`--${cliOptions.clean} [boolean]`, "Clean output directory before creating tokens", parseBoolean, false).option("--dry [boolean]", `Dry run for created ${chalk.blue("design-tokens")}`, parseBoolean, false).option(`-f, --${cliOptions.theme.typography.fontFamily} <string>`, `Font family`, DEFAULT_FONT).option(
39
42
  `-b, --${cliOptions.theme.borderRadius} <number>`,
40
43
  `Unitless base border-radius in px`,
41
44
  (radiusAsString) => Number(radiusAsString),
42
45
  4
43
46
  ).option("--theme <string>", "Theme name (ignored when using JSON config file)", DEFAULT_THEME_NAME).option(
44
- "--json <string>",
45
- `Path to JSON config file (default: "${DEFAULT_CONFIG_FILE}")`,
46
- (value) => parseJsonConfig(value, { allowFileNotFound: false })
47
+ "--config <string>",
48
+ `Path to config file (default: "${DEFAULT_CONFIG_FILE}")`,
49
+ (value) => parseConfig(value, { allowFileNotFound: false })
47
50
  ).action(async (opts, cmd) => {
48
- const dry = Boolean(opts.dry);
49
- if (dry) {
51
+ if (opts.dry) {
50
52
  console.log(`Performing dry run, no files will be written`);
51
53
  }
52
- const configFile = await (opts.json ? opts.json : parseJsonConfig(DEFAULT_CONFIG_FILE, { allowFileNotFound: true }));
54
+ const configFile = await (opts.config ? opts.config : parseConfig(DEFAULT_CONFIG_FILE, { allowFileNotFound: true }));
53
55
  const propsFromJson = configFile?.config;
54
56
  if (propsFromJson) {
55
57
  const themeColors = Object.values(propsFromJson?.themes ?? {}).map(
@@ -58,7 +60,7 @@ function makeTokenCommands() {
58
60
  if (!R.all(R.equals(R.__, themeColors[0]), themeColors)) {
59
61
  console.error(
60
62
  chalk.redBright(
61
- `In JSON config ${configFile.path}, all themes must have the same custom color names, but we found:`
63
+ `In config ${configFile.path}, all themes must have the same custom color names, but we found:`
62
64
  )
63
65
  );
64
66
  const themeNames = R.keys(propsFromJson.themes ?? {});
@@ -84,6 +86,7 @@ function makeTokenCommands() {
84
86
  });
85
87
  const unvalidatedConfig = noUndefined({
86
88
  outDir: propsFromJson?.outDir ?? getDefaultOrExplicitOption(cmd, "outDir"),
89
+ clean: propsFromJson?.clean ?? getDefaultOrExplicitOption(cmd, "clean"),
87
90
  themes: propsFromJson?.themes ? (
88
91
  // For each theme specified in the JSON config, we override the config values
89
92
  // with the explicitly set options from the CLI.
@@ -100,7 +103,7 @@ function makeTokenCommands() {
100
103
  try {
101
104
  config = combinedConfigSchema.parse(unvalidatedConfig);
102
105
  } catch (err) {
103
- console.error(chalk.redBright("Invalid config after combining JSON file and CLI options"));
106
+ console.error(chalk.redBright("Invalid config after combining config file and CLI options"));
104
107
  const validationError = makeFriendlyError(err);
105
108
  console.error(validationError.toString());
106
109
  process.exit(1);
@@ -109,7 +112,7 @@ function makeTokenCommands() {
109
112
  for (const [name, themeWithoutName] of Object.entries(config.themes)) {
110
113
  const theme = { name, ...themeWithoutName };
111
114
  const tokens = createTokens(theme);
112
- await writeTokens({ outDir: config.outDir, tokens, theme, dry });
115
+ await writeTokens({ outDir: config.outDir, tokens, theme, dry: opts.dry, clean: config.clean });
113
116
  }
114
117
  });
115
118
  return tokenCmd;
@@ -134,11 +137,12 @@ program.command("migrate").description("run a Designsystemet migration").addArgu
134
137
  }
135
138
  });
136
139
  await program.parseAsync(process.argv);
137
- async function parseJsonConfig(jsonPath, options) {
138
- const resolvedPath = path.resolve(process.cwd(), jsonPath);
139
- let jsonFile;
140
+ async function parseConfig(configPath, options) {
141
+ const resolvedPath = path.resolve(process.cwd(), configPath);
142
+ let configFile;
140
143
  try {
141
- jsonFile = await fs.readFile(resolvedPath, { encoding: "utf-8" });
144
+ configFile = await fs.readFile(resolvedPath, { encoding: "utf-8" });
145
+ console.log(`Found config file: ${chalk.green(resolvedPath)}`);
142
146
  } catch (err) {
143
147
  if (err instanceof Error) {
144
148
  const nodeErr = err;
@@ -150,11 +154,11 @@ async function parseJsonConfig(jsonPath, options) {
150
154
  }
151
155
  try {
152
156
  return {
153
- path: jsonPath,
154
- config: await configFileSchema.parseAsync(JSON.parse(jsonFile))
157
+ path: configPath,
158
+ config: await configFileSchema.parseAsync(JSON.parse(configFile))
155
159
  };
156
160
  } catch (err) {
157
- console.error(chalk.redBright(`Invalid JSON config in ${jsonPath}`));
161
+ console.error(chalk.redBright(`Invalid config in ${configPath}`));
158
162
  const validationError = makeFriendlyError(err);
159
163
  console.error(validationError.toString());
160
164
  process.exit(1);
@@ -177,3 +181,6 @@ function parseColorValues(value, previous = {}) {
177
181
  previous[name] = convertToHex(hex);
178
182
  return previous;
179
183
  }
184
+ function parseBoolean(value, previous) {
185
+ return value === "true" || value === true;
186
+ }
@@ -0,0 +1,12 @@
1
+ const getOptionIfMatchingSource = (...sources) => (command, option) => {
2
+ const source = command.getOptionValueSource(option);
3
+ if (sources.includes(source)) {
4
+ return command.getOptionValue(option);
5
+ }
6
+ };
7
+ const getExplicitOptionOnly = getOptionIfMatchingSource("cli");
8
+ const getDefaultOrExplicitOption = getOptionIfMatchingSource("cli", "default");
9
+ export {
10
+ getDefaultOrExplicitOption,
11
+ getExplicitOptionOnly
12
+ };
@@ -8,6 +8,10 @@
8
8
  "type": "string",
9
9
  "description": "Path to the output directory for the created design tokens"
10
10
  },
11
+ "clean": {
12
+ "type": "boolean",
13
+ "description": "Delete the output directory before building or creating tokens"
14
+ },
11
15
  "themes": {
12
16
  "type": "object",
13
17
  "additionalProperties": {
@@ -26,7 +30,9 @@
26
30
  "description": "One or more color definitions"
27
31
  },
28
32
  "support": {
29
- "$ref": "#/properties/themes/additionalProperties/properties/colors/properties/main"
33
+ "$ref": "#/properties/themes/additionalProperties/properties/colors/properties/main",
34
+ "description": "One or more color definitions",
35
+ "default": {}
30
36
  },
31
37
  "neutral": {
32
38
  "$ref": "#/properties/themes/additionalProperties/properties/colors/properties/main/additionalProperties"
@@ -34,7 +40,6 @@
34
40
  },
35
41
  "required": [
36
42
  "main",
37
- "support",
38
43
  "neutral"
39
44
  ],
40
45
  "additionalProperties": false,
@@ -1 +1 @@
1
- {"version":3,"file":"configs.d.ts","sourceRoot":"","sources":["../../../../src/tokens/build/configs.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,IAAI,qBAAqB,EAAoB,MAAM,wBAAwB,CAAC;AAQhG,OAAO,KAAK,EAEV,kBAAkB,EAClB,2BAA2B,EAC3B,cAAc,EACd,gBAAgB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,oBAAoB,EAA6B,MAAM,sCAAsC,CAAC;AAO5G,eAAO,MAAM,MAAM,OAAO,CAAC;AAC3B,eAAO,MAAM,cAAc,KAAK,CAAC;AA8BjC,MAAM,MAAM,wBAAwB,GAAG,CACrC,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,KACE,qBAAqB,GAAG;IAAE,MAAM,EAAE,qBAAqB,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;CAAE,EAAE,CAAC;AA+PnH,eAAO,MAAM,OAAO;;;;;;;CAOnB,CAAC;AAEF,eAAO,MAAM,4BAA4B,cAC5B,wBAAwB,UAC3B,oBAAoB,EAAE,cAClB,cAAc,EAAE,WACnB,kBAAkB,KAC1B,2BAA2B,EA8B7B,CAAC"}
1
+ {"version":3,"file":"configs.d.ts","sourceRoot":"","sources":["../../../../src/tokens/build/configs.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,IAAI,qBAAqB,EAAoB,MAAM,wBAAwB,CAAC;AAQhG,OAAO,KAAK,EAEV,kBAAkB,EAClB,2BAA2B,EAC3B,cAAc,EACd,gBAAgB,EACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,oBAAoB,EAA6B,MAAM,sCAAsC,CAAC;AAO5G,eAAO,MAAM,MAAM,OAAO,CAAC;AAC3B,eAAO,MAAM,cAAc,KAAK,CAAC;AA8BjC,MAAM,MAAM,wBAAwB,GAAG,CACrC,WAAW,EAAE,gBAAgB,EAC7B,OAAO,EAAE;IACP,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,KACE,qBAAqB,GAAG;IAAE,MAAM,EAAE,qBAAqB,CAAC;IAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;CAAE,EAAE,CAAC;AAwOnH,eAAO,MAAM,OAAO;;;;;;;CAOnB,CAAC;AAEF,eAAO,MAAM,4BAA4B,cAC5B,wBAAwB,UAC3B,oBAAoB,EAAE,cAClB,cAAc,EAAE,WACnB,kBAAkB,KAC1B,2BAA2B,EA8B7B,CAAC"}
@@ -2,7 +2,7 @@ import { expandTypesMap, register } from "@tokens-studio/sd-transforms";
2
2
  import * as R from "ramda";
3
3
  import StyleDictionary from "style-dictionary";
4
4
  import { outputReferencesFilter } from "style-dictionary/utils";
5
- import { DEFAULT_COLOR, buildOptions } from "../build.js";
5
+ import { buildOptions } from "../build.js";
6
6
  import { isColorCategoryToken, isDigit, pathStartsWithOneOf, typeEquals } from "../utils.js";
7
7
  import { formats } from "./formats/css.js";
8
8
  import { jsTokens } from "./formats/js-tokens.js";
@@ -70,8 +70,8 @@ const colorSchemeVariables = ({ "color-scheme": colorScheme = "light", theme },
70
70
  };
71
71
  const colorCategoryVariables = (category) => ({ "color-scheme": colorScheme, theme, [`${category}-color`]: color }, { outPath }) => {
72
72
  const layer = `ds.theme.color`;
73
- const isDefault = color === buildOptions?.accentColor;
74
- const selector = `${isDefault ? ":root, [data-color-scheme], " : ""}[data-color="${color}"]`;
73
+ const isRootColor = color === buildOptions?.rootColor;
74
+ const selector = `${isRootColor ? ":root, [data-color-scheme], " : ""}[data-color="${color}"]`;
75
75
  const config = {
76
76
  usesDtcg,
77
77
  preprocessors: ["tokens-studio"],
@@ -101,29 +101,6 @@ const colorCategoryVariables = (category) => ({ "color-scheme": colorScheme, the
101
101
  }
102
102
  }
103
103
  };
104
- if (isDefault && color !== DEFAULT_COLOR) {
105
- console.log(
106
- `Creating "${DEFAULT_COLOR}" color variables pointing to "${color}", since a color named "${DEFAULT_COLOR}" is not defined`
107
- );
108
- const defaultColorConfig = R.mergeDeepRight(config, {
109
- platforms: {
110
- css: {
111
- selector: ":root",
112
- files: [
113
- {
114
- ...config.platforms?.css?.files?.[0],
115
- destination: `color/${DEFAULT_COLOR}.css`
116
- }
117
- ],
118
- options: { replaceCategoryWith: DEFAULT_COLOR }
119
- }
120
- }
121
- });
122
- return [
123
- { config },
124
- { config: defaultColorConfig, permutationOverrides: { "main-color": `${DEFAULT_COLOR} \u2192 ${color}` } }
125
- ];
126
- }
127
104
  return config;
128
105
  };
129
106
  const semanticVariables = ({ theme }, { outPath }) => {
@@ -11,7 +11,7 @@ export type ColorCategories = keyof typeof colorCategories;
11
11
  export type ThemePermutation = {
12
12
  'color-scheme': string;
13
13
  'main-color': string;
14
- 'support-color': string;
14
+ 'support-color'?: string;
15
15
  semantic: string;
16
16
  size: string;
17
17
  theme: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/tokens/build/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAE7D,eAAO,MAAM,eAAe;;;CAGlB,CAAC;AACX,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,eAAe,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,qBAAqB,KAAK,OAAO,CAAC;AAEtG,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,SAAS,EAAE,wBAAwB,CAAC;IACpC,0FAA0F;IAC1F,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,uGAAuG;IACvG,OAAO,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACtC,mEAAmE;IACnE,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,2BAA2B,EAAE,EAAE,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjG,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IAAE,WAAW,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/tokens/build/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAE7D,eAAO,MAAM,eAAe;;;CAGlB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,eAAe,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,gBAAgB,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,qBAAqB,KAAK,OAAO,CAAC;AAEtG,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,SAAS,EAAE,wBAAwB,CAAC;IACpC,0FAA0F;IAC1F,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,uGAAuG;IACvG,OAAO,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACtC,mEAAmE;IACnE,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,2BAA2B,EAAE,EAAE,OAAO,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjG,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IAAE,WAAW,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,qBAAqB,CAAA;CAAE,CAAC"}
@@ -1,4 +1,3 @@
1
- export declare const DEFAULT_COLOR = "accent";
2
1
  type Options = {
3
2
  /** Design tokens path */
4
3
  tokens: string;
@@ -8,10 +7,12 @@ type Options = {
8
7
  preview: boolean;
9
8
  /** Enable verbose output */
10
9
  verbose: boolean;
11
- /** Set the default "accent" color, if not overridden with data-color */
12
- accentColor?: string;
13
- /** Dry run */
10
+ /** Set the default color for ":root" */
11
+ rootColor?: string;
12
+ /** Dry run, no files will be written */
14
13
  dry?: boolean;
14
+ /** Clean the output path before building tokens */
15
+ clean?: boolean;
15
16
  };
16
17
  export declare let buildOptions: Options | undefined;
17
18
  export declare function buildTokens(options: Options): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/tokens/build.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,aAAa,WAAW,CAAC;AAEtC,KAAK,OAAO,GAAG;IACb,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,4BAA4B;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc;IACd,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,eAAO,IAAI,YAAY,EAAE,OAAO,GAAG,SAAS,CAAC;AAwC7C,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAiFjE"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/tokens/build.ts"],"names":[],"mappings":"AAcA,KAAK,OAAO,GAAG;IACb,yBAAyB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,8BAA8B;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,4BAA4B;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,mDAAmD;IACnD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,eAAO,IAAI,YAAY,EAAE,OAAO,GAAG,SAAS,CAAC;AAwC7C,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA2FjE"}
@@ -7,8 +7,7 @@ import { configs, getConfigsForThemeDimensions } from "./build/configs.js";
7
7
  import { colorCategories } from "./build/types.js";
8
8
  import { makeEntryFile } from "./build/utils/entryfile.js";
9
9
  import { processThemeObject } from "./build/utils/getMultidimensionalThemes.js";
10
- import { copyFile, writeFile } from "./utils.js";
11
- const DEFAULT_COLOR = "accent";
10
+ import { cleanDir, copyFile, writeFile } from "./utils.js";
12
11
  let buildOptions;
13
12
  const sd = new StyleDictionary();
14
13
  const buildConfigs = {
@@ -42,30 +41,39 @@ const buildConfigs = {
42
41
  }
43
42
  };
44
43
  async function buildTokens(options) {
45
- const { dry } = options;
44
+ const { dry, clean } = options;
46
45
  const tokensDir = options.tokens;
47
46
  const targetDir = path.resolve(options.outDir);
48
47
  buildOptions = options;
49
48
  const $themes = JSON.parse(await fs.readFile(path.resolve(`${tokensDir}/$themes.json`), "utf-8")).map(processThemeObject);
50
49
  const relevant$themes = $themes.filter((theme) => R.not(theme.group === "size" && theme.name !== "medium"));
51
- if (!buildOptions.accentColor) {
52
- const accentOrFirstMainColor = relevant$themes.find((theme) => theme.name === DEFAULT_COLOR) || relevant$themes.find((theme) => theme.group === "main-color");
53
- buildOptions.accentColor = accentOrFirstMainColor?.name;
50
+ if (!buildOptions.rootColor) {
51
+ const firstMainColor = relevant$themes.find((theme) => theme.group === "main-color");
52
+ buildOptions.rootColor = firstMainColor?.name;
53
+ console.log(`Using first main color; ${chalk.blue(firstMainColor?.name)}, as ${chalk.green(`":root"`)} color`);
54
54
  }
55
- if (buildOptions.accentColor !== DEFAULT_COLOR) {
56
- console.log("accent color:", buildOptions.accentColor);
55
+ const buildAndSdConfigs = R.map((buildConfig) => {
56
+ const sdConfigs = getConfigsForThemeDimensions(buildConfig.getConfig, relevant$themes, buildConfig.dimensions, {
57
+ outPath: targetDir,
58
+ tokensDir,
59
+ ...buildConfig.options
60
+ });
61
+ const unknownConfigs = buildConfig.dimensions.map(
62
+ (dimension) => sdConfigs.filter((x) => x.permutation[dimension] === "unknown")
63
+ );
64
+ for (const unknowns of unknownConfigs) {
65
+ if (unknowns.length === sdConfigs.length) {
66
+ buildConfig.enabled = () => false;
67
+ }
68
+ }
69
+ return {
70
+ buildConfig,
71
+ sdConfigs
72
+ };
73
+ }, buildConfigs);
74
+ if (clean) {
75
+ await cleanDir(targetDir, dry);
57
76
  }
58
- const buildAndSdConfigs = R.map(
59
- (val) => ({
60
- buildConfig: val,
61
- sdConfigs: getConfigsForThemeDimensions(val.getConfig, relevant$themes, val.dimensions, {
62
- outPath: targetDir,
63
- tokensDir,
64
- ...val.options
65
- })
66
- }),
67
- buildConfigs
68
- );
69
77
  try {
70
78
  for (const [key, { buildConfig, sdConfigs }] of R.toPairs(buildAndSdConfigs)) {
71
79
  if (!(buildConfig.enabled?.() ?? true)) {
@@ -118,7 +126,6 @@ ${mainAndSupportColors.map((color) => ` ${color}: never;`).join("\n")}
118
126
  await writeFile(path.resolve(outPath, colorsFileName), typeDeclaration, dry);
119
127
  }
120
128
  export {
121
- DEFAULT_COLOR,
122
129
  buildOptions,
123
130
  buildTokens
124
131
  };
@@ -1,6 +1,7 @@
1
1
  import type { Theme, Tokens } from './types.js';
2
2
  export declare const cliOptions: {
3
3
  readonly outDir: "out-dir";
4
+ readonly clean: "clean";
4
5
  readonly theme: {
5
6
  readonly colors: {
6
7
  readonly main: "main-colors";
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/tokens/create.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAU,KAAK,EAAE,MAAM,EAAqC,MAAM,YAAY,CAAC;AAE3F,eAAO,MAAM,UAAU;;;;;;;;;;;;;CAab,CAAC;AAgFX,eAAO,MAAM,YAAY,SAAU,KAAK,WAqBvC,CAAC"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../../src/tokens/create.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAU,KAAK,EAAE,MAAM,EAAqC,MAAM,YAAY,CAAC;AAE3F,eAAO,MAAM,UAAU;;;;;;;;;;;;;;CAcb,CAAC;AAgFX,eAAO,MAAM,YAAY,SAAU,KAAK,WAqBvC,CAAC"}
@@ -2,6 +2,7 @@ import * as R from "ramda";
2
2
  import { baseColors, generateColorScale } from "../colors/index.js";
3
3
  const cliOptions = {
4
4
  outDir: "out-dir",
5
+ clean: "clean",
5
6
  theme: {
6
7
  colors: {
7
8
  main: "main-colors",
@@ -20,7 +20,6 @@
20
20
  "semantic/modes/support-color/brand1",
21
21
  "semantic/modes/support-color/brand2",
22
22
  "semantic/modes/support-color/brand3",
23
- "semantic/style",
24
- "Figma/components"
23
+ "semantic/style"
25
24
  ]
26
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../src/tokens/template.ts"],"names":[],"mappings":"AA2BA,eAAO,MAAM,eAAe,qBAyG3B,CAAC"}
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../src/tokens/template.ts"],"names":[],"mappings":"AA2BA,eAAO,MAAM,eAAe,qBAwG3B,CAAC"}
@@ -16,7 +16,6 @@ const argsFromToPaths = (path_) => [
16
16
  const options = { recursive: true };
17
17
  const endsWithOneOf = (suffixes, str) => R.any((suffix) => R.endsWith(suffix, str), suffixes);
18
18
  const updateTemplates = async () => {
19
- await fs.cp(...argsFromToPaths("Figma"), options);
20
19
  await fs.cp(...argsFromToPaths("primitives/globals.json"), options);
21
20
  await fs.cp(...argsFromToPaths("primitives/modes/size"), options);
22
21
  await fs.cp(...argsFromToPaths("primitives/modes/typography/size"), options);
@@ -30,4 +30,5 @@ export declare const writeFile: (path: string, data: string, dry?: boolean) => P
30
30
  export declare const cp: (src: string, dest: string, dry?: boolean) => Promise<void>;
31
31
  export declare const copyFile: (src: string, dest: string, dry?: boolean) => Promise<void>;
32
32
  export declare const isDigit: (s: string) => boolean;
33
+ export declare const cleanDir: (dir: string, dry?: boolean) => Promise<void>;
33
34
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/tokens/utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAM5E;;;;GAIG;AACH,eAAO,MAAM,OAAO,UAAW,gBAAgB,WAAkD,CAAC;AAElG;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,SAAS,gBAAgB,GAAG,WAAW,KAAG,CAAuC,CAAC;AAE5G;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,4DAAmB,MAAM,EAAE,GAAG,MAAM,SAAS,gBAAgB,aAMlF,CAAC;AAEH,eAAO,MAAM,mBAAmB,4DAAmB,MAAM,EAAE,SAAS,gBAAgB,aASlF,CAAC;AAEH,wBAAgB,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAEhE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAEnE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKpG;AAED,eAAO,MAAM,KAAK,QAAe,MAAM,QAAQ,OAAO,2BAOrD,CAAC;AAEF,eAAO,MAAM,SAAS,SAAgB,MAAM,QAAQ,MAAM,QAAQ,OAAO,kBAOxE,CAAC;AAEF,eAAO,MAAM,EAAE,QAAe,MAAM,QAAQ,MAAM,QAAQ,OAAO,kBAOhE,CAAC;AAEF,eAAO,MAAM,QAAQ,QAAe,MAAM,QAAQ,MAAM,QAAQ,OAAO,kBAOtE,CAAC;AAEF,eAAO,MAAM,OAAO,MAAO,MAAM,YAAoB,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/tokens/utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAM5E;;;;GAIG;AACH,eAAO,MAAM,OAAO,UAAW,gBAAgB,WAAkD,CAAC;AAElG;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,GAAI,CAAC,SAAS,gBAAgB,GAAG,WAAW,KAAG,CAAuC,CAAC;AAE5G;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,4DAAmB,MAAM,EAAE,GAAG,MAAM,SAAS,gBAAgB,aAMlF,CAAC;AAEH,eAAO,MAAM,mBAAmB,4DAAmB,MAAM,EAAE,SAAS,gBAAgB,aASlF,CAAC;AAEH,wBAAgB,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAEhE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAEnE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKpG;AAED,eAAO,MAAM,KAAK,QAAe,MAAM,QAAQ,OAAO,2BAOrD,CAAC;AAEF,eAAO,MAAM,SAAS,SAAgB,MAAM,QAAQ,MAAM,QAAQ,OAAO,kBAOxE,CAAC;AAEF,eAAO,MAAM,EAAE,QAAe,MAAM,QAAQ,MAAM,QAAQ,OAAO,kBAOhE,CAAC;AAEF,eAAO,MAAM,QAAQ,QAAe,MAAM,QAAQ,MAAM,QAAQ,OAAO,kBAOtE,CAAC;AAEF,eAAO,MAAM,OAAO,MAAO,MAAM,YAAoB,CAAC;AAEtD,eAAO,MAAM,QAAQ,QAAe,MAAM,QAAQ,OAAO,kBASxD,CAAC"}
@@ -60,7 +60,16 @@ const copyFile = async (src, dest, dry) => {
60
60
  return await fs.copyFile(src, dest);
61
61
  };
62
62
  const isDigit = (s) => /^\d+$/.test(s);
63
+ const cleanDir = async (dir, dry) => {
64
+ if (dry) {
65
+ console.log(`${chalk.blue("cleanDir")} ${dir}`);
66
+ return Promise.resolve();
67
+ }
68
+ console.log(`${chalk.red(`Cleaning outputDir: ${dir.trim()}`)} `);
69
+ return await fs.rm(dir, { recursive: true, force: true });
70
+ };
63
71
  export {
72
+ cleanDir,
64
73
  copyFile,
65
74
  cp,
66
75
  getType,
@@ -1 +1 @@
1
- {"version":3,"file":"generate$metadata.d.ts","sourceRoot":"","sources":["../../../../src/tokens/write/generate$metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,KAAK,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;AAEvC,KAAK,QAAQ,GAAG;IACd,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,CAyBtG"}
1
+ {"version":3,"file":"generate$metadata.d.ts","sourceRoot":"","sources":["../../../../src/tokens/write/generate$metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,KAAK,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;AAEvC,KAAK,QAAQ,GAAG;IACd,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,CAwBtG"}
@@ -19,8 +19,7 @@ function generateMetadataJson(schemes, themes, colors) {
19
19
  "semantic/color",
20
20
  ...Object.entries(colors.main).map(([color]) => `semantic/modes/main-color/${color}`),
21
21
  ...Object.entries(colors.support).map(([color]) => `semantic/modes/support-color/${color}`),
22
- "semantic/style",
23
- "Figma/components"
22
+ "semantic/style"
24
23
  ]
25
24
  };
26
25
  }
@@ -4,7 +4,10 @@ type WriteTokensOptions = {
4
4
  outDir: string;
5
5
  tokens: Tokens;
6
6
  theme: Theme;
7
+ /** Dry run, no files will be written */
7
8
  dry?: boolean;
9
+ /** Clean output directory before writing tokens */
10
+ clean?: boolean;
8
11
  };
9
12
  export declare const writeTokens: (options: WriteTokensOptions) => Promise<void>;
10
13
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/tokens/write.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAoB,KAAK,EAAE,MAAM,EAA8B,MAAM,YAAY,CAAC;AAS9F,eAAO,MAAM,SAAS,SAAU,OAAO,WAAkC,CAAC;AAyB1E,KAAK,kBAAkB,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,WAAW,YAAmB,kBAAkB,kBA4K5D,CAAC"}
1
+ {"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/tokens/write.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAoB,KAAK,EAAE,MAAM,EAA8B,MAAM,YAAY,CAAC;AAS9F,eAAO,MAAM,SAAS,SAAU,OAAO,WAAkC,CAAC;AAyB1E,KAAK,kBAAkB,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC;IACb,wCAAwC;IACxC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,mDAAmD;IACnD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,WAAW,YAAmB,kBAAkB,kBAiL5D,CAAC"}
@@ -7,7 +7,7 @@ import customColorTemplate from "./design-tokens/template/semantic/modes/categor
7
7
  import semanticColorTemplate from "./design-tokens/template/semantic/semantic-color-template.json" with { type: "json" };
8
8
  import themeBaseFile from "./design-tokens/template/themes/theme-base-file.json" with { type: "json" };
9
9
  import themeColorTemplate from "./design-tokens/template/themes/theme-color-template.json" with { type: "json" };
10
- import { cp, mkdir, writeFile } from "./utils.js";
10
+ import { cleanDir, cp, mkdir, writeFile } from "./utils.js";
11
11
  import { generateMetadataJson } from "./write/generate$metadata.js";
12
12
  import { generateThemesJson } from "./write/generate$themes.js";
13
13
  const DIRNAME = import.meta.dirname || __dirname;
@@ -35,12 +35,16 @@ const writeTokens = async (options) => {
35
35
  outDir,
36
36
  tokens,
37
37
  theme: { name: themeName, colors, borderRadius },
38
- dry
38
+ dry,
39
+ clean
39
40
  } = options;
40
41
  const targetDir = path.resolve(process.cwd(), String(outDir));
41
42
  const $themesPath = path.join(targetDir, "$themes.json");
42
43
  const $metadataPath = path.join(targetDir, "$metadata.json");
43
44
  let themes = [themeName];
45
+ if (clean) {
46
+ await cleanDir(targetDir, dry);
47
+ }
44
48
  await mkdir(targetDir, dry);
45
49
  try {
46
50
  const $themes = await fs.readFile($themesPath, "utf-8");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digdir/designsystemet",
3
- "version": "1.0.0-next.46",
3
+ "version": "1.0.0-next.48",
4
4
  "description": "CLI for Designsystemet",
5
5
  "author": "Designsystemet team",
6
6
  "engines": {
@@ -34,62 +34,57 @@
34
34
  },
35
35
  "scripts": {
36
36
  "designsystemet": "tsx ./bin/designsystemet.ts",
37
- "build:tokens": "yarn clean:theme && yarn designsystemet tokens build -p -t ../../design-tokens -o ../../packages/theme/brand",
38
- "build:tokens:debug": "yarn clean:theme && tsx --inspect-brk ./bin/designsystemet.ts tokens build -p -t ../../design-tokens -o ../../packages/theme/brand",
37
+ "build:tokens": "yarn designsystemet tokens build -p -t ../../design-tokens -o ../../packages/theme/brand --clean",
38
+ "build:tokens:debug": "tsx --inspect-brk ./bin/designsystemet.ts tokens build -p -t ../../design-tokens -o ../../packages/theme/brand --clean",
39
39
  "build": "tsup && yarn build:types && yarn build:json-schema",
40
40
  "build:types": "tsc --emitDeclarationOnly --declaration",
41
41
  "build:json-schema": "tsx ./src/build-scripts/createJsonSchema.ts",
42
42
  "types": "tsc --noEmit",
43
- "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",
44
- "test:tokens-create-json": "yarn designsystemet tokens create --json ./test-tokens-create-complex.config.json",
45
- "test:tokens-build": "yarn designsystemet tokens build -t ./test-tokens-create -o ./test-tokens-build",
46
- "test:tokens-create-and-build-options": "yarn clean:test-tokens && yarn test:tokens-create-options && yarn test:tokens-build",
47
- "test:tokens-create-and-build-json": "yarn clean:test-tokens && yarn test:tokens-create-json && yarn test:tokens-build",
48
- "test": "yarn test:tokens-create-and-build-options && yarn test:tokens-create-and-build-json",
49
- "clean": "rimraf dist",
50
- "clean:test-tokens": "rimraf test-tokens-create && rimraf test-tokens-build",
51
- "clean:theme": "yarn workspace @digdir/designsystemet-theme clean",
43
+ "test:tokens-create-options": "yarn designsystemet tokens create -m dominant:#007682 -n #003333 -b 99 -o ./test-tokens-create --theme options-test --clean",
44
+ "test:tokens-create-config": "yarn designsystemet tokens create --config ./test-tokens-create-complex.config.json",
45
+ "test:tokens-build": "yarn designsystemet tokens build -t ./test-tokens-create -o ./test-tokens-build --clean",
46
+ "test:tokens-create-and-build-options": "yarn test:tokens-create-options && yarn test:tokens-build",
47
+ "test:tokens-create-and-build-config": "yarn test:tokens-create-config && yarn test:tokens-build",
48
+ "test": "yarn test:tokens-create-and-build-options && yarn test:tokens-create-and-build-config",
52
49
  "update:template": "tsx ./src/tokens/template.ts",
53
- "internal:tokens-create-digdir": "yarn designsystemet tokens create --theme theme -m accent:#0062BA -n #1E2B3C -s brand1:#F45F63 brand2:#E5AA20 brand3:#1E98F5 -o ./internal/design-tokens",
50
+ "internal:tokens-create-digdir": "yarn designsystemet tokens create --theme theme -m accent:#0062BA -n #1E2B3C -s brand1:#F45F63 brand2:#E5AA20 brand3:#1E98F5 -o ./internal/design-tokens --clean",
54
51
  "internal:tokens-create-altinn": "yarn designsystemet tokens create --theme theme2 -m accent:#0162BA -n #1E2B3C -s brand1:#0162BA brand2:#3F3161 brand3:#E02F4A -o ./internal/design-tokens",
55
52
  "internal:tokens-create-uutilsynet": "yarn designsystemet tokens create --theme theme3 -m accent:#0162BA -n #1E2B3C -s brand1:#5B60D1 brand2:#FEA769 brand3:#5DA290 -o ./internal/design-tokens",
56
53
  "internal:tokens-create-portal": "yarn designsystemet tokens create --theme theme4 -m accent:#4D107D -n #1E2B3C -s brand1:#A259DC brand2:#DF73E4 brand3:#E86ABF -o ./internal/design-tokens",
57
54
  "internal:tokens-create-all": "yarn internal:tokens-create-digdir && yarn internal:tokens-create-altinn && yarn internal:tokens-create-uutilsynet && yarn internal:tokens-create-portal"
58
55
  },
59
56
  "dependencies": {
60
- "@commander-js/extra-typings": "^12.1.0",
61
- "@tokens-studio/sd-transforms": "1.2.2",
57
+ "@commander-js/extra-typings": "^13.0.0",
58
+ "@tokens-studio/sd-transforms": "1.2.9",
62
59
  "apca-w3": "^0.1.9",
63
- "chalk": "^5.3.0",
60
+ "chalk": "^5.4.1",
64
61
  "change-case": "^5.4.4",
65
- "chroma-js": "^2.6.0",
66
- "commander": "^12.1.0",
67
- "fast-glob": "^3.3.2",
62
+ "chroma-js": "^3.1.2",
63
+ "commander": "^13.1.0",
64
+ "fast-glob": "^3.3.3",
68
65
  "hsluv": "^1.0.1",
69
- "jscodeshift": "^0.16.1",
66
+ "jscodeshift": "^17.1.2",
70
67
  "object-hash": "^3.0.0",
71
- "postcss": "^8.4.41",
72
- "prompts": "^2.4.2",
68
+ "postcss": "^8.5.1",
73
69
  "ramda": "^0.30.1",
74
- "rimraf": "^6.0.1",
75
- "style-dictionary": "^4.0.1",
76
- "zod": "^3.23.8",
70
+ "style-dictionary": "^4.3.1",
71
+ "zod": "^3.24.1",
77
72
  "zod-validation-error": "^3.4.0"
78
73
  },
79
74
  "devDependencies": {
80
75
  "@types/apca-w3": "^0.1.3",
76
+ "@types/chroma-js": "^3.1.0",
81
77
  "@types/fs-extra": "^11.0.4",
82
78
  "@types/glob": "^8.1.0",
83
- "@types/jscodeshift": "^0.11.11",
84
- "@types/node": "^22.1.0",
79
+ "@types/jscodeshift": "^0.12.0",
80
+ "@types/node": "^22.10.7",
85
81
  "@types/object-hash": "^3.0.6",
86
- "@types/prompts": "^2.4.9",
87
- "@types/ramda": "^0.30.1",
88
- "fs-extra": "^11.2.0",
89
- "tslib": "^2.6.3",
90
- "tsup": "^8.2.4",
91
- "tsx": "^4.16.5",
92
- "typescript": "^5.5.4",
82
+ "@types/ramda": "^0.30.2",
83
+ "fs-extra": "^11.3.0",
84
+ "tslib": "^2.8.1",
85
+ "tsup": "^8.3.5",
86
+ "tsx": "^4.19.2",
87
+ "typescript": "^5.7.3",
93
88
  "zod-to-json-schema": "^3.24.1"
94
89
  }
95
90
  }
@@ -1,22 +0,0 @@
1
- {
2
- "switch": {
3
- "circle": {
4
- "small": {
5
- "$type": "sizing",
6
- "$value": "{_size.5} - {switch.border}"
7
- },
8
- "medium": {
9
- "$type": "sizing",
10
- "$value": "{_size.6} - {switch.border}"
11
- },
12
- "large": {
13
- "$type": "sizing",
14
- "$value": "{_size.7} - {switch.border}"
15
- }
16
- },
17
- "border": {
18
- "$type": "sizing",
19
- "$value": "4"
20
- }
21
- }
22
- }