lokiplay 0.1.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/LICENSE +21 -0
- package/README.md +13 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +675 -0
- package/dist/index.js.map +1 -0
- package/package.json +34 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Loki Play contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# lokiplay
|
|
2
|
+
|
|
3
|
+
Command-line tools for initializing, validating, deploying, and checking the
|
|
4
|
+
status of Loki game projects.
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
npm install --global lokiplay
|
|
8
|
+
lokiplay init ./my-game
|
|
9
|
+
lokiplay validate ./my-game
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Deployment and status commands require a configured Loki API endpoint and
|
|
13
|
+
project credentials.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export type PackageManager = "npm" | "pnpm" | "yarn" | "bun";
|
|
3
|
+
export type Framework = "vite" | "next" | "astro" | "sveltekit" | "angular" | "webpack" | "parcel" | "react-scripts" | "unknown";
|
|
4
|
+
interface PackageJson {
|
|
5
|
+
name?: string;
|
|
6
|
+
scripts?: Record<string, string>;
|
|
7
|
+
dependencies?: Record<string, string>;
|
|
8
|
+
devDependencies?: Record<string, string>;
|
|
9
|
+
}
|
|
10
|
+
export declare function detectPackageManager(directory: string): Promise<PackageManager>;
|
|
11
|
+
export declare function detectFramework(directory: string): Promise<Framework>;
|
|
12
|
+
export declare function selectBuildScript(packageJson: PackageJson): string;
|
|
13
|
+
export declare function detectOutputDirectory(directory: string, framework?: Framework, buildScript?: string): Promise<string>;
|
|
14
|
+
export declare function initializeProject(directory: string, input: {
|
|
15
|
+
name: string;
|
|
16
|
+
projectId?: string;
|
|
17
|
+
}): Promise<void>;
|
|
18
|
+
export declare function validateBuildDirectory(directory: string): Promise<{
|
|
19
|
+
files: string[];
|
|
20
|
+
warnings: string[];
|
|
21
|
+
}>;
|
|
22
|
+
export declare function archiveBuild(directory: string): Promise<Uint8Array>;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAqCA,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAC7D,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,MAAM,GACN,OAAO,GACP,WAAW,GACX,SAAS,GACT,SAAS,GACT,QAAQ,GACR,eAAe,GACf,SAAS,CAAC;AAEd,UAAU,WAAW;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;AAuBD,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CAwBzB;AAWD,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAuC3E;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAgBlE;AAkED,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,SAAS,EACrB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CAgDjB;AAeD,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1C,OAAO,CAAC,IAAI,CAAC,CAkCf;AAED,wBAAsB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IACvE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC,CAqBD;AAED,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAWzE"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { chmod, copyFile, mkdir, readFile, readdir, stat, writeFile, } from "node:fs/promises";
|
|
3
|
+
import { spawn } from "node:child_process";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import os from "node:os";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { pathToFileURL } from "node:url";
|
|
8
|
+
import { zipSync } from "fflate";
|
|
9
|
+
import { GameManifestSchema } from "@lokiplay/protocol";
|
|
10
|
+
const AGENT_INSTRUCTIONS = `# Loki integration rules
|
|
11
|
+
|
|
12
|
+
- Install and use \`@lokiplay/sdk\`; do not import Nakama APIs into game code.
|
|
13
|
+
- Production multiplayer runs only from a Loki-hosted finished browser build.
|
|
14
|
+
- Upload \`game.json\`, \`index.html\`, and static assets. Do not upload source-only
|
|
15
|
+
repositories, backend processes, secrets, creator ad scripts, or localhost
|
|
16
|
+
dependencies.
|
|
17
|
+
- MVP multiplayer is host-authoritative. Loki controls identity, tenant
|
|
18
|
+
boundaries, membership, matchmaking, sequencing, snapshots, and host
|
|
19
|
+
migration.
|
|
20
|
+
- Never trust or override the \`projectId\`, player identity, room membership, or
|
|
21
|
+
sequence returned by Loki.
|
|
22
|
+
- Keep game state JSON-compatible and use finite safe integers.
|
|
23
|
+
- Handle reconnect snapshots, host changes, stale-update errors, and focus
|
|
24
|
+
release when the Loki overlay opens.
|
|
25
|
+
- Connect and ship with \`npx lokiplay connect --project <uuid>\` followed by
|
|
26
|
+
\`npx lokiplay ship\`.
|
|
27
|
+
`;
|
|
28
|
+
async function exists(file) {
|
|
29
|
+
try {
|
|
30
|
+
await stat(file);
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function readPackageJson(directory) {
|
|
38
|
+
try {
|
|
39
|
+
return JSON.parse(await readFile(path.join(directory, "package.json"), "utf8"));
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
throw new Error(`Could not read package.json: ${error instanceof Error ? error.message : String(error)}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export async function detectPackageManager(directory) {
|
|
46
|
+
const lockfiles = [
|
|
47
|
+
["package-lock.json", "npm"],
|
|
48
|
+
["npm-shrinkwrap.json", "npm"],
|
|
49
|
+
["pnpm-lock.yaml", "pnpm"],
|
|
50
|
+
["yarn.lock", "yarn"],
|
|
51
|
+
["bun.lock", "bun"],
|
|
52
|
+
["bun.lockb", "bun"],
|
|
53
|
+
];
|
|
54
|
+
const found = await Promise.all(lockfiles.map(async ([file, manager]) => ({
|
|
55
|
+
file,
|
|
56
|
+
manager,
|
|
57
|
+
found: await exists(path.join(directory, file)),
|
|
58
|
+
})));
|
|
59
|
+
const present = found.filter((item) => item.found);
|
|
60
|
+
const managers = [...new Set(present.map((item) => item.manager))];
|
|
61
|
+
if (managers.length > 1) {
|
|
62
|
+
throw new Error(`Ambiguous package manager: found ${present.map((item) => item.file).join(", ")}`);
|
|
63
|
+
}
|
|
64
|
+
return managers[0] ?? "npm";
|
|
65
|
+
}
|
|
66
|
+
const frameworkConfigFiles = {
|
|
67
|
+
vite: /^vite\.config\.(?:js|mjs|cjs|ts|mts|cts)$/,
|
|
68
|
+
next: /^next\.config\.(?:js|mjs|cjs|ts)$/,
|
|
69
|
+
astro: /^astro\.config\.(?:js|mjs|cjs|ts|mts|cts)$/,
|
|
70
|
+
sveltekit: /^svelte\.config\.(?:js|mjs|cjs|ts)$/,
|
|
71
|
+
angular: /^angular\.json$/,
|
|
72
|
+
webpack: /^webpack\.config\.(?:js|mjs|cjs|ts)$/,
|
|
73
|
+
};
|
|
74
|
+
export async function detectFramework(directory) {
|
|
75
|
+
const packageJson = await readPackageJson(directory);
|
|
76
|
+
const dependencies = {
|
|
77
|
+
...packageJson.dependencies,
|
|
78
|
+
...packageJson.devDependencies,
|
|
79
|
+
};
|
|
80
|
+
const entries = await readdir(directory);
|
|
81
|
+
const candidates = new Set();
|
|
82
|
+
for (const [framework, pattern] of Object.entries(frameworkConfigFiles)) {
|
|
83
|
+
if (entries.some((entry) => pattern.test(entry)))
|
|
84
|
+
candidates.add(framework);
|
|
85
|
+
}
|
|
86
|
+
const dependencyMarkers = [
|
|
87
|
+
["next", "next"],
|
|
88
|
+
["astro", "astro"],
|
|
89
|
+
["@sveltejs/kit", "sveltekit"],
|
|
90
|
+
["@angular/cli", "angular"],
|
|
91
|
+
["vite", "vite"],
|
|
92
|
+
["webpack", "webpack"],
|
|
93
|
+
["parcel", "parcel"],
|
|
94
|
+
["react-scripts", "react-scripts"],
|
|
95
|
+
];
|
|
96
|
+
for (const [dependency, framework] of dependencyMarkers) {
|
|
97
|
+
if (dependencies[dependency])
|
|
98
|
+
candidates.add(framework);
|
|
99
|
+
}
|
|
100
|
+
if (candidates.size > 1) {
|
|
101
|
+
const compatible = candidates.size === 2 &&
|
|
102
|
+
candidates.has("vite") &&
|
|
103
|
+
candidates.has("sveltekit");
|
|
104
|
+
if (!compatible) {
|
|
105
|
+
throw new Error(`Ambiguous framework/build tool: ${[...candidates].sort().join(", ")}`);
|
|
106
|
+
}
|
|
107
|
+
return "sveltekit";
|
|
108
|
+
}
|
|
109
|
+
return candidates.values().next().value ?? "unknown";
|
|
110
|
+
}
|
|
111
|
+
export function selectBuildScript(packageJson) {
|
|
112
|
+
const scripts = packageJson.scripts ?? {};
|
|
113
|
+
if (typeof scripts.build === "string" && scripts.build.trim())
|
|
114
|
+
return "build";
|
|
115
|
+
const candidates = Object.keys(scripts).filter((name) => /^build:(?:prod|production)$/.test(name) &&
|
|
116
|
+
typeof scripts[name] === "string" &&
|
|
117
|
+
scripts[name].trim().length > 0);
|
|
118
|
+
if (candidates.length > 1) {
|
|
119
|
+
throw new Error(`Ambiguous build scripts: ${candidates.join(", ")}`);
|
|
120
|
+
}
|
|
121
|
+
if (candidates.length === 1)
|
|
122
|
+
return candidates[0];
|
|
123
|
+
throw new Error("No existing build script found (expected build, build:prod, or build:production)");
|
|
124
|
+
}
|
|
125
|
+
function scriptOutputCandidates(script) {
|
|
126
|
+
const candidates = [];
|
|
127
|
+
for (const pattern of [
|
|
128
|
+
/(?:^|\s)--outDir(?:=|\s+)(?:"([^"]+)"|'([^']+)'|([^\s]+))/g,
|
|
129
|
+
/(?:^|\s)--output-path(?:=|\s+)(?:"([^"]+)"|'([^']+)'|([^\s]+))/g,
|
|
130
|
+
/(?:^|\s)--output(?:=|\s+)(?:"([^"]+)"|'([^']+)'|([^\s]+))/g,
|
|
131
|
+
]) {
|
|
132
|
+
for (const match of script.matchAll(pattern)) {
|
|
133
|
+
candidates.push(match[1] ?? match[2] ?? match[3]);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return candidates;
|
|
137
|
+
}
|
|
138
|
+
async function configOutputCandidates(directory, framework) {
|
|
139
|
+
if (framework === "angular") {
|
|
140
|
+
const input = JSON.parse(await readFile(path.join(directory, "angular.json"), "utf8"));
|
|
141
|
+
return Object.values(input.projects ?? {}).flatMap((project) => {
|
|
142
|
+
const output = project.architect?.build?.options?.outputPath;
|
|
143
|
+
if (typeof output === "string")
|
|
144
|
+
return [output];
|
|
145
|
+
return output?.base ? [output.base] : [];
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
const matcher = framework === "vite" || framework === "astro"
|
|
149
|
+
? /\boutDir\s*:\s*["']([^"']+)["']/g
|
|
150
|
+
: framework === "webpack"
|
|
151
|
+
? /\bpath\s*:\s*(?:path\.(?:resolve|join)\([^,]+,\s*)?["']([^"']+)["']/g
|
|
152
|
+
: undefined;
|
|
153
|
+
if (matcher) {
|
|
154
|
+
const entries = await readdir(directory);
|
|
155
|
+
const configPattern = framework === "webpack"
|
|
156
|
+
? frameworkConfigFiles.webpack
|
|
157
|
+
: framework === "astro"
|
|
158
|
+
? frameworkConfigFiles.astro
|
|
159
|
+
: frameworkConfigFiles.vite;
|
|
160
|
+
const candidates = [];
|
|
161
|
+
for (const entry of entries.filter((name) => configPattern.test(name))) {
|
|
162
|
+
const source = await readFile(path.join(directory, entry), "utf8");
|
|
163
|
+
for (const match of source.matchAll(matcher))
|
|
164
|
+
candidates.push(match[1]);
|
|
165
|
+
}
|
|
166
|
+
return candidates;
|
|
167
|
+
}
|
|
168
|
+
if (framework === "next") {
|
|
169
|
+
const entries = await readdir(directory);
|
|
170
|
+
for (const entry of entries.filter((name) => frameworkConfigFiles.next.test(name))) {
|
|
171
|
+
const source = await readFile(path.join(directory, entry), "utf8");
|
|
172
|
+
if (/\boutput\s*:\s*["']export["']/.test(source))
|
|
173
|
+
return ["out"];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return [];
|
|
177
|
+
}
|
|
178
|
+
export async function detectOutputDirectory(directory, framework, buildScript) {
|
|
179
|
+
const selectedFramework = framework ?? (await detectFramework(directory));
|
|
180
|
+
const packageJson = await readPackageJson(directory);
|
|
181
|
+
const scriptName = buildScript ?? selectBuildScript(packageJson);
|
|
182
|
+
const explicit = [
|
|
183
|
+
...scriptOutputCandidates(packageJson.scripts?.[scriptName] ?? ""),
|
|
184
|
+
...(await configOutputCandidates(directory, selectedFramework)),
|
|
185
|
+
];
|
|
186
|
+
const normalizedExplicit = [
|
|
187
|
+
...new Set(explicit.map((candidate) => candidate.replace(/^\.\//, "").replace(/\/$/, ""))),
|
|
188
|
+
];
|
|
189
|
+
if (normalizedExplicit.length > 1) {
|
|
190
|
+
throw new Error(`Ambiguous output directory in build configuration: ${normalizedExplicit.join(", ")}`);
|
|
191
|
+
}
|
|
192
|
+
if (normalizedExplicit.length === 1) {
|
|
193
|
+
return path.resolve(directory, normalizedExplicit[0]);
|
|
194
|
+
}
|
|
195
|
+
const defaults = {
|
|
196
|
+
vite: "dist",
|
|
197
|
+
astro: "dist",
|
|
198
|
+
sveltekit: "build",
|
|
199
|
+
angular: "dist",
|
|
200
|
+
webpack: "dist",
|
|
201
|
+
parcel: "dist",
|
|
202
|
+
"react-scripts": "build",
|
|
203
|
+
};
|
|
204
|
+
const common = ["dist", "build", "out"];
|
|
205
|
+
const existing = (await Promise.all(common.map(async (candidate) => ({
|
|
206
|
+
candidate,
|
|
207
|
+
exists: await exists(path.join(directory, candidate)),
|
|
208
|
+
})))).filter((item) => item.exists);
|
|
209
|
+
const preferred = defaults[selectedFramework];
|
|
210
|
+
if (existing.length > 1) {
|
|
211
|
+
throw new Error(`Ambiguous output directory: found ${existing.map((item) => item.candidate).join(", ")}`);
|
|
212
|
+
}
|
|
213
|
+
if (existing.length === 1)
|
|
214
|
+
return path.join(directory, existing[0].candidate);
|
|
215
|
+
if (preferred)
|
|
216
|
+
return path.join(directory, preferred);
|
|
217
|
+
throw new Error("Could not detect build output; configure an output directory or create one of dist, build, or out");
|
|
218
|
+
}
|
|
219
|
+
async function walk(root, relative = "") {
|
|
220
|
+
const directory = path.join(root, relative);
|
|
221
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
222
|
+
const files = [];
|
|
223
|
+
for (const entry of entries) {
|
|
224
|
+
const child = path.posix.join(relative.replaceAll("\\", "/"), entry.name);
|
|
225
|
+
if (entry.isSymbolicLink())
|
|
226
|
+
throw new Error(`symbolic link not allowed: ${child}`);
|
|
227
|
+
if (entry.isDirectory())
|
|
228
|
+
files.push(...(await walk(root, child)));
|
|
229
|
+
else if (entry.isFile())
|
|
230
|
+
files.push(child);
|
|
231
|
+
}
|
|
232
|
+
return files;
|
|
233
|
+
}
|
|
234
|
+
export async function initializeProject(directory, input) {
|
|
235
|
+
await mkdir(directory, { recursive: true });
|
|
236
|
+
const manifestPath = path.join(directory, "game.json");
|
|
237
|
+
try {
|
|
238
|
+
await stat(manifestPath);
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
await writeFile(manifestPath, `${JSON.stringify({
|
|
242
|
+
schemaVersion: 1,
|
|
243
|
+
name: input.name,
|
|
244
|
+
entrypoint: "index.html",
|
|
245
|
+
multiplayer: {
|
|
246
|
+
enabled: true,
|
|
247
|
+
authority: "host",
|
|
248
|
+
maxPlayers: 8,
|
|
249
|
+
tickRate: 10,
|
|
250
|
+
},
|
|
251
|
+
networkAllowlist: [],
|
|
252
|
+
}, null, 2)}\n`);
|
|
253
|
+
}
|
|
254
|
+
await writeFile(path.join(directory, "AGENTS.md"), AGENT_INSTRUCTIONS);
|
|
255
|
+
if (input.projectId) {
|
|
256
|
+
await mkdir(path.join(directory, ".loki"), { recursive: true });
|
|
257
|
+
await writeFile(path.join(directory, ".loki", "project.json"), `${JSON.stringify({ projectId: input.projectId }, null, 2)}\n`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
export async function validateBuildDirectory(directory) {
|
|
261
|
+
const files = await walk(directory);
|
|
262
|
+
if (!files.includes("game.json"))
|
|
263
|
+
throw new Error("game.json is required");
|
|
264
|
+
const manifest = GameManifestSchema.parse(JSON.parse(await readFile(path.join(directory, "game.json"), "utf8")));
|
|
265
|
+
if (!files.includes(manifest.entrypoint)) {
|
|
266
|
+
throw new Error(`entrypoint ${manifest.entrypoint} is missing`);
|
|
267
|
+
}
|
|
268
|
+
const warnings = [];
|
|
269
|
+
for (const file of files) {
|
|
270
|
+
if (/(^|\/)(server|backend)(\.|\/)/i.test(file)) {
|
|
271
|
+
throw new Error(`backend source is not supported: ${file}`);
|
|
272
|
+
}
|
|
273
|
+
if (!/\.(?:html|js|mjs|css|json|txt)$/i.test(file))
|
|
274
|
+
continue;
|
|
275
|
+
const source = await readFile(path.join(directory, file), "utf8");
|
|
276
|
+
if (/https?:\/\/(?:localhost|127\.0\.0\.1)/i.test(source)) {
|
|
277
|
+
warnings.push(`${file}: contains a localhost URL`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return { files, warnings };
|
|
281
|
+
}
|
|
282
|
+
export async function archiveBuild(directory) {
|
|
283
|
+
const validation = await validateBuildDirectory(directory);
|
|
284
|
+
const archive = {};
|
|
285
|
+
for (const file of [...validation.files].sort()) {
|
|
286
|
+
if (file.startsWith(".loki/") || file === "AGENTS.md")
|
|
287
|
+
continue;
|
|
288
|
+
archive[file] = [
|
|
289
|
+
new Uint8Array(await readFile(path.join(directory, file))),
|
|
290
|
+
{ mtime: new Date("1980-01-01T00:00:00.000Z") },
|
|
291
|
+
];
|
|
292
|
+
}
|
|
293
|
+
return zipSync(archive, { level: 6 });
|
|
294
|
+
}
|
|
295
|
+
async function readCliSession() {
|
|
296
|
+
try {
|
|
297
|
+
return JSON.parse(await readFile(path.join(os.homedir(), ".config", "lokiplay", "session.json"), "utf8"));
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
return undefined;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
async function readProjectId(directory) {
|
|
304
|
+
if (process.env.LOKI_PROJECT_ID)
|
|
305
|
+
return process.env.LOKI_PROJECT_ID;
|
|
306
|
+
try {
|
|
307
|
+
const linked = JSON.parse(await readFile(path.join(directory, ".loki", "project.json"), "utf8"));
|
|
308
|
+
return linked.projectId;
|
|
309
|
+
}
|
|
310
|
+
catch {
|
|
311
|
+
return undefined;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function parseArguments(argv) {
|
|
315
|
+
const command = argv[0];
|
|
316
|
+
let directory;
|
|
317
|
+
let projectId;
|
|
318
|
+
const positional = [];
|
|
319
|
+
for (let index = 1; index < argv.length; index += 1) {
|
|
320
|
+
const argument = argv[index];
|
|
321
|
+
if (argument === "--") {
|
|
322
|
+
positional.push(...argv.slice(index + 1));
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
if (argument === "--project" || argument === "--dir") {
|
|
326
|
+
const value = argv[++index];
|
|
327
|
+
if (!value || value.startsWith("--")) {
|
|
328
|
+
throw new Error(`${argument} requires a value`);
|
|
329
|
+
}
|
|
330
|
+
if (argument === "--project") {
|
|
331
|
+
if (projectId)
|
|
332
|
+
throw new Error("--project may only be specified once");
|
|
333
|
+
projectId = value;
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
if (directory)
|
|
337
|
+
throw new Error("--dir may only be specified once");
|
|
338
|
+
directory = value;
|
|
339
|
+
}
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
if (argument.startsWith("--project=")) {
|
|
343
|
+
if (projectId)
|
|
344
|
+
throw new Error("--project may only be specified once");
|
|
345
|
+
projectId = argument.slice("--project=".length);
|
|
346
|
+
if (!projectId)
|
|
347
|
+
throw new Error("--project requires a value");
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
if (argument.startsWith("--dir=")) {
|
|
351
|
+
if (directory)
|
|
352
|
+
throw new Error("--dir may only be specified once");
|
|
353
|
+
directory = argument.slice("--dir=".length);
|
|
354
|
+
if (!directory)
|
|
355
|
+
throw new Error("--dir requires a value");
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
if (argument.startsWith("-"))
|
|
359
|
+
throw new Error(`Unknown option: ${argument}`);
|
|
360
|
+
positional.push(argument);
|
|
361
|
+
}
|
|
362
|
+
if (positional.length > 1 || (directory && positional.length)) {
|
|
363
|
+
throw new Error("Specify exactly one directory, either positionally or with --dir");
|
|
364
|
+
}
|
|
365
|
+
return {
|
|
366
|
+
command,
|
|
367
|
+
directory: path.resolve(directory ?? positional[0] ?? "."),
|
|
368
|
+
projectId,
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
function requireUuid(value, option) {
|
|
372
|
+
if (!value ||
|
|
373
|
+
!/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value)) {
|
|
374
|
+
throw new Error(`${option} must be a valid UUID`);
|
|
375
|
+
}
|
|
376
|
+
return value;
|
|
377
|
+
}
|
|
378
|
+
function stage(name, status, detail) {
|
|
379
|
+
console.log(JSON.stringify({ stage: name, status, ...detail }));
|
|
380
|
+
}
|
|
381
|
+
async function apiJson(url, accessToken, init) {
|
|
382
|
+
const response = await fetch(url, {
|
|
383
|
+
...init,
|
|
384
|
+
headers: {
|
|
385
|
+
authorization: `Bearer ${accessToken}`,
|
|
386
|
+
...init?.headers,
|
|
387
|
+
},
|
|
388
|
+
});
|
|
389
|
+
if (!response.ok)
|
|
390
|
+
throw new Error(await response.text());
|
|
391
|
+
return (await response.json());
|
|
392
|
+
}
|
|
393
|
+
async function connectProject(directory, projectId, session) {
|
|
394
|
+
if (session) {
|
|
395
|
+
await apiJson(`${session.endpoint}/v1/projects/${projectId}`, session.accessToken);
|
|
396
|
+
}
|
|
397
|
+
const packageJson = await readPackageJson(directory);
|
|
398
|
+
await initializeProject(directory, {
|
|
399
|
+
name: typeof packageJson.name === "string" && packageJson.name.trim()
|
|
400
|
+
? packageJson.name
|
|
401
|
+
: path.basename(directory),
|
|
402
|
+
projectId,
|
|
403
|
+
});
|
|
404
|
+
console.log(`Connected project ${projectId}`);
|
|
405
|
+
console.log("Required package: @lokiplay/sdk");
|
|
406
|
+
console.log("Optional web UI package: @lokiplay/ui-web");
|
|
407
|
+
}
|
|
408
|
+
async function runBuild(directory, packageManager, script) {
|
|
409
|
+
const command = {
|
|
410
|
+
npm: ["npm", ["run", script]],
|
|
411
|
+
pnpm: ["pnpm", ["run", script]],
|
|
412
|
+
yarn: ["yarn", ["run", script]],
|
|
413
|
+
bun: ["bun", ["run", script]],
|
|
414
|
+
};
|
|
415
|
+
const [executable, args] = command[packageManager];
|
|
416
|
+
await new Promise((resolve, reject) => {
|
|
417
|
+
const child = spawn(executable, args, {
|
|
418
|
+
cwd: directory,
|
|
419
|
+
stdio: "inherit",
|
|
420
|
+
shell: false,
|
|
421
|
+
});
|
|
422
|
+
child.once("error", reject);
|
|
423
|
+
child.once("exit", (code, signal) => {
|
|
424
|
+
if (code === 0)
|
|
425
|
+
resolve();
|
|
426
|
+
else {
|
|
427
|
+
reject(new Error(`Build failed (${signal ? `signal ${signal}` : `exit ${code ?? "unknown"}`})`));
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
async function activateDeployment(endpoint, accessToken, projectId, deploymentId) {
|
|
433
|
+
await apiJson(`${endpoint}/v1/projects/${projectId}/deployments/${deploymentId}/activate`, accessToken, { method: "POST" });
|
|
434
|
+
}
|
|
435
|
+
async function pollDeployment(endpoint, accessToken, projectId, deploymentId) {
|
|
436
|
+
stage("poll", "started", { deploymentId });
|
|
437
|
+
for (let attempt = 0; attempt < 30; attempt += 1) {
|
|
438
|
+
const deployments = await apiJson(`${endpoint}/v1/projects/${projectId}/deployments`, accessToken);
|
|
439
|
+
const deployment = deployments.find((candidate) => candidate.id === deploymentId);
|
|
440
|
+
if (deployment) {
|
|
441
|
+
if (deployment.status === "blocked") {
|
|
442
|
+
throw new Error(`Deployment ${deploymentId} was blocked`);
|
|
443
|
+
}
|
|
444
|
+
stage("poll", "complete", {
|
|
445
|
+
deploymentId,
|
|
446
|
+
deploymentStatus: deployment.status,
|
|
447
|
+
});
|
|
448
|
+
return deployment;
|
|
449
|
+
}
|
|
450
|
+
await new Promise((resolve) => setTimeout(resolve, 1_000));
|
|
451
|
+
}
|
|
452
|
+
throw new Error(`Timed out waiting for deployment ${deploymentId}`);
|
|
453
|
+
}
|
|
454
|
+
async function ship(directory, requestedProjectId) {
|
|
455
|
+
stage("authenticate", "started");
|
|
456
|
+
const session = await readCliSession();
|
|
457
|
+
const endpoint = process.env.LOKI_API_URL ?? session?.endpoint;
|
|
458
|
+
if (!endpoint || !session?.accessToken)
|
|
459
|
+
throw new Error("Run `lokiplay login` first");
|
|
460
|
+
stage("authenticate", "complete");
|
|
461
|
+
const linkedProjectId = await readProjectId(directory);
|
|
462
|
+
const projectId = requireUuid(requestedProjectId ?? linkedProjectId, requestedProjectId ? "--project" : "linked project");
|
|
463
|
+
if (!linkedProjectId || linkedProjectId !== projectId) {
|
|
464
|
+
stage("connect", "started", { projectId });
|
|
465
|
+
await connectProject(directory, projectId, {
|
|
466
|
+
endpoint,
|
|
467
|
+
accessToken: session.accessToken,
|
|
468
|
+
});
|
|
469
|
+
stage("connect", "complete", { projectId });
|
|
470
|
+
}
|
|
471
|
+
const packageJson = await readPackageJson(directory);
|
|
472
|
+
const packageManager = await detectPackageManager(directory);
|
|
473
|
+
const framework = await detectFramework(directory);
|
|
474
|
+
const buildScript = selectBuildScript(packageJson);
|
|
475
|
+
stage("build", "started", { packageManager, framework, script: buildScript });
|
|
476
|
+
await runBuild(directory, packageManager, buildScript);
|
|
477
|
+
stage("build", "complete");
|
|
478
|
+
const outputDirectory = await detectOutputDirectory(directory, framework, buildScript);
|
|
479
|
+
if (!(await exists(outputDirectory))) {
|
|
480
|
+
throw new Error(`Build output does not exist: ${outputDirectory}`);
|
|
481
|
+
}
|
|
482
|
+
const sourceManifest = path.join(directory, "game.json");
|
|
483
|
+
if (!(await exists(sourceManifest))) {
|
|
484
|
+
throw new Error("game.json is required; run `lokiplay connect --project <uuid>`");
|
|
485
|
+
}
|
|
486
|
+
if (path.resolve(outputDirectory) !== path.resolve(directory)) {
|
|
487
|
+
await copyFile(sourceManifest, path.join(outputDirectory, "game.json"));
|
|
488
|
+
}
|
|
489
|
+
stage("validate", "started", { outputDirectory });
|
|
490
|
+
const validation = await validateBuildDirectory(outputDirectory);
|
|
491
|
+
for (const warning of validation.warnings)
|
|
492
|
+
console.warn(`Warning: ${warning}`);
|
|
493
|
+
stage("validate", "complete", { files: validation.files.length });
|
|
494
|
+
const archive = await archiveBuild(outputDirectory);
|
|
495
|
+
const contentHash = createHash("sha256").update(archive).digest("hex");
|
|
496
|
+
stage("hash", "complete", { contentHash });
|
|
497
|
+
const existingResponse = await fetch(`${endpoint}/v1/projects/${projectId}/deployments/by-hash/${contentHash}`, { headers: { authorization: `Bearer ${session.accessToken}` } });
|
|
498
|
+
if (existingResponse.status !== 404 && !existingResponse.ok) {
|
|
499
|
+
throw new Error(await existingResponse.text());
|
|
500
|
+
}
|
|
501
|
+
let deployment = existingResponse.status === 404
|
|
502
|
+
? undefined
|
|
503
|
+
: (await existingResponse.json());
|
|
504
|
+
if (deployment?.status === "blocked")
|
|
505
|
+
deployment = undefined;
|
|
506
|
+
if (deployment) {
|
|
507
|
+
stage("upload", "reused", { deploymentId: deployment.id });
|
|
508
|
+
stage("activate", "started", { deploymentId: deployment.id });
|
|
509
|
+
await activateDeployment(endpoint, session.accessToken, projectId, deployment.id);
|
|
510
|
+
stage("activate", "complete", { deploymentId: deployment.id });
|
|
511
|
+
const polled = await pollDeployment(endpoint, session.accessToken, projectId, deployment.id);
|
|
512
|
+
deployment = { ...polled, playableUrl: deployment.playableUrl };
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
stage("credentials", "started");
|
|
516
|
+
const credential = await apiJson(`${endpoint}/v1/projects/${projectId}/deployment-credentials`, session.accessToken, { method: "POST" });
|
|
517
|
+
stage("credentials", "complete");
|
|
518
|
+
stage("upload", "started", { contentHash });
|
|
519
|
+
stage("activate", "started");
|
|
520
|
+
const response = await fetch(`${endpoint}/v1/deployments?activate=true`, {
|
|
521
|
+
method: "POST",
|
|
522
|
+
headers: {
|
|
523
|
+
"content-type": "application/zip",
|
|
524
|
+
"x-loki-credential-id": credential.credentialId,
|
|
525
|
+
authorization: `Bearer ${credential.secret}`,
|
|
526
|
+
},
|
|
527
|
+
body: Buffer.from(archive),
|
|
528
|
+
});
|
|
529
|
+
if (!response.ok)
|
|
530
|
+
throw new Error(await response.text());
|
|
531
|
+
deployment = (await response.json());
|
|
532
|
+
stage("upload", "complete", {
|
|
533
|
+
deploymentId: deployment.id,
|
|
534
|
+
deploymentStatus: deployment.status,
|
|
535
|
+
});
|
|
536
|
+
stage("activate", "complete", { deploymentId: deployment.id });
|
|
537
|
+
const polled = await pollDeployment(endpoint, session.accessToken, projectId, deployment.id);
|
|
538
|
+
deployment = { ...polled, playableUrl: deployment.playableUrl };
|
|
539
|
+
}
|
|
540
|
+
stage("ready", "complete", { deploymentId: deployment.id });
|
|
541
|
+
console.log(`Deployment ID: ${deployment.id}`);
|
|
542
|
+
const playableUrl = deployment.playableUrl ??
|
|
543
|
+
(process.env.LOKI_WEB_URL
|
|
544
|
+
? `${process.env.LOKI_WEB_URL.replace(/\/$/, "")}/play/${projectId}`
|
|
545
|
+
: undefined);
|
|
546
|
+
if (!playableUrl) {
|
|
547
|
+
throw new Error("Deployment succeeded, but the API did not return a playable URL");
|
|
548
|
+
}
|
|
549
|
+
console.log(`Playable URL: ${playableUrl}`);
|
|
550
|
+
}
|
|
551
|
+
async function main(argv) {
|
|
552
|
+
const { command, directory, projectId } = parseArguments(argv);
|
|
553
|
+
if (command === "login") {
|
|
554
|
+
const endpoint = process.env.LOKI_API_URL;
|
|
555
|
+
if (!endpoint)
|
|
556
|
+
throw new Error("LOKI_API_URL is required");
|
|
557
|
+
const started = await fetch(`${endpoint}/v1/cli/device`, { method: "POST" });
|
|
558
|
+
if (!started.ok)
|
|
559
|
+
throw new Error(await started.text());
|
|
560
|
+
const device = (await started.json());
|
|
561
|
+
const verificationUrl = new URL(device.verificationUri);
|
|
562
|
+
verificationUrl.searchParams.set("user_code", device.userCode);
|
|
563
|
+
console.log(`Open ${verificationUrl.toString()} and confirm ${device.userCode}`);
|
|
564
|
+
const deadline = Date.now() + device.expiresIn * 1_000;
|
|
565
|
+
while (Date.now() < deadline) {
|
|
566
|
+
await new Promise((resolve) => setTimeout(resolve, Math.max(1, device.interval) * 1_000));
|
|
567
|
+
const polled = await fetch(`${endpoint}/v1/cli/device/${encodeURIComponent(device.deviceCode)}`);
|
|
568
|
+
if (polled.status === 202)
|
|
569
|
+
continue;
|
|
570
|
+
if (!polled.ok)
|
|
571
|
+
throw new Error(await polled.text());
|
|
572
|
+
const session = (await polled.json());
|
|
573
|
+
const configDirectory = path.join(os.homedir(), ".config", "lokiplay");
|
|
574
|
+
const configPath = path.join(configDirectory, "session.json");
|
|
575
|
+
await mkdir(configDirectory, { recursive: true, mode: 0o700 });
|
|
576
|
+
await writeFile(configPath, `${JSON.stringify({ endpoint, accessToken: session.accessToken })}\n`, { mode: 0o600 });
|
|
577
|
+
await chmod(configPath, 0o600);
|
|
578
|
+
console.log("Logged in");
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
throw new Error("device login expired");
|
|
582
|
+
}
|
|
583
|
+
if (command === "init") {
|
|
584
|
+
await initializeProject(directory, {
|
|
585
|
+
name: path.basename(directory),
|
|
586
|
+
projectId: process.env.LOKI_PROJECT_ID,
|
|
587
|
+
});
|
|
588
|
+
console.log("Initialized Loki project");
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
if (command === "connect") {
|
|
592
|
+
const id = requireUuid(projectId, "--project");
|
|
593
|
+
const session = await readCliSession();
|
|
594
|
+
const endpoint = process.env.LOKI_API_URL ?? session?.endpoint;
|
|
595
|
+
if (!endpoint || !session?.accessToken) {
|
|
596
|
+
throw new Error("Run `lokiplay login` first");
|
|
597
|
+
}
|
|
598
|
+
await connectProject(directory, id, {
|
|
599
|
+
endpoint,
|
|
600
|
+
accessToken: session.accessToken,
|
|
601
|
+
});
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
if (command === "ship") {
|
|
605
|
+
await ship(directory, projectId);
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
if (command === "validate") {
|
|
609
|
+
const result = await validateBuildDirectory(directory);
|
|
610
|
+
console.log(`Valid build: ${result.files.length} files`);
|
|
611
|
+
for (const warning of result.warnings)
|
|
612
|
+
console.warn(`Warning: ${warning}`);
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
if (command === "deploy") {
|
|
616
|
+
const session = await readCliSession();
|
|
617
|
+
const endpoint = process.env.LOKI_API_URL ?? session?.endpoint;
|
|
618
|
+
const projectId = await readProjectId(directory);
|
|
619
|
+
if (!endpoint || !projectId) {
|
|
620
|
+
throw new Error("Log in and link a project before deploying");
|
|
621
|
+
}
|
|
622
|
+
let credentialId = process.env.LOKI_DEPLOY_CREDENTIAL_ID;
|
|
623
|
+
let secret = process.env.LOKI_DEPLOY_SECRET;
|
|
624
|
+
if (!credentialId || !secret) {
|
|
625
|
+
if (!session?.accessToken)
|
|
626
|
+
throw new Error("Run `lokiplay login` first");
|
|
627
|
+
const credentialResponse = await fetch(`${endpoint}/v1/projects/${projectId}/deployment-credentials`, {
|
|
628
|
+
method: "POST",
|
|
629
|
+
headers: { authorization: `Bearer ${session.accessToken}` },
|
|
630
|
+
});
|
|
631
|
+
if (!credentialResponse.ok)
|
|
632
|
+
throw new Error(await credentialResponse.text());
|
|
633
|
+
const credential = (await credentialResponse.json());
|
|
634
|
+
credentialId = credential.credentialId;
|
|
635
|
+
secret = credential.secret;
|
|
636
|
+
}
|
|
637
|
+
const archive = await archiveBuild(directory);
|
|
638
|
+
const response = await fetch(`${endpoint}/v1/deployments`, {
|
|
639
|
+
method: "POST",
|
|
640
|
+
headers: {
|
|
641
|
+
"content-type": "application/zip",
|
|
642
|
+
"x-loki-credential-id": credentialId,
|
|
643
|
+
authorization: `Bearer ${secret}`,
|
|
644
|
+
},
|
|
645
|
+
body: Buffer.from(archive),
|
|
646
|
+
});
|
|
647
|
+
if (!response.ok)
|
|
648
|
+
throw new Error(await response.text());
|
|
649
|
+
console.log(JSON.stringify(await response.json(), null, 2));
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
if (command === "status") {
|
|
653
|
+
const session = await readCliSession();
|
|
654
|
+
const endpoint = process.env.LOKI_API_URL ?? session?.endpoint;
|
|
655
|
+
const projectId = await readProjectId(directory);
|
|
656
|
+
if (!endpoint || !projectId || !session?.accessToken) {
|
|
657
|
+
throw new Error("Log in and link a project before checking status");
|
|
658
|
+
}
|
|
659
|
+
const response = await fetch(`${endpoint}/v1/projects/${projectId}`, {
|
|
660
|
+
headers: { authorization: `Bearer ${session.accessToken}` },
|
|
661
|
+
});
|
|
662
|
+
if (!response.ok)
|
|
663
|
+
throw new Error(await response.text());
|
|
664
|
+
console.log(JSON.stringify(await response.json(), null, 2));
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
throw new Error("usage: lokiplay <login|init|connect|validate|ship|deploy|status> [directory] [--project <uuid>]");
|
|
668
|
+
}
|
|
669
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
670
|
+
main(process.argv.slice(2)).catch((error) => {
|
|
671
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
672
|
+
process.exitCode = 1;
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "lokiplay",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Command-line tools for Loki game projects and deployments.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"README.md"
|
|
10
|
+
],
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"bin": {
|
|
21
|
+
"lokiplay": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && tsc -b --force && node ../../scripts/rewrite-package-imports.mjs dist",
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@lokiplay/protocol": "0.1.0",
|
|
32
|
+
"fflate": "^0.8.3"
|
|
33
|
+
}
|
|
34
|
+
}
|