@digdir/designsystemet 1.0.7 → 1.0.8

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.
Files changed (46) hide show
  1. package/dist/bin/config.d.ts +12 -0
  2. package/dist/bin/config.d.ts.map +1 -0
  3. package/dist/bin/config.js +516 -0
  4. package/dist/bin/designsystemet.js +3392 -3327
  5. package/dist/config.schema.json +1 -0
  6. package/dist/src/config.d.ts +25 -14
  7. package/dist/src/config.d.ts.map +1 -1
  8. package/dist/src/config.js +49 -6
  9. package/dist/src/index.js +45 -18
  10. package/dist/src/migrations/beta-to-v1.js +9 -2
  11. package/dist/src/migrations/codemods/css/run.js +9 -2
  12. package/dist/src/migrations/color-rename-next49.js +9 -2
  13. package/dist/src/migrations/index.js +9 -2
  14. package/dist/src/scripts/createJsonSchema.js +10 -5
  15. package/dist/src/scripts/update-template.js +9 -2
  16. package/dist/src/tokens/build.d.ts +1 -1
  17. package/dist/src/tokens/build.d.ts.map +1 -1
  18. package/dist/src/tokens/build.js +54 -32
  19. package/dist/src/tokens/create/generators/$designsystemet.js +3 -3
  20. package/dist/src/tokens/create/write.js +12 -5
  21. package/dist/src/tokens/format.d.ts +1 -1
  22. package/dist/src/tokens/format.d.ts.map +1 -1
  23. package/dist/src/tokens/format.js +45 -18
  24. package/dist/src/tokens/index.js +45 -18
  25. package/dist/src/tokens/process/configs/color.js +12 -10
  26. package/dist/src/tokens/process/configs/semantic.js +11 -9
  27. package/dist/src/tokens/process/configs/storefront.js +11 -1
  28. package/dist/src/tokens/process/configs/typography.js +11 -9
  29. package/dist/src/tokens/process/configs.js +13 -26
  30. package/dist/src/tokens/process/formats/css/color.js +3 -1
  31. package/dist/src/tokens/process/formats/css.js +3 -1
  32. package/dist/src/tokens/process/formats/js-tokens.js +11 -1
  33. package/dist/src/tokens/process/platform.d.ts +3 -5
  34. package/dist/src/tokens/process/platform.d.ts.map +1 -1
  35. package/dist/src/tokens/process/platform.js +41 -14
  36. package/dist/src/tokens/process/theme.js +3 -3
  37. package/dist/src/tokens/process/utils/getMultidimensionalThemes.js +5 -4
  38. package/dist/src/tokens/types.d.ts +2 -2
  39. package/dist/src/tokens/types.d.ts.map +1 -1
  40. package/dist/src/tokens/utils.d.ts +2 -2
  41. package/dist/src/tokens/utils.d.ts.map +1 -1
  42. package/dist/src/tokens/utils.js +11 -1
  43. package/dist/src/utils.d.ts +1 -1
  44. package/dist/src/utils.d.ts.map +1 -1
  45. package/dist/src/utils.js +9 -2
  46. package/package.json +3 -3
@@ -88,6 +88,7 @@
88
88
  }
89
89
  },
90
90
  "required": [
91
+ "outDir",
91
92
  "themes"
92
93
  ],
93
94
  "additionalProperties": false
@@ -1,5 +1,15 @@
1
1
  import { z } from 'zod/v4';
2
- export declare function mapPathToOptionName(path: (string | number)[]): string | undefined;
2
+ /**
3
+ * Validates a configuration object against a provided Zod schema.
4
+ *
5
+ * @template T - The expected type of the validated configuration.
6
+ * @param schema - A Zod schema used to validate the configuration object.
7
+ * @param unvalidatedConfig - The configuration object to validate.
8
+ * @returns The validated configuration object, typed as T.
9
+ * @throws Exits the process with code 1 if validation fails, after logging a friendly error message.
10
+ */
11
+ export declare function validateConfig<T>(schema: z.ZodType<T>, unvalidatedConfig: Record<string, unknown>, configPath: string): T;
12
+ export declare function parseConfig<T>(schema: z.ZodType<T>, configFile: string, configPath: string): T;
3
13
  export declare const colorRegex: RegExp;
