@executor-js/sdk 0.0.1-beta.6 → 0.0.2

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.
Files changed (96) hide show
  1. package/README.md +125 -107
  2. package/dist/blob.d.ts +48 -0
  3. package/dist/blob.d.ts.map +1 -0
  4. package/dist/blob.test.d.ts +2 -0
  5. package/dist/blob.test.d.ts.map +1 -0
  6. package/dist/chunk-6LMMN2GP.js +4396 -0
  7. package/dist/chunk-6LMMN2GP.js.map +1 -0
  8. package/dist/config.d.ts +14 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/connections.d.ts +107 -0
  11. package/dist/connections.d.ts.map +1 -0
  12. package/dist/connections.test.d.ts +2 -0
  13. package/dist/connections.test.d.ts.map +1 -0
  14. package/dist/core-schema.d.ts +372 -0
  15. package/dist/core-schema.d.ts.map +1 -0
  16. package/dist/core.js +273 -57
  17. package/dist/core.js.map +1 -1
  18. package/dist/elicitation.d.ts +18 -34
  19. package/dist/elicitation.d.ts.map +1 -1
  20. package/dist/error-handling.test.d.ts +2 -0
  21. package/dist/error-handling.test.d.ts.map +1 -0
  22. package/dist/errors.d.ts +95 -24
  23. package/dist/errors.d.ts.map +1 -1
  24. package/dist/executor.d.ts +107 -48
  25. package/dist/executor.d.ts.map +1 -1
  26. package/dist/executor.test.d.ts +2 -0
  27. package/dist/executor.test.d.ts.map +1 -0
  28. package/dist/ids.d.ts +6 -4
  29. package/dist/ids.d.ts.map +1 -1
  30. package/dist/index.d.ts +22 -16
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +80 -308
  33. package/dist/index.js.map +1 -1
  34. package/dist/oauth-discovery.d.ts +138 -0
  35. package/dist/oauth-discovery.d.ts.map +1 -0
  36. package/dist/oauth-discovery.test.d.ts +2 -0
  37. package/dist/oauth-discovery.test.d.ts.map +1 -0
  38. package/dist/oauth-helpers.d.ts +89 -0
  39. package/dist/oauth-helpers.d.ts.map +1 -0
  40. package/dist/oauth-helpers.test.d.ts +2 -0
  41. package/dist/oauth-helpers.test.d.ts.map +1 -0
  42. package/dist/oauth-popup-types.d.ts +14 -0
  43. package/dist/oauth-popup-types.d.ts.map +1 -0
  44. package/dist/oauth-service.d.ts +33 -0
  45. package/dist/oauth-service.d.ts.map +1 -0
  46. package/dist/oauth.d.ts +275 -0
  47. package/dist/oauth.d.ts.map +1 -0
  48. package/dist/plugin.d.ts +261 -27
  49. package/dist/plugin.d.ts.map +1 -1
  50. package/dist/policies.d.ts +56 -64
  51. package/dist/policies.d.ts.map +1 -1
  52. package/dist/policies.test.d.ts +2 -0
  53. package/dist/policies.test.d.ts.map +1 -0
  54. package/dist/promise-executor.d.ts +26 -128
  55. package/dist/promise-executor.d.ts.map +1 -1
  56. package/dist/promise.d.ts +12 -6
  57. package/dist/promise.d.ts.map +1 -1
  58. package/dist/promise.test.d.ts +2 -0
  59. package/dist/promise.test.d.ts.map +1 -0
  60. package/dist/schema-types.d.ts +6 -5
  61. package/dist/schema-types.d.ts.map +1 -1
  62. package/dist/scope.d.ts +5 -15
  63. package/dist/scope.d.ts.map +1 -1
  64. package/dist/scoped-adapter.d.ts +13 -0
  65. package/dist/scoped-adapter.d.ts.map +1 -0
  66. package/dist/scoped-adapter.test.d.ts +2 -0
  67. package/dist/scoped-adapter.test.d.ts.map +1 -0
  68. package/dist/secret-backed-value.d.ts +27 -0
  69. package/dist/secret-backed-value.d.ts.map +1 -0
  70. package/dist/secrets.d.ts +52 -106
  71. package/dist/secrets.d.ts.map +1 -1
  72. package/dist/testing.d.ts +5 -3
  73. package/dist/testing.d.ts.map +1 -1
  74. package/dist/types.d.ts +84 -0
  75. package/dist/types.d.ts.map +1 -0
  76. package/package.json +7 -4
  77. package/dist/chunk-CJY7TT3J.js +0 -1384
  78. package/dist/chunk-CJY7TT3J.js.map +0 -1
  79. package/dist/in-memory/policy-engine.d.ts +0 -10
  80. package/dist/in-memory/policy-engine.d.ts.map +0 -1
  81. package/dist/in-memory/secret-store.d.ts +0 -16
  82. package/dist/in-memory/secret-store.d.ts.map +0 -1
  83. package/dist/in-memory/tool-registry.d.ts +0 -35
  84. package/dist/in-memory/tool-registry.d.ts.map +0 -1
  85. package/dist/index.test.d.ts +0 -2
  86. package/dist/index.test.d.ts.map +0 -1
  87. package/dist/plugin-kv.d.ts +0 -48
  88. package/dist/plugin-kv.d.ts.map +0 -1
  89. package/dist/plugins/in-memory-tools.d.ts +0 -42
  90. package/dist/plugins/in-memory-tools.d.ts.map +0 -1
  91. package/dist/runtime-tools.d.ts +0 -41
  92. package/dist/runtime-tools.d.ts.map +0 -1
  93. package/dist/sources.d.ts +0 -124
  94. package/dist/sources.d.ts.map +0 -1
  95. package/dist/tools.d.ts +0 -219
  96. package/dist/tools.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,158 +1,176 @@
