buildpartner 0.10.0 → 0.11.0-dev.20260803211229
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/dist/src/api-client.d.ts +9 -0
- package/dist/src/api-client.js +13 -1
- package/dist/src/api-client.js.map +1 -1
- package/dist/src/commands/login.d.ts +7 -1
- package/dist/src/commands/login.js +39 -8
- package/dist/src/commands/login.js.map +1 -1
- package/dist/src/mcp/server.js +24 -9
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/store/local-store.d.ts +0 -10
- package/dist/src/store/local-store.js +0 -15
- package/dist/src/store/local-store.js.map +1 -1
- package/package.json +1 -1
package/dist/src/api-client.d.ts
CHANGED
|
@@ -3,7 +3,16 @@
|
|
|
3
3
|
* All API calls from the CLI go through this module.
|
|
4
4
|
* Handles auth headers, timeouts, and error logging automatically.
|
|
5
5
|
*/
|
|
6
|
+
/** Default (production) API base used when nothing else is configured. */
|
|
7
|
+
export declare const DEFAULT_API_BASE = "https://www.buildpartner.ai";
|
|
6
8
|
export declare const API_BASE: string;
|
|
9
|
+
/**
|
|
10
|
+
* True when a base URL points at production. We only persist api_base in
|
|
11
|
+
* auth.json for non-prod bases, so a normal user's file stays clean and the
|
|
12
|
+
* default resolution (which already falls back to prod) applies. Mirrors the
|
|
13
|
+
* prod check in plugin/scripts/install.sh.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isProdApiBase(base: string): boolean;
|
|
7
16
|
/**
|
|
8
17
|
* Make an authenticated request to the BuildPartner API.
|
|
9
18
|
* Returns the raw Response, or null if offline/unauthenticated.
|
package/dist/src/api-client.js
CHANGED
|
@@ -4,15 +4,27 @@
|
|
|
4
4
|
* Handles auth headers, timeouts, and error logging automatically.
|
|
5
5
|
*/
|
|
6
6
|
import { readAuth, logError } from "./store/local-store.js";
|
|
7
|
+
/** Default (production) API base used when nothing else is configured. */
|
|
8
|
+
export const DEFAULT_API_BASE = "https://www.buildpartner.ai";
|
|
7
9
|
function getApiBase() {
|
|
8
10
|
if (process.env.BP_API_BASE)
|
|
9
11
|
return process.env.BP_API_BASE;
|
|
10
12
|
const auth = readAuth();
|
|
11
13
|
if (auth?.api_base)
|
|
12
14
|
return auth.api_base;
|
|
13
|
-
return
|
|
15
|
+
return DEFAULT_API_BASE;
|
|
14
16
|
}
|
|
15
17
|
export const API_BASE = getApiBase();
|
|
18
|
+
/**
|
|
19
|
+
* True when a base URL points at production. We only persist api_base in
|
|
20
|
+
* auth.json for non-prod bases, so a normal user's file stays clean and the
|
|
21
|
+
* default resolution (which already falls back to prod) applies. Mirrors the
|
|
22
|
+
* prod check in plugin/scripts/install.sh.
|
|
23
|
+
*/
|
|
24
|
+
export function isProdApiBase(base) {
|
|
25
|
+
const host = base.replace(/^https?:\/\//, "").replace(/\/.*$/, "");
|
|
26
|
+
return host === "buildpartner.ai" || host === "www.buildpartner.ai";
|
|
27
|
+
}
|
|
16
28
|
/**
|
|
17
29
|
* Make an authenticated request to the BuildPartner API.
|
|
18
30
|
* Returns the raw Response, or null if offline/unauthenticated.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/api-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAE5D,SAAS,UAAU;IACjB,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAC5D,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,IAAI,EAAE,QAAQ;QAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzC,OAAO,
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/api-client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAE5D,0EAA0E;AAC1E,MAAM,CAAC,MAAM,gBAAgB,GAAG,6BAA6B,CAAC;AAE9D,SAAS,UAAU;IACjB,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IAC5D,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,IAAI,EAAE,QAAQ;QAAE,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AACD,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,EAAE,CAAC;AAErC;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACnE,OAAO,IAAI,KAAK,iBAAiB,IAAI,IAAI,KAAK,qBAAqB,CAAC;AACtE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAY,EAAE,OAAqB;IAChE,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,IAAI,EAAE,KAAK;QAAE,OAAO,IAAI,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,QAAQ,GAAG,IAAI,EAAE,EAAE;YAC5C,GAAG,OAAO;YACV,OAAO,EAAE;gBACP,eAAe,EAAE,UAAU,IAAI,CAAC,KAAK,EAAE;gBACvC,cAAc,EAAE,kBAAkB;gBAClC,GAAG,OAAO,EAAE,OAAO;aACpB;YACD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,QAAQ,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAI,IAAY;IAC1C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAI,IAAY,EAAE,IAAa;IAC1D,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE;QAC/B,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,GAAG,CAAC,IAAI,EAAgB,CAAC;AAClC,CAAC"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `buildpartner login <token
|
|
2
|
+
* `buildpartner login <token> [--api <url>]` - Connect an existing account on a new machine.
|
|
3
3
|
*
|
|
4
4
|
* Takes an sk_ token (provided by the dashboard after OTP verification),
|
|
5
5
|
* verifies it against the API, and saves it locally.
|
|
6
|
+
*
|
|
7
|
+
* `--api <url>` (or the BP_API_BASE env var) points the CLI at a non-prod
|
|
8
|
+
* environment. When set to a non-prod base, we persist it as `api_base` in
|
|
9
|
+
* auth.json so every later call sticks to that environment. The dashboard's
|
|
10
|
+
* login page injects this flag automatically when it is not on prod, so a dev
|
|
11
|
+
* user's copy-pasted command just works. Mirrors plugin/scripts/install.sh.
|
|
6
12
|
*/
|
|
7
13
|
export declare function login(): Promise<void>;
|
|
@@ -1,15 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `buildpartner login <token
|
|
2
|
+
* `buildpartner login <token> [--api <url>]` - Connect an existing account on a new machine.
|
|
3
3
|
*
|
|
4
4
|
* Takes an sk_ token (provided by the dashboard after OTP verification),
|
|
5
5
|
* verifies it against the API, and saves it locally.
|
|
6
|
+
*
|
|
7
|
+
* `--api <url>` (or the BP_API_BASE env var) points the CLI at a non-prod
|
|
8
|
+
* environment. When set to a non-prod base, we persist it as `api_base` in
|
|
9
|
+
* auth.json so every later call sticks to that environment. The dashboard's
|
|
10
|
+
* login page injects this flag automatically when it is not on prod, so a dev
|
|
11
|
+
* user's copy-pasted command just works. Mirrors plugin/scripts/install.sh.
|
|
6
12
|
*/
|
|
7
13
|
import chalk from "chalk";
|
|
8
14
|
import { writeAuth } from "../store/local-store.js";
|
|
9
|
-
import {
|
|
15
|
+
import { DEFAULT_API_BASE, isProdApiBase } from "../api-client.js";
|
|
10
16
|
const orange = chalk.hex("#E47025");
|
|
17
|
+
/** Pull the token and an optional --api base out of the login argv. */
|
|
18
|
+
function parseArgs(argv) {
|
|
19
|
+
let token;
|
|
20
|
+
let apiFlag;
|
|
21
|
+
// argv here is process.argv.slice(3) -> everything after `login`.
|
|
22
|
+
for (let i = 0; i < argv.length; i++) {
|
|
23
|
+
const arg = argv[i];
|
|
24
|
+
if (arg === "--api") {
|
|
25
|
+
apiFlag = argv[i + 1];
|
|
26
|
+
i++;
|
|
27
|
+
}
|
|
28
|
+
else if (arg.startsWith("--api=")) {
|
|
29
|
+
apiFlag = arg.slice("--api=".length);
|
|
30
|
+
}
|
|
31
|
+
else if (!arg.startsWith("-") && !token) {
|
|
32
|
+
token = arg;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const apiBase = (apiFlag || process.env.BP_API_BASE || DEFAULT_API_BASE).replace(/\/$/, "");
|
|
36
|
+
return { token, apiBase };
|
|
37
|
+
}
|
|
11
38
|
export async function login() {
|
|
12
|
-
const token = process.argv
|
|
39
|
+
const { token, apiBase } = parseArgs(process.argv.slice(3));
|
|
40
|
+
const domain = apiBase.replace(/^https?:\/\//, "");
|
|
13
41
|
if (!token || !token.startsWith("sk_")) {
|
|
14
42
|
console.log();
|
|
15
43
|
console.log(chalk.red(" ✗ Missing or invalid token."));
|
|
@@ -17,14 +45,14 @@ export async function login() {
|
|
|
17
45
|
console.log(" Usage: npx buildpartner login sk_your_token_here");
|
|
18
46
|
console.log();
|
|
19
47
|
console.log(chalk.dim(" Get your token by signing in at:"));
|
|
20
|
-
console.log(chalk.dim(` ${
|
|
48
|
+
console.log(chalk.dim(` ${apiBase}/dashboard/login?connect=1`));
|
|
21
49
|
console.log();
|
|
22
50
|
process.exit(1);
|
|
23
51
|
}
|
|
24
52
|
console.log();
|
|
25
53
|
console.log(chalk.dim(" Verifying token..."));
|
|
26
54
|
try {
|
|
27
|
-
const res = await fetch(`${
|
|
55
|
+
const res = await fetch(`${apiBase}/api/buildpartner/verify-token`, {
|
|
28
56
|
headers: { Authorization: `Bearer ${token}` },
|
|
29
57
|
signal: AbortSignal.timeout(10000),
|
|
30
58
|
});
|
|
@@ -32,7 +60,7 @@ export async function login() {
|
|
|
32
60
|
console.log(chalk.red(" ✗ Invalid token. It may have expired or been reset."));
|
|
33
61
|
console.log();
|
|
34
62
|
console.log(chalk.dim(" Sign in again at:"));
|
|
35
|
-
console.log(chalk.dim(` ${
|
|
63
|
+
console.log(chalk.dim(` ${apiBase}/dashboard/login?connect=1`));
|
|
36
64
|
console.log();
|
|
37
65
|
process.exit(1);
|
|
38
66
|
}
|
|
@@ -41,8 +69,11 @@ export async function login() {
|
|
|
41
69
|
email: data.email,
|
|
42
70
|
username: data.username,
|
|
43
71
|
token,
|
|
44
|
-
profile_url: data.profile_url ||
|
|
72
|
+
profile_url: data.profile_url || `${domain}/${data.username}`,
|
|
45
73
|
created_at: data.created_at || new Date().toISOString(),
|
|
74
|
+
// Only persist api_base for non-prod, so a normal user's auth.json stays
|
|
75
|
+
// clean and the default (prod) resolution applies.
|
|
76
|
+
...(isProdApiBase(apiBase) ? {} : { api_base: apiBase }),
|
|
46
77
|
});
|
|
47
78
|
console.log(chalk.green(` ✓ Logged in as ${data.email}`));
|
|
48
79
|
console.log();
|
|
@@ -52,7 +83,7 @@ export async function login() {
|
|
|
52
83
|
console.log();
|
|
53
84
|
}
|
|
54
85
|
catch {
|
|
55
|
-
console.log(chalk.red(
|
|
86
|
+
console.log(chalk.red(` ✗ Could not reach ${domain}. Check your connection and try again.`));
|
|
56
87
|
console.log();
|
|
57
88
|
process.exit(1);
|
|
58
89
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/commands/login.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
package/dist/src/mcp/server.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
11
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
12
|
import { z } from "zod";
|
|
13
|
-
import { apiFetch } from "../api-client.js";
|
|
13
|
+
import { apiFetch, API_BASE } from "../api-client.js";
|
|
14
14
|
import { readAuth } from "../store/local-store.js";
|
|
15
15
|
import { readFileSync } from "fs";
|
|
16
16
|
import { join, dirname } from "path";
|
|
@@ -30,7 +30,14 @@ function getCliVersion() {
|
|
|
30
30
|
}
|
|
31
31
|
/** Helper to format a text response for MCP */
|
|
32
32
|
const textResponse = (text) => ({ content: [{ type: "text", text }] });
|
|
33
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Where we send someone whose machine has no usable token. This page verifies
|
|
35
|
+
* their email and hands back the `buildpartner login` command, which is one hop
|
|
36
|
+
* instead of routing them through the installer only to be told the email is
|
|
37
|
+
* already registered. Env-aware via API_BASE so dev installs stay on dev.
|
|
38
|
+
*/
|
|
39
|
+
const CONNECT_URL = `${API_BASE}/dashboard/login?connect=1`;
|
|
40
|
+
const NOT_SIGNED_IN = `Not signed in. If you're new, run: curl -fsSL https://buildpartner.ai/install.sh | sh — if you already have an account, reconnect this machine at ${CONNECT_URL}`;
|
|
34
41
|
/** Check if the user has auth. Returns an error response if not, null if OK. */
|
|
35
42
|
function requireLocalAuth() {
|
|
36
43
|
const auth = readAuth();
|
|
@@ -41,16 +48,16 @@ function requireLocalAuth() {
|
|
|
41
48
|
/** Turn an HTTP error status into a message the user can act on. */
|
|
42
49
|
function friendlyError(status) {
|
|
43
50
|
if (status === 401)
|
|
44
|
-
return
|
|
51
|
+
return `Not logged in. Reconnect this machine at ${CONNECT_URL} — verify your email there and it gives you the command to paste.`;
|
|
45
52
|
if (status === 404)
|
|
46
|
-
return
|
|
53
|
+
return `Account not found. Your login may be out of date. Reconnect this machine at ${CONNECT_URL}.`;
|
|
47
54
|
if (status === 403)
|
|
48
55
|
return ""; // handled separately (subscription block)
|
|
49
56
|
if (status === 503)
|
|
50
57
|
return "BuildPartner is temporarily unavailable. Try again in a minute.";
|
|
51
58
|
if (status >= 500)
|
|
52
59
|
return "BuildPartner's server hit an error. Try again in a minute. If it keeps happening, visit buildpartner.ai for status updates.";
|
|
53
|
-
return `Something went wrong (${status}).
|
|
60
|
+
return `Something went wrong (${status}). Try again shortly, or reconnect this machine at ${CONNECT_URL}.`;
|
|
54
61
|
}
|
|
55
62
|
/**
|
|
56
63
|
* Handle a 403 (subscription limit) gracefully.
|
|
@@ -93,10 +100,16 @@ export function createServer() {
|
|
|
93
100
|
return textResponse(JSON.stringify({ error: friendlyError(res.status) }));
|
|
94
101
|
return textResponse(JSON.stringify(await res.json(), null, 2));
|
|
95
102
|
});
|
|
96
|
-
server.tool("get_build", "Fetch BuildPartner
|
|
97
|
-
current: z.boolean().optional().describe("Return the
|
|
98
|
-
slug: z.string().optional().describe("Return a specific build by slug"),
|
|
99
|
-
|
|
103
|
+
server.tool("get_build", "Fetch BuildPartner build content to walk a user through it one step at a time. No args: index of all builds plus which slug is current. current=true (or slug): the build's ORIENTATION (benefit, summary, stepCount, outcome) but NOT the steps. slug+step=N (1-indexed): a single step with its prompt/inputs/verify. Open a build with orientation, then pull steps one by one using the slug it returns. Locked archive builds return a stub unless the user's plan unlocks them.", {
|
|
104
|
+
current: z.boolean().optional().describe("Return the current featured build's orientation (no steps)"),
|
|
105
|
+
slug: z.string().optional().describe("Return a specific build's orientation by slug"),
|
|
106
|
+
step: z
|
|
107
|
+
.number()
|
|
108
|
+
.int()
|
|
109
|
+
.positive()
|
|
110
|
+
.optional()
|
|
111
|
+
.describe("With slug (or current), return just this step (1-indexed). Walk one step at a time."),
|
|
112
|
+
}, async ({ current, slug, step }) => {
|
|
100
113
|
const authErr = requireLocalAuth();
|
|
101
114
|
if (authErr)
|
|
102
115
|
return authErr;
|
|
@@ -105,6 +118,8 @@ export function createServer() {
|
|
|
105
118
|
params.set("current", "1");
|
|
106
119
|
if (slug)
|
|
107
120
|
params.set("slug", slug);
|
|
121
|
+
if (step)
|
|
122
|
+
params.set("step", String(step));
|
|
108
123
|
const queryString = params.toString();
|
|
109
124
|
const path = queryString ? `/api/builds?${queryString}` : "/api/builds";
|
|
110
125
|
const res = await apiFetch(path);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,15 +21,5 @@ export declare function readAuth(): AuthData | null;
|
|
|
21
21
|
export declare function writeAuth(auth: AuthData): void;
|
|
22
22
|
/** Append an error to the local error log for diagnostics. */
|
|
23
23
|
export declare function logError(error: unknown): void;
|
|
24
|
-
export interface AccessState {
|
|
25
|
-
has_access: boolean;
|
|
26
|
-
remaining: number;
|
|
27
|
-
plan: "free" | "pro";
|
|
28
|
-
checked_at: string;
|
|
29
|
-
}
|
|
30
|
-
/** Read cached access state from disk. Returns null on failure. */
|
|
31
|
-
export declare function readAccess(): AccessState | null;
|
|
32
|
-
/** Write access state to disk. */
|
|
33
|
-
export declare function writeAccess(access: AccessState): void;
|
|
34
24
|
/** Append one event as a JSON line to the spool file. */
|
|
35
25
|
export declare function appendSpool(event: Record<string, unknown>): void;
|
|
@@ -45,22 +45,7 @@ export function logError(error) {
|
|
|
45
45
|
// If we can't even log errors, silently fail
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
-
const ACCESS_FILE = join(BUILDPARTNER_DIR, "access.json");
|
|
49
48
|
const SPOOL_FILE = join(BUILDPARTNER_DIR, "spool.ndjson");
|
|
50
|
-
/** Read cached access state from disk. Returns null on failure. */
|
|
51
|
-
export function readAccess() {
|
|
52
|
-
try {
|
|
53
|
-
return JSON.parse(readFileSync(ACCESS_FILE, "utf-8").replace(/^\uFEFF/, ""));
|
|
54
|
-
}
|
|
55
|
-
catch {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
/** Write access state to disk. */
|
|
60
|
-
export function writeAccess(access) {
|
|
61
|
-
ensureDir();
|
|
62
|
-
writeFileSync(ACCESS_FILE, JSON.stringify(access, null, 2) + "\n");
|
|
63
|
-
}
|
|
64
49
|
/** Append one event as a JSON line to the spool file. */
|
|
65
50
|
export function appendSpool(event) {
|
|
66
51
|
ensureDir();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-store.js","sourceRoot":"","sources":["../../../src/store/local-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AACxF,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;AACtD,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;AAWvD,+CAA+C;AAC/C,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAClC,SAAS,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,kBAAkB;IAChC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,QAAQ;IACtB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAa,CAAC;IACzF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,SAAS,EAAE,CAAC;IACZ,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,IAAI,CAAC;QACH,SAAS,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtF,cAAc,CAAC,SAAS,EAAE,IAAI,SAAS,KAAK,OAAO,IAAI,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;IAC/C,CAAC;AACH,CAAC;AAED,MAAM,
|
|
1
|
+
{"version":3,"file":"local-store.js","sourceRoot":"","sources":["../../../src/store/local-store.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AACxF,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;AACtD,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;AAWvD,+CAA+C;AAC/C,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAClC,SAAS,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,kBAAkB;IAChC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,QAAQ;IACtB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAa,CAAC;IACzF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,SAAS,EAAE,CAAC;IACZ,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,IAAI,CAAC;QACH,SAAS,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtF,cAAc,CAAC,SAAS,EAAE,IAAI,SAAS,KAAK,OAAO,IAAI,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;IAC/C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC;AAE1D,yDAAyD;AACzD,MAAM,UAAU,WAAW,CAAC,KAA8B;IACxD,SAAS,EAAE,CAAC;IACZ,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;AAC3D,CAAC"}
|