豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit f631e36

Browse files
josephperrottdevversion
authored andcommitted
feat(ng-dev): support performing configuration assertions in the getConfig function (#204)
Allow the getConfig function take in a list of assertions functions which will assert against the retrieved config object. Errors from the assertions will be thrown as expected. The returned config object will has the asserted typings. This will allow retrieving the config object already typed, which provides a convenience for cases where getConfig is called on intialization. PR Close #204
1 parent c5da4aa commit f631e36

File tree

5 files changed

+63
-12
lines changed

5 files changed

+63
-12
lines changed

github-actions/slash-commands/main.js

Lines changed: 13 additions & 3 deletions
Large diffs are not rendered by default.

ng-dev/caretaker/cli.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import {info} from 'console';
1010
import {Arguments, Argv} from 'yargs';
11-
import {getConfig} from '../utils/config';
11+
import {assertValidGithubConfig, getConfig} from '../utils/config';
1212
import {CheckModule} from './check/cli';
1313
import {assertValidCaretakerConfig} from './config';
1414
import {HandoffModule} from './handoff/cli';
@@ -22,9 +22,8 @@ export function buildCaretakerParser(yargs: Argv) {
2222
}
2323

2424
function caretakerCommandCanRun(argv: Arguments) {
25-
const config = getConfig();
2625
try {
27-
assertValidCaretakerConfig(config);
26+
getConfig([assertValidCaretakerConfig, assertValidGithubConfig]);
2827
} catch {
2928
info('The `caretaker` command is not enabled in this repository.');
3029
info(` To enable it, provide a caretaker config in the repository's .ng-dev/ directory`);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
type UnionToIntersection<U> = (U extends unknown ? (union: U) => void : never) extends (
2+
intersection: infer I,
3+
) => void
4+
? I
5+
: never;
6+
7+
type AssertedType<A> = A extends AssertionFn<infer T> ? T : never;
8+
type AllAssertedTypes<A extends readonly AssertionFn<unknown>[]> = {
9+
[K in keyof A]: AssertedType<A[K]>;
10+
};
11+
type ExtractValuesAsUnionFromObject<T> = T[keyof T & number];
12+
13+
export type Assertions<A extends readonly AssertionFn<unknown>[]> = UnionToIntersection<
14+
ExtractValuesAsUnionFromObject<AllAssertedTypes<A>>
15+
>;
16+
export type AssertionFn<T> = (value: Partial<T>) => asserts value is T;
17+
export type MultipleAssertions = AssertionFn<unknown>[];

ng-dev/utils/config.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import {existsSync} from 'fs';
1010
import {dirname, join} from 'path';
11+
import {Assertions, MultipleAssertions} from './assertion-typings';
1112

1213
import {debug, error} from './console';
1314
import {GitClient} from './git/git-client';
@@ -61,16 +62,30 @@ export function setConfig(config: {}) {
6162
* copy if it is defined.
6263
*/
6364
export function getConfig(): {};
64-
export function getConfig(baseDir?: string): {};
65-
export function getConfig(baseDir?: string): {} {
65+
export function getConfig(baseDir: string): {};
66+
export function getConfig<A extends MultipleAssertions>(assertions: A): Assertions<A>;
67+
export function getConfig(baseDirOrAssertions?: unknown) {
68+
let baseDir: string;
69+
if (typeof baseDirOrAssertions === 'string') {
70+
baseDir = baseDirOrAssertions;
71+
} else {
72+
baseDir = GitClient.get().baseDir;
73+
}
74+
6675
// If the global config is not defined, load it from the file system.
6776
if (cachedConfig === null) {
68-
baseDir = baseDir || GitClient.get().baseDir;
6977
// The full path to the configuration file.
7078
const configPath = join(baseDir, CONFIG_FILE_PATH);
7179
// Read the configuration and validate it before caching it for the future.
7280
cachedConfig = readConfigFile(configPath);
7381
}
82+
83+
if (Array.isArray(baseDirOrAssertions)) {
84+
for (const assertion of baseDirOrAssertions) {
85+
assertion(cachedConfig);
86+
}
87+
}
88+
7489
// Return a clone of the cached global config to ensure that a new instance of the config
7590
// is returned each time, preventing unexpected effects of modifications to the config object.
7691
return {...cachedConfig};

tools/local-actions/changelog/main.js

Lines changed: 13 additions & 3 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)