@andersundsehr/storybook-typo3 0.1.10 → 0.1.12

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 CHANGED
@@ -1,9 +1,9 @@
1
1
  # `EXT:storybook`
2
- <img alt="TYPO3" src="./Documentation/assets/TYPO3-Logo-rgb.svg" height="40" /> &nbsp;&nbsp;&nbsp;&nbsp;
3
- <img alt="Love" src="./Documentation/assets/heart.svg" height="40" /> &nbsp;&nbsp;&nbsp;&nbsp;
2
+ <img alt="TYPO3" src="./Documentation/assets/TYPO3-Logo-rgb.svg" height="40" />
3
+ <img alt="Love" src="./Documentation/assets/heart.svg" height="40" />
4
4
  <img alt="Storybook" src="./Documentation/assets/logo-storybook-default.svg" height="40" />
5
5
 
6
- [Getting Started](https://docs.typo3.org/p/andersundsehr/storybook)
6
+ [Getting Started](https://docs.typo3.org/permalink/andersundsehr-storybook:start) - [TYPO3 Slack](https://typo3.slack.com/archives/C098AQPGXLM)
7
7
 
8
8
  The TYPO3 extension `storybook` integrates Storybook into TYPO3 projects.
9
9
  With the open-source tool Storybook, developers can develop and test UI components in isolation.
@@ -46,7 +46,7 @@ After that you can run storybook with:
46
46
  npx http-server ./storybook-static
47
47
  ```
48
48
 
49
- > Also See [full installation steps](https://docs.typo3.org/p/andersundsehr/storybook/latest/en-us/Installation/Index.html) in the Getting Started Guide.
49
+ > Also See [full installation steps](https://docs.typo3.org/permalink/andersundsehr-storybook:installation) in the Getting Started Guide.
50
50
 
51
51
  ## Configuration:
52
52
 
@@ -154,7 +154,7 @@ You can Select the site and the language in the top right corner of the Storyboo
154
154
 
155
155
  ## Documentation: Where to find more information? (Links, references, tutorials)
156
156
 
157
- https://docs.typo3.org/p/andersundsehr/storybook
157
+ https://docs.typo3.org/permalink/andersundsehr-storybook:start
158
158
 
159
159
  - docs TODO link to hosted Storybook instance
160
160
  - docs TODO link to playwright report?
@@ -1,6 +1,6 @@
1
1
  import { SourceType } from 'storybook/internal/docs-tools';
2
2
  import { type FluidRenderer } from '@andersundsehr/storybook-typo3';
3
- import { DecoratorFunction } from 'storybook/internal/types';
3
+ import { type DecoratorFunction } from 'storybook/internal/types';
4
4
  export declare const tags: string[];
5
5
  export declare const decorators: DecoratorFunction<FluidRenderer>[];
6
6
  export declare const parameters: {
@@ -6,7 +6,7 @@ export async function fetchComponent(component) {
6
6
  alert(message);
7
7
  throw new Error(message);
8
8
  }
9
- const data = await fetchWithUserRetry(url + '/_storybook/componentMeta?viewHelper=' + component, {}, 'metadata for component `' + component + '` from TYPO3');
9
+ const data = await fetchWithUserRetry(url + '/_storybook/componentMeta?viewHelper=' + component, {}, 'metadata for component `' + component + '`');
10
10
  return {
11
11
  fullName: component,
12
12
  name: component.split(':')[1],
@@ -32,7 +32,7 @@ export async function fetchPreviewConfig(currentGlobals) {
32
32
  'Content-Type': 'application/json',
33
33
  },
34
34
  body: JSON.stringify({ globals }),
35
- }, 'preview config from TYPO3');
35
+ }, 'preview config');
36
36
  }
37
37
  export function initGlobalsHandling(initalGlobalTypes) {
38
38
  const channel = addons.getChannel();
@@ -15,6 +15,6 @@ export async function fetchRenderAction(urlA, id, params, storyContext) {
15
15
  return await fetchWithUserRetry(url + '/_storybook/render', {
16
16
  method: 'POST',
17
17
  body: JSON.stringify(body),
18
- }, 'rendering component in TYPO3', 'text');
18
+ }, 'rendering component', 'text');
19
19
  }
20
20
  ;
@@ -1 +1,3 @@
1
- export declare function fetchWithUserRetry<T>(url: string, options: RequestInit, message: string, result?: 'json' | 'text'): Promise<T>;
1
+ type PossibleResults = string | object;
2
+ export declare function fetchWithUserRetry<T extends PossibleResults>(url: string, options: RequestInit, message: string, resultType?: 'json' | 'text'): Promise<T>;
3
+ export {};
@@ -1,23 +1,124 @@
1
- export async function fetchWithUserRetry(url, options, message, result = 'json') {
2
- options = { ...options }; // Clone options to avoid mutating the original
3
- options.signal = options.signal || AbortSignal.timeout(5000);
1
+ /*
2
+ We want to make it obvious for the user what he has to do.
3
+
4
+ We have 2 different use cases:
5
+ - background fetches (componentMeta & preview)
6
+ - html Fetches
7
+
8
+ most of the time the user has to do something in their IDE to fix the problem.
9
+ So we want to show a message that tells the user what he has to do.
10
+
11
+ In the case of a background fetch, we want to show the full error in the console.
12
+ And give the user a alert with the error message and a retry button.
13
+
14
+ In the case of a html fetch, we want to show the error as html response?
15
+ - yes: because the user can see the error in the browser and can fix it
16
+ - no: because storybook does not understand that it is an error
17
+
18
+ In any case we should get the error in json so we can handle it in the frontend as we like.
19
+ Sometimes it can still be text/html so we need to handle that as well.
20
+ */
21
+ export async function fetchWithUserRetry(url, options, message, resultType = 'json') {
4
22
  try {
23
+ options = { ...options }; // Clone options to avoid mutating the original
24
+ options.signal = options.signal || AbortSignal.timeout(5000);
5
25
  const response = await fetch(url, options);
6
- if (result === 'text') {
7
- return await response.text();
26
+ if (!response.ok) {
27
+ return retry(response, url, options, message, resultType);
8
28
  }
9
- return await response.json();
29
+ return (await response[resultType]());
10
30
  }
11
31
  catch (error) {
12
- console.error('Fetch failed:', { error });
13
- const retry = confirm('Error while fetching ' + message + '. \n\n'
14
- + 'fetch: ' + url + '\n'
15
- + 'ERROR: ' + String(error) + '\n\n'
16
- + 'look at the console for more details.\n\n'
17
- + 'Do you want to retry?');
18
- if (retry) {
19
- return fetchWithUserRetry(url, options, message);
32
+ return retry(error, url, options, message, resultType);
33
+ }
34
+ }
35
+ async function retry(errorOrResponse, url, options, message, resultType) {
36
+ const errorType = await getErrorExplanation(errorOrResponse);
37
+ let exception = errorOrResponse instanceof Error ? errorOrResponse : undefined;
38
+ let confirmationMessage = '';
39
+ if (errorType.errorType === 'network') {
40
+ confirmationMessage = `šŸ›œ+🚫 A network error occurred while fetching ${message} from TYPO3:\n\n`
41
+ + `šŸ’¬ ${errorType.message}\n\n`
42
+ + `ā© Please check your network connection and try again.\n\n`
43
+ + `šŸ”— url: ${url}\n\n`;
44
+ exception = new Error(`Network error: ${errorType.message}`);
45
+ }
46
+ else if (errorType.errorType === 'extension') {
47
+ if (resultType === 'text') {
48
+ // no retry via confirm()
49
+ return errorType.errorHtml;
50
+ }
51
+ confirmationMessage = `šŸ’„ An error occurred while fetching ${message} from TYPO3:\n\n`
52
+ + `šŸ’¬ ${errorType.reason}\n\n`
53
+ + `${errorType.stackTrace ? `šŸ•µšŸ»ā€ā™‚ļø Stack trace: ${errorType.stackTrace}\n\n` : ''}`
54
+ + `šŸ”— url: ${url}\n\n`;
55
+ exception = new Error(`Extension error: ${errorType.reason}`);
56
+ }
57
+ else {
58
+ if (resultType === 'text' && errorType.message) {
59
+ // no retry via confirm()
60
+ return errorType.message;
61
+ }
62
+ // unknown error
63
+ confirmationMessage = `😳 An error occurred while fetching ${message} from TYPO3:\n\n`
64
+ + `šŸ’¬ ${errorType.message}\n\n`
65
+ + `#ļøāƒ£ Status code: ${errorType.statusCode || 'unknown'}\n\n`
66
+ + `šŸ”— url: ${url}\n\n`;
67
+ }
68
+ confirmationMessage = confirmationMessage.trim();
69
+ confirmationMessage = confirmationMessage.length > 700 ? confirmationMessage.substring(0, 700 - 3) + '\n…' : confirmationMessage;
70
+ const retry = confirm(confirmationMessage + '\n\n Do you want to retry šŸ”„ā“');
71
+ if (retry) {
72
+ options.signal = undefined;
73
+ return fetchWithUserRetry(url, options, message, resultType);
74
+ }
75
+ throw exception || new Error(`Failed to fetch ${message} from TYPO3: ${JSON.stringify(errorType)}`);
76
+ }
77
+ async function getErrorExplanation(errorOrResponse) {
78
+ if (errorOrResponse instanceof Response) {
79
+ let text = undefined;
80
+ try {
81
+ text = await errorOrResponse.text();
82
+ }
83
+ catch (e) {
84
+ return {
85
+ errorType: 'unknown',
86
+ message: `Failed to read response from TYPO3: ${errorOrResponse.status}\n ${errorOrResponse.statusText}`,
87
+ };
88
+ }
89
+ try {
90
+ const extensionError = JSON.parse(text);
91
+ if (extensionError && typeof extensionError === 'object' && 'errorType' in extensionError && extensionError.errorType === 'extension') {
92
+ return extensionError;
93
+ }
94
+ return {
95
+ errorType: 'unknown',
96
+ statusCode: errorOrResponse.status,
97
+ message: `Received an unexpected response from TYPO3: ${errorOrResponse.status}\n ${JSON.stringify(extensionError)}`,
98
+ };
20
99
  }
21
- throw error; // Re-throw the error if the user does not want to retry
100
+ catch (e) {
101
+ console.warn('ā‰ļø Failed to parse JSON from TYPO3 response:', e);
102
+ }
103
+ return {
104
+ errorType: 'unknown',
105
+ message: `Received an unexpected response from TYPO3: ${errorOrResponse.status}\n ${text}`,
106
+ };
107
+ }
108
+ if (errorOrResponse instanceof Error) {
109
+ return {
110
+ errorType: 'network',
111
+ message: errorOrResponse.message,
112
+ };
113
+ }
114
+ if (typeof errorOrResponse === 'string') {
115
+ return {
116
+ errorType: 'unknown',
117
+ message: errorOrResponse,
118
+ };
22
119
  }
120
+ return {
121
+ errorType: 'unknown',
122
+ message: `An unknown error occurred: ${JSON.stringify(errorOrResponse) || ''}`,
123
+ };
23
124
  }
