@pictogrammers/element-esbuild 0.0.13 → 0.0.15
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/README.md +7 -0
- package/bin/element-build.js +10 -502
- package/bin/element-publish.js +0 -2
- package/bin/element-start.js +10 -2276
- package/package.json +2 -2
- package/scripts/element-build.ts +20 -1
- package/scripts/element-start.ts +59 -3
- package/scripts/getDirectories.ts +0 -1
- package/scripts/htmlDependentsPlugin.ts +56 -35
package/README.md
CHANGED
|
@@ -26,6 +26,11 @@ Example configuration for a app.
|
|
|
26
26
|
export default {
|
|
27
27
|
// root hello/app/app.ts
|
|
28
28
|
namespace: 'hello', // for applications
|
|
29
|
+
// optionally include external component packages
|
|
30
|
+
external: ['mynodepackage'],
|
|
31
|
+
copy: [
|
|
32
|
+
{ from: 'assets', to: 'assets' }
|
|
33
|
+
],
|
|
29
34
|
}
|
|
30
35
|
```
|
|
31
36
|
|
|
@@ -48,3 +53,5 @@ export default {
|
|
|
48
53
|
```
|
|
49
54
|
|
|
50
55
|
Leaving off the `namespace` will treat the repo as a component library. Each component will be built individually instead of a single application. The component's `__examples__` folders will render as demo.
|
|
56
|
+
|
|
57
|
+
Changes to the `/components/*` will sync to the `/publish/*` directory. This is by design so the publish directory can be linked with the `npm link` command.
|
package/bin/element-build.js
CHANGED
|
@@ -1,504 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
function dashToCamel(str) {
|
|
14
|
-
return str.replace(/-([a-z])/g, (m) => m[1].toUpperCase());
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// scripts/htmlDependentsPlugin.ts
|
|
18
|
-
var root = process.cwd();
|
|
19
|
-
var rootDepth = root.split(sep).length;
|
|
20
|
-
var htmlDependentsPlugin = {
|
|
21
|
-
name: "html-dependents-plugin",
|
|
22
|
-
setup(build2) {
|
|
23
|
-
build2.onLoad({ filter: /\.html$/ }, async (args) => {
|
|
24
|
-
const parts = args.path.split(sep).splice(rootDepth);
|
|
25
|
-
const [src, componentsDir3, currentNamspace, currentComponent, ...file] = parts;
|
|
26
|
-
const contents = await readFile(args.path, "utf8");
|
|
27
|
-
const matches = contents.matchAll(/<\/(?<namespace>\w+)-(?<value>[^>]+)/g);
|
|
28
|
-
const components = /* @__PURE__ */ new Map();
|
|
29
|
-
for (const match of matches) {
|
|
30
|
-
const { namespace: namespace2, value } = match.groups;
|
|
31
|
-
const component = dashToCamel(value);
|
|
32
|
-
components.set(`${namespace2}-${component}`, [namespace2, component]);
|
|
33
|
-
}
|
|
34
|
-
const imports = [];
|
|
35
|
-
components.forEach(([namespace2, component]) => {
|
|
36
|
-
const depth = parts.length - 4;
|
|
37
|
-
const backPaths = new Array(depth).fill("..");
|
|
38
|
-
if (namespace2 === currentNamspace) {
|
|
39
|
-
if (component === currentComponent) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
imports.push(`import './${backPaths.join("/")}/${component}/${component}';`);
|
|
43
|
-
} else {
|
|
44
|
-
imports.push(`import './${backPaths.join("/")}/${namespace2}/${component}/${component}';`);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
imports.push(`export default \`${contents}\`;`);
|
|
48
|
-
return {
|
|
49
|
-
contents: imports.join("\n"),
|
|
50
|
-
loader: "js"
|
|
51
|
-
};
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
// scripts/rebuildNotifyPlugin.ts
|
|
57
|
-
var green = (text) => `\x1B[32m${text}\x1B[0m`;
|
|
58
|
-
var rebuildNotifyPlugin = {
|
|
59
|
-
name: "rebuild-notify",
|
|
60
|
-
setup(build2) {
|
|
61
|
-
build2.onEnd((result) => {
|
|
62
|
-
if (result.errors.length > 0) {
|
|
63
|
-
console.error(`Build ended with ${result.errors.length} errors`);
|
|
64
|
-
} else {
|
|
65
|
-
console.log(green("Build succeeded!"));
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
// scripts/fileExists.ts
|
|
72
|
-
import { access } from "node:fs/promises";
|
|
73
|
-
import { constants } from "node:fs";
|
|
74
|
-
async function fileExists(filePath) {
|
|
75
|
-
try {
|
|
76
|
-
await access(filePath, constants.F_OK);
|
|
77
|
-
return true;
|
|
78
|
-
} catch (error) {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// scripts/element-build.ts
|
|
84
|
-
import { copyFile, writeFile as writeFile2 } from "node:fs/promises";
|
|
85
|
-
import { dirname as dirname2, join as join3 } from "node:path";
|
|
86
|
-
|
|
87
|
-
// scripts/playgroundPlugin.ts
|
|
88
|
-
import { join } from "node:path";
|
|
89
|
-
|
|
90
|
-
// scripts/getDirectories.ts
|
|
91
|
-
import { readdir } from "node:fs/promises";
|
|
92
|
-
async function getDirectories(dirPath) {
|
|
93
|
-
const directories = [];
|
|
94
|
-
try {
|
|
95
|
-
const entries = await readdir(dirPath, { withFileTypes: true });
|
|
96
|
-
for (const entry of entries) {
|
|
97
|
-
if (entry.isDirectory()) {
|
|
98
|
-
directories.push(entry.name);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
} catch (err) {
|
|
102
|
-
console.error("Error reading directory:", err);
|
|
103
|
-
}
|
|
104
|
-
return directories;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// scripts/folderExists.ts
|
|
108
|
-
import { access as access2 } from "node:fs/promises";
|
|
109
|
-
import { constants as constants2 } from "node:fs";
|
|
110
|
-
async function folderExists(folderPath) {
|
|
111
|
-
try {
|
|
112
|
-
await access2(folderPath, constants2.F_OK);
|
|
113
|
-
return true;
|
|
114
|
-
} catch (error) {
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// scripts/playgroundPlugin.ts
|
|
120
|
-
import { readFile as readFile2 } from "node:fs/promises";
|
|
121
|
-
|
|
122
|
-
// scripts/capitalizeFirstChracter.ts
|
|
123
|
-
function capitalizeFirstCharacter(str) {
|
|
124
|
-
if (!str) {
|
|
125
|
-
return str;
|
|
126
|
-
}
|
|
127
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// scripts/camelToDash.ts
|
|
131
|
-
function camelToDash(str) {
|
|
132
|
-
return str.replace(/([a-zA-Z])(?=[A-Z])/g, "$1-").toLowerCase();
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// scripts/playgroundPlugin.ts
|
|
136
|
-
var red = (text) => `\x1B[31m${text}\x1B[0m`;
|
|
137
|
-
var rootDir = process.cwd();
|
|
138
|
-
var srcDir = "src";
|
|
139
|
-
var componentsDir = "components";
|
|
140
|
-
function playgroundPlugin(options) {
|
|
141
|
-
return {
|
|
142
|
-
name: "playground-plugin",
|
|
143
|
-
setup(build2) {
|
|
144
|
-
const entryPointName = "playground-entry";
|
|
145
|
-
const virtualNamespace = "playground-module";
|
|
146
|
-
build2.onResolve({ filter: new RegExp(`^${entryPointName}$`) }, (args) => {
|
|
147
|
-
return {
|
|
148
|
-
path: entryPointName,
|
|
149
|
-
namespace: virtualNamespace
|
|
150
|
-
};
|
|
151
|
-
});
|
|
152
|
-
build2.onLoad({ filter: /.*/, namespace: virtualNamespace }, async (args) => {
|
|
153
|
-
const entryPoints2 = [];
|
|
154
|
-
const namespaces = await getDirectories(join(srcDir, componentsDir));
|
|
155
|
-
if (namespaces.length === 0) {
|
|
156
|
-
console.log(red('Missing at least 1 namespace folder under "src/components/"'));
|
|
157
|
-
process.exit();
|
|
158
|
-
}
|
|
159
|
-
const meta = [];
|
|
160
|
-
for (let namespace2 of namespaces) {
|
|
161
|
-
const metaNamespace = {
|
|
162
|
-
namespace: namespace2,
|
|
163
|
-
components: []
|
|
164
|
-
};
|
|
165
|
-
meta.push(metaNamespace);
|
|
166
|
-
const namespaceDir = join(srcDir, componentsDir, namespace2);
|
|
167
|
-
const components = await getDirectories(namespaceDir);
|
|
168
|
-
for (let component of components) {
|
|
169
|
-
if (await fileExists(join(srcDir, componentsDir, namespace2, component, `${component}.ts`))) {
|
|
170
|
-
let readme = "";
|
|
171
|
-
if (await fileExists(join(srcDir, componentsDir, namespace2, component, "README.md"))) {
|
|
172
|
-
readme = await readFile2(join(srcDir, componentsDir, namespace2, component, "README.md"), "utf8");
|
|
173
|
-
}
|
|
174
|
-
const metaComponent = {
|
|
175
|
-
namespace: namespace2,
|
|
176
|
-
component,
|
|
177
|
-
tag: `${namespace2}-${camelToDash(component)}`,
|
|
178
|
-
examples: [],
|
|
179
|
-
className: "",
|
|
180
|
-
classExtends: "",
|
|
181
|
-
readme
|
|
182
|
-
};
|
|
183
|
-
entryPoints2.push(`import '${componentsDir}/${namespace2}/${component}/${component}';`);
|
|
184
|
-
if (await folderExists(join(namespaceDir, component, "__examples__"))) {
|
|
185
|
-
const examples = await getDirectories(join(namespaceDir, component, "__examples__"));
|
|
186
|
-
for (let example of examples) {
|
|
187
|
-
if (await fileExists(join(namespaceDir, component, "__examples__", example, `${example}.ts`))) {
|
|
188
|
-
entryPoints2.push(`import '${componentsDir}/${namespace2}/${component}/__examples__/${example}/${example}';`);
|
|
189
|
-
metaComponent.examples.push({
|
|
190
|
-
namespace: namespace2,
|
|
191
|
-
component,
|
|
192
|
-
example,
|
|
193
|
-
tag: `x-${namespace2}-${camelToDash(component)}-${camelToDash(example)}`,
|
|
194
|
-
className: `X${capitalizeFirstCharacter(namespace2)}${capitalizeFirstCharacter(component)}${capitalizeFirstCharacter(example)}`
|
|
195
|
-
});
|
|
196
|
-
} else {
|
|
197
|
-
console.log(red(`Missing ${componentsDir}/${namespace2}/${component}/__examples__/${example}/${example}.ts`));
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
const data = await readFile2(join(srcDir, componentsDir, namespace2, component, `${component}.ts`), "utf8");
|
|
202
|
-
const matches = data.match(/class (\w+) extends (\w+)/);
|
|
203
|
-
if (!matches) {
|
|
204
|
-
console.log(red(`Component "${namespace2}-${component}" must extend HtmlElement or base class`));
|
|
205
|
-
process.exit();
|
|
206
|
-
}
|
|
207
|
-
metaComponent.className = matches[1];
|
|
208
|
-
metaComponent.classExtends = matches[2];
|
|
209
|
-
metaNamespace.components.push(metaComponent);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
options.after(meta);
|
|
214
|
-
return {
|
|
215
|
-
contents: entryPoints2.join("\n"),
|
|
216
|
-
resolveDir: join(process.cwd(), srcDir)
|
|
217
|
-
};
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// scripts/createPlaygroundIndex.ts
|
|
224
|
-
import { join as join2 } from "node:path";
|
|
225
|
-
import { readFile as readFile3 } from "node:fs/promises";
|
|
226
|
-
async function createPlaygroundIndex({
|
|
227
|
-
mode,
|
|
228
|
-
rootDir: rootDir3,
|
|
229
|
-
srcDir: srcDir3,
|
|
230
|
-
indexFile: indexFile2,
|
|
231
|
-
defaultDir: defaultDir2,
|
|
232
|
-
playgroundFile: playgroundFile2,
|
|
233
|
-
title: title2,
|
|
234
|
-
repo: repo2,
|
|
235
|
-
repoComponent: repoComponent2,
|
|
236
|
-
navigation: navigation2,
|
|
237
|
-
namespaces
|
|
238
|
-
}) {
|
|
239
|
-
let indexContent = "";
|
|
240
|
-
if (await fileExists(join2(rootDir3, srcDir3, indexFile2))) {
|
|
241
|
-
indexContent = await readFile3(join2(rootDir3, srcDir3, indexFile2), "utf8");
|
|
242
|
-
} else {
|
|
243
|
-
indexContent = await readFile3(join2(defaultDir2, playgroundFile2), "utf8");
|
|
244
|
-
}
|
|
245
|
-
indexContent = indexContent.replace(
|
|
246
|
-
"<title>Default</title>",
|
|
247
|
-
`<title>${title2 ?? "Default"}</title>`
|
|
248
|
-
);
|
|
249
|
-
indexContent = indexContent.replace(
|
|
250
|
-
"<h1>Default</h1>",
|
|
251
|
-
`<h1>${title2 ?? "Default"}</h1>`
|
|
252
|
-
);
|
|
253
|
-
const navItems = structuredClone(navigation2 ?? []);
|
|
254
|
-
for (let navItem of navItems) {
|
|
255
|
-
navItem.items = [];
|
|
256
|
-
}
|
|
257
|
-
let defaultItem;
|
|
258
|
-
if (navItems.length === 0) {
|
|
259
|
-
defaultItem = { label: "Components", items: [] };
|
|
260
|
-
navItems.push(defaultItem);
|
|
261
|
-
} else {
|
|
262
|
-
defaultItem = navItems.find((x) => !x.extends && !x.components && !x.namespaces);
|
|
263
|
-
if (!defaultItem) {
|
|
264
|
-
defaultItem = { label: "Other", items: [] };
|
|
265
|
-
navItems.push(defaultItem);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
const componentMap = /* @__PURE__ */ new Map();
|
|
269
|
-
namespaces.forEach(({ components }) => {
|
|
270
|
-
components.forEach(({ component, namespace: namespace2, tag, readme, examples, className, classExtends }) => {
|
|
271
|
-
componentMap.set(className, {
|
|
272
|
-
className,
|
|
273
|
-
// MyComponent
|
|
274
|
-
classExtends,
|
|
275
|
-
// MyModal
|
|
276
|
-
component,
|
|
277
|
-
// component
|
|
278
|
-
namespace: namespace2,
|
|
279
|
-
// my
|
|
280
|
-
tag,
|
|
281
|
-
// my-component
|
|
282
|
-
readme,
|
|
283
|
-
// # My Component
|
|
284
|
-
examples: examples.map((example) => example.className)
|
|
285
|
-
});
|
|
286
|
-
examples.forEach((example) => {
|
|
287
|
-
componentMap.set(example.className, {
|
|
288
|
-
className: example.className,
|
|
289
|
-
// XMyComponentBasic
|
|
290
|
-
classExtends: example.classExtends,
|
|
291
|
-
// HtmlElement
|
|
292
|
-
component: example.component,
|
|
293
|
-
// myComponentBasic
|
|
294
|
-
namespace: example.namespace,
|
|
295
|
-
// x
|
|
296
|
-
tag: example.tag,
|
|
297
|
-
// x-my-component-basic
|
|
298
|
-
example: example.example
|
|
299
|
-
// Basic
|
|
300
|
-
});
|
|
301
|
-
});
|
|
302
|
-
for (let navItem of navItems) {
|
|
303
|
-
if (navItem.include && navItem.include.includes(className)) {
|
|
304
|
-
navItem.items.push({
|
|
305
|
-
namespace: namespace2,
|
|
306
|
-
component,
|
|
307
|
-
className,
|
|
308
|
-
tag
|
|
309
|
-
});
|
|
310
|
-
return;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
for (let navItem of navItems) {
|
|
314
|
-
if (navItem === defaultItem) {
|
|
315
|
-
continue;
|
|
316
|
-
}
|
|
317
|
-
if (navItem.exclude && navItem.exclude.includes(className)) {
|
|
318
|
-
continue;
|
|
319
|
-
}
|
|
320
|
-
if (navItem.namespaces && !navItem.namespaces.includes(namespace2)) {
|
|
321
|
-
continue;
|
|
322
|
-
}
|
|
323
|
-
if (navItem.extends && !navItem.extends.includes(classExtends)) {
|
|
324
|
-
continue;
|
|
325
|
-
}
|
|
326
|
-
navItem.items.push({
|
|
327
|
-
namespace: namespace2,
|
|
328
|
-
component,
|
|
329
|
-
className,
|
|
330
|
-
tag
|
|
331
|
-
});
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
defaultItem.items.push({
|
|
335
|
-
namespace: namespace2,
|
|
336
|
-
component,
|
|
337
|
-
examples,
|
|
338
|
-
className,
|
|
339
|
-
tag
|
|
340
|
-
});
|
|
341
|
-
});
|
|
342
|
-
});
|
|
343
|
-
indexContent = indexContent.replace(/([ ]*)<!-- \[Navigation\] -->/, (match, indent) => {
|
|
344
|
-
return navItems.map(({ label, items }) => {
|
|
345
|
-
return [
|
|
346
|
-
indent,
|
|
347
|
-
`<div>${label}</div>`,
|
|
348
|
-
"<ul>",
|
|
349
|
-
items.map(({ component, namespace: namespace2, tag, className }) => {
|
|
350
|
-
return [
|
|
351
|
-
`<li data-tag="${tag}" data-class-name="${className}" data-component="${component}"><a href="#${tag}">${component}</a></li>`
|
|
352
|
-
].join(`
|
|
353
|
-
${indent}`);
|
|
354
|
-
}).join(`
|
|
355
|
-
${indent}`),
|
|
356
|
-
"</ul>"
|
|
357
|
-
].join(`
|
|
358
|
-
${indent}`);
|
|
359
|
-
}).join(`
|
|
360
|
-
${indent}`);
|
|
361
|
-
});
|
|
362
|
-
if (repo2) {
|
|
363
|
-
const github = "M12,2A10,10 0 0,0 2,12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0 0,0 12,2Z";
|
|
364
|
-
const generic = "M6,2H18A2,2 0 0,1 20,4V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V4A2,2 0 0,1 6,2M12.75,13.5C15.5,13.5 16.24,11.47 16.43,10.4C17.34,10.11 18,9.26 18,8.25C18,7 17,6 15.75,6C14.5,6 13.5,7 13.5,8.25C13.5,9.19 14.07,10 14.89,10.33C14.67,11 14,12 12,12C10.62,12 9.66,12.35 9,12.84V8.87C9.87,8.56 10.5,7.73 10.5,6.75C10.5,5.5 9.5,4.5 8.25,4.5C7,4.5 6,5.5 6,6.75C6,7.73 6.63,8.56 7.5,8.87V15.13C6.63,15.44 6,16.27 6,17.25C6,18.5 7,19.5 8.25,19.5C9.5,19.5 10.5,18.5 10.5,17.25C10.5,16.32 9.94,15.5 9.13,15.18C9.41,14.5 10.23,13.5 12.75,13.5M8.25,16.5A0.75,0.75 0 0,1 9,17.25A0.75,0.75 0 0,1 8.25,18A0.75,0.75 0 0,1 7.5,17.25A0.75,0.75 0 0,1 8.25,16.5M8.25,6A0.75,0.75 0 0,1 9,6.75A0.75,0.75 0 0,1 8.25,7.5A0.75,0.75 0 0,1 7.5,6.75A0.75,0.75 0 0,1 8.25,6M15.75,7.5A0.75,0.75 0 0,1 16.5,8.25A0.75,0.75 0 0,1 15.75,9A0.75,0.75 0 0,1 15,8.25A0.75,0.75 0 0,1 15.75,7.5Z";
|
|
365
|
-
const repoIcon = repo2.includes("github.com") ? github : generic;
|
|
366
|
-
indexContent = indexContent.replace(/([ ]*)<!-- \[Repo\] -->/, (match, indent) => {
|
|
367
|
-
return [
|
|
368
|
-
indent,
|
|
369
|
-
`<a href="${repo2}">`,
|
|
370
|
-
' <svg viewBox="0 0 24 24">',
|
|
371
|
-
` <path fill="currentColor" d="${repoIcon}" />`,
|
|
372
|
-
" </svg>",
|
|
373
|
-
" <span>View Repo</span>",
|
|
374
|
-
"</a>"
|
|
375
|
-
].join(`
|
|
376
|
-
${indent}`);
|
|
377
|
-
});
|
|
378
|
-
indexContent = indexContent.replace(/const repo = '';/, (match) => {
|
|
379
|
-
return `const repo = '${repo2}';`;
|
|
380
|
-
});
|
|
381
|
-
indexContent = indexContent.replace(/const repoComponent = '';/, (match) => {
|
|
382
|
-
return `const repoComponent = '${repoComponent2.replace(/\$repo/g, repo2)}';`;
|
|
383
|
-
});
|
|
384
|
-
indexContent = indexContent.replace(/const repoIcon = '';/, (match) => {
|
|
385
|
-
return `const repoIcon = '${repoIcon}';`;
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
if (mode === "dev") {
|
|
389
|
-
indexContent = indexContent.replace(/([ ]*)<!-- \[info\] -->/, (match, indent) => {
|
|
390
|
-
return [
|
|
391
|
-
indent,
|
|
392
|
-
"<p>This page is generated from <code>npm start</code>. To render only specific components use <code>npm start c-button</code>.</p>"
|
|
393
|
-
].join(`
|
|
394
|
-
${indent}`);
|
|
395
|
-
});
|
|
396
|
-
}
|
|
397
|
-
const classNames = [...componentMap.keys()];
|
|
398
|
-
indexContent = indexContent.replace(/([ ]*)const componentMap = new Map\(\);/, (match, indent) => {
|
|
399
|
-
return [
|
|
400
|
-
`${indent}const componentMap = new Map();`,
|
|
401
|
-
...classNames.map((className) => {
|
|
402
|
-
const data = componentMap.get(className);
|
|
403
|
-
return `componentMap.set('${className}', ${JSON.stringify(data)});`;
|
|
404
|
-
})
|
|
405
|
-
].join(`${indent}
|
|
406
|
-
`);
|
|
407
|
-
});
|
|
408
|
-
indexContent = indexContent.replace(/([ ]*)const navigation = \[\];/, (match, indent) => {
|
|
409
|
-
return `${indent}const navigation = ${JSON.stringify(navItems, null, " ")};`;
|
|
410
|
-
});
|
|
411
|
-
return indexContent;
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
// scripts/element-build.ts
|
|
415
|
-
var plugins = [htmlDependentsPlugin, rebuildNotifyPlugin];
|
|
416
|
-
var entryPoints = [];
|
|
417
|
-
var green2 = (text) => `\x1B[32m${text}\x1B[0m`;
|
|
418
|
-
var red2 = (text) => `\x1B[31m${text}\x1B[0m`;
|
|
419
|
-
var playgroundFile = "playground.html";
|
|
420
|
-
var __filename = fileURLToPath(import.meta.url);
|
|
421
|
-
var __dirname = dirname2(__filename);
|
|
422
|
-
var defaultDir = join3(__dirname, "..", "default");
|
|
423
|
-
var indexFile = "index.html";
|
|
424
|
-
var srcDir2 = "src";
|
|
425
|
-
var componentsDir2 = "components";
|
|
426
|
-
var configFile = "element.config.ts";
|
|
427
|
-
var rootDir2 = process.cwd();
|
|
428
|
-
var buildDir = "build";
|
|
429
|
-
var fullConfigPath = pathToFileURL(configFile);
|
|
430
|
-
if (!await fileExists(configFile)) {
|
|
431
|
-
console.log(red2("Missing element.config.ts in root."), "Add with content:");
|
|
432
|
-
console.log("export default {");
|
|
433
|
-
console.log(` namespace: 'hello',`);
|
|
434
|
-
console.log("}");
|
|
435
|
-
process.exit();
|
|
436
|
-
}
|
|
437
|
-
var config = await import(fullConfigPath.href);
|
|
438
|
-
var {
|
|
439
|
-
namespace,
|
|
440
|
-
title,
|
|
441
|
-
repo,
|
|
442
|
-
repoComponent,
|
|
443
|
-
navigation
|
|
444
|
-
} = config.default;
|
|
445
|
-
if (namespace) {
|
|
446
|
-
console.log(green2("Building app..."));
|
|
447
|
-
entryPoints.push(`./${srcDir2}/${componentsDir2}/${namespace}/app/app.ts`);
|
|
448
|
-
} else {
|
|
449
|
-
entryPoints.push("playground-entry");
|
|
450
|
-
plugins.push(
|
|
451
|
-
playgroundPlugin({
|
|
452
|
-
after: async (namespaces) => {
|
|
453
|
-
const indexContent = await createPlaygroundIndex({
|
|
454
|
-
mode: "production",
|
|
455
|
-
rootDir: rootDir2,
|
|
456
|
-
srcDir: srcDir2,
|
|
457
|
-
indexFile,
|
|
458
|
-
defaultDir,
|
|
459
|
-
playgroundFile,
|
|
460
|
-
title,
|
|
461
|
-
repo,
|
|
462
|
-
repoComponent,
|
|
463
|
-
navigation,
|
|
464
|
-
namespaces
|
|
465
|
-
});
|
|
466
|
-
await writeFile2(join3(rootDir2, buildDir, indexFile), indexContent);
|
|
467
|
-
}
|
|
468
|
-
})
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
|
-
build({
|
|
472
|
-
entryPoints,
|
|
473
|
-
bundle: true,
|
|
474
|
-
platform: "browser",
|
|
475
|
-
outfile: `./${buildDir}/main.js`,
|
|
476
|
-
sourcemap: false,
|
|
477
|
-
minify: true,
|
|
478
|
-
// aka production
|
|
479
|
-
format: "esm",
|
|
480
|
-
// Use ES Modules
|
|
481
|
-
target: "es2024",
|
|
482
|
-
// Target ES6 syntax
|
|
483
|
-
loader: {
|
|
484
|
-
".html": "text",
|
|
485
|
-
".css": "text"
|
|
486
|
-
},
|
|
487
|
-
plugins
|
|
488
|
-
}).then(async () => {
|
|
489
|
-
const faviconSvg = "favicon.svg";
|
|
490
|
-
if (await fileExists(join3(rootDir2, srcDir2, faviconSvg))) {
|
|
491
|
-
await copyFile(
|
|
492
|
-
join3(rootDir2, srcDir2, faviconSvg),
|
|
493
|
-
join3(rootDir2, buildDir, faviconSvg)
|
|
494
|
-
);
|
|
495
|
-
} else {
|
|
496
|
-
await copyFile(
|
|
497
|
-
join3(defaultDir, faviconSvg),
|
|
498
|
-
join3(rootDir2, buildDir, faviconSvg)
|
|
499
|
-
);
|
|
500
|
-
}
|
|
501
|
-
}).catch((err) => {
|
|
502
|
-
process.stderr.write(err.stderr);
|
|
503
|
-
process.exit(1);
|
|
504
|
-
});
|
|
3
|
+
import{fileURLToPath as fe,pathToFileURL as de}from"node:url";import{build as ge}from"esbuild";import{sep as z}from"node:path";import{readFile as ne}from"node:fs/promises";function k(e){return e.replace(/-([a-z])/g,r=>r[1].toUpperCase())}var oe="node_modules",se=process.cwd(),re=se.split(z).length,ae=e=>`\x1B[31m${e}\x1B[0m`;function B({localNamespaces:e,externalNamespaces:r}){return{name:"html-dependents-plugin",setup(m){m.onLoad({filter:/\.html$/},async f=>{let y=f.path.split(z).splice(re),[M,E,g,c,...P]=y,x=await ne(f.path,"utf8"),o=x.matchAll(/<\/(?<namespace>\w+)-(?<value>[^>]+)/g),t=new Map;for(let l of o){let{namespace:u,value:i}=l.groups,n=k(i);t.set(`${u}-${n}`,[u,n])}let p=[];return t.forEach(([l,u])=>{let i=y.length-4,n=new Array(i).fill("..");if(l===g){if(u===c)return;p.push(`import './${n.join("/")}/${u}/${u}';`)}else if(e.includes(l))p.push(`import './${n.join("/")}/${l}/${u}/${u}';`);else if(r.has(l)){n.push(".."),n.push(".."),n.push("..");let s=r.get(l);p.push(`import './${n.join("/")}/${oe}/${s}/${l}/${u}/${u}';`)}else console.log(ae(`Unable to find namespace folder "${l}". Possibly missing 'external' in element.config.ts`)),process.exit()}),p.push(`export default \`${x}\`;`),{contents:p.join(`
|
|
4
|
+
`),loader:"js"}})}}}var ie=e=>`\x1B[32m${e}\x1B[0m`,Z={name:"rebuild-notify",setup(e){e.onEnd(r=>{r.errors.length>0?console.error(`Build ended with ${r.errors.length} errors`):console.log(ie("Build succeeded!"))})}};import{access as ce}from"node:fs/promises";import{constants as le}from"node:fs";async function C(e){try{return await ce(e,le.F_OK),!0}catch{return!1}}import{copyFile as q,writeFile as he}from"node:fs/promises";import{dirname as $e,join as b}from"node:path";import{join as $}from"node:path";import{readdir as pe}from"node:fs/promises";async function A(e){let r=[];try{let m=await pe(e,{withFileTypes:!0});for(let f of m)f.isDirectory()&&r.push(f.name)}catch(m){console.error("Error reading directory:",m)}return r}import{access as me}from"node:fs/promises";import{constants as ue}from"node:fs";async function H(e){try{return await me(e,ue.F_OK),!0}catch{return!1}}import{readFile as S}from"node:fs/promises";function I(e){return e&&e.charAt(0).toUpperCase()+e.slice(1)}function T(e){return e.replace(/([a-zA-Z])(?=[A-Z])/g,"$1-").toLowerCase()}var O=e=>`\x1B[31m${e}\x1B[0m`,nt=process.cwd();var v="src",w="components";function J(e){return{name:"playground-plugin",setup(r){let m="playground-entry",f="playground-module";r.onResolve({filter:new RegExp(`^${m}$`)},y=>({path:m,namespace:f})),r.onLoad({filter:/.*/,namespace:f},async y=>{let M=[],E=await A($(v,w));E.length===0&&(console.log(O('Missing at least 1 namespace folder under "src/components/"')),process.exit());let g=[];for(let c of E){let P={namespace:c,components:[]};g.push(P);let x=$(v,w,c),o=await A(x);for(let t of o)if(await C($(v,w,c,t,`${t}.ts`))){let p="";await C($(v,w,c,t,"README.md"))&&(p=await S($(v,w,c,t,"README.md"),"utf8"));let l={namespace:c,component:t,tag:`${c}-${T(t)}`,examples:[],className:"",classExtends:"",readme:p};if(M.push(`import '${w}/${c}/${t}/${t}';`),await H($(x,t,"__examples__"))){let n=await A($(x,t,"__examples__"));for(let s of n)await C($(x,t,"__examples__",s,`${s}.ts`))?(M.push(`import '${w}/${c}/${t}/__examples__/${s}/${s}';`),l.examples.push({namespace:c,component:t,example:s,tag:`x-${c}-${T(t)}-${T(s)}`,className:`X${I(c)}${I(t)}${I(s)}`})):console.log(O(`Missing ${w}/${c}/${t}/__examples__/${s}/${s}.ts`))}let i=(await S($(v,w,c,t,`${t}.ts`),"utf8")).match(/class (\w+) extends (\w+)/);i||(console.log(O(`Component "${c}-${t}" must extend HtmlElement or base class`)),process.exit()),l.className=i[1],l.classExtends=i[2],P.components.push(l)}}return e.after(g),{contents:M.join(`
|
|
5
|
+
`),resolveDir:$(process.cwd(),v)}})}}}import{join as L}from"node:path";import{readFile as K}from"node:fs/promises";async function X({mode:e,rootDir:r,srcDir:m,indexFile:f,defaultDir:y,playgroundFile:M,title:E,repo:g,repoComponent:c,navigation:P,namespaces:x}){let o="";await C(L(r,m,f))?o=await K(L(r,m,f),"utf8"):o=await K(L(y,M),"utf8"),o=o.replace("<title>Default</title>",`<title>${E??"Default"}</title>`),o=o.replace("<h1>Default</h1>",`<h1>${E??"Default"}</h1>`);let t=structuredClone(P??[]);for(let i of t)i.items=[];let p;t.length===0?(p={label:"Components",items:[]},t.push(p)):(p=t.find(i=>!i.extends&&!i.components&&!i.namespaces),p||(p={label:"Other",items:[]},t.push(p)));let l=new Map;if(x.forEach(({components:i})=>{i.forEach(({component:n,namespace:s,tag:d,readme:_,examples:F,className:h,classExtends:N})=>{l.set(h,{className:h,classExtends:N,component:n,namespace:s,tag:d,readme:_,examples:F.map(a=>a.className)}),F.forEach(a=>{l.set(a.className,{className:a.className,classExtends:a.classExtends,component:a.component,namespace:a.namespace,tag:a.tag,example:a.example})});for(let a of t)if(a.include&&a.include.includes(h)){a.items.push({namespace:s,component:n,className:h,tag:d});return}for(let a of t)if(a!==p&&!(a.exclude&&a.exclude.includes(h))&&!(a.namespaces&&!a.namespaces.includes(s))&&!(a.extends&&!a.extends.includes(N))){a.items.push({namespace:s,component:n,className:h,tag:d});return}p.items.push({namespace:s,component:n,examples:F,className:h,tag:d})})}),o=o.replace(/([ ]*)<!-- \[Navigation\] -->/,(i,n)=>t.map(({label:s,items:d})=>[n,`<div>${s}</div>`,"<ul>",d.map(({component:_,namespace:F,tag:h,className:N})=>[`<li data-tag="${h}" data-class-name="${N}" data-component="${_}"><a href="#${h}">${_}</a></li>`].join(`
|
|
6
|
+
${n}`)).join(`
|
|
7
|
+
${n}`),"</ul>"].join(`
|
|
8
|
+
${n}`)).join(`
|
|
9
|
+
${n}`)),g){let s=g.includes("github.com")?"M12,2A10,10 0 0,0 2,12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0 0,0 12,2Z":"M6,2H18A2,2 0 0,1 20,4V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V4A2,2 0 0,1 6,2M12.75,13.5C15.5,13.5 16.24,11.47 16.43,10.4C17.34,10.11 18,9.26 18,8.25C18,7 17,6 15.75,6C14.5,6 13.5,7 13.5,8.25C13.5,9.19 14.07,10 14.89,10.33C14.67,11 14,12 12,12C10.62,12 9.66,12.35 9,12.84V8.87C9.87,8.56 10.5,7.73 10.5,6.75C10.5,5.5 9.5,4.5 8.25,4.5C7,4.5 6,5.5 6,6.75C6,7.73 6.63,8.56 7.5,8.87V15.13C6.63,15.44 6,16.27 6,17.25C6,18.5 7,19.5 8.25,19.5C9.5,19.5 10.5,18.5 10.5,17.25C10.5,16.32 9.94,15.5 9.13,15.18C9.41,14.5 10.23,13.5 12.75,13.5M8.25,16.5A0.75,0.75 0 0,1 9,17.25A0.75,0.75 0 0,1 8.25,18A0.75,0.75 0 0,1 7.5,17.25A0.75,0.75 0 0,1 8.25,16.5M8.25,6A0.75,0.75 0 0,1 9,6.75A0.75,0.75 0 0,1 8.25,7.5A0.75,0.75 0 0,1 7.5,6.75A0.75,0.75 0 0,1 8.25,6M15.75,7.5A0.75,0.75 0 0,1 16.5,8.25A0.75,0.75 0 0,1 15.75,9A0.75,0.75 0 0,1 15,8.25A0.75,0.75 0 0,1 15.75,7.5Z";o=o.replace(/([ ]*)<!-- \[Repo\] -->/,(d,_)=>[_,`<a href="${g}">`,' <svg viewBox="0 0 24 24">',` <path fill="currentColor" d="${s}" />`," </svg>"," <span>View Repo</span>","</a>"].join(`
|
|
10
|
+
${_}`)),o=o.replace(/const repo = '';/,d=>`const repo = '${g}';`),o=o.replace(/const repoComponent = '';/,d=>`const repoComponent = '${c.replace(/\$repo/g,g)}';`),o=o.replace(/const repoIcon = '';/,d=>`const repoIcon = '${s}';`)}e==="dev"&&(o=o.replace(/([ ]*)<!-- \[info\] -->/,(i,n)=>[n,"<p>This page is generated from <code>npm start</code>. To render only specific components use <code>npm start c-button</code>.</p>"].join(`
|
|
11
|
+
${n}`)));let u=[...l.keys()];return o=o.replace(/([ ]*)const componentMap = new Map\(\);/,(i,n)=>[`${n}const componentMap = new Map();`,...u.map(s=>{let d=l.get(s);return`componentMap.set('${s}', ${JSON.stringify(d)});`})].join(`${n}
|
|
12
|
+
`)),o=o.replace(/([ ]*)const navigation = \[\];/,(i,n)=>`${n}const navigation = ${JSON.stringify(t,null," ")};`),o}var U=[Z],V=[],ye=e=>`\x1B[32m${e}\x1B[0m`,xe=e=>`\x1B[31m${e}\x1B[0m`,G="node_modules",Ce="playground.html",we=fe(import.meta.url),be=$e(we),ee=b(be,"..","default"),Q="index.html";var j="src",W="components",te="element.config.ts",D=process.cwd(),R="build",De=de(te);await C(te)||(console.log(xe("Missing element.config.ts in root."),"Add with content:"),console.log("export default {"),console.log(" namespace: 'hello',"),console.log("}"),process.exit());var _e=await import(De.href),{namespace:Y,title:Ae,repo:ve,repoComponent:Me,navigation:Ee,external:Pe}=_e.default;if(Y){console.log(ye("Building app...")),V.push(`./${j}/${W}/${Y}/app/app.ts`);let e=await A(b(D,j,W)),r=new Map;for(let m of Pe??[])(await A(b(D,G,...m.split("/")))).forEach(y=>{y!==G&&r.set(y,m)});U.push(B({localNamespaces:e,externalNamespaces:r}))}else V.push("playground-entry"),U.push(J({after:async e=>{let r=await X({mode:"production",rootDir:D,srcDir:j,indexFile:Q,defaultDir:ee,playgroundFile:Ce,title:Ae,repo:ve,repoComponent:Me,navigation:Ee,namespaces:e});await he(b(D,R,Q),r)}}));ge({entryPoints:V,bundle:!0,platform:"browser",outfile:`./${R}/main.js`,sourcemap:!1,minify:!0,format:"esm",target:"es2024",loader:{".html":"text",".css":"text"},plugins:U}).then(async()=>{let e="favicon.svg";await C(b(D,j,e))?await q(b(D,j,e),b(D,R,e)):await q(b(ee,e),b(D,R,e))}).catch(e=>{process.stderr.write(e.stderr),process.exit(1)});
|