Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15,745 changes: 8,050 additions & 7,695 deletions connect-go/gen/proto/wg/cosmo/platform/v1/platform.pb.go

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

24 changes: 23 additions & 1 deletion connect/src/wg/cosmo/platform/v1/platform_connect.ts

Large diffs are not rendered by default.

215 changes: 200 additions & 15 deletions connect/src/wg/cosmo/platform/v1/platform_pb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3593,19 +3593,6 @@ export class GetFederatedGraphByNameResponse extends Message<GetFederatedGraphBy
*/
graphRequestToken = "";

/**
* @generated from field: repeated wg.cosmo.platform.v1.FeatureFlag featureFlagsInLatestValidComposition = 5;
*/
featureFlagsInLatestValidComposition: FeatureFlag[] = [];

/**
* includes all the feature subgraphs that are part of the federated graph;
* even the ones that are not part of the latest composition
*
* @generated from field: repeated wg.cosmo.platform.v1.Subgraph featureSubgraphs = 6;
*/
featureSubgraphs: Subgraph[] = [];

constructor(data?: PartialMessage<GetFederatedGraphByNameResponse>) {
super();
proto3.util.initPartial(data, this);
Expand All @@ -3618,8 +3605,6 @@ export class GetFederatedGraphByNameResponse extends Message<GetFederatedGraphBy
{ no: 2, name: "graph", kind: "message", T: FederatedGraph },
{ no: 3, name: "subgraphs", kind: "message", T: Subgraph, repeated: true },
{ no: 4, name: "graphRequestToken", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 5, name: "featureFlagsInLatestValidComposition", kind: "message", T: FeatureFlag, repeated: true },
{ no: 6, name: "featureSubgraphs", kind: "message", T: Subgraph, repeated: true },
]);

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetFederatedGraphByNameResponse {
Expand Down Expand Up @@ -19824,6 +19809,206 @@ export class GetFeatureFlagsByFederatedGraphResponse extends Message<GetFeatureF
}
}

/**
* @generated from message wg.cosmo.platform.v1.GetFeatureFlagsInLatestCompositionByFederatedGraphRequest
*/
export class GetFeatureFlagsInLatestCompositionByFederatedGraphRequest extends Message<GetFeatureFlagsInLatestCompositionByFederatedGraphRequest> {
/**
* @generated from field: string federated_graph_name = 1;
*/
federatedGraphName = "";

/**
* @generated from field: string namespace = 2;
*/
namespace = "";

constructor(data?: PartialMessage<GetFeatureFlagsInLatestCompositionByFederatedGraphRequest>) {
super();
proto3.util.initPartial(data, this);
}

static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "wg.cosmo.platform.v1.GetFeatureFlagsInLatestCompositionByFederatedGraphRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "federated_graph_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "namespace", kind: "scalar", T: 9 /* ScalarType.STRING */ },
]);

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetFeatureFlagsInLatestCompositionByFederatedGraphRequest {
return new GetFeatureFlagsInLatestCompositionByFederatedGraphRequest().fromBinary(bytes, options);
}

static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetFeatureFlagsInLatestCompositionByFederatedGraphRequest {
return new GetFeatureFlagsInLatestCompositionByFederatedGraphRequest().fromJson(jsonValue, options);
}

static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetFeatureFlagsInLatestCompositionByFederatedGraphRequest {
return new GetFeatureFlagsInLatestCompositionByFederatedGraphRequest().fromJsonString(jsonString, options);
}

static equals(a: GetFeatureFlagsInLatestCompositionByFederatedGraphRequest | PlainMessage<GetFeatureFlagsInLatestCompositionByFederatedGraphRequest> | undefined, b: GetFeatureFlagsInLatestCompositionByFederatedGraphRequest | PlainMessage<GetFeatureFlagsInLatestCompositionByFederatedGraphRequest> | undefined): boolean {
return proto3.util.equals(GetFeatureFlagsInLatestCompositionByFederatedGraphRequest, a, b);
}
}

