@automattic/jetpack-ai-client 0.12.1 → 0.12.3
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/CHANGELOG.md +10 -0
- package/build/components/ai-control/ai-control.d.ts +28 -0
- package/build/components/ai-control/ai-control.js +22 -0
- package/build/components/ai-control/block-ai-control.d.ts +37 -0
- package/build/components/ai-control/block-ai-control.js +82 -0
- package/build/components/ai-control/extension-ai-control.d.ts +35 -0
- package/build/components/ai-control/extension-ai-control.js +86 -0
- package/build/components/ai-control/index.d.ts +3 -40
- package/build/components/ai-control/index.js +3 -86
- package/build/components/index.d.ts +2 -2
- package/build/components/index.js +2 -2
- package/build/components/{ai-control/message.d.ts → message/index.d.ts} +25 -8
- package/build/components/message/index.js +69 -0
- package/build/icons/error-exclamation.d.ts +2 -0
- package/build/icons/error-exclamation.js +7 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +4 -0
- package/build/libs/index.d.ts +1 -0
- package/build/libs/index.js +1 -0
- package/build/libs/markdown/html-to-markdown.d.ts +23 -0
- package/build/libs/markdown/html-to-markdown.js +31 -0
- package/build/libs/markdown/index.d.ts +17 -0
- package/build/libs/markdown/index.js +14 -0
- package/build/libs/markdown/markdown-to-html.d.ts +24 -0
- package/build/libs/markdown/markdown-to-html.js +33 -0
- package/build/types.d.ts +10 -0
- package/package.json +8 -3
- package/src/components/ai-control/ai-control.tsx +79 -0
- package/src/components/ai-control/block-ai-control.tsx +278 -0
- package/src/components/ai-control/extension-ai-control.tsx +217 -0
- package/src/components/ai-control/index.tsx +3 -281
- package/src/components/ai-control/style.scss +4 -42
- package/src/components/index.ts +3 -2
- package/src/components/message/index.tsx +157 -0
- package/src/components/message/style.scss +83 -0
- package/src/icons/error-exclamation.tsx +18 -0
- package/src/index.ts +5 -0
- package/src/libs/index.ts +6 -0
- package/src/libs/markdown/README.md +74 -0
- package/src/libs/markdown/html-to-markdown.ts +42 -0
- package/src/libs/markdown/index.ts +28 -0
- package/src/libs/markdown/markdown-to-html.ts +48 -0
- package/src/types.ts +11 -0
- package/build/components/ai-control/message.js +0 -57
- package/src/components/ai-control/message.tsx +0 -118
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { ExternalLink, Button } from '@wordpress/components';
|
|
5
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
6
|
+
import { Icon, check, arrowRight } from '@wordpress/icons';
|
|
7
|
+
import classNames from 'classnames';
|
|
8
|
+
/**
|
|
9
|
+
* Internal dependencies
|
|
10
|
+
*/
|
|
11
|
+
import './style.scss';
|
|
12
|
+
import errorExclamation from '../../icons/error-exclamation.js';
|
|
13
|
+
/**
|
|
14
|
+
* Types
|
|
15
|
+
*/
|
|
16
|
+
import type React from 'react';
|
|
17
|
+
|
|
18
|
+
export const MESSAGE_SEVERITY_WARNING = 'warning';
|
|
19
|
+
export const MESSAGE_SEVERITY_ERROR = 'error';
|
|
20
|
+
export const MESSAGE_SEVERITY_SUCCESS = 'success';
|
|
21
|
+
export const MESSAGE_SEVERITY_INFO = 'info';
|
|
22
|
+
|
|
23
|
+
const messageSeverityTypes = [
|
|
24
|
+
MESSAGE_SEVERITY_WARNING,
|
|
25
|
+
MESSAGE_SEVERITY_ERROR,
|
|
26
|
+
MESSAGE_SEVERITY_SUCCESS,
|
|
27
|
+
MESSAGE_SEVERITY_INFO,
|
|
28
|
+
] as const;
|
|
29
|
+
|
|
30
|
+
export type MessageSeverityProp = ( typeof messageSeverityTypes )[ number ] | null;
|
|
31
|
+
|
|
32
|
+
export type MessageProps = {
|
|
33
|
+
icon?: React.ReactNode;
|
|
34
|
+
severity?: MessageSeverityProp;
|
|
35
|
+
showSidebarIcon?: boolean;
|
|
36
|
+
onSidebarIconClick?: () => void;
|
|
37
|
+
children: React.ReactNode;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type UpgradeMessageProps = {
|
|
41
|
+
requestsRemaining: number;
|
|
42
|
+
onUpgradeClick: () => void;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type ErrorMessageProps = {
|
|
46
|
+
error?: string;
|
|
47
|
+
onTryAgainClick: () => void;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const messageIconsMap = {
|
|
51
|
+
[ MESSAGE_SEVERITY_INFO ]: null,
|
|
52
|
+
[ MESSAGE_SEVERITY_WARNING ]: null,
|
|
53
|
+
[ MESSAGE_SEVERITY_ERROR ]: errorExclamation,
|
|
54
|
+
[ MESSAGE_SEVERITY_SUCCESS ]: check,
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* React component to render a block message.
|
|
59
|
+
*
|
|
60
|
+
* @param {MessageProps} props - Component props.
|
|
61
|
+
* @returns {React.ReactElement } Banner component.
|
|
62
|
+
*/
|
|
63
|
+
export default function Message( {
|
|
64
|
+
severity = MESSAGE_SEVERITY_INFO,
|
|
65
|
+
icon = null,
|
|
66
|
+
showSidebarIcon = false,
|
|
67
|
+
onSidebarIconClick = () => {},
|
|
68
|
+
children,
|
|
69
|
+
}: MessageProps ): React.ReactElement {
|
|
70
|
+
return (
|
|
71
|
+
<div
|
|
72
|
+
className={ classNames(
|
|
73
|
+
'jetpack-ai-assistant__message',
|
|
74
|
+
`jetpack-ai-assistant__message-severity-${ severity }`
|
|
75
|
+
) }
|
|
76
|
+
>
|
|
77
|
+
{ ( messageIconsMap[ severity ] || icon ) && (
|
|
78
|
+
<Icon icon={ messageIconsMap[ severity ] || icon } />
|
|
79
|
+
) }
|
|
80
|
+
<div className="jetpack-ai-assistant__message-content">{ children }</div>
|
|
81
|
+
{ showSidebarIcon && (
|
|
82
|
+
<Button className="jetpack-ai-assistant__message-sidebar" onClick={ onSidebarIconClick }>
|
|
83
|
+
<Icon size={ 20 } icon={ arrowRight } />
|
|
84
|
+
</Button>
|
|
85
|
+
) }
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* React component to render a guideline message.
|
|
92
|
+
*
|
|
93
|
+
* @returns {React.ReactElement } - Message component.
|
|
94
|
+
*/
|
|
95
|
+
export function GuidelineMessage(): React.ReactElement {
|
|
96
|
+
return (
|
|
97
|
+
<Message>
|
|
98
|
+
<span>
|
|
99
|
+
{ __( 'AI-generated content could be inaccurate or biased.', 'jetpack-ai-client' ) }
|
|
100
|
+
</span>
|
|
101
|
+
<ExternalLink href="https://automattic.com/ai-guidelines">
|
|
102
|
+
{ __( 'Learn more', 'jetpack-ai-client' ) }
|
|
103
|
+
</ExternalLink>
|
|
104
|
+
</Message>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* React component to render an upgrade message for free tier users
|
|
110
|
+
*
|
|
111
|
+
* @param {number} requestsRemaining - Number of requests remaining.
|
|
112
|
+
* @returns {React.ReactElement } - Message component.
|
|
113
|
+
*/
|
|
114
|
+
export function UpgradeMessage( {
|
|
115
|
+
requestsRemaining,
|
|
116
|
+
onUpgradeClick,
|
|
117
|
+
}: UpgradeMessageProps ): React.ReactElement {
|
|
118
|
+
return (
|
|
119
|
+
<Message severity={ MESSAGE_SEVERITY_WARNING }>
|
|
120
|
+
<span>
|
|
121
|
+
{ sprintf(
|
|
122
|
+
// translators: %1$d: number of requests remaining
|
|
123
|
+
__( 'You have %1$d free requests remaining.', 'jetpack-ai-client' ),
|
|
124
|
+
requestsRemaining
|
|
125
|
+
) }
|
|
126
|
+
</span>
|
|
127
|
+
<Button variant="link" onClick={ onUpgradeClick }>
|
|
128
|
+
{ __( 'Upgrade now', 'jetpack-ai-client' ) }
|
|
129
|
+
</Button>
|
|
130
|
+
</Message>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* React component to render an error message
|
|
136
|
+
*
|
|
137
|
+
* @param {number} requestsRemaining - Number of requests remaining.
|
|
138
|
+
* @returns {React.ReactElement } - Message component.
|
|
139
|
+
*/
|
|
140
|
+
export function ErrorMessage( { error, onTryAgainClick }: ErrorMessageProps ): React.ReactElement {
|
|
141
|
+
const errorMessage = error || __( 'Something went wrong', 'jetpack-ai-client' );
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
<Message severity={ MESSAGE_SEVERITY_ERROR }>
|
|
145
|
+
<span>
|
|
146
|
+
{ sprintf(
|
|
147
|
+
// translators: %1$d: A dynamic error message
|
|
148
|
+
__( 'Error: %1$s.', 'jetpack-ai-client' ),
|
|
149
|
+
errorMessage
|
|
150
|
+
) }
|
|
151
|
+
</span>
|
|
152
|
+
<Button variant="link" onClick={ onTryAgainClick }>
|
|
153
|
+
{ __( 'Try Again', 'jetpack-ai-client' ) }
|
|
154
|
+
</Button>
|
|
155
|
+
</Message>
|
|
156
|
+
);
|
|
157
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
@import '@automattic/jetpack-base-styles/root-variables';
|
|
2
|
+
|
|
3
|
+
.jetpack-ai-assistant__message {
|
|
4
|
+
display: flex;
|
|
5
|
+
line-height: 28px;
|
|
6
|
+
font-size: 12px;
|
|
7
|
+
align-self: center;
|
|
8
|
+
align-items: center;
|
|
9
|
+
padding: 0 12px;
|
|
10
|
+
border-radius: 4px;
|
|
11
|
+
min-height: 28px;
|
|
12
|
+
|
|
13
|
+
> svg {
|
|
14
|
+
fill: var( --jp-gray-40 );
|
|
15
|
+
flex-shrink: 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.jetpack-ai-assistant__message-content {
|
|
19
|
+
flex-grow: 2;
|
|
20
|
+
margin: 0 8px;
|
|
21
|
+
line-height: 1.4em;
|
|
22
|
+
display: flex;
|
|
23
|
+
gap: 4px;
|
|
24
|
+
align-items: center;
|
|
25
|
+
|
|
26
|
+
span {
|
|
27
|
+
padding: 5px 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.components-external-link {
|
|
31
|
+
color: var( --jp-gray-50 );
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Force padding 0 in link buttons, since default Gutenberg version in WordPress doesn't use iframe and
|
|
35
|
+
// Buttons receive styles from edit-post-visual-editor.
|
|
36
|
+
.components-button.is-link {
|
|
37
|
+
padding: 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.components-button.is-link,
|
|
41
|
+
.components-external-link {
|
|
42
|
+
flex-shrink: 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.jetpack-ai-assistant__message-severity-info {
|
|
48
|
+
background-color: var( --jp-gray-0 );
|
|
49
|
+
color: var( --jp-gray-50 );
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.jetpack-ai-assistant__message-severity-warning {
|
|
53
|
+
background-color: #FEF8EE;
|
|
54
|
+
color: var( --jp-gray-100 );
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.jetpack-ai-assistant__message-severity-error {
|
|
58
|
+
background-color: var( --jp-red-0 );
|
|
59
|
+
color: var( --jp-gray-100 );
|
|
60
|
+
|
|
61
|
+
> svg {
|
|
62
|
+
fill: var( --jp-red-40, #E65054 );
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.jetpack-ai-assistant__message-severity-success {
|
|
67
|
+
background-color: var( --jp-green-5 );
|
|
68
|
+
color: var( --jp-gray-100 );
|
|
69
|
+
|
|
70
|
+
> svg {
|
|
71
|
+
fill: var( --jp-green-30 );
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.jetpack-ai-assistant__message-sidebar {
|
|
76
|
+
display: flex;
|
|
77
|
+
padding: 0;
|
|
78
|
+
height: unset;
|
|
79
|
+
|
|
80
|
+
> svg {
|
|
81
|
+
fill: var( --jp-gray-50 );
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { SVG, Path } from '@wordpress/components';
|
|
5
|
+
|
|
6
|
+
const errorExclamation = (
|
|
7
|
+
<SVG width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
8
|
+
<Path
|
|
9
|
+
fillRule="evenodd"
|
|
10
|
+
clipRule="evenodd"
|
|
11
|
+
d="M10 3.95833C6.66328 3.95833 3.95833 6.66327 3.95833 9.99999C3.95833 13.3367 6.66328 16.0417 10 16.0417C13.3367 16.0417 16.0417 13.3367 16.0417 9.99999C16.0417 6.66327 13.3367 3.95833 10 3.95833ZM2.70833 9.99999C2.70833 5.97292 5.97292 2.70833 10 2.70833C14.0271 2.70833 17.2917 5.97292 17.2917 9.99999C17.2917 14.0271 14.0271 17.2917 10 17.2917C5.97292 17.2917 2.70833 14.0271 2.70833 9.99999Z"
|
|
12
|
+
/>
|
|
13
|
+
<Path d="M10.8333 5.83333H9.16667V10.8333H10.8333V5.83333Z" />
|
|
14
|
+
<Path d="M10.8333 12.5H9.16667V14.1667H10.8333V12.5Z" />
|
|
15
|
+
</SVG>
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
export default errorExclamation;
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Markdown converters
|
|
2
|
+
|
|
3
|
+
Typescript functions and classes to convert Markdown to and from HTML.
|
|
4
|
+
|
|
5
|
+
## HTML to Markdown
|
|
6
|
+
|
|
7
|
+
The HTML to Markdown conversion uses the [Turndown](https://github.com/mixmark-io/turndown) library and supports Turndown's options and rules.
|
|
8
|
+
|
|
9
|
+
Example:
|
|
10
|
+
```typescript
|
|
11
|
+
/**
|
|
12
|
+
* External dependencies
|
|
13
|
+
*/
|
|
14
|
+
import { renderMarkdownFromHTML } from '@automattic/jetpack-ai-client';
|
|
15
|
+
|
|
16
|
+
const htmlContent = '<strong>Hello world</strong>';
|
|
17
|
+
const markdownContent = renderMarkdownFromHTML( { content: htmlContent } );
|
|
18
|
+
// **Hello world**
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
To use custom options and rules:
|
|
22
|
+
```typescript
|
|
23
|
+
/**
|
|
24
|
+
* External dependencies
|
|
25
|
+
*/
|
|
26
|
+
import { HTMLToMarkdown } from '@automattic/jetpack-ai-client';
|
|
27
|
+
|
|
28
|
+
const htmlContent = '<strong>Hello world</strong>';
|
|
29
|
+
const options = { headingStyle: 'setext' };
|
|
30
|
+
const rules = {
|
|
31
|
+
customStrong: {
|
|
32
|
+
filter: [ 'strong' ],
|
|
33
|
+
replacement: function( content: string ) {
|
|
34
|
+
return '***' + content + '***';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const renderer = new HTMLToMarkdown( options, rules );
|
|
39
|
+
const markdownContent = renderer.render( { content: htmlContent } );
|
|
40
|
+
// ***Hello world***
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Markdown to HTML
|
|
44
|
+
|
|
45
|
+
The Markdown to HTML conversion uses the [markdown-it](https://github.com/markdown-it/markdown-it) library and supports markdown-it's options. It also adds access to common fixes.
|
|
46
|
+
|
|
47
|
+
Example:
|
|
48
|
+
```typescript
|
|
49
|
+
/**
|
|
50
|
+
* External dependencies
|
|
51
|
+
*/
|
|
52
|
+
import { renderHTMLFromMarkdown } from '@automattic/jetpack-ai-client';
|
|
53
|
+
|
|
54
|
+
const markdownContent = '**Hello world**';
|
|
55
|
+
const htmlContent = renderHTMLFromMarkdown( { content: markdownContent, rules: 'all' } ); // 'all' is a default value
|
|
56
|
+
// <p><strong>Hello world</strong></p>\n
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
To use custom options and fixes:
|
|
60
|
+
```typescript
|
|
61
|
+
/**
|
|
62
|
+
* External dependencies
|
|
63
|
+
*/
|
|
64
|
+
import { MarkdownToHTML } from '@automattic/jetpack-ai-client';
|
|
65
|
+
|
|
66
|
+
const markdownContent = '**Hello world**';
|
|
67
|
+
const options = { breaks: 'false' };
|
|
68
|
+
const rules = [ 'list' ];
|
|
69
|
+
const renderer = new MarkdownToHTML( options );
|
|
70
|
+
const htmlContent = renderer.render( { content: markdownContent, rules } );
|
|
71
|
+
// <p><strong>Hello world</strong></p>\n
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Currently `rules` only supports `'all'` and `['list']`. Further specific fixes can be added when necessary.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import TurndownService from 'turndown';
|
|
5
|
+
/**
|
|
6
|
+
* Types
|
|
7
|
+
*/
|
|
8
|
+
import type { Options, Rule } from 'turndown';
|
|
9
|
+
|
|
10
|
+
const defaultTurndownOptions: Options = { emDelimiter: '_', headingStyle: 'atx' };
|
|
11
|
+
const defaultTurndownRules: { [ key: string ]: Rule } = {
|
|
12
|
+
strikethrough: {
|
|
13
|
+
filter: [ 'del', 's' ],
|
|
14
|
+
replacement: function ( content: string ) {
|
|
15
|
+
return '~~' + content + '~~';
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default class HTMLToMarkdown {
|
|
21
|
+
turndownService: TurndownService;
|
|
22
|
+
|
|
23
|
+
constructor(
|
|
24
|
+
options: Options = defaultTurndownOptions,
|
|
25
|
+
rules: { [ key: string ]: Rule } = defaultTurndownRules
|
|
26
|
+
) {
|
|
27
|
+
this.turndownService = new TurndownService( options );
|
|
28
|
+
for ( const rule in rules ) {
|
|
29
|
+
this.turndownService.addRule( rule, rules[ rule ] );
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Renders HTML from Markdown content with specified processing rules.
|
|
35
|
+
* @param {object} options - The options to use when rendering the Markdown content
|
|
36
|
+
* @param {string} options.content - The HTML content to render
|
|
37
|
+
* @returns {string} The rendered Markdown content
|
|
38
|
+
*/
|
|
39
|
+
render( { content }: { content: string } ): string {
|
|
40
|
+
return this.turndownService.turndown( content );
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import HTMLToMarkdown from './html-to-markdown.js';
|
|
5
|
+
import MarkdownToHTML from './markdown-to-html.js';
|
|
6
|
+
/**
|
|
7
|
+
* Types
|
|
8
|
+
*/
|
|
9
|
+
import type { Fix as HTMLFix } from './markdown-to-html.js';
|
|
10
|
+
|
|
11
|
+
const defaultMarkdownConverter = new MarkdownToHTML();
|
|
12
|
+
const defaultHTMLConverter = new HTMLToMarkdown();
|
|
13
|
+
|
|
14
|
+
const renderHTMLFromMarkdown = ( {
|
|
15
|
+
content,
|
|
16
|
+
rules = 'all',
|
|
17
|
+
}: {
|
|
18
|
+
content: string;
|
|
19
|
+
rules?: Array< HTMLFix > | 'all';
|
|
20
|
+
} ) => {
|
|
21
|
+
return defaultMarkdownConverter.render( { content, rules } );
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const renderMarkdownFromHTML = ( { content }: { content: string } ) => {
|
|
25
|
+
return defaultHTMLConverter.render( { content } );
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export { MarkdownToHTML, HTMLToMarkdown, renderHTMLFromMarkdown, renderMarkdownFromHTML };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import MarkdownIt from 'markdown-it';
|
|
5
|
+
/**
|
|
6
|
+
* Types
|
|
7
|
+
*/
|
|
8
|
+
import type { Options } from 'markdown-it';
|
|
9
|
+
|
|
10
|
+
export type Fix = 'list';
|
|
11
|
+
type Fixes = {
|
|
12
|
+
[ key in Fix ]: ( content: string ) => string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const fixes: Fixes = {
|
|
16
|
+
list: ( content: string ) => {
|
|
17
|
+
// Fix list indentation
|
|
18
|
+
return content.replace( /<li>\s+<p>/g, '<li>' ).replace( /<\/p>\s+<\/li>/g, '</li>' );
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const defaultMarkdownItOptions: Options = {
|
|
23
|
+
breaks: true,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default class MarkdownToHTML {
|
|
27
|
+
markdownConverter: MarkdownIt;
|
|
28
|
+
|
|
29
|
+
constructor( options: Options = defaultMarkdownItOptions ) {
|
|
30
|
+
this.markdownConverter = new MarkdownIt( options );
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Renders HTML from Markdown content with specified processing rules.
|
|
35
|
+
* @param {object} options - The options to use when rendering the HTML content
|
|
36
|
+
* @param {string} options.content - The Markdown content to render
|
|
37
|
+
* @param {string} options.rules - The rules to apply to the rendered content
|
|
38
|
+
* @returns {string} The rendered HTML content
|
|
39
|
+
*/
|
|
40
|
+
render( { content, rules = 'all' }: { content: string; rules: Array< Fix > | 'all' } ): string {
|
|
41
|
+
const rendered = this.markdownConverter.render( content );
|
|
42
|
+
const rulesToApply = rules === 'all' ? Object.keys( fixes ) : rules;
|
|
43
|
+
|
|
44
|
+
return rulesToApply.reduce( ( renderedContent, rule ) => {
|
|
45
|
+
return fixes[ rule ]( renderedContent );
|
|
46
|
+
}, rendered );
|
|
47
|
+
}
|
|
48
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -93,6 +93,17 @@ export type { RecordingState } from './hooks/use-media-recording/index.js';
|
|
|
93
93
|
*/
|
|
94
94
|
export type CancelablePromise< T = void > = Promise< T > & { canceled?: boolean };
|
|
95
95
|
|
|
96
|
+
export type Block = {
|
|
97
|
+
attributes?: {
|
|
98
|
+
[ key: string ]: unknown;
|
|
99
|
+
};
|
|
100
|
+
clientId?: string;
|
|
101
|
+
innerBlocks?: Block[];
|
|
102
|
+
isValid?: boolean;
|
|
103
|
+
name?: string;
|
|
104
|
+
originalContent?: string;
|
|
105
|
+
};
|
|
106
|
+
|
|
96
107
|
/*
|
|
97
108
|
* Transcription types
|
|
98
109
|
*/
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* External dependencies
|
|
4
|
-
*/
|
|
5
|
-
import { ExternalLink, Button } from '@wordpress/components';
|
|
6
|
-
import { createInterpolateElement } from '@wordpress/element';
|
|
7
|
-
import { __, sprintf } from '@wordpress/i18n';
|
|
8
|
-
import { Icon, warning, info, cancelCircleFilled as error, check as success, } from '@wordpress/icons';
|
|
9
|
-
import './style.scss';
|
|
10
|
-
export const MESSAGE_SEVERITY_WARNING = 'warning';
|
|
11
|
-
export const MESSAGE_SEVERITY_ERROR = 'error';
|
|
12
|
-
export const MESSAGE_SEVERITY_SUCCESS = 'success';
|
|
13
|
-
export const MESSAGE_SEVERITY_INFO = 'info';
|
|
14
|
-
const messageSeverityTypes = [
|
|
15
|
-
MESSAGE_SEVERITY_WARNING,
|
|
16
|
-
MESSAGE_SEVERITY_ERROR,
|
|
17
|
-
MESSAGE_SEVERITY_SUCCESS,
|
|
18
|
-
MESSAGE_SEVERITY_INFO,
|
|
19
|
-
];
|
|
20
|
-
const messageIconsMap = {
|
|
21
|
-
[MESSAGE_SEVERITY_WARNING]: warning,
|
|
22
|
-
[MESSAGE_SEVERITY_ERROR]: error,
|
|
23
|
-
[MESSAGE_SEVERITY_SUCCESS]: success,
|
|
24
|
-
[MESSAGE_SEVERITY_INFO]: info,
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* React component to render a block message.
|
|
28
|
-
*
|
|
29
|
-
* @param {MessageProps} props - Component props.
|
|
30
|
-
* @returns {React.ReactElement } Banner component.
|
|
31
|
-
*/
|
|
32
|
-
export default function Message({ severity = null, icon = null, children, }) {
|
|
33
|
-
return (_jsxs("div", { className: "jetpack-ai-assistant__message", children: [(severity || icon) && _jsx(Icon, { icon: messageIconsMap[severity] || icon }), _jsx("div", { className: "jetpack-ai-assistant__message-content", children: children })] }));
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* React component to render a guideline message.
|
|
37
|
-
*
|
|
38
|
-
* @returns {React.ReactElement } - Message component.
|
|
39
|
-
*/
|
|
40
|
-
export function GuidelineMessage() {
|
|
41
|
-
return (_jsx(Message, { severity: MESSAGE_SEVERITY_INFO, children: createInterpolateElement(__('AI-generated content could be inaccurate or biased. <link>Learn more</link>', 'jetpack-ai-client'), {
|
|
42
|
-
link: _jsx(ExternalLink, { href: "https://automattic.com/ai-guidelines" }),
|
|
43
|
-
}) }));
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* React component to render a upgrade message.
|
|
47
|
-
*
|
|
48
|
-
* @param {number} requestsRemaining - Number of requests remaining.
|
|
49
|
-
* @returns {React.ReactElement } - Message component.
|
|
50
|
-
*/
|
|
51
|
-
export function UpgradeMessage({ requestsRemaining, onUpgradeClick, }) {
|
|
52
|
-
return (_jsx(Message, { severity: MESSAGE_SEVERITY_INFO, children: createInterpolateElement(sprintf(
|
|
53
|
-
// translators: %1$d: number of requests remaining
|
|
54
|
-
__('You have %1$d free requests remaining. <link>Upgrade</link> and avoid interruptions', 'jetpack-ai-client'), requestsRemaining), {
|
|
55
|
-
link: _jsx(Button, { variant: "link", onClick: onUpgradeClick }),
|
|
56
|
-
}) }));
|
|
57
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* External dependencies
|
|
3
|
-
*/
|
|
4
|
-
import { ExternalLink, Button } from '@wordpress/components';
|
|
5
|
-
import { createInterpolateElement } from '@wordpress/element';
|
|
6
|
-
import { __, sprintf } from '@wordpress/i18n';
|
|
7
|
-
import {
|
|
8
|
-
Icon,
|
|
9
|
-
warning,
|
|
10
|
-
info,
|
|
11
|
-
cancelCircleFilled as error,
|
|
12
|
-
check as success,
|
|
13
|
-
} from '@wordpress/icons';
|
|
14
|
-
/**
|
|
15
|
-
* Types
|
|
16
|
-
*/
|
|
17
|
-
import type React from 'react';
|
|
18
|
-
|
|
19
|
-
import './style.scss';
|
|
20
|
-
|
|
21
|
-
export const MESSAGE_SEVERITY_WARNING = 'warning';
|
|
22
|
-
export const MESSAGE_SEVERITY_ERROR = 'error';
|
|
23
|
-
export const MESSAGE_SEVERITY_SUCCESS = 'success';
|
|
24
|
-
export const MESSAGE_SEVERITY_INFO = 'info';
|
|
25
|
-
|
|
26
|
-
const messageSeverityTypes = [
|
|
27
|
-
MESSAGE_SEVERITY_WARNING,
|
|
28
|
-
MESSAGE_SEVERITY_ERROR,
|
|
29
|
-
MESSAGE_SEVERITY_SUCCESS,
|
|
30
|
-
MESSAGE_SEVERITY_INFO,
|
|
31
|
-
] as const;
|
|
32
|
-
|
|
33
|
-
export type MessageSeverityProp = ( typeof messageSeverityTypes )[ number ] | null;
|
|
34
|
-
|
|
35
|
-
export type MessageProps = {
|
|
36
|
-
icon?: React.ReactNode;
|
|
37
|
-
children: React.ReactNode;
|
|
38
|
-
severity: MessageSeverityProp;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const messageIconsMap = {
|
|
42
|
-
[ MESSAGE_SEVERITY_WARNING ]: warning,
|
|
43
|
-
[ MESSAGE_SEVERITY_ERROR ]: error,
|
|
44
|
-
[ MESSAGE_SEVERITY_SUCCESS ]: success,
|
|
45
|
-
[ MESSAGE_SEVERITY_INFO ]: info,
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* React component to render a block message.
|
|
50
|
-
*
|
|
51
|
-
* @param {MessageProps} props - Component props.
|
|
52
|
-
* @returns {React.ReactElement } Banner component.
|
|
53
|
-
*/
|
|
54
|
-
export default function Message( {
|
|
55
|
-
severity = null,
|
|
56
|
-
icon = null,
|
|
57
|
-
children,
|
|
58
|
-
}: MessageProps ): React.ReactElement {
|
|
59
|
-
return (
|
|
60
|
-
<div className="jetpack-ai-assistant__message">
|
|
61
|
-
{ ( severity || icon ) && <Icon icon={ messageIconsMap[ severity ] || icon } /> }
|
|
62
|
-
<div className="jetpack-ai-assistant__message-content">{ children }</div>
|
|
63
|
-
</div>
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* React component to render a guideline message.
|
|
69
|
-
*
|
|
70
|
-
* @returns {React.ReactElement } - Message component.
|
|
71
|
-
*/
|
|
72
|
-
export function GuidelineMessage(): React.ReactElement {
|
|
73
|
-
return (
|
|
74
|
-
<Message severity={ MESSAGE_SEVERITY_INFO }>
|
|
75
|
-
{ createInterpolateElement(
|
|
76
|
-
__(
|
|
77
|
-
'AI-generated content could be inaccurate or biased. <link>Learn more</link>',
|
|
78
|
-
'jetpack-ai-client'
|
|
79
|
-
),
|
|
80
|
-
{
|
|
81
|
-
link: <ExternalLink href="https://automattic.com/ai-guidelines" />,
|
|
82
|
-
}
|
|
83
|
-
) }
|
|
84
|
-
</Message>
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* React component to render a upgrade message.
|
|
90
|
-
*
|
|
91
|
-
* @param {number} requestsRemaining - Number of requests remaining.
|
|
92
|
-
* @returns {React.ReactElement } - Message component.
|
|
93
|
-
*/
|
|
94
|
-
export function UpgradeMessage( {
|
|
95
|
-
requestsRemaining,
|
|
96
|
-
onUpgradeClick,
|
|
97
|
-
}: {
|
|
98
|
-
requestsRemaining: number;
|
|
99
|
-
onUpgradeClick: () => void;
|
|
100
|
-
} ): React.ReactElement {
|
|
101
|
-
return (
|
|
102
|
-
<Message severity={ MESSAGE_SEVERITY_INFO }>
|
|
103
|
-
{ createInterpolateElement(
|
|
104
|
-
sprintf(
|
|
105
|
-
// translators: %1$d: number of requests remaining
|
|
106
|
-
__(
|
|
107
|
-
'You have %1$d free requests remaining. <link>Upgrade</link> and avoid interruptions',
|
|
108
|
-
'jetpack-ai-client'
|
|
109
|
-
),
|
|
110
|
-
requestsRemaining
|
|
111
|
-
),
|
|
112
|
-
{
|
|
113
|
-
link: <Button variant="link" onClick={ onUpgradeClick } />,
|
|
114
|
-
}
|
|
115
|
-
) }
|
|
116
|
-
</Message>
|
|
117
|
-
);
|
|
118
|
-
}
|