Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add support for custom GraphQL scalars @gql(scalars: { website: "AWSURL" }) #88

Closed
Tenrys opened this issue Jan 5, 2023 · 5 comments
Assignees
Labels
is: feature request New feature request package: generator Generator package
Milestone

Comments

@Tenrys
Copy link
Contributor

Tenrys commented Jan 5, 2023

Right now it seems like only fields that are named url or email have been hardcoded to use the AWSURL and AWSEmail scalar types from AWS, however I would like to be able to use these types on fields like urlPhoto or something like secondaryEmail.

As seen here:

if (type === 'String') {
switch (field.name.toLocaleLowerCase()) {
case 'email':
type = 'AWSEmail'
break
case 'url':
type = 'AWSURL'
break
}
}

Would it be possible to use triple slash comments in the Prisma schema to define which fields turn up as what scalar types in the GraphQL schema?

@maoosi
Copy link
Owner

maoosi commented Jan 5, 2023

Possibly yes, but would need to find the right syntax...

There is already a custom notation in place (not documented yet) that allows customising the generated GraphQL schema.

/// @gql(queries: { list: null, count: "countyPosts" }, fields: { text: null }, subscriptions: null)
model Post {
    text  String?
    urlPhoto  String?
}

The above notation equals to:

  • Remove listPosts
  • Rename countPosts to countyPosts
  • Remove text field
  • Remove all subscriptions

One option could be:

/// @gql(scalars: { urlPhoto: "AWSURL" })
model Post {
    urlPhoto  String?
}

Implementing the above would be quite simple, as the code to read the @gql directive is already in place.

What do you think?

@maoosi maoosi added is: feature request New feature request package: generator Generator package labels Jan 5, 2023
@Tenrys
Copy link
Contributor Author

Tenrys commented Jan 5, 2023

I think that makes sense yes! Until documentation gets written, is there a way to know where exactly the code involving that custom notation is in place?

@maoosi
Copy link
Owner

maoosi commented Jan 5, 2023

Parsing the @gql directive as a JSON object is done here:

const gqlDirectives = directives.match(gqlRegex)
if (gqlDirectives) {
for (let i = 0; i < gqlDirectives.length; i++) {
const str = replaceAll(gqlDirectives[i].replace(gqlRegex, '$1'), find, replace)
// eslint-disable-next-line no-new-func
gql = merge({}, gql, new Function(`return ({${str}})`)())
}
}

The following is the config object where to add _scalars: gqlObject?.scalars || {}:

const gqlOutput: {
_model: boolean
_fields: any
_usesQueries: boolean
_usesMutations: boolean
_usesSubscriptions: boolean
[key: string]: any
} = {
_model: gqlObject?.model !== null,
_fields: gqlObject?.fields || {},
_usesQueries: false,
_usesMutations: false,
_usesSubscriptions: false,
}

Here is where the check to ignore fields is done:

const isFieldIgnored = gqlConfig?._fields?.[field.name] === null
if (!field.isGenerated && !isFieldIgnored) {
fields.push({
name: field.name,
type: field.type,
scalar: this.getFieldScalar(field),
isRequired: this.isFieldRequired(field),
isList: this.isFieldList(field),
isEnum: this.isFieldEnum(field),
isEditable: !this.isFieldGeneratedRelation(field, model),
isUnique: this.isFieldUnique(field),
...(field.relationName && {
relation: {
name: this.getFieldRelationName(field, model),
kind: this.getFieldRelationKind(field),
type: this.getFieldScalar(field),
},
}),
directives,
sample: this.getFieldSample(field),
})
}
})

For example, we could do:

const scalar = gqlConfig?._scalars?.[field.name] || this.getFieldScalar(field)

@maoosi
Copy link
Owner

maoosi commented Jan 6, 2023

@Tenrys do you want to work on a PR for this feature?

@maoosi maoosi added this to the 1.0.0-rc.6 milestone Jan 6, 2023
@maoosi maoosi changed the title Feature: Allow flagging certain fields as specific AWS AppSync scalar types Feature: Add support for custom GraphQL scalars @gql(scalars: { website: "AWSURL" }) Jan 29, 2023
maoosi added a commit that referenced this issue Jan 29, 2023
@maoosi maoosi closed this as completed Jan 29, 2023
@maoosi
Copy link
Owner

maoosi commented Jan 29, 2023

Will be released as part of 1.0.0-rc.6 (you can also try it now with prisma-appsync@1.0.0-preview.6.6).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
is: feature request New feature request package: generator Generator package
Projects
Status: Released
Development

No branches or pull requests

2 participants