firebase-mcp 0.3.1 → 0.3.3
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 +78 -44
- package/dist/config/index.test.d.ts +2 -0
- package/dist/config/index.test.d.ts.map +1 -0
- package/dist/config/index.test.js +98 -0
- package/dist/config/index.test.js.map +1 -0
- package/dist/task/index.test.d.ts +2 -0
- package/dist/task/index.test.d.ts.map +1 -0
- package/dist/task/index.test.js +318 -0
- package/dist/task/index.test.js.map +1 -0
- package/dist/tools/firestore/utils/paths.test.d.ts +2 -0
- package/dist/tools/firestore/utils/paths.test.d.ts.map +1 -0
- package/dist/tools/firestore/utils/paths.test.js +68 -0
- package/dist/tools/firestore/utils/paths.test.js.map +1 -0
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -4,39 +4,53 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that ex
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **2 Firebase Auth
|
|
7
|
+
- **12 Firestore read operations** covering collections, documents, queries, aggregations, distinct value counts, and schema inference
|
|
8
|
+
- **2 Firebase Auth operations** — look up users by UID or email, list users with pagination
|
|
9
|
+
- **Multi-project support** — configure multiple Firebase projects in one config file; each tool call targets a specific project via `projectId`
|
|
9
10
|
- **Glob-based access control** — allow/deny rules evaluated per Firestore path before any read is performed
|
|
10
11
|
- **Pagination** on `query_collection`, `read_collection`, and `list_users` via cursor-based tokens
|
|
11
12
|
- **Batch fetching** with configurable `maxBatchFetchSize`
|
|
12
13
|
- **Schema inference** via `get_collection_schema` — samples documents and infers field types without reading the full collection
|
|
14
|
+
- **Distinct value counts** via `distinct_values` — count occurrences of unique field values across a collection or collection group
|
|
13
15
|
- **Normalized output** — Firestore Timestamps, GeoPoints, and DocumentReferences are converted to JSON-serializable values on all tools
|
|
14
16
|
- Zero runtime state — each tool call hits Firebase directly through the Admin SDK
|
|
15
17
|
|
|
16
18
|
## Tools
|
|
17
19
|
|
|
18
|
-
###
|
|
19
|
-
|
|
20
|
-
| Tool
|
|
21
|
-
|
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
20
|
+
### Config
|
|
21
|
+
|
|
22
|
+
| Tool | Description |
|
|
23
|
+
| --------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
24
|
+
| `get_config` | Returns the current in-memory config, listing all available projects. Call this first to discover valid `projectId` values. |
|
|
25
|
+
| `reload_config` | Re-reads `firebase-mcp.json` from disk and evicts all cached project runtimes. |
|
|
26
|
+
|
|
27
|
+
### Firestore (`firestore_read`)
|
|
28
|
+
|
|
29
|
+
All operations are dispatched through the single `firestore_read` tool via the `operation` field. Every call requires a `projectId` matching a key in `firebase-mcp.json`.
|
|
30
|
+
|
|
31
|
+
| Operation | Description |
|
|
32
|
+
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
33
|
+
| `list_collections` | List root collections or subcollections of a document. Optionally include document counts. |
|
|
34
|
+
| `list_documents` | List all document IDs in a collection, including phantom documents. Optionally include subcollection names. |
|
|
35
|
+
| `read_collection` | Read documents from a collection with optional phantom-doc surfacing. |
|
|
36
|
+
| `get_document` | Fetch a single document by path. |
|
|
37
|
+
| `get_many_documents` | Batch-fetch documents by a list of paths or a collection + ID list. |
|
|
38
|
+
| `query_collection` | Query with filters, ordering, limit, and pagination. |
|
|
39
|
+
| `query_collection_group` | Query across all collections sharing the same name, regardless of parent path. |
|
|
40
|
+
| `count_documents` | Server-side document count with optional filters. |
|
|
41
|
+
| `aggregate_collection` | Native `sum()`, `avg()`, and `count()` aggregations without fetching documents. |
|
|
42
|
+
| `get_collection_schema` | Sample a collection from both ends and infer field types. |
|
|
43
|
+
| `list_indexes` | List Firestore composite indexes for the project. |
|
|
44
|
+
| `distinct_values` | Count occurrences of each unique value (or value combination) of one or more fields across a collection or collection group. |
|
|
45
|
+
|
|
46
|
+
### Auth (`auth_read`)
|
|
47
|
+
|
|
48
|
+
All operations are dispatched through the single `auth_read` tool via the `operation` field. Every call requires a `projectId`.
|
|
49
|
+
|
|
50
|
+
| Operation | Description |
|
|
51
|
+
| ------------ | ------------------------------------------------------------------ |
|
|
52
|
+
| `get_user` | Fetch a Firebase Auth user by UID or email. |
|
|
53
|
+
| `list_users` | List Firebase Auth users with optional pagination via `pageToken`. |
|
|
40
54
|
|
|
41
55
|
## Requirements
|
|
42
56
|
|
|
@@ -48,26 +62,43 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that ex
|
|
|
48
62
|
|
|
49
63
|
**1. Create `firebase-mcp.json`**
|
|
50
64
|
|
|
65
|
+
The config supports multiple projects under a `projects` key. Each key becomes the `projectId` value you pass to tool calls.
|
|
66
|
+
|
|
51
67
|
```json
|
|
52
68
|
{
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
"projects": {
|
|
70
|
+
"my-app": {
|
|
71
|
+
"firebase": {
|
|
72
|
+
"projectId": "your-firebase-project-id",
|
|
73
|
+
"serviceAccountPath": "secrets/serviceAccount.json"
|
|
74
|
+
},
|
|
75
|
+
"firestore": {
|
|
76
|
+
"rules": {
|
|
77
|
+
"allow": ["**"],
|
|
78
|
+
"deny": []
|
|
79
|
+
},
|
|
80
|
+
"maxCollectionReadSize": 100,
|
|
81
|
+
"maxBatchFetchSize": 200
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
To configure multiple projects, add additional keys under `projects`:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"projects": {
|
|
93
|
+
"prod": { "firebase": { ... }, "firestore": { ... } },
|
|
94
|
+
"staging": { "firebase": { ... }, "firestore": { ... } }
|
|
64
95
|
}
|
|
65
96
|
}
|
|
66
97
|
```
|
|
67
98
|
|
|
68
99
|
**2. Add your service account key**
|
|
69
100
|
|
|
70
|
-
Place your Firebase service account JSON at any path you prefer — you'll reference it in `firebase-mcp.json` above.
|
|
101
|
+
Place your Firebase service account JSON at any path you prefer — you'll reference it in `firebase-mcp.json` above. Paths are resolved relative to the working directory when the server starts, or you can use an absolute path.
|
|
71
102
|
|
|
72
103
|
**3. Wire it into your MCP host**
|
|
73
104
|
|
|
@@ -75,14 +106,15 @@ See the [Connecting to Cursor](#connecting-to-cursor) section below — no insta
|
|
|
75
106
|
|
|
76
107
|
## Configuration
|
|
77
108
|
|
|
78
|
-
| Field
|
|
79
|
-
|
|
|
80
|
-
| `
|
|
81
|
-
| `firebase.
|
|
82
|
-
| `
|
|
83
|
-
| `firestore.rules.
|
|
84
|
-
| `firestore.
|
|
85
|
-
| `firestore.
|
|
109
|
+
| Field | Type | Default | Description |
|
|
110
|
+
| ------------------------------------------------ | ---------- | ------- | ---------------------------------------------------------- |
|
|
111
|
+
| `projects` | `object` | — | Map of project keys to project configs |
|
|
112
|
+
| `projects.<key>.firebase.projectId` | `string` | — | Firebase project ID |
|
|
113
|
+
| `projects.<key>.firebase.serviceAccountPath` | `string` | — | Path to service account JSON (relative to CWD or absolute) |
|
|
114
|
+
| `projects.<key>.firestore.rules.allow` | `string[]` | — | Glob patterns for allowed Firestore paths |
|
|
115
|
+
| `projects.<key>.firestore.rules.deny` | `string[]` | — | Glob patterns for denied Firestore paths (evaluated first) |
|
|
116
|
+
| `projects.<key>.firestore.maxCollectionReadSize` | `number` | `100` | Default document limit for collection reads |
|
|
117
|
+
| `projects.<key>.firestore.maxBatchFetchSize` | `number` | `200` | Maximum documents per batch fetch |
|
|
86
118
|
|
|
87
119
|
A custom config path can be passed at startup:
|
|
88
120
|
|
|
@@ -120,6 +152,8 @@ Add to your MCP config (e.g. `.cursor/mcp.json`):
|
|
|
120
152
|
|
|
121
153
|
`npx -y` will download and cache the package automatically on first run. No manual installation needed.
|
|
122
154
|
|
|
155
|
+
`firestore_read` and `auth_read` are safe to add to Cursor's tool allowlist for unattended use. `get_config` and `reload_config` are also read-only and safe to allowlist.
|
|
156
|
+
|
|
123
157
|
## License
|
|
124
158
|
|
|
125
159
|
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/config/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const index_1 = require("./index");
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// ProjectConfigSchema — the innermost validated unit, no file I/O needed
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
const validProject = {
|
|
9
|
+
firebase: {
|
|
10
|
+
projectId: 'my-project',
|
|
11
|
+
serviceAccountPath: '/path/to/sa.json',
|
|
12
|
+
},
|
|
13
|
+
firestore: {
|
|
14
|
+
rules: {
|
|
15
|
+
allow: ['**'],
|
|
16
|
+
deny: [],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
(0, vitest_1.describe)('ProjectConfigSchema', () => {
|
|
21
|
+
(0, vitest_1.it)('parses a fully valid project config', () => {
|
|
22
|
+
const result = index_1.ProjectConfigSchema.safeParse(validProject);
|
|
23
|
+
(0, vitest_1.expect)(result.success).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
(0, vitest_1.it)('applies default maxCollectionReadSize of 100', () => {
|
|
26
|
+
const result = index_1.ProjectConfigSchema.safeParse(validProject);
|
|
27
|
+
(0, vitest_1.expect)(result.success).toBe(true);
|
|
28
|
+
if (result.success) {
|
|
29
|
+
(0, vitest_1.expect)(result.data.firestore.maxCollectionReadSize).toBe(100);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
(0, vitest_1.it)('applies default maxBatchFetchSize of 200', () => {
|
|
33
|
+
const result = index_1.ProjectConfigSchema.safeParse(validProject);
|
|
34
|
+
(0, vitest_1.expect)(result.success).toBe(true);
|
|
35
|
+
if (result.success) {
|
|
36
|
+
(0, vitest_1.expect)(result.data.firestore.maxBatchFetchSize).toBe(200);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
(0, vitest_1.it)('accepts explicit maxCollectionReadSize and maxBatchFetchSize', () => {
|
|
40
|
+
const input = {
|
|
41
|
+
...validProject,
|
|
42
|
+
firestore: {
|
|
43
|
+
...validProject.firestore,
|
|
44
|
+
maxCollectionReadSize: 50,
|
|
45
|
+
maxBatchFetchSize: 75,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
const result = index_1.ProjectConfigSchema.safeParse(input);
|
|
49
|
+
(0, vitest_1.expect)(result.success).toBe(true);
|
|
50
|
+
if (result.success) {
|
|
51
|
+
(0, vitest_1.expect)(result.data.firestore.maxCollectionReadSize).toBe(50);
|
|
52
|
+
(0, vitest_1.expect)(result.data.firestore.maxBatchFetchSize).toBe(75);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
(0, vitest_1.it)('fails when firebase.projectId is missing', () => {
|
|
56
|
+
const input = {
|
|
57
|
+
...validProject,
|
|
58
|
+
firebase: { serviceAccountPath: '/path/to/sa.json' },
|
|
59
|
+
};
|
|
60
|
+
const result = index_1.ProjectConfigSchema.safeParse(input);
|
|
61
|
+
(0, vitest_1.expect)(result.success).toBe(false);
|
|
62
|
+
});
|
|
63
|
+
(0, vitest_1.it)('fails when firebase.serviceAccountPath is missing', () => {
|
|
64
|
+
const input = {
|
|
65
|
+
...validProject,
|
|
66
|
+
firebase: { projectId: 'my-project' },
|
|
67
|
+
};
|
|
68
|
+
const result = index_1.ProjectConfigSchema.safeParse(input);
|
|
69
|
+
(0, vitest_1.expect)(result.success).toBe(false);
|
|
70
|
+
});
|
|
71
|
+
(0, vitest_1.it)('fails when firestore.rules is missing', () => {
|
|
72
|
+
const input = { ...validProject, firestore: {} };
|
|
73
|
+
const result = index_1.ProjectConfigSchema.safeParse(input);
|
|
74
|
+
(0, vitest_1.expect)(result.success).toBe(false);
|
|
75
|
+
});
|
|
76
|
+
(0, vitest_1.it)('fails when firestore.rules.allow is not an array', () => {
|
|
77
|
+
const input = {
|
|
78
|
+
...validProject,
|
|
79
|
+
firestore: { rules: { allow: '**', deny: [] } },
|
|
80
|
+
};
|
|
81
|
+
const result = index_1.ProjectConfigSchema.safeParse(input);
|
|
82
|
+
(0, vitest_1.expect)(result.success).toBe(false);
|
|
83
|
+
});
|
|
84
|
+
(0, vitest_1.it)('fails when firestore.rules.deny is not an array', () => {
|
|
85
|
+
const input = {
|
|
86
|
+
...validProject,
|
|
87
|
+
firestore: { rules: { allow: ['**'], deny: 'none' } },
|
|
88
|
+
};
|
|
89
|
+
const result = index_1.ProjectConfigSchema.safeParse(input);
|
|
90
|
+
(0, vitest_1.expect)(result.success).toBe(false);
|
|
91
|
+
});
|
|
92
|
+
(0, vitest_1.it)('fails when the top-level object is missing', () => {
|
|
93
|
+
(0, vitest_1.expect)(index_1.ProjectConfigSchema.safeParse(null).success).toBe(false);
|
|
94
|
+
(0, vitest_1.expect)(index_1.ProjectConfigSchema.safeParse(undefined).success).toBe(false);
|
|
95
|
+
(0, vitest_1.expect)(index_1.ProjectConfigSchema.safeParse('string').success).toBe(false);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/config/index.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/task/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const index_1 = require("./index");
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Exit constructors & guards
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
(0, vitest_1.describe)('Exit', () => {
|
|
9
|
+
(0, vitest_1.describe)('constructors', () => {
|
|
10
|
+
(0, vitest_1.it)('ok wraps a value', () => {
|
|
11
|
+
const e = index_1.Exit.ok(42);
|
|
12
|
+
(0, vitest_1.expect)(e._tag).toBe('ok');
|
|
13
|
+
(0, vitest_1.expect)(e.value).toBe(42);
|
|
14
|
+
});
|
|
15
|
+
(0, vitest_1.it)('err wraps an error', () => {
|
|
16
|
+
const e = index_1.Exit.err('boom');
|
|
17
|
+
(0, vitest_1.expect)(e._tag).toBe('err');
|
|
18
|
+
(0, vitest_1.expect)(e.error).toBe('boom');
|
|
19
|
+
});
|
|
20
|
+
(0, vitest_1.it)('die wraps an optional cause', () => {
|
|
21
|
+
(0, vitest_1.expect)(index_1.Exit.die()._tag).toBe('die');
|
|
22
|
+
const e = index_1.Exit.die(new Error('oops'));
|
|
23
|
+
(0, vitest_1.expect)(e._tag).toBe('die');
|
|
24
|
+
(0, vitest_1.expect)(e.cause).toBeInstanceOf(Error);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
(0, vitest_1.describe)('guards', () => {
|
|
28
|
+
(0, vitest_1.it)('isOk returns true only for ok exits', () => {
|
|
29
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(index_1.Exit.ok(1))).toBe(true);
|
|
30
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(index_1.Exit.err('e'))).toBe(false);
|
|
31
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(index_1.Exit.die())).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
(0, vitest_1.it)('isErr returns true only for err exits', () => {
|
|
34
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(index_1.Exit.err('e'))).toBe(true);
|
|
35
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(index_1.Exit.ok(1))).toBe(false);
|
|
36
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(index_1.Exit.die())).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
(0, vitest_1.it)('isDie returns true only for die exits', () => {
|
|
39
|
+
(0, vitest_1.expect)(index_1.Exit.isDie(index_1.Exit.die())).toBe(true);
|
|
40
|
+
(0, vitest_1.expect)(index_1.Exit.isDie(index_1.Exit.ok(1))).toBe(false);
|
|
41
|
+
(0, vitest_1.expect)(index_1.Exit.isDie(index_1.Exit.err('e'))).toBe(false);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Helpers
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
async function run(task) {
|
|
49
|
+
const { exit } = task.fork();
|
|
50
|
+
return exit;
|
|
51
|
+
}
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// Task static constructors
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
(0, vitest_1.describe)('Task.succeed', () => {
|
|
56
|
+
(0, vitest_1.it)('resolves to ok', async () => {
|
|
57
|
+
const exit = await run(index_1.Task.succeed(99));
|
|
58
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(exit)).toBe(true);
|
|
59
|
+
if (index_1.Exit.isOk(exit))
|
|
60
|
+
(0, vitest_1.expect)(exit.value).toBe(99);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
(0, vitest_1.describe)('Task.fail', () => {
|
|
64
|
+
(0, vitest_1.it)('resolves to err', async () => {
|
|
65
|
+
const exit = await run(index_1.Task.fail('reason'));
|
|
66
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(exit)).toBe(true);
|
|
67
|
+
if (index_1.Exit.isErr(exit))
|
|
68
|
+
(0, vitest_1.expect)(exit.error).toBe('reason');
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
(0, vitest_1.describe)('Task.die', () => {
|
|
72
|
+
(0, vitest_1.it)('resolves to die', async () => {
|
|
73
|
+
const exit = await run(index_1.Task.die('cause'));
|
|
74
|
+
(0, vitest_1.expect)(index_1.Exit.isDie(exit)).toBe(true);
|
|
75
|
+
if (index_1.Exit.isDie(exit))
|
|
76
|
+
(0, vitest_1.expect)(exit.cause).toBe('cause');
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
(0, vitest_1.describe)('Task.sync', () => {
|
|
80
|
+
(0, vitest_1.it)('wraps a synchronous value', async () => {
|
|
81
|
+
const exit = await run(index_1.Task.sync(() => 'hello'));
|
|
82
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(exit)).toBe(true);
|
|
83
|
+
if (index_1.Exit.isOk(exit))
|
|
84
|
+
(0, vitest_1.expect)(exit.value).toBe('hello');
|
|
85
|
+
});
|
|
86
|
+
(0, vitest_1.it)('converts a thrown error to die', async () => {
|
|
87
|
+
const exit = await run(index_1.Task.sync(() => { throw new Error('sync boom'); }));
|
|
88
|
+
(0, vitest_1.expect)(index_1.Exit.isDie(exit)).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
(0, vitest_1.describe)('Task.lazy', () => {
|
|
92
|
+
(0, vitest_1.it)('defers construction until run', async () => {
|
|
93
|
+
let constructed = false;
|
|
94
|
+
const task = index_1.Task.lazy(() => {
|
|
95
|
+
constructed = true;
|
|
96
|
+
return index_1.Task.succeed(1);
|
|
97
|
+
});
|
|
98
|
+
(0, vitest_1.expect)(constructed).toBe(false);
|
|
99
|
+
await run(task);
|
|
100
|
+
(0, vitest_1.expect)(constructed).toBe(true);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
(0, vitest_1.describe)('Task.attempt', () => {
|
|
104
|
+
(0, vitest_1.it)('resolves to ok when the factory succeeds', async () => {
|
|
105
|
+
const exit = await run(index_1.Task.attempt({
|
|
106
|
+
try: () => Promise.resolve('done'),
|
|
107
|
+
catch: (e) => e,
|
|
108
|
+
}));
|
|
109
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(exit)).toBe(true);
|
|
110
|
+
if (index_1.Exit.isOk(exit))
|
|
111
|
+
(0, vitest_1.expect)(exit.value).toBe('done');
|
|
112
|
+
});
|
|
113
|
+
(0, vitest_1.it)('resolves to err when the factory throws', async () => {
|
|
114
|
+
const exit = await run(index_1.Task.attempt({
|
|
115
|
+
try: () => { throw new Error('fail'); },
|
|
116
|
+
catch: (e) => ({ mapped: true, cause: e }),
|
|
117
|
+
}));
|
|
118
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(exit)).toBe(true);
|
|
119
|
+
if (index_1.Exit.isErr(exit))
|
|
120
|
+
(0, vitest_1.expect)(exit.error.mapped).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
(0, vitest_1.it)('resolves to err when the promise rejects', async () => {
|
|
123
|
+
const exit = await run(index_1.Task.attempt({
|
|
124
|
+
try: () => Promise.reject(new Error('async fail')),
|
|
125
|
+
catch: (e) => String(e),
|
|
126
|
+
}));
|
|
127
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(exit)).toBe(true);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// Task instance combinators
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
(0, vitest_1.describe)('Task#map', () => {
|
|
134
|
+
(0, vitest_1.it)('transforms the ok value', async () => {
|
|
135
|
+
const exit = await run(index_1.Task.succeed(3).map((n) => n * 2));
|
|
136
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(exit)).toBe(true);
|
|
137
|
+
if (index_1.Exit.isOk(exit))
|
|
138
|
+
(0, vitest_1.expect)(exit.value).toBe(6);
|
|
139
|
+
});
|
|
140
|
+
(0, vitest_1.it)('passes err through unchanged', async () => {
|
|
141
|
+
const exit = await run(index_1.Task.fail('e').map((n) => n * 2));
|
|
142
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(exit)).toBe(true);
|
|
143
|
+
if (index_1.Exit.isErr(exit))
|
|
144
|
+
(0, vitest_1.expect)(exit.error).toBe('e');
|
|
145
|
+
});
|
|
146
|
+
(0, vitest_1.it)('converts a mapper throw to die', async () => {
|
|
147
|
+
const exit = await run(index_1.Task.succeed(1).map(() => { throw new Error('map boom'); }));
|
|
148
|
+
(0, vitest_1.expect)(index_1.Exit.isDie(exit)).toBe(true);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
(0, vitest_1.describe)('Task#flatMap', () => {
|
|
152
|
+
(0, vitest_1.it)('chains a successful continuation', async () => {
|
|
153
|
+
const exit = await run(index_1.Task.succeed(5).flatMap((n) => index_1.Task.succeed(n + 1)));
|
|
154
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(exit)).toBe(true);
|
|
155
|
+
if (index_1.Exit.isOk(exit))
|
|
156
|
+
(0, vitest_1.expect)(exit.value).toBe(6);
|
|
157
|
+
});
|
|
158
|
+
(0, vitest_1.it)('short-circuits on err', async () => {
|
|
159
|
+
let ran = false;
|
|
160
|
+
const exit = await run(index_1.Task.fail('original').flatMap(() => {
|
|
161
|
+
ran = true;
|
|
162
|
+
return index_1.Task.succeed(42);
|
|
163
|
+
}));
|
|
164
|
+
(0, vitest_1.expect)(ran).toBe(false);
|
|
165
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(exit)).toBe(true);
|
|
166
|
+
});
|
|
167
|
+
(0, vitest_1.it)('can chain to a failing task', async () => {
|
|
168
|
+
const exit = await run(index_1.Task.succeed(1).flatMap(() => index_1.Task.fail('chained error')));
|
|
169
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(exit)).toBe(true);
|
|
170
|
+
if (index_1.Exit.isErr(exit))
|
|
171
|
+
(0, vitest_1.expect)(exit.error).toBe('chained error');
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
(0, vitest_1.describe)('Task#tap', () => {
|
|
175
|
+
(0, vitest_1.it)('runs a side effect and preserves the value', async () => {
|
|
176
|
+
let seen;
|
|
177
|
+
const exit = await run(index_1.Task.succeed(7).tap((n) => { seen = n; }));
|
|
178
|
+
(0, vitest_1.expect)(seen).toBe(7);
|
|
179
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(exit)).toBe(true);
|
|
180
|
+
if (index_1.Exit.isOk(exit))
|
|
181
|
+
(0, vitest_1.expect)(exit.value).toBe(7);
|
|
182
|
+
});
|
|
183
|
+
(0, vitest_1.it)('skips the side effect on err', async () => {
|
|
184
|
+
let ran = false;
|
|
185
|
+
await run(index_1.Task.fail('e').tap(() => { ran = true; }));
|
|
186
|
+
(0, vitest_1.expect)(ran).toBe(false);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
(0, vitest_1.describe)('Task#mapError', () => {
|
|
190
|
+
(0, vitest_1.it)('transforms the error', async () => {
|
|
191
|
+
const exit = await run(index_1.Task.fail(1).mapError((n) => n * 10));
|
|
192
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(exit)).toBe(true);
|
|
193
|
+
if (index_1.Exit.isErr(exit))
|
|
194
|
+
(0, vitest_1.expect)(exit.error).toBe(10);
|
|
195
|
+
});
|
|
196
|
+
(0, vitest_1.it)('passes ok through', async () => {
|
|
197
|
+
const exit = await run(index_1.Task.succeed('v').mapError(() => 'new error'));
|
|
198
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(exit)).toBe(true);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
(0, vitest_1.describe)('Task#catchAll', () => {
|
|
202
|
+
(0, vitest_1.it)('recovers from an err', async () => {
|
|
203
|
+
const exit = await run(index_1.Task.fail('oops').catchAll(() => index_1.Task.succeed('recovered')));
|
|
204
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(exit)).toBe(true);
|
|
205
|
+
if (index_1.Exit.isOk(exit))
|
|
206
|
+
(0, vitest_1.expect)(exit.value).toBe('recovered');
|
|
207
|
+
});
|
|
208
|
+
(0, vitest_1.it)('does not run the handler on ok', async () => {
|
|
209
|
+
let ran = false;
|
|
210
|
+
const exit = await run(index_1.Task.succeed(1).catchAll(() => {
|
|
211
|
+
ran = true;
|
|
212
|
+
return index_1.Task.succeed(2);
|
|
213
|
+
}));
|
|
214
|
+
(0, vitest_1.expect)(ran).toBe(false);
|
|
215
|
+
if (index_1.Exit.isOk(exit))
|
|
216
|
+
(0, vitest_1.expect)(exit.value).toBe(1);
|
|
217
|
+
});
|
|
218
|
+
(0, vitest_1.it)('passes die through unchanged', async () => {
|
|
219
|
+
const exit = await run(index_1.Task.die('fatal').catchAll(() => index_1.Task.succeed('recovered')));
|
|
220
|
+
(0, vitest_1.expect)(index_1.Exit.isDie(exit)).toBe(true);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
(0, vitest_1.describe)('Task#catchWhen', () => {
|
|
224
|
+
(0, vitest_1.it)('handles only the matching error tag', async () => {
|
|
225
|
+
const errA = index_1.Task.fail({ _tag: 'A' });
|
|
226
|
+
const errB = index_1.Task.fail({ _tag: 'B' });
|
|
227
|
+
const exitA = await run(errA.catchWhen('_tag', 'A', () => index_1.Task.succeed('caught A')));
|
|
228
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(exitA)).toBe(true);
|
|
229
|
+
if (index_1.Exit.isOk(exitA))
|
|
230
|
+
(0, vitest_1.expect)(exitA.value).toBe('caught A');
|
|
231
|
+
const exitB = await run(errB.catchWhen('_tag', 'A', () => index_1.Task.succeed('caught A')));
|
|
232
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(exitB)).toBe(true);
|
|
233
|
+
if (index_1.Exit.isErr(exitB))
|
|
234
|
+
(0, vitest_1.expect)(exitB.error).toEqual({ _tag: 'B' });
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
(0, vitest_1.describe)('Task#filter', () => {
|
|
238
|
+
(0, vitest_1.it)('passes when the predicate holds', async () => {
|
|
239
|
+
const exit = await run(index_1.Task.succeed(10).filter((n) => n > 5, () => 'too small'));
|
|
240
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(exit)).toBe(true);
|
|
241
|
+
});
|
|
242
|
+
(0, vitest_1.it)('fails when the predicate does not hold', async () => {
|
|
243
|
+
const exit = await run(index_1.Task.succeed(3).filter((n) => n > 5, (n) => `${n} is too small`));
|
|
244
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(exit)).toBe(true);
|
|
245
|
+
if (index_1.Exit.isErr(exit))
|
|
246
|
+
(0, vitest_1.expect)(exit.error).toBe('3 is too small');
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
(0, vitest_1.describe)('Task#tapError', () => {
|
|
250
|
+
(0, vitest_1.it)('runs a side effect on err without changing it', async () => {
|
|
251
|
+
let seen;
|
|
252
|
+
const exit = await run(index_1.Task.fail('e').tapError((e) => { seen = e; }));
|
|
253
|
+
(0, vitest_1.expect)(seen).toBe('e');
|
|
254
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(exit)).toBe(true);
|
|
255
|
+
if (index_1.Exit.isErr(exit))
|
|
256
|
+
(0, vitest_1.expect)(exit.error).toBe('e');
|
|
257
|
+
});
|
|
258
|
+
(0, vitest_1.it)('skips the side effect on ok', async () => {
|
|
259
|
+
let ran = false;
|
|
260
|
+
await run(index_1.Task.succeed(1).tapError(() => { ran = true; }));
|
|
261
|
+
(0, vitest_1.expect)(ran).toBe(false);
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
// ---------------------------------------------------------------------------
|
|
265
|
+
// Task.gen
|
|
266
|
+
// ---------------------------------------------------------------------------
|
|
267
|
+
(0, vitest_1.describe)('Task.gen', () => {
|
|
268
|
+
(0, vitest_1.it)('sequences successful tasks', async () => {
|
|
269
|
+
const exit = await run(index_1.Task.gen(function* () {
|
|
270
|
+
const a = yield* index_1.Task.succeed(1);
|
|
271
|
+
const b = yield* index_1.Task.succeed(2);
|
|
272
|
+
return a + b;
|
|
273
|
+
}));
|
|
274
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(exit)).toBe(true);
|
|
275
|
+
if (index_1.Exit.isOk(exit))
|
|
276
|
+
(0, vitest_1.expect)(exit.value).toBe(3);
|
|
277
|
+
});
|
|
278
|
+
(0, vitest_1.it)('short-circuits on the first err', async () => {
|
|
279
|
+
let reached = false;
|
|
280
|
+
const exit = await run(index_1.Task.gen(function* () {
|
|
281
|
+
yield* index_1.Task.fail('first error');
|
|
282
|
+
reached = true;
|
|
283
|
+
yield* index_1.Task.succeed(1);
|
|
284
|
+
return 'done';
|
|
285
|
+
}));
|
|
286
|
+
(0, vitest_1.expect)(reached).toBe(false);
|
|
287
|
+
(0, vitest_1.expect)(index_1.Exit.isErr(exit)).toBe(true);
|
|
288
|
+
if (index_1.Exit.isErr(exit))
|
|
289
|
+
(0, vitest_1.expect)(exit.error).toBe('first error');
|
|
290
|
+
});
|
|
291
|
+
(0, vitest_1.it)('returns the final value', async () => {
|
|
292
|
+
const exit = await run(index_1.Task.gen(function* () {
|
|
293
|
+
const x = yield* index_1.Task.succeed(10);
|
|
294
|
+
return x * 3;
|
|
295
|
+
}));
|
|
296
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(exit)).toBe(true);
|
|
297
|
+
if (index_1.Exit.isOk(exit))
|
|
298
|
+
(0, vitest_1.expect)(exit.value).toBe(30);
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
// ---------------------------------------------------------------------------
|
|
302
|
+
// Abort / fork
|
|
303
|
+
// ---------------------------------------------------------------------------
|
|
304
|
+
(0, vitest_1.describe)('Task#fork / abort', () => {
|
|
305
|
+
(0, vitest_1.it)('abort resolves to die', async () => {
|
|
306
|
+
const { exit, abort } = index_1.Task.never().fork();
|
|
307
|
+
abort();
|
|
308
|
+
const result = await exit;
|
|
309
|
+
(0, vitest_1.expect)(index_1.Exit.isDie(result)).toBe(true);
|
|
310
|
+
});
|
|
311
|
+
(0, vitest_1.it)('aborting an already-resolved task is a no-op', async () => {
|
|
312
|
+
const { exit, abort } = index_1.Task.succeed(1).fork();
|
|
313
|
+
const result = await exit;
|
|
314
|
+
abort();
|
|
315
|
+
(0, vitest_1.expect)(index_1.Exit.isOk(result)).toBe(true);
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/task/index.test.ts"],"names":[],"mappings":";;AAAA,mCAA8C;AAE9C,mCAAqC;AAErC,8EAA8E;AAC9E,6BAA6B;AAC7B,8EAA8E;AAE9E,IAAA,iBAAQ,EAAC,MAAM,EAAE,GAAG,EAAE;IACpB,IAAA,iBAAQ,EAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,IAAA,WAAE,EAAC,kBAAkB,EAAE,GAAG,EAAE;YAC1B,MAAM,CAAC,GAAG,YAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACtB,IAAA,eAAM,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAA,eAAM,EAAE,CAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,oBAAoB,EAAE,GAAG,EAAE;YAC5B,MAAM,CAAC,GAAG,YAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAA,eAAM,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAA,eAAM,EAAE,CAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,IAAA,eAAM,EAAC,YAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpC,MAAM,CAAC,GAAG,YAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YACtC,IAAA,eAAM,EAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAA,eAAM,EAAE,CAAS,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,QAAQ,EAAE,GAAG,EAAE;QACtB,IAAA,WAAE,EAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,YAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzC,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,YAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC7C,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,YAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,YAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,YAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,YAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;QAEH,IAAA,WAAE,EAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,YAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1C,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,YAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,YAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,KAAK,UAAU,GAAG,CAAO,IAAgB;IACvC,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,2BAA2B;AAC3B,8EAA8E;AAE9E,IAAA,iBAAQ,EAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAA,WAAE,EAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;QAC9B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACzC,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,WAAW,EAAE,GAAG,EAAE;IACzB,IAAA,WAAE,EAAC,iBAAiB,EAAE,KAAK,IAAI,EAAE;QAC/B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC5C,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,UAAU,EAAE,GAAG,EAAE;IACxB,IAAA,WAAE,EAAC,iBAAiB,EAAE,KAAK,IAAI,EAAE;QAC/B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAC1C,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,WAAW,EAAE,GAAG,EAAE;IACzB,IAAA,WAAE,EAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,WAAW,EAAE,GAAG,EAAE;IACzB,IAAA,WAAE,EAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,MAAM,IAAI,GAAG,YAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YAC1B,WAAW,GAAG,IAAI,CAAC;YACnB,OAAO,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,IAAA,eAAM,EAAC,WAAW,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC;QAChB,IAAA,eAAM,EAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAA,WAAE,EAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,OAAO,CAAC;YAClC,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;YAClC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;SAChB,CAAC,CAAC,CAAC;QACJ,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,OAAO,CAAC;YAClC,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;SAC3C,CAAC,CAAC,CAAC;QACJ,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAE,IAAI,CAAC,KAAa,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,OAAO,CAAC;YAClC,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;YAClD,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;SACxB,CAAC,CAAC,CAAC;QACJ,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,4BAA4B;AAC5B,8EAA8E;AAE9E,IAAA,iBAAQ,EAAC,UAAU,EAAE,GAAG,EAAE;IACxB,IAAA,WAAE,EAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC1D,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,IAAI,CAAS,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACzE,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpF,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAA,WAAE,EAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,IAAI,GAAG,MAAM,GAAG,CACpB,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CACpD,CAAC;QACF,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACrC,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,MAAM,IAAI,GAAG,MAAM,GAAG,CACpB,YAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;YACjC,GAAG,GAAG,IAAI,CAAC;YACX,OAAO,YAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC1B,CAAC,CAAC,CACH,CAAC;QACF,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,IAAI,GAAG,MAAM,GAAG,CACpB,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,YAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAC1D,CAAC;QACF,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,UAAU,EAAE,GAAG,EAAE;IACxB,IAAA,WAAE,EAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,IAAI,IAAwB,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAClE,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,MAAM,GAAG,CAAC,YAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAA,WAAE,EAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC7D,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,mBAAmB,EAAE,KAAK,IAAI,EAAE;QACjC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;QACtE,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAA,WAAE,EAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,IAAI,GAAG,MAAM,GAAG,CACpB,YAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,YAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAC5D,CAAC;QACF,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,MAAM,IAAI,GAAG,MAAM,GAAG,CACpB,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE;YAC5B,GAAG,GAAG,IAAI,CAAC;YACX,OAAO,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,CAAC,CAAC,CACH,CAAC;QACF,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,IAAI,GAAG,MAAM,GAAG,CACpB,YAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,YAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAC5D,CAAC;QACF,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,IAAA,WAAE,EAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QAEnD,MAAM,IAAI,GAAG,YAAI,CAAC,IAAI,CAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QACzC,MAAM,IAAI,GAAG,YAAI,CAAC,IAAI,CAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QAEzC,MAAM,KAAK,GAAG,MAAM,GAAG,CACrB,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,YAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAC5D,CAAC;QACF,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,YAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,IAAA,eAAM,EAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE3D,MAAM,KAAK,GAAG,MAAM,GAAG,CACrB,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,YAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAC5D,CAAC;QACF,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,YAAI,CAAC,KAAK,CAAC,KAAK,CAAC;YAAE,IAAA,eAAM,EAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAA,WAAE,EAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,IAAI,GAAG,MAAM,GAAG,CACpB,YAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,CACzD,CAAC;QACF,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,IAAI,GAAG,MAAM,GAAG,CACpB,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,CACjE,CAAC;QACF,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAA,WAAE,EAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,IAAI,IAAa,CAAC;QAClB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,YAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtE,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,MAAM,GAAG,CAAC,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E,IAAA,iBAAQ,EAAC,UAAU,EAAE,GAAG,EAAE;IACxB,IAAA,WAAE,EAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,IAAI,GAAG,MAAM,GAAG,CACpB,YAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YAChB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACjC,OAAO,CAAC,GAAG,CAAC,CAAC;QACf,CAAC,CAAC,CACH,CAAC;QACF,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,IAAI,GAAG,MAAM,GAAG,CACpB,YAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YAChB,KAAK,CAAC,CAAC,YAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAChC,OAAO,GAAG,IAAI,CAAC;YACf,KAAK,CAAC,CAAC,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACvB,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CACH,CAAC;QACF,IAAA,eAAM,EAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,YAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,IAAI,GAAG,MAAM,GAAG,CACpB,YAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YAChB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,YAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAClC,OAAO,CAAC,GAAG,CAAC,CAAC;QACf,CAAC,CAAC,CACH,CAAC;QACF,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,YAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,IAAA,eAAM,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,IAAA,iBAAQ,EAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,IAAA,WAAE,EAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACrC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,YAAI,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC;QAC5C,KAAK,EAAE,CAAC;QACR,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC;QAC1B,IAAA,eAAM,EAAC,YAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,YAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC;QAC1B,KAAK,EAAE,CAAC;QACR,IAAA,eAAM,EAAC,YAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.test.d.ts","sourceRoot":"","sources":["../../../../src/tools/firestore/utils/paths.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const vitest_1 = require("vitest");
|
|
4
|
+
const paths_1 = require("./paths");
|
|
5
|
+
(0, vitest_1.describe)('segmentCount', () => {
|
|
6
|
+
(0, vitest_1.it)('counts single-segment paths', () => {
|
|
7
|
+
(0, vitest_1.expect)((0, paths_1.segmentCount)('users')).toBe(1);
|
|
8
|
+
});
|
|
9
|
+
(0, vitest_1.it)('counts multi-segment paths', () => {
|
|
10
|
+
(0, vitest_1.expect)((0, paths_1.segmentCount)('users/123/posts')).toBe(3);
|
|
11
|
+
(0, vitest_1.expect)((0, paths_1.segmentCount)('users/123')).toBe(2);
|
|
12
|
+
});
|
|
13
|
+
(0, vitest_1.it)('ignores leading and trailing slashes', () => {
|
|
14
|
+
(0, vitest_1.expect)((0, paths_1.segmentCount)('/users/')).toBe(1);
|
|
15
|
+
(0, vitest_1.expect)((0, paths_1.segmentCount)('/users/123/')).toBe(2);
|
|
16
|
+
});
|
|
17
|
+
(0, vitest_1.it)('returns 0 for an empty string', () => {
|
|
18
|
+
(0, vitest_1.expect)((0, paths_1.segmentCount)('')).toBe(0);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// collectionPathError
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
(0, vitest_1.describe)('collectionPathError', () => {
|
|
25
|
+
(0, vitest_1.it)('returns null for a valid single-segment collection path', () => {
|
|
26
|
+
(0, vitest_1.expect)((0, paths_1.collectionPathError)('users')).toBeNull();
|
|
27
|
+
});
|
|
28
|
+
(0, vitest_1.it)('returns null for a valid three-segment collection path', () => {
|
|
29
|
+
(0, vitest_1.expect)((0, paths_1.collectionPathError)('users/123/posts')).toBeNull();
|
|
30
|
+
});
|
|
31
|
+
(0, vitest_1.it)('returns null for a valid five-segment collection path', () => {
|
|
32
|
+
(0, vitest_1.expect)((0, paths_1.collectionPathError)('a/b/c/d/e')).toBeNull();
|
|
33
|
+
});
|
|
34
|
+
(0, vitest_1.it)('returns an error message for a two-segment (document) path', () => {
|
|
35
|
+
const msg = (0, paths_1.collectionPathError)('users/123');
|
|
36
|
+
(0, vitest_1.expect)(msg).toBeTypeOf('string');
|
|
37
|
+
(0, vitest_1.expect)(msg).toContain('2');
|
|
38
|
+
(0, vitest_1.expect)(msg).toContain('document path');
|
|
39
|
+
});
|
|
40
|
+
(0, vitest_1.it)('returns an error message for a four-segment path', () => {
|
|
41
|
+
const msg = (0, paths_1.collectionPathError)('stores/ABC/orders/456');
|
|
42
|
+
(0, vitest_1.expect)(msg).toBeTypeOf('string');
|
|
43
|
+
(0, vitest_1.expect)(msg).toContain('4');
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
// documentPathError
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
(0, vitest_1.describe)('documentPathError', () => {
|
|
50
|
+
(0, vitest_1.it)('returns null for a valid two-segment document path', () => {
|
|
51
|
+
(0, vitest_1.expect)((0, paths_1.documentPathError)('users/123')).toBeNull();
|
|
52
|
+
});
|
|
53
|
+
(0, vitest_1.it)('returns null for a valid four-segment document path', () => {
|
|
54
|
+
(0, vitest_1.expect)((0, paths_1.documentPathError)('stores/ABC/orders/456')).toBeNull();
|
|
55
|
+
});
|
|
56
|
+
(0, vitest_1.it)('returns an error message for a single-segment (collection) path', () => {
|
|
57
|
+
const msg = (0, paths_1.documentPathError)('users');
|
|
58
|
+
(0, vitest_1.expect)(msg).toBeTypeOf('string');
|
|
59
|
+
(0, vitest_1.expect)(msg).toContain('1');
|
|
60
|
+
(0, vitest_1.expect)(msg).toContain('collection path');
|
|
61
|
+
});
|
|
62
|
+
(0, vitest_1.it)('returns an error message for a three-segment path', () => {
|
|
63
|
+
const msg = (0, paths_1.documentPathError)('users/123/posts');
|
|
64
|
+
(0, vitest_1.expect)(msg).toBeTypeOf('string');
|
|
65
|
+
(0, vitest_1.expect)(msg).toContain('3');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
//# sourceMappingURL=paths.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.test.js","sourceRoot":"","sources":["../../../../src/tools/firestore/utils/paths.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firebase-mcp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "MCP server that exposes Firebase Firestore to AI agents (Cursor, Claude Desktop, etc.)",
|
|
5
5
|
"main": "dist/cli/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
"build": "tsc",
|
|
14
14
|
"dev": "tsx src/cli/index.ts",
|
|
15
15
|
"start": "node dist/cli/index.js",
|
|
16
|
-
"prepublishOnly": "pnpm build"
|
|
16
|
+
"prepublishOnly": "pnpm build",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:watch": "vitest",
|
|
19
|
+
"test:coverage": "vitest run --coverage"
|
|
17
20
|
},
|
|
18
21
|
"keywords": [
|
|
19
22
|
"mcp",
|