From 996126259eab9d46ec09dc15a7ac589fbba25a34 Mon Sep 17 00:00:00 2001 From: Niklas May Date: Sun, 24 Sep 2023 15:55:32 +0200 Subject: [PATCH] fix: grofmt bug, object modei naked groq synntax error --- package.json | 2 +- playground/components/Video.tsx | 14 ++ .../queries/get-page-by-slug.ts | 90 +++++++++++-- .../generator-output/queries/get-pages.ts | 90 +++++++++++-- playground/generator-output/resolver/index.ts | 4 - .../resolver/inline-resolver0.ts | 4 - .../resolver/inline-resolver1.ts | 4 - .../resolver/inline-resolver2.ts | 4 - .../resolver/locale-string.ts | 4 - playground/sanity-generator.config.ts | 3 +- playground/sanity.config.ts | 19 +++ playground/schemas/documents/page.ts | 117 +++++------------ playground/schemas/factories/header.ts | 20 +-- playground/schemas/factories/index.ts | 1 + playground/schemas/factories/media.ts | 122 ++++++++++++++++++ playground/schemas/index.ts | 4 +- playground/schemas/types/index.ts | 1 - playground/schemas/types/media.ts | 95 -------------- src/core/generate.ts | 13 +- src/core/lib/groq.ts | 4 +- src/core/projector.ts | 21 ++- test/main.test.ts | 9 +- tsconfig.json | 2 +- yarn.lock | 8 +- 24 files changed, 393 insertions(+), 262 deletions(-) create mode 100644 playground/components/Video.tsx delete mode 100644 playground/generator-output/resolver/index.ts delete mode 100644 playground/generator-output/resolver/inline-resolver0.ts delete mode 100644 playground/generator-output/resolver/inline-resolver1.ts delete mode 100644 playground/generator-output/resolver/inline-resolver2.ts delete mode 100644 playground/generator-output/resolver/locale-string.ts create mode 100644 playground/schemas/factories/media.ts delete mode 100644 playground/schemas/types/media.ts diff --git a/package.json b/package.json index 675e252..a926d19 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "commander": "^11.0.0", "consola": "^3.2.3", "defu": "^6.1.2", - "groqfmt-nodejs": "^0.0.6", + "groqfmt-nodejs": "^1.0.0", "prettier": "^3.0.3", "rimraf": "^5.0.1", "serialize-javascript": "^6.0.1", diff --git a/playground/components/Video.tsx b/playground/components/Video.tsx new file mode 100644 index 0000000..1bf4030 --- /dev/null +++ b/playground/components/Video.tsx @@ -0,0 +1,14 @@ +import React, {FC, ReactElement} from 'react' +import "./styles.css"; + +interface Props { + src: string +} + +export const Video = ({src}: Props) => { + return ( +
+
+ ) +} diff --git a/playground/generator-output/queries/get-page-by-slug.ts b/playground/generator-output/queries/get-page-by-slug.ts index 37d9346..0759d88 100644 --- a/playground/generator-output/queries/get-page-by-slug.ts +++ b/playground/generator-output/queries/get-page-by-slug.ts @@ -1,10 +1,80 @@ -import { - inlineResolver0, - inlineResolver1, - localeString, - inlineResolver2, -} from "../resolver"; - -// prettier-ignore -export const getPageBySlug = /* groq */` -*[_type == "page" && slug.current == $slug] { ..., ${inlineResolver0("seoTitle")}, ${inlineResolver1("pageHeader")}, gallery { ..., ${localeString("sectionTitle")}, slides[] { ..., slide { ..., ${inlineResolver2("title")} } } }, sections[] { ..., gallerySection { ..., ${localeString("sectionTitle")}, slides[] { ..., slide { ..., ${localeString("title")} } } }, textSection { ..., ${localeString("title")} }, featuresSection { ..., ${localeString("title")}, ${localeString("subtitle")} } } }[0] ` +export const getPageBySlug = /* groq */ ` +*[_type == "page" && slug.current == $slug] { + ..., + "pageHeader": { + "title": pageHeader.title, + "subtitle": pageHeader.subtitle + }, + featuredImage { + _type, + type, + type == "image" => { + image { + "title": asset->.title, + "altText": asset->.altText, + "src": asset->.url, + "metaData": { + "crop": crop, + "hotspot": hotspot, + "width": asset->.metadata.dimensions.width, + "height": asset->.metadata.dimensions.height + } + } + }, + type == "video" => { + "player": player.asset-> { + "playbackId": playbackId, + "ratio": data.aspect_ratio, + thumbTime + }, + "mood": mood.asset-> { + "playbackId": playbackId, + "ratio": data.aspect_ratio + } + } + }, + "seoTitle": coalesce(seoTitle[$lang], seoTitle.en), + sections[] { + ..., + _type == "gallerySection" => { + ..., + "sectionTitle": coalesce(sectionTitle[$lang], sectionTitle.en), + slides[] { + ..., + slide { + _type, + type, + type == "image" => { + image { + "title": asset->.title, + "altText": asset->.altText, + "src": asset->.url, + "metaData": { + "crop": crop, + "hotspot": hotspot, + "width": asset->.metadata.dimensions.width, + "height": asset->.metadata.dimensions.height + } + } + }, + type == "video" => { + "player": player.asset-> { + "playbackId": playbackId, + "ratio": data.aspect_ratio, + thumbTime + }, + "mood": mood.asset-> { + "playbackId": playbackId, + "ratio": data.aspect_ratio + } + } + } + } + }, + _type == "textSection" => { + ..., + "title": coalesce(title[$lang], title.en) + } + } +}[0] +`; diff --git a/playground/generator-output/queries/get-pages.ts b/playground/generator-output/queries/get-pages.ts index e14dd05..9e24bf4 100644 --- a/playground/generator-output/queries/get-pages.ts +++ b/playground/generator-output/queries/get-pages.ts @@ -1,10 +1,80 @@ -import { - inlineResolver0, - inlineResolver1, - localeString, - inlineResolver2, -} from "../resolver"; - -// prettier-ignore -export const getPages = /* groq */` -*[_type == "page"] { ..., ${inlineResolver0("seoTitle")}, ${inlineResolver1("pageHeader")}, gallery { ..., ${localeString("sectionTitle")}, slides[] { ..., slide { ..., ${inlineResolver2("title")} } } }, sections[] { ..., gallerySection { ..., ${localeString("sectionTitle")}, slides[] { ..., slide { ..., ${localeString("title")} } } }, textSection { ..., ${localeString("title")} }, featuresSection { ..., ${localeString("title")}, ${localeString("subtitle")} } } }[0] ` +export const getPages = /* groq */ ` +*[_type == "page"] { + ..., + "pageHeader": { + "title": pageHeader.title, + "subtitle": pageHeader.subtitle + }, + featuredImage { + _type, + type, + type == "image" => { + image { + "title": asset->.title, + "altText": asset->.altText, + "src": asset->.url, + "metaData": { + "crop": crop, + "hotspot": hotspot, + "width": asset->.metadata.dimensions.width, + "height": asset->.metadata.dimensions.height + } + } + }, + type == "video" => { + "player": player.asset-> { + "playbackId": playbackId, + "ratio": data.aspect_ratio, + thumbTime + }, + "mood": mood.asset-> { + "playbackId": playbackId, + "ratio": data.aspect_ratio + } + } + }, + "seoTitle": coalesce(seoTitle[$lang], seoTitle.en), + sections[] { + ..., + _type == "gallerySection" => { + ..., + "sectionTitle": coalesce(sectionTitle[$lang], sectionTitle.en), + slides[] { + ..., + slide { + _type, + type, + type == "image" => { + image { + "title": asset->.title, + "altText": asset->.altText, + "src": asset->.url, + "metaData": { + "crop": crop, + "hotspot": hotspot, + "width": asset->.metadata.dimensions.width, + "height": asset->.metadata.dimensions.height + } + } + }, + type == "video" => { + "player": player.asset-> { + "playbackId": playbackId, + "ratio": data.aspect_ratio, + thumbTime + }, + "mood": mood.asset-> { + "playbackId": playbackId, + "ratio": data.aspect_ratio + } + } + } + } + }, + _type == "textSection" => { + ..., + "title": coalesce(title[$lang], title.en) + } + } +}[0] +`; diff --git a/playground/generator-output/resolver/index.ts b/playground/generator-output/resolver/index.ts deleted file mode 100644 index dfd2ffb..0000000 --- a/playground/generator-output/resolver/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./inline-resolver0"; -export * from "./inline-resolver1"; -export * from "./inline-resolver2"; -export * from "./locale-string"; diff --git a/playground/generator-output/resolver/inline-resolver0.ts b/playground/generator-output/resolver/inline-resolver0.ts deleted file mode 100644 index 3e30053..0000000 --- a/playground/generator-output/resolver/inline-resolver0.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { type Resolver } from "sanity-generator/types"; - -// prettier-ignore -export const inlineResolver0: Resolver = (name) => ( /* groq */ ` "${name}": { "germanTitle": ${name}.de, "englishTitle": ${name}.en } ` ) diff --git a/playground/generator-output/resolver/inline-resolver1.ts b/playground/generator-output/resolver/inline-resolver1.ts deleted file mode 100644 index c6137cb..0000000 --- a/playground/generator-output/resolver/inline-resolver1.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { type Resolver } from "sanity-generator/types"; - -// prettier-ignore -export const inlineResolver1: Resolver = (name2) => ( /* groq */ ` "${name2}-wrapped": { "title": ${name2}.title, "subtitle": ${name2}.subtitle } ` ) diff --git a/playground/generator-output/resolver/inline-resolver2.ts b/playground/generator-output/resolver/inline-resolver2.ts deleted file mode 100644 index 83b7d33..0000000 --- a/playground/generator-output/resolver/inline-resolver2.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { type Resolver } from "sanity-generator/types"; - -// prettier-ignore -export const inlineResolver2: Resolver = (name) => ( /* groq */ `"${name}": {"super": "cool"}` ) diff --git a/playground/generator-output/resolver/locale-string.ts b/playground/generator-output/resolver/locale-string.ts deleted file mode 100644 index 526fb40..0000000 --- a/playground/generator-output/resolver/locale-string.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { type Resolver } from "sanity-generator/types"; - -// prettier-ignore -export const localeString: Resolver = (name) => ( /* groq */ ` "${name}": coalesce(${name}[$lang], ${name}.en) ` ) diff --git a/playground/sanity-generator.config.ts b/playground/sanity-generator.config.ts index afe2dbb..3d4d81c 100644 --- a/playground/sanity-generator.config.ts +++ b/playground/sanity-generator.config.ts @@ -30,8 +30,7 @@ export default createConfig( }, }, { - inlineResolver: false, - trim: true, + inlineResolver: true, outPath: path.resolve(__dirname, './generator-output'), }, ) diff --git a/playground/sanity.config.ts b/playground/sanity.config.ts index 59e33cf..d8ecc6a 100644 --- a/playground/sanity.config.ts +++ b/playground/sanity.config.ts @@ -2,6 +2,10 @@ import {defineConfig} from 'sanity' import {deskTool} from 'sanity/desk' import {visionTool} from '@sanity/vision' import {schemaTypes} from './schemas' +import { getPages } from './generator-output/queries/get-pages' + +import { createClient } from '@sanity/client' + export default defineConfig({ name: 'default', @@ -17,5 +21,20 @@ export default defineConfig({ }, }) +const client = createClient({ + projectId: "gmpiajy6", + dataset: process.env.SANITY_STUDIO_DATASET!, + apiVersion: "2023-09-23", + useCdn: false, +}) + +async function main(){ + const res = await client.fetch(getPages, {lang: "en"}) + console.log(res) +} +main() + + + diff --git a/playground/schemas/documents/page.ts b/playground/schemas/documents/page.ts index 02bbc64..58172f6 100644 --- a/playground/schemas/documents/page.ts +++ b/playground/schemas/documents/page.ts @@ -1,6 +1,5 @@ -import {defineArrayMember, defineField, defineType} from 'sanity' -import {header} from '../factories' -import {title} from 'process' +import { defineField, defineType} from 'sanity' +import {headerFactory, mediaFactory} from '../factories' type Page = any export const pageSchema: Page = defineType({ @@ -18,67 +17,12 @@ export const pageSchema: Page = defineType({ }, ], fields: [ + headerFactory('pageHeader', 'content'), + mediaFactory("featuredImage", 'content', {video: false}), defineField({ type: 'localeString', - title: 'Title (Open Graph)', name: 'seoTitle', - description: 'Used for Open Graph previews implemented by facebook, twitter, google etc.', - generator: { - resolver: (name) => /* groq */ ` - "${name}": { - "germanTitle": ${name}.de, - "englishTitle": ${name}.en - } - `, - }, - }), - header('pageHeader', 'content'), - defineField({ - type: 'object', - name: 'gallery', - group: 'content', - - fields: [ - defineField({ - type: 'localeString', - name: 'sectionTitle', - }), - defineField({ - type: 'array', - name: 'slides', - of: [ - defineArrayMember({ - type: 'object', - name: 'slide', - fields: [ - defineField({ - name: 'image', - type: 'image', - }), - { - type: 'string', - name: 'title', - generator: { - resolver: (name) => /* groq */ `"${name}": {"super": "cool"}`, - }, - }, - ], - preview: { - select: { - title: 'title', - image: "image" - }, - prepare(props) { - return { - title: props.title, - media: props.image - } - }, - }, - }), - ], - }), - ], + group: 'seo', }), defineField({ type: 'array', @@ -96,20 +40,16 @@ export const pageSchema: Page = defineType({ defineField({ type: 'array', name: 'slides', - of: [ - defineArrayMember({ - type: 'object', - name: 'slide', - fields: [ - defineField({ - type: 'localeString', - name: 'title', - }), - ], - }), - ], + of: [mediaFactory('slide')], }), ], + preview: { + prepare() { + return { + title: 'Gallery Section', + } + }, + }, }), defineField({ type: 'object', @@ -120,22 +60,25 @@ export const pageSchema: Page = defineType({ name: 'title', }), ], - }), - defineField({ - type: 'object', - name: 'featuresSection', - fields: [ - defineField({ - type: 'localeString', - name: 'title', - }), - defineField({ - type: 'localeString', - name: 'subtitle', - }), - ], + preview: { + prepare() { + return { + title: 'Text Section', + } + }, + }, }), ], }), ], + preview: { + select: { + title: 'pageHeader.title', + }, + prepare(props) { + return { + title: props.title, + } + }, + }, }) diff --git a/playground/schemas/factories/header.ts b/playground/schemas/factories/header.ts index fdbc1db..41485d6 100644 --- a/playground/schemas/factories/header.ts +++ b/playground/schemas/factories/header.ts @@ -1,7 +1,8 @@ +import {Resolver} from './../../../src/types/index' import {defineField} from 'sanity' -export const header = (name: string, group = "") => - defineField({ +export function headerFactory(name: string, group = '') { + return defineField({ type: 'object', name, group, @@ -10,11 +11,14 @@ export const header = (name: string, group = "") => {name: 'subtitle', type: 'string'}, ], generator: { - resolver: (name: string) => /* groq */ ` - "${name}-wrapped": { - "title": ${name}.title, - "subtitle": ${name}.subtitle - } - `, + resolver, }, }) +} + +const resolver: Resolver = (name: string) => /* groq */ ` +"${name}": { + "title": ${name}.title, + "subtitle": ${name}.subtitle +} +` diff --git a/playground/schemas/factories/index.ts b/playground/schemas/factories/index.ts index c73f6da..c53fbd8 100644 --- a/playground/schemas/factories/index.ts +++ b/playground/schemas/factories/index.ts @@ -1 +1,2 @@ export * from './header' +export * from './media' diff --git a/playground/schemas/factories/media.ts b/playground/schemas/factories/media.ts new file mode 100644 index 0000000..deda0cf --- /dev/null +++ b/playground/schemas/factories/media.ts @@ -0,0 +1,122 @@ +import {Resolver} from './../../../src/types/index' +import {defineField} from 'sanity' +import {Video} from '../../components/Video' +type Options = { + video?: boolean +} +const defaultOptions: Options = { + video: true, +} + +export function mediaFactory(name: string, group = '', options: Options = defaultOptions) { + return defineField({ + name, + group, + type: 'object', + options: { + collapsible: false, + }, + fields: [ + defineField({ + name: 'type', + title: 'Type', + type: 'string', + options: { + list: ['image', 'video'], + layout: 'radio', + direction: 'horizontal', + }, + hidden: options.video === false, + initialValue: 'image', + }), + defineField({ + name: 'mood', + title: 'Mood Video', + description: 'Automatic playback without audio. Videos should be max. 10 seconds long.', + type: 'file', + hidden: ({parent}) => parent?.type !== 'video' || options.video === false, + }), + defineField({ + name: 'player', + title: 'Video Player', + description: + 'Video Player with all playback controls. If combined with a mood video, the mood video will replace the image poster.', + type: 'file', + hidden: ({parent}) => parent?.type !== 'video' || options.video === false, + }), + defineField({ + name: 'image', + type: 'image', + options: { + hotspot: true, + }, + hidden: ({parent}) => { + const hidden = parent?.type === undefined ? false : parent?.type !== 'image' + return hidden + }, + }), + ], + preview: { + select: { + type: 'type', + mood: 'mood.asset.url', + player: 'player.asset.url', + image: 'image', + }, + prepare(args) { + if (args.type === 'video') { + return { + title: [args.mood && 'Mood Video', args.player && 'Video Player'] + .filter(Boolean) + .join(' and '), + media: () => Video({src: args.mood || args.player}), + } + } else { + return { + title: 'Image', + media: args.image, + } + } + }, + }, + generator: { + resolver, + }, + }) +} + +const resolver: Resolver = (name) => /* groq */` +${name} { + _type, + type, + type == "image" => { + image { + "title": asset -> title, + "altText": asset -> altText, + "src": asset -> url, + "metaData": { + "crop": crop, + "hotspot": hotspot, + "width": asset -> metadata.dimensions.width, + "height": asset -> metadata.dimensions.height, + } + }, + }, + type == "video" => { + "player": player.asset -> { + "playbackId": playbackId, + "ratio": data.aspect_ratio, + thumbTime + + }, + "mood": mood.asset -> { + "playbackId": playbackId, + "ratio": data.aspect_ratio + } + } + +} +` + + + diff --git a/playground/schemas/index.ts b/playground/schemas/index.ts index c2665d0..7a61c88 100644 --- a/playground/schemas/index.ts +++ b/playground/schemas/index.ts @@ -1,7 +1,7 @@ -import {localeStringSchema, mediaSchema} from './types' +import {localeStringSchema} from './types' import {pageSchema} from './documents' const documents = [pageSchema] -const types = [localeStringSchema, mediaSchema] +const types = [localeStringSchema] export const schemaTypes = [...types, ...documents] diff --git a/playground/schemas/types/index.ts b/playground/schemas/types/index.ts index 079999c..223eb7c 100644 --- a/playground/schemas/types/index.ts +++ b/playground/schemas/types/index.ts @@ -1,2 +1 @@ export * from "./locale-string" -export * from "./media" \ No newline at end of file diff --git a/playground/schemas/types/media.ts b/playground/schemas/types/media.ts deleted file mode 100644 index b181b10..0000000 --- a/playground/schemas/types/media.ts +++ /dev/null @@ -1,95 +0,0 @@ -import {Resolver} from './../../../src/types/' -import {Image} from '../../components/Image' - -export const mediaSchema = { - type: 'object', - name: 'media', - fields: [ - { - type: 'string', - name: 'type', - title: 'Type', - options: { - list: ['image', 'video'], - layout: 'radio', - direction: 'horizontal', - }, - initialValue: 'image', - validation: (Rule) => Rule.required(), - }, - { - name: 'mood', - title: 'Mood Video', - description: 'Automatic playback without audio. Videos should be max. 10 seconds long.', - type: 'file', - hidden: ({parent}) => parent?.type !== 'video', - }, - { - name: 'player', - title: 'Video Player', - description: - 'Video Player with all playback controls. If combined with a mood video, the mood video will replace the image poster.', - type: 'file', - hidden: ({parent}) => parent?.type !== 'video', - }, - { - name: 'image', - type: 'image', - options: { - hotspot: true, - }, - hidden: ({parent}) => parent?.type !== 'image', - }, - ], - preview: { - select: { - mood: 'mood.asset.playbackId', - type: 'type', - player: 'player.asset.playbackId', - image: 'image', - }, - prepare(args) { - if (args.type === 'video') { - const thumbnail = `https://image.mux.com/${args.mood || args.player}/thumbnail.jpg` - return { - title: [args.mood && 'Mood Video', args.player && 'Video Player'] - .filter(Boolean) - .join(' and '), - media: () => Image({src: thumbnail}), - } - } else { - return { - title: 'Image', - media: args.image, - } - } - }, - }, -} - -export const mediaResolver: Resolver = (name: string) => /* groq */ ` - ${name} { - _type, - type == 'image' => { - 'image': image.asset->{ - url, - 'lqip': metadata.lqip, - 'ratio': metadata.dimensions.aspectRatio - }, - hotspot, - crop, - }, - type == 'video' => { - 'player': player.asset->{ - 'playbackId': playbackId, - 'ratio': data.aspect_ratio, - thumbTime - - }, - 'mood': mood.asset -> { - 'playbackId': playbackId, - 'ratio': data.aspect_ratio - } - } - } -` diff --git a/src/core/generate.ts b/src/core/generate.ts index 580795e..01fa6e3 100644 --- a/src/core/generate.ts +++ b/src/core/generate.ts @@ -19,10 +19,10 @@ export async function generate>(config: Config, consola.info("Looking for GROQ syntax errors..."); - for (const [_, queryFn] of configQueries) { + configQueries.forEach(([_, queryFn]) => { const queryString = queryFn({ schemas: schemas }); - await prettifyGroq(queryString); - } + prettifyGroq(queryString); + }); consola.info("No errors found."); @@ -31,7 +31,7 @@ export async function generate>(config: Config, configQueries.map(async ([queryName, queryFn]) => { const queryString = queryFn({ schemas: schemas }); - const query = await prettifyGroq(queryString); + const query = prettifyGroq(queryString); const queryProcessed = opts.trim ? trimString(query) : query; const code = `${ @@ -42,6 +42,7 @@ export async function generate>(config: Config, return await writeTypeScript(filePath, code); }) ); + await writeBarrelFile(configQuerieNames, path.resolve(opts.outPath, "queries")); } let usedResolvers = 0; if (opts?.inlineResolver === false) { @@ -49,10 +50,9 @@ export async function generate>(config: Config, usedResolvers = types.size; createMissingDirectories(path.join(opts.outPath, "resolver")); - await Promise.all( configQueries.map(async ([queryName, queryFn]) => { - const queryTemplate = await prettifyGroq(queryFn({ schemas: schemas })); + const queryTemplate = prettifyGroq(queryFn({ schemas: schemas })); const { query, resolverDependencies } = Projector.insertResolver(queryTemplate); const queryProcessed = opts.trim ? trimString(query) : query; @@ -70,7 +70,6 @@ export async function generate>(config: Config, ); await wirteResolver(types, resolvers, path.join(opts.outPath, "resolver"), opts); await writeBarrelFile(configQuerieNames, path.resolve(opts.outPath, "queries")); - } if (opts.inlineResolver) { diff --git a/src/core/lib/groq.ts b/src/core/lib/groq.ts index d9294c3..2e95343 100644 --- a/src/core/lib/groq.ts +++ b/src/core/lib/groq.ts @@ -31,9 +31,9 @@ function colorizeSubstring(source, startIndex, endIndex) { return beforeIndex + coloredSubstring + afterIndex; } -export async function prettifyGroq(code: string) { +export function prettifyGroq(code: string) { try { - return await format(String(code).trim()); + return format(String(code).trim()); } catch (e: any) { const query = getPart(String(e), /echo\s+"([^"]+)"/); const msg = getPart(String(e), /parsing query:\s+parse\s+error\s(.+)/); diff --git a/src/core/projector.ts b/src/core/projector.ts index 7613515..8bd8960 100644 --- a/src/core/projector.ts +++ b/src/core/projector.ts @@ -47,7 +47,7 @@ export class Projector { let resolverName = ""; for (let [key, val] of Object.entries(this.resolvers)) { - if (val.toString() === field.generator.resolver.toString()) { + if (val?.toString() === field.generator.resolver.toString()) { resolverName = key; } } @@ -83,7 +83,13 @@ export class Projector { return `_type == '${name}' => {\n ${children} } `; - } else return children; + } else if (objectMode === "naked") { + return ` + ${children} + `; + } else { + return children; + } } #projectNodeAndSpread({ fields, foundTypes, inline, objectMode }: TraversalArguments): [string, Set] { @@ -93,7 +99,7 @@ export class Projector { fields .sort((a) => (this.#isCustomType(a.type) || this.#getSubfields(a) ? 1 : -1)) .reduce( - (acc: string, curr) => { + (acc: string, curr, index) => { const subFields = this.#getSubfields(curr); if ( @@ -121,10 +127,11 @@ export class Projector { ); } else { return acc.concat( - curr.name, - `{\n ${ - this.#projectNodeAndSpread({ fields: subFields, foundTypes: childCustomTypes, inline })[0] - } \n}, ` + this.#warpField( + objectMode, + this.#projectNodeAndSpread({ fields: subFields, foundTypes: childCustomTypes, inline })[0], + curr.name + ), index < fields.length - 1 ? ',' : '' ); } } else { diff --git a/test/main.test.ts b/test/main.test.ts index 871c9f7..8c7d3ce 100644 --- a/test/main.test.ts +++ b/test/main.test.ts @@ -29,23 +29,22 @@ describe.each(testConfigs)(`Run CLI from ${testSource} with $fileName`, async ({ describe.each(queries)("Current Query: $queryName", ({ queryName }) => { const filePath = path.join(options.outPath, "queries", `${paramCase(queryName)}.ts`); - test(`Query file should exist`, () => { + test(`Should be written to disk`, () => { return expect(fs.existsSync(filePath)).toBe(true); }); - test(`Query file should compile`, async () => { + test(`Should compile when imported`, async () => { return await importFresh(filePath).then((module) => { - console.log("Should compile"); return expect(module[queryName]).toBeDefined(); }); }); - test(`Query file should have reference query`, () => { + test(`Should have a reference query`, () => { return expectTypeOf(referenceConfig.queries[queryName]).toBeString(); }); test( - "Query result should match reference", + "Fetch result should match reference query", async () => { const params = { lang: "en" }; diff --git a/tsconfig.json b/tsconfig.json index 33e4be2..bb68b04 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,5 +22,5 @@ } }, "exclude": ["playground", "build", "src/static"], - "include": ["src"] + "include": ["src", "test/generator-output"] } diff --git a/yarn.lock b/yarn.lock index f47cfb9..8eb9cbb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2216,10 +2216,10 @@ groq-js@^1.1.12: resolved "https://registry.yarnpkg.com/groq-js/-/groq-js-1.3.0.tgz#7fc03a41c0b5a4160edfd714735e756d653b637a" integrity sha512-J7+JcxM0OvoowSkhNZAabCLueldEMkKzd9ufCEDRjKvkD1PcBUwyfsGvxUI59UojRCqFqp0y76LLzPzwSZTetw== -groqfmt-nodejs@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/groqfmt-nodejs/-/groqfmt-nodejs-0.0.6.tgz#5f18a70800eaefb8cc90b19e8ed2585093ec52d3" - integrity sha512-jDp+AVNhatg5+5OehFEHv745/1zkwFN6CmGRnm1/AFU2vmSNHUpM0H2kZw/VaNOEI8NBoGpVD63VnyHFe2wvEQ== +groqfmt-nodejs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/groqfmt-nodejs/-/groqfmt-nodejs-1.0.0.tgz#7890c24fe00e20f11fdf1406d003d6ee4ab3010c" + integrity sha512-IuA0r7dSBKoPdZPOcg524od8SP/BibN018g/LVaPNhCX/1YAM1B/23HpEFMnM5Q9Tcd0TGV28W2dMnsOptymUA== dependencies: mkdirp "^3.0.1"