@schalkneethling/miyagi-core 4.9.0 → 4.10.0

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/lib/cli/perf.js CHANGED
@@ -59,6 +59,7 @@ export default async function perfCli(args) {
59
59
 
60
60
  const result = await runPerformance({
61
61
  cwd,
62
+ componentsFolder: global.config.components.folder,
62
63
  compression: args.compression,
63
64
  warnRatio: warnRatioOverride,
64
65
  render: renderPageHtml,
@@ -39,6 +39,7 @@ export default {
39
39
  ".miyagi.js",
40
40
  ".miyagi.mjs",
41
41
  ],
42
+ hidden: [],
42
43
  lang: "en",
43
44
  textDirection: "ltr",
44
45
  },
@@ -500,6 +500,12 @@ export default (userConfig = {}) => {
500
500
  sanitizePath,
501
501
  );
502
502
  }
503
+
504
+ if (config.components.hidden) {
505
+ config.components.hidden = arrayfy(config.components.hidden).map(
506
+ sanitizePath,
507
+ );
508
+ }
503
509
  }
504
510
 
505
511
  if (!config.ui) config.ui = {};
@@ -68,6 +68,7 @@ export default function Router() {
68
68
  if (!global.config.isBuild) {
69
69
  attachPerformanceRoutes(global.app, {
70
70
  cwd: process.cwd(),
71
+ componentsFolder: global.config.components.folder,
71
72
  render: renderPageHtml,
72
73
  });
73
74
  }
@@ -55,6 +55,7 @@ function resolveImportGraph(entryPath) {
55
55
  * 50 kB util shows the real reachable size, not just the entry file.
56
56
  * @param {{
57
57
  * cwd: string,
58
+ * componentsFolder: string,
58
59
  * componentPath: string,
59
60
  * entry: { css?: { budget?: string }, js?: { budget?: string } },
60
61
  * compression: "raw"|"gzip"|"brotli",
@@ -64,12 +65,13 @@ function resolveImportGraph(entryPath) {
64
65
  */
65
66
  export function measureComponent({
66
67
  cwd,
68
+ componentsFolder = "",
67
69
  componentPath,
68
70
  entry,
69
71
  compression,
70
72
  warnRatio,
71
73
  }) {
72
- const folder = path.join(cwd, componentPath);
74
+ const folder = path.join(cwd, componentsFolder, componentPath);
73
75
  const componentName = path.basename(componentPath);
74
76
  const cssPath = path.join(folder, `${componentName}.css`);
75
77
  const jsPath = path.join(folder, `${componentName}.js`);
@@ -47,6 +47,7 @@ function tally(statuses) {
47
47
  * declared page variation.
48
48
  * @param {{
49
49
  * cwd?: string,
50
+ * componentsFolder?: string,
50
51
  * compression?: "raw"|"gzip"|"brotli",
51
52
  * warnRatio?: number,
52
53
  * render?: (templatePath: string, variation: string) => Promise<string>,
@@ -60,6 +61,7 @@ export async function runPerformance(options = {}) {
60
61
  }
61
62
 
62
63
  const cwd = options.cwd ?? process.cwd();
64
+ const componentsFolder = options.componentsFolder ?? "";
63
65
  const compression = options.compression ?? config.compression;
64
66
  const warnRatio = options.warnRatio ?? config.warnRatio;
65
67
 
@@ -68,6 +70,7 @@ export async function runPerformance(options = {}) {
68
70
  for (const [componentPath, entry] of Object.entries(config.components)) {
69
71
  const measurement = measureComponent({
70
72
  cwd,
73
+ componentsFolder,
71
74
  componentPath,
72
75
  entry,
73
76
  compression,
@@ -19,6 +19,7 @@ import { runPerformance } from "./index.js";
19
19
  * @param {object} app - Express app
20
20
  * @param {{
21
21
  * cwd: string,
22
+ * componentsFolder?: string,
22
23
  * render?: (templatePath: string, variation: string) => Promise<string>,
23
24
  * }} options
24
25
  * @returns {boolean} true when the config file exists at registration time
@@ -28,6 +29,7 @@ export function attachPerformanceRoutes(app, options) {
28
29
  try {
29
30
  const result = await runPerformance({
30
31
  cwd: options.cwd,
32
+ componentsFolder: options.componentsFolder,
31
33
  render: options.render,
32
34
  });
33
35
  if (!result.enabled) {
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import path from "path";
7
+ import anymatch from "anymatch";
7
8
 
8
9
  /**
9
10
  * @param {object} config - the user configuration object
@@ -49,3 +50,58 @@ export const getThemeMode = (cookies = {}) => {
49
50
  `miyagi_${global.config.projectName.replaceAll(" ", "-")}_theme`
50
51
  ];
51
52
  };
53
+
54
+ /**
55
+ * @param {Array} menu
56
+ * @returns {Array} menu with hidden components removed
57
+ */
58
+ export function getDisplayMenu(menu) {
59
+ const hidden = global.config.components.hidden;
60
+
61
+ if (!menu || !hidden?.length) {
62
+ return menu;
63
+ }
64
+
65
+ if (!Array.isArray(menu)) {
66
+ return menu;
67
+ }
68
+
69
+ return menu.reduce((acc, item) => {
70
+ if (
71
+ item.shortPath &&
72
+ anymatch(hidden, item.shortPath.replaceAll("\\", "/"))
73
+ ) {
74
+ return acc;
75
+ }
76
+
77
+ if (item.children) {
78
+ const filteredChildren = getDisplayMenu(item.children);
79
+
80
+ if (filteredChildren.length === 0) {
81
+ return acc;
82
+ }
83
+
84
+ acc.push({ ...item, children: filteredChildren });
85
+ } else {
86
+ acc.push(item);
87
+ }
88
+
89
+ return acc;
90
+ }, []);
91
+ }
92
+
93
+ /**
94
+ * @param {Array} components
95
+ * @returns {Array} components with hidden entries removed
96
+ */
97
+ export function getDisplayComponents(components) {
98
+ const hidden = global.config.components.hidden;
99
+
100
+ if (!components || !hidden?.length) {
101
+ return components;
102
+ }
103
+
104
+ return components.filter(
105
+ (c) => !anymatch(hidden, c.shortPath.replaceAll("\\", "/")),
106
+ );
107
+ }
@@ -250,7 +250,10 @@ async function renderVariations({
250
250
 
251
251
  let perfSection;
252
252
  try {
253
- const perfResult = await runPerformance({ cwd: process.cwd() });
253
+ const perfResult = await runPerformance({
254
+ cwd: process.cwd(),
255
+ componentsFolder: global.config.components.folder,
256
+ });
254
257
  perfSection = buildComponentPerfSection(
255
258
  perfResult,
256
259
  component.paths.dir.short,
@@ -1,5 +1,10 @@
1
1
  import config from "../../../default-config.js";
2
- import { getUserUiConfig, getThemeMode } from "../../helpers.js";
2
+ import {
3
+ getUserUiConfig,
4
+ getThemeMode,
5
+ getDisplayMenu,
6
+ getDisplayComponents,
7
+ } from "../../helpers.js";
3
8
 
4
9
  /**
5
10
  * @param {object} object - parameter object
@@ -21,8 +26,8 @@ export default async function renderMainComponentDocs({
21
26
  "main.twig.miyagi",
22
27
  {
23
28
  lang: global.config.ui.lang,
24
- folders: global.state.menu,
25
- components: global.state.components,
29
+ folders: getDisplayMenu(global.state.menu),
30
+ components: getDisplayComponents(global.state.components),
26
31
  flatUrlPattern: global.config.isBuild
27
32
  ? "/show-{{component}}.html"
28
33
  : "/show?file={{component}}",
@@ -1,6 +1,11 @@
1
1
  import config from "../../../default-config.js";
2
2
  import * as helpers from "../../../helpers.js";
3
- import { getUserUiConfig, getThemeMode } from "../../helpers.js";
3
+ import {
4
+ getUserUiConfig,
5
+ getThemeMode,
6
+ getDisplayMenu,
7
+ getDisplayComponents,
8
+ } from "../../helpers.js";
4
9
  import { runPerformance } from "../../../performance/index.js";
5
10
  import { buildPagePerfBanner } from "../../../performance/view-data.js";
6
11
  import { renderPageHtml } from "../../../performance/render-page.js";
@@ -45,6 +50,7 @@ export default async function renderMainComponent({
45
50
  try {
46
51
  const perfResult = await runPerformance({
47
52
  cwd: process.cwd(),
53
+ componentsFolder: global.config.components.folder,
48
54
  render: renderPageHtml,
49
55
  });
50
56
  perfBanner = buildPagePerfBanner(
@@ -63,8 +69,8 @@ export default async function renderMainComponent({
63
69
  {
64
70
  perfBanner,
65
71
  lang: global.config.ui.lang,
66
- folders: global.state.menu,
67
- components: global.state.components,
72
+ folders: getDisplayMenu(global.state.menu),
73
+ components: getDisplayComponents(global.state.components),
68
74
  flatUrlPattern: global.config.isBuild
69
75
  ? "/show-{{component}}.html"
70
76
  : "/show?file={{component}}",
@@ -1,5 +1,10 @@
1
1
  import config from "../../../default-config.js";
2
- import { getUserUiConfig, getThemeMode } from "../../helpers.js";
2
+ import {
3
+ getUserUiConfig,
4
+ getThemeMode,
5
+ getDisplayMenu,
6
+ getDisplayComponents,
7
+ } from "../../helpers.js";
3
8
 
4
9
  /**
5
10
  * @param {object} object - parameter object
@@ -17,8 +22,8 @@ export default function renderMainDesignTokens({ res, cb, cookies, type }) {
17
22
  "main.twig.miyagi",
18
23
  {
19
24
  lang: global.config.ui.lang,
20
- folders: global.state.menu,
21
- components: global.state.components,
25
+ folders: getDisplayMenu(global.state.menu),
26
+ components: getDisplayComponents(global.state.components),
22
27
  flatUrlPattern: global.config.isBuild
23
28
  ? "/show-{{component}}.html"
24
29
  : "/show?file={{component}}",
@@ -1,5 +1,10 @@
1
1
  import config from "../../../default-config.js";
2
- import { getUserUiConfig, getThemeMode } from "../../helpers.js";
2
+ import {
3
+ getUserUiConfig,
4
+ getThemeMode,
5
+ getDisplayMenu,
6
+ getDisplayComponents,
7
+ } from "../../helpers.js";
3
8
 
4
9
  /**
5
10
  * @param {object} object - parameter object
@@ -15,8 +20,8 @@ export default async function renderMainDocs({ res, doc, cb, cookies }) {
15
20
  "main.twig.miyagi",
16
21
  {
17
22
  lang: global.config.ui.lang,
18
- folders: global.state.menu,
19
- components: global.state.components,
23
+ folders: getDisplayMenu(global.state.menu),
24
+ components: getDisplayComponents(global.state.components),
20
25
  flatUrlPattern: global.config.isBuild
21
26
  ? "/show-{{component}}.html"
22
27
  : "/show?file={{component}}",
@@ -1,5 +1,10 @@
1
1
  import config from "../../../default-config.js";
2
- import { getUserUiConfig, getThemeMode } from "../../helpers.js";
2
+ import {
3
+ getUserUiConfig,
4
+ getThemeMode,
5
+ getDisplayMenu,
6
+ getDisplayComponents,
7
+ } from "../../helpers.js";
3
8
 
4
9
  /**
5
10
  * @param {object} object - parameter object
@@ -14,8 +19,8 @@ export default function renderMainIndex({ res, cb, cookies }) {
14
19
  "main.twig.miyagi",
15
20
  {
16
21
  lang: global.config.ui.lang,
17
- folders: global.state.menu,
18
- components: global.state.components,
22
+ folders: getDisplayMenu(global.state.menu),
23
+ components: getDisplayComponents(global.state.components),
19
24
  flatUrlPattern: global.config.isBuild
20
25
  ? "/show-{{component}}.html"
21
26
  : "/show?file={{component}}",
@@ -1,6 +1,7 @@
1
1
  import jsYaml from "js-yaml";
2
2
  import { existsSync } from "node:fs";
3
3
  import deepMerge from "deepmerge";
4
+ import anymatch from "anymatch";
4
5
  import log from "../logger.js";
5
6
  import { t } from "../i18n/index.js";
6
7
  import { loadGlobalSchemas } from "./schemas.js";
@@ -116,21 +117,25 @@ export default function validateMockData(
116
117
  }
117
118
 
118
119
  if (!global.config.isBuild && !noCli) {
119
- const parseError =
120
- global.state.fileReadErrors?.[component.paths.schema.full];
121
- const schemaExistsOnDisk = existsSync(component.paths.schema.full);
122
- const warningMessage = parseError
123
- ? t("validator.mocks.schemaParseFailed")
124
- .replace("{{schemaFile}}", component.paths.schema.short)
125
- .replace("{{format}}", "JSON or YAML")
126
- : schemaExistsOnDisk
127
- ? t("validator.mocks.schemaParseFailed")
128
- .replace("{{schemaFile}}", component.paths.schema.short)
129
- .replace("{{format}}", "JSON or YAML")
130
- : t("validator.mocks.schemaMissing")
131
- .replace("{{component}}", component.paths.dir.short)
132
- .replace("{{schemaFile}}", component.paths.schema.short);
133
- log("warn", warningMessage);
120
+ const isHidden = anymatch(
121
+ global.config.components.hidden ?? [],
122
+ component.paths.dir.short.replaceAll("\\", "/"),
123
+ );
124
+
125
+ if (!isHidden) {
126
+ const parseError =
127
+ global.state.fileReadErrors?.[component.paths.schema.full];
128
+ const schemaExistsOnDisk = existsSync(component.paths.schema.full);
129
+ const warningMessage =
130
+ parseError || schemaExistsOnDisk
131
+ ? t("validator.mocks.schemaParseFailed")
132
+ .replace("{{schemaFile}}", component.paths.schema.short)
133
+ .replace("{{format}}", "JSON or YAML")
134
+ : t("validator.mocks.schemaMissing")
135
+ .replace("{{component}}", component.paths.dir.short)
136
+ .replace("{{schemaFile}}", component.paths.schema.short);
137
+ log("warn", warningMessage);
138
+ }
134
139
  }
135
140
 
136
141
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schalkneethling/miyagi-core",
3
- "version": "4.9.0",
3
+ "version": "4.10.0",
4
4
  "description": "miyagi is a component development tool for JavaScript template engines.",
5
5
  "main": "index.js",
6
6
  "author": "Schalk Neethling <schalkneethling@duck.com>, Michael Großklaus <mail@mgrossklaus.de> (https://www.mgrossklaus.de)",