diff --git a/docs/en/development/ui-extensions.md b/docs/en/development/ui-extensions.md index 1b3a22af3d..7f0821550f 100644 --- a/docs/en/development/ui-extensions.md +++ b/docs/en/development/ui-extensions.md @@ -107,3 +107,37 @@ binder.bind("repo.avatar", GitAvatar, (props) => props.type === "git"); ```javascript ``` + +### Typings + +Both extension points and extensions can share a common typescript type to define the contract between them. +This includes the `name`, the type of `props` passed to the predicate and what `type` the extensions themselves can be. + +Example: +```typescript + type CalculatorExtensionPoint = ExtensionPointDefinition<"extension.calculator", (input: number[]) => number, undefined>; + + const sum = (a: number, b: number) => a + b; + binder.bind("extension.calculator", (input: number[]) => input.reduce(sum, 0)); + const calculator = binder.getExtension("extension.calculator"); + const result = calculator([1, 2, 3]); +``` + +In this example, we use the base type `ExtensionPointDefinition` to declare a new extension point. + +As we do not need a predicate, we can define the `props` type parameter as `undefined`. This allows us to skip the `props` parameter in the +`getExtension` method and the `predicate` parameter in the `bind` method. + +When using `bind` to define an extension or `getExtension` to retrieve an extension, we can pass the new type as a type parameter. +By doing this, we allow typescript to help us with type-checks and offer us type-completion. + +Negative Example: +```typescript + type CalculatorExtensionPoint = ExtensionPointDefinition<"extension.calculator", (input: number[]) => number, undefined>; + + const sum = (a: number, b: number) => a + b; + binder.bind("extension.calculato", (input: number[]) => input.reduce(sum, 0)); +``` + +This code for example, would lead to a compile time type error because we made a typo in the `name` of the extension when binding it. +If we had used the `bind` method without the type parameter, we would not have gotten an error but run into problems at runtime. diff --git a/gradle/changelog/extension-point-typings.yaml b/gradle/changelog/extension-point-typings.yaml new file mode 100644 index 0000000000..0322582413 --- /dev/null +++ b/gradle/changelog/extension-point-typings.yaml @@ -0,0 +1,2 @@ +- type: added + description: Implement api for extension point typings ([#1638](https://github.com/scm-manager/scm-manager/pull/1638)) diff --git a/scm-plugins/scm-git-plugin/package.json b/scm-plugins/scm-git-plugin/package.json index a2aab63ff7..3396f49177 100644 --- a/scm-plugins/scm-git-plugin/package.json +++ b/scm-plugins/scm-git-plugin/package.json @@ -14,7 +14,7 @@ "@scm-manager/ui-plugins": "^2.18.1-SNAPSHOT" }, "devDependencies": { - "@scm-manager/babel-preset": "^2.11.1", + "@scm-manager/babel-preset": "^2.12.0", "@scm-manager/eslint-config": "^2.11.1", "@scm-manager/jest-preset": "^2.12.7", "@scm-manager/plugin-scripts": "^1.0.1", diff --git a/scm-plugins/scm-hg-plugin/package.json b/scm-plugins/scm-hg-plugin/package.json index 10c26de915..7b3c149a11 100644 --- a/scm-plugins/scm-hg-plugin/package.json +++ b/scm-plugins/scm-hg-plugin/package.json @@ -13,7 +13,7 @@ "@scm-manager/ui-plugins": "^2.18.1-SNAPSHOT" }, "devDependencies": { - "@scm-manager/babel-preset": "^2.11.1", + "@scm-manager/babel-preset": "^2.12.0", "@scm-manager/eslint-config": "^2.11.1", "@scm-manager/jest-preset": "^2.12.7", "@scm-manager/plugin-scripts": "^1.0.1", diff --git a/scm-plugins/scm-legacy-plugin/package.json b/scm-plugins/scm-legacy-plugin/package.json index 437e40623e..03c43c145d 100644 --- a/scm-plugins/scm-legacy-plugin/package.json +++ b/scm-plugins/scm-legacy-plugin/package.json @@ -13,7 +13,7 @@ "@scm-manager/ui-plugins": "^2.18.1-SNAPSHOT" }, "devDependencies": { - "@scm-manager/babel-preset": "^2.11.1", + "@scm-manager/babel-preset": "^2.12.0", "@scm-manager/eslint-config": "^2.11.1", "@scm-manager/jest-preset": "^2.12.7", "@scm-manager/plugin-scripts": "^1.0.1", diff --git a/scm-plugins/scm-svn-plugin/package.json b/scm-plugins/scm-svn-plugin/package.json index 50bc029b9d..b4b62262f1 100644 --- a/scm-plugins/scm-svn-plugin/package.json +++ b/scm-plugins/scm-svn-plugin/package.json @@ -13,7 +13,7 @@ "@scm-manager/ui-plugins": "^2.18.1-SNAPSHOT" }, "devDependencies": { - "@scm-manager/babel-preset": "^2.11.1", + "@scm-manager/babel-preset": "^2.12.0", "@scm-manager/eslint-config": "^2.11.1", "@scm-manager/jest-preset": "^2.12.7", "@scm-manager/plugin-scripts": "^1.0.1", diff --git a/scm-ui/ui-api/package.json b/scm-ui/ui-api/package.json index d4a8af91e7..25f9c17546 100644 --- a/scm-ui/ui-api/package.json +++ b/scm-ui/ui-api/package.json @@ -15,7 +15,7 @@ "typecheck": "tsc" }, "devDependencies": { - "@scm-manager/babel-preset": "^2.11.2", + "@scm-manager/babel-preset": "^2.12.0", "@scm-manager/eslint-config": "^2.10.1", "@scm-manager/jest-preset": "^2.12.7", "@scm-manager/prettier-config": "^2.10.1", diff --git a/scm-ui/ui-api/src/repositories.ts b/scm-ui/ui-api/src/repositories.ts index 3f14afe2ad..63506740bf 100644 --- a/scm-ui/ui-api/src/repositories.ts +++ b/scm-ui/ui-api/src/repositories.ts @@ -284,7 +284,7 @@ const EXPORT_MEDIA_TYPE = "application/vnd.scmm-repositoryExport+json;v=2"; export const useExportRepository = () => { const queryClient = useQueryClient(); - const [intervalId, setIntervalId] = useState(); + const [intervalId, setIntervalId] = useState>(); useEffect(() => { return () => { if (intervalId) { diff --git a/scm-ui/ui-components/package.json b/scm-ui/ui-components/package.json index 290c7232ff..1b1546a772 100644 --- a/scm-ui/ui-components/package.json +++ b/scm-ui/ui-components/package.json @@ -20,7 +20,7 @@ "update-storyshots": "jest --testPathPattern=\"storyshots.test.ts\" --collectCoverage=false -u" }, "devDependencies": { - "@scm-manager/babel-preset": "^2.11.2", + "@scm-manager/babel-preset": "^2.12.0", "@scm-manager/eslint-config": "^2.12.0", "@scm-manager/jest-preset": "^2.12.7", "@scm-manager/prettier-config": "^2.10.1", diff --git a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap index b6765931b0..4ff705e8e8 100644 --- a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap +++ b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap @@ -2,7 +2,7 @@ exports[`Storyshots Annotate Default 1`] = `
Arthur Dent
1
2
Tricia Marie McMillan
3
4
Arthur Dent
5
Ford Prefect
6
Arthur Dent
7
8
Arthur Dent
1
2
Tricia Marie McMillan
3
4
Arthur Dent
5
Ford Prefect
6
Arthur Dent
7
8
Arthur Dent Arthur Dent
1
2
Tricia Marie McMillan Tricia Marie McMillan
3
4
Arthur Dent Arthur Dent
5
Ford Prefect Ford Prefect
6
Arthur Dent Arthur Dent
7
8