@akanjs/cli 3.1.0-rc.4 → 3.1.0-rc.6
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/.build-stamp +1 -1
- package/{CodeAgent-ymte1tv8.js → CodeAgent-rkjyxgec.js} +2 -2
- package/{CodeTui-4rhdm1qw.js → CodeTui-h7pyj6xa.js} +1 -1
- package/TunnelShare-661cxz5e.js +14 -0
- package/{agent.command-r5x1mch5.js → agent.command-3qxf4xcj.js} +5 -5
- package/akanCode.js +2 -2
- package/{application.command-3dkr7rdz.js → application.command-m1kcd7jf.js} +12 -11
- package/{applicationBuildRunner-h0j2swx1.js → applicationBuildRunner-dj0xkrep.js} +16 -9
- package/buildBatch.proc.js +7 -7
- package/{cloud.command-4kyxfw0y.js → cloud.command-3jzym8q7.js} +17 -16
- package/cloud.script-r4nskbc6.js +24 -0
- package/{code.command-sjvzt8fc.js → code.command-0ad6gw2a.js} +6 -6
- package/{context.command-j9frz0dz.js → context.command-0qx447mb.js} +17 -16
- package/context.runner-1vsjztjg.js +25 -0
- package/{dependencyScanner-06z2dmrr.js → dependencyScanner-3afj2vt1.js} +1 -1
- package/{guideline.command-1epw6hey.js → guideline.command-cv5bmrx2.js} +2 -2
- package/guidelines/conventions/conventions.instruction.md +450 -1084
- package/guidelines/cssRule/cssRule.instruction.md +16 -1
- package/guidelines/fieldRule/fieldRule.instruction.md +57 -0
- package/guidelines/framework/framework.instruction.md +4 -7
- package/guidelines/mcpRule/mcpRule.instruction.md +11 -8
- package/guidelines/modelConstant/modelConstant.instruction.md +2 -1
- package/guidelines/modelStore/modelStore.instruction.md +9 -0
- package/guidelines/pageRule/pageRule.instruction.md +80 -0
- package/guidelines/queryRule/queryRule.instruction.md +35 -8
- package/guidelines/runtimeRule/runtimeRule.instruction.md +89 -2
- package/guidelines/ssrRule/ssrRule.instruction.md +13 -0
- package/guidelines/transportRule/transportRule.instruction.md +76 -8
- package/guidelines/workspaceOnboarding/workspaceOnboarding.instruction.md +4 -4
- package/guidelines/workspaceRecipes/workspaceRecipes.instruction.md +49 -4
- package/incrementalBuilder.proc.js +4 -4
- package/{index-jw6st2rd.js → index-192ha4xh.js} +356 -307
- package/{index-1hkr7mrb.js → index-1p98exm2.js} +2 -2
- package/{index-8byzcvxp.js → index-1xj2t7cb.js} +7 -7
- package/{index-er3hekv9.js → index-20bxxyvn.js} +80 -80
- package/{index-xe3x2kw5.js → index-35hc95h5.js} +1 -1
- package/{index-p5nrc5he.js → index-4mhy6qme.js} +4 -4
- package/{index-0qc5nd61.js → index-5edzv8fn.js} +5 -5
- package/{index-k9rrten6.js → index-5nd1wtkv.js} +92 -94
- package/index-62md4dwy.js +260 -0
- package/{index-z3v7abrk.js → index-665zp9rs.js} +38 -15
- package/{index-1t2xw0p0.js → index-6xn2n442.js} +4 -4
- package/{index-jg3fj8h0.js → index-86jt2a0e.js} +1 -1
- package/{index-k33me5sp.js → index-8fp3b47h.js} +419 -418
- package/{index-shastb7m.js → index-9z426msb.js} +17 -12
- package/{index-gdybjw3x.js → index-awbdfcf2.js} +4 -4
- package/{index-3hx1z96c.js → index-bqbf654f.js} +1 -1
- package/{index-jppthsff.js → index-cpb3nvma.js} +57 -58
- package/{index-b60ccq2s.js → index-d47ypebv.js} +17 -15
- package/{index-gc05vqd2.js → index-d72hfmdm.js} +13 -13
- package/{index-akha197v.js → index-fmzcs8v6.js} +4 -4
- package/{index-28ftaz3d.js → index-fyq1z6kt.js} +29 -27
- package/{index-vwmv64ad.js → index-g1mbppa9.js} +238 -236
- package/{index-hedt951c.js → index-h47cf1gg.js} +7 -7
- package/{index-hfqs9jvc.js → index-j4mkhz93.js} +3 -3
- package/{index-08a5ga6n.js → index-jw1zm273.js} +28 -30
- package/{index-q958tqqg.js → index-m9jj544v.js} +1 -1
- package/{index-8935h3n1.js → index-mdjc93e1.js} +1 -1
- package/{index-2wyn17fa.js → index-pydbnfez.js} +2 -2
- package/{index-bjh4wbtk.js → index-qwa5k1j8.js} +1 -1
- package/{index-81a1ywp6.js → index-tamvyvj3.js} +3 -3
- package/{index-dez4t5sd.js → index-trpasv9q.js} +260 -259
- package/{index-2ahj896a.js → index-tvehn2sp.js} +1 -1
- package/{index-2k0t8p3p.js → index-va06nr10.js} +1086 -1075
- package/{index-9c3cd767.js → index-vk0pa0mn.js} +20 -21
- package/{index-qyaqzh8e.js → index-w44cy4vs.js} +2216 -2216
- package/index.js +22 -22
- package/{library.command-n58dgakb.js → library.command-erp2f56n.js} +3 -3
- package/{localRegistry.command-f2768sww.js → localRegistry.command-xxpqgxjw.js} +15 -14
- package/{module.command-xzjg5k7n.js → module.command-gs2r615e.js} +5 -5
- package/{package.command-24sh1j1q.js → package.command-7343f74r.js} +4 -4
- package/package.json +2 -2
- package/{page.command-fqnm88na.js → page.command-4h4a8pnh.js} +3 -3
- package/{pipeline.command-vn6taz75.js → pipeline.command-a2nrk26m.js} +3 -3
- package/{primitive.command-4j1g1a0d.js → primitive.command-w6t0asqz.js} +6 -6
- package/{projectTypecheck-3y7ayty0.js → projectTypecheck-f534enqj.js} +1 -1
- package/{quality.command-5hqmcdwt.js → quality.command-77x7vbbx.js} +4 -4
- package/{repair.command-rw5tk460.js → repair.command-y6sstev7.js} +5 -5
- package/{scalar.command-0jpap45m.js → scalar.command-20b8cy0k.js} +4 -4
- package/{subspace.command-y7n9sghk.js → subspace.command-92xkc0s0.js} +11 -10
- package/templates/lib/cnst.ts +0 -1
- package/templates/workspaceRoot/.gitignore.template +24 -53
- package/{tunnel.command-5gjwh1f8.js → tunnel.command-2kw8vt9g.js} +8 -7
- package/{workflow.command-3t22f7eb.js → workflow.command-2djwmpqf.js} +10 -10
- package/{workspace.command-cq5xg2jq.js → workspace.command-5se6spqb.js} +28 -27
- package/TunnelShare-p8ymkww8.js +0 -13
- package/cloud.script-jc3hc5d9.js +0 -23
- package/context.runner-v0def5my.js +0 -24
- package/index-n68jx79w.js +0 -120
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// pkgs/@akanjs/devkit/frontendBuild/cssBlockParser.ts
|
|
3
|
+
class CssBlockParser {
|
|
4
|
+
#css;
|
|
5
|
+
#stack = [{ kind: "block", prelude: "", atRule: null, nodes: [] }];
|
|
6
|
+
#pendingParts = [];
|
|
7
|
+
#segmentStart = 0;
|
|
8
|
+
#parenDepth = 0;
|
|
9
|
+
constructor(css) {
|
|
10
|
+
this.#css = css;
|
|
11
|
+
}
|
|
12
|
+
static parse(css) {
|
|
13
|
+
return new CssBlockParser(css).#run();
|
|
14
|
+
}
|
|
15
|
+
static walk(root, context, visit) {
|
|
16
|
+
const stack = [{ nodes: root.nodes, idx: 0, context }];
|
|
17
|
+
while (stack.length > 0) {
|
|
18
|
+
const frame = stack[stack.length - 1];
|
|
19
|
+
const node = frame.nodes[frame.idx];
|
|
20
|
+
if (!node) {
|
|
21
|
+
stack.pop();
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
frame.idx += 1;
|
|
25
|
+
const childContext = visit(node, frame.context);
|
|
26
|
+
if (node.kind === "block" && childContext !== null)
|
|
27
|
+
stack.push({ nodes: node.nodes, idx: 0, context: childContext });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
#run() {
|
|
31
|
+
const css = this.#css;
|
|
32
|
+
let idx = 0;
|
|
33
|
+
while (idx < css.length) {
|
|
34
|
+
const char = css[idx];
|
|
35
|
+
if (char === "/" && css[idx + 1] === "*") {
|
|
36
|
+
this.#pendingParts.push(css.slice(this.#segmentStart, idx));
|
|
37
|
+
const end = css.indexOf("*/", idx + 2);
|
|
38
|
+
idx = end === -1 ? css.length : end + 2;
|
|
39
|
+
this.#segmentStart = idx;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (char === "\\") {
|
|
43
|
+
idx += 2;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (char === '"' || char === "'") {
|
|
47
|
+
idx = this.#skipString(idx);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (char === "(")
|
|
51
|
+
this.#parenDepth += 1;
|
|
52
|
+
else if (char === ")")
|
|
53
|
+
this.#parenDepth = Math.max(0, this.#parenDepth - 1);
|
|
54
|
+
else if (char === "{")
|
|
55
|
+
this.#openBlock(idx);
|
|
56
|
+
else if (char === "}")
|
|
57
|
+
this.#closeBlock(idx);
|
|
58
|
+
else if (char === ";" && this.#parenDepth === 0)
|
|
59
|
+
this.#endStatement(idx);
|
|
60
|
+
idx += 1;
|
|
61
|
+
}
|
|
62
|
+
this.#endStatement(css.length);
|
|
63
|
+
return this.#stack[0];
|
|
64
|
+
}
|
|
65
|
+
get #current() {
|
|
66
|
+
return this.#stack[this.#stack.length - 1];
|
|
67
|
+
}
|
|
68
|
+
#skipString(start) {
|
|
69
|
+
const css = this.#css;
|
|
70
|
+
const quote = css[start];
|
|
71
|
+
let idx = start + 1;
|
|
72
|
+
while (idx < css.length) {
|
|
73
|
+
const char = css[idx];
|
|
74
|
+
if (char === "\\")
|
|
75
|
+
idx += 2;
|
|
76
|
+
else if (char === quote)
|
|
77
|
+
return idx + 1;
|
|
78
|
+
else if (char === `
|
|
79
|
+
`)
|
|
80
|
+
return idx;
|
|
81
|
+
else
|
|
82
|
+
idx += 1;
|
|
83
|
+
}
|
|
84
|
+
return css.length;
|
|
85
|
+
}
|
|
86
|
+
#takeSegment(end) {
|
|
87
|
+
const text = this.#pendingParts.join("") + this.#css.slice(this.#segmentStart, end);
|
|
88
|
+
this.#pendingParts = [];
|
|
89
|
+
this.#segmentStart = end + 1;
|
|
90
|
+
return text.trim();
|
|
91
|
+
}
|
|
92
|
+
#openBlock(idx) {
|
|
93
|
+
const prelude = this.#takeSegment(idx);
|
|
94
|
+
const block = { kind: "block", prelude, atRule: CssBlockParser.#atRuleOf(prelude), nodes: [] };
|
|
95
|
+
this.#current.nodes.push(block);
|
|
96
|
+
this.#stack.push(block);
|
|
97
|
+
this.#parenDepth = 0;
|
|
98
|
+
}
|
|
99
|
+
#closeBlock(idx) {
|
|
100
|
+
this.#endStatement(idx);
|
|
101
|
+
if (this.#stack.length > 1)
|
|
102
|
+
this.#stack.pop();
|
|
103
|
+
this.#parenDepth = 0;
|
|
104
|
+
}
|
|
105
|
+
#endStatement(idx) {
|
|
106
|
+
const text = this.#takeSegment(idx);
|
|
107
|
+
if (!text || text.startsWith("@"))
|
|
108
|
+
return;
|
|
109
|
+
const colon = text.indexOf(":");
|
|
110
|
+
if (colon <= 0)
|
|
111
|
+
return;
|
|
112
|
+
const property = text.slice(0, colon).trim();
|
|
113
|
+
if (!/^[\w-]+$/.test(property))
|
|
114
|
+
return;
|
|
115
|
+
this.#current.nodes.push({ kind: "declaration", property, value: text.slice(colon + 1).trim() });
|
|
116
|
+
}
|
|
117
|
+
static #atRuleOf(prelude) {
|
|
118
|
+
return prelude.match(/^@[\w-]+/)?.[0].toLowerCase() ?? null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// pkgs/@akanjs/devkit/frontendBuild/styleContract.ts
|
|
123
|
+
var countBlocking = (violations) => violations.theme.length;
|
|
124
|
+
var formatStyleContract = (violations) => violations.theme.flatMap((theme) => [
|
|
125
|
+
` [error] contrast ${theme.scope} ${theme.pair} = ${theme.ratio}:1 (min ${theme.threshold}:1)`,
|
|
126
|
+
` \u2192 ${theme.suggestion}`
|
|
127
|
+
]).join(`
|
|
128
|
+
`);
|
|
129
|
+
|
|
130
|
+
// pkgs/@akanjs/devkit/frontendBuild/themeValidator.ts
|
|
131
|
+
var PAIRS = [
|
|
132
|
+
{ base: "background", fg: "foreground", threshold: 4.5 },
|
|
133
|
+
{ base: "primary", fg: "primary-foreground", threshold: 4.5 },
|
|
134
|
+
{ base: "secondary", fg: "secondary-foreground", threshold: 4.5 },
|
|
135
|
+
{ base: "accent", fg: "accent-foreground", threshold: 4.5 },
|
|
136
|
+
{ base: "neutral", fg: "neutral-foreground", threshold: 4.5 },
|
|
137
|
+
{ base: "card", fg: "card-foreground", threshold: 4.5 },
|
|
138
|
+
{ base: "popover", fg: "popover-foreground", threshold: 4.5 },
|
|
139
|
+
{ base: "muted", fg: "muted-foreground", threshold: 3 },
|
|
140
|
+
{ base: "info", fg: "info-foreground", threshold: 3 },
|
|
141
|
+
{ base: "success", fg: "success-foreground", threshold: 3 },
|
|
142
|
+
{ base: "warning", fg: "warning-foreground", threshold: 3 },
|
|
143
|
+
{ base: "destructive", fg: "destructive-foreground", threshold: 3 },
|
|
144
|
+
{ base: "open", fg: "open-foreground", threshold: 3 }
|
|
145
|
+
];
|
|
146
|
+
var THEME_SCOPES = new Set([":root", '[data-theme="dark"]', '[data-theme="light"]']);
|
|
147
|
+
var CONDITIONAL_AT_RULES = new Set(["@media", "@supports", "@container"]);
|
|
148
|
+
|
|
149
|
+
class ThemeValidator {
|
|
150
|
+
validate(css) {
|
|
151
|
+
const tokensByScope = ThemeValidator.parseThemeTokens(css);
|
|
152
|
+
const violations = [];
|
|
153
|
+
for (const [scope, tokens] of Object.entries(tokensByScope)) {
|
|
154
|
+
const underlying = THEME_SCOPES.has(scope) ? null : [...THEME_SCOPES].find((name) => scope.endsWith(` ${name}`));
|
|
155
|
+
const effective = underlying ? ThemeValidator.#overlayPairs(tokensByScope[underlying] ?? {}, tokens) : tokens;
|
|
156
|
+
violations.push(...this.validateScope(effective, scope));
|
|
157
|
+
}
|
|
158
|
+
return violations;
|
|
159
|
+
}
|
|
160
|
+
validateScope(tokens, scope) {
|
|
161
|
+
const violations = [];
|
|
162
|
+
for (const { base, fg, threshold } of PAIRS) {
|
|
163
|
+
const bg = tokens[base];
|
|
164
|
+
const front = tokens[fg];
|
|
165
|
+
if (!bg || !front)
|
|
166
|
+
continue;
|
|
167
|
+
const bgRgb = ThemeValidator.parseHex(bg);
|
|
168
|
+
const fgRgb = ThemeValidator.parseHex(front);
|
|
169
|
+
if (!bgRgb || !fgRgb)
|
|
170
|
+
continue;
|
|
171
|
+
const ratio = ThemeValidator.contrastRatio(bgRgb, fgRgb);
|
|
172
|
+
if (ratio >= threshold)
|
|
173
|
+
continue;
|
|
174
|
+
violations.push({
|
|
175
|
+
scope,
|
|
176
|
+
pair: `${base} / ${fg}`,
|
|
177
|
+
background: bg,
|
|
178
|
+
foreground: front,
|
|
179
|
+
ratio: Math.round(ratio * 100) / 100,
|
|
180
|
+
threshold,
|
|
181
|
+
suggestion: `In ${scope}, --${base} (${bg}) against --${fg} (${front}) is ${ratio.toFixed(2)}:1, under the ${threshold}:1 minimum. Lighten or darken one of them until it clears.`
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return violations;
|
|
185
|
+
}
|
|
186
|
+
static parseThemeTokens(css) {
|
|
187
|
+
const result = {};
|
|
188
|
+
CssBlockParser.walk(CssBlockParser.parse(css), "", (node, condition) => {
|
|
189
|
+
if (node.kind !== "block")
|
|
190
|
+
return null;
|
|
191
|
+
if (node.atRule === "@layer")
|
|
192
|
+
return condition;
|
|
193
|
+
if (node.atRule)
|
|
194
|
+
return CONDITIONAL_AT_RULES.has(node.atRule) ? node.prelude.replace(/\s+/g, " ") : null;
|
|
195
|
+
const scopes = node.prelude.split(",").map((selector) => ThemeValidator.#normalizeScope(selector)).filter((scope) => THEME_SCOPES.has(scope));
|
|
196
|
+
if (scopes.length === 0)
|
|
197
|
+
return null;
|
|
198
|
+
const tokens = ThemeValidator.#customProperties(node);
|
|
199
|
+
for (const scope of scopes) {
|
|
200
|
+
const key = condition ? `${condition} ${scope}` : scope;
|
|
201
|
+
result[key] = Object.assign(result[key] ?? {}, tokens);
|
|
202
|
+
}
|
|
203
|
+
return null;
|
|
204
|
+
});
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
static #customProperties(block) {
|
|
208
|
+
const tokens = {};
|
|
209
|
+
for (const node of block.nodes) {
|
|
210
|
+
if (node.kind === "declaration" && node.property.startsWith("--"))
|
|
211
|
+
tokens[node.property.slice(2)] = node.value;
|
|
212
|
+
}
|
|
213
|
+
return tokens;
|
|
214
|
+
}
|
|
215
|
+
static #overlayPairs(underlying, tokens) {
|
|
216
|
+
const effective = {};
|
|
217
|
+
for (const name of PAIRS.flatMap(({ base, fg }) => [base, fg])) {
|
|
218
|
+
const value = tokens[name] ?? underlying[name];
|
|
219
|
+
if (value)
|
|
220
|
+
effective[name] = value;
|
|
221
|
+
}
|
|
222
|
+
return effective;
|
|
223
|
+
}
|
|
224
|
+
static #normalizeScope(selector) {
|
|
225
|
+
return selector.replace(/\[data-theme=['"]?([\w-]+)['"]?\]/g, '[data-theme="$1"]').trim();
|
|
226
|
+
}
|
|
227
|
+
static parseHex(value) {
|
|
228
|
+
const v = value.trim();
|
|
229
|
+
if (!v.startsWith("#"))
|
|
230
|
+
return null;
|
|
231
|
+
const hex = v.slice(1);
|
|
232
|
+
let full;
|
|
233
|
+
if (hex.length === 3 || hex.length === 4)
|
|
234
|
+
full = hex.slice(0, 3).split("").map((c) => c + c).join("");
|
|
235
|
+
else if (hex.length === 6 || hex.length === 8)
|
|
236
|
+
full = hex.slice(0, 6);
|
|
237
|
+
else
|
|
238
|
+
return null;
|
|
239
|
+
if (!/^[0-9a-fA-F]{6}$/.test(full))
|
|
240
|
+
return null;
|
|
241
|
+
const n = Number.parseInt(full, 16);
|
|
242
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
243
|
+
}
|
|
244
|
+
static #relativeLuminance([r, g, b]) {
|
|
245
|
+
const channel = (c) => {
|
|
246
|
+
const s = c / 255;
|
|
247
|
+
return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
|
|
248
|
+
};
|
|
249
|
+
return 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b);
|
|
250
|
+
}
|
|
251
|
+
static contrastRatio(a, b) {
|
|
252
|
+
const la = ThemeValidator.#relativeLuminance(a);
|
|
253
|
+
const lb = ThemeValidator.#relativeLuminance(b);
|
|
254
|
+
const hi = Math.max(la, lb);
|
|
255
|
+
const lo = Math.min(la, lb);
|
|
256
|
+
return (hi + 0.05) / (lo + 0.05);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export { countBlocking, formatStyleContract, CssBlockParser, ThemeValidator };
|
|
@@ -1,17 +1,40 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
resolveSsrPageEntriesForApp
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-va06nr10.js";
|
|
5
5
|
import {
|
|
6
6
|
bundleDefine,
|
|
7
7
|
CsrEntryFiles,
|
|
8
8
|
PagesEntrySourceGenerator,
|
|
9
9
|
PagesBundleBuilder
|
|
10
|
-
} from "./index-
|
|
10
|
+
} from "./index-192ha4xh.js";
|
|
11
11
|
|
|
12
12
|
// pkgs/@akanjs/devkit/frontendBuild/csrArtifactBuilder.ts
|
|
13
13
|
import { mkdir, rm, unlink } from "fs/promises";
|
|
14
|
+
import path2 from "path";
|
|
15
|
+
|
|
16
|
+
// pkgs/@akanjs/devkit/transforms/browserDirnamePlugin.ts
|
|
14
17
|
import path from "path";
|
|
18
|
+
var vendorScript = /[\\/]node_modules[\\/].+\.[cm]?js$/;
|
|
19
|
+
var createBrowserDirnamePlugin = () => ({
|
|
20
|
+
name: "akan-browser-dirname",
|
|
21
|
+
setup(build) {
|
|
22
|
+
build.onLoad({ filter: vendorScript }, async (args) => {
|
|
23
|
+
const source = await Bun.file(args.path).text();
|
|
24
|
+
if (!source.includes("__dirname") && !source.includes("__filename"))
|
|
25
|
+
return;
|
|
26
|
+
const posixPath = args.path.replaceAll("\\", "/");
|
|
27
|
+
const filename = posixPath.slice(posixPath.indexOf("/node_modules/"));
|
|
28
|
+
const define = { __dirname: JSON.stringify(path.posix.dirname(filename)), __filename: JSON.stringify(filename) };
|
|
29
|
+
return {
|
|
30
|
+
loader: "js",
|
|
31
|
+
contents: new Bun.Transpiler({ loader: "js", target: "browser", define }).transformSync(source)
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// pkgs/@akanjs/devkit/frontendBuild/csrArtifactBuilder.ts
|
|
15
38
|
class CsrArtifactBuilder {
|
|
16
39
|
#app;
|
|
17
40
|
#command;
|
|
@@ -67,11 +90,11 @@ ${logs}` : ""}`);
|
|
|
67
90
|
minify: true,
|
|
68
91
|
define: bundleDefine(app, command, "csr"),
|
|
69
92
|
optimizeImports,
|
|
70
|
-
plugins: [PagesBundleBuilder.createCssStubPlugin()]
|
|
93
|
+
plugins: [PagesBundleBuilder.createCssStubPlugin(), createBrowserDirnamePlugin()]
|
|
71
94
|
};
|
|
72
95
|
}
|
|
73
96
|
static publicEnvPath(app) {
|
|
74
|
-
return
|
|
97
|
+
return path2.join(app.dist.cwdPath, ".akan", "artifact", "csr-public-env.json");
|
|
75
98
|
}
|
|
76
99
|
static async writePublicEnv(app, define) {
|
|
77
100
|
const prefix = "process.env.";
|
|
@@ -89,20 +112,20 @@ ${logs}` : ""}`);
|
|
|
89
112
|
return CsrEntryFiles.entryFilename(basePath);
|
|
90
113
|
}
|
|
91
114
|
static basePathOfHtml(htmlPath) {
|
|
92
|
-
const name =
|
|
115
|
+
const name = path2.basename(htmlPath, ".html");
|
|
93
116
|
return name === "index" ? "" : name;
|
|
94
117
|
}
|
|
95
118
|
get #outputDir() {
|
|
96
|
-
return
|
|
119
|
+
return path2.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, this.#command === "build" ? "csr" : ".akan/artifact/csr");
|
|
97
120
|
}
|
|
98
121
|
get #generatedDir() {
|
|
99
|
-
return
|
|
122
|
+
return path2.join(this.#app.cwdPath, ".akan/generated/csr");
|
|
100
123
|
}
|
|
101
124
|
get #artifactDir() {
|
|
102
|
-
return
|
|
125
|
+
return path2.join(this.#command === "build" ? this.#app.dist.cwdPath : this.#app.cwdPath, ".akan/artifact");
|
|
103
126
|
}
|
|
104
127
|
#generatedPath(filename) {
|
|
105
|
-
return
|
|
128
|
+
return path2.join(this.#generatedDir, filename);
|
|
106
129
|
}
|
|
107
130
|
async#createEntryFile(basePath, pageEntries) {
|
|
108
131
|
return [
|
|
@@ -135,7 +158,7 @@ void bootCsr(pages);
|
|
|
135
158
|
async#loadCssAssets() {
|
|
136
159
|
if (this.#cssAssets)
|
|
137
160
|
return this.#cssAssets;
|
|
138
|
-
const artifactFile = Bun.file(
|
|
161
|
+
const artifactFile = Bun.file(path2.join(this.#artifactDir, "base-artifact.json"));
|
|
139
162
|
if (!await artifactFile.exists())
|
|
140
163
|
return {};
|
|
141
164
|
const artifact = await artifactFile.json();
|
|
@@ -150,7 +173,7 @@ void bootCsr(pages);
|
|
|
150
173
|
const basePath = CsrArtifactBuilder.basePathOfHtml(htmlPath);
|
|
151
174
|
const cssAsset = cssAssets[basePath];
|
|
152
175
|
if (!cssAsset) {
|
|
153
|
-
this.#app.logger.warn(`[csr-build] base-artifact.json has no compiled stylesheet for ${basePath || "root"}; ${
|
|
176
|
+
this.#app.logger.warn(`[csr-build] base-artifact.json has no compiled stylesheet for ${basePath || "root"}; ${path2.basename(htmlPath)} ships without CSS`);
|
|
154
177
|
}
|
|
155
178
|
const inlined = await this.#inlineHtmlAssets(await htmlFile.text(), htmlPath, cssAsset);
|
|
156
179
|
for (const filePath of inlined.jsFiles)
|
|
@@ -171,7 +194,7 @@ ${remainingAssets.join(`
|
|
|
171
194
|
async#inlineHtmlAssets(html, htmlPath, cssAsset) {
|
|
172
195
|
let next = html;
|
|
173
196
|
if (cssAsset) {
|
|
174
|
-
const css = await Bun.file(
|
|
197
|
+
const css = await Bun.file(path2.join(this.#artifactDir, cssAsset.cssRelPath)).text();
|
|
175
198
|
next = CsrArtifactBuilder.injectBeforeHeadEnd(next, CsrArtifactBuilder.createInlineStyle(css));
|
|
176
199
|
}
|
|
177
200
|
const jsFiles = [];
|
|
@@ -189,7 +212,7 @@ ${remainingAssets.join(`
|
|
|
189
212
|
if (predicate(filePath))
|
|
190
213
|
files.push(filePath);
|
|
191
214
|
}
|
|
192
|
-
return files.sort();
|
|
215
|
+
return files.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
193
216
|
}
|
|
194
217
|
static injectBeforeHeadEnd(html, snippet) {
|
|
195
218
|
const scannable = CsrArtifactBuilder.blankEmbeddedContent(html);
|
|
@@ -205,7 +228,7 @@ ${html.slice(bodyStart)}`;
|
|
|
205
228
|
${snippet}`;
|
|
206
229
|
}
|
|
207
230
|
static blankEmbeddedContent(html) {
|
|
208
|
-
return html.replace(/<script\b[^>]*>[\s\S]
|
|
231
|
+
return html.replace(/<script\b[^>]*>[\s\S]*?(?:<\/script(?:[\s/][^<>]*)?>|$)|<style\b[^>]*>[\s\S]*?(?:<\/style(?:[\s/][^<>]*)?>|$)|<!--[\s\S]*?(?:--!?>|$)/gi, (match) => " ".repeat(match.length));
|
|
209
232
|
}
|
|
210
233
|
static createInlineStyle(css) {
|
|
211
234
|
return `<style data-akan-css="active">
|
|
@@ -241,7 +264,7 @@ ${CsrArtifactBuilder.escapeInlineScript(await loadScript(src))}
|
|
|
241
264
|
throw new Error(`[csr-build] cannot inline external script: ${src}`);
|
|
242
265
|
}
|
|
243
266
|
const normalized = src.startsWith("/") ? src.slice(1) : src;
|
|
244
|
-
return
|
|
267
|
+
return path2.resolve(path2.dirname(htmlPath), normalized);
|
|
245
268
|
}
|
|
246
269
|
}
|
|
247
270
|
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
import {
|
|
3
3
|
runner,
|
|
4
4
|
script
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-jw1zm273.js";
|
|
6
6
|
import {
|
|
7
7
|
FileSys2
|
|
8
8
|
} from "./index-52w0fvh8.js";
|
|
9
9
|
import {
|
|
10
10
|
PkgExecutor
|
|
11
|
-
} from "./index-
|
|
11
|
+
} from "./index-va06nr10.js";
|
|
12
12
|
import {
|
|
13
13
|
TypeScriptDependencyScanner2
|
|
14
|
-
} from "./index-
|
|
14
|
+
} from "./index-tvehn2sp.js";
|
|
15
15
|
|
|
16
16
|
// pkgs/@akanjs/cli/package/package.runner.ts
|
|
17
17
|
import path2 from "path";
|
|
@@ -273,7 +273,7 @@ class PackageRunner extends runner("package") {
|
|
|
273
273
|
if (!failures.length)
|
|
274
274
|
return;
|
|
275
275
|
throw new Error(`[package] ${pkg.name} dist imports ${failures.length} subpath(s) no consumer can resolve:
|
|
276
|
-
` + `${failures.sort().join(`
|
|
276
|
+
` + `${failures.sort((a, b) => a < b ? -1 : a > b ? 1 : 0).join(`
|
|
277
277
|
`)}
|
|
278
278
|
` + `Add the missing "exports" entries: a bare file facet needs "./*": "./*.ts", a directory facet ` + `needs its own "./name": "./name/index.ts", and "./*.ts": "./*.ts" keeps an already-suffixed ` + `specifier from gaining a second extension.`);
|
|
279
279
|
}
|