Skip to content

Commit

Permalink
I18n: ReflectionKind
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerrit0 committed Feb 18, 2024
1 parent 41a60ee commit 37b9eb7
Show file tree
Hide file tree
Showing 11 changed files with 216 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/lib/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export class Application extends ChildableComponent<
/**
* Proxy based shortcuts for internationalization keys.
*/
i18n = this.internationalization.createProxy();
i18n = this.internationalization.proxy;

options = new Options();

Expand Down
35 changes: 34 additions & 1 deletion src/lib/converter/plugins/GroupPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,28 @@ import { getSortFunction } from "../../utils/sort";
import { Option, removeIf } from "../../utils";
import { Comment } from "../../models";

// Same as the defaultKindSortOrder in sort.ts
const defaultGroupOrder = [
ReflectionKind.Reference,
// project is never a child so never added to a group
ReflectionKind.Module,
ReflectionKind.Namespace,
ReflectionKind.Enum,
ReflectionKind.EnumMember,
ReflectionKind.Class,
ReflectionKind.Interface,
ReflectionKind.TypeAlias,

ReflectionKind.Constructor,
ReflectionKind.Property,
ReflectionKind.Variable,
ReflectionKind.Function,
ReflectionKind.Accessor,
ReflectionKind.Method,

// others are never added to groups
];

/**
* A handler that sorts and groups the found reflections in the resolving phase.
*
Expand Down Expand Up @@ -45,6 +67,13 @@ export class GroupPlugin extends ConverterComponent {
this.application.options,
);
GroupPlugin.WEIGHTS = this.groupOrder;
if (GroupPlugin.WEIGHTS.length === 0) {
GroupPlugin.WEIGHTS = defaultGroupOrder.map((kind) =>
this.application.internationalization.kindPluralString(
kind,
),
);
}
},
[Converter.EVENT_RESOLVE_END]: this.onEndResolve,
},
Expand Down Expand Up @@ -138,7 +167,11 @@ export class GroupPlugin extends ConverterComponent {

groups.delete("");
if (groups.size === 0) {
groups.add(ReflectionKind.pluralString(reflection.kind));
groups.add(
this.application.internationalization.kindPluralString(
reflection.kind,
),
);
}

for (const group of groups) {
Expand Down
117 changes: 109 additions & 8 deletions src/lib/internationalization/internationalization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from "./translatable";
import { readdirSync } from "fs";
import { join } from "path";
import { ReflectionKind } from "../models/reflections/kind";

/**
* ### What is translatable?
Expand Down Expand Up @@ -110,6 +111,108 @@ export class Internationalization {
}) as TranslatedString;
}

kindSingularString(kind: ReflectionKind): TranslatedString {
switch (kind) {
case ReflectionKind.Project:
return this.proxy.kind_project();
case ReflectionKind.Module:
return this.proxy.kind_module();
case ReflectionKind.Namespace:
return this.proxy.kind_namespace();
case ReflectionKind.Enum:
return this.proxy.kind_enum();
case ReflectionKind.EnumMember:
return this.proxy.kind_enum_member();
case ReflectionKind.Variable:
return this.proxy.kind_variable();
case ReflectionKind.Function:
return this.proxy.kind_function();
case ReflectionKind.Class:
return this.proxy.kind_class();
case ReflectionKind.Interface:
return this.proxy.kind_interface();
case ReflectionKind.Constructor:
return this.proxy.kind_constructor();
case ReflectionKind.Property:
return this.proxy.kind_property();
case ReflectionKind.Method:
return this.proxy.kind_method();
case ReflectionKind.CallSignature:
return this.proxy.kind_call_signature();
case ReflectionKind.IndexSignature:
return this.proxy.kind_index_signature();
case ReflectionKind.ConstructorSignature:
return this.proxy.kind_constructor_signature();
case ReflectionKind.Parameter:
return this.proxy.kind_parameter();
case ReflectionKind.TypeLiteral:
return this.proxy.kind_type_literal();
case ReflectionKind.TypeParameter:
return this.proxy.kind_type_parameter();
case ReflectionKind.Accessor:
return this.proxy.kind_accessor();
case ReflectionKind.GetSignature:
return this.proxy.kind_get_signature();
case ReflectionKind.SetSignature:
return this.proxy.kind_set_signature();
case ReflectionKind.TypeAlias:
return this.proxy.kind_type_alias();
case ReflectionKind.Reference:
return this.proxy.kind_reference();
}
}

kindPluralString(kind: ReflectionKind): TranslatedString {
switch (kind) {
case ReflectionKind.Project:
return this.proxy.kind_plural_project();
case ReflectionKind.Module:
return this.proxy.kind_plural_module();
case ReflectionKind.Namespace:
return this.proxy.kind_plural_namespace();
case ReflectionKind.Enum:
return this.proxy.kind_plural_enum();
case ReflectionKind.EnumMember:
return this.proxy.kind_plural_enum_member();
case ReflectionKind.Variable:
return this.proxy.kind_plural_variable();
case ReflectionKind.Function:
return this.proxy.kind_plural_function();
case ReflectionKind.Class:
return this.proxy.kind_plural_class();
case ReflectionKind.Interface:
return this.proxy.kind_plural_interface();
case ReflectionKind.Constructor:
return this.proxy.kind_plural_constructor();
case ReflectionKind.Property:
return this.proxy.kind_plural_property();
case ReflectionKind.Method:
return this.proxy.kind_plural_method();
case ReflectionKind.CallSignature:
return this.proxy.kind_plural_call_signature();
case ReflectionKind.IndexSignature:
return this.proxy.kind_plural_index_signature();
case ReflectionKind.ConstructorSignature:
return this.proxy.kind_plural_constructor_signature();
case ReflectionKind.Parameter:
return this.proxy.kind_plural_parameter();
case ReflectionKind.TypeLiteral:
return this.proxy.kind_plural_type_literal();
case ReflectionKind.TypeParameter:
return this.proxy.kind_plural_type_parameter();
case ReflectionKind.Accessor:
return this.proxy.kind_plural_accessor();
case ReflectionKind.GetSignature:
return this.proxy.kind_plural_get_signature();
case ReflectionKind.SetSignature:
return this.proxy.kind_plural_set_signature();
case ReflectionKind.TypeAlias:
return this.proxy.kind_plural_type_alias();
case ReflectionKind.Reference:
return this.proxy.kind_plural_reference();
}
}

/**
* Add translations for a string which will be displayed to the user.
*/
Expand Down Expand Up @@ -151,12 +254,10 @@ export class Internationalization {
* method so that renaming a key on the `translatable` object that contains
* all of the default translations will automatically update usage locations.
*/
createProxy(): TranslationProxy {
return new Proxy({} as TranslationProxy, {
get: ({}, key) => {
return (...args: string[]) =>
this.translate(key as never, ...(args as never));
},
});
}
proxy: TranslationProxy = new Proxy({} as TranslationProxy, {
get: ({}, key) => {

Check failure on line 258 in src/lib/internationalization/internationalization.ts

View workflow job for this annotation

GitHub Actions / Node 18 Windows

Unexpected empty object pattern

Check failure on line 258 in src/lib/internationalization/internationalization.ts

View workflow job for this annotation

GitHub Actions / Node 16

Unexpected empty object pattern

Check failure on line 258 in src/lib/internationalization/internationalization.ts

View workflow job for this annotation

GitHub Actions / Node 18

Unexpected empty object pattern

Check failure on line 258 in src/lib/internationalization/internationalization.ts

View workflow job for this annotation

GitHub Actions / Node 20

Unexpected empty object pattern
return (...args: string[]) =>
this.translate(key as never, ...(args as never));
},
});
}
50 changes: 50 additions & 0 deletions src/lib/internationalization/translatable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,56 @@ export const translatable = {
"A list of reflection kinds that must be documented",
help_validation:
"Specify which validation steps TypeDoc should perform on your generated documentation.",

// ReflectionKind singular translations
kind_project: "Project",
kind_module: "Module",
kind_namespace: "Namespace",
kind_enum: "Enumeration",
kind_enum_member: "Enumeration Member",
kind_variable: "Variable",
kind_function: "Function",
kind_class: "Class",
kind_interface: "Interface",
kind_constructor: "Constructor",
kind_property: "Property",
kind_method: "Method",
kind_call_signature: "Call Signature",
kind_index_signature: "Index Signature",
kind_constructor_signature: "Constructor Signature",
kind_parameter: "Parameter",
kind_type_literal: "Type Literal",
kind_type_parameter: "Type Parameter",
kind_accessor: "Accessor",
kind_get_signature: "Get Signature",
kind_set_signature: "Set Signature",
kind_type_alias: "Type Alias",
kind_reference: "Reference",

// ReflectionKind plural translations
kind_plural_project: "Projects",
kind_plural_module: "Modules",
kind_plural_namespace: "Namespaces",
kind_plural_enum: "Enumerations",
kind_plural_enum_member: "Enumeration Members",
kind_plural_variable: "Variables",
kind_plural_function: "Functions",
kind_plural_class: "Classes",
kind_plural_interface: "Interfaces",
kind_plural_constructor: "Constructors",
kind_plural_property: "Properties",
kind_plural_method: "Methods",
kind_plural_call_signature: "Call Signatures",
kind_plural_index_signature: "Index Signatures",
kind_plural_constructor_signature: "Constructor Signatures",
kind_plural_parameter: "Parameters",
kind_plural_type_literal: "Type Literals",
kind_plural_type_parameter: "Type Parameters",
kind_plural_accessor: "Accessors",
kind_plural_get_signature: "Get Signatures",
kind_plural_set_signature: "Set Signatures",
kind_plural_type_alias: "Type Aliases",
kind_plural_reference: "References",
} as const;

export type BuiltinTranslatableStringArgs = {
Expand Down
8 changes: 8 additions & 0 deletions src/lib/models/reflections/kind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,10 @@ export namespace ReflectionKind {
export const SignatureContainer =
ContainsCallSignatures | ReflectionKind.Accessor;

/** @internal */
export const VariableContainer = SomeModule | ReflectionKind.Project;

/** @internal */
export const MethodContainer =
ClassOrInterface |
VariableOrProperty |
Expand All @@ -146,6 +148,9 @@ export namespace ReflectionKind {
[ReflectionKind.TypeAlias]: "Type Aliases",
};

/**
* Get a non-localized kind string. For the localized string, use `app.internationalization.kindSingularString(kind)`
*/
export function singularString(kind: ReflectionKind): string {
if (kind in SINGULARS) {
return SINGULARS[kind as keyof typeof SINGULARS];
Expand All @@ -154,6 +159,9 @@ export namespace ReflectionKind {
}
}

/**
* Get a non-localized kind string. For the localized string, use `app.internationalization.kindPluralString(kind)`
*/
export function pluralString(kind: ReflectionKind): string {
if (kind in PLURALS) {
return PLURALS[kind as keyof typeof PLURALS];
Expand Down
8 changes: 8 additions & 0 deletions src/lib/output/themes/default/DefaultThemeRenderContext.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import type { PageEvent, RendererHooks } from "../..";
import type {
Internationalization,
TranslationProxy,
} from "../../../internationalization/internationalization";
import {
Comment,
CommentDisplayPart,
Expand Down Expand Up @@ -56,13 +60,17 @@ export class DefaultThemeRenderContext {
private _iconsCache: JSX.Element;
private _refIcons: typeof icons;
options: Options;
internationalization: Internationalization;
i18n: TranslationProxy;

constructor(
private theme: DefaultTheme,
public page: PageEvent<Reflection>,
options: Options,
) {
this.options = options;
this.internationalization = theme.application.internationalization;
this.i18n = this.internationalization.proxy;

const { refs, cache } = buildRefIcons(icons);
this._refIcons = refs;
Expand Down
3 changes: 2 additions & 1 deletion src/lib/output/themes/default/partials/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export const header = (context: DefaultThemeRenderContext, props: PageEvent<Refl
<div class="tsd-page-title">
{!!props.model.parent && <ul class="tsd-breadcrumb">{context.breadcrumb(props.model)}</ul>}
<HeadingLevel class={classNames({ deprecated: props.model.isDeprecated() })}>
{props.model.kind !== ReflectionKind.Project && `${ReflectionKind.singularString(props.model.kind)} `}
{props.model.kind !== ReflectionKind.Project &&
`${context.internationalization.kindSingularString(props.model.kind)} `}
{getDisplayName(props.model)}
{hasTypeParameters(props.model) && (
<>
Expand Down
22 changes: 1 addition & 21 deletions src/lib/utils/options/sources/typedoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -656,27 +656,7 @@ export function addTypeDocOptions(options: Pick<Options, "addDeclaration">) {
name: "groupOrder",
help: (i18n) => i18n.help_groupOrder(),
type: ParameterType.Array,
// Defaults to the same as the defaultKindSortOrder in sort.ts
defaultValue: [
ReflectionKind.Reference,
// project is never a child so never added to a group
ReflectionKind.Module,
ReflectionKind.Namespace,
ReflectionKind.Enum,
ReflectionKind.EnumMember,
ReflectionKind.Class,
ReflectionKind.Interface,
ReflectionKind.TypeAlias,

ReflectionKind.Constructor,
ReflectionKind.Property,
ReflectionKind.Variable,
ReflectionKind.Function,
ReflectionKind.Accessor,
ReflectionKind.Method,

// others are never added to groups
].map(ReflectionKind.pluralString),
// default order specified in GroupPlugin to correctly handle localization.
});
options.addDeclaration({
name: "sort",
Expand Down
4 changes: 1 addition & 3 deletions src/test/TestLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ const levelMap: Record<LogLevel, string> = {

export class TestLogger extends Logger {
messages: string[] = [];
override i18n: TranslationProxy = new Internationalization(
null,
).createProxy();
override i18n: TranslationProxy = new Internationalization(null).proxy;

reset() {
this.resetErrors();
Expand Down
2 changes: 1 addition & 1 deletion src/test/utils/options/help.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { getOptionsHelp } from "../../../lib/utils/options/help";
import { Internationalization } from "../../../lib/internationalization/internationalization";

describe("Options - help", () => {
const i18n = new Internationalization(null).createProxy();
const i18n = new Internationalization(null).proxy;
const options = new Options();
for (const decl of [
{ name: "td-option", help: "help", type: ParameterType.String },
Expand Down
2 changes: 1 addition & 1 deletion src/test/utils/plugins.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe("loadPlugins", () => {
let project: Project;
let logger: TestLogger;
const fakeApp = {
i18n: new Internationalization(null).createProxy(),
i18n: new Internationalization(null).proxy,
} as any as Application;
beforeEach(() => {
project = tempdirProject();
Expand Down

0 comments on commit 37b9eb7

Please sign in to comment.