blockparty 0.1.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 +102 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +54 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/build.d.ts +2 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +66 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/storybook.d.ts +2 -0
- package/dist/commands/storybook.d.ts.map +1 -0
- package/dist/commands/storybook.js +95 -0
- package/dist/commands/storybook.js.map +1 -0
- package/dist/discoverBlocks.d.ts +9 -0
- package/dist/discoverBlocks.d.ts.map +1 -0
- package/dist/discoverBlocks.js +63 -0
- package/dist/discoverBlocks.js.map +1 -0
- package/dist/extractProps.d.ts +10 -0
- package/dist/extractProps.d.ts.map +1 -0
- package/dist/extractProps.js +251 -0
- package/dist/extractProps.js.map +1 -0
- package/dist/extractProps.test.d.ts +2 -0
- package/dist/extractProps.test.d.ts.map +1 -0
- package/dist/extractProps.test.js +305 -0
- package/dist/extractProps.test.js.map +1 -0
- package/dist/generateBlocksModule.d.ts +3 -0
- package/dist/generateBlocksModule.d.ts.map +1 -0
- package/dist/generateBlocksModule.js +21 -0
- package/dist/generateBlocksModule.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/parseReadme.d.ts +15 -0
- package/dist/parseReadme.d.ts.map +1 -0
- package/dist/parseReadme.js +84 -0
- package/dist/parseReadme.js.map +1 -0
- package/dist/parseReadme.test.d.ts +2 -0
- package/dist/parseReadme.test.d.ts.map +1 -0
- package/dist/parseReadme.test.js +142 -0
- package/dist/parseReadme.test.js.map +1 -0
- package/dist/templates/App.tsx +236 -0
- package/dist/templates/ErrorBoundary.tsx +53 -0
- package/dist/templates/PropsEditor.tsx +707 -0
- package/dist/templates/index.html +27 -0
- package/dist/templates/index.tsx +10 -0
- package/dist/viteConfig.d.ts +12 -0
- package/dist/viteConfig.d.ts.map +1 -0
- package/dist/viteConfig.js +22 -0
- package/dist/viteConfig.js.map +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Block Party
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/blockparty)
|
|
4
|
+
|
|
5
|
+
Easy, zero-config, convention-based React components.
|
|
6
|
+
|
|
7
|
+
## Hello, World
|
|
8
|
+
|
|
9
|
+
A component in Block Party is called a Block. Here is a simple Block:
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
export interface Props {
|
|
13
|
+
who: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default ({ who }: Props) => (
|
|
17
|
+
<h1>Hello, {who}!</h1>
|
|
18
|
+
)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Create a new directory and paste the above into a file called `index.tsx`. You've just created your first Block!
|
|
22
|
+
|
|
23
|
+
### Run the Storybook
|
|
24
|
+
|
|
25
|
+
Block Party includes a storybook-style UI for quick previews of your Blocks.
|
|
26
|
+
|
|
27
|
+
Just run `npx blockparty` in the directory with your Block. The preview will automatically update if changes are made to the Block's source code.
|
|
28
|
+
|
|
29
|
+
### Publish the Storybook
|
|
30
|
+
|
|
31
|
+
You may want to publish a static site build of the storybook UI, for instance during a CI run on a git repo.
|
|
32
|
+
|
|
33
|
+
To create a static site build of the storybook, run `npx blockparty build` from the root (where each block is in a different subdirectory).
|
|
34
|
+
|
|
35
|
+
By default, the output goes into a `dist` directory, but you can specify a different path on the command line. For instance, if you are using GitHub Pages, you may want to put it in the `docs` directory:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
npx blockparty build . docs
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Metadata
|
|
42
|
+
|
|
43
|
+
If the Block has a `README.md` file in its directory, frontmatter can be added to the beginning of the file to provide metadata:
|
|
44
|
+
|
|
45
|
+
```markdown
|
|
46
|
+
---
|
|
47
|
+
name: Hello Component
|
|
48
|
+
description: Greets whomever is specified.
|
|
49
|
+
foo: bar
|
|
50
|
+
...
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
# Detailed documentation...
|
|
55
|
+
|
|
56
|
+
Blah blah blah
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
If the `name` or `description` fields are not present in the frontmatter, Block Party will extract them from the README content:
|
|
60
|
+
|
|
61
|
+
- **Name**: The first heading (`# Heading`) in the document
|
|
62
|
+
- **Description**: The first paragraph of text after the heading
|
|
63
|
+
|
|
64
|
+
For example:
|
|
65
|
+
|
|
66
|
+
```markdown
|
|
67
|
+
# Hello Component
|
|
68
|
+
|
|
69
|
+
Greets whomever is specified.
|
|
70
|
+
|
|
71
|
+
## Usage
|
|
72
|
+
|
|
73
|
+
...
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Both of the above `README.md` files will yield the name, "Hello Component" and description, "Greets whomever is specified."
|
|
77
|
+
|
|
78
|
+
The name and description are displayed in the storybook UI.
|
|
79
|
+
|
|
80
|
+
## Documenting Props
|
|
81
|
+
|
|
82
|
+
You can add JSDoc comments to your props to provide helpful descriptions in the storybook UI:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
export interface Props {
|
|
86
|
+
/**
|
|
87
|
+
* The person's name to greet
|
|
88
|
+
*/
|
|
89
|
+
who: string
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Optional greeting message (default: 'Hello')
|
|
93
|
+
*/
|
|
94
|
+
greeting?: string
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export default ({ who, greeting = 'Hello' }: Props) => (
|
|
98
|
+
<h1>{greeting}, {who}!</h1>
|
|
99
|
+
)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { resolve } from 'path';
|
|
4
|
+
import { startStorybookServer } from './commands/storybook.js';
|
|
5
|
+
import { buildStorybook } from './commands/build.js';
|
|
6
|
+
async function main() {
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
// Parse command and path
|
|
9
|
+
let command;
|
|
10
|
+
let targetPath;
|
|
11
|
+
let outDir;
|
|
12
|
+
if (args.length === 0) {
|
|
13
|
+
// No arguments - default to storybook in current directory
|
|
14
|
+
command = 'storybook';
|
|
15
|
+
targetPath = process.cwd();
|
|
16
|
+
}
|
|
17
|
+
else if (args[0] === 'storybook' || args[0] === 'build') {
|
|
18
|
+
// Explicit command
|
|
19
|
+
command = args[0];
|
|
20
|
+
targetPath = args[1] ?? process.cwd();
|
|
21
|
+
outDir = args[2]; // Optional output directory for build command
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.error('❌ Unknown command');
|
|
25
|
+
console.error('Usage: blockparty [storybook|build] [path] [outDir]');
|
|
26
|
+
console.error('');
|
|
27
|
+
console.error('Commands:');
|
|
28
|
+
console.error(' storybook Start storybook dev server (default)');
|
|
29
|
+
console.error(' build Build storybook to static files');
|
|
30
|
+
console.error('');
|
|
31
|
+
console.error('Arguments:');
|
|
32
|
+
console.error(' path Path to Block or root directory for Blocks (default: current directory)');
|
|
33
|
+
console.error(' outDir Output directory for build (default: dist)');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
// Resolve the path
|
|
37
|
+
const resolvedPath = resolve(process.cwd(), targetPath);
|
|
38
|
+
if (!existsSync(resolvedPath)) {
|
|
39
|
+
console.error(`❌ Path not found: ${resolvedPath}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
// Run the appropriate command
|
|
43
|
+
if (command === 'storybook') {
|
|
44
|
+
await startStorybookServer(resolvedPath);
|
|
45
|
+
}
|
|
46
|
+
else if (command === 'build') {
|
|
47
|
+
await buildStorybook(resolvedPath, outDir ?? 'dist');
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
main().catch(error => {
|
|
51
|
+
console.error('Failed to run Block Party:', error);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAA;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAC9B,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAElC,yBAAyB;IACzB,IAAI,OAAe,CAAA;IACnB,IAAI,UAAkB,CAAA;IACtB,IAAI,MAA0B,CAAA;IAE9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,2DAA2D;QAC3D,OAAO,GAAG,WAAW,CAAA;QACrB,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IAC5B,CAAC;SAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QAC1D,mBAAmB;QACnB,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;QACrC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA,CAAC,8CAA8C;IACjE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAA;QAClC,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAA;QACpE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACjB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QAC1B,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAA;QAClE,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAA;QAC7D,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACjB,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAC3B,OAAO,CAAC,KAAK,CAAC,sFAAsF,CAAC,CAAA;QACrG,OAAO,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAA;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,mBAAmB;IACnB,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAA;IAEvD,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,qBAAqB,YAAY,EAAE,CAAC,CAAA;QAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,8BAA8B;IAC9B,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;QAC5B,MAAM,oBAAoB,CAAC,YAAY,CAAC,CAAA;IAC1C,CAAC;SAAM,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QAC/B,MAAM,cAAc,CAAC,YAAY,EAAE,MAAM,IAAI,MAAM,CAAC,CAAA;IACtD,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAA;IAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAOA,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAgEtE"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { resolve } from 'path';
|
|
2
|
+
import { mkdir, writeFile, rm } from 'fs/promises';
|
|
3
|
+
import { build as viteBuild } from 'vite';
|
|
4
|
+
import { discoverBlocks } from '../discoverBlocks.js';
|
|
5
|
+
import { generateBlocksModule } from '../generateBlocksModule.js';
|
|
6
|
+
import { templatesDir, getViteResolveConfig, getVitePlugins } from '../viteConfig.js';
|
|
7
|
+
export async function buildStorybook(targetPath, outDir) {
|
|
8
|
+
console.log('🏗️ Building Blocks...');
|
|
9
|
+
console.log(`📂 Target: ${targetPath}`);
|
|
10
|
+
console.log(`📦 Output: ${outDir}\n`);
|
|
11
|
+
const blocks = await discoverBlocks(targetPath);
|
|
12
|
+
if (blocks.length === 0) {
|
|
13
|
+
console.error('❌ No Blocks found!');
|
|
14
|
+
console.error('A Block should have an index.ts or index.tsx file with:');
|
|
15
|
+
console.error(' - An exported Props interface');
|
|
16
|
+
console.error(' - A default exported function component');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
console.log(`✅ Found ${blocks.length} Block(s):`);
|
|
20
|
+
blocks.forEach(block => {
|
|
21
|
+
console.log(` - ${block.name}`);
|
|
22
|
+
});
|
|
23
|
+
console.log();
|
|
24
|
+
// Generate blocks module
|
|
25
|
+
const blocksModule = await generateBlocksModule(blocks);
|
|
26
|
+
// Create a temporary directory for the virtual blocks module
|
|
27
|
+
const tempDir = resolve(process.cwd(), '.blockparty-build');
|
|
28
|
+
await mkdir(tempDir, { recursive: true });
|
|
29
|
+
const blocksPath = resolve(tempDir, 'blocks.ts');
|
|
30
|
+
await writeFile(blocksPath, blocksModule);
|
|
31
|
+
console.log('📝 Generating static bundle...');
|
|
32
|
+
try {
|
|
33
|
+
// Build with Vite
|
|
34
|
+
const viteResolve = getViteResolveConfig();
|
|
35
|
+
await viteBuild({
|
|
36
|
+
root: templatesDir,
|
|
37
|
+
base: './',
|
|
38
|
+
resolve: {
|
|
39
|
+
...viteResolve,
|
|
40
|
+
alias: {
|
|
41
|
+
...viteResolve.alias,
|
|
42
|
+
'./blocks': blocksPath,
|
|
43
|
+
'./blocks.ts': blocksPath
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
plugins: getVitePlugins(),
|
|
47
|
+
build: {
|
|
48
|
+
outDir: resolve(process.cwd(), outDir),
|
|
49
|
+
emptyOutDir: true,
|
|
50
|
+
rollupOptions: {
|
|
51
|
+
input: resolve(templatesDir, 'index.html')
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
console.log(`\n✅ Build complete! Output in ${outDir}/`);
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.error('\n❌ Build failed:', error);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
// Clean up temporary directory
|
|
63
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storybook.d.ts","sourceRoot":"","sources":["../../src/commands/storybook.ts"],"names":[],"mappings":"AAMA,wBAAsB,oBAAoB,CAAC,UAAU,EAAE,MAAM,iBAsG5D"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { realpathSync } from 'fs';
|
|
2
|
+
import { createServer } from 'vite';
|
|
3
|
+
import { discoverBlocks } from '../discoverBlocks.js';
|
|
4
|
+
import { generateBlocksModule } from '../generateBlocksModule.js';
|
|
5
|
+
import { blockPartyRoot, templatesDir, getViteResolveConfig, getVitePlugins } from '../viteConfig.js';
|
|
6
|
+
export async function startStorybookServer(targetPath) {
|
|
7
|
+
console.log('🎉 Starting Block Party...');
|
|
8
|
+
console.log(`📂 Target path: ${targetPath}\n`);
|
|
9
|
+
const blocks = await discoverBlocks(targetPath);
|
|
10
|
+
if (blocks.length === 0) {
|
|
11
|
+
console.error('❌ No Blocks found!');
|
|
12
|
+
console.error('A Block should have an index.ts or index.tsx file with:');
|
|
13
|
+
console.error(' - An exported Props interface');
|
|
14
|
+
console.error(' - A default exported function component');
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
console.log(`✅ Found ${blocks.length} Block(s):`);
|
|
18
|
+
blocks.forEach(block => {
|
|
19
|
+
console.log(` - ${block.name}`);
|
|
20
|
+
});
|
|
21
|
+
console.log();
|
|
22
|
+
// Generate initial blocks module
|
|
23
|
+
let blocksModule = await generateBlocksModule(blocks);
|
|
24
|
+
// Resolve target path through symlinks for comparison
|
|
25
|
+
const realTargetPath = realpathSync(targetPath);
|
|
26
|
+
// Start Vite dev server
|
|
27
|
+
const server = await createServer({
|
|
28
|
+
root: templatesDir,
|
|
29
|
+
resolve: getViteResolveConfig(),
|
|
30
|
+
optimizeDeps: {
|
|
31
|
+
include: ['react', 'react-dom', 'react/jsx-runtime', 'react/jsx-dev-runtime']
|
|
32
|
+
},
|
|
33
|
+
plugins: [
|
|
34
|
+
{
|
|
35
|
+
name: 'blockparty-virtual',
|
|
36
|
+
enforce: 'pre',
|
|
37
|
+
resolveId(id) {
|
|
38
|
+
if (id === './blocks' || id === './blocks.ts') {
|
|
39
|
+
return '\0virtual:blocks.ts';
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
load(id) {
|
|
43
|
+
if (id === '\0virtual:blocks.ts') {
|
|
44
|
+
return blocksModule;
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
async handleHotUpdate({ file, server }) {
|
|
48
|
+
// Check if the changed file is in the target directory (resolve through symlinks)
|
|
49
|
+
if (file.startsWith(realTargetPath)) {
|
|
50
|
+
console.log(`🔄 Block file changed: ${file}`);
|
|
51
|
+
// Re-discover blocks to get updated prop definitions
|
|
52
|
+
const updatedBlocks = await discoverBlocks(targetPath);
|
|
53
|
+
blocksModule = await generateBlocksModule(updatedBlocks);
|
|
54
|
+
// Invalidate the virtual module
|
|
55
|
+
const module = server.moduleGraph.getModuleById('\0virtual:blocks.ts');
|
|
56
|
+
if (module) {
|
|
57
|
+
server.moduleGraph.invalidateModule(module);
|
|
58
|
+
}
|
|
59
|
+
// Trigger HMR for the blocks module
|
|
60
|
+
server.ws.send({
|
|
61
|
+
type: 'full-reload'
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
...getVitePlugins()
|
|
67
|
+
],
|
|
68
|
+
server: {
|
|
69
|
+
fs: {
|
|
70
|
+
allow: [blockPartyRoot, targetPath]
|
|
71
|
+
},
|
|
72
|
+
port: 5173,
|
|
73
|
+
strictPort: false,
|
|
74
|
+
open: true
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
await server.listen();
|
|
78
|
+
const urls = server.resolvedUrls;
|
|
79
|
+
console.log('🚀 Block Party is running!');
|
|
80
|
+
if (urls?.local && urls.local.length > 0) {
|
|
81
|
+
urls.local.forEach(url => {
|
|
82
|
+
console.log(` Local: ${url}`);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
if (urls?.network && urls.network.length > 0) {
|
|
86
|
+
urls.network.forEach(url => {
|
|
87
|
+
console.log(` Network: ${url}`);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (!urls?.local && !urls?.network) {
|
|
91
|
+
console.log(' http://localhost:5173');
|
|
92
|
+
}
|
|
93
|
+
console.log();
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=storybook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storybook.js","sourceRoot":"","sources":["../../src/commands/storybook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type PropDefinition } from './extractProps.js';
|
|
2
|
+
import { type BlockMetadata } from './parseReadme.js';
|
|
3
|
+
export interface BlockInfo extends BlockMetadata {
|
|
4
|
+
name: string;
|
|
5
|
+
path: string;
|
|
6
|
+
propDefinitions: PropDefinition[];
|
|
7
|
+
}
|
|
8
|
+
export declare function discoverBlocks(targetPath: string): Promise<BlockInfo[]>;
|
|
9
|
+
//# sourceMappingURL=discoverBlocks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discoverBlocks.d.ts","sourceRoot":"","sources":["../src/discoverBlocks.ts"],"names":[],"mappings":"AAGA,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAC7E,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,kBAAkB,CAAA;AAE1E,MAAM,WAAW,SAAU,SAAQ,aAAa;IAC9C,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,eAAe,EAAE,cAAc,EAAE,CAAA;CAClC;AAmCD,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CA4B7E"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { readdir, stat } from 'fs/promises';
|
|
3
|
+
import { join, dirname, basename } from 'path';
|
|
4
|
+
import { extractPropsFromFile } from './extractProps.js';
|
|
5
|
+
import { parseReadmeMetadata } from './parseReadme.js';
|
|
6
|
+
async function getBlockInfo(path) {
|
|
7
|
+
let blockDir;
|
|
8
|
+
let indexPath;
|
|
9
|
+
const targetStat = await stat(path);
|
|
10
|
+
if (targetStat.isFile()) {
|
|
11
|
+
blockDir = dirname(path);
|
|
12
|
+
indexPath = path;
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
blockDir = path;
|
|
16
|
+
const indexTsPath = join(blockDir, 'index.ts');
|
|
17
|
+
const indexTsxPath = join(blockDir, 'index.tsx');
|
|
18
|
+
if (existsSync(indexTsxPath)) {
|
|
19
|
+
indexPath = indexTsxPath;
|
|
20
|
+
}
|
|
21
|
+
else if (existsSync(indexTsPath)) {
|
|
22
|
+
indexPath = indexTsPath;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const propDefinitions = await extractPropsFromFile(indexPath);
|
|
29
|
+
const blockName = basename(blockDir);
|
|
30
|
+
const metadata = await parseReadmeMetadata(blockDir);
|
|
31
|
+
return {
|
|
32
|
+
...metadata,
|
|
33
|
+
name: metadata.name ?? blockName,
|
|
34
|
+
path: indexPath,
|
|
35
|
+
propDefinitions
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export async function discoverBlocks(targetPath) {
|
|
39
|
+
const blocks = [];
|
|
40
|
+
const blockInfo = await getBlockInfo(targetPath);
|
|
41
|
+
if (blockInfo) {
|
|
42
|
+
blocks.push(blockInfo);
|
|
43
|
+
return blocks;
|
|
44
|
+
}
|
|
45
|
+
// Check subdirectories for Blocks
|
|
46
|
+
try {
|
|
47
|
+
const entries = await readdir(targetPath, { withFileTypes: true });
|
|
48
|
+
for (const entry of entries) {
|
|
49
|
+
if (entry.isDirectory() && !entry.name.startsWith('.') && entry.name !== 'node_modules') {
|
|
50
|
+
const dirPath = join(targetPath, entry.name);
|
|
51
|
+
const blockInfo = await getBlockInfo(dirPath);
|
|
52
|
+
if (blockInfo) {
|
|
53
|
+
blocks.push(blockInfo);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error('Error reading directory:', error);
|
|
60
|
+
}
|
|
61
|
+
return blocks;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=discoverBlocks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discoverBlocks.js","sourceRoot":"","sources":["../src/discoverBlocks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAA;AAC/B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAC9C,OAAO,EAAE,oBAAoB,EAAuB,MAAM,mBAAmB,CAAA;AAC7E,OAAO,EAAsB,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAQ1E,KAAK,UAAU,YAAY,CAAC,IAAY;IACtC,IAAI,QAAgB,CAAA;IACpB,IAAI,SAAiB,CAAA;IAErB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;QACxB,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;QACxB,SAAS,GAAG,IAAI,CAAA;IAClB,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,IAAI,CAAA;QAEf,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;QAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;QAChD,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7B,SAAS,GAAG,YAAY,CAAA;QAC1B,CAAC;aAAM,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACnC,SAAS,GAAG,WAAW,CAAA;QACzB,CAAC;aAAM,CAAC;YACN,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;IACD,MAAM,eAAe,GAAG,MAAM,oBAAoB,CAAC,SAAS,CAAC,CAAA;IAC7D,MAAM,SAAS,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;IACpC,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAA;IAEpD,OAAO;QACL,GAAG,QAAQ;QACX,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,SAAS;QAChC,IAAI,EAAE,SAAS;QACf,eAAe;KAChB,CAAA;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkB;IACrD,MAAM,MAAM,GAAgB,EAAE,CAAA;IAE9B,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,CAAA;IAChD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACtB,OAAO,MAAM,CAAA;IACf,CAAC;IAED,kCAAkC;IAClC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAA;QAElE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBACxF,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;gBAC5C,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,CAAA;gBAE7C,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;gBACxB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAA;IAClD,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface PropDefinition {
|
|
2
|
+
name: string;
|
|
3
|
+
type: string;
|
|
4
|
+
optional: boolean;
|
|
5
|
+
properties?: PropDefinition[];
|
|
6
|
+
description?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function extractPropsFromSource(content: string, fileName?: string): PropDefinition[];
|
|
9
|
+
export declare function extractPropsFromFile(filePath: string): Promise<PropDefinition[]>;
|
|
10
|
+
//# sourceMappingURL=extractProps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractProps.d.ts","sourceRoot":"","sources":["../src/extractProps.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,cAAc,EAAE,CAAA;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AA2MD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAqB,GAAG,cAAc,EAAE,CAiEzG;AAwBD,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAQtF"}
|