@component-compass/manifest-react 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.
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +24 -0
- package/dist/cli.js.map +1 -0
- package/dist/extract-props.d.ts +25 -0
- package/dist/extract-props.js +120 -0
- package/dist/extract-props.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/scan.d.ts +7 -0
- package/dist/scan.js +122 -0
- package/dist/scan.js.map +1 -0
- package/package.json +51 -0
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { writeFile } from "node:fs/promises";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { scanReactPackage } from "./scan.js";
|
|
5
|
+
async function main() {
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
if (args.length < 1) {
|
|
8
|
+
process.stderr.write("Usage: component-compass-scan-react <packageRoot> [--out <path>]\n");
|
|
9
|
+
process.exit(2);
|
|
10
|
+
}
|
|
11
|
+
const root = resolve(args[0] ?? ".");
|
|
12
|
+
const outIdx = args.indexOf("--out");
|
|
13
|
+
const out = outIdx >= 0 && args[outIdx + 1]
|
|
14
|
+
? resolve(args[outIdx + 1])
|
|
15
|
+
: resolve(root, "component-compass-manifest.json");
|
|
16
|
+
const manifest = await scanReactPackage({ packageRoot: root });
|
|
17
|
+
await writeFile(out, `${JSON.stringify(manifest, null, 2)}\n`, "utf8");
|
|
18
|
+
process.stdout.write(`Wrote ${out} (${manifest.components.length} components)\n`);
|
|
19
|
+
}
|
|
20
|
+
main().catch((err) => {
|
|
21
|
+
process.stderr.write(`manifest-react error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oEAAoE,CACrE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,GAAG,GACP,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7B,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAW,CAAC;QACrC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,iCAAiC,CAAC,CAAC;IACvD,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/D,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,GAAG,KAAK,QAAQ,CAAC,UAAU,CAAC,MAAM,gBAAgB,CAAC,CAAC;AACpF,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,yBAAyB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC9E,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type * as t from "@babel/types";
|
|
2
|
+
import type { Lifecycle, ManifestProp } from "@component-compass/plugin-core";
|
|
3
|
+
type LiteralDefault = string | number | boolean | null;
|
|
4
|
+
export declare function extractProps(paramTypeAnnotation: t.TSTypeAnnotation | t.TypeAnnotation | null | undefined, fileTypeAliases: Map<string, t.TSTypeLiteral>): ManifestProp[];
|
|
5
|
+
/**
|
|
6
|
+
* Pull literal defaults from a destructured-argument pattern, e.g.
|
|
7
|
+
* function Foo({ size = "medium" }: Props) { ... }
|
|
8
|
+
*
|
|
9
|
+
* Returns a name -> literal-value map. Non-literal initialisers are skipped.
|
|
10
|
+
*/
|
|
11
|
+
export declare function extractDefaultsFromParam(param: t.Identifier | t.Pattern | t.RestElement | null | undefined): Map<string, LiteralDefault>;
|
|
12
|
+
/**
|
|
13
|
+
* Pull literal defaults from a `Component.defaultProps = { ... }` ObjectExpression.
|
|
14
|
+
* Returns a name -> literal-value map. Non-literal values are skipped.
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractDefaultPropsAssignment(obj: t.ObjectExpression): Map<string, LiteralDefault>;
|
|
17
|
+
/**
|
|
18
|
+
* Parse a leading-comment list for JSDoc `@deprecated` tags.
|
|
19
|
+
* Returns `{ status: "deprecated" }`, optionally with `supersededBy` if the
|
|
20
|
+
* deprecation text contains `use <packageName>#<ExportName>`.
|
|
21
|
+
* Returns undefined when no `@deprecated` tag is present (so absence is treated
|
|
22
|
+
* as stable downstream rather than emitting a synthetic stable marker).
|
|
23
|
+
*/
|
|
24
|
+
export declare function extractLifecycleFromComments(comments: readonly t.Comment[] | null | undefined): Lifecycle | undefined;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
export function extractProps(paramTypeAnnotation, fileTypeAliases) {
|
|
2
|
+
if (!paramTypeAnnotation || paramTypeAnnotation.type !== "TSTypeAnnotation")
|
|
3
|
+
return [];
|
|
4
|
+
const lit = resolveLiteral(paramTypeAnnotation.typeAnnotation, fileTypeAliases);
|
|
5
|
+
if (!lit)
|
|
6
|
+
return [];
|
|
7
|
+
const out = [];
|
|
8
|
+
for (const m of lit.members) {
|
|
9
|
+
if (m.type !== "TSPropertySignature")
|
|
10
|
+
continue;
|
|
11
|
+
const name = keyName(m.key);
|
|
12
|
+
if (!name)
|
|
13
|
+
continue;
|
|
14
|
+
out.push({ name });
|
|
15
|
+
}
|
|
16
|
+
return out;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Pull literal defaults from a destructured-argument pattern, e.g.
|
|
20
|
+
* function Foo({ size = "medium" }: Props) { ... }
|
|
21
|
+
*
|
|
22
|
+
* Returns a name -> literal-value map. Non-literal initialisers are skipped.
|
|
23
|
+
*/
|
|
24
|
+
export function extractDefaultsFromParam(param) {
|
|
25
|
+
const out = new Map();
|
|
26
|
+
if (!param || param.type !== "ObjectPattern")
|
|
27
|
+
return out;
|
|
28
|
+
for (const prop of param.properties) {
|
|
29
|
+
if (prop.type !== "ObjectProperty")
|
|
30
|
+
continue;
|
|
31
|
+
const value = prop.value;
|
|
32
|
+
if (value.type !== "AssignmentPattern")
|
|
33
|
+
continue;
|
|
34
|
+
if (value.left.type !== "Identifier")
|
|
35
|
+
continue;
|
|
36
|
+
const lit = literalValue(value.right);
|
|
37
|
+
if (lit === NO_LITERAL)
|
|
38
|
+
continue;
|
|
39
|
+
out.set(value.left.name, lit);
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Pull literal defaults from a `Component.defaultProps = { ... }` ObjectExpression.
|
|
45
|
+
* Returns a name -> literal-value map. Non-literal values are skipped.
|
|
46
|
+
*/
|
|
47
|
+
export function extractDefaultPropsAssignment(obj) {
|
|
48
|
+
const out = new Map();
|
|
49
|
+
for (const prop of obj.properties) {
|
|
50
|
+
if (prop.type !== "ObjectProperty")
|
|
51
|
+
continue;
|
|
52
|
+
const name = keyName(prop.key);
|
|
53
|
+
if (!name)
|
|
54
|
+
continue;
|
|
55
|
+
const lit = literalValue(prop.value);
|
|
56
|
+
if (lit === NO_LITERAL)
|
|
57
|
+
continue;
|
|
58
|
+
out.set(name, lit);
|
|
59
|
+
}
|
|
60
|
+
return out;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Parse a leading-comment list for JSDoc `@deprecated` tags.
|
|
64
|
+
* Returns `{ status: "deprecated" }`, optionally with `supersededBy` if the
|
|
65
|
+
* deprecation text contains `use <packageName>#<ExportName>`.
|
|
66
|
+
* Returns undefined when no `@deprecated` tag is present (so absence is treated
|
|
67
|
+
* as stable downstream rather than emitting a synthetic stable marker).
|
|
68
|
+
*/
|
|
69
|
+
export function extractLifecycleFromComments(comments) {
|
|
70
|
+
if (!comments || comments.length === 0)
|
|
71
|
+
return undefined;
|
|
72
|
+
for (const c of comments) {
|
|
73
|
+
if (c.type !== "CommentBlock")
|
|
74
|
+
continue;
|
|
75
|
+
const match = c.value.match(/@deprecated\b([^\n]*)/);
|
|
76
|
+
if (!match)
|
|
77
|
+
continue;
|
|
78
|
+
const text = match[1] ?? "";
|
|
79
|
+
const ref = text.match(/use\s+([\w@/.-]+)#([A-Z]\w*)/);
|
|
80
|
+
if (ref?.[1] && ref[2]) {
|
|
81
|
+
return {
|
|
82
|
+
status: "deprecated",
|
|
83
|
+
supersededBy: { packageName: ref[1], exportName: ref[2] },
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return { status: "deprecated" };
|
|
87
|
+
}
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
const NO_LITERAL = Symbol("no-literal");
|
|
91
|
+
function literalValue(node) {
|
|
92
|
+
switch (node.type) {
|
|
93
|
+
case "StringLiteral":
|
|
94
|
+
return node.value;
|
|
95
|
+
case "NumericLiteral":
|
|
96
|
+
return node.value;
|
|
97
|
+
case "BooleanLiteral":
|
|
98
|
+
return node.value;
|
|
99
|
+
case "NullLiteral":
|
|
100
|
+
return null;
|
|
101
|
+
default:
|
|
102
|
+
return NO_LITERAL;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function resolveLiteral(node, aliases) {
|
|
106
|
+
if (node.type === "TSTypeLiteral")
|
|
107
|
+
return node;
|
|
108
|
+
if (node.type === "TSTypeReference" && node.typeName.type === "Identifier") {
|
|
109
|
+
return aliases.get(node.typeName.name) ?? null;
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
function keyName(key) {
|
|
114
|
+
if (key.type === "Identifier")
|
|
115
|
+
return key.name;
|
|
116
|
+
if (key.type === "StringLiteral")
|
|
117
|
+
return key.value;
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=extract-props.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract-props.js","sourceRoot":"","sources":["../src/extract-props.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/scan.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ManifestFile } from "@component-compass/plugin-core";
|
|
2
|
+
export type ScanReactOptions = {
|
|
3
|
+
packageRoot: string;
|
|
4
|
+
/** Override package name; otherwise read from package.json */
|
|
5
|
+
packageName?: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function scanReactPackage(opts: ScanReactOptions): Promise<ManifestFile>;
|
package/dist/scan.js
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { extname, join } from "node:path";
|
|
3
|
+
import { parse } from "@babel/parser";
|
|
4
|
+
import { ManifestBuilder, } from "@component-compass/plugin-core";
|
|
5
|
+
import { traverse } from "@component-compass/ast-utils";
|
|
6
|
+
import { extractDefaultPropsAssignment, extractDefaultsFromParam, extractLifecycleFromComments, extractProps, } from "./extract-props.js";
|
|
7
|
+
export async function scanReactPackage(opts) {
|
|
8
|
+
const pkgJson = JSON.parse(await readFile(join(opts.packageRoot, "package.json"), "utf8"));
|
|
9
|
+
const pkgName = opts.packageName ?? pkgJson.name;
|
|
10
|
+
const entry = pkgJson.module ?? pkgJson.main ?? "src/index.ts";
|
|
11
|
+
const entryAbs = join(opts.packageRoot, entry);
|
|
12
|
+
const source = await readFile(entryAbs, "utf8");
|
|
13
|
+
const builder = new ManifestBuilder({ source: "react", package: pkgName });
|
|
14
|
+
const ast = parse(source, {
|
|
15
|
+
sourceType: "module",
|
|
16
|
+
plugins: ["typescript", isTsx(entryAbs) ? "jsx" : "jsx"],
|
|
17
|
+
});
|
|
18
|
+
const aliases = new Map();
|
|
19
|
+
traverse(ast, {
|
|
20
|
+
TSTypeAliasDeclaration(p) {
|
|
21
|
+
const decl = p.node;
|
|
22
|
+
if (decl.typeAnnotation.type === "TSTypeLiteral" && decl.id.type === "Identifier") {
|
|
23
|
+
aliases.set(decl.id.name, decl.typeAnnotation);
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
// Pre-scan: collect `Component.defaultProps = { ... }` assignments by name.
|
|
28
|
+
const defaultPropsByComponent = new Map();
|
|
29
|
+
traverse(ast, {
|
|
30
|
+
AssignmentExpression(p) {
|
|
31
|
+
const { left, right } = p.node;
|
|
32
|
+
if (left.type !== "MemberExpression" ||
|
|
33
|
+
left.computed ||
|
|
34
|
+
left.object.type !== "Identifier" ||
|
|
35
|
+
left.property.type !== "Identifier" ||
|
|
36
|
+
left.property.name !== "defaultProps" ||
|
|
37
|
+
right.type !== "ObjectExpression") {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
defaultPropsByComponent.set(left.object.name, extractDefaultPropsAssignment(right));
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
const seen = new Set();
|
|
44
|
+
const emit = (name, param, leadingComments) => {
|
|
45
|
+
if (seen.has(name) || !looksLikeComponentName(name))
|
|
46
|
+
return;
|
|
47
|
+
seen.add(name);
|
|
48
|
+
const ann = param && "typeAnnotation" in param
|
|
49
|
+
? param.typeAnnotation
|
|
50
|
+
: null;
|
|
51
|
+
const props = extractProps(ann, aliases);
|
|
52
|
+
const patternDefaults = extractDefaultsFromParam(param);
|
|
53
|
+
const assignedDefaults = defaultPropsByComponent.get(name) ?? new Map();
|
|
54
|
+
const propsWithDefaults = props.map((p) => {
|
|
55
|
+
// `Component.defaultProps` wins over destructured-arg defaults when both exist.
|
|
56
|
+
const def = assignedDefaults.get(p.name) ?? patternDefaults.get(p.name);
|
|
57
|
+
return def === undefined ? p : { ...p, default: def };
|
|
58
|
+
});
|
|
59
|
+
const lifecycle = extractLifecycleFromComments(leadingComments);
|
|
60
|
+
builder.addComponent({
|
|
61
|
+
kind: "react-component",
|
|
62
|
+
source: { type: "external", package: pkgName },
|
|
63
|
+
export: name,
|
|
64
|
+
props: propsWithDefaults,
|
|
65
|
+
...(lifecycle ? { lifecycle } : {}),
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
traverse(ast, {
|
|
69
|
+
ExportNamedDeclaration(p) {
|
|
70
|
+
const d = p.node.declaration;
|
|
71
|
+
if (!d) {
|
|
72
|
+
for (const spec of p.node.specifiers) {
|
|
73
|
+
if (spec.type === "ExportSpecifier" && spec.exported.type === "Identifier") {
|
|
74
|
+
const name = spec.exported.name;
|
|
75
|
+
if (looksLikeComponentName(name) && !seen.has(name)) {
|
|
76
|
+
seen.add(name);
|
|
77
|
+
builder.addComponent({
|
|
78
|
+
kind: "react-component",
|
|
79
|
+
source: { type: "external", package: pkgName },
|
|
80
|
+
export: name,
|
|
81
|
+
props: [],
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// Leading comments commonly attach to the outer ExportNamedDeclaration.
|
|
89
|
+
// Fall back to the inner declaration if absent.
|
|
90
|
+
const leading = pickLeadingComments(p.node, d);
|
|
91
|
+
if (d.type === "FunctionDeclaration" && d.id) {
|
|
92
|
+
emit(d.id.name, d.params[0] ?? null, leading);
|
|
93
|
+
}
|
|
94
|
+
else if (d.type === "VariableDeclaration") {
|
|
95
|
+
for (const decl of d.declarations) {
|
|
96
|
+
if (decl.id.type !== "Identifier")
|
|
97
|
+
continue;
|
|
98
|
+
const init = decl.init;
|
|
99
|
+
if (!init)
|
|
100
|
+
continue;
|
|
101
|
+
if (init.type === "ArrowFunctionExpression" || init.type === "FunctionExpression") {
|
|
102
|
+
emit(decl.id.name, init.params[0] ?? null, leading);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
return builder.build();
|
|
109
|
+
}
|
|
110
|
+
function pickLeadingComments(outer, inner) {
|
|
111
|
+
if (outer.leadingComments && outer.leadingComments.length > 0)
|
|
112
|
+
return outer.leadingComments;
|
|
113
|
+
return inner.leadingComments;
|
|
114
|
+
}
|
|
115
|
+
function looksLikeComponentName(s) {
|
|
116
|
+
return /^[A-Z]/.test(s);
|
|
117
|
+
}
|
|
118
|
+
function isTsx(path) {
|
|
119
|
+
const e = extname(path).toLowerCase();
|
|
120
|
+
return e === ".tsx" || e === ".jsx";
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=scan.js.map
|
package/dist/scan.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@component-compass/manifest-react",
|
|
3
|
+
"componentCompass": {
|
|
4
|
+
"kind": "manifest"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.0.0-pr-3-8916f3c-20260507145532",
|
|
7
|
+
"description": "Babel-based scanner that emits component-compass-manifest.json from a React-only design-system source tree.",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"bin": {
|
|
13
|
+
"component-compass-scan-react": "./dist/cli.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc -p tsconfig.json",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"lint": "biome lint src tests",
|
|
30
|
+
"clean": "rm -rf dist .turbo"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@babel/parser": "^7.29.0",
|
|
34
|
+
"@babel/traverse": "^7.29.0",
|
|
35
|
+
"@babel/types": "^7.29.0",
|
|
36
|
+
"@component-compass/ast-utils": "0.0.0-pr-3-8916f3c-20260507145532",
|
|
37
|
+
"@component-compass/plugin-core": "0.0.0-pr-3-8916f3c-20260507145532"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/babel__traverse": "^7.28.0",
|
|
41
|
+
"@types/node": "^24.0.0",
|
|
42
|
+
"typescript": "^5.9.0",
|
|
43
|
+
"vitest": "^4.0.0"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=24"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
}
|
|
51
|
+
}
|