mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 01:53:26 +00:00
Highlight discriminator properties in oneOf, allOf, anyOf objects (#3691)
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"@gitbook/react-openapi": patch
|
||||||
|
"gitbook": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Highlight discriminator properties in oneOf, allOf, anyOf objects
|
||||||
@@ -192,7 +192,7 @@
|
|||||||
.openapi-schema-name {
|
.openapi-schema-name {
|
||||||
/* To make double click on the property name select only the name,
|
/* To make double click on the property name select only the name,
|
||||||
we disable selection on the parent and re-enable it on the children. */
|
we disable selection on the parent and re-enable it on the children. */
|
||||||
@apply select-none text-sm text-balance *:whitespace-nowrap flex flex-wrap gap-y-1.5 gap-x-2.5;
|
@apply select-none text-sm text-balance *:whitespace-nowrap flex flex-wrap gap-y-1.5 gap-x-2.5 items-center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.openapi-schema-name .openapi-deprecated {
|
.openapi-schema-name .openapi-deprecated {
|
||||||
@@ -207,6 +207,10 @@
|
|||||||
@apply line-through opacity-9;
|
@apply line-through opacity-9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.openapi-schema-discriminator {
|
||||||
|
@apply text-primary-subtle/9 text-[0.813rem] lowercase;
|
||||||
|
}
|
||||||
|
|
||||||
.openapi-schema-required {
|
.openapi-schema-required {
|
||||||
@apply text-warning-subtle text-[0.813rem] lowercase;
|
@apply text-warning-subtle text-[0.813rem] lowercase;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,17 +22,20 @@ describe('getSchemaAlternatives', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
).toEqual([
|
).toEqual({
|
||||||
{
|
type: 'oneOf',
|
||||||
type: 'number',
|
schemas: [
|
||||||
},
|
{
|
||||||
{
|
type: 'number',
|
||||||
type: 'boolean',
|
},
|
||||||
},
|
{
|
||||||
{
|
type: 'boolean',
|
||||||
type: 'string',
|
},
|
||||||
},
|
{
|
||||||
]);
|
type: 'string',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('merges string enum', () => {
|
it('merges string enum', () => {
|
||||||
@@ -54,13 +57,16 @@ describe('getSchemaAlternatives', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
).toEqual([
|
).toEqual({
|
||||||
{
|
type: 'oneOf',
|
||||||
type: 'string',
|
schemas: [
|
||||||
enum: ['a', 'b', 'c', 'd'],
|
{
|
||||||
nullable: true,
|
type: 'string',
|
||||||
},
|
enum: ['a', 'b', 'c', 'd'],
|
||||||
]);
|
nullable: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('merges objects with allOf', () => {
|
it('merges objects with allOf', () => {
|
||||||
@@ -93,26 +99,29 @@ describe('getSchemaAlternatives', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
).toEqual([
|
).toEqual({
|
||||||
{
|
type: 'allOf',
|
||||||
type: 'object',
|
schemas: [
|
||||||
properties: {
|
{
|
||||||
name: {
|
type: 'object',
|
||||||
type: 'string',
|
properties: {
|
||||||
},
|
name: {
|
||||||
map: {
|
type: 'string',
|
||||||
type: 'string',
|
},
|
||||||
},
|
map: {
|
||||||
description: {
|
type: 'string',
|
||||||
type: 'string',
|
},
|
||||||
},
|
description: {
|
||||||
externalId: {
|
type: 'string',
|
||||||
type: 'string',
|
},
|
||||||
|
externalId: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
required: ['name', 'map', 'externalId'],
|
||||||
},
|
},
|
||||||
required: ['name', 'map', 'externalId'],
|
],
|
||||||
},
|
});
|
||||||
]);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not flatten oneOf and allOf', () => {
|
it('should not flatten oneOf and allOf', () => {
|
||||||
@@ -134,21 +143,24 @@ describe('getSchemaAlternatives', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
).toEqual([
|
).toEqual({
|
||||||
{
|
type: 'oneOf',
|
||||||
allOf: [
|
schemas: [
|
||||||
{
|
{
|
||||||
type: 'number',
|
allOf: [
|
||||||
},
|
{
|
||||||
{
|
type: 'number',
|
||||||
type: 'boolean',
|
},
|
||||||
},
|
{
|
||||||
],
|
type: 'boolean',
|
||||||
},
|
},
|
||||||
{
|
],
|
||||||
type: 'string',
|
},
|
||||||
},
|
{
|
||||||
]);
|
type: 'string',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should stop at circular references', () => {
|
it('should stop at circular references', () => {
|
||||||
@@ -162,11 +174,14 @@ describe('getSchemaAlternatives', () => {
|
|||||||
|
|
||||||
a.anyOf?.push(a);
|
a.anyOf?.push(a);
|
||||||
|
|
||||||
expect(getSchemaAlternatives(a)).toEqual([
|
expect(getSchemaAlternatives(a)).toEqual({
|
||||||
{
|
type: 'anyOf',
|
||||||
type: 'string',
|
schemas: [
|
||||||
},
|
{
|
||||||
a,
|
type: 'string',
|
||||||
]);
|
},
|
||||||
|
a,
|
||||||
|
],
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ type CircularRefsIds = Map<OpenAPIV3.SchemaObject, string>;
|
|||||||
export interface OpenAPISchemaPropertyEntry {
|
export interface OpenAPISchemaPropertyEntry {
|
||||||
propertyName?: string;
|
propertyName?: string;
|
||||||
required?: boolean | null;
|
required?: boolean | null;
|
||||||
|
isDiscriminatorProperty?: boolean;
|
||||||
schema: OpenAPIV3.SchemaObject;
|
schema: OpenAPIV3.SchemaObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,17 +70,19 @@ function OpenAPISchemaProperty(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alternatives) {
|
if (alternatives?.schemas) {
|
||||||
|
const { schemas, discriminator } = alternatives;
|
||||||
return (
|
return (
|
||||||
<div className="openapi-schema-alternatives">
|
<div className="openapi-schema-alternatives">
|
||||||
{alternatives.map((alternativeSchema, index) => (
|
{schemas.map((alternativeSchema, index) => (
|
||||||
<div key={index} className="openapi-schema-alternative">
|
<div key={index} className="openapi-schema-alternative">
|
||||||
<OpenAPISchemaAlternative
|
<OpenAPISchemaAlternative
|
||||||
schema={alternativeSchema}
|
schema={alternativeSchema}
|
||||||
|
discriminator={discriminator}
|
||||||
circularRefs={circularRefs}
|
circularRefs={circularRefs}
|
||||||
context={context}
|
context={context}
|
||||||
/>
|
/>
|
||||||
{index < alternatives.length - 1 ? (
|
{index < schemas.length - 1 ? (
|
||||||
<OpenAPISchemaAlternativeSeparator
|
<OpenAPISchemaAlternativeSeparator
|
||||||
schema={schema}
|
schema={schema}
|
||||||
context={context}
|
context={context}
|
||||||
@@ -228,11 +231,12 @@ export function OpenAPIRootSchemaFromServer(props: {
|
|||||||
*/
|
*/
|
||||||
function OpenAPISchemaAlternative(props: {
|
function OpenAPISchemaAlternative(props: {
|
||||||
schema: OpenAPIV3.SchemaObject;
|
schema: OpenAPIV3.SchemaObject;
|
||||||
|
discriminator: OpenAPIV3.DiscriminatorObject | undefined;
|
||||||
circularRefs: CircularRefsIds;
|
circularRefs: CircularRefsIds;
|
||||||
context: OpenAPIClientContext;
|
context: OpenAPIClientContext;
|
||||||
}) {
|
}) {
|
||||||
const { schema, circularRefs, context } = props;
|
const { schema, discriminator, circularRefs, context } = props;
|
||||||
const properties = getSchemaProperties(schema);
|
const properties = getSchemaProperties(schema, discriminator);
|
||||||
|
|
||||||
return properties?.length ? (
|
return properties?.length ? (
|
||||||
<OpenAPIDisclosure
|
<OpenAPIDisclosure
|
||||||
@@ -359,7 +363,7 @@ export function OpenAPISchemaPresentation(props: {
|
|||||||
context: OpenAPIClientContext;
|
context: OpenAPIClientContext;
|
||||||
}) {
|
}) {
|
||||||
const {
|
const {
|
||||||
property: { schema, propertyName, required },
|
property: { schema, propertyName, required, isDiscriminatorProperty },
|
||||||
context,
|
context,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
@@ -372,6 +376,7 @@ export function OpenAPISchemaPresentation(props: {
|
|||||||
schema={schema}
|
schema={schema}
|
||||||
type={getSchemaTitle(schema)}
|
type={getSchemaTitle(schema)}
|
||||||
propertyName={propertyName}
|
propertyName={propertyName}
|
||||||
|
isDiscriminatorProperty={isDiscriminatorProperty}
|
||||||
required={required}
|
required={required}
|
||||||
context={context}
|
context={context}
|
||||||
/>
|
/>
|
||||||
@@ -414,13 +419,19 @@ export function OpenAPISchemaPresentation(props: {
|
|||||||
/**
|
/**
|
||||||
* Get the sub-properties of a schema.
|
* Get the sub-properties of a schema.
|
||||||
*/
|
*/
|
||||||
function getSchemaProperties(schema: OpenAPIV3.SchemaObject): null | OpenAPISchemaPropertyEntry[] {
|
function getSchemaProperties(
|
||||||
|
schema: OpenAPIV3.SchemaObject,
|
||||||
|
discriminator?: OpenAPIV3.DiscriminatorObject | undefined
|
||||||
|
): null | OpenAPISchemaPropertyEntry[] {
|
||||||
// check array AND schema.items as this is sometimes null despite what the type indicates
|
// check array AND schema.items as this is sometimes null despite what the type indicates
|
||||||
if (schema.type === 'array' && schema.items && !checkIsReference(schema.items)) {
|
if (schema.type === 'array' && schema.items && !checkIsReference(schema.items)) {
|
||||||
const items = schema.items;
|
const items = schema.items;
|
||||||
const itemProperties = getSchemaProperties(items);
|
const itemProperties = getSchemaProperties(items);
|
||||||
if (itemProperties) {
|
if (itemProperties) {
|
||||||
return itemProperties;
|
return itemProperties.map((prop) => ({
|
||||||
|
...prop,
|
||||||
|
isDiscriminatorProperty: discriminator?.propertyName === prop.propertyName,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the items are a primitive type, we don't need to display them
|
// If the items are a primitive type, we don't need to display them
|
||||||
@@ -451,6 +462,7 @@ function getSchemaProperties(schema: OpenAPIV3.SchemaObject): null | OpenAPISche
|
|||||||
required: Array.isArray(schema.required)
|
required: Array.isArray(schema.required)
|
||||||
? schema.required.includes(propertyName)
|
? schema.required.includes(propertyName)
|
||||||
: undefined,
|
: undefined,
|
||||||
|
isDiscriminatorProperty: discriminator?.propertyName === propertyName,
|
||||||
schema: propertySchema,
|
schema: propertySchema,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -471,14 +483,20 @@ function getSchemaProperties(schema: OpenAPIV3.SchemaObject): null | OpenAPISche
|
|||||||
|
|
||||||
type AlternativeType = 'oneOf' | 'allOf' | 'anyOf';
|
type AlternativeType = 'oneOf' | 'allOf' | 'anyOf';
|
||||||
|
|
||||||
|
type SchemaAlternatives = {
|
||||||
|
type: AlternativeType;
|
||||||
|
schemas: OpenAPIV3.SchemaObject[];
|
||||||
|
discriminator?: OpenAPIV3.DiscriminatorObject;
|
||||||
|
} | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the alternatives to display for a schema.
|
* Get the alternatives to display for a schema.
|
||||||
*/
|
*/
|
||||||
export function getSchemaAlternatives(
|
export function getSchemaAlternatives(
|
||||||
schema: OpenAPIV3.SchemaObject,
|
schema: OpenAPIV3.SchemaObject,
|
||||||
ancestors: Set<OpenAPIV3.SchemaObject> = new Set()
|
ancestors: Set<OpenAPIV3.SchemaObject> = new Set()
|
||||||
): OpenAPIV3.SchemaObject[] | null {
|
): SchemaAlternatives {
|
||||||
// Search for alternatives in the items property if it exists
|
// Check for nested alternatives in `items`
|
||||||
if (
|
if (
|
||||||
schema.items &&
|
schema.items &&
|
||||||
('oneOf' in schema.items || 'allOf' in schema.items || 'anyOf' in schema.items)
|
('oneOf' in schema.items || 'allOf' in schema.items || 'anyOf' in schema.items)
|
||||||
@@ -487,20 +505,21 @@ export function getSchemaAlternatives(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const alternatives:
|
const alternatives:
|
||||||
| [AlternativeType, (OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject)[]]
|
| [
|
||||||
|
AlternativeType,
|
||||||
|
(OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject)[],
|
||||||
|
OpenAPIV3.DiscriminatorObject?,
|
||||||
|
]
|
||||||
| null = (() => {
|
| null = (() => {
|
||||||
if (schema.anyOf) {
|
if (schema.anyOf) {
|
||||||
return ['anyOf', schema.anyOf];
|
return ['anyOf', schema.anyOf, schema.discriminator];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schema.oneOf) {
|
if (schema.oneOf) {
|
||||||
return ['oneOf', schema.oneOf];
|
return ['oneOf', schema.oneOf, schema.discriminator];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schema.allOf) {
|
if (schema.allOf) {
|
||||||
return ['allOf', schema.allOf];
|
return ['allOf', schema.allOf, schema.discriminator];
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
@@ -508,11 +527,17 @@ export function getSchemaAlternatives(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [type, schemas] = alternatives;
|
const [type, schemas, discriminator] = alternatives;
|
||||||
return mergeAlternatives(
|
|
||||||
|
return {
|
||||||
type,
|
type,
|
||||||
flattenAlternatives(type, schemas, new Set(ancestors).add(schema))
|
schemas:
|
||||||
);
|
mergeAlternatives(
|
||||||
|
type,
|
||||||
|
flattenAlternatives(type, schemas, new Set(ancestors).add(schema))
|
||||||
|
) ?? [],
|
||||||
|
discriminator,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -610,10 +635,10 @@ function flattenAlternatives(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (schemaOrRef[alternativeType] && !ancestors.has(schemaOrRef)) {
|
if (schemaOrRef[alternativeType] && !ancestors.has(schemaOrRef)) {
|
||||||
const schemas = getSchemaAlternatives(schemaOrRef, ancestors);
|
const alternatives = getSchemaAlternatives(schemaOrRef, ancestors);
|
||||||
if (schemas) {
|
if (alternatives?.schemas) {
|
||||||
acc.push(
|
acc.push(
|
||||||
...schemas.map((schema) => ({
|
...alternatives.schemas.map((schema) => ({
|
||||||
...schema,
|
...schema,
|
||||||
required: mergeRequiredFields(schema, latestAncestor),
|
required: mergeRequiredFields(schema, latestAncestor),
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ interface OpenAPISchemaNameProps {
|
|||||||
schema?: OpenAPIV3.SchemaObject;
|
schema?: OpenAPIV3.SchemaObject;
|
||||||
propertyName?: string | React.JSX.Element;
|
propertyName?: string | React.JSX.Element;
|
||||||
required?: boolean | null;
|
required?: boolean | null;
|
||||||
|
isDiscriminatorProperty?: boolean;
|
||||||
type?: string;
|
type?: string;
|
||||||
context: OpenAPIClientContext;
|
context: OpenAPIClientContext;
|
||||||
}
|
}
|
||||||
@@ -16,7 +17,7 @@ interface OpenAPISchemaNameProps {
|
|||||||
* It includes the property name, type, required and deprecated status.
|
* It includes the property name, type, required and deprecated status.
|
||||||
*/
|
*/
|
||||||
export function OpenAPISchemaName(props: OpenAPISchemaNameProps) {
|
export function OpenAPISchemaName(props: OpenAPISchemaNameProps) {
|
||||||
const { schema, type, propertyName, required, context } = props;
|
const { schema, type, propertyName, required, isDiscriminatorProperty, context } = props;
|
||||||
|
|
||||||
const additionalItems = schema && getAdditionalItems(schema, context);
|
const additionalItems = schema && getAdditionalItems(schema, context);
|
||||||
|
|
||||||
@@ -27,9 +28,18 @@ export function OpenAPISchemaName(props: OpenAPISchemaNameProps) {
|
|||||||
{propertyName}
|
{propertyName}
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
|
{isDiscriminatorProperty ? (
|
||||||
|
<span className="openapi-schema-discriminator">
|
||||||
|
{t(context.translation, 'discriminator')}
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
{type || additionalItems ? (
|
{type || additionalItems ? (
|
||||||
<span>
|
<span>
|
||||||
{type ? <span className="openapi-schema-type">{type}</span> : null}
|
{schema?.const ? (
|
||||||
|
<span className="openapi-schema-type">const: {schema?.const}</span>
|
||||||
|
) : type ? (
|
||||||
|
<span className="openapi-schema-type">{type}</span>
|
||||||
|
) : null}
|
||||||
{additionalItems ? (
|
{additionalItems ? (
|
||||||
<span className="openapi-schema-type">{additionalItems}</span>
|
<span className="openapi-schema-type">{additionalItems}</span>
|
||||||
) : null}
|
) : null}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const de = {
|
|||||||
stability_experimental: 'Experimentell',
|
stability_experimental: 'Experimentell',
|
||||||
stability_alpha: 'Alpha',
|
stability_alpha: 'Alpha',
|
||||||
stability_beta: 'Beta',
|
stability_beta: 'Beta',
|
||||||
|
discriminator: 'Diskriminator',
|
||||||
copy_to_clipboard: 'In die Zwischenablage kopieren',
|
copy_to_clipboard: 'In die Zwischenablage kopieren',
|
||||||
copied: 'Kopiert',
|
copied: 'Kopiert',
|
||||||
no_content: 'Kein Inhalt',
|
no_content: 'Kein Inhalt',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const en = {
|
|||||||
stability_experimental: 'Experimental',
|
stability_experimental: 'Experimental',
|
||||||
stability_alpha: 'Alpha',
|
stability_alpha: 'Alpha',
|
||||||
stability_beta: 'Beta',
|
stability_beta: 'Beta',
|
||||||
|
discriminator: 'Discriminator',
|
||||||
copy_to_clipboard: 'Copy to clipboard',
|
copy_to_clipboard: 'Copy to clipboard',
|
||||||
copied: 'Copied',
|
copied: 'Copied',
|
||||||
no_content: 'No content',
|
no_content: 'No content',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const es = {
|
|||||||
stability_experimental: 'Experimental',
|
stability_experimental: 'Experimental',
|
||||||
stability_alpha: 'Alfa',
|
stability_alpha: 'Alfa',
|
||||||
stability_beta: 'Beta',
|
stability_beta: 'Beta',
|
||||||
|
discriminator: 'Discriminador',
|
||||||
copy_to_clipboard: 'Copiar al portapapeles',
|
copy_to_clipboard: 'Copiar al portapapeles',
|
||||||
copied: 'Copiado',
|
copied: 'Copiado',
|
||||||
no_content: 'Sin contenido',
|
no_content: 'Sin contenido',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const fr = {
|
|||||||
stability_experimental: 'Expérimental',
|
stability_experimental: 'Expérimental',
|
||||||
stability_alpha: 'Alpha',
|
stability_alpha: 'Alpha',
|
||||||
stability_beta: 'Bêta',
|
stability_beta: 'Bêta',
|
||||||
|
discriminator: 'Discriminateur',
|
||||||
copy_to_clipboard: 'Copier dans le presse-papiers',
|
copy_to_clipboard: 'Copier dans le presse-papiers',
|
||||||
copied: 'Copié',
|
copied: 'Copié',
|
||||||
no_content: 'Aucun contenu',
|
no_content: 'Aucun contenu',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const ja = {
|
|||||||
stability_experimental: '実験的',
|
stability_experimental: '実験的',
|
||||||
stability_alpha: 'アルファ',
|
stability_alpha: 'アルファ',
|
||||||
stability_beta: 'ベータ',
|
stability_beta: 'ベータ',
|
||||||
|
discriminator: '識別子',
|
||||||
copy_to_clipboard: 'クリップボードにコピー',
|
copy_to_clipboard: 'クリップボードにコピー',
|
||||||
copied: 'コピー済み',
|
copied: 'コピー済み',
|
||||||
no_content: 'コンテンツなし',
|
no_content: 'コンテンツなし',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const nl = {
|
|||||||
stability_experimental: 'Experimenteel',
|
stability_experimental: 'Experimenteel',
|
||||||
stability_alpha: 'Alfa',
|
stability_alpha: 'Alfa',
|
||||||
stability_beta: 'Bèta',
|
stability_beta: 'Bèta',
|
||||||
|
discriminator: 'Discriminator',
|
||||||
copy_to_clipboard: 'Kopiëren naar klembord',
|
copy_to_clipboard: 'Kopiëren naar klembord',
|
||||||
copied: 'Gekopieerd',
|
copied: 'Gekopieerd',
|
||||||
no_content: 'Geen inhoud',
|
no_content: 'Geen inhoud',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const no = {
|
|||||||
stability_experimental: 'Eksperimentell',
|
stability_experimental: 'Eksperimentell',
|
||||||
stability_alpha: 'Alfa',
|
stability_alpha: 'Alfa',
|
||||||
stability_beta: 'Beta',
|
stability_beta: 'Beta',
|
||||||
|
discriminator: 'Diskriminator',
|
||||||
copy_to_clipboard: 'Kopier til utklippstavle',
|
copy_to_clipboard: 'Kopier til utklippstavle',
|
||||||
copied: 'Kopiert',
|
copied: 'Kopiert',
|
||||||
no_content: 'Ingen innhold',
|
no_content: 'Ingen innhold',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const pt_br = {
|
|||||||
stability_experimental: 'Experimental',
|
stability_experimental: 'Experimental',
|
||||||
stability_alpha: 'Alfa',
|
stability_alpha: 'Alfa',
|
||||||
stability_beta: 'Beta',
|
stability_beta: 'Beta',
|
||||||
|
discriminator: 'Discriminador',
|
||||||
copy_to_clipboard: 'Copiar para a área de transferência',
|
copy_to_clipboard: 'Copiar para a área de transferência',
|
||||||
copied: 'Copiado',
|
copied: 'Copiado',
|
||||||
no_content: 'Sem conteúdo',
|
no_content: 'Sem conteúdo',
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const zh = {
|
|||||||
stability_experimental: '实验性',
|
stability_experimental: '实验性',
|
||||||
stability_alpha: 'Alpha',
|
stability_alpha: 'Alpha',
|
||||||
stability_beta: 'Beta',
|
stability_beta: 'Beta',
|
||||||
|
discriminator: '判别器',
|
||||||
copy_to_clipboard: '复制到剪贴板',
|
copy_to_clipboard: '复制到剪贴板',
|
||||||
copied: '已复制',
|
copied: '已复制',
|
||||||
no_content: '无内容',
|
no_content: '无内容',
|
||||||
|
|||||||
Reference in New Issue
Block a user