Skip to content

Commit bb94a9c

Browse files
authored
Merge pull request #134 from HassanBahati/additional-useConnectQuery-useConnectMutation-tests
2 parents 0d72bef + d9df02c commit bb94a9c

File tree

6 files changed

+668
-59
lines changed

6 files changed

+668
-59
lines changed

.github/workflows/tests.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ jobs:
3535

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

3941
- name: Verify Running Emulators
4042
run: |

dataconnect/.dataconnect/schema/prelude.gql

Lines changed: 145 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -120,26 +120,6 @@ input String_Filter {
120120
`LIKE '%value'`
121121
"""
122122
endsWith: String
123-
"""
124-
Match if field value matches the provided pattern. See `String_Pattern` for
125-
more details.
126-
"""
127-
pattern: String_Pattern
128-
}
129-
130-
"""
131-
The pattern match condition on a string. Specify either like or regex.
132-
https://www.postgresql.org/docs/current/functions-matching.html
133-
"""
134-
input String_Pattern {
135-
"Match using the provided `LIKE` expression."
136-
like: String
137-
"Match using the provided POSIX regular expression."
138-
regex: String
139-
"When true, ignore case when matching."
140-
ignoreCase: Boolean
141-
"When true, invert the match result. Equivalent to `NOT LIKE` or `!~`."
142-
invert: Boolean
143123
}
144124

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

468-
type Mutation {
469-
# This is just a dummy field so that Mutation is always non-empty.
470-
_firebase: Void @fdc_deprecated(reason: "dummy field -- does nothing useful")
471-
}
472-
473448
"""
474449
`UUID` is a string of hexadecimal digits representing an RFC4122-compliant UUID.
475450
@@ -495,12 +470,83 @@ On the wire, it's encoded as string because 64-bit integer exceeds the range of
495470
scalar Int64
496471

497472
"""
498-
The `Any` scalar represents any valid [JSON value](https://www.json.org/json-en.html).
499-
It can be an object, array, string, number, or boolean.
473+
The `Any` scalar type accommodates any valid [JSON value](https://www.json.org/json-en.html)
474+
(e.g., numbers, strings, booleans, arrays, objects). PostgreSQL efficiently
475+
stores this data as jsonb, providing flexibility for schemas with evolving structures.
500476
501477
Caution: JSON doesn't distinguish Int and Float.
502478
503-
In the PostgreSQL table, it's stored as [`jsonb`](https://www.postgresql.org/docs/current/datatype-json.html).
479+
##### Example:
480+
481+
#### Schema
482+
483+
```graphql
484+
type Movie @table {
485+
name: String!
486+
metadata: Any!
487+
}
488+
```
489+
490+
#### Mutation
491+
492+
Insert a movie with name and metadata from JSON literal.
493+
494+
```graphql
495+
mutation InsertMovie {
496+
movie_insert(
497+
data: {
498+
name: "The Dark Knight"
499+
metadata: {
500+
release_year: 2008
501+
genre: ["Action", "Adventure", "Superhero"]
502+
cast: [
503+
{ name: "Christopher Bale", age: 31 }
504+
{ name: "Heath Ledger", age: 28 }
505+
]
506+
director: "Christopher Nolan"
507+
}
508+
}
509+
)
510+
}
511+
```
512+
513+
Insert a movie with name and metadata that's constructed from a few GQL variables.
514+
515+
```graphql
516+
mutation InsertMovie($name: String!, $releaseDate: Date!, $genre: [String], $cast: [Any], $director: String!, $boxOfficeInUSD: Int) {
517+
movie_insert(data: {
518+
name: $name,
519+
release_date: $releaseDate,
520+
genre: $genre,
521+
cast: $cast,
522+
director: $director,
523+
box_office: $boxOfficeInUSD
524+
})
525+
}
526+
```
527+
**Note**:
528+
529+
- A mix of non-null and nullable variables can be provided.
530+
531+
- `Date!` can be passed into scalar `Any` as well! It's stored as string.
532+
533+
- `$cast` is a nested array. `[Any]` can represent an array of arbitrary types, but it won't enforce the input shape.
534+
535+
#### Query
536+
537+
Since `metadata` field has scalar `Any` type, it would return the full JSON in the response.
538+
539+
**Note**: You can't define selection set to scalar based on [GraphQL spec](https://spec.graphql.org/October2021/#sec-Field-Selections).
540+
541+
```graphql
542+
query GetAllMovies {
543+
movies {
544+
name
545+
metadata
546+
}
547+
}
548+
```
549+
504550
"""
505551
scalar Any @specifiedBy(url: "https://www.json.org/json-en.html")
506552

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

1937+
"""
1938+
Redact a part of the response from the client.
1939+
1940+
Redacted fields are still evaluated for side effects (including data changes and
1941+
`@check`) and the results are still available to later steps in CEL expressions
1942+
(via `response.fieldName`).
1943+
"""
1944+
directive @redact on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
1945+
1946+
"""
1947+
Ensure this field is present and is not null or `[]`, or abort the request / transaction.
1948+
1949+
A CEL expression, `expr` is used to test the field value. It defaults to
1950+
rejecting null and `[]` but a custom expression can be provided instead.
1951+
1952+
If the field occurs multiple times (i.e. directly or indirectly nested under a
1953+
list), `expr` will be executed once for each occurrence and `@check` succeeds if
1954+
all values succeed. `@check` fails when the field is not present at all (i.e.
1955+
all ancestor paths contain `null` or `[]`), unless `optional` is true.
1956+
1957+
If a `@check` fails in a mutation, the top-level field containing it will be
1958+
replaced with a partial error, whose message can be customzied via the `message`
1959+
argument. Each subsequent top-level fields will return an aborted error (i.e.
1960+
not executed). To rollback previous steps, see `@transaction`.
1961+
"""
1962+
directive @check(
1963+
"""
1964+
The CEL expression to test the field value (or values if nested under a list).
1965+
1966+
Within the CEL expression, a special value `this` evaluates to the field that
1967+
this directive is attached to. If this field occurs multiple times because
1968+
any ancestor is a list, each occurrence is tested with `this` bound to each
1969+
value. When the field itself is a list or object, `this` follows the same
1970+
structure (including all decendants selected in case of objects).
1971+
1972+
For any given path, if an ancestor is `null` or `[]`, the field will not be
1973+
reached and the CEL evaluation will be skipped for that path. In other words,
1974+
evaluation only takes place when `this` is `null` or non-null, but never
1975+
undefined. (See also the `optional` argument.)
1976+
"""
1977+
expr: Boolean_Expr! = "!(this in [null, []])"
1978+
"""
1979+
The error message to return to the client if the check fails.
1980+
1981+
Defaults to "permission denied" if not specified.
1982+
"""
1983+
message: String! = "permission denied"
1984+
"""
1985+
Whether the check should pass or fail (default) when the field is not present.
1986+
1987+
A field will not be reached at a given path if its parent or any ancestor is
1988+
`[]` or `null`. When this happens to all paths, the field will not be present
1989+
anywhere in the response tree. In other words, `expr` is evaluated 0 times.
1990+
By default, @check will automatically fail in this case. Set this argument to
1991+
`true` to make it pass even if no tests are run (a.k.a. "vacuously true").
1992+
"""
1993+
optional: Boolean = false
1994+
) repeatable on QUERY | MUTATION | FIELD | FRAGMENT_DEFINITION | FRAGMENT_SPREAD | INLINE_FRAGMENT
1995+
1996+
type Mutation {
1997+
"""
1998+
Run a query during the mutation and add fields into the response.
1999+
2000+
Example: foo: query { users { id } } will add a field foo: {users: [{id: "..."}, …]} into the response JSON.
2001+
2002+
Note: Data fetched this way can be handy for permission checks. See @check.
2003+
"""
2004+
query: Query
2005+
}
2006+

0 commit comments

Comments
 (0)