@databricks/appkit 0.82.0 → 0.84.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +21 -1
- package/dist/agents/databricks.d.ts +15 -3
- package/dist/agents/databricks.d.ts.map +1 -1
- package/dist/agents/databricks.js +25 -8
- package/dist/agents/databricks.js.map +1 -1
- package/dist/appkit/package.js +1 -1
- package/dist/beta.d.ts +2 -2
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +6 -1
- package/dist/cache/index.js.map +1 -1
- package/dist/cli/commands/agent/eval.js +1 -1
- package/dist/cli/commands/generate-types.js +1 -1
- package/dist/cli/commands/plugin/sync/sync.js +28 -15
- package/dist/cli/commands/plugin/sync/sync.js.map +1 -1
- package/dist/cli/commands/registry/add.js +3 -11
- package/dist/cli/commands/registry/add.js.map +1 -1
- package/dist/cli/commands/registry/config-writer.js +1 -1
- package/dist/connectors/lakebase/index.js +1 -1
- package/dist/connectors/lakebase/routing-pool.d.ts +1 -1
- package/dist/connectors/lakebase/routing-pool.d.ts.map +1 -1
- package/dist/connectors/lakebase/routing-pool.js +6 -12
- package/dist/connectors/lakebase/routing-pool.js.map +1 -1
- package/dist/context/caller-context.d.ts +25 -0
- package/dist/context/caller-context.d.ts.map +1 -0
- package/dist/context/caller-context.js +21 -0
- package/dist/context/caller-context.js.map +1 -0
- package/dist/context/deprecation.js +14 -0
- package/dist/context/deprecation.js.map +1 -0
- package/dist/context/execution-context.d.ts +40 -4
- package/dist/context/execution-context.d.ts.map +1 -1
- package/dist/context/execution-context.js +87 -33
- package/dist/context/execution-context.js.map +1 -1
- package/dist/context/index.d.ts +3 -2
- package/dist/context/index.js +3 -1
- package/dist/context/request-scope.d.ts +2 -0
- package/dist/context/request-scope.js +39 -0
- package/dist/context/request-scope.js.map +1 -0
- package/dist/context/resource-capabilities.js +59 -0
- package/dist/context/resource-capabilities.js.map +1 -0
- package/dist/context/scoped-api.js +104 -0
- package/dist/context/scoped-api.js.map +1 -0
- package/dist/context/service-context.d.ts +18 -12
- package/dist/context/service-context.d.ts.map +1 -1
- package/dist/context/service-context.js +45 -55
- package/dist/context/service-context.js.map +1 -1
- package/dist/context/user-context.d.ts +16 -22
- package/dist/context/user-context.d.ts.map +1 -1
- package/dist/context/user-context.js +57 -3
- package/dist/context/user-context.js.map +1 -1
- package/dist/core/agent/load-agents.d.ts.map +1 -1
- package/dist/core/agent/load-agents.js +5 -2
- package/dist/core/agent/load-agents.js.map +1 -1
- package/dist/core/agent/run-agent.d.ts +19 -6
- package/dist/core/agent/run-agent.d.ts.map +1 -1
- package/dist/core/agent/run-agent.js +53 -17
- package/dist/core/agent/run-agent.js.map +1 -1
- package/dist/core/agent/types.d.ts +18 -1
- package/dist/core/agent/types.d.ts.map +1 -1
- package/dist/core/agent/types.js.map +1 -1
- package/dist/core/appkit.d.ts +4 -3
- package/dist/core/appkit.d.ts.map +1 -1
- package/dist/core/appkit.js +34 -11
- package/dist/core/appkit.js.map +1 -1
- package/dist/core/plugin-context.d.ts +14 -15
- package/dist/core/plugin-context.d.ts.map +1 -1
- package/dist/core/plugin-context.js +24 -14
- package/dist/core/plugin-context.js.map +1 -1
- package/dist/errors/base.d.ts +2 -2
- package/dist/errors/base.js +2 -2
- package/dist/errors/base.js.map +1 -1
- package/dist/errors/identity-expired.d.ts +14 -0
- package/dist/errors/identity-expired.d.ts.map +1 -0
- package/dist/errors/identity-expired.js +33 -0
- package/dist/errors/identity-expired.js.map +1 -0
- package/dist/errors/index.js +1 -0
- package/dist/index.d.ts +12 -6
- package/dist/index.js +7 -2
- package/dist/logging/logger.js +1 -1
- package/dist/plugin/execution-result.d.ts +4 -1
- package/dist/plugin/execution-result.d.ts.map +1 -1
- package/dist/plugin/interceptors/telemetry.js +6 -4
- package/dist/plugin/interceptors/telemetry.js.map +1 -1
- package/dist/plugin/plugin.d.ts +14 -22
- package/dist/plugin/plugin.d.ts.map +1 -1
- package/dist/plugin/plugin.js +42 -123
- package/dist/plugin/plugin.js.map +1 -1
- package/dist/plugins/agents/agents.d.ts +13 -1
- package/dist/plugins/agents/agents.d.ts.map +1 -1
- package/dist/plugins/agents/agents.js +65 -15
- package/dist/plugins/agents/agents.js.map +1 -1
- package/dist/plugins/agents/auth-mode.js +42 -0
- package/dist/plugins/agents/auth-mode.js.map +1 -0
- package/dist/plugins/agents/index.d.ts +1 -1
- package/dist/plugins/agents/mlflow.js +11 -3
- package/dist/plugins/agents/mlflow.js.map +1 -1
- package/dist/plugins/agents/tool-dispatch.js +9 -1
- package/dist/plugins/agents/tool-dispatch.js.map +1 -1
- package/dist/plugins/ai-search/ai-search.d.ts +1 -1
- package/dist/plugins/ai-search/ai-search.d.ts.map +1 -1
- package/dist/plugins/ai-search/ai-search.js +4 -4
- package/dist/plugins/ai-search/ai-search.js.map +1 -1
- package/dist/plugins/analytics/analytics.d.ts +3 -3
- package/dist/plugins/analytics/analytics.d.ts.map +1 -1
- package/dist/plugins/analytics/analytics.js +9 -7
- package/dist/plugins/analytics/analytics.js.map +1 -1
- package/dist/plugins/database/crud/contract.js +2 -2
- package/dist/plugins/database/crud/contract.js.map +1 -1
- package/dist/plugins/database/database.d.ts +1 -1
- package/dist/plugins/files/plugin.d.ts +21 -15
- package/dist/plugins/files/plugin.d.ts.map +1 -1
- package/dist/plugins/files/plugin.js +50 -29
- package/dist/plugins/files/plugin.js.map +1 -1
- package/dist/plugins/genie/genie.d.ts +10 -1
- package/dist/plugins/genie/genie.d.ts.map +1 -1
- package/dist/plugins/genie/genie.js +12 -3
- package/dist/plugins/genie/genie.js.map +1 -1
- package/dist/plugins/genie/manifest.js +1 -0
- package/dist/plugins/jobs/plugin.d.ts +1 -1
- package/dist/plugins/jobs/plugin.js +2 -2
- package/dist/plugins/jobs/plugin.js.map +1 -1
- package/dist/plugins/lakebase/lakebase.d.ts +11 -18
- package/dist/plugins/lakebase/lakebase.d.ts.map +1 -1
- package/dist/plugins/lakebase/lakebase.js +16 -21
- package/dist/plugins/lakebase/lakebase.js.map +1 -1
- package/dist/plugins/server/client-config-sanitizer.js +1 -4
- package/dist/plugins/server/client-config-sanitizer.js.map +1 -1
- package/dist/plugins/server/dev-obo-middleware.js +60 -0
- package/dist/plugins/server/dev-obo-middleware.js.map +1 -0
- package/dist/plugins/server/index.d.ts +1 -1
- package/dist/plugins/server/index.d.ts.map +1 -1
- package/dist/plugins/server/index.js +3 -0
- package/dist/plugins/server/index.js.map +1 -1
- package/dist/plugins/serving/manifest.js +1 -0
- package/dist/plugins/serving/serving.d.ts +1 -1
- package/dist/plugins/serving/serving.js +6 -6
- package/dist/plugins/serving/serving.js.map +1 -1
- package/dist/resources/index.d.ts +1 -0
- package/dist/resources/index.js +3 -0
- package/dist/resources/warehouse.d.ts +16 -0
- package/dist/resources/warehouse.d.ts.map +1 -0
- package/dist/resources/warehouse.js +93 -0
- package/dist/resources/warehouse.js.map +1 -0
- package/dist/schemas/manifest.d.ts +44 -1
- package/dist/schemas/manifest.d.ts.map +1 -1
- package/dist/schemas/manifest.js +122 -3
- package/dist/schemas/manifest.js.map +1 -1
- package/dist/shared/src/dev-obo.js +86 -0
- package/dist/shared/src/dev-obo.js.map +1 -0
- package/dist/shared/src/index.d.ts +1 -1
- package/dist/shared/src/plugin.d.ts +12 -1
- package/dist/shared/src/plugin.d.ts.map +1 -1
- package/dist/shared/src/schemas/manifest.d.ts +17 -0
- package/dist/shared/src/schemas/manifest.d.ts.map +1 -1
- package/dist/shared/src/schemas/manifest.js +53 -3
- package/dist/shared/src/schemas/manifest.js.map +1 -1
- package/dist/stream/stream-manager.d.ts.map +1 -1
- package/dist/stream/stream-manager.js +5 -2
- package/dist/stream/stream-manager.js.map +1 -1
- package/dist/telemetry/execution-span-processor.js +21 -0
- package/dist/telemetry/execution-span-processor.js.map +1 -0
- package/dist/telemetry/telemetry-manager.js +2 -1
- package/dist/telemetry/telemetry-manager.js.map +1 -1
- package/dist/testing/create-test-app.d.ts +2 -2
- package/dist/testing/create-test-app.js +2 -2
- package/dist/testing/create-test-app.js.map +1 -1
- package/dist/testing/fixtures.d.ts +3 -2
- package/dist/testing/fixtures.d.ts.map +1 -1
- package/dist/testing/fixtures.js +21 -14
- package/dist/testing/fixtures.js.map +1 -1
- package/dist/testing/reset-singletons.js +1 -1
- package/dist/testing/test-plugin-context.d.ts +3 -12
- package/dist/testing/test-plugin-context.d.ts.map +1 -1
- package/dist/testing/test-plugin-context.js +24 -16
- package/dist/testing/test-plugin-context.js.map +1 -1
- package/dist/utils/is-plain-object.js +11 -0
- package/dist/utils/is-plain-object.js.map +1 -0
- package/docs/api/appkit/Class.AppKitError.md +2 -1
- package/docs/api/appkit/Class.AuthenticationError.md +1 -1
- package/docs/api/appkit/Class.ConfigurationError.md +1 -1
- package/docs/api/appkit/Class.ConnectionError.md +1 -1
- package/docs/api/appkit/Class.DatabaseValidationError.md +1 -1
- package/docs/api/appkit/Class.ExecutionError.md +1 -1
- package/docs/api/appkit/Class.IdentityExpiredError.md +190 -0
- package/docs/api/appkit/Class.InitializationError.md +1 -1
- package/docs/api/appkit/Class.Plugin.md +9 -13
- package/docs/api/appkit/Class.ServerError.md +1 -1
- package/docs/api/appkit/Class.ServiceContext.md +169 -0
- package/docs/api/appkit/Class.TunnelError.md +1 -1
- package/docs/api/appkit/Class.ValidationError.md +1 -1
- package/docs/api/appkit/Function.createApp.md +12 -12
- package/docs/api/appkit/Function.getCallerContext.md +12 -0
- package/docs/api/appkit/Function.getCurrentActorId.md +12 -0
- package/docs/api/appkit/Function.getCurrentPrincipalKey.md +12 -0
- package/docs/api/appkit/Function.getCurrentUserId.md +14 -0
- package/docs/api/appkit/Function.getExecutionContext.md +5 -3
- package/docs/api/appkit/Function.getUserContext.md +16 -0
- package/docs/api/appkit/Function.getWarehouseId.md +20 -0
- package/docs/api/appkit/Function.isInUserContext.md +12 -0
- package/docs/api/appkit/Function.isUserContext.md +20 -0
- package/docs/api/appkit/Function.runAgent.md +1 -1
- package/docs/api/appkit/Function.runInCallerContext.md +27 -0
- package/docs/api/appkit/Function.runInUserContext.md +29 -0
- package/docs/api/appkit/Interface.AgentDefinition.md +11 -0
- package/docs/api/appkit/Interface.AgentsPluginConfig.md +11 -0
- package/docs/api/appkit/Interface.CallerContext.md +54 -0
- package/docs/api/appkit/Interface.IndexConfig.md +1 -1
- package/docs/api/appkit/Interface.PluginManifest.md +33 -2
- package/docs/api/appkit/Interface.RegisteredAgent.md +11 -0
- package/docs/api/appkit/Interface.RunAgentInput.md +45 -1
- package/docs/api/appkit/TypeAlias.AgentAuth.md +8 -0
- package/docs/api/appkit/TypeAlias.AppKitApi.md +35 -0
- package/docs/api/appkit/TypeAlias.CallerPrincipal.md +13 -0
- package/docs/api/appkit/TypeAlias.ExecutionContext.md +9 -0
- package/docs/api/appkit/TypeAlias.ExecutionResult.md +65 -0
- package/docs/api/appkit/TypeAlias.ScopedPluginMap.md +12 -0
- package/docs/api/appkit/TypeAlias.UserContext.md +109 -0
- package/docs/api/appkit/TypeAlias.UserScopedApp.md +39 -0
- package/docs/api/appkit.md +20 -0
- package/docs/plugins/agents.md +45 -0
- package/docs/plugins/analytics.md +8 -0
- package/docs/plugins/execution-context.md +101 -50
- package/docs/plugins/lakebase.md +6 -82
- package/llms.txt +21 -1
- package/package.json +1 -1
- package/sbom.cdx.json +1 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ApiError } from "../../shared/src/workspace-client/errors.js";
|
|
2
2
|
import { AuthenticationError } from "../../errors/authentication.js";
|
|
3
3
|
import "../../errors/index.js";
|
|
4
|
-
import {
|
|
4
|
+
import { isCallerContext } from "../../context/caller-context.js";
|
|
5
5
|
import { createLogger } from "../../logging/logger.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { ServiceContext } from "../../context/service-context.js";
|
|
7
|
+
import { getCallerContext, getCurrentPrincipalId, getExecutionContext, getWorkspaceClient, runInCallerContext } from "../../context/execution-context.js";
|
|
8
8
|
import "../../context/index.js";
|
|
9
9
|
import { Plugin } from "../../plugin/plugin.js";
|
|
10
10
|
import { toPlugin } from "../../plugin/to-plugin.js";
|
|
@@ -22,8 +22,8 @@ import { FILES_DOWNLOAD_DEFAULTS, FILES_MAX_UPLOAD_SIZE, FILES_READ_DEFAULTS, FI
|
|
|
22
22
|
import { parentDirectory, sanitizeFilename } from "./helpers.js";
|
|
23
23
|
import manifest_default from "./manifest.js";
|
|
24
24
|
import { z } from "zod";
|
|
25
|
-
import { STATUS_CODES } from "node:http";
|
|
26
25
|
import { Readable } from "node:stream";
|
|
26
|
+
import { STATUS_CODES } from "node:http";
|
|
27
27
|
|
|
28
28
|
//#region src/plugins/files/plugin.ts
|
|
29
29
|
const logger = createLogger("files");
|
|
@@ -113,7 +113,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
113
113
|
* return a policy user explicitly marked `isServicePrincipal: true`, so
|
|
114
114
|
* even in dev a `usersOnly`-style policy that gates on
|
|
115
115
|
* `!user.isServicePrincipal` cannot be tricked. The matching SDK execution
|
|
116
|
-
* path also falls through to the SP client (no `
|
|
116
|
+
* path also falls through to the SP client (no `runInCallerContext` wrap),
|
|
117
117
|
* so the policy user and the SDK identity stay aligned.
|
|
118
118
|
*/
|
|
119
119
|
_extractUser(req) {
|
|
@@ -126,7 +126,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
126
126
|
if (process.env.NODE_ENV === "development") {
|
|
127
127
|
logger.warn("asUser(req) called without complete x-forwarded-user + x-forwarded-access-token headers — falling back to service principal identity (dev mode). In production this request would 401.");
|
|
128
128
|
return {
|
|
129
|
-
id:
|
|
129
|
+
id: getCurrentPrincipalId(),
|
|
130
130
|
isServicePrincipal: true
|
|
131
131
|
};
|
|
132
132
|
}
|
|
@@ -153,7 +153,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
153
153
|
if (!token && process.env.NODE_ENV === "development") {
|
|
154
154
|
logger.warn("OBO volume requested without x-forwarded-access-token — falling back to service principal identity (dev mode). In production this request would 401.");
|
|
155
155
|
return {
|
|
156
|
-
id:
|
|
156
|
+
id: getCurrentPrincipalId(),
|
|
157
157
|
isServicePrincipal: true
|
|
158
158
|
};
|
|
159
159
|
}
|
|
@@ -191,7 +191,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
191
191
|
* NOTE: This method only selects which identity the *policy* sees. The
|
|
192
192
|
* matching SDK execution identity is selected separately by
|
|
193
193
|
* `_resolveAuthForRequest` and applied via `_runWithAuth` /
|
|
194
|
-
* `
|
|
194
|
+
* `runInCallerContext` in each handler. The two selections are designed to
|
|
195
195
|
* converge on the same identity per the policy-user matrix in the docs —
|
|
196
196
|
* see `docs/docs/plugins/files.md#policy-user-matrix`.
|
|
197
197
|
*/
|
|
@@ -205,7 +205,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
205
205
|
else {
|
|
206
206
|
logger.debug("No x-forwarded-user header — proceeding with service principal identity for policy evaluation.");
|
|
207
207
|
user = {
|
|
208
|
-
id:
|
|
208
|
+
id: getCurrentPrincipalId(),
|
|
209
209
|
isServicePrincipal: true
|
|
210
210
|
};
|
|
211
211
|
}
|
|
@@ -481,7 +481,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
481
481
|
*
|
|
482
482
|
* On OBO volumes the read cache is disabled (see `_readSettings`), so
|
|
483
483
|
* invalidation is a no-op here for `mode === "on-behalf-of-user"`. The
|
|
484
|
-
* cache layer is keyed by `
|
|
484
|
+
* cache layer is keyed by `getCurrentPrincipalId()`, so user A's writes can
|
|
485
485
|
* only invalidate user A's cache entry — user B would otherwise see stale
|
|
486
486
|
* data for the same volume/path until TTL. Disabling the cache on OBO
|
|
487
487
|
* trades read performance for correctness; the alternative is a
|
|
@@ -501,7 +501,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
501
501
|
async _invalidateListCache(volumeKey, writtenPath, connector, mode = "service-principal") {
|
|
502
502
|
if (mode === "on-behalf-of-user") return;
|
|
503
503
|
const parent = parentDirectory(writtenPath);
|
|
504
|
-
const userKey =
|
|
504
|
+
const userKey = getCurrentPrincipalId();
|
|
505
505
|
const tryDelete = async (segment) => {
|
|
506
506
|
try {
|
|
507
507
|
await this.cache.delete(this.cache.generateKey([`files:${volumeKey}:list`, segment], userKey));
|
|
@@ -942,7 +942,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
942
942
|
return this.volumeConfigs[volumeKey]?.auth ?? this.config.auth ?? "service-principal";
|
|
943
943
|
}
|
|
944
944
|
/**
|
|
945
|
-
* Build a `
|
|
945
|
+
* Build a `CallerContext` from request headers when both
|
|
946
946
|
* `x-forwarded-access-token` and `x-forwarded-user` are present, otherwise
|
|
947
947
|
* return `null`. Used by OBO route handlers to wrap SDK calls in the
|
|
948
948
|
* end-user's identity. A `null` result means "fall back to the service
|
|
@@ -954,12 +954,12 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
954
954
|
const token = req.header("x-forwarded-access-token")?.trim();
|
|
955
955
|
const userId = req.header("x-forwarded-user")?.trim();
|
|
956
956
|
if (!token || !userId) return null;
|
|
957
|
-
return ServiceContext.
|
|
957
|
+
return ServiceContext.createCallerContext(token, userId);
|
|
958
958
|
}
|
|
959
959
|
/**
|
|
960
960
|
* Build the telemetry attribute hash for the `files.auth_mode` span
|
|
961
961
|
* attribute. The value reflects what operationally happened — i.e.
|
|
962
|
-
* whether `
|
|
962
|
+
* whether `runInCallerContext` actually wrapped the SDK call:
|
|
963
963
|
* - HTTP route on OBO volume + valid token → `"on-behalf-of-user"`.
|
|
964
964
|
* - HTTP route on OBO volume + dev-fallback (no token) →
|
|
965
965
|
* `"service-principal"` (the route falls through to the SP client).
|
|
@@ -973,12 +973,12 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
973
973
|
}
|
|
974
974
|
/**
|
|
975
975
|
* One-shot resolver for HTTP route handlers. Builds the request's
|
|
976
|
-
* `
|
|
976
|
+
* `CallerContext` AT MOST ONCE (when the volume is OBO and the headers are
|
|
977
977
|
* present) and returns both the operationally-effective auth mode and the
|
|
978
|
-
* pre-built `
|
|
978
|
+
* pre-built `CallerContext`.
|
|
979
979
|
*
|
|
980
980
|
* Handlers thread the `userCtx` into `_runWithAuth(userCtx, fn)` to avoid
|
|
981
|
-
* a second `ServiceContext.
|
|
981
|
+
* a second `ServiceContext.createCallerContext()` allocation. That call
|
|
982
982
|
* builds a fresh `WorkspaceClient` per invocation, so doing it twice per
|
|
983
983
|
* request was pure throwaway overhead.
|
|
984
984
|
*/
|
|
@@ -999,11 +999,11 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
999
999
|
/**
|
|
1000
1000
|
* Run `fn` under the correct execution context.
|
|
1001
1001
|
* - `userCtx` is `null`: invokes `fn` directly so the service-principal
|
|
1002
|
-
* `WorkspaceClient` and `
|
|
1002
|
+
* `WorkspaceClient` and `getCurrentPrincipalId()` are used, identical
|
|
1003
1003
|
* behavior to pre-OBO releases. This covers both SP volumes and the
|
|
1004
1004
|
* OBO dev-fallback path (where headers were missing).
|
|
1005
|
-
* - `userCtx` is a `
|
|
1006
|
-
* so SDK calls execute as the end user and `
|
|
1005
|
+
* - `userCtx` is a `CallerContext`: wraps `fn` in `runInCallerContext(userCtx)`,
|
|
1006
|
+
* so SDK calls execute as the end user and `getCurrentPrincipalId()` (and
|
|
1007
1007
|
* therefore cache keys) resolve to the user's ID.
|
|
1008
1008
|
*
|
|
1009
1009
|
* The caller is responsible for building `userCtx` exactly once per
|
|
@@ -1011,7 +1011,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
1011
1011
|
* NOT take a `req` so it cannot accidentally re-build the context.
|
|
1012
1012
|
*/
|
|
1013
1013
|
async _runWithAuth(userCtx, fn) {
|
|
1014
|
-
if (userCtx) return
|
|
1014
|
+
if (userCtx) return runInCallerContext(userCtx, fn);
|
|
1015
1015
|
return fn();
|
|
1016
1016
|
}
|
|
1017
1017
|
/**
|
|
@@ -1042,6 +1042,25 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
1042
1042
|
* additional parent span is opened, so each call produces exactly one
|
|
1043
1043
|
* `files.<operation>` span instead of two.
|
|
1044
1044
|
*/
|
|
1045
|
+
/**
|
|
1046
|
+
* Like `_wrapVolumeAPIWithSPSpan`, but picks `files.auth_mode` from the
|
|
1047
|
+
* active scope at call time: "on-behalf-of-user" inside a caller scope
|
|
1048
|
+
* (for example `appkit.asUser(req)`), "service-principal" otherwise.
|
|
1049
|
+
*/
|
|
1050
|
+
_wrapVolumeAPIWithScopeSpan(api) {
|
|
1051
|
+
const wrap = (operation, fn) => (...args) => this._withAuthModeAttributes(operation, getCallerContext() ? "on-behalf-of-user" : "service-principal", () => fn(...args));
|
|
1052
|
+
return {
|
|
1053
|
+
list: wrap("list", api.list),
|
|
1054
|
+
read: wrap("read", api.read),
|
|
1055
|
+
download: wrap("download", api.download),
|
|
1056
|
+
exists: wrap("exists", api.exists),
|
|
1057
|
+
metadata: wrap("metadata", api.metadata),
|
|
1058
|
+
upload: wrap("upload", api.upload),
|
|
1059
|
+
createDirectory: wrap("createDirectory", api.createDirectory),
|
|
1060
|
+
delete: wrap("delete", api.delete),
|
|
1061
|
+
preview: wrap("preview", api.preview)
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1045
1064
|
_wrapVolumeAPIWithSPSpan(api) {
|
|
1046
1065
|
const wrap = (operation, fn) => (...args) => this._withAuthModeAttributes(operation, "service-principal", () => fn(...args));
|
|
1047
1066
|
return {
|
|
@@ -1058,10 +1077,10 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
1058
1077
|
}
|
|
1059
1078
|
/**
|
|
1060
1079
|
* Wrap each `VolumeAPI` method so its execution runs inside
|
|
1061
|
-
* `
|
|
1080
|
+
* `runInCallerContext(userCtx, ...)`. Used by `VolumeHandle.asUser(req)` to
|
|
1062
1081
|
* force the SDK identity to the end user regardless of the volume's
|
|
1063
1082
|
* `auth` setting. The policy check baked into each method (via
|
|
1064
|
-
* `createVolumeAPI`) runs inside the same scope, so `
|
|
1083
|
+
* `createVolumeAPI`) runs inside the same scope, so `getCurrentPrincipalId()`
|
|
1065
1084
|
* and any cache `userKey` derived from it also resolve to the user.
|
|
1066
1085
|
*
|
|
1067
1086
|
* Each wrapped invocation tags the connector's span with
|
|
@@ -1069,7 +1088,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
1069
1088
|
* propagation — no additional parent span is opened.
|
|
1070
1089
|
*/
|
|
1071
1090
|
_wrapVolumeAPIInUserContext(api, userCtx) {
|
|
1072
|
-
const wrap = (operation, fn) => (...args) => this._withAuthModeAttributes(operation, "on-behalf-of-user", () =>
|
|
1091
|
+
const wrap = (operation, fn) => (...args) => this._withAuthModeAttributes(operation, "on-behalf-of-user", () => runInCallerContext(userCtx, () => fn(...args)));
|
|
1073
1092
|
return {
|
|
1074
1093
|
list: wrap("list", api.list),
|
|
1075
1094
|
read: wrap("read", api.read),
|
|
@@ -1142,7 +1161,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
1142
1161
|
_defineVolumeTools(volumeKey) {
|
|
1143
1162
|
const buildUser = () => {
|
|
1144
1163
|
const ctx = getExecutionContext();
|
|
1145
|
-
return
|
|
1164
|
+
return isCallerContext(ctx) ? { id: ctx.principal.userId } : {
|
|
1146
1165
|
id: ctx.serviceUserId,
|
|
1147
1166
|
isServicePrincipal: true
|
|
1148
1167
|
};
|
|
@@ -1265,7 +1284,7 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
1265
1284
|
* through the HTTP routes run as the end user; for programmatic calls
|
|
1266
1285
|
* outside a route, use `asUser(req)` to opt into per-user execution.
|
|
1267
1286
|
* `asUser(req)` is a hard override at the SDK level: it forces every
|
|
1268
|
-
* subsequent call to execute as the end user inside `
|
|
1287
|
+
* subsequent call to execute as the end user inside `runInCallerContext`,
|
|
1269
1288
|
* regardless of the volume's `auth` setting. Policies control per-user
|
|
1270
1289
|
* access in either mode.
|
|
1271
1290
|
*
|
|
@@ -1283,11 +1302,13 @@ var FilesPlugin = class FilesPlugin extends Plugin {
|
|
|
1283
1302
|
const resolveVolume = (volumeKey) => {
|
|
1284
1303
|
if (!this.volumeKeys.includes(volumeKey)) throw new Error(`Unknown volume "${volumeKey}". Available volumes: ${this.volumeKeys.join(", ")}`);
|
|
1285
1304
|
return {
|
|
1286
|
-
...this.
|
|
1305
|
+
...this._wrapVolumeAPIWithScopeSpan(this.createVolumeAPI(volumeKey, {
|
|
1287
1306
|
get id() {
|
|
1288
|
-
return
|
|
1307
|
+
return getCurrentPrincipalId();
|
|
1289
1308
|
},
|
|
1290
|
-
isServicePrincipal
|
|
1309
|
+
get isServicePrincipal() {
|
|
1310
|
+
return getCallerContext() === void 0;
|
|
1311
|
+
}
|
|
1291
1312
|
})),
|
|
1292
1313
|
asUser: (req) => {
|
|
1293
1314
|
const user = this._extractUser(req);
|