package/dist/preset.d.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  import type { PresetProperty } from 'storybook/internal/types';
2
+ import type { ViteFinal } from '@storybook/builder-vite';
2
3
  export declare const addons: string[];
4
+ /**
5
+ * We want storybook to not use your local vite config.
6
+ * As that is not really needed, and can cause issues or break storybook.
7
+ */
8
+ export declare const viteFinal: ViteFinal;
3
9
  export declare const core: PresetProperty<'core'>;
4
10
  export declare const previewAnnotations: PresetProperty<'previewAnnotations'>;
5
11
  export declare const tags: string[];
package/dist/preset.js CHANGED
@@ -8,6 +8,13 @@ export const addons = [
8
8
  '@storybook/addon-docs',
9
9
  '@storybook/addon-a11y',
10
10
  ];
11
+ /**
12
+ * We want storybook to not use your local vite config.
13
+ * As that is not really needed, and can cause issues or break storybook.
14
+ */
15
+ export const viteFinal = (config, options) => {
16
+ return config;
17
+ };
11
18
  export const core = {
12
19
  builder: getAbsolutePath('@storybook/builder-vite'),
13
20
  renderer: getAbsolutePath('@storybook/server'),
@@ -1,5 +1,5 @@
1
1
  import type { Args, StrictArgs } from '@storybook/server';
2
- import { AnnotatedStoryFn, CompatibleString, ComponentAnnotations, DecoratorFunction, LoaderFunction, ProjectAnnotations, StoryAnnotations, StorybookConfig as StorybookConfigBase, StoryContext as StoryContext$1, WebRenderer } from 'storybook/internal/types';
2
+ import type { AnnotatedStoryFn, CompatibleString, ComponentAnnotations, DecoratorFunction, LoaderFunction, ProjectAnnotations, StoryAnnotations, StorybookConfig as StorybookConfigBase, StoryContext as StoryContext$1, WebRenderer } from 'storybook/internal/types';
3
3
  import type { BuilderOptions, StorybookConfigVite } from '@storybook/builder-vite';
4
4
  type FrameworkName = CompatibleString<'@andersundsehr/storybook-typo3'>;
5
5
  type BuilderName = CompatibleString<'@storybook/builder-vite'>;
@@ -54,4 +54,4 @@ type Decorator<TArgs = StrictArgs> = DecoratorFunction<FluidRenderer, TArgs>;
54
54
  type Loader<TArgs = StrictArgs> = LoaderFunction<FluidRenderer, TArgs>;
55
55
  type StoryContext<TArgs = StrictArgs> = StoryContext$1<FluidRenderer, TArgs>;
56
56
  type Preview = ProjectAnnotations<FluidRenderer>;
57
- export { Decorator, Loader, Meta, Preview, FluidRenderer, StoryContext, StoryFn, StoryObj };
57
+ export type { Decorator, Loader, Meta, Preview, FluidRenderer, StoryContext, StoryFn, StoryObj };
package/package.json CHANGED
@@ -49,5 +49,5 @@
49
49
  "dist",
50
50
  "README.md"
51
51
  ],
52
- "version": "0.1.10"
52
+ "version": "0.1.12"
53
53
  }