Skip to content

Instantly share code, notes, and snippets.

@smokku
Created March 21, 2022 18:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save smokku/5df4400e898d9805f45ddbb3af1180c5 to your computer and use it in GitHub Desktop.
Save smokku/5df4400e898d9805f45ddbb3af1180c5 to your computer and use it in GitHub Desktop.
--- models/generate.orig.js 2022-02-16 16:38:08.286386783 +0100
+++ models/generate.js 2022-02-16 16:38:08.285386773 +0100
@@ -343,11 +343,11 @@
function handleField(field) {
let r = ''
if (field.description) r += ` /** ${sanitizeComment(field.description)} */\n`
- r += ` ${field.name}: ${handleFieldType(field.name, field.type)},`
+ r += ` ${field.name}: ${handleFieldType(field.name, field.type, field.args)},`
return r
}
- function handleFieldType(fieldName, fieldType, isNested = false) {
+ function handleFieldType(fieldName, fieldType, fieldArgs, isNested = false) {
let isNullable = true
if (fieldType.kind === 'NON_NULL') {
fieldType = fieldType.ofType
@@ -360,6 +360,15 @@
? `types.union(${canBeUndef ? 'types.undefined, ' : ''}${canBeNull ? 'types.null, ' : ''}${thing})`
: thing
}
+ for (let arg of fieldArgs) {
+ let argType = arg.type
+ while (['NON_NULL', 'LIST'].includes(argType.kind)) {
+ argType = argType.ofType
+ }
+ if (argType.kind === 'ENUM') {
+ addImport(argType.name + (!argType.name.toLowerCase().endsWith('enum') ? 'Enum' : ''), argType.name)
+ }
+ }
switch (fieldType.kind) {
case 'SCALAR':
primitiveFields.push(fieldName)
@@ -368,9 +377,9 @@
const isRequired = requiredTypes.includes(primitiveType)
return result(`types.${primitiveType}`, isRequired)
case 'OBJECT':
- return result(handleObjectFieldType(fieldName, fieldType, isNested))
+ return result(handleObjectFieldType(fieldName, fieldType, fieldArgs, isNested))
case 'LIST':
- return result(`types.array(${handleFieldType(fieldName, fieldType.ofType, true)})`)
+ return result(`types.array(${handleFieldType(fieldName, fieldType.ofType, fieldArgs, true)})`)
case 'ENUM':
primitiveFields.push(fieldName)
const enumType = fieldType.name + (!fieldType.name.toLowerCase().endsWith('enum') ? 'EnumType' : 'Type')
@@ -381,14 +390,16 @@
return result(enumType)
case 'INTERFACE':
case 'UNION':
- return result(handleInterfaceOrUnionFieldType(fieldName, fieldType))
+ return result(handleInterfaceOrUnionFieldType(fieldName, fieldType, fieldArgs))
default:
throw new Error(`Failed to convert type ${JSON.stringify(fieldType)}. PR Welcome!`)
}
}
- function handleObjectFieldType(fieldName, fieldType, isNested) {
- nonPrimitiveFields.push([fieldName, fieldType.name])
+ function handleObjectFieldType(fieldName, fieldType, fieldArgs, isNested, skipField) {
+ if (!skipField) {
+ nonPrimitiveFields.push([fieldName, fieldType.name, fieldArgs])
+ }
const isSelf = fieldType.name === currentType
// this type is not going to be handled by mst-gql, store as frozen
@@ -414,7 +425,7 @@
return `MSTGQLRef(${realType})`
}
- function handleInterfaceOrUnionFieldType(fieldName, fieldType) {
+ function handleInterfaceOrUnionFieldType(fieldName, fieldType, fieldArgs) {
nonPrimitiveFields.push([fieldName, fieldType.name])
// import the type
@@ -425,14 +436,7 @@
const mstUnionArgs = interfaceOrUnionType.ofTypes.map((t) => {
// Note that members of a union type need to be concrete object types;
// you can't create a union type out of interfaces or other unions.
- const subTypeClassName = t.name + 'Model'
- if (type.kind !== 'INTERFACE' && type.kind !== 'UNION') {
- // TODO: split field type resolvement from model properties output
- addImport(subTypeClassName, subTypeClassName)
- }
- const isSelf = fieldType.name === currentType
- // always using late prevents potential circular dependency issues between files
- return `types.late(()${isSelf && format === 'ts' ? ': any' : ''} => ${subTypeClassName})`
+ return handleObjectFieldType(t.name, t, fieldArgs, false, true)
})
return `types.union(${mstUnionArgs.join(', ')})`
}
@@ -445,11 +449,27 @@
output += primitiveFields.map((p) => ` get ${p}() { return this.__attr(\`${p}\`) }`).join('\n')
output += primitiveFields.length > 0 ? '\n' : ''
output += nonPrimitiveFields
- .map(([field, fieldName]) => {
+ .map(([field, fieldName, fieldArgs]) => {
+ let args = ''
const selector = `${fieldName}ModelSelector`
let p = ` ${field}(builder`
- p += ifTS(`?: string | ${selector} | ((selector: ${selector}) => ${selector})`)
- p += `) { return this.__child(\`${field}\`, ${selector}, builder) }`
+ p += ifTS(`: string | ${selector} | ((selector: ${selector}) => ${selector}) | undefined`)
+ if (fieldArgs && fieldArgs.length) {
+ const required = fieldArgs.find(({ type }) => type.kind === 'NON_NULL')
+ p += ', args'
+ p += ifTS(`${required ? '' : '?'}: { ${fieldArgs.map((arg) => printTsType(arg)).join(', ')} }`)
+ args = `(${fieldArgs
+ .map(({ name, type }) => {
+ if (type.kind === 'NON_NULL') type = type.ofType
+ if (type.kind === 'LIST' && type.ofType.kind === 'ENUM') {
+ return `${name}: [\${args['${name}']?.join(',')}]`
+ } else {
+ return `${name}: \${JSON.stringify(args['${name}'])}`
+ }
+ })
+ .join(', ')})`
+ }
+ p += `) { return this.__child(\`${field}${args}\`, ${selector}, builder) }`
return p
})
.join('\n')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment