diff --git a/hugolib/js_test.go b/hugolib/js_test.go
index 1e59927c79f..fb7c125975b 100644
--- a/hugolib/js_test.go
+++ b/hugolib/js_test.go
@@ -15,6 +15,7 @@ package hugolib
import (
"os"
+ "os/exec"
"path/filepath"
"testing"
@@ -29,7 +30,7 @@ import (
"github.com/gohugoio/hugo/common/loggers"
)
-func TestJS_Build(t *testing.T) {
+func TestJSBuild(t *testing.T) {
if !isCI() {
t.Skip("skip (relative) long running modules test when running locally")
}
@@ -43,13 +44,44 @@ func TestJS_Build(t *testing.T) {
mainJS := `
import "./included";
+ import { toCamelCase } from "to-camel-case";
+
console.log("main");
- `
+ console.log("To camel:", toCamelCase("space case"));
+`
includedJS := `
console.log("included");
+
`
- workDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-test-babel")
+ jsxContent := `
+import * as React from 'react'
+import * as ReactDOM from 'react-dom'
+
+ ReactDOM.render(
+
Hello, world!
,
+ document.getElementById('root')
+ );
+`
+
+ tsContent := `function greeter(person: string) {
+ return "Hello, " + person;
+}
+
+let user = [0, 1, 2];
+
+document.body.textContent = greeter(user);`
+
+ packageJSON := `{
+ "scripts": {},
+
+ "dependencies": {
+ "to-camel-case": "1.0.0"
+ }
+}
+`
+
+ workDir, clean, err := htesting.CreateTempDir(hugofs.Os, "hugo-test-js")
c.Assert(err, qt.IsNil)
defer clean()
@@ -65,23 +97,38 @@ func TestJS_Build(t *testing.T) {
b.WithContent("p1.md", "")
b.WithTemplates("index.html", `
- {{ $options := dict "minify" true }}
- {{ $transpiled := resources.Get "js/main.js" | js.Build $options }}
- Built: {{ $transpiled.Content | safeJS }}
- `)
+{{ $options := dict "minify" false "externals" (slice "react" "react-dom") }}
+{{ $js := resources.Get "js/main.js" | js.Build $options }}
+JS: {{ template "print" $js }}
+{{ $jsx := resources.Get "js/myjsx.jsx" | js.Build $options }}
+JSX: {{ template "print" $jsx }}
+{{ $ts := resources.Get "js/myts.ts" | js.Build }}
+TS: {{ template "print" $ts }}
+
+{{ define "print" }}RelPermalink: {{.RelPermalink}}|MIME: {{ .MediaType }}|Content: {{ .Content | safeJS }}{{ end }}
+
+`)
jsDir := filepath.Join(workDir, "assets", "js")
b.Assert(os.MkdirAll(jsDir, 0777), qt.IsNil)
+ b.Assert(os.Chdir(workDir), qt.IsNil)
+ b.WithSourceFile("package.json", packageJSON)
b.WithSourceFile("assets/js/main.js", mainJS)
+ b.WithSourceFile("assets/js/myjsx.jsx", jsxContent)
+ b.WithSourceFile("assets/js/myts.ts", tsContent)
+
b.WithSourceFile("assets/js/included.js", includedJS)
- _, err = captureStdout(func() error {
- return b.BuildE(BuildCfg{})
- })
- b.Assert(err, qt.IsNil)
+ out, err := exec.Command("npm", "install").CombinedOutput()
+ b.Assert(err, qt.IsNil, qt.Commentf(string(out)))
+
+ b.Build(BuildCfg{})
b.AssertFileContent("public/index.html", `
- Built: (()=>{console.log("included");console.log("main");})();
- `)
+console.log("included");
+if (hasSpace.test(string))
+const React = __toModule(require("react"));
+function greeter(person) {
+`)
}
diff --git a/media/mediaType.go b/media/mediaType.go
index e33583a0e45..8a2efc4a454 100644
--- a/media/mediaType.go
+++ b/media/mediaType.go
@@ -45,7 +45,6 @@ type Type struct {
Delimiter string `json:"delimiter"` // e.g. "."
- // TODO(bep) make this a string to make it hashable + method
Suffixes []string `json:"suffixes"`
// Set when doing lookup by suffix.
@@ -130,13 +129,17 @@ var (
CSVType = Type{MainType: "text", SubType: "csv", Suffixes: []string{"csv"}, Delimiter: defaultDelimiter}
HTMLType = Type{MainType: "text", SubType: "html", Suffixes: []string{"html"}, Delimiter: defaultDelimiter}
JavascriptType = Type{MainType: "application", SubType: "javascript", Suffixes: []string{"js"}, Delimiter: defaultDelimiter}
- JSONType = Type{MainType: "application", SubType: "json", Suffixes: []string{"json"}, Delimiter: defaultDelimiter}
- RSSType = Type{MainType: "application", SubType: "rss", mimeSuffix: "xml", Suffixes: []string{"xml"}, Delimiter: defaultDelimiter}
- XMLType = Type{MainType: "application", SubType: "xml", Suffixes: []string{"xml"}, Delimiter: defaultDelimiter}
- SVGType = Type{MainType: "image", SubType: "svg", mimeSuffix: "xml", Suffixes: []string{"svg"}, Delimiter: defaultDelimiter}
- TextType = Type{MainType: "text", SubType: "plain", Suffixes: []string{"txt"}, Delimiter: defaultDelimiter}
- TOMLType = Type{MainType: "application", SubType: "toml", Suffixes: []string{"toml"}, Delimiter: defaultDelimiter}
- YAMLType = Type{MainType: "application", SubType: "yaml", Suffixes: []string{"yaml", "yml"}, Delimiter: defaultDelimiter}
+ TypeScriptType = Type{MainType: "application", SubType: "typescript", Suffixes: []string{"ts"}, Delimiter: defaultDelimiter}
+ TSXType = Type{MainType: "text", SubType: "tsx", Suffixes: []string{"tsx"}, Delimiter: defaultDelimiter}
+ JSXType = Type{MainType: "text", SubType: "jsx", Suffixes: []string{"jsx"}, Delimiter: defaultDelimiter}
+
+ JSONType = Type{MainType: "application", SubType: "json", Suffixes: []string{"json"}, Delimiter: defaultDelimiter}
+ RSSType = Type{MainType: "application", SubType: "rss", mimeSuffix: "xml", Suffixes: []string{"xml"}, Delimiter: defaultDelimiter}
+ XMLType = Type{MainType: "application", SubType: "xml", Suffixes: []string{"xml"}, Delimiter: defaultDelimiter}
+ SVGType = Type{MainType: "image", SubType: "svg", mimeSuffix: "xml", Suffixes: []string{"svg"}, Delimiter: defaultDelimiter}
+ TextType = Type{MainType: "text", SubType: "plain", Suffixes: []string{"txt"}, Delimiter: defaultDelimiter}
+ TOMLType = Type{MainType: "application", SubType: "toml", Suffixes: []string{"toml"}, Delimiter: defaultDelimiter}
+ YAMLType = Type{MainType: "application", SubType: "yaml", Suffixes: []string{"yaml", "yml"}, Delimiter: defaultDelimiter}
// Common image types
PNGType = Type{MainType: "image", SubType: "png", Suffixes: []string{"png"}, Delimiter: defaultDelimiter}
@@ -165,6 +168,9 @@ var DefaultTypes = Types{
SASSType,
HTMLType,
JavascriptType,
+ TypeScriptType,
+ TSXType,
+ JSXType,
JSONType,
RSSType,
XMLType,
diff --git a/media/mediaType_test.go b/media/mediaType_test.go
index f18fd90bb0a..ee7d4407afe 100644
--- a/media/mediaType_test.go
+++ b/media/mediaType_test.go
@@ -40,6 +40,9 @@ func TestDefaultTypes(t *testing.T) {
{CSVType, "text", "csv", "csv", "text/csv", "text/csv"},
{HTMLType, "text", "html", "html", "text/html", "text/html"},
{JavascriptType, "application", "javascript", "js", "application/javascript", "application/javascript"},
+ {TypeScriptType, "application", "typescript", "ts", "application/typescript", "application/typescript"},
+ {TSXType, "text", "tsx", "tsx", "text/tsx", "text/tsx"},
+ {JSXType, "text", "jsx", "jsx", "text/jsx", "text/jsx"},
{JSONType, "application", "json", "json", "application/json", "application/json"},
{RSSType, "application", "rss", "xml", "application/rss+xml", "application/rss+xml"},
{SVGType, "image", "svg", "svg", "image/svg+xml", "image/svg+xml"},
@@ -58,7 +61,7 @@ func TestDefaultTypes(t *testing.T) {
}
- c.Assert(len(DefaultTypes), qt.Equals, 23)
+ c.Assert(len(DefaultTypes), qt.Equals, 26)
}
diff --git a/resources/resource_transformers/js/build.go b/resources/resource_transformers/js/build.go
index 6224ee178ce..7591816962c 100644
--- a/resources/resource_transformers/js/build.go
+++ b/resources/resource_transformers/js/build.go
@@ -17,8 +17,11 @@ import (
"fmt"
"io/ioutil"
"path"
+ "strings"
+ "github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/hugolib/filesystems"
+ "github.com/gohugoio/hugo/media"
"github.com/gohugoio/hugo/resources/internal"
"github.com/mitchellh/mapstructure"
@@ -28,15 +31,46 @@ import (
"github.com/gohugoio/hugo/resources/resource"
)
+const defaultTarget = "esnext"
+
type Options struct {
+ // If not set, the source path will be used as the base target path.
+ // Note that the target path's extension may change if the target MIME type
+ // is different, e.g. when the source is TypeScript.
+ TargetPath string
+
+ // Whether to minify to output.
+ Minify bool
+
+ // The language target.
+ // One of: es2015, es2016, es2017, es2018, es2019, es2020 or esnext.
+ // Default is esnext.
+ Target string
+
+ // External dependencies, e.g. "react".
+ Externals []string `hash:"set"`
+
+ // What to use instead of React.createElement.
+ JSXFactory string
+
+ // What to use instead of React.Fragment.
+ JSXFragment string
+}
+
+type internalOptions struct {
+ TargetPath string
Minify bool
- Externals []string
Target string
- Loader string
- Defines map[string]string
JSXFactory string
JSXFragment string
- TSConfig string
+
+ Externals []string `hash:"set"`
+
+ // These are currently not exposed in the public Options struct,
+ // but added here to make the options hash as stable as possible for
+ // whenever we do.
+ Defines map[string]string
+ TSConfig string
}
func DecodeOptions(m map[string]interface{}) (opts Options, err error) {
@@ -44,6 +78,13 @@ func DecodeOptions(m map[string]interface{}) (opts Options, err error) {
return
}
err = mapstructure.WeakDecode(m, &opts)
+
+ if opts.TargetPath != "" {
+ opts.TargetPath = helpers.ToSlashTrimLeading(opts.TargetPath)
+ }
+
+ opts.Target = strings.ToLower(opts.Target)
+
return
}
@@ -57,7 +98,7 @@ func New(fs *filesystems.SourceFilesystem, rs *resources.Spec) *Client {
}
type buildTransformation struct {
- options Options
+ options internalOptions
rs *resources.Spec
sfs *filesystems.SourceFilesystem
}
@@ -67,9 +108,17 @@ func (t *buildTransformation) Key() internal.ResourceTransformationKey {
}
func (t *buildTransformation) Transform(ctx *resources.ResourceTransformationCtx) error {
+ ctx.OutMediaType = media.JavascriptType
+
+ if t.options.TargetPath != "" {
+ ctx.OutPath = t.options.TargetPath
+ } else {
+ ctx.ReplaceOutPathExtension(".js")
+ }
+
var target api.Target
switch t.options.Target {
- case "", "esnext":
+ case defaultTarget:
target = api.ESNext
case "es6", "es2015":
target = api.ES2015
@@ -88,29 +137,20 @@ func (t *buildTransformation) Transform(ctx *resources.ResourceTransformationCtx
}
var loader api.Loader
- switch t.options.Loader {
- case "", "js":
+ switch ctx.InMediaType.SubType {
+ // TODO(bep) ESBuild support a set of other loaders, but I currently fail
+ // to see the relevance. That may change as we start using this.
+ case media.JavascriptType.SubType:
loader = api.LoaderJS
- case "jsx":
- loader = api.LoaderJSX
- case "ts":
+ case media.TypeScriptType.SubType:
loader = api.LoaderTS
- case "tsx":
+ case media.TSXType.SubType:
loader = api.LoaderTSX
- case "json":
- loader = api.LoaderJSON
- case "text":
- loader = api.LoaderText
- case "base64":
- loader = api.LoaderBase64
- case "dataURL":
- loader = api.LoaderDataURL
- case "file":
- loader = api.LoaderFile
- case "binary":
- loader = api.LoaderBinary
+ case media.JSXType.SubType:
+ loader = api.LoaderJSX
default:
- return fmt.Errorf("invalid loader: %q", t.options.Loader)
+ return fmt.Errorf("unsupported Media Type: %q", ctx.InMediaType)
+
}
src, err := ioutil.ReadAll(ctx.From)
@@ -159,8 +199,22 @@ func (t *buildTransformation) Transform(ctx *resources.ResourceTransformationCtx
return nil
}
-func (c *Client) Process(res resources.ResourceTransformer, options Options) (resource.Resource, error) {
+func (c *Client) Process(res resources.ResourceTransformer, opts Options) (resource.Resource, error) {
return res.Transform(
- &buildTransformation{rs: c.rs, sfs: c.sfs, options: options},
+ &buildTransformation{rs: c.rs, sfs: c.sfs, options: toInternalOptions(opts)},
)
}
+
+func toInternalOptions(opts Options) internalOptions {
+ target := opts.Target
+ if target == "" {
+ target = defaultTarget
+ }
+ return internalOptions{
+ TargetPath: opts.TargetPath,
+ Target: target,
+ Externals: opts.Externals,
+ JSXFactory: opts.JSXFactory,
+ JSXFragment: opts.JSXFragment,
+ }
+}
diff --git a/resources/resource_transformers/js/build_test.go b/resources/resource_transformers/js/build_test.go
new file mode 100644
index 00000000000..ddb249a2587
--- /dev/null
+++ b/resources/resource_transformers/js/build_test.go
@@ -0,0 +1,68 @@
+// Copyright 2020 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package js
+
+import (
+ "testing"
+
+ qt "github.com/frankban/quicktest"
+)
+
+// This test is added to test/warn against breaking the "stability" of the
+// cache key. It's sometimes needed to break this, but should be avoided if possible.
+func TestOptionKey(t *testing.T) {
+ c := qt.New(t)
+
+ opts := internalOptions{
+ TargetPath: "foo",
+ }
+
+ key := (&buildTransformation{options: opts}).Key()
+
+ c.Assert(key.Value(), qt.Equals, "jsbuild_9405671309963492201")
+}
+
+func TestToInternalOptions(t *testing.T) {
+ c := qt.New(t)
+
+ o := Options{
+ TargetPath: "v1",
+ Target: "v2",
+ JSXFactory: "v3",
+ JSXFragment: "v4",
+ Externals: []string{"react"},
+ }
+
+ c.Assert(toInternalOptions(o), qt.DeepEquals, internalOptions{
+ TargetPath: "v1",
+ Minify: false,
+ Target: "v2",
+ JSXFactory: "v3",
+ JSXFragment: "v4",
+ Externals: []string{"react"},
+ Defines: nil,
+ TSConfig: "",
+ })
+
+ c.Assert(toInternalOptions(Options{}), qt.DeepEquals, internalOptions{
+ TargetPath: "",
+ Minify: false,
+ Target: "esnext",
+ JSXFactory: "",
+ JSXFragment: "",
+ Externals: nil,
+ Defines: nil,
+ TSConfig: "",
+ })
+}
diff --git a/tpl/internal/resourcehelpers/helpers.go b/tpl/internal/resourcehelpers/helpers.go
new file mode 100644
index 00000000000..4f8b7539a74
--- /dev/null
+++ b/tpl/internal/resourcehelpers/helpers.go
@@ -0,0 +1,71 @@
+// Copyright 2020 The Hugo Authors. All rights reserved.
+//
+// Portions Copyright The Go Authors.
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package resourcehelpers
+
+import (
+ "errors"
+ "fmt"
+
+ _errors "github.com/pkg/errors"
+
+ "github.com/gohugoio/hugo/common/maps"
+ "github.com/gohugoio/hugo/resources"
+)
+
+// We allow string or a map as the first argument in some cases.
+func ResolveIfFirstArgIsString(args []interface{}) (resources.ResourceTransformer, string, bool) {
+ if len(args) != 2 {
+ return nil, "", false
+ }
+
+ v1, ok1 := args[0].(string)
+ if !ok1 {
+ return nil, "", false
+ }
+ v2, ok2 := args[1].(resources.ResourceTransformer)
+
+ return v2, v1, ok2
+}
+
+// This roundabout way of doing it is needed to get both pipeline behaviour and options as arguments.
+func ResolveArgs(args []interface{}) (resources.ResourceTransformer, map[string]interface{}, error) {
+ if len(args) == 0 {
+ return nil, nil, errors.New("no Resource provided in transformation")
+ }
+
+ if len(args) == 1 {
+ r, ok := args[0].(resources.ResourceTransformer)
+ if !ok {
+ return nil, nil, fmt.Errorf("type %T not supported in Resource transformations", args[0])
+ }
+ return r, nil, nil
+ }
+
+ r, ok := args[1].(resources.ResourceTransformer)
+ if !ok {
+ if _, ok := args[1].(map[string]interface{}); !ok {
+ return nil, nil, fmt.Errorf("no Resource provided in transformation")
+ }
+ return nil, nil, fmt.Errorf("type %T not supported in Resource transformations", args[0])
+ }
+
+ m, err := maps.ToStringMapE(args[0])
+ if err != nil {
+ return nil, nil, _errors.Wrap(err, "invalid options type")
+ }
+
+ return r, m, nil
+}
diff --git a/tpl/js/js.go b/tpl/js/js.go
index d8ba35a76ee..4dc97a70765 100644
--- a/tpl/js/js.go
+++ b/tpl/js/js.go
@@ -15,15 +15,12 @@
package js
import (
- "errors"
- "fmt"
-
- "github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/deps"
+ "github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/resources"
"github.com/gohugoio/hugo/resources/resource"
"github.com/gohugoio/hugo/resources/resource_transformers/js"
- _errors "github.com/pkg/errors"
+ "github.com/gohugoio/hugo/tpl/internal/resourcehelpers"
)
// New returns a new instance of the js-namespaced template functions.
@@ -41,50 +38,33 @@ type Namespace struct {
// Build processes the given Resource with ESBuild.
func (ns *Namespace) Build(args ...interface{}) (resource.Resource, error) {
- r, m, err := ns.resolveArgs(args)
- if err != nil {
- return nil, err
- }
- var options js.Options
- if m != nil {
- options, err = js.DecodeOptions(m)
+ var (
+ r resources.ResourceTransformer
+ m map[string]interface{}
+ targetPath string
+ err error
+ ok bool
+ )
+
+ r, targetPath, ok = resourcehelpers.ResolveIfFirstArgIsString(args)
+ if !ok {
+ r, m, err = resourcehelpers.ResolveArgs(args)
if err != nil {
return nil, err
}
}
- return ns.client.Process(r, options)
-
-}
-
-// This roundabout way of doing it is needed to get both pipeline behaviour and options as arguments.
-// This is a copy of tpl/resources/resolveArgs
-func (ns *Namespace) resolveArgs(args []interface{}) (resources.ResourceTransformer, map[string]interface{}, error) {
- if len(args) == 0 {
- return nil, nil, errors.New("no Resource provided in transformation")
- }
-
- if len(args) == 1 {
- r, ok := args[0].(resources.ResourceTransformer)
- if !ok {
- return nil, nil, fmt.Errorf("type %T not supported in Resource transformations", args[0])
- }
- return r, nil, nil
- }
-
- r, ok := args[1].(resources.ResourceTransformer)
- if !ok {
- if _, ok := args[1].(map[string]interface{}); !ok {
- return nil, nil, fmt.Errorf("no Resource provided in transformation")
+ var options js.Options
+ if targetPath != "" {
+ options.TargetPath = helpers.ToSlashTrimLeading(targetPath)
+ } else if m != nil {
+ options, err = js.DecodeOptions(m)
+ if err != nil {
+ return nil, err
}
- return nil, nil, fmt.Errorf("type %T not supported in Resource transformations", args[0])
}
- m, err := maps.ToStringMapE(args[0])
- if err != nil {
- return nil, nil, _errors.Wrap(err, "invalid options type")
- }
+ return ns.client.Process(r, options)
- return r, m, nil
}
diff --git a/tpl/resources/resources.go b/tpl/resources/resources.go
index 6625702ab26..cdde6bd5d31 100644
--- a/tpl/resources/resources.go
+++ b/tpl/resources/resources.go
@@ -19,13 +19,14 @@ import (
"fmt"
"path/filepath"
+ "github.com/gohugoio/hugo/tpl/internal/resourcehelpers"
+
+ "github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/resources/postpub"
- "github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/deps"
"github.com/gohugoio/hugo/resources"
"github.com/gohugoio/hugo/resources/resource"
- _errors "github.com/pkg/errors"
"github.com/gohugoio/hugo/resources/resource_factories/bundler"
"github.com/gohugoio/hugo/resources/resource_factories/create"
@@ -239,10 +240,10 @@ func (ns *Namespace) ToCSS(args ...interface{}) (resource.Resource, error) {
ok bool
)
- r, targetPath, ok = ns.resolveIfFirstArgIsString(args)
+ r, targetPath, ok = resourcehelpers.ResolveIfFirstArgIsString(args)
if !ok {
- r, m, err = ns.resolveArgs(args)
+ r, m, err = resourcehelpers.ResolveArgs(args)
if err != nil {
return nil, err
}
@@ -250,7 +251,7 @@ func (ns *Namespace) ToCSS(args ...interface{}) (resource.Resource, error) {
var options scss.Options
if targetPath != "" {
- options.TargetPath = targetPath
+ options.TargetPath = helpers.ToSlashTrimLeading(targetPath)
} else if m != nil {
options, err = scss.DecodeOptions(m)
if err != nil {
@@ -263,7 +264,7 @@ func (ns *Namespace) ToCSS(args ...interface{}) (resource.Resource, error) {
// PostCSS processes the given Resource with PostCSS
func (ns *Namespace) PostCSS(args ...interface{}) (resource.Resource, error) {
- r, m, err := ns.resolveArgs(args)
+ r, m, err := resourcehelpers.ResolveArgs(args)
if err != nil {
return nil, err
}
@@ -285,7 +286,7 @@ func (ns *Namespace) PostProcess(r resource.Resource) (postpub.PostPublishedReso
// Babel processes the given Resource with Babel.
func (ns *Namespace) Babel(args ...interface{}) (resource.Resource, error) {
- r, m, err := ns.resolveArgs(args)
+ r, m, err := resourcehelpers.ResolveArgs(args)
if err != nil {
return nil, err
}
@@ -301,48 +302,3 @@ func (ns *Namespace) Babel(args ...interface{}) (resource.Resource, error) {
return ns.babelClient.Process(r, options)
}
-
-// We allow string or a map as the first argument in some cases.
-func (ns *Namespace) resolveIfFirstArgIsString(args []interface{}) (resources.ResourceTransformer, string, bool) {
- if len(args) != 2 {
- return nil, "", false
- }
-
- v1, ok1 := args[0].(string)
- if !ok1 {
- return nil, "", false
- }
- v2, ok2 := args[1].(resources.ResourceTransformer)
-
- return v2, v1, ok2
-}
-
-// This roundabout way of doing it is needed to get both pipeline behaviour and options as arguments.
-func (ns *Namespace) resolveArgs(args []interface{}) (resources.ResourceTransformer, map[string]interface{}, error) {
- if len(args) == 0 {
- return nil, nil, errors.New("no Resource provided in transformation")
- }
-
- if len(args) == 1 {
- r, ok := args[0].(resources.ResourceTransformer)
- if !ok {
- return nil, nil, fmt.Errorf("type %T not supported in Resource transformations", args[0])
- }
- return r, nil, nil
- }
-
- r, ok := args[1].(resources.ResourceTransformer)
- if !ok {
- if _, ok := args[1].(map[string]interface{}); !ok {
- return nil, nil, fmt.Errorf("no Resource provided in transformation")
- }
- return nil, nil, fmt.Errorf("type %T not supported in Resource transformations", args[0])
- }
-
- m, err := maps.ToStringMapE(args[0])
- if err != nil {
- return nil, nil, _errors.Wrap(err, "invalid options type")
- }
-
- return r, m, nil
-}