Skip to content

Commit 479d7b6

Browse files
authored
Merge branch 'main' into dependabot/npm_and_yarn/types/node-22.5.4
2 parents 36b43ad + d6358d2 commit 479d7b6

File tree

15 files changed

+451
-275
lines changed

15 files changed

+451
-275
lines changed

Diff for: package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"lerna": "^7.4.2",
5050
"postcss": "8.4.43",
5151
"postcss-cli": "8.3.1",
52-
"postcss-import": "14.0.2",
52+
"postcss-import": "16.1.0",
5353
"postcss-loader": "8.1.1",
5454
"prettier": "2.8.8",
5555
"process": "0.11.10",
@@ -68,7 +68,8 @@
6868
"resolutions": {
6969
"fast-xml-parser": "4.4.1",
7070
"tar": "6.2.1",
71-
"micromatch": "4.0.8"
71+
"micromatch": "4.0.8",
72+
"@stoplight/react-error-boundary": "3.0.0"
7273
},
7374
"scripts": {
7475
"demo": "yarn workspace @stoplight/elements-demo",

Diff for: packages/elements-core/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@stoplight/elements-core",
3-
"version": "8.4.3",
3+
"version": "8.4.7",
44
"sideEffects": [
55
"web-components.min.js",
66
"src/web-components/**",

Diff for: packages/elements-core/src/components/Docs/HttpOperation/Body.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { SectionSubtitle } from '../Sections';
1313
export interface BodyProps {
1414
body: IHttpOperationRequestBody;
1515
onChange?: (requestBodyIndex: number) => void;
16+
isHttpWebhookOperation?: boolean;
1617
}
1718

1819
export const isBodyEmpty = (body?: BodyProps['body']) => {
@@ -23,7 +24,7 @@ export const isBodyEmpty = (body?: BodyProps['body']) => {
2324
return contents.length === 0 && !description?.trim();
2425
};
2526

26-
export const Body = ({ body, onChange }: BodyProps) => {
27+
export const Body = ({ body, onChange, isHttpWebhookOperation = false }: BodyProps) => {
2728
const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
2829
const [chosenContent, setChosenContent] = React.useState(0);
2930
const { nodeHasChanged, renderExtensionAddon } = useOptionsCtx();
@@ -61,13 +62,12 @@ export const Body = ({ body, onChange }: BodyProps) => {
6162
<NodeAnnotation change={descriptionChanged} />
6263
</Box>
6364
)}
64-
6565
{isJSONSchema(schema) && (
6666
<JsonSchemaViewer
6767
resolveRef={refResolver}
6868
maxRefDepth={maxRefDepth}
6969
schema={getOriginalObject(schema)}
70-
viewMode="write"
70+
viewMode={isHttpWebhookOperation ? 'standalone' : 'write'}
7171
renderRootTreeLines
7272
nodeHasChanged={nodeHasChanged}
7373
renderExtensionAddon={renderExtensionAddon}

Diff for: packages/elements-core/src/components/Docs/HttpOperation/HttpOperation.tsx

+6-10
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,13 @@ const HttpOperationComponent = React.memo<HttpOperationProps>(
9595
<NodeAnnotation change={descriptionChanged} />
9696
</Box>
9797
)}
98-
9998
<NodeVendorExtensions data={data} />
100-
10199
<Request
102100
onChange={setTextRequestBodyIndex}
103101
operation={data}
104102
hideSecurityInfo={layoutOptions?.hideSecurityInfo}
103+
isHttpWebhookOperation={isHttpWebhookOperation(data)}
105104
/>
106-
107105
{data.responses && (
108106
<Responses
109107
responses={data.responses}
@@ -112,9 +110,7 @@ const HttpOperationComponent = React.memo<HttpOperationProps>(
112110
isCompact={isCompact}
113111
/>
114112
)}
115-
116113
{data.callbacks?.length ? <Callbacks callbacks={data.callbacks} isCompact={isCompact} /> : null}
117-
118114
{isCompact && tryItPanel}
119115
</VStack>
120116
);
@@ -159,13 +155,13 @@ function MethodPathInner({ method, path, chosenServerUrl }: MethodPathProps & {
159155

160156
const pathElem = (
161157
<Flex overflowX="hidden" fontSize="lg" userSelect="all">
162-
<Box dir="rtl" color="muted" textOverflow="truncate" overflowX="hidden">
163-
<Box as="span" dir="ltr" style={{ unicodeBidi: 'bidi-override' }}>
158+
<Box dir="rtl" textOverflow="truncate" overflowX="hidden">
159+
<Box as="span" dir="ltr" color="muted" style={{ unicodeBidi: 'bidi-override' }}>
164160
{chosenServerUrl}
165161
</Box>
166-
</Box>
167-
<Box fontWeight="semibold" flex={1}>
168-
{path}
162+
<Box as="span" fontWeight="semibold" flex={1}>
163+
{path}
164+
</Box>
169165
</Box>
170166
</Flex>
171167
);

Diff for: packages/elements-core/src/components/Docs/HttpOperation/Request.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ interface IRequestProps {
1717
operation: IHttpEndpointOperation;
1818
hideSecurityInfo?: boolean;
1919
onChange?: (requestBodyIndex: number) => void;
20+
isHttpWebhookOperation?: boolean;
2021
}
2122

2223
export const Request: React.FunctionComponent<IRequestProps> = ({
@@ -33,6 +34,7 @@ export const Request: React.FunctionComponent<IRequestProps> = ({
3334
},
3435
hideSecurityInfo,
3536
onChange,
37+
isHttpWebhookOperation = false,
3638
}) => {
3739
if (!request || typeof request !== 'object') return null;
3840

@@ -82,7 +84,7 @@ export const Request: React.FunctionComponent<IRequestProps> = ({
8284
</VStack>
8385
)}
8486

85-
{body && <Body onChange={onChange} body={body} />}
87+
{body && <Body onChange={onChange} body={body} isHttpWebhookOperation={isHttpWebhookOperation} />}
8688
</VStack>
8789
);
8890
};

Diff for: packages/elements-core/src/components/Docs/HttpService/AdditionalInfo.stories.ts

+9-6
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ const meta: Meta<typeof AdditionalInfo> = {
1010
export default meta;
1111
type Story = StoryObj<typeof AdditionalInfo>;
1212

13-
export const LicenseNameAndURL: Story = {
14-
name: 'License Name with URL',
13+
// Story when only the license URL is provided
14+
export const LicenseWithOnlyURL: Story = {
15+
name: 'License with only URL',
1516
args: {
1617
id: 'id',
1718
license: {
@@ -21,8 +22,9 @@ export const LicenseNameAndURL: Story = {
2122
},
2223
};
2324

24-
export const LicenseNameAndIdentifier: Story = {
25-
name: 'License Name and Identifier',
25+
// Story when only the license identifier is provided
26+
export const LicenseWithOnlyIdentifier: Story = {
27+
name: 'License with only Identifier',
2628
args: {
2729
id: 'id',
2830
license: {
@@ -32,8 +34,9 @@ export const LicenseNameAndIdentifier: Story = {
3234
},
3335
};
3436

35-
export const LicenseIdentifierAndNameAndUrl: Story = {
36-
name: 'License Identifier, Name and URL',
37+
// Story when both the license URL and identifier are provided (URL should take precedence)
38+
export const LicenseWithURLAndIdentifier: Story = {
39+
name: 'License with URL and Identifier (URL takes precedence)',
3740
args: {
3841
id: 'id',
3942
license: {

Diff for: packages/elements-core/src/components/Docs/HttpService/AdditionalInfo.tsx

+12-3
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,23 @@ export const AdditionalInfo: React.FC<AdditionalInfoProps> = ({ id, termsOfServi
2424
: '';
2525

2626
//use spdx to look up url for license identifier if available
27-
const licenseUrl =
28-
license?.url || license?.identifier ? `https://spdx.org/licenses/${license?.identifier}.html` : undefined;
27+
// The licenseUrl is determined based on the mutual exclusivity of the `url` and `identifier` fields.
28+
// If a `license.url` is provided, it takes precedence over the `license.identifier`.
29+
// This is because the OpenAPI specification defines `url` and `identifier` as mutually exclusive fields,
30+
// meaning you should use either one or the other, but not both. If both are provided, the `url` should be used.
31+
// See: https://spec.openapis.org/oas/latest.html#license-object
32+
const licenseUrl = license?.url
33+
? license?.url
34+
: license?.identifier
35+
? `https://spdx.org/licenses/${license?.identifier}.html`
36+
: undefined;
37+
2938
const licenseLink =
3039
license?.name && licenseUrl
3140
? `[${license.name}](${licenseUrl})`
3241
: license?.identifier && licenseUrl
3342
? `[${license?.identifier}](${licenseUrl})`
34-
: undefined;
43+
: '';
3544
const tosLink = termsOfService ? `[Terms of Service](${termsOfService})` : '';
3645

3746
return contactLink || licenseLink || tosLink ? (

Diff for: packages/elements-core/src/components/Docs/HttpService/HttpService.spec.tsx

+33
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,39 @@ describe('HttpService', () => {
267267
expect(title).toBeInTheDocument();
268268
});
269269

270+
it('should render additional information with SPDX license identifier', () => {
271+
const contact = {
272+
name: 'Developer',
273+
274+
url: 'https://stoplight.io/contact-us/',
275+
};
276+
277+
const license = {
278+
name: 'MIT License',
279+
identifier: 'MIT',
280+
};
281+
282+
render(
283+
<AdditionalInfo id="a" contact={contact} license={license} termsOfService="https://stoplight.io/terms/" />,
284+
);
285+
286+
const licenseLink = screen.getByText('MIT License');
287+
expect(licenseLink).toHaveAttribute('href', 'https://spdx.org/licenses/MIT.html');
288+
});
289+
290+
it('should prefer license URL over SPDX identifier if both are provided', () => {
291+
const license = {
292+
name: 'MIT License',
293+
url: 'https://opensource.org/licenses/MIT',
294+
identifier: 'MIT',
295+
};
296+
297+
render(<AdditionalInfo id="a" license={license} />);
298+
299+
const licenseLink = screen.getByText('MIT License');
300+
expect(licenseLink).toHaveAttribute('href', 'https://opensource.org/licenses/MIT');
301+
});
302+
270303
it('should not render if contact, license, and terms of service do not exist', () => {
271304
render(<AdditionalInfo id="a" />);
272305

Diff for: packages/elements-core/src/components/TryIt/Body/useTextRequestBodyState.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import { useGenerateExampleFromMediaTypeContent } from '../../../utils/exampleGe
1111

1212
export const useTextRequestBodyState = (
1313
mediaTypeContent: IMediaTypeContent | undefined,
14+
skipReadOnly: boolean,
1415
): [string, React.Dispatch<React.SetStateAction<string>>] => {
1516
const initialRequestBody = useGenerateExampleFromMediaTypeContent(mediaTypeContent, undefined, {
16-
skipReadOnly: true,
17+
skipReadOnly,
1718
});
1819

1920
const [textRequestBody, setTextRequestBody] = React.useState<string>(initialRequestBody);

Diff for: packages/elements-core/src/components/TryIt/TryIt.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,10 @@ export const TryIt: React.FC<TryItProps> = ({
9898
const [bodyParameterValues, setBodyParameterValues, isAllowedEmptyValues, setAllowedEmptyValues, formDataState] =
9999
useBodyParameterState(mediaTypeContent);
100100

101-
const [textRequestBody, setTextRequestBody] = useTextRequestBodyState(mediaTypeContent);
101+
const [textRequestBody, setTextRequestBody] = useTextRequestBodyState(
102+
mediaTypeContent,
103+
!isHttpWebhookOperation(httpOperation),
104+
);
102105

103106
const [operationAuthValue, setOperationAuthValue, setCurrentScheme] = usePersistedSecuritySchemeWithValues();
104107

0 commit comments

Comments
 (0)