@lessonkit/themes 1.0.0 → 1.0.2

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.
package/dist/index.cjs CHANGED
@@ -104,24 +104,46 @@ function validateColorsExtra(value, issues) {
104
104
  }
105
105
  return extra;
106
106
  }
107
+ function rejectUnknownKeys(obj, allowed, path, issues) {
108
+ for (const key of Object.keys(obj)) {
109
+ if (!allowed.includes(key)) {
110
+ issues.push({ path: path ? `${path}.${key}` : key, message: "unknown property" });
111
+ }
112
+ }
113
+ }
107
114
  function validateTheme(input) {
108
115
  const issues = [];
109
116
  if (input === null || typeof input !== "object" || Array.isArray(input)) {
110
117
  return { ok: false, issues: [{ path: "", message: "theme must be an object" }] };
111
118
  }
112
119
  const raw = input;
120
+ rejectUnknownKeys(raw, ["name", "colors", "spacing", "typography", "radius", "shadows"], "", issues);
113
121
  if (!isNonEmptyString(raw.name)) {
114
122
  issues.push({ path: "name", message: "required non-empty string" });
115
123
  }
116
124
  const colorsBase = validateRequiredGroup("colors", raw.colors, COLOR_KEYS, issues);
117
125
  let colorsExtra;
118
126
  if (raw.colors !== null && typeof raw.colors === "object" && !Array.isArray(raw.colors)) {
119
- colorsExtra = validateColorsExtra(raw.colors.extra, issues);
127
+ const colorsObj = raw.colors;
128
+ rejectUnknownKeys(colorsObj, [...COLOR_KEYS, "extra"], "colors", issues);
129
+ colorsExtra = validateColorsExtra(colorsObj.extra, issues);
120
130
  }
121
131
  const spacing = validateRequiredGroup("spacing", raw.spacing, SPACING_KEYS, issues);
132
+ if (raw.spacing !== null && typeof raw.spacing === "object" && !Array.isArray(raw.spacing)) {
133
+ rejectUnknownKeys(raw.spacing, SPACING_KEYS, "spacing", issues);
134
+ }
122
135
  const typography = validateRequiredGroup("typography", raw.typography, TYPOGRAPHY_KEYS, issues);
136
+ if (raw.typography !== null && typeof raw.typography === "object" && !Array.isArray(raw.typography)) {
137
+ rejectUnknownKeys(raw.typography, TYPOGRAPHY_KEYS, "typography", issues);
138
+ }
123
139
  const radius = validateRequiredGroup("radius", raw.radius, RADIUS_KEYS, issues);
140
+ if (raw.radius !== null && typeof raw.radius === "object" && !Array.isArray(raw.radius)) {
141
+ rejectUnknownKeys(raw.radius, RADIUS_KEYS, "radius", issues);
142
+ }
124
143
  const shadows = validateRequiredGroup("shadows", raw.shadows, SHADOW_KEYS, issues);
144
+ if (raw.shadows !== null && typeof raw.shadows === "object" && !Array.isArray(raw.shadows)) {
145
+ rejectUnknownKeys(raw.shadows, SHADOW_KEYS, "shadows", issues);
146
+ }
125
147
  if (issues.length > 0) {
126
148
  return { ok: false, issues };
127
149
  }
package/dist/index.js CHANGED
@@ -56,24 +56,46 @@ function validateColorsExtra(value, issues) {
56
56
  }
57
57
  return extra;
58
58
  }
59
+ function rejectUnknownKeys(obj, allowed, path, issues) {
60
+ for (const key of Object.keys(obj)) {
61
+ if (!allowed.includes(key)) {
62
+ issues.push({ path: path ? `${path}.${key}` : key, message: "unknown property" });
63
+ }
64
+ }
65
+ }
59
66
  function validateTheme(input) {
60
67
  const issues = [];
61
68
  if (input === null || typeof input !== "object" || Array.isArray(input)) {
62
69
  return { ok: false, issues: [{ path: "", message: "theme must be an object" }] };
63
70
  }
64
71
  const raw = input;
72
+ rejectUnknownKeys(raw, ["name", "colors", "spacing", "typography", "radius", "shadows"], "", issues);
65
73
  if (!isNonEmptyString(raw.name)) {
66
74
  issues.push({ path: "name", message: "required non-empty string" });
67
75
  }
68
76
  const colorsBase = validateRequiredGroup("colors", raw.colors, COLOR_KEYS, issues);
69
77
  let colorsExtra;
70
78
  if (raw.colors !== null && typeof raw.colors === "object" && !Array.isArray(raw.colors)) {
71
- colorsExtra = validateColorsExtra(raw.colors.extra, issues);
79
+ const colorsObj = raw.colors;
80
+ rejectUnknownKeys(colorsObj, [...COLOR_KEYS, "extra"], "colors", issues);
81
+ colorsExtra = validateColorsExtra(colorsObj.extra, issues);
72
82
  }
73
83
  const spacing = validateRequiredGroup("spacing", raw.spacing, SPACING_KEYS, issues);
84
+ if (raw.spacing !== null && typeof raw.spacing === "object" && !Array.isArray(raw.spacing)) {
85
+ rejectUnknownKeys(raw.spacing, SPACING_KEYS, "spacing", issues);
86
+ }
74
87
  const typography = validateRequiredGroup("typography", raw.typography, TYPOGRAPHY_KEYS, issues);
88
+ if (raw.typography !== null && typeof raw.typography === "object" && !Array.isArray(raw.typography)) {
89
+ rejectUnknownKeys(raw.typography, TYPOGRAPHY_KEYS, "typography", issues);
90
+ }
75
91
  const radius = validateRequiredGroup("radius", raw.radius, RADIUS_KEYS, issues);
92
+ if (raw.radius !== null && typeof raw.radius === "object" && !Array.isArray(raw.radius)) {
93
+ rejectUnknownKeys(raw.radius, RADIUS_KEYS, "radius", issues);
94
+ }
76
95
  const shadows = validateRequiredGroup("shadows", raw.shadows, SHADOW_KEYS, issues);
96
+ if (raw.shadows !== null && typeof raw.shadows === "object" && !Array.isArray(raw.shadows)) {
97
+ rejectUnknownKeys(raw.shadows, SHADOW_KEYS, "shadows", issues);
98
+ }
77
99
  if (issues.length > 0) {
78
100
  return { ok: false, issues };
79
101
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lessonkit/themes",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "private": false,
5
5
  "description": "Theme primitives and tokens for LessonKit.",
6
6
  "license": "Apache-2.0",
@@ -50,6 +50,6 @@
50
50
  "devDependencies": {
51
51
  "tsup": "^8.5.0",
52
52
  "typescript": "^5.8.3",
53
- "vitest": "^3.2.4"
53
+ "vitest": "^4.1.8"
54
54
  }
55
55
  }