@tailor-platform/sdk 1.80.1 → 1.82.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/CHANGELOG.md +28 -0
- package/dist/application-CP0W2sQo.mjs +3 -0
- package/dist/{application-C1d52JP9.mjs → application-CVeA53ok.mjs} +172 -27
- package/dist/application-CVeA53ok.mjs.map +1 -0
- package/dist/cli/index.mjs +19 -34
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.mjs +2 -2
- package/dist/cli/skills.mjs +1 -1
- package/dist/completion/zsh-worker.zsh +1 -1
- package/dist/configure/config/types.d.mts +3 -1
- package/dist/configure/index.d.mts +2 -1
- package/dist/configure/index.mjs +9 -0
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/services/idp/permission.d.mts +1 -16
- package/dist/configure/services/index.d.mts +2 -1
- package/dist/configure/services/resolver/index.d.mts +2 -1
- package/dist/configure/services/resolver/permission.d.mts +64 -0
- package/dist/configure/services/resolver/resolver.d.mts +14 -2
- package/dist/configure/services/tailordb/permission.d.mts +1 -16
- package/dist/configure/types/permission-operand.types.d.mts +20 -0
- package/dist/{crashreport-BNWUM6Kf.mjs → crashreport-DMYuHnBN.mjs} +2 -2
- package/dist/{crashreport-BNWUM6Kf.mjs.map → crashreport-DMYuHnBN.mjs.map} +1 -1
- package/dist/{crashreport-BafWvjjX.mjs → crashreport-ecqnz51B.mjs} +1 -1
- package/dist/{globals-DVJ8RVvm.mjs → globals-DUqEetIh.mjs} +11 -2
- package/dist/{globals-DVJ8RVvm.mjs.map → globals-DUqEetIh.mjs.map} +1 -1
- package/dist/{logger-BwS4ppwO.mjs → logger-CXQq9YIp.mjs} +110 -13
- package/dist/logger-CXQq9YIp.mjs.map +1 -0
- package/dist/logger-t5ASCDZm.mjs +49 -0
- package/dist/logger-t5ASCDZm.mjs.map +1 -0
- package/dist/{register-typescript-runtime-Bd4bcLbW.mjs → register-typescript-runtime-O7zQNif0.mjs} +44 -17
- package/dist/register-typescript-runtime-O7zQNif0.mjs.map +1 -0
- package/dist/runtime/globals.d.mts +7 -0
- package/dist/runtime/index.d.mts +3 -1
- package/dist/runtime/index.mjs +2 -1
- package/dist/runtime/logger.d.mts +98 -0
- package/dist/runtime/logger.mjs +3 -0
- package/dist/{service-CDPatibu.mjs → service-B0MaodSg.mjs} +2 -2
- package/dist/{service-CDPatibu.mjs.map → service-B0MaodSg.mjs.map} +1 -1
- package/dist/{service-Cp0I7ZFe.mjs → service-CIGSGg9I.mjs} +2 -2
- package/dist/{service-Cp0I7ZFe.mjs.map → service-CIGSGg9I.mjs.map} +1 -1
- package/dist/service-KnAiVofD.mjs +3 -0
- package/dist/{service_pb-BoLM0X4K.mjs → service_pb-BwZRiNug.mjs} +2 -2
- package/dist/{service_pb-BoLM0X4K.mjs.map → service_pb-BwZRiNug.mjs.map} +1 -1
- package/dist/{service_pb-r1T7kpJc.mjs → service_pb-wRkxUta6.mjs} +1 -1
- package/dist/types/auth.generated.d.mts +14 -2
- package/dist/types/executor.generated.d.mts +19 -0
- package/dist/types/http-adapter.generated.d.mts +5 -0
- package/dist/types/idp.generated.d.mts +30 -0
- package/dist/types/resolver.generated.d.mts +28 -2
- package/dist/types/tailordb.generated.d.mts +15 -1
- package/dist/vitest/environment.mjs +1 -1
- package/dist/vitest/index.d.mts +4 -2
- package/dist/vitest/index.mjs +83 -2
- package/dist/vitest/index.mjs.map +1 -1
- package/dist/vitest/mock.d.mts +2 -1
- package/dist/vitest/mocks/file.d.mts +1 -1
- package/dist/vitest/mocks/logger.d.mts +45 -0
- package/dist/vitest/setup.mjs +1 -1
- package/dist/{workspace_resource_pb-Db3fv68L.mjs → workspace_resource_pb-UGK1SSn_.mjs} +7 -2
- package/dist/{workspace_resource_pb-Db3fv68L.mjs.map → workspace_resource_pb-UGK1SSn_.mjs.map} +1 -1
- package/docs/configuration.md +3 -1
- package/docs/runtime.md +4 -0
- package/docs/services/resolver.md +54 -0
- package/docs/testing.md +23 -2
- package/package.json +11 -6
- package/dist/application-C1d52JP9.mjs.map +0 -1
- package/dist/application-Nlh9BHQf.mjs +0 -3
- package/dist/logger-BwS4ppwO.mjs.map +0 -1
- package/dist/register-typescript-runtime-Bd4bcLbW.mjs.map +0 -1
- package/dist/service-Cg7Qibit.mjs +0 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @tailor-platform/sdk
|
|
2
2
|
|
|
3
|
+
## 1.82.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#1866](https://github.com/tailor-platform/sdk/pull/1866) [`1ae2485`](https://github.com/tailor-platform/sdk/commit/1ae24854f049ac51036842bacf4f35eb74ecd50c) Thanks [@toiroakr](https://github.com/toiroakr)! - `logLevel` now also controls `logger.*` calls (from `@tailor-platform/sdk/runtime`) in bundled functions, in addition to `console.*`. `logger.debug`/`logger.info`/`logger.warn`/`logger.error` are dropped at the same thresholds as their `console` counterparts.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- [#1848](https://github.com/tailor-platform/sdk/pull/1848) [`6f16760`](https://github.com/tailor-platform/sdk/commit/6f167606f01d3eacf157e81f7b7f4c6026b2dc99) Thanks [@toiroakr](https://github.com/toiroakr)! - Replaced the `table` dependency (heavy transitive deps, low OpenSSF Scorecard) with an in-house single-line box-drawing table renderer used by the CLI's tabular output (`logger.out`, `formatTable`/`formatKeyValueTable`/`formatTableWithHeaders`). Column width calculation now uses the small, dependency-free `get-east-asian-width` package for correct alignment with full-width (CJK) characters. No user-facing behavior change is expected.
|
|
12
|
+
|
|
13
|
+
## 1.81.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- [#1824](https://github.com/tailor-platform/sdk/pull/1824) [`617a263`](https://github.com/tailor-platform/sdk/commit/617a2632ae50f9b4db8e436d1da4c4888c907a58) Thanks [@haru0017](https://github.com/haru0017)! - Add a `logger` API for structured logging from Tailor Platform functions, exposing `debug`, `info`, `warn`, `error`, and `setAttributes`. The message is written to standard output, and the full entry with its attributes is exported over OpenTelemetry, where the attributes are queryable. Attribute values are typed to what OpenTelemetry can carry (`string`, `number`, `boolean`, and homogeneous arrays of those).
|
|
18
|
+
|
|
19
|
+
- [#1718](https://github.com/tailor-platform/sdk/pull/1718) [`d688c30`](https://github.com/tailor-platform/sdk/commit/d688c303be1b6693a36b50a03d52c670c05d035a) Thanks [@toiroakr](https://github.com/toiroakr)! - Add `permission` field to `createResolver` for declaring a resolver's access requirement, using the same `conditions`/`permit` policy notation as TailorDB's `.permission()` (restricted to `user` operands, e.g. `permission: [{ conditions: [[{ user: "_loggedIn" }, "=", true]], permit: true }]`). Rejects non-matching callers before `body` runs. At least one `permit: true` policy is required (deny by default, granted only by a match); a matching `permit: false` policy always overrides that grant, for carving out an explicit exception. `permission: "allowAnonymous"` explicitly documents that anonymous callers are allowed. Omitting `permission` keeps prior behavior unchanged. `tailor-sdk function test-run` enforces the same guard.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- [#1797](https://github.com/tailor-platform/sdk/pull/1797) [`93c1659`](https://github.com/tailor-platform/sdk/commit/93c16590eb21537ded9272ec12ecc683b61de04e) Thanks [@toiroakr](https://github.com/toiroakr)! - Fix deploy reporting spurious updates on every run: TailorDB types no longer drift when the platform proto gains new fields, IdP services without an explicit userAuthPolicy no longer drift against the platform's default password policy, and deploys with pending migrations no longer silently skip type changes in namespaces that have no migrations
|
|
24
|
+
|
|
25
|
+
- [#1842](https://github.com/tailor-platform/sdk/pull/1842) [`b19c22b`](https://github.com/tailor-platform/sdk/commit/b19c22bd8a22c8ec79a5f02545222706101926c6) Thanks [@toiroakr](https://github.com/toiroakr)! - fix(deps): update transitive dependency fast-uri to 3.1.4 [security]
|
|
26
|
+
|
|
27
|
+
- [#1822](https://github.com/tailor-platform/sdk/pull/1822) [`bcfc9ea`](https://github.com/tailor-platform/sdk/commit/bcfc9ea550744c9481fb29d8ed1629851fc0b1f0) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update dependency execa to v10
|
|
28
|
+
|
|
29
|
+
- [#1826](https://github.com/tailor-platform/sdk/pull/1826) [`bc85e4a`](https://github.com/tailor-platform/sdk/commit/bc85e4a72e25a9d0e0dadd7e2fae3a7be4d1ce59) Thanks [@renovate](https://github.com/apps/renovate)! - fix(deps): update oxc
|
|
30
|
+
|
|
3
31
|
## 1.80.1
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { n as isSdkBranded } from "./brand-Eo4pLXPJ.mjs";
|
|
2
2
|
import { t as assertDefined } from "./assert-DBxo8jPo.mjs";
|
|
3
|
-
import { a as parseBoolean, n as logger, r as styles } from "./logger-
|
|
4
|
-
import { a as TailorFieldSchema, i as AuthInvokerSchema, n as ExecutorSchema, o as loadFilesWithIgnores, r as AuthConfigSchema, s as functionSchema, t as createExecutorService } from "./service-
|
|
3
|
+
import { a as parseBoolean, n as logger, r as styles } from "./logger-CXQq9YIp.mjs";
|
|
4
|
+
import { a as TailorFieldSchema, i as AuthInvokerSchema, n as ExecutorSchema, o as loadFilesWithIgnores, r as AuthConfigSchema, s as functionSchema, t as createExecutorService } from "./service-B0MaodSg.mjs";
|
|
5
5
|
import { t as multiline } from "./multiline-sfHpTZZK.mjs";
|
|
6
6
|
import { t as isPluginGeneratedType } from "./type-source-DH_LH20p.mjs";
|
|
7
7
|
import { t as userAgent } from "./user-agent-DX2Jnw0-.mjs";
|
|
@@ -180,7 +180,7 @@ function initOAuth2Client(config) {
|
|
|
180
180
|
*/
|
|
181
181
|
async function initOperatorClient(accessToken, config) {
|
|
182
182
|
const platformConfig = config ?? getPlatformConfigForToken(accessToken);
|
|
183
|
-
const [{ createTracingInterceptor }, { OperatorService }] = await Promise.all([import("./interceptor-D-q1rvRl.mjs"), import("./service_pb-
|
|
183
|
+
const [{ createTracingInterceptor }, { OperatorService }] = await Promise.all([import("./interceptor-D-q1rvRl.mjs"), import("./service_pb-wRkxUta6.mjs")]);
|
|
184
184
|
const interceptors = [
|
|
185
185
|
await userAgentInterceptor(),
|
|
186
186
|
await bearerTokenInterceptor(accessToken),
|
|
@@ -260,7 +260,7 @@ function retryInterceptor() {
|
|
|
260
260
|
logger.debug(`retry: ${req.method.name} returned AlreadyExists on attempt ${i + 1}; treating as success (prior attempt likely committed)`);
|
|
261
261
|
return synthesizeEmptyUnaryResponse(req);
|
|
262
262
|
}
|
|
263
|
-
const { reportCrash } = await import("./crashreport-
|
|
263
|
+
const { reportCrash } = await import("./crashreport-ecqnz51B.mjs");
|
|
264
264
|
await reportCrash(error, "handledError");
|
|
265
265
|
}
|
|
266
266
|
if (req.method.name !== "CreateWorkspace" && isRetirable(error, req.method.idempotency)) {
|
|
@@ -2057,20 +2057,36 @@ const DEBUG_LEVEL_CONSOLE_METHODS = [
|
|
|
2057
2057
|
];
|
|
2058
2058
|
const WARN_LEVEL_CONSOLE_METHODS = ["console.warn"];
|
|
2059
2059
|
const ERROR_LEVEL_CONSOLE_METHODS = ["console.error"];
|
|
2060
|
+
const DEBUG_LEVEL_LOGGER_METHODS = ["globalThis.tailor.logger.debug"];
|
|
2061
|
+
const INFO_LEVEL_LOGGER_METHODS = ["globalThis.tailor.logger.info"];
|
|
2062
|
+
const WARN_LEVEL_LOGGER_METHODS = ["globalThis.tailor.logger.warn"];
|
|
2063
|
+
const ERROR_LEVEL_LOGGER_METHODS = ["globalThis.tailor.logger.error"];
|
|
2060
2064
|
const MANUAL_PURE_FUNCTIONS_BY_LOG_LEVEL = {
|
|
2061
2065
|
DEBUG: [],
|
|
2062
|
-
INFO: DEBUG_LEVEL_CONSOLE_METHODS,
|
|
2063
|
-
WARN: [
|
|
2066
|
+
INFO: [...DEBUG_LEVEL_CONSOLE_METHODS, ...DEBUG_LEVEL_LOGGER_METHODS],
|
|
2067
|
+
WARN: [
|
|
2068
|
+
...DEBUG_LEVEL_CONSOLE_METHODS,
|
|
2069
|
+
...INFO_LEVEL_CONSOLE_METHODS,
|
|
2070
|
+
...DEBUG_LEVEL_LOGGER_METHODS,
|
|
2071
|
+
...INFO_LEVEL_LOGGER_METHODS
|
|
2072
|
+
],
|
|
2064
2073
|
ERROR: [
|
|
2065
2074
|
...DEBUG_LEVEL_CONSOLE_METHODS,
|
|
2066
2075
|
...INFO_LEVEL_CONSOLE_METHODS,
|
|
2067
|
-
...WARN_LEVEL_CONSOLE_METHODS
|
|
2076
|
+
...WARN_LEVEL_CONSOLE_METHODS,
|
|
2077
|
+
...DEBUG_LEVEL_LOGGER_METHODS,
|
|
2078
|
+
...INFO_LEVEL_LOGGER_METHODS,
|
|
2079
|
+
...WARN_LEVEL_LOGGER_METHODS
|
|
2068
2080
|
],
|
|
2069
2081
|
SILENT: [
|
|
2070
2082
|
...DEBUG_LEVEL_CONSOLE_METHODS,
|
|
2071
2083
|
...INFO_LEVEL_CONSOLE_METHODS,
|
|
2072
2084
|
...WARN_LEVEL_CONSOLE_METHODS,
|
|
2073
|
-
...ERROR_LEVEL_CONSOLE_METHODS
|
|
2085
|
+
...ERROR_LEVEL_CONSOLE_METHODS,
|
|
2086
|
+
...DEBUG_LEVEL_LOGGER_METHODS,
|
|
2087
|
+
...INFO_LEVEL_LOGGER_METHODS,
|
|
2088
|
+
...WARN_LEVEL_LOGGER_METHODS,
|
|
2089
|
+
...ERROR_LEVEL_LOGGER_METHODS
|
|
2074
2090
|
]
|
|
2075
2091
|
};
|
|
2076
2092
|
function normalizeBundleLogLevel(value) {
|
|
@@ -3918,6 +3934,111 @@ function buildExecutorArgsExpr(triggerKind, env) {
|
|
|
3918
3934
|
function buildResolverOperationHookExpr(env) {
|
|
3919
3935
|
return `({ ...context.pipeline, input: context.args, user: ${tailorUserMap}, env: ${JSON.stringify(env)} });`;
|
|
3920
3936
|
}
|
|
3937
|
+
function isSingleResolverCondition(conditions) {
|
|
3938
|
+
return conditions.length === 3 && typeof conditions[1] === "string";
|
|
3939
|
+
}
|
|
3940
|
+
function resolverPermissionOperandExpr(operand) {
|
|
3941
|
+
if (typeof operand === "object") {
|
|
3942
|
+
if (operand.user === "_loggedIn") return `(context.user.type !== "")`;
|
|
3943
|
+
if (operand.user === "id") return `context.user.id`;
|
|
3944
|
+
return `context.user.attributes?.[${JSON.stringify(operand.user)}]`;
|
|
3945
|
+
}
|
|
3946
|
+
return JSON.stringify(operand);
|
|
3947
|
+
}
|
|
3948
|
+
function isArbitraryAttributeOperand(operand) {
|
|
3949
|
+
return typeof operand === "object" && operand.user !== "_loggedIn" && operand.user !== "id";
|
|
3950
|
+
}
|
|
3951
|
+
function resolverPermissionConditionExpr(condition) {
|
|
3952
|
+
const [left, operator, right] = condition;
|
|
3953
|
+
const leftExpr = resolverPermissionOperandExpr(left);
|
|
3954
|
+
const rightExpr = resolverPermissionOperandExpr(right);
|
|
3955
|
+
if (operator === "!=") {
|
|
3956
|
+
const userOperandExpr = isArbitraryAttributeOperand(left) ? leftExpr : isArbitraryAttributeOperand(right) ? rightExpr : void 0;
|
|
3957
|
+
if (userOperandExpr) return `(${userOperandExpr} !== undefined && ${leftExpr} !== ${rightExpr})`;
|
|
3958
|
+
}
|
|
3959
|
+
return `(${leftExpr} ${operator === "=" ? "===" : "!=="} ${rightExpr})`;
|
|
3960
|
+
}
|
|
3961
|
+
function resolverPermissionPolicyExpr(policy) {
|
|
3962
|
+
const conditions = isSingleResolverCondition(policy.conditions) ? [policy.conditions] : policy.conditions;
|
|
3963
|
+
if (conditions.length === 0) throw new Error("Resolver permission policy must have at least one condition, got an empty array.");
|
|
3964
|
+
return conditions.map(resolverPermissionConditionExpr).join(" && ");
|
|
3965
|
+
}
|
|
3966
|
+
/**
|
|
3967
|
+
* Build a JS object literal capturing whether `policy` matched and its
|
|
3968
|
+
* (possibly empty) description, for runtime denial-reason attribution.
|
|
3969
|
+
* @param policy - The policy to compile
|
|
3970
|
+
* @returns A JS object literal expression: `{ matched, description }`
|
|
3971
|
+
*/
|
|
3972
|
+
function policyEntryExpr(policy) {
|
|
3973
|
+
return `{ matched: ${resolverPermissionPolicyExpr(policy)}, description: ${JSON.stringify(policy.description ?? "")} }`;
|
|
3974
|
+
}
|
|
3975
|
+
/**
|
|
3976
|
+
* Build the permission guard statement injected at resolver entry.
|
|
3977
|
+
*
|
|
3978
|
+
* Rejects the call with `TailorErrorMessage` when the caller doesn't match
|
|
3979
|
+
* `permission`, evaluated against `context.user` — the original caller,
|
|
3980
|
+
* unaffected by `authInvoker`. `permission` is deny-by-default: a caller is
|
|
3981
|
+
* granted only by a matching `permit: true` policy, and a matching
|
|
3982
|
+
* `permit: false` policy always overrides that grant. The thrown message only
|
|
3983
|
+
* includes the description(s) of the policy/policies that actually caused the
|
|
3984
|
+
* denial.
|
|
3985
|
+
*
|
|
3986
|
+
* The schema requires at least one `permit: true` policy (an array of only
|
|
3987
|
+
* `permit: false` policies is rejected at build time), so `allowPolicies` is
|
|
3988
|
+
* never empty here for schema-valid input; this function still handles that
|
|
3989
|
+
* case defensively since it also runs against test-authored raw shapes.
|
|
3990
|
+
* @param permission - The resolver's `permission` config
|
|
3991
|
+
* @returns A JS statement, or `undefined` when `permission` is omitted or `"allowAnonymous"`
|
|
3992
|
+
*/
|
|
3993
|
+
function buildResolverPermissionGuardExpr(permission) {
|
|
3994
|
+
if (!permission || permission === "allowAnonymous") return;
|
|
3995
|
+
if (permission.length === 0) throw new Error("Resolver permission must have at least one policy, got an empty array.");
|
|
3996
|
+
const denyPolicies = permission.filter((policy) => policy.permit === false);
|
|
3997
|
+
const allowPolicies = permission.filter((policy) => policy.permit !== false);
|
|
3998
|
+
return `{
|
|
3999
|
+
const $denyPolicies = ${`[${denyPolicies.map(policyEntryExpr).join(", ")}]`};
|
|
4000
|
+
const $allowPolicies = ${`[${allowPolicies.map(policyEntryExpr).join(", ")}]`};
|
|
4001
|
+
const $matchedDeny = $denyPolicies.filter((p) => p.matched);
|
|
4002
|
+
const $anyAllowMatched = $allowPolicies.some((p) => p.matched);
|
|
4003
|
+
if ($matchedDeny.length > 0 || ($allowPolicies.length > 0 && !$anyAllowMatched)) {
|
|
4004
|
+
const $reasons = ($matchedDeny.length > 0 ? $matchedDeny : $allowPolicies)
|
|
4005
|
+
.map((p) => p.description)
|
|
4006
|
+
.filter(Boolean);
|
|
4007
|
+
throw new TailorErrorMessage($reasons.length > 0 ? "access denied: " + $reasons.join("; ") : "access denied");
|
|
4008
|
+
}
|
|
4009
|
+
}`;
|
|
4010
|
+
}
|
|
4011
|
+
/**
|
|
4012
|
+
* Build the permission guard and input-validation statements shared by every
|
|
4013
|
+
* resolver entry wrapper (production bundling and `function test-run`).
|
|
4014
|
+
*
|
|
4015
|
+
* Kept as a single generator so a resolver-wrapping behavior (like the
|
|
4016
|
+
* permission guard) can't be added to one entry-point template and forgotten
|
|
4017
|
+
* in the other. References `context.user`, `context.input`, and
|
|
4018
|
+
* `_internalResolver` — the caller's wrapper must bind a `context` object
|
|
4019
|
+
* with `user`/`input` properties before inlining this expression.
|
|
4020
|
+
* @param permission - The resolver's `permission` config
|
|
4021
|
+
* @returns A JS statement block to inline before calling `_internalResolver.body(...)`
|
|
4022
|
+
*/
|
|
4023
|
+
function buildResolverPermissionAndInputCheckExpr(permission) {
|
|
4024
|
+
return `
|
|
4025
|
+
${buildResolverPermissionGuardExpr(permission) ?? ""}
|
|
4026
|
+
if (_internalResolver.input) {
|
|
4027
|
+
const result = t.object(_internalResolver.input).parse({
|
|
4028
|
+
value: context.input,
|
|
4029
|
+
data: context.input,
|
|
4030
|
+
user: context.user,
|
|
4031
|
+
});
|
|
4032
|
+
|
|
4033
|
+
if (result.issues) {
|
|
4034
|
+
throw new TailorErrors(result.issues.map(issue => ({
|
|
4035
|
+
message: issue.message,
|
|
4036
|
+
path: issue.path ?? [],
|
|
4037
|
+
})));
|
|
4038
|
+
}
|
|
4039
|
+
}
|
|
4040
|
+
`;
|
|
4041
|
+
}
|
|
3921
4042
|
|
|
3922
4043
|
//#endregion
|
|
3923
4044
|
//#region src/cli/services/executor/loader.ts
|
|
@@ -4338,6 +4459,42 @@ function isAsyncFunction(fn) {
|
|
|
4338
4459
|
//#endregion
|
|
4339
4460
|
//#region src/parser/service/resolver/schema.ts
|
|
4340
4461
|
const QueryTypeSchema = z.union([z.literal("query"), z.literal("mutation")]).describe("GraphQL operation type");
|
|
4462
|
+
const ResolverPermissionOperandSchema = z.union([
|
|
4463
|
+
z.object({ user: z.string() }).strict(),
|
|
4464
|
+
z.string(),
|
|
4465
|
+
z.boolean()
|
|
4466
|
+
]);
|
|
4467
|
+
const ResolverPermissionOperatorSchema = z.union([z.literal("="), z.literal("!=")]);
|
|
4468
|
+
const isUserOperand = (operand) => typeof operand === "object";
|
|
4469
|
+
const KNOWN_USER_OPERAND_TYPES = {
|
|
4470
|
+
_loggedIn: "boolean",
|
|
4471
|
+
id: "string"
|
|
4472
|
+
};
|
|
4473
|
+
const operandTypeMismatch = (userOperand, otherOperand) => {
|
|
4474
|
+
if (typeof userOperand !== "object") return;
|
|
4475
|
+
const expected = KNOWN_USER_OPERAND_TYPES[userOperand.user];
|
|
4476
|
+
if (expected === void 0 || typeof otherOperand === "object" || typeof otherOperand === expected) return;
|
|
4477
|
+
return {
|
|
4478
|
+
key: userOperand.user,
|
|
4479
|
+
expected
|
|
4480
|
+
};
|
|
4481
|
+
};
|
|
4482
|
+
const ResolverPermissionConditionSchema = z.tuple([
|
|
4483
|
+
ResolverPermissionOperandSchema,
|
|
4484
|
+
ResolverPermissionOperatorSchema,
|
|
4485
|
+
ResolverPermissionOperandSchema
|
|
4486
|
+
]).refine(([left, , right]) => isUserOperand(left) !== isUserOperand(right), "Resolver permission condition must reference a `user` operand on exactly one side (comparing two `user` operands to each other can match on `undefined === undefined`)").superRefine(([left, , right], ctx) => {
|
|
4487
|
+
for (const mismatch of [operandTypeMismatch(left, right), operandTypeMismatch(right, left)]) if (mismatch) ctx.addIssue({
|
|
4488
|
+
code: "custom",
|
|
4489
|
+
message: `\`${mismatch.key}\` must compare to a ${mismatch.expected}`
|
|
4490
|
+
});
|
|
4491
|
+
}).readonly();
|
|
4492
|
+
const ResolverPermissionPolicySchema = z.object({
|
|
4493
|
+
conditions: z.union([ResolverPermissionConditionSchema, z.array(ResolverPermissionConditionSchema).min(1, "Resolver permission policy must have at least one condition").readonly()]),
|
|
4494
|
+
permit: z.boolean(),
|
|
4495
|
+
description: z.string().optional().describe("Reason recorded for this policy, used in the access-denied error message")
|
|
4496
|
+
});
|
|
4497
|
+
const ResolverPermissionSchema = z.union([z.array(ResolverPermissionPolicySchema).min(1, "Resolver permission must have at least one policy").refine((policies) => policies.some((policy) => policy.permit === true), "Resolver permission must include at least one `permit: true` policy — a policy array with only `permit: false` policies still lets any caller through by simply not authenticating, since none of the deny conditions apply to a caller with no user attributes at all").readonly(), z.literal("allowAnonymous")]).describe("Access requirement for this resolver, evaluated against the original caller (unaffected by `authInvoker`) before `body` runs. \"allowAnonymous\" documents that anonymous callers are allowed. Omitted (default): unchanged, anonymous callers can reach the resolver");
|
|
4341
4498
|
const ResolverSchema = z.object({
|
|
4342
4499
|
operation: QueryTypeSchema.describe("GraphQL operation type (query or mutation)"),
|
|
4343
4500
|
name: z.string().describe("Resolver name"),
|
|
@@ -4346,7 +4503,8 @@ const ResolverSchema = z.object({
|
|
|
4346
4503
|
body: functionSchema.describe("Resolver implementation function"),
|
|
4347
4504
|
output: TailorFieldSchema.describe("Output field definition"),
|
|
4348
4505
|
publishEvents: z.boolean().optional().describe("Enable publishing events from this resolver"),
|
|
4349
|
-
authInvoker: AuthInvokerSchema.optional().describe("Machine user to execute this resolver as")
|
|
4506
|
+
authInvoker: AuthInvokerSchema.optional().describe("Machine user to execute this resolver as"),
|
|
4507
|
+
permission: ResolverPermissionSchema.optional()
|
|
4350
4508
|
});
|
|
4351
4509
|
|
|
4352
4510
|
//#endregion
|
|
@@ -4399,7 +4557,8 @@ async function bundleResolvers(namespace, config, baseDir, triggerContext, cache
|
|
|
4399
4557
|
}
|
|
4400
4558
|
resolvers.push({
|
|
4401
4559
|
name: resolver.name,
|
|
4402
|
-
sourceFile: file
|
|
4560
|
+
sourceFile: file,
|
|
4561
|
+
permission: resolver.permission
|
|
4403
4562
|
});
|
|
4404
4563
|
}
|
|
4405
4564
|
const tsconfig = await resolveTSConfigWithFallback(baseDir);
|
|
@@ -4431,21 +4590,7 @@ async function bundleSingleResolver(namespace, resolver, tsconfig, triggerContex
|
|
|
4431
4590
|
|
|
4432
4591
|
const $tailor_resolver_body = async (context) => {
|
|
4433
4592
|
const invoker = ${INVOKER_EXPR};
|
|
4434
|
-
|
|
4435
|
-
const result = t.object(_internalResolver.input).parse({
|
|
4436
|
-
value: context.input,
|
|
4437
|
-
data: context.input,
|
|
4438
|
-
user: context.user,
|
|
4439
|
-
});
|
|
4440
|
-
|
|
4441
|
-
if (result.issues) {
|
|
4442
|
-
throw new TailorErrors(result.issues.map(issue => ({
|
|
4443
|
-
message: issue.message,
|
|
4444
|
-
path: issue.path ?? [],
|
|
4445
|
-
})));
|
|
4446
|
-
}
|
|
4447
|
-
}
|
|
4448
|
-
|
|
4593
|
+
${buildResolverPermissionAndInputCheckExpr(resolver.permission)}
|
|
4449
4594
|
return _internalResolver.body({ ...context, invoker });
|
|
4450
4595
|
};
|
|
4451
4596
|
|
|
@@ -5611,5 +5756,5 @@ async function loadApplication(params) {
|
|
|
5611
5756
|
}
|
|
5612
5757
|
|
|
5613
5758
|
//#endregion
|
|
5614
|
-
export {
|
|
5615
|
-
//# sourceMappingURL=application-
|
|
5759
|
+
export { defaultPlatformBaseUrl as A, getPlatformBaseUrl as B, getPluginGenerationDependencies as C, hashContent as D, getDistDir as E, fetchPlatformMachineUserToken as F, rememberPlatformConfigForToken as G, initOperatorClient as H, fetchUserInfo as I, createApplyLimiter as J, resolveStaticWebsiteUrls as K, getConsoleBaseUrl as L, fetchAllTolerant as M, fetchMachineUserToken as N, hashFile as O, fetchPaged as P, getOAuth2ClientId as R, resolveBundleLogLevel as S, createBundleCache as T, isDefaultPlatform as U, initOAuth2Client as V, normalizeBaseUrl as W, LOG_LEVELS as Y, stringifyFunction as _, resolveInlineSourcemap as a, composeFunctionTreeshakeOptions as b, ResolverSchema as c, buildExecutorArgsExpr as d, buildResolverOperationHookExpr as f, TailorDBTypeSchema as g, assertUniqueTailorDBTypeNamesWithExternal as h, resolverBundleKey as i, fetchAll as j, closeConnectionPool as k, HTTP_METHODS as l, assertUniqueLocalTailorDBTypeNames as m, generatePluginFilesIfNeeded as n, WorkflowJobFunctionExecutionPolicySchema as o, buildResolverPermissionAndInputCheckExpr as p, byName as q, loadApplication as r, WorkflowJobSchema as s, defineApplication as t, INVOKER_EXPR as u, resolveTSConfigWithFallback as v, hasGenerationHooks as w, createLogLevelTreeshakeOptions as x, platformBundleDefinePlugin as y, getOrNull as z };
|
|
5760
|
+
//# sourceMappingURL=application-CVeA53ok.mjs.map
|