@poveste/shared 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.
Files changed (59) hide show
  1. package/LICENSE +22 -0
  2. package/dist/codegen/const.d.ts +2 -0
  3. package/dist/codegen/const.d.ts.map +1 -0
  4. package/dist/codegen/const.js +17 -0
  5. package/dist/codegen/index.d.ts +4 -0
  6. package/dist/codegen/index.d.ts.map +1 -0
  7. package/dist/codegen/index.js +3 -0
  8. package/dist/codegen/serialize-js.d.ts +2 -0
  9. package/dist/codegen/serialize-js.d.ts.map +1 -0
  10. package/dist/codegen/serialize-js.js +126 -0
  11. package/dist/codegen/util.d.ts +11 -0
  12. package/dist/codegen/util.d.ts.map +1 -0
  13. package/dist/codegen/util.js +69 -0
  14. package/dist/index.d.ts +6 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +5 -0
  17. package/dist/state.d.ts +4 -0
  18. package/dist/state.d.ts.map +1 -0
  19. package/dist/state.js +40 -0
  20. package/dist/story.d.ts +2 -0
  21. package/dist/story.d.ts.map +1 -0
  22. package/dist/story.js +10 -0
  23. package/dist/type-utils.d.ts +2 -0
  24. package/dist/type-utils.d.ts.map +1 -0
  25. package/dist/type-utils.js +1 -0
  26. package/dist/types/command.d.ts +36 -0
  27. package/dist/types/command.d.ts.map +1 -0
  28. package/dist/types/command.js +1 -0
  29. package/dist/types/config.d.ts +242 -0
  30. package/dist/types/config.d.ts.map +1 -0
  31. package/dist/types/config.js +1 -0
  32. package/dist/types/index.d.ts +6 -0
  33. package/dist/types/index.d.ts.map +1 -0
  34. package/dist/types/index.js +5 -0
  35. package/dist/types/plugin.d.ts +117 -0
  36. package/dist/types/plugin.d.ts.map +1 -0
  37. package/dist/types/plugin.js +1 -0
  38. package/dist/types/prompt.d.ts +20 -0
  39. package/dist/types/prompt.d.ts.map +1 -0
  40. package/dist/types/prompt.js +1 -0
  41. package/dist/types/story.d.ts +189 -0
  42. package/dist/types/story.d.ts.map +1 -0
  43. package/dist/types/story.js +1 -0
  44. package/package.json +46 -0
  45. package/src/codegen/const.ts +17 -0
  46. package/src/codegen/index.ts +3 -0
  47. package/src/codegen/serialize-js.ts +143 -0
  48. package/src/codegen/util.ts +77 -0
  49. package/src/index.ts +5 -0
  50. package/src/state.ts +42 -0
  51. package/src/story.ts +10 -0
  52. package/src/type-utils.ts +1 -0
  53. package/src/types/command.ts +38 -0
  54. package/src/types/config.ts +252 -0
  55. package/src/types/index.ts +5 -0
  56. package/src/types/plugin.ts +135 -0
  57. package/src/types/prompt.ts +22 -0
  58. package/src/types/story.ts +204 -0
  59. package/tsconfig.json +51 -0
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './codegen/index.js'
2
+ export * from './state.js'
3
+ export * from './story.js'
4
+ export * from './type-utils.js'
5
+ export * from './types/index.js'
package/src/state.ts ADDED
@@ -0,0 +1,42 @@
1
+ export function clone(data) {
2
+ try {
3
+ return structuredClone(data)
4
+ }
5
+ catch (e) {
6
+ console.warn(e, `Fallback to JSON cloning`)
7
+ try {
8
+ return JSON.parse(JSON.stringify(data))
9
+ }
10
+ catch (e) {
11
+ console.error(e)
12
+ }
13
+ return data
14
+ }
15
+ }
16
+
17
+ export function omit(data, keys: string[]) {
18
+ const copy = {}
19
+ for (const key in data) {
20
+ if (!keys.includes(key)) {
21
+ copy[key] = data[key]
22
+ }
23
+ }
24
+ return copy
25
+ }
26
+
27
+ export function applyState(target: any, state: any, override = false) {
28
+ for (const key in state) {
29
+ // iframe sync needs to update properties without overriding them
30
+ if (!override && target[key] && !key.startsWith('_h') && typeof target[key] === 'object' && !Array.isArray(target[key])) {
31
+ Object.assign(target[key], state[key])
32
+ }
33
+ else {
34
+ try {
35
+ target[key] = state[key]
36
+ }
37
+ catch (e) {
38
+ // noop
39
+ }
40
+ }
41
+ }
42
+ }
package/src/story.ts ADDED
@@ -0,0 +1,10 @@
1
+ export const omitInheritStoryProps = [
2
+ 'id',
3
+ 'title',
4
+ 'group',
5
+ 'layout',
6
+ 'variants',
7
+ 'file',
8
+ 'slots',
9
+ 'lastSelectedVariant',
10
+ ]
@@ -0,0 +1 @@
1
+ export type Awaitable<T> = Promise<T> | T
@@ -0,0 +1,38 @@
1
+ import type { RouteLocationNormalizedLoaded } from 'vue-router'
2
+ import type { Prompt } from './prompt.js'
3
+ import type { Story, Variant } from './story.js'
4
+
5
+ export interface CommonCommandOptions {
6
+ icon?: string
7
+ searchText?: string
8
+ prompts?: Prompt[]
9
+ }
10
+
11
+ export interface Command extends CommonCommandOptions {
12
+ id: string
13
+ label: string
14
+ }
15
+
16
+ export interface ClientCommandOptions extends CommonCommandOptions {
17
+ showIf?: (ctx: ClientCommandContext) => boolean
18
+ getParams?: (ctx: ClientCommandContext & { answers?: Record<string, any> }) => Record<string, any>
19
+ clientAction?: (params: Record<string, any>, ctx: ClientCommandContext) => unknown
20
+ }
21
+
22
+ /**
23
+ * A command that can be executed from the search bar.
24
+ */
25
+ export type ClientCommand = Command & ClientCommandOptions
26
+
27
+ export interface ClientCommandContext {
28
+ route: RouteLocationNormalizedLoaded
29
+ currentStory: Story
30
+ currentVariant: Variant
31
+ }
32
+
33
+ export interface PluginCommand<
34
+ TParams = Record<string, any>,
35
+ > extends Command {
36
+ serverAction?: (params: TParams) => unknown // @TODO ctx
37
+ clientSetupFile?: string | { file: string, importName: string }
38
+ }
@@ -0,0 +1,252 @@
1
+ import type MarkdownIt from 'markdown-it'
2
+ import type {
3
+ UserConfig as ViteConfig,
4
+ ConfigEnv as ViteConfigEnv,
5
+ } from 'vite'
6
+ import type { Plugin } from './plugin.js'
7
+ import type { ServerTreeFile, StoryProps } from './story.js'
8
+
9
+ export interface SupportMatchPattern {
10
+ id: string
11
+ patterns: string[]
12
+ pluginIds: string[]
13
+ }
14
+
15
+ export type CustomizableColors = 'primary' | 'gray'
16
+ export type ColorKeys = '50' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'
17
+ export type GrayColorKeys = ColorKeys | '750' | '850' | '950'
18
+
19
+ export interface ResponsivePreset {
20
+ label: string
21
+ width: number
22
+ height?: number
23
+ }
24
+
25
+ export interface BackgroundPreset {
26
+ label: string
27
+ color: string
28
+ contrastColor?: string
29
+ }
30
+
31
+ export interface TreeGroupConfig {
32
+ title: string
33
+ id?: string
34
+ include?: (file: ServerTreeFile) => boolean
35
+ }
36
+
37
+ /**
38
+ * @deprecated Use `PovesteConfig` instead. Kept for drop-in compat with histoire.
39
+ */
40
+ export type HistoireConfig = PovesteConfig
41
+
42
+ export interface PovesteConfig {
43
+ plugins: Plugin[]
44
+ /**
45
+ * Output directory.
46
+ */
47
+ outDir: string
48
+ /**
49
+ * Glob patterns for story files to include.
50
+ */
51
+ storyMatch: string[]
52
+ /**
53
+ * Glob patterns to ignore files while searching for story files.
54
+ */
55
+ storyIgnored: string[]
56
+ /**
57
+ * Patterns to match stories to support plugins automatically.
58
+ */
59
+ supportMatch: SupportMatchPattern[]
60
+ /**
61
+ * How to generate the story tree.
62
+ */
63
+ tree: {
64
+ /**
65
+ * Use `'title'` to create the path from the title of the story, using `/` as the separator.
66
+ *
67
+ * Use `'path'` use the real folder structure on your computer.
68
+ */
69
+ file?: 'title' | 'path' | ((file: ServerTreeFile) => string[])
70
+ order?: 'asc' | ((a: string, b: string) => number)
71
+ groups?: TreeGroupConfig[]
72
+ }
73
+ /**
74
+ * Customize the look of the histoire book.
75
+ */
76
+ theme: {
77
+ /**
78
+ * Main page title. For example: 'Acme Inc.'
79
+ */
80
+ title?: string
81
+ /**
82
+ * Custom logo files. Should be import paths (processed by Vite).
83
+ *
84
+ * Example: `'/src/assets/my-logo.svg'`
85
+ */
86
+ logo?: {
87
+ /**
88
+ * Square logo without text.
89
+ */
90
+ square?: string
91
+ /**
92
+ * Full logo for light theme.
93
+ */
94
+ light?: string
95
+ /**
96
+ * Full logo for dark theme.
97
+ */
98
+ dark?: string
99
+ }
100
+ /**
101
+ * Href to the favicon file (**not** processed by Vite). Put the file in the `public` directory.
102
+ *
103
+ * Example: `'/favicon.ico'`
104
+ */
105
+ favicon?: string
106
+ /**
107
+ * Customize the colors. Each color should be an object with shades as keys.
108
+ *
109
+ * Example: ```{ primary: { 50: '#eef2ff', 100: '#e0e7ff', ..., 900: '#312e81' } }```
110
+ *
111
+ * You can import `defaultColors` from `'poveste'` to use predefined colors or you can create your own colors from scratch.
112
+ */
113
+ colors?: {
114
+ [key in CustomizableColors]?: key extends 'gray' ? {
115
+ [key in GrayColorKeys]?: string
116
+ } : {
117
+ [key in ColorKeys]?: string
118
+ }
119
+ }
120
+ /**
121
+ * Add a link to the main logo
122
+ */
123
+ logoHref?: string
124
+ /**
125
+ * Default color scheme for the app.
126
+ */
127
+ defaultColorScheme?: 'light' | 'dark' | 'auto'
128
+ /**
129
+ * Hides the dark mode button in the toolbar.
130
+ */
131
+ hideColorSchemeSwitch?: boolean
132
+ /**
133
+ * Enable persistence of the color scheme in the browser.
134
+ */
135
+ storeColorScheme?: boolean
136
+ /**
137
+ * Class added to the story preview when dark mode is enabled.
138
+ */
139
+ darkClass?: string
140
+ }
141
+ /**
142
+ * Setup file exporting a default function executed when setting up each story preview.
143
+ *
144
+ * Import custom CSS files from this file.
145
+ *
146
+ * Example: `'/src/histoire-setup.ts'`
147
+ */
148
+ setupFile?: string | {
149
+ /**
150
+ * Only loaded in the browser client.
151
+ */
152
+ browser: string
153
+ } | {
154
+ /**
155
+ * Only loaded while collecting stories in the node server.
156
+ */
157
+ server: string
158
+ } | {
159
+ /**
160
+ * Only loaded in the browser client.
161
+ */
162
+ browser: string
163
+ /**
164
+ * Only loaded while collecting stories in the node server.
165
+ */
166
+ server: string
167
+ }
168
+ /**
169
+ * Setup code created by plugins
170
+ */
171
+ setupCode?: string[]
172
+ /**
173
+ * Predefined responsive sizes for story playgrounds.
174
+ */
175
+ responsivePresets?: ResponsivePreset[]
176
+ /**
177
+ * Background color of the story preview.
178
+ */
179
+ backgroundPresets?: BackgroundPreset[]
180
+ /**
181
+ * Automatically apply the current background preset's contrast color to the story preview text.
182
+ */
183
+ autoApplyContrastColor?: boolean
184
+ /**
185
+ * Class added to the html root of the story preview when dark mode is enabled.
186
+ * @deprecated use `theme.darkClass` instead
187
+ */
188
+ sandboxDarkClass?: string
189
+ /**
190
+ * Default props for stories.
191
+ */
192
+ defaultStoryProps?: Omit<StoryProps, 'id' | 'setupApp' | 'title' | 'source'>
193
+ /**
194
+ * Customize the markdown-it renderer
195
+ */
196
+ markdown?: (md: MarkdownIt) => MarkdownIt | Promise<MarkdownIt>
197
+ /**
198
+ * Change the router mode.
199
+ * - history: use HTML history with cleaner URLs
200
+ * - hash: use hashtag hack in the URL to support more hosting services
201
+ */
202
+ routerMode?: 'history' | 'hash'
203
+ /**
204
+ * Vite config override
205
+ */
206
+ vite?: ViteConfig | ((config: ViteConfig, env: ViteConfigEnv) => void | ViteConfig | Promise<void | ViteConfig>)
207
+ /**
208
+ * Remove those plugins from the Vite configuration
209
+ */
210
+ viteIgnorePlugins?: string[]
211
+ /**
212
+ * Transpile dependencies when collecting stories on Node.js
213
+ */
214
+ viteNodeInlineDeps?: (string | RegExp)[]
215
+ /**
216
+ * Determine the transform method of modules
217
+ */
218
+ viteNodeTransformMode?: {
219
+ /**
220
+ * Use SSR transform pipeline for the specified files.
221
+ * Vite plugins will receive `ssr: true` flag when processing those files.
222
+ *
223
+ * @default [/\.([cm]?[jt]sx?|json)$/]
224
+ */
225
+ ssr?: RegExp[]
226
+ /**
227
+ * First do a normal transform pipeline (targeting browser),
228
+ * then then do a SSR rewrite to run the code in Node.
229
+ * Vite plugins will receive `ssr: false` flag when processing those files.
230
+ *
231
+ * @default other than `ssr`
232
+ */
233
+ web?: RegExp[]
234
+ }
235
+ /**
236
+ * Maximum number of threads used to collect stories.
237
+ * By default based on available number of cores.
238
+ */
239
+ collectMaxThreads?: number
240
+ /**
241
+ * Build options
242
+ */
243
+ build?: {
244
+ /**
245
+ * By default all dependencies in `node_modules` are bundled into a single 'vendors' file.
246
+ * You can use this option to exclude some dependencies from this file.
247
+ */
248
+ excludeFromVendorsChunk?: (string | RegExp)[]
249
+ }
250
+ }
251
+
252
+ export type ConfigMode = 'build' | 'dev'
@@ -0,0 +1,5 @@
1
+ export * from './command.js'
2
+ export * from './config.js'
3
+ export * from './plugin.js'
4
+ export * from './prompt.js'
5
+ export * from './story.js'
@@ -0,0 +1,135 @@
1
+ import type chokidar from 'chokidar'
2
+ import type fs from 'fs-extra'
3
+ import type path from 'pathe'
4
+ import type pc from 'picocolors'
5
+ import type { InlineConfig as ViteInlineConfig, Plugin as VitePlugin } from 'vite'
6
+ import type { Awaitable } from '../type-utils.js'
7
+ import type {
8
+ PluginCommand,
9
+ } from './command.js'
10
+ import type {
11
+ ConfigMode,
12
+ PovesteConfig,
13
+ } from './config.js'
14
+ import type {
15
+ ServerStory,
16
+ ServerStoryFile,
17
+ ServerVariant,
18
+ } from './story.js'
19
+
20
+ export interface SupportPlugin {
21
+ id: string
22
+ moduleName: string
23
+ setupFn: string | string[]
24
+ importStoriesPrepend?: string
25
+ importStoryComponent: (file: ServerStoryFile, index: number) => string
26
+ }
27
+
28
+ export interface FinalSupportPlugin extends SupportPlugin {
29
+ // For now, no additional properties
30
+ }
31
+
32
+ export interface ModuleLoader {
33
+ clearCache: () => void
34
+ loadModule: (file: string) => Promise<any>
35
+ destroy: () => void
36
+ }
37
+
38
+ export interface PluginApiBase {
39
+ colors: typeof pc
40
+ path: typeof path
41
+ fs: typeof fs
42
+ moduleLoader: ModuleLoader
43
+
44
+ readonly pluginTempDir: string
45
+
46
+ log: (...msg) => void
47
+ warn: (...msg) => void
48
+ error: (...msg) => void
49
+
50
+ getStories: () => ServerStory[]
51
+ addStoryFile: (file: string) => void
52
+
53
+ getConfig: () => PovesteConfig
54
+ }
55
+
56
+ export interface PluginApiDev extends PluginApiBase {
57
+ watcher: typeof chokidar
58
+ }
59
+
60
+ export type ChangeViteConfigCallback = (config: ViteInlineConfig) => Awaitable<void>
61
+ export type BuildEndCallback = () => Awaitable<void>
62
+ export type PreviewStoryCallback = (payload: { file: string, story: ServerStory, variant: ServerVariant, url: string }) => Awaitable<void>
63
+
64
+ export interface PluginApiBuild extends PluginApiBase {
65
+ changeViteConfigCallbacks: ChangeViteConfigCallback[]
66
+ buildEndCallbacks: BuildEndCallback[]
67
+ previewStoryCallbacks: PreviewStoryCallback[]
68
+
69
+ changeViteConfig: (cb: ChangeViteConfigCallback) => void
70
+ onBuildEnd: (cb: BuildEndCallback) => void
71
+ onPreviewStory: (cb: PreviewStoryCallback) => void
72
+ }
73
+
74
+ export interface PluginApiDevEvent extends PluginApiBase {
75
+ event: string
76
+ payload: any
77
+ }
78
+
79
+ export interface Plugin {
80
+ /**
81
+ * Name of the plugin
82
+ */
83
+ name: string
84
+ /**
85
+ * Modify histoire default config. The hook can either mutate the passed config or
86
+ * return a partial config object that will be deeply merged into the existing
87
+ * config. User config will have higher priority than default config.
88
+ *
89
+ * Note: User plugins are resolved before running this hook so injecting other
90
+ * plugins inside the `config` hook will have no effect.
91
+ */
92
+ defaultConfig?: (defaultConfig: PovesteConfig, mode: ConfigMode) => Partial<PovesteConfig> | null | void | Promise<Partial<PovesteConfig> | null | void>
93
+ /**
94
+ * Modify histoire config. The hook can either mutate the passed config or
95
+ * return a partial config object that will be deeply merged into the existing
96
+ * config.
97
+ *
98
+ * Note: User plugins are resolved before running this hook so injecting other
99
+ * plugins inside the `config` hook will have no effect.
100
+ */
101
+ config?: (config: PovesteConfig, mode: ConfigMode) => Partial<PovesteConfig> | null | void | Promise<Partial<PovesteConfig> | null | void>
102
+ /**
103
+ * Use this hook to read and store the final resolved histoire config.
104
+ */
105
+ configResolved?: (config: PovesteConfig) => Awaitable<void>
106
+ /**
107
+ * Use this hook to do processing during development. The `onCleanup` hook
108
+ * should handle cleanup tasks when development server is closed.
109
+ */
110
+ onDev?: (api: PluginApiDev, onCleanup: (cb: () => Awaitable<void>) => void) => Awaitable<void>
111
+ /**
112
+ * Use this hook to do processing during production build.
113
+ */
114
+ onBuild?: (api: PluginApiBuild) => Awaitable<void>
115
+ /**
116
+ * Use this hook to do processing when preview is started.
117
+ */
118
+ onPreview?: () => Awaitable<void>
119
+ /**
120
+ * This plugin exposes a support plugin (example: Vue, Svelte, etc.)
121
+ */
122
+ supportPlugin?: SupportPlugin
123
+ /**
124
+ * This plugin exposes commands that can be executed from the search bar in development mode.
125
+ */
126
+ commands?: PluginCommand[]
127
+ /**
128
+ * Handle a custom event from the client in development mode.
129
+ */
130
+ onDevEvent?: (api: PluginApiDevEvent) => Awaitable<any>
131
+ /**
132
+ * Use this hook to manipulate Vite plugins before they are passed to Vite.
133
+ */
134
+ vitePlugins?: (plugins: VitePlugin[]) => Awaitable<void>
135
+ }
@@ -0,0 +1,22 @@
1
+ import type { Awaitable } from '../type-utils.js'
2
+
3
+ export interface PromptBase<TValue> {
4
+ field: string
5
+ label: string
6
+ required?: boolean
7
+ defaultValue?: TValue | ((answers: Record<string, any>) => TValue)
8
+ }
9
+
10
+ export interface TextPrompt extends PromptBase<string> {
11
+ type: 'text'
12
+ }
13
+
14
+ export type SelectPromptOption = string | { value: string, label: string }
15
+
16
+ export interface SelectPrompt extends PromptBase<string> {
17
+ type: 'select'
18
+ options: SelectPromptOption[] | ((search: string, answers: Record<string, any>) => Awaitable<SelectPromptOption[]>)
19
+ }
20
+
21
+ export type Prompt<TValue = any> = TextPrompt
22
+ | SelectPrompt