Repository: maizzle/framework (js)

Issue:
urlParameters without _options causing production build to fail
- Maizzle Version: 4.2.0
- Node.js Version: 14.19.3

The production build is failing when urlParameters is missing `_options`.

1. Created a new project with the starter `npx degit maizzle/maizzle my-project`. 

2. Added the following to the config:

```
urlParameters: {
  utm_source: 'maizzle'
}
```

3. Build it: `npx maizzle build production`

```
⚠ Failed to compile template: promotional.html
TypeError: Cannot read property 'tags' of undefined
    at module.exports (/Users/homedir/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/transformers/urlParameters.js:10:27)
    at Object.exports.process (/Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/transformers/index.js:36:16)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async module.exports (/Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/generators/output/to-string.js:54:12)
    at async /Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/generators/output/to-disk.js:105:32
    at async asyncForEach (/Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/utils/helpers.js:4:7)
    at async /Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/generators/output/to-disk.js:97:11
    at async /Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/generators/output/to-disk.js:79:7
    at async asyncForEach (/Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/utils/helpers.js:4:7)
    at async /Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/generators/output/to-disk.js:71:5
⚠ Failed to compile template: transactional.html
TypeError: Cannot read property 'tags' of undefined
    at module.exports (/Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/transformers/urlParameters.js:10:27)
    at Object.exports.process (/Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/transformers/index.js:36:16)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
    at async module.exports (/Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/generators/output/to-string.js:54:12)
    at async /Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/generators/output/to-disk.js:105:32
    at async asyncForEach (/Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/utils/helpers.js:4:7)
    at async /Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/generators/output/to-disk.js:97:11
    at async /Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/generators/output/to-disk.js:79:7
    at async asyncForEach (/Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/utils/helpers.js:4:7)
    at async /Users/username/Projects AdHoc/my-project/node_modules/@maizzle/framework/src/generators/output/to-disk.js:71:5
✔ Built 0 templates in 0.645s
```


It will build successfully if the config is changed to:

```
urlParameters: {
  _options: {},
  utm_source: 'maizzle',
}
```

Also, it fails in the same way if urlParameters is added to the frontmatter without _options.

Pull request:
fix: don't require _options for urlParameters transformer
This PR fixes #771, where if you didn't provide the `_options` object to the `urlParameters` transformer in addition to the parameters that you wanted apended to URLs, the build would fail.


Patch:
diff --git a/src/transformers/urlParameters.js b/src/transformers/urlParameters.js
index 098d967..b57bf84 100644
--- a/src/transformers/urlParameters.js
+++ b/src/transformers/urlParameters.js
@@ -6,11 +6,11 @@ module.exports = async (html, config = {}, direct = false) => {
   const urlParameters = direct ? config : get(config, 'urlParameters', {})
 
   if (!isEmpty(urlParameters)) {
-    const {_options, ...parameters} = urlParameters
-    const tags = _options.tags ?? ['a']
-    const strict = _options.strict ?? true
-    const qs = _options.qs ?? {encode: false}
     const posthtmlOptions = get(config, 'build.posthtml.options', {})
+    const {_options, ...parameters} = urlParameters
+    const tags = get(_options, 'tags', ['a'])
+    const strict = get(_options, 'strict', true)
+    const qs = get(_options, 'qs', {encode: false})
 
     return posthtml([urlParams({parameters, tags, qs, strict})]).process(html, posthtmlOptions).then(result => result.html)
   }


Test patch:
diff --git a/test/test-transformers.js b/test/test-transformers.js
index 1519483..00e719a 100644
--- a/test/test-transformers.js
+++ b/test/test-transformers.js
@@ -315,20 +315,35 @@ test('filters (postcss)', async t => {
 })
 
 test('url parameters', async t => {
-  const html = await Maizzle.addURLParams(
+  const simple = await Maizzle.addURLParams(
+    `<a href="https://example.com">test</a>
+      <link href="https://foo.bar">`,
+    {
+      bar: 'baz',
+      qix: 'qux'
+    }
+  )
+
+  const withOptions = await Maizzle.addURLParams(
     `<a href="example.com">test</a>
       <link href="https://foo.bar">`,
     {
       _options: {
         tags: ['a[href*="example"]'],
-        strict: false
+        strict: false,
+        qs: {
+          encode: true
+        }
       },
-      bar: 'baz',
-      qix: 'qux'
+      foo: '@Bar@',
+      bar: 'baz'
     }
   )
 
-  t.is(html, `<a href="example.com?bar=baz&qix=qux">test</a>
+  t.is(simple, `<a href="https://example.com?bar=baz&qix=qux">test</a>
+      <link href="https://foo.bar">`)
+
+  t.is(withOptions, `<a href="example.com?bar=baz&foo=%40Bar%40">test</a>
       <link href="https://foo.bar">`)
 })