feat: allow control over nexus schema import id (#408)
Currently the typegen output is designed with the assumption that @nexus/schema will be available at node_modules/@nexus/schema. This assumes that either the project depends on @nexus/schema or that @nexus/schema has been hoisted. The former is fine but does not support being wrapped by another tool, while the latter is liable to result in module not found errors for hard-to-debug reasons (especially users who know little or nothing about the internals).
This commit is contained in:
parent
358c33efaa
commit
a6c29bae64
|
|
@ -285,6 +285,18 @@ export interface TypegenInfo {
|
|||
* The type of the context for the resolvers
|
||||
*/
|
||||
contextType?: string;
|
||||
/**
|
||||
* The path to the @nexus/schema package.
|
||||
*
|
||||
* @default '@nexus/schema'
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* This setting is particularly useful when @nexus/schema is being wrapped by
|
||||
* another library/framework such that @nexus/schema is not expected to be a
|
||||
* direct dependency at the application level.
|
||||
*/
|
||||
nexusSchemaImportId?: string;
|
||||
}
|
||||
|
||||
export type TypeToWalk =
|
||||
|
|
@ -1629,7 +1641,6 @@ export function makeSchemaInternal(config: SchemaConfig) {
|
|||
export function makeSchema(config: SchemaConfig): NexusGraphQLSchema {
|
||||
const { schema, missingTypes, finalConfig } = makeSchemaInternal(config);
|
||||
const typegenConfig = resolveTypegenConfig(finalConfig);
|
||||
|
||||
if (typegenConfig.outputs.schema || typegenConfig.outputs.typegen) {
|
||||
// Generating in the next tick allows us to use the schema
|
||||
// in the optional thunk for the typegen config
|
||||
|
|
|
|||
|
|
@ -113,6 +113,18 @@ export interface ConnectionPluginConfig {
|
|||
* Prefix for the Connection / Edge type
|
||||
*/
|
||||
typePrefix?: string;
|
||||
/**
|
||||
* The path to the @nexus/schema package. Needed for typegen.
|
||||
*
|
||||
* @default '@nexus/schema'
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* This setting is particularly useful when @nexus/schema is being wrapped by
|
||||
* another library/framework such that @nexus/schema is not expected to be a
|
||||
* direct dependency at the application level.
|
||||
*/
|
||||
nexusSchemaImportId?: string;
|
||||
}
|
||||
|
||||
// Extract the node value from the connection for a given field.
|
||||
|
|
@ -340,7 +352,8 @@ export const connectionPlugin = (
|
|||
name: "ConnectionPlugin",
|
||||
fieldDefTypes: [
|
||||
printedGenTypingImport({
|
||||
module: getOwnPackage().name,
|
||||
module:
|
||||
connectionPluginConfig?.nexusSchemaImportId ?? getOwnPackage().name,
|
||||
bindings: ["core", "connectionPluginCore"],
|
||||
}),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { GraphQLNamedType, GraphQLSchema, isOutputType } from "graphql";
|
|||
import path from "path";
|
||||
import { TypegenInfo } from "./builder";
|
||||
import { TYPEGEN_HEADER } from "./lang";
|
||||
import { log, objValues, relativePathTo } from "./utils";
|
||||
import { getOwnPackage, log, objValues, relativePathTo } from "./utils";
|
||||
|
||||
/**
|
||||
* Any common types / constants that would otherwise be circular-imported
|
||||
|
|
@ -327,6 +327,7 @@ export function typegenAutoConfig(options: TypegenAutoConfigOptions) {
|
|||
backingTypeMap,
|
||||
imports,
|
||||
contextType,
|
||||
nexusSchemaImportId: getOwnPackage().name,
|
||||
};
|
||||
|
||||
return typegenInfo;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { TypegenPrinter } from "./typegenPrinter";
|
|||
|
||||
export interface TypegenMetadataConfig
|
||||
extends Omit<BuilderConfig, "outputs" | "shouldGenerateArtifacts"> {
|
||||
nexusSchemaImportId?: string;
|
||||
outputs: {
|
||||
schema: false | string;
|
||||
typegen: false | string;
|
||||
|
|
@ -27,7 +28,7 @@ export class TypegenMetadata {
|
|||
constructor(protected config: TypegenMetadataConfig) {}
|
||||
|
||||
/**
|
||||
* Generates the artifacts of the buid based on what we
|
||||
* Generates the artifacts of the build based on what we
|
||||
* know about the schema and how it was defined.
|
||||
*/
|
||||
async generateArtifacts(schema: NexusGraphQLSchema) {
|
||||
|
|
@ -69,7 +70,7 @@ export class TypegenMetadata {
|
|||
if (typeof filePath !== "string" || !path.isAbsolute(filePath)) {
|
||||
return Promise.reject(
|
||||
new Error(
|
||||
`Expected an absolute path to output the GraphQL Nexus ${type}, saw ${filePath}`
|
||||
`Expected an absolute path to output the Nexus ${type}, saw ${filePath}`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -163,6 +164,7 @@ export class TypegenMetadata {
|
|||
}
|
||||
|
||||
return {
|
||||
nexusSchemaImportId: this.config.nexusSchemaImportId,
|
||||
headers: [TYPEGEN_HEADER],
|
||||
imports: [],
|
||||
contextType: "any",
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ type RootTypeMapping = Record<
|
|||
string | Record<string, [string, string]>
|
||||
>;
|
||||
|
||||
interface TypegenInfoWithFile extends TypegenInfo {
|
||||
typegenFile: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* We track and output a few main things:
|
||||
*
|
||||
|
|
@ -72,11 +76,11 @@ type RootTypeMapping = Record<
|
|||
*/
|
||||
export class TypegenPrinter {
|
||||
groupedTypes: GroupedTypes;
|
||||
printImports: Record<string, Record<string, any>>;
|
||||
printImports: Record<string, Record<string, boolean | string>>;
|
||||
|
||||
constructor(
|
||||
protected schema: NexusGraphQLSchema,
|
||||
protected typegenInfo: TypegenInfo & { typegenFile: string }
|
||||
protected typegenInfo: TypegenInfoWithFile
|
||||
) {
|
||||
this.groupedTypes = groupTypes(schema);
|
||||
this.printImports = {};
|
||||
|
|
@ -153,18 +157,21 @@ export class TypegenPrinter {
|
|||
const imports: string[] = [];
|
||||
const importMap: Record<string, Set<string>> = {};
|
||||
const outputPath = this.typegenInfo.typegenFile;
|
||||
// For backward compat.
|
||||
const nexusSchemaImportId =
|
||||
this.typegenInfo.nexusSchemaImportId ?? getOwnPackage().name;
|
||||
|
||||
const packName = getOwnPackage().name;
|
||||
if (!this.printImports[packName]) {
|
||||
if (!this.printImports[nexusSchemaImportId]) {
|
||||
if (
|
||||
[dynamicInputFields, dynamicOutputFields].some(
|
||||
(o) => Object.keys(o).length > 0
|
||||
)
|
||||
) {
|
||||
this.printImports[packName] = { core: true };
|
||||
this.printImports[nexusSchemaImportId] = {
|
||||
core: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
eachObj(rootTypings, (val, key) => {
|
||||
if (typeof val !== "string") {
|
||||
const importPath = (path.isAbsolute(val.path)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { BuilderConfig } from "./builder";
|
||||
import { TypegenMetadataConfig } from "./typegenMetadata";
|
||||
import { assertAbsolutePath } from "./utils";
|
||||
import { assertAbsolutePath, getOwnPackage } from "./utils";
|
||||
|
||||
/**
|
||||
* Normalizes the builder config into the config we need for typegen
|
||||
|
|
@ -36,6 +36,7 @@ export function resolveTypegenConfig(
|
|||
|
||||
return {
|
||||
...rest,
|
||||
nexusSchemaImportId: getOwnPackage().name,
|
||||
outputs: {
|
||||
typegen: shouldGenerateArtifacts ? typegenPath : false,
|
||||
schema: shouldGenerateArtifacts ? schemaPath : false,
|
||||
|
|
|
|||
Loading…
Reference in New Issue