Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/npm_and_yarn/types/node-22.5.4
Browse files Browse the repository at this point in the history
  • Loading branch information
mnaumanali94 authored Nov 5, 2024
2 parents 36b43ad + d6358d2 commit 479d7b6
Show file tree
Hide file tree
Showing 15 changed files with 451 additions and 275 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"lerna": "^7.4.2",
"postcss": "8.4.43",
"postcss-cli": "8.3.1",
"postcss-import": "14.0.2",
"postcss-import": "16.1.0",
"postcss-loader": "8.1.1",
"prettier": "2.8.8",
"process": "0.11.10",
Expand All @@ -68,7 +68,8 @@
"resolutions": {
"fast-xml-parser": "4.4.1",
"tar": "6.2.1",
"micromatch": "4.0.8"
"micromatch": "4.0.8",
"@stoplight/react-error-boundary": "3.0.0"
},
"scripts": {
"demo": "yarn workspace @stoplight/elements-demo",
Expand Down
2 changes: 1 addition & 1 deletion packages/elements-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@stoplight/elements-core",
"version": "8.4.3",
"version": "8.4.7",
"sideEffects": [
"web-components.min.js",
"src/web-components/**",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { SectionSubtitle } from '../Sections';
export interface BodyProps {
body: IHttpOperationRequestBody;
onChange?: (requestBodyIndex: number) => void;
isHttpWebhookOperation?: boolean;
}

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

export const Body = ({ body, onChange }: BodyProps) => {
export const Body = ({ body, onChange, isHttpWebhookOperation = false }: BodyProps) => {
const [refResolver, maxRefDepth] = useSchemaInlineRefResolver();
const [chosenContent, setChosenContent] = React.useState(0);
const { nodeHasChanged, renderExtensionAddon } = useOptionsCtx();
Expand Down Expand Up @@ -61,13 +62,12 @@ export const Body = ({ body, onChange }: BodyProps) => {
<NodeAnnotation change={descriptionChanged} />
</Box>
)}

{isJSONSchema(schema) && (
<JsonSchemaViewer
resolveRef={refResolver}
maxRefDepth={maxRefDepth}
schema={getOriginalObject(schema)}
viewMode="write"
viewMode={isHttpWebhookOperation ? 'standalone' : 'write'}
renderRootTreeLines
nodeHasChanged={nodeHasChanged}
renderExtensionAddon={renderExtensionAddon}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,13 @@ const HttpOperationComponent = React.memo<HttpOperationProps>(
<NodeAnnotation change={descriptionChanged} />
</Box>
)}

<NodeVendorExtensions data={data} />

<Request
onChange={setTextRequestBodyIndex}
operation={data}
hideSecurityInfo={layoutOptions?.hideSecurityInfo}
isHttpWebhookOperation={isHttpWebhookOperation(data)}
/>

{data.responses && (
<Responses
responses={data.responses}
Expand All @@ -112,9 +110,7 @@ const HttpOperationComponent = React.memo<HttpOperationProps>(
isCompact={isCompact}
/>
)}

{data.callbacks?.length ? <Callbacks callbacks={data.callbacks} isCompact={isCompact} /> : null}

{isCompact && tryItPanel}
</VStack>
);
Expand Down Expand Up @@ -159,13 +155,13 @@ function MethodPathInner({ method, path, chosenServerUrl }: MethodPathProps & {

const pathElem = (
<Flex overflowX="hidden" fontSize="lg" userSelect="all">
<Box dir="rtl" color="muted" textOverflow="truncate" overflowX="hidden">
<Box as="span" dir="ltr" style={{ unicodeBidi: 'bidi-override' }}>
<Box dir="rtl" textOverflow="truncate" overflowX="hidden">
<Box as="span" dir="ltr" color="muted" style={{ unicodeBidi: 'bidi-override' }}>
{chosenServerUrl}
</Box>
</Box>
<Box fontWeight="semibold" flex={1}>
{path}
<Box as="span" fontWeight="semibold" flex={1}>
{path}
</Box>
</Box>
</Flex>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ interface IRequestProps {
operation: IHttpEndpointOperation;
hideSecurityInfo?: boolean;
onChange?: (requestBodyIndex: number) => void;
isHttpWebhookOperation?: boolean;
}

export const Request: React.FunctionComponent<IRequestProps> = ({
Expand All @@ -33,6 +34,7 @@ export const Request: React.FunctionComponent<IRequestProps> = ({
},
hideSecurityInfo,
onChange,
isHttpWebhookOperation = false,
}) => {
if (!request || typeof request !== 'object') return null;

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

{body && <Body onChange={onChange} body={body} />}
{body && <Body onChange={onChange} body={body} isHttpWebhookOperation={isHttpWebhookOperation} />}
</VStack>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ const meta: Meta<typeof AdditionalInfo> = {
export default meta;
type Story = StoryObj<typeof AdditionalInfo>;

export const LicenseNameAndURL: Story = {
name: 'License Name with URL',
// Story when only the license URL is provided
export const LicenseWithOnlyURL: Story = {
name: 'License with only URL',
args: {
id: 'id',
license: {
Expand All @@ -21,8 +22,9 @@ export const LicenseNameAndURL: Story = {
},
};

export const LicenseNameAndIdentifier: Story = {
name: 'License Name and Identifier',
// Story when only the license identifier is provided
export const LicenseWithOnlyIdentifier: Story = {
name: 'License with only Identifier',
args: {
id: 'id',
license: {
Expand All @@ -32,8 +34,9 @@ export const LicenseNameAndIdentifier: Story = {
},
};

export const LicenseIdentifierAndNameAndUrl: Story = {
name: 'License Identifier, Name and URL',
// Story when both the license URL and identifier are provided (URL should take precedence)
export const LicenseWithURLAndIdentifier: Story = {
name: 'License with URL and Identifier (URL takes precedence)',
args: {
id: 'id',
license: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,23 @@ export const AdditionalInfo: React.FC<AdditionalInfoProps> = ({ id, termsOfServi
: '';

//use spdx to look up url for license identifier if available
const licenseUrl =
license?.url || license?.identifier ? `https://spdx.org/licenses/${license?.identifier}.html` : undefined;
// The licenseUrl is determined based on the mutual exclusivity of the `url` and `identifier` fields.
// If a `license.url` is provided, it takes precedence over the `license.identifier`.
// This is because the OpenAPI specification defines `url` and `identifier` as mutually exclusive fields,
// meaning you should use either one or the other, but not both. If both are provided, the `url` should be used.
// See: https://spec.openapis.org/oas/latest.html#license-object
const licenseUrl = license?.url
? license?.url
: license?.identifier
? `https://spdx.org/licenses/${license?.identifier}.html`
: undefined;

const licenseLink =
license?.name && licenseUrl
? `[${license.name}](${licenseUrl})`
: license?.identifier && licenseUrl
? `[${license?.identifier}](${licenseUrl})`
: undefined;
: '';
const tosLink = termsOfService ? `[Terms of Service](${termsOfService})` : '';

return contactLink || licenseLink || tosLink ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,39 @@ describe('HttpService', () => {
expect(title).toBeInTheDocument();
});

it('should render additional information with SPDX license identifier', () => {
const contact = {
name: 'Developer',
email: '[email protected]',
url: 'https://stoplight.io/contact-us/',
};

const license = {
name: 'MIT License',
identifier: 'MIT',
};

render(
<AdditionalInfo id="a" contact={contact} license={license} termsOfService="https://stoplight.io/terms/" />,
);

const licenseLink = screen.getByText('MIT License');
expect(licenseLink).toHaveAttribute('href', 'https://spdx.org/licenses/MIT.html');
});

it('should prefer license URL over SPDX identifier if both are provided', () => {
const license = {
name: 'MIT License',
url: 'https://opensource.org/licenses/MIT',
identifier: 'MIT',
};

render(<AdditionalInfo id="a" license={license} />);

const licenseLink = screen.getByText('MIT License');
expect(licenseLink).toHaveAttribute('href', 'https://opensource.org/licenses/MIT');
});

it('should not render if contact, license, and terms of service do not exist', () => {
render(<AdditionalInfo id="a" />);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import { useGenerateExampleFromMediaTypeContent } from '../../../utils/exampleGe

export const useTextRequestBodyState = (
mediaTypeContent: IMediaTypeContent | undefined,
skipReadOnly: boolean,
): [string, React.Dispatch<React.SetStateAction<string>>] => {
const initialRequestBody = useGenerateExampleFromMediaTypeContent(mediaTypeContent, undefined, {
skipReadOnly: true,
skipReadOnly,
});

const [textRequestBody, setTextRequestBody] = React.useState<string>(initialRequestBody);
Expand Down
5 changes: 4 additions & 1 deletion packages/elements-core/src/components/TryIt/TryIt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ export const TryIt: React.FC<TryItProps> = ({
const [bodyParameterValues, setBodyParameterValues, isAllowedEmptyValues, setAllowedEmptyValues, formDataState] =
useBodyParameterState(mediaTypeContent);

const [textRequestBody, setTextRequestBody] = useTextRequestBodyState(mediaTypeContent);
const [textRequestBody, setTextRequestBody] = useTextRequestBodyState(
mediaTypeContent,
!isHttpWebhookOperation(httpOperation),
);

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

Expand Down
Loading

0 comments on commit 479d7b6

Please sign in to comment.