@cmpose/core 0.3.0 → 0.5.0
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 +1 -1
- package/package.json +1 -1
- package/src/backend/contract.js +39 -0
- package/src/backend/describe.js +73 -0
- package/src/backend/generate.js +39 -0
- package/src/backend/identity.js +109 -0
- package/src/backend/index.js +24 -0
- package/src/backend/options.js +159 -0
- package/src/backend/record.js +31 -0
- package/src/backend/validate.js +64 -0
- package/src/backend/verifier.js +69 -0
- package/src/backendOption.js +1 -64
- package/src/game/applyTheme.js +129 -0
- package/src/game/contract.js +4 -1
- package/src/game/describe.js +15 -3
- package/src/game/generate.js +19 -4
- package/src/game/index.js +8 -0
- package/src/game/record.js +4 -2
- package/src/game/themeColors.js +173 -0
- package/src/game/themes.js +112 -0
- package/src/game/validate.js +10 -1
- package/src/index.js +2 -0
- package/src/markerBlocks.js +93 -0
- package/src/pins.js +3 -1
package/src/game/validate.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const PV = require('../ProjectValidator');
|
|
3
3
|
const limits = require('../limits');
|
|
4
4
|
const { GAME_SCHEMA: S } = require('./contract');
|
|
5
|
+
const { checkThemeShape } = require('./themes');
|
|
5
6
|
|
|
6
7
|
const CSHARP_KEYWORDS = ('abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual void volatile while').split(' ');
|
|
7
8
|
const KOTLIN_KEYWORDS = PV.KOTLIN_HARD_KEYWORDS;
|
|
@@ -179,9 +180,17 @@ function validateGame(input) {
|
|
|
179
180
|
ids = r.value;
|
|
180
181
|
}
|
|
181
182
|
|
|
183
|
+
// The family and font pair are checked against the template's themes.json later (validateTheme)
|
|
184
|
+
let theme = null;
|
|
185
|
+
if (input.theme !== undefined) {
|
|
186
|
+
const r = checkThemeShape(input.theme);
|
|
187
|
+
if (r.error) return fail(r.error);
|
|
188
|
+
theme = r.value;
|
|
189
|
+
}
|
|
190
|
+
|
|
182
191
|
return {
|
|
183
192
|
ok: true,
|
|
184
|
-
value: { projectName, appName, packageName, companyName, templateType, render, flags, features, minSdk, iosVersion, ids }
|
|
193
|
+
value: { projectName, appName, packageName, companyName, templateType, render, flags, features, minSdk, iosVersion, ids, theme }
|
|
185
194
|
};
|
|
186
195
|
}
|
|
187
196
|
|
package/src/index.js
CHANGED
|
@@ -27,6 +27,7 @@ module.exports = {
|
|
|
27
27
|
fileService: require('./fileService'),
|
|
28
28
|
featureModules: require('./featureModules'),
|
|
29
29
|
backendOption: require('./backendOption'),
|
|
30
|
+
markerBlocks: require('./markerBlocks'),
|
|
30
31
|
TemplateCapabilityError: require('./featureModules').TemplateCapabilityError,
|
|
31
32
|
verifyGeneratedProject: require('./generationVerifier').verifyGeneratedProject,
|
|
32
33
|
validate: require('./validate').validate,
|
|
@@ -35,5 +36,6 @@ module.exports = {
|
|
|
35
36
|
generateCmpProject: require('./generate').generateCmpProject,
|
|
36
37
|
templateCache: require('./templateCache'),
|
|
37
38
|
game: require('./game'),
|
|
39
|
+
backend: require('./backend'),
|
|
38
40
|
TemplateFetchError: require('./templateCache').TemplateFetchError
|
|
39
41
|
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
// The cmpose:<tag> marker blocks a template wraps around an optional part (the CMP template's backend, the backend
|
|
5
|
+
// template's sharing). Off drops each block, on drops only the marker lines.
|
|
6
|
+
|
|
7
|
+
const COMMENTS = { slash: '//', dash: '--', hash: '#' };
|
|
8
|
+
// html: the CMP template's name for the xml form
|
|
9
|
+
const XML_KINDS = new Set(['xml', 'html']);
|
|
10
|
+
|
|
11
|
+
// The backend template's marker form by file name (the CMP backend option keeps its own table)
|
|
12
|
+
const KIND_BY_EXTENSION = {
|
|
13
|
+
'.kt': 'slash', '.kts': 'slash',
|
|
14
|
+
'.sql': 'dash',
|
|
15
|
+
'.yml': 'hash', '.yaml': 'hash', '.toml': 'hash', '.properties': 'hash',
|
|
16
|
+
'.md': 'xml'
|
|
17
|
+
};
|
|
18
|
+
const KIND_BY_NAME = { '.gitignore': 'hash', '.env.example': 'hash', '.dockerignore': 'hash' };
|
|
19
|
+
|
|
20
|
+
function markersOf(kind, tag) {
|
|
21
|
+
if (XML_KINDS.has(kind)) return { open: `<!-- cmpose:${tag} -->`, close: `<!-- /cmpose:${tag} -->` };
|
|
22
|
+
const comment = COMMENTS[kind];
|
|
23
|
+
if (!comment) throw new Error(`unknown marker kind: ${kind}`);
|
|
24
|
+
return { open: `${comment} cmpose:${tag}`, close: `${comment} /cmpose:${tag}` };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Off: drops each marked block with its marker lines; on: drops only the marker lines. Either way a blank
|
|
28
|
+
// line on both sides of a dropped run becomes one (blank runs elsewhere stay).
|
|
29
|
+
function removeMarkedBlocks(content, kind, keep, tag = 'backend') {
|
|
30
|
+
const { open, close } = markersOf(kind, tag);
|
|
31
|
+
const out = [];
|
|
32
|
+
const joins = [];
|
|
33
|
+
let inside = false;
|
|
34
|
+
let dropped = false;
|
|
35
|
+
for (const line of content.split('\n')) {
|
|
36
|
+
const t = line.trim();
|
|
37
|
+
if (t === open) {
|
|
38
|
+
if (inside) throw new Error(`nested ${open}`);
|
|
39
|
+
inside = true;
|
|
40
|
+
dropped = true;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (t === close) {
|
|
44
|
+
if (!inside) throw new Error(`stray ${close}`);
|
|
45
|
+
inside = false;
|
|
46
|
+
dropped = true;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (inside && !keep) continue;
|
|
50
|
+
if (dropped) joins.push(out.length);
|
|
51
|
+
dropped = false;
|
|
52
|
+
out.push(line);
|
|
53
|
+
}
|
|
54
|
+
if (inside) throw new Error(`unclosed cmpose:${tag} block`);
|
|
55
|
+
if (dropped) joins.push(out.length);
|
|
56
|
+
return collapseBlankRuns(out, joins).join('\n');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// At each join (the index of the first line after a dropped run), blank lines that follow a blank line go
|
|
60
|
+
function collapseBlankRuns(lines, joins) {
|
|
61
|
+
const drop = new Set();
|
|
62
|
+
for (const join of joins) {
|
|
63
|
+
if (join === 0 || lines[join - 1] !== '') continue;
|
|
64
|
+
for (let i = join; i < lines.length && lines[i] === ''; i++) drop.add(i);
|
|
65
|
+
}
|
|
66
|
+
return lines.filter((_, i) => !drop.has(i));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Off: the line after a swap marker becomes the marker's text at that line's indentation; on: the marker goes
|
|
70
|
+
function applySwapMarkers(content, keep, tag = 'backend', kind = 'slash') {
|
|
71
|
+
const comment = COMMENTS[kind];
|
|
72
|
+
if (!comment) throw new Error(`no swap marker for kind: ${kind}`);
|
|
73
|
+
const swap = `${comment} cmpose:${tag}-off: `;
|
|
74
|
+
const lines = content.split('\n');
|
|
75
|
+
const out = [];
|
|
76
|
+
for (let i = 0; i < lines.length; i++) {
|
|
77
|
+
const t = lines[i].trim();
|
|
78
|
+
if (!t.startsWith(swap)) { out.push(lines[i]); continue; }
|
|
79
|
+
const next = lines[i + 1];
|
|
80
|
+
if (next === undefined) throw new Error(`cmpose:${tag}-off marker on the last line`);
|
|
81
|
+
if (keep) { out.push(next); } else { out.push(next.match(/^\s*/)[0] + t.slice(swap.length)); }
|
|
82
|
+
i++;
|
|
83
|
+
}
|
|
84
|
+
return out.join('\n');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// The marker kind of a backend template file; undefined when it takes no markers
|
|
88
|
+
function kindOf(file) {
|
|
89
|
+
const name = path.basename(file);
|
|
90
|
+
return Object.hasOwn(KIND_BY_NAME, name) ? KIND_BY_NAME[name] : KIND_BY_EXTENSION[path.extname(name)];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
module.exports = { removeMarkedBlocks, applySwapMarkers, kindOf };
|
package/src/pins.js
CHANGED
|
@@ -3,5 +3,7 @@
|
|
|
3
3
|
module.exports = Object.freeze({
|
|
4
4
|
cmp: Object.freeze({ repo: 'whinstudio/cmpose-template', ref: 'template-2026.10.17' }),
|
|
5
5
|
// The release step replaces the placeholder with the game template's tag
|
|
6
|
-
game: Object.freeze({ repo: 'whinstudio/cmpose-game-template', ref: 'game-template-2026.10.
|
|
6
|
+
game: Object.freeze({ repo: 'whinstudio/cmpose-game-template', ref: 'game-template-2026.10.17' }),
|
|
7
|
+
// The release step replaces the placeholder with the backend template's tag
|
|
8
|
+
backend: Object.freeze({ repo: 'whinstudio/cmpose-backend-template', ref: 'backend-template-2026.10.17' })
|
|
7
9
|
});
|