4
14
  declare const themeSchema: z.ZodObject<{
5
15
  colors: z.ZodObject<{
@@ -12,13 +22,13 @@ declare const themeSchema: z.ZodObject<{
12
22
  }, z.core.$strip>>;
13
23
  borderRadius: z.ZodOptional<z.ZodNumber>;
14
24
  }, z.core.$strip>;
15
- /**
16
- * This defines the structure of the JSON config file
17
- */
18
- export declare const configFileSchema: z.ZodObject<{
19
- outDir: z.ZodOptional<z.ZodString>;
25
+ export declare const configFileBuildSchema: z.ZodObject<{
20
26
  clean: z.ZodOptional<z.ZodBoolean>;
21
- themes: z.ZodRecord<z.ZodString, z.ZodObject<{
27
+ }, z.core.$strip>;
28
+ export declare const configFileCreateSchema: z.ZodObject<{
29
+ outDir: z.ZodNonOptional<z.ZodString>;
30
+ clean: z.ZodNonOptional<z.ZodOptional<z.ZodBoolean>>;
31
+ themes: z.ZodNonOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
22
32
  colors: z.ZodObject<{
23
33
  main: z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodString, z.ZodTransform<`#${string}`, string>>>;
24
34
  support: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodString, z.ZodTransform<`#${string}`, string>>>>>;
@@ -28,15 +38,13 @@ export declare const configFileSchema: z.ZodObject<{
28
38
  fontFamily: z.ZodString;
29
39
  }, z.core.$strip>>;
30
40
  borderRadius: z.ZodOptional<z.ZodNumber>;
31
- }, z.core.$strip>>;
41
+ }, z.core.$strip>>>;
32
42
  }, z.core.$strip>;
33
43
  /**
34
- * This defines the structure of the final configuration after combining the config file,
35
- * command-line options and default values.
44
+ * This defines the structure of the final configuration file
36
45
  */
37
46
  export declare const combinedConfigSchema: z.ZodObject<{
38
- outDir: z.ZodNonOptional<z.ZodOptional<z.ZodString>>;
39
- clean: z.ZodNonOptional<z.ZodOptional<z.ZodBoolean>>;
47
+ outDir: z.ZodNonOptional<z.ZodString>;
40
48
  themes: z.ZodNonOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
41
49
  colors: z.ZodObject<{
42
50
  main: z.ZodRecord<z.ZodString, z.ZodPipe<z.ZodString, z.ZodTransform<`#${string}`, string>>>;
@@ -48,8 +56,11 @@ export declare const combinedConfigSchema: z.ZodObject<{
48
56
  }, z.core.$strip>>;
49
57
  borderRadius: z.ZodOptional<z.ZodNumber>;
50
58
  }, z.core.$strip>>>;
59
+ clean: z.ZodOptional<z.ZodBoolean>;
51
60
  }, z.core.$strip>;
52
- export type Config = z.infer<typeof combinedConfigSchema>;
53
- export type ThemeConfig = z.infer<typeof themeSchema>;
61
+ export type ConfigSchema = z.infer<typeof combinedConfigSchema>;
62
+ export type ConfigSchemaBuild = z.infer<typeof configFileBuildSchema>;
63
+ export type ConfigSchemaCreate = z.infer<typeof configFileCreateSchema>;
64
+ export type ConfigSchemaTheme = z.infer<typeof themeSchema>;
54
65
  export {};
55
66
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAK3B,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,sBAQ5D;AAWD,eAAO,MAAM,UAAU,QAA2C,CAAC;AAyBnE,QAAA,MAAM,WAAW;;;;;;;;;;iBAiBmG,CAAC;AAErH;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;iBAO3B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;iBAA8B,CAAC;AAChE,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAC1D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAgC3B;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EACpB,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1C,UAAU,EAAE,MAAM,GACjB,CAAC,CASH;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,CAAC,CAc9F;AAWD,eAAO,MAAM,UAAU,QAA2C,CAAC;AAyBnE,QAAA,MAAM,WAAW;;;;;;;;;;iBAiBmG,CAAC;AAErH,eAAO,MAAM,qBAAqB;;iBAEhC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;iBAYtB,CAAC;AAEd;;GAEG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;iBAA6D,CAAC;AAC/F,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAChE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC"}
@@ -1,5 +1,7 @@
1
1
  // src/config.ts
2
+ import chalk from "chalk";
2
3
  import * as R7 from "ramda";
4
+ import { fromError } from "zod-validation-error";
3
5
  import { z } from "zod/v4";
4
6
 
5
7
  // src/colors/utils.ts
@@ -318,6 +320,42 @@ function mapPathToOptionName(path2) {
318
320
  }
319
321
  return option;
320
322
  }
323
+ function makeFriendlyError(err) {
324
+ return fromError(err, {
325
+ messageBuilder: (issues) => issues.map((issue) => {
326
+ const issuePath = issue.path.join(".");
327
+ const optionName = mapPathToOptionName(issue.path);
328
+ const errorCode = `(error code: ${issue.code})`;
329
+ const optionMessage = optionName ? ` or CLI option --${optionName}` : "";
330
+ return ` - Error in JSON value ${chalk.red(issuePath)}${optionMessage}:
331
+ ${issue.message} ${chalk.dim(errorCode)}`;
332
+ }).join("\n")
333
+ });
334
+ }
335
+ function validateConfig(schema, unvalidatedConfig, configPath) {
336
+ try {
337
+ return schema.parse(unvalidatedConfig);
338
+ } catch (err) {
339
+ console.error(chalk.redBright(`Invalid config file at ${chalk.red(configPath)}`));
340
+ const validationError = makeFriendlyError(err);
341
+ console.error(validationError.toString());
342
+ process.exit(1);
343
+ }
344
+ }
345
+ function parseConfig(schema, configFile, configPath) {
346
+ if (!configFile) {
347
+ return {};
348
+ }
349
+ try {
350
+ const parsedConfig = JSON.parse(configFile);
351
+ return schema.parse(parsedConfig);
352
+ } catch (err) {
353
+ console.error(chalk.redBright(`Failed parsing config file at ${chalk.red(configPath)}`));
354
+ const validationError = makeFriendlyError(err);
355
+ console.error(validationError.toString());
356
+ process.exit(1);
357
+ }
358
+ }
321
359
  var hexPatterns = [
322
360
  // Hex colors: #000, #0000, #000000, #00000000
323
361
  `#[0-9a-fA-F]{3}`,
@@ -352,17 +390,22 @@ var themeSchema = z.object({
352
390
  }).describe("Defines the typography for a given theme").optional(),
353
391
  borderRadius: z.number().meta({ description: "Defines the border-radius for this theme" }).optional()
354
392
  }).meta({ description: "An object defining a theme. The property name holding the object becomes the theme name." });
