featuredrop 1.1.0 → 1.2.0

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 (60) hide show
  1. package/README.md +376 -4
  2. package/dist/angular.cjs +286 -0
  3. package/dist/angular.cjs.map +1 -0
  4. package/dist/angular.d.cts +229 -0
  5. package/dist/angular.d.ts +229 -0
  6. package/dist/angular.js +283 -0
  7. package/dist/angular.js.map +1 -0
  8. package/dist/featuredrop.cjs +1256 -0
  9. package/dist/featuredrop.cjs.map +1 -0
  10. package/dist/index.cjs +2762 -16
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.cts +979 -9
  13. package/dist/index.d.ts +979 -9
  14. package/dist/index.js +2720 -17
  15. package/dist/index.js.map +1 -1
  16. package/dist/preact.cjs +7289 -0
  17. package/dist/preact.cjs.map +1 -0
  18. package/dist/preact.d.cts +1266 -0
  19. package/dist/preact.d.ts +1266 -0
  20. package/dist/preact.js +7259 -0
  21. package/dist/preact.js.map +1 -0
  22. package/dist/react.cjs +6119 -101
  23. package/dist/react.cjs.map +1 -1
  24. package/dist/react.d.cts +798 -5
  25. package/dist/react.d.ts +798 -5
  26. package/dist/react.js +6103 -103
  27. package/dist/react.js.map +1 -1
  28. package/dist/schema.cjs +215 -0
  29. package/dist/schema.cjs.map +1 -0
  30. package/dist/schema.d.cts +203 -0
  31. package/dist/schema.d.ts +203 -0
  32. package/dist/schema.js +209 -0
  33. package/dist/schema.js.map +1 -0
  34. package/dist/solid.cjs +373 -0
  35. package/dist/solid.cjs.map +1 -0
  36. package/dist/solid.d.cts +242 -0
  37. package/dist/solid.d.ts +242 -0
  38. package/dist/solid.js +366 -0
  39. package/dist/solid.js.map +1 -0
  40. package/dist/svelte.cjs +329 -0
  41. package/dist/svelte.cjs.map +1 -0
  42. package/dist/svelte.js +324 -0
  43. package/dist/svelte.js.map +1 -0
  44. package/dist/testing.cjs +1422 -0
  45. package/dist/testing.cjs.map +1 -0
  46. package/dist/testing.d.cts +339 -0
  47. package/dist/testing.d.ts +339 -0
  48. package/dist/testing.js +1415 -0
  49. package/dist/testing.js.map +1 -0
  50. package/dist/vue.cjs +1084 -0
  51. package/dist/vue.cjs.map +1 -0
  52. package/dist/vue.js +1072 -0
  53. package/dist/vue.js.map +1 -0
  54. package/dist/web-components.cjs +483 -0
  55. package/dist/web-components.cjs.map +1 -0
  56. package/dist/web-components.d.cts +211 -0
  57. package/dist/web-components.d.ts +211 -0
  58. package/dist/web-components.js +477 -0
  59. package/dist/web-components.js.map +1 -0
  60. package/package.json +126 -3
