Skip to content

Commit

Permalink
Use .keystone
Browse files Browse the repository at this point in the history
  • Loading branch information
emmatown authored and dcousens committed Aug 9, 2022
1 parent 7cb5e1c commit 0657aef
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .changeset/bright-pots-pretend.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
'@keystone-6/core': minor
---

Adds `graphql` export to `.keystone/types` that is the same as the `graphql` export from `@keystone-6/core` but uses the specific generated context type for the project
Renames `.keystone/types` to `.keystone` and adds `graphql` export to `.keystone` that is the same as the `graphql` export from `@keystone-6/core` but uses the specific generated context type for the project
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ To create and edit blog records in Keystone’s Admin UI, add a `keystone.ts` [c

import { config, list } from '@keystone-6/core';
import { text } from '@keystone-6/core/fields';
import { Lists } from '.keystone/types';
import { Lists } from '.keystone';

const Post: Lists.Post = list({
fields: {
Expand Down Expand Up @@ -186,7 +186,7 @@ import Link from 'next/link';

// Import the generated Lists API and types from Keystone
import { query } from '.keystone/api';
import { Lists } from '.keystone/types';
import { Lists } from '.keystone';

type Post = {
id: string;
Expand Down Expand Up @@ -236,7 +236,7 @@ import { GetStaticPathsResult, GetStaticPropsContext, InferGetStaticPropsType }
import Link from 'next/link';

import { query } from '.keystone/api';
import { Lists } from '.keystone/types';
import { Lists } from '.keystone';

type Post = {
id: string;
Expand Down
2 changes: 1 addition & 1 deletion examples/basic/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from '@keystone-6/core/fields';
import { document } from '@keystone-6/fields-document';
import { v4 } from 'uuid';
import * as Keystone from '.keystone/types';
import * as Keystone from '.keystone';

type AccessArgs = {
session?: {
Expand Down
2 changes: 1 addition & 1 deletion examples/ecommerce/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { KeystoneListsAPI } from '@keystone-6/core/types';

// NOTE -- these types are commented out in main because they aren't generated by the build (yet)
// To get full List and GraphQL API type support, uncomment them here and use them below
// import type { KeystoneListsTypeInfo } from '.keystone/types';
// import type { KeystoneListsTypeInfo } from '.keystone';

import type { Permission } from './schemas/fields';
export type { Permission } from './schemas/fields';
Expand Down
2 changes: 1 addition & 1 deletion examples/extend-graphql-schema-graphql-ts/custom-schema.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { graphql, Context } from '.keystone/types';
import { graphql, Context } from '.keystone';

export const extendGraphqlSchema = graphql.extend(base => {
const Statistics = graphql.object<{ authorId: string }>()({
Expand Down
2 changes: 1 addition & 1 deletion examples/extend-graphql-schema/custom-schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { graphQLSchemaExtension } from '@keystone-6/core';
import { Context } from '.keystone/types';
import { Context } from '.keystone';

export const extendGraphqlSchema = graphQLSchemaExtension<Context>({
typeDefs: `
Expand Down
2 changes: 1 addition & 1 deletion examples/virtual-field/schema.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { list } from '@keystone-6/core';
import { select, relationship, text, timestamp, virtual } from '@keystone-6/core/fields';
import { Lists, Context, graphql } from '.keystone/types';
import { Lists, Context, graphql } from '.keystone';

export const lists: Lists = {
Post: list({
Expand Down
23 changes: 18 additions & 5 deletions packages/core/src/artifacts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ export default config;
`;

const graphqlTsAPI = `import * as graphqlTsSchema from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/graphql-ts';
import type { Context } from '../types';
import type { Context } from '../index';
export * from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/graphql-ts-without-context';
export { field, fields, interface, interfaceField, object, union } from './graphql-ts-with-context';
Expand Down Expand Up @@ -246,14 +246,20 @@ declare const __graphql: GraphQLSchemaAPIWithContext<Context>;
export = __graphql;
`;

export async function generateTypesJSFile(cwd: string) {
export async function generateDotKeystoneJSFile(cwd: string) {
const dotKeystoneDir = path.join(cwd, 'node_modules/.keystone');
await fs.outputFile(
path.join(dotKeystoneDir, 'types.js'),
path.join(dotKeystoneDir, 'index.js'),
"exports.graphql = require('@keystone-6/core').graphql;"
);
}

function throwIfProblematicError(err: any) {
if (err.code !== 'ENOENT') {
throw err;
}
}

export async function generateNodeModulesArtifactsWithoutPrismaClient(
graphQLSchema: GraphQLSchema,
config: KeystoneConfig,
Expand All @@ -263,16 +269,23 @@ export async function generateNodeModulesArtifactsWithoutPrismaClient(

const dotKeystoneDir = path.join(cwd, 'node_modules/.keystone');
await Promise.all([
// this is so that when you upgrade from a keystone version that generates `.keystone/types` to `.keystone`
// and then .keystone/types sort of works locally but it doesn't update when you make new changes
// and your CI or etc. breaks and you're confused as to why
// this could be swapped to a "find all the things that aren't generated by keystone today and delete those"
// but that would be a bunch more code when we know there are the only things that should exist right now
fs.unlink(path.join(dotKeystoneDir, 'types.js')).catch(throwIfProblematicError),
fs.unlink(path.join(dotKeystoneDir, 'types.d.ts')).catch(throwIfProblematicError),
fs.outputFile(
path.join(dotKeystoneDir, 'types.d.ts'),
path.join(dotKeystoneDir, 'index.d.ts'),
printGeneratedTypes(graphQLSchema, lists)
),
fs.outputFile(path.join(dotKeystoneDir, 'internal/graphql-ts.d.ts'), graphqlTsAPI),
fs.outputFile(
path.join(dotKeystoneDir, 'internal/graphql-ts-with-context.d.ts'),
graphqlTsWithContextAPI
),
generateTypesJSFile(cwd),
generateDotKeystoneJSFile(cwd),
...(config.experimental?.generateNodeAPI
? [
fs.outputFile(path.join(dotKeystoneDir, 'api.js'), nodeAPIJS(cwd, config)),
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/lib/config/loadConfig.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import path from 'path';
import { generateTypesJSFile } from '../../artifacts';
import { generateDotKeystoneJSFile } from '../../artifacts';
import { KeystoneConfig } from '../../types';
import { initConfig } from './initConfig';
import { requireSource } from './requireSource';

export async function loadConfig(cwd: string): Promise<KeystoneConfig> {
await generateTypesJSFile(cwd);
await generateDotKeystoneJSFile(cwd);
return initConfig(requireSource(path.join(cwd, 'keystone')).default);
}
5 changes: 2 additions & 3 deletions packages/core/src/lib/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,8 @@ export type UnwrapPromises<T extends Promise<any>[]> = {
};

// please do not make this type be the value of KeystoneContext['prisma']
// this type is meant for generic usage, KeystoneContext should be generic over a PrismaClient
// and we should generate a KeystoneContext type in node_modules/.keystone/types which passes in the user's PrismaClient type
// so that users get right PrismaClient types specifically for their project
// the generated prisma client type should be used in actual apps
// this type is meant for "we have _some_ prisma client" not "we have _a_ prisma client"
export type PrismaClient = {
$disconnect(): Promise<void>;
$connect(): Promise<void>;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`postinstall writes the correct node_modules files 1`] = `
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ node_modules/.keystone/types.d.ts ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ node_modules/.keystone/index.d.ts ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
type Scalars = {
readonly ID: string;
readonly Boolean: boolean;
Expand Down Expand Up @@ -141,6 +141,50 @@ export type Lists = {
[Key in keyof TypeInfo['lists']]?: import('@keystone-6/core').ListConfig<TypeInfo['lists'][Key], any>
} & Record<string, import('@keystone-6/core').ListConfig<any, any>>;
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ node_modules/.keystone/types.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
export * as graphql from './internal/graphql-ts';
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ node_modules/.keystone/index.js ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
exports.graphql = require('@keystone-6/core').graphql;
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ node_modules/.keystone/internal/graphql-ts-with-context.d.ts ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
import { GraphQLSchemaAPIWithContext } from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/graphql-ts';
import { Context } from './graphql-ts';
declare const __graphql: GraphQLSchemaAPIWithContext<Context>;
export = __graphql;
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ node_modules/.keystone/internal/graphql-ts.d.ts ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
import * as graphqlTsSchema from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/graphql-ts';
import type { Context } from '../index';
export * from '@keystone-6/core/___internal-do-not-use-will-break-in-patch/graphql-ts-without-context';
export { field, fields, interface, interfaceField, object, union } from './graphql-ts-with-context';
export type { Context }
export type NullableType = graphqlTsSchema.NullableType<Context>;
export type Type = graphqlTsSchema.Type<Context>;
export type NullableOutputType = graphqlTsSchema.NullableOutputType<Context>;
export type OutputType = graphqlTsSchema.OutputType<Context>;
export type Field<
Source,
Args extends Record<string, graphqlTsSchema.Arg<any>>,
TType extends OutputType,
Key extends string
> = graphqlTsSchema.Field<Source, Args, TType, Key, Context>;
export type FieldResolver<
Source,
Args extends Record<string, graphqlTsSchema.Arg<any>>,
TType extends OutputType
> = graphqlTsSchema.FieldResolver<Source, Args, TType, Context>;
export type ObjectType<Source> = graphqlTsSchema.ObjectType<Source, Context>;
export type UnionType<Source> = graphqlTsSchema.UnionType<Source, Context>;
export type InterfaceType<
Source,
Fields extends Record<string, graphqlTsSchema.InterfaceField<any, OutputType, Context>>
> = graphqlTsSchema.InterfaceType<Source, Fields, Context>;
export type InterfaceField<
Args extends Record<string, graphqlTsSchema.Arg<any>>,
TType extends OutputType
> = graphqlTsSchema.InterfaceField<Args, TType, Context>;
`;
2 changes: 0 additions & 2 deletions packages/core/src/scripts/tests/build.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import execa from 'execa';
import * as fs from 'fs-extra';
import { ExitError } from '../utils';
import {
basicKeystoneConfig,
Expand Down Expand Up @@ -62,7 +61,6 @@ test('build works with typescript without the user defining a babel config', asy
NEXT_TELEMETRY_DISABLED: '1',
} as any,
});
expect(await fs.readFile(`${tmp}/node_modules/.keystone/types.js`, 'utf8')).toBe('');
expect(
result
.all!.replace(
Expand Down

0 comments on commit 0657aef

Please sign in to comment.