@sealcode/sealgen 0.15.63 → 0.16.1-beta2
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/@types/src/CSSBuilder.d.ts +19 -0
- package/@types/src/builder.d.ts +2 -9
- package/@types/src/find-css-includes.d.ts +1 -1
- package/lib/CSSBuilder.js +143 -0
- package/lib/build.js +6 -5
- package/lib/builder.js +3 -53
- package/lib/cli.js +0 -2
- package/lib/find-css-includes.js +0 -24
- package/lib/utils/walk.js +7 -1
- package/package.json +2 -1
- package/src/CSSBuilder.ts +154 -0
- package/src/build.ts +6 -5
- package/src/builder.ts +3 -59
- package/src/cli.ts +0 -2
- package/src/find-css-includes.ts +0 -31
- package/src/utils/walk.ts +8 -2
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Builder } from "./builder.js";
|
|
2
|
+
export declare class CSSClump {
|
|
3
|
+
project_dir: string;
|
|
4
|
+
name: string;
|
|
5
|
+
files: string[];
|
|
6
|
+
constructor(project_dir: string, name: string);
|
|
7
|
+
addFile(full_path: string): void;
|
|
8
|
+
build(): Promise<void>;
|
|
9
|
+
getEntrypointPath(): string;
|
|
10
|
+
makeEntrypoint(): Promise<void>;
|
|
11
|
+
static assignFileToClumps(file_path: string): string[];
|
|
12
|
+
static findCSSClumps(project_dir: string): Promise<CSSClump[]>;
|
|
13
|
+
}
|
|
14
|
+
export declare class CSSBuilder extends Builder {
|
|
15
|
+
getName(): string;
|
|
16
|
+
ownsFile(file_path: string): boolean;
|
|
17
|
+
dispose(): Promise<void>;
|
|
18
|
+
_build(): Promise<void>;
|
|
19
|
+
}
|
package/@types/src/builder.d.ts
CHANGED
|
@@ -1,20 +1,13 @@
|
|
|
1
|
-
import { BuildContext } from "esbuild";
|
|
2
1
|
export declare abstract class Builder {
|
|
2
|
+
project_dir: string;
|
|
3
3
|
abstract ownsFile(file_path: string): boolean;
|
|
4
4
|
abstract getName(): string;
|
|
5
5
|
abstract _build(): Promise<void>;
|
|
6
6
|
abstract dispose(): Promise<void>;
|
|
7
|
+
constructor(project_dir: string);
|
|
7
8
|
ongoing_build: Promise<void> | null;
|
|
8
9
|
build(notifier?: (message: string) => void): Promise<void>;
|
|
9
10
|
}
|
|
10
|
-
export declare class CSSBuilder extends Builder {
|
|
11
|
-
getName(): string;
|
|
12
|
-
private context_promise;
|
|
13
|
-
ownsFile(file_path: string): boolean;
|
|
14
|
-
dispose(): Promise<void>;
|
|
15
|
-
getBuildContext(): Promise<BuildContext>;
|
|
16
|
-
_build(): Promise<void>;
|
|
17
|
-
}
|
|
18
11
|
export declare class FontsBuilder extends Builder {
|
|
19
12
|
getName(): string;
|
|
20
13
|
ownsFile(file_path: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { build } from "esbuild";
|
|
2
|
+
import { resolve, relative, basename, dirname } from "node:path";
|
|
3
|
+
import glob from "tiny-glob";
|
|
4
|
+
import { promises as fs } from "fs";
|
|
5
|
+
import { walkDir } from "./utils/walk.js";
|
|
6
|
+
import { Builder } from "./builder.js";
|
|
7
|
+
class CSSClump {
|
|
8
|
+
constructor(project_dir, name) {
|
|
9
|
+
this.project_dir = project_dir;
|
|
10
|
+
this.name = name;
|
|
11
|
+
this.files = [];
|
|
12
|
+
}
|
|
13
|
+
addFile(full_path) {
|
|
14
|
+
this.files.push(full_path);
|
|
15
|
+
}
|
|
16
|
+
async build() {
|
|
17
|
+
await this.makeEntrypoint();
|
|
18
|
+
const loader = Object.fromEntries(
|
|
19
|
+
[
|
|
20
|
+
"png",
|
|
21
|
+
"svg",
|
|
22
|
+
"jpg",
|
|
23
|
+
"gif",
|
|
24
|
+
"jpeg",
|
|
25
|
+
"otf",
|
|
26
|
+
"ttf",
|
|
27
|
+
"woff",
|
|
28
|
+
"woff2"
|
|
29
|
+
].map((ext) => ["." + ext, "file"])
|
|
30
|
+
);
|
|
31
|
+
const result = await build({
|
|
32
|
+
entryPoints: [relative(this.project_dir, this.getEntrypointPath())],
|
|
33
|
+
sourcemap: true,
|
|
34
|
+
bundle: true,
|
|
35
|
+
outdir: "./public/dist",
|
|
36
|
+
logLevel: "info",
|
|
37
|
+
loader,
|
|
38
|
+
minify: true,
|
|
39
|
+
target: ["safari16.5"],
|
|
40
|
+
// to make css nesting work without manually adding `&`
|
|
41
|
+
metafile: true
|
|
42
|
+
});
|
|
43
|
+
await fs.writeFile(
|
|
44
|
+
relative(this.project_dir, "public/dist") + "/" + this.name + ".meta.json",
|
|
45
|
+
JSON.stringify(result.metafile)
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
getEntrypointPath() {
|
|
49
|
+
return resolve(
|
|
50
|
+
this.project_dir,
|
|
51
|
+
`src/style-entrypoints/${this.name}.entrypoint.css`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
async makeEntrypoint() {
|
|
55
|
+
const entrypoint_path = this.getEntrypointPath();
|
|
56
|
+
await fs.mkdir(dirname(entrypoint_path), { recursive: true });
|
|
57
|
+
await fs.writeFile(
|
|
58
|
+
entrypoint_path,
|
|
59
|
+
[
|
|
60
|
+
`/* DO NOT EDIT! Automatically generated by sealgen */`,
|
|
61
|
+
...this.files.sort().map(
|
|
62
|
+
(fullpath) => `@import "${relative(
|
|
63
|
+
dirname(entrypoint_path),
|
|
64
|
+
fullpath
|
|
65
|
+
)}";`
|
|
66
|
+
)
|
|
67
|
+
].join("\n")
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
static assignFileToClumps(file_path) {
|
|
71
|
+
const segments = basename(file_path).split(".");
|
|
72
|
+
segments.shift();
|
|
73
|
+
segments.pop();
|
|
74
|
+
if (!segments.length) {
|
|
75
|
+
if (file_path.includes("/jdd-components/")) {
|
|
76
|
+
const component_name = file_path.match(
|
|
77
|
+
/jdd-components\/([^/]+)\//
|
|
78
|
+
)?.[1];
|
|
79
|
+
if (!component_name) {
|
|
80
|
+
return [];
|
|
81
|
+
}
|
|
82
|
+
return ["jdd-component__" + component_name];
|
|
83
|
+
} else {
|
|
84
|
+
return ["default"];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (segments.length == 1 && segments[0] == "entrypoint") {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
return segments;
|
|
91
|
+
}
|
|
92
|
+
static async findCSSClumps(project_dir) {
|
|
93
|
+
const clumps = {};
|
|
94
|
+
const all_files = await walkDir(resolve(project_dir, "src"));
|
|
95
|
+
for (const file of all_files) {
|
|
96
|
+
if (!file.endsWith(".css"))
|
|
97
|
+
continue;
|
|
98
|
+
const clump_names = CSSClump.assignFileToClumps(file);
|
|
99
|
+
for (const clump_name of clump_names) {
|
|
100
|
+
if (!clump_name)
|
|
101
|
+
continue;
|
|
102
|
+
if (!clumps[clump_name]) {
|
|
103
|
+
clumps[clump_name] = new CSSClump(project_dir, clump_name);
|
|
104
|
+
}
|
|
105
|
+
clumps[clump_name]?.addFile(file);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return Object.values(clumps);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
class CSSBuilder extends Builder {
|
|
112
|
+
getName() {
|
|
113
|
+
return "css";
|
|
114
|
+
}
|
|
115
|
+
ownsFile(file_path) {
|
|
116
|
+
return file_path.endsWith(".css") && !file_path.endsWith("/includes.css");
|
|
117
|
+
}
|
|
118
|
+
async dispose() {
|
|
119
|
+
}
|
|
120
|
+
async _build() {
|
|
121
|
+
try {
|
|
122
|
+
const entrypoints = await glob(`./src/*.entrypoint.css`);
|
|
123
|
+
await Promise.allSettled(
|
|
124
|
+
entrypoints.map(
|
|
125
|
+
(rel_path) => fs.unlink(resolve(this.project_dir, rel_path))
|
|
126
|
+
)
|
|
127
|
+
);
|
|
128
|
+
const clumps = await CSSClump.findCSSClumps(this.project_dir);
|
|
129
|
+
console.log(
|
|
130
|
+
"clumps!",
|
|
131
|
+
clumps.map((c) => c.name)
|
|
132
|
+
);
|
|
133
|
+
await Promise.all(clumps.map((clump) => clump.build()));
|
|
134
|
+
} catch (e) {
|
|
135
|
+
console.error(e);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export {
|
|
140
|
+
CSSBuilder,
|
|
141
|
+
CSSClump
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=CSSBuilder.js.map
|
package/lib/build.js
CHANGED
|
@@ -5,10 +5,10 @@ import getPort from "get-port";
|
|
|
5
5
|
import _locreq from "locreq";
|
|
6
6
|
import {
|
|
7
7
|
BackendTSBuilder,
|
|
8
|
-
CSSBuilder,
|
|
9
8
|
FontsBuilder,
|
|
10
9
|
FrontendTSBuilder
|
|
11
10
|
} from "./builder.js";
|
|
11
|
+
import { CSSBuilder } from "./CSSBuilder.js";
|
|
12
12
|
const target_locreq = _locreq(process.cwd());
|
|
13
13
|
async function get_notifier_port() {
|
|
14
14
|
return getPort({ port: 4e3 });
|
|
@@ -24,10 +24,11 @@ async function write_notifier_config(watch, port) {
|
|
|
24
24
|
);
|
|
25
25
|
}
|
|
26
26
|
async function build(watch) {
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
27
|
+
const project_dir = target_locreq.resolve("");
|
|
28
|
+
const fonts_builder = new FontsBuilder(project_dir);
|
|
29
|
+
const backend_ts_builder = new BackendTSBuilder(project_dir);
|
|
30
|
+
const frontend_ts_builder = new FrontendTSBuilder(project_dir);
|
|
31
|
+
const css_builder = new CSSBuilder(project_dir);
|
|
31
32
|
const builders = [
|
|
32
33
|
fonts_builder,
|
|
33
34
|
backend_ts_builder,
|
package/lib/builder.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { build
|
|
1
|
+
import { build } from "esbuild";
|
|
2
2
|
import glob from "tiny-glob";
|
|
3
3
|
import { embeddable_file_extensions } from "./embeddable-file-extensions.js";
|
|
4
4
|
import { load_assets_plugin } from "./esbuild-plugins/load-assets.js";
|
|
5
5
|
import { rewrite_asset_imports_plugin } from "./esbuild-plugins/rewrite-asset-imports.js";
|
|
6
|
-
import { generate_css_includes } from "./find-css-includes.js";
|
|
7
6
|
import { generateCollections } from "./generate-collections.js";
|
|
8
7
|
import { generateComponents } from "./generate-components.js";
|
|
9
8
|
import { generateRoutes } from "./generate-routes.js";
|
|
10
9
|
import { generateStimulusControllers } from "./generate-stimulus.js";
|
|
11
10
|
import { FONTS_CONFIG_PATH, getFonts } from "./get-fonts.js";
|
|
12
11
|
class Builder {
|
|
13
|
-
constructor() {
|
|
12
|
+
constructor(project_dir) {
|
|
13
|
+
this.project_dir = project_dir;
|
|
14
14
|
this.ongoing_build = null;
|
|
15
15
|
}
|
|
16
16
|
build(notifier) {
|
|
@@ -26,55 +26,6 @@ class Builder {
|
|
|
26
26
|
return this.ongoing_build;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
class CSSBuilder extends Builder {
|
|
30
|
-
getName() {
|
|
31
|
-
return "css";
|
|
32
|
-
}
|
|
33
|
-
ownsFile(file_path) {
|
|
34
|
-
return file_path.endsWith(".css") && !file_path.endsWith("/includes.css");
|
|
35
|
-
}
|
|
36
|
-
async dispose() {
|
|
37
|
-
return (await this.getBuildContext()).dispose();
|
|
38
|
-
}
|
|
39
|
-
async getBuildContext() {
|
|
40
|
-
if (!this.context_promise) {
|
|
41
|
-
const loader = Object.fromEntries(
|
|
42
|
-
[
|
|
43
|
-
"png",
|
|
44
|
-
"svg",
|
|
45
|
-
"jpg",
|
|
46
|
-
"gif",
|
|
47
|
-
"jpeg",
|
|
48
|
-
"otf",
|
|
49
|
-
"ttf",
|
|
50
|
-
"woff",
|
|
51
|
-
"woff2"
|
|
52
|
-
].map((ext) => ["." + ext, "file"])
|
|
53
|
-
);
|
|
54
|
-
const context_promise = context({
|
|
55
|
-
entryPoints: ["./src/main.css"],
|
|
56
|
-
sourcemap: true,
|
|
57
|
-
bundle: true,
|
|
58
|
-
outdir: "./public/dist",
|
|
59
|
-
logLevel: "info",
|
|
60
|
-
// plugins: [sassPlugin()],
|
|
61
|
-
loader,
|
|
62
|
-
minify: true,
|
|
63
|
-
target: ["safari16.5"]
|
|
64
|
-
// to make css nesting work without manually adding `&`
|
|
65
|
-
});
|
|
66
|
-
this.context_promise = context_promise;
|
|
67
|
-
return context_promise;
|
|
68
|
-
} else {
|
|
69
|
-
return this.context_promise;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
async _build() {
|
|
73
|
-
const context2 = await this.getBuildContext();
|
|
74
|
-
await generate_css_includes();
|
|
75
|
-
await context2.rebuild();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
29
|
class FontsBuilder extends Builder {
|
|
79
30
|
getName() {
|
|
80
31
|
return "fonts";
|
|
@@ -153,7 +104,6 @@ class FrontendTSBuilder extends Builder {
|
|
|
153
104
|
export {
|
|
154
105
|
BackendTSBuilder,
|
|
155
106
|
Builder,
|
|
156
|
-
CSSBuilder,
|
|
157
107
|
FontsBuilder,
|
|
158
108
|
FrontendTSBuilder
|
|
159
109
|
};
|
package/lib/cli.js
CHANGED
|
@@ -3,7 +3,6 @@ import { addCollection } from "./add-collection.js";
|
|
|
3
3
|
import { addJDDComponent } from "./add-jdd-component.js";
|
|
4
4
|
import { addRoute } from "./add-route.js";
|
|
5
5
|
import { buildProject } from "./build.js";
|
|
6
|
-
import { generate_css_includes } from "./find-css-includes.js";
|
|
7
6
|
import { generateCollections } from "./generate-collections.js";
|
|
8
7
|
import { generateComponents } from "./generate-components.js";
|
|
9
8
|
import { generateRoutes } from "./generate-routes.js";
|
|
@@ -19,7 +18,6 @@ const actions = {
|
|
|
19
18
|
"generate-collections": generateCollections,
|
|
20
19
|
"generate-components": generateComponents,
|
|
21
20
|
"generate-routes": generateRoutes,
|
|
22
|
-
"generate-css-includes": generate_css_includes,
|
|
23
21
|
build: buildProject,
|
|
24
22
|
default: async function() {
|
|
25
23
|
console.log("Usage: `npx sealgen <action>`");
|
package/lib/find-css-includes.js
CHANGED
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
import { promises as fs } from "fs";
|
|
2
1
|
import _locreq from "locreq";
|
|
3
|
-
import { relative } from "path";
|
|
4
|
-
import { walkDir } from "./utils/walk.js";
|
|
5
2
|
const target_locreq = _locreq(process.cwd());
|
|
6
|
-
async function generate_css_includes() {
|
|
7
|
-
const files = (await Promise.all(
|
|
8
|
-
(await walkDir(target_locreq.resolve("src/"))).filter(
|
|
9
|
-
(f) => f.endsWith(".css") && !f.endsWith("/main.css") && !f.endsWith("\\main.css") && !f.endsWith("/includes.css") && !f.endsWith("\\includes.css") && !f.includes(".#")
|
|
10
|
-
).map(
|
|
11
|
-
(fullpath) => relative(target_locreq.resolve("src/"), fullpath)
|
|
12
|
-
)
|
|
13
|
-
)).sort();
|
|
14
|
-
await fs.writeFile(
|
|
15
|
-
target_locreq.resolve("src/includes.css"),
|
|
16
|
-
`/* DO NOT EDIT! This file is generated automaticaly with npx sealgen generate-css-includes */
|
|
17
|
-
|
|
18
|
-
@import "../node_modules/@sealcode/sealgen/src/forms/forms.css";
|
|
19
|
-
${files.map((path) => `@import "${path.replaceAll("\\", "/")}";`).join("\n")}
|
|
20
|
-
`
|
|
21
|
-
);
|
|
22
|
-
console.log("Successfuly generated new src/includes.css file");
|
|
23
|
-
}
|
|
24
|
-
export {
|
|
25
|
-
generate_css_includes
|
|
26
|
-
};
|
|
27
3
|
//# sourceMappingURL=find-css-includes.js.map
|
package/lib/utils/walk.js
CHANGED
|
@@ -8,7 +8,13 @@ async function walkDir(dir) {
|
|
|
8
8
|
continue;
|
|
9
9
|
}
|
|
10
10
|
const fullpath = resolve(dir, entry);
|
|
11
|
-
|
|
11
|
+
let info;
|
|
12
|
+
try {
|
|
13
|
+
info = await fs.stat(fullpath);
|
|
14
|
+
} catch (e) {
|
|
15
|
+
console.error(e);
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
12
18
|
if (info.isDirectory()) {
|
|
13
19
|
ret = [...ret, ...await walkDir(fullpath)];
|
|
14
20
|
} else {
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sealcode/sealgen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.1-beta2",
|
|
4
4
|
"description": "Module to automate adding routes and collections to a sealious application",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"prebuild": "npm run lint && rm -rf lib",
|
|
9
9
|
"build": "node ./build.js",
|
|
10
|
+
"watch": "npm run build -- --watch",
|
|
10
11
|
"postbuild": "npm run build-types",
|
|
11
12
|
"pretest": "npm run build",
|
|
12
13
|
"test": "node test.cjs",
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { build } from "esbuild";
|
|
2
|
+
import { resolve, relative, basename, dirname } from "node:path";
|
|
3
|
+
import glob from "tiny-glob";
|
|
4
|
+
import { promises as fs } from "fs";
|
|
5
|
+
import { walkDir } from "./utils/walk.js";
|
|
6
|
+
import { Builder } from "./builder.js";
|
|
7
|
+
|
|
8
|
+
export class CSSClump {
|
|
9
|
+
public files: string[] = [];
|
|
10
|
+
constructor(public project_dir: string, public name: string) {}
|
|
11
|
+
|
|
12
|
+
addFile(full_path: string) {
|
|
13
|
+
this.files.push(full_path);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async build() {
|
|
17
|
+
await this.makeEntrypoint();
|
|
18
|
+
const loader = Object.fromEntries(
|
|
19
|
+
(<const>[
|
|
20
|
+
"png",
|
|
21
|
+
"svg",
|
|
22
|
+
"jpg",
|
|
23
|
+
"gif",
|
|
24
|
+
"jpeg",
|
|
25
|
+
"otf",
|
|
26
|
+
"ttf",
|
|
27
|
+
"woff",
|
|
28
|
+
"woff2",
|
|
29
|
+
]).map((ext) => <const>["." + ext, "file"])
|
|
30
|
+
);
|
|
31
|
+
const result = await build({
|
|
32
|
+
entryPoints: [relative(this.project_dir, this.getEntrypointPath())],
|
|
33
|
+
sourcemap: true,
|
|
34
|
+
bundle: true,
|
|
35
|
+
outdir: "./public/dist",
|
|
36
|
+
logLevel: "info",
|
|
37
|
+
loader,
|
|
38
|
+
minify: true,
|
|
39
|
+
target: ["safari16.5"], // to make css nesting work without manually adding `&`
|
|
40
|
+
metafile: true,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
await fs.writeFile(
|
|
44
|
+
relative(this.project_dir, "public/dist") +
|
|
45
|
+
"/" +
|
|
46
|
+
this.name +
|
|
47
|
+
".meta.json",
|
|
48
|
+
JSON.stringify(result.metafile)
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
getEntrypointPath(): string {
|
|
53
|
+
return resolve(
|
|
54
|
+
this.project_dir,
|
|
55
|
+
`src/style-entrypoints/${this.name}.entrypoint.css`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async makeEntrypoint() {
|
|
60
|
+
const entrypoint_path = this.getEntrypointPath();
|
|
61
|
+
await fs.mkdir(dirname(entrypoint_path), { recursive: true });
|
|
62
|
+
await fs.writeFile(
|
|
63
|
+
entrypoint_path,
|
|
64
|
+
[
|
|
65
|
+
`/* DO NOT EDIT! Automatically generated by sealgen */`,
|
|
66
|
+
...this.files
|
|
67
|
+
.sort()
|
|
68
|
+
.map(
|
|
69
|
+
(fullpath) =>
|
|
70
|
+
`@import "${relative(
|
|
71
|
+
dirname(entrypoint_path),
|
|
72
|
+
fullpath
|
|
73
|
+
)}";`
|
|
74
|
+
),
|
|
75
|
+
].join("\n")
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static assignFileToClumps(file_path: string): string[] {
|
|
80
|
+
const segments = basename(file_path).split(".");
|
|
81
|
+
segments.shift(); // filename
|
|
82
|
+
segments.pop(); // extension
|
|
83
|
+
if (!segments.length) {
|
|
84
|
+
if (file_path.includes("/jdd-components/")) {
|
|
85
|
+
const component_name = file_path.match(
|
|
86
|
+
/jdd-components\/([^/]+)\//
|
|
87
|
+
)?.[1];
|
|
88
|
+
if (!component_name) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
return ["jdd-component__" + component_name];
|
|
92
|
+
} else {
|
|
93
|
+
// no segments, default clump
|
|
94
|
+
return ["default"];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (segments.length == 1 && segments[0] == "entrypoint") {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
return segments;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static async findCSSClumps(project_dir: string): Promise<CSSClump[]> {
|
|
104
|
+
const clumps: Record<string, CSSClump> = {};
|
|
105
|
+
const all_files = await walkDir(resolve(project_dir, "src"));
|
|
106
|
+
for (const file of all_files) {
|
|
107
|
+
if (!file.endsWith(".css")) continue;
|
|
108
|
+
const clump_names = CSSClump.assignFileToClumps(file);
|
|
109
|
+
for (const clump_name of clump_names) {
|
|
110
|
+
if (!clump_name) continue;
|
|
111
|
+
if (!clumps[clump_name]) {
|
|
112
|
+
clumps[clump_name] = new CSSClump(project_dir, clump_name);
|
|
113
|
+
}
|
|
114
|
+
clumps[clump_name]?.addFile(file);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return Object.values(clumps);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export class CSSBuilder extends Builder {
|
|
122
|
+
getName(): string {
|
|
123
|
+
return "css";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
ownsFile(file_path: string) {
|
|
127
|
+
return (
|
|
128
|
+
file_path.endsWith(".css") && !file_path.endsWith("/includes.css")
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async dispose(): Promise<void> {
|
|
133
|
+
//noop
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async _build() {
|
|
137
|
+
try {
|
|
138
|
+
const entrypoints = await glob(`./src/*.entrypoint.css`);
|
|
139
|
+
await Promise.allSettled(
|
|
140
|
+
entrypoints.map((rel_path) =>
|
|
141
|
+
fs.unlink(resolve(this.project_dir, rel_path))
|
|
142
|
+
)
|
|
143
|
+
);
|
|
144
|
+
const clumps = await CSSClump.findCSSClumps(this.project_dir);
|
|
145
|
+
console.log(
|
|
146
|
+
"clumps!",
|
|
147
|
+
clumps.map((c) => c.name)
|
|
148
|
+
);
|
|
149
|
+
await Promise.all(clumps.map((clump) => clump.build()));
|
|
150
|
+
} catch (e) {
|
|
151
|
+
console.error(e);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
package/src/build.ts
CHANGED
|
@@ -7,10 +7,10 @@ import _locreq from "locreq";
|
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
BackendTSBuilder,
|
|
10
|
-
CSSBuilder,
|
|
11
10
|
FontsBuilder,
|
|
12
11
|
FrontendTSBuilder,
|
|
13
12
|
} from "./builder.js";
|
|
13
|
+
import { CSSBuilder } from "./CSSBuilder.js";
|
|
14
14
|
const target_locreq = _locreq(process.cwd());
|
|
15
15
|
|
|
16
16
|
async function get_notifier_port() {
|
|
@@ -29,10 +29,11 @@ async function write_notifier_config(watch: boolean, port?: number) {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
async function build(watch: boolean): Promise<void> {
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const
|
|
32
|
+
const project_dir = target_locreq.resolve("");
|
|
33
|
+
const fonts_builder = new FontsBuilder(project_dir);
|
|
34
|
+
const backend_ts_builder = new BackendTSBuilder(project_dir);
|
|
35
|
+
const frontend_ts_builder = new FrontendTSBuilder(project_dir);
|
|
36
|
+
const css_builder = new CSSBuilder(project_dir);
|
|
36
37
|
const builders = [
|
|
37
38
|
fonts_builder,
|
|
38
39
|
backend_ts_builder,
|
package/src/builder.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { build
|
|
1
|
+
import { build } from "esbuild";
|
|
2
2
|
import glob from "tiny-glob";
|
|
3
3
|
import { embeddable_file_extensions } from "./embeddable-file-extensions.js";
|
|
4
4
|
import { load_assets_plugin } from "./esbuild-plugins/load-assets.js";
|
|
5
5
|
import { rewrite_asset_imports_plugin } from "./esbuild-plugins/rewrite-asset-imports.js";
|
|
6
|
-
import { generate_css_includes } from "./find-css-includes.js";
|
|
7
6
|
import { generateCollections } from "./generate-collections.js";
|
|
8
7
|
import { generateComponents } from "./generate-components.js";
|
|
9
8
|
import { generateRoutes } from "./generate-routes.js";
|
|
@@ -16,6 +15,8 @@ export abstract class Builder {
|
|
|
16
15
|
abstract _build(): Promise<void>;
|
|
17
16
|
abstract dispose(): Promise<void>;
|
|
18
17
|
|
|
18
|
+
constructor(public project_dir: string) {}
|
|
19
|
+
|
|
19
20
|
public ongoing_build: Promise<void> | null = null;
|
|
20
21
|
|
|
21
22
|
public build(notifier?: (message: string) => void) {
|
|
@@ -34,63 +35,6 @@ export abstract class Builder {
|
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
export class CSSBuilder extends Builder {
|
|
38
|
-
getName(): string {
|
|
39
|
-
return "css";
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private context_promise: Promise<BuildContext> | null;
|
|
43
|
-
|
|
44
|
-
ownsFile(file_path: string) {
|
|
45
|
-
return (
|
|
46
|
-
file_path.endsWith(".css") && !file_path.endsWith("/includes.css")
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
async dispose(): Promise<void> {
|
|
51
|
-
return (await this.getBuildContext()).dispose();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async getBuildContext(): Promise<BuildContext> {
|
|
55
|
-
if (!this.context_promise) {
|
|
56
|
-
const loader = Object.fromEntries(
|
|
57
|
-
(<const>[
|
|
58
|
-
"png",
|
|
59
|
-
"svg",
|
|
60
|
-
"jpg",
|
|
61
|
-
"gif",
|
|
62
|
-
"jpeg",
|
|
63
|
-
"otf",
|
|
64
|
-
"ttf",
|
|
65
|
-
"woff",
|
|
66
|
-
"woff2",
|
|
67
|
-
]).map((ext) => <const>["." + ext, "file"])
|
|
68
|
-
);
|
|
69
|
-
const context_promise = context({
|
|
70
|
-
entryPoints: ["./src/main.css"],
|
|
71
|
-
sourcemap: true,
|
|
72
|
-
bundle: true,
|
|
73
|
-
outdir: "./public/dist",
|
|
74
|
-
logLevel: "info",
|
|
75
|
-
// plugins: [sassPlugin()],
|
|
76
|
-
loader,
|
|
77
|
-
minify: true,
|
|
78
|
-
target: ["safari16.5"], // to make css nesting work without manually adding `&`
|
|
79
|
-
});
|
|
80
|
-
this.context_promise = context_promise;
|
|
81
|
-
return context_promise;
|
|
82
|
-
} else {
|
|
83
|
-
return this.context_promise;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
async _build() {
|
|
88
|
-
const context = await this.getBuildContext();
|
|
89
|
-
await generate_css_includes();
|
|
90
|
-
await context.rebuild();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
38
|
export class FontsBuilder extends Builder {
|
|
95
39
|
getName(): string {
|
|
96
40
|
return "fonts";
|
package/src/cli.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { addCollection } from "./add-collection.js";
|
|
|
3
3
|
import { addJDDComponent } from "./add-jdd-component.js";
|
|
4
4
|
import { addRoute } from "./add-route.js";
|
|
5
5
|
import { buildProject } from "./build.js";
|
|
6
|
-
import { generate_css_includes } from "./find-css-includes.js";
|
|
7
6
|
import { generateCollections } from "./generate-collections.js";
|
|
8
7
|
import { generateComponents } from "./generate-components.js";
|
|
9
8
|
import { generateRoutes } from "./generate-routes.js";
|
|
@@ -23,7 +22,6 @@ const actions: Record<
|
|
|
23
22
|
"generate-collections": generateCollections,
|
|
24
23
|
"generate-components": generateComponents,
|
|
25
24
|
"generate-routes": generateRoutes,
|
|
26
|
-
"generate-css-includes": generate_css_includes,
|
|
27
25
|
build: buildProject,
|
|
28
26
|
default: async function () {
|
|
29
27
|
console.log("Usage: `npx sealgen <action>`");
|
package/src/find-css-includes.ts
CHANGED
|
@@ -4,34 +4,3 @@ import { relative } from "path";
|
|
|
4
4
|
import { walkDir } from "./utils/walk.js";
|
|
5
5
|
|
|
6
6
|
const target_locreq = _locreq(process.cwd());
|
|
7
|
-
|
|
8
|
-
export async function generate_css_includes(): Promise<void> {
|
|
9
|
-
const files = (
|
|
10
|
-
await Promise.all(
|
|
11
|
-
(await walkDir(target_locreq.resolve("src/")))
|
|
12
|
-
.filter(
|
|
13
|
-
(f) =>
|
|
14
|
-
f.endsWith(".css") &&
|
|
15
|
-
!f.endsWith("/main.css") &&
|
|
16
|
-
!f.endsWith("\\main.css") &&
|
|
17
|
-
!f.endsWith("/includes.css") &&
|
|
18
|
-
!f.endsWith("\\includes.css") &&
|
|
19
|
-
!f.includes(".#")
|
|
20
|
-
)
|
|
21
|
-
.map((fullpath) =>
|
|
22
|
-
relative(target_locreq.resolve("src/"), fullpath)
|
|
23
|
-
)
|
|
24
|
-
)
|
|
25
|
-
).sort();
|
|
26
|
-
|
|
27
|
-
await fs.writeFile(
|
|
28
|
-
target_locreq.resolve("src/includes.css"),
|
|
29
|
-
`/* DO NOT EDIT! This file is generated automaticaly with npx sealgen generate-css-includes */
|
|
30
|
-
|
|
31
|
-
@import "../node_modules/@sealcode/sealgen/src/forms/forms.css";
|
|
32
|
-
${files.map((path) => `@import "${path.replaceAll("\\", "/")}";`).join("\n")}
|
|
33
|
-
`
|
|
34
|
-
);
|
|
35
|
-
// eslint-disable-next-line no-console
|
|
36
|
-
console.log("Successfuly generated new src/includes.css file");
|
|
37
|
-
}
|
package/src/utils/walk.ts
CHANGED
|
@@ -10,8 +10,14 @@ export async function walkDir(dir: string): Promise<string[]> {
|
|
|
10
10
|
}
|
|
11
11
|
const fullpath = resolve(dir, entry);
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
let info;
|
|
14
|
+
try {
|
|
15
|
+
// eslint-disable-next-line no-await-in-loop
|
|
16
|
+
info = await fs.stat(fullpath);
|
|
17
|
+
} catch (e) {
|
|
18
|
+
console.error(e);
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
15
21
|
|
|
16
22
|
if (info.isDirectory()) {
|
|
17
23
|
// eslint-disable-next-line no-await-in-loop
|