@component-compass/cli 0.1.22 → 0.1.24
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.js +103503 -104
- package/package.json +21 -25
- package/dist/auth/browser.d.ts +0 -13
- package/dist/auth/browser.js +0 -21
- package/dist/auth/browser.js.map +0 -1
- package/dist/auth/client.d.ts +0 -48
- package/dist/auth/client.js +0 -89
- package/dist/auth/client.js.map +0 -1
- package/dist/auth/paths.d.ts +0 -2
- package/dist/auth/paths.js +0 -14
- package/dist/auth/paths.js.map +0 -1
- package/dist/auth/session.d.ts +0 -38
- package/dist/auth/session.js +0 -88
- package/dist/auth/session.js.map +0 -1
- package/dist/auth/store.d.ts +0 -16
- package/dist/auth/store.js +0 -37
- package/dist/auth/store.js.map +0 -1
- package/dist/auth/upload-auth.d.ts +0 -22
- package/dist/auth/upload-auth.js +0 -51
- package/dist/auth/upload-auth.js.map +0 -1
- package/dist/cli/help.d.ts +0 -4
- package/dist/cli/help.js +0 -52
- package/dist/cli/help.js.map +0 -1
- package/dist/cli/parse.d.ts +0 -14
- package/dist/cli/parse.js +0 -75
- package/dist/cli/parse.js.map +0 -1
- package/dist/cli/suggest.d.ts +0 -4
- package/dist/cli/suggest.js +0 -38
- package/dist/cli/suggest.js.map +0 -1
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js.map +0 -1
- package/dist/commands/auth.d.ts +0 -33
- package/dist/commands/auth.js +0 -248
- package/dist/commands/auth.js.map +0 -1
- package/dist/commands/init.d.ts +0 -11
- package/dist/commands/init.js +0 -112
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/scan.d.ts +0 -33
- package/dist/commands/scan.js +0 -745
- package/dist/commands/scan.js.map +0 -1
- package/dist/composition-rollup.d.ts +0 -23
- package/dist/composition-rollup.js +0 -64
- package/dist/composition-rollup.js.map +0 -1
- package/dist/config/loader.d.ts +0 -6
- package/dist/config/loader.js +0 -71
- package/dist/config/loader.js.map +0 -1
- package/dist/config/schema.d.ts +0 -18
- package/dist/config/schema.js +0 -15
- package/dist/config/schema.js.map +0 -1
- package/dist/dispatcher.d.ts +0 -8
- package/dist/dispatcher.js +0 -22
- package/dist/dispatcher.js.map +0 -1
- package/dist/envelope/git.d.ts +0 -13
- package/dist/envelope/git.js +0 -69
- package/dist/envelope/git.js.map +0 -1
- package/dist/envelope/index.d.ts +0 -1
- package/dist/envelope/index.js +0 -12
- package/dist/envelope/index.js.map +0 -1
- package/dist/envelope/repo-id.d.ts +0 -16
- package/dist/envelope/repo-id.js +0 -40
- package/dist/envelope/repo-id.js.map +0 -1
- package/dist/identity.d.ts +0 -56
- package/dist/identity.js +0 -115
- package/dist/identity.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -3
- package/dist/index.js.map +0 -1
- package/dist/local-index/declared-props.d.ts +0 -15
- package/dist/local-index/declared-props.js +0 -101
- package/dist/local-index/declared-props.js.map +0 -1
- package/dist/local-index/detect-react.d.ts +0 -3
- package/dist/local-index/detect-react.js +0 -378
- package/dist/local-index/detect-react.js.map +0 -1
- package/dist/local-index/detect-vue.d.ts +0 -16
- package/dist/local-index/detect-vue.js +0 -284
- package/dist/local-index/detect-vue.js.map +0 -1
- package/dist/local-index/detect-wc.d.ts +0 -8
- package/dist/local-index/detect-wc.js +0 -70
- package/dist/local-index/detect-wc.js.map +0 -1
- package/dist/local-index/index.d.ts +0 -14
- package/dist/local-index/index.js +0 -46
- package/dist/local-index/index.js.map +0 -1
- package/dist/local-index/types.d.ts +0 -2
- package/dist/local-index/types.js +0 -2
- package/dist/local-index/types.js.map +0 -1
- package/dist/manifest/barrel-parser.d.ts +0 -35
- package/dist/manifest/barrel-parser.js +0 -76
- package/dist/manifest/barrel-parser.js.map +0 -1
- package/dist/manifest/lazy-resolver.d.ts +0 -123
- package/dist/manifest/lazy-resolver.js +0 -712
- package/dist/manifest/lazy-resolver.js.map +0 -1
- package/dist/occurrences.d.ts +0 -15
- package/dist/occurrences.js +0 -101
- package/dist/occurrences.js.map +0 -1
- package/dist/parse-by-ext.d.ts +0 -21
- package/dist/parse-by-ext.js +0 -53
- package/dist/parse-by-ext.js.map +0 -1
- package/dist/prompts/adapter.d.ts +0 -43
- package/dist/prompts/adapter.js +0 -32
- package/dist/prompts/adapter.js.map +0 -1
- package/dist/reporter/index.d.ts +0 -39
- package/dist/reporter/index.js +0 -144
- package/dist/reporter/index.js.map +0 -1
- package/dist/reporter/json.d.ts +0 -6
- package/dist/reporter/json.js +0 -11
- package/dist/reporter/json.js.map +0 -1
- package/dist/reporter/stdout.d.ts +0 -3
- package/dist/reporter/stdout.js +0 -41
- package/dist/reporter/stdout.js.map +0 -1
- package/dist/rollup.d.ts +0 -26
- package/dist/rollup.js +0 -135
- package/dist/rollup.js.map +0 -1
- package/dist/scan/cem-index.d.ts +0 -38
- package/dist/scan/cem-index.js +0 -139
- package/dist/scan/cem-index.js.map +0 -1
- package/dist/scan/entry-packages.d.ts +0 -42
- package/dist/scan/entry-packages.js +0 -87
- package/dist/scan/entry-packages.js.map +0 -1
- package/dist/scan/framework-root.d.ts +0 -1
- package/dist/scan/framework-root.js +0 -22
- package/dist/scan/framework-root.js.map +0 -1
- package/dist/scan/git-mtime.d.ts +0 -2
- package/dist/scan/git-mtime.js +0 -22
- package/dist/scan/git-mtime.js.map +0 -1
- package/dist/scan/global-components.d.ts +0 -37
- package/dist/scan/global-components.js +0 -228
- package/dist/scan/global-components.js.map +0 -1
- package/dist/scan/meta.d.ts +0 -5
- package/dist/scan/meta.js +0 -58
- package/dist/scan/meta.js.map +0 -1
- package/dist/scan/stamp-version.d.ts +0 -18
- package/dist/scan/stamp-version.js +0 -94
- package/dist/scan/stamp-version.js.map +0 -1
- package/dist/scan/wrap-relationships.d.ts +0 -12
- package/dist/scan/wrap-relationships.js +0 -38
- package/dist/scan/wrap-relationships.js.map +0 -1
- package/dist/seeds.d.ts +0 -81
- package/dist/seeds.js +0 -258
- package/dist/seeds.js.map +0 -1
- package/dist/types/brand.d.ts +0 -11
- package/dist/types/brand.js +0 -5
- package/dist/types/brand.js.map +0 -1
- package/dist/types/component-id.d.ts +0 -2
- package/dist/types/component-id.js +0 -2
- package/dist/types/component-id.js.map +0 -1
- package/dist/types.d.ts +0 -13
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/upload.d.ts +0 -18
- package/dist/upload.js +0 -34
- package/dist/upload.js.map +0 -1
- package/dist/util/color.d.ts +0 -24
- package/dist/util/color.js +0 -45
- package/dist/util/color.js.map +0 -1
- package/dist/util/git.d.ts +0 -10
- package/dist/util/git.js +0 -95
- package/dist/util/git.js.map +0 -1
- package/dist/util/interactive.d.ts +0 -17
- package/dist/util/interactive.js +0 -19
- package/dist/util/interactive.js.map +0 -1
- package/dist/util/log.d.ts +0 -9
- package/dist/util/log.js +0 -20
- package/dist/util/log.js.map +0 -1
- package/dist/util/pkg.d.ts +0 -1
- package/dist/util/pkg.js +0 -13
- package/dist/util/pkg.js.map +0 -1
- package/dist/util/pnp-check.d.ts +0 -1
- package/dist/util/pnp-check.js +0 -6
- package/dist/util/pnp-check.js.map +0 -1
- package/dist/util/posix.d.ts +0 -2
- package/dist/util/posix.js +0 -15
- package/dist/util/posix.js.map +0 -1
- package/dist/util/progress.d.ts +0 -21
- package/dist/util/progress.js +0 -54
- package/dist/util/progress.js.map +0 -1
- package/dist/util/version.d.ts +0 -7
- package/dist/util/version.js +0 -13
- package/dist/util/version.js.map +0 -1
- package/dist/walker/bounded-definition-resolver.d.ts +0 -9
- package/dist/walker/bounded-definition-resolver.js +0 -125
- package/dist/walker/bounded-definition-resolver.js.map +0 -1
- package/dist/walker/files.d.ts +0 -7
- package/dist/walker/files.js +0 -24
- package/dist/walker/files.js.map +0 -1
- package/dist/walker/package-alias-layers.d.ts +0 -7
- package/dist/walker/package-alias-layers.js +0 -40
- package/dist/walker/package-alias-layers.js.map +0 -1
- package/dist/walker/resolve-import.d.ts +0 -25
- package/dist/walker/resolve-import.js +0 -243
- package/dist/walker/resolve-import.js.map +0 -1
- package/dist/walker/tsconfig-discovery.d.ts +0 -36
- package/dist/walker/tsconfig-discovery.js +0 -52
- package/dist/walker/tsconfig-discovery.js.map +0 -1
- package/dist/walker/tsconfig-loader.d.ts +0 -35
- package/dist/walker/tsconfig-loader.js +0 -138
- package/dist/walker/tsconfig-loader.js.map +0 -1
- package/dist/walker/workspace-exports.d.ts +0 -3
- package/dist/walker/workspace-exports.js +0 -120
- package/dist/walker/workspace-exports.js.map +0 -1
- package/dist/workspace/build-graph.d.ts +0 -15
- package/dist/workspace/build-graph.js +0 -120
- package/dist/workspace/build-graph.js.map +0 -1
- package/dist/workspace/declared-deps.d.ts +0 -5
- package/dist/workspace/declared-deps.js +0 -42
- package/dist/workspace/declared-deps.js.map +0 -1
- package/dist/workspace/find-owning-package.d.ts +0 -8
- package/dist/workspace/find-owning-package.js +0 -69
- package/dist/workspace/find-owning-package.js.map +0 -1
- package/dist/workspace/find-workspace-root.d.ts +0 -1
- package/dist/workspace/find-workspace-root.js +0 -60
- package/dist/workspace/find-workspace-root.js.map +0 -1
- package/dist/workspace/index.d.ts +0 -4
- package/dist/workspace/index.js +0 -4
- package/dist/workspace/index.js.map +0 -1
- package/dist/workspace/types.d.ts +0 -49
- package/dist/workspace/types.js +0 -13
- package/dist/workspace/types.js.map +0 -1
|
@@ -1,712 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
|
-
import { dirname, extname, isAbsolute, join, relative, resolve as pathResolve } from "node:path";
|
|
4
|
-
import picomatch from "picomatch";
|
|
5
|
-
import { parse as babelParse } from "@babel/parser";
|
|
6
|
-
import { posixPath } from "@component-compass/plugin-core";
|
|
7
|
-
import { validateManifest, createDiagnosticCollector, } from "@component-compass/plugin-core";
|
|
8
|
-
import { parseBarrelTopLevel, parseBarrelTopLevelFromAst, } from "./barrel-parser.js";
|
|
9
|
-
/**
|
|
10
|
-
* Hard ceiling on re-export hops a single resolution may walk. Real chains
|
|
11
|
-
* top out around 10 hops (deep barrel piles); 32 is a pathological-input
|
|
12
|
-
* safety net. When this fires we emit a `chain-too-deep` diagnostic and
|
|
13
|
-
* treat the current file as terminal so the user sees a signal rather than
|
|
14
|
-
* a silent wrong-leaf attribution.
|
|
15
|
-
*/
|
|
16
|
-
const MAX_REEXPORT_HOPS = 32;
|
|
17
|
-
export function createLazyResolver(opts) {
|
|
18
|
-
const { resolveImport } = opts;
|
|
19
|
-
const repoRoot = opts.repoRoot;
|
|
20
|
-
// Repo-root-relative POSIX path for output stability (so manifestRef.path
|
|
21
|
-
// and diagnostic.resolvedFile hash/diff identically across machines).
|
|
22
|
-
// Falls back to the absolute path when no repoRoot was provided (unit
|
|
23
|
-
// tests).
|
|
24
|
-
const toRelPath = (abs) => repoRoot && isAbsolute(abs) ? posixPath(relative(repoRoot, abs)) : abs;
|
|
25
|
-
// `manifestPatterns` is the per-package gate for manifest IO (CEM/CCM loads,
|
|
26
|
-
// byTag indexing, snapshot views). Undefined or empty array disables manifest
|
|
27
|
-
// enrichment entirely; identity resolution (`leafPackage` + `modulePath`)
|
|
28
|
-
// runs independently. Use `['**']` to opt every package into enrichment —
|
|
29
|
-
// `'*'` won't match scoped names like `@scope/pkg` since picomatch's `*`
|
|
30
|
-
// doesn't cross `/`.
|
|
31
|
-
const manifestPatterns = opts.manifestPatterns ?? [];
|
|
32
|
-
const manifestMatchers = manifestPatterns.map((p) => picomatch(p));
|
|
33
|
-
const isManifestEligible = (pkgName) => manifestMatchers.length > 0 && manifestMatchers.some((m) => m(pkgName));
|
|
34
|
-
// (absoluteFilePath::exportName) → cached hit (or null for negative cache).
|
|
35
|
-
const hitCache = new Map();
|
|
36
|
-
// tagName → custom-element entry (populated as authored manifests load).
|
|
37
|
-
const byTag = new Map();
|
|
38
|
-
// Leaf packages whose authored manifest has been loaded. `snapshotEligible`
|
|
39
|
-
// scopes participation in `snapshotComponents()` / `snapshotManifestRefs()`
|
|
40
|
-
// — warm-path and Vue-lane visits are eligible, lookup-only
|
|
41
|
-
// engine-adapter visits are not. Sticky: once true, never flips back.
|
|
42
|
-
const visitedLeafs = new Map();
|
|
43
|
-
const collector = opts.collector ?? createDiagnosticCollector();
|
|
44
|
-
// Parsed barrel AST per absolute path. Deep re-export chains (wrapper-style
|
|
45
|
-
// design-system monorepos: `webc` → `web-button` → leaf) revisit the same barrel
|
|
46
|
-
// many times across one scan; caching the parsed AST collapses the cost to
|
|
47
|
-
// one parse per file regardless of fan-in.
|
|
48
|
-
const barrelAstCache = new Map();
|
|
49
|
-
const barrelParseCounts = new Map();
|
|
50
|
-
function parsedBarrel(absPath, source) {
|
|
51
|
-
const hit = barrelAstCache.get(absPath);
|
|
52
|
-
if (hit)
|
|
53
|
-
return hit;
|
|
54
|
-
const ext = extname(absPath).toLowerCase();
|
|
55
|
-
const plugins = ["typescript", "decorators-legacy", "classProperties"];
|
|
56
|
-
if (ext !== ".ts")
|
|
57
|
-
plugins.push("jsx");
|
|
58
|
-
const ast = babelParse(source, { sourceType: "module", plugins, errorRecovery: true });
|
|
59
|
-
barrelAstCache.set(absPath, ast);
|
|
60
|
-
barrelParseCounts.set(absPath, (barrelParseCounts.get(absPath) ?? 0) + 1);
|
|
61
|
-
return ast;
|
|
62
|
-
}
|
|
63
|
-
function loadLeafManifest(leafPackage, leafDir, opts) {
|
|
64
|
-
const { snapshotEligible } = opts;
|
|
65
|
-
const cached = visitedLeafs.get(leafPackage);
|
|
66
|
-
if (cached) {
|
|
67
|
-
// Sticky upgrade: a snapshot-eligible revisit (warm/Vue) flips an
|
|
68
|
-
// ineligible entry (prior engine lookup) to eligible; never the
|
|
69
|
-
// reverse.
|
|
70
|
-
cached.snapshotEligible = cached.snapshotEligible || snapshotEligible;
|
|
71
|
-
return cached.components;
|
|
72
|
-
}
|
|
73
|
-
const cemPath = join(leafDir, "custom-elements.json");
|
|
74
|
-
const ccmPath = join(leafDir, "component-compass-manifest.json");
|
|
75
|
-
let components = [];
|
|
76
|
-
let manifestPath = null;
|
|
77
|
-
let manifestSource = null;
|
|
78
|
-
let pkgVersion;
|
|
79
|
-
try {
|
|
80
|
-
const raw = readFileSync(join(leafDir, "package.json"), "utf8");
|
|
81
|
-
const pkg = JSON.parse(raw);
|
|
82
|
-
pkgVersion = pkg.version;
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
// Best-effort; leave undefined.
|
|
86
|
-
}
|
|
87
|
-
if (existsSync(cemPath)) {
|
|
88
|
-
try {
|
|
89
|
-
const raw = readFileSync(cemPath, "utf8");
|
|
90
|
-
const cem = JSON.parse(raw);
|
|
91
|
-
components = absorbCemDeclarations(cem, leafPackage);
|
|
92
|
-
manifestPath = cemPath;
|
|
93
|
-
manifestSource = "cem";
|
|
94
|
-
}
|
|
95
|
-
catch {
|
|
96
|
-
// Treat malformed CEM as no manifest.
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
else if (existsSync(ccmPath)) {
|
|
100
|
-
try {
|
|
101
|
-
const raw = readFileSync(ccmPath, "utf8");
|
|
102
|
-
const parsed = JSON.parse(raw);
|
|
103
|
-
const v = validateManifest(parsed);
|
|
104
|
-
if (v.ok) {
|
|
105
|
-
components = absorbCcmComponents(v.data, leafPackage);
|
|
106
|
-
manifestPath = ccmPath;
|
|
107
|
-
manifestSource = v.data.source;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
catch {
|
|
111
|
-
// Treat malformed CCM as no manifest.
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (!manifestPath || !manifestSource) {
|
|
115
|
-
visitedLeafs.set(leafPackage, {
|
|
116
|
-
components: [],
|
|
117
|
-
manifestRef: { source: "cem", packageName: leafPackage, path: "", version: pkgVersion ?? null },
|
|
118
|
-
snapshotEligible,
|
|
119
|
-
});
|
|
120
|
-
return [];
|
|
121
|
-
}
|
|
122
|
-
// Index custom elements by tagName.
|
|
123
|
-
for (const c of components) {
|
|
124
|
-
if (c.kind === "custom-element")
|
|
125
|
-
byTag.set(c.tagName, c);
|
|
126
|
-
}
|
|
127
|
-
visitedLeafs.set(leafPackage, {
|
|
128
|
-
components,
|
|
129
|
-
manifestRef: {
|
|
130
|
-
source: manifestSource,
|
|
131
|
-
packageName: leafPackage,
|
|
132
|
-
path: toRelPath(manifestPath),
|
|
133
|
-
version: pkgVersion ?? null,
|
|
134
|
-
},
|
|
135
|
-
snapshotEligible,
|
|
136
|
-
});
|
|
137
|
-
return components;
|
|
138
|
-
}
|
|
139
|
-
function findPackageRoot(absFile) {
|
|
140
|
-
let dir = dirname(absFile);
|
|
141
|
-
while (dir !== dirname(dir)) {
|
|
142
|
-
const pkgJson = join(dir, "package.json");
|
|
143
|
-
if (existsSync(pkgJson)) {
|
|
144
|
-
try {
|
|
145
|
-
const pkg = JSON.parse(readFileSync(pkgJson, "utf8"));
|
|
146
|
-
if (pkg.name)
|
|
147
|
-
return { name: pkg.name, dir };
|
|
148
|
-
}
|
|
149
|
-
catch {
|
|
150
|
-
// Continue walking if unreadable.
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
dir = dirname(dir);
|
|
154
|
-
}
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
function matchInLeaf(components, exportName) {
|
|
158
|
-
// First pass: react/vue components match on their declared export name.
|
|
159
|
-
for (const c of components) {
|
|
160
|
-
if (c.kind === "react-component" || c.kind === "vue-component") {
|
|
161
|
-
if (c.export === exportName)
|
|
162
|
-
return c;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
// Second pass: className-equality match for custom-elements. Scoped to
|
|
166
|
-
// THIS leaf only — never iterates a global byTag map, which cannot tell
|
|
167
|
-
// which leaf a name belongs to. Safe because the resolver has already traversed the chain
|
|
168
|
-
// to a specific leaf package; if that leaf's CEM declares a custom-element
|
|
169
|
-
// class with exactly this name, the consumer's import is the React wrapper
|
|
170
|
-
// for it.
|
|
171
|
-
for (const c of components) {
|
|
172
|
-
if (c.kind === "custom-element" && c.className === exportName)
|
|
173
|
-
return c;
|
|
174
|
-
}
|
|
175
|
-
return null;
|
|
176
|
-
}
|
|
177
|
-
// Shared walk/cache/return for `resolveLazyManifest` and
|
|
178
|
-
// `lookupExternalLeaf`. `snapshotEligible` is the only difference
|
|
179
|
-
// between the two public entry points: it decides whether the leaf
|
|
180
|
-
// manifest this call loads (or upgrades, on a cache hit below) counts
|
|
181
|
-
// toward `snapshotComponents()` / `snapshotManifestRefs()`.
|
|
182
|
-
function resolveLeaf(fromFile, specifier, exportName, options) {
|
|
183
|
-
const initialAbs = resolveImport(fromFile, specifier);
|
|
184
|
-
if (!initialAbs)
|
|
185
|
-
return null;
|
|
186
|
-
// Workspace identity rule: workspace packages that carry a `name` field in
|
|
187
|
-
// their package.json get external-style identity (packageName + exportName
|
|
188
|
-
// keys), making them cross-repo joinable just like node_modules deps.
|
|
189
|
-
// findPackageRoot skips package.json files without a `name` field, so
|
|
190
|
-
// any package it returns is guaranteed to carry an identity key.
|
|
191
|
-
//
|
|
192
|
-
// When the resolved target lands inside a named workspace package, fall
|
|
193
|
-
// through to the normal resolution path — the lazy resolver will walk the
|
|
194
|
-
// re-export chain and emit { leafPackage, modulePath } exactly as it does
|
|
195
|
-
// for node_modules packages.
|
|
196
|
-
// Resolved file lives in the same package as the importer (e.g.
|
|
197
|
-
// `../components/Foo.vue` from a sibling file in the consumer repo).
|
|
198
|
-
// The lazy resolver's contract is "external packages are opaque tuples";
|
|
199
|
-
// local files belong to the local-detection pipeline. Return null so the
|
|
200
|
-
// engine's import-resolution / localIndex path handles it. Different
|
|
201
|
-
// package names — whether resolved through node_modules or through a
|
|
202
|
-
// yarn workspace symlink — are external and continue normal resolution.
|
|
203
|
-
const fromPkg = findPackageRoot(fromFile);
|
|
204
|
-
const initialPkg = findPackageRoot(initialAbs);
|
|
205
|
-
if (fromPkg && initialPkg && fromPkg.name === initialPkg.name) {
|
|
206
|
-
return null;
|
|
207
|
-
}
|
|
208
|
-
// Entry-package provenance: the resolved specifier target sits inside
|
|
209
|
-
// the ENTRY package's
|
|
210
|
-
// installed copy — its package root is the wrapper identity + the dir
|
|
211
|
-
// whose package.json carries the installed version. Only meaningful when
|
|
212
|
-
// onEntryPackage is set (see the record call below); reuses `initialPkg`
|
|
213
|
-
// computed above rather than re-walking the same directory chain.
|
|
214
|
-
const entryRoot = opts.onEntryPackage ? initialPkg : null;
|
|
215
|
-
const cacheKey = `${initialAbs}::${exportName}`;
|
|
216
|
-
if (hitCache.has(cacheKey)) {
|
|
217
|
-
const cachedHit = hitCache.get(cacheKey) ?? null;
|
|
218
|
-
// Cache-hit upgrade: a snapshot-eligible caller (warm/Vue) landing on a
|
|
219
|
-
// hit previously resolved only by a lookup-only caller (engine leaf
|
|
220
|
-
// lookup) must retroactively flip the leaf eligible — otherwise call
|
|
221
|
-
// order decides whether the Vue lane's snapshot output changes vs main.
|
|
222
|
-
// The reverse order needs no handling: the flag is already true and
|
|
223
|
-
// sticky (never downgraded).
|
|
224
|
-
if (options.snapshotEligible && cachedHit) {
|
|
225
|
-
const leafEntry = visitedLeafs.get(cachedHit.leafPackage);
|
|
226
|
-
if (leafEntry)
|
|
227
|
-
leafEntry.snapshotEligible = true;
|
|
228
|
-
}
|
|
229
|
-
return cachedHit;
|
|
230
|
-
}
|
|
231
|
-
const visited = new Set();
|
|
232
|
-
let currentAbs = initialAbs;
|
|
233
|
-
let currentExport = exportName;
|
|
234
|
-
// Walk the re-export chain. If we advance MAX_REEXPORT_HOPS times without
|
|
235
|
-
// the chain naturally terminating (i.e. the next file would also be a
|
|
236
|
-
// barrel carrying our export), surface `chain-too-deep` and treat the
|
|
237
|
-
// current file as terminal so a wrong-leaf attribution is never silent.
|
|
238
|
-
let hops = 0;
|
|
239
|
-
while (true) {
|
|
240
|
-
const visitKey = `${currentAbs}::${currentExport}`;
|
|
241
|
-
if (visited.has(visitKey)) {
|
|
242
|
-
const cyclePkg = findPackageRoot(currentAbs)?.name;
|
|
243
|
-
collector.emit({
|
|
244
|
-
code: "cycle-detected",
|
|
245
|
-
severity: "warning",
|
|
246
|
-
filePath: toRelPath(currentAbs),
|
|
247
|
-
exportName: currentExport,
|
|
248
|
-
...(cyclePkg !== undefined ? { packageName: cyclePkg } : {}),
|
|
249
|
-
});
|
|
250
|
-
hitCache.set(cacheKey, null);
|
|
251
|
-
return null;
|
|
252
|
-
}
|
|
253
|
-
visited.add(visitKey);
|
|
254
|
-
const source = safeReadFile(currentAbs);
|
|
255
|
-
if (source === null)
|
|
256
|
-
break;
|
|
257
|
-
let reExports;
|
|
258
|
-
try {
|
|
259
|
-
const ast = parsedBarrel(currentAbs, source);
|
|
260
|
-
reExports = parseBarrelTopLevelFromAst(ast);
|
|
261
|
-
}
|
|
262
|
-
catch {
|
|
263
|
-
// parseByExt throws on unrecoverable syntax — fall back to the
|
|
264
|
-
// source-level parse, which swallows parse errors and returns an
|
|
265
|
-
// empty array so the chain terminates gracefully on garbage files.
|
|
266
|
-
reExports = parseBarrelTopLevel(source);
|
|
267
|
-
}
|
|
268
|
-
// unsupported barrel forms (try/switch-wrapped, dynamic re-exports etc.)
|
|
269
|
-
// are silently treated as terminal — the resolver returns identity from
|
|
270
|
-
// the current file and the parser falls back to opaque emission.
|
|
271
|
-
if (reExports.length === 0)
|
|
272
|
-
break; // terminal
|
|
273
|
-
// Find the re-export that carries `currentExport`.
|
|
274
|
-
const next = pickReExportFor(reExports, currentExport);
|
|
275
|
-
if (!next)
|
|
276
|
-
break; // terminal — none of the re-exports carry this export
|
|
277
|
-
const nextAbs = resolveImport(currentAbs, next.from);
|
|
278
|
-
if (!nextAbs)
|
|
279
|
-
break; // unresolvable next hop → treat current as terminal
|
|
280
|
-
// We're about to advance. If we've already consumed our budget, bail
|
|
281
|
-
// out with a diagnostic instead. `currentAbs` stays on the last barrel
|
|
282
|
-
// we successfully read so package-root walk continues from there.
|
|
283
|
-
if (hops >= MAX_REEXPORT_HOPS) {
|
|
284
|
-
const deepPkg = findPackageRoot(currentAbs)?.name;
|
|
285
|
-
collector.emit({
|
|
286
|
-
code: "chain-too-deep",
|
|
287
|
-
severity: "warning",
|
|
288
|
-
filePath: toRelPath(currentAbs),
|
|
289
|
-
exportName: currentExport,
|
|
290
|
-
depth: MAX_REEXPORT_HOPS,
|
|
291
|
-
...(deepPkg !== undefined ? { packageName: deepPkg } : {}),
|
|
292
|
-
});
|
|
293
|
-
break;
|
|
294
|
-
}
|
|
295
|
-
currentAbs = nextAbs;
|
|
296
|
-
currentExport = next.targetExport;
|
|
297
|
-
hops++;
|
|
298
|
-
}
|
|
299
|
-
// Walk up to the package root of currentAbs.
|
|
300
|
-
const pkg = findPackageRoot(currentAbs);
|
|
301
|
-
if (!pkg) {
|
|
302
|
-
hitCache.set(cacheKey, null);
|
|
303
|
-
return null;
|
|
304
|
-
}
|
|
305
|
-
const modulePath = posixPath(relative(pkg.dir, currentAbs));
|
|
306
|
-
// Fire onEntryPackage only when the walk actually crossed a
|
|
307
|
-
// package boundary (entry package name !== terminal leaf package name).
|
|
308
|
-
// Direct imports into the leaf (entryRoot.name === pkg.name) never record.
|
|
309
|
-
const recordEntry = () => {
|
|
310
|
-
if (!opts.onEntryPackage || !entryRoot || entryRoot.name === pkg.name)
|
|
311
|
-
return;
|
|
312
|
-
const target = exportName === ""
|
|
313
|
-
? { kind: "leaf-package", leafPackage: pkg.name }
|
|
314
|
-
: { kind: "identity", leafPackage: pkg.name, modulePath, exportName: currentExport };
|
|
315
|
-
opts.onEntryPackage({ name: entryRoot.name, dir: entryRoot.dir }, target);
|
|
316
|
-
};
|
|
317
|
-
// Per-package manifest gate. Identity is now computed; if the package
|
|
318
|
-
// is excluded by manifestPatterns (or no patterns set), short-circuit to
|
|
319
|
-
// identity-only emission. Caller gets {leafPackage, modulePath, matched:
|
|
320
|
-
// null}; parser falls back to opaque opportunistic emission with manifest: null.
|
|
321
|
-
if (!isManifestEligible(pkg.name)) {
|
|
322
|
-
const identityOnlyHit = {
|
|
323
|
-
leafPackage: pkg.name,
|
|
324
|
-
modulePath,
|
|
325
|
-
exportName: currentExport,
|
|
326
|
-
matched: null,
|
|
327
|
-
};
|
|
328
|
-
recordEntry();
|
|
329
|
-
hitCache.set(cacheKey, identityOnlyHit);
|
|
330
|
-
return identityOnlyHit;
|
|
331
|
-
}
|
|
332
|
-
const components = loadLeafManifest(pkg.name, pkg.dir, {
|
|
333
|
-
snapshotEligible: options.snapshotEligible,
|
|
334
|
-
});
|
|
335
|
-
const matched = matchInLeaf(components, currentExport);
|
|
336
|
-
const hit = { leafPackage: pkg.name, modulePath, exportName: currentExport, matched };
|
|
337
|
-
recordEntry();
|
|
338
|
-
hitCache.set(cacheKey, hit);
|
|
339
|
-
return hit;
|
|
340
|
-
}
|
|
341
|
-
function resolveLazyManifest(fromFile, specifier, exportName) {
|
|
342
|
-
return resolveLeaf(fromFile, specifier, exportName, { snapshotEligible: true });
|
|
343
|
-
}
|
|
344
|
-
// Engine-adapter entry point: identical walk/cache/return to
|
|
345
|
-
// `resolveLazyManifest`, but snapshot-INELIGIBLE — see `resolveLeaf`.
|
|
346
|
-
//
|
|
347
|
-
// ORDERING DEPENDENCY: leaf loads triggered here still index tags into the
|
|
348
|
-
// shared `byTag` map. That never leaks into tag-lane output only because
|
|
349
|
-
// every plugin.parse() (the sole lookupByTag consumer) completes before the
|
|
350
|
-
// engine resolve phase that calls this. If parse and resolve ever
|
|
351
|
-
// interleave (e.g. a per-file single-pass refactor), byTag population must
|
|
352
|
-
// be scoped to snapshot-eligible visits too — nothing needs it unscoped
|
|
353
|
-
// (lookupReactWrapper reads visitedLeafs.components, not byTag).
|
|
354
|
-
function lookupExternalLeaf(fromFile, specifier, exportName) {
|
|
355
|
-
return resolveLeaf(fromFile, specifier, exportName, { snapshotEligible: false });
|
|
356
|
-
}
|
|
357
|
-
function resolveLocalExport(filePath, exportName) {
|
|
358
|
-
// Accept either repo-relative or absolute input; normalise to absolute for
|
|
359
|
-
// the walk. Output is always repo-relative POSIX so the caller's
|
|
360
|
-
// `localIndex.byPath` lookup matches the same key form local-index uses.
|
|
361
|
-
const entryAbs = isAbsolute(filePath)
|
|
362
|
-
? filePath
|
|
363
|
-
: (repoRoot ? pathResolve(repoRoot, filePath) : filePath);
|
|
364
|
-
const entryPkg = findPackageRoot(entryAbs);
|
|
365
|
-
const visited = new Set();
|
|
366
|
-
let currentAbs = entryAbs;
|
|
367
|
-
let currentExport = exportName;
|
|
368
|
-
let hops = 0;
|
|
369
|
-
while (true) {
|
|
370
|
-
const visitKey = `${currentAbs}::${currentExport}`;
|
|
371
|
-
if (visited.has(visitKey)) {
|
|
372
|
-
const cyclePkg = findPackageRoot(currentAbs)?.name;
|
|
373
|
-
collector.emit({
|
|
374
|
-
code: "cycle-detected",
|
|
375
|
-
severity: "warning",
|
|
376
|
-
filePath: toRelPath(currentAbs),
|
|
377
|
-
exportName: currentExport,
|
|
378
|
-
...(cyclePkg !== undefined ? { packageName: cyclePkg } : {}),
|
|
379
|
-
});
|
|
380
|
-
return null;
|
|
381
|
-
}
|
|
382
|
-
visited.add(visitKey);
|
|
383
|
-
const source = safeReadFile(currentAbs);
|
|
384
|
-
if (source === null)
|
|
385
|
-
return null;
|
|
386
|
-
let reExports;
|
|
387
|
-
try {
|
|
388
|
-
const ast = parsedBarrel(currentAbs, source);
|
|
389
|
-
reExports = parseBarrelTopLevelFromAst(ast);
|
|
390
|
-
}
|
|
391
|
-
catch {
|
|
392
|
-
reExports = parseBarrelTopLevel(source);
|
|
393
|
-
}
|
|
394
|
-
if (reExports.length === 0) {
|
|
395
|
-
return { filePath: toRelPath(currentAbs), exportName: currentExport };
|
|
396
|
-
}
|
|
397
|
-
const next = pickReExportFor(reExports, currentExport);
|
|
398
|
-
if (!next) {
|
|
399
|
-
return { filePath: toRelPath(currentAbs), exportName: currentExport };
|
|
400
|
-
}
|
|
401
|
-
const nextAbs = resolveImport(currentAbs, next.from);
|
|
402
|
-
if (!nextAbs)
|
|
403
|
-
return null;
|
|
404
|
-
const nextPkg = findPackageRoot(nextAbs);
|
|
405
|
-
if (entryPkg && nextPkg && entryPkg.name !== nextPkg.name) {
|
|
406
|
-
return null;
|
|
407
|
-
}
|
|
408
|
-
if (hops >= MAX_REEXPORT_HOPS) {
|
|
409
|
-
const deepPkg = findPackageRoot(currentAbs)?.name;
|
|
410
|
-
collector.emit({
|
|
411
|
-
code: "chain-too-deep",
|
|
412
|
-
severity: "warning",
|
|
413
|
-
filePath: toRelPath(currentAbs),
|
|
414
|
-
exportName: currentExport,
|
|
415
|
-
depth: MAX_REEXPORT_HOPS,
|
|
416
|
-
...(deepPkg !== undefined ? { packageName: deepPkg } : {}),
|
|
417
|
-
});
|
|
418
|
-
return null;
|
|
419
|
-
}
|
|
420
|
-
currentAbs = nextAbs;
|
|
421
|
-
currentExport = next.targetExport;
|
|
422
|
-
hops++;
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
function lookupByTag(tagName) {
|
|
426
|
-
return byTag.get(tagName) ?? null;
|
|
427
|
-
}
|
|
428
|
-
function lookupReactWrapper(packageName, exportName) {
|
|
429
|
-
if (!isManifestEligible(packageName))
|
|
430
|
-
return null;
|
|
431
|
-
const cached = visitedLeafs.get(packageName);
|
|
432
|
-
if (!cached)
|
|
433
|
-
return null;
|
|
434
|
-
for (const c of cached.components) {
|
|
435
|
-
if (c.kind === "custom-element" && c.className === exportName) {
|
|
436
|
-
return { tagName: c.tagName, packageName };
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
return null;
|
|
440
|
-
}
|
|
441
|
-
function snapshotComponents() {
|
|
442
|
-
const out = [];
|
|
443
|
-
for (const v of visitedLeafs.values()) {
|
|
444
|
-
if (!v.snapshotEligible)
|
|
445
|
-
continue;
|
|
446
|
-
out.push(...v.components);
|
|
447
|
-
}
|
|
448
|
-
return out;
|
|
449
|
-
}
|
|
450
|
-
function snapshotManifestRefs() {
|
|
451
|
-
const out = [];
|
|
452
|
-
for (const v of visitedLeafs.values()) {
|
|
453
|
-
if (!v.snapshotEligible)
|
|
454
|
-
continue;
|
|
455
|
-
if (v.manifestRef.path)
|
|
456
|
-
out.push(v.manifestRef);
|
|
457
|
-
}
|
|
458
|
-
return out;
|
|
459
|
-
}
|
|
460
|
-
function eagerLoadRoots(packageNames) {
|
|
461
|
-
// Anchor at <repoRoot>/_ so Node's resolution walks up through
|
|
462
|
-
// <repoRoot>/node_modules and parents, mirroring resolve-import.ts.
|
|
463
|
-
const anchor = pathResolve(opts.repoRoot ?? process.cwd(), "_");
|
|
464
|
-
const requireFromRepo = createRequire(anchor);
|
|
465
|
-
for (const name of packageNames) {
|
|
466
|
-
if (visitedLeafs.has(name))
|
|
467
|
-
continue;
|
|
468
|
-
// Honour the per-package manifest gate. Packages excluded by
|
|
469
|
-
// manifestPatterns don't get their CEM eagerly loaded — keeps the
|
|
470
|
-
// byTag map empty for them so HTML/Vue-template tag lookups also
|
|
471
|
-
// return null.
|
|
472
|
-
if (!isManifestEligible(name))
|
|
473
|
-
continue;
|
|
474
|
-
try {
|
|
475
|
-
const pkgJsonPath = requireFromRepo.resolve(`${name}/package.json`);
|
|
476
|
-
loadLeafManifest(name, dirname(pkgJsonPath), { snapshotEligible: true });
|
|
477
|
-
}
|
|
478
|
-
catch {
|
|
479
|
-
// Package not installed or its package.json not exposed via exports —
|
|
480
|
-
// skip silently. Warm-up is best-effort; missing entries are fine.
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
// The factory returns a LazyResolver. `lookupByTag` is captured in a closure
|
|
485
|
-
// and only attached when the caller goes through `.warm(...)` to obtain a
|
|
486
|
-
// WarmedResolver. Calling `.warm([])` on an identity-only resolver returns a
|
|
487
|
-
// structurally-valid WarmedResolver whose `lookupByTag` always returns null
|
|
488
|
-
// (the byTag map stays empty when no manifestPatterns match).
|
|
489
|
-
const base = {
|
|
490
|
-
resolveLazyManifest,
|
|
491
|
-
lookupExternalLeaf,
|
|
492
|
-
resolveLocalExport,
|
|
493
|
-
snapshotComponents,
|
|
494
|
-
snapshotManifestRefs,
|
|
495
|
-
diagnostics: () => collector.drain(),
|
|
496
|
-
warm(packageNames) {
|
|
497
|
-
eagerLoadRoots(packageNames);
|
|
498
|
-
return {
|
|
499
|
-
...base,
|
|
500
|
-
lookupByTag,
|
|
501
|
-
lookupReactWrapper,
|
|
502
|
-
};
|
|
503
|
-
},
|
|
504
|
-
_barrelParseCount(absPath) {
|
|
505
|
-
return barrelParseCounts.get(absPath) ?? 0;
|
|
506
|
-
},
|
|
507
|
-
};
|
|
508
|
-
return base;
|
|
509
|
-
}
|
|
510
|
-
// ---------------------------------------------------------------------------
|
|
511
|
-
// Helpers
|
|
512
|
-
// ---------------------------------------------------------------------------
|
|
513
|
-
function safeReadFile(path) {
|
|
514
|
-
try {
|
|
515
|
-
if (!statSync(path).isFile())
|
|
516
|
-
return null;
|
|
517
|
-
return readFileSync(path, "utf8");
|
|
518
|
-
}
|
|
519
|
-
catch {
|
|
520
|
-
return null;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
function pickReExportFor(reExports, exportName) {
|
|
524
|
-
// Named re-export carrying our export wins over star re-exports.
|
|
525
|
-
for (const re of reExports) {
|
|
526
|
-
if (re.kind === "named") {
|
|
527
|
-
const found = re.names.find((n) => n.exported === exportName);
|
|
528
|
-
if (found)
|
|
529
|
-
return { from: re.from, targetExport: found.local };
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
// Star re-export: any star may carry the export; resolver tries the first
|
|
533
|
-
// and its terminal will tell us whether the leaf has it. v1 picks the first
|
|
534
|
-
// star — multi-star ambiguity in the same file is rare and a `barrel-
|
|
535
|
-
// unsupported-form` diagnostic could be added in a patch if real cases
|
|
536
|
-
// surface.
|
|
537
|
-
for (const re of reExports) {
|
|
538
|
-
if (re.kind === "star")
|
|
539
|
-
return { from: re.from, targetExport: exportName };
|
|
540
|
-
}
|
|
541
|
-
return null;
|
|
542
|
-
}
|
|
543
|
-
function absorbCemDeclarations(cem, packageName) {
|
|
544
|
-
const out = [];
|
|
545
|
-
for (const mod of cem.modules ?? []) {
|
|
546
|
-
for (const decl of mod.declarations ?? []) {
|
|
547
|
-
const d = decl;
|
|
548
|
-
if (!d.customElement || !d.tagName || !d.name)
|
|
549
|
-
continue;
|
|
550
|
-
const props = buildPropsFromCem(d);
|
|
551
|
-
const events = buildEventsFromCem(d);
|
|
552
|
-
const slots = buildSlotsFromCem(d);
|
|
553
|
-
const componentLifecycle = buildLifecycleFromDeprecated(d.deprecated);
|
|
554
|
-
const entry = {
|
|
555
|
-
kind: "custom-element",
|
|
556
|
-
tagName: d.tagName,
|
|
557
|
-
source: { type: "external", package: packageName },
|
|
558
|
-
props,
|
|
559
|
-
events,
|
|
560
|
-
slots,
|
|
561
|
-
className: d.name,
|
|
562
|
-
};
|
|
563
|
-
if (d.description !== undefined)
|
|
564
|
-
entry.description = d.description;
|
|
565
|
-
if (componentLifecycle !== undefined)
|
|
566
|
-
entry.lifecycle = componentLifecycle;
|
|
567
|
-
out.push(entry);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
return out;
|
|
571
|
-
}
|
|
572
|
-
function buildPropsFromCem(decl) {
|
|
573
|
-
const props = [];
|
|
574
|
-
const seen = new Set();
|
|
575
|
-
// Pass 1: `attributes[]` are the canonical source for prop names + values.
|
|
576
|
-
for (const attr of decl.attributes ?? []) {
|
|
577
|
-
if (!attr.name || seen.has(attr.name))
|
|
578
|
-
continue;
|
|
579
|
-
seen.add(attr.name);
|
|
580
|
-
props.push(buildPropFromCemField(attr));
|
|
581
|
-
}
|
|
582
|
-
// Pass 2: `members[]` of `kind: "field"` fall through for any field that
|
|
583
|
-
// doesn't have an attribute counterpart (DOM-only properties). Mirror the
|
|
584
|
-
// privacy gate from before — private fields stay out.
|
|
585
|
-
for (const member of decl.members ?? []) {
|
|
586
|
-
if (member.kind !== "field" || member.privacy === "private")
|
|
587
|
-
continue;
|
|
588
|
-
if (!member.name || seen.has(member.name))
|
|
589
|
-
continue;
|
|
590
|
-
seen.add(member.name);
|
|
591
|
-
props.push(buildPropFromCemField(member));
|
|
592
|
-
}
|
|
593
|
-
return props;
|
|
594
|
-
}
|
|
595
|
-
function buildPropFromCemField(field) {
|
|
596
|
-
// `field.name` is asserted by the caller (gating happens in the loops above).
|
|
597
|
-
const prop = { name: field.name };
|
|
598
|
-
if (field.type?.text !== undefined)
|
|
599
|
-
prop.type = field.type.text;
|
|
600
|
-
// CEM declares `default` as the source-form string of the field's
|
|
601
|
-
// initializer (e.g. "'medium'" for a string literal, "42" for a
|
|
602
|
-
// number). Pass through as-is; rollup's `defaultApplied` matcher
|
|
603
|
-
// only checks for !== undefined, and richer coercion is a separate
|
|
604
|
-
// display concern tracked downstream.
|
|
605
|
-
if (field.default !== undefined)
|
|
606
|
-
prop.default = field.default;
|
|
607
|
-
if (field.description !== undefined)
|
|
608
|
-
prop.description = field.description;
|
|
609
|
-
const values = parseStringUnionValues(field.type?.text);
|
|
610
|
-
if (values !== undefined)
|
|
611
|
-
prop.values = values;
|
|
612
|
-
const lifecycle = buildLifecycleFromDeprecated(field.deprecated);
|
|
613
|
-
if (lifecycle !== undefined)
|
|
614
|
-
prop.lifecycle = lifecycle;
|
|
615
|
-
return prop;
|
|
616
|
-
}
|
|
617
|
-
function buildEventsFromCem(decl) {
|
|
618
|
-
const events = [];
|
|
619
|
-
for (const e of decl.events ?? []) {
|
|
620
|
-
if (!e.name)
|
|
621
|
-
continue;
|
|
622
|
-
const event = { name: e.name };
|
|
623
|
-
if (e.type?.text !== undefined)
|
|
624
|
-
event.payloadType = e.type.text;
|
|
625
|
-
if (e.description !== undefined)
|
|
626
|
-
event.description = e.description;
|
|
627
|
-
const lifecycle = buildLifecycleFromDeprecated(e.deprecated);
|
|
628
|
-
if (lifecycle !== undefined)
|
|
629
|
-
event.lifecycle = lifecycle;
|
|
630
|
-
events.push(event);
|
|
631
|
-
}
|
|
632
|
-
return events;
|
|
633
|
-
}
|
|
634
|
-
function buildSlotsFromCem(decl) {
|
|
635
|
-
const slots = [];
|
|
636
|
-
for (const s of decl.slots ?? []) {
|
|
637
|
-
const slot = { name: s.name ?? "" };
|
|
638
|
-
if (s.description !== undefined)
|
|
639
|
-
slot.description = s.description;
|
|
640
|
-
const lifecycle = buildLifecycleFromDeprecated(s.deprecated);
|
|
641
|
-
if (lifecycle !== undefined)
|
|
642
|
-
slot.lifecycle = lifecycle;
|
|
643
|
-
slots.push(slot);
|
|
644
|
-
}
|
|
645
|
-
return slots;
|
|
646
|
-
}
|
|
647
|
-
/**
|
|
648
|
-
* CEM `deprecated` is `true` (deprecated, no reason) or a reason string.
|
|
649
|
-
* Both shape into a `Lifecycle` with status: "deprecated"; `false` / undefined
|
|
650
|
-
* leave the lifecycle unset (consumers default to "stable" when absent).
|
|
651
|
-
*/
|
|
652
|
-
function buildLifecycleFromDeprecated(deprecated) {
|
|
653
|
-
if (deprecated === undefined || deprecated === false)
|
|
654
|
-
return undefined;
|
|
655
|
-
if (typeof deprecated === "string") {
|
|
656
|
-
return { status: "deprecated", deprecationReason: deprecated };
|
|
657
|
-
}
|
|
658
|
-
return { status: "deprecated" };
|
|
659
|
-
}
|
|
660
|
-
/**
|
|
661
|
-
* Parse a CEM `type.text` like `"'small' | 'medium' | 'large'"` into the
|
|
662
|
-
* declared allowed values `["small", "medium", "large"]`. Only returns a
|
|
663
|
-
* result when EVERY `|`-separated part is a single-quoted or double-quoted
|
|
664
|
-
* string literal (mixed unions like `"'small' | number"` return undefined).
|
|
665
|
-
*/
|
|
666
|
-
function parseStringUnionValues(typeText) {
|
|
667
|
-
if (!typeText)
|
|
668
|
-
return undefined;
|
|
669
|
-
const parts = typeText.split("|").map((s) => s.trim());
|
|
670
|
-
const stringLiterals = parts
|
|
671
|
-
.map((p) => {
|
|
672
|
-
const m = /^['"](.*)['"]$/.exec(p);
|
|
673
|
-
return m ? m[1] : null;
|
|
674
|
-
})
|
|
675
|
-
.filter((v) => v !== null);
|
|
676
|
-
return stringLiterals.length === parts.length && stringLiterals.length > 0
|
|
677
|
-
? stringLiterals
|
|
678
|
-
: undefined;
|
|
679
|
-
}
|
|
680
|
-
function absorbCcmComponents(manifest, packageName) {
|
|
681
|
-
const out = [];
|
|
682
|
-
for (const c of manifest.components) {
|
|
683
|
-
if (c.kind === "custom-element")
|
|
684
|
-
continue;
|
|
685
|
-
if (c.kind !== "react-component" && c.kind !== "vue-component")
|
|
686
|
-
continue;
|
|
687
|
-
if (!c.export)
|
|
688
|
-
continue;
|
|
689
|
-
const externalSrc = { type: "external", package: packageName };
|
|
690
|
-
// Thread `default` and `type` from each CCM-declared prop through to the
|
|
691
|
-
// absorbed IndexedComponent. Mirrors `absorbCemDeclarations`' members[]
|
|
692
|
-
// handling so the `defaultApplied` rollup matcher fires for CCM-sourced
|
|
693
|
-
// consumers (hand-authored component-compass-manifest.json) on parity with
|
|
694
|
-
// CEM-sourced ones.
|
|
695
|
-
const props = (c.props ?? []).map((p) => {
|
|
696
|
-
const absorbed = { name: p.name };
|
|
697
|
-
if (p.type !== undefined)
|
|
698
|
-
absorbed.type = p.type;
|
|
699
|
-
if (p.default !== undefined)
|
|
700
|
-
absorbed.default = p.default;
|
|
701
|
-
return absorbed;
|
|
702
|
-
});
|
|
703
|
-
out.push({
|
|
704
|
-
kind: c.kind,
|
|
705
|
-
export: c.export,
|
|
706
|
-
source: externalSrc,
|
|
707
|
-
props,
|
|
708
|
-
});
|
|
709
|
-
}
|
|
710
|
-
return out;
|
|
711
|
-
}
|
|
712
|
-
//# sourceMappingURL=lazy-resolver.js.map
|