@fragments-sdk/cli 0.9.0 → 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 +502 -84
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-CJEGT3WD.js → chunk-566BNPQZ.js} +21 -6
- package/dist/chunk-566BNPQZ.js.map +1 -0
- package/dist/{chunk-WI6SLMSO.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-NGIMCIK2.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-2JIKCJX3.js → chunk-ZDA3PLQ6.js} +17 -14
- package/dist/chunk-ZDA3PLQ6.js.map +1 -0
- package/dist/core/index.d.ts +1 -2092
- package/dist/core/index.js +26 -21
- package/dist/{discovery-Z4RDDFVR.js → discovery-NEOY4MPN.js} +3 -3
- package/dist/generate-BGKTKO6E.js +459 -0
- package/dist/generate-BGKTKO6E.js.map +1 -0
- package/dist/index.d.ts +3 -5
- package/dist/index.js +7 -8
- package/dist/index.js.map +1 -1
- package/dist/{init-KSAAS7X3.js → init-Q53R5Q2T.js} +66 -76
- package/dist/init-Q53R5Q2T.js.map +1 -0
- package/dist/mcp-bin.js +5 -7
- 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-A5GIGGGK.js → service-TQYWY65E.js} +4 -5
- package/dist/{static-viewer-NSODM5VX.js → static-viewer-NUBFPKWH.js} +4 -5
- package/dist/static-viewer-NUBFPKWH.js.map +1 -0
- package/dist/{test-RPWZAYSJ.js → test-2CSOSS3B.js} +4 -5
- package/dist/{test-RPWZAYSJ.js.map → test-2CSOSS3B.js.map} +1 -1
- package/dist/{tokens-NIXSZRX7.js → tokens-DXEGYTOJ.js} +6 -7
- package/dist/{tokens-NIXSZRX7.js.map → tokens-DXEGYTOJ.js.map} +1 -1
- package/dist/{viewer-SBTJDMP7.js → viewer-DBEPYM3G.js} +245 -23
- package/dist/viewer-DBEPYM3G.js.map +1 -0
- package/package.json +2 -1
- package/src/bin.ts +33 -1
- package/src/build.ts +13 -3
- package/src/commands/__tests__/scan-generate.test.ts +308 -0
- package/src/commands/build.ts +16 -2
- package/src/commands/generate.ts +383 -68
- package/src/commands/init.ts +81 -56
- 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 +16 -4
- 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 +11 -1
- package/src/core/graph-extractor.ts +1 -1
- package/src/core/index.ts +3 -190
- 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/migrate/converter.ts +9 -1
- package/src/migrate/parser.ts +2 -0
- package/src/migrate/types.ts +2 -0
- package/src/service/snippet-validation.test.ts +1 -1
- package/src/service/snippet-validation.ts +2 -2
- package/src/setup.ts +69 -24
- package/src/viewer/__tests__/viewer-integration.test.ts +4 -10
- package/src/viewer/components/AccessibilityPanel.tsx +305 -312
- package/src/viewer/components/ActionsPanel.tsx +31 -29
- package/src/viewer/components/AllVariantsPreview.tsx +78 -0
- package/src/viewer/components/App.tsx +187 -740
- package/src/viewer/components/BottomPanel.tsx +228 -132
- package/src/viewer/components/CodePanel.tsx +1 -1
- package/src/viewer/components/CommandPalette.tsx +7 -10
- package/src/viewer/components/ComponentDocView.tsx +164 -0
- package/src/viewer/components/ComponentGraph.tsx +111 -142
- package/src/viewer/components/ContractPanel.tsx +6 -6
- package/src/viewer/components/EmptyVariantMessage.tsx +54 -0
- package/src/viewer/components/FigmaEmbed.tsx +20 -18
- package/src/viewer/components/FragmentEditor.tsx +92 -115
- package/src/viewer/components/HeaderSearch.tsx +24 -0
- package/src/viewer/components/HealthDashboard.tsx +16 -2
- package/src/viewer/components/Icons.tsx +9 -0
- package/src/viewer/components/InteractionsPanel.tsx +101 -117
- package/src/viewer/components/IsolatedPreviewFrame.tsx +1 -0
- package/src/viewer/components/LandingPage.tsx +3 -3
- package/src/viewer/components/LeftSidebar.tsx +141 -63
- package/src/viewer/components/LoadErrorMessage.tsx +102 -0
- package/src/viewer/components/MultiViewportPreview.tsx +61 -142
- package/src/viewer/components/NoVariantsMessage.tsx +59 -0
- package/src/viewer/components/PanelShell.tsx +161 -0
- package/src/viewer/components/PerformancePanel.tsx +31 -28
- package/src/viewer/components/PreviewArea.tsx +1 -1
- package/src/viewer/components/PreviewAside.tsx +168 -0
- package/src/viewer/components/PreviewFrameHost.tsx +3 -3
- package/src/viewer/components/PropsEditor.tsx +70 -156
- package/src/viewer/components/ResizablePanel.tsx +103 -263
- package/src/viewer/components/RightSidebar.tsx +3 -9
- package/src/viewer/components/SkeletonLoader.tsx +13 -13
- package/src/viewer/components/TokenStylePanel.tsx +182 -209
- package/src/viewer/components/TopToolbar.tsx +159 -0
- package/src/viewer/components/VariantMatrix.tsx +42 -86
- package/src/viewer/components/VariantTabs.tsx +3 -3
- package/src/viewer/components/ViewerHeader.tsx +69 -0
- package/src/viewer/components/WebMCPDevTools.tsx +17 -23
- package/src/viewer/components/viewer-utils.ts +16 -0
- package/src/viewer/entry.tsx +5 -0
- package/src/viewer/hooks/useAppState.ts +27 -4
- package/src/viewer/hooks/usePreviewBridge.ts +2 -2
- package/src/viewer/preview-frame.html +6 -12
- package/src/viewer/server.ts +169 -2
- package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss +10 -0
- package/src/viewer/vendor/shared/src/ComponentDocContent.module.scss.d.ts +2 -0
- package/src/viewer/vendor/shared/src/ComponentDocContent.tsx +274 -0
- package/src/viewer/vendor/shared/src/DocsHeaderBar.tsx +6 -18
- package/src/viewer/vendor/shared/src/DocsPageShell.tsx +5 -0
- package/src/viewer/vendor/shared/src/DocsSidebarNav.tsx +5 -16
- package/src/viewer/vendor/shared/src/PropsTable.module.scss +68 -0
- package/src/viewer/vendor/shared/src/PropsTable.module.scss.d.ts +2 -0
- package/src/viewer/vendor/shared/src/PropsTable.tsx +76 -0
- package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss +114 -0
- package/src/viewer/vendor/shared/src/VariantPreviewCard.module.scss.d.ts +2 -0
- package/src/viewer/vendor/shared/src/VariantPreviewCard.tsx +134 -0
- package/src/viewer/vendor/shared/src/index.ts +8 -0
- package/src/viewer/vendor/shared/src/types.ts +12 -0
- package/src/viewer/vite-plugin.ts +109 -4
- package/dist/chunk-2JIKCJX3.js.map +0 -1
- package/dist/chunk-AWYCDRPG.js.map +0 -1
- package/dist/chunk-CJEGT3WD.js.map +0 -1
- package/dist/chunk-EKLMXTWU.js +0 -80
- package/dist/chunk-EKLMXTWU.js.map +0 -1
- package/dist/chunk-GOVI6COW.js +0 -195
- package/dist/chunk-GOVI6COW.js.map +0 -1
- package/dist/chunk-NGIMCIK2.js.map +0 -1
- package/dist/defineFragment-D0UTve-I.d.ts +0 -665
- package/dist/generate-35OIMW4Y.js +0 -252
- package/dist/generate-35OIMW4Y.js.map +0 -1
- package/dist/init-KSAAS7X3.js.map +0 -1
- package/dist/scan-65RH3QMM.js +0 -15
- package/dist/viewer-SBTJDMP7.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 -221
- package/src/core/storyAdapter.test.ts +0 -571
- package/src/core/storyAdapter.ts +0 -761
- 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 -762
- /package/dist/{chunk-WI6SLMSO.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-65RH3QMM.js.map → discovery-NEOY4MPN.js.map} +0 -0
- /package/dist/{service-A5GIGGGK.js.map → scan-OQU7M4GH.js.map} +0 -0
- /package/dist/{static-viewer-NSODM5VX.js.map → service-TQYWY65E.js.map} +0 -0
package/src/core/index.ts
CHANGED
|
@@ -1,192 +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
|
-
// Token configuration
|
|
61
|
-
TokenConfig,
|
|
62
|
-
// Compiled token types
|
|
63
|
-
CompiledTokenEntry,
|
|
64
|
-
CompiledTokenData,
|
|
65
|
-
} from "./types.js";
|
|
66
|
-
|
|
67
|
-
// Performance presets
|
|
68
|
-
export {
|
|
69
|
-
resolvePerformanceConfig,
|
|
70
|
-
classifyComplexity,
|
|
71
|
-
formatBytes,
|
|
72
|
-
budgetBar,
|
|
73
|
-
PRESET_NAMES,
|
|
74
|
-
} from "./performance-presets.js";
|
|
75
|
-
export type {
|
|
76
|
-
PerformanceBudgets,
|
|
77
|
-
PerformanceConfig,
|
|
78
|
-
ComplexityTier,
|
|
79
|
-
PerformanceData as PerfData,
|
|
80
|
-
PerformanceSummary as PerfSummary,
|
|
81
|
-
} from "./performance-presets.js";
|
|
82
|
-
|
|
83
|
-
// Token types
|
|
84
|
-
export type {
|
|
85
|
-
TokenCategory,
|
|
86
|
-
DesignToken,
|
|
87
|
-
TokenRegistry,
|
|
88
|
-
TokenRegistryMeta,
|
|
89
|
-
EnhancedStyleDiffItem,
|
|
90
|
-
TokenFix,
|
|
91
|
-
TokenParseResult,
|
|
92
|
-
TokenParseError,
|
|
93
|
-
TokenMatchRequest,
|
|
94
|
-
TokenMatchResult,
|
|
95
|
-
TokenUsageSummary,
|
|
96
|
-
} from "./token-types.js";
|
|
97
|
-
|
|
98
|
-
// Schema validation (Zod is browser-safe)
|
|
99
|
-
export {
|
|
100
|
-
fragmentMetaSchema,
|
|
101
|
-
fragmentUsageSchema,
|
|
102
|
-
propDefinitionSchema,
|
|
103
|
-
componentRelationSchema,
|
|
104
|
-
fragmentVariantSchema,
|
|
105
|
-
fragmentDefinitionSchema,
|
|
106
|
-
fragmentsConfigSchema,
|
|
107
|
-
figmaPropMappingSchema,
|
|
108
|
-
// Contract and provenance schemas
|
|
109
|
-
fragmentContractSchema,
|
|
110
|
-
fragmentGeneratedSchema,
|
|
111
|
-
fragmentBanSchema,
|
|
112
|
-
blockDefinitionSchema,
|
|
113
|
-
recipeDefinitionSchema, // @deprecated - use blockDefinitionSchema
|
|
114
|
-
// AI metadata schema
|
|
115
|
-
aiMetadataSchema,
|
|
116
|
-
} from "./schema.js";
|
|
117
|
-
|
|
118
|
-
// Main API
|
|
119
|
-
export { defineFragment, compileFragment, defineBlock, compileBlock, defineRecipe, compileRecipe } from "./defineFragment.js";
|
|
120
|
-
export type { InferProps } from "./defineFragment.js";
|
|
121
|
-
|
|
122
|
-
// Story adapter (runtime conversion of Storybook modules)
|
|
123
|
-
export {
|
|
124
|
-
storyModuleToFragment,
|
|
125
|
-
setPreviewConfig,
|
|
126
|
-
getPreviewConfig,
|
|
127
|
-
// Re-export @storybook/csf utilities
|
|
128
|
-
toId,
|
|
129
|
-
storyNameFromExport,
|
|
130
|
-
isExportStory,
|
|
131
|
-
} from "./storyAdapter.js";
|
|
132
|
-
export type {
|
|
133
|
-
StoryModule,
|
|
134
|
-
StoryMeta,
|
|
135
|
-
Story,
|
|
136
|
-
StoryArgType,
|
|
137
|
-
StoryContext,
|
|
138
|
-
Decorator,
|
|
139
|
-
Loader,
|
|
140
|
-
PreviewConfig,
|
|
141
|
-
CSF2Story,
|
|
142
|
-
} from "./storyAdapter.js";
|
|
143
|
-
|
|
144
|
-
// Context generation for AI agents
|
|
145
|
-
export { generateContext } from "./context.js";
|
|
146
|
-
export type { ContextOptions, ContextResult } from "./context.js";
|
|
147
|
-
|
|
148
|
-
// Figma property mapping DSL
|
|
149
|
-
export { figma, isFigmaPropMapping, resolveFigmaMapping } from "./figma.js";
|
|
150
|
-
|
|
151
|
-
// Fragment JSON types (for .fragment.json files)
|
|
152
|
-
export type {
|
|
153
|
-
Fragment,
|
|
154
|
-
FragmentFigma,
|
|
155
|
-
FragmentUsage as FragmentJsonUsage,
|
|
156
|
-
FragmentDoNotItem,
|
|
157
|
-
FragmentPattern,
|
|
158
|
-
FragmentAccessibility,
|
|
159
|
-
FragmentRelated,
|
|
160
|
-
FragmentMeta as FragmentJsonMeta,
|
|
161
|
-
FragmentIndex,
|
|
162
|
-
FragmentRegistry,
|
|
163
|
-
RegistryComponentEntry,
|
|
164
|
-
RegistryPropEntry,
|
|
165
|
-
FragmentContextOptions,
|
|
166
|
-
} from "./fragment-types.js";
|
|
167
|
-
|
|
168
|
-
// Token parsing
|
|
169
|
-
export { parseTokenFile } from "./token-parser.js";
|
|
170
|
-
export type { ParsedToken, TokenParseOutput } from "./token-parser.js";
|
|
171
|
-
|
|
172
|
-
// Composition analysis
|
|
173
|
-
export { analyzeComposition } from "./composition.js";
|
|
174
|
-
export type {
|
|
175
|
-
CompositionAnalysis,
|
|
176
|
-
CompositionWarning,
|
|
177
|
-
CompositionSuggestion,
|
|
178
|
-
CompositionGuideline,
|
|
179
|
-
} from "./composition.js";
|
|
180
|
-
|
|
181
|
-
// Shared preview runtime
|
|
182
|
-
export {
|
|
183
|
-
executeVariantLoaders,
|
|
184
|
-
resolvePreviewRuntimeState,
|
|
185
|
-
usePreviewVariantRuntime,
|
|
186
|
-
PreviewVariantRuntime,
|
|
187
|
-
} from "./preview-runtime.js";
|
|
188
|
-
export type {
|
|
189
|
-
PreviewVariantLike,
|
|
190
|
-
PreviewRuntimeState,
|
|
191
|
-
PreviewRuntimeOptions,
|
|
192
|
-
} 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";
|
package/src/migrate/converter.ts
CHANGED
|
@@ -87,6 +87,7 @@ export function convertToFragment(parsed: ParsedStoryFile): ConversionResult {
|
|
|
87
87
|
const code = generateFragmentCode({
|
|
88
88
|
componentName,
|
|
89
89
|
componentImport: parsed.meta.componentImport,
|
|
90
|
+
isDefaultImport: parsed.meta.isDefaultImport,
|
|
90
91
|
description: parsed.meta.description,
|
|
91
92
|
category,
|
|
92
93
|
tags: parsed.meta.tags,
|
|
@@ -484,6 +485,7 @@ interface GeneratedMetadata {
|
|
|
484
485
|
interface GenerateOptions {
|
|
485
486
|
componentName: string;
|
|
486
487
|
componentImport: string;
|
|
488
|
+
isDefaultImport?: boolean;
|
|
487
489
|
description?: string;
|
|
488
490
|
category: string;
|
|
489
491
|
tags?: string[];
|
|
@@ -504,6 +506,7 @@ function generateFragmentCode(options: GenerateOptions): string {
|
|
|
504
506
|
const {
|
|
505
507
|
componentName,
|
|
506
508
|
componentImport,
|
|
509
|
+
isDefaultImport,
|
|
507
510
|
description,
|
|
508
511
|
category,
|
|
509
512
|
tags,
|
|
@@ -550,8 +553,13 @@ ${generated.skippedVariants.map(sv => ` { name: "${escapeString(sv.name)}",
|
|
|
550
553
|
}
|
|
551
554
|
|
|
552
555
|
// Import the actual component - this makes the fragment immediately usable
|
|
556
|
+
// Use default import when the source component uses export default
|
|
557
|
+
const componentImportStatement = isDefaultImport
|
|
558
|
+
? `import ${componentName} from "${componentImport}";`
|
|
559
|
+
: `import { ${componentName} } from "${componentImport}";`;
|
|
560
|
+
|
|
553
561
|
return `import { defineFragment } from "@fragments-sdk/cli/core";
|
|
554
|
-
|
|
562
|
+
${componentImportStatement}
|
|
555
563
|
|
|
556
564
|
export default defineFragment({
|
|
557
565
|
component: ${componentName},
|
package/src/migrate/parser.ts
CHANGED
|
@@ -235,6 +235,7 @@ function parseMeta(
|
|
|
235
235
|
);
|
|
236
236
|
if (importMatch) {
|
|
237
237
|
result.componentImport = importMatch[1];
|
|
238
|
+
result.isDefaultImport = false;
|
|
238
239
|
} else {
|
|
239
240
|
// Try default import
|
|
240
241
|
const defaultImportMatch = content.match(
|
|
@@ -244,6 +245,7 @@ function parseMeta(
|
|
|
244
245
|
);
|
|
245
246
|
if (defaultImportMatch) {
|
|
246
247
|
result.componentImport = defaultImportMatch[1];
|
|
248
|
+
result.isDefaultImport = true;
|
|
247
249
|
}
|
|
248
250
|
}
|
|
249
251
|
}
|
package/src/migrate/types.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface ParsedMeta {
|
|
|
12
12
|
componentName: string;
|
|
13
13
|
/** Component import path */
|
|
14
14
|
componentImport?: string;
|
|
15
|
+
/** Whether the component uses a default import (export default) */
|
|
16
|
+
isDefaultImport?: boolean;
|
|
15
17
|
/** Tags from the story */
|
|
16
18
|
tags?: string[];
|
|
17
19
|
/** Description from parameters.docs */
|
|
@@ -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,
|
package/src/setup.ts
CHANGED
|
@@ -2,6 +2,7 @@ import pc from 'picocolors';
|
|
|
2
2
|
import { BRAND } from './core/index.js';
|
|
3
3
|
import { loadConfig, discoverFragmentFiles } from './core/node.js';
|
|
4
4
|
import { buildFragments } from './build.js';
|
|
5
|
+
import { scan } from './commands/scan.js';
|
|
5
6
|
import {
|
|
6
7
|
detectStorybookConfig,
|
|
7
8
|
discoverStoryFiles as discoverStorybookFiles,
|
|
@@ -125,48 +126,78 @@ export async function runSetup(options: SetupOptions = {}): Promise<SetupResult>
|
|
|
125
126
|
let fragmentFiles = await discoverFragmentFiles(config, configDir);
|
|
126
127
|
|
|
127
128
|
if (fragmentFiles.length === 0 && !options.skipStorybook) {
|
|
128
|
-
// No fragment files - check for Storybook
|
|
129
|
+
// No fragment files - check for Storybook stories that the viewer can load directly
|
|
129
130
|
log(pc.yellow('\n No fragment files found'));
|
|
130
131
|
|
|
131
132
|
const sbConfig = await detectStorybookConfig(configDir);
|
|
132
133
|
if (sbConfig) {
|
|
133
134
|
log(pc.dim(` Found Storybook at ${sbConfig.configPath}`));
|
|
134
|
-
log(pc.dim(' Converting stories to fragments...\n'));
|
|
135
135
|
|
|
136
|
-
//
|
|
137
|
-
const
|
|
136
|
+
// Check if config.include already covers story files
|
|
137
|
+
const hasStoryPatterns = config.include.some((p: string) => p.includes('.stories.'));
|
|
138
138
|
|
|
139
|
-
if (
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const fragmentResult = convertToFragment(parsed);
|
|
139
|
+
if (hasStoryPatterns) {
|
|
140
|
+
// Stories are in the include config — discover them directly
|
|
141
|
+
// The viewer handles .stories.tsx natively via storyModuleToFragment()
|
|
142
|
+
log(pc.dim(' Stories included in config — viewer will load them directly\n'));
|
|
143
|
+
fragmentFiles = await discoverFragmentFiles(config, configDir);
|
|
145
144
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
await fs.writeFile(fragmentResult.outputFile, fragmentResult.code);
|
|
149
|
-
converted++;
|
|
150
|
-
} catch {
|
|
151
|
-
// Skip files that can't be converted
|
|
152
|
-
}
|
|
145
|
+
if (fragmentFiles.length > 0) {
|
|
146
|
+
log(pc.green(` Found ${fragmentFiles.length} story/fragment file(s)`));
|
|
153
147
|
}
|
|
148
|
+
} else {
|
|
149
|
+
// Stories not in config — fall back to conversion
|
|
150
|
+
log(pc.dim(' Converting stories to fragments...\n'));
|
|
151
|
+
|
|
152
|
+
const storyFiles = await discoverStorybookFiles(configDir, sbConfig.storyPatterns);
|
|
153
|
+
|
|
154
|
+
if (storyFiles.length > 0) {
|
|
155
|
+
let converted = 0;
|
|
156
|
+
for (const storyFile of storyFiles) {
|
|
157
|
+
try {
|
|
158
|
+
const parsed = await parseStoryFile(storyFile);
|
|
159
|
+
const fragmentResult = convertToFragment(parsed);
|
|
160
|
+
|
|
161
|
+
// Create directory and write file
|
|
162
|
+
await fs.mkdir(path.dirname(fragmentResult.outputFile), { recursive: true });
|
|
163
|
+
await fs.writeFile(fragmentResult.outputFile, fragmentResult.code);
|
|
164
|
+
converted++;
|
|
165
|
+
} catch {
|
|
166
|
+
// Skip files that can't be converted
|
|
167
|
+
}
|
|
168
|
+
}
|
|
154
169
|
|
|
155
|
-
|
|
156
|
-
|
|
170
|
+
result.fragmentFilesCreated = converted;
|
|
171
|
+
log(pc.green(` Generated ${converted} fragment file(s)`));
|
|
157
172
|
|
|
158
|
-
|
|
159
|
-
|
|
173
|
+
// Refresh fragment files list
|
|
174
|
+
fragmentFiles = await discoverFragmentFiles(config, configDir);
|
|
175
|
+
}
|
|
160
176
|
}
|
|
161
177
|
} else {
|
|
178
|
+
// No Storybook — auto-scan source code to generate fragments.json
|
|
162
179
|
log(pc.dim(' No Storybook config found'));
|
|
163
|
-
log(pc.dim(
|
|
180
|
+
log(pc.dim(' Auto-scanning source code...\n'));
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
const scanResult = await scan({
|
|
184
|
+
config: options.configPath,
|
|
185
|
+
verbose: false,
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
if (scanResult.componentCount > 0) {
|
|
189
|
+
result.fragmentsBuilt = scanResult.componentCount;
|
|
190
|
+
log(pc.green(` Scanned ${scanResult.componentCount} component(s) from source`));
|
|
191
|
+
}
|
|
192
|
+
} catch {
|
|
193
|
+
log(pc.dim(` Run ${pc.cyan(`${BRAND.cliCommand} scan`)} to generate documentation from source`));
|
|
194
|
+
}
|
|
164
195
|
}
|
|
165
196
|
} else if (fragmentFiles.length > 0) {
|
|
166
197
|
log(pc.green(` Found ${fragmentFiles.length} fragment file(s)`));
|
|
167
198
|
}
|
|
168
199
|
|
|
169
|
-
// Step 2: Build fragments.json if needed
|
|
200
|
+
// Step 2: Build fragments.json if needed (only when fragment files exist)
|
|
170
201
|
if (fragmentFiles.length > 0 && !options.skipBuild) {
|
|
171
202
|
const outFile = config.outFile || BRAND.outFile;
|
|
172
203
|
const { stale, missing } = await isFragmentsJsonStale(configDir, outFile);
|
|
@@ -185,7 +216,21 @@ export async function runSetup(options: SetupOptions = {}): Promise<SetupResult>
|
|
|
185
216
|
}
|
|
186
217
|
}
|
|
187
218
|
|
|
188
|
-
|
|
219
|
+
if (buildResult.fragmentCount > 0) {
|
|
220
|
+
log(pc.green(` Built ${buildResult.fragmentCount} fragment(s)`));
|
|
221
|
+
} else {
|
|
222
|
+
// Build found 0 fragments — fallback to scan
|
|
223
|
+
log(pc.dim(' No compilable fragments found, falling back to source scan...'));
|
|
224
|
+
try {
|
|
225
|
+
const scanResult = await scan({ verbose: false });
|
|
226
|
+
if (scanResult.componentCount > 0) {
|
|
227
|
+
result.fragmentsBuilt = scanResult.componentCount;
|
|
228
|
+
log(pc.green(` Scanned ${scanResult.componentCount} component(s) from source`));
|
|
229
|
+
}
|
|
230
|
+
} catch {
|
|
231
|
+
// scan failed silently
|
|
232
|
+
}
|
|
233
|
+
}
|
|
189
234
|
} catch (error) {
|
|
190
235
|
result.errors.push(`Build failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
191
236
|
}
|
|
@@ -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
|
|
|
@@ -91,7 +85,7 @@ describe("virtual module @fragments-sdk/cli/core import", () => {
|
|
|
91
85
|
|
|
92
86
|
// The generated virtual module string should reference @fragments-sdk/cli/core
|
|
93
87
|
expect(content).toContain(
|
|
94
|
-
'import { storyModuleToFragment, setPreviewConfig } from "@fragments-sdk/cli/core"'
|
|
88
|
+
'import { storyModuleToFragment, setPreviewConfig, checkStoryExclusion, isForceIncluded, isConfigExcluded } from "@fragments-sdk/cli/core"'
|
|
95
89
|
);
|
|
96
90
|
});
|
|
97
91
|
|