@fragments-sdk/cli 0.9.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.d.ts +1 -0
- package/dist/bin.js +435 -67
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-BW3ZATBW.js → chunk-566BNPQZ.js} +3 -5
- package/dist/chunk-566BNPQZ.js.map +1 -0
- package/dist/{chunk-5GT62FCB.js → chunk-CAMXG5HJ.js} +5 -5
- package/dist/chunk-D2CDBRNU.js +2 -0
- package/dist/{chunk-YMPGYEWK.js → chunk-D5PYOXEI.js} +2 -2
- package/dist/{chunk-GF6OVPIN.js → chunk-OQO55NKV.js} +405 -34
- package/dist/chunk-OQO55NKV.js.map +1 -0
- package/dist/{chunk-TOIE7VXF.js → chunk-PW7QTQA6.js} +2 -2
- package/dist/{chunk-AWYCDRPG.js → chunk-WXSR2II7.js} +2 -2
- package/dist/chunk-WXSR2II7.js.map +1 -0
- package/dist/{chunk-D7372LQX.js → chunk-ZDA3PLQ6.js} +8 -12
- package/dist/chunk-ZDA3PLQ6.js.map +1 -0
- package/dist/core/index.d.ts +1 -2194
- package/dist/core/index.js +22 -27
- package/dist/{discovery-Z4RDDFVR.js → discovery-NEOY4MPN.js} +3 -3
- package/dist/{generate-LQA2R7FN.js → generate-BGKTKO6E.js} +5 -7
- package/dist/{generate-LQA2R7FN.js.map → generate-BGKTKO6E.js.map} +1 -1
- package/dist/index.d.ts +3 -5
- package/dist/index.js +7 -9
- package/dist/index.js.map +1 -1
- package/dist/{init-2GEGVIUQ.js → init-Q53R5Q2T.js} +58 -6
- package/dist/init-Q53R5Q2T.js.map +1 -0
- package/dist/mcp-bin.js +5 -8
- package/dist/mcp-bin.js.map +1 -1
- package/dist/scan-OQU7M4GH.js +14 -0
- package/dist/scan-generate-T5QNUG7N.js +691 -0
- package/dist/scan-generate-T5QNUG7N.js.map +1 -0
- package/dist/{service-XP2EAJXD.js → service-TQYWY65E.js} +4 -6
- package/dist/{static-viewer-XCS7UJTO.js → static-viewer-NUBFPKWH.js} +4 -6
- package/dist/{test-TD6TJNVY.js → test-2CSOSS3B.js} +4 -5
- package/dist/{test-TD6TJNVY.js.map → test-2CSOSS3B.js.map} +1 -1
- package/dist/{tokens-2EXPCVP3.js → tokens-DXEGYTOJ.js} +6 -8
- package/dist/{tokens-2EXPCVP3.js.map → tokens-DXEGYTOJ.js.map} +1 -1
- package/dist/{viewer-RFA2KVBG.js → viewer-DBEPYM3G.js} +16 -19
- package/dist/viewer-DBEPYM3G.js.map +1 -0
- package/package.json +2 -1
- package/src/bin.ts +33 -1
- package/src/build.ts +1 -1
- package/src/commands/__tests__/scan-generate.test.ts +308 -0
- package/src/commands/init.ts +72 -5
- package/src/commands/perf.ts +1 -1
- package/src/commands/scan-generate.ts +1013 -0
- package/src/commands/setup.ts +499 -0
- package/src/core/auto-props.ts +1 -1
- package/src/core/bundle-measurer.ts +2 -2
- package/src/core/config.ts +2 -3
- package/src/core/discovery.ts +2 -2
- package/src/core/generators/context.ts +1 -1
- package/src/core/generators/registry.ts +3 -3
- package/src/core/generators/typescript-extractor.ts +1 -1
- package/src/core/graph-extractor.ts +1 -1
- package/src/core/index.ts +3 -205
- package/src/core/loader.ts +2 -2
- package/src/core/parser.ts +1 -1
- package/src/core/previewLoader.ts +1 -1
- package/src/index.ts +2 -2
- package/src/service/snippet-validation.test.ts +1 -1
- package/src/service/snippet-validation.ts +2 -2
- package/src/viewer/__tests__/viewer-integration.test.ts +3 -9
- package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss +2 -10
- package/src/viewer/vite-plugin.ts +1 -1
- package/dist/chunk-AWYCDRPG.js.map +0 -1
- package/dist/chunk-BW3ZATBW.js.map +0 -1
- package/dist/chunk-D7372LQX.js.map +0 -1
- package/dist/chunk-EKLMXTWU.js +0 -80
- package/dist/chunk-EKLMXTWU.js.map +0 -1
- package/dist/chunk-EZYXYWNF.js +0 -131
- package/dist/chunk-EZYXYWNF.js.map +0 -1
- package/dist/chunk-GF6OVPIN.js.map +0 -1
- package/dist/chunk-NVSPGSKB.js +0 -203
- package/dist/chunk-NVSPGSKB.js.map +0 -1
- package/dist/defineFragment-CBMS7Bab.d.ts +0 -685
- package/dist/init-2GEGVIUQ.js.map +0 -1
- package/dist/scan-JGS65S7P.js +0 -16
- package/dist/storyFilters-3LUYAFZF.js +0 -15
- package/dist/viewer-RFA2KVBG.js.map +0 -1
- package/src/core/__tests__/preview-runtime.test.tsx +0 -111
- package/src/core/composition.test.ts +0 -262
- package/src/core/composition.ts +0 -318
- package/src/core/constants.ts +0 -114
- package/src/core/context.ts +0 -2
- package/src/core/defineFragment.ts +0 -141
- package/src/core/figma.ts +0 -263
- package/src/core/fragment-types.ts +0 -214
- package/src/core/performance-presets.ts +0 -142
- package/src/core/preview-runtime.tsx +0 -144
- package/src/core/schema.ts +0 -229
- package/src/core/storyAdapter.test.ts +0 -571
- package/src/core/storyAdapter.ts +0 -761
- package/src/core/storyFilters.test.ts +0 -350
- package/src/core/storyFilters.ts +0 -253
- package/src/core/storybook-csf.ts +0 -11
- package/src/core/token-parser.ts +0 -321
- package/src/core/token-types.ts +0 -287
- package/src/core/types.ts +0 -784
- /package/dist/{chunk-5GT62FCB.js.map → chunk-CAMXG5HJ.js.map} +0 -0
- /package/dist/{discovery-Z4RDDFVR.js.map → chunk-D2CDBRNU.js.map} +0 -0
- /package/dist/{chunk-YMPGYEWK.js.map → chunk-D5PYOXEI.js.map} +0 -0
- /package/dist/{chunk-TOIE7VXF.js.map → chunk-PW7QTQA6.js.map} +0 -0
- /package/dist/{scan-JGS65S7P.js.map → discovery-NEOY4MPN.js.map} +0 -0
- /package/dist/{service-XP2EAJXD.js.map → scan-OQU7M4GH.js.map} +0 -0
- /package/dist/{static-viewer-XCS7UJTO.js.map → service-TQYWY65E.js.map} +0 -0
- /package/dist/{storyFilters-3LUYAFZF.js.map → static-viewer-NUBFPKWH.js.map} +0 -0
package/src/core/index.ts
CHANGED
|
@@ -1,207 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* @deprecated Import from '@fragments-sdk/core' directly.
|
|
3
|
+
* This re-export exists for backwards compatibility with '@fragments-sdk/cli/core'.
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
// Brand and default constants
|
|
7
|
-
export { BRAND, DEFAULTS } from "./constants.js";
|
|
8
|
-
export type { Brand, Defaults } from "./constants.js";
|
|
9
|
-
|
|
10
|
-
// Types
|
|
11
|
-
export type {
|
|
12
|
-
FragmentComponent,
|
|
13
|
-
FragmentMeta,
|
|
14
|
-
FragmentUsage,
|
|
15
|
-
PropType,
|
|
16
|
-
PropDefinition,
|
|
17
|
-
ControlType,
|
|
18
|
-
RelationshipType,
|
|
19
|
-
ComponentRelation,
|
|
20
|
-
VariantLoader,
|
|
21
|
-
PlayFunction,
|
|
22
|
-
PlayFunctionContext,
|
|
23
|
-
FragmentVariant,
|
|
24
|
-
FragmentDefinition,
|
|
25
|
-
FragmentsConfig,
|
|
26
|
-
SnippetPolicyConfig,
|
|
27
|
-
RegistryOptions,
|
|
28
|
-
CompiledFragment,
|
|
29
|
-
CompiledFragmentsFile,
|
|
30
|
-
BlockDefinition,
|
|
31
|
-
CompiledBlock,
|
|
32
|
-
RecipeDefinition, // @deprecated - use BlockDefinition
|
|
33
|
-
CompiledRecipe, // @deprecated - use CompiledBlock
|
|
34
|
-
// Contract and provenance types
|
|
35
|
-
FragmentContract,
|
|
36
|
-
FragmentGenerated,
|
|
37
|
-
// AI metadata type
|
|
38
|
-
AIMetadata,
|
|
39
|
-
// Screenshot types
|
|
40
|
-
ScreenshotConfig,
|
|
41
|
-
ServiceConfig,
|
|
42
|
-
Viewport,
|
|
43
|
-
Theme,
|
|
44
|
-
Screenshot,
|
|
45
|
-
ScreenshotMetadata,
|
|
46
|
-
DiffResult,
|
|
47
|
-
BoundingBox,
|
|
48
|
-
BaselineInfo,
|
|
49
|
-
Manifest,
|
|
50
|
-
VerifyRequest,
|
|
51
|
-
VerifyResult,
|
|
52
|
-
// Figma property mapping types
|
|
53
|
-
FigmaPropMapping,
|
|
54
|
-
FigmaStringMapping,
|
|
55
|
-
FigmaBooleanMapping,
|
|
56
|
-
FigmaEnumMapping,
|
|
57
|
-
FigmaInstanceMapping,
|
|
58
|
-
FigmaChildrenMapping,
|
|
59
|
-
FigmaTextContentMapping,
|
|
60
|
-
// Storybook filter configuration
|
|
61
|
-
StorybookFilterConfig,
|
|
62
|
-
// Token configuration
|
|
63
|
-
TokenConfig,
|
|
64
|
-
// Compiled token types
|
|
65
|
-
CompiledTokenEntry,
|
|
66
|
-
CompiledTokenData,
|
|
67
|
-
} from "./types.js";
|
|
68
|
-
|
|
69
|
-
// Performance presets
|
|
70
|
-
export {
|
|
71
|
-
resolvePerformanceConfig,
|
|
72
|
-
classifyComplexity,
|
|
73
|
-
formatBytes,
|
|
74
|
-
budgetBar,
|
|
75
|
-
PRESET_NAMES,
|
|
76
|
-
} from "./performance-presets.js";
|
|
77
|
-
export type {
|
|
78
|
-
PerformanceBudgets,
|
|
79
|
-
PerformanceConfig,
|
|
80
|
-
ComplexityTier,
|
|
81
|
-
PerformanceData as PerfData,
|
|
82
|
-
PerformanceSummary as PerfSummary,
|
|
83
|
-
} from "./performance-presets.js";
|
|
84
|
-
|
|
85
|
-
// Token types
|
|
86
|
-
export type {
|
|
87
|
-
TokenCategory,
|
|
88
|
-
DesignToken,
|
|
89
|
-
TokenRegistry,
|
|
90
|
-
TokenRegistryMeta,
|
|
91
|
-
EnhancedStyleDiffItem,
|
|
92
|
-
TokenFix,
|
|
93
|
-
TokenParseResult,
|
|
94
|
-
TokenParseError,
|
|
95
|
-
TokenMatchRequest,
|
|
96
|
-
TokenMatchResult,
|
|
97
|
-
TokenUsageSummary,
|
|
98
|
-
} from "./token-types.js";
|
|
99
|
-
|
|
100
|
-
// Schema validation (Zod is browser-safe)
|
|
101
|
-
export {
|
|
102
|
-
fragmentMetaSchema,
|
|
103
|
-
fragmentUsageSchema,
|
|
104
|
-
propDefinitionSchema,
|
|
105
|
-
componentRelationSchema,
|
|
106
|
-
fragmentVariantSchema,
|
|
107
|
-
fragmentDefinitionSchema,
|
|
108
|
-
fragmentsConfigSchema,
|
|
109
|
-
figmaPropMappingSchema,
|
|
110
|
-
// Contract and provenance schemas
|
|
111
|
-
fragmentContractSchema,
|
|
112
|
-
fragmentGeneratedSchema,
|
|
113
|
-
fragmentBanSchema,
|
|
114
|
-
blockDefinitionSchema,
|
|
115
|
-
recipeDefinitionSchema, // @deprecated - use blockDefinitionSchema
|
|
116
|
-
// AI metadata schema
|
|
117
|
-
aiMetadataSchema,
|
|
118
|
-
} from "./schema.js";
|
|
119
|
-
|
|
120
|
-
// Main API
|
|
121
|
-
export { defineFragment, compileFragment, defineBlock, compileBlock, defineRecipe, compileRecipe } from "./defineFragment.js";
|
|
122
|
-
export type { InferProps } from "./defineFragment.js";
|
|
123
|
-
|
|
124
|
-
// Story adapter (runtime conversion of Storybook modules)
|
|
125
|
-
export {
|
|
126
|
-
storyModuleToFragment,
|
|
127
|
-
setPreviewConfig,
|
|
128
|
-
getPreviewConfig,
|
|
129
|
-
// Re-export @storybook/csf utilities
|
|
130
|
-
toId,
|
|
131
|
-
storyNameFromExport,
|
|
132
|
-
isExportStory,
|
|
133
|
-
} from "./storyAdapter.js";
|
|
134
|
-
export type {
|
|
135
|
-
StoryModule,
|
|
136
|
-
StoryMeta,
|
|
137
|
-
Story,
|
|
138
|
-
StoryArgType,
|
|
139
|
-
StoryContext,
|
|
140
|
-
Decorator,
|
|
141
|
-
Loader,
|
|
142
|
-
PreviewConfig,
|
|
143
|
-
CSF2Story,
|
|
144
|
-
} from "./storyAdapter.js";
|
|
145
|
-
|
|
146
|
-
// Storybook adapter filtering
|
|
147
|
-
export {
|
|
148
|
-
checkStoryExclusion,
|
|
149
|
-
detectSubComponentPaths,
|
|
150
|
-
isForceIncluded,
|
|
151
|
-
isConfigExcluded,
|
|
152
|
-
} from "./storyFilters.js";
|
|
153
|
-
export type {
|
|
154
|
-
ExclusionReason,
|
|
155
|
-
ExclusionResult,
|
|
156
|
-
CheckStoryExclusionOpts,
|
|
157
|
-
} from "./storyFilters.js";
|
|
158
|
-
|
|
159
|
-
// Context generation for AI agents
|
|
160
|
-
export { generateContext } from "./context.js";
|
|
161
|
-
export type { ContextOptions, ContextResult } from "./context.js";
|
|
162
|
-
|
|
163
|
-
// Figma property mapping DSL
|
|
164
|
-
export { figma, isFigmaPropMapping, resolveFigmaMapping } from "./figma.js";
|
|
165
|
-
|
|
166
|
-
// Fragment JSON types (for .fragment.json files)
|
|
167
|
-
export type {
|
|
168
|
-
Fragment,
|
|
169
|
-
FragmentFigma,
|
|
170
|
-
FragmentUsage as FragmentJsonUsage,
|
|
171
|
-
FragmentDoNotItem,
|
|
172
|
-
FragmentPattern,
|
|
173
|
-
FragmentAccessibility,
|
|
174
|
-
FragmentRelated,
|
|
175
|
-
FragmentMeta as FragmentJsonMeta,
|
|
176
|
-
FragmentIndex,
|
|
177
|
-
FragmentRegistry,
|
|
178
|
-
RegistryComponentEntry,
|
|
179
|
-
RegistryPropEntry,
|
|
180
|
-
FragmentContextOptions,
|
|
181
|
-
} from "./fragment-types.js";
|
|
182
|
-
|
|
183
|
-
// Token parsing
|
|
184
|
-
export { parseTokenFile } from "./token-parser.js";
|
|
185
|
-
export type { ParsedToken, TokenParseOutput } from "./token-parser.js";
|
|
186
|
-
|
|
187
|
-
// Composition analysis
|
|
188
|
-
export { analyzeComposition } from "./composition.js";
|
|
189
|
-
export type {
|
|
190
|
-
CompositionAnalysis,
|
|
191
|
-
CompositionWarning,
|
|
192
|
-
CompositionSuggestion,
|
|
193
|
-
CompositionGuideline,
|
|
194
|
-
} from "./composition.js";
|
|
195
|
-
|
|
196
|
-
// Shared preview runtime
|
|
197
|
-
export {
|
|
198
|
-
executeVariantLoaders,
|
|
199
|
-
resolvePreviewRuntimeState,
|
|
200
|
-
usePreviewVariantRuntime,
|
|
201
|
-
PreviewVariantRuntime,
|
|
202
|
-
} from "./preview-runtime.js";
|
|
203
|
-
export type {
|
|
204
|
-
PreviewVariantLike,
|
|
205
|
-
PreviewRuntimeState,
|
|
206
|
-
PreviewRuntimeOptions,
|
|
207
|
-
} from "./preview-runtime.js";
|
|
5
|
+
export * from '@fragments-sdk/core';
|
package/src/core/loader.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { writeFile, unlink } from 'node:fs/promises';
|
|
|
2
2
|
import { dirname, basename, join } from 'node:path';
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
4
|
import { build, type Plugin } from 'esbuild';
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
5
|
+
import { BRAND } from '@fragments-sdk/core';
|
|
6
|
+
import type { FragmentDefinition } from '@fragments-sdk/core';
|
|
7
7
|
|
|
8
8
|
// Inline implementation of defineFragment that will be injected into bundled files
|
|
9
9
|
// This allows fragment files to work without @fragments/core being installed
|
package/src/core/parser.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import ts from "typescript";
|
|
11
|
-
import type { FragmentMeta, FragmentUsage, PropDefinition, AIMetadata, FragmentContract } from
|
|
11
|
+
import type { FragmentMeta, FragmentUsage, PropDefinition, AIMetadata, FragmentContract } from '@fragments-sdk/core';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Parsed fragment metadata (extracted statically from AST)
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { existsSync } from "node:fs";
|
|
14
14
|
import { join, resolve } from "node:path";
|
|
15
|
-
import type { PreviewConfig } from
|
|
15
|
+
import type { PreviewConfig } from '@fragments-sdk/core';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Possible file extensions and names for preview config
|
package/src/index.ts
CHANGED
|
@@ -44,10 +44,10 @@ export type { AnalyzeOptions, AnalyzeResult } from "./analyze.js";
|
|
|
44
44
|
export { generateStaticViewer, generateViewerFromJson } from "./static-viewer.js";
|
|
45
45
|
|
|
46
46
|
// Config type (used by generated fragments.config.ts)
|
|
47
|
-
export type { FragmentsConfig } from "./core/
|
|
47
|
+
export type { FragmentsConfig } from "./core/index.js";
|
|
48
48
|
|
|
49
49
|
// Fragment definition API (used by generated .fragment.tsx files)
|
|
50
|
-
export { defineFragment, defineBlock } from "./core/
|
|
50
|
+
export { defineFragment, defineBlock } from "./core/index.js";
|
|
51
51
|
|
|
52
52
|
// CLI Command metadata (for docs)
|
|
53
53
|
export { CLI_COMMANDS, CLI_COMMAND_CATEGORIES } from "./cli-commands.js";
|
|
@@ -2,7 +2,7 @@ import { afterEach, describe, expect, it } from 'vitest';
|
|
|
2
2
|
import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
|
-
import type { FragmentsConfig } from '../core/
|
|
5
|
+
import type { FragmentsConfig } from '../core/index.js';
|
|
6
6
|
import { validateSnippetPolicy } from './snippet-validation.js';
|
|
7
7
|
|
|
8
8
|
async function createTempProject(): Promise<string> {
|
|
@@ -2,8 +2,8 @@ import ts from 'typescript';
|
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
3
|
import { existsSync } from 'node:fs';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
-
import type { FragmentsConfig, SnippetPolicyConfig } from '../core/
|
|
6
|
-
import { BRAND } from '../core/
|
|
5
|
+
import type { FragmentsConfig, SnippetPolicyConfig } from '../core/index.js';
|
|
6
|
+
import { BRAND } from '../core/index.js';
|
|
7
7
|
import {
|
|
8
8
|
discoverBlockFiles,
|
|
9
9
|
discoverFragmentFiles,
|
|
@@ -68,17 +68,11 @@ describe("@fragments-sdk/cli/core alias resolution", () => {
|
|
|
68
68
|
expect(existsSync(corePath)).toBe(true);
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
it("core/index.ts exports
|
|
71
|
+
it("core/index.ts re-exports from @fragments-sdk/core", async () => {
|
|
72
72
|
const corePath = resolve(cliPackageRoot, "src/core/index.ts");
|
|
73
73
|
const content = await readFile(corePath, "utf-8");
|
|
74
|
-
//
|
|
75
|
-
expect(content).toContain("
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it("core/index.ts exports setPreviewConfig", async () => {
|
|
79
|
-
const corePath = resolve(cliPackageRoot, "src/core/index.ts");
|
|
80
|
-
const content = await readFile(corePath, "utf-8");
|
|
81
|
-
expect(content).toContain("setPreviewConfig");
|
|
74
|
+
// After core extraction, cli/core is a thin re-export shim
|
|
75
|
+
expect(content).toContain("@fragments-sdk/core");
|
|
82
76
|
});
|
|
83
77
|
});
|
|
84
78
|
|
|
@@ -44,21 +44,16 @@
|
|
|
44
44
|
// Preview area with subtle dotted grid pattern
|
|
45
45
|
.previewPanel {
|
|
46
46
|
position: relative;
|
|
47
|
-
min-height: 400px;
|
|
48
47
|
padding: var(--fui-space-4);
|
|
49
48
|
display: flex;
|
|
50
49
|
flex-direction: column;
|
|
51
|
-
align-items:
|
|
50
|
+
align-items: center;
|
|
51
|
+
justify-content: center;
|
|
52
52
|
background-color: var(--fui-bg-primary);
|
|
53
53
|
|
|
54
54
|
// Subtle dotted grid pattern
|
|
55
55
|
background-image: radial-gradient(circle, var(--fui-border) 1px, transparent 1px);
|
|
56
56
|
background-size: 24px 24px;
|
|
57
|
-
|
|
58
|
-
> * {
|
|
59
|
-
width: 100%;
|
|
60
|
-
flex: 1;
|
|
61
|
-
}
|
|
62
57
|
}
|
|
63
58
|
|
|
64
59
|
// Code panel
|
|
@@ -116,7 +111,4 @@
|
|
|
116
111
|
margin: 0;
|
|
117
112
|
}
|
|
118
113
|
|
|
119
|
-
:global([class*="Tabs_panel"]) {
|
|
120
|
-
padding: 0;
|
|
121
|
-
}
|
|
122
114
|
}
|
|
@@ -1715,7 +1715,7 @@ async function generateFragmentsModule(
|
|
|
1715
1715
|
|
|
1716
1716
|
// Compute sub-component map from story file paths (build-time)
|
|
1717
1717
|
const storyOnlyFiles = fragmentFiles.filter(f => isStoryFile(f.relativePath));
|
|
1718
|
-
const { detectSubComponentPaths: _detectSubs } = await import("../core/
|
|
1718
|
+
const { detectSubComponentPaths: _detectSubs } = await import("../core/index.js");
|
|
1719
1719
|
const subComponentMap = _detectSubs(storyOnlyFiles);
|
|
1720
1720
|
|
|
1721
1721
|
// Group files by base component path to identify pairs
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/discovery.ts"],"sourcesContent":["import { resolve, dirname, basename } from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport fg from 'fast-glob';\nimport type { FragmentsConfig } from './types.js';\nimport { BRAND } from './constants.js';\n\nexport interface DiscoveredFile {\n /** Absolute path to the file */\n absolutePath: string;\n /** Path relative to config directory */\n relativePath: string;\n}\n\n/**\n * Discovered component with source file information\n */\nexport interface DiscoveredComponent {\n /** Component name (e.g., \"Button\") */\n name: string;\n /** Absolute path to the component source file */\n sourcePath: string;\n /** Path relative to config directory */\n relativePath: string;\n /** Path to storybook file if found */\n storyPath?: string;\n}\n\n/**\n * Discover block files (*.block.ts) under the config directory.\n * Also discovers legacy *.recipe.ts files for backward compatibility.\n */\nexport async function discoverBlockFiles(\n configDir: string,\n exclude?: string[]\n): Promise<DiscoveredFile[]> {\n const patterns = [\n `**/*${BRAND.blockFileExtension}`,\n `**/*${BRAND.recipeFileExtension}`,\n ];\n const files = await fg(patterns, {\n cwd: configDir,\n ignore: exclude ?? ['**/node_modules/**', '**/dist/**'],\n absolute: false,\n });\n\n return files.map((relativePath) => ({\n relativePath,\n absolutePath: resolve(configDir, relativePath),\n }));\n}\n\n/**\n * @deprecated Use discoverBlockFiles instead\n */\nexport const discoverRecipeFiles = discoverBlockFiles;\n\n/**\n * Discover fragment files matching the config patterns\n */\nexport async function discoverFragmentFiles(\n config: FragmentsConfig,\n configDir: string\n): Promise<DiscoveredFile[]> {\n const defaultExcludes = [\n '**/*.test.stories.*',\n '**/*.stories.test.*',\n '**/*.test.story.*',\n '**/*.story.test.*',\n ];\n const files = await fg(config.include, {\n cwd: configDir,\n ignore: [...defaultExcludes, ...(config.exclude ?? [])],\n absolute: false,\n });\n\n return files.map((relativePath) => ({\n relativePath,\n absolutePath: resolve(configDir, relativePath),\n }));\n}\n\n/**\n * Discover component files for coverage validation\n */\nexport async function discoverComponentFiles(\n config: FragmentsConfig,\n configDir: string\n): Promise<DiscoveredFile[]> {\n if (!config.components || config.components.length === 0) {\n return [];\n }\n\n const files = await fg(config.components, {\n cwd: configDir,\n ignore: [\n ...(config.exclude ?? []),\n // Exclude fragment files themselves\n ...config.include,\n // Exclude test files\n '**/*.test.*',\n '**/*.spec.*',\n '**/__tests__/**',\n ],\n absolute: false,\n });\n\n return files.map((relativePath) => ({\n relativePath,\n absolutePath: resolve(configDir, relativePath),\n }));\n}\n\n/**\n * Extract component name from file path\n */\nexport function extractComponentName(filePath: string): string {\n // Handle index.tsx files - use parent directory name\n const parts = filePath.replace(/\\\\/g, '/').split('/');\n const fileName = parts[parts.length - 1];\n\n if (fileName === 'index.tsx' || fileName === 'index.ts') {\n return parts[parts.length - 2] ?? 'Unknown';\n }\n\n // Remove extension\n return fileName.replace(/\\.(tsx?|jsx?)$/, '');\n}\n\n/**\n * Default patterns for component discovery\n */\nconst DEFAULT_COMPONENT_PATTERNS = [\n 'src/components/**/*.tsx',\n 'src/components/**/index.tsx',\n 'components/**/*.tsx',\n 'lib/components/**/*.tsx',\n 'packages/*/src/components/**/*.tsx',\n];\n\n/**\n * Patterns to exclude from component discovery\n */\nconst DEFAULT_EXCLUDE_PATTERNS = [\n '**/*.test.*',\n '**/*.spec.*',\n '**/*.stories.*',\n '**/*.story.*',\n '**/__tests__/**',\n '**/__mocks__/**',\n '**/node_modules/**',\n '**/dist/**',\n];\n\n/**\n * Discover components from source files\n *\n * This function finds React components by:\n * 1. Looking for TypeScript/TSX files in common component directories\n * 2. Filtering out test files, stories, and internal files\n * 3. Extracting component names from file names or directories\n */\nexport async function discoverComponentsFromSource(\n configDir: string,\n patterns?: string[],\n exclude?: string[]\n): Promise<DiscoveredComponent[]> {\n const searchPatterns = patterns && patterns.length > 0\n ? patterns\n : DEFAULT_COMPONENT_PATTERNS;\n\n const excludePatterns = [\n ...DEFAULT_EXCLUDE_PATTERNS,\n ...(exclude ?? []),\n ];\n\n const files = await fg(searchPatterns, {\n cwd: configDir,\n ignore: excludePatterns,\n absolute: false,\n });\n\n // Filter to only component-like files (start with uppercase)\n const componentFiles = files.filter((file) => {\n const name = extractComponentName(file);\n return /^[A-Z]/.test(name);\n });\n\n // Find associated story files\n const storyPatterns = [\n '**/*.stories.tsx',\n '**/*.stories.ts',\n '**/*.story.tsx',\n '**/*.story.ts',\n ];\n\n const storyFiles = await fg(storyPatterns, {\n cwd: configDir,\n ignore: ['**/node_modules/**', '**/dist/**'],\n absolute: false,\n });\n\n const storyMap = new Map<string, string>();\n for (const storyFile of storyFiles) {\n const name = extractComponentName(storyFile.replace(/\\.stories?\\.(tsx?|jsx?)$/, '.tsx'));\n storyMap.set(name, storyFile);\n }\n\n // Build discovered components\n const components: DiscoveredComponent[] = [];\n\n for (const file of componentFiles) {\n const name = extractComponentName(file);\n const absolutePath = resolve(configDir, file);\n\n // Look for story file\n const storyFile = storyMap.get(name);\n\n components.push({\n name,\n sourcePath: absolutePath,\n relativePath: file,\n storyPath: storyFile ? resolve(configDir, storyFile) : undefined,\n });\n }\n\n // Sort by name\n components.sort((a, b) => a.name.localeCompare(b.name));\n\n return components;\n}\n\n/**\n * Discover components from a barrel export file (index.ts)\n *\n * Parses the barrel file to find exported components.\n * This is useful for libraries that expose components through a single entry point.\n */\nexport async function discoverComponentsFromBarrel(\n barrelPath: string,\n configDir: string\n): Promise<DiscoveredComponent[]> {\n const absoluteBarrelPath = resolve(configDir, barrelPath);\n\n if (!existsSync(absoluteBarrelPath)) {\n return [];\n }\n\n const content = await readFile(absoluteBarrelPath, 'utf-8');\n const components: DiscoveredComponent[] = [];\n\n // Match export statements like:\n // export { Button } from './Button'\n // export { Card, CardHeader } from './Card'\n // export * from './Modal'\n const exportRegex = /export\\s+(?:\\*|{([^}]+)})\\s+from\\s+['\"]([^'\"]+)['\"]/g;\n\n let match;\n while ((match = exportRegex.exec(content)) !== null) {\n const exportedNames = match[1];\n const importPath = match[2];\n\n // Resolve the import path\n const barrelDir = dirname(absoluteBarrelPath);\n let resolvedPath = resolve(barrelDir, importPath);\n\n // Add extension if needed\n if (!resolvedPath.endsWith('.tsx') && !resolvedPath.endsWith('.ts')) {\n if (existsSync(`${resolvedPath}.tsx`)) {\n resolvedPath = `${resolvedPath}.tsx`;\n } else if (existsSync(`${resolvedPath}.ts`)) {\n resolvedPath = `${resolvedPath}.ts`;\n } else if (existsSync(`${resolvedPath}/index.tsx`)) {\n resolvedPath = `${resolvedPath}/index.tsx`;\n } else if (existsSync(`${resolvedPath}/index.ts`)) {\n resolvedPath = `${resolvedPath}/index.ts`;\n }\n }\n\n if (!existsSync(resolvedPath)) {\n continue;\n }\n\n if (exportedNames) {\n // Named exports: { Button, Card }\n const names = exportedNames.split(',').map((n) => n.trim().split(/\\s+as\\s+/)[0].trim());\n for (const name of names) {\n if (/^[A-Z]/.test(name)) {\n const relativePath = resolvedPath.replace(configDir + '/', '');\n components.push({\n name,\n sourcePath: resolvedPath,\n relativePath,\n });\n }\n }\n } else {\n // Star export: export * from './Component'\n const name = extractComponentName(importPath);\n if (/^[A-Z]/.test(name)) {\n const relativePath = resolvedPath.replace(configDir + '/', '');\n components.push({\n name,\n sourcePath: resolvedPath,\n relativePath,\n });\n }\n }\n }\n\n return components;\n}\n\n/**\n * Default glob patterns for discovering token files (SCSS/CSS with custom properties)\n */\nconst DEFAULT_TOKEN_PATTERNS = [\n 'src/**/tokens/**/_variables.scss',\n 'src/**/tokens/**/variables.scss',\n 'src/**/styles/**/variables.scss',\n 'src/**/styles/**/tokens.scss',\n 'src/**/styles/**/variables.css',\n 'src/**/theme/**/_variables.scss',\n 'src/**/theme/**/tokens.css',\n];\n\n/**\n * Discover token files (SCSS/CSS files containing CSS custom properties).\n * Uses config.tokens.include patterns if provided, otherwise falls back\n * to default patterns that match common project structures.\n */\nexport async function discoverTokenFiles(\n configDir: string,\n patterns?: string[],\n exclude?: string[]\n): Promise<DiscoveredFile[]> {\n const searchPatterns = patterns && patterns.length > 0\n ? patterns\n : DEFAULT_TOKEN_PATTERNS;\n\n const files = await fg(searchPatterns, {\n cwd: configDir,\n ignore: exclude ?? ['**/node_modules/**', '**/dist/**'],\n absolute: false,\n });\n\n return files.map((relativePath) => ({\n relativePath,\n absolutePath: resolve(configDir, relativePath),\n }));\n}\n\n/**\n * Discover fragment files from installed packages that declare a \"fragments\" field\n * in their package.json. This allows consumer projects to see components from\n * installed packages (e.g. @fragments-sdk/ui) in the dev viewer.\n */\nexport async function discoverInstalledFragments(\n projectRoot: string\n): Promise<DiscoveredFile[]> {\n const pkgJsonPath = resolve(projectRoot, 'package.json');\n if (!existsSync(pkgJsonPath)) return [];\n\n const pkgJson = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));\n const allDeps = { ...pkgJson.dependencies, ...pkgJson.devDependencies };\n const results: DiscoveredFile[] = [];\n\n for (const depName of Object.keys(allDeps)) {\n const depDir = resolve(projectRoot, 'node_modules', depName);\n const depPkgPath = resolve(depDir, 'package.json');\n if (!existsSync(depPkgPath)) continue;\n\n const depPkg = JSON.parse(await readFile(depPkgPath, 'utf-8'));\n if (!depPkg.fragments) continue;\n\n // Package declares fragments — scan for source fragment files\n const files = await fg(\n [`src/**/*${BRAND.fileExtension}`, 'src/**/*.stories.tsx'],\n { cwd: depDir, ignore: ['**/node_modules/**'], absolute: false }\n );\n\n for (const rel of files) {\n results.push({\n relativePath: `${depName}/${rel}`,\n absolutePath: resolve(depDir, rel),\n });\n }\n }\n\n return results;\n}\n\n/**\n * Discover all components using multiple strategies\n */\nexport async function discoverAllComponents(\n configDir: string,\n options: {\n patterns?: string[];\n exclude?: string[];\n barrelFiles?: string[];\n } = {}\n): Promise<DiscoveredComponent[]> {\n const componentsMap = new Map<string, DiscoveredComponent>();\n\n // Discover from source files\n const sourceComponents = await discoverComponentsFromSource(\n configDir,\n options.patterns,\n options.exclude\n );\n\n for (const comp of sourceComponents) {\n componentsMap.set(comp.name, comp);\n }\n\n // Discover from barrel files if specified\n if (options.barrelFiles && options.barrelFiles.length > 0) {\n for (const barrelFile of options.barrelFiles) {\n const barrelComponents = await discoverComponentsFromBarrel(barrelFile, configDir);\n for (const comp of barrelComponents) {\n // Only add if not already found\n if (!componentsMap.has(comp.name)) {\n componentsMap.set(comp.name, comp);\n }\n }\n }\n }\n\n return Array.from(componentsMap.values()).sort((a, b) => a.name.localeCompare(b.name));\n}\n"],"mappings":"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","names":[]}
|