Created
June 25, 2025 09:50
-
-
Save syrusakbary/229d90362e00caf56dc77b91e3ded28a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from typing import Optional, Union | |
| from graphql.language import DocumentNode, Location, OperationType, Source, Token, parse | |
| from graphql.language.ast import Node | |
| class GraphQLDocument: | |
| source: Source | |
| locations: list[Location] | |
| tokens: list[Token] | |
| def __init__( | |
| self, | |
| source: Union[Source, str], | |
| document: Optional[DocumentNode] = None, | |
| locations: Optional[list[Location]] = None, | |
| tokens: Optional[list[Token]] = None, | |
| ): | |
| if isinstance(source, str): | |
| source = Source(source) | |
| if document is None: | |
| document = parse(source) | |
| self.source = source | |
| self.document = document | |
| self.prefix = "" | |
| self.locations = locations or [] | |
| self.tokens = tokens or [] | |
| def use_source(self) -> str: | |
| return "source" | |
| def use_location(self, loc: Location) -> str: | |
| if loc not in self.locations: | |
| self.locations.append(loc) | |
| self.use_token(loc.start_token) | |
| self.use_token(loc.end_token) | |
| location_index = len(self.locations) - 1 | |
| else: | |
| location_index = self.locations.index(loc) | |
| return f"locations[{location_index}]" | |
| def use_token(self, token: Token) -> str: | |
| if token not in self.tokens: | |
| self.tokens.append(token) | |
| token_index = len(self.tokens) - 1 | |
| else: | |
| token_index = self.tokens.index(token) | |
| return f"tokens[{token_index}]" | |
| def to_code(self) -> str: | |
| ident = ",\n " | |
| # Important, this must go before tokens and locations, so those are computed properly | |
| document_repr = self.ast_to_code(self.document) | |
| return f""" | |
| from graphql.language import Source, TokenKind | |
| from graphql.language.ast import * | |
| def get_document(): | |
| source = Source({self.source.body!r}) | |
| tokens = [ | |
| {ident.join([self.token_to_code(token) for token in self.tokens])} | |
| ] | |
| locations = [ | |
| {ident.join([self.loc_to_code(loc) for loc in self.locations])} | |
| ] | |
| document = {document_repr} | |
| return source, tokens, locations, document | |
| """ | |
| @staticmethod | |
| def from_code(code: str) -> "GraphQLDocument": | |
| out = {} | |
| exec(code, out) | |
| get_document = out["get_document"] | |
| source, tokens, locations, document = get_document() | |
| return GraphQLDocument(source=source, document=document, locations=locations, tokens=tokens) | |
| # return GraphQLDocument(source = out['source'], locations = out['locations'], tokens = out['tokens']) | |
| def __eq__(self, other: "GraphQLDocument") -> bool: | |
| return ( | |
| self.source == other.source | |
| and self.locations == other.locations | |
| and self.tokens == other.tokens | |
| ) | |
| def token_to_code(self, token: Token) -> str: | |
| """ | |
| Converts a token into a python code representation of the token. | |
| """ | |
| # prev = self.use_token(token.prev) if token.prev else repr(None) | |
| return "{}Token({}{}, {}, {}, {}, {}, value={})".format( | |
| self.prefix, | |
| self.prefix, | |
| token.kind, | |
| token.start, | |
| token.end, | |
| token.line, | |
| token.column, | |
| repr(token.value), | |
| ) | |
| def loc_to_code(self, loc: Location) -> str: | |
| """ | |
| Converts a location into a python code representation of the location. | |
| """ | |
| return "{}Location({}, {}, {})".format( | |
| self.prefix, | |
| self.use_token(loc.start_token), | |
| self.use_token(loc.end_token), | |
| self.use_source(), | |
| ) | |
| def ast_to_code( | |
| self, | |
| ast: Union[Node, Location, list[Node], OperationType, int, str, float, bool], | |
| indent: int = 0, | |
| ) -> str: | |
| """ | |
| Converts an ast into a python code representation of the AST. | |
| """ | |
| code = [] | |
| def append(line): | |
| return code.append((" " * indent) + line) | |
| if isinstance(ast, Node): | |
| append(f"{self.prefix}{ast.__class__.__name__}(") | |
| indent += 1 | |
| for i, k in enumerate(ast.keys, 1): | |
| v = getattr(ast, k) | |
| append( | |
| "{}={},".format( | |
| k, | |
| self.ast_to_code(v, indent), | |
| ) | |
| ) | |
| indent -= 1 | |
| append(")") | |
| elif isinstance(ast, Location): | |
| append(self.use_location(ast)) | |
| elif isinstance(ast, list): | |
| if ast: | |
| append("[") | |
| indent += 1 | |
| for i, it in enumerate(ast, 1): | |
| is_last = i == len(ast) | |
| append(self.ast_to_code(it, indent) + ("," if not is_last else "")) | |
| indent -= 1 | |
| append("]") | |
| else: | |
| append("[]") | |
| elif ast is None or isinstance(ast, (int, str, float, bool)): | |
| append(repr(ast)) | |
| elif isinstance(ast, OperationType): | |
| append(f"{self.prefix}OperationType.{ast.name}") | |
| else: | |
| raise Exception(f"Unknown ast type: {type(ast)}") | |
| return "\n".join(code).strip() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from graphql.language import Source, ast, parse | |
| from .ast import GraphQLDocument | |
| def test_source(): | |
| source = Source("query { a { b } }") | |
| document = GraphQLDocument(source) | |
| start_token1 = ast.Token(ast.TokenKind.NAME, 1, 1, 1, 1) | |
| start_token2 = ast.Token(ast.TokenKind.NAME, 2, 2, 2, 2) | |
| start_token3 = ast.Token(ast.TokenKind.NAME, 3, 3, 3, 3) | |
| start_token4 = ast.Token(ast.TokenKind.NAME, 4, 4, 4, 4) | |
| start_token5 = ast.Token(ast.TokenKind.NAME, 5, 5, 5, 5) | |
| location_12 = ast.Location(start_token1, start_token2, source) | |
| location_13 = ast.Location(start_token1, start_token3, source) | |
| location_23 = ast.Location(start_token2, start_token3, source) | |
| location_34 = ast.Location(start_token3, start_token4, source) | |
| location_15 = ast.Location(start_token1, start_token5, source) | |
| location_var: str = document.use_location(location_12) | |
| assert location_var == "locations[0]" | |
| assert len(document.locations) == 1 | |
| assert document.locations[0] == location_12 | |
| assert len(document.tokens) == 2 | |
| assert document.tokens[0] == start_token1 | |
| assert document.tokens[1] == start_token2 | |
| location_var: str = document.use_location(location_13) | |
| assert len(document.locations) == 2 | |
| assert location_var == "locations[1]" | |
| assert document.locations[1] == location_13 | |
| assert len(document.tokens) == 3 | |
| assert document.tokens[1] == start_token2 | |
| assert document.tokens[2] == start_token3 | |
| location_var: str = document.use_location(location_23) | |
| assert len(document.locations) == 3 | |
| assert location_var == "locations[2]" | |
| assert document.locations[2] == location_23 | |
| assert len(document.tokens) == 3 | |
| assert document.tokens[0] == start_token1 | |
| assert document.tokens[1] == start_token2 | |
| assert document.tokens[2] == start_token3 | |
| # Repeated location | |
| location_var: str = document.use_location(location_23) | |
| assert len(document.locations) == 3 | |
| assert location_var == "locations[2]" | |
| assert document.locations[2] == location_23 | |
| assert len(document.tokens) == 3 | |
| assert document.tokens[0] == start_token1 | |
| assert document.tokens[1] == start_token2 | |
| assert document.tokens[2] == start_token3 | |
| location_var: str = document.use_location(location_34) | |
| assert len(document.locations) == 4 | |
| assert location_var == "locations[3]" | |
| assert document.locations[3] == location_34 | |
| assert len(document.tokens) == 4 | |
| assert document.tokens[0] == start_token1 | |
| assert document.tokens[1] == start_token2 | |
| assert document.tokens[2] == start_token3 | |
| assert document.tokens[3] == start_token4 | |
| location_var: str = document.use_location(location_15) | |
| assert len(document.locations) == 5 | |
| assert location_var == "locations[4]" | |
| assert document.locations[4] == location_15 | |
| assert len(document.tokens) == 5 | |
| assert document.tokens[0] == start_token1 | |
| assert document.tokens[1] == start_token2 | |
| assert document.tokens[2] == start_token3 | |
| assert document.tokens[3] == start_token4 | |
| assert document.tokens[4] == start_token5 | |
| def test_source_to_code(): | |
| source = Source("query { a { b } }") | |
| document = GraphQLDocument(source) | |
| code = document.to_code() | |
| document2 = GraphQLDocument.from_code(code) | |
| assert document.source == document2.source | |
| assert document.locations == document2.locations | |
| assert document.tokens == document2.tokens | |
| assert document.document == document2.document | |
| assert document == document2 | |
| def test_long_query_benchmark(benchmark): | |
| document = GraphQLDocument(LONG_QUERY) | |
| doc_code = document.to_code() | |
| def get_document(): | |
| document.from_code(doc_code) | |
| # assert document == document2 | |
| benchmark(get_document) | |
| def test_long_query_benchmark_parse(benchmark): | |
| def parse_document(): | |
| parse(LONG_QUERY) | |
| benchmark(parse_document) | |
| LONG_QUERY = """ | |
| query ownerQuery( | |
| $owner: String! | |
| $timeRange: TimeRangeInput | |
| $appIds: [ID] | |
| $appId: ID! | |
| $tabOverview: Boolean! | |
| $tabPkgs: Boolean! | |
| $tabApps: Boolean! | |
| $tabTeam: Boolean! | |
| $tabSettings: Boolean! | |
| $tabUsage: Boolean! | |
| $tabSetGen: Boolean! | |
| $tabSetCollabs: Boolean! | |
| $tabAccToken: Boolean! | |
| $tabBilling: Boolean! | |
| ) { | |
| viewer { | |
| globalName | |
| ...LayoutWrapper_data | |
| ...DashboardActivityViewer_data | |
| ...dashboardNamespaceIntentCardsFragment | |
| ...namespacesCommandDialog | |
| id | |
| } | |
| owner: getGlobalObject(slug: $owner) { | |
| __typename | |
| ... on User { | |
| globalName | |
| ...dashboardUserNavigationHeaderOwner | |
| ...dashboardUserFragment | |
| } | |
| ... on Namespace { | |
| globalName | |
| isAdmin: viewerHasRole(role: ADMIN) | |
| isEditor: viewerHasRole(role: EDITOR) | |
| ...dashboardNamespaceNavigationHeaderOwner | |
| ...dashboardNamespaceFragment | |
| } | |
| ... on Node { | |
| __isNode: __typename | |
| id | |
| } | |
| } | |
| ownerUsage: getGlobalObject(slug: $owner) { | |
| __typename | |
| ...UsageAppRateLimiterCalloutFragment | |
| ... on Node { | |
| __isNode: __typename | |
| id | |
| } | |
| } | |
| ...AppSelectorFragment_2CQkps @include(if: $tabUsage) | |
| } | |
| fragment AccessTokenSettings_viewer on User { | |
| id | |
| apiTokens { | |
| edges { | |
| node { | |
| id | |
| identifier | |
| createdAt | |
| lastUsedAt | |
| revokedAt | |
| } | |
| } | |
| } | |
| } | |
| fragment Account_SettingsAccount on User { | |
| id | |
| username | |
| fullName | |
| bio | |
| avatar | |
| isEmailValidated | |
| githubUrl | |
| twitterUrl | |
| websiteUrl | |
| location | |
| packages { | |
| edges { | |
| node { | |
| id | |
| name | |
| namespace | |
| packageName | |
| icon | |
| } | |
| } | |
| } | |
| } | |
| fragment AppActivityCard_data on DeployApp { | |
| id | |
| activeVersion { | |
| ...AppRowCard_deployAppVersion | |
| id | |
| } | |
| } | |
| fragment AppActivityItem_data on ActivityEvent { | |
| ...DashboardActivityItemHeader_data | |
| id | |
| body { | |
| text | |
| ranges { | |
| entity { | |
| __typename | |
| ... on DeployApp { | |
| id | |
| ...AppActivityCard_data | |
| } | |
| id | |
| } | |
| } | |
| } | |
| } | |
| fragment AppRowCard_deployAppVersion on DeployAppVersion { | |
| favicon | |
| sourcePackage { | |
| icon | |
| name | |
| packageName | |
| owner { | |
| __typename | |
| globalName | |
| ... on Node { | |
| __isNode: __typename | |
| id | |
| } | |
| } | |
| id | |
| } | |
| clientName | |
| isActive | |
| app { | |
| name | |
| owner { | |
| __typename | |
| globalName | |
| ... on Node { | |
| __isNode: __typename | |
| id | |
| } | |
| } | |
| url | |
| id | |
| } | |
| publishedBy { | |
| avatar | |
| fullName | |
| username | |
| id | |
| } | |
| url | |
| screenshot | |
| } | |
| fragment AppSelectorFragment_2CQkps on Query { | |
| selectedApp: node(id: $appId) { | |
| __typename | |
| ... on DeployApp { | |
| activeVersion { | |
| app { | |
| id | |
| name | |
| } | |
| screenshot | |
| id | |
| } | |
| } | |
| id | |
| } | |
| search(query: "", first: 15, apps: {owner: $owner}) { | |
| edges { | |
| node { | |
| __typename | |
| ... on DeployApp { | |
| activeVersion { | |
| app { | |
| id | |
| name | |
| } | |
| screenshot | |
| id | |
| } | |
| } | |
| ... on Node { | |
| __isNode: __typename | |
| id | |
| } | |
| } | |
| cursor | |
| } | |
| pageInfo { | |
| endCursor | |
| hasNextPage | |
| } | |
| } | |
| } | |
| fragment AppVersionActivityCard_data on DeployAppVersion { | |
| id | |
| ...AppRowCard_deployAppVersion | |
| } | |
| fragment AppVersionActivityItem_data on ActivityEvent { | |
| ...DashboardActivityItemHeader_data | |
| id | |
| body { | |
| text | |
| ranges { | |
| entity { | |
| __typename | |
| ... on DeployAppVersion { | |
| id | |
| ...AppVersionActivityCard_data | |
| } | |
| id | |
| } | |
| } | |
| } | |
| } | |
| fragment AuthenticatedNavbarUserAvatar_data on User { | |
| username | |
| avatar | |
| } | |
| fragment BillingPage_viewer on User { | |
| id | |
| username | |
| isEmailValidated | |
| isPro | |
| billing { | |
| paymentMethods { | |
| __typename | |
| ... on CardPaymentMethod { | |
| id | |
| brand | |
| country | |
| expMonth | |
| expYear | |
| funding | |
| last4 | |
| } | |
| ... on Node { | |
| __isNode: __typename | |
| id | |
| } | |
| } | |
| payments { | |
| amount | |
| currency | |
| status | |
| id | |
| } | |
| } | |
| } | |
| fragment BlogPostActivityCard_data on BlogPost { | |
| id | |
| slug | |
| title | |
| tags { | |
| id | |
| name | |
| } | |
| coverImageUrl | |
| } | |
| fragment BlogPostActivityItem_data on ActivityEvent { | |
| ...DashboardActivityItemHeader_data | |
| id | |
| body { | |
| text | |
| ranges { | |
| entity { | |
| __typename | |
| ... on BlogPost { | |
| id | |
| ...BlogPostActivityCard_data | |
| } | |
| id | |
| } | |
| } | |
| } | |
| } | |
| fragment CollabRow_NamespaceCollaborator on NamespaceCollaborator { | |
| id | |
| createdAt | |
| role | |
| user { | |
| userId: id | |
| username | |
| fullName | |
| avatar | |
| id | |
| } | |
| } | |
| fragment CollabRow_NamespaceCollaboratorInvite on NamespaceCollaboratorInvite { | |
| id | |
| createdAt | |
| role | |
| user { | |
| userId: id | |
| username | |
| fullName | |
| avatar | |
| id | |
| } | |
| } | |
| fragment CollaboratorsInvits_NamespacesSettingsNamespace on Namespace { | |
| id | |
| nspPendingInvites: pendingInvites(first: 10) { | |
| totalCount | |
| edges { | |
| node { | |
| nodeType: __typename | |
| id | |
| ...CollabRow_NamespaceCollaboratorInvite | |
| __typename | |
| } | |
| cursor | |
| } | |
| pageInfo { | |
| endCursor | |
| hasNextPage | |
| } | |
| } | |
| } | |
| fragment Collaborators_NamespacesSettingsNamespace on Namespace { | |
| id | |
| nspCollaborators: collaborators(first: 10) { | |
| totalCount | |
| edges { | |
| node { | |
| nodeType: __typename | |
| id | |
| ...CollabRow_NamespaceCollaborator | |
| __typename | |
| } | |
| cursor | |
| } | |
| pageInfo { | |
| endCursor | |
| hasNextPage | |
| } | |
| } | |
| } | |
| fragment DashboardActivityItemHeader_data on ActivityEvent { | |
| body { | |
| ...RenderRanges_data | |
| } | |
| id | |
| actorIcon | |
| createdAt | |
| } | |
| fragment DashboardActivityItem_data on ActivityEvent { | |
| ...DashboardActivityItemHeader_data | |
| ...PackageVersionActivityItem_data | |
| ...PackageActivityItem_data | |
| ...AppActivityItem_data | |
| ...AppVersionActivityItem_data | |
| ...BlogPostActivityItem_data | |
| body { | |
| text | |
| ranges { | |
| packageEntity: entity { | |
| __typename | |
| ... on Package { | |
| id | |
| } | |
| id | |
| } | |
| packageVersionEntity: entity { | |
| __typename | |
| ... on PackageVersion { | |
| id | |
| } | |
| id | |
| } | |
| blogPostEntity: entity { | |
| __typename | |
| ... on BlogPost { | |
| id | |
| } | |
| id | |
| } | |
| appEntity: entity { | |
| __typename | |
| ... on DeployApp { | |
| id | |
| } | |
| id | |
| } | |
| appVersionEntity: entity { | |
| __typename | |
| ... on DeployAppVersion { | |
| id | |
| } | |
| id | |
| } | |
| } | |
| } | |
| } | |
| fragment DashboardActivityViewer_data on User { | |
| registerIntent | |
| firstName | |
| username | |
| } | |
| fragment HeaderFragment on User { | |
| globalName | |
| ...AuthenticatedNavbarUserAvatar_data | |
| ...NotificationMenu_fragment_User | |
| } | |
| fragment Intercom_viewer on User { | |
| id | |
| username | |
| avatar | |
| dateJoined | |
| fullName | |
| } | |
| fragment LayoutWrapper_data on User { | |
| id | |
| fullName | |
| avatar | |
| ...Intercom_viewer | |
| ...HeaderFragment | |
| } | |
| fragment NamespacesSettings_general on Namespace { | |
| id | |
| name | |
| avatar | |
| displayName | |
| description | |
| githubHandle | |
| twitterHandle | |
| websiteUrl | |
| packages { | |
| totalCount | |
| edges { | |
| node { | |
| id | |
| name | |
| namespace | |
| packageName | |
| icon | |
| } | |
| } | |
| } | |
| } | |
| fragment NotificationItemInvitCollabNsp_UserNotificationKindIncomingNamespaceInvite on UserNotification { | |
| id | |
| icon | |
| seenState | |
| createdAt | |
| kind { | |
| __typename | |
| ... on UserNotificationKindIncomingNamespaceInvite { | |
| namespaceInvite { | |
| id | |
| createdAt | |
| declinedBy { | |
| globalName | |
| avatar | |
| id | |
| } | |
| approvedBy { | |
| globalName | |
| avatar | |
| id | |
| } | |
| requestedBy { | |
| globalName | |
| avatar | |
| id | |
| } | |
| namespace { | |
| globalId | |
| globalName | |
| displayName | |
| avatar | |
| id | |
| } | |
| } | |
| } | |
| } | |
| } | |
| fragment NotificationItemInvitCollabPkg_UserNotificationKindIncomingPackageInvite on UserNotification { | |
| id | |
| icon | |
| seenState | |
| createdAt | |
| kind { | |
| __typename | |
| ... on UserNotificationKindIncomingPackageInvite { | |
| packageInvite { | |
| id | |
| createdAt | |
| declinedBy { | |
| globalName | |
| avatar | |
| id | |
| } | |
| approvedBy { | |
| globalName | |
| avatar | |
| id | |
| } | |
| requestedBy { | |
| globalName | |
| avatar | |
| id | |
| } | |
| package { | |
| owner { | |
| __typename | |
| globalName | |
| ... on Node { | |
| __isNode: __typename | |
| id | |
| } | |
| } | |
| packageName | |
| icon | |
| id | |
| } | |
| } | |
| } | |
| } | |
| } | |
| fragment NotificationItemReqTransfertPkg_UserNotificationKindIncomingPackageInvite on UserNotification { | |
| id | |
| icon | |
| seenState | |
| createdAt | |
| kind { | |
| __typename | |
| ... on UserNotificationKindIncomingPackageTransfer { | |
| packageTransferRequest { | |
| id | |
| createdAt | |
| declinedBy { | |
| globalName | |
| avatar | |
| id | |
| } | |
| approvedBy { | |
| globalName | |
| avatar | |
| id | |
| } | |
| requestedBy { | |
| globalName | |
| avatar | |
| id | |
| } | |
| package { | |
| owner { | |
| __typename | |
| globalName | |
| ... on Node { | |
| __isNode: __typename | |
| id | |
| } | |
| } | |
| packageName | |
| icon | |
| id | |
| } | |
| } | |
| } | |
| } | |
| } | |
| fragment NotificationItemValidateEmail_UserNotificationKindValidateEmail on UserNotification { | |
| id | |
| icon | |
| seenState | |
| createdAt | |
| kind { | |
| __typename | |
| ... on UserNotificationKindValidateEmail { | |
| user { | |
| id | |
| username | |
| fullName | |
| avatar | |
| isEmailValidated | |
| } | |
| } | |
| } | |
| } | |
| fragment NotificationMenuItem_UserNotification on UserNotification { | |
| id | |
| body { | |
| ...RenderRanges_data | |
| text | |
| ranges { | |
| entity { | |
| __typename | |
| ...RenderRangesEntity | |
| ... on User { | |
| id | |
| avatar | |
| } | |
| id | |
| } | |
| offset | |
| length | |
| } | |
| } | |
| icon | |
| seenState | |
| createdAt | |
| ...NotificationItemInvitCollabNsp_UserNotificationKindIncomingNamespaceInvite | |
| ...NotificationItemInvitCollabPkg_UserNotificationKindIncomingPackageInvite | |
| ...NotificationItemReqTransfertPkg_UserNotificationKindIncomingPackageInvite | |
| ...NotificationItemValidateEmail_UserNotificationKindValidateEmail | |
| kind { | |
| __typename | |
| ... on UserNotificationKindIncomingPackageTransfer { | |
| __typename | |
| } | |
| ... on UserNotificationKindIncomingPackageInvite { | |
| __typename | |
| } | |
| ... on UserNotificationKindIncomingNamespaceInvite { | |
| __typename | |
| } | |
| ... on UserNotificationKindValidateEmail { | |
| __typename | |
| } | |
| } | |
| } | |
| fragment NotificationMenu_fragment_User on User { | |
| id | |
| notifications(first: 4) { | |
| hasPendingNotifications | |
| edges { | |
| node { | |
| id | |
| ...NotificationMenuItem_UserNotification | |
| seenState | |
| __typename | |
| } | |
| cursor | |
| } | |
| pageInfo { | |
| endCursor | |
| hasNextPage | |
| } | |
| } | |
| } | |
| fragment PackageActivityCard_data on Package { | |
| id | |
| lastVersion { | |
| ...PackageCard_data | |
| id | |
| } | |
| } | |
| fragment PackageActivityItem_data on ActivityEvent { | |
| ...DashboardActivityItemHeader_data | |
| id | |
| body { | |
| text | |
| ranges { | |
| entity { | |
| __typename | |
| ... on Package { | |
| id | |
| ...PackageActivityCard_data | |
| } | |
| id | |
| } | |
| } | |
| } | |
| } | |
| fragment PackageCard_data on PackageVersion { | |
| typeResult: __typename | |
| description | |
| package { | |
| id | |
| icon | |
| packageName | |
| likersCount | |
| viewerHasLiked | |
| showDeployButton | |
| owner { | |
| __typename | |
| globalName | |
| ... on Node { | |
| __isNode: __typename | |
| id | |
| } | |
| } | |
| collaborators { | |
| totalCount | |
| edges { | |
| node { | |
| id | |
| user { | |
| avatar | |
| username | |
| fullName | |
| id | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| fragment PackageVersionActivityCard_data on PackageVersion { | |
| id | |
| ...PackageCard_data | |
| } | |
| fragment PackageVersionActivityItem_data on ActivityEvent { | |
| ...DashboardActivityItemHeader_data | |
| id | |
| body { | |
| text | |
| ranges { | |
| entity { | |
| __typename | |
| ... on PackageVersion { | |
| id | |
| ...PackageVersionActivityCard_data | |
| } | |
| id | |
| } | |
| } | |
| } | |
| } | |
| fragment RenderRangesEntity on Node { | |
| __isNode: __typename | |
| __typename | |
| id | |
| ... on User { | |
| username | |
| } | |
| ... on Package { | |
| id | |
| name | |
| likersCount | |
| downloadsCount | |
| packageName | |
| owner { | |
| __typename | |
| globalName | |
| ... on Node { | |
| __isNode: __typename | |
| id | |
| } | |
| } | |
| watchersCount | |
| viewerHasLiked | |
| viewerIsWatching | |
| } | |
| ... on PackageVersion { | |
| id | |
| version | |
| package { | |
| id | |
| icon | |
| name | |
| packageName | |
| owner { | |
| __typename | |
| globalName | |
| ... on Node { | |
| __isNode: __typename | |
| id | |
| } | |
| } | |
| likersCount | |
| downloadsCount | |
| watchersCount | |
| viewerHasLiked | |
| viewerIsWatching | |
| } | |
| } | |
| ... on Namespace { | |
| globalName | |
| } | |
| ... on BlogPost { | |
| slug | |
| } | |
| ... on DeployApp { | |
| name | |
| owner { | |
| __typename | |
| globalName | |
| ... on Node { | |
| __isNode: __typename | |
| id | |
| } | |
| } | |
| } | |
| } | |
| fragment RenderRanges_data on EventBody { | |
| text | |
| ranges { | |
| entity { | |
| __typename | |
| ...RenderRangesEntity | |
| id | |
| } | |
| offset | |
| length | |
| } | |
| } | |
| fragment UsageAppRateLimiterCalloutFragment on Owner { | |
| __isOwner: __typename | |
| __typename | |
| ... on User { | |
| limitState | |
| probationStartedAt | |
| currentUsage { | |
| cpuTime { | |
| nearingLimits | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| noRequests { | |
| nearingLimits | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| ingress { | |
| nearingLimits | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| egress { | |
| nearingLimits | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| } | |
| } | |
| ... on Namespace { | |
| limitState | |
| probationStartedAt | |
| currentUsage { | |
| cpuTime { | |
| nearingLimits | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| noRequests { | |
| nearingLimits | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| ingress { | |
| nearingLimits | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| egress { | |
| nearingLimits | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| } | |
| } | |
| } | |
| fragment dashboardNamespaceAppsFragment on Namespace { | |
| apps(first: 5, sortBy: NEWEST) { | |
| totalCount | |
| edges { | |
| node { | |
| id | |
| activeVersion { | |
| ...AppRowCard_deployAppVersion | |
| id | |
| } | |
| __typename | |
| } | |
| cursor | |
| } | |
| pageInfo { | |
| endCursor | |
| hasNextPage | |
| } | |
| } | |
| id | |
| } | |
| fragment dashboardNamespaceFragment on Namespace { | |
| isAdmin: viewerHasRole(role: ADMIN) | |
| ...dashboardNamespaceHeaderFragment | |
| ...dashboardNamespaceNavigationFragment | |
| ...dashboardNamespaceOverviewFragment @include(if: $tabOverview) | |
| ...dashboardNamespaceAppsFragment @include(if: $tabApps) | |
| ...dashboardNamespacePackagesFragment @include(if: $tabPkgs) | |
| ...dashboardNamespaceTeamFragment @include(if: $tabTeam) | |
| ...dashboardNamespaceSettingsFragment @include(if: $tabSettings) | |
| ...dashboardNamespaceUsageFragment_1LoqyQ @include(if: $tabUsage) | |
| ...dashboardNamespaceInvitationsFragment | |
| } | |
| fragment dashboardNamespaceHeaderFragment on Namespace { | |
| globalName | |
| avatar | |
| displayName | |
| description | |
| twitterHandle | |
| githubHandle | |
| websiteUrl | |
| collaborators { | |
| totalCount | |
| edges { | |
| node { | |
| user { | |
| id | |
| avatar | |
| username | |
| } | |
| id | |
| } | |
| } | |
| } | |
| } | |
| fragment dashboardNamespaceIntentCardsFragment on User { | |
| ...dashboardNamespaceOverviewIntentCardsFragment | |
| } | |
| fragment dashboardNamespaceInvitationsFragment on Namespace { | |
| globalName | |
| avatar | |
| viewerIsInvited | |
| viewerInvitation { | |
| id | |
| requestedBy { | |
| id | |
| fullName | |
| username | |
| } | |
| } | |
| } | |
| fragment dashboardNamespaceNavigationFragment on Namespace { | |
| globalName | |
| isAdmin: viewerHasRole(role: ADMIN) | |
| } | |
| fragment dashboardNamespaceNavigationHeaderOwner on Namespace { | |
| globalName | |
| avatar | |
| } | |
| fragment dashboardNamespaceOverviewActivityFragment on Namespace { | |
| activity: publicActivity(first: 6) { | |
| edges { | |
| node { | |
| id | |
| ...DashboardActivityItem_data | |
| __typename | |
| } | |
| cursor | |
| } | |
| pageInfo { | |
| endCursor | |
| hasNextPage | |
| } | |
| } | |
| id | |
| } | |
| fragment dashboardNamespaceOverviewAppsFragment on Namespace { | |
| globalName | |
| newestApps: apps(first: 5, sortBy: NEWEST) { | |
| totalCount | |
| edges { | |
| node { | |
| activeVersion { | |
| id | |
| ...AppRowCard_deployAppVersion | |
| } | |
| id | |
| } | |
| } | |
| } | |
| } | |
| fragment dashboardNamespaceOverviewFragment on Namespace { | |
| ...dashboardNamespaceOverviewActivityFragment | |
| ...dashboardNamespaceOverviewAppsFragment | |
| ...dashboardNamespaceOverviewPackagesFragment | |
| } | |
| fragment dashboardNamespaceOverviewIntentCardsFragment on User { | |
| isViewer | |
| registerIntent | |
| activeApps: apps(sortBy: MOST_ACTIVE) { | |
| totalCount | |
| } | |
| } | |
| fragment dashboardNamespaceOverviewPackagesFragment on Namespace { | |
| globalName | |
| popularPackages: packages(first: 5) { | |
| totalCount | |
| edges { | |
| node { | |
| id | |
| lastVersion { | |
| ...PackageCard_data | |
| id | |
| } | |
| } | |
| } | |
| } | |
| } | |
| fragment dashboardNamespacePackagesFragment on Namespace { | |
| pkgVersions: packageVersions(first: 10) { | |
| totalCount | |
| edges { | |
| node { | |
| id | |
| ...PackageCard_data | |
| __typename | |
| } | |
| cursor | |
| } | |
| pageInfo { | |
| endCursor | |
| hasNextPage | |
| } | |
| } | |
| id | |
| } | |
| fragment dashboardNamespaceSettingsFragment on Namespace { | |
| globalName | |
| avatar | |
| displayName | |
| ...dashboardNamespaceSettingsNavigation | |
| ...NamespacesSettings_general @include(if: $tabSetGen) | |
| ...Collaborators_NamespacesSettingsNamespace @include(if: $tabSetCollabs) | |
| ...CollaboratorsInvits_NamespacesSettingsNamespace @include(if: $tabSetCollabs) | |
| } | |
| fragment dashboardNamespaceSettingsNavigation on Namespace { | |
| globalName | |
| } | |
| fragment dashboardNamespaceTeamFragment on Namespace { | |
| id | |
| nspTeam: collaborators(first: 10) { | |
| totalCount | |
| edges { | |
| node { | |
| nodeType: __typename | |
| id | |
| ...CollabRow_NamespaceCollaborator | |
| __typename | |
| } | |
| cursor | |
| } | |
| pageInfo { | |
| endCursor | |
| hasNextPage | |
| } | |
| } | |
| } | |
| fragment dashboardNamespaceUsageFragment_1LoqyQ on Namespace { | |
| globalName | |
| avatar | |
| networkIngress: usageMetrics(timeRange: $timeRange, variant: network_ingress, appIds: $appIds, grouping: BY_DAY) { | |
| value | |
| unit | |
| timestamp | |
| } | |
| networkEgress: usageMetrics(timeRange: $timeRange, variant: network_egress, appIds: $appIds, grouping: BY_DAY) { | |
| value | |
| unit | |
| timestamp | |
| } | |
| cpuTime: usageMetrics(timeRange: $timeRange, variant: cpu_time, appIds: $appIds, grouping: BY_DAY) { | |
| value | |
| unit | |
| timestamp | |
| } | |
| noRequests: usageMetrics(timeRange: $timeRange, variant: no_of_requests, appIds: $appIds, grouping: BY_DAY) { | |
| value | |
| unit | |
| timestamp | |
| } | |
| noFailedRequests: usageMetrics(timeRange: $timeRange, variant: no_of_failed_requests, appIds: $appIds, grouping: BY_DAY) { | |
| value | |
| unit | |
| timestamp | |
| } | |
| currentUsage(appIds: $appIds, timeRange: $timeRange) { | |
| since | |
| cpuTime { | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| noRequests { | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| ingress { | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| egress { | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| buildMinutes { | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| appCount { | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| } | |
| id | |
| } | |
| fragment dashboardUserAppsFragment on User { | |
| apps(first: 5, sortBy: NEWEST) { | |
| totalCount | |
| edges { | |
| node { | |
| id | |
| activeVersion { | |
| ...AppRowCard_deployAppVersion | |
| id | |
| } | |
| __typename | |
| } | |
| cursor | |
| } | |
| pageInfo { | |
| endCursor | |
| hasNextPage | |
| } | |
| } | |
| id | |
| } | |
| fragment dashboardUserFragment on User { | |
| isViewer | |
| canSeeApps: viewerCan(action: DEPLOY_APP) | |
| ...dashboardUserHeaderFragment | |
| ...dashboardUserNavigationFragment | |
| ...dashboardUserOverviewFragment @include(if: $tabOverview) | |
| ...dashboardUserAppsFragment @include(if: $tabApps) | |
| ...dashboardUserPackagesFragment @include(if: $tabPkgs) | |
| ...dashboardUserSettingsFragment @include(if: $tabSettings) | |
| ...dashboardUserUsageFragment_1LoqyQ @include(if: $tabUsage) | |
| } | |
| fragment dashboardUserHeaderFragment on User { | |
| globalName | |
| avatar | |
| firstName | |
| lastName | |
| bio | |
| fullName | |
| githubUrl | |
| twitterUrl | |
| websiteUrl | |
| } | |
| fragment dashboardUserNavigationFragment on User { | |
| globalName | |
| isViewer | |
| } | |
| fragment dashboardUserNavigationHeaderOwner on User { | |
| globalName | |
| avatar | |
| } | |
| fragment dashboardUserOverviewActivityFragment on User { | |
| activity: publicActivity(first: 6) { | |
| edges { | |
| node { | |
| id | |
| ...DashboardActivityItem_data | |
| __typename | |
| } | |
| cursor | |
| } | |
| pageInfo { | |
| endCursor | |
| hasNextPage | |
| } | |
| } | |
| id | |
| } | |
| fragment dashboardUserOverviewAppsFragment on User { | |
| globalName | |
| newestApps: apps(first: 5, sortBy: NEWEST) { | |
| totalCount | |
| edges { | |
| node { | |
| activeVersion { | |
| id | |
| ...AppRowCard_deployAppVersion | |
| } | |
| id | |
| } | |
| } | |
| } | |
| } | |
| fragment dashboardUserOverviewFragment on User { | |
| isViewer | |
| registerIntent | |
| activeApps: apps(sortBy: MOST_ACTIVE) { | |
| totalCount | |
| } | |
| ...dashboardUserOverviewActivityFragment | |
| ...dashboardUserOverviewAppsFragment | |
| ...dashboardUserOverviewPackagesFragment | |
| } | |
| fragment dashboardUserOverviewPackagesFragment on User { | |
| isViewer | |
| globalName | |
| popularPackages: packages(first: 5) { | |
| totalCount | |
| edges { | |
| node { | |
| id | |
| lastVersion { | |
| ...PackageCard_data | |
| id | |
| } | |
| } | |
| } | |
| } | |
| } | |
| fragment dashboardUserPackagesFragment on User { | |
| isViewer | |
| pkgVersions: packageVersions(first: 10) { | |
| totalCount | |
| edges { | |
| node { | |
| id | |
| ...PackageCard_data | |
| __typename | |
| } | |
| cursor | |
| } | |
| pageInfo { | |
| endCursor | |
| hasNextPage | |
| } | |
| } | |
| id | |
| } | |
| fragment dashboardUserSettingsFragment on User { | |
| globalName | |
| avatar | |
| ...dashboardUserSettingsNavigation | |
| ...Account_SettingsAccount @include(if: $tabSetGen) | |
| ...AccessTokenSettings_viewer @include(if: $tabAccToken) | |
| ...BillingPage_viewer @include(if: $tabBilling) | |
| } | |
| fragment dashboardUserSettingsNavigation on User { | |
| globalName | |
| } | |
| fragment dashboardUserUsageFragment_1LoqyQ on User { | |
| globalName | |
| avatar | |
| networkIngress: usageMetrics(timeRange: $timeRange, variant: network_ingress, appIds: $appIds, grouping: BY_DAY) { | |
| value | |
| unit | |
| timestamp | |
| } | |
| networkEgress: usageMetrics(timeRange: $timeRange, variant: network_egress, appIds: $appIds, grouping: BY_DAY) { | |
| value | |
| unit | |
| timestamp | |
| } | |
| cpuTime: usageMetrics(timeRange: $timeRange, variant: cpu_time, appIds: $appIds, grouping: BY_DAY) { | |
| value | |
| unit | |
| timestamp | |
| } | |
| noRequests: usageMetrics(timeRange: $timeRange, variant: no_of_requests, appIds: $appIds, grouping: BY_DAY) { | |
| value | |
| unit | |
| timestamp | |
| } | |
| noFailedRequests: usageMetrics(timeRange: $timeRange, variant: no_of_failed_requests, appIds: $appIds, grouping: BY_DAY) { | |
| value | |
| unit | |
| timestamp | |
| } | |
| currentUsage(appIds: $appIds, timeRange: $timeRange) { | |
| cpuTime { | |
| nearingLimits | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| noRequests { | |
| nearingLimits | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| ingress { | |
| nearingLimits | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| egress { | |
| nearingLimits | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| buildMinutes { | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| appCount { | |
| used | |
| usedPercent | |
| max | |
| unit | |
| charge { | |
| amount | |
| currency | |
| } | |
| } | |
| } | |
| id | |
| } | |
| fragment namespacesCommandDialog on User { | |
| globalName | |
| fullName | |
| avatar | |
| isPro | |
| namespaces(first: 10) { | |
| edges { | |
| node { | |
| id | |
| avatar | |
| displayName | |
| globalName | |
| description | |
| isPro | |
| __typename | |
| } | |
| cursor | |
| } | |
| pageInfo { | |
| endCursor | |
| hasNextPage | |
| } | |
| } | |
| id | |
| } | |
| """ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment