@schalkneethling/miyagi-core 4.0.2

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.
Files changed (138) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +43 -0
  3. package/api/app.js +39 -0
  4. package/api/index.js +236 -0
  5. package/bin/miyagi.js +2 -0
  6. package/dist/css/iframe.css +31 -0
  7. package/dist/css/main.css +1 -0
  8. package/dist/js/_iframe-links-DdifIr4P.js +1 -0
  9. package/dist/js/_mock-data-Dypo4Bl_.js +1 -0
  10. package/dist/js/_prism-By3NMwUd.js +1 -0
  11. package/dist/js/iframe.build.js +1 -0
  12. package/dist/js/iframe.js +1 -0
  13. package/dist/js/index-BKDKaBC6.js +1 -0
  14. package/dist/js/jsontree.js +1 -0
  15. package/dist/js/main.build.js +1 -0
  16. package/dist/js/main.js +1 -0
  17. package/frontend/assets/css/iframe/accordion-tabs.css +77 -0
  18. package/frontend/assets/css/iframe/jsontree.js.css +325 -0
  19. package/frontend/assets/css/iframe/prism.css +132 -0
  20. package/frontend/assets/css/iframe/styleguide/colors.css +61 -0
  21. package/frontend/assets/css/iframe/styleguide/fonts.css +37 -0
  22. package/frontend/assets/css/iframe/styleguide/index.css +109 -0
  23. package/frontend/assets/css/iframe/styleguide/spacings.css +21 -0
  24. package/frontend/assets/css/iframe.css +410 -0
  25. package/frontend/assets/css/main/menu/config-switcher.css +49 -0
  26. package/frontend/assets/css/main/menu/config-switchers.css +67 -0
  27. package/frontend/assets/css/main/menu/goto.css +24 -0
  28. package/frontend/assets/css/main/menu/nav.css +113 -0
  29. package/frontend/assets/css/main/menu/search.css +64 -0
  30. package/frontend/assets/css/main/menu/title.css +40 -0
  31. package/frontend/assets/css/main/menu.css +114 -0
  32. package/frontend/assets/css/main/reset.css +217 -0
  33. package/frontend/assets/css/main.css +71 -0
  34. package/frontend/assets/css/shared.css +34 -0
  35. package/frontend/assets/css/tokens.css +112 -0
  36. package/frontend/assets/favicon.ico +0 -0
  37. package/frontend/assets/js/_accordion-tabs.js +403 -0
  38. package/frontend/assets/js/_goto.js +63 -0
  39. package/frontend/assets/js/_iframe-links.js +19 -0
  40. package/frontend/assets/js/_is-triggered.js +15 -0
  41. package/frontend/assets/js/_main.js +379 -0
  42. package/frontend/assets/js/_mock-data.js +13 -0
  43. package/frontend/assets/js/_prism.js +1098 -0
  44. package/frontend/assets/js/_search.js +190 -0
  45. package/frontend/assets/js/_socket.js +9 -0
  46. package/frontend/assets/js/config-switcher/development-mode.js +49 -0
  47. package/frontend/assets/js/config-switcher/index.js +63 -0
  48. package/frontend/assets/js/config-switcher/text-direction.js +30 -0
  49. package/frontend/assets/js/config-switcher/theme.js +87 -0
  50. package/frontend/assets/js/iframe.build.js +43 -0
  51. package/frontend/assets/js/iframe.js +52 -0
  52. package/frontend/assets/js/jsontree.js +979 -0
  53. package/frontend/assets/js/main.build.js +40 -0
  54. package/frontend/assets/js/main.js +42 -0
  55. package/frontend/assets/js/styleguide/color-converter.js +741 -0
  56. package/frontend/assets/js/styleguide/index.js +119 -0
  57. package/frontend/views/component_variation.twig.miyagi +57 -0
  58. package/frontend/views/design-tokens/colors.twig.miyagi +43 -0
  59. package/frontend/views/design-tokens/sizes.twig.miyagi +35 -0
  60. package/frontend/views/design-tokens/typography.twig.miyagi +38 -0
  61. package/frontend/views/iframe_component.twig.miyagi +141 -0
  62. package/frontend/views/iframe_component_variation.twig.miyagi +55 -0
  63. package/frontend/views/iframe_index.twig.miyagi +14 -0
  64. package/frontend/views/layouts/iframe_default.twig.miyagi +22 -0
  65. package/frontend/views/main.twig.miyagi +24 -0
  66. package/frontend/views/menu/config-switchers.twig.miyagi +83 -0
  67. package/frontend/views/menu/goto.twig.miyagi +9 -0
  68. package/frontend/views/menu/menu.twig.miyagi +21 -0
  69. package/frontend/views/menu/nav.twig.miyagi +95 -0
  70. package/frontend/views/menu/search.twig.miyagi +13 -0
  71. package/frontend/views/menu/title.twig.miyagi +24 -0
  72. package/index.js +3 -0
  73. package/lib/build/index.js +1020 -0
  74. package/lib/cli/app.js +38 -0
  75. package/lib/cli/component.js +56 -0
  76. package/lib/cli/index.js +5 -0
  77. package/lib/cli/lint.js +180 -0
  78. package/lib/config.js +74 -0
  79. package/lib/default-config.js +105 -0
  80. package/lib/generator/component.js +199 -0
  81. package/lib/generator/mocks.js +201 -0
  82. package/lib/helpers.js +184 -0
  83. package/lib/i18n/en.js +91 -0
  84. package/lib/i18n/index.js +17 -0
  85. package/lib/index.js +166 -0
  86. package/lib/init/args.js +55 -0
  87. package/lib/init/config.js +330 -0
  88. package/lib/init/engines.js +65 -0
  89. package/lib/init/index.js +102 -0
  90. package/lib/init/rendering.js +12 -0
  91. package/lib/init/router.js +249 -0
  92. package/lib/init/static.js +133 -0
  93. package/lib/init/twing/cache.js +34 -0
  94. package/lib/init/twing/functions.js +51 -0
  95. package/lib/init/views.js +19 -0
  96. package/lib/init/watcher.js +402 -0
  97. package/lib/logger.js +94 -0
  98. package/lib/mocks/get.js +111 -0
  99. package/lib/mocks/index.js +9 -0
  100. package/lib/mocks/resolve/ref.js +484 -0
  101. package/lib/mocks/resolve/tpl.js +246 -0
  102. package/lib/mocks/resolve.js +205 -0
  103. package/lib/render/helpers.js +51 -0
  104. package/lib/render/index.js +38 -0
  105. package/lib/render/views/iframe/component.docs.js +77 -0
  106. package/lib/render/views/iframe/component.js +338 -0
  107. package/lib/render/views/iframe/design-tokens/colors.js +52 -0
  108. package/lib/render/views/iframe/design-tokens/index.js +9 -0
  109. package/lib/render/views/iframe/design-tokens/sizes.js +49 -0
  110. package/lib/render/views/iframe/design-tokens/typography.js +52 -0
  111. package/lib/render/views/iframe/docs.js +68 -0
  112. package/lib/render/views/iframe/index.js +44 -0
  113. package/lib/render/views/iframe/variation.js +116 -0
  114. package/lib/render/views/iframe/variation.standalone.js +89 -0
  115. package/lib/render/views/main/component.docs.js +53 -0
  116. package/lib/render/views/main/component.js +74 -0
  117. package/lib/render/views/main/design-tokens.js +53 -0
  118. package/lib/render/views/main/docs.js +47 -0
  119. package/lib/render/views/main/index.js +46 -0
  120. package/lib/state/components.js +132 -0
  121. package/lib/state/css.js +50 -0
  122. package/lib/state/docs.js +111 -0
  123. package/lib/state/file-contents.js +207 -0
  124. package/lib/state/helpers.js +86 -0
  125. package/lib/state/index.js +56 -0
  126. package/lib/state/menu/index.js +275 -0
  127. package/lib/state/menu/structure.js +146 -0
  128. package/lib/state/partials.js +23 -0
  129. package/lib/state/source-tree.js +75 -0
  130. package/lib/styleguide/color-names.js +150 -0
  131. package/lib/styleguide/colors.js +135 -0
  132. package/lib/styleguide/helpers.js +37 -0
  133. package/lib/styleguide/index.js +17 -0
  134. package/lib/styleguide/media-queries.js +26 -0
  135. package/lib/styleguide/spacings.js +35 -0
  136. package/lib/styleguide/typography.js +61 -0
  137. package/lib/validator/mocks.js +105 -0
  138. package/package.json +117 -0
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Module for accepting and routing requests
3
+ * @module initRouter
4
+ */
5
+
6
+ import path from "path";
7
+ import config from "../default-config.js";
8
+ import render from "../render/index.js";
9
+ import { getVariationData } from "../mocks/index.js";
10
+ import log from "../logger.js";
11
+
12
+ /**
13
+ * @param {object} component
14
+ * @returns {object} the mock data of the given component
15
+ */
16
+ function getDataForComponent(component) {
17
+ const { fileContents } = global.state;
18
+ const { name, extension } = global.config.files.mocks;
19
+
20
+ const defaultPath = path.join(
21
+ component.paths.dir.full,
22
+ `${name}.${extension[0]}`,
23
+ );
24
+
25
+ const jsPath = path.join(component.paths.dir.full, `${name}.${extension[1]}`);
26
+
27
+ return fileContents[defaultPath] || fileContents[jsPath];
28
+ }
29
+
30
+ /**
31
+ * @param {object} data - mock data object
32
+ * @param {string} variation - requested variation name
33
+ * @returns {boolean} is true of the requested variation is in the given mock data
34
+ */
35
+ function checkIfDataIncludesVariation(data, variation) {
36
+ return data?.$variants?.find((variant) => variant.$name === variation);
37
+ }
38
+
39
+ /**
40
+ * @param {object} component
41
+ * @param {string} variation - the requested variation name
42
+ * @returns {boolean} is true if the requested variation exists in the mock data of the given component
43
+ */
44
+ function checkIfRequestedVariationIsValid(component, variation) {
45
+ const data = getDataForComponent(component);
46
+
47
+ if (
48
+ data &&
49
+ (variation === data.$name || variation === config.defaultVariationName) &&
50
+ !data.$hidden
51
+ ) {
52
+ return true;
53
+ }
54
+
55
+ if (!data && variation === config.defaultVariationName) {
56
+ return true;
57
+ }
58
+
59
+ return checkIfDataIncludesVariation(data, variation);
60
+ }
61
+
62
+ /**
63
+ * @returns {void}
64
+ */
65
+ export default function Router() {
66
+ global.app.get("/design-tokens/colors", async (req, res) => {
67
+ return render.renderMainDesignTokens({
68
+ res,
69
+ cookies: req.cookies,
70
+ type: "colors",
71
+ });
72
+ });
73
+
74
+ global.app.get("/iframe/design-tokens/colors", async (req, res) => {
75
+ return render.iframe.designTokens.colors({ res, cookies: req.cookies });
76
+ });
77
+
78
+ global.app.get("/design-tokens/sizes", async (req, res) => {
79
+ return render.renderMainDesignTokens({
80
+ res,
81
+ cookies: req.cookies,
82
+ type: "sizes",
83
+ });
84
+ });
85
+
86
+ global.app.get("/iframe/design-tokens/sizes", async (req, res) => {
87
+ return render.iframe.designTokens.sizes({ res, cookies: req.cookies });
88
+ });
89
+
90
+ global.app.get("/design-tokens/typography", async (req, res) => {
91
+ return render.renderMainDesignTokens({
92
+ res,
93
+ cookies: req.cookies,
94
+ type: "typography",
95
+ });
96
+ });
97
+
98
+ global.app.get("/iframe/design-tokens/typography", async (req, res) => {
99
+ return render.iframe.designTokens.typography({
100
+ res,
101
+ cookies: req.cookies,
102
+ });
103
+ });
104
+
105
+ global.app.get("/show", async (req, res) => {
106
+ const { file, variation } = req.query;
107
+
108
+ if (!file) {
109
+ return res.redirect(302, "/");
110
+ }
111
+
112
+ if (file === "all") {
113
+ return await render.renderMainIndex({ res, cookies: req.cookies });
114
+ }
115
+
116
+ const routesEntry = global.state.routes.find(
117
+ (route) => route.paths.dir.short === file,
118
+ );
119
+
120
+ if (!routesEntry) {
121
+ return res.redirect(302, "/");
122
+ }
123
+
124
+ switch (routesEntry.type) {
125
+ case "components": {
126
+ if (!routesEntry.paths.tpl) {
127
+ return await render.renderMainComponentDocs({
128
+ res,
129
+ component: routesEntry,
130
+ cookies: req.cookies,
131
+ });
132
+ }
133
+
134
+ return await render.renderMainComponent(
135
+ checkIfRequestedVariationIsValid(routesEntry, variation)
136
+ ? {
137
+ res,
138
+ component: routesEntry,
139
+ cookies: req.cookies,
140
+ variation,
141
+ }
142
+ : {
143
+ res,
144
+ component: routesEntry,
145
+ cookies: req.cookies,
146
+ },
147
+ );
148
+ }
149
+
150
+ case "docs": {
151
+ return await render.renderMainDocs({
152
+ res,
153
+ doc: routesEntry,
154
+ cookies: req.cookies,
155
+ });
156
+ }
157
+
158
+ default:
159
+ return res.redirect(302, "/");
160
+ }
161
+ });
162
+
163
+ global.app.get("/component", async (req, res) => {
164
+ const { file, variation, embedded } = req.query;
165
+
166
+ if (!file) {
167
+ return res.redirect(302, global.config.indexPath.default);
168
+ }
169
+
170
+ if (file === "all") {
171
+ return await render.renderIframeIndex({ res, cookies: req.cookies });
172
+ }
173
+
174
+ const routesEntry = global.state.routes.find(
175
+ (route) => route.paths.dir.short === file,
176
+ );
177
+
178
+ if (!routesEntry) {
179
+ res.redirect(302, global.config.indexPath.default);
180
+ }
181
+
182
+ switch (routesEntry.type) {
183
+ case "components": {
184
+ if (!routesEntry.paths.tpl) {
185
+ return await render.renderIframeComponentDocs({
186
+ res,
187
+ component: routesEntry,
188
+ cookies: req.cookies,
189
+ });
190
+ }
191
+
192
+ if (
193
+ !variation ||
194
+ !checkIfRequestedVariationIsValid(routesEntry, variation)
195
+ ) {
196
+ return await render.renderIframeComponent({
197
+ res,
198
+ component: routesEntry,
199
+ cookies: req.cookies,
200
+ });
201
+ }
202
+
203
+ const data = await getVariationData(routesEntry, decodeURI(variation));
204
+
205
+ if (embedded) {
206
+ return await render.renderIframeVariation({
207
+ res,
208
+ component: routesEntry,
209
+ variation,
210
+ cookies: req.cookies,
211
+ data,
212
+ });
213
+ }
214
+
215
+ if (data?.messages?.length) {
216
+ for (const { type, text, verbose } of data.messages) {
217
+ log(type, text, verbose);
218
+ }
219
+ }
220
+
221
+ return await render.renderIframeVariationStandalone({
222
+ res,
223
+ component: routesEntry,
224
+ componentData: data?.resolved ?? {},
225
+ cookies: req.cookies,
226
+ });
227
+ }
228
+
229
+ case "docs": {
230
+ return await render.renderIframeDocs({
231
+ res,
232
+ doc: routesEntry,
233
+ cookies: req.cookies,
234
+ });
235
+ }
236
+
237
+ default:
238
+ res.redirect(302, global.config.indexPath.default);
239
+ }
240
+ });
241
+
242
+ global.app.get("/", async (req, res) => {
243
+ await render.renderMainIndex({ res, cookies: req.cookies });
244
+ });
245
+
246
+ global.app.all("*splat", async (req, res) => {
247
+ res.sendStatus(404);
248
+ });
249
+ }
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Module for registering static files
3
+ * @module initStatic
4
+ */
5
+
6
+ import path from "path";
7
+ import express from "express";
8
+ import config from "../default-config.js";
9
+
10
+ /**
11
+ * @returns {void}
12
+ */
13
+ function registerUserAssetFolder() {
14
+ const { assets } = global.config;
15
+
16
+ if (assets && assets.folder) {
17
+ for (const folder of assets.folder) {
18
+ global.app.use(
19
+ path.join("/", folder),
20
+ express.static(path.join(assets.root, folder)),
21
+ );
22
+ }
23
+ }
24
+ }
25
+
26
+ /**
27
+ * @returns {void}
28
+ */
29
+ function registerThemeFavicon() {
30
+ if (global.config.ui && global.config.ui.theme) {
31
+ const file = global.config.ui.theme.favicon;
32
+
33
+ if (file) {
34
+ global.app.use(`/favicon.ico`, express.static(path.resolve(file)));
35
+ }
36
+ }
37
+ }
38
+
39
+ /**
40
+ * @returns {void}
41
+ */
42
+ function registerThemeLogo() {
43
+ const files = [
44
+ global.config.ui.theme.logo.light,
45
+ global.config.ui.theme.logo.dark,
46
+ ];
47
+
48
+ files.forEach((file) => {
49
+ if (file) {
50
+ global.app.use(
51
+ path.join("/", path.dirname(file)),
52
+ express.static(path.resolve(path.dirname(file))),
53
+ );
54
+ }
55
+ });
56
+ }
57
+
58
+ /**
59
+ * @param {("css"|"js")} files - the type of user assets that should be registered
60
+ */
61
+ function registerUserFiles(files) {
62
+ const { assets } = global.config;
63
+
64
+ if (assets) {
65
+ for (const file of assets[files]) {
66
+ const asset = files === "js" ? file.src : file;
67
+
68
+ if (asset.startsWith("https://")) continue;
69
+
70
+ global.app.use(
71
+ path.join("/", path.dirname(asset)),
72
+ express.static(path.join(assets.root, path.dirname(asset))),
73
+ );
74
+ }
75
+ }
76
+ }
77
+
78
+ /**
79
+ * @returns {void}
80
+ */
81
+ function registerCustomPropertyFiles() {
82
+ const { assets } = global.config;
83
+
84
+ if (assets?.customProperties?.files) {
85
+ for (const file of assets.customProperties.files) {
86
+ global.app.use(
87
+ path.join("/", path.dirname(file)),
88
+ express.static(path.dirname(file)),
89
+ );
90
+ }
91
+ }
92
+ }
93
+
94
+ /**
95
+ * @returns {void}
96
+ */
97
+ function registerAssetFolder() {
98
+ const assetFolder =
99
+ config.folders.assets[
100
+ process.env.MIYAGI_DEVELOPMENT ? "development" : "production"
101
+ ];
102
+
103
+ global.app.use(
104
+ `/${config.projectName}`,
105
+ express.static(path.join(import.meta.dirname, `../../${assetFolder}`)),
106
+ );
107
+ }
108
+
109
+ /**
110
+ * @returns {void}
111
+ */
112
+ function registerUserComponentAssets() {
113
+ if (!global.config.components.folder) return;
114
+
115
+ global.app.use(
116
+ path.join("/", global.config.components.folder),
117
+ express.static(global.config.components.folder),
118
+ );
119
+ }
120
+
121
+ /**
122
+ * @returns {void}
123
+ */
124
+ export default function initStatic() {
125
+ registerThemeFavicon();
126
+ registerThemeLogo();
127
+ registerUserAssetFolder();
128
+ registerUserComponentAssets();
129
+ registerUserFiles("css");
130
+ registerUserFiles("js");
131
+ registerCustomPropertyFiles();
132
+ registerAssetFolder();
133
+ }
@@ -0,0 +1,34 @@
1
+ export default class TwingCache {
2
+ #cache = new Map();
3
+
4
+ /**
5
+ * @param {string} key
6
+ * @returns {object|null}
7
+ */
8
+ load(key) {
9
+ if (this.#cache.get(key)?.content) {
10
+ return this.#cache.get(key)?.content;
11
+ }
12
+
13
+ return null;
14
+ }
15
+
16
+ /**
17
+ * @param {string} key
18
+ * @param {object} content
19
+ */
20
+ write(key, content) {
21
+ const timestamp = new Date().getTime();
22
+ const value = { content, timestamp };
23
+
24
+ this.#cache.set(key, value);
25
+ }
26
+
27
+ /**
28
+ * @param {string} key
29
+ * @returns {number|null}
30
+ */
31
+ getTimestamp(key) {
32
+ return this.#cache.get(key)?.timestamp ?? null;
33
+ }
34
+ }
@@ -0,0 +1,51 @@
1
+ import { createSynchronousFunction } from "twing";
2
+
3
+ export const isExpanded = createSynchronousFunction(
4
+ "is_expanded",
5
+ (_context, item, requestedComponent) => {
6
+ if (item.topLevel) return true;
7
+ if (!requestedComponent) return false;
8
+
9
+ return !!(
10
+ item.children?.find(
11
+ ({ shortPath }) => shortPath === requestedComponent,
12
+ ) ||
13
+ (item.shortPath && item.shortPath === requestedComponent) ||
14
+ requestedComponent.startsWith(item.shortPath)
15
+ );
16
+ },
17
+ [{ name: "item" }, { name: "requestedComponent" }],
18
+ );
19
+
20
+ export const isActiveComponent = createSynchronousFunction(
21
+ "is_active_component",
22
+ (_context, item, requestedComponent, requestedVariation) => {
23
+ if (!requestedComponent) return false;
24
+
25
+ if (requestedComponent === "design-tokens") {
26
+ return (
27
+ item.section === "design-tokens" && item.name == requestedVariation
28
+ );
29
+ }
30
+
31
+ return (
32
+ item.shortPath &&
33
+ item.shortPath === requestedComponent &&
34
+ !requestedVariation
35
+ );
36
+ },
37
+ ["item", "requestedComponent", "requestedVariation"],
38
+ );
39
+
40
+ export const isActiveVariant = createSynchronousFunction(
41
+ "is_active_variant",
42
+ (_context, item, requestedComponent, requestedVariation) => {
43
+ if (!item || !requestedComponent || !requestedVariation) return false;
44
+
45
+ return (
46
+ requestedComponent == item.parentShortPath &&
47
+ requestedVariation == item.name
48
+ );
49
+ },
50
+ ["item", "requestedComponent", "requestedVariation"],
51
+ );
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Module for registering the views in express
3
+ * @module initViews
4
+ */
5
+
6
+ import path from "path";
7
+
8
+ /**
9
+ * @returns {void}
10
+ */
11
+ export default function initViews() {
12
+ const views = [path.join(import.meta.dirname, "../../frontend/views")];
13
+
14
+ if (global.config.components.folder) {
15
+ views.push(path.resolve(global.config.components.folder));
16
+ }
17
+
18
+ global.app.set("views", views);
19
+ }