[codegen/nodejs] Emit externally referenced resources/types (#6225)
This commit is contained in:
parent
2779de38ea
commit
e86a69bedd
30
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/argFunction.ts
vendored
Normal file
30
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/argFunction.ts
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "./types";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
import * as random from "@pulumi/random";
|
||||
|
||||
export function argFunction(args?: ArgFunctionArgs, opts?: pulumi.InvokeOptions): Promise<ArgFunctionResult> {
|
||||
args = args || {};
|
||||
if (!opts) {
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (!opts.version) {
|
||||
opts.version = utilities.getVersion();
|
||||
}
|
||||
return pulumi.runtime.invoke("example::argFunction", {
|
||||
"name": args.name,
|
||||
}, opts);
|
||||
}
|
||||
|
||||
export interface ArgFunctionArgs {
|
||||
readonly name?: random.RandomPet;
|
||||
}
|
||||
|
||||
export interface ArgFunctionResult {
|
||||
readonly age?: number;
|
||||
}
|
72
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/cat.ts
vendored
Normal file
72
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/cat.ts
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "./types";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
import * as random from "@pulumi/random";
|
||||
|
||||
export class Cat extends pulumi.CustomResource {
|
||||
/**
|
||||
* Get an existing Cat resource's state with the given name, ID, and optional extra
|
||||
* properties used to qualify the lookup.
|
||||
*
|
||||
* @param name The _unique_ name of the resulting resource.
|
||||
* @param id The _unique_ provider ID of the resource to lookup.
|
||||
* @param opts Optional settings to control the behavior of the CustomResource.
|
||||
*/
|
||||
public static get(name: string, id: pulumi.Input<pulumi.ID>, opts?: pulumi.CustomResourceOptions): Cat {
|
||||
return new Cat(name, undefined as any, { ...opts, id: id });
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public static readonly __pulumiType = 'example::Cat';
|
||||
|
||||
/**
|
||||
* Returns true if the given object is an instance of Cat. This is designed to work even
|
||||
* when multiple copies of the Pulumi SDK have been loaded into the same process.
|
||||
*/
|
||||
public static isInstance(obj: any): obj is Cat {
|
||||
if (obj === undefined || obj === null) {
|
||||
return false;
|
||||
}
|
||||
return obj['__pulumiType'] === Cat.__pulumiType;
|
||||
}
|
||||
|
||||
public /*out*/ readonly name!: pulumi.Output<string | undefined>;
|
||||
|
||||
/**
|
||||
* Create a Cat resource with the given unique name, arguments, and options.
|
||||
*
|
||||
* @param name The _unique_ name of the resource.
|
||||
* @param args The arguments to use to populate this resource's properties.
|
||||
* @param opts A bag of options that control this resource's behavior.
|
||||
*/
|
||||
constructor(name: string, args?: CatArgs, opts?: pulumi.CustomResourceOptions) {
|
||||
let inputs: pulumi.Inputs = {};
|
||||
if (!(opts && opts.id)) {
|
||||
inputs["age"] = args ? args.age : undefined;
|
||||
inputs["pet"] = args ? args.pet : undefined;
|
||||
inputs["name"] = undefined /*out*/;
|
||||
} else {
|
||||
inputs["name"] = undefined /*out*/;
|
||||
}
|
||||
if (!opts) {
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (!opts.version) {
|
||||
opts.version = utilities.getVersion();
|
||||
}
|
||||
super(Cat.__pulumiType, name, inputs, opts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The set of arguments for constructing a Cat resource.
|
||||
*/
|
||||
export interface CatArgs {
|
||||
readonly age?: pulumi.Input<number>;
|
||||
readonly pet?: pulumi.Input<inputs.Pet>;
|
||||
}
|
76
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/component.ts
vendored
Normal file
76
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/component.ts
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
import * as aws from "@pulumi/aws";
|
||||
import * as kubernetes from "@pulumi/kubernetes";
|
||||
|
||||
export class Component extends pulumi.CustomResource {
|
||||
/**
|
||||
* Get an existing Component resource's state with the given name, ID, and optional extra
|
||||
* properties used to qualify the lookup.
|
||||
*
|
||||
* @param name The _unique_ name of the resulting resource.
|
||||
* @param id The _unique_ provider ID of the resource to lookup.
|
||||
* @param opts Optional settings to control the behavior of the CustomResource.
|
||||
*/
|
||||
public static get(name: string, id: pulumi.Input<pulumi.ID>, opts?: pulumi.CustomResourceOptions): Component {
|
||||
return new Component(name, undefined as any, { ...opts, id: id });
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public static readonly __pulumiType = 'example::Component';
|
||||
|
||||
/**
|
||||
* Returns true if the given object is an instance of Component. This is designed to work even
|
||||
* when multiple copies of the Pulumi SDK have been loaded into the same process.
|
||||
*/
|
||||
public static isInstance(obj: any): obj is Component {
|
||||
if (obj === undefined || obj === null) {
|
||||
return false;
|
||||
}
|
||||
return obj['__pulumiType'] === Component.__pulumiType;
|
||||
}
|
||||
|
||||
public /*out*/ readonly provider!: pulumi.Output<kubernetes.Provider | undefined>;
|
||||
public /*out*/ readonly securityGroup!: pulumi.Output<aws.ec2.SecurityGroup | undefined>;
|
||||
public /*out*/ readonly storageClasses!: pulumi.Output<{[key: string]: kubernetes.storage.v1.StorageClass} | undefined>;
|
||||
|
||||
/**
|
||||
* Create a Component resource with the given unique name, arguments, and options.
|
||||
*
|
||||
* @param name The _unique_ name of the resource.
|
||||
* @param args The arguments to use to populate this resource's properties.
|
||||
* @param opts A bag of options that control this resource's behavior.
|
||||
*/
|
||||
constructor(name: string, args?: ComponentArgs, opts?: pulumi.CustomResourceOptions) {
|
||||
let inputs: pulumi.Inputs = {};
|
||||
if (!(opts && opts.id)) {
|
||||
inputs["metadata"] = args ? args.metadata : undefined;
|
||||
inputs["provider"] = undefined /*out*/;
|
||||
inputs["securityGroup"] = undefined /*out*/;
|
||||
inputs["storageClasses"] = undefined /*out*/;
|
||||
} else {
|
||||
inputs["provider"] = undefined /*out*/;
|
||||
inputs["securityGroup"] = undefined /*out*/;
|
||||
inputs["storageClasses"] = undefined /*out*/;
|
||||
}
|
||||
if (!opts) {
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (!opts.version) {
|
||||
opts.version = utilities.getVersion();
|
||||
}
|
||||
super(Component.__pulumiType, name, inputs, opts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The set of arguments for constructing a Component resource.
|
||||
*/
|
||||
export interface ComponentArgs {
|
||||
readonly metadata?: pulumi.Input<kubernetes.types.input.meta.v1.ObjectMeta>;
|
||||
}
|
53
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/index.ts
vendored
Normal file
53
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/index.ts
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
// Export members:
|
||||
export * from "./argFunction";
|
||||
export * from "./cat";
|
||||
export * from "./component";
|
||||
export * from "./provider";
|
||||
export * from "./workload";
|
||||
|
||||
// Export sub-modules:
|
||||
import * as types from "./types";
|
||||
|
||||
export {
|
||||
types,
|
||||
};
|
||||
|
||||
// Import resources to register:
|
||||
import { Cat } from "./cat";
|
||||
import { Component } from "./component";
|
||||
import { Workload } from "./workload";
|
||||
|
||||
const _module = {
|
||||
version: utilities.getVersion(),
|
||||
construct: (name: string, type: string, urn: string): pulumi.Resource => {
|
||||
switch (type) {
|
||||
case "example::Cat":
|
||||
return new Cat(name, <any>undefined, { urn })
|
||||
case "example::Component":
|
||||
return new Component(name, <any>undefined, { urn })
|
||||
case "example::Workload":
|
||||
return new Workload(name, <any>undefined, { urn })
|
||||
default:
|
||||
throw new Error(`unknown resource type ${type}`);
|
||||
}
|
||||
},
|
||||
};
|
||||
pulumi.runtime.registerResourceModule("example", "", _module)
|
||||
|
||||
import { Provider } from "./provider";
|
||||
|
||||
pulumi.runtime.registerResourcePackage("example", {
|
||||
version: utilities.getVersion(),
|
||||
constructProvider: (name: string, type: string, urn: string): pulumi.ProviderResource => {
|
||||
if (type !== "pulumi:providers:example") {
|
||||
throw new Error(`unknown provider type ${type}`);
|
||||
}
|
||||
return new Provider(name, <any>undefined, { urn });
|
||||
},
|
||||
});
|
11
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/types/index.ts
vendored
Normal file
11
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/types/index.ts
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
// Export sub-modules:
|
||||
import * as input from "./input";
|
||||
import * as output from "./output";
|
||||
|
||||
export {
|
||||
input,
|
||||
output,
|
||||
};
|
12
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/types/input.ts
vendored
Normal file
12
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/types/input.ts
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "../types";
|
||||
|
||||
import * as random from "@pulumi/random";
|
||||
|
||||
export interface Pet {
|
||||
age?: pulumi.Input<number>;
|
||||
name?: pulumi.Input<random.RandomPet>;
|
||||
}
|
8
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/types/output.ts
vendored
Normal file
8
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/types/output.ts
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import { input as inputs, output as outputs } from "../types";
|
||||
|
||||
import * as random from "@pulumi/random";
|
||||
|
67
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/workload.ts
vendored
Normal file
67
pkg/codegen/internal/test/testdata/external-resource-schema/nodejs/workload.ts
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
// *** WARNING: this file was generated by test. ***
|
||||
// *** Do not edit by hand unless you're certain you know what you are doing! ***
|
||||
|
||||
import * as pulumi from "@pulumi/pulumi";
|
||||
import * as utilities from "./utilities";
|
||||
|
||||
import * as kubernetes from "@pulumi/kubernetes";
|
||||
|
||||
export class Workload extends pulumi.CustomResource {
|
||||
/**
|
||||
* Get an existing Workload resource's state with the given name, ID, and optional extra
|
||||
* properties used to qualify the lookup.
|
||||
*
|
||||
* @param name The _unique_ name of the resulting resource.
|
||||
* @param id The _unique_ provider ID of the resource to lookup.
|
||||
* @param opts Optional settings to control the behavior of the CustomResource.
|
||||
*/
|
||||
public static get(name: string, id: pulumi.Input<pulumi.ID>, opts?: pulumi.CustomResourceOptions): Workload {
|
||||
return new Workload(name, undefined as any, { ...opts, id: id });
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
public static readonly __pulumiType = 'example::Workload';
|
||||
|
||||
/**
|
||||
* Returns true if the given object is an instance of Workload. This is designed to work even
|
||||
* when multiple copies of the Pulumi SDK have been loaded into the same process.
|
||||
*/
|
||||
public static isInstance(obj: any): obj is Workload {
|
||||
if (obj === undefined || obj === null) {
|
||||
return false;
|
||||
}
|
||||
return obj['__pulumiType'] === Workload.__pulumiType;
|
||||
}
|
||||
|
||||
public /*out*/ readonly pod!: pulumi.Output<kubernetes.types.output.core.v1.Pod | undefined>;
|
||||
|
||||
/**
|
||||
* Create a Workload resource with the given unique name, arguments, and options.
|
||||
*
|
||||
* @param name The _unique_ name of the resource.
|
||||
* @param args The arguments to use to populate this resource's properties.
|
||||
* @param opts A bag of options that control this resource's behavior.
|
||||
*/
|
||||
constructor(name: string, args?: WorkloadArgs, opts?: pulumi.CustomResourceOptions) {
|
||||
let inputs: pulumi.Inputs = {};
|
||||
if (!(opts && opts.id)) {
|
||||
inputs["pod"] = undefined /*out*/;
|
||||
} else {
|
||||
inputs["pod"] = undefined /*out*/;
|
||||
}
|
||||
if (!opts) {
|
||||
opts = {}
|
||||
}
|
||||
|
||||
if (!opts.version) {
|
||||
opts.version = utilities.getVersion();
|
||||
}
|
||||
super(Workload.__pulumiType, name, inputs, opts);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The set of arguments for constructing a Workload resource.
|
||||
*/
|
||||
export interface WorkloadArgs {
|
||||
}
|
|
@ -117,24 +117,63 @@ func (mod *modContext) tokenToModName(tok string) string {
|
|||
return modName
|
||||
}
|
||||
|
||||
func (mod *modContext) tokenToType(tok string, input, enum bool) string {
|
||||
modName, name := mod.tokenToModName(tok), tokenToName(tok)
|
||||
func (mod *modContext) namingContext(pkg *schema.Package) (namingCtx *modContext, pkgName string, external bool) {
|
||||
namingCtx = mod
|
||||
if pkg != nil && pkg != mod.pkg {
|
||||
external = true
|
||||
pkgName = pkg.Name + "."
|
||||
|
||||
if enum {
|
||||
return "enums." + modName + title(name)
|
||||
var info NodePackageInfo
|
||||
contract.AssertNoError(pkg.ImportLanguages(map[string]schema.Language{"nodejs": Importer}))
|
||||
if v, ok := pkg.Language["nodejs"].(NodePackageInfo); ok {
|
||||
info = v
|
||||
}
|
||||
namingCtx = &modContext{
|
||||
pkg: pkg,
|
||||
modToPkg: info.ModuleToPackage,
|
||||
compatibility: info.Compatibility,
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (mod *modContext) objectType(pkg *schema.Package, tok string, input, enum bool) string {
|
||||
root := "outputs."
|
||||
if input {
|
||||
root = "inputs."
|
||||
}
|
||||
|
||||
return root + modName + title(name)
|
||||
namingCtx, pkgName, external := mod.namingContext(pkg)
|
||||
if external {
|
||||
root = "types.output."
|
||||
if input {
|
||||
root = "types.input."
|
||||
}
|
||||
}
|
||||
|
||||
modName, name := namingCtx.tokenToModName(tok), tokenToName(tok)
|
||||
|
||||
if enum {
|
||||
return "enums." + modName + title(name)
|
||||
}
|
||||
return pkgName + root + modName + title(name)
|
||||
}
|
||||
|
||||
func (mod *modContext) tokenToResource(tok string) string {
|
||||
modName, name := mod.tokenToModName(tok), tokenToName(tok)
|
||||
func (mod *modContext) resourceType(r *schema.ResourceType) string {
|
||||
if strings.HasPrefix(r.Token, "pulumi:providers:") {
|
||||
pkgName := strings.TrimPrefix(r.Token, "pulumi:providers:")
|
||||
return fmt.Sprintf("%s.Provider", pkgName)
|
||||
}
|
||||
|
||||
return modName + title(name)
|
||||
pkg := mod.pkg
|
||||
if r.Resource != nil {
|
||||
pkg = r.Resource.Package
|
||||
}
|
||||
namingCtx, pkgName, _ := mod.namingContext(pkg)
|
||||
|
||||
modName, name := namingCtx.tokenToModName(r.Token), tokenToName(r.Token)
|
||||
|
||||
return pkgName + modName + title(name)
|
||||
}
|
||||
|
||||
func tokenToName(tok string) string {
|
||||
|
@ -166,15 +205,15 @@ func (mod *modContext) typeString(t schema.Type, input, wrapInput, optional bool
|
|||
var typ string
|
||||
switch t := t.(type) {
|
||||
case *schema.EnumType:
|
||||
typ = mod.tokenToType(t.Token, input, true)
|
||||
typ = mod.objectType(nil, t.Token, input, true)
|
||||
case *schema.ArrayType:
|
||||
typ = mod.typeString(t.ElementType, input, wrapInput, false, constValue) + "[]"
|
||||
case *schema.MapType:
|
||||
typ = fmt.Sprintf("{[key: string]: %v}", mod.typeString(t.ElementType, input, wrapInput, false, constValue))
|
||||
case *schema.ObjectType:
|
||||
typ = mod.tokenToType(t.Token, input, false)
|
||||
typ = mod.objectType(t.Package, t.Token, input, false)
|
||||
case *schema.ResourceType:
|
||||
typ = mod.tokenToResource(t.Token)
|
||||
typ = mod.resourceType(t)
|
||||
case *schema.TokenType:
|
||||
typ = tokenToName(t.Token)
|
||||
case *schema.UnionType:
|
||||
|
@ -815,7 +854,7 @@ func (mod *modContext) genType(w io.Writer, obj *schema.ObjectType, input bool,
|
|||
mod.genPlainType(w, tokenToName(obj.Token), obj.Comment, properties, input, wrapInput, false, level)
|
||||
}
|
||||
|
||||
func (mod *modContext) getTypeImports(t schema.Type, recurse bool, imports map[string]codegen.StringSet, seen codegen.Set) bool {
|
||||
func (mod *modContext) getTypeImports(t schema.Type, recurse bool, externalImports codegen.StringSet, imports map[string]codegen.StringSet, seen codegen.Set) bool {
|
||||
if seen.Has(t) {
|
||||
return false
|
||||
}
|
||||
|
@ -843,24 +882,38 @@ func (mod *modContext) getTypeImports(t schema.Type, recurse bool, imports map[s
|
|||
|
||||
switch t := t.(type) {
|
||||
case *schema.ArrayType:
|
||||
return mod.getTypeImports(t.ElementType, recurse, imports, seen)
|
||||
return mod.getTypeImports(t.ElementType, recurse, externalImports, imports, seen)
|
||||
case *schema.MapType:
|
||||
return mod.getTypeImports(t.ElementType, recurse, imports, seen)
|
||||
return mod.getTypeImports(t.ElementType, recurse, externalImports, imports, seen)
|
||||
case *schema.EnumType:
|
||||
return true
|
||||
case *schema.ObjectType:
|
||||
// If it's from another package, add an import for the external package.
|
||||
if t.Package != nil && t.Package != mod.pkg {
|
||||
pkg := t.Package.Name
|
||||
externalImports.Add(fmt.Sprintf("import * as %[1]s from \"@pulumi/%[1]s\";", pkg))
|
||||
return false
|
||||
}
|
||||
|
||||
for _, p := range t.Properties {
|
||||
mod.getTypeImports(p.Type, recurse, imports, seen)
|
||||
mod.getTypeImports(p.Type, recurse, externalImports, imports, seen)
|
||||
}
|
||||
return true
|
||||
case *schema.ResourceType:
|
||||
// If it's from another package, add an import for the external package.
|
||||
if t.Resource != nil && t.Resource.Package != mod.pkg {
|
||||
pkg := t.Resource.Package.Name
|
||||
externalImports.Add(fmt.Sprintf("import * as %[1]s from \"@pulumi/%[1]s\";", pkg))
|
||||
return false
|
||||
}
|
||||
|
||||
return resourceOrTokenImport(t.Token)
|
||||
case *schema.TokenType:
|
||||
return resourceOrTokenImport(t.Token)
|
||||
case *schema.UnionType:
|
||||
needsTypes := false
|
||||
for _, e := range t.ElementTypes {
|
||||
needsTypes = mod.getTypeImports(e, recurse, imports, seen) || needsTypes
|
||||
needsTypes = mod.getTypeImports(e, recurse, externalImports, imports, seen) || needsTypes
|
||||
}
|
||||
return needsTypes
|
||||
default:
|
||||
|
@ -868,40 +921,40 @@ func (mod *modContext) getTypeImports(t schema.Type, recurse bool, imports map[s
|
|||
}
|
||||
}
|
||||
|
||||
func (mod *modContext) getImports(member interface{}, imports map[string]codegen.StringSet) bool {
|
||||
func (mod *modContext) getImports(member interface{}, externalImports codegen.StringSet, imports map[string]codegen.StringSet) bool {
|
||||
seen := codegen.Set{}
|
||||
switch member := member.(type) {
|
||||
case *schema.ObjectType:
|
||||
needsTypes := false
|
||||
for _, p := range member.Properties {
|
||||
needsTypes = mod.getTypeImports(p.Type, true, imports, seen) || needsTypes
|
||||
needsTypes = mod.getTypeImports(p.Type, true, externalImports, imports, seen) || needsTypes
|
||||
}
|
||||
return needsTypes
|
||||
case *schema.ResourceType:
|
||||
mod.getTypeImports(member, true, imports, seen)
|
||||
mod.getTypeImports(member, true, externalImports, imports, seen)
|
||||
return false
|
||||
case *schema.Resource:
|
||||
needsTypes := false
|
||||
for _, p := range member.Properties {
|
||||
needsTypes = mod.getTypeImports(p.Type, false, imports, seen) || needsTypes
|
||||
needsTypes = mod.getTypeImports(p.Type, false, externalImports, imports, seen) || needsTypes
|
||||
}
|
||||
for _, p := range member.InputProperties {
|
||||
needsTypes = mod.getTypeImports(p.Type, false, imports, seen) || needsTypes
|
||||
needsTypes = mod.getTypeImports(p.Type, false, externalImports, imports, seen) || needsTypes
|
||||
}
|
||||
return needsTypes
|
||||
case *schema.Function:
|
||||
needsTypes := false
|
||||
if member.Inputs != nil {
|
||||
needsTypes = mod.getTypeImports(member.Inputs, false, imports, seen) || needsTypes
|
||||
needsTypes = mod.getTypeImports(member.Inputs, false, externalImports, imports, seen) || needsTypes
|
||||
}
|
||||
if member.Outputs != nil {
|
||||
needsTypes = mod.getTypeImports(member.Outputs, false, imports, seen) || needsTypes
|
||||
needsTypes = mod.getTypeImports(member.Outputs, false, externalImports, imports, seen) || needsTypes
|
||||
}
|
||||
return needsTypes
|
||||
case []*schema.Property:
|
||||
needsTypes := false
|
||||
for _, p := range member {
|
||||
needsTypes = mod.getTypeImports(p.Type, false, imports, seen) || needsTypes
|
||||
needsTypes = mod.getTypeImports(p.Type, false, externalImports, imports, seen) || needsTypes
|
||||
}
|
||||
return needsTypes
|
||||
default:
|
||||
|
@ -909,7 +962,7 @@ func (mod *modContext) getImports(member interface{}, imports map[string]codegen
|
|||
}
|
||||
}
|
||||
|
||||
func (mod *modContext) genHeader(w io.Writer, imports []string, importedTypes map[string]codegen.StringSet) {
|
||||
func (mod *modContext) genHeader(w io.Writer, imports []string, externalImports codegen.StringSet, importedTypes map[string]codegen.StringSet) {
|
||||
fmt.Fprintf(w, "// *** WARNING: this file was generated by %v. ***\n", mod.tool)
|
||||
fmt.Fprintf(w, "// *** Do not edit by hand unless you're certain you know what you are doing! ***\n\n")
|
||||
|
||||
|
@ -920,6 +973,13 @@ func (mod *modContext) genHeader(w io.Writer, imports []string, importedTypes ma
|
|||
fmt.Fprintf(w, "\n")
|
||||
}
|
||||
|
||||
if externalImports.Any() {
|
||||
for _, i := range externalImports.SortedValues() {
|
||||
fmt.Fprintf(w, "%s\n", i)
|
||||
}
|
||||
fmt.Fprintf(w, "\n")
|
||||
}
|
||||
|
||||
if len(importedTypes) > 0 {
|
||||
var modules []string
|
||||
for module := range importedTypes {
|
||||
|
@ -928,20 +988,14 @@ func (mod *modContext) genHeader(w io.Writer, imports []string, importedTypes ma
|
|||
sort.Strings(modules)
|
||||
|
||||
for _, module := range modules {
|
||||
var names []string
|
||||
for name := range importedTypes[module] {
|
||||
names = append(names, name)
|
||||
}
|
||||
sort.Strings(names)
|
||||
|
||||
fmt.Fprintf(w, "import {")
|
||||
for i, name := range names {
|
||||
for i, name := range importedTypes[module].SortedValues() {
|
||||
if i > 0 {
|
||||
fmt.Fprint(w, ", ")
|
||||
}
|
||||
fmt.Fprint(w, name)
|
||||
}
|
||||
fmt.Fprintf(w, "} from \"%v\";\n", module)
|
||||
fmt.Fprintf(w, "} from \"%s\";\n", module)
|
||||
}
|
||||
fmt.Fprintf(w, "\n")
|
||||
}
|
||||
|
@ -963,10 +1017,10 @@ func (mod *modContext) configGetter(v *schema.Property) (string, string) {
|
|||
}
|
||||
|
||||
func (mod *modContext) genConfig(w io.Writer, variables []*schema.Property) error {
|
||||
imports := map[string]codegen.StringSet{}
|
||||
referencesNestedTypes := mod.getImports(variables, imports)
|
||||
externalImports, imports := codegen.NewStringSet(), map[string]codegen.StringSet{}
|
||||
referencesNestedTypes := mod.getImports(variables, externalImports, imports)
|
||||
|
||||
mod.genHeader(w, mod.sdkImports(referencesNestedTypes, true), imports)
|
||||
mod.genHeader(w, mod.sdkImports(referencesNestedTypes, true), externalImports, imports)
|
||||
|
||||
// Create a config bag for the variables to pull from.
|
||||
fmt.Fprintf(w, "let __config = new pulumi.Config(\"%v\");\n", mod.pkg.Name)
|
||||
|
@ -1025,15 +1079,15 @@ func (mod *modContext) sdkImports(nested, utilities bool) []string {
|
|||
}
|
||||
|
||||
func (mod *modContext) genTypes() (string, string) {
|
||||
imports := map[string]codegen.StringSet{}
|
||||
externalImports, imports := codegen.NewStringSet(), map[string]codegen.StringSet{}
|
||||
for _, t := range mod.types {
|
||||
mod.getImports(t, imports)
|
||||
mod.getImports(t, externalImports, imports)
|
||||
}
|
||||
|
||||
inputs, outputs := &bytes.Buffer{}, &bytes.Buffer{}
|
||||
|
||||
mod.genHeader(inputs, mod.sdkImports(true, false), imports)
|
||||
mod.genHeader(outputs, mod.sdkImports(true, false), imports)
|
||||
mod.genHeader(inputs, mod.sdkImports(true, false), externalImports, imports)
|
||||
mod.genHeader(outputs, mod.sdkImports(true, false), externalImports, imports)
|
||||
|
||||
// Build a namespace tree out of the types, then emit them.
|
||||
namespaces := mod.getNamespaces()
|
||||
|
@ -1188,7 +1242,7 @@ func (mod *modContext) gen(fs fs) error {
|
|||
switch mod.mod {
|
||||
case "":
|
||||
buffer := &bytes.Buffer{}
|
||||
mod.genHeader(buffer, nil, nil)
|
||||
mod.genHeader(buffer, nil, nil, nil)
|
||||
fmt.Fprintf(buffer, "%s", utilitiesFile)
|
||||
fs.add(path.Join(modDir, "utilities.ts"), buffer.Bytes())
|
||||
|
||||
|
@ -1222,11 +1276,11 @@ func (mod *modContext) gen(fs fs) error {
|
|||
|
||||
// Resources
|
||||
for _, r := range mod.resources {
|
||||
imports := map[string]codegen.StringSet{}
|
||||
referencesNestedTypes := mod.getImports(r, imports)
|
||||
externalImports, imports := codegen.NewStringSet(), map[string]codegen.StringSet{}
|
||||
referencesNestedTypes := mod.getImports(r, externalImports, imports)
|
||||
|
||||
buffer := &bytes.Buffer{}
|
||||
mod.genHeader(buffer, mod.sdkImports(referencesNestedTypes, true), imports)
|
||||
mod.genHeader(buffer, mod.sdkImports(referencesNestedTypes, true), externalImports, imports)
|
||||
|
||||
if err := mod.genResource(buffer, r); err != nil {
|
||||
return err
|
||||
|
@ -1238,11 +1292,11 @@ func (mod *modContext) gen(fs fs) error {
|
|||
|
||||
// Functions
|
||||
for _, f := range mod.functions {
|
||||
imports := map[string]codegen.StringSet{}
|
||||
referencesNestedTypes := mod.getImports(f, imports)
|
||||
externalImports, imports := codegen.NewStringSet(), map[string]codegen.StringSet{}
|
||||
referencesNestedTypes := mod.getImports(f, externalImports, imports)
|
||||
|
||||
buffer := &bytes.Buffer{}
|
||||
mod.genHeader(buffer, mod.sdkImports(referencesNestedTypes, true), imports)
|
||||
mod.genHeader(buffer, mod.sdkImports(referencesNestedTypes, true), externalImports, imports)
|
||||
|
||||
mod.genFunction(buffer, f)
|
||||
|
||||
|
@ -1255,7 +1309,7 @@ func (mod *modContext) gen(fs fs) error {
|
|||
|
||||
if mod.hasEnums() {
|
||||
buffer := &bytes.Buffer{}
|
||||
mod.genHeader(buffer, []string{}, nil)
|
||||
mod.genHeader(buffer, []string{}, nil, nil)
|
||||
|
||||
err := mod.genEnums(buffer, mod.enums)
|
||||
if err != nil {
|
||||
|
@ -1304,7 +1358,7 @@ func (mod *modContext) genIndex(exports []string) string {
|
|||
if len(mod.resources) != 0 {
|
||||
imports = mod.sdkImports(false /*nested*/, true /*utilities*/)
|
||||
}
|
||||
mod.genHeader(w, imports, nil)
|
||||
mod.genHeader(w, imports, nil, nil)
|
||||
|
||||
// Export anything flatly that is a direct export rather than sub-module.
|
||||
if len(exports) > 0 {
|
||||
|
|
|
@ -40,6 +40,20 @@ func TestGeneratePackage(t *testing.T) {
|
|||
"types/enums/tree/v1/index.ts",
|
||||
},
|
||||
},
|
||||
{
|
||||
"External resource schema",
|
||||
"external-resource-schema",
|
||||
[]string{
|
||||
"index.ts",
|
||||
"argFunction.ts",
|
||||
"cat.ts",
|
||||
"component.ts",
|
||||
"workload.ts",
|
||||
"types/index.ts",
|
||||
"types/input.ts",
|
||||
"types/output.ts",
|
||||
},
|
||||
},
|
||||
}
|
||||
testDir := filepath.Join("..", "internal", "test", "testdata")
|
||||
for _, tt := range tests {
|
||||
|
|
|
@ -38,6 +38,10 @@ func (ss StringSet) Add(s string) {
|
|||
ss[s] = struct{}{}
|
||||
}
|
||||
|
||||
func (ss StringSet) Any() bool {
|
||||
return len(ss) > 0
|
||||
}
|
||||
|
||||
func (ss StringSet) Delete(s string) {
|
||||
delete(ss, s)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue