@studyportals/fawkes 2.0.1-20 → 2.0.1-21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -8
- package/dist/index.js +1 -3
- package/dist/scholarships-seo/index.d.ts +7 -7
- package/dist/scholarships-seo/index.js +2 -2
- package/dist/sitemap-generator-seo/index.d.ts +5 -0
- package/dist/sitemap-generator-seo/index.js +2 -1
- package/dist/src/common/BaseSeoIndexabilityPolicy.d.ts +13 -9
- package/dist/src/common/BaseSeoIndexabilityPolicy.js +18 -8
- package/dist/src/common/ICustomRule.d.ts +6 -0
- package/dist/src/common/IDependencies.d.ts +4 -0
- package/dist/src/common/IFilterKeyValues.d.ts +6 -0
- package/dist/src/common/IFilterKeyValues.js +1 -0
- package/dist/src/common/IIndexabilityPolicyDependencies.d.ts +8 -0
- package/dist/src/common/ISitemapUrlGenerator.d.ts +5 -0
- package/dist/src/common/ISitemapUrlGenerator.js +1 -0
- package/dist/src/common/RuleBasedIndexabilityPolicy.d.ts +10 -0
- package/dist/src/common/RuleBasedIndexabilityPolicy.js +12 -0
- package/dist/src/enums/DependencyTypes.d.ts +4 -0
- package/dist/src/enums/DependencyTypes.js +5 -0
- package/dist/src/enums/FilterCombinations.d.ts +9 -0
- package/dist/src/enums/FilterCombinations.js +10 -0
- package/dist/src/organisations/ISeoInfoBaseOrganisations.d.ts +1 -1
- package/dist/src/organisations/SearchIndexabilityManager.d.ts +2 -2
- package/dist/src/organisations/SeoIndexabilityPolicy.d.ts +3 -4
- package/dist/src/organisations/SeoIndexabilityPolicy.js +2 -2
- package/dist/src/organisations/SeoRuleBasedIndexabilityPolicy.d.ts +7 -8
- package/dist/src/organisations/SeoRuleBasedIndexabilityPolicy.js +4 -3
- package/dist/src/presenters/AreaPresenter.d.ts +9 -0
- package/dist/src/presenters/AreaPresenter.js +33 -0
- package/dist/src/presenters/CountryPresenter.d.ts +9 -0
- package/dist/src/presenters/CountryPresenter.js +36 -0
- package/dist/src/presenters/DisciplinePresenter.d.ts +9 -0
- package/dist/src/presenters/DisciplinePresenter.js +31 -0
- package/dist/src/presenters/fragments/IAreaFragment.d.ts +4 -0
- package/dist/src/presenters/fragments/IAreaFragment.js +1 -0
- package/dist/src/presenters/fragments/ICountryFragment.d.ts +4 -0
- package/dist/src/presenters/fragments/ICountryFragment.js +1 -0
- package/dist/src/presenters/fragments/IFragment.d.ts +4 -0
- package/dist/src/presenters/fragments/IFragment.js +1 -0
- package/dist/src/scholarships/SearchIndexabilityManager.d.ts +6 -5
- package/dist/src/scholarships/SearchIndexabilityManager.js +14 -11
- package/dist/src/scholarships/index.d.ts +0 -1
- package/dist/src/scholarships/index.js +0 -1
- package/dist/src/scholarships/policies/AreaPolicy.d.ts +10 -9
- package/dist/src/scholarships/policies/AreaPolicy.js +36 -16
- package/dist/src/scholarships/policies/CountryPolicy.d.ts +10 -6
- package/dist/src/scholarships/policies/CountryPolicy.js +32 -10
- package/dist/src/scholarships/policies/DisciplineCountryPolicy.d.ts +10 -9
- package/dist/src/scholarships/policies/DisciplineCountryPolicy.js +43 -15
- package/dist/src/scholarships/policies/DisciplinePolicy.d.ts +10 -6
- package/dist/src/scholarships/policies/DisciplinePolicy.js +33 -10
- package/dist/src/scholarships/policies/UnfilteredPolicy.d.ts +6 -5
- package/dist/src/scholarships/policies/UnfilteredPolicy.js +11 -6
- package/dist/src/scholarships/policies/UniversityCountryPolicy.d.ts +6 -5
- package/dist/src/scholarships/policies/UniversityCountryPolicy.js +35 -9
- package/dist/src/scholarships/rules/ExceptAustaliaAreasRule.d.ts +14 -0
- package/dist/src/scholarships/rules/ExceptAustaliaAreasRule.js +45 -0
- package/dist/src/scholarships/rules/SearchVolumeAreasRule.d.ts +12 -0
- package/dist/src/scholarships/rules/SearchVolumeAreasRule.js +34 -0
- package/dist/src/scholarships/rules/SearchVolumeCountriesRule.d.ts +12 -0
- package/dist/src/scholarships/rules/SearchVolumeCountriesRule.js +34 -0
- package/dist/src/scholarships/rules/SearchVolumeCountryDisciplineRule.d.ts +12 -0
- package/dist/src/scholarships/rules/SearchVolumeCountryDisciplineRule.js +37 -0
- package/dist/src/scholarships/rules/SearchVolumeDisciplinesRule.d.ts +12 -0
- package/dist/src/scholarships/rules/SearchVolumeDisciplinesRule.js +38 -0
- package/dist/src/scholarships/rules/files/search-volume.json +39334 -0
- package/dist/src/sitemap-generator/IOrganisation.d.ts +6 -0
- package/dist/src/sitemap-generator/IOrganisation.js +1 -0
- package/dist/src/sitemap-generator/IOrganisationsClient.d.ts +4 -0
- package/dist/src/sitemap-generator/IOrganisationsClient.js +1 -0
- package/dist/src/sitemap-generator/ISearchApiClient.d.ts +3 -0
- package/dist/src/sitemap-generator/ISearchApiClient.js +1 -0
- package/dist/src/sitemap-generator/ISitemapUrlGeneratorDependencies.d.ts +9 -0
- package/dist/src/sitemap-generator/ISitemapUrlGeneratorDependencies.js +1 -0
- package/dist/src/sitemap-generator/ISitemapUrlGeneratorManager.d.ts +4 -0
- package/dist/src/sitemap-generator/ISitemapUrlGeneratorManager.js +1 -0
- package/dist/src/sitemap-generator/SitemapUrlGeneratorManager.d.ts +8 -0
- package/dist/src/sitemap-generator/SitemapUrlGeneratorManager.js +20 -0
- package/dist/src/sitemap-generator/index.d.ts +0 -2
- package/dist/src/sitemap-generator/index.js +1 -2
- package/dist/src/types/SeoDependencies.d.ts +3 -0
- package/dist/src/types/SeoDependencies.js +1 -0
- package/package.json +16 -6
- package/dist/fawkes.js +0 -2
- package/dist/fawkes.js.map +0 -1
- package/dist/organisations-seo.js +0 -0
- package/dist/scholarships-seo.js +0 -2
- package/dist/scholarships-seo.js.map +0 -1
- package/dist/sitemap-generator-seo.js +0 -0
- package/dist/src/common/DisciplinePresenter.d.ts +0 -5
- package/dist/src/common/DisciplinePresenter.js +0 -48
- package/dist/src/common/IPrettyPathGenerator.d.ts +0 -3
- package/dist/src/common/fragments/Fragment.d.ts +0 -6
- package/dist/src/common/fragments/Fragment.js +0 -8
- package/dist/src/common/fragments/IFragment.d.ts +0 -4
- package/dist/src/scholarships/CustomRules.d.ts +0 -6
- package/dist/src/scholarships/CustomRules.js +0 -18
- package/dist/src/scholarships/policies/DisciplineAreaPolicy.d.ts +0 -12
- package/dist/src/scholarships/policies/DisciplineAreaPolicy.js +0 -34
- package/dist/src/sitemap-generator/CombinationType.d.ts +0 -2
- package/dist/src/sitemap-generator/CombinationType.js +0 -3
- package/dist/src/sitemap-generator/ISitemapPathGeneratorChain.d.ts +0 -4
- package/dist/src/sitemap-generator/SitemapPathGeneratorChain.d.ts +0 -7
- package/dist/src/sitemap-generator/SitemapPathGeneratorChain.js +0 -9
- /package/dist/src/common/{IPrettyPathGenerator.js → ICustomRule.js} +0 -0
- /package/dist/src/common/{fragments/IFragment.js → IDependencies.js} +0 -0
- /package/dist/src/{sitemap-generator/ISitemapPathGeneratorChain.js → common/IIndexabilityPolicyDependencies.js} +0 -0
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { FilterCombinations } from '../../enums/FilterCombinations';
|
|
2
|
+
import { ICustomRule } from '../../common/ICustomRule';
|
|
3
|
+
import { SeoDependencies } from '../../types/SeoDependencies';
|
|
4
|
+
import { RuleBasedIndexabilityPolicy } from '../../common/RuleBasedIndexabilityPolicy';
|
|
5
|
+
import { ISeoIndexabilityPolicy } from '../../common/ISeoIndexabilityPolicy';
|
|
6
|
+
export declare class CountryPolicy extends RuleBasedIndexabilityPolicy implements ISeoIndexabilityPolicy {
|
|
7
|
+
protected rules: ICustomRule[];
|
|
8
|
+
constructor(dependencies: SeoDependencies);
|
|
6
9
|
protected matchesFilters(): Promise<boolean>;
|
|
7
|
-
|
|
10
|
+
generateUrls(): Promise<string[]>;
|
|
11
|
+
get filterCombination(): FilterCombinations;
|
|
8
12
|
}
|
|
@@ -1,17 +1,39 @@
|
|
|
1
1
|
import { FilterKey } from '@studyportals/search-filters';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { FilterCombinations } from '../../enums/FilterCombinations';
|
|
3
|
+
import { SearchVolumeCountriesRule } from '../rules/SearchVolumeCountriesRule';
|
|
4
|
+
import { RuleBasedIndexabilityPolicy } from '../../common/RuleBasedIndexabilityPolicy';
|
|
5
|
+
import { CountryPresenter } from '../../presenters/CountryPresenter';
|
|
6
|
+
export class CountryPolicy extends RuleBasedIndexabilityPolicy {
|
|
7
|
+
rules = [
|
|
8
|
+
SearchVolumeCountriesRule.getInstance()
|
|
9
|
+
];
|
|
10
|
+
constructor(dependencies) {
|
|
11
|
+
super(dependencies);
|
|
6
12
|
}
|
|
7
13
|
async matchesFilters() {
|
|
8
|
-
const
|
|
9
|
-
const
|
|
14
|
+
const { seoInfoBase, filterState } = this.dependencies;
|
|
15
|
+
const singleCountrySelected = await seoInfoBase.singleSelectionFor(FilterKey.COUNTRY, filterState);
|
|
16
|
+
const onlyCountrySelected = await seoInfoBase.selectionOnlyFor([
|
|
10
17
|
FilterKey.COUNTRY
|
|
11
|
-
],
|
|
12
|
-
|
|
18
|
+
], filterState);
|
|
19
|
+
const countrySelected = seoInfoBase.getFilterOptionValueBy(FilterKey.COUNTRY, filterState);
|
|
20
|
+
const hasSearchVolume = this.checksEveryRuleForSearch({
|
|
21
|
+
[FilterKey.COUNTRY]: countrySelected ?? undefined
|
|
22
|
+
});
|
|
23
|
+
return singleCountrySelected
|
|
24
|
+
&& onlyCountrySelected
|
|
25
|
+
&& hasSearchVolume;
|
|
13
26
|
}
|
|
14
|
-
|
|
15
|
-
|
|
27
|
+
generateUrls() {
|
|
28
|
+
const countryFragments = CountryPresenter.getInstance().getFragments();
|
|
29
|
+
const paths = countryFragments
|
|
30
|
+
.filter(country => this.checksEveryRuleForSitemap({
|
|
31
|
+
[FilterKey.COUNTRY]: country.id
|
|
32
|
+
}))
|
|
33
|
+
.map(country => country.path);
|
|
34
|
+
return Promise.resolve(paths);
|
|
35
|
+
}
|
|
36
|
+
get filterCombination() {
|
|
37
|
+
return FilterCombinations.COUNTRY;
|
|
16
38
|
}
|
|
17
39
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
export declare class DisciplineCountryPolicy extends
|
|
7
|
-
|
|
8
|
-
constructor(
|
|
1
|
+
import { ISeoIndexabilityPolicy } from '../../common/ISeoIndexabilityPolicy';
|
|
2
|
+
import { FilterCombinations } from '../../enums/FilterCombinations';
|
|
3
|
+
import { SeoDependencies } from '../../types/SeoDependencies';
|
|
4
|
+
import { RuleBasedIndexabilityPolicy } from '../../common/RuleBasedIndexabilityPolicy';
|
|
5
|
+
import { ICustomRule } from '../../common/ICustomRule';
|
|
6
|
+
export declare class DisciplineCountryPolicy extends RuleBasedIndexabilityPolicy implements ISeoIndexabilityPolicy {
|
|
7
|
+
protected rules: ICustomRule[];
|
|
8
|
+
constructor(dependencies: SeoDependencies);
|
|
9
9
|
protected matchesFilters(): Promise<boolean>;
|
|
10
|
-
|
|
10
|
+
generateUrls(): Promise<string[]>;
|
|
11
|
+
get filterCombination(): FilterCombinations;
|
|
11
12
|
}
|
|
@@ -1,26 +1,54 @@
|
|
|
1
1
|
import { FilterKey } from '@studyportals/search-filters';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import { FilterCombinations } from '../../enums/FilterCombinations';
|
|
3
|
+
import { RuleBasedIndexabilityPolicy } from '../../common/RuleBasedIndexabilityPolicy';
|
|
4
|
+
import { SearchVolumeCountriesDisciplinesRule } from '../rules/SearchVolumeCountryDisciplineRule';
|
|
5
|
+
import { CountryPresenter } from '../../presenters/CountryPresenter';
|
|
6
|
+
export class DisciplineCountryPolicy extends RuleBasedIndexabilityPolicy {
|
|
7
|
+
rules = [
|
|
8
|
+
SearchVolumeCountriesDisciplinesRule.getInstance()
|
|
9
|
+
];
|
|
10
|
+
constructor(dependencies) {
|
|
11
|
+
super(dependencies);
|
|
9
12
|
}
|
|
10
13
|
async matchesFilters() {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
const { seoInfoBase, filterState, applicationState } = this.dependencies;
|
|
15
|
+
if (!applicationState) {
|
|
16
|
+
throw new Error('Application State dependencies are missing.');
|
|
17
|
+
}
|
|
18
|
+
const singleDisciplineSelected = await seoInfoBase.singleSelectionFor(FilterKey.DISCIPLINES, filterState);
|
|
19
|
+
const singleCountrySelected = await seoInfoBase.singleSelectionFor(FilterKey.COUNTRY, filterState);
|
|
20
|
+
const onlyDisciplineAndCountrySelected = await seoInfoBase.selectionOnlyFor([
|
|
14
21
|
FilterKey.DISCIPLINES,
|
|
15
22
|
FilterKey.COUNTRY
|
|
16
|
-
],
|
|
17
|
-
const
|
|
23
|
+
], filterState);
|
|
24
|
+
const countrySelected = seoInfoBase.getFilterOptionValueBy(FilterKey.COUNTRY, filterState);
|
|
25
|
+
const disciplineSelected = seoInfoBase.getFilterOptionValueBy(FilterKey.DISCIPLINES, filterState);
|
|
26
|
+
const hasSearchVolume = this.checksEveryRuleForSearch({
|
|
27
|
+
[FilterKey.COUNTRY]: countrySelected ?? undefined,
|
|
28
|
+
[FilterKey.DISCIPLINES]: disciplineSelected ?? undefined
|
|
29
|
+
});
|
|
18
30
|
return singleDisciplineSelected
|
|
19
31
|
&& singleCountrySelected
|
|
20
32
|
&& onlyDisciplineAndCountrySelected
|
|
21
|
-
&&
|
|
33
|
+
&& hasSearchVolume;
|
|
22
34
|
}
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
generateUrls() {
|
|
36
|
+
const paths = [];
|
|
37
|
+
const countryFragments = CountryPresenter.getInstance().getFragments();
|
|
38
|
+
const disciplineFragments = CountryPresenter.getInstance().getFragments();
|
|
39
|
+
countryFragments.forEach(country => {
|
|
40
|
+
disciplineFragments.forEach(discipline => {
|
|
41
|
+
if (this.checksEveryRuleForSitemap({
|
|
42
|
+
[FilterKey.COUNTRY]: country.id,
|
|
43
|
+
[FilterKey.DISCIPLINES]: discipline.id
|
|
44
|
+
})) {
|
|
45
|
+
paths.push(`${country.path}/${discipline.path}`);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
return Promise.resolve(paths);
|
|
50
|
+
}
|
|
51
|
+
get filterCombination() {
|
|
52
|
+
return FilterCombinations.DISCIPLINE_COUNTRY;
|
|
25
53
|
}
|
|
26
54
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { SeoDependencies } from '../../types/SeoDependencies';
|
|
2
|
+
import { ICustomRule } from '../../common/ICustomRule';
|
|
3
|
+
import { ISeoIndexabilityPolicy } from '../../common/ISeoIndexabilityPolicy';
|
|
4
|
+
import { FilterCombinations } from '../../enums/FilterCombinations';
|
|
5
|
+
import { RuleBasedIndexabilityPolicy } from '../../common/RuleBasedIndexabilityPolicy';
|
|
6
|
+
export declare class DisciplinePolicy extends RuleBasedIndexabilityPolicy implements ISeoIndexabilityPolicy {
|
|
7
|
+
protected rules: ICustomRule[];
|
|
8
|
+
constructor(dependencies: SeoDependencies);
|
|
6
9
|
protected matchesFilters(): Promise<boolean>;
|
|
7
|
-
|
|
10
|
+
generateUrls(): Promise<string[]>;
|
|
11
|
+
get filterCombination(): FilterCombinations;
|
|
8
12
|
}
|
|
@@ -1,17 +1,40 @@
|
|
|
1
1
|
import { FilterKey } from '@studyportals/search-filters';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { DisciplinePresenter } from '../../presenters/DisciplinePresenter';
|
|
3
|
+
import { SearchVolumeDisciplinesRule } from '../../scholarships/rules/SearchVolumeDisciplinesRule';
|
|
4
|
+
import { FilterCombinations } from '../../enums/FilterCombinations';
|
|
5
|
+
import { RuleBasedIndexabilityPolicy } from '../../common/RuleBasedIndexabilityPolicy';
|
|
6
|
+
export class DisciplinePolicy extends RuleBasedIndexabilityPolicy {
|
|
7
|
+
rules;
|
|
8
|
+
constructor(dependencies) {
|
|
9
|
+
super(dependencies);
|
|
10
|
+
this.rules = [
|
|
11
|
+
SearchVolumeDisciplinesRule.getInstance(),
|
|
12
|
+
];
|
|
6
13
|
}
|
|
7
14
|
async matchesFilters() {
|
|
8
|
-
const
|
|
9
|
-
const
|
|
15
|
+
const { seoInfoBase, filterState } = this.dependencies;
|
|
16
|
+
const singleDisciplineSelected = await seoInfoBase.singleSelectionFor(FilterKey.DISCIPLINES, filterState);
|
|
17
|
+
const onlyDisciplineSelected = await seoInfoBase.selectionOnlyFor([
|
|
10
18
|
FilterKey.DISCIPLINES
|
|
11
|
-
],
|
|
12
|
-
|
|
19
|
+
], filterState);
|
|
20
|
+
const disciplineSelected = seoInfoBase.getFilterOptionValueBy(FilterKey.DISCIPLINES, filterState);
|
|
21
|
+
const hasSearchVolume = this.checksEveryRuleForSearch({
|
|
22
|
+
[FilterKey.DISCIPLINES]: disciplineSelected ?? undefined
|
|
23
|
+
});
|
|
24
|
+
return singleDisciplineSelected
|
|
25
|
+
&& onlyDisciplineSelected
|
|
26
|
+
&& hasSearchVolume;
|
|
13
27
|
}
|
|
14
|
-
|
|
15
|
-
|
|
28
|
+
generateUrls() {
|
|
29
|
+
const disciplineFragments = DisciplinePresenter.getInstance().getFragments();
|
|
30
|
+
const paths = disciplineFragments
|
|
31
|
+
.filter(discipline => this.checksEveryRuleForSitemap({
|
|
32
|
+
[FilterKey.DISCIPLINES]: discipline.id
|
|
33
|
+
}))
|
|
34
|
+
.map(discipline => discipline.path);
|
|
35
|
+
return Promise.resolve(paths);
|
|
36
|
+
}
|
|
37
|
+
get filterCombination() {
|
|
38
|
+
return FilterCombinations.DISCIPLINE;
|
|
16
39
|
}
|
|
17
40
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { BaseSeoIndexabilityPolicy } from '../../common/BaseSeoIndexabilityPolicy';
|
|
2
|
+
import { SeoDependencies } from '../../types/SeoDependencies';
|
|
3
|
+
import { FilterCombinations } from '../../enums/FilterCombinations';
|
|
4
4
|
export declare class UnfilteredPolicy extends BaseSeoIndexabilityPolicy {
|
|
5
|
-
constructor(
|
|
5
|
+
constructor(dependencies: SeoDependencies);
|
|
6
6
|
protected matchesFilters(): Promise<boolean>;
|
|
7
|
-
|
|
7
|
+
generateUrls(): Promise<string[]>;
|
|
8
|
+
get filterCombination(): FilterCombinations;
|
|
8
9
|
}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import { BaseSeoIndexabilityPolicy } from '
|
|
1
|
+
import { BaseSeoIndexabilityPolicy } from '../../common/BaseSeoIndexabilityPolicy';
|
|
2
|
+
import { FilterCombinations } from '../../enums/FilterCombinations';
|
|
2
3
|
export class UnfilteredPolicy extends BaseSeoIndexabilityPolicy {
|
|
3
|
-
constructor(
|
|
4
|
-
super(
|
|
4
|
+
constructor(dependencies) {
|
|
5
|
+
super(dependencies);
|
|
5
6
|
}
|
|
6
7
|
async matchesFilters() {
|
|
7
|
-
|
|
8
|
+
const { seoInfoBase, filterState } = this.dependencies;
|
|
9
|
+
return Promise.resolve(seoInfoBase.getSelectionTypeCount(filterState) === 0);
|
|
8
10
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
generateUrls() {
|
|
12
|
+
return Promise.resolve(['/']);
|
|
13
|
+
}
|
|
14
|
+
get filterCombination() {
|
|
15
|
+
return FilterCombinations.UNFILTERED;
|
|
11
16
|
}
|
|
12
17
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { BaseSeoIndexabilityPolicy } from '
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { BaseSeoIndexabilityPolicy } from '../../common/BaseSeoIndexabilityPolicy';
|
|
2
|
+
import { FilterCombinations } from '../../enums/FilterCombinations';
|
|
3
|
+
import { SeoDependencies } from '../../types/SeoDependencies';
|
|
4
4
|
export declare class UniversityCountryPolicy extends BaseSeoIndexabilityPolicy {
|
|
5
|
-
constructor(
|
|
5
|
+
constructor(dependencies: SeoDependencies);
|
|
6
6
|
protected matchesFilters(): Promise<boolean>;
|
|
7
|
-
|
|
7
|
+
generateUrls(): Promise<string[]>;
|
|
8
|
+
get filterCombination(): FilterCombinations;
|
|
8
9
|
}
|
|
@@ -1,21 +1,47 @@
|
|
|
1
1
|
import { FilterKey } from '@studyportals/search-filters';
|
|
2
|
-
import { BaseSeoIndexabilityPolicy } from '
|
|
2
|
+
import { BaseSeoIndexabilityPolicy } from '../../common/BaseSeoIndexabilityPolicy';
|
|
3
|
+
import { FilterCombinations } from '../../enums/FilterCombinations';
|
|
4
|
+
import { CountryPresenter } from '../../presenters/CountryPresenter';
|
|
3
5
|
export class UniversityCountryPolicy extends BaseSeoIndexabilityPolicy {
|
|
4
|
-
constructor(
|
|
5
|
-
super(
|
|
6
|
+
constructor(dependencies) {
|
|
7
|
+
super(dependencies);
|
|
6
8
|
}
|
|
7
9
|
async matchesFilters() {
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
10
|
+
const { seoInfoBase, filterState } = this.dependencies;
|
|
11
|
+
const singleUniversitySelected = await seoInfoBase.singleSelectionFor(FilterKey.ORGANISATIONS, filterState);
|
|
12
|
+
const singleCountrySelected = await seoInfoBase.singleSelectionFor(FilterKey.COUNTRY, filterState);
|
|
13
|
+
const onlyUniversityAndDisciplineSelected = await seoInfoBase.selectionOnlyFor([
|
|
11
14
|
FilterKey.ORGANISATIONS,
|
|
12
15
|
FilterKey.COUNTRY
|
|
13
|
-
],
|
|
16
|
+
], filterState);
|
|
14
17
|
return singleUniversitySelected
|
|
15
18
|
&& singleCountrySelected
|
|
16
19
|
&& onlyUniversityAndDisciplineSelected;
|
|
17
20
|
}
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
async generateUrls() {
|
|
22
|
+
const { searchApiClient, organisationsClient } = this.dependencies;
|
|
23
|
+
if (!searchApiClient || !organisationsClient) {
|
|
24
|
+
throw new Error('Search API Client or Organisation Client dependencies are missing.');
|
|
25
|
+
}
|
|
26
|
+
const organisationIds = await searchApiClient.getOrganisationIds();
|
|
27
|
+
const organisations = await organisationsClient.getOrganisations(organisationIds);
|
|
28
|
+
const isoToPath = new Map();
|
|
29
|
+
const countries = CountryPresenter.getInstance().getFragments();
|
|
30
|
+
countries.forEach(country => {
|
|
31
|
+
isoToPath.set(country.id, country.path);
|
|
32
|
+
});
|
|
33
|
+
const paths = [];
|
|
34
|
+
organisations.forEach(org => {
|
|
35
|
+
org.countryIsoCodes.forEach(iso => {
|
|
36
|
+
const countryVirtualPath = isoToPath.get(iso);
|
|
37
|
+
if (countryVirtualPath) {
|
|
38
|
+
paths.push(`/${countryVirtualPath}/${org.virtualPath}`);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
return Promise.resolve(paths);
|
|
43
|
+
}
|
|
44
|
+
get filterCombination() {
|
|
45
|
+
return FilterCombinations.UNIVERSITY_COUNTRY;
|
|
20
46
|
}
|
|
21
47
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ICustomRule } from "../../common/ICustomRule";
|
|
2
|
+
import { IFilterKeyValues } from "../../common/IFilterKeyValues";
|
|
3
|
+
export declare class ExceptAustraliaAreasRule implements ICustomRule {
|
|
4
|
+
private areasPresenter;
|
|
5
|
+
private static instance;
|
|
6
|
+
private australiaCountryId;
|
|
7
|
+
private constructor();
|
|
8
|
+
static getInstance(): ExceptAustraliaAreasRule;
|
|
9
|
+
forSearch(filterSet: IFilterKeyValues): boolean;
|
|
10
|
+
forSitemapGenerator(filterKeyValues: IFilterKeyValues): boolean;
|
|
11
|
+
getName(): string;
|
|
12
|
+
private isNotAustralia;
|
|
13
|
+
private doesNotBelongToAustralia;
|
|
14
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { AreaPresenter } from "../../presenters/AreaPresenter";
|
|
2
|
+
import { FilterKey } from "@studyportals/search-filters";
|
|
3
|
+
export class ExceptAustraliaAreasRule {
|
|
4
|
+
areasPresenter;
|
|
5
|
+
static instance;
|
|
6
|
+
australiaCountryId = 202;
|
|
7
|
+
constructor() {
|
|
8
|
+
this.areasPresenter = AreaPresenter.getInstance();
|
|
9
|
+
}
|
|
10
|
+
static getInstance() {
|
|
11
|
+
if (!ExceptAustraliaAreasRule.instance) {
|
|
12
|
+
ExceptAustraliaAreasRule.instance = new ExceptAustraliaAreasRule();
|
|
13
|
+
}
|
|
14
|
+
return ExceptAustraliaAreasRule.instance;
|
|
15
|
+
}
|
|
16
|
+
forSearch(filterSet) {
|
|
17
|
+
const value = filterSet[FilterKey.AREA];
|
|
18
|
+
if (!value) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return this.doesNotBelongToAustralia(value);
|
|
22
|
+
}
|
|
23
|
+
forSitemapGenerator(filterKeyValues) {
|
|
24
|
+
const value = filterKeyValues[FilterKey.COUNTRY];
|
|
25
|
+
if (!value) {
|
|
26
|
+
throw new Error(`Invalid filter provided or undefined value.`);
|
|
27
|
+
}
|
|
28
|
+
return this.isNotAustralia(value);
|
|
29
|
+
}
|
|
30
|
+
getName() {
|
|
31
|
+
return 'ExceptAustraliaAreasRule';
|
|
32
|
+
}
|
|
33
|
+
isNotAustralia(countryId) {
|
|
34
|
+
return countryId !== this.australiaCountryId.toString();
|
|
35
|
+
}
|
|
36
|
+
doesNotBelongToAustralia(filterId) {
|
|
37
|
+
const areas = this.areasPresenter.getFragments();
|
|
38
|
+
const foundArea = areas.find((area) => area.id === filterId);
|
|
39
|
+
// TODO: This condition is not correct, decide what to do
|
|
40
|
+
if (!foundArea) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return foundArea.countryId !== this.australiaCountryId.toString();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ICustomRule } from "../../common/ICustomRule";
|
|
2
|
+
import { IFilterKeyValues } from "../../common/IFilterKeyValues";
|
|
3
|
+
export declare class SearchVolumeAreasRule implements ICustomRule {
|
|
4
|
+
private static instance;
|
|
5
|
+
private areasWithNoSearchVolume;
|
|
6
|
+
private constructor();
|
|
7
|
+
static getInstance(): SearchVolumeAreasRule;
|
|
8
|
+
forSearch(filterSet: IFilterKeyValues): boolean;
|
|
9
|
+
forSitemapGenerator(filterSet: IFilterKeyValues): boolean;
|
|
10
|
+
getName(): string;
|
|
11
|
+
private hasSearchVolume;
|
|
12
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { FilterKey } from "@studyportals/search-filters";
|
|
2
|
+
export class SearchVolumeAreasRule {
|
|
3
|
+
static instance;
|
|
4
|
+
areasWithNoSearchVolume;
|
|
5
|
+
constructor() {
|
|
6
|
+
this.areasWithNoSearchVolume = [3579, 995];
|
|
7
|
+
}
|
|
8
|
+
static getInstance() {
|
|
9
|
+
if (!SearchVolumeAreasRule.instance) {
|
|
10
|
+
SearchVolumeAreasRule.instance = new SearchVolumeAreasRule();
|
|
11
|
+
}
|
|
12
|
+
return SearchVolumeAreasRule.instance;
|
|
13
|
+
}
|
|
14
|
+
forSearch(filterSet) {
|
|
15
|
+
const value = filterSet[FilterKey.AREA];
|
|
16
|
+
if (!value) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return this.hasSearchVolume(value);
|
|
20
|
+
}
|
|
21
|
+
forSitemapGenerator(filterSet) {
|
|
22
|
+
const value = filterSet[FilterKey.AREA];
|
|
23
|
+
if (!value) {
|
|
24
|
+
throw new Error(`Invalid filter provided or undefined value.`);
|
|
25
|
+
}
|
|
26
|
+
return this.hasSearchVolume(value);
|
|
27
|
+
}
|
|
28
|
+
getName() {
|
|
29
|
+
return 'SearchVolumeAreasRule';
|
|
30
|
+
}
|
|
31
|
+
hasSearchVolume(areaId) {
|
|
32
|
+
return !this.areasWithNoSearchVolume.includes(Number(areaId));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ICustomRule } from "../../common/ICustomRule";
|
|
2
|
+
import { IFilterKeyValues } from "../../common/IFilterKeyValues";
|
|
3
|
+
export declare class SearchVolumeCountriesRule implements ICustomRule {
|
|
4
|
+
private static instance;
|
|
5
|
+
private countriesWithNoSearchVolume;
|
|
6
|
+
private constructor();
|
|
7
|
+
static getInstance(): SearchVolumeCountriesRule;
|
|
8
|
+
forSearch(filterSet: IFilterKeyValues): boolean;
|
|
9
|
+
forSitemapGenerator(filterSet: IFilterKeyValues): boolean;
|
|
10
|
+
getName(): string;
|
|
11
|
+
private hasSearchVolume;
|
|
12
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { FilterKey } from "@studyportals/search-filters";
|
|
2
|
+
export class SearchVolumeCountriesRule {
|
|
3
|
+
static instance;
|
|
4
|
+
countriesWithNoSearchVolume;
|
|
5
|
+
constructor() {
|
|
6
|
+
this.countriesWithNoSearchVolume = [122, 107, 18];
|
|
7
|
+
}
|
|
8
|
+
static getInstance() {
|
|
9
|
+
if (!SearchVolumeCountriesRule.instance) {
|
|
10
|
+
SearchVolumeCountriesRule.instance = new SearchVolumeCountriesRule();
|
|
11
|
+
}
|
|
12
|
+
return SearchVolumeCountriesRule.instance;
|
|
13
|
+
}
|
|
14
|
+
forSearch(filterSet) {
|
|
15
|
+
const value = filterSet[FilterKey.COUNTRY];
|
|
16
|
+
if (!value) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return this.hasSearchVolume(value);
|
|
20
|
+
}
|
|
21
|
+
forSitemapGenerator(filterSet) {
|
|
22
|
+
const value = filterSet[FilterKey.COUNTRY];
|
|
23
|
+
if (!value) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return this.hasSearchVolume(value);
|
|
27
|
+
}
|
|
28
|
+
getName() {
|
|
29
|
+
return 'SearchVolumeCountriesRule';
|
|
30
|
+
}
|
|
31
|
+
hasSearchVolume(countryId) {
|
|
32
|
+
return !this.countriesWithNoSearchVolume.includes(Number(countryId));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ICustomRule } from "../../common/ICustomRule";
|
|
2
|
+
import { IFilterKeyValues } from "../../common/IFilterKeyValues";
|
|
3
|
+
export declare class SearchVolumeCountriesDisciplinesRule implements ICustomRule {
|
|
4
|
+
private static instance;
|
|
5
|
+
private combinationsWithSearchVolume;
|
|
6
|
+
private constructor();
|
|
7
|
+
static getInstance(): SearchVolumeCountriesDisciplinesRule;
|
|
8
|
+
forSearch(filterSet: IFilterKeyValues): boolean;
|
|
9
|
+
forSitemapGenerator(filterSet: IFilterKeyValues): boolean;
|
|
10
|
+
getName(): string;
|
|
11
|
+
private hasSearchVolume;
|
|
12
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import searchVolume from './files/search-volume.json';
|
|
2
|
+
import { FilterKey } from "@studyportals/search-filters";
|
|
3
|
+
export class SearchVolumeCountriesDisciplinesRule {
|
|
4
|
+
static instance;
|
|
5
|
+
combinationsWithSearchVolume;
|
|
6
|
+
constructor() {
|
|
7
|
+
this.combinationsWithSearchVolume = new Set(searchVolume.map(({ ci, di }) => `${ci},${di}`));
|
|
8
|
+
}
|
|
9
|
+
static getInstance() {
|
|
10
|
+
if (!SearchVolumeCountriesDisciplinesRule.instance) {
|
|
11
|
+
SearchVolumeCountriesDisciplinesRule.instance = new SearchVolumeCountriesDisciplinesRule();
|
|
12
|
+
}
|
|
13
|
+
return SearchVolumeCountriesDisciplinesRule.instance;
|
|
14
|
+
}
|
|
15
|
+
forSearch(filterSet) {
|
|
16
|
+
const countryValue = filterSet[FilterKey.COUNTRY];
|
|
17
|
+
const disciplineValue = filterSet[FilterKey.DISCIPLINES];
|
|
18
|
+
if (!countryValue || !disciplineValue) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return this.hasSearchVolume(countryValue, disciplineValue);
|
|
22
|
+
}
|
|
23
|
+
forSitemapGenerator(filterSet) {
|
|
24
|
+
const countryValue = filterSet[FilterKey.COUNTRY];
|
|
25
|
+
const disciplineValue = filterSet[FilterKey.DISCIPLINES];
|
|
26
|
+
if (!countryValue || !disciplineValue) {
|
|
27
|
+
throw new Error(`SitemapGenerator: Invalid filter provided or undefined value.`);
|
|
28
|
+
}
|
|
29
|
+
return this.hasSearchVolume(countryValue, disciplineValue);
|
|
30
|
+
}
|
|
31
|
+
getName() {
|
|
32
|
+
return 'SearchVolumeCountriesDisciplinesRule';
|
|
33
|
+
}
|
|
34
|
+
hasSearchVolume(countryId, disciplineId) {
|
|
35
|
+
return this.combinationsWithSearchVolume.has(`${countryId},${disciplineId}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ICustomRule } from "../../common/ICustomRule";
|
|
2
|
+
import { IFilterKeyValues } from "../../common/IFilterKeyValues";
|
|
3
|
+
export declare class SearchVolumeDisciplinesRule implements ICustomRule {
|
|
4
|
+
private static instance;
|
|
5
|
+
private disciplinesWithNoSearchVolume;
|
|
6
|
+
private constructor();
|
|
7
|
+
static getInstance(): SearchVolumeDisciplinesRule;
|
|
8
|
+
forSearch(filterSet: IFilterKeyValues): boolean;
|
|
9
|
+
forSitemapGenerator(filterSet: IFilterKeyValues): boolean;
|
|
10
|
+
getName(): string;
|
|
11
|
+
private hasSearchVolume;
|
|
12
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { FilterKey } from "@studyportals/search-filters";
|
|
2
|
+
export class SearchVolumeDisciplinesRule {
|
|
3
|
+
static instance;
|
|
4
|
+
disciplinesWithNoSearchVolume;
|
|
5
|
+
constructor() {
|
|
6
|
+
this.disciplinesWithNoSearchVolume = [
|
|
7
|
+
243, 415, 405, 379, 269, 413,
|
|
8
|
+
408, 274, 411, 401, 381, 390,
|
|
9
|
+
410, 412, 130
|
|
10
|
+
];
|
|
11
|
+
}
|
|
12
|
+
static getInstance() {
|
|
13
|
+
if (!SearchVolumeDisciplinesRule.instance) {
|
|
14
|
+
SearchVolumeDisciplinesRule.instance = new SearchVolumeDisciplinesRule();
|
|
15
|
+
}
|
|
16
|
+
return SearchVolumeDisciplinesRule.instance;
|
|
17
|
+
}
|
|
18
|
+
forSearch(filterSet) {
|
|
19
|
+
const value = filterSet[FilterKey.DISCIPLINES];
|
|
20
|
+
if (!value) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return this.hasSearchVolume(value);
|
|
24
|
+
}
|
|
25
|
+
forSitemapGenerator(filterSet) {
|
|
26
|
+
const value = filterSet[FilterKey.DISCIPLINES];
|
|
27
|
+
if (!value) {
|
|
28
|
+
throw new Error(`Invalid filter provided or undefined value.`);
|
|
29
|
+
}
|
|
30
|
+
return this.hasSearchVolume(value);
|
|
31
|
+
}
|
|
32
|
+
getName() {
|
|
33
|
+
return 'SearchVolumeDisciplinesRule';
|
|
34
|
+
}
|
|
35
|
+
hasSearchVolume(disciplineId) {
|
|
36
|
+
return !this.disciplinesWithNoSearchVolume.includes(Number(disciplineId));
|
|
37
|
+
}
|
|
38
|
+
}
|