355
- var configFileSchema = z.object({
356
- outDir: z.string().meta({ description: "Path to the output directory for the created design tokens" }).optional(),
393
+ var configFileBuildSchema = z.object({
394
+ clean: z.boolean().meta({ description: "Delete the output directory before building or creating tokens" }).optional()
395
+ });
396
+ var configFileCreateSchema = z.object({
397
+ outDir: z.string().meta({ description: "Path to the output directory for the created design tokens" }),
357
398
  clean: z.boolean().meta({ description: "Delete the output directory before building or creating tokens" }).optional(),
358
399
  themes: z.record(z.string(), themeSchema).meta({
359
400
  description: "An object with one or more themes. Each property defines a theme, and the property name is used as the theme name."
360
401
  })
361
- });
362
- var combinedConfigSchema = configFileSchema.required();
402
+ }).required();
403
+ var combinedConfigSchema = configFileCreateSchema.extend(configFileBuildSchema.shape);
363
404
  export {
364
405
  colorRegex,
365
406
  combinedConfigSchema,
366
- configFileSchema,
367
- mapPathToOptionName
407
+ configFileBuildSchema,
408
+ configFileCreateSchema,
409
+ parseConfig,
410
+ validateConfig
368
411
  };
package/dist/src/index.js CHANGED
@@ -2615,7 +2615,9 @@ function isGlobalColorToken(token) {
2615
2615
  }
2616
2616
  function isColorCategoryToken(token, category) {
2617
2617
  if (!category) {
2618
- return ["main", "support"].some((c) => isColorCategoryToken(token, c));
2618
+ return Object.keys(colorCategories).some(
2619
+ (colorCategory2) => isColorCategoryToken(token, colorCategory2)
2620
+ );
2619
2621
  }
2620
2622
  return R7.startsWith(["color", category], token.path);
2621
2623
  }
@@ -2952,7 +2954,7 @@ var colorCategoryVariables = (opts) => ({ "color-scheme": colorScheme2, theme, .
2952
2954
  );
2953
2955
  }
2954
2956
  const layer = `ds.theme.color`;
2955
- const isRootColor = color === buildOptions?.rootColor;
2957
+ const isRootColor = color === buildOptions?.defaultColor;
2956
2958
  const selector = isRootColor ? `:root, [data-color-scheme], [data-color="${color}"]` : `[data-color="${color}"], [data-color-scheme][data-color="${color}"]`;