/**
* @generated from message wg.cosmo.platform.v1.GetFeatureFlagsInLatestCompositionByFederatedGraphResponse
*/
export class GetFeatureFlagsInLatestCompositionByFederatedGraphResponse extends Message<GetFeatureFlagsInLatestCompositionByFederatedGraphResponse> {
/**
* @generated from field: wg.cosmo.platform.v1.Response response = 1;
*/
response?: Response;

/**
* feature flags that are part of the latest valid composition of the federated graph
*
* @generated from field: repeated wg.cosmo.platform.v1.FeatureFlag feature_flags = 2;
*/
featureFlags: FeatureFlag[] = [];

constructor(data?: PartialMessage<GetFeatureFlagsInLatestCompositionByFederatedGraphResponse>) {
super();
proto3.util.initPartial(data, this);
}

static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "wg.cosmo.platform.v1.GetFeatureFlagsInLatestCompositionByFederatedGraphResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "response", kind: "message", T: Response },
{ no: 2, name: "feature_flags", kind: "message", T: FeatureFlag, repeated: true },
]);

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetFeatureFlagsInLatestCompositionByFederatedGraphResponse {
return new GetFeatureFlagsInLatestCompositionByFederatedGraphResponse().fromBinary(bytes, options);
}

static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetFeatureFlagsInLatestCompositionByFederatedGraphResponse {
return new GetFeatureFlagsInLatestCompositionByFederatedGraphResponse().fromJson(jsonValue, options);
}

static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetFeatureFlagsInLatestCompositionByFederatedGraphResponse {
return new GetFeatureFlagsInLatestCompositionByFederatedGraphResponse().fromJsonString(jsonString, options);
}

static equals(a: GetFeatureFlagsInLatestCompositionByFederatedGraphResponse | PlainMessage<GetFeatureFlagsInLatestCompositionByFederatedGraphResponse> | undefined, b: GetFeatureFlagsInLatestCompositionByFederatedGraphResponse | PlainMessage<GetFeatureFlagsInLatestCompositionByFederatedGraphResponse> | undefined): boolean {
return proto3.util.equals(GetFeatureFlagsInLatestCompositionByFederatedGraphResponse, a, b);
}
}

/**
* @generated from message wg.cosmo.platform.v1.GetFeatureSubgraphsByFederatedGraphRequest
*/
export class GetFeatureSubgraphsByFederatedGraphRequest extends Message<GetFeatureSubgraphsByFederatedGraphRequest> {
/**
* @generated from field: string federated_graph_name = 1;
*/
federatedGraphName = "";

/**
* @generated from field: string namespace = 2;
*/
namespace = "";

/**
* @generated from field: int32 limit = 3;
*/
limit = 0;

/**
* @generated from field: int32 offset = 4;
*/
offset = 0;

/**
* @generated from field: optional string query = 5;
*/
query?: string;

constructor(data?: PartialMessage<GetFeatureSubgraphsByFederatedGraphRequest>) {
super();
proto3.util.initPartial(data, this);
}

static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "wg.cosmo.platform.v1.GetFeatureSubgraphsByFederatedGraphRequest";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "federated_graph_name", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 2, name: "namespace", kind: "scalar", T: 9 /* ScalarType.STRING */ },
{ no: 3, name: "limit", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
{ no: 4, name: "offset", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
{ no: 5, name: "query", kind: "scalar", T: 9 /* ScalarType.STRING */, opt: true },
]);

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetFeatureSubgraphsByFederatedGraphRequest {
return new GetFeatureSubgraphsByFederatedGraphRequest().fromBinary(bytes, options);
}

static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetFeatureSubgraphsByFederatedGraphRequest {
return new GetFeatureSubgraphsByFederatedGraphRequest().fromJson(jsonValue, options);
}

static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetFeatureSubgraphsByFederatedGraphRequest {
return new GetFeatureSubgraphsByFederatedGraphRequest().fromJsonString(jsonString, options);
}

static equals(a: GetFeatureSubgraphsByFederatedGraphRequest | PlainMessage<GetFeatureSubgraphsByFederatedGraphRequest> | undefined, b: GetFeatureSubgraphsByFederatedGraphRequest | PlainMessage<GetFeatureSubgraphsByFederatedGraphRequest> | undefined): boolean {
return proto3.util.equals(GetFeatureSubgraphsByFederatedGraphRequest, a, b);
}
}