@@ -0,0 +1,215 @@
1
+ 'use strict';
2
+
3
+ var zod = require('zod');
4
+
5
+ // src/dependencies.ts
6
+ function getDirectDependencies(feature) {
7
+ const dependsOn = feature.dependsOn;
8
+ if (!dependsOn) return [];
9
+ const seen = dependsOn.seen ?? [];
10
+ const clicked = dependsOn.clicked ?? [];
11
+ const dismissed = dependsOn.dismissed ?? [];
12
+ const unique = /* @__PURE__ */ new Set();
13
+ for (const id of [...seen, ...clicked, ...dismissed]) {
14
+ if (id) unique.add(id);
15
+ }
16
+ return Array.from(unique);
17
+ }
18
+ function hasDependencyCycle(manifest) {
19
+ const ids = new Set(manifest.map((feature) => feature.id));
20
+ const outgoing = /* @__PURE__ */ new Map();
21
+ const indegree = /* @__PURE__ */ new Map();
22
+ for (const feature of manifest) {
23
+ outgoing.set(feature.id, /* @__PURE__ */ new Set());
24
+ indegree.set(feature.id, 0);
25
+ }
26
+ for (const feature of manifest) {
27
+ for (const dependencyId of getDirectDependencies(feature)) {
28
+ if (!ids.has(dependencyId)) continue;
29
+ const edges = outgoing.get(dependencyId);
30
+ if (!edges || edges.has(feature.id)) continue;
31
+ edges.add(feature.id);
32
+ indegree.set(feature.id, (indegree.get(feature.id) ?? 0) + 1);
33
+ }
34
+ }
35
+ const queue = [];
36
+ for (const feature of manifest) {
37
+ if ((indegree.get(feature.id) ?? 0) === 0) queue.push(feature.id);
38
+ }
39
+ let visited = 0;
40
+ while (queue.length > 0) {
41
+ const id = queue.shift();
42
+ if (!id) continue;
43
+ visited += 1;
44
+ const edges = outgoing.get(id);
45
+ if (!edges) continue;
46
+ for (const nextId of edges) {
47
+ const nextDegree = (indegree.get(nextId) ?? 0) - 1;
48
+ indegree.set(nextId, nextDegree);
49
+ if (nextDegree === 0) queue.push(nextId);
50
+ }
51
+ }
52
+ return visited !== manifest.length;
53
+ }
54
+ var featureEntryJsonSchema = {
55
+ type: "object",
56
+ required: ["id", "label", "releasedAt", "showNewUntil"],
57
+ properties: {
58
+ id: { type: "string" },
59
+ label: { type: "string" },
60
+ description: { type: "string" },
61
+ releasedAt: { type: "string", format: "date-time" },
62
+ showNewUntil: { type: "string", format: "date-time" },
63
+ type: { enum: ["feature", "improvement", "fix", "breaking"] },
64
+ priority: { enum: ["critical", "normal", "low"] }
65
+ }
66
+ };
67
+ var featureManifestJsonSchema = {
68
+ type: "array",
69
+ items: featureEntryJsonSchema
70
+ };
71
+ function isRecord(value) {
72
+ return !!value && typeof value === "object" && !Array.isArray(value);
73
+ }
74
+ function isValidDate(value) {
75
+ return Number.isFinite(new Date(value).getTime());
76
+ }
77
+ var nonEmptyString = zod.z.string().trim().min(1, "must be a non-empty string");
78
+ var isoDateString = nonEmptyString.refine(isValidDate, {
79
+ message: "must be a valid date",
80
+ params: { featuredropCode: "invalid_date" }
81
+ });
82
+ var dependsOnSchema = zod.z.object({
83
+ seen: zod.z.array(zod.z.string()).optional(),
84
+ clicked: zod.z.array(zod.z.string()).optional(),
85
+ dismissed: zod.z.array(zod.z.string()).optional()
86
+ }).optional();
87
+ var featureEntrySchema = zod.z.object({
88
+ id: nonEmptyString,
89
+ label: nonEmptyString,
90
+ releasedAt: isoDateString,
91
+ showNewUntil: isoDateString,
92
+ description: zod.z.string().optional(),
93
+ type: zod.z.enum(["feature", "improvement", "fix", "breaking"]).optional(),
94
+ priority: zod.z.enum(["critical", "normal", "low"]).optional(),
95
+ dependsOn: dependsOnSchema
96
+ }).passthrough();
97
+ var featureManifestSchema = zod.z.array(featureEntrySchema);
98
+ function toIssuePath(path) {
99
+ if (path.length === 0) return "$";
100
+ let output = "";
101
+ for (const part of path) {
102
+ if (typeof part === "number") output += `[${part}]`;
103
+ else output += output ? `.${part}` : part;
104
+ }
105
+ return output;
106
+ }
107
+ function mapZodIssue(issue) {
108
+ const codeParam = issue.params?.featuredropCode;
109
+ if (codeParam === "invalid_date") {
110
+ return {
111
+ path: toIssuePath(issue.path),
112
+ message: issue.message,
113
+ code: "invalid_date"
114
+ };
115
+ }
116
+ if (issue.code === "invalid_type") {
117
+ return {
118
+ path: toIssuePath(issue.path),
119
+ message: issue.message,
120
+ code: issue.received === "undefined" ? "missing_required" : "invalid_type"
121
+ };
122
+ }
123
+ return {
124
+ path: toIssuePath(issue.path),
125
+ message: issue.message,
126
+ code: "invalid_value"
127
+ };
128
+ }
129
+ function validateFeatureEntry(raw, index) {
130
+ if (!isRecord(raw)) {
131
+ return {
132
+ issues: [
133
+ {
134
+ path: `[${index}]`,
135
+ message: "Feature entry must be an object",
136
+ code: "invalid_type"
137
+ }
138
+ ]
139
+ };
140
+ }
141
+ const parsed = featureEntrySchema.safeParse(raw);
142
+ if (!parsed.success) {
143
+ return {
144
+ issues: parsed.error.issues.map((issue) => ({
145
+ ...mapZodIssue(issue),
146
+ path: `[${index}]${issue.path.length > 0 ? `.${toIssuePath(issue.path)}` : ""}`
147
+ }))
148
+ };
149
+ }
150
+ return {
151
+ issues: [],
152
+ entry: parsed.data
153
+ };
154
+ }
155
+ function validateManifest(data) {
156
+ const errors = [];
157
+ if (!Array.isArray(data)) {
158
+ return {
159
+ valid: false,
160
+ errors: [
161
+ {
162
+ path: "$",
163
+ message: "Manifest must be an array",
164
+ code: "invalid_type"
165
+ }
166
+ ]
167
+ };
168
+ }
169
+ const entries = [];
170
+ const seenIds = /* @__PURE__ */ new Set();
171
+ data.forEach((item, index) => {
172
+ const result = validateFeatureEntry(item, index);
173
+ errors.push(...result.issues);
174
+ if (!result.entry) return;
175
+ if (seenIds.has(result.entry.id)) {
176
+ errors.push({
177
+ path: `[${index}].id`,
178
+ message: `Duplicate feature id "${result.entry.id}"`,
179
+ code: "duplicate_id"
180
+ });
181
+ return;
182
+ }
183
+ seenIds.add(result.entry.id);
184
+ entries.push(result.entry);
185
+ });
186
+ if (entries.length > 0 && hasDependencyCycle(entries)) {
187
+ errors.push({
188
+ path: "$",
189
+ message: "Circular dependsOn relationship detected",
190
+ code: "circular_dependency"
191
+ });
192
+ }
193
+ for (let index = 0; index < entries.length; index++) {
194
+ const entry = entries[index];
195
+ if (new Date(entry.showNewUntil).getTime() <= new Date(entry.releasedAt).getTime()) {
196
+ errors.push({
197
+ path: `[${index}].showNewUntil`,
198
+ message: "showNewUntil must be after releasedAt",
199
+ code: "invalid_value"
200
+ });
201
+ }
202
+ }
203
+ return {
204
+ valid: errors.length === 0,
205
+ errors
206
+ };
207
+ }
208
+
209
+ exports.featureEntryJsonSchema = featureEntryJsonSchema;
210
+ exports.featureEntrySchema = featureEntrySchema;
211
+ exports.featureManifestJsonSchema = featureManifestJsonSchema;
212
+ exports.featureManifestSchema = featureManifestSchema;
213
+ exports.validateManifest = validateManifest;
214
+ //# sourceMappingURL=schema.cjs.map
215
+ //# sourceMappingURL=schema.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/dependencies.ts","../src/schema.ts"],"names":["z"],"mappings":"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","file":"schema.cjs","sourcesContent":["import type { FeatureEntry, FeatureManifest } from \"./types\";\n\nfunction getDirectDependencies(feature: FeatureEntry): string[] {\n const dependsOn = feature.dependsOn;\n if (!dependsOn) return [];\n const seen = dependsOn.seen ?? [];\n const clicked = dependsOn.clicked ?? [];\n const dismissed = dependsOn.dismissed ?? [];\n const unique = new Set<string>();\n for (const id of [...seen, ...clicked, ...dismissed]) {\n if (id) unique.add(id);\n }\n return Array.from(unique);\n}\n\nexport function resolveDependencyOrder(manifest: FeatureManifest): string[] {\n const ids = new Set(manifest.map((feature) => feature.id));\n const outgoing = new Map<string, Set<string>>();\n const indegree = new Map<string, number>();\n\n for (const feature of manifest) {\n outgoing.set(feature.id, new Set());\n indegree.set(feature.id, 0);\n }\n\n for (const feature of manifest) {\n for (const dependencyId of getDirectDependencies(feature)) {\n if (!ids.has(dependencyId)) continue;\n const edges = outgoing.get(dependencyId);\n if (!edges || edges.has(feature.id)) continue;\n edges.add(feature.id);\n indegree.set(feature.id, (indegree.get(feature.id) ?? 0) + 1);\n }\n }\n\n const queue: string[] = [];\n for (const feature of manifest) {\n if ((indegree.get(feature.id) ?? 0) === 0) queue.push(feature.id);\n }\n\n const ordered: string[] = [];\n while (queue.length > 0) {\n const id = queue.shift();\n if (!id) continue;\n ordered.push(id);\n const edges = outgoing.get(id);\n if (!edges) continue;\n for (const nextId of edges) {\n const nextDegree = (indegree.get(nextId) ?? 0) - 1;\n indegree.set(nextId, nextDegree);\n if (nextDegree === 0) queue.push(nextId);\n }\n }\n\n // On cycles, append remaining IDs in original order to keep behavior stable.\n if (ordered.length < manifest.length) {\n const included = new Set(ordered);\n for (const feature of manifest) {\n if (included.has(feature.id)) continue;\n ordered.push(feature.id);\n }\n }\n\n return ordered;\n}\n\nexport function hasDependencyCycle(manifest: FeatureManifest): boolean {\n const ids = new Set(manifest.map((feature) => feature.id));\n const outgoing = new Map<string, Set<string>>();\n const indegree = new Map<string, number>();\n\n for (const feature of manifest) {\n outgoing.set(feature.id, new Set());\n indegree.set(feature.id, 0);\n }\n\n for (const feature of manifest) {\n for (const dependencyId of getDirectDependencies(feature)) {\n if (!ids.has(dependencyId)) continue;\n const edges = outgoing.get(dependencyId);\n if (!edges || edges.has(feature.id)) continue;\n edges.add(feature.id);\n indegree.set(feature.id, (indegree.get(feature.id) ?? 0) + 1);\n }\n }\n\n const queue: string[] = [];\n for (const feature of manifest) {\n if ((indegree.get(feature.id) ?? 0) === 0) queue.push(feature.id);\n }\n\n let visited = 0;\n while (queue.length > 0) {\n const id = queue.shift();\n if (!id) continue;\n visited += 1;\n const edges = outgoing.get(id);\n if (!edges) continue;\n for (const nextId of edges) {\n const nextDegree = (indegree.get(nextId) ?? 0) - 1;\n indegree.set(nextId, nextDegree);\n if (nextDegree === 0) queue.push(nextId);\n }\n }\n\n return visited !== manifest.length;\n}\n\nexport function sortFeaturesByDependencies(features: FeatureEntry[]): FeatureEntry[] {\n if (features.length <= 1) return [...features];\n const order = resolveDependencyOrder(features);\n const rank = new Map(order.map((id, index) => [id, index]));\n return [...features].sort((a, b) => {\n const ra = rank.get(a.id);\n const rb = rank.get(b.id);\n if (ra === undefined || rb === undefined) return 0;\n return ra - rb;\n });\n}\n","import { hasDependencyCycle } from \"./dependencies\";\nimport type { FeatureEntry, FeatureManifest } from \"./types\";\nimport { z } from \"zod\";\n\nexport interface ValidationIssue {\n path: string;\n message: string;\n code:\n | \"invalid_type\"\n | \"missing_required\"\n | \"invalid_value\"\n | \"invalid_date\"\n | \"duplicate_id\"\n | \"circular_dependency\";\n}\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationIssue[];\n}\n\nexport const featureEntryJsonSchema = {\n type: \"object\",\n required: [\"id\", \"label\", \"releasedAt\", \"showNewUntil\"],\n properties: {\n id: { type: \"string\" },\n label: { type: \"string\" },\n description: { type: \"string\" },\n releasedAt: { type: \"string\", format: \"date-time\" },\n showNewUntil: { type: \"string\", format: \"date-time\" },\n type: { enum: [\"feature\", \"improvement\", \"fix\", \"breaking\"] },\n priority: { enum: [\"critical\", \"normal\", \"low\"] },\n },\n} as const;\n\nexport const featureManifestJsonSchema = {\n type: \"array\",\n items: featureEntryJsonSchema,\n} as const;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isValidDate(value: string): boolean {\n return Number.isFinite(new Date(value).getTime());\n}\n\nconst nonEmptyString = z.string().trim().min(1, \"must be a non-empty string\");\n\nconst isoDateString = nonEmptyString.refine(isValidDate, {\n message: \"must be a valid date\",\n params: { featuredropCode: \"invalid_date\" },\n});\n\nconst dependsOnSchema = z\n .object({\n seen: z.array(z.string()).optional(),\n clicked: z.array(z.string()).optional(),\n dismissed: z.array(z.string()).optional(),\n })\n .optional();\n\nexport const featureEntrySchema = z\n .object({\n id: nonEmptyString,\n label: nonEmptyString,\n releasedAt: isoDateString,\n showNewUntil: isoDateString,\n description: z.string().optional(),\n type: z.enum([\"feature\", \"improvement\", \"fix\", \"breaking\"]).optional(),\n priority: z.enum([\"critical\", \"normal\", \"low\"]).optional(),\n dependsOn: dependsOnSchema,\n })\n .passthrough();\n\nexport const featureManifestSchema = z.array(featureEntrySchema);\n\nfunction toIssuePath(path: Array<string | number>): string {\n if (path.length === 0) return \"$\";\n let output = \"\";\n for (const part of path) {\n if (typeof part === \"number\") output += `[${part}]`;\n else output += output ? `.${part}` : part;\n }\n return output;\n}\n\nfunction mapZodIssue(issue: z.ZodIssue): ValidationIssue {\n const codeParam = (issue as { params?: Record<string, unknown> }).params?.featuredropCode;\n if (codeParam === \"invalid_date\") {\n return {\n path: toIssuePath(issue.path),\n message: issue.message,\n code: \"invalid_date\",\n };\n }\n if (issue.code === \"invalid_type\") {\n return {\n path: toIssuePath(issue.path),\n message: issue.message,\n code: issue.received === \"undefined\" ? \"missing_required\" : \"invalid_type\",\n };\n }\n return {\n path: toIssuePath(issue.path),\n message: issue.message,\n code: \"invalid_value\",\n };\n}\n\nfunction validateFeatureEntry(raw: unknown, index: number): { entry?: FeatureEntry; issues: ValidationIssue[] } {\n if (!isRecord(raw)) {\n return {\n issues: [\n {\n path: `[${index}]`,\n message: \"Feature entry must be an object\",\n code: \"invalid_type\",\n },\n ],\n };\n }\n\n const parsed = featureEntrySchema.safeParse(raw);\n if (!parsed.success) {\n return {\n issues: parsed.error.issues.map((issue) => ({\n ...mapZodIssue(issue),\n path: `[${index}]${issue.path.length > 0 ? `.${toIssuePath(issue.path)}` : \"\"}`,\n })),\n };\n }\n\n return {\n issues: [],\n entry: parsed.data as FeatureEntry,\n };\n}\n\nexport function validateManifest(data: unknown): ValidationResult {\n const errors: ValidationIssue[] = [];\n if (!Array.isArray(data)) {\n return {\n valid: false,\n errors: [\n {\n path: \"$\",\n message: \"Manifest must be an array\",\n code: \"invalid_type\",\n },\n ],\n };\n }\n\n const entries: FeatureEntry[] = [];\n const seenIds = new Set<string>();\n data.forEach((item, index) => {\n const result = validateFeatureEntry(item, index);\n errors.push(...result.issues);\n if (!result.entry) return;\n if (seenIds.has(result.entry.id)) {\n errors.push({\n path: `[${index}].id`,\n message: `Duplicate feature id \"${result.entry.id}\"`,\n code: \"duplicate_id\",\n });\n return;\n }\n seenIds.add(result.entry.id);\n entries.push(result.entry);\n });\n\n if (entries.length > 0 && hasDependencyCycle(entries as FeatureManifest)) {\n errors.push({\n path: \"$\",\n message: \"Circular dependsOn relationship detected\",\n code: \"circular_dependency\",\n });\n }\n\n for (let index = 0; index < entries.length; index++) {\n const entry = entries[index];\n if (new Date(entry.showNewUntil).getTime() <= new Date(entry.releasedAt).getTime()) {\n errors.push({\n path: `[${index}].showNewUntil`,\n message: \"showNewUntil must be after releasedAt\",\n code: \"invalid_value\",\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n"]}
@@ -0,0 +1,203 @@
1
+ import { z } from 'zod';
2
+
3
+ interface ValidationIssue {
4
+ path: string;
5
+ message: string;
6
+ code: "invalid_type" | "missing_required" | "invalid_value" | "invalid_date" | "duplicate_id" | "circular_dependency";
7
+ }
8
+ interface ValidationResult {
9
+ valid: boolean;
10
+ errors: ValidationIssue[];
11
+ }
12
+ declare const featureEntryJsonSchema: {
13
+ readonly type: "object";
14
+ readonly required: readonly ["id", "label", "releasedAt", "showNewUntil"];
15
+ readonly properties: {
16
+ readonly id: {
17
+ readonly type: "string";
18
+ };
19
+ readonly label: {
20
+ readonly type: "string";
21
+ };
22
+ readonly description: {
23
+ readonly type: "string";
24
+ };
25
+ readonly releasedAt: {
26
+ readonly type: "string";
27
+ readonly format: "date-time";
28
+ };
29
+ readonly showNewUntil: {
30
+ readonly type: "string";
31
+ readonly format: "date-time";
32
+ };
33
+ readonly type: {
34
+ readonly enum: readonly ["feature", "improvement", "fix", "breaking"];
35
+ };
36
+ readonly priority: {
37
+ readonly enum: readonly ["critical", "normal", "low"];
38
+ };
39
+ };
40
+ };
41
+ declare const featureManifestJsonSchema: {
42
+ readonly type: "array";
43
+ readonly items: {
44
+ readonly type: "object";
45
+ readonly required: readonly ["id", "label", "releasedAt", "showNewUntil"];
46
+ readonly properties: {
47
+ readonly id: {
48
+ readonly type: "string";
49
+ };
50
+ readonly label: {
51
+ readonly type: "string";
52
+ };
53
+ readonly description: {
54
+ readonly type: "string";
55
+ };
56
+ readonly releasedAt: {
57
+ readonly type: "string";
58
+ readonly format: "date-time";
59
+ };
60
+ readonly showNewUntil: {
61
+ readonly type: "string";
62
+ readonly format: "date-time";
63
+ };
64
+ readonly type: {
65
+ readonly enum: readonly ["feature", "improvement", "fix", "breaking"];
66
+ };
67
+ readonly priority: {
68
+ readonly enum: readonly ["critical", "normal", "low"];
69
+ };
70
+ };
71
+ };
72
+ };
73
+ declare const featureEntrySchema: z.ZodObject<{
74
+ id: z.ZodString;
75
+ label: z.ZodString;
76
+ releasedAt: z.ZodEffects<z.ZodString, string, string>;
77
+ showNewUntil: z.ZodEffects<z.ZodString, string, string>;
78
+ description: z.ZodOptional<z.ZodString>;
79
+ type: z.ZodOptional<z.ZodEnum<["feature", "improvement", "fix", "breaking"]>>;
80
+ priority: z.ZodOptional<z.ZodEnum<["critical", "normal", "low"]>>;
81
+ dependsOn: z.ZodOptional<z.ZodObject<{
82
+ seen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
83
+ clicked: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
84
+ dismissed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
85
+ }, "strip", z.ZodTypeAny, {
86
+ seen?: string[] | undefined;
87
+ clicked?: string[] | undefined;
88
+ dismissed?: string[] | undefined;
89
+ }, {
90
+ seen?: string[] | undefined;
91
+ clicked?: string[] | undefined;
92
+ dismissed?: string[] | undefined;
93
+ }>>;
94
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
95
+ id: z.ZodString;
96
+ label: z.ZodString;
97
+ releasedAt: z.ZodEffects<z.ZodString, string, string>;
98
+ showNewUntil: z.ZodEffects<z.ZodString, string, string>;
99
+ description: z.ZodOptional<z.ZodString>;
100
+ type: z.ZodOptional<z.ZodEnum<["feature", "improvement", "fix", "breaking"]>>;
101
+ priority: z.ZodOptional<z.ZodEnum<["critical", "normal", "low"]>>;
102
+ dependsOn: z.ZodOptional<z.ZodObject<{
103
+ seen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
104
+ clicked: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
105
+ dismissed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
106
+ }, "strip", z.ZodTypeAny, {
107
+ seen?: string[] | undefined;
108
+ clicked?: string[] | undefined;
109
+ dismissed?: string[] | undefined;
110
+ }, {
111
+ seen?: string[] | undefined;
112
+ clicked?: string[] | undefined;
113
+ dismissed?: string[] | undefined;
114
+ }>>;
115
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
116
+ id: z.ZodString;
117
+ label: z.ZodString;
118
+ releasedAt: z.ZodEffects<z.ZodString, string, string>;
119
+ showNewUntil: z.ZodEffects<z.ZodString, string, string>;
120
+ description: z.ZodOptional<z.ZodString>;
121
+ type: z.ZodOptional<z.ZodEnum<["feature", "improvement", "fix", "breaking"]>>;
122
+ priority: z.ZodOptional<z.ZodEnum<["critical", "normal", "low"]>>;
123
+ dependsOn: z.ZodOptional<z.ZodObject<{
124
+ seen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
125
+ clicked: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
126
+ dismissed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
127
+ }, "strip", z.ZodTypeAny, {
128
+ seen?: string[] | undefined;
129
+ clicked?: string[] | undefined;
130
+ dismissed?: string[] | undefined;
131
+ }, {
132
+ seen?: string[] | undefined;
133
+ clicked?: string[] | undefined;
134
+ dismissed?: string[] | undefined;
135
+ }>>;
136
+ }, z.ZodTypeAny, "passthrough">>;
137
+ declare const featureManifestSchema: z.ZodArray<z.ZodObject<{
138
+ id: z.ZodString;
139
+ label: z.ZodString;
140
+ releasedAt: z.ZodEffects<z.ZodString, string, string>;
141
+ showNewUntil: z.ZodEffects<z.ZodString, string, string>;
142
+ description: z.ZodOptional<z.ZodString>;
143
+ type: z.ZodOptional<z.ZodEnum<["feature", "improvement", "fix", "breaking"]>>;
144
+ priority: z.ZodOptional<z.ZodEnum<["critical", "normal", "low"]>>;
145
+ dependsOn: z.ZodOptional<z.ZodObject<{
146
+ seen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
147
+ clicked: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
148
+ dismissed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
149
+ }, "strip", z.ZodTypeAny, {
150
+ seen?: string[] | undefined;
151
+ clicked?: string[] | undefined;
152
+ dismissed?: string[] | undefined;
153
+ }, {
154
+ seen?: string[] | undefined;
155
+ clicked?: string[] | undefined;
156
+ dismissed?: string[] | undefined;
157
+ }>>;
158
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
159
+ id: z.ZodString;
160
+ label: z.ZodString;
161
+ releasedAt: z.ZodEffects<z.ZodString, string, string>;
162
+ showNewUntil: z.ZodEffects<z.ZodString, string, string>;
163
+ description: z.ZodOptional<z.ZodString>;
164
+ type: z.ZodOptional<z.ZodEnum<["feature", "improvement", "fix", "breaking"]>>;
165
+ priority: z.ZodOptional<z.ZodEnum<["critical", "normal", "low"]>>;
166
+ dependsOn: z.ZodOptional<z.ZodObject<{
167
+ seen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
168
+ clicked: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
169
+ dismissed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
170
+ }, "strip", z.ZodTypeAny, {
171
+ seen?: string[] | undefined;
172
+ clicked?: string[] | undefined;
173
+ dismissed?: string[] | undefined;
174
+ }, {
175
+ seen?: string[] | undefined;
176
+ clicked?: string[] | undefined;
177
+ dismissed?: string[] | undefined;
178
+ }>>;
179
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
180
+ id: z.ZodString;
181
+ label: z.ZodString;
182
+ releasedAt: z.ZodEffects<z.ZodString, string, string>;
183
+ showNewUntil: z.ZodEffects<z.ZodString, string, string>;
184
+ description: z.ZodOptional<z.ZodString>;
185
+ type: z.ZodOptional<z.ZodEnum<["feature", "improvement", "fix", "breaking"]>>;
186
+ priority: z.ZodOptional<z.ZodEnum<["critical", "normal", "low"]>>;
187
+ dependsOn: z.ZodOptional<z.ZodObject<{
188
+ seen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
189
+ clicked: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
190
+ dismissed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
191
+ }, "strip", z.ZodTypeAny, {
192
+ seen?: string[] | undefined;
193
+ clicked?: string[] | undefined;
194
+ dismissed?: string[] | undefined;
195
+ }, {
196
+ seen?: string[] | undefined;
197
+ clicked?: string[] | undefined;
198
+ dismissed?: string[] | undefined;
199
+ }>>;
200
+ }, z.ZodTypeAny, "passthrough">>, "many">;
201
+ declare function validateManifest(data: unknown): ValidationResult;
202
+
203
+ export { type ValidationIssue, type ValidationResult, featureEntryJsonSchema, featureEntrySchema, featureManifestJsonSchema, featureManifestSchema, validateManifest };
@@ -0,0 +1,203 @@
1
+ import { z } from 'zod';
2
+
3
+ interface ValidationIssue {
4
+ path: string;
5
+ message: string;
6
+ code: "invalid_type" | "missing_required" | "invalid_value" | "invalid_date" | "duplicate_id" | "circular_dependency";
7
+ }
8
+ interface ValidationResult {
9
+ valid: boolean;
10
+ errors: ValidationIssue[];
11
+ }
12
+ declare const featureEntryJsonSchema: {
13
+ readonly type: "object";
14
+ readonly required: readonly ["id", "label", "releasedAt", "showNewUntil"];
15
+ readonly properties: {
16
+ readonly id: {
17
+ readonly type: "string";
18
+ };
19
+ readonly label: {
20
+ readonly type: "string";
21
+ };
22
+ readonly description: {
23
+ readonly type: "string";
24
+ };
25
+ readonly releasedAt: {
26
+ readonly type: "string";
27
+ readonly format: "date-time";
28
+ };
29
+ readonly showNewUntil: {
30
+ readonly type: "string";
31
+ readonly format: "date-time";
32
+ };
33
+ readonly type: {
34
+ readonly enum: readonly ["feature", "improvement", "fix", "breaking"];
35
+ };
36
+ readonly priority: {
37
+ readonly enum: readonly ["critical", "normal", "low"];
38
+ };
39
+ };
40
+ };
41
+ declare const featureManifestJsonSchema: {
42
+ readonly type: "array";
43
+ readonly items: {
44
+ readonly type: "object";
45
+ readonly required: readonly ["id", "label", "releasedAt", "showNewUntil"];
46
+ readonly properties: {
47
+ readonly id: {
48
+ readonly type: "string";
49
+ };
50
+ readonly label: {
51
+ readonly type: "string";
52
+ };
53
+ readonly description: {
54
+ readonly type: "string";
55
+ };
56
+ readonly releasedAt: {
57
+ readonly type: "string";
58
+ readonly format: "date-time";
59
+ };
60
+ readonly showNewUntil: {
61
+ readonly type: "string";
62
+ readonly format: "date-time";
63
+ };
64
+ readonly type: {
65
+ readonly enum: readonly ["feature", "improvement", "fix", "breaking"];
66
+ };
67
+ readonly priority: {
68
+ readonly enum: readonly ["critical", "normal", "low"];
69
+ };
70
+ };
71
+ };
72
+ };
73
+ declare const featureEntrySchema: z.ZodObject<{
74
+ id: z.ZodString;
75
+ label: z.ZodString;
76
+ releasedAt: z.ZodEffects<z.ZodString, string, string>;
77
+ showNewUntil: z.ZodEffects<z.ZodString, string, string>;
78
+ description: z.ZodOptional<z.ZodString>;
79
+ type: z.ZodOptional<z.ZodEnum<["feature", "improvement", "fix", "breaking"]>>;
80
+ priority: z.ZodOptional<z.ZodEnum<["critical", "normal", "low"]>>;
81
+ dependsOn: z.ZodOptional<z.ZodObject<{
82
+ seen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
83
+ clicked: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
84
+ dismissed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
85
+ }, "strip", z.ZodTypeAny, {
86
+ seen?: string[] | undefined;
87
+ clicked?: string[] | undefined;
88
+ dismissed?: string[] | undefined;
89
+ }, {
90
+ seen?: string[] | undefined;
91
+ clicked?: string[] | undefined;
92
+ dismissed?: string[] | undefined;
93
+ }>>;
94
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
95
+ id: z.ZodString;
96
+ label: z.ZodString;
97
+ releasedAt: z.ZodEffects<z.ZodString, string, string>;
98
+ showNewUntil: z.ZodEffects<z.ZodString, string, string>;
99
+ description: z.ZodOptional<z.ZodString>;
100
+ type: z.ZodOptional<z.ZodEnum<["feature", "improvement", "fix", "breaking"]>>;
101
+ priority: z.ZodOptional<z.ZodEnum<["critical", "normal", "low"]>>;
102
+ dependsOn: z.ZodOptional<z.ZodObject<{
103
+ seen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
104
+ clicked: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
105
+ dismissed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
106
+ }, "strip", z.ZodTypeAny, {
107
+ seen?: string[] | undefined;
108
+ clicked?: string[] | undefined;
109
+ dismissed?: string[] | undefined;
110
+ }, {
111
+ seen?: string[] | undefined;
112
+ clicked?: string[] | undefined;
113
+ dismissed?: string[] | undefined;
114
+ }>>;
115
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
116
+ id: z.ZodString;
117
+ label: z.ZodString;
118
+ releasedAt: z.ZodEffects<z.ZodString, string, string>;
119
+ showNewUntil: z.ZodEffects<z.ZodString, string, string>;
120
+ description: z.ZodOptional<z.ZodString>;
121
+ type: z.ZodOptional<z.ZodEnum<["feature", "improvement", "fix", "breaking"]>>;
122
+ priority: z.ZodOptional<z.ZodEnum<["critical", "normal", "low"]>>;
123
+ dependsOn: z.ZodOptional<z.ZodObject<{
124
+ seen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
125
+ clicked: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
126
+ dismissed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
127
+ }, "strip", z.ZodTypeAny, {
128
+ seen?: string[] | undefined;
129
+ clicked?: string[] | undefined;
130
+ dismissed?: string[] | undefined;
131
+ }, {
132
+ seen?: string[] | undefined;
133
+ clicked?: string[] | undefined;
134
+ dismissed?: string[] | undefined;
135
+ }>>;
136
+ }, z.ZodTypeAny, "passthrough">>;
137
+ declare const featureManifestSchema: z.ZodArray<z.ZodObject<{
138
+ id: z.ZodString;
139
+ label: z.ZodString;
140
+ releasedAt: z.ZodEffects<z.ZodString, string, string>;
141
+ showNewUntil: z.ZodEffects<z.ZodString, string, string>;
142
+ description: z.ZodOptional<z.ZodString>;
143
+ type: z.ZodOptional<z.ZodEnum<["feature", "improvement", "fix", "breaking"]>>;
144
+ priority: z.ZodOptional<z.ZodEnum<["critical", "normal", "low"]>>;
145
+ dependsOn: z.ZodOptional<z.ZodObject<{
146
+ seen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
147
+ clicked: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
148
+ dismissed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
149
+ }, "strip", z.ZodTypeAny, {
150
+ seen?: string[] | undefined;
151
+ clicked?: string[] | undefined;
152
+ dismissed?: string[] | undefined;
153
+ }, {
154
+ seen?: string[] | undefined;
155
+ clicked?: string[] | undefined;
156
+ dismissed?: string[] | undefined;
157
+ }>>;
158
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
159
+ id: z.ZodString;
160
+ label: z.ZodString;
161
+ releasedAt: z.ZodEffects<z.ZodString, string, string>;
162
+ showNewUntil: z.ZodEffects<z.ZodString, string, string>;
163
+ description: z.ZodOptional<z.ZodString>;
164
+ type: z.ZodOptional<z.ZodEnum<["feature", "improvement", "fix", "breaking"]>>;
165
+ priority: z.ZodOptional<z.ZodEnum<["critical", "normal", "low"]>>;
166
+ dependsOn: z.ZodOptional<z.ZodObject<{
167
+ seen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
168
+ clicked: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
169
+ dismissed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
170
+ }, "strip", z.ZodTypeAny, {
171
+ seen?: string[] | undefined;
172
+ clicked?: string[] | undefined;
173
+ dismissed?: string[] | undefined;
174
+ }, {
175
+ seen?: string[] | undefined;
176
+ clicked?: string[] | undefined;
177
+ dismissed?: string[] | undefined;
178
+ }>>;
179
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
180
+ id: z.ZodString;
181
+ label: z.ZodString;
182
+ releasedAt: z.ZodEffects<z.ZodString, string, string>;
183
+ showNewUntil: z.ZodEffects<z.ZodString, string, string>;
184
+ description: z.ZodOptional<z.ZodString>;
185
+ type: z.ZodOptional<z.ZodEnum<["feature", "improvement", "fix", "breaking"]>>;
186
+ priority: z.ZodOptional<z.ZodEnum<["critical", "normal", "low"]>>;
187
+ dependsOn: z.ZodOptional<z.ZodObject<{
188
+ seen: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
189
+ clicked: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
190
+ dismissed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
191
+ }, "strip", z.ZodTypeAny, {
192
+ seen?: string[] | undefined;
193
+ clicked?: string[] | undefined;
194
+ dismissed?: string[] | undefined;
195
+ }, {
196
+ seen?: string[] | undefined;
197
+ clicked?: string[] | undefined;
198
+ dismissed?: string[] | undefined;
199
+ }>>;
200
+ }, z.ZodTypeAny, "passthrough">>, "many">;
201
+ declare function validateManifest(data: unknown): ValidationResult;
202
+
203
+ export { type ValidationIssue, type ValidationResult, featureEntryJsonSchema, featureEntrySchema, featureManifestJsonSchema, featureManifestSchema, validateManifest };