-
Notifications
You must be signed in to change notification settings - Fork 227
Expand file tree
/
Copy pathgetFeatureFlagsInLatestCompositionByFederatedGraph.ts
More file actions
98 lines (89 loc) · 3.52 KB
/
getFeatureFlagsInLatestCompositionByFederatedGraph.ts
File metadata and controls
98 lines (89 loc) · 3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import { PlainMessage } from '@bufbuild/protobuf';
import { HandlerContext } from '@connectrpc/connect';
import { EnumStatusCode } from '@wundergraph/cosmo-connect/dist/common/common_pb';
import {
GetFeatureFlagsInLatestCompositionByFederatedGraphRequest,
GetFeatureFlagsInLatestCompositionByFederatedGraphResponse,
} from '@wundergraph/cosmo-connect/dist/platform/v1/platform_pb';
import { FeatureFlagDTO } from '../../../types/index.js';
import { FeatureFlagRepository } from '../../repositories/FeatureFlagRepository.js';
import { FederatedGraphRepository } from '../../repositories/FederatedGraphRepository.js';
import { NamespaceRepository } from '../../repositories/NamespaceRepository.js';
import type { RouterOptions } from '../../routes.js';
import { enrichLogger, getLogger, handleError } from '../../util.js';
import { UnauthorizedError } from '../../errors/errors.js';
export function getFeatureFlagsInLatestCompositionByFederatedGraph(
opts: RouterOptions,
req: GetFeatureFlagsInLatestCompositionByFederatedGraphRequest,
ctx: HandlerContext,
): Promise<PlainMessage<GetFeatureFlagsInLatestCompositionByFederatedGraphResponse>> {
let logger = getLogger(ctx, opts.logger);
return handleError<PlainMessage<GetFeatureFlagsInLatestCompositionByFederatedGraphResponse>>(
ctx,
logger,
async () => {
const authContext = await opts.authenticator.authenticate(ctx.requestHeader);
logger = enrichLogger(ctx, logger, authContext);
const featureFlagRepo = new FeatureFlagRepository(logger, opts.db, authContext.organizationId);
const fedGraphRepo = new FederatedGraphRepository(logger, opts.db, authContext.organizationId);
const namespaceRepo = new NamespaceRepository(opts.db, authContext.organizationId);
const namespace = await namespaceRepo.byName(req.namespace);
if (!namespace) {
return {
response: {
code: EnumStatusCode.ERR_NOT_FOUND,
details: `Namespace ${req.namespace} not found`,
},
featureFlags: [],
};
}
const federatedGraph = await fedGraphRepo.byName(req.federatedGraphName, req.namespace);
if (!federatedGraph) {
return {
response: {
code: EnumStatusCode.ERR_NOT_FOUND,
details: `Federated Graph '${req.federatedGraphName}' not found`,
},
featureFlags: [],
};
}
if (!authContext.rbac.hasFederatedGraphReadAccess(federatedGraph)) {
throw new UnauthorizedError();
}
if (!federatedGraph.schemaVersionId) {
return {
response: {
code: EnumStatusCode.OK,
},
featureFlags: [],
};
}
// Get feature flag IDs from the latest valid composition
const ffsInLatestValidComposition = await featureFlagRepo.getFeatureFlagSchemaVersionsByBaseSchemaVersion({
baseSchemaVersionId: federatedGraph.schemaVersionId,
});
const featureFlags: FeatureFlagDTO[] = [];
if (ffsInLatestValidComposition) {
for (const ff of ffsInLatestValidComposition) {
if (!ff.featureFlagId) {
continue;
}
const flag = await featureFlagRepo.getFeatureFlagById({
featureFlagId: ff.featureFlagId,
namespaceId: namespace.id,
includeSubgraphs: false,
});
if (flag) {
featureFlags.push(flag);
}
}
}
return {
response: {
code: EnumStatusCode.OK,
},
featureFlags,
};
},
);
}