/**
* @generated from message wg.cosmo.platform.v1.GetFeatureSubgraphsByFederatedGraphResponse
*/
export class GetFeatureSubgraphsByFederatedGraphResponse extends Message<GetFeatureSubgraphsByFederatedGraphResponse> {
/**
* @generated from field: wg.cosmo.platform.v1.Response response = 1;
*/
response?: Response;

/**
* all unique feature subgraphs across all feature flags of the federated graph
*
* @generated from field: repeated wg.cosmo.platform.v1.Subgraph feature_subgraphs = 2;
*/
featureSubgraphs: Subgraph[] = [];

/**
* @generated from field: int32 total_count = 3;
*/
totalCount = 0;

constructor(data?: PartialMessage<GetFeatureSubgraphsByFederatedGraphResponse>) {
super();
proto3.util.initPartial(data, this);
}

static readonly runtime: typeof proto3 = proto3;
static readonly typeName = "wg.cosmo.platform.v1.GetFeatureSubgraphsByFederatedGraphResponse";
static readonly fields: FieldList = proto3.util.newFieldList(() => [
{ no: 1, name: "response", kind: "message", T: Response },
{ no: 2, name: "feature_subgraphs", kind: "message", T: Subgraph, repeated: true },
{ no: 3, name: "total_count", kind: "scalar", T: 5 /* ScalarType.INT32 */ },
]);

static fromBinary(bytes: Uint8Array, options?: Partial<BinaryReadOptions>): GetFeatureSubgraphsByFederatedGraphResponse {
return new GetFeatureSubgraphsByFederatedGraphResponse().fromBinary(bytes, options);
}

static fromJson(jsonValue: JsonValue, options?: Partial<JsonReadOptions>): GetFeatureSubgraphsByFederatedGraphResponse {
return new GetFeatureSubgraphsByFederatedGraphResponse().fromJson(jsonValue, options);
}

static fromJsonString(jsonString: string, options?: Partial<JsonReadOptions>): GetFeatureSubgraphsByFederatedGraphResponse {
return new GetFeatureSubgraphsByFederatedGraphResponse().fromJsonString(jsonString, options);
}

static equals(a: GetFeatureSubgraphsByFederatedGraphResponse | PlainMessage<GetFeatureSubgraphsByFederatedGraphResponse> | undefined, b: GetFeatureSubgraphsByFederatedGraphResponse | PlainMessage<GetFeatureSubgraphsByFederatedGraphResponse> | undefined): boolean {
return proto3.util.equals(GetFeatureSubgraphsByFederatedGraphResponse, a, b);
}
}

/**
* @generated from message wg.cosmo.platform.v1.GetOrganizationWebhookHistoryRequest
*/
Expand Down
10 changes: 10 additions & 0 deletions controlplane/src/core/bufservices/PlatformService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ import { enableFeatureFlag } from './feature-flag/enableFeatureFlag.js';
import { getFeatureFlagByName } from './feature-flag/getFeatureFlagByName.js';
import { getFeatureFlags } from './feature-flag/getFeatureFlags.js';
import { getFeatureFlagsByFederatedGraph } from './feature-flag/getFeatureFlagsByFederatedGraph.js';
import { getFeatureFlagsInLatestCompositionByFederatedGraph } from './feature-flag/getFeatureFlagsInLatestCompositionByFederatedGraph.js';
import { getFeatureSubgraphs } from './feature-flag/getFeatureSubgraphs.js';
import { getFeatureSubgraphsByFederatedGraph } from './feature-flag/getFeatureSubgraphsByFederatedGraph.js';
import { getFeatureSubgraphsByFeatureFlag } from './feature-flag/getFeatureSubgraphsByFeatureFlag.js';
import { updateFeatureFlag } from './feature-flag/updateFeatureFlag.js';
import { checkFederatedGraph } from './federated-graph/checkFederatedGraph.js';
Expand Down Expand Up @@ -755,6 +757,14 @@ export default function (opts: RouterOptions): Partial<ServiceImpl<typeof Platfo
return getFeatureFlagsByFederatedGraph(opts, req, ctx);
},

getFeatureFlagsInLatestCompositionByFederatedGraph: (req, ctx) => {
return getFeatureFlagsInLatestCompositionByFederatedGraph(opts, req, ctx);
},

getFeatureSubgraphsByFederatedGraph: (req, ctx) => {
return getFeatureSubgraphsByFederatedGraph(opts, req, ctx);
},

getOrganizationWebhookHistory: (req, ctx) => {
return getOrganizationWebhookHistory(opts, req, ctx);
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,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,
};
},
);
}
Loading
Loading