Skip to content

Commit

Permalink
Merge pull request #134 from HassanBahati/additional-useConnectQuery-…
Browse files Browse the repository at this point in the history
…useConnectMutation-tests
  • Loading branch information
Ehesp authored Dec 23, 2024
2 parents 0d72bef + d9df02c commit bb94a9c
Show file tree
Hide file tree
Showing 6 changed files with 668 additions and 59 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ jobs:

- name: Start Firebase Emulator Suite
uses: invertase/[email protected]
with:
emulators: 'auth,firestore,functions,storage,database,dataconnect'

- name: Verify Running Emulators
run: |
Expand Down
174 changes: 145 additions & 29 deletions dataconnect/.dataconnect/schema/prelude.gql
Original file line number Diff line number Diff line change
Expand Up @@ -120,26 +120,6 @@ input String_Filter {
`LIKE '%value'`
"""
endsWith: String
"""
Match if field value matches the provided pattern. See `String_Pattern` for
more details.
"""
pattern: String_Pattern
}

"""
The pattern match condition on a string. Specify either like or regex.
https://www.postgresql.org/docs/current/functions-matching.html
"""
input String_Pattern {
"Match using the provided `LIKE` expression."
like: String
"Match using the provided POSIX regular expression."
regex: String
"When true, ignore case when matching."
ignoreCase: Boolean
"When true, invert the match result. Equivalent to `NOT LIKE` or `!~`."
invert: Boolean
}

"Query filter criteris for `[String!]` scalar fields."
Expand Down Expand Up @@ -465,11 +445,6 @@ directive @fdc_oneOf(
required: Boolean! = false
) repeatable on FIELD_DEFINITION | ARGUMENT_DEFINITION | INPUT_FIELD_DEFINITION

type Mutation {
# This is just a dummy field so that Mutation is always non-empty.
_firebase: Void @fdc_deprecated(reason: "dummy field -- does nothing useful")
}

"""
`UUID` is a string of hexadecimal digits representing an RFC4122-compliant UUID.
Expand All @@ -495,12 +470,83 @@ On the wire, it's encoded as string because 64-bit integer exceeds the range of
scalar Int64

"""
The `Any` scalar represents any valid [JSON value](https://www.json.org/json-en.html).
It can be an object, array, string, number, or boolean.
The `Any` scalar type accommodates any valid [JSON value](https://www.json.org/json-en.html)
(e.g., numbers, strings, booleans, arrays, objects). PostgreSQL efficiently
stores this data as jsonb, providing flexibility for schemas with evolving structures.
Caution: JSON doesn't distinguish Int and Float.
In the PostgreSQL table, it's stored as [`jsonb`](https://www.postgresql.org/docs/current/datatype-json.html).
##### Example:
#### Schema
```graphql
type Movie @table {
name: String!
metadata: Any!
}
```
#### Mutation
Insert a movie with name and metadata from JSON literal.
```graphql
mutation InsertMovie {
movie_insert(
data: {
name: "The Dark Knight"
metadata: {
release_year: 2008
genre: ["Action", "Adventure", "Superhero"]
cast: [
{ name: "Christopher Bale", age: 31 }
{ name: "Heath Ledger", age: 28 }
]
director: "Christopher Nolan"
}
}
)
}
```
Insert a movie with name and metadata that's constructed from a few GQL variables.
```graphql
mutation InsertMovie($name: String!, $releaseDate: Date!, $genre: [String], $cast: [Any], $director: String!, $boxOfficeInUSD: Int) {
movie_insert(data: {
name: $name,
release_date: $releaseDate,
genre: $genre,
cast: $cast,
director: $director,
box_office: $boxOfficeInUSD
})
}
```
**Note**:
- A mix of non-null and nullable variables can be provided.
- `Date!` can be passed into scalar `Any` as well! It's stored as string.
- `$cast` is a nested array. `[Any]` can represent an array of arbitrary types, but it won't enforce the input shape.
#### Query
Since `metadata` field has scalar `Any` type, it would return the full JSON in the response.
**Note**: You can't define selection set to scalar based on [GraphQL spec](https://spec.graphql.org/October2021/#sec-Field-Selections).
```graphql
query GetAllMovies {
movies {
name
metadata
}
}
```
"""
scalar Any @specifiedBy(url: "https://www.json.org/json-en.html")

Expand Down Expand Up @@ -895,7 +941,7 @@ directive @col(
Each GraphQL type can map to multiple SQL data types.
Refer to [Postgres supported data types](https://www.postgresql.org/docs/current/datatype.html).
Incompatible SQL data type will lead to undefiend barehavior.
Incompatible SQL data type will lead to undefined behavior.
"""
dataType: String
"""
Expand Down Expand Up @@ -1888,3 +1934,73 @@ scalar Vector_Embed_Model
@fdc_example(value: "textembedding-gecko@001", description: "An older version of the textembedding-gecko model")
@fdc_example(value: "text-embedding-004", description: "Another text embedding model")

"""
Redact a part of the response from the client.
Redacted fields are still evaluated for side effects (including data changes and
`@check`) and the results are still available to later steps in CEL expressions
(via `response.fieldName`).
"""
directive @redact on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT

"""
Ensure this field is present and is not null or `[]`, or abort the request / transaction.
A CEL expression, `expr` is used to test the field value. It defaults to
rejecting null and `[]` but a custom expression can be provided instead.
If the field occurs multiple times (i.e. directly or indirectly nested under a
list), `expr` will be executed once for each occurrence and `@check` succeeds if
all values succeed. `@check` fails when the field is not present at all (i.e.
all ancestor paths contain `null` or `[]`), unless `optional` is true.
If a `@check` fails in a mutation, the top-level field containing it will be
replaced with a partial error, whose message can be customzied via the `message`
argument. Each subsequent top-level fields will return an aborted error (i.e.
not executed). To rollback previous steps, see `@transaction`.
"""
directive @check(
"""
The CEL expression to test the field value (or values if nested under a list).
Within the CEL expression, a special value `this` evaluates to the field that
this directive is attached to. If this field occurs multiple times because
any ancestor is a list, each occurrence is tested with `this` bound to each
value. When the field itself is a list or object, `this` follows the same
structure (including all decendants selected in case of objects).
For any given path, if an ancestor is `null` or `[]`, the field will not be
reached and the CEL evaluation will be skipped for that path. In other words,
evaluation only takes place when `this` is `null` or non-null, but never
undefined. (See also the `optional` argument.)
"""
expr: Boolean_Expr! = "!(this in [null, []])"
"""
The error message to return to the client if the check fails.
Defaults to "permission denied" if not specified.
"""
message: String! = "permission denied"
"""
Whether the check should pass or fail (default) when the field is not present.
A field will not be reached at a given path if its parent or any ancestor is
`[]` or `null`. When this happens to all paths, the field will not be present
anywhere in the response tree. In other words, `expr` is evaluated 0 times.
By default, @check will automatically fail in this case. Set this argument to
`true` to make it pass even if no tests are run (a.k.a. "vacuously true").
"""
optional: Boolean = false
) repeatable on QUERY | MUTATION | FIELD | FRAGMENT_DEFINITION | FRAGMENT_SPREAD | INLINE_FRAGMENT

type Mutation {
"""
Run a query during the mutation and add fields into the response.
Example: foo: query { users { id } } will add a field foo: {users: [{id: "..."}, …]} into the response JSON.
Note: Data fetched this way can be handy for permission checks. See @check.
"""
query: Query
}

Loading

0 comments on commit bb94a9c

Please sign in to comment.