@cascivo/registry 0.1.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.
- package/LICENSE +21 -0
- package/README.md +19 -0
- package/dist/index.d.mts +99 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +273 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +51 -0
- package/readme.body.md +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 urbanisierung
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<!-- generated by scripts/readme/generate.ts — edit readme.body.md, not this file -->
|
|
2
|
+
|
|
3
|
+
# @cascivo/registry
|
|
4
|
+
|
|
5
|
+
> Registry schema v2 types, validation, and static build for the cascade ecosystem
|
|
6
|
+
|
|
7
|
+
[cascivo.com](https://cascivo.com) · [Docs](https://docs.cascivo.com) · [Storybook](https://storybook.cascivo.com) · [GitHub](https://github.com/urbanisierung/cascivo)
|
|
8
|
+
|
|
9
|
+
Registry client and type definitions — reads `registry.json` and validates component entries. Used internally by the CLI and MCP server.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
pnpm add @cascivo/registry
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
[cascivo.com](https://cascivo.com) · [Docs](https://docs.cascivo.com) · [Storybook](https://storybook.cascivo.com) · [GitHub](https://github.com/urbanisierung/cascivo) · AI agents: use [`@cascivo/mcp`](https://github.com/urbanisierung/cascivo/tree/main/packages/mcp) and [`registry.json`](https://github.com/urbanisierung/cascivo/blob/main/registry.json) · MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
//#region src/types.d.ts
|
|
2
|
+
interface RegistryFile {
|
|
3
|
+
url: string;
|
|
4
|
+
target?: string;
|
|
5
|
+
}
|
|
6
|
+
type RegistryItemType = 'component' | 'layout' | 'block' | 'chart' | 'section' | 'theme' | 'style';
|
|
7
|
+
interface RegistryAdvisory {
|
|
8
|
+
id: string;
|
|
9
|
+
severity: 'low' | 'moderate' | 'high' | 'critical';
|
|
10
|
+
affectedVersions: string;
|
|
11
|
+
fixedIn?: string;
|
|
12
|
+
summary: string;
|
|
13
|
+
refs?: string[];
|
|
14
|
+
}
|
|
15
|
+
interface RegistryItem {
|
|
16
|
+
schemaVersion: 2;
|
|
17
|
+
name: string;
|
|
18
|
+
type: RegistryItemType;
|
|
19
|
+
description: string;
|
|
20
|
+
category?: string;
|
|
21
|
+
version: string;
|
|
22
|
+
changelog?: {
|
|
23
|
+
version: string;
|
|
24
|
+
note: string;
|
|
25
|
+
}[];
|
|
26
|
+
author?: string;
|
|
27
|
+
license?: string;
|
|
28
|
+
homepage?: string;
|
|
29
|
+
files: RegistryFile[];
|
|
30
|
+
install?: string;
|
|
31
|
+
dependencies: string[];
|
|
32
|
+
registryDependencies?: string[];
|
|
33
|
+
tags: string[];
|
|
34
|
+
meta?: unknown;
|
|
35
|
+
advisories?: RegistryAdvisory[];
|
|
36
|
+
}
|
|
37
|
+
interface RegistryIndex {
|
|
38
|
+
schemaVersion: 2;
|
|
39
|
+
name: string;
|
|
40
|
+
homepage?: string;
|
|
41
|
+
items: RegistryItem[];
|
|
42
|
+
}
|
|
43
|
+
interface LegacyRegistryEntry {
|
|
44
|
+
name: string;
|
|
45
|
+
type: string;
|
|
46
|
+
description: string;
|
|
47
|
+
category: string;
|
|
48
|
+
version: string;
|
|
49
|
+
files: string[];
|
|
50
|
+
install?: string;
|
|
51
|
+
dependencies: string[];
|
|
52
|
+
tags: string[];
|
|
53
|
+
meta?: unknown;
|
|
54
|
+
}
|
|
55
|
+
interface LegacyRegistry {
|
|
56
|
+
version: string;
|
|
57
|
+
generatedAt: string;
|
|
58
|
+
components: LegacyRegistryEntry[];
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/validate.d.ts
|
|
62
|
+
interface ValidationResult {
|
|
63
|
+
ok: boolean;
|
|
64
|
+
errors: string[];
|
|
65
|
+
warnings: string[];
|
|
66
|
+
}
|
|
67
|
+
declare function validateItem(raw: unknown): ValidationResult;
|
|
68
|
+
declare function validateIndex(raw: unknown): ValidationResult;
|
|
69
|
+
declare function parseLegacyRegistry(raw: unknown): RegistryIndex;
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/build.d.ts
|
|
72
|
+
declare function buildRegistry(index: RegistryIndex, outDir: string): Promise<void>;
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/advisories.d.ts
|
|
75
|
+
declare function matchAdvisories(item: Pick<RegistryItem, 'advisories'>, lockedVersion: string): RegistryAdvisory[];
|
|
76
|
+
//#endregion
|
|
77
|
+
//#region src/directory.d.ts
|
|
78
|
+
interface DirectoryEntry {
|
|
79
|
+
namespace: string;
|
|
80
|
+
name: string;
|
|
81
|
+
description: string;
|
|
82
|
+
homepage: string;
|
|
83
|
+
registryUrl: string;
|
|
84
|
+
tags: string[];
|
|
85
|
+
verified: boolean;
|
|
86
|
+
}
|
|
87
|
+
interface RegistryDirectory {
|
|
88
|
+
schemaVersion: 1;
|
|
89
|
+
registries: DirectoryEntry[];
|
|
90
|
+
}
|
|
91
|
+
interface DirectoryValidationResult {
|
|
92
|
+
ok: boolean;
|
|
93
|
+
errors: string[];
|
|
94
|
+
warnings: string[];
|
|
95
|
+
}
|
|
96
|
+
declare function validateDirectory(raw: unknown): DirectoryValidationResult;
|
|
97
|
+
//#endregion
|
|
98
|
+
export { type DirectoryEntry, type DirectoryValidationResult, type LegacyRegistry, type LegacyRegistryEntry, type RegistryAdvisory, type RegistryDirectory, type RegistryFile, type RegistryIndex, type RegistryItem, type RegistryItemType, type ValidationResult, buildRegistry, matchAdvisories, parseLegacyRegistry, validateDirectory, validateIndex, validateItem };
|
|
99
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/validate.ts","../src/build.ts","../src/advisories.ts","../src/directory.ts"],"mappings":";UAAiB,YAAA;EACf,GAAA;EACA,MAAM;AAAA;AAAA,KAGI,gBAAA;AAAA,UASK,gBAAA;EACf,EAAA;EACA,QAAA;EACA,gBAAA;EACA,OAAA;EACA,OAAA;EACA,IAAA;AAAA;AAAA,UAGe,YAAA;EACf,aAAA;EACA,IAAA;EACA,IAAA,EAAM,gBAAA;EACN,WAAA;EACA,QAAA;EACA,OAAA;EACA,SAAA;IAAc,OAAA;IAAiB,IAAA;EAAA;EAC/B,MAAA;EACA,OAAA;EACA,QAAA;EACA,KAAA,EAAO,YAAA;EACP,OAAA;EACA,YAAA;EACA,oBAAA;EACA,IAAA;EACA,IAAA;EACA,UAAA,GAAa,gBAAA;AAAA;AAAA,UAGE,aAAA;EACf,aAAA;EACA,IAAA;EACA,QAAA;EACA,KAAA,EAAO,YAAY;AAAA;AAAA,UAGJ,mBAAA;EACf,IAAA;EACA,IAAA;EACA,WAAA;EACA,QAAA;EACA,OAAA;EACA,KAAA;EACA,OAAA;EACA,YAAA;EACA,IAAA;EACA,IAAA;AAAA;AAAA,UAGe,cAAA;EACf,OAAA;EACA,WAAA;EACA,UAAA,EAAY,mBAAmB;AAAA;;;UChEhB,gBAAA;EACf,EAAA;EACA,MAAA;EACA,QAAA;AAAA;AAAA,iBAcc,YAAA,CAAa,GAAA,YAAe,gBAAgB;AAAA,iBAsF5C,aAAA,CAAc,GAAA,YAAe,gBAAgB;AAAA,iBAkC7C,mBAAA,CAAoB,GAAA,YAAe,aAAa;;;iBC5H1C,aAAA,CAAc,KAAA,EAAO,aAAA,EAAe,MAAA,WAAiB,OAAO;;;iBC4ClE,eAAA,CACd,IAAA,EAAM,IAAA,CAAK,YAAA,iBACX,aAAA,WACC,gBAAA;;;UC9Dc,cAAA;EACf,SAAA;EACA,IAAA;EACA,WAAA;EACA,QAAA;EACA,WAAA;EACA,IAAA;EACA,QAAA;AAAA;AAAA,UAGe,iBAAA;EACf,aAAA;EACA,UAAA,EAAY,cAAc;AAAA;AAAA,UAGX,yBAAA;EACf,EAAA;EACA,MAAA;EACA,QAAA;AAAA;AAAA,iBAoBc,iBAAA,CAAkB,GAAA,YAAe,yBAAyB"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
//#region src/validate.ts
|
|
4
|
+
const VALID_TYPES = new Set([
|
|
5
|
+
"component",
|
|
6
|
+
"layout",
|
|
7
|
+
"block",
|
|
8
|
+
"chart",
|
|
9
|
+
"section",
|
|
10
|
+
"theme",
|
|
11
|
+
"style"
|
|
12
|
+
]);
|
|
13
|
+
const VALID_SEVERITIES = new Set([
|
|
14
|
+
"low",
|
|
15
|
+
"moderate",
|
|
16
|
+
"high",
|
|
17
|
+
"critical"
|
|
18
|
+
]);
|
|
19
|
+
function ok(warnings = []) {
|
|
20
|
+
return {
|
|
21
|
+
ok: true,
|
|
22
|
+
errors: [],
|
|
23
|
+
warnings
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function fail(errors, warnings = []) {
|
|
27
|
+
return {
|
|
28
|
+
ok: false,
|
|
29
|
+
errors,
|
|
30
|
+
warnings
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function validateItem(raw) {
|
|
34
|
+
if (!raw || typeof raw !== "object") return fail(["Item must be an object"]);
|
|
35
|
+
const obj = raw;
|
|
36
|
+
const errors = [];
|
|
37
|
+
const warnings = [];
|
|
38
|
+
if (obj["schemaVersion"] !== 2) errors.push(`schemaVersion must be 2, got ${JSON.stringify(obj["schemaVersion"])}`);
|
|
39
|
+
if (typeof obj["name"] !== "string" || !obj["name"]) errors.push("name is required and must be a non-empty string");
|
|
40
|
+
if (!VALID_TYPES.has(obj["type"])) errors.push(`type must be one of ${[...VALID_TYPES].join("|")}, got ${JSON.stringify(obj["type"])}`);
|
|
41
|
+
if (typeof obj["description"] !== "string") errors.push("description is required and must be a string");
|
|
42
|
+
if (typeof obj["version"] !== "string" || !obj["version"]) errors.push("version is required and must be a non-empty string");
|
|
43
|
+
if (!Array.isArray(obj["files"])) errors.push("files is required and must be an array");
|
|
44
|
+
if (!Array.isArray(obj["dependencies"])) errors.push("dependencies is required and must be an array");
|
|
45
|
+
if (!Array.isArray(obj["tags"])) errors.push("tags is required and must be an array");
|
|
46
|
+
if (obj["advisories"] !== void 0) if (!Array.isArray(obj["advisories"])) errors.push("advisories must be an array");
|
|
47
|
+
else {
|
|
48
|
+
const ids = /* @__PURE__ */ new Set();
|
|
49
|
+
for (const adv of obj["advisories"]) {
|
|
50
|
+
if (!adv || typeof adv !== "object") {
|
|
51
|
+
errors.push("each advisory must be an object");
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const a = adv;
|
|
55
|
+
if (typeof a["id"] !== "string") errors.push("advisory.id must be a string");
|
|
56
|
+
else if (ids.has(a["id"])) errors.push(`advisory id "${a["id"]}" is not unique`);
|
|
57
|
+
else ids.add(a["id"]);
|
|
58
|
+
if (!VALID_SEVERITIES.has(a["severity"])) errors.push(`advisory.severity must be one of ${[...VALID_SEVERITIES].join("|")}`);
|
|
59
|
+
if (typeof a["affectedVersions"] !== "string") errors.push("advisory.affectedVersions must be a string");
|
|
60
|
+
if (typeof a["summary"] !== "string") errors.push("advisory.summary must be a string");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const knownKeys = new Set([
|
|
64
|
+
"schemaVersion",
|
|
65
|
+
"name",
|
|
66
|
+
"type",
|
|
67
|
+
"description",
|
|
68
|
+
"category",
|
|
69
|
+
"version",
|
|
70
|
+
"changelog",
|
|
71
|
+
"author",
|
|
72
|
+
"license",
|
|
73
|
+
"homepage",
|
|
74
|
+
"files",
|
|
75
|
+
"install",
|
|
76
|
+
"dependencies",
|
|
77
|
+
"registryDependencies",
|
|
78
|
+
"tags",
|
|
79
|
+
"meta",
|
|
80
|
+
"advisories"
|
|
81
|
+
]);
|
|
82
|
+
for (const key of Object.keys(obj)) if (!knownKeys.has(key)) warnings.push(`Unknown field "${key}" — ignored (forward compat)`);
|
|
83
|
+
return errors.length > 0 ? fail(errors, warnings) : ok(warnings);
|
|
84
|
+
}
|
|
85
|
+
function validateIndex(raw) {
|
|
86
|
+
if (!raw || typeof raw !== "object") return fail(["Index must be an object"]);
|
|
87
|
+
const obj = raw;
|
|
88
|
+
const errors = [];
|
|
89
|
+
const warnings = [];
|
|
90
|
+
if (obj["schemaVersion"] !== 2) errors.push(`schemaVersion must be 2, got ${JSON.stringify(obj["schemaVersion"])}`);
|
|
91
|
+
if (typeof obj["name"] !== "string" || !obj["name"]) errors.push("name is required and must be a non-empty string");
|
|
92
|
+
if (!Array.isArray(obj["items"])) errors.push("items is required and must be an array");
|
|
93
|
+
else for (let i = 0; i < obj["items"].length; i++) {
|
|
94
|
+
const itemResult = validateItem(obj["items"][i]);
|
|
95
|
+
for (const e of itemResult.errors) errors.push(`items[${i}]: ${e}`);
|
|
96
|
+
for (const w of itemResult.warnings) warnings.push(`items[${i}]: ${w}`);
|
|
97
|
+
}
|
|
98
|
+
const knownKeys = new Set([
|
|
99
|
+
"schemaVersion",
|
|
100
|
+
"name",
|
|
101
|
+
"homepage",
|
|
102
|
+
"items"
|
|
103
|
+
]);
|
|
104
|
+
for (const key of Object.keys(obj)) if (!knownKeys.has(key)) warnings.push(`Unknown field "${key}" — ignored (forward compat)`);
|
|
105
|
+
return errors.length > 0 ? fail(errors, warnings) : ok(warnings);
|
|
106
|
+
}
|
|
107
|
+
function parseLegacyRegistry(raw) {
|
|
108
|
+
if (!raw || typeof raw !== "object") throw new Error("Legacy registry must be an object");
|
|
109
|
+
const obj = raw;
|
|
110
|
+
const topVersion = typeof obj["version"] === "string" ? obj["version"] : "0.0.0";
|
|
111
|
+
return {
|
|
112
|
+
schemaVersion: 2,
|
|
113
|
+
name: "cascivo",
|
|
114
|
+
items: (Array.isArray(obj["components"]) ? obj["components"] : []).map((c) => {
|
|
115
|
+
const item = {
|
|
116
|
+
schemaVersion: 2,
|
|
117
|
+
name: typeof c["name"] === "string" ? c["name"] : "",
|
|
118
|
+
type: c["type"] ?? "component",
|
|
119
|
+
description: typeof c["description"] === "string" ? c["description"] : "",
|
|
120
|
+
version: topVersion,
|
|
121
|
+
files: Array.isArray(c["files"]) ? c["files"].map((url) => ({ url })) : [],
|
|
122
|
+
dependencies: Array.isArray(c["dependencies"]) ? c["dependencies"] : [],
|
|
123
|
+
tags: Array.isArray(c["tags"]) ? c["tags"] : []
|
|
124
|
+
};
|
|
125
|
+
if (typeof c["category"] === "string") item.category = c["category"];
|
|
126
|
+
if (typeof c["install"] === "string") item.install = c["install"];
|
|
127
|
+
if (c["meta"]) item.meta = c["meta"];
|
|
128
|
+
return item;
|
|
129
|
+
})
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/build.ts
|
|
134
|
+
function flatName(name) {
|
|
135
|
+
return name.replace(/\//g, "-");
|
|
136
|
+
}
|
|
137
|
+
function itemWithoutExamples(item) {
|
|
138
|
+
if (!item.meta || typeof item.meta !== "object") return item;
|
|
139
|
+
const meta = item.meta;
|
|
140
|
+
if (!Array.isArray(meta["examples"]) || meta["examples"].length === 0) return item;
|
|
141
|
+
return {
|
|
142
|
+
...item,
|
|
143
|
+
meta: {
|
|
144
|
+
...meta,
|
|
145
|
+
examples: []
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
async function buildRegistry(index, outDir) {
|
|
150
|
+
await mkdir(outDir, { recursive: true });
|
|
151
|
+
const sortedItems = [...index.items].sort((a, b) => a.name.localeCompare(b.name));
|
|
152
|
+
const indexOut = {
|
|
153
|
+
schemaVersion: 2,
|
|
154
|
+
name: index.name,
|
|
155
|
+
...index.homepage ? { homepage: index.homepage } : {},
|
|
156
|
+
items: sortedItems.map(itemWithoutExamples)
|
|
157
|
+
};
|
|
158
|
+
await writeFile(join(outDir, "registry.json"), `${JSON.stringify(indexOut, null, 2)}\n`, "utf8");
|
|
159
|
+
for (const item of sortedItems) {
|
|
160
|
+
const flat = flatName(item.name);
|
|
161
|
+
await writeFile(join(outDir, `${flat}.json`), `${JSON.stringify(item, null, 2)}\n`, "utf8");
|
|
162
|
+
await writeFile(join(outDir, `${flat}@${item.version}.json`), `${JSON.stringify(item, null, 2)}\n`, "utf8");
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/advisories.ts
|
|
167
|
+
function parseVersionParts(v) {
|
|
168
|
+
return v.replace(/^[^0-9]*/, "").split(".").map(Number);
|
|
169
|
+
}
|
|
170
|
+
function compareVersions(a, b) {
|
|
171
|
+
const pa = parseVersionParts(a);
|
|
172
|
+
const pb = parseVersionParts(b);
|
|
173
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
174
|
+
const na = pa[i] ?? 0;
|
|
175
|
+
const nb = pb[i] ?? 0;
|
|
176
|
+
if (na !== nb) return na - nb;
|
|
177
|
+
}
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
180
|
+
function matchesRange(version, range) {
|
|
181
|
+
try {
|
|
182
|
+
const trimmed = range.trim();
|
|
183
|
+
if (trimmed.startsWith(">=")) return compareVersions(version, trimmed.slice(2).trim()) >= 0;
|
|
184
|
+
if (trimmed.startsWith(">")) return compareVersions(version, trimmed.slice(1).trim()) > 0;
|
|
185
|
+
if (trimmed.startsWith("<=")) return compareVersions(version, trimmed.slice(2).trim()) <= 0;
|
|
186
|
+
if (trimmed.startsWith("<")) return compareVersions(version, trimmed.slice(1).trim()) < 0;
|
|
187
|
+
if (trimmed.startsWith("^")) {
|
|
188
|
+
const base = trimmed.slice(1).trim();
|
|
189
|
+
const major = parseVersionParts(base)[0] ?? 0;
|
|
190
|
+
return (parseVersionParts(version)[0] ?? 0) === major && compareVersions(version, base) >= 0;
|
|
191
|
+
}
|
|
192
|
+
if (trimmed.startsWith("~")) {
|
|
193
|
+
const base = trimmed.slice(1).trim();
|
|
194
|
+
const baseParts = parseVersionParts(base);
|
|
195
|
+
const major = baseParts[0] ?? 0;
|
|
196
|
+
const minor = baseParts[1] ?? 0;
|
|
197
|
+
const vParts = parseVersionParts(version);
|
|
198
|
+
const vMajor = vParts[0] ?? 0;
|
|
199
|
+
const vMinor = vParts[1] ?? 0;
|
|
200
|
+
return vMajor === major && vMinor === minor && compareVersions(version, base) >= 0;
|
|
201
|
+
}
|
|
202
|
+
return version === trimmed;
|
|
203
|
+
} catch {
|
|
204
|
+
return false;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function matchAdvisories(item, lockedVersion) {
|
|
208
|
+
if (!item.advisories) return [];
|
|
209
|
+
const matched = [];
|
|
210
|
+
for (const adv of item.advisories) try {
|
|
211
|
+
if (matchesRange(lockedVersion, adv.affectedVersions)) matched.push(adv);
|
|
212
|
+
} catch {}
|
|
213
|
+
return matched;
|
|
214
|
+
}
|
|
215
|
+
//#endregion
|
|
216
|
+
//#region src/directory.ts
|
|
217
|
+
function levenshtein(a, b) {
|
|
218
|
+
const m = a.length;
|
|
219
|
+
const n = b.length;
|
|
220
|
+
const dp = Array.from({ length: m + 1 }, (_, i) => Array.from({ length: n + 1 }, (_, j) => i === 0 ? j : j === 0 ? i : 0));
|
|
221
|
+
for (let i = 1; i <= m; i++) for (let j = 1; j <= n; j++) dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
222
|
+
return dp[m][n];
|
|
223
|
+
}
|
|
224
|
+
function validateDirectory(raw) {
|
|
225
|
+
if (!raw || typeof raw !== "object") return {
|
|
226
|
+
ok: false,
|
|
227
|
+
errors: ["Directory must be an object"],
|
|
228
|
+
warnings: []
|
|
229
|
+
};
|
|
230
|
+
const obj = raw;
|
|
231
|
+
const errors = [];
|
|
232
|
+
const warnings = [];
|
|
233
|
+
if (obj["schemaVersion"] !== 1) errors.push(`schemaVersion must be 1, got ${JSON.stringify(obj["schemaVersion"])}`);
|
|
234
|
+
if (!Array.isArray(obj["registries"])) {
|
|
235
|
+
errors.push("registries must be an array");
|
|
236
|
+
return {
|
|
237
|
+
ok: false,
|
|
238
|
+
errors,
|
|
239
|
+
warnings
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
const namespaces = [];
|
|
243
|
+
for (let i = 0; i < obj["registries"].length; i++) {
|
|
244
|
+
const entry = obj["registries"][i];
|
|
245
|
+
const ns = entry["namespace"];
|
|
246
|
+
if (typeof ns !== "string" || !ns) errors.push(`registries[${i}].namespace is required`);
|
|
247
|
+
else {
|
|
248
|
+
if (namespaces.includes(ns)) errors.push(`Duplicate namespace "${ns}" at index ${i}`);
|
|
249
|
+
namespaces.push(ns);
|
|
250
|
+
}
|
|
251
|
+
if (typeof entry["name"] !== "string") errors.push(`registries[${i}].name is required`);
|
|
252
|
+
if (typeof entry["description"] !== "string") errors.push(`registries[${i}].description is required`);
|
|
253
|
+
if (typeof entry["homepage"] !== "string") errors.push(`registries[${i}].homepage is required`);
|
|
254
|
+
if (typeof entry["registryUrl"] !== "string") errors.push(`registries[${i}].registryUrl is required`);
|
|
255
|
+
else if (!entry["registryUrl"].includes("{name}")) errors.push(`registries[${i}].registryUrl must contain {name} placeholder`);
|
|
256
|
+
if (!Array.isArray(entry["tags"])) errors.push(`registries[${i}].tags must be an array`);
|
|
257
|
+
if (typeof entry["verified"] !== "boolean") errors.push(`registries[${i}].verified must be a boolean`);
|
|
258
|
+
}
|
|
259
|
+
for (let i = 0; i < namespaces.length; i++) for (let j = i + 1; j < namespaces.length; j++) {
|
|
260
|
+
const a = namespaces[i];
|
|
261
|
+
const b = namespaces[j];
|
|
262
|
+
if (levenshtein(a, b) <= 2) warnings.push(`Namespaces "${a}" and "${b}" are suspiciously similar (Levenshtein distance ≤ 2)`);
|
|
263
|
+
}
|
|
264
|
+
return {
|
|
265
|
+
ok: errors.length === 0,
|
|
266
|
+
errors,
|
|
267
|
+
warnings
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
//#endregion
|
|
271
|
+
export { buildRegistry, matchAdvisories, parseLegacyRegistry, validateDirectory, validateIndex, validateItem };
|
|
272
|
+
|
|
273
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/validate.ts","../src/build.ts","../src/advisories.ts","../src/directory.ts"],"sourcesContent":["import type { RegistryIndex, RegistryItem } from './types.ts'\n\nexport interface ValidationResult {\n ok: boolean\n errors: string[]\n warnings: string[]\n}\n\nconst VALID_TYPES = new Set(['component', 'layout', 'block', 'chart', 'section', 'theme', 'style'])\nconst VALID_SEVERITIES = new Set(['low', 'moderate', 'high', 'critical'])\n\nfunction ok(warnings: string[] = []): ValidationResult {\n return { ok: true, errors: [], warnings }\n}\n\nfunction fail(errors: string[], warnings: string[] = []): ValidationResult {\n return { ok: false, errors, warnings }\n}\n\nexport function validateItem(raw: unknown): ValidationResult {\n if (!raw || typeof raw !== 'object') {\n return fail(['Item must be an object'])\n }\n const obj = raw as Record<string, unknown>\n const errors: string[] = []\n const warnings: string[] = []\n\n if (obj['schemaVersion'] !== 2) {\n errors.push(`schemaVersion must be 2, got ${JSON.stringify(obj['schemaVersion'])}`)\n }\n if (typeof obj['name'] !== 'string' || !obj['name']) {\n errors.push('name is required and must be a non-empty string')\n }\n if (!VALID_TYPES.has(obj['type'] as string)) {\n errors.push(\n `type must be one of ${[...VALID_TYPES].join('|')}, got ${JSON.stringify(obj['type'])}`,\n )\n }\n if (typeof obj['description'] !== 'string') {\n errors.push('description is required and must be a string')\n }\n if (typeof obj['version'] !== 'string' || !obj['version']) {\n errors.push('version is required and must be a non-empty string')\n }\n if (!Array.isArray(obj['files'])) {\n errors.push('files is required and must be an array')\n }\n if (!Array.isArray(obj['dependencies'])) {\n errors.push('dependencies is required and must be an array')\n }\n if (!Array.isArray(obj['tags'])) {\n errors.push('tags is required and must be an array')\n }\n\n if (obj['advisories'] !== undefined) {\n if (!Array.isArray(obj['advisories'])) {\n errors.push('advisories must be an array')\n } else {\n const ids = new Set<string>()\n for (const adv of obj['advisories'] as unknown[]) {\n if (!adv || typeof adv !== 'object') {\n errors.push('each advisory must be an object')\n continue\n }\n const a = adv as Record<string, unknown>\n if (typeof a['id'] !== 'string') errors.push('advisory.id must be a string')\n else if (ids.has(a['id'] as string)) errors.push(`advisory id \"${a['id']}\" is not unique`)\n else ids.add(a['id'] as string)\n if (!VALID_SEVERITIES.has(a['severity'] as string))\n errors.push(`advisory.severity must be one of ${[...VALID_SEVERITIES].join('|')}`)\n if (typeof a['affectedVersions'] !== 'string')\n errors.push('advisory.affectedVersions must be a string')\n if (typeof a['summary'] !== 'string') errors.push('advisory.summary must be a string')\n }\n }\n }\n\n const knownKeys = new Set([\n 'schemaVersion',\n 'name',\n 'type',\n 'description',\n 'category',\n 'version',\n 'changelog',\n 'author',\n 'license',\n 'homepage',\n 'files',\n 'install',\n 'dependencies',\n 'registryDependencies',\n 'tags',\n 'meta',\n 'advisories',\n ])\n for (const key of Object.keys(obj)) {\n if (!knownKeys.has(key)) {\n warnings.push(`Unknown field \"${key}\" — ignored (forward compat)`)\n }\n }\n\n return errors.length > 0 ? fail(errors, warnings) : ok(warnings)\n}\n\nexport function validateIndex(raw: unknown): ValidationResult {\n if (!raw || typeof raw !== 'object') {\n return fail(['Index must be an object'])\n }\n const obj = raw as Record<string, unknown>\n const errors: string[] = []\n const warnings: string[] = []\n\n if (obj['schemaVersion'] !== 2) {\n errors.push(`schemaVersion must be 2, got ${JSON.stringify(obj['schemaVersion'])}`)\n }\n if (typeof obj['name'] !== 'string' || !obj['name']) {\n errors.push('name is required and must be a non-empty string')\n }\n if (!Array.isArray(obj['items'])) {\n errors.push('items is required and must be an array')\n } else {\n for (let i = 0; i < obj['items'].length; i++) {\n const itemResult = validateItem(obj['items'][i])\n for (const e of itemResult.errors) errors.push(`items[${i}]: ${e}`)\n for (const w of itemResult.warnings) warnings.push(`items[${i}]: ${w}`)\n }\n }\n\n const knownKeys = new Set(['schemaVersion', 'name', 'homepage', 'items'])\n for (const key of Object.keys(obj)) {\n if (!knownKeys.has(key)) {\n warnings.push(`Unknown field \"${key}\" — ignored (forward compat)`)\n }\n }\n\n return errors.length > 0 ? fail(errors, warnings) : ok(warnings)\n}\n\nexport function parseLegacyRegistry(raw: unknown): RegistryIndex {\n if (!raw || typeof raw !== 'object') throw new Error('Legacy registry must be an object')\n const obj = raw as Record<string, unknown>\n const topVersion = typeof obj['version'] === 'string' ? obj['version'] : '0.0.0'\n const components = Array.isArray(obj['components']) ? obj['components'] : []\n\n return {\n schemaVersion: 2,\n name: 'cascivo',\n items: (components as Record<string, unknown>[]).map((c) => {\n const item: RegistryItem = {\n schemaVersion: 2,\n name: typeof c['name'] === 'string' ? c['name'] : '',\n type: (c['type'] as RegistryItem['type']) ?? 'component',\n description: typeof c['description'] === 'string' ? c['description'] : '',\n version: topVersion,\n files: Array.isArray(c['files']) ? (c['files'] as string[]).map((url) => ({ url })) : [],\n dependencies: Array.isArray(c['dependencies']) ? (c['dependencies'] as string[]) : [],\n tags: Array.isArray(c['tags']) ? (c['tags'] as string[]) : [],\n }\n if (typeof c['category'] === 'string') item.category = c['category']\n if (typeof c['install'] === 'string') item.install = c['install']\n if (c['meta']) item.meta = c['meta'] as RegistryItem['meta']\n return item\n }),\n }\n}\n","import { mkdir, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { RegistryIndex, RegistryItem } from './types.ts'\n\nfunction flatName(name: string): string {\n return name.replace(/\\//g, '-')\n}\n\nfunction itemWithoutExamples(item: RegistryItem): RegistryItem {\n if (!item.meta || typeof item.meta !== 'object') return item\n const meta = item.meta as Record<string, unknown>\n if (!Array.isArray(meta['examples']) || meta['examples'].length === 0) return item\n return { ...item, meta: { ...meta, examples: [] } }\n}\n\nexport async function buildRegistry(index: RegistryIndex, outDir: string): Promise<void> {\n await mkdir(outDir, { recursive: true })\n\n const sortedItems = [...index.items].sort((a, b) => a.name.localeCompare(b.name))\n\n const indexOut: RegistryIndex = {\n schemaVersion: 2,\n name: index.name,\n ...(index.homepage ? { homepage: index.homepage } : {}),\n items: sortedItems.map(itemWithoutExamples),\n }\n await writeFile(join(outDir, 'registry.json'), `${JSON.stringify(indexOut, null, 2)}\\n`, 'utf8')\n\n for (const item of sortedItems) {\n const flat = flatName(item.name)\n await writeFile(join(outDir, `${flat}.json`), `${JSON.stringify(item, null, 2)}\\n`, 'utf8')\n await writeFile(\n join(outDir, `${flat}@${item.version}.json`),\n `${JSON.stringify(item, null, 2)}\\n`,\n 'utf8',\n )\n }\n}\n","import type { RegistryAdvisory, RegistryItem } from './types.ts'\n\nfunction parseVersionParts(v: string): number[] {\n return v\n .replace(/^[^0-9]*/, '')\n .split('.')\n .map(Number)\n}\n\nfunction compareVersions(a: string, b: string): number {\n const pa = parseVersionParts(a)\n const pb = parseVersionParts(b)\n for (let i = 0; i < Math.max(pa.length, pb.length); i++) {\n const na = pa[i] ?? 0\n const nb = pb[i] ?? 0\n if (na !== nb) return na - nb\n }\n return 0\n}\n\nfunction matchesRange(version: string, range: string): boolean {\n try {\n const trimmed = range.trim()\n if (trimmed.startsWith('>=')) {\n return compareVersions(version, trimmed.slice(2).trim()) >= 0\n }\n if (trimmed.startsWith('>')) {\n return compareVersions(version, trimmed.slice(1).trim()) > 0\n }\n if (trimmed.startsWith('<=')) {\n return compareVersions(version, trimmed.slice(2).trim()) <= 0\n }\n if (trimmed.startsWith('<')) {\n return compareVersions(version, trimmed.slice(1).trim()) < 0\n }\n if (trimmed.startsWith('^')) {\n const base = trimmed.slice(1).trim()\n const baseParts = parseVersionParts(base)\n const major = baseParts[0] ?? 0\n const vParts = parseVersionParts(version)\n const vMajor = vParts[0] ?? 0\n return vMajor === major && compareVersions(version, base) >= 0\n }\n if (trimmed.startsWith('~')) {\n const base = trimmed.slice(1).trim()\n const baseParts = parseVersionParts(base)\n const major = baseParts[0] ?? 0\n const minor = baseParts[1] ?? 0\n const vParts = parseVersionParts(version)\n const vMajor = vParts[0] ?? 0\n const vMinor = vParts[1] ?? 0\n return vMajor === major && vMinor === minor && compareVersions(version, base) >= 0\n }\n return version === trimmed\n } catch {\n return false\n }\n}\n\nexport function matchAdvisories(\n item: Pick<RegistryItem, 'advisories'>,\n lockedVersion: string,\n): RegistryAdvisory[] {\n if (!item.advisories) return []\n const matched: RegistryAdvisory[] = []\n for (const adv of item.advisories) {\n try {\n if (matchesRange(lockedVersion, adv.affectedVersions)) {\n matched.push(adv)\n }\n } catch {\n // malformed range — skip silently, never crash an audit\n }\n }\n return matched\n}\n","export interface DirectoryEntry {\n namespace: string\n name: string\n description: string\n homepage: string\n registryUrl: string\n tags: string[]\n verified: boolean\n}\n\nexport interface RegistryDirectory {\n schemaVersion: 1\n registries: DirectoryEntry[]\n}\n\nexport interface DirectoryValidationResult {\n ok: boolean\n errors: string[]\n warnings: string[]\n}\n\nfunction levenshtein(a: string, b: string): number {\n const m = a.length\n const n = b.length\n const dp: number[][] = Array.from({ length: m + 1 }, (_, i) =>\n Array.from({ length: n + 1 }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)),\n )\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n dp[i]![j] =\n a[i - 1] === b[j - 1]\n ? dp[i - 1]![j - 1]!\n : 1 + Math.min(dp[i - 1]![j]!, dp[i]![j - 1]!, dp[i - 1]![j - 1]!)\n }\n }\n return dp[m]![n]!\n}\n\nexport function validateDirectory(raw: unknown): DirectoryValidationResult {\n if (!raw || typeof raw !== 'object') {\n return { ok: false, errors: ['Directory must be an object'], warnings: [] }\n }\n const obj = raw as Record<string, unknown>\n const errors: string[] = []\n const warnings: string[] = []\n\n if (obj['schemaVersion'] !== 1) {\n errors.push(`schemaVersion must be 1, got ${JSON.stringify(obj['schemaVersion'])}`)\n }\n if (!Array.isArray(obj['registries'])) {\n errors.push('registries must be an array')\n return { ok: false, errors, warnings }\n }\n\n const namespaces: string[] = []\n for (let i = 0; i < obj['registries'].length; i++) {\n const entry = obj['registries'][i] as Record<string, unknown>\n const ns = entry['namespace']\n if (typeof ns !== 'string' || !ns) errors.push(`registries[${i}].namespace is required`)\n else {\n if (namespaces.includes(ns)) errors.push(`Duplicate namespace \"${ns}\" at index ${i}`)\n namespaces.push(ns)\n }\n if (typeof entry['name'] !== 'string') errors.push(`registries[${i}].name is required`)\n if (typeof entry['description'] !== 'string')\n errors.push(`registries[${i}].description is required`)\n if (typeof entry['homepage'] !== 'string') errors.push(`registries[${i}].homepage is required`)\n if (typeof entry['registryUrl'] !== 'string')\n errors.push(`registries[${i}].registryUrl is required`)\n else if (!(entry['registryUrl'] as string).includes('{name}'))\n errors.push(`registries[${i}].registryUrl must contain {name} placeholder`)\n if (!Array.isArray(entry['tags'])) errors.push(`registries[${i}].tags must be an array`)\n if (typeof entry['verified'] !== 'boolean')\n errors.push(`registries[${i}].verified must be a boolean`)\n }\n\n for (let i = 0; i < namespaces.length; i++) {\n for (let j = i + 1; j < namespaces.length; j++) {\n const a = namespaces[i]!\n const b = namespaces[j]!\n if (levenshtein(a, b) <= 2) {\n warnings.push(\n `Namespaces \"${a}\" and \"${b}\" are suspiciously similar (Levenshtein distance ≤ 2)`,\n )\n }\n }\n }\n\n return { ok: errors.length === 0, errors, warnings }\n}\n"],"mappings":";;;AAQA,MAAM,cAAc,IAAI,IAAI;CAAC;CAAa;CAAU;CAAS;CAAS;CAAW;CAAS;AAAO,CAAC;AAClG,MAAM,mBAAmB,IAAI,IAAI;CAAC;CAAO;CAAY;CAAQ;AAAU,CAAC;AAExE,SAAS,GAAG,WAAqB,CAAC,GAAqB;CACrD,OAAO;EAAE,IAAI;EAAM,QAAQ,CAAC;EAAG;CAAS;AAC1C;AAEA,SAAS,KAAK,QAAkB,WAAqB,CAAC,GAAqB;CACzE,OAAO;EAAE,IAAI;EAAO;EAAQ;CAAS;AACvC;AAEA,SAAgB,aAAa,KAAgC;CAC3D,IAAI,CAAC,OAAO,OAAO,QAAQ,UACzB,OAAO,KAAK,CAAC,wBAAwB,CAAC;CAExC,MAAM,MAAM;CACZ,MAAM,SAAmB,CAAC;CAC1B,MAAM,WAAqB,CAAC;CAE5B,IAAI,IAAI,qBAAqB,GAC3B,OAAO,KAAK,gCAAgC,KAAK,UAAU,IAAI,gBAAgB,GAAG;CAEpF,IAAI,OAAO,IAAI,YAAY,YAAY,CAAC,IAAI,SAC1C,OAAO,KAAK,iDAAiD;CAE/D,IAAI,CAAC,YAAY,IAAI,IAAI,OAAiB,GACxC,OAAO,KACL,uBAAuB,CAAC,GAAG,WAAW,EAAE,KAAK,GAAG,EAAE,QAAQ,KAAK,UAAU,IAAI,OAAO,GACtF;CAEF,IAAI,OAAO,IAAI,mBAAmB,UAChC,OAAO,KAAK,8CAA8C;CAE5D,IAAI,OAAO,IAAI,eAAe,YAAY,CAAC,IAAI,YAC7C,OAAO,KAAK,oDAAoD;CAElE,IAAI,CAAC,MAAM,QAAQ,IAAI,QAAQ,GAC7B,OAAO,KAAK,wCAAwC;CAEtD,IAAI,CAAC,MAAM,QAAQ,IAAI,eAAe,GACpC,OAAO,KAAK,+CAA+C;CAE7D,IAAI,CAAC,MAAM,QAAQ,IAAI,OAAO,GAC5B,OAAO,KAAK,uCAAuC;CAGrD,IAAI,IAAI,kBAAkB,KAAA,GACxB,IAAI,CAAC,MAAM,QAAQ,IAAI,aAAa,GAClC,OAAO,KAAK,6BAA6B;MACpC;EACL,MAAM,sBAAM,IAAI,IAAY;EAC5B,KAAK,MAAM,OAAO,IAAI,eAA4B;GAChD,IAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;IACnC,OAAO,KAAK,iCAAiC;IAC7C;GACF;GACA,MAAM,IAAI;GACV,IAAI,OAAO,EAAE,UAAU,UAAU,OAAO,KAAK,8BAA8B;QACtE,IAAI,IAAI,IAAI,EAAE,KAAe,GAAG,OAAO,KAAK,gBAAgB,EAAE,MAAM,gBAAgB;QACpF,IAAI,IAAI,EAAE,KAAe;GAC9B,IAAI,CAAC,iBAAiB,IAAI,EAAE,WAAqB,GAC/C,OAAO,KAAK,oCAAoC,CAAC,GAAG,gBAAgB,EAAE,KAAK,GAAG,GAAG;GACnF,IAAI,OAAO,EAAE,wBAAwB,UACnC,OAAO,KAAK,4CAA4C;GAC1D,IAAI,OAAO,EAAE,eAAe,UAAU,OAAO,KAAK,mCAAmC;EACvF;CACF;CAGF,MAAM,YAAY,IAAI,IAAI;EACxB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CACD,KAAK,MAAM,OAAO,OAAO,KAAK,GAAG,GAC/B,IAAI,CAAC,UAAU,IAAI,GAAG,GACpB,SAAS,KAAK,kBAAkB,IAAI,6BAA6B;CAIrE,OAAO,OAAO,SAAS,IAAI,KAAK,QAAQ,QAAQ,IAAI,GAAG,QAAQ;AACjE;AAEA,SAAgB,cAAc,KAAgC;CAC5D,IAAI,CAAC,OAAO,OAAO,QAAQ,UACzB,OAAO,KAAK,CAAC,yBAAyB,CAAC;CAEzC,MAAM,MAAM;CACZ,MAAM,SAAmB,CAAC;CAC1B,MAAM,WAAqB,CAAC;CAE5B,IAAI,IAAI,qBAAqB,GAC3B,OAAO,KAAK,gCAAgC,KAAK,UAAU,IAAI,gBAAgB,GAAG;CAEpF,IAAI,OAAO,IAAI,YAAY,YAAY,CAAC,IAAI,SAC1C,OAAO,KAAK,iDAAiD;CAE/D,IAAI,CAAC,MAAM,QAAQ,IAAI,QAAQ,GAC7B,OAAO,KAAK,wCAAwC;MAEpD,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,SAAS,QAAQ,KAAK;EAC5C,MAAM,aAAa,aAAa,IAAI,SAAS,EAAE;EAC/C,KAAK,MAAM,KAAK,WAAW,QAAQ,OAAO,KAAK,SAAS,EAAE,KAAK,GAAG;EAClE,KAAK,MAAM,KAAK,WAAW,UAAU,SAAS,KAAK,SAAS,EAAE,KAAK,GAAG;CACxE;CAGF,MAAM,YAAY,IAAI,IAAI;EAAC;EAAiB;EAAQ;EAAY;CAAO,CAAC;CACxE,KAAK,MAAM,OAAO,OAAO,KAAK,GAAG,GAC/B,IAAI,CAAC,UAAU,IAAI,GAAG,GACpB,SAAS,KAAK,kBAAkB,IAAI,6BAA6B;CAIrE,OAAO,OAAO,SAAS,IAAI,KAAK,QAAQ,QAAQ,IAAI,GAAG,QAAQ;AACjE;AAEA,SAAgB,oBAAoB,KAA6B;CAC/D,IAAI,CAAC,OAAO,OAAO,QAAQ,UAAU,MAAM,IAAI,MAAM,mCAAmC;CACxF,MAAM,MAAM;CACZ,MAAM,aAAa,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa;CAGzE,OAAO;EACL,eAAe;EACf,MAAM;EACN,QALiB,MAAM,QAAQ,IAAI,aAAa,IAAI,IAAI,gBAAgB,CAAC,GAKxB,KAAK,MAAM;GAC1D,MAAM,OAAqB;IACzB,eAAe;IACf,MAAM,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;IAClD,MAAO,EAAE,WAAoC;IAC7C,aAAa,OAAO,EAAE,mBAAmB,WAAW,EAAE,iBAAiB;IACvE,SAAS;IACT,OAAO,MAAM,QAAQ,EAAE,QAAQ,IAAK,EAAE,SAAsB,KAAK,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC;IACvF,cAAc,MAAM,QAAQ,EAAE,eAAe,IAAK,EAAE,kBAA+B,CAAC;IACpF,MAAM,MAAM,QAAQ,EAAE,OAAO,IAAK,EAAE,UAAuB,CAAC;GAC9D;GACA,IAAI,OAAO,EAAE,gBAAgB,UAAU,KAAK,WAAW,EAAE;GACzD,IAAI,OAAO,EAAE,eAAe,UAAU,KAAK,UAAU,EAAE;GACvD,IAAI,EAAE,SAAS,KAAK,OAAO,EAAE;GAC7B,OAAO;EACT,CAAC;CACH;AACF;;;ACjKA,SAAS,SAAS,MAAsB;CACtC,OAAO,KAAK,QAAQ,OAAO,GAAG;AAChC;AAEA,SAAS,oBAAoB,MAAkC;CAC7D,IAAI,CAAC,KAAK,QAAQ,OAAO,KAAK,SAAS,UAAU,OAAO;CACxD,MAAM,OAAO,KAAK;CAClB,IAAI,CAAC,MAAM,QAAQ,KAAK,WAAW,KAAK,KAAK,YAAY,WAAW,GAAG,OAAO;CAC9E,OAAO;EAAE,GAAG;EAAM,MAAM;GAAE,GAAG;GAAM,UAAU,CAAC;EAAE;CAAE;AACpD;AAEA,eAAsB,cAAc,OAAsB,QAA+B;CACvF,MAAM,MAAM,QAAQ,EAAE,WAAW,KAAK,CAAC;CAEvC,MAAM,cAAc,CAAC,GAAG,MAAM,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;CAEhF,MAAM,WAA0B;EAC9B,eAAe;EACf,MAAM,MAAM;EACZ,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;EACrD,OAAO,YAAY,IAAI,mBAAmB;CAC5C;CACA,MAAM,UAAU,KAAK,QAAQ,eAAe,GAAG,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE,KAAK,MAAM;CAE/F,KAAK,MAAM,QAAQ,aAAa;EAC9B,MAAM,OAAO,SAAS,KAAK,IAAI;EAC/B,MAAM,UAAU,KAAK,QAAQ,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,UAAU,MAAM,MAAM,CAAC,EAAE,KAAK,MAAM;EAC1F,MAAM,UACJ,KAAK,QAAQ,GAAG,KAAK,GAAG,KAAK,QAAQ,MAAM,GAC3C,GAAG,KAAK,UAAU,MAAM,MAAM,CAAC,EAAE,KACjC,MACF;CACF;AACF;;;ACnCA,SAAS,kBAAkB,GAAqB;CAC9C,OAAO,EACJ,QAAQ,YAAY,EAAE,EACtB,MAAM,GAAG,EACT,IAAI,MAAM;AACf;AAEA,SAAS,gBAAgB,GAAW,GAAmB;CACrD,MAAM,KAAK,kBAAkB,CAAC;CAC9B,MAAM,KAAK,kBAAkB,CAAC;CAC9B,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK;EACvD,MAAM,KAAK,GAAG,MAAM;EACpB,MAAM,KAAK,GAAG,MAAM;EACpB,IAAI,OAAO,IAAI,OAAO,KAAK;CAC7B;CACA,OAAO;AACT;AAEA,SAAS,aAAa,SAAiB,OAAwB;CAC7D,IAAI;EACF,MAAM,UAAU,MAAM,KAAK;EAC3B,IAAI,QAAQ,WAAW,IAAI,GACzB,OAAO,gBAAgB,SAAS,QAAQ,MAAM,CAAC,EAAE,KAAK,CAAC,KAAK;EAE9D,IAAI,QAAQ,WAAW,GAAG,GACxB,OAAO,gBAAgB,SAAS,QAAQ,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI;EAE7D,IAAI,QAAQ,WAAW,IAAI,GACzB,OAAO,gBAAgB,SAAS,QAAQ,MAAM,CAAC,EAAE,KAAK,CAAC,KAAK;EAE9D,IAAI,QAAQ,WAAW,GAAG,GACxB,OAAO,gBAAgB,SAAS,QAAQ,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI;EAE7D,IAAI,QAAQ,WAAW,GAAG,GAAG;GAC3B,MAAM,OAAO,QAAQ,MAAM,CAAC,EAAE,KAAK;GAEnC,MAAM,QADY,kBAAkB,IACd,EAAE,MAAM;GAG9B,QAFe,kBAAkB,OACb,EAAE,MAAM,OACV,SAAS,gBAAgB,SAAS,IAAI,KAAK;EAC/D;EACA,IAAI,QAAQ,WAAW,GAAG,GAAG;GAC3B,MAAM,OAAO,QAAQ,MAAM,CAAC,EAAE,KAAK;GACnC,MAAM,YAAY,kBAAkB,IAAI;GACxC,MAAM,QAAQ,UAAU,MAAM;GAC9B,MAAM,QAAQ,UAAU,MAAM;GAC9B,MAAM,SAAS,kBAAkB,OAAO;GACxC,MAAM,SAAS,OAAO,MAAM;GAC5B,MAAM,SAAS,OAAO,MAAM;GAC5B,OAAO,WAAW,SAAS,WAAW,SAAS,gBAAgB,SAAS,IAAI,KAAK;EACnF;EACA,OAAO,YAAY;CACrB,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAgB,gBACd,MACA,eACoB;CACpB,IAAI,CAAC,KAAK,YAAY,OAAO,CAAC;CAC9B,MAAM,UAA8B,CAAC;CACrC,KAAK,MAAM,OAAO,KAAK,YACrB,IAAI;EACF,IAAI,aAAa,eAAe,IAAI,gBAAgB,GAClD,QAAQ,KAAK,GAAG;CAEpB,QAAQ,CAER;CAEF,OAAO;AACT;;;ACtDA,SAAS,YAAY,GAAW,GAAmB;CACjD,MAAM,IAAI,EAAE;CACZ,MAAM,IAAI,EAAE;CACZ,MAAM,KAAiB,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,IAAI,GAAG,MACvD,MAAM,KAAK,EAAE,QAAQ,IAAI,EAAE,IAAI,GAAG,MAAO,MAAM,IAAI,IAAI,MAAM,IAAI,IAAI,CAAE,CACzE;CACA,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KACtB,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KACtB,GAAG,GAAI,KACL,EAAE,IAAI,OAAO,EAAE,IAAI,KACf,GAAG,IAAI,GAAI,IAAI,KACf,IAAI,KAAK,IAAI,GAAG,IAAI,GAAI,IAAK,GAAG,GAAI,IAAI,IAAK,GAAG,IAAI,GAAI,IAAI,EAAG;CAGzE,OAAO,GAAG,GAAI;AAChB;AAEA,SAAgB,kBAAkB,KAAyC;CACzE,IAAI,CAAC,OAAO,OAAO,QAAQ,UACzB,OAAO;EAAE,IAAI;EAAO,QAAQ,CAAC,6BAA6B;EAAG,UAAU,CAAC;CAAE;CAE5E,MAAM,MAAM;CACZ,MAAM,SAAmB,CAAC;CAC1B,MAAM,WAAqB,CAAC;CAE5B,IAAI,IAAI,qBAAqB,GAC3B,OAAO,KAAK,gCAAgC,KAAK,UAAU,IAAI,gBAAgB,GAAG;CAEpF,IAAI,CAAC,MAAM,QAAQ,IAAI,aAAa,GAAG;EACrC,OAAO,KAAK,6BAA6B;EACzC,OAAO;GAAE,IAAI;GAAO;GAAQ;EAAS;CACvC;CAEA,MAAM,aAAuB,CAAC;CAC9B,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,cAAc,QAAQ,KAAK;EACjD,MAAM,QAAQ,IAAI,cAAc;EAChC,MAAM,KAAK,MAAM;EACjB,IAAI,OAAO,OAAO,YAAY,CAAC,IAAI,OAAO,KAAK,cAAc,EAAE,wBAAwB;OAClF;GACH,IAAI,WAAW,SAAS,EAAE,GAAG,OAAO,KAAK,wBAAwB,GAAG,aAAa,GAAG;GACpF,WAAW,KAAK,EAAE;EACpB;EACA,IAAI,OAAO,MAAM,YAAY,UAAU,OAAO,KAAK,cAAc,EAAE,mBAAmB;EACtF,IAAI,OAAO,MAAM,mBAAmB,UAClC,OAAO,KAAK,cAAc,EAAE,0BAA0B;EACxD,IAAI,OAAO,MAAM,gBAAgB,UAAU,OAAO,KAAK,cAAc,EAAE,uBAAuB;EAC9F,IAAI,OAAO,MAAM,mBAAmB,UAClC,OAAO,KAAK,cAAc,EAAE,0BAA0B;OACnD,IAAI,CAAE,MAAM,eAA0B,SAAS,QAAQ,GAC1D,OAAO,KAAK,cAAc,EAAE,8CAA8C;EAC5E,IAAI,CAAC,MAAM,QAAQ,MAAM,OAAO,GAAG,OAAO,KAAK,cAAc,EAAE,wBAAwB;EACvF,IAAI,OAAO,MAAM,gBAAgB,WAC/B,OAAO,KAAK,cAAc,EAAE,6BAA6B;CAC7D;CAEA,KAAK,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KACrC,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;EAC9C,MAAM,IAAI,WAAW;EACrB,MAAM,IAAI,WAAW;EACrB,IAAI,YAAY,GAAG,CAAC,KAAK,GACvB,SAAS,KACP,eAAe,EAAE,SAAS,EAAE,sDAC9B;CAEJ;CAGF,OAAO;EAAE,IAAI,OAAO,WAAW;EAAG;EAAQ;CAAS;AACrD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cascivo/registry",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Registry schema v2 types, validation, and static build for the cascade ecosystem",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"cascivo",
|
|
8
|
+
"components",
|
|
9
|
+
"css",
|
|
10
|
+
"design-system",
|
|
11
|
+
"react",
|
|
12
|
+
"registry",
|
|
13
|
+
"signals"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/urbanisierung/cascivo/tree/main/packages/registry#readme",
|
|
16
|
+
"bugs": "https://github.com/urbanisierung/cascivo/issues",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"author": "urbanisierung",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/urbanisierung/cascivo.git",
|
|
22
|
+
"directory": "packages/registry"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist"
|
|
26
|
+
],
|
|
27
|
+
"type": "module",
|
|
28
|
+
"types": "./dist/index.d.mts",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"import": "./dist/index.mjs",
|
|
32
|
+
"types": "./dist/index.d.mts",
|
|
33
|
+
"default": "./dist/index.mjs"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public",
|
|
38
|
+
"provenance": true
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/node": "^25",
|
|
42
|
+
"typescript": "^5",
|
|
43
|
+
"vite-plus": "^0.1.24"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "vp pack",
|
|
47
|
+
"check": "tsc --noEmit",
|
|
48
|
+
"test": "vp test",
|
|
49
|
+
"dev": "vp pack --watch"
|
|
50
|
+
}
|
|
51
|
+
}
|
package/readme.body.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Registry client and type definitions — reads `registry.json` and validates component entries. Used internally by the CLI and MCP server.
|