1
- # @executor/sdk
1
+ # @executor-js/sdk
2
2
 
3
3
  A TypeScript SDK for building executors that wire together tool sources, secrets, and policies across MCP, OpenAPI, GraphQL, and custom plugins.
4
4
 
5
- Everything is `async`/`await`. Plug in any combination of plugins, register your own tools, and invoke them through a unified catalog.
5
+ The default surface is `Promise`-based plugins are built on [Effect](https://effect.website/) under the hood, but consumers never have to touch it.
6
6
 
7
7
  ## Install
8
8
 
9
9
  ```sh
10
- bun add @executor/sdk
10
+ bun add @executor-js/sdk
11
11
  # or
12
- npm install @executor/sdk
12
+ npm install @executor-js/sdk
13
13
  ```
14
14
 
15
15
  ## Quick start
16
16
 
17
17
  ```ts
18
- import {
19
- createExecutor,
20
- definePlugin,
21
- ToolRegistration,
22
- ToolId,
23
- ToolInvocationResult,
24
- } from "@executor/sdk";
25
-
26
- // Define a custom plugin with async/await.
27
- const weatherPlugin = definePlugin({
28
- key: "weather",
29
- init: async (ctx) => {
30
- await ctx.tools.registerInvoker("weather", {
31
- invoke: async (_toolId, args) => {
32
- const { city } = args as { city: string };
33
- return new ToolInvocationResult({
34
- data: { city, temperature: 72, condition: "sunny" },
35
- error: null,
36
- });
37
- },
38
- });
39
-
40
- await ctx.tools.register([
41
- new ToolRegistration({
42
- id: ToolId.make("weather.getForecast"),
43
- pluginKey: "weather",
44
- sourceId: "weather",
45
- name: "getForecast",
46
- description: "Get weather forecast for a city",
47
- inputSchema: {
48
- type: "object",
49
- properties: { city: { type: "string" } },
50
- required: ["city"],
51
- },
52
- }),
53
- ]);
54
-
55
- return {
56
- extension: {
57
- forecast: async (city: string) => {
58
- const result = await ctx.tools.invoke(
59
- "weather.getForecast",
60
- { city },
61
- { onElicitation: "accept-all" },
62
- );
63
- return result.data as { city: string; temperature: number; condition: string };
64
- },
65
- },
66
- };
67
- },
68
- });
18
+ import { createExecutor } from "@executor-js/sdk";
69
19
 
70
20
  const executor = await createExecutor({
71
- scope: { name: "my-app" },
72
- plugins: [weatherPlugin] as const,
21
+ // Required: how to respond when a tool requests user input mid-call.
22
+ // `"accept-all"` auto-approves every prompt — fine for tests/automation.
23
+ // For an interactive host, pass a handler `(ctx) => Promise<ElicitationResponse>`.
24
+ onElicitation: "accept-all",
73
25
  });
74
26
 
75
- // The plugin's extension is available under its key.
76
- const forecast = await executor.weather.forecast("San Francisco");
77
-
78
- // Every plugin contributes to a unified tool catalog.
79
27
  const tools = await executor.tools.list();
28
+ console.log(`scope=${executor.scopes[0]!.id} tools=${tools.length}`);
80
29
 
81
- // Invoke any tool with the same call shape.
82
- const result = await executor.tools.invoke(
83
- "weather.getForecast",
84
- { city: "Tokyo" },
85
- { onElicitation: "accept-all" },
86
- );
30
+ await executor.close();
31
+ ```
32
+
33
+ `createExecutor` returns an executor backed by an in-memory store and a default scope (`default-scope`). Without plugins it has no tools or secret providers — the surface is still there, it just enumerates empty. Add plugins to contribute tools, secret providers, and per-plugin extension methods.
34
+
35
+ To invoke a tool once one is registered:
36
+
37
+ ```ts
38
+ import { createExecutor } from "@executor-js/sdk";
39
+
40
+ const executor = await createExecutor({ onElicitation: "accept-all" });
41
+
42
+ const tools = await executor.tools.list();
43
+ const target = tools[0];
44
+ if (target) {
45
+ const result = await executor.tools.invoke(target.id, {
46
+ /* args matching target.inputSchema */
47
+ });
48
+ console.log(result);
49
+ }
87
50
 
88
51
  await executor.close();
89
52
  ```
90
53
 
91
- ## Using plugins
54
+ Pass an `options` object only if you need to override the executor-level handler for a single call (rare — typically used by hosts that bridge per-client elicitation channels):
55
+
56
+ ```ts
57
+ await executor.tools.invoke(target.id, args, {
58
+ onElicitation: customHandler,
59
+ });
60
+ ```
61
+
62
+ ## Two import paths
63
+
64
+ The SDK ships two surfaces from the same package:
65
+
66
+ - `@executor-js/sdk` — the **Promise** surface for end users. Returns plain `Promise`s, no Effect required. This is what the quick start above uses.
67
+ - `@executor-js/sdk/core` — the **Effect** surface for plugin authors. Exposes `definePlugin`, the typed error classes, schema helpers, and the Effect-shaped `Executor`. Every `@executor-js/plugin-*` package mirrors the same split.
68
+
69
+ End users only ever need the root import. Plugin authors reach for `/core` because writing a plugin means returning Effect-shaped callbacks for storage, tool invocation, and secret providers.
92
70
 
93
- Install whichever plugins you need and pass their factory call into `plugins`:
71
+ ## Authoring a plugin
72
+
73
+ A plugin is a factory that returns a spec object. The factory accepts plugin-author options and returns `{ id, storage, extension?, secretProviders?, ... }`. The shape of `extension` becomes `executor[plugin.id]` in the resulting executor — and on the Promise side every Effect-returning method is automatically promisified.
94
74
 
95
75
  ```ts
96
- import { createExecutor } from "@executor/sdk";
97
- import { mcpPlugin } from "@executor/plugin-mcp";
98
- import { openApiPlugin } from "@executor/plugin-openapi";
99
- import { graphqlPlugin } from "@executor/plugin-graphql";
76
+ import { Effect } from "effect";
77
+ import { definePlugin, type SecretProvider } from "@executor-js/sdk/core";
78
+ import { createExecutor } from "@executor-js/sdk";
79
+
80
+ interface MemorySecretsConfig {
81
+ readonly initial?: Readonly<Record<string, string>>;
82
+ }
83
+
84
+ // definePlugin takes a factory and returns a configured-plugin function
85
+ // that the consumer calls with options.
86
+ export const memorySecretsPlugin = definePlugin(
87
+ (options?: MemorySecretsConfig) => {
88
+ const map = new Map<string, string>(
89
+ Object.entries(options?.initial ?? {}),
90
+ );
91
+ const provider: SecretProvider = {
92
+ key: "memory",
93
+ writable: true,
94
+ get: (id: string) => Effect.sync(() => map.get(id) ?? null),
95
+ has: (id: string) => Effect.sync(() => map.has(id)),
96
+ set: (id: string, value: string) =>
97
+ Effect.sync(() => void map.set(id, value)),
98
+ delete: (id: string) => Effect.sync(() => map.delete(id)),
99
+ list: () =>
100
+ Effect.sync(() =>
101
+ Array.from(map.keys()).map((k) => ({ id: k, name: k })),
102
+ ),
103
+ };
100
104
 
105
+ return {
106
+ id: "memorySecrets" as const,
107
+ storage: () => ({}),
108
+ extension: () => ({
109
+ label: "in-memory secrets",
110
+ }),
111
+ secretProviders: () => [provider],
112
+ };
113
+ },
114
+ );
115
+
116
+ // End users compose the executor exactly the same way as above —
117
+ // the plugin's extension is reachable as `executor.memorySecrets`.
101
118
  const executor = await createExecutor({
102
- scope: { name: "my-app" },
103
- plugins: [mcpPlugin(), openApiPlugin(), graphqlPlugin()] as const,
119
+ plugins: [memorySecretsPlugin({ initial: { greeting: "hello" } })] as const,
120
+ onElicitation: "accept-all",
104
121
  });
105
122
 
106
- await executor.mcp.addSource({
107
- transport: "remote",
108
- name: "Context7",
109
- endpoint: "https://mcp.context7.com/mcp",
110
- });
111
- await executor.openapi.addSpec({
112
- spec: "https://petstore3.swagger.io/api/v3/openapi.json",
113
- namespace: "petstore",
123
+ console.log(executor.memorySecrets.label); // "in-memory secrets"
124
+
125
+ await executor.secrets.set({
126
+ id: "api-token",
127
+ name: "API Token",
128
+ value: "sk_live_xxx",
129
+ scope: executor.scopes[0]!.id,
114
130
  });
115
- await executor.graphql.addSource({ endpoint: "https://graphql.anilist.co", namespace: "anilist" });
116
131
 
117
- const tools = await executor.tools.list();
132
+ console.log(await executor.secrets.get("api-token")); // "sk_live_xxx"
133
+
134
+ await executor.close();
118
135
  ```
119
136
 
120
- Available plugins:
137
+ The same pattern is what every shipped `@executor-js/plugin-*` package does internally. See [`packages/plugins/file-secrets`](https://github.com/RhysSullivan/executor/tree/main/packages/plugins/file-secrets) for a production example that backs `secretProviders` with an XDG-located JSON file.
138
+
139
+ ## Plugins
140
+
141
+ These plugin packages are published from the monorepo:
121
142
 
122
- - [`@executor/plugin-mcp`](https://www.npmjs.com/package/@executor/plugin-mcp) — Model Context Protocol (stdio + remote)
123
- - [`@executor/plugin-openapi`](https://www.npmjs.com/package/@executor/plugin-openapi) — OpenAPI specs as tools
124
- - [`@executor/plugin-graphql`](https://www.npmjs.com/package/@executor/plugin-graphql) — GraphQL endpoints as tools
125
- - [`@executor/plugin-google-discovery`](https://www.npmjs.com/package/@executor/plugin-google-discovery) — Google Discovery APIs
126
- - [`@executor/plugin-file-secrets`](https://www.npmjs.com/package/@executor/plugin-file-secrets) — file-backed secret store
127
- - [`@executor/plugin-keychain`](https://www.npmjs.com/package/@executor/plugin-keychain) — OS keychain secret store
128
- - [`@executor/plugin-onepassword`](https://www.npmjs.com/package/@executor/plugin-onepassword) — 1Password secret source
143
+ - [`@executor-js/plugin-mcp`](https://www.npmjs.com/package/@executor-js/plugin-mcp) — Model Context Protocol sources (stdio + remote)
144
+ - [`@executor-js/plugin-openapi`](https://www.npmjs.com/package/@executor-js/plugin-openapi) — OpenAPI specs as tools
145
+ - [`@executor-js/plugin-graphql`](https://www.npmjs.com/package/@executor-js/plugin-graphql) — GraphQL endpoints as tools
146
+ - [`@executor-js/plugin-google-discovery`](https://www.npmjs.com/package/@executor-js/plugin-google-discovery) — Google Discovery APIs
147
+ - [`@executor-js/plugin-file-secrets`](https://www.npmjs.com/package/@executor-js/plugin-file-secrets) — file-backed secret store
148
+ - [`@executor-js/plugin-keychain`](https://www.npmjs.com/package/@executor-js/plugin-keychain) — OS keychain secret store
149
+ - [`@executor-js/plugin-onepassword`](https://www.npmjs.com/package/@executor-js/plugin-onepassword) — 1Password secret source
150
+
151
+ Each plugin exposes the same dual `.` / `./core` entry split as the SDK itself: end users import from the root, plugin authors who need to compose internals import from `/core`.
129
152
 
130
153
  ## Secrets
131
154
 
132
- Secrets are scoped per executor and shared across every plugin that resolves them:
155
+ Secrets are scoped per executor and shared across every plugin that contributes a provider. A writable provider must be registered (via a plugin) before `set` will succeed.
133
156
 
134
157
  ```ts
158
+ import { createExecutor } from "@executor-js/sdk";
159
+
160
+ declare const executor: Awaited<ReturnType<typeof createExecutor>>;
161
+
135
162
  await executor.secrets.set({
136
163
  id: "github-token",
137
164
  name: "GitHub Token",
138
165
  value: "ghp_...",
139
- purpose: "authentication",
166
+ scope: executor.scopes[0]!.id, // which scope owns the secret
140
167
  });
141
168
 
142
- const value = await executor.secrets.resolve("github-token");
143
- ```
144
-
145
- Plugins accept `{ secretId, prefix }` wherever a header value is expected, so you never write tokens into source configs.
146
-
147
- ## Using with Effect
148
-
149
- The SDK is built on [Effect](https://effect.website/) under the hood. If you want the raw Effect-based primitives instead of the promise wrapper, import from the `/core` subpath:
150
-
151
- ```ts
152
- import { createExecutor } from "@executor/sdk";
169
+ const value = await executor.secrets.get("github-token");
170
+ const refs = await executor.secrets.list();
153
171
  ```
154
172
 
155
- `/core` exposes `createExecutor` returning an `Effect`, the `ToolRegistry` / `SourceRegistry` / `SecretStore` / `PolicyEngine` Context tags, the in-memory store factories, and every branded ID + error class. Every `@executor/plugin-*` ships a matching `/core` subpath.
173
+ Plugins that need a token HTTP-backed sources, OAuth flows, etc. accept a secret id at the source-config layer and resolve through the executor, so token strings never live in your config files.
156
174
 
157
175
  ## Status
158
176
 
package/dist/blob.d.ts ADDED
@@ -0,0 +1,48 @@
1
+ import { Effect } from "effect";
2
+ import { StorageError } from "@executor-js/storage-core";
3
+ export interface BlobStore {
4
+ readonly get: (namespace: string, key: string) => Effect.Effect<string | null, StorageError>;
5
+ /** Multi-namespace lookup for a single key. Backends issue one query
6
+ * (`WHERE namespace IN (...) AND key = ?`) and return the hits keyed
7
+ * by namespace — the caller applies its own precedence. Lets
8
+ * `pluginBlobStore` walk the scope stack in O(1) round-trips instead
9
+ * of one per scope. */
10
+ readonly getMany: (namespaces: readonly string[], key: string) => Effect.Effect<ReadonlyMap<string, string>, StorageError>;
11
+ readonly put: (namespace: string, key: string, value: string) => Effect.Effect<void, StorageError>;
12
+ readonly delete: (namespace: string, key: string) => Effect.Effect<void, StorageError>;
13
+ readonly has: (namespace: string, key: string) => Effect.Effect<boolean, StorageError>;
14
+ }
15
+ export interface PluginBlobStore {
16
+ /** Walk the scope stack (innermost first) and return the first
17
+ * non-null value for `key`. */
18
+ readonly get: (key: string) => Effect.Effect<string | null, StorageError>;
19
+ /** Write `value` under `key` at the named scope. Scope must be one
20
+ * of the executor's configured scopes. */
21
+ readonly put: (key: string, value: string, options: {
22
+ readonly scope: string;
23
+ }) => Effect.Effect<void, StorageError>;
24
+ /** Delete `key` at the named scope. */
25
+ readonly delete: (key: string, options: {
26
+ readonly scope: string;
27
+ }) => Effect.Effect<void, StorageError>;
28
+ /** Walk the scope stack and return true if any scope has a value for `key`. */
29
+ readonly has: (key: string) => Effect.Effect<boolean, StorageError>;
30
+ }
31
+ /**
32
+ * Bind a `BlobStore` to a specific scope stack and plugin id. Reads
33
+ * fall through the stack; writes require an explicit scope. Used by
34
+ * the executor to build the `blobs` field handed to each plugin's
35
+ * `storage` factory.
36
+ */
37
+ export declare const pluginBlobStore: (store: BlobStore, scopes: readonly string[], pluginId: string) => PluginBlobStore;
38
+ /**
39
+ * Minimal in-memory BlobStore — good for tests and trivial hosts. Real
40
+ * backends (filesystem, S3/R2, SQLite-table-backed) implement the same
41
+ * interface.
42
+ *
43
+ * Every method is `Effect<_, never>` — a pure in-memory Map can't fail.
44
+ * `never` is assignable to `StorageError`, so the result still fits the
45
+ * `BlobStore` interface.
46
+ */
47
+ export declare const makeInMemoryBlobStore: () => BlobStore;
48
+ //# sourceMappingURL=blob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blob.d.ts","sourceRoot":"","sources":["../src/blob.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,GAAG,EAAE,CACZ,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,KACR,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,EAAE,YAAY,CAAC,CAAC;IAChD;;;;4BAIwB;IACxB,QAAQ,CAAC,OAAO,EAAE,CAChB,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,GAAG,EAAE,MAAM,KACR,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,CAAC,CAAC;IAC9D,QAAQ,CAAC,GAAG,EAAE,CACZ,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,KACV,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,CACf,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,KACR,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACvC,QAAQ,CAAC,GAAG,EAAE,CACZ,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,KACR,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,eAAe;IAC9B;oCACgC;IAChC,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,EAAE,YAAY,CAAC,CAAC;IAC1E;+CAC2C;IAC3C,QAAQ,CAAC,GAAG,EAAE,CACZ,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAChC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACvC,uCAAuC;IACvC,QAAQ,CAAC,MAAM,EAAE,CACf,GAAG,EAAE,MAAM,EACX,OAAO,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAChC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACvC,+EAA+E;IAC/E,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;CACrE;AAmBD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAC1B,OAAO,SAAS,EAChB,QAAQ,SAAS,MAAM,EAAE,EACzB,UAAU,MAAM,KACf,eA2BD,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,QAAO,SAwBxC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=blob.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blob.test.d.ts","sourceRoot":"","sources":["../src/blob.test.ts"],"names":[],"mappings":""}