@infrascan/shared-types 0.2.0
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/.eslintrc.js +9 -0
- package/CHANGELOG.md +11 -0
- package/README.md +3 -0
- package/package.json +36 -0
- package/src/api.ts +138 -0
- package/src/config.ts +134 -0
- package/src/graph.ts +70 -0
- package/src/index.ts +19 -0
- package/src/scan.ts +12 -0
- package/src/services.ts +64 -0
- package/tsconfig.json +8 -0
- package/typedoc.json +4 -0
package/.eslintrc.js
ADDED
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# @infrascan/shared-types
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 7d71a0e: Restructure the project into per service scanner modules. Each module must be registered with the SDK for the service to be scanned and graphed.
|
|
8
|
+
|
|
9
|
+
The initial implementation for Infrascan used a single config file which defined the scanning approach for every service, and their graph structure. It very quickly became difficult to debug, and reason about. The core logic was also completely untestable in any sane way.
|
|
10
|
+
|
|
11
|
+
This release is a rewrite of the entire project. The SDK by default will do nothing. Each individual service's scanner has to be registered into an instance of the SDK for it to be scanned or graphed. This reduces the SDK complexity massively, as it only needs to step through the registered services and call into their APIs.
|
package/README.md
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@infrascan/shared-types",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Shared types for multiple infrascan packages",
|
|
5
|
+
"main": "src/index.ts",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"lint": "tsc --noEmit ; eslint ."
|
|
8
|
+
},
|
|
9
|
+
"keywords": [],
|
|
10
|
+
"author": "Liam Farrelly <liam@l3f7.dev> (https://whoisli.am/)",
|
|
11
|
+
"license": "MPL-2.0",
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@aws-sdk/client-apigatewayv2": "3.428.0",
|
|
14
|
+
"@aws-sdk/client-auto-scaling": "3.428.0",
|
|
15
|
+
"@aws-sdk/client-cloudfront": "3.428.0",
|
|
16
|
+
"@aws-sdk/client-cloudwatch-logs": "3.428.0",
|
|
17
|
+
"@aws-sdk/client-dynamodb": "3.428.0",
|
|
18
|
+
"@aws-sdk/client-ec2": "3.428.0",
|
|
19
|
+
"@aws-sdk/client-ecs": "3.428.0",
|
|
20
|
+
"@aws-sdk/client-elastic-load-balancing-v2": "3.428.0",
|
|
21
|
+
"@aws-sdk/client-iam": "3.428.0",
|
|
22
|
+
"@aws-sdk/client-lambda": "3.428.0",
|
|
23
|
+
"@aws-sdk/client-rds": "3.428.0",
|
|
24
|
+
"@aws-sdk/client-route-53": "3.428.0",
|
|
25
|
+
"@aws-sdk/client-s3": "3.428.0",
|
|
26
|
+
"@aws-sdk/client-sns": "3.428.0",
|
|
27
|
+
"@aws-sdk/client-sqs": "3.428.0",
|
|
28
|
+
"@aws-sdk/client-sts": "3.428.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@aws-sdk/types": "3.428.0",
|
|
32
|
+
"eslint-config-custom": "*",
|
|
33
|
+
"tsconfig": "*",
|
|
34
|
+
"typescript": "^5.1.6"
|
|
35
|
+
}
|
|
36
|
+
}
|
package/src/api.ts
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import type { AwsCredentialIdentityProvider } from "@aws-sdk/types";
|
|
2
|
+
|
|
3
|
+
import type { Service } from "./services";
|
|
4
|
+
import type { BaseEdgeResolver } from "./config";
|
|
5
|
+
import type { GraphEdge, GraphNode } from "./graph";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Callback to store state from a specific function call
|
|
10
|
+
*
|
|
11
|
+
* This is callback is invoked after every full scan of a service endpoint.
|
|
12
|
+
*/
|
|
13
|
+
export type ServiceScanCompleteCallbackFn = (
|
|
14
|
+
/**
|
|
15
|
+
* The AWS account being scanned
|
|
16
|
+
*/
|
|
17
|
+
account: string,
|
|
18
|
+
/**
|
|
19
|
+
* The region being scanned
|
|
20
|
+
*/
|
|
21
|
+
region: string,
|
|
22
|
+
/**
|
|
23
|
+
* The service being scanned
|
|
24
|
+
*/
|
|
25
|
+
service: Service | "IAM",
|
|
26
|
+
/**
|
|
27
|
+
* The specific function called during scanning
|
|
28
|
+
*/
|
|
29
|
+
functionName: string,
|
|
30
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
31
|
+
/**
|
|
32
|
+
* The state retrieved from the function call
|
|
33
|
+
*/
|
|
34
|
+
functionState: any,
|
|
35
|
+
) => Promise<void>;
|
|
36
|
+
|
|
37
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
38
|
+
/**
|
|
39
|
+
* Callback to load scan state from a specific service call.
|
|
40
|
+
*
|
|
41
|
+
* This is used by the scan function pull back parameters for future function calls
|
|
42
|
+
* A common pattern is to have resources listed, and then described.
|
|
43
|
+
*/
|
|
44
|
+
export type ResolveStateForServiceFunction = (
|
|
45
|
+
/**
|
|
46
|
+
* The AWS account that was scanned
|
|
47
|
+
*/
|
|
48
|
+
account: string,
|
|
49
|
+
/**
|
|
50
|
+
* The scanned region
|
|
51
|
+
*/
|
|
52
|
+
region: string,
|
|
53
|
+
/**
|
|
54
|
+
* The scanned service e.g. Lambda
|
|
55
|
+
*/
|
|
56
|
+
service: Service,
|
|
57
|
+
/**
|
|
58
|
+
* The specific function called during the scan e.g. GetFunction
|
|
59
|
+
*/
|
|
60
|
+
functionName: string,
|
|
61
|
+
) => Promise<any>;
|
|
62
|
+
|
|
63
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
64
|
+
export type GetGlobalStateForServiceFunction = (
|
|
65
|
+
service: string,
|
|
66
|
+
functionName: string,
|
|
67
|
+
) => Promise<any>;
|
|
68
|
+
|
|
69
|
+
export interface Connector {
|
|
70
|
+
onServiceScanCompleteCallback: ServiceScanCompleteCallbackFn;
|
|
71
|
+
resolveStateForServiceFunction: ResolveStateForServiceFunction;
|
|
72
|
+
getGlobalStateForServiceFunction: GetGlobalStateForServiceFunction;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
type ClientBuilder<T, P extends Provider> = (
|
|
76
|
+
credentials: AwsCredentialIdentityProvider,
|
|
77
|
+
context: ProviderContextMap[P],
|
|
78
|
+
) => T;
|
|
79
|
+
|
|
80
|
+
type GetterFn<T, P extends Provider> = (
|
|
81
|
+
client: T,
|
|
82
|
+
stateConnector: Connector,
|
|
83
|
+
context: ProviderContextMap[P]
|
|
84
|
+
) => Promise<void>;
|
|
85
|
+
|
|
86
|
+
type GetNodeFn<T extends Provider> = (
|
|
87
|
+
stateConnector: Connector,
|
|
88
|
+
context: ProviderContextMap[T]
|
|
89
|
+
) => Promise<GraphNode[]>;
|
|
90
|
+
|
|
91
|
+
type GetEdgeFn = (stateConnector: Connector) => Promise<GraphEdge[]>;
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
export type Provider = "aws";
|
|
95
|
+
|
|
96
|
+
export type AwsContext = {
|
|
97
|
+
account: string;
|
|
98
|
+
region: string;
|
|
99
|
+
partition?: string;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
type ProviderContextMap = {
|
|
103
|
+
aws: AwsContext
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export type ProviderContext<T extends Provider> = {
|
|
107
|
+
provider: T;
|
|
108
|
+
context: ProviderContextMap[T];
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
type FormatNodeFn<P extends Provider> = (node: GraphNode, context: ProviderContextMap[P]) => GraphNode;
|
|
112
|
+
type FormatEdgeFn<P extends Provider> = (
|
|
113
|
+
node: GraphEdge,
|
|
114
|
+
context: ProviderContextMap[P]
|
|
115
|
+
) => GraphEdge;
|
|
116
|
+
|
|
117
|
+
export type EntityRoleData = {
|
|
118
|
+
roleArn: string;
|
|
119
|
+
executor: string;
|
|
120
|
+
};
|
|
121
|
+
type GetIamRoleFn = (stateConnector: Connector) => Promise<EntityRoleData[]>;
|
|
122
|
+
|
|
123
|
+
export interface ServiceModule<T, P extends Provider> {
|
|
124
|
+
provider: P;
|
|
125
|
+
service: string;
|
|
126
|
+
arnLabel?: string;
|
|
127
|
+
key: string;
|
|
128
|
+
getClient: ClientBuilder<T, P>;
|
|
129
|
+
callPerRegion: boolean;
|
|
130
|
+
getters: GetterFn<T, P>[];
|
|
131
|
+
nodes?: string[];
|
|
132
|
+
getNodes?: GetNodeFn<P>;
|
|
133
|
+
formatNode?: FormatNodeFn<P>;
|
|
134
|
+
edges?: BaseEdgeResolver[];
|
|
135
|
+
getEdges?: GetEdgeFn;
|
|
136
|
+
formatEdge?: FormatEdgeFn<P>;
|
|
137
|
+
getIamRoles?: GetIamRoleFn;
|
|
138
|
+
};
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
export type GenericEdgeSelector = `${string}|${string}`;
|
|
2
|
+
|
|
3
|
+
export type BaseEdgeResolver = {
|
|
4
|
+
state: GenericEdgeSelector;
|
|
5
|
+
from: string;
|
|
6
|
+
to: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type PaginationToken = {
|
|
10
|
+
request?: string;
|
|
11
|
+
response?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type BaseGetter = {
|
|
15
|
+
id?: string;
|
|
16
|
+
fn: string;
|
|
17
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
18
|
+
parameters?: (BaseParameterResolver & { Value?: any, Selector?: string })[];
|
|
19
|
+
formatter?: string;
|
|
20
|
+
paginationToken?: PaginationToken;
|
|
21
|
+
iamRoleSelectors?: string[];
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type GenericNodeSelector = `${string}|${string}|${string}`;
|
|
25
|
+
|
|
26
|
+
export type BaseScannerDefinition = {
|
|
27
|
+
provider?: string;
|
|
28
|
+
// Name of the service to be scanned
|
|
29
|
+
service: string;
|
|
30
|
+
// Key of the client in imported SDK
|
|
31
|
+
clientKey: string;
|
|
32
|
+
// Label used to identify this service within AWS ARNs
|
|
33
|
+
arnLabel?: string;
|
|
34
|
+
// Default 'type' for the generated graph entities, useful for applying a default style to a service's nodes.
|
|
35
|
+
key: string;
|
|
36
|
+
// Should the codegen skip implementing the client builder. Defaults to false.
|
|
37
|
+
skipClientBuilder?: boolean;
|
|
38
|
+
// Should this scanner be called in every region, or is it considered global (e.g. S3, Cloudfront, Route53)
|
|
39
|
+
callPerRegion: boolean;
|
|
40
|
+
// Scanner functions for pulling state from a service
|
|
41
|
+
getters: BaseGetter[];
|
|
42
|
+
// Scrapers for pulling Nodes from service state
|
|
43
|
+
nodes?: GenericNodeSelector[];
|
|
44
|
+
// Scrapers for pulling Edges from service state
|
|
45
|
+
edges?: BaseEdgeResolver[];
|
|
46
|
+
// Scrapers for pulling IAM Roles from service state, used to generate permission based edges
|
|
47
|
+
iamRoles?: GenericNodeSelector[];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
type AsCommand<S extends string> = `${S}Command`;
|
|
51
|
+
export type AvailableCommand<
|
|
52
|
+
Serv extends object,
|
|
53
|
+
Funcs extends string,
|
|
54
|
+
> = AsCommand<Funcs> extends `${infer P}Command` & keyof Serv ? P : never;
|
|
55
|
+
|
|
56
|
+
export type StateSelector<
|
|
57
|
+
ServiceName extends string,
|
|
58
|
+
Serv extends object,
|
|
59
|
+
Funcs extends string,
|
|
60
|
+
> = `${ServiceName}|${AvailableCommand<Serv, Funcs>}|${string}`;
|
|
61
|
+
|
|
62
|
+
export type EdgeSelector<
|
|
63
|
+
ServiceName extends string,
|
|
64
|
+
Serv extends object,
|
|
65
|
+
Funcs extends string,
|
|
66
|
+
> = {
|
|
67
|
+
state: StateSelector<ServiceName, Serv, Funcs>;
|
|
68
|
+
to: string;
|
|
69
|
+
from: string;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export type BaseParameterResolver = {
|
|
73
|
+
Key: string;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
77
|
+
export type ConstantParameterResolver = {
|
|
78
|
+
Value: any;
|
|
79
|
+
} & BaseParameterResolver;
|
|
80
|
+
|
|
81
|
+
export type StatefulParameterResolver<
|
|
82
|
+
ServiceName extends string,
|
|
83
|
+
Serv extends object,
|
|
84
|
+
Funcs extends string,
|
|
85
|
+
> = {
|
|
86
|
+
Selector: StateSelector<ServiceName, Serv, Funcs>;
|
|
87
|
+
} & BaseParameterResolver;
|
|
88
|
+
|
|
89
|
+
export type GenericStatefulParameterResolver = {
|
|
90
|
+
Selector: string;
|
|
91
|
+
} & BaseParameterResolver;
|
|
92
|
+
|
|
93
|
+
export type ParameterResolver<
|
|
94
|
+
ServiceName extends string,
|
|
95
|
+
Serv extends object,
|
|
96
|
+
Funcs extends string,
|
|
97
|
+
> =
|
|
98
|
+
| ConstantParameterResolver
|
|
99
|
+
| StatefulParameterResolver<ServiceName, Serv, Funcs>;
|
|
100
|
+
|
|
101
|
+
export type GenericParameterResolver = BaseParameterResolver & {
|
|
102
|
+
Selector?: string;
|
|
103
|
+
Value?: any;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export type ServiceGetter<
|
|
107
|
+
ServiceName extends string,
|
|
108
|
+
Serv extends object,
|
|
109
|
+
Funcs extends string,
|
|
110
|
+
> = {
|
|
111
|
+
id?: string;
|
|
112
|
+
fn: AvailableCommand<Serv, Funcs>;
|
|
113
|
+
paginationToken?: PaginationToken;
|
|
114
|
+
parameters?: ParameterResolver<ServiceName, Serv, Funcs>[];
|
|
115
|
+
iamRoleSelectors?: string[];
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export type ScannerDefinition<
|
|
119
|
+
ServiceName extends string,
|
|
120
|
+
Serv extends object,
|
|
121
|
+
Funcs extends string,
|
|
122
|
+
> = {
|
|
123
|
+
provider: string;
|
|
124
|
+
service: string;
|
|
125
|
+
clientKey: ServiceName;
|
|
126
|
+
arnLabel?: string;
|
|
127
|
+
key: string;
|
|
128
|
+
skipClientBuilder?: boolean;
|
|
129
|
+
callPerRegion: boolean;
|
|
130
|
+
getters: ServiceGetter<ServiceName, Serv, Funcs>[];
|
|
131
|
+
nodes?: StateSelector<ServiceName, Serv, Funcs>[];
|
|
132
|
+
edges?: EdgeSelector<ServiceName, Serv, Funcs>[];
|
|
133
|
+
iamRoles?: StateSelector<ServiceName, Serv, Funcs>[];
|
|
134
|
+
};
|
package/src/graph.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A node returned from a state selector before its been formatted for a graphing library
|
|
3
|
+
*/
|
|
4
|
+
export type SelectedNode = {
|
|
5
|
+
id: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
parent?: string;
|
|
8
|
+
type?: string;
|
|
9
|
+
rawState?: any;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A node on the graph
|
|
14
|
+
*/
|
|
15
|
+
export type GraphNode = {
|
|
16
|
+
group: "nodes";
|
|
17
|
+
id: string;
|
|
18
|
+
data: {
|
|
19
|
+
id: string;
|
|
20
|
+
type: string;
|
|
21
|
+
/**
|
|
22
|
+
* Parent node (account, region etc)
|
|
23
|
+
*/
|
|
24
|
+
parent?: string;
|
|
25
|
+
name?: string;
|
|
26
|
+
service?: string;
|
|
27
|
+
};
|
|
28
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
29
|
+
metadata?: any;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* An edge connecting two nodes within a graph
|
|
34
|
+
*/
|
|
35
|
+
export type GraphEdge = {
|
|
36
|
+
group: "edges";
|
|
37
|
+
/**
|
|
38
|
+
* Unique ID for the edge
|
|
39
|
+
*/
|
|
40
|
+
id?: string;
|
|
41
|
+
data: {
|
|
42
|
+
id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
/**
|
|
45
|
+
* Source Node
|
|
46
|
+
*/
|
|
47
|
+
source: string;
|
|
48
|
+
/**
|
|
49
|
+
* Target Node
|
|
50
|
+
*/
|
|
51
|
+
target: string;
|
|
52
|
+
type: string;
|
|
53
|
+
};
|
|
54
|
+
metadata?: {
|
|
55
|
+
label: string;
|
|
56
|
+
roleArn?: string;
|
|
57
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
58
|
+
statement?: any;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Generic type for elements in a graph
|
|
64
|
+
*/
|
|
65
|
+
export type GraphElement = GraphNode | GraphEdge;
|
|
66
|
+
|
|
67
|
+
export type EdgeTarget = {
|
|
68
|
+
name: string;
|
|
69
|
+
target: string;
|
|
70
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GlobalServiceClients,
|
|
3
|
+
RegionalServiceClients,
|
|
4
|
+
ServiceClients,
|
|
5
|
+
} from "./services";
|
|
6
|
+
import type { GlobalService, RegionalService, Service } from "./services";
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
ServiceClients,
|
|
10
|
+
GlobalServiceClients,
|
|
11
|
+
RegionalServiceClients,
|
|
12
|
+
GlobalService,
|
|
13
|
+
RegionalService,
|
|
14
|
+
Service,
|
|
15
|
+
};
|
|
16
|
+
export * from "./api";
|
|
17
|
+
export * from "./config";
|
|
18
|
+
export * from "./graph";
|
|
19
|
+
export * from "./scan";
|
package/src/scan.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type State<T> = {
|
|
2
|
+
_metadata: {
|
|
3
|
+
account: string;
|
|
4
|
+
region: string;
|
|
5
|
+
};
|
|
6
|
+
_result: T;
|
|
7
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
8
|
+
_parameters?: any;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
12
|
+
export type GenericState = State<any>;
|
package/src/services.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as S3 from "@aws-sdk/client-s3";
|
|
2
|
+
import * as CloudFront from "@aws-sdk/client-cloudfront";
|
|
3
|
+
import * as Route53 from "@aws-sdk/client-route-53";
|
|
4
|
+
|
|
5
|
+
import * as ApiGatewayV2 from "@aws-sdk/client-apigatewayv2";
|
|
6
|
+
import * as AutoScaling from "@aws-sdk/client-auto-scaling";
|
|
7
|
+
import * as CloudWatchLogs from "@aws-sdk/client-cloudwatch-logs";
|
|
8
|
+
import * as DynamoDB from "@aws-sdk/client-dynamodb";
|
|
9
|
+
import * as EC2 from "@aws-sdk/client-ec2";
|
|
10
|
+
import * as ECS from "@aws-sdk/client-ecs";
|
|
11
|
+
import * as ElasticLoadBalancingV2 from "@aws-sdk/client-elastic-load-balancing-v2";
|
|
12
|
+
import * as Lambda from "@aws-sdk/client-lambda";
|
|
13
|
+
import * as RDS from "@aws-sdk/client-rds";
|
|
14
|
+
import * as SNS from "@aws-sdk/client-sns";
|
|
15
|
+
import * as SQS from "@aws-sdk/client-sqs";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Clients for Global Services
|
|
19
|
+
*/
|
|
20
|
+
export const GlobalServiceClients = {
|
|
21
|
+
S3,
|
|
22
|
+
CloudFront,
|
|
23
|
+
Route53,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Clients for Regional Services
|
|
28
|
+
*/
|
|
29
|
+
export const RegionalServiceClients = {
|
|
30
|
+
ApiGatewayV2,
|
|
31
|
+
AutoScaling,
|
|
32
|
+
CloudWatchLogs,
|
|
33
|
+
DynamoDB,
|
|
34
|
+
EC2,
|
|
35
|
+
ECS,
|
|
36
|
+
ElasticLoadBalancingV2,
|
|
37
|
+
Lambda,
|
|
38
|
+
RDS,
|
|
39
|
+
SNS,
|
|
40
|
+
SQS,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Clients for every service
|
|
45
|
+
*/
|
|
46
|
+
export const ServiceClients = {
|
|
47
|
+
...GlobalServiceClients,
|
|
48
|
+
...RegionalServiceClients,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Type for Global Services
|
|
53
|
+
*/
|
|
54
|
+
export type GlobalService = keyof typeof GlobalServiceClients;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Type for Regional Services
|
|
58
|
+
*/
|
|
59
|
+
export type RegionalService = keyof typeof RegionalServiceClients;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Type for any support service
|
|
63
|
+
*/
|
|
64
|
+
export type Service = GlobalService | RegionalService;
|
package/tsconfig.json
ADDED
package/typedoc.json
ADDED