@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.
- package/LICENSE.md +21 -0
- package/README.md +43 -0
- package/api/app.js +39 -0
- package/api/index.js +236 -0
- package/bin/miyagi.js +2 -0
- package/dist/css/iframe.css +31 -0
- package/dist/css/main.css +1 -0
- package/dist/js/_iframe-links-DdifIr4P.js +1 -0
- package/dist/js/_mock-data-Dypo4Bl_.js +1 -0
- package/dist/js/_prism-By3NMwUd.js +1 -0
- package/dist/js/iframe.build.js +1 -0
- package/dist/js/iframe.js +1 -0
- package/dist/js/index-BKDKaBC6.js +1 -0
- package/dist/js/jsontree.js +1 -0
- package/dist/js/main.build.js +1 -0
- package/dist/js/main.js +1 -0
- package/frontend/assets/css/iframe/accordion-tabs.css +77 -0
- package/frontend/assets/css/iframe/jsontree.js.css +325 -0
- package/frontend/assets/css/iframe/prism.css +132 -0
- package/frontend/assets/css/iframe/styleguide/colors.css +61 -0
- package/frontend/assets/css/iframe/styleguide/fonts.css +37 -0
- package/frontend/assets/css/iframe/styleguide/index.css +109 -0
- package/frontend/assets/css/iframe/styleguide/spacings.css +21 -0
- package/frontend/assets/css/iframe.css +410 -0
- package/frontend/assets/css/main/menu/config-switcher.css +49 -0
- package/frontend/assets/css/main/menu/config-switchers.css +67 -0
- package/frontend/assets/css/main/menu/goto.css +24 -0
- package/frontend/assets/css/main/menu/nav.css +113 -0
- package/frontend/assets/css/main/menu/search.css +64 -0
- package/frontend/assets/css/main/menu/title.css +40 -0
- package/frontend/assets/css/main/menu.css +114 -0
- package/frontend/assets/css/main/reset.css +217 -0
- package/frontend/assets/css/main.css +71 -0
- package/frontend/assets/css/shared.css +34 -0
- package/frontend/assets/css/tokens.css +112 -0
- package/frontend/assets/favicon.ico +0 -0
- package/frontend/assets/js/_accordion-tabs.js +403 -0
- package/frontend/assets/js/_goto.js +63 -0
- package/frontend/assets/js/_iframe-links.js +19 -0
- package/frontend/assets/js/_is-triggered.js +15 -0
- package/frontend/assets/js/_main.js +379 -0
- package/frontend/assets/js/_mock-data.js +13 -0
- package/frontend/assets/js/_prism.js +1098 -0
- package/frontend/assets/js/_search.js +190 -0
- package/frontend/assets/js/_socket.js +9 -0
- package/frontend/assets/js/config-switcher/development-mode.js +49 -0
- package/frontend/assets/js/config-switcher/index.js +63 -0
- package/frontend/assets/js/config-switcher/text-direction.js +30 -0
- package/frontend/assets/js/config-switcher/theme.js +87 -0
- package/frontend/assets/js/iframe.build.js +43 -0
- package/frontend/assets/js/iframe.js +52 -0
- package/frontend/assets/js/jsontree.js +979 -0
- package/frontend/assets/js/main.build.js +40 -0
- package/frontend/assets/js/main.js +42 -0
- package/frontend/assets/js/styleguide/color-converter.js +741 -0
- package/frontend/assets/js/styleguide/index.js +119 -0
- package/frontend/views/component_variation.twig.miyagi +57 -0
- package/frontend/views/design-tokens/colors.twig.miyagi +43 -0
- package/frontend/views/design-tokens/sizes.twig.miyagi +35 -0
- package/frontend/views/design-tokens/typography.twig.miyagi +38 -0
- package/frontend/views/iframe_component.twig.miyagi +141 -0
- package/frontend/views/iframe_component_variation.twig.miyagi +55 -0
- package/frontend/views/iframe_index.twig.miyagi +14 -0
- package/frontend/views/layouts/iframe_default.twig.miyagi +22 -0
- package/frontend/views/main.twig.miyagi +24 -0
- package/frontend/views/menu/config-switchers.twig.miyagi +83 -0
- package/frontend/views/menu/goto.twig.miyagi +9 -0
- package/frontend/views/menu/menu.twig.miyagi +21 -0
- package/frontend/views/menu/nav.twig.miyagi +95 -0
- package/frontend/views/menu/search.twig.miyagi +13 -0
- package/frontend/views/menu/title.twig.miyagi +24 -0
- package/index.js +3 -0
- package/lib/build/index.js +1020 -0
- package/lib/cli/app.js +38 -0
- package/lib/cli/component.js +56 -0
- package/lib/cli/index.js +5 -0
- package/lib/cli/lint.js +180 -0
- package/lib/config.js +74 -0
- package/lib/default-config.js +105 -0
- package/lib/generator/component.js +199 -0
- package/lib/generator/mocks.js +201 -0
- package/lib/helpers.js +184 -0
- package/lib/i18n/en.js +91 -0
- package/lib/i18n/index.js +17 -0
- package/lib/index.js +166 -0
- package/lib/init/args.js +55 -0
- package/lib/init/config.js +330 -0
- package/lib/init/engines.js +65 -0
- package/lib/init/index.js +102 -0
- package/lib/init/rendering.js +12 -0
- package/lib/init/router.js +249 -0
- package/lib/init/static.js +133 -0
- package/lib/init/twing/cache.js +34 -0
- package/lib/init/twing/functions.js +51 -0
- package/lib/init/views.js +19 -0
- package/lib/init/watcher.js +402 -0
- package/lib/logger.js +94 -0
- package/lib/mocks/get.js +111 -0
- package/lib/mocks/index.js +9 -0
- package/lib/mocks/resolve/ref.js +484 -0
- package/lib/mocks/resolve/tpl.js +246 -0
- package/lib/mocks/resolve.js +205 -0
- package/lib/render/helpers.js +51 -0
- package/lib/render/index.js +38 -0
- package/lib/render/views/iframe/component.docs.js +77 -0
- package/lib/render/views/iframe/component.js +338 -0
- package/lib/render/views/iframe/design-tokens/colors.js +52 -0
- package/lib/render/views/iframe/design-tokens/index.js +9 -0
- package/lib/render/views/iframe/design-tokens/sizes.js +49 -0
- package/lib/render/views/iframe/design-tokens/typography.js +52 -0
- package/lib/render/views/iframe/docs.js +68 -0
- package/lib/render/views/iframe/index.js +44 -0
- package/lib/render/views/iframe/variation.js +116 -0
- package/lib/render/views/iframe/variation.standalone.js +89 -0
- package/lib/render/views/main/component.docs.js +53 -0
- package/lib/render/views/main/component.js +74 -0
- package/lib/render/views/main/design-tokens.js +53 -0
- package/lib/render/views/main/docs.js +47 -0
- package/lib/render/views/main/index.js +46 -0
- package/lib/state/components.js +132 -0
- package/lib/state/css.js +50 -0
- package/lib/state/docs.js +111 -0
- package/lib/state/file-contents.js +207 -0
- package/lib/state/helpers.js +86 -0
- package/lib/state/index.js +56 -0
- package/lib/state/menu/index.js +275 -0
- package/lib/state/menu/structure.js +146 -0
- package/lib/state/partials.js +23 -0
- package/lib/state/source-tree.js +75 -0
- package/lib/styleguide/color-names.js +150 -0
- package/lib/styleguide/colors.js +135 -0
- package/lib/styleguide/helpers.js +37 -0
- package/lib/styleguide/index.js +17 -0
- package/lib/styleguide/media-queries.js +26 -0
- package/lib/styleguide/spacings.js +35 -0
- package/lib/styleguide/typography.js +61 -0
- package/lib/validator/mocks.js +105 -0
- package/package.json +117 -0
package/lib/init/args.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module for printing and parsing CLI arguments
|
|
3
|
+
* @module initArgs
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import yargs from "yargs";
|
|
7
|
+
import { hideBin } from "yargs/helpers";
|
|
8
|
+
import pkgJson from "../../package.json" with { type: "json" };
|
|
9
|
+
|
|
10
|
+
export default yargs(hideBin(process.argv))
|
|
11
|
+
.command("start", "Starts the miyagi server", {
|
|
12
|
+
verbose: {
|
|
13
|
+
description:
|
|
14
|
+
"Logging additional information — helpful mainly in case of errors.",
|
|
15
|
+
type: "boolean",
|
|
16
|
+
},
|
|
17
|
+
})
|
|
18
|
+
.command("build", "Creates a static build of all your components", {
|
|
19
|
+
folder: {
|
|
20
|
+
description: "The folder where your static build files will be saved",
|
|
21
|
+
type: "string",
|
|
22
|
+
},
|
|
23
|
+
})
|
|
24
|
+
.command(
|
|
25
|
+
"new",
|
|
26
|
+
"Creates a new component folder (including template, CSS, JS, documentation, mocks, and schema files)",
|
|
27
|
+
{
|
|
28
|
+
skip: {
|
|
29
|
+
description:
|
|
30
|
+
"files that will not be created\n(space separated list of tpl, css, js, docs, mocks, schema)",
|
|
31
|
+
type: "array",
|
|
32
|
+
},
|
|
33
|
+
only: {
|
|
34
|
+
description:
|
|
35
|
+
"tells miyagi to only created the passes file types\n(space separated list of tpl, css, js, docs, mocks, schema)",
|
|
36
|
+
type: "array",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
)
|
|
40
|
+
.command(
|
|
41
|
+
"mocks",
|
|
42
|
+
"Creates a mock data file with dummy content based on the schema file",
|
|
43
|
+
)
|
|
44
|
+
.command(
|
|
45
|
+
"lint",
|
|
46
|
+
"Validates if the component's mock data matches its JSON schema",
|
|
47
|
+
)
|
|
48
|
+
.help()
|
|
49
|
+
.version(pkgJson.version)
|
|
50
|
+
.alias("help", "h")
|
|
51
|
+
.alias("verbose", "v")
|
|
52
|
+
.demandCommand()
|
|
53
|
+
.epilogue(
|
|
54
|
+
"Please check https://docs.miyagi.dev/configuration/options/ for all options",
|
|
55
|
+
);
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module for sanitizing the user configuration and merging it with the default configuration
|
|
3
|
+
* @module initConfig
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import deepMerge from "deepmerge";
|
|
7
|
+
import log from "../logger.js";
|
|
8
|
+
import appConfig from "../default-config.js";
|
|
9
|
+
import { t, available as langAvailable } from "../i18n/index.js";
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import path from "path";
|
|
12
|
+
|
|
13
|
+
const { defaultUserConfig } = appConfig;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} path - unsanitized directory or file path
|
|
17
|
+
* @returns {string} the given path sanitized
|
|
18
|
+
*/
|
|
19
|
+
function sanitizePath(path) {
|
|
20
|
+
if (path === null) return path;
|
|
21
|
+
|
|
22
|
+
let sanitizedPath = path;
|
|
23
|
+
|
|
24
|
+
if (sanitizedPath.startsWith("./")) {
|
|
25
|
+
sanitizedPath = sanitizedPath.slice(2);
|
|
26
|
+
} else if (sanitizedPath.startsWith("/")) {
|
|
27
|
+
sanitizedPath = sanitizedPath.slice(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (sanitizedPath === "." || sanitizedPath === "/") {
|
|
31
|
+
sanitizedPath = "";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (sanitizedPath.endsWith("/")) {
|
|
35
|
+
sanitizedPath = sanitizedPath.slice(0, -1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return sanitizedPath;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {string|Array} strOrArr - file path or array of file paths
|
|
43
|
+
* @returns {Array} the given file path in an array or simply the given array
|
|
44
|
+
*/
|
|
45
|
+
function arrayfy(strOrArr) {
|
|
46
|
+
return Array.isArray(strOrArr) ? strOrArr : [strOrArr];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
*
|
|
51
|
+
* @param {object} root0
|
|
52
|
+
* @param {string} root0.src
|
|
53
|
+
* @param {boolean} [root0.defer]
|
|
54
|
+
* @param {boolean} [root0.async]
|
|
55
|
+
* @param {string} [root0.type]
|
|
56
|
+
* @param {string} [root0.position]
|
|
57
|
+
* @returns {object}
|
|
58
|
+
*/
|
|
59
|
+
function getJsFileObject({ src, defer, async, type, position = "head" }) {
|
|
60
|
+
return {
|
|
61
|
+
src,
|
|
62
|
+
defer,
|
|
63
|
+
async,
|
|
64
|
+
type,
|
|
65
|
+
position,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @param {string|Array|object} strOrArrOrObj - user assets files, either one file as string, an array of files or an object with strings or array for each NODE_ENV
|
|
71
|
+
* @param {object} manifest - manifest object
|
|
72
|
+
* @param {string} [manifest.file] - manifest file path
|
|
73
|
+
* @param {object} [manifest.content] - parsed json content of manifest file
|
|
74
|
+
* @param {string} root
|
|
75
|
+
* @returns {string[]} converts the given object to an array of asset file path strings
|
|
76
|
+
*/
|
|
77
|
+
function getJsFilesArray(strOrArrOrObj, manifest, root) {
|
|
78
|
+
if (!Array.isArray(strOrArrOrObj)) {
|
|
79
|
+
log("warn", "config.assets.js is not an array.");
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let files = strOrArrOrObj.map((entry) =>
|
|
84
|
+
typeof entry === "string" ? getJsFileObject({ src: entry }) : entry,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
if (files.length > 0 && manifest.file && manifest.content) {
|
|
88
|
+
files = files.map((file) => {
|
|
89
|
+
const manifestEntry = getPathFromManifest(file.src, manifest, root);
|
|
90
|
+
|
|
91
|
+
if (manifestEntry) {
|
|
92
|
+
return {
|
|
93
|
+
...file,
|
|
94
|
+
src: path.join(path.dirname(manifest.file), manifestEntry),
|
|
95
|
+
};
|
|
96
|
+
} else {
|
|
97
|
+
return file;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return files
|
|
103
|
+
.filter((file) => typeof file.src === "string")
|
|
104
|
+
.map((file) => ({
|
|
105
|
+
...file,
|
|
106
|
+
src: sanitizePath(file.src),
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @param {string|Array|object} strOrArrOrObj - user assets files, either one file as string, an array of files or an object with strings or array for each NODE_ENV
|
|
112
|
+
* @param {object} manifest - manifest object
|
|
113
|
+
* @param {string|null} [manifest.file] - manifest file path
|
|
114
|
+
* @param {object} [manifest.content] - parsed json content of manifest file
|
|
115
|
+
* @param {string} root
|
|
116
|
+
* @returns {string[]} converts the given object to an array of asset file path strings
|
|
117
|
+
*/
|
|
118
|
+
function getCssFilesArray(strOrArrOrObj, manifest, root) {
|
|
119
|
+
if (!Array.isArray(strOrArrOrObj)) {
|
|
120
|
+
log("warn", "config.assets.css is not an array.");
|
|
121
|
+
return [];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
let files = strOrArrOrObj.filter((entry) => typeof entry === "string");
|
|
125
|
+
|
|
126
|
+
if (files.length > 0 && manifest.content && manifest.file) {
|
|
127
|
+
files = files.map((file) => {
|
|
128
|
+
const manifestEntry = getPathFromManifest(file, manifest, root);
|
|
129
|
+
|
|
130
|
+
if (manifestEntry) {
|
|
131
|
+
return path.join(path.dirname(manifest.file), manifestEntry);
|
|
132
|
+
} else {
|
|
133
|
+
return file;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return files.map(sanitizePath);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @param {string|Array|object} strOrArrOrObj
|
|
143
|
+
* @returns {string[]} the given param converted to an array of asset file path strings
|
|
144
|
+
*/
|
|
145
|
+
function getAssetFoldersArray(strOrArrOrObj) {
|
|
146
|
+
if (!Array.isArray(strOrArrOrObj)) {
|
|
147
|
+
log("warn", "config.assets.folder is not an array.");
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return strOrArrOrObj
|
|
152
|
+
.filter((entry) => typeof entry === "string")
|
|
153
|
+
.map(sanitizePath);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @param {object} [userConfig] the unmerged user configuration
|
|
158
|
+
* @returns {object} the user configuration merged with the default configuration
|
|
159
|
+
*/
|
|
160
|
+
export default (userConfig = {}) => {
|
|
161
|
+
const config = { ...userConfig };
|
|
162
|
+
|
|
163
|
+
if (config.build) {
|
|
164
|
+
if (config.build.basePath) {
|
|
165
|
+
if (!config.build.basePath.startsWith("/")) {
|
|
166
|
+
config.build.basePath = `/${config.build.basePath}`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (!config.build.basePath.endsWith("/")) {
|
|
170
|
+
config.build.basePath = `${config.build.basePath}/`;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (config.assets) {
|
|
176
|
+
let manifest = {};
|
|
177
|
+
|
|
178
|
+
if (config.assets.manifest) {
|
|
179
|
+
try {
|
|
180
|
+
const manifestContent = fs.readFileSync(
|
|
181
|
+
path.resolve(
|
|
182
|
+
path.join(config.assets.root || "", config.assets.manifest),
|
|
183
|
+
),
|
|
184
|
+
{ encoding: "utf8" },
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
manifest.file = config.assets.manifest;
|
|
188
|
+
manifest.content = JSON.parse(manifestContent);
|
|
189
|
+
|
|
190
|
+
// eslint-disable-next-line no-unused-vars
|
|
191
|
+
} catch (e) {
|
|
192
|
+
log(
|
|
193
|
+
"warn",
|
|
194
|
+
t("manifestNotFound").replace("{{manifest}}", config.assets.manifest),
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (config.assets.folder) {
|
|
200
|
+
config.assets.folder = getAssetFoldersArray(config.assets.folder);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (config.assets.css) {
|
|
204
|
+
config.assets.css = getCssFilesArray(
|
|
205
|
+
config.assets.css,
|
|
206
|
+
manifest,
|
|
207
|
+
config.assets.root,
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (config.assets.js) {
|
|
212
|
+
config.assets.js = getJsFilesArray(
|
|
213
|
+
config.assets.js,
|
|
214
|
+
manifest,
|
|
215
|
+
config.assets.root,
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (!config.assets.customProperties) {
|
|
220
|
+
config.assets.customProperties = {};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (Array.isArray(config.assets.customProperties.files)) {
|
|
224
|
+
config.assets.customProperties.files =
|
|
225
|
+
config.assets.customProperties.files.filter(
|
|
226
|
+
(entry) => typeof entry === "string",
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
if (manifest?.content) {
|
|
230
|
+
config.assets.customProperties.files =
|
|
231
|
+
config.assets.customProperties.files.map((file) => {
|
|
232
|
+
const manifestEntry = getPathFromManifest(
|
|
233
|
+
file,
|
|
234
|
+
manifest,
|
|
235
|
+
config.assets.root,
|
|
236
|
+
);
|
|
237
|
+
|
|
238
|
+
if (manifestEntry) {
|
|
239
|
+
return path.join(path.dirname(manifest.file), manifestEntry);
|
|
240
|
+
} else {
|
|
241
|
+
return file;
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
} else {
|
|
246
|
+
log("warn", "config.assets.customProperties.files is not an array.");
|
|
247
|
+
|
|
248
|
+
config.assets.customProperties.files = [];
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (config.components) {
|
|
253
|
+
if (config.components.ignores) {
|
|
254
|
+
config.components.ignores = arrayfy(config.components.ignores).map(
|
|
255
|
+
sanitizePath,
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (!config.ui) config.ui = {};
|
|
261
|
+
if (!config.ui.theme) config.ui.theme = {};
|
|
262
|
+
if (!config.ui.theme.light) config.ui.theme.light = {};
|
|
263
|
+
if (!config.ui.theme.dark) config.ui.theme.dark = {};
|
|
264
|
+
|
|
265
|
+
if (config.ui.theme.logo) {
|
|
266
|
+
if (typeof config.ui.theme.logo === "string") {
|
|
267
|
+
const { logo } = config.ui.theme;
|
|
268
|
+
|
|
269
|
+
config.ui.theme.logo = {
|
|
270
|
+
light: logo,
|
|
271
|
+
dark: logo,
|
|
272
|
+
};
|
|
273
|
+
} else {
|
|
274
|
+
if (config.ui.theme.logo.light && !config.ui.theme.logo.dark) {
|
|
275
|
+
config.ui.theme.logo.dark = config.ui.theme.logo.light;
|
|
276
|
+
} else if (config.ui.theme.logo.dark && !config.ui.theme.logo.light) {
|
|
277
|
+
config.ui.theme.logo.light = config.ui.theme.logo.dark;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (config.ui.theme.logo.light) {
|
|
282
|
+
config.ui.theme.logo.light = sanitizePath(config.ui.theme.logo.light);
|
|
283
|
+
}
|
|
284
|
+
if (config.ui.theme.logo.dark) {
|
|
285
|
+
config.ui.theme.logo.dark = sanitizePath(config.ui.theme.logo.dark);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const merged = deepMerge(defaultUserConfig, config);
|
|
290
|
+
|
|
291
|
+
merged.components.folder = sanitizePath(merged.components.folder);
|
|
292
|
+
|
|
293
|
+
// do this later as otherwise the deepMerge would do concatenation which we do not want
|
|
294
|
+
if (config.files) {
|
|
295
|
+
if (config.files.mocks) {
|
|
296
|
+
if (config.files.mocks.extension) {
|
|
297
|
+
merged.files.mocks.extension = arrayfy(config.files.mocks.extension);
|
|
298
|
+
|
|
299
|
+
if (merged.files.mocks.extension.length === 1) {
|
|
300
|
+
merged.files.mocks.extension.push(
|
|
301
|
+
defaultUserConfig.files.mocks.extension[1],
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (!langAvailable.includes(merged.ui.lang)) {
|
|
309
|
+
merged.ui.lang = "en";
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return merged;
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* @param {string} file
|
|
317
|
+
* @param {object} manifest
|
|
318
|
+
* @param {string} root
|
|
319
|
+
* @returns {string|null}
|
|
320
|
+
*/
|
|
321
|
+
function getPathFromManifest(file, manifest, root = "") {
|
|
322
|
+
const entry = Object.entries(manifest.content).find(([key]) => {
|
|
323
|
+
return (
|
|
324
|
+
path.resolve(root, path.dirname(manifest.file), sanitizePath(key)) ===
|
|
325
|
+
path.resolve(root, sanitizePath(file))
|
|
326
|
+
);
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
return entry ? entry[1] : null;
|
|
330
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import {
|
|
3
|
+
createSynchronousEnvironment,
|
|
4
|
+
createSynchronousFilesystemLoader,
|
|
5
|
+
} from "twing";
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
import { t } from "../i18n/index.js";
|
|
8
|
+
import log from "../logger.js";
|
|
9
|
+
import * as helpers from "../helpers.js";
|
|
10
|
+
import TwingCache from "./twing/cache.js";
|
|
11
|
+
import * as twingFunctions from "./twing/functions.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @returns {void}
|
|
15
|
+
*/
|
|
16
|
+
function setMiyagiEngine() {
|
|
17
|
+
const loader = createSynchronousFilesystemLoader(fs);
|
|
18
|
+
const twing = createSynchronousEnvironment(loader, {
|
|
19
|
+
cache: new TwingCache(),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
loader.addPath(
|
|
23
|
+
path.join(import.meta.dirname, "../../frontend/views"),
|
|
24
|
+
"@miyagi",
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
Object.values(twingFunctions).forEach((twingFunction) => {
|
|
28
|
+
twing.addFunction(twingFunction);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
global.app.engine("miyagi", async (str, options, cb) =>
|
|
32
|
+
cb(await twing.render(str, options)),
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @returns {Promise<void>}
|
|
38
|
+
*/
|
|
39
|
+
async function setUserEngine() {
|
|
40
|
+
const { extension } = global.config.files.templates;
|
|
41
|
+
const { engine } = global.config;
|
|
42
|
+
|
|
43
|
+
if (!engine.render) {
|
|
44
|
+
log("error", "No render function has beend defined.");
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
global.app.engine(
|
|
50
|
+
helpers.getSingleFileExtension(extension),
|
|
51
|
+
async (name, context, cb) => await engine.render({ name, context, cb }),
|
|
52
|
+
);
|
|
53
|
+
} catch (e) {
|
|
54
|
+
log("error", t("settingEngineFailed"), e);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @returns {Promise<void>}
|
|
61
|
+
*/
|
|
62
|
+
export default async function initEngines() {
|
|
63
|
+
await setUserEngine();
|
|
64
|
+
setMiyagiEngine();
|
|
65
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module for initializing miyagi
|
|
3
|
+
* @module init
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import express from "express";
|
|
7
|
+
// deepcode ignore HttpToHttps: local server only
|
|
8
|
+
import http from "http";
|
|
9
|
+
import cookieParser from "cookie-parser";
|
|
10
|
+
|
|
11
|
+
import appConfig from "../default-config.js";
|
|
12
|
+
import { t } from "../i18n/index.js";
|
|
13
|
+
import build from "../build/index.js";
|
|
14
|
+
import log from "../logger.js";
|
|
15
|
+
import setEngines from "./engines.js";
|
|
16
|
+
import setRouter from "./router.js";
|
|
17
|
+
import setState from "../state/index.js";
|
|
18
|
+
import setStatic from "./static.js";
|
|
19
|
+
import setViews from "./views.js";
|
|
20
|
+
import setWatcher from "./watcher.js";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @param {object} mergedConfig
|
|
24
|
+
* @returns {Promise<object>}
|
|
25
|
+
*/
|
|
26
|
+
export default async function init(mergedConfig) {
|
|
27
|
+
// deepcode ignore UseCsurfForExpress: local server only, deepcode ignore DisablePoweredBy: local server only
|
|
28
|
+
global.app = express();
|
|
29
|
+
global.app.use(cookieParser());
|
|
30
|
+
global.config = mergedConfig;
|
|
31
|
+
global.app.set("view cache", global.config.isBuild);
|
|
32
|
+
global.app.set("cache", global.config.isBuild);
|
|
33
|
+
|
|
34
|
+
await setEngines();
|
|
35
|
+
|
|
36
|
+
const port = process.env.PORT || appConfig.defaultPort;
|
|
37
|
+
|
|
38
|
+
global.app.set("port", port);
|
|
39
|
+
|
|
40
|
+
await setState({
|
|
41
|
+
sourceTree: true,
|
|
42
|
+
menu: true,
|
|
43
|
+
partials: true,
|
|
44
|
+
fileContents: true,
|
|
45
|
+
css: true,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
setStatic();
|
|
49
|
+
setRouter();
|
|
50
|
+
setViews();
|
|
51
|
+
|
|
52
|
+
if (global.config.isBuild) {
|
|
53
|
+
return build()
|
|
54
|
+
.then((message) => {
|
|
55
|
+
log("success", message);
|
|
56
|
+
process.exit(0);
|
|
57
|
+
})
|
|
58
|
+
.catch((error) => {
|
|
59
|
+
log("error", error);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const { server, port: actualPort } = await startServer(
|
|
65
|
+
global.app.get("port"),
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
setWatcher(server);
|
|
69
|
+
|
|
70
|
+
log("success", `${t("serverStarted").replace("{{port}}", actualPort)}\n`);
|
|
71
|
+
|
|
72
|
+
return server;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @param {number} port - the port that should be used
|
|
77
|
+
* @returns {Promise} gets resolved with the server instance and the actual port
|
|
78
|
+
*/
|
|
79
|
+
function startServer(port) {
|
|
80
|
+
const server = http.createServer(global.app);
|
|
81
|
+
|
|
82
|
+
return new Promise((resolve) => {
|
|
83
|
+
server
|
|
84
|
+
.listen(port, function () {
|
|
85
|
+
resolve({ server, port });
|
|
86
|
+
})
|
|
87
|
+
.on("error", (error) => {
|
|
88
|
+
if (error["code"] === "EADDRINUSE") {
|
|
89
|
+
log(
|
|
90
|
+
"error",
|
|
91
|
+
t("portInUse").replace("{{port}}", port),
|
|
92
|
+
error.toString(),
|
|
93
|
+
);
|
|
94
|
+
server.close(async function () {
|
|
95
|
+
const response = await startServer(port + 1);
|
|
96
|
+
|
|
97
|
+
resolve(response);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import init from "./index.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Runs the renderer to either start the server or create a build
|
|
5
|
+
* @param {object} config - the user configuration object
|
|
6
|
+
* @returns {Promise<object>}
|
|
7
|
+
*/
|
|
8
|
+
export default async function initRendering(config) {
|
|
9
|
+
if (config) {
|
|
10
|
+
return await init(config);
|
|
11
|
+
}
|
|
12
|
+
}
|