2957
2959
  const config = {
2958
2960
  preprocessors: ["tokens-studio"],
@@ -3196,8 +3198,7 @@ function processThemeObject(theme) {
3196
3198
  }
3197
3199
  function groupThemes(themes) {
3198
3200
  const groups = {};
3199
- for (const rawTheme of themes) {
3200
- const theme = processThemeObject(rawTheme);
3201
+ for (const theme of themes) {
3201
3202
  if (theme.group) {
3202
3203
  const groupKey = theme.group;
3203
3204
  groups[groupKey] = [...groups[groupKey] ?? [], theme];
@@ -3348,9 +3349,12 @@ var initResult = {
3348
3349
  };
3349
3350
  var buildOptions;
3350
3351
  var sd = new StyleDictionary2();
3351
- var getCustomColors = (processed$themes) => processed$themes.filter(
3352
- (x) => x.group && [colorCategories.main, colorCategories.support].map((c) => `${c}-color`).includes(x.group)
3353
- ).map((x) => x.name);
3352
+ var getCustomColors = (processed$themes, colorGroups) => processed$themes.filter((x) => {
3353
+ if (!x.group) {
3354
+ return false;
3355
+ }
3356
+ return colorGroups.includes(x.group);
3357
+ }).map((x) => x.name);
3354
3358
  var buildConfigs = {
3355
3359
  typography: { getConfig: configs.typographyVariables, dimensions: ["typography"] },
3356
3360
  "color-scheme": { getConfig: configs.colorSchemeVariables, dimensions: ["color-scheme"] },
@@ -3391,17 +3395,40 @@ var buildConfigs = {
3391
3395
  // },
3392
3396
  };
3393
3397
  async function processPlatform(options) {
3394
- const { process, $themes } = options;
3398
+ const { type, $themes } = options;
3395
3399
  const platform = "css";
3396
- const tokenSets = process === "format" ? options.tokenSets : void 0;
3397
- const tokensDir = process === "build" ? options.tokensDir : void 0;
3400
+ const tokenSets = type === "format" ? options.tokenSets : void 0;
3401
+ const tokensDir = type === "build" ? options.tokensDir : void 0;
3402
+ const UNSAFE_DEFAULT_COLOR = process.env.UNSAFE_DEFAULT_COLOR ?? "";
3403
+ if (UNSAFE_DEFAULT_COLOR) {
3404
+ console.warn(
3405
+ chalk2.yellow(
3406
+ `
3407
+ \u26A0\uFE0F UNSAFE_DEFAULT_COLOR is set to ${chalk2.blue(UNSAFE_DEFAULT_COLOR)}. This will override the default color.`
3408
+ )
3409
+ );
3410
+ }
3411
+ const UNSAFE_COLOR_GROUPS = Array.from(process.env.UNSAFE_COLOR_GROUPS?.split(",") ?? []);
3412
+ if (UNSAFE_COLOR_GROUPS.length > 0) {
3413
+ console.warn(
3414
+ chalk2.yellow(
3415
+ `
3416
+ \u26A0\uFE0F UNSAFE_COLOR_GROUPS is set to ${chalk2.blue(`[${UNSAFE_COLOR_GROUPS.join(", ")}]`)}. This will override the default color groups.`
3417
+ )
3418
+ );
3419
+ }
3420
+ const colorGroups = UNSAFE_COLOR_GROUPS.length > 0 ? UNSAFE_COLOR_GROUPS : [colorCategories.main, colorCategories.support].map((c) => `${c}-color`);
3398
3421
  buildOptions = options;
3422
+ buildOptions.defaultColor = UNSAFE_DEFAULT_COLOR;
3399
3423
  const processed$themes = $themes.map(processThemeObject).filter((theme) => R18.not(theme.group === "size" && theme.name !== "medium"));
3400
- const customColors = getCustomColors(processed$themes);
3401
- if (!buildOptions.rootColor) {
3424
+ const customColors = getCustomColors(processed$themes, colorGroups);
3425
+ if (!buildOptions.defaultColor) {
3402
3426
  const firstMainColor = R18.head(customColors);
3403
- buildOptions.rootColor = firstMainColor;
3404
- console.log(`Using first main color; ${chalk2.blue(firstMainColor)}, as ${chalk2.green(`":root"`)} color`);
3427
+ buildOptions.defaultColor = firstMainColor;
3428
+ }
3429
+ if (buildOptions.defaultColor) {
3430
+ console.log(`
3431
+ \u{1F3A8} Using ${chalk2.blue(buildOptions.defaultColor)} as default color`);
3405
3432
  }
3406
3433
  const buildAndSdConfigs = R18.map((buildConfig) => {
3407
3434
  const sdConfigs = getConfigsForThemeDimensions(buildConfig.getConfig, processed$themes, buildConfig.dimensions, {
@@ -3499,7 +3526,7 @@ import chalk3 from "chalk";
3499
3526
  // package.json
3500
3527
  var package_default = {
3501
3528
  name: "@digdir/designsystemet",
3502
- version: "1.0.7",
3529
+ version: "1.0.8",
3503
3530
  description: "CLI for Designsystemet",
3504
3531
  author: "Designsystemet team",
3505
3532
  engines: {
@@ -3549,8 +3576,8 @@ var package_default = {
3549
3576
  test: "pnpm test:tokens-create-and-build-options && pnpm test:tokens-create-and-build-config",
3550
3577
  "digdir:tokens-create": "pnpm run designsystemet tokens create --config ./configs/digdir.config.json",
3551
3578
  "update:template": "tsx ./src/scripts/update-template.ts",
3552
- "update:design-tokens": "pnpm digdir:tokens-create && tsx ./src/scripts/update-design-tokens.ts",
3553
- verify: "pnpm test && pnpm update:template && pnpm update:design-tokens"
3579
+ "update:theme-digdir": "pnpm digdir:tokens-create && tsx ./src/scripts/update-design-tokens.ts",
3580
+ verify: "pnpm test && pnpm update:template && pnpm update:theme-digdir && pnpm build:tokens"
3554
3581
  },
3555
3582
  dependencies: {
3556
3583
  "@commander-js/extra-typings": "^13.1.0",
@@ -3663,7 +3690,7 @@ ${fileHeader2}
3663
3690
  // src/tokens/format.ts
3664
3691
  var formatTokens = async (options) => {
3665
3692
  const processedBuilds = await processPlatform({
3666
- process: "format",
3693
+ type: "format",
3667
3694
  ...options
3668
3695
  });
3669
3696
  return processedBuilds;
@@ -49,12 +49,19 @@ import postcss from "postcss";
49
49
  // src/utils.ts
50
50
  import fs from "fs/promises";
51
51
  import chalk2 from "chalk";
52
- var readFile = async (path, dry) => {
52
+ var readFile = async (path, dry, allowFileNotFound) => {
53
53
  if (dry) {
54
54
  console.log(`${chalk2.blue("readFile")} ${path}`);
55
55
  return Promise.resolve("");
56
56
  }
57
- return fs.readFile(path, "utf-8");
57
+ try {
58
+ return await fs.readFile(path, "utf-8");
59
+ } catch (error) {
60
+ if (allowFileNotFound && error.code === "ENOENT") {
61
+ return "";
62
+ }
63
+ throw error;
64
+ }
58
65
  };
59
66
 
60
67
  // src/migrations/codemods/css/run.ts
@@ -6,12 +6,19 @@ import postcss from "postcss";
6
6
  // src/utils.ts
7
7
  import fs from "fs/promises";
8
8
  import chalk from "chalk";
9
- var readFile = async (path, dry) => {
9
+ var readFile = async (path, dry, allowFileNotFound) => {
10
10
  if (dry) {
11
11
  console.log(`${chalk.blue("readFile")} ${path}`);
12
12
  return Promise.resolve("");
13
13
  }
14
- return fs.readFile(path, "utf-8");
14
+ try {
15
+ return await fs.readFile(path, "utf-8");
16
+ } catch (error) {
17
+ if (allowFileNotFound && error.code === "ENOENT") {
18
+ return "";
19
+ }
20
+ throw error;
21
+ }
15
22
  };
16
23
 
17
24
  // src/migrations/codemods/css/run.ts
@@ -40,12 +40,19 @@ import postcss from "postcss";
40
40
  // src/utils.ts
41
41
  import fs from "fs/promises";
42
42
  import chalk2 from "chalk";
43
- var readFile = async (path, dry) => {
43
+ var readFile = async (path, dry, allowFileNotFound) => {
44
44
  if (dry) {
45
45
  console.log(`${chalk2.blue("readFile")} ${path}`);
46
46
  return Promise.resolve("");
47
47
  }
48
- return fs.readFile(path, "utf-8");
48
+ try {
49
+ return await fs.readFile(path, "utf-8");
50
+ } catch (error) {
51
+ if (allowFileNotFound && error.code === "ENOENT") {
52
+ return "";
53
+ }
54
+ throw error;
55
+ }
49
56
  };
50
57
 
51
58
  // src/migrations/codemods/css/run.ts
@@ -49,12 +49,19 @@ import postcss from "postcss";
49
49
  // src/utils.ts
50
50
  import fs from "fs/promises";
51
51
  import chalk2 from "chalk";
52
- var readFile = async (path, dry) => {
52
+ var readFile = async (path, dry, allowFileNotFound) => {
53
53
  if (dry) {
54
54
  console.log(`${chalk2.blue("readFile")} ${path}`);
55
55
  return Promise.resolve("");
56
56
  }
57
- return fs.readFile(path, "utf-8");
57
+ try {
58
+ return await fs.readFile(path, "utf-8");
59
+ } catch (error) {
60
+ if (allowFileNotFound && error.code === "ENOENT") {
61
+ return "";
62
+ }
63
+ throw error;
64
+ }
58
65
  };
59
66
 
60
67
  // src/migrations/codemods/css/run.ts
@@ -4,7 +4,9 @@ import { resolve } from "path";
4
4
  import { z as z2 } from "zod/v4";
5
5
 
6
6
  // src/config.ts
7
+ import chalk from "chalk";
7
8
  import * as R7 from "ramda";
9
+ import { fromError } from "zod-validation-error";
8
10
  import { z } from "zod/v4";
9
11
 
10
12
  // src/colors/utils.ts
@@ -332,19 +334,22 @@ var themeSchema = z.object({
332
334
  }).describe("Defines the typography for a given theme").optional(),
333
335
  borderRadius: z.number().meta({ description: "Defines the border-radius for this theme" }).optional()
334
336
  }).meta({ description: "An object defining a theme. The property name holding the object becomes the theme name." });
335
- var configFileSchema = z.object({
336
- outDir: z.string().meta({ description: "Path to the output directory for the created design tokens" }).optional(),
337
+ var configFileBuildSchema = z.object({
338
+ clean: z.boolean().meta({ description: "Delete the output directory before building or creating tokens" }).optional()
339
+ });
340
+ var configFileCreateSchema = z.object({
341
+ outDir: z.string().meta({ description: "Path to the output directory for the created design tokens" }),
337
342
  clean: z.boolean().meta({ description: "Delete the output directory before building or creating tokens" }).optional(),
338
343
  themes: z.record(z.string(), themeSchema).meta({
339
344
  description: "An object with one or more themes. Each property defines a theme, and the property name is used as the theme name."
340
345
  })
341
- });
342
- var combinedConfigSchema = configFileSchema.required();
346
+ }).required();
347
+ var combinedConfigSchema = configFileCreateSchema.extend(configFileBuildSchema.shape);
343
348
 
344
349
  // src/scripts/createJsonSchema.ts
345
350
  var schema = z2.object({
346
351
  $schema: z2.string().optional()
347
- }).extend(configFileSchema.shape);
352
+ }).extend(combinedConfigSchema.shape);
348
353
  writeFile(
349
354
  resolve(import.meta.dirname, "../../dist/config.schema.json"),
350
355
  JSON.stringify(
@@ -1122,12 +1122,19 @@ var cleanDir = async (dir, dry) => {
1122
1122
  \u{1F525} Cleaning dir ${chalk.red(`${dir.trim()}`)} `);
1123
1123
  return fs.rm(dir, { recursive: true, force: true });
1124
1124
  };
1125
- var readFile = async (path2, dry) => {
1125
+ var readFile = async (path2, dry, allowFileNotFound) => {
1126
1126
  if (dry) {
1127
1127
  console.log(`${chalk.blue("readFile")} ${path2}`);
1128
1128
  return Promise.resolve("");
1129
1129
  }
1130
- return fs.readFile(path2, "utf-8");
1130
+ try {
1131
+ return await fs.readFile(path2, "utf-8");
1132
+ } catch (error) {
1133
+ if (allowFileNotFound && error.code === "ENOENT") {
1134
+ return "";
1135
+ }
1136
+ throw error;
1137
+ }
1131
1138
  };
1132
1139
 
1133
1140
  // src/scripts/update-template.ts
@@ -1,3 +1,3 @@
1
1
  import { type BuildOptions } from './process/platform.js';
2
- export declare const buildTokens: (options: Omit<BuildOptions, "process" | "$themes">) => Promise<import("./process/platform.js").ProcessReturn>;
2
+ export declare const buildTokens: (options: Omit<BuildOptions, "type" | "$themes">) => Promise<import("./process/platform.js").ProcessReturn>;
3
3
  //# sourceMappingURL=build.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/tokens/build.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,YAAY,EAAmB,MAAM,uBAAuB,CAAC;AAiB3E,eAAO,MAAM,WAAW,GAAU,SAAS,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,SAAS,CAAC,2DAiDnF,CAAC"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/tokens/build.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,YAAY,EAAmB,MAAM,uBAAuB,CAAC;AAiB3E,eAAO,MAAM,WAAW,GAAU,SAAS,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC,2DA6ChF,CAAC"}
@@ -28,21 +28,19 @@ var writeFile = async (path2, data, dry) => {
28
28
  throw error;
29
29
  });
30
30
  };
31
- var cleanDir = async (dir, dry) => {
32
- if (dry) {
33
- console.log(`${chalk.blue("cleanDir")} ${dir}`);
34
- return Promise.resolve();
35
- }
36
- console.log(`
37
- \u{1F525} Cleaning dir ${chalk.red(`${dir.trim()}`)} `);
38
- return fs.rm(dir, { recursive: true, force: true });
39
- };
40
- var readFile = async (path2, dry) => {
31
+ var readFile = async (path2, dry, allowFileNotFound) => {
41
32
  if (dry) {
42
33
  console.log(`${chalk.blue("readFile")} ${path2}`);
43
34
  return Promise.resolve("");
44
35
  }
45
- return fs.readFile(path2, "utf-8");
36
+ try {
37
+ return await fs.readFile(path2, "utf-8");
38
+ } catch (error) {
39
+ if (allowFileNotFound && error.code === "ENOENT") {
40
+ return "";
41
+ }
42
+ throw error;
43
+ }
46
44
  };
47
45
 
48
46
  // src/tokens/process/theme.ts
@@ -52,7 +50,7 @@ import chalk2 from "chalk";
52
50
  // package.json
53
51
  var package_default = {
54
52
  name: "@digdir/designsystemet",
55
- version: "1.0.7",
53
+ version: "1.0.8",
56
54
  description: "CLI for Designsystemet",
57
55
  author: "Designsystemet team",
58
56
  engines: {
@@ -102,8 +100,8 @@ var package_default = {
102
100
  test: "pnpm test:tokens-create-and-build-options && pnpm test:tokens-create-and-build-config",
103
101
  "digdir:tokens-create": "pnpm run designsystemet tokens create --config ./configs/digdir.config.json",
104
102
  "update:template": "tsx ./src/scripts/update-template.ts",
105
- "update:design-tokens": "pnpm digdir:tokens-create && tsx ./src/scripts/update-design-tokens.ts",
106
- verify: "pnpm test && pnpm update:template && pnpm update:design-tokens"
103
+ "update:theme-digdir": "pnpm digdir:tokens-create && tsx ./src/scripts/update-design-tokens.ts",
104
+ verify: "pnpm test && pnpm update:template && pnpm update:theme-digdir && pnpm build:tokens"
107
105
  },
108
106
  dependencies: {
109
107
  "@commander-js/extra-typings": "^13.1.0",
@@ -264,7 +262,9 @@ function isGlobalColorToken(token) {
264
262
  }
265
263
  function isColorCategoryToken(token, category) {
266
264
  if (!category) {
267
- return ["main", "support"].some((c) => isColorCategoryToken(token, c));
265
+ return Object.keys(colorCategories).some(
266
+ (colorCategory2) => isColorCategoryToken(token, colorCategory2)
267
+ );
268
268
  }
269
269
  return R2.startsWith(["color", category], token.path);
270
270
  }
@@ -601,7 +601,7 @@ var colorCategoryVariables = (opts) => ({ "color-scheme": colorScheme2, theme, .
601
601
  );
602
602
  }
603
603
  const layer = `ds.theme.color`;
604
- const isRootColor = color === buildOptions?.rootColor;
604
+ const isRootColor = color === buildOptions?.defaultColor;
605
605
  const selector = isRootColor ? `:root, [data-color-scheme], [data-color="${color}"]` : `[data-color="${color}"], [data-color-scheme][data-color="${color}"]`;
606
606
  const config = {
607
607
  preprocessors: ["tokens-studio"],
@@ -1008,8 +1008,7 @@ function processThemeObject(theme) {
1008
1008
  }
1009
1009
  function groupThemes(themes) {
1010
1010
  const groups = {};
1011
- for (const rawTheme of themes) {
1012
- const theme = processThemeObject(rawTheme);
1011
+ for (const theme of themes) {
1013
1012
  if (theme.group) {
1014
1013
  const groupKey = theme.group;
1015
1014
  groups[groupKey] = [...groups[groupKey] ?? [], theme];
@@ -1160,9 +1159,12 @@ var initResult = {
1160
1159
  };
1161
1160
  var buildOptions;
1162
1161
  var sd = new StyleDictionary2();
1163
- var getCustomColors = (processed$themes) => processed$themes.filter(
1164
- (x) => x.group && [colorCategories.main, colorCategories.support].map((c) => `${c}-color`).includes(x.group)
1165
- ).map((x) => x.name);
1162
+ var getCustomColors = (processed$themes, colorGroups) => processed$themes.filter((x) => {
1163
+ if (!x.group) {
1164
+ return false;
1165
+ }
1166
+ return colorGroups.includes(x.group);
1167
+ }).map((x) => x.name);
1166
1168
  var buildConfigs = {
1167
1169
  typography: { getConfig: configs.typographyVariables, dimensions: ["typography"] },
1168
1170
  "color-scheme": { getConfig: configs.colorSchemeVariables, dimensions: ["color-scheme"] },
@@ -1203,17 +1205,40 @@ var buildConfigs = {
1203
1205
  // },
1204
1206
  };
1205
1207
  async function processPlatform(options) {
1206
- const { process, $themes } = options;
1208
+ const { type, $themes } = options;
1207
1209
  const platform = "css";
1208
- const tokenSets = process === "format" ? options.tokenSets : void 0;
1209
- const tokensDir = process === "build" ? options.tokensDir : void 0;
1210
+ const tokenSets = type === "format" ? options.tokenSets : void 0;
1211
+ const tokensDir = type === "build" ? options.tokensDir : void 0;
1212
+ const UNSAFE_DEFAULT_COLOR = process.env.UNSAFE_DEFAULT_COLOR ?? "";
1213
+ if (UNSAFE_DEFAULT_COLOR) {
1214
+ console.warn(
1215
+ chalk4.yellow(
1216
+ `
1217
+ \u26A0\uFE0F UNSAFE_DEFAULT_COLOR is set to ${chalk4.blue(UNSAFE_DEFAULT_COLOR)}. This will override the default color.`
1218
+ )
1219
+ );
1220
+ }
1221
+ const UNSAFE_COLOR_GROUPS = Array.from(process.env.UNSAFE_COLOR_GROUPS?.split(",") ?? []);
1222
+ if (UNSAFE_COLOR_GROUPS.length > 0) {
1223
+ console.warn(
1224
+ chalk4.yellow(
1225
+ `
1226
+ \u26A0\uFE0F UNSAFE_COLOR_GROUPS is set to ${chalk4.blue(`[${UNSAFE_COLOR_GROUPS.join(", ")}]`)}. This will override the default color groups.`
1227
+ )
1228
+ );
1229
+ }
1230
+ const colorGroups = UNSAFE_COLOR_GROUPS.length > 0 ? UNSAFE_COLOR_GROUPS : [colorCategories.main, colorCategories.support].map((c) => `${c}-color`);
1210
1231
  buildOptions = options;
1232
+ buildOptions.defaultColor = UNSAFE_DEFAULT_COLOR;
1211
1233
  const processed$themes = $themes.map(processThemeObject).filter((theme) => R13.not(theme.group === "size" && theme.name !== "medium"));
1212
- const customColors = getCustomColors(processed$themes);
1213
- if (!buildOptions.rootColor) {
1234
+ const customColors = getCustomColors(processed$themes, colorGroups);
1235
+ if (!buildOptions.defaultColor) {
1214
1236
  const firstMainColor = R13.head(customColors);
1215
- buildOptions.rootColor = firstMainColor;
1216
- console.log(`Using first main color; ${chalk4.blue(firstMainColor)}, as ${chalk4.green(`":root"`)} color`);
1237
+ buildOptions.defaultColor = firstMainColor;
1238
+ }
1239
+ if (buildOptions.defaultColor) {
1240
+ console.log(`
1241
+ \u{1F3A8} Using ${chalk4.blue(buildOptions.defaultColor)} as default color`);
1217
1242
  }
1218
1243
  const buildAndSdConfigs = R13.map((buildConfig) => {
1219
1244
  const sdConfigs = getConfigsForThemeDimensions(buildConfig.getConfig, processed$themes, buildConfig.dimensions, {
@@ -1332,12 +1357,9 @@ var buildTokens = async (options) => {
1332
1357
  ...options,
1333
1358
  outDir,
1334
1359
  tokensDir,
1335
- process: "build",
1360
+ type: "build",
1336
1361
  $themes
1337
1362
  });
1338
- if (options.clean) {
1339
- await cleanDir(outDir, options.dry);
1340
- }
1341
1363
  console.log(`
1342
1364
  \u{1F4BE} Writing build to ${chalk5.green(outDir)}`);
1343
1365
  for (const { formatted } of processedBuilds.types) {
@@ -1,7 +1,7 @@
1
1
  // package.json
2
2
  var package_default = {
3
3
  name: "@digdir/designsystemet",
4
- version: "1.0.7",
4
+ version: "1.0.8",
5
5
  description: "CLI for Designsystemet",
6
6
  author: "Designsystemet team",
7
7
  engines: {
@@ -51,8 +51,8 @@ var package_default = {
51
51
  test: "pnpm test:tokens-create-and-build-options && pnpm test:tokens-create-and-build-config",
52
52
  "digdir:tokens-create": "pnpm run designsystemet tokens create --config ./configs/digdir.config.json",
53
53
  "update:template": "tsx ./src/scripts/update-template.ts",
54
- "update:design-tokens": "pnpm digdir:tokens-create && tsx ./src/scripts/update-design-tokens.ts",
55
- verify: "pnpm test && pnpm update:template && pnpm update:design-tokens"
54
+ "update:theme-digdir": "pnpm digdir:tokens-create && tsx ./src/scripts/update-design-tokens.ts",
55
+ verify: "pnpm test && pnpm update:template && pnpm update:theme-digdir && pnpm build:tokens"
56
56
  },
57
57
  dependencies: {
58
58
  "@commander-js/extra-typings": "^13.1.0",