@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,201 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import schemaFaker from "@stoplight/json-schema-sampler";
3
+ import jsYaml from "js-yaml";
4
+ import path from "path";
5
+ import log from "../logger.js";
6
+ import { t } from "../i18n/index.js";
7
+
8
+ /**
9
+ * Module for creating dummy mock data based on JSON schema
10
+ * @module generatorMocks
11
+ * @param {string} folderPath - the path for the component that should be created
12
+ * @param {object} filesConfig - the files configuration from the user configuration object
13
+ * @returns {Promise<{success, message?}>}
14
+ */
15
+ export default async function mockGenerator(folderPath, filesConfig) {
16
+ if (!folderPath) {
17
+ return {
18
+ success: false,
19
+ message: {
20
+ type: "error",
21
+ text: t("dataGenerator.noComponentFolderDefined"),
22
+ },
23
+ };
24
+ }
25
+
26
+ log("info", t("dataGenerator.starting").replace("{{fileName}}", folderPath));
27
+
28
+ const mockFilePath = `${path.join(folderPath, filesConfig.mocks.name)}.${
29
+ filesConfig.mocks.extension[0]
30
+ }`;
31
+ const schemaFilePath = `${path.join(folderPath, filesConfig.schema.name)}.${
32
+ filesConfig.schema.extension
33
+ }`;
34
+
35
+ const {
36
+ status,
37
+ data: schemaData,
38
+ message,
39
+ } = await readAndParseFile(schemaFilePath, filesConfig);
40
+
41
+ if (status === "success") {
42
+ try {
43
+ const content = getContent(filesConfig.mocks.extension[0], schemaData);
44
+
45
+ const { status, data } = await readAndParseFile(
46
+ mockFilePath,
47
+ filesConfig,
48
+ );
49
+
50
+ if (status === "success") {
51
+ if (data === "") {
52
+ const { status, message } = await createFile(content, mockFilePath);
53
+
54
+ if (status === "error") {
55
+ return {
56
+ success: false,
57
+ message: {
58
+ type: "error",
59
+ text: message,
60
+ },
61
+ };
62
+ } else {
63
+ return {
64
+ success: true,
65
+ };
66
+ }
67
+ } else {
68
+ return {
69
+ success: false,
70
+ message: {
71
+ type: "error",
72
+ text: t("dataGenerator.dataFileExists").replace(
73
+ "{{fileName}}",
74
+ mockFilePath,
75
+ ),
76
+ },
77
+ };
78
+ }
79
+ } else {
80
+ const { status, message } = await createFile(content, mockFilePath);
81
+
82
+ if (status === "error") {
83
+ return {
84
+ success: false,
85
+ message: {
86
+ type: "error",
87
+ text: message,
88
+ },
89
+ };
90
+ } else {
91
+ return {
92
+ success: true,
93
+ };
94
+ }
95
+ }
96
+ // eslint-disable-next-line no-unused-vars
97
+ } catch (e) {
98
+ return {
99
+ success: false,
100
+ message: {
101
+ type: "error",
102
+ text: t("dataGenerator.schemaFileCantBeParsed").replace(
103
+ "{{fileName}}",
104
+ schemaFilePath,
105
+ ),
106
+ },
107
+ };
108
+ }
109
+ } else {
110
+ return {
111
+ success: false,
112
+ message: {
113
+ type: "error",
114
+ text: t("dataGenerator.noSchemaFile").replace(
115
+ "{{fileName}}",
116
+ schemaFilePath,
117
+ ),
118
+ verbose: message,
119
+ },
120
+ };
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Returns the dummy mock data in the correct format
126
+ * @param {string} fileType - the file type of the mock data that should be created
127
+ * @param {object} schema - the JSON schema object
128
+ * @returns {string} the dummy mock data
129
+ */
130
+ function getContent(fileType, schema) {
131
+ let content;
132
+ const data = schemaFaker.sample(schema);
133
+
134
+ switch (fileType) {
135
+ case "yaml":
136
+ case "yml":
137
+ content = jsYaml.dump(data);
138
+ break;
139
+ case "json":
140
+ content = JSON.stringify(data, null, 2);
141
+ break;
142
+ case "js":
143
+ content = `module.exports = ${JSON.stringify(data, null, 2)}
144
+ `;
145
+ break;
146
+ default:
147
+ content = "";
148
+ }
149
+
150
+ return content;
151
+ }
152
+
153
+ /**
154
+ * Creates the mock file with the dummy mock data
155
+ * @param {string} content - the content for the mock file
156
+ * @param {string} mockFilePath - the path to the mock file
157
+ * @returns {Promise<object>}
158
+ */
159
+ async function createFile(content, mockFilePath) {
160
+ try {
161
+ await writeFile(mockFilePath, content);
162
+ return {
163
+ status: "success",
164
+ message: t("generator.done"),
165
+ };
166
+ } catch (err) {
167
+ return {
168
+ status: "error",
169
+ message: err.message,
170
+ };
171
+ }
172
+ }
173
+
174
+ /**
175
+ * Reads the content of a given file
176
+ * @param {string} filePath - path to a file that should be read
177
+ * @param {object} filesConfig
178
+ * @returns {Promise<object>}
179
+ */
180
+ async function readAndParseFile(filePath, filesConfig) {
181
+ try {
182
+ const result = await readFile(filePath, "utf8");
183
+ let data;
184
+
185
+ if (["yaml", "yml"].includes(filesConfig.schema.extension)) {
186
+ data = jsYaml.load(result);
187
+ } else {
188
+ data = JSON.parse(result);
189
+ }
190
+
191
+ return {
192
+ status: "success",
193
+ data,
194
+ };
195
+ } catch (err) {
196
+ return {
197
+ status: "error",
198
+ message: err.message,
199
+ };
200
+ }
201
+ }
package/lib/helpers.js ADDED
@@ -0,0 +1,184 @@
1
+ import v8 from "v8";
2
+ import path from "path";
3
+
4
+ /**
5
+ * Module for globally used helper functions
6
+ * @module helpers
7
+ */
8
+
9
+ /**
10
+ * Removes all keys starting with $ from an object
11
+ * @param {object} [obj] the object whose keys with $ should be removed
12
+ * @returns {object} the modified object
13
+ */
14
+ export const removeInternalKeys = function (obj = {}) {
15
+ const o = {};
16
+
17
+ for (const [key, value] of Object.entries(obj)) {
18
+ if (!key.startsWith("$") || key === "$ref" || key === "$opts") {
19
+ o[key] = value;
20
+ }
21
+ }
22
+
23
+ return o;
24
+ };
25
+
26
+ /**
27
+ * Returns everything after the last "." of a file extension (e.g. `html.twig` -> `twig`)
28
+ * @param {string} [extension] - File extension like `twig` or `html.twig`
29
+ * @returns {string} the last part of a the file extension
30
+ */
31
+ export const getSingleFileExtension = function (extension = "") {
32
+ return extension.slice(extension.lastIndexOf(".") + 1);
33
+ };
34
+
35
+ /**
36
+ * Normalizes a string be replacing whitespace, underscore, / etc with - and lowercases it
37
+ * @param {string} [str] string that should be normalized
38
+ * @returns {string} the normalized string
39
+ */
40
+ export const normalizeString = function (str = "") {
41
+ if (typeof str === "string") {
42
+ return str
43
+ .replace(/[^\w\s]/gi, "-")
44
+ .replace(/_/g, "-")
45
+ .replace(/ /g, "-")
46
+ .toLowerCase();
47
+ }
48
+
49
+ return str;
50
+ };
51
+
52
+ /**
53
+ * If "<component>"" is set as the file name in the config, it returns the given file name, otherwise it returns the value from the config
54
+ * @param {string} nameInConfig - The defined name for a file in the config
55
+ * @param {string} fileName - The actual file name
56
+ * @returns {string} the filename based on the configuration file
57
+ */
58
+ export const getResolvedFileName = function (nameInConfig, fileName) {
59
+ if (nameInConfig === "<component>") {
60
+ return fileName;
61
+ }
62
+
63
+ return nameInConfig;
64
+ };
65
+
66
+ /**
67
+ * Creates a deep clone of a object using internal v8 methods
68
+ * @param {object} obj - the object to clone
69
+ * @returns {object} clone of rhe given object
70
+ */
71
+ export const cloneDeep = function (obj) {
72
+ return v8.deserialize(v8.serialize(obj));
73
+ };
74
+
75
+ /**
76
+ * Accepts a path relative from the config.components.folder and returns the complete path based on the file system
77
+ * @param {string} shortPath - a relative file path based from the components folder
78
+ * @returns {string} absolute file path
79
+ */
80
+ export const getFullPathFromShortPath = function (shortPath) {
81
+ return path.join(
82
+ process.cwd(),
83
+ `${global.config.components.folder}/${shortPath}`,
84
+ );
85
+ };
86
+
87
+ /**
88
+ * Accepts an absolute (file system based) path and returns the short path relative from config.components.folder
89
+ * @param {string} fullPath - absolute file path
90
+ * @returns {string} relative file path based from the components folder
91
+ */
92
+ export const getShortPathFromFullPath = function (fullPath) {
93
+ return fullPath.replace(
94
+ `${path.join(process.cwd(), global.config.components.folder)}/`,
95
+ "",
96
+ );
97
+ };
98
+
99
+ /**
100
+ * Accepts a file path and checks if it is a mock file
101
+ * @param {string} filePath - path to any type of file
102
+ * @returns {boolean} is true if the given file is a mock file
103
+ */
104
+ export const fileIsDataFile = function (filePath) {
105
+ const extension = path.extname(filePath);
106
+
107
+ if (!["js", "json", "yaml", "yml"].includes(extension.slice(1))) return false;
108
+
109
+ const basename = path.basename(filePath, extension);
110
+ if (global.config.files.mocks.name === basename) return true;
111
+
112
+ return false;
113
+ };
114
+
115
+ /**
116
+ * Accepts a file path and checks if it is a documentation file
117
+ * @param {string} filePath - path to any type of file
118
+ * @returns {boolean} is true if the given file is a doc file
119
+ */
120
+ export const fileIsDocumentationFile = function (filePath) {
121
+ return path.extname(filePath) === ".md";
122
+ };
123
+
124
+ /**
125
+ * Accepts a file path and checks if it is a schema file
126
+ * @param {string} filePath - path to any type of file
127
+ * @returns {boolean} is true if the given file is a schema file
128
+ */
129
+ export const fileIsSchemaFile = function (filePath) {
130
+ return (
131
+ path.basename(filePath) ===
132
+ `${global.config.files.schema.name}.${global.config.files.schema.extension}`
133
+ );
134
+ };
135
+
136
+ /**
137
+ * Accepts a file path and checks if it is component js or css file
138
+ * @param {string} filePath - path to any type of file
139
+ * @returns {boolean} is true if the given file is a css or js file
140
+ */
141
+ export const fileIsAssetFile = function (filePath) {
142
+ return (
143
+ path.basename(filePath) ===
144
+ `${getResolvedFileName(
145
+ global.config.files.css.name,
146
+ path.basename(filePath, `.${global.config.files.css.extension}`),
147
+ )}.${global.config.files.css.extension}` ||
148
+ path.basename(filePath) ===
149
+ `${getResolvedFileName(
150
+ global.config.files.js.name,
151
+ path.basename(filePath, `.${global.config.files.js.extension}`),
152
+ )}.${global.config.files.js.extension}`
153
+ );
154
+ };
155
+
156
+ /**
157
+ * Accepts a file path and returns checks if it is a template file
158
+ * @param {string} filePath - path to any type of file
159
+ * @returns {boolean} is true if the given file is a template file
160
+ */
161
+ export const fileIsTemplateFile = function (filePath) {
162
+ return (
163
+ path.basename(filePath) ===
164
+ `${getResolvedFileName(
165
+ global.config.files.templates.name,
166
+ path.basename(filePath, `.${global.config.files.templates.extension}`),
167
+ )}.${global.config.files.templates.extension}`
168
+ );
169
+ };
170
+
171
+ export const docFileIsIndexFile = function (fileName) {
172
+ const baseName = path.basename(fileName);
173
+ const extname = path.extname(fileName);
174
+
175
+ if (extname !== ".md") return false;
176
+ if (baseName === "README.md") return true;
177
+ if (baseName === "index.md") return true;
178
+
179
+ const dirParts = path.dirname(fileName).split(path.sep);
180
+ if (dirParts[dirParts.length - 1] === path.basename(fileName, ".md"))
181
+ return true;
182
+
183
+ return false;
184
+ };
package/lib/i18n/en.js ADDED
@@ -0,0 +1,91 @@
1
+ export default {
2
+ buildStarting: "Creating miyagi build…",
3
+ buildDone: "Build done! Wrote {{count}} directories and files.",
4
+ commandNotFound: "Please run `miyagi --help` for all available commands.",
5
+ componentCouldNotBeRendered: "Component couldn't be rendered.",
6
+ customPropertyFileNotFound:
7
+ "Couldn't find file {{filePath}}. Is the 'assets.customProperties.files' in your configuration set correctly?",
8
+ dataGenerator: {
9
+ dataFileExists: "The mock file {{fileName}} exists already.",
10
+ done: "Done!",
11
+ noComponentFolderDefined: "No directory has been defined.",
12
+ noSchemaFile: "miyagi can't find or parse the schema file {{fileName}}.",
13
+ schemaFileCantBeParsed: "The schema file {{fileName}} can't be parsed.",
14
+ starting: "Creating mock file {{fileName}}…",
15
+ },
16
+ jsonFileHasInvalidFormat:
17
+ "It seems like the file {{filePath}} has an invalid format as miyagi was not able to parse it.",
18
+ checkShellForFurtherErrors:
19
+ "Please also check the messages printed by miyagi in your shell as there might be more information.",
20
+ fileNotFound:
21
+ "Couldn't find file {{filePath}}. Is the 'components.folder' in your configuration set correctly?",
22
+ fileNotFoundLinkIncorrect:
23
+ "Couldn't find mock data '{{filePath}}' referenced in {{component}}. Please check that it's linked correctly.",
24
+ generator: {
25
+ starting: "Creating component…",
26
+ done: "Done!",
27
+ noComponentNameDefined:
28
+ "Please specify a component name like this: miyagi new directoryName/componentName",
29
+ fileAlreadyExists: "The file {{name}} already exists.",
30
+ component: {
31
+ done: "Finished creating component {{component}}.",
32
+ },
33
+ },
34
+ linter: {
35
+ all: {
36
+ start: "Validating schema files and mock data for all components…",
37
+ valid: "All schema and mock data is valid!",
38
+ schema: {
39
+ invalid: {
40
+ one: "1 schema file is invalid!",
41
+ other: "{{amount}} schema files are invalid!",
42
+ },
43
+ },
44
+ mocks: {
45
+ invalid: {
46
+ one: "1 mock data file is invalid!",
47
+ other: "{{amount}} mock data files are invalid!",
48
+ },
49
+ },
50
+ },
51
+ component: {
52
+ start: "Validating schema file and mock data for {{component}}…",
53
+ valid: "Schema file and mock data is valid!",
54
+ },
55
+ },
56
+ manifestNotFound: "Manifest file {{manifest}} not found or unparseable.",
57
+ missingExtension:
58
+ "Please specify the file extension of your template files in your config file (key: 'files.templates.extension', type: String) or as a cli argument (--files.templates.extension=<extension>).",
59
+ noDataSetForVariation:
60
+ 'No mock data defined for variation "{{variation}}" in {{file}}.',
61
+ noNameSetForVariation: "No name defined for variation {{i}} in {{file}}.",
62
+ portInUse: "Port {{port}} already in use, trying to find a free port…",
63
+ referencedMockFileNotFound: "Couldn't find referenced mock file.",
64
+ renderingTemplateFailed:
65
+ "Rendering {{filePath}} failed. Please check that it is linked correctly and that its content is correct syntax.",
66
+ scanningFiles: "Scanning and analyzing files…",
67
+ validator: {
68
+ mocks: {
69
+ valid: "Mock data matches schema.",
70
+ invalid: "Mock data does not match schema file.",
71
+ noSchemaFound:
72
+ "No schema file found or the schema file could not be parsed as valid JSON.",
73
+ },
74
+ },
75
+ serverStarted: "Running miyagi server at http://localhost:{{port}}",
76
+ serverStarting: "Starting miyagi server in {{node_env}} mode…",
77
+ settingEngineFailed:
78
+ "Setting the template engine failed. Are you sure the engine defined in your config file is correct?",
79
+ srcFolderNotFound:
80
+ "The specified {{type}} directory '{{directory}}' does not seem to exist. You can specify this in your config file (key: '{{config}}', type: String) or as a cli argument (--{{config}}=<String>). If you do not have any {{type}}, you can also set the value to null.",
81
+ templateDoesNotExist: "The template '{{template}}' can't be found.",
82
+ updatingDone: "Updating done!",
83
+ updatingConfiguration: "Updating configuration…",
84
+ updatingConfigurationDone: "Reloading browser window!",
85
+ updatingStarted: "A file has been changed, miyagi is updating the state.",
86
+ userConfigUnparseable:
87
+ "miyagi wasn't able to find or parse your config file. If you created a .miyagi.js or .miyagi.mjs, please check if its syntax is correct.",
88
+ variationNotFound: 'Variation "{{variation}}" not found in {{fileName}}.',
89
+ watchingFilesFailed: "Watching files failed.",
90
+ wrongFileType: "{{fileName}} does not have the correct file type.",
91
+ };
@@ -0,0 +1,17 @@
1
+ import en from "./en.js";
2
+
3
+ export const t = function (key) {
4
+ const translations = {
5
+ en,
6
+ };
7
+
8
+ let object = translations[global.config?.ui?.lang];
9
+
10
+ if (!object) {
11
+ object = translations.en;
12
+ }
13
+
14
+ return key.split(".").reduce((o, i) => o[i], object);
15
+ };
16
+
17
+ export const available = ["en"];
package/lib/index.js ADDED
@@ -0,0 +1,166 @@
1
+ /**
2
+ * The miyagi module
3
+ * @module index
4
+ */
5
+
6
+ import { t } from "./i18n/index.js";
7
+ import initRendering from "./init/rendering.js";
8
+ import log from "./logger.js";
9
+ import yargs from "./init/args.js";
10
+ import mockGenerator from "./generator/mocks.js";
11
+ import getConfig from "./config.js";
12
+ import { lint, component as createComponentViaCli } from "./cli/index.js";
13
+ import apiApp from "../api/app.js";
14
+
15
+ /**
16
+ * Checks if miyagi was started with "mocks" command
17
+ * @param {object} args - the cli args
18
+ * @returns {boolean} is true if the miyagi was started with "mocks"
19
+ */
20
+ function argsIncludeMockGenerator(args) {
21
+ return args._.includes("mocks");
22
+ }
23
+
24
+ /**
25
+ * Checks if miyagi was started with "new" command
26
+ * @param {object} args - the cli args
27
+ * @returns {boolean} is true if the miyagi was started with "new"
28
+ */
29
+ function argsIncludeComponentGenerator(args) {
30
+ return args._.includes("new");
31
+ }
32
+
33
+ /**
34
+ * Checks if miyagi was started with "build" command
35
+ * @param {object} args - the cli args
36
+ * @returns {boolean} is true if the miyagi was started with "new"
37
+ */
38
+ function argsIncludeBuild(args) {
39
+ return args._.includes("build");
40
+ }
41
+
42
+ /**
43
+ * Checks if miyagi was started with "start" command
44
+ * @param {object} args - the cli args
45
+ * @returns {boolean} is true if the miyagi was started with "start"
46
+ */
47
+ function argsIncludeServer(args) {
48
+ return args._.includes("start");
49
+ }
50
+
51
+ /**
52
+ * Checks if miyagi was started with "lint" command
53
+ * @param {object} args
54
+ * @returns {boolean}
55
+ */
56
+ function argsIncludeLint(args) {
57
+ return args._.includes("lint");
58
+ }
59
+
60
+ /**
61
+ * Runs the mock generator
62
+ * @param {object} config - the user configuration object
63
+ * @param {object} args - the cli args
64
+ * @returns {Promise}
65
+ */
66
+ function runMockGenerator(config, args) {
67
+ return mockGenerator(args._.slice(1)[0], config.files).catch(() => {});
68
+ }
69
+
70
+ /**
71
+ * @param {object} config
72
+ * @returns {Promise<object>}
73
+ */
74
+ async function initApi(config) {
75
+ return await apiApp(config);
76
+ }
77
+
78
+ /**
79
+ * Requires the user config and initializes and calls correct modules based on command
80
+ * @param {string} cmd
81
+ * @param {object} [options]
82
+ * @param {boolean} [options.isBuild]
83
+ * @returns {Promise}
84
+ */
85
+ export default async function Miyagi(cmd, { isBuild: isApiBuild } = {}) {
86
+ if (cmd === "api") {
87
+ process.env.NODE_ENV = "development";
88
+
89
+ global.config = await getConfig(null, isApiBuild);
90
+
91
+ return await initApi(global.config);
92
+ }
93
+
94
+ let args;
95
+ let isServer;
96
+ let isBuild;
97
+ let isComponentGenerator;
98
+ let isMockGenerator;
99
+ let isLinter;
100
+
101
+ if (cmd) {
102
+ isBuild = cmd === "build";
103
+ } else {
104
+ args = yargs.argv;
105
+ isServer = argsIncludeServer(args);
106
+ isBuild = argsIncludeBuild(args);
107
+ isComponentGenerator = argsIncludeComponentGenerator(args);
108
+ isMockGenerator = argsIncludeMockGenerator(args);
109
+ isLinter = argsIncludeLint(args);
110
+ }
111
+
112
+ if (args.verbose) {
113
+ process.env.VERBOSE = args.verbose;
114
+ }
115
+
116
+ if (isLinter) {
117
+ return lint(args);
118
+ }
119
+
120
+ if (isBuild || isComponentGenerator || isServer || isMockGenerator) {
121
+ if (isBuild) {
122
+ process.env.NODE_ENV = "production";
123
+ log("info", t("buildStarting"));
124
+ } else {
125
+ if (!process.env.NODE_ENV) {
126
+ process.env.NODE_ENV = "development";
127
+ }
128
+
129
+ if (isComponentGenerator) {
130
+ log("info", t("generator.starting"));
131
+ } else if (isServer) {
132
+ log(
133
+ "info",
134
+ t("serverStarting").replace("{{node_env}}", process.env.NODE_ENV),
135
+ );
136
+ }
137
+ }
138
+
139
+ global.config = await getConfig(args, isBuild, isComponentGenerator);
140
+
141
+ if (!global.config.components.folder && !global.config.docs.folder) {
142
+ log(
143
+ "error",
144
+ "Please specify at least either components.folder or docs.folder in your configuration file.",
145
+ );
146
+ process.exit(1);
147
+ }
148
+
149
+ if (isMockGenerator) {
150
+ await runMockGenerator(global.config, args);
151
+ // Force-exit in case imported user config has active resources preventing Node.js from exiting.
152
+ process.exit();
153
+ }
154
+
155
+ if (isComponentGenerator) {
156
+ await createComponentViaCli(args);
157
+ // Force-exit in case imported user config has active resources preventing Node.js from exiting.
158
+ process.exit();
159
+ }
160
+
161
+ return initRendering(global.config);
162
+ }
163
+
164
+ log("error", t("commandNotFound"));
165
+ process.exit(1);
166
+ }