mikser-io 6.3.0 → 6.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "mikser-io",
3
- "version": "6.3.0",
3
+ "version": "6.4.1",
4
4
  "description": "<p align=\"center\"> <img src=\"mikser-lockup-stacked.svg\" alt=\"mikser\" width=\"198\" /> </p>",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
- "test": "node --no-warnings app.js --debug --working-folder test"
7
+ "debug": "node --no-warnings app.js --debug --working-folder test/fixture",
8
+ "test:unit": "node --test --test-reporter=spec 'test/unit/**/*.test.js'",
9
+ "test:smoke": "node --no-warnings app.js --working-folder test/fixture",
10
+ "test": "npm run test:unit && npm run test:smoke"
8
11
  },
9
12
  "bin": {
10
13
  "mikser": "app.js"
@@ -21,6 +21,7 @@ export default ({
21
21
  onSync,
22
22
  matchEntity,
23
23
  changeExtension,
24
+ getFormatInfo,
24
25
  findEntity,
25
26
  findEntities,
26
27
  constants: { ACTION, OPERATION, TASKS },
@@ -28,15 +29,6 @@ export default ({
28
29
  const collection = 'layouts'
29
30
  const type = 'layout'
30
31
 
31
- function getFormatInfo(relativePath) {
32
- const template = path.extname(relativePath).substring(1).toLowerCase()
33
- const withoutTemplate = relativePath.replace(path.extname(relativePath), '')
34
- const formatExt = path.extname(withoutTemplate).substring(1).toLowerCase()
35
- const [format, postprocessor] = formatExt.split('-')
36
- const name = formatExt ? withoutTemplate.replace(path.extname(withoutTemplate), '') : withoutTemplate
37
- return { name, format: format || 'html', template, postprocessor }
38
- }
39
-
40
32
  function addToSitemap(entity) {
41
33
  const logger = useLogger()
42
34
  const { sitemap } = runtime.state.layouts
@@ -36,7 +36,7 @@ export default ({
36
36
  try {
37
37
  const { page: rawPage, limit: rawLimit, ...filter } = req.query
38
38
  const page = Math.max(1, parseInt(rawPage) || 1)
39
- const limit = Math.min(100, Math.max(1, parseInt(rawLimit) || runtime.config.rest?.pageSize ?? 10))
39
+ const limit = Math.min(100, Math.max(1, parseInt(rawLimit) || (runtime.config.rest?.pageSize ?? 10)))
40
40
  const query = Object.keys(filter).length ? filter : undefined
41
41
 
42
42
  const all = await findEntities(query)
@@ -10,7 +10,7 @@ export default ({
10
10
  onLoad(() => {
11
11
  for (let { match, validate, operations = [OPERATION.CREATE, OPERATION.UPDATE] } of runtime.config.validator?.validators || []) {
12
12
  onValidate(operations, async entry => {
13
- if (entity.meta && matchEntity(entry.entity, match)) {
13
+ if (entry.entity?.meta && matchEntity(entry.entity, match)) {
14
14
  return await validate(entry.entity)
15
15
  }
16
16
  })
package/src/plugins.js CHANGED
@@ -51,7 +51,7 @@ export async function loadPlugin(pluginName) {
51
51
  }
52
52
  }
53
53
  }
54
- logger.error('Plugin %s not found. Searched: %s', pluginName, resolveLocations.join(', '))
54
+ logger.error('Plugin %s not found.', pluginName)
55
55
  }
56
56
 
57
57
  onLoad(async () => {
@@ -36,7 +36,7 @@ export async function loadPlugin(pluginName, workingFolder) {
36
36
  }
37
37
  }
38
38
 
39
- logger?.error('Postprocess plugin %s not found. Searched: %s', pluginName, resolveLocations.join(', '))
39
+ logger?.error('Postprocess plugin %s not found.', pluginName)
40
40
  }
41
41
 
42
42
  export default async ({ entity, options, config, context, state, logger }) => {
package/src/render.js CHANGED
@@ -3,24 +3,7 @@ import { createRequire } from 'node:module'
3
3
  import path from 'node:path'
4
4
  import _ from 'lodash'
5
5
  import { useLogger } from './engine.js'
6
-
7
- // Flatten template-helper args into a single human-readable message.
8
- // Handlebars helpers receive a trailing options object (it has a `.hash`
9
- // property) which we drop.
10
- function formatLogArgs(args) {
11
- if (args.length && typeof args[args.length - 1] === 'object' && args[args.length - 1] !== null && 'hash' in args[args.length - 1]) {
12
- args = args.slice(0, -1)
13
- }
14
- return args
15
- .map(arg => {
16
- if (arg == null) return String(arg)
17
- if (typeof arg === 'object') {
18
- try { return JSON.stringify(arg) } catch { return String(arg) }
19
- }
20
- return String(arg)
21
- })
22
- .join(' ')
23
- }
6
+ import { formatLogArgs } from './utils.js'
24
7
 
25
8
  export default async ({ entity, options, config, context, state, logger, port }) => {
26
9
  logger = logger || {
@@ -73,7 +56,7 @@ export default async ({ entity, options, config, context, state, logger, port })
73
56
  }
74
57
  }
75
58
 
76
- logger.error('Render plugin %s not found. Searched: %s', pluginName, resolveLocations.join(', '))
59
+ logger.error('Render plugin %s not found.', pluginName)
77
60
  }
78
61
 
79
62
  const { renderer } = options
package/src/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- import { hashFile, hashingStream } from 'hasha'
1
+ import { hashFile, hash } from 'hasha'
2
2
  import { stat } from 'node:fs/promises'
3
3
  import TruncateStream from 'truncate-stream'
4
4
  import { createReadStream } from 'node:fs'
@@ -23,7 +23,7 @@ export async function checksum(uri) {
23
23
  const truncate = new TruncateStream({ maxBytes })
24
24
  const fileStream = createReadStream(uri)
25
25
  fileStream.pipe(truncate)
26
- const checksum = size.toString() + ':' + await hashingStream(truncate, { algorithm: 'md5' })
26
+ const checksum = size.toString() + ':' + await hash(truncate, { algorithm: 'md5' })
27
27
  return checksum
28
28
  }
29
29
  }
@@ -48,7 +48,7 @@ export function matchEntity(entity, match) {
48
48
  if (!match) return false
49
49
  if (typeof match == 'function') return match(entity)
50
50
  else if (typeof match == 'string') {
51
- if (match.substring(0, 1) == '@/') {
51
+ if (match.substring(0, 2) == '@/') {
52
52
  return minimatch(entity.name, match.substring(2))
53
53
  } else {
54
54
  return minimatch(entity.id, match)
@@ -64,6 +64,43 @@ export function changeExtension(file, format) {
64
64
  return result
65
65
  }
66
66
 
67
+ // Decode a layout filename into its parts. `template` is the outer
68
+ // extension (the renderer); `format` is the output format encoded as a
69
+ // second extension (defaults to 'html'); `postprocessor`, if present,
70
+ // is everything after the `-` in the format segment.
71
+ //
72
+ // Examples:
73
+ // foo.hbs -> { name:'foo', format:'html', template:'hbs', postprocessor:undefined }
74
+ // page.css.hbs -> { name:'page', format:'css', template:'hbs', postprocessor:undefined }
75
+ // report.html-pdf.hbs -> { name:'report', format:'html', template:'hbs', postprocessor:'pdf' }
76
+ // welcome.html-mjml.liquid-> { name:'welcome', format:'html', template:'liquid', postprocessor:'mjml' }
77
+ export function getFormatInfo(relativePath) {
78
+ const template = path.extname(relativePath).substring(1).toLowerCase()
79
+ const withoutTemplate = relativePath.replace(path.extname(relativePath), '')
80
+ const formatExt = path.extname(withoutTemplate).substring(1).toLowerCase()
81
+ const [format, postprocessor] = formatExt.split('-')
82
+ const name = formatExt ? withoutTemplate.replace(path.extname(withoutTemplate), '') : withoutTemplate
83
+ return { name, format: format || 'html', template, postprocessor }
84
+ }
85
+
86
+ // Flatten template-helper args into a single human-readable message.
87
+ // Handlebars helpers receive a trailing options object (it has a `.hash`
88
+ // property) which we drop. Liquid filters and Eta calls don't.
89
+ export function formatLogArgs(args) {
90
+ if (args.length && typeof args[args.length - 1] === 'object' && args[args.length - 1] !== null && 'hash' in args[args.length - 1]) {
91
+ args = args.slice(0, -1)
92
+ }
93
+ return args
94
+ .map(arg => {
95
+ if (arg == null) return String(arg)
96
+ if (typeof arg === 'object') {
97
+ try { return JSON.stringify(arg) } catch { return String(arg) }
98
+ }
99
+ return String(arg)
100
+ })
101
+ .join(' ')
102
+ }
103
+
67
104
  // Build a compact "[layouts/foo.hbs:12:4]" suffix from whatever the
68
105
  // underlying template engine attached to its thrown error. Renderer
69
106
  // plugins are expected to set `err.layoutUri` (and optionally `err.line` /