@cogcoin/client 0.5.4 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/app-paths.d.ts +2 -0
- package/dist/app-paths.js +4 -0
- package/dist/art/wallet.txt +9 -9
- package/dist/bitcoind/bootstrap/chainstate.d.ts +2 -1
- package/dist/bitcoind/bootstrap/chainstate.js +4 -1
- package/dist/bitcoind/bootstrap/chunk-manifest.d.ts +14 -0
- package/dist/bitcoind/bootstrap/chunk-manifest.js +85 -0
- package/dist/bitcoind/bootstrap/chunk-recovery.d.ts +4 -0
- package/dist/bitcoind/bootstrap/chunk-recovery.js +122 -0
- package/dist/bitcoind/bootstrap/constants.d.ts +3 -1
- package/dist/bitcoind/bootstrap/constants.js +3 -1
- package/dist/bitcoind/bootstrap/controller.d.ts +10 -2
- package/dist/bitcoind/bootstrap/controller.js +56 -12
- package/dist/bitcoind/bootstrap/default-snapshot-chunk-manifest.d.ts +2 -0
- package/dist/bitcoind/bootstrap/default-snapshot-chunk-manifest.js +2309 -0
- package/dist/bitcoind/bootstrap/download.js +177 -83
- package/dist/bitcoind/bootstrap/headers.d.ts +16 -2
- package/dist/bitcoind/bootstrap/headers.js +124 -14
- package/dist/bitcoind/bootstrap/state.d.ts +11 -1
- package/dist/bitcoind/bootstrap/state.js +50 -23
- package/dist/bitcoind/bootstrap/types.d.ts +12 -1
- package/dist/bitcoind/client/factory.js +11 -2
- package/dist/bitcoind/client/internal-types.d.ts +1 -0
- package/dist/bitcoind/client/managed-client.d.ts +1 -1
- package/dist/bitcoind/client/managed-client.js +29 -15
- package/dist/bitcoind/client/sync-engine.js +88 -16
- package/dist/bitcoind/errors.js +9 -0
- package/dist/bitcoind/indexer-daemon.d.ts +7 -0
- package/dist/bitcoind/indexer-daemon.js +31 -22
- package/dist/bitcoind/processing-start-height.d.ts +7 -0
- package/dist/bitcoind/processing-start-height.js +9 -0
- package/dist/bitcoind/progress/controller.js +1 -0
- package/dist/bitcoind/progress/formatting.js +4 -1
- package/dist/bitcoind/retryable-rpc.d.ts +11 -0
- package/dist/bitcoind/retryable-rpc.js +30 -0
- package/dist/bitcoind/service.d.ts +16 -1
- package/dist/bitcoind/service.js +228 -115
- package/dist/bitcoind/testing.d.ts +1 -1
- package/dist/bitcoind/testing.js +1 -1
- package/dist/bitcoind/types.d.ts +10 -0
- package/dist/cli/commands/follow.js +9 -0
- package/dist/cli/commands/service-runtime.js +150 -134
- package/dist/cli/commands/sync.js +9 -0
- package/dist/cli/commands/wallet-admin.js +77 -21
- package/dist/cli/context.js +4 -2
- package/dist/cli/mutation-json.js +2 -0
- package/dist/cli/output.js +3 -1
- package/dist/cli/parse.d.ts +1 -1
- package/dist/cli/parse.js +6 -0
- package/dist/cli/preview-json.js +2 -0
- package/dist/cli/runner.js +1 -0
- package/dist/cli/types.d.ts +6 -3
- package/dist/cli/types.js +1 -1
- package/dist/cli/wallet-format.js +134 -14
- package/dist/wallet/lifecycle.d.ts +6 -0
- package/dist/wallet/lifecycle.js +168 -37
- package/dist/wallet/read/context.js +10 -4
- package/dist/wallet/reset.d.ts +61 -2
- package/dist/wallet/reset.js +208 -63
- package/dist/wallet/root-resolution.d.ts +20 -0
- package/dist/wallet/root-resolution.js +37 -0
- package/dist/wallet/runtime.d.ts +3 -0
- package/dist/wallet/runtime.js +3 -0
- package/dist/wallet/state/crypto.d.ts +3 -0
- package/dist/wallet/state/crypto.js +3 -0
- package/dist/wallet/state/pending-init.d.ts +24 -0
- package/dist/wallet/state/pending-init.js +59 -0
- package/dist/wallet/state/provider.d.ts +1 -0
- package/dist/wallet/state/provider.js +7 -1
- package/dist/wallet/state/storage.d.ts +7 -1
- package/dist/wallet/state/storage.js +39 -0
- package/dist/wallet/types.d.ts +9 -0
- package/package.json +4 -2
package/dist/wallet/runtime.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CogcoinPathResolution } from "../app-paths.js";
|
|
2
2
|
export interface WalletRuntimePaths {
|
|
3
3
|
dataRoot: string;
|
|
4
|
+
clientDataDir: string;
|
|
4
5
|
clientConfigPath: string;
|
|
5
6
|
runtimeRoot: string;
|
|
6
7
|
hooksRoot: string;
|
|
@@ -9,6 +10,8 @@ export interface WalletRuntimePaths {
|
|
|
9
10
|
indexerRoot: string;
|
|
10
11
|
walletStatePath: string;
|
|
11
12
|
walletStateBackupPath: string;
|
|
13
|
+
walletInitPendingPath: string;
|
|
14
|
+
walletInitPendingBackupPath: string;
|
|
12
15
|
walletUnlockSessionPath: string;
|
|
13
16
|
walletExplicitLockPath: string;
|
|
14
17
|
walletControlLockPath: string;
|
package/dist/wallet/runtime.js
CHANGED
|
@@ -3,6 +3,7 @@ export function resolveWalletRuntimePathsForTesting(resolution = {}) {
|
|
|
3
3
|
const paths = resolveCogcoinPathsForTesting(resolution);
|
|
4
4
|
return {
|
|
5
5
|
dataRoot: paths.dataRoot,
|
|
6
|
+
clientDataDir: paths.clientDataDir,
|
|
6
7
|
clientConfigPath: paths.clientConfigPath,
|
|
7
8
|
runtimeRoot: paths.runtimeRoot,
|
|
8
9
|
hooksRoot: paths.hooksRoot,
|
|
@@ -11,6 +12,8 @@ export function resolveWalletRuntimePathsForTesting(resolution = {}) {
|
|
|
11
12
|
indexerRoot: paths.indexerRoot,
|
|
12
13
|
walletStatePath: paths.walletStatePath,
|
|
13
14
|
walletStateBackupPath: paths.walletStateBackupPath,
|
|
15
|
+
walletInitPendingPath: paths.walletInitPendingPath,
|
|
16
|
+
walletInitPendingBackupPath: paths.walletInitPendingBackupPath,
|
|
14
17
|
walletUnlockSessionPath: paths.walletUnlockSessionPath,
|
|
15
18
|
walletExplicitLockPath: paths.walletExplicitLockPath,
|
|
16
19
|
walletControlLockPath: paths.walletControlLockPath,
|
|
@@ -15,6 +15,7 @@ export declare function rederiveKeyFromEnvelope(passphrase: Uint8Array | string,
|
|
|
15
15
|
export declare function encryptBytesWithKey(plaintext: Uint8Array, key: Uint8Array, metadata: {
|
|
16
16
|
format: string;
|
|
17
17
|
wrappedBy: string;
|
|
18
|
+
walletRootIdHint?: string | null;
|
|
18
19
|
argon2id?: Argon2EnvelopeParams | null;
|
|
19
20
|
secretProvider?: WalletSecretReference | null;
|
|
20
21
|
}): EncryptedEnvelopeV1;
|
|
@@ -22,10 +23,12 @@ export declare function decryptBytesWithKey(envelope: EncryptedEnvelopeV1, key:
|
|
|
22
23
|
export declare function encryptJsonWithPassphrase<T>(value: T, passphrase: Uint8Array | string, metadata: {
|
|
23
24
|
format: string;
|
|
24
25
|
wrappedBy?: string;
|
|
26
|
+
walletRootIdHint?: string | null;
|
|
25
27
|
}): Promise<EncryptedEnvelopeV1>;
|
|
26
28
|
export declare function encryptJsonWithSecretProvider<T>(value: T, provider: WalletSecretProvider, secretReference: WalletSecretReference, metadata: {
|
|
27
29
|
format: string;
|
|
28
30
|
wrappedBy?: string;
|
|
31
|
+
walletRootIdHint?: string | null;
|
|
29
32
|
}): Promise<EncryptedEnvelopeV1>;
|
|
30
33
|
export declare function decryptJsonWithPassphrase<T>(envelope: EncryptedEnvelopeV1, passphrase: Uint8Array | string): Promise<T>;
|
|
31
34
|
export declare function decryptJsonWithSecretProvider<T>(envelope: EncryptedEnvelopeV1, provider: WalletSecretProvider): Promise<T>;
|
|
@@ -76,6 +76,7 @@ export function encryptBytesWithKey(plaintext, key, metadata) {
|
|
|
76
76
|
version: 1,
|
|
77
77
|
cipher: "aes-256-gcm",
|
|
78
78
|
wrappedBy: metadata.wrappedBy,
|
|
79
|
+
walletRootIdHint: metadata.walletRootIdHint ?? null,
|
|
79
80
|
argon2id: metadata.argon2id ?? null,
|
|
80
81
|
secretProvider: metadata.secretProvider ?? null,
|
|
81
82
|
nonce: nonce.toString("base64"),
|
|
@@ -96,6 +97,7 @@ export async function encryptJsonWithPassphrase(value, passphrase, metadata) {
|
|
|
96
97
|
return encryptBytesWithKey(Buffer.from(JSON.stringify(value, jsonReplacer)), derived.key, {
|
|
97
98
|
format: metadata.format,
|
|
98
99
|
wrappedBy: metadata.wrappedBy ?? "passphrase",
|
|
100
|
+
walletRootIdHint: metadata.walletRootIdHint ?? null,
|
|
99
101
|
argon2id: derived.params,
|
|
100
102
|
});
|
|
101
103
|
}
|
|
@@ -104,6 +106,7 @@ export async function encryptJsonWithSecretProvider(value, provider, secretRefer
|
|
|
104
106
|
return encryptBytesWithKey(Buffer.from(JSON.stringify(value, jsonReplacer)), key, {
|
|
105
107
|
format: metadata.format,
|
|
106
108
|
wrappedBy: metadata.wrappedBy ?? "secret-provider",
|
|
109
|
+
walletRootIdHint: metadata.walletRootIdHint ?? null,
|
|
107
110
|
secretProvider: secretReference,
|
|
108
111
|
});
|
|
109
112
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { WalletPendingInitializationStateV1 } from "../types.js";
|
|
2
|
+
import type { WalletSecretProvider, WalletSecretReference } from "./provider.js";
|
|
3
|
+
export interface WalletPendingInitializationStoragePaths {
|
|
4
|
+
primaryPath: string;
|
|
5
|
+
backupPath: string;
|
|
6
|
+
}
|
|
7
|
+
export interface LoadedWalletPendingInitializationState {
|
|
8
|
+
source: "primary" | "backup";
|
|
9
|
+
state: WalletPendingInitializationStateV1;
|
|
10
|
+
}
|
|
11
|
+
export declare function saveWalletPendingInitializationState(paths: WalletPendingInitializationStoragePaths, state: WalletPendingInitializationStateV1, access: {
|
|
12
|
+
provider: WalletSecretProvider;
|
|
13
|
+
secretReference: WalletSecretReference;
|
|
14
|
+
}): Promise<void>;
|
|
15
|
+
export declare function loadWalletPendingInitializationState(paths: WalletPendingInitializationStoragePaths, access: {
|
|
16
|
+
provider: WalletSecretProvider;
|
|
17
|
+
}): Promise<LoadedWalletPendingInitializationState>;
|
|
18
|
+
export declare function loadWalletPendingInitializationStateOrNull(paths: WalletPendingInitializationStoragePaths, access: {
|
|
19
|
+
provider: WalletSecretProvider;
|
|
20
|
+
}): Promise<LoadedWalletPendingInitializationState | null>;
|
|
21
|
+
export declare function clearWalletPendingInitializationState(paths: WalletPendingInitializationStoragePaths, access?: {
|
|
22
|
+
provider?: WalletSecretProvider;
|
|
23
|
+
secretReference?: WalletSecretReference;
|
|
24
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { readFile, rm } from "node:fs/promises";
|
|
2
|
+
import { writeJsonFileAtomic } from "../fs/atomic.js";
|
|
3
|
+
import { decryptJsonWithSecretProvider, encryptJsonWithSecretProvider, } from "./crypto.js";
|
|
4
|
+
function isMissingFileError(error) {
|
|
5
|
+
return error instanceof Error
|
|
6
|
+
&& "code" in error
|
|
7
|
+
&& error.code === "ENOENT";
|
|
8
|
+
}
|
|
9
|
+
async function readEnvelope(path) {
|
|
10
|
+
const raw = await readFile(path, "utf8");
|
|
11
|
+
return JSON.parse(raw);
|
|
12
|
+
}
|
|
13
|
+
async function loadFromPath(path, source, provider) {
|
|
14
|
+
return {
|
|
15
|
+
source,
|
|
16
|
+
state: await decryptJsonWithSecretProvider(await readEnvelope(path), provider),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export async function saveWalletPendingInitializationState(paths, state, access) {
|
|
20
|
+
const envelope = await encryptJsonWithSecretProvider(state, access.provider, access.secretReference, {
|
|
21
|
+
format: "cogcoin-wallet-init-pending-state",
|
|
22
|
+
});
|
|
23
|
+
await writeJsonFileAtomic(paths.primaryPath, envelope, { mode: 0o600 });
|
|
24
|
+
await writeJsonFileAtomic(paths.backupPath, envelope, { mode: 0o600 });
|
|
25
|
+
}
|
|
26
|
+
export async function loadWalletPendingInitializationState(paths, access) {
|
|
27
|
+
try {
|
|
28
|
+
return await loadFromPath(paths.primaryPath, "primary", access.provider);
|
|
29
|
+
}
|
|
30
|
+
catch (primaryError) {
|
|
31
|
+
try {
|
|
32
|
+
return await loadFromPath(paths.backupPath, "backup", access.provider);
|
|
33
|
+
}
|
|
34
|
+
catch (backupError) {
|
|
35
|
+
if (isMissingFileError(primaryError)) {
|
|
36
|
+
throw backupError;
|
|
37
|
+
}
|
|
38
|
+
throw primaryError;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export async function loadWalletPendingInitializationStateOrNull(paths, access) {
|
|
43
|
+
try {
|
|
44
|
+
return await loadWalletPendingInitializationState(paths, access);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (isMissingFileError(error)) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export async function clearWalletPendingInitializationState(paths, access) {
|
|
54
|
+
await rm(paths.primaryPath, { force: true }).catch(() => undefined);
|
|
55
|
+
await rm(paths.backupPath, { force: true }).catch(() => undefined);
|
|
56
|
+
if (access?.provider != null && access.secretReference != null) {
|
|
57
|
+
await access.provider.deleteSecret(access.secretReference.keyId).catch(() => undefined);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -23,6 +23,7 @@ export interface WalletSecretProvider {
|
|
|
23
23
|
deleteSecret(keyId: string): Promise<void>;
|
|
24
24
|
}
|
|
25
25
|
export declare function createWalletSecretReference(walletRootId: string): WalletSecretReference;
|
|
26
|
+
export declare function createWalletPendingInitSecretReference(stateRoot: string): WalletSecretReference;
|
|
26
27
|
export declare class MemoryWalletSecretProvider implements WalletSecretProvider {
|
|
27
28
|
#private;
|
|
28
29
|
readonly kind = "memory-test";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { randomUUID } from "node:crypto";
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import { execFile, spawn } from "node:child_process";
|
|
3
3
|
import { mkdir, readFile, rm } from "node:fs/promises";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
@@ -17,6 +17,12 @@ export function createWalletSecretReference(walletRootId) {
|
|
|
17
17
|
keyId: `wallet-state:${walletRootId}`,
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
+
export function createWalletPendingInitSecretReference(stateRoot) {
|
|
21
|
+
return {
|
|
22
|
+
kind: "wallet-init-pending-key",
|
|
23
|
+
keyId: `wallet-init-pending:${createHash("sha256").update(stateRoot).digest("hex")}`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
20
26
|
function bytesToBase64(secret) {
|
|
21
27
|
return Buffer.from(secret).toString("base64");
|
|
22
28
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { WalletStateV1 } from "../types.js";
|
|
1
|
+
import type { EncryptedEnvelopeV1, WalletStateV1 } from "../types.js";
|
|
2
2
|
import type { WalletSecretProvider, WalletSecretReference } from "./provider.js";
|
|
3
3
|
export interface WalletStateStoragePaths {
|
|
4
4
|
primaryPath: string;
|
|
@@ -8,6 +8,10 @@ export interface LoadedWalletState {
|
|
|
8
8
|
source: "primary" | "backup";
|
|
9
9
|
state: WalletStateV1;
|
|
10
10
|
}
|
|
11
|
+
export interface RawWalletStateEnvelope {
|
|
12
|
+
source: "primary" | "backup";
|
|
13
|
+
envelope: EncryptedEnvelopeV1;
|
|
14
|
+
}
|
|
11
15
|
export type WalletStateSaveAccess = Uint8Array | string | {
|
|
12
16
|
provider: WalletSecretProvider;
|
|
13
17
|
secretReference: WalletSecretReference;
|
|
@@ -15,5 +19,7 @@ export type WalletStateSaveAccess = Uint8Array | string | {
|
|
|
15
19
|
export type WalletStateLoadAccess = Uint8Array | string | {
|
|
16
20
|
provider: WalletSecretProvider;
|
|
17
21
|
};
|
|
22
|
+
export declare function loadRawWalletStateEnvelope(paths: WalletStateStoragePaths): Promise<RawWalletStateEnvelope | null>;
|
|
23
|
+
export declare function extractWalletRootIdHintFromWalletStateEnvelope(envelope: EncryptedEnvelopeV1 | null): string | null;
|
|
18
24
|
export declare function saveWalletState(paths: WalletStateStoragePaths, state: WalletStateV1, access: WalletStateSaveAccess): Promise<void>;
|
|
19
25
|
export declare function loadWalletState(paths: WalletStateStoragePaths, access: WalletStateLoadAccess): Promise<LoadedWalletState>;
|
|
@@ -5,6 +5,43 @@ async function readEnvelope(path) {
|
|
|
5
5
|
const raw = await readFile(path, "utf8");
|
|
6
6
|
return JSON.parse(raw);
|
|
7
7
|
}
|
|
8
|
+
export async function loadRawWalletStateEnvelope(paths) {
|
|
9
|
+
try {
|
|
10
|
+
return {
|
|
11
|
+
source: "primary",
|
|
12
|
+
envelope: await readEnvelope(paths.primaryPath),
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
catch (primaryError) {
|
|
16
|
+
try {
|
|
17
|
+
return {
|
|
18
|
+
source: "backup",
|
|
19
|
+
envelope: await readEnvelope(paths.backupPath),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
if (primaryError instanceof SyntaxError
|
|
24
|
+
|| !(primaryError instanceof Error)
|
|
25
|
+
|| !("code" in primaryError)
|
|
26
|
+
|| primaryError.code !== "ENOENT") {
|
|
27
|
+
throw primaryError;
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function extractWalletRootIdHintFromWalletStateEnvelope(envelope) {
|
|
34
|
+
const hint = envelope?.walletRootIdHint?.trim() ?? "";
|
|
35
|
+
if (hint.length > 0) {
|
|
36
|
+
return hint;
|
|
37
|
+
}
|
|
38
|
+
const keyId = envelope?.secretProvider?.keyId ?? null;
|
|
39
|
+
const prefix = "wallet-state:";
|
|
40
|
+
if (keyId === null || !keyId.startsWith(prefix)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return keyId.slice(prefix.length);
|
|
44
|
+
}
|
|
8
45
|
export async function saveWalletState(paths, state, access) {
|
|
9
46
|
let previousPrimary = null;
|
|
10
47
|
try {
|
|
@@ -21,9 +58,11 @@ export async function saveWalletState(paths, state, access) {
|
|
|
21
58
|
const envelope = typeof access === "string" || access instanceof Uint8Array
|
|
22
59
|
? await encryptJsonWithPassphrase(state, access, {
|
|
23
60
|
format: "cogcoin-local-wallet-state",
|
|
61
|
+
walletRootIdHint: state.walletRootId,
|
|
24
62
|
})
|
|
25
63
|
: await encryptJsonWithSecretProvider(state, access.provider, access.secretReference, {
|
|
26
64
|
format: "cogcoin-local-wallet-state",
|
|
65
|
+
walletRootIdHint: state.walletRootId,
|
|
27
66
|
});
|
|
28
67
|
await writeJsonFileAtomic(paths.primaryPath, envelope, { mode: 0o600 });
|
|
29
68
|
if (previousPrimary !== null) {
|
package/dist/wallet/types.d.ts
CHANGED
|
@@ -229,6 +229,7 @@ export interface EncryptedEnvelopeV1 {
|
|
|
229
229
|
version: 1;
|
|
230
230
|
cipher: "aes-256-gcm";
|
|
231
231
|
wrappedBy: string;
|
|
232
|
+
walletRootIdHint?: string | null;
|
|
232
233
|
argon2id?: Argon2EnvelopeParams | null;
|
|
233
234
|
secretProvider?: {
|
|
234
235
|
kind: string;
|
|
@@ -252,3 +253,11 @@ export interface WalletExplicitLockStateV1 {
|
|
|
252
253
|
walletRootId: string;
|
|
253
254
|
lockedAtUnixMs: number;
|
|
254
255
|
}
|
|
256
|
+
export interface WalletPendingInitializationStateV1 {
|
|
257
|
+
schemaVersion: 1;
|
|
258
|
+
createdAtUnixMs: number;
|
|
259
|
+
mnemonic: {
|
|
260
|
+
phrase: string;
|
|
261
|
+
language: WalletMnemonicLanguage;
|
|
262
|
+
};
|
|
263
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cogcoin/client",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
4
4
|
"description": "Store-backed Cogcoin client with wallet flows, SQLite persistence, and managed Bitcoin Core integration.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -53,10 +53,12 @@
|
|
|
53
53
|
"files": [
|
|
54
54
|
"LICENSE",
|
|
55
55
|
"README.md",
|
|
56
|
-
"dist
|
|
56
|
+
"dist"
|
|
57
57
|
],
|
|
58
58
|
"scripts": {
|
|
59
59
|
"build": "rm -rf dist && node ./node_modules/typescript/bin/tsc -p tsconfig.json && node -e \"import('node:fs/promises').then(async (fs) => { await fs.mkdir('dist/art', { recursive: true }); await Promise.all([fs.copyFile('src/writing_quotes.json', 'dist/writing_quotes.json'), fs.copyFile('src/art/banner.txt', 'dist/art/banner.txt'), fs.copyFile('src/art/scroll.txt', 'dist/art/scroll.txt'), fs.copyFile('src/art/train-smoke.txt', 'dist/art/train-smoke.txt'), fs.copyFile('src/art/train.txt', 'dist/art/train.txt'), fs.copyFile('src/art/train-car.txt', 'dist/art/train-car.txt'), fs.copyFile('src/art/wallet.txt', 'dist/art/wallet.txt')]); })\"",
|
|
60
|
+
"generate:default-snapshot-chunk-manifest": "node scripts/generate-default-snapshot-chunk-manifest.mjs",
|
|
61
|
+
"verify:default-snapshot-chunk-manifest": "node scripts/generate-default-snapshot-chunk-manifest.mjs --check",
|
|
60
62
|
"test": "rm -rf .test-dist && node ./node_modules/typescript/bin/tsc -p tsconfig.test.json && node -e \"import('node:fs/promises').then(async (fs) => { await fs.mkdir('.test-dist/src/art', { recursive: true }); await Promise.all([fs.copyFile('src/writing_quotes.json', '.test-dist/src/writing_quotes.json'), fs.copyFile('src/art/banner.txt', '.test-dist/src/art/banner.txt'), fs.copyFile('src/art/scroll.txt', '.test-dist/src/art/scroll.txt'), fs.copyFile('src/art/train-smoke.txt', '.test-dist/src/art/train-smoke.txt'), fs.copyFile('src/art/train.txt', '.test-dist/src/art/train.txt'), fs.copyFile('src/art/train-car.txt', '.test-dist/src/art/train-car.txt'), fs.copyFile('src/art/wallet.txt', '.test-dist/src/art/wallet.txt')]); })\" && node --test .test-dist/test/*.test.js"
|
|
61
63
|
},
|
|
62
64
|
"dependencies": {
|