@component-compass/plugin-core 0.0.0-pr-3-8916f3c-20260507145532

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.
@@ -0,0 +1,27 @@
1
+ import type { ManifestComponent, ManifestFile, ManifestSource } from "./types.js";
2
+ type BuilderOpts = {
3
+ source: ManifestSource;
4
+ package: string;
5
+ };
6
+ type AddInput = (Omit<Extract<ManifestComponent, {
7
+ kind: "custom-element";
8
+ }>, "deprecated"> & {
9
+ deprecated?: boolean | string;
10
+ }) | (Omit<Extract<ManifestComponent, {
11
+ kind: "react-component";
12
+ }>, "deprecated"> & {
13
+ deprecated?: boolean | string;
14
+ }) | (Omit<Extract<ManifestComponent, {
15
+ kind: "vue-component";
16
+ }>, "deprecated"> & {
17
+ deprecated?: boolean | string;
18
+ });
19
+ export declare class ManifestBuilder {
20
+ private readonly source;
21
+ private readonly packageName;
22
+ private readonly components;
23
+ constructor(opts: BuilderOpts);
24
+ addComponent(c: AddInput): this;
25
+ build(): ManifestFile;
26
+ }
27
+ export {};
@@ -0,0 +1,49 @@
1
+ import { compareComponentId } from "./id.js";
2
+ import { validateManifest } from "./validate.js";
3
+ const SCHEMA_VERSION = "2.0.0";
4
+ const expectedKindFor = {
5
+ cem: "custom-element",
6
+ react: "react-component",
7
+ vue: "vue-component",
8
+ };
9
+ export class ManifestBuilder {
10
+ source;
11
+ packageName;
12
+ components = [];
13
+ constructor(opts) {
14
+ this.source = opts.source;
15
+ this.packageName = opts.package;
16
+ }
17
+ addComponent(c) {
18
+ const expected = expectedKindFor[this.source];
19
+ if (c.kind !== expected) {
20
+ throw new Error(`Component kind "${c.kind}" does not match builder source "${this.source}" (expected kind "${expected}")`);
21
+ }
22
+ this.components.push({ deprecated: false, ...c });
23
+ return this;
24
+ }
25
+ build() {
26
+ const sorted = [...this.components].sort(compareComponents);
27
+ const out = {
28
+ schemaVersion: SCHEMA_VERSION,
29
+ source: this.source,
30
+ package: this.packageName,
31
+ components: sorted,
32
+ };
33
+ const result = validateManifest(out);
34
+ if (!result.ok) {
35
+ throw new Error(`Built manifest fails validation:\n${result.errors.join("\n")}`);
36
+ }
37
+ return out;
38
+ }
39
+ }
40
+ function compareComponents(a, b) {
41
+ return compareComponentId(toId(a), toId(b));
42
+ }
43
+ function toId(c) {
44
+ if (c.kind === "custom-element") {
45
+ return { kind: "custom-element", tagName: c.tagName, source: c.source };
46
+ }
47
+ return { kind: c.kind, export: c.export, source: c.source };
48
+ }
49
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,cAAc,GAAG,OAAO,CAAC;AAE/B,MAAM,eAAe,GAAsD;IACzE,GAAG,EAAE,gBAAgB;IACrB,KAAK,EAAE,iBAAiB;IACxB,GAAG,EAAE,eAAe;CACrB,CAAC;AASF,MAAM,OAAO,eAAe;IACT,MAAM,CAAiB;IACvB,WAAW,CAAS;IACpB,UAAU,GAAwB,EAAE,CAAC;IAEtD,YAAY,IAAiB;QAC3B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC;IAClC,CAAC;IAED,YAAY,CAAC,CAAW;QACtB,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,mBAAmB,CAAC,CAAC,IAAI,oCAAoC,IAAI,CAAC,MAAM,qBAAqB,QAAQ,IAAI,CAC1G,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,CAAC,EAAuB,CAAC,CAAC;QACvE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK;QACH,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAiB;YACxB,aAAa,EAAE,cAAc;YAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,WAAW;YACzB,UAAU,EAAE,MAAM;SACnB,CAAC;QACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,qCAAqC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnF,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AAED,SAAS,iBAAiB,CAAC,CAAoB,EAAE,CAAoB;IACnE,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,IAAI,CAAC,CAAoB;IAChC,IAAI,CAAC,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QAChC,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAC1E,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAC9D,CAAC"}
package/dist/id.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { ComponentId, ComponentSource } from "./types.js";
2
+ export declare function externalPackageOf(source: ComponentSource): string;
3
+ export declare function serialiseComponentId(id: ComponentId): string;
4
+ export declare function compareComponentId(a: ComponentId, b: ComponentId): number;
package/dist/id.js ADDED
@@ -0,0 +1,31 @@
1
+ export function externalPackageOf(source) {
2
+ if (source.type === "external")
3
+ return source.package;
4
+ throw new Error(`externalPackageOf called with non-external source (type=${source.type}). Caller must narrow before invoking, or use a different accessor.`);
5
+ }
6
+ function sourceSegment(source) {
7
+ switch (source.type) {
8
+ case "external":
9
+ return `external:${source.package}`;
10
+ case "local":
11
+ return `local:${source.filePath}`;
12
+ case "unknown":
13
+ return "unknown";
14
+ }
15
+ }
16
+ function identityPayload(id) {
17
+ switch (id.kind) {
18
+ case "custom-element":
19
+ return id.tagName;
20
+ case "react-component":
21
+ case "vue-component":
22
+ return id.export;
23
+ }
24
+ }
25
+ export function serialiseComponentId(id) {
26
+ return `${id.kind}:${sourceSegment(id.source)}::${identityPayload(id)}`;
27
+ }
28
+ export function compareComponentId(a, b) {
29
+ return serialiseComponentId(a).localeCompare(serialiseComponentId(b));
30
+ }
31
+ //# sourceMappingURL=id.js.map
package/dist/id.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.js","sourceRoot":"","sources":["../src/id.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,iBAAiB,CAAC,MAAuB;IACvD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC;IACtD,MAAM,IAAI,KAAK,CACb,2DAA2D,MAAM,CAAC,IAAI,qEAAqE,CAC5I,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,MAAuB;IAC5C,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,UAAU;YACb,OAAO,YAAY,MAAM,CAAC,OAAO,EAAE,CAAC;QACtC,KAAK,OAAO;YACV,OAAO,SAAS,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpC,KAAK,SAAS;YACZ,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,EAAe;IACtC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;QAChB,KAAK,gBAAgB;YACnB,OAAO,EAAE,CAAC,OAAO,CAAC;QACpB,KAAK,iBAAiB,CAAC;QACvB,KAAK,eAAe;YAClB,OAAO,EAAE,CAAC,MAAM,CAAC;IACrB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,EAAe;IAClD,OAAO,GAAG,EAAE,CAAC,IAAI,IAAI,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,CAAc,EAAE,CAAc;IAC/D,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC"}
@@ -0,0 +1,9 @@
1
+ export type { ComponentId, ComponentKind, ComponentSource, Lifecycle, ManifestComponent, ManifestEvent, ManifestFile, ManifestProp, ManifestSlot, ManifestSource, } from "./types.js";
2
+ export { serialiseComponentId, compareComponentId, externalPackageOf } from "./id.js";
3
+ export { validateManifest } from "./validate.js";
4
+ export type { ValidationResult } from "./validate.js";
5
+ export { manifestJsonSchema } from "./schema.js";
6
+ export { ManifestBuilder } from "./builder.js";
7
+ export type { TagName, WrapperId, ImportRole, ImportEntry, IndexedComponent, ComponentIndex, Loc, WarningCode, Warning, ScanConfig, PropUsage, OccurrenceVia, Occurrence, WrapperDef, FileImport, ParseResult, ParseContext, ParserPlugin, ScanEnvelope, ScanOutput, ManifestRef, ScanStats, DetectorId, LocalDefinition, LocalDefinitionIndex, } from "./scan-types.js";
8
+ export { asTagName, asWrapperId, emptyLocalIndex } from "./scan-types.js";
9
+ export * from "./output-types.js";
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { serialiseComponentId, compareComponentId, externalPackageOf } from "./id.js";
2
+ export { validateManifest } from "./validate.js";
3
+ export { manifestJsonSchema } from "./schema.js";
4
+ export { ManifestBuilder } from "./builder.js";
5
+ export { asTagName, asWrapperId, emptyLocalIndex } from "./scan-types.js";
6
+ export * from "./output-types.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAa/C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE1E,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Types describing the CLI's emitted JSON artifact (two-grain: components +
3
+ * occurrences). Lives in plugin-core so consumers (cli, future analytics,
4
+ * agents) share one source of truth without depending on cli internals.
5
+ */
6
+ import type { OccurrenceVia } from "./via-types.js";
7
+ export type ComponentScope = "ds" | "external" | "local";
8
+ export type ComponentKindOutput = "custom-element" | "react-component" | "vue-component";
9
+ export type ViaKindOutput = "html-tag" | "lit-template" | "react-wrapper" | "direct-import" | "vue-template";
10
+ export type OutputIdentity = {
11
+ scope: ComponentScope;
12
+ kind: ComponentKindOutput;
13
+ /** Present for ds + external; absent for local. */
14
+ packageName?: string;
15
+ /** For react-component / vue-component. */
16
+ exportName?: string;
17
+ /** For custom-element. */
18
+ tagName?: string;
19
+ via: {
20
+ kind: ViaKindOutput;
21
+ };
22
+ /** Present for local; absent for ds/external. */
23
+ repoId?: string;
24
+ /** Present for local; absent for ds/external. Repo-relative path of the defining file. */
25
+ filePath?: string;
26
+ };
27
+ export type OutputManifest = {
28
+ lifecycle?: {
29
+ status: "stable" | "deprecated";
30
+ supersededBy?: {
31
+ packageName: string;
32
+ exportName: string;
33
+ };
34
+ };
35
+ props?: Record<string, {
36
+ default?: string | number | boolean | null;
37
+ }>;
38
+ };
39
+ export type DynamicKind = "spread" | "expr" | "identifier";
40
+ /**
41
+ * Per-occurrence prop value:
42
+ * - a literal (string/number/boolean/null) when the source value is statically known,
43
+ * - a `{ __dynamic }` marker when the value is a non-literal expression,
44
+ * - or absent (key omitted from the map) when the prop was not set on the occurrence.
45
+ */
46
+ export type PropValueState = string | number | boolean | null | {
47
+ __dynamic: DynamicKind;
48
+ };
49
+ export type PropDistribution = {
50
+ /** Stringified literal value -> occurrence count. */
51
+ distribution: Record<string, number>;
52
+ dynamic: number;
53
+ omitted: number;
54
+ defaultApplied: number;
55
+ };
56
+ export type OutputComponent = {
57
+ id: string;
58
+ identity: OutputIdentity;
59
+ derivedTags: string[];
60
+ manifest: OutputManifest | null;
61
+ stats: {
62
+ occurrenceCount: number;
63
+ fileCount: number;
64
+ };
65
+ props: Record<string, PropDistribution>;
66
+ };
67
+ export type OutputOccurrence = {
68
+ componentId: string;
69
+ filePath: string;
70
+ line: number;
71
+ column: number;
72
+ via: OccurrenceVia;
73
+ props: Record<string, PropValueState>;
74
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=output-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-types.js","sourceRoot":"","sources":["../src/output-types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Shared types consumed by all parser packages and the CLI host.
3
+ *
4
+ * Parsers (`parser-react`, `parser-vue`, `parser-lit`, `parser-html`) cannot
5
+ * depend on the CLI package (circular), so every type that crosses the
6
+ * parser ↔ CLI boundary lives here in `plugin-core`.
7
+ */
8
+ import type { OutputComponent, OutputOccurrence } from "./output-types.js";
9
+ import type { ComponentId, ManifestComponent, ManifestSource } from "./types.js";
10
+ import type { OccurrenceVia } from "./via-types.js";
11
+ declare const __brand: unique symbol;
12
+ type Brand<K, T> = K & {
13
+ readonly [__brand]: T;
14
+ };
15
+ export type TagName = Brand<string, "TagName">;
16
+ export type WrapperId = Brand<string, "WrapperId">;
17
+ /** Unsafe constructors — use only at the data-ingest boundary. */
18
+ export declare const asTagName: (s: string) => TagName;
19
+ export declare const asWrapperId: (s: string) => WrapperId;
20
+ export type ImportRole = "native" | "react";
21
+ export type ImportEntry = {
22
+ specifier: string;
23
+ export?: string;
24
+ };
25
+ export type IndexedComponent = (Extract<ManifestComponent, {
26
+ kind: "custom-element";
27
+ }> & {
28
+ className?: string;
29
+ imports: Partial<Record<ImportRole, ImportEntry[]>>;
30
+ }) | Extract<ManifestComponent, {
31
+ kind: "react-component" | "vue-component";
32
+ }>;
33
+ export type ComponentIndex = {
34
+ /** key = serialiseComponentId(id) */
35
+ byId: Map<string, IndexedComponent>;
36
+ /** custom-element only, keyed by tagName */
37
+ byTag: Map<string, Extract<IndexedComponent, {
38
+ kind: "custom-element";
39
+ }>>;
40
+ /** key = `${specifier}::${export}` — covers WC react-wrappers AND direct react/vue imports */
41
+ byImport: Map<string, IndexedComponent>;
42
+ /** key = native specifier (WC bare imports for side-effect registration) */
43
+ byNativeSpecifier: Map<string, Extract<IndexedComponent, {
44
+ kind: "custom-element";
45
+ }>>;
46
+ /** Local-component definitions discovered in repo source. */
47
+ local: LocalDefinitionIndex;
48
+ };
49
+ export type DetectorId = "react-default-fn" | "react-arrow" | "react-class" | "react-forward-ref" | "react-memo" | "vue-sfc" | "vue-define-component" | "vue-functional" | "wc-decorator" | "wc-customelements-define";
50
+ export type LocalDefinition = {
51
+ /** componentId.source is always { type: "local", filePath }. */
52
+ componentId: ComponentId;
53
+ /**
54
+ * Local export identifier. For default exports, this is the declaration
55
+ * name (e.g. "Button" for `export default function Button()`); use
56
+ * `isDefault` to distinguish default from named-with-same-name.
57
+ */
58
+ exportName: string;
59
+ /** True when emitted via `export default`. */
60
+ isDefault: boolean;
61
+ detector: DetectorId;
62
+ };
63
+ export type LocalDefinitionIndex = {
64
+ /** POSIX repo-relative filePath → definitions in that file. */
65
+ byPath: Map<string, LocalDefinition[]>;
66
+ /** hyphenated-tag → WC local definition. */
67
+ byTag: Map<string, LocalDefinition>;
68
+ };
69
+ export declare const emptyLocalIndex: LocalDefinitionIndex;
70
+ export type Loc = {
71
+ file: string;
72
+ line: number;
73
+ column: number;
74
+ };
75
+ export type WarningCode = "MISSING_REACT_EXPORT_EXTENSION" | "PARSE_FAILURE" | "IMPORT_UNRESOLVABLE" | "MANIFEST_TAG_COLLISION" | "EMPTY_INCLUDE";
76
+ interface WarningBase {
77
+ message: string;
78
+ }
79
+ export type Warning = (WarningBase & {
80
+ code: "PARSE_FAILURE";
81
+ file: string;
82
+ line: number;
83
+ }) | (WarningBase & {
84
+ code: "IMPORT_UNRESOLVABLE";
85
+ file: string;
86
+ line: number;
87
+ }) | (WarningBase & {
88
+ code: "MISSING_REACT_EXPORT_EXTENSION";
89
+ package: string;
90
+ file: string;
91
+ }) | (WarningBase & {
92
+ code: "MANIFEST_TAG_COLLISION";
93
+ package: string;
94
+ }) | (WarningBase & {
95
+ code: "EMPTY_INCLUDE";
96
+ });
97
+ /**
98
+ * The subset of the CLI's resolved configuration that parsers actually consume.
99
+ * Using a structural interface rather than the full `ResolvedConfig` keeps
100
+ * parsers decoupled from CLI-specific fields (configPath, output, etc.).
101
+ */
102
+ export type ScanConfig = {
103
+ packageScopes: string[];
104
+ captureValues: boolean;
105
+ };
106
+ export type PropUsage = {
107
+ name: string;
108
+ isDynamic: boolean;
109
+ literalValue?: string | number | boolean;
110
+ /**
111
+ * When `isDynamic` is true, distinguishes the kind of dynamic value:
112
+ * - "spread" — JSX spread attribute (`{...rest}`); name is `"...rest"`.
113
+ * - "identifier" — bare identifier reference (`prop={someVar}`).
114
+ * - "expr" — any other expression (`prop={a + b}`, calls, ternaries, etc.).
115
+ * Omitted when `isDynamic` is false.
116
+ */
117
+ dynamicKind?: "spread" | "expr" | "identifier";
118
+ };
119
+ export type { OccurrenceVia } from "./via-types.js";
120
+ export type Occurrence = {
121
+ componentId: ComponentId;
122
+ loc: Loc;
123
+ via: OccurrenceVia;
124
+ props: PropUsage[];
125
+ events: string[];
126
+ };
127
+ export type WrapperDef = {
128
+ id: WrapperId;
129
+ name: string;
130
+ file: string;
131
+ exportName: string;
132
+ componentDeps: ComponentId[];
133
+ };
134
+ export type FileImport = {
135
+ file: string;
136
+ /** Local binding name as used at the import site. */
137
+ imported: string;
138
+ source: string;
139
+ loc: Loc;
140
+ };
141
+ export type ParseResult = {
142
+ occurrences: Occurrence[];
143
+ wrappers: WrapperDef[];
144
+ imports: FileImport[];
145
+ warnings: Warning[];
146
+ };
147
+ export type ParseContext = {
148
+ index: ComponentIndex;
149
+ config: ScanConfig;
150
+ resolveImport: (from: string, spec: string) => string | null;
151
+ repoRoot: string;
152
+ };
153
+ export interface ParserPlugin {
154
+ name: string;
155
+ extensions: string[];
156
+ parse(file: string, source: string, ctx: ParseContext): ParseResult;
157
+ }
158
+ export type ScanEnvelope = {
159
+ scanId: string;
160
+ repoId: string;
161
+ commitSha: string | null;
162
+ branch: string | null;
163
+ timestamp: string;
164
+ toolVersion: string;
165
+ cwd: string;
166
+ };
167
+ export type ManifestRef = {
168
+ source: ManifestSource;
169
+ package: string;
170
+ path: string;
171
+ version: string | null;
172
+ };
173
+ export type ScanStats = {
174
+ filesScanned: number;
175
+ filesWithUsage: number;
176
+ scanDurationMs: number;
177
+ componentsDetected: number;
178
+ totalOccurrences: number;
179
+ };
180
+ export type ScanOutput = {
181
+ envelope: ScanEnvelope;
182
+ manifests: ManifestRef[];
183
+ stats: ScanStats;
184
+ components: OutputComponent[];
185
+ occurrences: OutputOccurrence[];
186
+ };
@@ -0,0 +1,8 @@
1
+ /** Unsafe constructors — use only at the data-ingest boundary. */
2
+ export const asTagName = (s) => s;
3
+ export const asWrapperId = (s) => s;
4
+ export const emptyLocalIndex = {
5
+ byPath: new Map(),
6
+ byTag: new Map(),
7
+ };
8
+ //# sourceMappingURL=scan-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-types.js","sourceRoot":"","sources":["../src/scan-types.ts"],"names":[],"mappings":"AAqBA,kEAAkE;AAClE,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAS,EAAW,EAAE,CAAC,CAAY,CAAC;AAC9D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAS,EAAa,EAAE,CAAC,CAAc,CAAC;AAsEpE,MAAM,CAAC,MAAM,eAAe,GAAyB;IACnD,MAAM,EAAE,IAAI,GAAG,EAAE;IACjB,KAAK,EAAE,IAAI,GAAG,EAAE;CACjB,CAAC"}
@@ -0,0 +1,205 @@
1
+ export declare const manifestJsonSchema: {
2
+ readonly $id: "https://component-compass.dev/manifest-2.0.0.json";
3
+ readonly type: "object";
4
+ readonly required: readonly ["schemaVersion", "source", "package", "components"];
5
+ readonly additionalProperties: true;
6
+ readonly properties: {
7
+ readonly schemaVersion: {
8
+ readonly const: "2.0.0";
9
+ };
10
+ readonly source: {
11
+ readonly enum: readonly ["cem", "react", "vue"];
12
+ };
13
+ readonly package: {
14
+ readonly type: "string";
15
+ readonly minLength: 1;
16
+ };
17
+ readonly components: {
18
+ readonly type: "array";
19
+ readonly items: {
20
+ readonly type: "object";
21
+ readonly required: readonly ["kind", "source", "deprecated", "props"];
22
+ readonly properties: {
23
+ readonly kind: {
24
+ readonly enum: readonly ["custom-element", "react-component", "vue-component"];
25
+ };
26
+ readonly source: {
27
+ readonly type: "object";
28
+ readonly required: readonly ["type"];
29
+ readonly properties: {
30
+ readonly type: {
31
+ readonly enum: readonly ["external", "local"];
32
+ };
33
+ readonly package: {
34
+ readonly type: "string";
35
+ readonly minLength: 1;
36
+ };
37
+ readonly filePath: {
38
+ readonly type: "string";
39
+ readonly minLength: 1;
40
+ };
41
+ };
42
+ readonly allOf: readonly [{
43
+ readonly if: {
44
+ readonly properties: {
45
+ readonly type: {
46
+ readonly const: "external";
47
+ };
48
+ };
49
+ };
50
+ readonly then: {
51
+ readonly required: readonly ["package"];
52
+ };
53
+ }, {
54
+ readonly if: {
55
+ readonly properties: {
56
+ readonly type: {
57
+ readonly const: "local";
58
+ };
59
+ };
60
+ };
61
+ readonly then: {
62
+ readonly required: readonly ["filePath"];
63
+ };
64
+ }];
65
+ };
66
+ readonly export: {
67
+ readonly type: "string";
68
+ };
69
+ readonly tagName: {
70
+ readonly type: "string";
71
+ };
72
+ readonly deprecated: {
73
+ readonly oneOf: readonly [{
74
+ readonly type: "boolean";
75
+ }, {
76
+ readonly type: "string";
77
+ }];
78
+ };
79
+ readonly props: {
80
+ readonly type: "array";
81
+ readonly items: {
82
+ readonly type: "object";
83
+ readonly required: readonly ["name"];
84
+ readonly properties: {
85
+ readonly name: {
86
+ readonly type: "string";
87
+ };
88
+ };
89
+ };
90
+ };
91
+ readonly events: {
92
+ readonly type: "array";
93
+ };
94
+ readonly slots: {
95
+ readonly type: "array";
96
+ };
97
+ readonly cssParts: {
98
+ readonly type: "array";
99
+ };
100
+ readonly cssProperties: {
101
+ readonly type: "array";
102
+ };
103
+ };
104
+ readonly allOf: readonly [{
105
+ readonly if: {
106
+ readonly properties: {
107
+ readonly kind: {
108
+ readonly const: "custom-element";
109
+ };
110
+ };
111
+ };
112
+ readonly then: {
113
+ readonly required: readonly ["tagName"];
114
+ };
115
+ }, {
116
+ readonly if: {
117
+ readonly properties: {
118
+ readonly kind: {
119
+ readonly const: "react-component";
120
+ };
121
+ };
122
+ };
123
+ readonly then: {
124
+ readonly required: readonly ["export"];
125
+ };
126
+ }, {
127
+ readonly if: {
128
+ readonly properties: {
129
+ readonly kind: {
130
+ readonly const: "vue-component";
131
+ };
132
+ };
133
+ };
134
+ readonly then: {
135
+ readonly required: readonly ["export"];
136
+ };
137
+ }];
138
+ };
139
+ };
140
+ };
141
+ readonly allOf: readonly [{
142
+ readonly if: {
143
+ readonly properties: {
144
+ readonly source: {
145
+ readonly const: "react";
146
+ };
147
+ };
148
+ };
149
+ readonly then: {
150
+ readonly properties: {
151
+ readonly components: {
152
+ readonly items: {
153
+ readonly properties: {
154
+ readonly kind: {
155
+ readonly const: "react-component";
156
+ };
157
+ };
158
+ };
159
+ };
160
+ };
161
+ };
162
+ }, {
163
+ readonly if: {
164
+ readonly properties: {
165
+ readonly source: {
166
+ readonly const: "vue";
167
+ };
168
+ };
169
+ };
170
+ readonly then: {
171
+ readonly properties: {
172
+ readonly components: {
173
+ readonly items: {
174
+ readonly properties: {
175
+ readonly kind: {
176
+ readonly const: "vue-component";
177
+ };
178
+ };
179
+ };
180
+ };
181
+ };
182
+ };
183
+ }, {
184
+ readonly if: {
185
+ readonly properties: {
186
+ readonly source: {
187
+ readonly const: "cem";
188
+ };
189
+ };
190
+ };
191
+ readonly then: {
192
+ readonly properties: {
193
+ readonly components: {
194
+ readonly items: {
195
+ readonly properties: {
196
+ readonly kind: {
197
+ readonly const: "custom-element";
198
+ };
199
+ };
200
+ };
201
+ };
202
+ };
203
+ };
204
+ }];
205
+ };
package/dist/schema.js ADDED
@@ -0,0 +1,62 @@
1
+ // biome-ignore lint/suspicious/noThenProperty: JSON Schema if/then for source⇄kind validation
2
+ export const manifestJsonSchema = {
3
+ $id: "https://component-compass.dev/manifest-2.0.0.json",
4
+ type: "object",
5
+ required: ["schemaVersion", "source", "package", "components"],
6
+ additionalProperties: true,
7
+ properties: {
8
+ schemaVersion: { const: "2.0.0" },
9
+ source: { enum: ["cem", "react", "vue"] },
10
+ package: { type: "string", minLength: 1 },
11
+ components: {
12
+ type: "array",
13
+ items: {
14
+ type: "object",
15
+ required: ["kind", "source", "deprecated", "props"],
16
+ properties: {
17
+ kind: { enum: ["custom-element", "react-component", "vue-component"] },
18
+ source: {
19
+ type: "object",
20
+ required: ["type"],
21
+ properties: {
22
+ type: { enum: ["external", "local"] },
23
+ package: { type: "string", minLength: 1 },
24
+ filePath: { type: "string", minLength: 1 },
25
+ },
26
+ allOf: [
27
+ // biome-ignore lint/suspicious/noThenProperty: JSON Schema if/then for source.type conditional
28
+ { if: { properties: { type: { const: "external" } } }, then: { required: ["package"] } },
29
+ // biome-ignore lint/suspicious/noThenProperty: JSON Schema if/then for source.type conditional
30
+ { if: { properties: { type: { const: "local" } } }, then: { required: ["filePath"] } },
31
+ ],
32
+ },
33
+ export: { type: "string" },
34
+ tagName: { type: "string" },
35
+ deprecated: { oneOf: [{ type: "boolean" }, { type: "string" }] },
36
+ props: { type: "array", items: { type: "object", required: ["name"], properties: { name: { type: "string" } } } },
37
+ events: { type: "array" },
38
+ slots: { type: "array" },
39
+ cssParts: { type: "array" },
40
+ cssProperties: { type: "array" },
41
+ },
42
+ allOf: [
43
+ // biome-ignore lint/suspicious/noThenProperty: JSON Schema if/then for kind conditional
44
+ { if: { properties: { kind: { const: "custom-element" } } }, then: { required: ["tagName"] } },
45
+ // biome-ignore lint/suspicious/noThenProperty: JSON Schema if/then for kind conditional
46
+ { if: { properties: { kind: { const: "react-component" } } }, then: { required: ["export"] } },
47
+ // biome-ignore lint/suspicious/noThenProperty: JSON Schema if/then for kind conditional
48
+ { if: { properties: { kind: { const: "vue-component" } } }, then: { required: ["export"] } },
49
+ ],
50
+ },
51
+ },
52
+ },
53
+ allOf: [
54
+ // biome-ignore lint/suspicious/noThenProperty: JSON Schema if/then for source conditional
55
+ { if: { properties: { source: { const: "react" } } }, then: { properties: { components: { items: { properties: { kind: { const: "react-component" } } } } } } },
56
+ // biome-ignore lint/suspicious/noThenProperty: JSON Schema if/then for source conditional
57
+ { if: { properties: { source: { const: "vue" } } }, then: { properties: { components: { items: { properties: { kind: { const: "vue-component" } } } } } } },
58
+ // biome-ignore lint/suspicious/noThenProperty: JSON Schema if/then for source conditional
59
+ { if: { properties: { source: { const: "cem" } } }, then: { properties: { components: { items: { properties: { kind: { const: "custom-element" } } } } } } },
60
+ ],
61
+ };
62
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ export type ComponentKind = "custom-element" | "react-component" | "vue-component";
2
+ export type ComponentSource = {
3
+ type: "external";
4
+ package: string;
5
+ } | {
6
+ type: "local";
7
+ filePath: string;
8
+ } | {
9
+ type: "unknown";
10
+ };
11
+ export type ComponentId = {
12
+ kind: "custom-element";
13
+ tagName: string;
14
+ source: ComponentSource;
15
+ } | {
16
+ kind: "react-component";
17
+ export: string;
18
+ source: ComponentSource;
19
+ } | {
20
+ kind: "vue-component";
21
+ export: string;
22
+ source: ComponentSource;
23
+ };
24
+ export type ManifestProp = {
25
+ name: string;
26
+ type?: string;
27
+ deprecated?: boolean | string;
28
+ default?: string | number | boolean | null;
29
+ };
30
+ export type ManifestEvent = {
31
+ name: string;
32
+ deprecated?: boolean | string;
33
+ };
34
+ export type ManifestSlot = {
35
+ name: string;
36
+ };
37
+ export type Lifecycle = {
38
+ status: "stable";
39
+ } | {
40
+ status: "deprecated";
41
+ supersededBy?: {
42
+ packageName: string;
43
+ exportName: string;
44
+ };
45
+ };
46
+ type ComponentBase = {
47
+ source: ComponentSource;
48
+ deprecated: boolean | string;
49
+ props: ManifestProp[];
50
+ lifecycle?: Lifecycle;
51
+ };
52
+ export type ManifestComponent = (ComponentBase & {
53
+ kind: "custom-element";
54
+ tagName: string;
55
+ events?: ManifestEvent[];
56
+ slots?: ManifestSlot[];
57
+ cssParts?: Array<{
58
+ name: string;
59
+ }>;
60
+ cssProperties?: Array<{
61
+ name: string;
62
+ }>;
63
+ }) | (ComponentBase & {
64
+ kind: "react-component";
65
+ export: string;
66
+ }) | (ComponentBase & {
67
+ kind: "vue-component";
68
+ export: string;
69
+ });
70
+ export type ManifestSource = "cem" | "react" | "vue";
71
+ export type ManifestFile = {
72
+ schemaVersion: "2.0.0";
73
+ source: ManifestSource;
74
+ package: string;
75
+ components: ManifestComponent[];
76
+ };
77
+ export {};
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { ManifestFile } from "./types.js";
2
+ export type ValidationResult = {
3
+ ok: true;
4
+ data: ManifestFile;
5
+ } | {
6
+ ok: false;
7
+ errors: string[];
8
+ };
9
+ export declare function validateManifest(doc: unknown): ValidationResult;
@@ -0,0 +1,18 @@
1
+ import { createRequire } from "node:module";
2
+ import { manifestJsonSchema } from "./schema.js";
3
+ // ajv is a CJS-only package. Under module: NodeNext, the bare default import
4
+ // is the namespace, not the class. createRequire is Node's official escape
5
+ // hatch for loading CJS from ESM. (Same pattern as packages/cli/src/config/schema.ts.)
6
+ const require = createRequire(import.meta.url);
7
+ const Ajv = require("ajv").default ?? require("ajv");
8
+ const ajv = new Ajv({ allErrors: true, strict: false });
9
+ const validate = ajv.compile(manifestJsonSchema);
10
+ export function validateManifest(doc) {
11
+ if (validate(doc))
12
+ return { ok: true, data: doc };
13
+ return {
14
+ ok: false,
15
+ errors: (validate.errors ?? []).map((e) => `${e.instancePath || "/"} ${e.message ?? "unknown error"}`),
16
+ };
17
+ }
18
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGjD,6EAA6E;AAC7E,2EAA2E;AAC3E,uFAAuF;AACvF,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAA2B,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;AAE7E,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AACxD,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAMjD,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,IAAI,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAmB,EAAE,CAAC;IAClE,OAAO;QACL,EAAE,EAAE,KAAK;QACT,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CACjC,CAAC,CAAc,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,YAAY,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,IAAI,eAAe,EAAE,CAC/E;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Discriminated union describing how a component instance was used.
3
+ * Shared between parser-emitted Occurrence (scan-types.ts) and the artifact-shape
4
+ * OutputOccurrence (output-types.ts). Lives in its own module to keep the two
5
+ * type files acyclic.
6
+ */
7
+ export type OccurrenceVia = {
8
+ kind: "html-tag";
9
+ } | {
10
+ kind: "lit-template";
11
+ specifier?: string;
12
+ } | {
13
+ kind: "react-wrapper";
14
+ specifier: string;
15
+ import: string;
16
+ } | {
17
+ kind: "direct-import";
18
+ specifier: string;
19
+ import: string;
20
+ } | {
21
+ kind: "vue-template";
22
+ specifier: string;
23
+ import: string;
24
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=via-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"via-types.js","sourceRoot":"","sources":["../src/via-types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@component-compass/plugin-core",
3
+ "version": "0.0.0-pr-3-8916f3c-20260507145532",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc -p tsconfig.json",
18
+ "lint": "biome lint src tests",
19
+ "test": "vitest run --passWithNoTests",
20
+ "typecheck": "tsc --noEmit",
21
+ "clean": "rm -rf dist .turbo"
22
+ },
23
+ "dependencies": {
24
+ "ajv": "^8.17.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "^24.0.0",
28
+ "typescript": "^5.9.0",
29
+ "vitest": "^4.0.0"
30
+ },
31
+ "engines": {
32
+ "node": ">=24"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ }
37
+ }