@asagiri-design/labels-config 0.2.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.js ADDED
@@ -0,0 +1,306 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
+
22
+ // src/index.ts
23
+ var index_exports = {};
24
+ __export(index_exports, {
25
+ LabelManager: () => LabelManager,
26
+ checkDuplicateColors: () => checkDuplicateColors,
27
+ checkDuplicateNames: () => checkDuplicateNames,
28
+ default: () => index_default,
29
+ flattenLabels: () => flattenLabels,
30
+ isCategorized: () => isCategorized,
31
+ labelCategorySchema: () => labelCategorySchema,
32
+ labelConfigSchema: () => labelConfigSchema,
33
+ labelRegistrySchema: () => labelRegistrySchema,
34
+ validateLabel: () => validateLabel,
35
+ validateLabels: () => validateLabels,
36
+ validateRegistry: () => validateRegistry,
37
+ validateWithDetails: () => validateWithDetails,
38
+ version: () => version
39
+ });
40
+ module.exports = __toCommonJS(index_exports);
41
+
42
+ // src/types.ts
43
+ function isCategorized(labels) {
44
+ return Array.isArray(labels) && labels.length > 0 && "category" in labels[0] && "labels" in labels[0];
45
+ }
46
+ function flattenLabels(labels) {
47
+ if (isCategorized(labels)) {
48
+ return labels.flatMap((cat) => cat.labels);
49
+ }
50
+ return labels;
51
+ }
52
+
53
+ // src/validation.ts
54
+ var import_zod = require("zod");
55
+
56
+ // src/utils/color.ts
57
+ function normalizeHexColor(input) {
58
+ const color = input.toLowerCase();
59
+ if (color.length === 3) {
60
+ return color.split("").map((c) => c + c).join("");
61
+ }
62
+ return color;
63
+ }
64
+
65
+ // src/validation.ts
66
+ var hexColorSchema = import_zod.z.string().regex(/^[0-9a-fA-F]{6}$|^[0-9a-fA-F]{3}$/, "Invalid hex color format").transform((color) => normalizeHexColor(color));
67
+ var labelConfigSchema = import_zod.z.object({
68
+ name: import_zod.z.string().min(1, "Label name is required").max(50, "Label name must be 50 characters or less").regex(
69
+ /^[a-zA-Z0-9\-\s\/\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FFF]+$/,
70
+ "Label name contains invalid characters"
71
+ ),
72
+ color: hexColorSchema,
73
+ description: import_zod.z.string().min(1, "Description is required").max(200, "Description must be 200 characters or less")
74
+ });
75
+ var labelCategorySchema = import_zod.z.object({
76
+ category: import_zod.z.string().min(1, "Category name is required").max(50, "Category name must be 50 characters or less"),
77
+ labels: import_zod.z.array(labelConfigSchema)
78
+ });
79
+ var labelRegistrySchema = import_zod.z.object({
80
+ version: import_zod.z.string(),
81
+ timestamp: import_zod.z.string().datetime().optional(),
82
+ labels: import_zod.z.union([
83
+ import_zod.z.array(labelConfigSchema),
84
+ import_zod.z.array(labelCategorySchema)
85
+ ]),
86
+ metadata: import_zod.z.record(import_zod.z.unknown()).optional()
87
+ });
88
+ function validateLabel(label) {
89
+ return labelConfigSchema.parse(label);
90
+ }
91
+ function validateLabels(labels) {
92
+ const schema = import_zod.z.array(labelConfigSchema);
93
+ return schema.parse(labels);
94
+ }
95
+ function validateRegistry(registry) {
96
+ return labelRegistrySchema.parse(registry);
97
+ }
98
+ function findDuplicateStrings(values) {
99
+ const seen = /* @__PURE__ */ new Map();
100
+ const duplicates = /* @__PURE__ */ new Set();
101
+ for (const value of values) {
102
+ const count = seen.get(value) || 0;
103
+ seen.set(value, count + 1);
104
+ if (count === 1) {
105
+ duplicates.add(value);
106
+ }
107
+ }
108
+ return Array.from(duplicates);
109
+ }
110
+ function checkDuplicateNames(labels) {
111
+ const names = labels.map((label) => label.name);
112
+ return findDuplicateStrings(names);
113
+ }
114
+ function checkDuplicateColors(labels) {
115
+ const colors = labels.map((label) => normalizeHexColor(label.color));
116
+ return findDuplicateStrings(colors);
117
+ }
118
+ function validateWithDetails(labels) {
119
+ try {
120
+ const parsed = validateLabels(labels);
121
+ const duplicateNames = checkDuplicateNames(parsed);
122
+ const duplicateColors = checkDuplicateColors(parsed);
123
+ return {
124
+ valid: duplicateNames.length === 0 && duplicateColors.length === 0,
125
+ labels: parsed,
126
+ errors: {
127
+ duplicateNames,
128
+ duplicateColors
129
+ }
130
+ };
131
+ } catch (error) {
132
+ if (error instanceof import_zod.z.ZodError) {
133
+ return {
134
+ valid: false,
135
+ labels: [],
136
+ errors: {
137
+ validationErrors: error.errors
138
+ }
139
+ };
140
+ }
141
+ throw error;
142
+ }
143
+ }
144
+
145
+ // src/manager.ts
146
+ var LabelManager = class {
147
+ constructor(options = {}) {
148
+ __publicField(this, "labels", /* @__PURE__ */ new Map());
149
+ __publicField(this, "strict", false);
150
+ this.strict = options.strict ?? false;
151
+ if (options.labels) {
152
+ this.loadLabels(options.labels);
153
+ }
154
+ }
155
+ /**
156
+ * Load labels from array
157
+ */
158
+ loadLabels(labels) {
159
+ const validation = validateWithDetails(labels);
160
+ if (!validation.valid && this.strict) {
161
+ throw new Error(`Label validation failed: ${JSON.stringify(validation.errors)}`);
162
+ }
163
+ this.labels.clear();
164
+ validation.labels.forEach((label) => {
165
+ this.labels.set(label.name.toLowerCase(), label);
166
+ });
167
+ }
168
+ /**
169
+ * Load labels from registry object
170
+ */
171
+ loadRegistry(registry) {
172
+ const labels = flattenLabels(registry.labels);
173
+ this.loadLabels(labels);
174
+ }
175
+ /**
176
+ * Add a single label
177
+ */
178
+ addLabel(label) {
179
+ const validation = validateLabels([label]);
180
+ const newLabel = validation[0];
181
+ if (this.labels.has(newLabel.name.toLowerCase())) {
182
+ throw new Error(`Label "${newLabel.name}" already exists`);
183
+ }
184
+ this.labels.set(newLabel.name.toLowerCase(), newLabel);
185
+ }
186
+ /**
187
+ * Update an existing label
188
+ */
189
+ updateLabel(name, updates) {
190
+ const key = name.toLowerCase();
191
+ const existing = this.labels.get(key);
192
+ if (!existing) {
193
+ throw new Error(`Label "${name}" not found`);
194
+ }
195
+ const updated = { ...existing, ...updates };
196
+ const validation = validateLabels([updated]);
197
+ this.labels.set(key, validation[0]);
198
+ }
199
+ /**
200
+ * Remove a label
201
+ */
202
+ removeLabel(name) {
203
+ this.labels.delete(name.toLowerCase());
204
+ }
205
+ /**
206
+ * Get a label by name
207
+ */
208
+ getLabel(name) {
209
+ return this.labels.get(name.toLowerCase());
210
+ }
211
+ /**
212
+ * Check if label exists
213
+ */
214
+ hasLabel(name) {
215
+ return this.labels.has(name.toLowerCase());
216
+ }
217
+ /**
218
+ * Get all labels
219
+ */
220
+ getAllLabels() {
221
+ return Array.from(this.labels.values());
222
+ }
223
+ /**
224
+ * Get labels count
225
+ */
226
+ count() {
227
+ return this.labels.size;
228
+ }
229
+ /**
230
+ * Export labels as array
231
+ */
232
+ export() {
233
+ return this.getAllLabels();
234
+ }
235
+ /**
236
+ * Export as registry object
237
+ */
238
+ exportRegistry(version2 = "1.0.0", metadata) {
239
+ return {
240
+ version: version2,
241
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
242
+ labels: this.getAllLabels(),
243
+ metadata
244
+ };
245
+ }
246
+ /**
247
+ * Search labels by name or description
248
+ */
249
+ search(query) {
250
+ const lowerQuery = query.toLowerCase();
251
+ return this.getAllLabels().filter(
252
+ (label) => label.name.toLowerCase().includes(lowerQuery) || label.description.toLowerCase().includes(lowerQuery)
253
+ );
254
+ }
255
+ /**
256
+ * Find labels by color
257
+ */
258
+ findByColor(color) {
259
+ const normalizedColor = color.toLowerCase();
260
+ return this.getAllLabels().filter((label) => label.color.toLowerCase() === normalizedColor);
261
+ }
262
+ /**
263
+ * Clear all labels
264
+ */
265
+ clear() {
266
+ this.labels.clear();
267
+ }
268
+ /**
269
+ * Validate current state
270
+ */
271
+ validate() {
272
+ const labels = this.getAllLabels();
273
+ const duplicates = checkDuplicateNames(labels);
274
+ return {
275
+ valid: duplicates.length === 0,
276
+ duplicates
277
+ };
278
+ }
279
+ };
280
+
281
+ // src/version.ts
282
+ var version = "0.2.2";
283
+
284
+ // src/index.ts
285
+ var index_default = {
286
+ LabelManager,
287
+ validateLabels,
288
+ validateWithDetails,
289
+ version
290
+ };
291
+ // Annotate the CommonJS export names for ESM import in node:
292
+ 0 && (module.exports = {
293
+ LabelManager,
294
+ checkDuplicateColors,
295
+ checkDuplicateNames,
296
+ flattenLabels,
297
+ isCategorized,
298
+ labelCategorySchema,
299
+ labelConfigSchema,
300
+ labelRegistrySchema,
301
+ validateLabel,
302
+ validateLabels,
303
+ validateRegistry,
304
+ validateWithDetails,
305
+ version
306
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,44 @@
1
+ import {
2
+ LabelManager,
3
+ flattenLabels,
4
+ isCategorized
5
+ } from "./chunk-DSI7SDAM.mjs";
6
+ import {
7
+ checkDuplicateColors,
8
+ checkDuplicateNames,
9
+ labelCategorySchema,
10
+ labelConfigSchema,
11
+ labelRegistrySchema,
12
+ validateLabel,
13
+ validateLabels,
14
+ validateRegistry,
15
+ validateWithDetails
16
+ } from "./chunk-VU2JB66N.mjs";
17
+ import "./chunk-QZ7TP4HQ.mjs";
18
+
19
+ // src/version.ts
20
+ var version = "0.2.2";
21
+
22
+ // src/index.ts
23
+ var index_default = {
24
+ LabelManager,
25
+ validateLabels,
26
+ validateWithDetails,
27
+ version
28
+ };
29
+ export {
30
+ LabelManager,
31
+ checkDuplicateColors,
32
+ checkDuplicateNames,
33
+ index_default as default,
34
+ flattenLabels,
35
+ isCategorized,
36
+ labelCategorySchema,
37
+ labelConfigSchema,
38
+ labelRegistrySchema,
39
+ validateLabel,
40
+ validateLabels,
41
+ validateRegistry,
42
+ validateWithDetails,
43
+ version
44
+ };
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Label Configuration Types
3
+ * Defines the structure and validation rules for labels
4
+ */
5
+ type HexColor = string & {
6
+ readonly __brand: 'HexColor';
7
+ };
8
+ interface LabelConfig {
9
+ /**
10
+ * Unique identifier for the label
11
+ * Used in GitHub as the label name
12
+ */
13
+ name: string;
14
+ /**
15
+ * Hex color code (without # prefix)
16
+ * Examples: 'ffb300', '008672', 'ff0000'
17
+ */
18
+ color: HexColor;
19
+ /**
20
+ * Human-readable description
21
+ * Displayed in GitHub and UI components
22
+ */
23
+ description: string;
24
+ }
25
+ interface LabelCategory {
26
+ /** Category name for grouping related labels */
27
+ category: string;
28
+ /** Labels in this category */
29
+ labels: LabelConfig[];
30
+ }
31
+ interface LabelRegistry {
32
+ /** Version of the label configuration */
33
+ version: string;
34
+ /** Timestamp of last update */
35
+ timestamp?: string;
36
+ /** All labels, optionally grouped by category */
37
+ labels: LabelConfig[] | LabelCategory[];
38
+ /** Custom metadata */
39
+ metadata?: Record<string, unknown>;
40
+ }
41
+ /**
42
+ * Type guard for checking if labels are categorized
43
+ */
44
+ declare function isCategorized(labels: LabelConfig[] | LabelCategory[]): labels is LabelCategory[];
45
+ /**
46
+ * Flatten categorized labels to a flat array
47
+ */
48
+ declare function flattenLabels(labels: LabelConfig[] | LabelCategory[]): LabelConfig[];
49
+
50
+ export { type HexColor as H, type LabelConfig as L, type LabelRegistry as a, type LabelCategory as b, flattenLabels as f, isCategorized as i };
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Label Configuration Types
3
+ * Defines the structure and validation rules for labels
4
+ */
5
+ type HexColor = string & {
6
+ readonly __brand: 'HexColor';
7
+ };
8
+ interface LabelConfig {
9
+ /**
10
+ * Unique identifier for the label
11
+ * Used in GitHub as the label name
12
+ */
13
+ name: string;
14
+ /**
15
+ * Hex color code (without # prefix)
16
+ * Examples: 'ffb300', '008672', 'ff0000'
17
+ */
18
+ color: HexColor;
19
+ /**
20
+ * Human-readable description
21
+ * Displayed in GitHub and UI components
22
+ */
23
+ description: string;
24
+ }
25
+ interface LabelCategory {
26
+ /** Category name for grouping related labels */
27
+ category: string;
28
+ /** Labels in this category */
29
+ labels: LabelConfig[];
30
+ }
31
+ interface LabelRegistry {
32
+ /** Version of the label configuration */
33
+ version: string;
34
+ /** Timestamp of last update */
35
+ timestamp?: string;
36
+ /** All labels, optionally grouped by category */
37
+ labels: LabelConfig[] | LabelCategory[];
38
+ /** Custom metadata */
39
+ metadata?: Record<string, unknown>;
40
+ }
41
+ /**
42
+ * Type guard for checking if labels are categorized
43
+ */
44
+ declare function isCategorized(labels: LabelConfig[] | LabelCategory[]): labels is LabelCategory[];
45
+ /**
46
+ * Flatten categorized labels to a flat array
47
+ */
48
+ declare function flattenLabels(labels: LabelConfig[] | LabelCategory[]): LabelConfig[];
49
+
50
+ export { type HexColor as H, type LabelConfig as L, type LabelRegistry as a, type LabelCategory as b, flattenLabels as f, isCategorized as i };