@kurot/cli 3.7.0 → 3.8.1
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/CHANGELOG.md +87 -1
- package/README.md +23 -11
- package/dist/core/config-watcher.d.ts +8 -0
- package/dist/core/config-watcher.d.ts.map +1 -0
- package/dist/core/config-watcher.js +63 -0
- package/dist/core/config-watcher.js.map +1 -0
- package/dist/core/config.d.ts +9 -3
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +23 -6
- package/dist/core/config.js.map +1 -1
- package/dist/core/dev-server.d.ts.map +1 -1
- package/dist/core/dev-server.js +2 -0
- package/dist/core/dev-server.js.map +1 -1
- package/dist/core/diagnostics/codes.d.ts +2 -0
- package/dist/core/diagnostics/codes.d.ts.map +1 -1
- package/dist/core/diagnostics/codes.js +2 -0
- package/dist/core/diagnostics/codes.js.map +1 -1
- package/dist/core/diagnostics/output.d.ts +1 -1
- package/dist/core/diagnostics/output.d.ts.map +1 -1
- package/dist/core/plugins/generate-html.d.ts +7 -1
- package/dist/core/plugins/generate-html.d.ts.map +1 -1
- package/dist/core/plugins/generate-html.js +20 -4
- package/dist/core/plugins/generate-html.js.map +1 -1
- package/dist/core/plugins/index.d.ts +1 -1
- package/dist/core/plugins/index.d.ts.map +1 -1
- package/dist/core/plugins/index.js +3 -3
- package/dist/core/plugins/index.js.map +1 -1
- package/dist/core/plugins/resource-version-css.d.ts +7 -0
- package/dist/core/plugins/resource-version-css.d.ts.map +1 -0
- package/dist/core/plugins/resource-version-css.js +41 -0
- package/dist/core/plugins/resource-version-css.js.map +1 -0
- package/dist/core/plugins/resource-version-html.d.ts +7 -0
- package/dist/core/plugins/resource-version-html.d.ts.map +1 -0
- package/dist/core/plugins/resource-version-html.js +66 -0
- package/dist/core/plugins/resource-version-html.js.map +1 -0
- package/dist/core/plugins/version-resources.d.ts +7 -0
- package/dist/core/plugins/version-resources.d.ts.map +1 -0
- package/dist/core/plugins/version-resources.js +89 -0
- package/dist/core/plugins/version-resources.js.map +1 -0
- package/docs/ai-context.md +15 -7
- package/docs/architecture.md +12 -7
- package/docs/default-ui-skins.md +4 -5
- package/docs/dev-resource-watching.md +23 -3
- package/docs/game-template.md +17 -0
- package/docs/release-assets.md +64 -55
- package/package.json +3 -2
- package/templates/empty/README.md +13 -1
- package/templates/empty/kurot.config.ts +1 -1
- package/templates/empty/src/Main.ts +5 -7
- package/templates/game/README.md +13 -1
- package/templates/game/kurot.config.ts +1 -1
- package/templates/game/src/Main.ts +3 -9
- package/templates/game/src/StyleManager.ts +3 -2
- package/dist/core/plugins/version-assets.d.ts +0 -7
- package/dist/core/plugins/version-assets.d.ts.map +0 -1
- package/dist/core/plugins/version-assets.js +0 -108
- package/dist/core/plugins/version-assets.js.map +0 -1
|
@@ -7,7 +7,7 @@ import { compileSource } from './compile-source.js';
|
|
|
7
7
|
import { generateHtml } from './generate-html.js';
|
|
8
8
|
import { writeManifest } from './manifest.js';
|
|
9
9
|
import { copyAssets } from './copy-assets.js';
|
|
10
|
-
import {
|
|
10
|
+
import { versionResources } from './version-resources.js';
|
|
11
11
|
export { cleanOutput } from './clean-output.js';
|
|
12
12
|
export { compileKUI } from './compile-kui.js';
|
|
13
13
|
export { compileEngine } from './compile-engine.js';
|
|
@@ -17,7 +17,7 @@ export { compileSource } from './compile-source.js';
|
|
|
17
17
|
export { generateHtml } from './generate-html.js';
|
|
18
18
|
export { writeManifest } from './manifest.js';
|
|
19
19
|
export { copyAssets } from './copy-assets.js';
|
|
20
|
-
export {
|
|
20
|
+
export { versionResources } from './version-resources.js';
|
|
21
21
|
/**
|
|
22
22
|
* The standard build sequence.
|
|
23
23
|
*
|
|
@@ -39,7 +39,7 @@ export function defaultPlugins() {
|
|
|
39
39
|
generateHtml(),
|
|
40
40
|
writeManifest(),
|
|
41
41
|
copyAssets(),
|
|
42
|
-
|
|
42
|
+
versionResources(),
|
|
43
43
|
];
|
|
44
44
|
}
|
|
45
45
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/plugins/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/plugins/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc;IAC7B,OAAO;QACN,WAAW,EAAE;QACb,UAAU,EAAE;QACZ,aAAa,EAAE;QACf,uBAAuB,EAAE;QACzB,qBAAqB,EAAE;QACvB,aAAa,EAAE;QACf,YAAY,EAAE;QACd,aAAa,EAAE;QACf,UAAU,EAAE;QACZ,gBAAgB,EAAE;KAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type ResourceUrlVersioner = (source: string, baseFile: string) => string;
|
|
2
|
+
/**
|
|
3
|
+
* Version CSS url() and string @import references, preserving comments and
|
|
4
|
+
* ordinary strings. CSS escaping is decoded for lookup and retained on output.
|
|
5
|
+
*/
|
|
6
|
+
export declare function versionCssResources(css: string, file: string, versionUrl: ResourceUrlVersioner): string;
|
|
7
|
+
//# sourceMappingURL=resource-version-css.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-version-css.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/resource-version-css.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;AAEhF;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,oBAAoB,GAAG,MAAM,CAmCvG"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import valueParser from 'postcss-value-parser';
|
|
2
|
+
/**
|
|
3
|
+
* Version CSS url() and string @import references, preserving comments and
|
|
4
|
+
* ordinary strings. CSS escaping is decoded for lookup and retained on output.
|
|
5
|
+
*/
|
|
6
|
+
export function versionCssResources(css, file, versionUrl) {
|
|
7
|
+
const parsed = valueParser(css);
|
|
8
|
+
parsed.walk((node, index, nodes) => {
|
|
9
|
+
if (node.type === 'function' && node.value.toLowerCase() === 'url') {
|
|
10
|
+
const value = node.nodes.find(child => child.type !== 'space' && child.type !== 'comment');
|
|
11
|
+
if (value?.type === 'string' || value?.type === 'word') {
|
|
12
|
+
update(value);
|
|
13
|
+
}
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
if (node.type === 'word' && node.value.toLowerCase() === '@import') {
|
|
17
|
+
const next = nodes.slice(index + 1).find(child => child.type !== 'space' && child.type !== 'comment');
|
|
18
|
+
if (next?.type === 'string') {
|
|
19
|
+
update(next);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
return parsed.toString();
|
|
24
|
+
function update(node) {
|
|
25
|
+
const decoded = node.value.replace(/\\(?:([a-f0-9]{1,6})\s?|([\s\S]))/gi, (_match, hex, character) => {
|
|
26
|
+
if (hex) {
|
|
27
|
+
const point = Number.parseInt(hex, 16);
|
|
28
|
+
return point > 0 && point <= 0x10ffff ? String.fromCodePoint(point) : '\uFFFD';
|
|
29
|
+
}
|
|
30
|
+
return character && !/[\r\n\f]/.test(character) ? character : '';
|
|
31
|
+
});
|
|
32
|
+
const next = versionUrl(decoded, file);
|
|
33
|
+
if (next === decoded) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
node.value = node.type === 'word'
|
|
37
|
+
? next.replace(/[\\\s"'()]/g, character => '\\' + character)
|
|
38
|
+
: next.replace(/\\/g, '\\\\').split(node.quote).join('\\' + node.quote);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=resource-version-css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-version-css.js","sourceRoot":"","sources":["../../../src/core/plugins/resource-version-css.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,sBAAsB,CAAC;AAI/C;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW,EAAE,IAAY,EAAE,UAAgC;IAC9F,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAClC,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;YACpE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;YAC3F,IAAI,KAAK,EAAE,IAAI,KAAK,QAAQ,IAAI,KAAK,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;gBACxD,MAAM,CAAC,KAAK,CAAC,CAAC;YACf,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,SAAS,EAAE,CAAC;YACpE,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;YACtG,IAAI,IAAI,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC,CAAC;YACd,CAAC;QACF,CAAC;IACF,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC;IAEzB,SAAS,MAAM,CAAC,IAAmD;QAClE,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,qCAAqC,EAAE,CAAC,MAAc,EAAE,GAAuB,EAAE,SAA6B,EAAE,EAAE;YACpJ,IAAI,GAAG,EAAE,CAAC;gBACT,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBACvC,OAAO,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;YAChF,CAAC;YACD,OAAO,SAAS,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACvC,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACtB,OAAO;QACR,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM;YAChC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,GAAG,SAAS,CAAC;YAC5D,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1E,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ResourceUrlVersioner } from './resource-version-css.js';
|
|
2
|
+
/**
|
|
3
|
+
* Write build metadata and static resource versions without serializing scripts
|
|
4
|
+
* or moving files. Navigation destinations and generated JS URLs remain intact.
|
|
5
|
+
*/
|
|
6
|
+
export declare function versionHtmlResources(html: string, file: string, version: string, versionUrl: ResourceUrlVersioner): string;
|
|
7
|
+
//# sourceMappingURL=resource-version-html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-version-html.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/resource-version-html.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAQtE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,oBAAoB,GAAG,MAAM,CAsD1H"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { defaultTreeAdapter, parse } from 'parse5';
|
|
2
|
+
import { BuildError } from '../errors.js';
|
|
3
|
+
import { versionCssResources } from './resource-version-css.js';
|
|
4
|
+
/**
|
|
5
|
+
* Write build metadata and static resource versions without serializing scripts
|
|
6
|
+
* or moving files. Navigation destinations and generated JS URLs remain intact.
|
|
7
|
+
*/
|
|
8
|
+
export function versionHtmlResources(html, file, version, versionUrl) {
|
|
9
|
+
const document = parse(html, { sourceCodeLocationInfo: true });
|
|
10
|
+
const pending = [document];
|
|
11
|
+
const edits = [];
|
|
12
|
+
let headEnd;
|
|
13
|
+
while (pending.length > 0) {
|
|
14
|
+
const parent = pending.pop();
|
|
15
|
+
for (const element of parent.childNodes.filter(defaultTreeAdapter.isElementNode)) {
|
|
16
|
+
pending.push(element);
|
|
17
|
+
if (element.tagName === 'base') {
|
|
18
|
+
throw new BuildError('output.versionedAssets requires document-relative resources; remove the authored base element.');
|
|
19
|
+
}
|
|
20
|
+
if (element.tagName === 'head') {
|
|
21
|
+
headEnd = element.sourceCodeLocation?.startTag?.endOffset;
|
|
22
|
+
}
|
|
23
|
+
if (element.tagName === 'meta' && element.attrs.some(attr => attr.name === 'name' && attr.value === 'kurot-resource-version')) {
|
|
24
|
+
throw new BuildError('output.versionedAssets owns the kurot-resource-version metadata; remove the authored value.');
|
|
25
|
+
}
|
|
26
|
+
for (const attr of element.attrs) {
|
|
27
|
+
const attributeName = attr.prefix ? `${attr.prefix}:${attr.name}` : attr.name;
|
|
28
|
+
const location = element.sourceCodeLocation?.attrs?.[attributeName];
|
|
29
|
+
if (!location) {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const asset = attr.name === 'src' || attr.name === 'poster' ||
|
|
33
|
+
(attr.name === 'href' && ['link', 'image', 'use'].includes(element.tagName)) ||
|
|
34
|
+
(attr.name === 'data' && element.tagName === 'object');
|
|
35
|
+
const next = attr.name === 'style'
|
|
36
|
+
? versionCssResources(attr.value, file, versionUrl)
|
|
37
|
+
: asset ? versionUrl(attr.value, file) : attr.value;
|
|
38
|
+
if (next !== attr.value) {
|
|
39
|
+
edits.push({ start: location.startOffset, end: location.endOffset, text: `${attributeName}="${escapeAttribute(next)}"` });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (element.tagName === 'style') {
|
|
43
|
+
for (const text of element.childNodes.filter(defaultTreeAdapter.isTextNode)) {
|
|
44
|
+
const location = text.sourceCodeLocation;
|
|
45
|
+
const next = versionCssResources(text.value, file, versionUrl);
|
|
46
|
+
if (location && next !== text.value) {
|
|
47
|
+
edits.push({ start: location.startOffset, end: location.endOffset, text: next });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (headEnd === undefined) {
|
|
54
|
+
throw new BuildError('output.versionedAssets requires an explicit HTML head element.');
|
|
55
|
+
}
|
|
56
|
+
edits.push({ start: headEnd, end: headEnd, text: `\n\t<meta name="kurot-resource-version" content="${escapeAttribute(version)}">` });
|
|
57
|
+
let result = html;
|
|
58
|
+
for (const edit of edits.sort((left, right) => right.start - left.start)) {
|
|
59
|
+
result = result.slice(0, edit.start) + edit.text + result.slice(edit.end);
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
function escapeAttribute(value) {
|
|
64
|
+
return value.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<');
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=resource-version-html.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-version-html.js","sourceRoot":"","sources":["../../../src/core/plugins/resource-version-html.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BuildPlugin } from '../pipeline.js';
|
|
2
|
+
/**
|
|
3
|
+
* Stamp resource requests with the release build number. Generated JavaScript
|
|
4
|
+
* keeps its content-hashed names and original paths; no document base is changed.
|
|
5
|
+
*/
|
|
6
|
+
export declare function versionResources(): BuildPlugin;
|
|
7
|
+
//# sourceMappingURL=version-resources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-resources.d.ts","sourceRoot":"","sources":["../../../src/core/plugins/version-resources.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAKhE;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,CA2B9C"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { BuildError } from '../errors.js';
|
|
4
|
+
import { versionCssResources } from './resource-version-css.js';
|
|
5
|
+
import { versionHtmlResources } from './resource-version-html.js';
|
|
6
|
+
/**
|
|
7
|
+
* Stamp resource requests with the release build number. Generated JavaScript
|
|
8
|
+
* keeps its content-hashed names and original paths; no document base is changed.
|
|
9
|
+
*/
|
|
10
|
+
export function versionResources() {
|
|
11
|
+
return {
|
|
12
|
+
name: 'version release resources',
|
|
13
|
+
async apply(ctx) {
|
|
14
|
+
if (ctx.project.mode !== 'release' || !ctx.project.config.output.versionedAssets) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const files = await listFiles(ctx.project.outputDir);
|
|
18
|
+
const version = path.basename(ctx.project.outputDir);
|
|
19
|
+
const versionUrl = createVersioner(new Set(files), version);
|
|
20
|
+
const updates = [];
|
|
21
|
+
for (const file of files) {
|
|
22
|
+
if (!/\.(?:html|css)$/i.test(file)) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const source = await fs.readFile(path.join(ctx.project.outputDir, file), 'utf8');
|
|
26
|
+
const contents = /\.html$/i.test(file)
|
|
27
|
+
? versionHtmlResources(source, file, version, versionUrl)
|
|
28
|
+
: versionCssResources(source, file, versionUrl);
|
|
29
|
+
updates.push({ file, contents });
|
|
30
|
+
}
|
|
31
|
+
// Validate every page before replacing any generated HTML/CSS.
|
|
32
|
+
for (const update of updates) {
|
|
33
|
+
await fs.writeFile(path.join(ctx.project.outputDir, update.file), update.contents);
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function createVersioner(files, version) {
|
|
39
|
+
return (source, baseFile) => {
|
|
40
|
+
if (!source || source.startsWith('#')) {
|
|
41
|
+
return source;
|
|
42
|
+
}
|
|
43
|
+
let target;
|
|
44
|
+
try {
|
|
45
|
+
target = new URL(source, `https://kurot.invalid/${baseFile}`);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return source;
|
|
49
|
+
}
|
|
50
|
+
if (target.origin !== 'https://kurot.invalid') {
|
|
51
|
+
return source;
|
|
52
|
+
}
|
|
53
|
+
let file;
|
|
54
|
+
try {
|
|
55
|
+
file = decodeURIComponent(target.pathname).slice(1);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return source;
|
|
59
|
+
}
|
|
60
|
+
if (!files.has(file) || file.startsWith('js/') || /\.html?$/i.test(file)) {
|
|
61
|
+
return source;
|
|
62
|
+
}
|
|
63
|
+
const hash = source.indexOf('#');
|
|
64
|
+
const fragment = hash < 0 ? '' : source.slice(hash);
|
|
65
|
+
const reference = hash < 0 ? source : source.slice(0, hash);
|
|
66
|
+
const query = reference.indexOf('?');
|
|
67
|
+
const pathname = query < 0 ? reference : reference.slice(0, query);
|
|
68
|
+
const parameters = new URLSearchParams(query < 0 ? '' : reference.slice(query + 1));
|
|
69
|
+
parameters.set('v', version);
|
|
70
|
+
return `${pathname}?${parameters}${fragment}`;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
async function listFiles(root, directory = '') {
|
|
74
|
+
const files = [];
|
|
75
|
+
for (const entry of await fs.readdir(path.join(root, directory), { withFileTypes: true })) {
|
|
76
|
+
const relative = path.posix.join(directory, entry.name);
|
|
77
|
+
if (entry.isDirectory()) {
|
|
78
|
+
files.push(...await listFiles(root, relative));
|
|
79
|
+
}
|
|
80
|
+
else if (entry.isFile()) {
|
|
81
|
+
files.push(relative);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
throw new BuildError(`Versioned resources require regular output files: ${relative}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return files;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=version-resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-resources.js","sourceRoot":"","sources":["../../../src/core/plugins/version-resources.ts"],"names":[],"mappings":"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"}
|
package/docs/ai-context.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @kurot/cli — AI context map
|
|
2
2
|
|
|
3
|
-
`@kurot/cli@3.
|
|
3
|
+
`@kurot/cli@3.8.1` (prepared for publication) is build-time tooling on Node.js >= 20, with ordinary
|
|
4
4
|
ui-document dependency **^0.13.0**. Projects supply their own Core/UI runtime.
|
|
5
5
|
Read [architecture](architecture.md) for the plugin pipeline; the source and
|
|
6
6
|
configuration exports establish current behavior.
|
|
@@ -150,12 +150,20 @@ manual prefix cannot conflict with `ui.components.namespace`.
|
|
|
150
150
|
Do not reorder namespace or source compilation without reviewing externalization
|
|
151
151
|
in `namespace-external-plugin.ts`.
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
153
|
+
CLI >= 3.8.1 within 3.x with Core >= 2.7.0 within 2.x supports resource
|
|
154
|
+
queries. `version-resources.ts` runs last and
|
|
155
|
+
stamps each HTML page with the release directory's timestamp. HTML/CSS local
|
|
156
|
+
assets receive a `v` query; Core transports version local resource/ requests.
|
|
157
|
+
Generated JS, import maps, manifest paths and output directories stay unchanged.
|
|
158
|
+
`resource-version-html.ts` preserves script bytes and owns metadata validation;
|
|
159
|
+
`resource-version-css.ts` owns CSS URL parsing. Native fetch/FontFace/Theme calls
|
|
160
|
+
use Core's resolveResourceUrl; new starters enable the flag explicitly. See
|
|
161
|
+
[release resources](release-assets.md) for the protocol and deployment limits.
|
|
162
|
+
|
|
163
|
+
Since CLI 3.8.0, root ESM config stage changes regenerate HTML in `kurot dev` without
|
|
164
|
+
restarting dev; `core/config-watcher.ts` owns this path. See
|
|
165
|
+
[development watching](dev-resource-watching.md). Core canvas-attribute startup
|
|
166
|
+
requires Core >= 2.6.0 within 2.x; explicit overrides remain supported.
|
|
159
167
|
|
|
160
168
|
## Configuration lookup
|
|
161
169
|
|
package/docs/architecture.md
CHANGED
|
@@ -40,7 +40,7 @@ factory variables, property assignments, semantic layout children, and state
|
|
|
40
40
|
property overrides. Document contracts, reusable instances, data bindings, and
|
|
41
41
|
actions remain `UIDocument` concepts.
|
|
42
42
|
|
|
43
|
-
CLI 3.
|
|
43
|
+
CLI 3.8.1 consumes ui-document ^0.13.0, retaining Label text-fitting metadata. The
|
|
44
44
|
compiler emits `textFit`, `minFontSize`, base font sizes and state overrides;
|
|
45
45
|
native UI owns measurement and derives drawing sizes after layout validation.
|
|
46
46
|
See [Label compilation](label-text-layout.md). The application supplies UI
|
|
@@ -72,12 +72,13 @@ Development builds preserve application source module structure under
|
|
|
72
72
|
`manifest.json`. Static resources retain stable paths because application code
|
|
73
73
|
addresses them by key or URL.
|
|
74
74
|
|
|
75
|
-
With
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
With CLI >= 3.8.1 within 3.x and Core >= 2.7.0 within 2.x,
|
|
76
|
+
`output.versionedAssets: true` writes the release directory timestamp to HTML
|
|
77
|
+
metadata and appends it as `v` to static HTML/CSS assets. Core transports use that
|
|
78
|
+
metadata for local resource/ files, including secondary atlas/font pages. Native
|
|
79
|
+
fetch/FontFace/Theme callers use Core's resolveResourceUrl. Generated JS hashes,
|
|
80
|
+
manifest paths and BuildContext outputs remain unchanged. No files move and no
|
|
81
|
+
HTML base is inserted. See [release resources](release-assets.md).
|
|
81
82
|
|
|
82
83
|
Asset copying creates directories only when an accepted runtime file needs them.
|
|
83
84
|
KUI source files and source theme JSON are excluded when UI compilation is enabled,
|
|
@@ -97,6 +98,10 @@ and reconciles additions, deletions and directory replacement. Runtime-only
|
|
|
97
98
|
changes do not recompile skins. The fixed style.json and default.res.json paths
|
|
98
99
|
still trigger KUI compilation; font loading remains an application responsibility.
|
|
99
100
|
Changes are debounced and queued, with changed bytes staged before publication.
|
|
101
|
+
A shallow root configuration watcher re-evaluates ESM config after stage edits
|
|
102
|
+
and publishes complete HTML through an atomic rename. Invalid values retain the
|
|
103
|
+
last successful page; structural build changes require restarting dev. This path
|
|
104
|
+
shares the resource build queue and does not mutate the immutable Project.
|
|
100
105
|
Browser refresh remains manual and HTTP responses use no-store. Individual
|
|
101
106
|
renames do not form an atomic multi-file transaction. See
|
|
102
107
|
[resource watching](dev-resource-watching.md).
|
package/docs/default-ui-skins.md
CHANGED
|
@@ -81,19 +81,18 @@ and wrap the node with Group/Image/Scroller for its surface and viewport.
|
|
|
81
81
|
`src/DefaultUI.ts` only connects data and events. The example installs its own
|
|
82
82
|
project font loader and document dependency; other projects are unchanged.
|
|
83
83
|
|
|
84
|
-
Use the
|
|
84
|
+
Use the example's installed registry CLI and SDKs. From the repository root:
|
|
85
85
|
|
|
86
86
|
```sh
|
|
87
|
-
pnpm --dir
|
|
88
|
-
|
|
89
|
-
node ../../packages/cli/dist/index.js dev
|
|
87
|
+
pnpm --dir examples/game install --frozen-lockfile
|
|
88
|
+
pnpm --dir examples/game dev
|
|
90
89
|
```
|
|
91
90
|
|
|
92
91
|
Open the server URL with `?ui=1`; the ordinary scene remains available without
|
|
93
92
|
that parameter. Try the inputs, switches, ComboBox, tabs, sliders, panel close
|
|
94
93
|
button and draggable List. The gallery uses the example's installed Core/UI
|
|
95
94
|
with compiled KUI XML, without modifying dependencies or locks. In that example
|
|
96
|
-
directory,
|
|
95
|
+
directory, `pnpm build --strict` and `pnpm release --strict` run one-shot builds.
|
|
97
96
|
The private asset tool's isolated source preview remains an optional maintenance
|
|
98
97
|
tool for testing checkout engine changes; it is not required by the installed Core.
|
|
99
98
|
|
|
@@ -17,9 +17,26 @@ translations and other project-owned files.
|
|
|
17
17
|
| PNG, fonts, language properties and other runtime files | Synchronize assets |
|
|
18
18
|
| Resource directory creation, replacement or deletion | Reconnect watcher and reconcile output; compile KUI when enabled |
|
|
19
19
|
| Reusable component source or skin | Retain component discovery/namespace/catalog rebuild and synchronize assets |
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
| Root kurot.config.ts or .js stage defaults | Validate and atomically regenerate HTML; refresh manually |
|
|
21
|
+
|
|
22
|
+
With CLI >= 3.8.0 within 3.x, stage defaults in `kurot.config.ts` / `.js` can be
|
|
23
|
+
saved without restarting `kurot dev`. `kurot build --watch` retains its existing
|
|
24
|
+
source-watch behavior and does not install the configuration watcher.
|
|
25
|
+
After the successful configuration update, refresh the browser manually. The
|
|
26
|
+
new Player consumes HTML canvas attributes with the Core behavior described in
|
|
27
|
+
[stage configuration](../../core/docs/stage-configuration.md), requiring Core
|
|
28
|
+
>= 2.6.0 within 2.x; explicit runtime options still take priority.
|
|
29
|
+
|
|
30
|
+
The watcher handles ordinary and atomic editor saves of the root ESM config file,
|
|
31
|
+
re-evaluates it with a fresh module URL, validates width/height, scale mode,
|
|
32
|
+
orientation and frame rate, and atomically replaces only the generated HTML.
|
|
33
|
+
Invalid edits keep the last successful page, report an error and allow correction
|
|
34
|
+
without restarting. Imported configuration helpers and dependencies are not
|
|
35
|
+
reloaded; edits to them still require restarting dev.
|
|
36
|
+
|
|
37
|
+
Changes outside `stage`, including entry/output/UI paths, or dependencies still
|
|
38
|
+
require restarting dev. A detected structural config change reports
|
|
39
|
+
`KUROT_CONFIG_RESTART_REQUIRED` and leaves the active outputs intact. Locale configuration is consumed by project code; the CLI does
|
|
23
40
|
not introduce a locale parser or mutate authored skins. A style edit may change
|
|
24
41
|
compiled skin assignments while its XML remains untouched.
|
|
25
42
|
|
|
@@ -52,6 +69,9 @@ A resource-only batch emits JSONL build-start with reason `resource-change`,
|
|
|
52
69
|
followed by build-complete after synchronization. Existing `kui-change` and
|
|
53
70
|
`source-change` reasons retain their meaning. Consumers should tolerate the
|
|
54
71
|
additional reason and refresh only after a successful build-complete event.
|
|
72
|
+
Root configuration updates emit `config-change`; failures additionally emit
|
|
73
|
+
`KUROT_CONFIG_RELOAD_FAILED` or `KUROT_CONFIG_RESTART_REQUIRED` diagnostics.
|
|
74
|
+
The stage watcher shares this serialized queue with resource/component work.
|
|
55
75
|
|
|
56
76
|
## Preview and atlas boundaries
|
|
57
77
|
|
package/docs/game-template.md
CHANGED
|
@@ -31,6 +31,23 @@ This ordering includes loading-screen Labels in the project font. The loading
|
|
|
31
31
|
screen's startup messages stay in English because translations are not loaded yet.
|
|
32
32
|
Templates do not implement live font/theme/language replacement.
|
|
33
33
|
|
|
34
|
+
## Stage defaults
|
|
35
|
+
|
|
36
|
+
Both starters use `createPlayer({ canvas })`. Configure width, height, scale mode,
|
|
37
|
+
orientation and frame rate in `kurot.config.ts`; the CLI writes canvas attributes.
|
|
38
|
+
This requires Core >= 2.6.0 within 2.x, documented in
|
|
39
|
+
[stage configuration](../../core/docs/stage-configuration.md). Explicit options
|
|
40
|
+
remain available for intentional overrides. In dev, save stage settings, wait
|
|
41
|
+
for the configuration update and refresh the browser with CLI >= 3.8.0 within
|
|
42
|
+
3.x; no dev restart is needed.
|
|
43
|
+
|
|
44
|
+
## Release resources
|
|
45
|
+
|
|
46
|
+
Both starters enable output.versionedAssets. Resource queries use the release
|
|
47
|
+
build number with Core >= 2.7.0 within 2.x and CLI >= 3.8.1 within 3.x. The game
|
|
48
|
+
starter resolves native style/font and Theme requests through resolveResourceUrl
|
|
49
|
+
before Player creation. See [release resources](release-assets.md).
|
|
50
|
+
|
|
34
51
|
## HTML brand splash
|
|
35
52
|
|
|
36
53
|
The game template's `web/index.html` presents `web/logo.png` beneath a small
|
package/docs/release-assets.md
CHANGED
|
@@ -1,76 +1,85 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Release resource versions
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The query-based protocol requires **CLI >= 3.8.1 within 3.x and Core >= 2.7.0
|
|
4
|
+
within 2.x**. These source versions are prepared for publication. It replaces
|
|
5
|
+
the earlier whole-build directory packaging.
|
|
6
|
+
|
|
7
|
+
Enable it in `kurot.config.ts`:
|
|
4
8
|
|
|
5
9
|
```ts
|
|
6
10
|
export default {
|
|
7
|
-
|
|
8
|
-
|
|
11
|
+
output: { dir: 'bin-debug', versionedAssets: true },
|
|
12
|
+
// Keep the project's other settings.
|
|
9
13
|
};
|
|
10
14
|
```
|
|
11
15
|
|
|
12
|
-
The
|
|
13
|
-
|
|
14
|
-
An index query string does not propagate to requests for resources.
|
|
16
|
+
The configuration field defaults to false for existing configurations. New game
|
|
17
|
+
and empty starters explicitly enable it. Development/watch builds are unchanged.
|
|
15
18
|
|
|
16
|
-
## Output and
|
|
19
|
+
## Output and build number
|
|
17
20
|
|
|
18
21
|
```text
|
|
19
|
-
bin-release/web
|
|
22
|
+
bin-release/web/261030123456/
|
|
20
23
|
├── index.html
|
|
21
24
|
├── manifest.json
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
└── <files copied beside the HTML template>
|
|
25
|
+
├── js/main.min_<content-hash>.js
|
|
26
|
+
├── resource/
|
|
27
|
+
└── <files copied beside the HTML template>
|
|
26
28
|
```
|
|
27
29
|
|
|
28
|
-
The
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
reserializing the template. Quoted attributes and script/style text are preserved.
|
|
44
|
-
The build rejects symbolic links and other nonregular output files. Relative URLs
|
|
45
|
-
must refer to files inside the build; root-relative URLs, remote URLs, and URLs
|
|
46
|
-
explicitly based on location.href remain outside this mechanism. Applications
|
|
47
|
-
that construct URLs should use document.baseURI for build assets. Relative links
|
|
48
|
-
and forms also inherit the base; use explicit destinations for application navigation.
|
|
49
|
-
If hosting has a CSP base-uri directive, it must allow this same-origin base.
|
|
50
|
-
|
|
51
|
-
## Theme loading with existing UI
|
|
52
|
-
|
|
53
|
-
UI runtimes that resolve a relative Theme config against location.href need an
|
|
54
|
-
absolute config URL. The game starter uses:
|
|
30
|
+
The existing release directory timestamp (`YYMMDDHHmmss`) is the resource build
|
|
31
|
+
number. The CLI inserts `<meta name="kurot-resource-version" content="261030123456">`
|
|
32
|
+
into each generated HTML page. It creates no asset hash directory or HTML base.
|
|
33
|
+
The release manifest, import map, generated JS filenames, source maps and JS
|
|
34
|
+
imports retain their original paths. Identical JS can retain its filename hash
|
|
35
|
+
across releases even when the resource build number changes.
|
|
36
|
+
|
|
37
|
+
Core reads the metadata before Player creation. Its GET HttpRequest, ImageLoader,
|
|
38
|
+
Sound, Video and sound-resource transports append `v` to same-origin files below
|
|
39
|
+
the page's `resource/` directory. Resource manifests, atlas and bitmap-font pages,
|
|
40
|
+
and adapters using these transports receive the same version. Authored resource
|
|
41
|
+
keys and descriptors remain unchanged. Existing query fields/fragments survive;
|
|
42
|
+
an existing `v` is replaced once.
|
|
43
|
+
|
|
44
|
+
Native browser callers must opt in through the public Core helper:
|
|
55
45
|
|
|
56
46
|
```ts
|
|
57
|
-
|
|
47
|
+
import { resolveResourceUrl } from '@kurot/core';
|
|
48
|
+
|
|
49
|
+
const response = await fetch(resolveResourceUrl('resource/config/style.json'));
|
|
50
|
+
const font = new FontFace('ProjectFont', `url("${resolveResourceUrl('resource/font.ttf')}")`);
|
|
51
|
+
const theme = new Theme(resolveResourceUrl(new URL('resource/default.thm.json', document.baseURI)));
|
|
58
52
|
```
|
|
59
53
|
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
The game starter includes this wiring for startup fonts/styles and Theme. Theme
|
|
55
|
+
config is versioned, while its generated `skinsJs` continues using the JS filename
|
|
56
|
+
hash. Core does not replace global fetch or XMLHttpRequest. API requests outside
|
|
57
|
+
`resource/`, POST requests, remote/CDN URLs, data/blob URLs and JS modules retain
|
|
58
|
+
their original URLs. Remote or signed resources need their own version policy.
|
|
59
|
+
|
|
60
|
+
## Static HTML and CSS
|
|
61
|
+
|
|
62
|
+
The CLI also versions existing local files referenced by HTML `src`, `poster`,
|
|
63
|
+
link/SVG `href`, object `data`, inline styles, style blocks, CSS `url()` and string
|
|
64
|
+
`@import`. This includes page logos, fonts, stylesheets and startup configuration
|
|
65
|
+
scripts outside `js/`. It preserves scripts and ordinary strings. Navigation
|
|
66
|
+
links, form destinations, HTML pages and generated files under `js/` are unchanged.
|
|
67
|
+
Native URLs constructed inside scripts must use the helper or read the generated
|
|
68
|
+
metadata in a standalone page without Core. `srcset` rewriting is not provided.
|
|
62
69
|
|
|
63
|
-
|
|
70
|
+
Custom HTML pages need an explicit `<head>` and no authored `<base>` or
|
|
71
|
+
`kurot-resource-version` metadata. The build validates every page before rewriting
|
|
72
|
+
HTML/CSS. Symbolic links and other nonregular output files are rejected.
|
|
73
|
+
Use document-relative paths to support deployment under a subdirectory.
|
|
64
74
|
|
|
65
|
-
|
|
66
|
-
asset directories first, then replace root manifest.json and index.html. Keep
|
|
67
|
-
previous version directories available while older sessions may request assets;
|
|
68
|
-
avoid deploy commands that delete those directories immediately. Publish the
|
|
69
|
-
entry at a directory URL ending in `/` or at its actual `index.html` URL.
|
|
75
|
+
## Deployment and caching
|
|
70
76
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
Deploy the entire generated release directory. Revalidate entry HTML and
|
|
78
|
+
manifest.json (for example `Cache-Control: no-cache`). Configure CDN/cache keys to
|
|
79
|
+
include `v`; otherwise different builds can still share stale resource responses.
|
|
80
|
+
Generated content-hashed JS can retain long-lived immutable caching. Resource
|
|
81
|
+
URLs may be cached by their version query, but replacing a same-path file does
|
|
82
|
+
not retain older bytes for an uncached old URL. This is cache busting, not release
|
|
83
|
+
snapshot storage. Use separate deployment directories if old sessions must lazily
|
|
84
|
+
load their exact previous files after deployment. Server headers and atomic
|
|
85
|
+
publishing remain deployment responsibilities.
|