@vampgg/cli 1.0.0-beta.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/LICENSE +21 -0
- package/README.md +20 -0
- package/dist/generate-mutation-schema-DPVvPX4h.mjs +1080 -0
- package/dist/index.d.mts +153 -0
- package/dist/index.mjs +2 -0
- package/dist/vamp.d.mts +1 -0
- package/dist/vamp.mjs +279 -0
- package/package.json +54 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
//#region src/config/types.d.ts
|
|
2
|
+
interface FrameworkConfig {
|
|
3
|
+
/** Path to the bebop.json config file (default: "./bebop.json") */
|
|
4
|
+
bebopConfig?: string;
|
|
5
|
+
schemas: {
|
|
6
|
+
entity: string;
|
|
7
|
+
actions: string;
|
|
8
|
+
state: string;
|
|
9
|
+
tags: string;
|
|
10
|
+
/**
|
|
11
|
+
* Path for the generated bebop mutation schema (EntityDelta, MutationScope).
|
|
12
|
+
* Defaults to a `mutation.bop` sibling of the entity schema.
|
|
13
|
+
*/
|
|
14
|
+
mutation?: string;
|
|
15
|
+
};
|
|
16
|
+
outFile: string;
|
|
17
|
+
}
|
|
18
|
+
interface BebopConfig {
|
|
19
|
+
include?: string[];
|
|
20
|
+
exclude?: string[];
|
|
21
|
+
generators?: {
|
|
22
|
+
ts?: {
|
|
23
|
+
outFile?: string;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
watchOptions?: {
|
|
27
|
+
excludeDirectories?: string[];
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
//#region src/config/loader.d.ts
|
|
32
|
+
declare function loadBebopConfig(cwd: string, configPath?: string): BebopConfig;
|
|
33
|
+
declare function loadVampConfig(cwd: string): FrameworkConfig;
|
|
34
|
+
//#endregion
|
|
35
|
+
//#region src/generators/parse-bop.d.ts
|
|
36
|
+
interface SchemaField {
|
|
37
|
+
name: string;
|
|
38
|
+
typeId: number;
|
|
39
|
+
isArray: boolean;
|
|
40
|
+
isMap: boolean;
|
|
41
|
+
/** For scalars, the scalar type name. For definitions, the definition name. */
|
|
42
|
+
typeName: string;
|
|
43
|
+
/** For arrays, the member type name */
|
|
44
|
+
memberTypeName?: string;
|
|
45
|
+
/** For maps, the key type name */
|
|
46
|
+
keyTypeName?: string;
|
|
47
|
+
/** For maps, the value type name */
|
|
48
|
+
valueTypeName?: string;
|
|
49
|
+
/** Bebop field tag (for messages) */
|
|
50
|
+
constantValue?: number | null;
|
|
51
|
+
}
|
|
52
|
+
interface SchemaDefinition {
|
|
53
|
+
name: string;
|
|
54
|
+
kind: "struct" | "message" | "union" | "enum";
|
|
55
|
+
fields: SchemaField[];
|
|
56
|
+
/** For unions: branch info */
|
|
57
|
+
branches?: {
|
|
58
|
+
discriminator: number;
|
|
59
|
+
typeName: string;
|
|
60
|
+
}[];
|
|
61
|
+
}
|
|
62
|
+
interface ParsedSchema {
|
|
63
|
+
definitions: Map<string, SchemaDefinition>;
|
|
64
|
+
}
|
|
65
|
+
declare function parseSchema(bebopSchemaBytes: Uint8Array): ParsedSchema;
|
|
66
|
+
declare function loadSchemaFromFile(bebopTsPath: string): Uint8Array;
|
|
67
|
+
declare function loadAndParseSchema(bebopTsPath: string): ParsedSchema;
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region src/generators/codegen.d.ts
|
|
70
|
+
declare function generate(cwd: string, config: BebopConfig, vampConfig: FrameworkConfig): string;
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region src/generators/parse-bop-source.d.ts
|
|
73
|
+
/** Recursive classification of a type token (base/array/map). */
|
|
74
|
+
interface TypeClassification {
|
|
75
|
+
/** Resolved element/base type name (e.g. "guid", "Pool"). For maps this is "map". */
|
|
76
|
+
typeName: string;
|
|
77
|
+
isArray: boolean;
|
|
78
|
+
isMap: boolean;
|
|
79
|
+
/** For arrays, the member type name */
|
|
80
|
+
memberType?: string;
|
|
81
|
+
/** For maps, the key type name */
|
|
82
|
+
keyType?: string;
|
|
83
|
+
/** For maps, the value type name (raw substring) */
|
|
84
|
+
valueType?: string;
|
|
85
|
+
/** For maps, the recursive classification of the value type */
|
|
86
|
+
valueClassified?: TypeClassification;
|
|
87
|
+
/** For arrays, the recursive classification of the member type */
|
|
88
|
+
memberClassified?: TypeClassification;
|
|
89
|
+
/** True when the resolved base/member type is a bebop scalar */
|
|
90
|
+
isScalar: boolean;
|
|
91
|
+
}
|
|
92
|
+
interface SourceField extends TypeClassification {
|
|
93
|
+
/** Bebop field tag/index */
|
|
94
|
+
index: number;
|
|
95
|
+
name: string;
|
|
96
|
+
/** Raw type token as written (e.g. "guid", "Pool", "Tags", "guid[]", "map[guid, Foo]") */
|
|
97
|
+
rawType: string;
|
|
98
|
+
}
|
|
99
|
+
interface SourceMessage {
|
|
100
|
+
name: string;
|
|
101
|
+
fields: SourceField[];
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Extract the body of `message <name> { ... }` from bebop source text.
|
|
105
|
+
* Returns null if the message is not found.
|
|
106
|
+
*/
|
|
107
|
+
declare function extractMessageBody(source: string, messageName: string): string | null;
|
|
108
|
+
/**
|
|
109
|
+
* Parse `message <name>` field declarations from bebop source text.
|
|
110
|
+
*
|
|
111
|
+
* This is intentionally a lightweight, syntax-focused parser (no import
|
|
112
|
+
* resolution). It only understands the constrained field syntax used in
|
|
113
|
+
* generated/authored entity schemas: `<index> -> <type> <name>;`.
|
|
114
|
+
*
|
|
115
|
+
* Nested/inline message blocks inside the message body are stripped before
|
|
116
|
+
* field extraction; their fields are NOT emitted as fields of this message. A
|
|
117
|
+
* warning is logged so the user knows an inline component was ignored.
|
|
118
|
+
*/
|
|
119
|
+
declare function parseMessage(source: string, messageName: string): SourceMessage | null;
|
|
120
|
+
/** Convenience wrapper for the `Entity` message. */
|
|
121
|
+
declare function parseEntityMessage(source: string): SourceMessage;
|
|
122
|
+
//#endregion
|
|
123
|
+
//#region src/generators/emit-mutation-bop.d.ts
|
|
124
|
+
/**
|
|
125
|
+
* Emit the bebop schema providing serializable EntityDelta + MutationScope
|
|
126
|
+
* types, derived from the Entity message.
|
|
127
|
+
*
|
|
128
|
+
* @param entity Parsed Entity message.
|
|
129
|
+
* @param entityImportPath Import path to the entity schema, relative to the
|
|
130
|
+
* emitted file (e.g. "./entity.bop").
|
|
131
|
+
* @param userDeltas Set of `<Type>Delta` message names already reachable from
|
|
132
|
+
* the user's schema (so they are reused verbatim, not re-synthesized).
|
|
133
|
+
* @param components Map of component name -> parsed component message, used to
|
|
134
|
+
* synthesize a `<Type>Delta` when one is not user-supplied.
|
|
135
|
+
* @param entitySchemaPath Absolute path to the entity schema (for error text).
|
|
136
|
+
*/
|
|
137
|
+
declare function emitMutationSchema(entity: SourceMessage, entityImportPath: string, userDeltas?: ReadonlySet<string>, components?: ReadonlyMap<string, SourceMessage>, entitySchemaPath?: string): string;
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region src/generators/generate-mutation-schema.d.ts
|
|
140
|
+
/** Default mutation schema path: a `mutation.bop` sibling of the entity schema. */
|
|
141
|
+
declare function resolveMutationPath(cwd: string, vampConfig: FrameworkConfig): string;
|
|
142
|
+
/**
|
|
143
|
+
* Parse the user's entity schema and (re)generate the bebop mutation schema
|
|
144
|
+
* (EntityDelta, MutationType, MutationRecord, MutationScope) next to it.
|
|
145
|
+
*
|
|
146
|
+
* IMPORTANT: this must run BEFORE `bebopc build` so the generated schema is
|
|
147
|
+
* picked up and compiled into serializable types.
|
|
148
|
+
*
|
|
149
|
+
* @returns the absolute path of the written mutation schema.
|
|
150
|
+
*/
|
|
151
|
+
declare function generateMutationSchema(cwd: string, vampConfig: FrameworkConfig): string;
|
|
152
|
+
//#endregion
|
|
153
|
+
export { type BebopConfig, type FrameworkConfig, type ParsedSchema, type SchemaDefinition, type SchemaField, type SourceField, type SourceMessage, emitMutationSchema, extractMessageBody, generate, generateMutationSchema, loadAndParseSchema, loadBebopConfig, loadSchemaFromFile, loadVampConfig, parseEntityMessage, parseMessage, parseSchema, resolveMutationPath };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as extractMessageBody, c as generate, d as parseSchema, f as loadBebopConfig, i as emitMutationSchema, l as loadAndParseSchema, n as resolveMutationPath, o as parseEntityMessage, p as loadVampConfig, s as parseMessage, t as generateMutationSchema, u as loadSchemaFromFile } from "./generate-mutation-schema-DPVvPX4h.mjs";
|
|
2
|
+
export { emitMutationSchema, extractMessageBody, generate, generateMutationSchema, loadAndParseSchema, loadBebopConfig, loadSchemaFromFile, loadVampConfig, parseEntityMessage, parseMessage, parseSchema, resolveMutationPath };
|
package/dist/vamp.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/vamp.mjs
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { c as generate, f as loadBebopConfig, p as loadVampConfig, r as resolveBebopImport, t as generateMutationSchema } from "./generate-mutation-schema-DPVvPX4h.mjs";
|
|
3
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { relative, resolve } from "node:path";
|
|
5
|
+
import { defineCommand, runMain } from "citty";
|
|
6
|
+
import { execSync } from "node:child_process";
|
|
7
|
+
//#region src/commands/generate.ts
|
|
8
|
+
/**
|
|
9
|
+
* Build a watch-mode scheduler that runs `run` on each change, never dropping a
|
|
10
|
+
* change saved while a run is in flight: a mid-run change sets a pending flag
|
|
11
|
+
* that triggers exactly one follow-up after the current run completes.
|
|
12
|
+
*
|
|
13
|
+
* Extracted (and exported) so the pending-rerun semantics can be unit-tested
|
|
14
|
+
* without invoking the real generator (plan 21 §4d / Case E).
|
|
15
|
+
*/
|
|
16
|
+
function createWatchScheduler(run, debounce, onComplete) {
|
|
17
|
+
let isRunning = false;
|
|
18
|
+
let pending = false;
|
|
19
|
+
const runOnce = () => {
|
|
20
|
+
isRunning = true;
|
|
21
|
+
const ok = run();
|
|
22
|
+
isRunning = false;
|
|
23
|
+
onComplete?.(ok);
|
|
24
|
+
if (pending) {
|
|
25
|
+
pending = false;
|
|
26
|
+
debounce(runOnce);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const onChange = () => {
|
|
30
|
+
if (isRunning) {
|
|
31
|
+
pending = true;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
debounce(runOnce);
|
|
35
|
+
};
|
|
36
|
+
return { onChange };
|
|
37
|
+
}
|
|
38
|
+
const generateCommand = defineCommand({
|
|
39
|
+
meta: {
|
|
40
|
+
name: "generate",
|
|
41
|
+
description: "Run bebopc build, then emit game.generated.ts with component map, delta types, helpers, and factory"
|
|
42
|
+
},
|
|
43
|
+
args: {
|
|
44
|
+
cwd: {
|
|
45
|
+
type: "string",
|
|
46
|
+
description: "Working directory",
|
|
47
|
+
default: process.cwd()
|
|
48
|
+
},
|
|
49
|
+
"skip-bebopc": {
|
|
50
|
+
type: "boolean",
|
|
51
|
+
description: "Skip running bebopc build",
|
|
52
|
+
default: false
|
|
53
|
+
},
|
|
54
|
+
watch: {
|
|
55
|
+
type: "boolean",
|
|
56
|
+
description: "Watch schema files for changes and regenerate on change",
|
|
57
|
+
default: false
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
async run({ args }) {
|
|
61
|
+
const cwd = args.cwd;
|
|
62
|
+
const vampConfig = loadVampConfig(cwd);
|
|
63
|
+
const bebopConfig = loadBebopConfig(cwd, vampConfig.bebopConfig);
|
|
64
|
+
const runGenerate = () => {
|
|
65
|
+
console.log("Generating mutation schema...");
|
|
66
|
+
const mutationPath = generateMutationSchema(cwd, vampConfig);
|
|
67
|
+
console.log(`Generated ${mutationPath}`);
|
|
68
|
+
const bebopTsPath = resolve(cwd, bebopConfig.generators?.ts?.outFile ?? "./src/bebop.ts");
|
|
69
|
+
if (!args["skip-bebopc"]) {
|
|
70
|
+
try {
|
|
71
|
+
execSync("npx --no-install bebopc --version", {
|
|
72
|
+
cwd,
|
|
73
|
+
stdio: "pipe"
|
|
74
|
+
});
|
|
75
|
+
} catch {
|
|
76
|
+
console.error("bebopc not found. Install it (e.g. `pnpm add -D bebop-tools`) before running `vamp generate`.");
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
console.log("Running bebopc build...");
|
|
80
|
+
try {
|
|
81
|
+
execSync("npx --no-install bebopc build", {
|
|
82
|
+
cwd,
|
|
83
|
+
stdio: "inherit"
|
|
84
|
+
});
|
|
85
|
+
} catch (err) {
|
|
86
|
+
console.error("bebopc build failed:");
|
|
87
|
+
const e = err;
|
|
88
|
+
if (e.stderr?.length) console.error(e.stderr.toString());
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
if (!existsSync(bebopTsPath)) {
|
|
92
|
+
console.error(`bebopc build did not produce ${bebopTsPath}`);
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
console.log("Generating ECS types...");
|
|
97
|
+
const outPath = generate(cwd, bebopConfig, vampConfig);
|
|
98
|
+
console.log(`Generated ${outPath}`);
|
|
99
|
+
return true;
|
|
100
|
+
};
|
|
101
|
+
if (!args.watch) {
|
|
102
|
+
if (!runGenerate()) process.exit(1);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const chokidar = await import("chokidar");
|
|
106
|
+
const schemaPaths = [
|
|
107
|
+
resolve(cwd, vampConfig.schemas.entity),
|
|
108
|
+
resolve(cwd, vampConfig.schemas.actions),
|
|
109
|
+
resolve(cwd, vampConfig.schemas.state),
|
|
110
|
+
resolve(cwd, vampConfig.schemas.tags)
|
|
111
|
+
];
|
|
112
|
+
let debounceTimer = null;
|
|
113
|
+
const debounce = (fn) => {
|
|
114
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
115
|
+
debounceTimer = setTimeout(fn, 100);
|
|
116
|
+
};
|
|
117
|
+
const scheduler = createWatchScheduler(runGenerate, debounce, (ok) => {
|
|
118
|
+
if (ok) console.log("Watching for changes...");
|
|
119
|
+
});
|
|
120
|
+
const watcher = chokidar.watch(schemaPaths, { persistent: true });
|
|
121
|
+
watcher.on("change", (path) => {
|
|
122
|
+
console.log(`\nSchema changed: ${path}`);
|
|
123
|
+
scheduler.onChange();
|
|
124
|
+
});
|
|
125
|
+
console.log("Watching for changes...");
|
|
126
|
+
if (!runGenerate()) {
|
|
127
|
+
await watcher.close();
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/templates/entity.bop.ts
|
|
134
|
+
/**
|
|
135
|
+
* Entity schema template. `__POOL_IMPORT__` is replaced at scaffold time with a
|
|
136
|
+
* path to `@vampgg/utils/schema/pool.bop` resolved via Node module resolution, so
|
|
137
|
+
* it is correct for the actual (hoisted or pnpm) `node_modules` layout.
|
|
138
|
+
*/
|
|
139
|
+
const entityTemplate = `import "__POOL_IMPORT__"
|
|
140
|
+
import "./tags.bop"
|
|
141
|
+
|
|
142
|
+
message Entity {
|
|
143
|
+
\t1 -> string id;
|
|
144
|
+
\t2 -> string sk;
|
|
145
|
+
\t3 -> Tags[] tags;
|
|
146
|
+
\t4 -> string parent;
|
|
147
|
+
\t5 -> string[] children;
|
|
148
|
+
\t6 -> Pool health;
|
|
149
|
+
}
|
|
150
|
+
`;
|
|
151
|
+
/** Fallback import path used when `@vampgg/utils` cannot be resolved at init time. */
|
|
152
|
+
const POOL_IMPORT_PLACEHOLDER = "__POOL_IMPORT__";
|
|
153
|
+
const POOL_IMPORT_FALLBACK = "../node_modules/@vampgg/utils/schema/pool.bop";
|
|
154
|
+
//#endregion
|
|
155
|
+
//#region src/templates/actions.bop.ts
|
|
156
|
+
const actionsTemplate = `union Actions {
|
|
157
|
+
\t1 -> message Attack {
|
|
158
|
+
\t\t1 -> guid source;
|
|
159
|
+
\t\t2 -> guid target;
|
|
160
|
+
\t\t3 -> uint32 damage;
|
|
161
|
+
\t}
|
|
162
|
+
}
|
|
163
|
+
`;
|
|
164
|
+
//#endregion
|
|
165
|
+
//#region src/templates/state.bop.ts
|
|
166
|
+
const stateTemplate = `message State {
|
|
167
|
+
\t1 -> string ns;
|
|
168
|
+
}
|
|
169
|
+
`;
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/templates/tags.bop.ts
|
|
172
|
+
const tagsTemplate = `enum Tags {
|
|
173
|
+
Default = 1;
|
|
174
|
+
}
|
|
175
|
+
`;
|
|
176
|
+
//#endregion
|
|
177
|
+
//#region src/commands/init.ts
|
|
178
|
+
/**
|
|
179
|
+
* Resolve a bebop import path (relative to `schemaDir`) for
|
|
180
|
+
* `@vampgg/utils/schema/pool.bop` using Node module resolution, so the scaffolded
|
|
181
|
+
* import is correct under hoisted or pnpm `node_modules` layouts. Falls back to
|
|
182
|
+
* a literal path (with a warning) when resolution fails.
|
|
183
|
+
*
|
|
184
|
+
* `resolve` is injectable so the fallback branch can be tested deterministically
|
|
185
|
+
* (Node resolution from a temp dir is environment-dependent — it may still find
|
|
186
|
+
* a `@vampgg/utils` in an ancestor `node_modules`).
|
|
187
|
+
*/
|
|
188
|
+
function resolvePoolImport(cwd, schemaDir, resolveImport = resolveBebopImport) {
|
|
189
|
+
const resolved = resolveImport("@vampgg/utils/schema/pool.bop", cwd);
|
|
190
|
+
if (!resolved) {
|
|
191
|
+
console.warn("Warning: could not resolve '@vampgg/utils/schema/pool.bop'. Scaffolding a literal import path that may not resolve under your node_modules layout — fix the import in schema/entity.bop if `bebopc build` fails.");
|
|
192
|
+
return POOL_IMPORT_FALLBACK;
|
|
193
|
+
}
|
|
194
|
+
const rel = relative(schemaDir, resolved).split("\\").join("/");
|
|
195
|
+
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
196
|
+
}
|
|
197
|
+
//#endregion
|
|
198
|
+
//#region src/vamp.ts
|
|
199
|
+
runMain(defineCommand({
|
|
200
|
+
meta: {
|
|
201
|
+
name: "vamp",
|
|
202
|
+
description: "ECS code generator for @vampgg"
|
|
203
|
+
},
|
|
204
|
+
subCommands: {
|
|
205
|
+
generate: generateCommand,
|
|
206
|
+
init: defineCommand({
|
|
207
|
+
meta: {
|
|
208
|
+
name: "init",
|
|
209
|
+
description: "Scaffold schema/ dir, template .bop files, and create bebop.json + vamp.json"
|
|
210
|
+
},
|
|
211
|
+
args: { cwd: {
|
|
212
|
+
type: "string",
|
|
213
|
+
description: "Working directory",
|
|
214
|
+
default: process.cwd()
|
|
215
|
+
} },
|
|
216
|
+
run({ args }) {
|
|
217
|
+
const cwd = args.cwd;
|
|
218
|
+
const schemaDir = resolve(cwd, "schema");
|
|
219
|
+
mkdirSync(schemaDir, { recursive: true });
|
|
220
|
+
console.log("Created schema/");
|
|
221
|
+
const poolImport = resolvePoolImport(cwd, schemaDir);
|
|
222
|
+
const files = [
|
|
223
|
+
{
|
|
224
|
+
path: "schema/entity.bop",
|
|
225
|
+
content: entityTemplate.replace(POOL_IMPORT_PLACEHOLDER, poolImport)
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
path: "schema/actions.bop",
|
|
229
|
+
content: actionsTemplate
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
path: "schema/state.bop",
|
|
233
|
+
content: stateTemplate
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
path: "schema/tags.bop",
|
|
237
|
+
content: tagsTemplate
|
|
238
|
+
}
|
|
239
|
+
];
|
|
240
|
+
for (const file of files) {
|
|
241
|
+
const fullPath = resolve(cwd, file.path);
|
|
242
|
+
if (existsSync(fullPath)) console.log(`Skipping ${file.path} (already exists)`);
|
|
243
|
+
else {
|
|
244
|
+
writeFileSync(fullPath, file.content, "utf-8");
|
|
245
|
+
console.log(`Created ${file.path}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
const bebopConfigPath = resolve(cwd, "bebop.json");
|
|
249
|
+
if (existsSync(bebopConfigPath)) console.log("Skipping bebop.json (already exists)");
|
|
250
|
+
else {
|
|
251
|
+
writeFileSync(bebopConfigPath, JSON.stringify({
|
|
252
|
+
include: ["schema/**/*.bop"],
|
|
253
|
+
generators: { ts: { outFile: "./src/bebop.ts" } }
|
|
254
|
+
}, null, 2) + "\n", "utf-8");
|
|
255
|
+
console.log("Created bebop.json");
|
|
256
|
+
}
|
|
257
|
+
const vampConfigPath = resolve(cwd, "vamp.json");
|
|
258
|
+
if (existsSync(vampConfigPath)) console.log("Skipping vamp.json (already exists)");
|
|
259
|
+
else {
|
|
260
|
+
writeFileSync(vampConfigPath, JSON.stringify({
|
|
261
|
+
schemas: {
|
|
262
|
+
entity: "schema/entity.bop",
|
|
263
|
+
actions: "schema/actions.bop",
|
|
264
|
+
state: "schema/state.bop",
|
|
265
|
+
tags: "schema/tags.bop"
|
|
266
|
+
},
|
|
267
|
+
outFile: "./src/game.generated.ts"
|
|
268
|
+
}, null, 2) + "\n", "utf-8");
|
|
269
|
+
console.log("Created vamp.json");
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
})
|
|
273
|
+
}
|
|
274
|
+
})).catch((err) => {
|
|
275
|
+
console.error(err);
|
|
276
|
+
process.exit(1);
|
|
277
|
+
});
|
|
278
|
+
//#endregion
|
|
279
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vampgg/cli",
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
|
+
"description": "ECS code generator CLI for @vampgg",
|
|
5
|
+
"homepage": "https://github.com/sammccord/vamp/tree/main/tools/cli#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/sammccord/vamp/issues"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"author": "Sam McCord <sam.mccord@protonmail.com>",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/sammccord/vamp.git",
|
|
14
|
+
"directory": "tools/cli"
|
|
15
|
+
},
|
|
16
|
+
"bin": {
|
|
17
|
+
"vamp": "./dist/vamp.mjs"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"type": "module",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": "./dist/index.mjs",
|
|
25
|
+
"./vamp": "./dist/vamp.mjs",
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"bebop": "3.2.3",
|
|
33
|
+
"chokidar": "^3.6.0",
|
|
34
|
+
"citty": "^0.1.6",
|
|
35
|
+
"jsonc-parser": "^3.3.1"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^24",
|
|
39
|
+
"bebop-tools": "^3.2.3",
|
|
40
|
+
"typescript": "^5",
|
|
41
|
+
"vite-plus": "^0.1.24",
|
|
42
|
+
"vitest": "npm:@voidzero-dev/vite-plus-test@latest",
|
|
43
|
+
"@vampgg/ecs": "1.0.0-beta.1",
|
|
44
|
+
"@vampgg/utils": "1.0.0-beta.1",
|
|
45
|
+
"@vampgg/worker": "1.0.0-beta.1"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "vp pack",
|
|
49
|
+
"dev": "vp pack --watch",
|
|
50
|
+
"test": "vp test",
|
|
51
|
+
"typecheck": "tsc --noEmit",
|
|
52
|
+
"codegen:typecheck-fixtures": "vp test --run roundtrip"
|
|
53
|
+
}
|
|
54
|
+
}
|