storybook-addon-dependency-previews 0.4.0-beta.7 → 0.5.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/README.md +82 -0
- package/dist/addon/vitePlugin.cjs.map +1 -1
- package/dist/addon/vitePlugin.mjs.map +1 -1
- package/dist/blocks/DependencyPreviews.cjs.map +1 -1
- package/dist/blocks/DependencyPreviews.mjs.map +1 -1
- package/dist/cli/sb-deps.cjs +30 -3
- package/dist/cli/sb-deps.cjs.map +1 -1
- package/dist/cli/sb-deps.mjs +30 -3
- package/dist/cli/sb-deps.mjs.map +1 -1
- package/dist/cli/scripts/postprocess.cjs.map +1 -1
- package/dist/cli/scripts/postprocess.mjs.map +1 -1
- package/dist/cli/setup/detect.cjs.map +1 -1
- package/dist/cli/setup/detect.mjs.map +1 -1
- package/dist/cli/setup/index.cjs +18 -1
- package/dist/cli/setup/index.cjs.map +1 -1
- package/dist/cli/setup/index.mjs +18 -1
- package/dist/cli/setup/index.mjs.map +1 -1
- package/dist/cli/setup/install.cjs.map +1 -1
- package/dist/cli/setup/install.mjs.map +1 -1
- package/dist/cli/setup/patchers/main.cjs +284 -14
- package/dist/cli/setup/patchers/main.cjs.map +1 -1
- package/dist/cli/setup/patchers/main.d.cts +13 -0
- package/dist/cli/setup/patchers/main.d.mts +13 -0
- package/dist/cli/setup/patchers/main.mjs +284 -14
- package/dist/cli/setup/patchers/main.mjs.map +1 -1
- package/dist/cli/setup/patchers/preview.cjs +23 -14
- package/dist/cli/setup/patchers/preview.cjs.map +1 -1
- package/dist/cli/setup/patchers/preview.mjs +23 -14
- package/dist/cli/setup/patchers/preview.mjs.map +1 -1
- package/dist/components/ComponentSourceLink.cjs.map +1 -1
- package/dist/components/ComponentSourceLink.mjs.map +1 -1
- package/dist/components/CopyButton.cjs.map +1 -1
- package/dist/components/CopyButton.mjs.map +1 -1
- package/dist/components/CopyButton.module.css +3 -1
- package/dist/components/Expandable.cjs.map +1 -1
- package/dist/components/Expandable.mjs.map +1 -1
- package/dist/components/FullParityStory.cjs.map +1 -1
- package/dist/components/FullParityStory.mjs.map +1 -1
- package/dist/components/PathCopyMolecule.cjs.map +1 -1
- package/dist/components/PathCopyMolecule.mjs.map +1 -1
- package/dist/components/PrimaryPreview.cjs.map +1 -1
- package/dist/components/PrimaryPreview.mjs.map +1 -1
- package/dist/components/SbHeading.cjs.map +1 -1
- package/dist/components/SbHeading.mjs.map +1 -1
- package/dist/components/StoryLink.cjs.map +1 -1
- package/dist/components/StoryLink.mjs.map +1 -1
- package/dist/components/TooltipTrigger.cjs.map +1 -1
- package/dist/components/TooltipTrigger.mjs.map +1 -1
- package/dist/components/TooltipTrigger.module.css +3 -1
- package/dist/components/icons/ArrowToRectangleIcon.cjs.map +1 -1
- package/dist/components/icons/ArrowToRectangleIcon.mjs.map +1 -1
- package/dist/components/icons/BuildIcon.cjs.map +1 -1
- package/dist/components/icons/BuildIcon.mjs.map +1 -1
- package/dist/components/icons/CopyIcon.cjs.map +1 -1
- package/dist/components/icons/CopyIcon.mjs.map +1 -1
- package/dist/components/icons/CubeIcon.cjs.map +1 -1
- package/dist/components/icons/CubeIcon.mjs.map +1 -1
- package/dist/components/icons/DoubleChevronDown.cjs.map +1 -1
- package/dist/components/icons/DoubleChevronDown.mjs.map +1 -1
- package/dist/components/icons/ExternalLinkIcon.cjs.map +1 -1
- package/dist/components/icons/ExternalLinkIcon.mjs.map +1 -1
- package/dist/components/icons/EyeOpen.cjs.map +1 -1
- package/dist/components/icons/EyeOpen.mjs.map +1 -1
- package/dist/components/icons/LoadingRipples.cjs.map +1 -1
- package/dist/components/icons/LoadingRipples.mjs.map +1 -1
- package/dist/components/icons/SquaresPlus.cjs.map +1 -1
- package/dist/components/icons/SquaresPlus.mjs.map +1 -1
- package/dist/components/icons/Svg.cjs.map +1 -1
- package/dist/components/icons/Svg.mjs.map +1 -1
- package/dist/components/icons/X.cjs.map +1 -1
- package/dist/components/icons/X.mjs.map +1 -1
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +15 -1
- package/dist/config.d.mts +15 -1
- package/dist/config.mjs.map +1 -1
- package/dist/hooks/useDependencyGraph.cjs.map +1 -1
- package/dist/hooks/useDependencyGraph.mjs.map +1 -1
- package/dist/hooks/useDynamicStory.cjs.map +1 -1
- package/dist/hooks/useDynamicStory.mjs.map +1 -1
- package/dist/manager.cjs.map +1 -1
- package/dist/manager.mjs.map +1 -1
- package/dist/panels/DefaultAutoDocsLayout.cjs.map +1 -1
- package/dist/panels/DefaultAutoDocsLayout.mjs.map +1 -1
- package/dist/panels/GraphView.cjs.map +1 -1
- package/dist/panels/GraphView.mjs.map +1 -1
- package/dist/types.d.cts +17 -4
- package/dist/types.d.mts +17 -4
- package/package.json +122 -121
package/README.md
CHANGED
|
@@ -148,6 +148,8 @@ export function ${componentName}({}: ${propsName}) {
|
|
|
148
148
|
svelte: {
|
|
149
149
|
/** Customize the generated .svelte component file */
|
|
150
150
|
component: ({ componentName }) => '...',
|
|
151
|
+
/** Customize the generated .decorator.svelte file */
|
|
152
|
+
decorator: ({ componentName }) => '...',
|
|
151
153
|
/** Customize the generated .stories.svelte file */
|
|
152
154
|
story: ({ componentName, title, tags }) => '...',
|
|
153
155
|
},
|
|
@@ -170,3 +172,83 @@ export function ${componentName}({}: ${propsName}) {
|
|
|
170
172
|
```
|
|
171
173
|
|
|
172
174
|
All scaffold options are optional — omit any key to keep the default template for that file type.
|
|
175
|
+
|
|
176
|
+
### Svelte decorators
|
|
177
|
+
|
|
178
|
+
Storybook decorators in Svelte are cleanest when written as their own `.svelte` file rather than inline in a story. `sb-deps` recognises decorator files by the `.decorator.svelte` suffix and treats them specially: it scaffolds them with a decorator-shaped template (importing and rendering the wrapped sibling component) and **does not** generate a `.stories.svelte` for them.
|
|
179
|
+
|
|
180
|
+
#### Recommended pattern: one shared decorator per component
|
|
181
|
+
|
|
182
|
+
Name the file `ComponentName.decorator.svelte` and use **props** to vary behaviour between stories. This is the preferred approach because it avoids near-duplicate decorator files for each story.
|
|
183
|
+
|
|
184
|
+
```svelte
|
|
185
|
+
<!-- ContactFormOrganism.decorator.svelte -->
|
|
186
|
+
<script lang="ts">
|
|
187
|
+
import type { ValidationMode } from '@formisch/svelte';
|
|
188
|
+
import FormDataMolecule from '../../zz-meta-components/FormDataPreview/FormDataMolecule.svelte';
|
|
189
|
+
import ContactFormOrganism from './ContactFormOrganism.svelte';
|
|
190
|
+
import { createContactForm, onContactFormSubmit } from './createContactForm';
|
|
191
|
+
|
|
192
|
+
interface DecoratorProps {
|
|
193
|
+
validate?: ValidationMode;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const { validate }: DecoratorProps = $props();
|
|
197
|
+
|
|
198
|
+
const form = $derived(createContactForm(validate));
|
|
199
|
+
</script>
|
|
200
|
+
|
|
201
|
+
<!--
|
|
202
|
+
Decorator files are useful for adding extra wrapper
|
|
203
|
+
components as additional context to stories
|
|
204
|
+
-->
|
|
205
|
+
<FormDataMolecule {form}>
|
|
206
|
+
<ContactFormOrganism {form} onSubmit={onContactFormSubmit} />
|
|
207
|
+
</FormDataMolecule>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
```svelte
|
|
211
|
+
<!-- ContactFormOrganism.stories.svelte (excerpt) -->
|
|
212
|
+
<Story name="Primary">
|
|
213
|
+
{#snippet template()}
|
|
214
|
+
<ContactFormOrganismDecorator validate="submit" />
|
|
215
|
+
{/snippet}
|
|
216
|
+
</Story>
|
|
217
|
+
|
|
218
|
+
<Story name="Error State">
|
|
219
|
+
{#snippet template()}
|
|
220
|
+
<ContactFormOrganismDecorator validate="initial" />
|
|
221
|
+
{/snippet}
|
|
222
|
+
</Story>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
#### Fallback pattern: per-story decorator files
|
|
226
|
+
|
|
227
|
+
If a particular story needs a decorator with a structurally different shape that can't reasonably be expressed via props, name the file `ComponentName.StoryName.decorator.svelte`. The wrapped component name is always the segment before the first `.` in the filename.
|
|
228
|
+
|
|
229
|
+
| Filename | Wrapped component | When to use |
|
|
230
|
+
| --------------------------------- | ----------------- | --------------------------------------------------------------------------------- |
|
|
231
|
+
| `Button.decorator.svelte` | `Button` | Default — single decorator for all stories, drive variants via props |
|
|
232
|
+
| `Button.Primary.decorator.svelte` | `Button` | Fallback — only when the `Primary` story needs a structurally different decorator |
|
|
233
|
+
| `Button.Error.decorator.svelte` | `Button` | Fallback — only when the `Error` story needs a structurally different decorator |
|
|
234
|
+
|
|
235
|
+
#### Default scaffold
|
|
236
|
+
|
|
237
|
+
When `sb-deps` detects a new empty `*.decorator.svelte` file, it fills it with:
|
|
238
|
+
|
|
239
|
+
```svelte
|
|
240
|
+
<script lang="ts">
|
|
241
|
+
import Button from "./Button.svelte";
|
|
242
|
+
|
|
243
|
+
interface DecoratorProps {
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const { }: DecoratorProps = $props();
|
|
247
|
+
</script>
|
|
248
|
+
|
|
249
|
+
<div class="decorator">
|
|
250
|
+
<Button />
|
|
251
|
+
</div>
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
The wrapper `<div class="decorator">` is a hint, not a requirement — replace it with whatever the decorator actually needs to wrap around the component (a form provider, a router, a theme context, …). Customise the whole template via [`scaffold.svelte.decorator`](#scaffold) in your `sb-deps.config.{js,mjs,ts}`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vitePlugin.cjs","names":[],"sources":["../../src/addon/vitePlugin.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nexport function sbDepsVitePlugin() {\n\tconst virtId = 'virtual:dependency-previews-json'\n\tconst resolved = '\\0' + virtId\n\treturn {\n\t\tname: 'sb-deps',\n\t\tresolveId(id: string) {\n\t\t\treturn id === virtId ? resolved : null\n\t\t},\n\t\tload(id: string) {\n\t\t\tif (id !== resolved) return null\n\t\t\tconst jsonPath = resolve(\n\t\t\t\tprocess.cwd(),\n\t\t\t\t'.storybook/dependency-previews.json',\n\t\t\t)\n\t\t\tconst json = existsSync(jsonPath)
|
|
1
|
+
{"version":3,"file":"vitePlugin.cjs","names":[],"sources":["../../src/addon/vitePlugin.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nexport function sbDepsVitePlugin() {\n\tconst virtId = 'virtual:dependency-previews-json'\n\tconst resolved = '\\0' + virtId\n\treturn {\n\t\tname: 'sb-deps',\n\t\tresolveId(id: string) {\n\t\t\treturn id === virtId ? resolved : null\n\t\t},\n\t\tload(id: string) {\n\t\t\tif (id !== resolved) return null\n\t\t\tconst jsonPath = resolve(\n\t\t\t\tprocess.cwd(),\n\t\t\t\t'.storybook/dependency-previews.json',\n\t\t\t)\n\t\t\tconst json = existsSync(jsonPath) ? readFileSync(jsonPath, 'utf8') : '{}'\n\t\t\treturn `export default ${json};`\n\t\t},\n\t}\n}\n"],"mappings":";;;;;;;AAGA,SAAgB,mBAAmB;CAClC,MAAM,SAAS;CACf,MAAM,WAAW,OAAO;AACxB,QAAO;EACN,MAAM;EACN,UAAU,IAAY;AACrB,UAAO,OAAO,SAAS,WAAW;;EAEnC,KAAK,IAAY;AAChB,OAAI,OAAO,SAAU,QAAO;GAC5B,MAAM,kCACL,QAAQ,KAAK,EACb,sCACA;GACD,MAAM,+BAAkB,SAAS,6BAAgB,UAAU,OAAO,GAAG;AACrE,UAAO,kBAAkB,KAAK;;EAE/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vitePlugin.mjs","names":[],"sources":["../../src/addon/vitePlugin.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nexport function sbDepsVitePlugin() {\n\tconst virtId = 'virtual:dependency-previews-json'\n\tconst resolved = '\\0' + virtId\n\treturn {\n\t\tname: 'sb-deps',\n\t\tresolveId(id: string) {\n\t\t\treturn id === virtId ? resolved : null\n\t\t},\n\t\tload(id: string) {\n\t\t\tif (id !== resolved) return null\n\t\t\tconst jsonPath = resolve(\n\t\t\t\tprocess.cwd(),\n\t\t\t\t'.storybook/dependency-previews.json',\n\t\t\t)\n\t\t\tconst json = existsSync(jsonPath)
|
|
1
|
+
{"version":3,"file":"vitePlugin.mjs","names":[],"sources":["../../src/addon/vitePlugin.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nexport function sbDepsVitePlugin() {\n\tconst virtId = 'virtual:dependency-previews-json'\n\tconst resolved = '\\0' + virtId\n\treturn {\n\t\tname: 'sb-deps',\n\t\tresolveId(id: string) {\n\t\t\treturn id === virtId ? resolved : null\n\t\t},\n\t\tload(id: string) {\n\t\t\tif (id !== resolved) return null\n\t\t\tconst jsonPath = resolve(\n\t\t\t\tprocess.cwd(),\n\t\t\t\t'.storybook/dependency-previews.json',\n\t\t\t)\n\t\t\tconst json = existsSync(jsonPath) ? readFileSync(jsonPath, 'utf8') : '{}'\n\t\t\treturn `export default ${json};`\n\t\t},\n\t}\n}\n"],"mappings":";;;;AAGA,SAAgB,mBAAmB;CAClC,MAAM,SAAS;CACf,MAAM,WAAW,OAAO;AACxB,QAAO;EACN,MAAM;EACN,UAAU,IAAY;AACrB,UAAO,OAAO,SAAS,WAAW;;EAEnC,KAAK,IAAY;AAChB,OAAI,OAAO,SAAU,QAAO;GAC5B,MAAM,WAAW,QAChB,QAAQ,KAAK,EACb,sCACA;GACD,MAAM,OAAO,WAAW,SAAS,GAAG,aAAa,UAAU,OAAO,GAAG;AACrE,UAAO,kBAAkB,KAAK;;EAE/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DependencyPreviews.cjs","names":["DependencyGraphProvider","useDependencyGraph","s","SbHeading","filterOutStoryAndNonComponentFiles","Expandable","EyeOpen","PrimaryPreview","ArrowToRectangle","PathCopyMolecule","ComponentSourceLink","StoryLink","BuildIcon","SquaresPlus","CubeIcon"],"sources":["../../src/blocks/DependencyPreviews.tsx"],"sourcesContent":["import React from
|
|
1
|
+
{"version":3,"file":"DependencyPreviews.cjs","names":["DependencyGraphProvider","useDependencyGraph","s","SbHeading","filterOutStoryAndNonComponentFiles","Expandable","EyeOpen","PrimaryPreview","ArrowToRectangle","PathCopyMolecule","ComponentSourceLink","StoryLink","BuildIcon","SquaresPlus","CubeIcon"],"sources":["../../src/blocks/DependencyPreviews.tsx"],"sourcesContent":["import React from 'react'\nimport { PrimaryPreview } from '../components/PrimaryPreview'\nimport { StoryLink } from '../components/StoryLink'\nimport {\n\tDependencyGraphProvider,\n\tfilterOutStoryAndNonComponentFiles,\n\tuseDependencyGraph,\n} from '../hooks/useDependencyGraph'\nimport type { StoryInfo } from '../types'\n\nimport { ComponentSourceLink } from '../components/ComponentSourceLink'\nimport { Expandable } from '../components/Expandable'\nimport { BuildIcon } from '../components/icons/BuildIcon'\nimport { EyeOpen } from '../components/icons/EyeOpen'\nimport { SquaresPlus } from '../components/icons/SquaresPlus'\n\nimport { ArrowToRectangle } from '../components/icons/ArrowToRectangleIcon'\nimport { CubeIcon } from '../components/icons/CubeIcon'\nimport { PathCopyMolecule } from '../components/PathCopyMolecule'\nimport { SbHeading } from '../components/SbHeading'\nimport s from './DependencyPreviews.module.css'\n\nexport function DependencyPreviews() {\n\treturn (\n\t\t<DependencyGraphProvider>\n\t\t\t<TopLevelDependencyPreviews />\n\t\t</DependencyGraphProvider>\n\t)\n}\n\nfunction TopLevelDependencyPreviews() {\n\tconst { node } = useDependencyGraph()\n\tif (!node) return <div>No dependency previews for this component.</div>\n\n\treturn (\n\t\t<div className={s.topLevelWrapper}>\n\t\t\t<SbHeading>Dependency previews</SbHeading>\n\t\t\t<DepsPreviewContent storyInfo={node} enablePreview={false} />\n\t\t</div>\n\t)\n}\n\ninterface PropsForDepsPreviewContent {\n\tstoryInfo: StoryInfo\n\tenablePreview?: boolean\n}\nfunction DepsPreviewContent({\n\tstoryInfo,\n\tenablePreview = true,\n}: PropsForDepsPreviewContent) {\n\tconst { graph } = useDependencyGraph()\n\tconst { builtWith, usedIn } = graph![storyInfo.componentPath]\n\tconst filteredBuiltWith = filterOutStoryAndNonComponentFiles(builtWith)\n\tconst filteredUsedIn = filterOutStoryAndNonComponentFiles(usedIn)\n\n\treturn (\n\t\t<div>\n\t\t\t{enablePreview && (\n\t\t\t\t<Expandable\n\t\t\t\t\tHeader={`Preview ${storyInfo.storyTitle} component`}\n\t\t\t\t\tIcon={EyeOpen}\n\t\t\t\t>\n\t\t\t\t\t<PrimaryPreview storyInfo={storyInfo} />\n\t\t\t\t</Expandable>\n\t\t\t)}\n\n\t\t\t<Expandable\n\t\t\t\tHeader={`Paths to ${storyInfo.storyTitle} component`}\n\t\t\t\tIcon={ArrowToRectangle}\n\t\t\t>\n\t\t\t\t<div className={s.pathData}>\n\t\t\t\t\t<PathCopyMolecule\n\t\t\t\t\t\tlabel=\"Source File Path\"\n\t\t\t\t\t\tcopyContent={storyInfo.componentPath}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ComponentSourceLink storyInfo={storyInfo} />\n\t\t\t\t\t</PathCopyMolecule>\n\n\t\t\t\t\t<PathCopyMolecule\n\t\t\t\t\t\tlabel=\"Story Title Path\"\n\t\t\t\t\t\tcopyContent={storyInfo.storyTitlePath!}\n\t\t\t\t\t>\n\t\t\t\t\t\t<StoryLink info={storyInfo}>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t\t\t\t// allow line breaks on slashes\n\t\t\t\t\t\t\t\t\t__html: storyInfo.storyTitlePath!.replaceAll('/', '/<wbr/>'),\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</StoryLink>\n\t\t\t\t\t</PathCopyMolecule>\n\n\t\t\t\t\t<PathCopyMolecule\n\t\t\t\t\t\tlabel=\"Story Page ID\"\n\t\t\t\t\t\tcopyContent={storyInfo.storyId!}\n\t\t\t\t\t>\n\t\t\t\t\t\t<StoryLink info={storyInfo}>{storyInfo.storyId}</StoryLink>\n\t\t\t\t\t</PathCopyMolecule>\n\t\t\t\t</div>\n\t\t\t</Expandable>\n\n\t\t\t{filteredBuiltWith.length > 0 && (\n\t\t\t\t<Expandable\n\t\t\t\t\tHeader={`Built with ${\n\t\t\t\t\t\tfilteredBuiltWith.length\n\t\t\t\t\t} component${plural(filteredBuiltWith)}`}\n\t\t\t\t\tIcon={BuildIcon}\n\t\t\t\t>\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t{filterOutStoryAndNonComponentFiles(builtWith).map((info) => (\n\t\t\t\t\t\t\t<DepsPreviewItem storyInfo={info} key={info.componentPath} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</Expandable>\n\t\t\t)}\n\t\t\t{filteredUsedIn.length > 0 && (\n\t\t\t\t<Expandable\n\t\t\t\t\tHeader={`Used in ${filteredUsedIn.length} component${plural(\n\t\t\t\t\t\tfilteredUsedIn,\n\t\t\t\t\t)}`}\n\t\t\t\t\tIcon={SquaresPlus}\n\t\t\t\t>\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t{filterOutStoryAndNonComponentFiles(usedIn).map((info) => (\n\t\t\t\t\t\t\t<DepsPreviewItem storyInfo={info} key={info.componentPath} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</Expandable>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\ninterface PropsForDepsPreviewItem {\n\tstoryInfo: StoryInfo\n}\n\nfunction DepsPreviewItem({ storyInfo }: PropsForDepsPreviewItem) {\n\treturn (\n\t\t<li key={storyInfo.componentPath}>\n\t\t\t{storyInfo.storyId ? (\n\t\t\t\t<Expandable\n\t\t\t\t\tIcon={CubeIcon}\n\t\t\t\t\tHeader={<StoryLink info={storyInfo} tooltipPosition=\"right\" />}\n\t\t\t\t>\n\t\t\t\t\t<DepsPreviewContent storyInfo={storyInfo} />\n\t\t\t\t</Expandable>\n\t\t\t) : (\n\t\t\t\t<StoryLink info={storyInfo} />\n\t\t\t)}\n\t\t</li>\n\t)\n}\n\nfunction plural(arr: Array<any>) {\n\treturn arr.length === 1 ? '' : 's'\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,qBAAqB;AACpC,QACC,4CAACA,0DACA,4CAAC,iCAA6B,CACL;;AAI5B,SAAS,6BAA6B;CACrC,MAAM,EAAE,SAASC,+CAAoB;AACrC,KAAI,CAAC,KAAM,QAAO,4CAAC,aAAI,6CAAgD;AAEvE,QACC,4CAAC,SAAI,WAAWC,iDAAE,mBACjB,4CAACC,mCAAU,sBAA+B,EAC1C,4CAAC;EAAmB,WAAW;EAAM,eAAe;GAAS,CACxD;;AAQR,SAAS,mBAAmB,EAC3B,WACA,gBAAgB,QACc;CAC9B,MAAM,EAAE,UAAUF,+CAAoB;CACtC,MAAM,EAAE,WAAW,WAAW,MAAO,UAAU;CAC/C,MAAM,oBAAoBG,8DAAmC,UAAU;CACvE,MAAM,iBAAiBA,8DAAmC,OAAO;AAEjE,QACC,4CAAC,aACC,iBACA,4CAACC;EACA,QAAQ,WAAW,UAAU,WAAW;EACxC,MAAMC;IAEN,4CAACC,yCAA0B,YAAa,CAC5B,EAGd,4CAACF;EACA,QAAQ,YAAY,UAAU,WAAW;EACzC,MAAMG;IAEN,4CAAC,SAAI,WAAWN,iDAAE,YACjB,4CAACO;EACA,OAAM;EACN,aAAa,UAAU;IAEvB,4CAACC,mDAA+B,YAAa,CAC3B,EAEnB,4CAACD;EACA,OAAM;EACN,aAAa,UAAU;IAEvB,4CAACE,+BAAU,MAAM,aAChB,4CAAC,UACA,yBAAyB,EAExB,QAAQ,UAAU,eAAgB,WAAW,KAAK,UAAU,EAC5D,GACA,CACS,CACM,EAEnB,4CAACF;EACA,OAAM;EACN,aAAa,UAAU;IAEvB,4CAACE,+BAAU,MAAM,aAAY,UAAU,QAAoB,CACzC,CACd,CACM,EAEZ,kBAAkB,SAAS,KAC3B,4CAACN;EACA,QAAQ,cACP,kBAAkB,OAClB,YAAY,OAAO,kBAAkB;EACtC,MAAMO;IAEN,4CAAC,YACCR,8DAAmC,UAAU,CAAC,KAAK,SACnD,4CAAC;EAAgB,WAAW;EAAM,KAAK,KAAK;GAAiB,CAC5D,CACE,CACO,EAEb,eAAe,SAAS,KACxB,4CAACC;EACA,QAAQ,WAAW,eAAe,OAAO,YAAY,OACpD,eACA;EACD,MAAMQ;IAEN,4CAAC,YACCT,8DAAmC,OAAO,CAAC,KAAK,SAChD,4CAAC;EAAgB,WAAW;EAAM,KAAK,KAAK;GAAiB,CAC5D,CACE,CACO,CAET;;AAQR,SAAS,gBAAgB,EAAE,aAAsC;AAChE,QACC,4CAAC,QAAG,KAAK,UAAU,iBACjB,UAAU,UACV,4CAACC;EACA,MAAMS;EACN,QAAQ,4CAACH;GAAU,MAAM;GAAW,iBAAgB;IAAU;IAE9D,4CAAC,sBAA8B,YAAa,CAChC,GAEb,4CAACA,+BAAU,MAAM,YAAa,CAE3B;;AAIP,SAAS,OAAO,KAAiB;AAChC,QAAO,IAAI,WAAW,IAAI,KAAK"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DependencyPreviews.mjs","names":[],"sources":["../../src/blocks/DependencyPreviews.tsx"],"sourcesContent":["import React from
|
|
1
|
+
{"version":3,"file":"DependencyPreviews.mjs","names":[],"sources":["../../src/blocks/DependencyPreviews.tsx"],"sourcesContent":["import React from 'react'\nimport { PrimaryPreview } from '../components/PrimaryPreview'\nimport { StoryLink } from '../components/StoryLink'\nimport {\n\tDependencyGraphProvider,\n\tfilterOutStoryAndNonComponentFiles,\n\tuseDependencyGraph,\n} from '../hooks/useDependencyGraph'\nimport type { StoryInfo } from '../types'\n\nimport { ComponentSourceLink } from '../components/ComponentSourceLink'\nimport { Expandable } from '../components/Expandable'\nimport { BuildIcon } from '../components/icons/BuildIcon'\nimport { EyeOpen } from '../components/icons/EyeOpen'\nimport { SquaresPlus } from '../components/icons/SquaresPlus'\n\nimport { ArrowToRectangle } from '../components/icons/ArrowToRectangleIcon'\nimport { CubeIcon } from '../components/icons/CubeIcon'\nimport { PathCopyMolecule } from '../components/PathCopyMolecule'\nimport { SbHeading } from '../components/SbHeading'\nimport s from './DependencyPreviews.module.css'\n\nexport function DependencyPreviews() {\n\treturn (\n\t\t<DependencyGraphProvider>\n\t\t\t<TopLevelDependencyPreviews />\n\t\t</DependencyGraphProvider>\n\t)\n}\n\nfunction TopLevelDependencyPreviews() {\n\tconst { node } = useDependencyGraph()\n\tif (!node) return <div>No dependency previews for this component.</div>\n\n\treturn (\n\t\t<div className={s.topLevelWrapper}>\n\t\t\t<SbHeading>Dependency previews</SbHeading>\n\t\t\t<DepsPreviewContent storyInfo={node} enablePreview={false} />\n\t\t</div>\n\t)\n}\n\ninterface PropsForDepsPreviewContent {\n\tstoryInfo: StoryInfo\n\tenablePreview?: boolean\n}\nfunction DepsPreviewContent({\n\tstoryInfo,\n\tenablePreview = true,\n}: PropsForDepsPreviewContent) {\n\tconst { graph } = useDependencyGraph()\n\tconst { builtWith, usedIn } = graph![storyInfo.componentPath]\n\tconst filteredBuiltWith = filterOutStoryAndNonComponentFiles(builtWith)\n\tconst filteredUsedIn = filterOutStoryAndNonComponentFiles(usedIn)\n\n\treturn (\n\t\t<div>\n\t\t\t{enablePreview && (\n\t\t\t\t<Expandable\n\t\t\t\t\tHeader={`Preview ${storyInfo.storyTitle} component`}\n\t\t\t\t\tIcon={EyeOpen}\n\t\t\t\t>\n\t\t\t\t\t<PrimaryPreview storyInfo={storyInfo} />\n\t\t\t\t</Expandable>\n\t\t\t)}\n\n\t\t\t<Expandable\n\t\t\t\tHeader={`Paths to ${storyInfo.storyTitle} component`}\n\t\t\t\tIcon={ArrowToRectangle}\n\t\t\t>\n\t\t\t\t<div className={s.pathData}>\n\t\t\t\t\t<PathCopyMolecule\n\t\t\t\t\t\tlabel=\"Source File Path\"\n\t\t\t\t\t\tcopyContent={storyInfo.componentPath}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ComponentSourceLink storyInfo={storyInfo} />\n\t\t\t\t\t</PathCopyMolecule>\n\n\t\t\t\t\t<PathCopyMolecule\n\t\t\t\t\t\tlabel=\"Story Title Path\"\n\t\t\t\t\t\tcopyContent={storyInfo.storyTitlePath!}\n\t\t\t\t\t>\n\t\t\t\t\t\t<StoryLink info={storyInfo}>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tdangerouslySetInnerHTML={{\n\t\t\t\t\t\t\t\t\t// allow line breaks on slashes\n\t\t\t\t\t\t\t\t\t__html: storyInfo.storyTitlePath!.replaceAll('/', '/<wbr/>'),\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</StoryLink>\n\t\t\t\t\t</PathCopyMolecule>\n\n\t\t\t\t\t<PathCopyMolecule\n\t\t\t\t\t\tlabel=\"Story Page ID\"\n\t\t\t\t\t\tcopyContent={storyInfo.storyId!}\n\t\t\t\t\t>\n\t\t\t\t\t\t<StoryLink info={storyInfo}>{storyInfo.storyId}</StoryLink>\n\t\t\t\t\t</PathCopyMolecule>\n\t\t\t\t</div>\n\t\t\t</Expandable>\n\n\t\t\t{filteredBuiltWith.length > 0 && (\n\t\t\t\t<Expandable\n\t\t\t\t\tHeader={`Built with ${\n\t\t\t\t\t\tfilteredBuiltWith.length\n\t\t\t\t\t} component${plural(filteredBuiltWith)}`}\n\t\t\t\t\tIcon={BuildIcon}\n\t\t\t\t>\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t{filterOutStoryAndNonComponentFiles(builtWith).map((info) => (\n\t\t\t\t\t\t\t<DepsPreviewItem storyInfo={info} key={info.componentPath} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</Expandable>\n\t\t\t)}\n\t\t\t{filteredUsedIn.length > 0 && (\n\t\t\t\t<Expandable\n\t\t\t\t\tHeader={`Used in ${filteredUsedIn.length} component${plural(\n\t\t\t\t\t\tfilteredUsedIn,\n\t\t\t\t\t)}`}\n\t\t\t\t\tIcon={SquaresPlus}\n\t\t\t\t>\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t{filterOutStoryAndNonComponentFiles(usedIn).map((info) => (\n\t\t\t\t\t\t\t<DepsPreviewItem storyInfo={info} key={info.componentPath} />\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</Expandable>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\ninterface PropsForDepsPreviewItem {\n\tstoryInfo: StoryInfo\n}\n\nfunction DepsPreviewItem({ storyInfo }: PropsForDepsPreviewItem) {\n\treturn (\n\t\t<li key={storyInfo.componentPath}>\n\t\t\t{storyInfo.storyId ? (\n\t\t\t\t<Expandable\n\t\t\t\t\tIcon={CubeIcon}\n\t\t\t\t\tHeader={<StoryLink info={storyInfo} tooltipPosition=\"right\" />}\n\t\t\t\t>\n\t\t\t\t\t<DepsPreviewContent storyInfo={storyInfo} />\n\t\t\t\t</Expandable>\n\t\t\t) : (\n\t\t\t\t<StoryLink info={storyInfo} />\n\t\t\t)}\n\t\t</li>\n\t)\n}\n\nfunction plural(arr: Array<any>) {\n\treturn arr.length === 1 ? '' : 's'\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAsBA,SAAgB,qBAAqB;AACpC,QACC,oCAAC,+BACA,oCAAC,iCAA6B,CACL;;AAI5B,SAAS,6BAA6B;CACrC,MAAM,EAAE,SAAS,oBAAoB;AACrC,KAAI,CAAC,KAAM,QAAO,oCAAC,aAAI,6CAAgD;AAEvE,QACC,oCAAC,SAAI,WAAW,EAAE,mBACjB,oCAAC,iBAAU,sBAA+B,EAC1C,oCAAC;EAAmB,WAAW;EAAM,eAAe;GAAS,CACxD;;AAQR,SAAS,mBAAmB,EAC3B,WACA,gBAAgB,QACc;CAC9B,MAAM,EAAE,UAAU,oBAAoB;CACtC,MAAM,EAAE,WAAW,WAAW,MAAO,UAAU;CAC/C,MAAM,oBAAoB,mCAAmC,UAAU;CACvE,MAAM,iBAAiB,mCAAmC,OAAO;AAEjE,QACC,oCAAC,aACC,iBACA,oCAAC;EACA,QAAQ,WAAW,UAAU,WAAW;EACxC,MAAM;IAEN,oCAAC,kBAA0B,YAAa,CAC5B,EAGd,oCAAC;EACA,QAAQ,YAAY,UAAU,WAAW;EACzC,MAAM;IAEN,oCAAC,SAAI,WAAW,EAAE,YACjB,oCAAC;EACA,OAAM;EACN,aAAa,UAAU;IAEvB,oCAAC,uBAA+B,YAAa,CAC3B,EAEnB,oCAAC;EACA,OAAM;EACN,aAAa,UAAU;IAEvB,oCAAC,aAAU,MAAM,aAChB,oCAAC,UACA,yBAAyB,EAExB,QAAQ,UAAU,eAAgB,WAAW,KAAK,UAAU,EAC5D,GACA,CACS,CACM,EAEnB,oCAAC;EACA,OAAM;EACN,aAAa,UAAU;IAEvB,oCAAC,aAAU,MAAM,aAAY,UAAU,QAAoB,CACzC,CACd,CACM,EAEZ,kBAAkB,SAAS,KAC3B,oCAAC;EACA,QAAQ,cACP,kBAAkB,OAClB,YAAY,OAAO,kBAAkB;EACtC,MAAM;IAEN,oCAAC,YACC,mCAAmC,UAAU,CAAC,KAAK,SACnD,oCAAC;EAAgB,WAAW;EAAM,KAAK,KAAK;GAAiB,CAC5D,CACE,CACO,EAEb,eAAe,SAAS,KACxB,oCAAC;EACA,QAAQ,WAAW,eAAe,OAAO,YAAY,OACpD,eACA;EACD,MAAM;IAEN,oCAAC,YACC,mCAAmC,OAAO,CAAC,KAAK,SAChD,oCAAC;EAAgB,WAAW;EAAM,KAAK,KAAK;GAAiB,CAC5D,CACE,CACO,CAET;;AAQR,SAAS,gBAAgB,EAAE,aAAsC;AAChE,QACC,oCAAC,QAAG,KAAK,UAAU,iBACjB,UAAU,UACV,oCAAC;EACA,MAAM;EACN,QAAQ,oCAAC;GAAU,MAAM;GAAW,iBAAgB;IAAU;IAE9D,oCAAC,sBAA8B,YAAa,CAChC,GAEb,oCAAC,aAAU,MAAM,YAAa,CAE3B;;AAIP,SAAS,OAAO,KAAiB;AAChC,QAAO,IAAI,WAAW,IAAI,KAAK"}
|
package/dist/cli/sb-deps.cjs
CHANGED
|
@@ -147,6 +147,10 @@ function isComponentsSvelte(absPath) {
|
|
|
147
147
|
const norm = absPath.replace(/\\/g, "/");
|
|
148
148
|
return /(?:^|\/)src\/components\/.+\.svelte$/i.test(norm) && !/\.stories?\.svelte$/i.test(norm);
|
|
149
149
|
}
|
|
150
|
+
function isDecoratorSvelte(absPath) {
|
|
151
|
+
const norm = absPath.replace(/\\/g, "/");
|
|
152
|
+
return /(?:^|\/)src\/components\/.+\.decorator\.svelte$/i.test(norm);
|
|
153
|
+
}
|
|
150
154
|
function isComponentsAngularTs(absPath) {
|
|
151
155
|
const norm = absPath.replace(/\\/g, "/");
|
|
152
156
|
return /(?:^|\/)src\/components\/.+\.component\.ts$/i.test(norm);
|
|
@@ -261,7 +265,6 @@ const meta: Meta<typeof ${componentName}> = {
|
|
|
261
265
|
tags: ${JSON.stringify(tags)},
|
|
262
266
|
parameters: {
|
|
263
267
|
layout: 'padded',
|
|
264
|
-
__filePath: import.meta.url,
|
|
265
268
|
} satisfies StoryParameters,
|
|
266
269
|
}
|
|
267
270
|
|
|
@@ -310,6 +313,26 @@ function scaffoldSvelteComponent(absCompPath) {
|
|
|
310
313
|
(0, node_fs.writeFileSync)(absCompPath, tpl, "utf8");
|
|
311
314
|
info(`scaffolded svelte component → ${rel(absCompPath)}`);
|
|
312
315
|
}
|
|
316
|
+
function scaffoldSvelteDecorator(absDecoratorPath) {
|
|
317
|
+
const fullBase = componentBaseFromSvelteComponent(absDecoratorPath);
|
|
318
|
+
const wrappedBase = fullBase.split(".")[0] ?? fullBase;
|
|
319
|
+
const componentName = toPascalCase(wrappedBase);
|
|
320
|
+
const tpl = SCAFFOLD_CONFIG?.svelte?.decorator?.({ componentName }) ?? `<script lang="ts">
|
|
321
|
+
import ${componentName} from "./${componentName}.svelte";
|
|
322
|
+
|
|
323
|
+
interface DecoratorProps {
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
const { }: DecoratorProps = $props();
|
|
327
|
+
<\/script>
|
|
328
|
+
|
|
329
|
+
<div class="decorator">
|
|
330
|
+
<${componentName} />
|
|
331
|
+
</div>
|
|
332
|
+
`;
|
|
333
|
+
(0, node_fs.writeFileSync)(absDecoratorPath, tpl, "utf8");
|
|
334
|
+
info(`scaffolded svelte decorator → ${rel(absDecoratorPath)}`);
|
|
335
|
+
}
|
|
313
336
|
function makeTitleFromSvelteComponent(absCompPath) {
|
|
314
337
|
const srcRoot = (0, node_path.join)(projectRoot, "src") + node_path.sep;
|
|
315
338
|
const normAbs = absCompPath.replace(/\\/g, "/");
|
|
@@ -346,7 +369,6 @@ function scaffoldStoryForSvelteComponent(absCompPath) {
|
|
|
346
369
|
tags: [${tags.map((t) => `'${t}'`).join(", ")}],
|
|
347
370
|
parameters: {
|
|
348
371
|
layout: 'padded',
|
|
349
|
-
__filePath: import.meta.url,
|
|
350
372
|
} satisfies StoryParameters,
|
|
351
373
|
})
|
|
352
374
|
type Args = Omit<PropsFor${componentName}, 'children'>;
|
|
@@ -546,7 +568,6 @@ const meta: Meta<${className}> = {
|
|
|
546
568
|
tags: ${JSON.stringify(tags)},
|
|
547
569
|
parameters: {
|
|
548
570
|
layout: 'padded',
|
|
549
|
-
__filePath: import.meta.url,
|
|
550
571
|
} satisfies StoryParameters,
|
|
551
572
|
}
|
|
552
573
|
|
|
@@ -659,6 +680,12 @@ function startWatcher() {
|
|
|
659
680
|
}
|
|
660
681
|
}
|
|
661
682
|
async function handleSvelteComponentCreation(abs, relPath) {
|
|
683
|
+
if (isDecoratorSvelte(abs)) {
|
|
684
|
+
if (isEmptyOrWhitespace(abs)) {
|
|
685
|
+
scaffoldSvelteDecorator(abs);
|
|
686
|
+
}
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
662
689
|
if (isEmptyOrWhitespace(abs)) {
|
|
663
690
|
scaffoldSvelteComponent(abs);
|
|
664
691
|
}
|
package/dist/cli/sb-deps.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sb-deps.cjs","names":["__filename","__dirname","SCAFFOLD_CONFIG: SbDepsConfig['scaffold']","best: null | { val: string; idx: number }","sep","posix","unitSize: number","unitChar: string","knownMappings: Array<[number, number]>","htmlContent: string | null","timer: NodeJS.Timeout | null","watcherParcel","sbChild: ChildProcess | null","cmd: string","args: string[]","shellMode: boolean","runSetup","watcher: watcherParcel.AsyncSubscription | null"],"sources":["../../cli/sb-deps.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/* eslint-disable no-console */\nimport watcherParcel from '@parcel/watcher'\nimport micromatch from 'micromatch'\nimport { execSync, spawn, type ChildProcess } from 'node:child_process'\nimport {\n\texistsSync,\n\tmkdirSync,\n\treadFileSync,\n\tstatSync,\n\twriteFileSync,\n} from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { basename, dirname, join, posix, resolve, sep } from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport type { SbDepsConfig } from '../src/config.js'\nimport { runSetup } from './setup/index.js'\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Args\n// ───────────────────────────────────────────────────────────────────────────────\nconst argv = process.argv.slice(2)\nconst SUBCOMMAND =\n\targv[0] && !argv[0].startsWith('--') ? argv[0] : null\nconst WATCH = argv.includes('--watch')\nconst RUN_SB_IDX = argv.indexOf('--run-storybook')\nconst RUN_SB = RUN_SB_IDX !== -1\nconst _RUN_SB_NEXT = RUN_SB ? argv[RUN_SB_IDX + 1] : undefined\nconst SB_CUSTOM_CMD =\n\t_RUN_SB_NEXT && !_RUN_SB_NEXT.startsWith('--') ? _RUN_SB_NEXT : undefined\nconst PORT_ARGI = argv.indexOf('--sb-port')\nconst SB_PORT =\n\tPORT_ARGI !== -1 && argv[PORT_ARGI + 1]\n\t\t? Number(argv[PORT_ARGI + 1]) || 6006\n\t\t: 6006\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Paths\n// ───────────────────────────────────────────────────────────────────────────────\nconst projectRoot = process.cwd()\nconst outDir = resolve(projectRoot, '.storybook')\nconst rawPath = join(outDir, 'dependency-previews.raw.json')\nconst cookedPath = join(outDir, 'dependency-previews.json')\n\n// Don't auto-create `.storybook/` for the setup subcommand — the wizard needs to\n// detect whether Storybook has been initialised so it can guide the user. The\n// regular build/watch path still needs the directory to exist for its JSON output.\nif (SUBCOMMAND !== 'setup' && !existsSync(outDir))\n\tmkdirSync(outDir, { recursive: true })\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\n// Resolve depcruise config: prefer project overrides, else bundled default\nconst pkgDefault = resolve(__dirname, 'scripts', 'depcruise.config.cjs')\nconst overrideCandidates = [\n\tresolve(projectRoot, 'depcruise.config.cjs'),\n\tresolve(projectRoot, '.dependency-cruiser.js'),\n\tresolve(projectRoot, '.dependency-cruiser.cjs'),\n]\nconst configPath =\n\toverrideCandidates.find((p) => existsSync(p)) ||\n\t(existsSync(pkgDefault) ? pkgDefault : null)\n\n// Path to postprocess helper (built as ESM)\nconst post = resolve(__dirname, 'scripts', 'postprocess.mjs')\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Config\n// ───────────────────────────────────────────────────────────────────────────────\nfunction checkIsProjectEsm(): boolean {\n\ttry {\n\t\tconst pkg = JSON.parse(\n\t\t\treadFileSync(resolve(projectRoot, 'package.json'), 'utf8'),\n\t\t)\n\t\treturn pkg.type === 'module'\n\t} catch {\n\t\treturn false\n\t}\n}\n\nasync function loadSbDepsConfig(): Promise<SbDepsConfig> {\n\tconst candidates = [\n\t\t{\n\t\t\tpath: resolve(projectRoot, 'sb-deps.config.js'),\n\t\t\tisEsm: checkIsProjectEsm(),\n\t\t},\n\t\t{ path: resolve(projectRoot, 'sb-deps.config.mjs'), isEsm: true },\n\t\t{ path: resolve(projectRoot, 'sb-deps.config.cjs'), isEsm: false },\n\t]\n\tfor (const { path: cfgPath, isEsm } of candidates) {\n\t\tif (!existsSync(cfgPath)) continue\n\t\ttry {\n\t\t\tif (isEsm) {\n\t\t\t\tconst mod = await import(pathToFileURL(cfgPath).href)\n\t\t\t\treturn (mod.default ?? mod) as SbDepsConfig\n\t\t\t} else {\n\t\t\t\tconst req = createRequire(import.meta.url)\n\t\t\t\tconst mod = req(cfgPath)\n\t\t\t\treturn (mod?.default ?? mod) as SbDepsConfig\n\t\t\t}\n\t\t} catch (e) {\n\t\t\terror(`failed to load sb-deps config: ${e}`)\n\t\t}\n\t}\n\treturn {}\n}\n\nlet ANGULAR_SELECTOR_PREFIX = 'app-'\nlet SCAFFOLD_CONFIG: SbDepsConfig['scaffold'] = {}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Runners\n// ───────────────────────────────────────────────────────────────────────────────\nfunction runDepCruiseOnce() {\n\tconst cfgFlag = configPath ? `--config \"${configPath}\"` : '--no-config'\n\tconst cmd = `npx depcruise . ${cfgFlag} --output-type json`\n\tconst start = Date.now()\n\tconst stdout = execSync(cmd, {\n\t\tcwd: projectRoot,\n\t\tstdio: ['ignore', 'pipe', 'inherit'],\n\t\tencoding: 'utf8',\n\t})\n\twriteFileSync(rawPath, stdout, 'utf8')\n\tinfo(`graph ✓ (${ms(Date.now() - start)})`)\n}\n\nfunction postprocessOnce() {\n\tconst start = Date.now()\n\tconst postCmd = `node \"${post}\" \"${rawPath}\" \"${cookedPath}\"`\n\texecSync(postCmd, { cwd: projectRoot, stdio: 'inherit' })\n\tinfo(`compiled ✓ → ${rel(cookedPath)} (${ms(Date.now() - start)})`)\n}\n\nfunction buildOnce() {\n\ttry {\n\t\trunDepCruiseOnce()\n\t\tpostprocessOnce()\n\t} catch (e) {\n\t\terror('build failed')\n\t\tif (!WATCH) throw e\n\t}\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// String utils\n// ───────────────────────────────────────────────────────────────────────────────\nfunction toWords(input: string) {\n\treturn String(input)\n\t\t.replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n\t\t.replace(/[_\\-./]+/g, ' ')\n\t\t.trim()\n\t\t.split(/\\s+/)\n}\nfunction toTitleCase(words: Array<string>) {\n\treturn words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')\n}\nfunction toPascalCase(input: string) {\n\treturn toTitleCase(toWords(input)).replace(/\\s+/g, '')\n}\nfunction toKebabCase(input: string) {\n\treturn toWords(input)\n\t\t.map((w) => w.toLowerCase())\n\t\t.join('-')\n}\n\nfunction isEmptyOrWhitespace(absPath: string) {\n\ttry {\n\t\tconst s = statSync(absPath)\n\t\tif (s.size === 0) return true\n\t\tconst txt = readFileSync(absPath, 'utf8')\n\t\treturn !txt.trim()\n\t} catch {\n\t\treturn true\n\t}\n}\n\n// src/components/**/Thing.tsx ? (and not a story file)\nfunction isComponentsTsx(absPath: string) {\n\tconst norm = absPath.replace(/\\\\/g, '/')\n\treturn (\n\t\t/(?:^|\\/)src\\/components\\/.+\\.tsx$/i.test(norm) &&\n\t\t!/\\.stories?\\.tsx$/i.test(norm)\n\t)\n}\n\n// src/components/**/Thing.svelte ? (and not a story file)\nfunction isComponentsSvelte(absPath: string) {\n\tconst norm = absPath.replace(/\\\\/g, '/')\n\treturn (\n\t\t/(?:^|\\/)src\\/components\\/.+\\.svelte$/i.test(norm) &&\n\t\t!/\\.stories?\\.svelte$/i.test(norm)\n\t)\n}\n\n// src/components/**/Thing.component.ts ? (and not a story file)\nfunction isComponentsAngularTs(absPath: string) {\n\tconst norm = absPath.replace(/\\\\/g, '/')\n\treturn /(?:^|\\/)src\\/components\\/.+\\.component\\.ts$/i.test(norm)\n}\n\n// src/components/**/Thing.component.html ?\nfunction isComponentsAngularHtml(absPath: string) {\n\tconst norm = absPath.replace(/\\\\/g, '/')\n\treturn /(?:^|\\/)src\\/components\\/.+\\.component\\.html$/i.test(norm)\n}\n\nfunction componentBaseFromComponent(absCompPath: string) {\n\treturn basename(absCompPath, '.tsx')\n}\n\nfunction componentBaseFromSvelteComponent(absCompPath: string) {\n\treturn basename(absCompPath, '.svelte')\n}\n\nfunction componentBaseFromAngularComponent(absCompPath: string) {\n\treturn basename(absCompPath).replace(/\\.component\\.(ts|html)$/i, '')\n}\n\nfunction angularComponentTsPath(absPath: string) {\n\tconst base = componentBaseFromAngularComponent(absPath)\n\treturn join(dirname(absPath), `${base}.component.ts`)\n}\n\nfunction detectAtomicTag(absPath: string) {\n\tconst adaptedPath = absPath.toLowerCase().replace(/\\\\/g, '/')\n\tconst tokens = ['atom', 'molecule', 'organism', 'template', 'page', 'icon']\n\tlet best: null | { val: string; idx: number } = null\n\tfor (const t of tokens) {\n\t\tconst idx = adaptedPath.lastIndexOf(t)\n\t\tif (idx !== -1 && (best === null || idx > best.idx))\n\t\t\tbest = { val: t, idx }\n\t}\n\treturn best ? best.val : null\n}\n\nfunction storyPathForComponent(absCompPath: string) {\n\tconst dir = dirname(absCompPath)\n\tconst base = componentBaseFromComponent(absCompPath)\n\treturn join(dir, `${base}.stories.tsx`)\n}\n\nfunction storyPathForSvelteComponent(absCompPath: string) {\n\tconst dir = dirname(absCompPath)\n\tconst base = componentBaseFromSvelteComponent(absCompPath)\n\treturn join(dir, `${base}.stories.svelte`)\n}\n\nfunction makeTitleFromComponent(absCompPath: string) {\n\tconst srcRoot = join(projectRoot, 'src') + sep\n\tconst normAbs = absCompPath.replace(/\\\\/g, '/')\n\tconst relFromSrc = normAbs.startsWith(srcRoot.replace(/\\\\/g, '/'))\n\t\t? normAbs.slice(srcRoot.length)\n\t\t: absCompPath.replace(projectRoot + sep, '').replace(/\\\\/g, '/')\n\n\tconst dir = posix.dirname(relFromSrc)\n\tlet segments = dir.split('/').filter(Boolean)\n\tif (segments[0] && /^components?$/i.test(segments[0]))\n\t\tsegments = segments.slice(1)\n\n\tconst titledFolders = segments.map((s) => toTitleCase(toWords(s)))\n\tconst compName = componentBaseFromComponent(absCompPath)\n\tconst compTitle = toTitleCase(toWords(compName))\n\n\tconst fullStoryPath = [...titledFolders, compTitle].filter(Boolean)\n\n\t// remove duplicates (e.g. Folder/Thing/Thing => Folder/Thing)\n\tconst dedupedStoryPath = [...new Set(fullStoryPath)]\n\n\treturn dedupedStoryPath.join(' / ')\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Story & component scaffolding\n// ───────────────────────────────────────────────────────────────────────────────\nfunction scaffoldComponent(absCompPath: string) {\n\tconst base = componentBaseFromComponent(absCompPath)\n\tconst componentName = toPascalCase(base)\n\tconst propsName = `PropsFor${componentName}`\n\n\tconst tpl =\n\t\tSCAFFOLD_CONFIG?.react?.component?.({ componentName, propsName }) ??\n\t\t`import type { ReactNode } from 'react'\n\nexport interface ${propsName} {\n children?: ReactNode\n}\n\nexport function ${componentName}({ children }: ${propsName}) {\n return (\n <div className=\"${componentName}\">\n <p>${componentName}</p>\n {children}\n </div>\n )\n}\n`\n\twriteFileSync(absCompPath, tpl, 'utf8')\n\tinfo(`scaffolded component → \\${rel(absCompPath)}`)\n}\n\nfunction scaffoldStoryForComponent(absCompPath: string) {\n\tconst base = componentBaseFromComponent(absCompPath)\n\tconst componentName = toPascalCase(base)\n\tconst propsName = `PropsFor${componentName}`\n\tconst title = makeTitleFromComponent(absCompPath)\n\tconst atomic = detectAtomicTag(absCompPath)\n\tconst tags = ['autodocs']\n\tif (atomic) tags.push(atomic)\n\n\tconst storyTpl =\n\t\tSCAFFOLD_CONFIG?.react?.story?.({\n\t\t\tcomponentName,\n\t\t\tpropsName,\n\t\t\ttitle,\n\t\t\ttags,\n\t\t\tbase,\n\t\t}) ??\n\t\t`import type { Meta, StoryObj } from '@storybook/react-vite'\nimport type { StoryParameters } from 'storybook-addon-dependency-previews'\nimport { ${componentName}, type ${propsName} } from './${componentName}'\n\nconst meta: Meta<typeof ${componentName}> = {\n title: '${title}',\n component: ${componentName},\n tags: ${JSON.stringify(tags)},\n parameters: {\n layout: 'padded',\n __filePath: import.meta.url,\n } satisfies StoryParameters,\n}\n\nexport default meta\n\ntype Story = StoryObj<typeof meta>\n\nexport const Primary: Story = {\n args: {} satisfies ${propsName},\n}\n`\n\tconst storyPath = storyPathForComponent(absCompPath)\n\twriteFileSync(storyPath, storyTpl, 'utf8')\n\tinfo(`scaffolded story → \\${rel(storyPath)}`)\n\treturn storyPath\n}\n\nfunction ensureStoryForComponent(absCompPath: string) {\n\tconst sPath = storyPathForComponent(absCompPath)\n\tif (existsSync(sPath)) return null\n\treturn scaffoldStoryForComponent(absCompPath)\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Svelte scaffolding\n// ───────────────────────────────────────────────────────────────────────────────\nfunction scaffoldSvelteComponent(absCompPath: string) {\n\tconst base = componentBaseFromSvelteComponent(absCompPath)\n\tconst componentName = toPascalCase(base)\n\n\tconst tpl =\n\t\tSCAFFOLD_CONFIG?.svelte?.component?.({ componentName }) ??\n\t\t`<script lang=\"ts\">\n\timport type { Snippet } from 'svelte';\n\n\texport interface PropsFor${componentName} {\n\t\tchildren?: Snippet;\n\t}\n\n\tconst { children }: PropsFor${componentName} = $props();\n</script>\n\n<div class=\"${componentName}\">\n\t<p>${componentName}</p>\n\t{@render children?.()}\n</div>\n\n<style>\n\t.${componentName} {\n\t\t/* styles go here */\n\t}\n</style>\n`\n\twriteFileSync(absCompPath, tpl, 'utf8')\n\tinfo(`scaffolded svelte component → ${rel(absCompPath)}`)\n}\n\nfunction makeTitleFromSvelteComponent(absCompPath: string) {\n\tconst srcRoot = join(projectRoot, 'src') + sep\n\tconst normAbs = absCompPath.replace(/\\\\/g, '/')\n\tconst relFromSrc = normAbs.startsWith(srcRoot.replace(/\\\\/g, '/'))\n\t\t? normAbs.slice(srcRoot.length)\n\t\t: absCompPath.replace(projectRoot + sep, '').replace(/\\\\/g, '/')\n\n\tconst dir = posix.dirname(relFromSrc)\n\tlet segments = dir.split('/').filter(Boolean)\n\tif (segments[0] && /^components?$/i.test(segments[0]))\n\t\tsegments = segments.slice(1)\n\n\tconst titledFolders = segments.map((s) => toTitleCase(toWords(s)))\n\tconst compName = componentBaseFromSvelteComponent(absCompPath)\n\tconst compTitle = toTitleCase(toWords(compName))\n\n\tconst fullStoryPath = [...titledFolders, compTitle].filter(Boolean)\n\n\t// remove duplicates (e.g. Folder/Thing/Thing => Folder/Thing)\n\tconst dedupedStoryPath = [...new Set(fullStoryPath)]\n\n\treturn dedupedStoryPath.join(' / ')\n}\n\nfunction scaffoldStoryForSvelteComponent(absCompPath: string) {\n\tconst base = componentBaseFromSvelteComponent(absCompPath)\n\tconst componentName = toPascalCase(base)\n\tconst title = makeTitleFromSvelteComponent(absCompPath)\n\tconst atomic = detectAtomicTag(absCompPath)\n\tconst tags = ['autodocs']\n\tif (atomic) tags.push(atomic)\n\n\tconst storyTpl =\n\t\tSCAFFOLD_CONFIG?.svelte?.story?.({ componentName, title, tags }) ??\n\t\t`<script lang=\"ts\" module>\n\timport type { StoryParameters } from 'storybook-addon-dependency-previews'\n\timport ${componentName}, { type PropsFor${componentName} } from './${componentName}.svelte'\n\timport { defineMeta } from '@storybook/addon-svelte-csf';\n\n\tconst { Story } = defineMeta({\n\t\ttitle: '${title}',\n\t\tcomponent: ${componentName},\n\t\ttags: [${tags.map((t) => `'${t}'`).join(', ')}],\n\t\tparameters: {\n\t\t\tlayout: 'padded',\n\t\t\t__filePath: import.meta.url,\n\t\t} satisfies StoryParameters,\n\t})\n\ttype Args = Omit<PropsFor${componentName}, 'children'>;\n</script>\n\n<Story name=\"Primary\" args={{} satisfies Args}>\n\t<p>${title}</p>\n</Story>\n`\n\tconst storyPath = storyPathForSvelteComponent(absCompPath)\n\twriteFileSync(storyPath, storyTpl, 'utf8')\n\tinfo(`scaffolded svelte story → ${rel(storyPath)}`)\n\treturn storyPath\n}\n\nfunction ensureStoryForSvelteComponent(absCompPath: string) {\n\tconst sPath = storyPathForSvelteComponent(absCompPath)\n\tif (existsSync(sPath)) return null\n\treturn scaffoldStoryForSvelteComponent(absCompPath)\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Angular scaffolding\n// ───────────────────────────────────────────────────────────────────────────────\nfunction storyPathForAngularComponent(absCompPath: string) {\n\tconst dir = dirname(absCompPath)\n\tconst base = componentBaseFromAngularComponent(absCompPath)\n\treturn join(dir, `${base}.stories.ts`)\n}\n\nfunction makeTitleFromAngularComponent(absCompPath: string) {\n\tconst srcRoot = join(projectRoot, 'src') + sep\n\tconst normAbs = absCompPath.replace(/\\\\/g, '/')\n\tconst relFromSrc = normAbs.startsWith(srcRoot.replace(/\\\\/g, '/'))\n\t\t? normAbs.slice(srcRoot.length)\n\t\t: absCompPath.replace(projectRoot + sep, '').replace(/\\\\/g, '/')\n\n\tconst dir = posix.dirname(relFromSrc)\n\tlet segments = dir.split('/').filter(Boolean)\n\tif (segments[0] && /^components?$/i.test(segments[0]))\n\t\tsegments = segments.slice(1)\n\n\tconst titledFolders = segments.map((s) => toTitleCase(toWords(s)))\n\tconst compName = componentBaseFromAngularComponent(absCompPath)\n\tconst compTitle = toTitleCase(toWords(compName))\n\n\tconst fullStoryPath = [...titledFolders, compTitle].filter(Boolean)\n\n\t// remove duplicates (e.g. Folder/Thing/Thing => Folder/Thing)\n\tconst dedupedStoryPath = [...new Set(fullStoryPath)]\n\n\treturn dedupedStoryPath.join(' / ')\n}\n\nfunction gcd(a: number, b: number): number {\n\treturn b === 0 ? a : gcd(b, a % b)\n}\n\n/**\n * Re-indents extracted HTML so that each indent level is exactly one unit deep.\n * Detects whether the content uses tabs or spaces (and how many spaces per level)\n * and enforces that indentation only ever increases by one level at a time.\n */\nfunction normalizeHtmlIndentation(html: string): string {\n\tconst lines = html.split('\\n')\n\tconst indentedLines = lines.filter((l) => l.trim() && /^\\s/.test(l))\n\tif (indentedLines.length === 0) return html\n\n\tconst usesTabs = indentedLines.some((l) => l.startsWith('\\t'))\n\tlet unitSize: number\n\tlet unitChar: string\n\n\tif (usesTabs) {\n\t\tunitSize = 1\n\t\tunitChar = '\\t'\n\t} else {\n\t\tconst spaceCounts = indentedLines\n\t\t\t.map((l) => (l.match(/^ +/) ?? [''])[0].length)\n\t\t\t.filter((n) => n > 0)\n\t\tconst g = spaceCounts.reduce((a, b) => gcd(a, b), spaceCounts[0])\n\t\tunitSize = g\n\t\tunitChar = ' '.repeat(g)\n\t}\n\n\tconst rawLevels = lines.map((line) => {\n\t\tif (!line.trim()) return -1\n\t\tconst ws = line.match(/^(\\s*)/)?.[1] ?? ''\n\t\tif (usesTabs) return [...ws].filter((c) => c === '\\t').length\n\t\treturn Math.round(ws.length / unitSize)\n\t})\n\n\t// Normalize: enforce max +1 increase per step.\n\t// knownMappings stays sorted by rawLevel.\n\tconst knownMappings: Array<[number, number]> = [[0, 0]]\n\tlet prevRaw = 0\n\tlet prevNorm = 0\n\n\tconst normLevels = rawLevels.map((raw) => {\n\t\tif (raw === -1) return -1\n\t\tif (raw === prevRaw) return prevNorm\n\n\t\tif (raw > prevRaw) {\n\t\t\tconst existing = knownMappings.find(([r]) => r === raw)\n\t\t\tif (existing) {\n\t\t\t\t;[prevRaw, prevNorm] = [raw, existing[1]]\n\t\t\t\treturn prevNorm\n\t\t\t}\n\t\t\tprevNorm += 1\n\t\t\tprevRaw = raw\n\t\t\tconst insertIdx = knownMappings.findIndex(([r]) => r > raw)\n\t\t\tif (insertIdx === -1) knownMappings.push([raw, prevNorm])\n\t\t\telse knownMappings.splice(insertIdx, 0, [raw, prevNorm])\n\t\t\treturn prevNorm\n\t\t}\n\n\t\t// Decrease: find the largest known rawLevel <= current\n\t\tconst below = knownMappings.filter(([r]) => r <= raw)\n\t\tconst norm = below.length > 0 ? below[below.length - 1][1] : 0\n\t\t;[prevRaw, prevNorm] = [raw, norm]\n\t\treturn norm\n\t})\n\n\treturn lines\n\t\t.map((line, i) => {\n\t\t\tif (normLevels[i] === -1) return ''\n\t\t\treturn unitChar.repeat(normLevels[i]) + line.trimStart()\n\t\t})\n\t\t.join('\\n')\n}\n\nfunction defaultAngularHtmlTemplate(componentName: string) {\n\treturn (\n\t\tSCAFFOLD_CONFIG?.angular?.componentHtml?.({ componentName }) ??\n\t\t`<p>${componentName}</p>\n\t<ng-content />\n`\n\t)\n}\n\nfunction scaffoldAngularComponent(\n\tabsCompPath: string,\n\ttemplateLocation: 'internal' | 'external',\n) {\n\tconst base = componentBaseFromAngularComponent(absCompPath)\n\tconst componentName = toPascalCase(base)\n\tconst className = `${componentName}Component`\n\tconst selector = ANGULAR_SELECTOR_PREFIX + toKebabCase(componentName)\n\tconst dir = dirname(absCompPath)\n\tconst tsPath = join(dir, `${base}.component.ts`)\n\tconst htmlPath = join(dir, `${base}.component.html`)\n\n\tif (!existsSync(tsPath) || isEmptyOrWhitespace(tsPath)) {\n\t\tconst defaultTsTpl =\n\t\t\ttemplateLocation === 'external'\n\t\t\t\t? `import { Component, input } from '@angular/core';\n\n@Component({\n\tselector: '${selector}',\n\thost: { '[class]': '[\"${componentName}\", class()].join(\" \")' },\n\ttemplateUrl: './${base}.component.html',\n\tstandalone: true,\n\timports: [],\n})\nexport class ${className} {\n class = input<string>('');\n}\n`\n\t\t\t\t: `import { Component, input } from '@angular/core';\n\n@Component({\n\tselector: '${selector}',\n\thost: { '[class]': '[\"${componentName}\", class()].join(\" \")' },\n\ttemplate: \\`\n\t\t<p>${componentName}</p>\n\t\t<ng-content />\n\t\\`,\n\tstandalone: true,\n\timports: [],\n})\nexport class ${className} {\n\tclass = input<string>('');\n}\n`\n\t\tconst tsTpl =\n\t\t\tSCAFFOLD_CONFIG?.angular?.component?.({\n\t\t\t\tcomponentName,\n\t\t\t\tclassName,\n\t\t\t\tselector,\n\t\t\t\tbase,\n\t\t\t\ttemplateLocation,\n\t\t\t}) ?? defaultTsTpl\n\t\twriteFileSync(tsPath, tsTpl, 'utf8')\n\t\tinfo(`scaffolded angular component → ${rel(tsPath)}`)\n\t}\n\n\t// Only scaffold the HTML file when using an external template\n\tif (\n\t\ttemplateLocation === 'external' &&\n\t\t(!existsSync(htmlPath) || isEmptyOrWhitespace(htmlPath))\n\t) {\n\t\twriteFileSync(\n\t\t\thtmlPath,\n\t\t\tdefaultAngularHtmlTemplate(componentName),\n\t\t\t'utf8',\n\t\t)\n\t\tinfo(`scaffolded angular template → ${rel(htmlPath)}`)\n\t}\n}\n\nfunction scaffoldAngularHtmlFromTs(absHtmlPath: string, absTsPath: string) {\n\tconst base = componentBaseFromAngularComponent(absHtmlPath)\n\tconst componentName = toPascalCase(base)\n\n\tlet htmlContent: string | null = null\n\n\t// Try to extract inline template from the existing .ts file\n\tif (existsSync(absTsPath) && !isEmptyOrWhitespace(absTsPath)) {\n\t\tconst tsContent = readFileSync(absTsPath, 'utf8')\n\t\tconst match = tsContent.match(/template:\\s*`([\\s\\S]*?)`/)\n\t\tif (match) {\n\t\t\thtmlContent = normalizeHtmlIndentation(match[1].trim()) + '\\n'\n\t\t\t// Swap template: `...` → templateUrl in the .ts file\n\t\t\tconst updated = tsContent.replace(\n\t\t\t\t/template:\\s*`[\\s\\S]*?`/,\n\t\t\t\t`templateUrl: './${base}.component.html'`,\n\t\t\t)\n\t\t\twriteFileSync(absTsPath, updated, 'utf8')\n\t\t\tinfo(\n\t\t\t\t`updated angular component to use templateUrl → ${rel(absTsPath)}`,\n\t\t\t)\n\t\t}\n\t}\n\n\t// Fall back to default scaffold\n\tif (htmlContent === null) {\n\t\thtmlContent = defaultAngularHtmlTemplate(componentName)\n\t}\n\n\twriteFileSync(absHtmlPath, htmlContent, 'utf8')\n\tinfo(`scaffolded angular template → ${rel(absHtmlPath)}`)\n}\n\nfunction scaffoldStoryForAngularComponent(absCompPath: string) {\n\tconst base = componentBaseFromAngularComponent(absCompPath)\n\tconst componentName = toPascalCase(base)\n\tconst className = `${componentName}Component`\n\tconst title = makeTitleFromAngularComponent(absCompPath)\n\tconst atomic = detectAtomicTag(absCompPath)\n\tconst tags = ['autodocs']\n\tif (atomic) tags.push(atomic)\n\n\tconst storyTpl =\n\t\tSCAFFOLD_CONFIG?.angular?.story?.({\n\t\t\tcomponentName,\n\t\t\tclassName,\n\t\t\tbase,\n\t\t\ttitle,\n\t\t\ttags,\n\t\t}) ??\n\t\t`import type { Meta, StoryObj } from '@storybook/angular'\nimport type { StoryParameters } from 'storybook-addon-dependency-previews'\nimport { ${className} } from './${base}.component'\n\nconst meta: Meta<${className}> = {\n\ttitle: '${title}',\n\tcomponent: ${className},\n\ttags: ${JSON.stringify(tags)},\n\tparameters: {\n\t\tlayout: 'padded',\n\t\t__filePath: import.meta.url,\n\t} satisfies StoryParameters,\n}\n\nexport default meta\n\ntype Story = StoryObj<${className}>\n\nexport const Primary: Story = {\n\targs: {},\n}\n`\n\tconst storyPath = storyPathForAngularComponent(absCompPath)\n\twriteFileSync(storyPath, storyTpl, 'utf8')\n\tinfo(`scaffolded angular story → ${rel(storyPath)}`)\n\treturn storyPath\n}\n\nfunction ensureStoryForAngularComponent(absCompPath: string) {\n\tconst sPath = storyPathForAngularComponent(absCompPath)\n\tif (existsSync(sPath)) return null\n\treturn scaffoldStoryForAngularComponent(absCompPath)\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Watcher\n// ───────────────────────────────────────────────────────────────────────────────\nfunction startWatcher() {\n\tconst root = projectRoot\n\tconst includeGlobs = [\n\t\t'**/*.stories.{ts,tsx,js,jsx,mdx,svelte}',\n\t\t'**/*.story.{ts,tsx,js,jsx,mdx,svelte}',\n\t\t'src/**/*.{ts,tsx,js,jsx,svelte}',\n\t\t'src/**/*.component.html',\n\t\t'depcruise.config.cjs',\n\t\t'.dependency-cruiser.{js,cjs}',\n\t]\n\tconst ignoreGlobs = [\n\t\t'node_modules/**',\n\t\t'.git/**',\n\t\t'.storybook/**',\n\t\t'**/.cache/**',\n\t\t'**/dist/**',\n\t\t'**/build/**',\n\t]\n\n\tlet pending = false\n\tlet timer: NodeJS.Timeout | null = null\n\tlet isDeletingFile = false\n\n\tfunction kick(reason: string, absPath: string) {\n\t\tif (pending) return\n\t\tpending = true\n\t\tif (timer) clearTimeout(timer)\n\t\ttimer = setTimeout(() => {\n\t\t\tinfo(`${reason}: ${rel(absPath)}`)\n\t\t\tbuildOnce()\n\t\t\tpending = false\n\t\t}, 120)\n\t}\n\n\treturn watcherParcel\n\t\t.subscribe(\n\t\t\troot,\n\t\t\tasync (err, events) => {\n\t\t\t\tif (err) {\n\t\t\t\t\terror(`watch error ${err?.message || err}`)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tfor (const ev of events) {\n\t\t\t\t\tconst abs = ev.path\n\t\t\t\t\tconst relPath = rel(abs)\n\t\t\t\t\tif (!micromatch.isMatch(relPath, includeGlobs)) continue\n\n\t\t\t\t\tif (ev.type === 'delete') {\n\t\t\t\t\t\tconsole.log('Deleted:', relPath)\n\t\t\t\t\t\tisDeletingFile = true\n\t\t\t\t\t\tkick('unlink', abs)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// COMPONENT CREATE — scaffold if empty and ensure story\n\t\t\t\t\tif (isComponentsTsx(abs) && ev.type === 'create') {\n\t\t\t\t\t\tawait handleComponentCreation(abs, relPath)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// SVELTE COMPONENT CREATE — scaffold if empty and ensure story\n\t\t\t\t\tif (isComponentsSvelte(abs) && ev.type === 'create') {\n\t\t\t\t\t\tawait handleSvelteComponentCreation(abs, relPath)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// ANGULAR .component.ts CREATE — scaffold with inline template\n\t\t\t\t\tif (isComponentsAngularTs(abs) && ev.type === 'create') {\n\t\t\t\t\t\tawait handleAngularComponentCreation(\n\t\t\t\t\t\t\tabs,\n\t\t\t\t\t\t\trelPath,\n\t\t\t\t\t\t\t'internal',\n\t\t\t\t\t\t)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// ANGULAR .component.html CREATE\n\t\t\t\t\tif (isComponentsAngularHtml(abs) && ev.type === 'create') {\n\t\t\t\t\t\tconst tsPath = angularComponentTsPath(abs)\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\texistsSync(tsPath) &&\n\t\t\t\t\t\t\t!isEmptyOrWhitespace(tsPath)\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t// .ts already exists — scaffold HTML from it (migrate inline template if present)\n\t\t\t\t\t\t\tif (isEmptyOrWhitespace(abs)) {\n\t\t\t\t\t\t\t\tscaffoldAngularHtmlFromTs(abs, tsPath)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconsole.log(\n\t\t\t\t\t\t\t\t'Angular component creation detected:',\n\t\t\t\t\t\t\t\trel(abs),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tconst createdStory =\n\t\t\t\t\t\t\t\tensureStoryForAngularComponent(tsPath)\n\t\t\t\t\t\t\tif (createdStory) {\n\t\t\t\t\t\t\t\tkick('create:story', createdStory)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// .ts doesn't exist yet — existing behavior: scaffold both with external templateUrl\n\t\t\t\t\t\t\tawait handleAngularComponentCreation(\n\t\t\t\t\t\t\t\ttsPath,\n\t\t\t\t\t\t\t\trel(tsPath),\n\t\t\t\t\t\t\t\t'external',\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// normal rebuild\n\t\t\t\t\tkick(ev.type, abs)\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ ignore: ignoreGlobs },\n\t\t)\n\t\t.then((result) => {\n\t\t\tinfo('watching… (ready)')\n\t\t\treturn result\n\t\t})\n\t\t.catch((e) => error(`watch init failed ${e?.message || e}`))\n\n\tasync function handleComponentCreation(abs: string, relPath: string) {\n\t\tif (isEmptyOrWhitespace(abs)) {\n\t\t\tscaffoldComponent(abs)\n\t\t}\n\n\t\tconsole.log('Component creation detected:', relPath)\n\t\tconst createdStory = ensureStoryForComponent(abs)\n\t\tif (createdStory) {\n\t\t\tkick('create:story', createdStory)\n\t\t}\n\t}\n\n\tasync function handleSvelteComponentCreation(abs: string, relPath: string) {\n\t\tif (isEmptyOrWhitespace(abs)) {\n\t\t\tscaffoldSvelteComponent(abs)\n\t\t}\n\n\t\tconst createdStory = ensureStoryForSvelteComponent(abs)\n\t\tif (createdStory) {\n\t\t\tkick('create:story', createdStory)\n\t\t}\n\t}\n\n\tasync function handleAngularComponentCreation(\n\t\tabs: string,\n\t\trelPath: string,\n\t\ttemplateStyle: 'internal' | 'external',\n\t) {\n\t\tif (isEmptyOrWhitespace(abs)) {\n\t\t\tscaffoldAngularComponent(abs, templateStyle)\n\t\t}\n\n\t\tconsole.log('Angular component creation detected:', relPath)\n\t\tconst createdStory = ensureStoryForAngularComponent(abs)\n\t\tif (createdStory) {\n\t\t\tkick('create:story', createdStory)\n\t\t}\n\t}\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Storybook child\n// ───────────────────────────────────────────────────────────────────────────────\nlet sbChild: ChildProcess | null = null\nasync function startStorybook() {\n\tconst isWin = process.platform === 'win32'\n\tlet cmd: string\n\tlet args: string[]\n\tlet shellMode: boolean\n\tif (SB_CUSTOM_CMD) {\n\t\tcmd = SB_CUSTOM_CMD\n\t\targs = []\n\t\tshellMode = true // shell:true handles quoted args and paths with spaces\n\t} else {\n\t\tcmd = 'npx'\n\t\targs = ['-y', 'storybook', 'dev', '-p', String(SB_PORT)]\n\t\tshellMode = isWin // ← critical to avoid EINVAL on Win + Git Bash\n\t}\n\n\tinfo(`[sb-deps] launching: ${cmd} ${args.join(' ')}`)\n\n\tsbChild = spawn(cmd, args, {\n\t\tcwd: projectRoot,\n\t\tstdio: 'inherit',\n\t\tshell: shellMode,\n\t\tenv: process.env,\n\t})\n\n\tsbChild.on('error', (err: any) => {\n\t\terror(`spawn failed: ${err?.message || err}`)\n\t})\n\n\tsbChild.on('exit', (code, sig) => {\n\t\tinfo(`storybook exited (${sig || code})`)\n\t\tsbChild = null\n\t})\n\n\tinfo(`storybook running on http://localhost:${SB_PORT}`)\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Boot\n// ───────────────────────────────────────────────────────────────────────────────\n;(async () => {\n\tif (SUBCOMMAND === 'setup') {\n\t\tawait runSetup(argv.slice(1))\n\t\treturn\n\t}\n\n\tconst cfg = await loadSbDepsConfig()\n\tANGULAR_SELECTOR_PREFIX = cfg.angularSelectorPrefix ?? 'app-'\n\tSCAFFOLD_CONFIG = cfg.scaffold ?? {}\n\n\tbanner('sb-deps')\n\tinfo(`outDir: ${rel(outDir)}`)\n\tinfo(configPath ? `config: ${rel(configPath)}` : 'config: (none)')\n\tbuildOnce()\n\n\tlet watcher: watcherParcel.AsyncSubscription | null = null\n\tif (WATCH) startWatcher().then((w) => (watcher = w || null))\n\tif (RUN_SB) startStorybook()\n\n\tprocess.on('SIGINT', async () => {\n\t\tinfo('shutting down…')\n\t\tawait watcher?.unsubscribe()\n\t\tsbChild?.kill('SIGINT')\n\t\tprocess.exit(0)\n\t})\n})()\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Utils\n// ───────────────────────────────────────────────────────────────────────────────\nfunction rel(p: string) {\n\t// remove the projectRoot prefix and normalize slashes for logs\n\tconst prefix = resolve(projectRoot) + sep\n\treturn p.replace(prefix, '')\n}\nfunction ms(n: number) {\n\treturn `${Math.max(1, Math.round(n))}ms`\n}\nfunction info(msg: string) {\n\tconsole.log('[sb-deps]', msg)\n}\nfunction error(msg: string) {\n\tconsole.error('[sb-deps]', msg)\n}\nfunction banner(title: string) {\n\tconsole.log(`\\n${title} – dependency previews\\n`)\n}\nfunction wait(time = 500) {\n\treturn new Promise((r) => setTimeout(r, time))\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sb-deps.cjs","names":["__filename","__dirname","SCAFFOLD_CONFIG: SbDepsConfig['scaffold']","best: null | { val: string; idx: number }","sep","posix","unitSize: number","unitChar: string","knownMappings: Array<[number, number]>","htmlContent: string | null","timer: NodeJS.Timeout | null","watcherParcel","sbChild: ChildProcess | null","cmd: string","args: string[]","shellMode: boolean","runSetup","watcher: watcherParcel.AsyncSubscription | null"],"sources":["../../cli/sb-deps.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/* eslint-disable no-console */\nimport watcherParcel from '@parcel/watcher'\nimport micromatch from 'micromatch'\nimport { execSync, spawn, type ChildProcess } from 'node:child_process'\nimport {\n\texistsSync,\n\tmkdirSync,\n\treadFileSync,\n\tstatSync,\n\twriteFileSync,\n} from 'node:fs'\nimport { createRequire } from 'node:module'\nimport { basename, dirname, join, posix, resolve, sep } from 'node:path'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport type { SbDepsConfig } from '../src/config.js'\nimport { runSetup } from './setup/index.js'\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Args\n// ───────────────────────────────────────────────────────────────────────────────\nconst argv = process.argv.slice(2)\nconst SUBCOMMAND = argv[0] && !argv[0].startsWith('--') ? argv[0] : null\nconst WATCH = argv.includes('--watch')\nconst RUN_SB_IDX = argv.indexOf('--run-storybook')\nconst RUN_SB = RUN_SB_IDX !== -1\nconst _RUN_SB_NEXT = RUN_SB ? argv[RUN_SB_IDX + 1] : undefined\nconst SB_CUSTOM_CMD =\n\t_RUN_SB_NEXT && !_RUN_SB_NEXT.startsWith('--') ? _RUN_SB_NEXT : undefined\nconst PORT_ARGI = argv.indexOf('--sb-port')\nconst SB_PORT =\n\tPORT_ARGI !== -1 && argv[PORT_ARGI + 1]\n\t\t? Number(argv[PORT_ARGI + 1]) || 6006\n\t\t: 6006\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Paths\n// ───────────────────────────────────────────────────────────────────────────────\nconst projectRoot = process.cwd()\nconst outDir = resolve(projectRoot, '.storybook')\nconst rawPath = join(outDir, 'dependency-previews.raw.json')\nconst cookedPath = join(outDir, 'dependency-previews.json')\n\n// Don't auto-create `.storybook/` for the setup subcommand — the wizard needs to\n// detect whether Storybook has been initialised so it can guide the user. The\n// regular build/watch path still needs the directory to exist for its JSON output.\nif (SUBCOMMAND !== 'setup' && !existsSync(outDir))\n\tmkdirSync(outDir, { recursive: true })\n\nconst __filename = fileURLToPath(import.meta.url)\nconst __dirname = dirname(__filename)\n\n// Resolve depcruise config: prefer project overrides, else bundled default\nconst pkgDefault = resolve(__dirname, 'scripts', 'depcruise.config.cjs')\nconst overrideCandidates = [\n\tresolve(projectRoot, 'depcruise.config.cjs'),\n\tresolve(projectRoot, '.dependency-cruiser.js'),\n\tresolve(projectRoot, '.dependency-cruiser.cjs'),\n]\nconst configPath =\n\toverrideCandidates.find((p) => existsSync(p)) ||\n\t(existsSync(pkgDefault) ? pkgDefault : null)\n\n// Path to postprocess helper (built as ESM)\nconst post = resolve(__dirname, 'scripts', 'postprocess.mjs')\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Config\n// ───────────────────────────────────────────────────────────────────────────────\nfunction checkIsProjectEsm(): boolean {\n\ttry {\n\t\tconst pkg = JSON.parse(\n\t\t\treadFileSync(resolve(projectRoot, 'package.json'), 'utf8'),\n\t\t)\n\t\treturn pkg.type === 'module'\n\t} catch {\n\t\treturn false\n\t}\n}\n\nasync function loadSbDepsConfig(): Promise<SbDepsConfig> {\n\tconst candidates = [\n\t\t{\n\t\t\tpath: resolve(projectRoot, 'sb-deps.config.js'),\n\t\t\tisEsm: checkIsProjectEsm(),\n\t\t},\n\t\t{ path: resolve(projectRoot, 'sb-deps.config.mjs'), isEsm: true },\n\t\t{ path: resolve(projectRoot, 'sb-deps.config.cjs'), isEsm: false },\n\t]\n\tfor (const { path: cfgPath, isEsm } of candidates) {\n\t\tif (!existsSync(cfgPath)) continue\n\t\ttry {\n\t\t\tif (isEsm) {\n\t\t\t\tconst mod = await import(pathToFileURL(cfgPath).href)\n\t\t\t\treturn (mod.default ?? mod) as SbDepsConfig\n\t\t\t} else {\n\t\t\t\tconst req = createRequire(import.meta.url)\n\t\t\t\tconst mod = req(cfgPath)\n\t\t\t\treturn (mod?.default ?? mod) as SbDepsConfig\n\t\t\t}\n\t\t} catch (e) {\n\t\t\terror(`failed to load sb-deps config: ${e}`)\n\t\t}\n\t}\n\treturn {}\n}\n\nlet ANGULAR_SELECTOR_PREFIX = 'app-'\nlet SCAFFOLD_CONFIG: SbDepsConfig['scaffold'] = {}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Runners\n// ───────────────────────────────────────────────────────────────────────────────\nfunction runDepCruiseOnce() {\n\tconst cfgFlag = configPath ? `--config \"${configPath}\"` : '--no-config'\n\tconst cmd = `npx depcruise . ${cfgFlag} --output-type json`\n\tconst start = Date.now()\n\tconst stdout = execSync(cmd, {\n\t\tcwd: projectRoot,\n\t\tstdio: ['ignore', 'pipe', 'inherit'],\n\t\tencoding: 'utf8',\n\t})\n\twriteFileSync(rawPath, stdout, 'utf8')\n\tinfo(`graph ✓ (${ms(Date.now() - start)})`)\n}\n\nfunction postprocessOnce() {\n\tconst start = Date.now()\n\tconst postCmd = `node \"${post}\" \"${rawPath}\" \"${cookedPath}\"`\n\texecSync(postCmd, { cwd: projectRoot, stdio: 'inherit' })\n\tinfo(`compiled ✓ → ${rel(cookedPath)} (${ms(Date.now() - start)})`)\n}\n\nfunction buildOnce() {\n\ttry {\n\t\trunDepCruiseOnce()\n\t\tpostprocessOnce()\n\t} catch (e) {\n\t\terror('build failed')\n\t\tif (!WATCH) throw e\n\t}\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// String utils\n// ───────────────────────────────────────────────────────────────────────────────\nfunction toWords(input: string) {\n\treturn String(input)\n\t\t.replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n\t\t.replace(/[_\\-./]+/g, ' ')\n\t\t.trim()\n\t\t.split(/\\s+/)\n}\nfunction toTitleCase(words: Array<string>) {\n\treturn words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ')\n}\nfunction toPascalCase(input: string) {\n\treturn toTitleCase(toWords(input)).replace(/\\s+/g, '')\n}\nfunction toKebabCase(input: string) {\n\treturn toWords(input)\n\t\t.map((w) => w.toLowerCase())\n\t\t.join('-')\n}\n\nfunction isEmptyOrWhitespace(absPath: string) {\n\ttry {\n\t\tconst s = statSync(absPath)\n\t\tif (s.size === 0) return true\n\t\tconst txt = readFileSync(absPath, 'utf8')\n\t\treturn !txt.trim()\n\t} catch {\n\t\treturn true\n\t}\n}\n\n// src/components/**/Thing.tsx ? (and not a story file)\nfunction isComponentsTsx(absPath: string) {\n\tconst norm = absPath.replace(/\\\\/g, '/')\n\treturn (\n\t\t/(?:^|\\/)src\\/components\\/.+\\.tsx$/i.test(norm) &&\n\t\t!/\\.stories?\\.tsx$/i.test(norm)\n\t)\n}\n\n// src/components/**/Thing.svelte ? (and not a story file)\nfunction isComponentsSvelte(absPath: string) {\n\tconst norm = absPath.replace(/\\\\/g, '/')\n\treturn (\n\t\t/(?:^|\\/)src\\/components\\/.+\\.svelte$/i.test(norm) &&\n\t\t!/\\.stories?\\.svelte$/i.test(norm)\n\t)\n}\n\n// src/components/**/Thing.decorator.svelte ?\nfunction isDecoratorSvelte(absPath: string) {\n\tconst norm = absPath.replace(/\\\\/g, '/')\n\treturn /(?:^|\\/)src\\/components\\/.+\\.decorator\\.svelte$/i.test(norm)\n}\n\n// src/components/**/Thing.component.ts ? (and not a story file)\nfunction isComponentsAngularTs(absPath: string) {\n\tconst norm = absPath.replace(/\\\\/g, '/')\n\treturn /(?:^|\\/)src\\/components\\/.+\\.component\\.ts$/i.test(norm)\n}\n\n// src/components/**/Thing.component.html ?\nfunction isComponentsAngularHtml(absPath: string) {\n\tconst norm = absPath.replace(/\\\\/g, '/')\n\treturn /(?:^|\\/)src\\/components\\/.+\\.component\\.html$/i.test(norm)\n}\n\nfunction componentBaseFromComponent(absCompPath: string) {\n\treturn basename(absCompPath, '.tsx')\n}\n\nfunction componentBaseFromSvelteComponent(absCompPath: string) {\n\treturn basename(absCompPath, '.svelte')\n}\n\nfunction componentBaseFromAngularComponent(absCompPath: string) {\n\treturn basename(absCompPath).replace(/\\.component\\.(ts|html)$/i, '')\n}\n\nfunction angularComponentTsPath(absPath: string) {\n\tconst base = componentBaseFromAngularComponent(absPath)\n\treturn join(dirname(absPath), `${base}.component.ts`)\n}\n\nfunction detectAtomicTag(absPath: string) {\n\tconst adaptedPath = absPath.toLowerCase().replace(/\\\\/g, '/')\n\tconst tokens = ['atom', 'molecule', 'organism', 'template', 'page', 'icon']\n\tlet best: null | { val: string; idx: number } = null\n\tfor (const t of tokens) {\n\t\tconst idx = adaptedPath.lastIndexOf(t)\n\t\tif (idx !== -1 && (best === null || idx > best.idx)) best = { val: t, idx }\n\t}\n\treturn best ? best.val : null\n}\n\nfunction storyPathForComponent(absCompPath: string) {\n\tconst dir = dirname(absCompPath)\n\tconst base = componentBaseFromComponent(absCompPath)\n\treturn join(dir, `${base}.stories.tsx`)\n}\n\nfunction storyPathForSvelteComponent(absCompPath: string) {\n\tconst dir = dirname(absCompPath)\n\tconst base = componentBaseFromSvelteComponent(absCompPath)\n\treturn join(dir, `${base}.stories.svelte`)\n}\n\nfunction makeTitleFromComponent(absCompPath: string) {\n\tconst srcRoot = join(projectRoot, 'src') + sep\n\tconst normAbs = absCompPath.replace(/\\\\/g, '/')\n\tconst relFromSrc = normAbs.startsWith(srcRoot.replace(/\\\\/g, '/'))\n\t\t? normAbs.slice(srcRoot.length)\n\t\t: absCompPath.replace(projectRoot + sep, '').replace(/\\\\/g, '/')\n\n\tconst dir = posix.dirname(relFromSrc)\n\tlet segments = dir.split('/').filter(Boolean)\n\tif (segments[0] && /^components?$/i.test(segments[0]))\n\t\tsegments = segments.slice(1)\n\n\tconst titledFolders = segments.map((s) => toTitleCase(toWords(s)))\n\tconst compName = componentBaseFromComponent(absCompPath)\n\tconst compTitle = toTitleCase(toWords(compName))\n\n\tconst fullStoryPath = [...titledFolders, compTitle].filter(Boolean)\n\n\t// remove duplicates (e.g. Folder/Thing/Thing => Folder/Thing)\n\tconst dedupedStoryPath = [...new Set(fullStoryPath)]\n\n\treturn dedupedStoryPath.join(' / ')\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Story & component scaffolding\n// ───────────────────────────────────────────────────────────────────────────────\nfunction scaffoldComponent(absCompPath: string) {\n\tconst base = componentBaseFromComponent(absCompPath)\n\tconst componentName = toPascalCase(base)\n\tconst propsName = `PropsFor${componentName}`\n\n\tconst tpl =\n\t\tSCAFFOLD_CONFIG?.react?.component?.({ componentName, propsName }) ??\n\t\t`import type { ReactNode } from 'react'\n\nexport interface ${propsName} {\n children?: ReactNode\n}\n\nexport function ${componentName}({ children }: ${propsName}) {\n return (\n <div className=\"${componentName}\">\n <p>${componentName}</p>\n {children}\n </div>\n )\n}\n`\n\twriteFileSync(absCompPath, tpl, 'utf8')\n\tinfo(`scaffolded component → \\${rel(absCompPath)}`)\n}\n\nfunction scaffoldStoryForComponent(absCompPath: string) {\n\tconst base = componentBaseFromComponent(absCompPath)\n\tconst componentName = toPascalCase(base)\n\tconst propsName = `PropsFor${componentName}`\n\tconst title = makeTitleFromComponent(absCompPath)\n\tconst atomic = detectAtomicTag(absCompPath)\n\tconst tags = ['autodocs']\n\tif (atomic) tags.push(atomic)\n\n\tconst storyTpl =\n\t\tSCAFFOLD_CONFIG?.react?.story?.({\n\t\t\tcomponentName,\n\t\t\tpropsName,\n\t\t\ttitle,\n\t\t\ttags,\n\t\t\tbase,\n\t\t}) ??\n\t\t`import type { Meta, StoryObj } from '@storybook/react-vite'\nimport type { StoryParameters } from 'storybook-addon-dependency-previews'\nimport { ${componentName}, type ${propsName} } from './${componentName}'\n\nconst meta: Meta<typeof ${componentName}> = {\n title: '${title}',\n component: ${componentName},\n tags: ${JSON.stringify(tags)},\n parameters: {\n layout: 'padded',\n } satisfies StoryParameters,\n}\n\nexport default meta\n\ntype Story = StoryObj<typeof meta>\n\nexport const Primary: Story = {\n args: {} satisfies ${propsName},\n}\n`\n\tconst storyPath = storyPathForComponent(absCompPath)\n\twriteFileSync(storyPath, storyTpl, 'utf8')\n\tinfo(`scaffolded story → \\${rel(storyPath)}`)\n\treturn storyPath\n}\n\nfunction ensureStoryForComponent(absCompPath: string) {\n\tconst sPath = storyPathForComponent(absCompPath)\n\tif (existsSync(sPath)) return null\n\treturn scaffoldStoryForComponent(absCompPath)\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Svelte scaffolding\n// ───────────────────────────────────────────────────────────────────────────────\nfunction scaffoldSvelteComponent(absCompPath: string) {\n\tconst base = componentBaseFromSvelteComponent(absCompPath)\n\tconst componentName = toPascalCase(base)\n\n\tconst tpl =\n\t\tSCAFFOLD_CONFIG?.svelte?.component?.({ componentName }) ??\n\t\t`<script lang=\"ts\">\n\timport type { Snippet } from 'svelte';\n\n\texport interface PropsFor${componentName} {\n\t\tchildren?: Snippet;\n\t}\n\n\tconst { children }: PropsFor${componentName} = $props();\n</script>\n\n<div class=\"${componentName}\">\n\t<p>${componentName}</p>\n\t{@render children?.()}\n</div>\n\n<style>\n\t.${componentName} {\n\t\t/* styles go here */\n\t}\n</style>\n`\n\twriteFileSync(absCompPath, tpl, 'utf8')\n\tinfo(`scaffolded svelte component → ${rel(absCompPath)}`)\n}\n\nfunction scaffoldSvelteDecorator(absDecoratorPath: string) {\n\tconst fullBase = componentBaseFromSvelteComponent(absDecoratorPath)\n\tconst wrappedBase = fullBase.split('.')[0] ?? fullBase\n\tconst componentName = toPascalCase(wrappedBase)\n\n\tconst tpl =\n\t\tSCAFFOLD_CONFIG?.svelte?.decorator?.({ componentName }) ??\n\t\t`<script lang=\"ts\">\n\timport ${componentName} from \"./${componentName}.svelte\";\n\n\tinterface DecoratorProps {\n\t}\n\n\tconst { }: DecoratorProps = $props();\n</script>\n\n<div class=\"decorator\">\n\t<${componentName} />\n</div>\n`\n\twriteFileSync(absDecoratorPath, tpl, 'utf8')\n\tinfo(`scaffolded svelte decorator → ${rel(absDecoratorPath)}`)\n}\n\nfunction makeTitleFromSvelteComponent(absCompPath: string) {\n\tconst srcRoot = join(projectRoot, 'src') + sep\n\tconst normAbs = absCompPath.replace(/\\\\/g, '/')\n\tconst relFromSrc = normAbs.startsWith(srcRoot.replace(/\\\\/g, '/'))\n\t\t? normAbs.slice(srcRoot.length)\n\t\t: absCompPath.replace(projectRoot + sep, '').replace(/\\\\/g, '/')\n\n\tconst dir = posix.dirname(relFromSrc)\n\tlet segments = dir.split('/').filter(Boolean)\n\tif (segments[0] && /^components?$/i.test(segments[0]))\n\t\tsegments = segments.slice(1)\n\n\tconst titledFolders = segments.map((s) => toTitleCase(toWords(s)))\n\tconst compName = componentBaseFromSvelteComponent(absCompPath)\n\tconst compTitle = toTitleCase(toWords(compName))\n\n\tconst fullStoryPath = [...titledFolders, compTitle].filter(Boolean)\n\n\t// remove duplicates (e.g. Folder/Thing/Thing => Folder/Thing)\n\tconst dedupedStoryPath = [...new Set(fullStoryPath)]\n\n\treturn dedupedStoryPath.join(' / ')\n}\n\nfunction scaffoldStoryForSvelteComponent(absCompPath: string) {\n\tconst base = componentBaseFromSvelteComponent(absCompPath)\n\tconst componentName = toPascalCase(base)\n\tconst title = makeTitleFromSvelteComponent(absCompPath)\n\tconst atomic = detectAtomicTag(absCompPath)\n\tconst tags = ['autodocs']\n\tif (atomic) tags.push(atomic)\n\n\tconst storyTpl =\n\t\tSCAFFOLD_CONFIG?.svelte?.story?.({ componentName, title, tags }) ??\n\t\t`<script lang=\"ts\" module>\n\timport type { StoryParameters } from 'storybook-addon-dependency-previews'\n\timport ${componentName}, { type PropsFor${componentName} } from './${componentName}.svelte'\n\timport { defineMeta } from '@storybook/addon-svelte-csf';\n\n\tconst { Story } = defineMeta({\n\t\ttitle: '${title}',\n\t\tcomponent: ${componentName},\n\t\ttags: [${tags.map((t) => `'${t}'`).join(', ')}],\n\t\tparameters: {\n\t\t\tlayout: 'padded',\n\t\t} satisfies StoryParameters,\n\t})\n\ttype Args = Omit<PropsFor${componentName}, 'children'>;\n</script>\n\n<Story name=\"Primary\" args={{} satisfies Args}>\n\t<p>${title}</p>\n</Story>\n`\n\tconst storyPath = storyPathForSvelteComponent(absCompPath)\n\twriteFileSync(storyPath, storyTpl, 'utf8')\n\tinfo(`scaffolded svelte story → ${rel(storyPath)}`)\n\treturn storyPath\n}\n\nfunction ensureStoryForSvelteComponent(absCompPath: string) {\n\tconst sPath = storyPathForSvelteComponent(absCompPath)\n\tif (existsSync(sPath)) return null\n\treturn scaffoldStoryForSvelteComponent(absCompPath)\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Angular scaffolding\n// ───────────────────────────────────────────────────────────────────────────────\nfunction storyPathForAngularComponent(absCompPath: string) {\n\tconst dir = dirname(absCompPath)\n\tconst base = componentBaseFromAngularComponent(absCompPath)\n\treturn join(dir, `${base}.stories.ts`)\n}\n\nfunction makeTitleFromAngularComponent(absCompPath: string) {\n\tconst srcRoot = join(projectRoot, 'src') + sep\n\tconst normAbs = absCompPath.replace(/\\\\/g, '/')\n\tconst relFromSrc = normAbs.startsWith(srcRoot.replace(/\\\\/g, '/'))\n\t\t? normAbs.slice(srcRoot.length)\n\t\t: absCompPath.replace(projectRoot + sep, '').replace(/\\\\/g, '/')\n\n\tconst dir = posix.dirname(relFromSrc)\n\tlet segments = dir.split('/').filter(Boolean)\n\tif (segments[0] && /^components?$/i.test(segments[0]))\n\t\tsegments = segments.slice(1)\n\n\tconst titledFolders = segments.map((s) => toTitleCase(toWords(s)))\n\tconst compName = componentBaseFromAngularComponent(absCompPath)\n\tconst compTitle = toTitleCase(toWords(compName))\n\n\tconst fullStoryPath = [...titledFolders, compTitle].filter(Boolean)\n\n\t// remove duplicates (e.g. Folder/Thing/Thing => Folder/Thing)\n\tconst dedupedStoryPath = [...new Set(fullStoryPath)]\n\n\treturn dedupedStoryPath.join(' / ')\n}\n\nfunction gcd(a: number, b: number): number {\n\treturn b === 0 ? a : gcd(b, a % b)\n}\n\n/**\n * Re-indents extracted HTML so that each indent level is exactly one unit deep.\n * Detects whether the content uses tabs or spaces (and how many spaces per level)\n * and enforces that indentation only ever increases by one level at a time.\n */\nfunction normalizeHtmlIndentation(html: string): string {\n\tconst lines = html.split('\\n')\n\tconst indentedLines = lines.filter((l) => l.trim() && /^\\s/.test(l))\n\tif (indentedLines.length === 0) return html\n\n\tconst usesTabs = indentedLines.some((l) => l.startsWith('\\t'))\n\tlet unitSize: number\n\tlet unitChar: string\n\n\tif (usesTabs) {\n\t\tunitSize = 1\n\t\tunitChar = '\\t'\n\t} else {\n\t\tconst spaceCounts = indentedLines\n\t\t\t.map((l) => (l.match(/^ +/) ?? [''])[0].length)\n\t\t\t.filter((n) => n > 0)\n\t\tconst g = spaceCounts.reduce((a, b) => gcd(a, b), spaceCounts[0])\n\t\tunitSize = g\n\t\tunitChar = ' '.repeat(g)\n\t}\n\n\tconst rawLevels = lines.map((line) => {\n\t\tif (!line.trim()) return -1\n\t\tconst ws = line.match(/^(\\s*)/)?.[1] ?? ''\n\t\tif (usesTabs) return [...ws].filter((c) => c === '\\t').length\n\t\treturn Math.round(ws.length / unitSize)\n\t})\n\n\t// Normalize: enforce max +1 increase per step.\n\t// knownMappings stays sorted by rawLevel.\n\tconst knownMappings: Array<[number, number]> = [[0, 0]]\n\tlet prevRaw = 0\n\tlet prevNorm = 0\n\n\tconst normLevels = rawLevels.map((raw) => {\n\t\tif (raw === -1) return -1\n\t\tif (raw === prevRaw) return prevNorm\n\n\t\tif (raw > prevRaw) {\n\t\t\tconst existing = knownMappings.find(([r]) => r === raw)\n\t\t\tif (existing) {\n\t\t\t\t;[prevRaw, prevNorm] = [raw, existing[1]]\n\t\t\t\treturn prevNorm\n\t\t\t}\n\t\t\tprevNorm += 1\n\t\t\tprevRaw = raw\n\t\t\tconst insertIdx = knownMappings.findIndex(([r]) => r > raw)\n\t\t\tif (insertIdx === -1) knownMappings.push([raw, prevNorm])\n\t\t\telse knownMappings.splice(insertIdx, 0, [raw, prevNorm])\n\t\t\treturn prevNorm\n\t\t}\n\n\t\t// Decrease: find the largest known rawLevel <= current\n\t\tconst below = knownMappings.filter(([r]) => r <= raw)\n\t\tconst norm = below.length > 0 ? below[below.length - 1][1] : 0\n\t\t;[prevRaw, prevNorm] = [raw, norm]\n\t\treturn norm\n\t})\n\n\treturn lines\n\t\t.map((line, i) => {\n\t\t\tif (normLevels[i] === -1) return ''\n\t\t\treturn unitChar.repeat(normLevels[i]) + line.trimStart()\n\t\t})\n\t\t.join('\\n')\n}\n\nfunction defaultAngularHtmlTemplate(componentName: string) {\n\treturn (\n\t\tSCAFFOLD_CONFIG?.angular?.componentHtml?.({ componentName }) ??\n\t\t`<p>${componentName}</p>\n\t<ng-content />\n`\n\t)\n}\n\nfunction scaffoldAngularComponent(\n\tabsCompPath: string,\n\ttemplateLocation: 'internal' | 'external',\n) {\n\tconst base = componentBaseFromAngularComponent(absCompPath)\n\tconst componentName = toPascalCase(base)\n\tconst className = `${componentName}Component`\n\tconst selector = ANGULAR_SELECTOR_PREFIX + toKebabCase(componentName)\n\tconst dir = dirname(absCompPath)\n\tconst tsPath = join(dir, `${base}.component.ts`)\n\tconst htmlPath = join(dir, `${base}.component.html`)\n\n\tif (!existsSync(tsPath) || isEmptyOrWhitespace(tsPath)) {\n\t\tconst defaultTsTpl =\n\t\t\ttemplateLocation === 'external'\n\t\t\t\t? `import { Component, input } from '@angular/core';\n\n@Component({\n\tselector: '${selector}',\n\thost: { '[class]': '[\"${componentName}\", class()].join(\" \")' },\n\ttemplateUrl: './${base}.component.html',\n\tstandalone: true,\n\timports: [],\n})\nexport class ${className} {\n class = input<string>('');\n}\n`\n\t\t\t\t: `import { Component, input } from '@angular/core';\n\n@Component({\n\tselector: '${selector}',\n\thost: { '[class]': '[\"${componentName}\", class()].join(\" \")' },\n\ttemplate: \\`\n\t\t<p>${componentName}</p>\n\t\t<ng-content />\n\t\\`,\n\tstandalone: true,\n\timports: [],\n})\nexport class ${className} {\n\tclass = input<string>('');\n}\n`\n\t\tconst tsTpl =\n\t\t\tSCAFFOLD_CONFIG?.angular?.component?.({\n\t\t\t\tcomponentName,\n\t\t\t\tclassName,\n\t\t\t\tselector,\n\t\t\t\tbase,\n\t\t\t\ttemplateLocation,\n\t\t\t}) ?? defaultTsTpl\n\t\twriteFileSync(tsPath, tsTpl, 'utf8')\n\t\tinfo(`scaffolded angular component → ${rel(tsPath)}`)\n\t}\n\n\t// Only scaffold the HTML file when using an external template\n\tif (\n\t\ttemplateLocation === 'external' &&\n\t\t(!existsSync(htmlPath) || isEmptyOrWhitespace(htmlPath))\n\t) {\n\t\twriteFileSync(htmlPath, defaultAngularHtmlTemplate(componentName), 'utf8')\n\t\tinfo(`scaffolded angular template → ${rel(htmlPath)}`)\n\t}\n}\n\nfunction scaffoldAngularHtmlFromTs(absHtmlPath: string, absTsPath: string) {\n\tconst base = componentBaseFromAngularComponent(absHtmlPath)\n\tconst componentName = toPascalCase(base)\n\n\tlet htmlContent: string | null = null\n\n\t// Try to extract inline template from the existing .ts file\n\tif (existsSync(absTsPath) && !isEmptyOrWhitespace(absTsPath)) {\n\t\tconst tsContent = readFileSync(absTsPath, 'utf8')\n\t\tconst match = tsContent.match(/template:\\s*`([\\s\\S]*?)`/)\n\t\tif (match) {\n\t\t\thtmlContent = normalizeHtmlIndentation(match[1].trim()) + '\\n'\n\t\t\t// Swap template: `...` → templateUrl in the .ts file\n\t\t\tconst updated = tsContent.replace(\n\t\t\t\t/template:\\s*`[\\s\\S]*?`/,\n\t\t\t\t`templateUrl: './${base}.component.html'`,\n\t\t\t)\n\t\t\twriteFileSync(absTsPath, updated, 'utf8')\n\t\t\tinfo(`updated angular component to use templateUrl → ${rel(absTsPath)}`)\n\t\t}\n\t}\n\n\t// Fall back to default scaffold\n\tif (htmlContent === null) {\n\t\thtmlContent = defaultAngularHtmlTemplate(componentName)\n\t}\n\n\twriteFileSync(absHtmlPath, htmlContent, 'utf8')\n\tinfo(`scaffolded angular template → ${rel(absHtmlPath)}`)\n}\n\nfunction scaffoldStoryForAngularComponent(absCompPath: string) {\n\tconst base = componentBaseFromAngularComponent(absCompPath)\n\tconst componentName = toPascalCase(base)\n\tconst className = `${componentName}Component`\n\tconst title = makeTitleFromAngularComponent(absCompPath)\n\tconst atomic = detectAtomicTag(absCompPath)\n\tconst tags = ['autodocs']\n\tif (atomic) tags.push(atomic)\n\n\tconst storyTpl =\n\t\tSCAFFOLD_CONFIG?.angular?.story?.({\n\t\t\tcomponentName,\n\t\t\tclassName,\n\t\t\tbase,\n\t\t\ttitle,\n\t\t\ttags,\n\t\t}) ??\n\t\t`import type { Meta, StoryObj } from '@storybook/angular'\nimport type { StoryParameters } from 'storybook-addon-dependency-previews'\nimport { ${className} } from './${base}.component'\n\nconst meta: Meta<${className}> = {\n\ttitle: '${title}',\n\tcomponent: ${className},\n\ttags: ${JSON.stringify(tags)},\n\tparameters: {\n\t\tlayout: 'padded',\n\t} satisfies StoryParameters,\n}\n\nexport default meta\n\ntype Story = StoryObj<${className}>\n\nexport const Primary: Story = {\n\targs: {},\n}\n`\n\tconst storyPath = storyPathForAngularComponent(absCompPath)\n\twriteFileSync(storyPath, storyTpl, 'utf8')\n\tinfo(`scaffolded angular story → ${rel(storyPath)}`)\n\treturn storyPath\n}\n\nfunction ensureStoryForAngularComponent(absCompPath: string) {\n\tconst sPath = storyPathForAngularComponent(absCompPath)\n\tif (existsSync(sPath)) return null\n\treturn scaffoldStoryForAngularComponent(absCompPath)\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Watcher\n// ───────────────────────────────────────────────────────────────────────────────\nfunction startWatcher() {\n\tconst root = projectRoot\n\tconst includeGlobs = [\n\t\t'**/*.stories.{ts,tsx,js,jsx,mdx,svelte}',\n\t\t'**/*.story.{ts,tsx,js,jsx,mdx,svelte}',\n\t\t'src/**/*.{ts,tsx,js,jsx,svelte}',\n\t\t'src/**/*.component.html',\n\t\t'depcruise.config.cjs',\n\t\t'.dependency-cruiser.{js,cjs}',\n\t]\n\tconst ignoreGlobs = [\n\t\t'node_modules/**',\n\t\t'.git/**',\n\t\t'.storybook/**',\n\t\t'**/.cache/**',\n\t\t'**/dist/**',\n\t\t'**/build/**',\n\t]\n\n\tlet pending = false\n\tlet timer: NodeJS.Timeout | null = null\n\tlet isDeletingFile = false\n\n\tfunction kick(reason: string, absPath: string) {\n\t\tif (pending) return\n\t\tpending = true\n\t\tif (timer) clearTimeout(timer)\n\t\ttimer = setTimeout(() => {\n\t\t\tinfo(`${reason}: ${rel(absPath)}`)\n\t\t\tbuildOnce()\n\t\t\tpending = false\n\t\t}, 120)\n\t}\n\n\treturn watcherParcel\n\t\t.subscribe(\n\t\t\troot,\n\t\t\tasync (err, events) => {\n\t\t\t\tif (err) {\n\t\t\t\t\terror(`watch error ${err?.message || err}`)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tfor (const ev of events) {\n\t\t\t\t\tconst abs = ev.path\n\t\t\t\t\tconst relPath = rel(abs)\n\t\t\t\t\tif (!micromatch.isMatch(relPath, includeGlobs)) continue\n\n\t\t\t\t\tif (ev.type === 'delete') {\n\t\t\t\t\t\tconsole.log('Deleted:', relPath)\n\t\t\t\t\t\tisDeletingFile = true\n\t\t\t\t\t\tkick('unlink', abs)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// COMPONENT CREATE — scaffold if empty and ensure story\n\t\t\t\t\tif (isComponentsTsx(abs) && ev.type === 'create') {\n\t\t\t\t\t\tawait handleComponentCreation(abs, relPath)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// SVELTE COMPONENT CREATE — scaffold if empty and ensure story\n\t\t\t\t\tif (isComponentsSvelte(abs) && ev.type === 'create') {\n\t\t\t\t\t\tawait handleSvelteComponentCreation(abs, relPath)\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// ANGULAR .component.ts CREATE — scaffold with inline template\n\t\t\t\t\tif (isComponentsAngularTs(abs) && ev.type === 'create') {\n\t\t\t\t\t\tawait handleAngularComponentCreation(abs, relPath, 'internal')\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// ANGULAR .component.html CREATE\n\t\t\t\t\tif (isComponentsAngularHtml(abs) && ev.type === 'create') {\n\t\t\t\t\t\tconst tsPath = angularComponentTsPath(abs)\n\t\t\t\t\t\tif (existsSync(tsPath) && !isEmptyOrWhitespace(tsPath)) {\n\t\t\t\t\t\t\t// .ts already exists — scaffold HTML from it (migrate inline template if present)\n\t\t\t\t\t\t\tif (isEmptyOrWhitespace(abs)) {\n\t\t\t\t\t\t\t\tscaffoldAngularHtmlFromTs(abs, tsPath)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconsole.log('Angular component creation detected:', rel(abs))\n\t\t\t\t\t\t\tconst createdStory = ensureStoryForAngularComponent(tsPath)\n\t\t\t\t\t\t\tif (createdStory) {\n\t\t\t\t\t\t\t\tkick('create:story', createdStory)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// .ts doesn't exist yet — existing behavior: scaffold both with external templateUrl\n\t\t\t\t\t\t\tawait handleAngularComponentCreation(\n\t\t\t\t\t\t\t\ttsPath,\n\t\t\t\t\t\t\t\trel(tsPath),\n\t\t\t\t\t\t\t\t'external',\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// normal rebuild\n\t\t\t\t\tkick(ev.type, abs)\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ ignore: ignoreGlobs },\n\t\t)\n\t\t.then((result) => {\n\t\t\tinfo('watching… (ready)')\n\t\t\treturn result\n\t\t})\n\t\t.catch((e) => error(`watch init failed ${e?.message || e}`))\n\n\tasync function handleComponentCreation(abs: string, relPath: string) {\n\t\tif (isEmptyOrWhitespace(abs)) {\n\t\t\tscaffoldComponent(abs)\n\t\t}\n\n\t\tconsole.log('Component creation detected:', relPath)\n\t\tconst createdStory = ensureStoryForComponent(abs)\n\t\tif (createdStory) {\n\t\t\tkick('create:story', createdStory)\n\t\t}\n\t}\n\n\tasync function handleSvelteComponentCreation(abs: string, relPath: string) {\n\t\tif (isDecoratorSvelte(abs)) {\n\t\t\tif (isEmptyOrWhitespace(abs)) {\n\t\t\t\tscaffoldSvelteDecorator(abs)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tif (isEmptyOrWhitespace(abs)) {\n\t\t\tscaffoldSvelteComponent(abs)\n\t\t}\n\n\t\tconst createdStory = ensureStoryForSvelteComponent(abs)\n\t\tif (createdStory) {\n\t\t\tkick('create:story', createdStory)\n\t\t}\n\t}\n\n\tasync function handleAngularComponentCreation(\n\t\tabs: string,\n\t\trelPath: string,\n\t\ttemplateStyle: 'internal' | 'external',\n\t) {\n\t\tif (isEmptyOrWhitespace(abs)) {\n\t\t\tscaffoldAngularComponent(abs, templateStyle)\n\t\t}\n\n\t\tconsole.log('Angular component creation detected:', relPath)\n\t\tconst createdStory = ensureStoryForAngularComponent(abs)\n\t\tif (createdStory) {\n\t\t\tkick('create:story', createdStory)\n\t\t}\n\t}\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Storybook child\n// ───────────────────────────────────────────────────────────────────────────────\nlet sbChild: ChildProcess | null = null\nasync function startStorybook() {\n\tconst isWin = process.platform === 'win32'\n\tlet cmd: string\n\tlet args: string[]\n\tlet shellMode: boolean\n\tif (SB_CUSTOM_CMD) {\n\t\tcmd = SB_CUSTOM_CMD\n\t\targs = []\n\t\tshellMode = true // shell:true handles quoted args and paths with spaces\n\t} else {\n\t\tcmd = 'npx'\n\t\targs = ['-y', 'storybook', 'dev', '-p', String(SB_PORT)]\n\t\tshellMode = isWin // ← critical to avoid EINVAL on Win + Git Bash\n\t}\n\n\tinfo(`[sb-deps] launching: ${cmd} ${args.join(' ')}`)\n\n\tsbChild = spawn(cmd, args, {\n\t\tcwd: projectRoot,\n\t\tstdio: 'inherit',\n\t\tshell: shellMode,\n\t\tenv: process.env,\n\t})\n\n\tsbChild.on('error', (err: any) => {\n\t\terror(`spawn failed: ${err?.message || err}`)\n\t})\n\n\tsbChild.on('exit', (code, sig) => {\n\t\tinfo(`storybook exited (${sig || code})`)\n\t\tsbChild = null\n\t})\n\n\tinfo(`storybook running on http://localhost:${SB_PORT}`)\n}\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Boot\n// ───────────────────────────────────────────────────────────────────────────────\n;(async () => {\n\tif (SUBCOMMAND === 'setup') {\n\t\tawait runSetup(argv.slice(1))\n\t\treturn\n\t}\n\n\tconst cfg = await loadSbDepsConfig()\n\tANGULAR_SELECTOR_PREFIX = cfg.angularSelectorPrefix ?? 'app-'\n\tSCAFFOLD_CONFIG = cfg.scaffold ?? {}\n\n\tbanner('sb-deps')\n\tinfo(`outDir: ${rel(outDir)}`)\n\tinfo(configPath ? `config: ${rel(configPath)}` : 'config: (none)')\n\tbuildOnce()\n\n\tlet watcher: watcherParcel.AsyncSubscription | null = null\n\tif (WATCH) startWatcher().then((w) => (watcher = w || null))\n\tif (RUN_SB) startStorybook()\n\n\tprocess.on('SIGINT', async () => {\n\t\tinfo('shutting down…')\n\t\tawait watcher?.unsubscribe()\n\t\tsbChild?.kill('SIGINT')\n\t\tprocess.exit(0)\n\t})\n})()\n\n// ───────────────────────────────────────────────────────────────────────────────\n// Utils\n// ───────────────────────────────────────────────────────────────────────────────\nfunction rel(p: string) {\n\t// remove the projectRoot prefix and normalize slashes for logs\n\tconst prefix = resolve(projectRoot) + sep\n\treturn p.replace(prefix, '')\n}\nfunction ms(n: number) {\n\treturn `${Math.max(1, Math.round(n))}ms`\n}\nfunction info(msg: string) {\n\tconsole.log('[sb-deps]', msg)\n}\nfunction error(msg: string) {\n\tconsole.error('[sb-deps]', msg)\n}\nfunction banner(title: string) {\n\tconsole.log(`\\n${title} – dependency previews\\n`)\n}\nfunction wait(time = 500) {\n\treturn new Promise((r) => setTimeout(r, time))\n}\n"],"mappings":"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"}
|
package/dist/cli/sb-deps.mjs
CHANGED
|
@@ -139,6 +139,10 @@ function isComponentsSvelte(absPath) {
|
|
|
139
139
|
const norm = absPath.replace(/\\/g, "/");
|
|
140
140
|
return /(?:^|\/)src\/components\/.+\.svelte$/i.test(norm) && !/\.stories?\.svelte$/i.test(norm);
|
|
141
141
|
}
|
|
142
|
+
function isDecoratorSvelte(absPath) {
|
|
143
|
+
const norm = absPath.replace(/\\/g, "/");
|
|
144
|
+
return /(?:^|\/)src\/components\/.+\.decorator\.svelte$/i.test(norm);
|
|
145
|
+
}
|
|
142
146
|
function isComponentsAngularTs(absPath) {
|
|
143
147
|
const norm = absPath.replace(/\\/g, "/");
|
|
144
148
|
return /(?:^|\/)src\/components\/.+\.component\.ts$/i.test(norm);
|
|
@@ -253,7 +257,6 @@ const meta: Meta<typeof ${componentName}> = {
|
|
|
253
257
|
tags: ${JSON.stringify(tags)},
|
|
254
258
|
parameters: {
|
|
255
259
|
layout: 'padded',
|
|
256
|
-
__filePath: import.meta.url,
|
|
257
260
|
} satisfies StoryParameters,
|
|
258
261
|
}
|
|
259
262
|
|
|
@@ -302,6 +305,26 @@ function scaffoldSvelteComponent(absCompPath) {
|
|
|
302
305
|
writeFileSync(absCompPath, tpl, "utf8");
|
|
303
306
|
info(`scaffolded svelte component → ${rel(absCompPath)}`);
|
|
304
307
|
}
|
|
308
|
+
function scaffoldSvelteDecorator(absDecoratorPath) {
|
|
309
|
+
const fullBase = componentBaseFromSvelteComponent(absDecoratorPath);
|
|
310
|
+
const wrappedBase = fullBase.split(".")[0] ?? fullBase;
|
|
311
|
+
const componentName = toPascalCase(wrappedBase);
|
|
312
|
+
const tpl = SCAFFOLD_CONFIG?.svelte?.decorator?.({ componentName }) ?? `<script lang="ts">
|
|
313
|
+
import ${componentName} from "./${componentName}.svelte";
|
|
314
|
+
|
|
315
|
+
interface DecoratorProps {
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const { }: DecoratorProps = $props();
|
|
319
|
+
<\/script>
|
|
320
|
+
|
|
321
|
+
<div class="decorator">
|
|
322
|
+
<${componentName} />
|
|
323
|
+
</div>
|
|
324
|
+
`;
|
|
325
|
+
writeFileSync(absDecoratorPath, tpl, "utf8");
|
|
326
|
+
info(`scaffolded svelte decorator → ${rel(absDecoratorPath)}`);
|
|
327
|
+
}
|
|
305
328
|
function makeTitleFromSvelteComponent(absCompPath) {
|
|
306
329
|
const srcRoot = join(projectRoot, "src") + sep;
|
|
307
330
|
const normAbs = absCompPath.replace(/\\/g, "/");
|
|
@@ -338,7 +361,6 @@ function scaffoldStoryForSvelteComponent(absCompPath) {
|
|
|
338
361
|
tags: [${tags.map((t) => `'${t}'`).join(", ")}],
|
|
339
362
|
parameters: {
|
|
340
363
|
layout: 'padded',
|
|
341
|
-
__filePath: import.meta.url,
|
|
342
364
|
} satisfies StoryParameters,
|
|
343
365
|
})
|
|
344
366
|
type Args = Omit<PropsFor${componentName}, 'children'>;
|
|
@@ -538,7 +560,6 @@ const meta: Meta<${className}> = {
|
|
|
538
560
|
tags: ${JSON.stringify(tags)},
|
|
539
561
|
parameters: {
|
|
540
562
|
layout: 'padded',
|
|
541
|
-
__filePath: import.meta.url,
|
|
542
563
|
} satisfies StoryParameters,
|
|
543
564
|
}
|
|
544
565
|
|
|
@@ -651,6 +672,12 @@ function startWatcher() {
|
|
|
651
672
|
}
|
|
652
673
|
}
|
|
653
674
|
async function handleSvelteComponentCreation(abs, relPath) {
|
|
675
|
+
if (isDecoratorSvelte(abs)) {
|
|
676
|
+
if (isEmptyOrWhitespace(abs)) {
|
|
677
|
+
scaffoldSvelteDecorator(abs);
|
|
678
|
+
}
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
654
681
|
if (isEmptyOrWhitespace(abs)) {
|
|
655
682
|
scaffoldSvelteComponent(abs);
|
|
656
683
|
}
|