@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.
Files changed (70) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/application-CP0W2sQo.mjs +3 -0
  3. package/dist/{application-C1d52JP9.mjs → application-CVeA53ok.mjs} +172 -27
  4. package/dist/application-CVeA53ok.mjs.map +1 -0
  5. package/dist/cli/index.mjs +19 -34
  6. package/dist/cli/index.mjs.map +1 -1
  7. package/dist/cli/lib.mjs +2 -2
  8. package/dist/cli/skills.mjs +1 -1
  9. package/dist/completion/zsh-worker.zsh +1 -1
  10. package/dist/configure/config/types.d.mts +3 -1
  11. package/dist/configure/index.d.mts +2 -1
  12. package/dist/configure/index.mjs +9 -0
  13. package/dist/configure/index.mjs.map +1 -1
  14. package/dist/configure/services/idp/permission.d.mts +1 -16
  15. package/dist/configure/services/index.d.mts +2 -1
  16. package/dist/configure/services/resolver/index.d.mts +2 -1
  17. package/dist/configure/services/resolver/permission.d.mts +64 -0
  18. package/dist/configure/services/resolver/resolver.d.mts +14 -2
  19. package/dist/configure/services/tailordb/permission.d.mts +1 -16
  20. package/dist/configure/types/permission-operand.types.d.mts +20 -0
  21. package/dist/{crashreport-BNWUM6Kf.mjs → crashreport-DMYuHnBN.mjs} +2 -2
  22. package/dist/{crashreport-BNWUM6Kf.mjs.map → crashreport-DMYuHnBN.mjs.map} +1 -1
  23. package/dist/{crashreport-BafWvjjX.mjs → crashreport-ecqnz51B.mjs} +1 -1
  24. package/dist/{globals-DVJ8RVvm.mjs → globals-DUqEetIh.mjs} +11 -2
  25. package/dist/{globals-DVJ8RVvm.mjs.map → globals-DUqEetIh.mjs.map} +1 -1
  26. package/dist/{logger-BwS4ppwO.mjs → logger-CXQq9YIp.mjs} +110 -13
  27. package/dist/logger-CXQq9YIp.mjs.map +1 -0
  28. package/dist/logger-t5ASCDZm.mjs +49 -0
  29. package/dist/logger-t5ASCDZm.mjs.map +1 -0
  30. package/dist/{register-typescript-runtime-Bd4bcLbW.mjs → register-typescript-runtime-O7zQNif0.mjs} +44 -17
  31. package/dist/register-typescript-runtime-O7zQNif0.mjs.map +1 -0
  32. package/dist/runtime/globals.d.mts +7 -0
  33. package/dist/runtime/index.d.mts +3 -1
  34. package/dist/runtime/index.mjs +2 -1
  35. package/dist/runtime/logger.d.mts +98 -0
  36. package/dist/runtime/logger.mjs +3 -0
  37. package/dist/{service-CDPatibu.mjs → service-B0MaodSg.mjs} +2 -2
  38. package/dist/{service-CDPatibu.mjs.map → service-B0MaodSg.mjs.map} +1 -1
  39. package/dist/{service-Cp0I7ZFe.mjs → service-CIGSGg9I.mjs} +2 -2
  40. package/dist/{service-Cp0I7ZFe.mjs.map → service-CIGSGg9I.mjs.map} +1 -1
  41. package/dist/service-KnAiVofD.mjs +3 -0
  42. package/dist/{service_pb-BoLM0X4K.mjs → service_pb-BwZRiNug.mjs} +2 -2
  43. package/dist/{service_pb-BoLM0X4K.mjs.map → service_pb-BwZRiNug.mjs.map} +1 -1
  44. package/dist/{service_pb-r1T7kpJc.mjs → service_pb-wRkxUta6.mjs} +1 -1
  45. package/dist/types/auth.generated.d.mts +14 -2
  46. package/dist/types/executor.generated.d.mts +19 -0
  47. package/dist/types/http-adapter.generated.d.mts +5 -0
  48. package/dist/types/idp.generated.d.mts +30 -0
  49. package/dist/types/resolver.generated.d.mts +28 -2
  50. package/dist/types/tailordb.generated.d.mts +15 -1
  51. package/dist/vitest/environment.mjs +1 -1
  52. package/dist/vitest/index.d.mts +4 -2
  53. package/dist/vitest/index.mjs +83 -2
  54. package/dist/vitest/index.mjs.map +1 -1
  55. package/dist/vitest/mock.d.mts +2 -1
  56. package/dist/vitest/mocks/file.d.mts +1 -1
  57. package/dist/vitest/mocks/logger.d.mts +45 -0
  58. package/dist/vitest/setup.mjs +1 -1
  59. package/dist/{workspace_resource_pb-Db3fv68L.mjs → workspace_resource_pb-UGK1SSn_.mjs} +7 -2
  60. package/dist/{workspace_resource_pb-Db3fv68L.mjs.map → workspace_resource_pb-UGK1SSn_.mjs.map} +1 -1
  61. package/docs/configuration.md +3 -1
  62. package/docs/runtime.md +4 -0
  63. package/docs/services/resolver.md +54 -0
  64. package/docs/testing.md +23 -2
  65. package/package.json +11 -6
  66. package/dist/application-C1d52JP9.mjs.map +0 -1
  67. package/dist/application-Nlh9BHQf.mjs +0 -3
  68. package/dist/logger-BwS4ppwO.mjs.map +0 -1
  69. package/dist/register-typescript-runtime-Bd4bcLbW.mjs.map +0 -1
  70. package/dist/service-Cg7Qibit.mjs +0 -3
@@ -41,7 +41,7 @@ export default defineConfig({
41
41
 
42
42
  **Disable Introspection**: Disable GraphQL introspection. Default is `false`.
43
43
 
44
- **Log Level**: Controls which `console.*` calls are kept when deployment functions are bundled. Supported values are `"DEBUG"`, `"INFO"`, `"WARN"`, `"ERROR"`, and `"SILENT"`. The default is `"DEBUG"` and keeps all console calls. `console.log` is treated as a DEBUG-level call (matching the platform's OpenTelemetry severity mapping), so it is dropped at `"INFO"` and above. For production deployments, use `"WARN"` to keep `console.warn` and `console.error` while dropping debug, log, and info calls:
44
+ **Log Level**: Controls which `console.*` and `logger.*` (from `@tailor-platform/sdk/runtime`) calls are kept when deployment functions are bundled. Supported values are `"DEBUG"`, `"INFO"`, `"WARN"`, `"ERROR"`, and `"SILENT"`. The default is `"DEBUG"` and keeps all calls. `console.log` is treated as a DEBUG-level call (matching the platform's OpenTelemetry severity mapping), so it is dropped at `"INFO"` and above, alongside `console.debug` and `logger.debug`. `logger.setAttributes` has no severity and is never dropped, regardless of `logLevel`. For production deployments, use `"WARN"` to keep warn/error calls while dropping debug, log, and info calls:
45
45
 
46
46
  ```typescript
47
47
  export default defineConfig({
@@ -52,6 +52,8 @@ export default defineConfig({
52
52
 
53
53
  This is a bundle-time setting. Changing `LOG_LEVEL` affects newly bundled deployments; already deployed functions must be redeployed.
54
54
 
55
+ Only `logger.*` calls made through the SDK's `logger` wrapper (from `@tailor-platform/sdk/runtime` or its `@tailor-platform/sdk/runtime/logger` subpath), or written as `globalThis.tailor.logger.*`, are covered. Other equivalent forms — such as the bare `tailor.logger.*` global or `self.tailor.logger.*` — are not affected by `logLevel`.
56
+
55
57
  ### Service Configuration
56
58
 
57
59
  Specify glob patterns to load service files:
package/docs/runtime.md CHANGED
@@ -20,6 +20,7 @@ import {
20
20
  context,
21
21
  file,
22
22
  aigateway,
23
+ logger,
23
24
  } from "@tailor-platform/sdk/runtime";
24
25
 
25
26
  const utf8 = iconv.convert(sjisBuffer, "Shift_JIS", "UTF-8");
@@ -38,6 +39,8 @@ const invoker = context.getInvoker();
38
39
  const { metadata } = await file.upload("my-namespace", "Document", "attachment", recordId, bytes);
39
40
 
40
41
  const { url } = await aigateway.get("my-aigateway");
42
+
43
+ logger.info("order processed", { orderId: "o-1", total: 99.5 });
41
44
  ```
42
45
 
43
46
  ## Subpath imports
@@ -83,6 +86,7 @@ The runtime entry re-exports the following namespaces. Detailed signatures, para
83
86
  - `context` — execution context (`getInvoker`)
84
87
  - `file` — `tailordb.file` BLOB API (`upload`, `download`, `downloadAsBase64`, `delete`, `getMetadata`, `downloadStream`, `uploadStream`, `openDownloadStream` _(deprecated)_)
85
88
  - `aigateway` — AI Gateway URL resolution (`get`)
89
+ - `logger` — structured logging with severity and attributes; the message is written to standard output, the full entry with its attributes is exported over OpenTelemetry where the attributes are queryable (`debug`, `info`, `warn`, `error`, `setAttributes`)
86
90
 
87
91
  ## Testing
88
92
 
@@ -350,6 +350,60 @@ createResolver({
350
350
  });
351
351
  ```
352
352
 
353
+ ## Permissions
354
+
355
+ ### Access Requirement (`permission`)
356
+
357
+ By default, a resolver with no in-body check is reachable by an anonymous (unauthenticated) caller. Set `permission` to reject callers that don't match a condition, evaluated before `body` runs:
358
+
359
+ ```typescript
360
+ import { createResolver, t } from "@tailor-platform/sdk";
361
+
362
+ export default createResolver({
363
+ name: "getMyOrders",
364
+ operation: "query",
365
+ permission: [{ conditions: [[{ user: "_loggedIn" }, "=", true]], permit: true }],
366
+ output: t.object({ count: t.int() }),
367
+ body: async (context) => {
368
+ // context.user is guaranteed to be an authenticated caller here
369
+ return { count: 0 };
370
+ },
371
+ });
372
+ ```
373
+
374
+ `permission` uses the same `conditions`/`permit` notation as TailorDB's `.permission()` — an array of policies, restricted to `user` operands (a resolver has no associated record to compare against) with equality (`=`/`!=`) comparisons:
375
+
376
+ - `{ user: "_loggedIn" }` — whether the caller is authenticated
377
+ - `{ user: "id" }` — the caller's user ID
378
+ - `{ user: "someAttribute" }` — any string or boolean attribute enabled in `auth.userProfile.attributes` (or `auth.machineUserAttributes` for machine users); array attributes aren't supported, since conditions only compare against a single string/boolean value
379
+
380
+ Multiple conditions within the same policy's `conditions` array are combined with AND. `permit` is required, with no implicit default. At least one `permit: true` policy is required: `permission` is an allow-list, denied by default and granted only by a matching `permit: true` policy. This lets you express different eligibility paths, e.g. allowing machine-user callers unconditionally while gating regular users behind a role check:
381
+
382
+ ```typescript
383
+ permission: [
384
+ { conditions: [[{ user: "isServiceAccount" }, "=", true]], permit: true },
385
+ { conditions: [[{ user: "role" }, "=", "ADMIN"]], permit: true },
386
+ ],
387
+ ```
388
+
389
+ A `permit: false` policy always denies matching callers, even ones another policy would otherwise allow. Combine it with a `permit: true` policy to carve out an explicit exception, e.g. granting access broadly but rejecting one banned role:
390
+
391
+ ```typescript
392
+ permission: [
393
+ { conditions: [[{ user: "_loggedIn" }, "=", true]], permit: true },
394
+ { conditions: [[{ user: "role" }, "=", "BANNED"]], permit: false },
395
+ ],
396
+ ```
397
+
398
+ A policy array made up of only `permit: false` policies is rejected: since none of its conditions apply to a caller presenting no user attributes at all, it wouldn't actually keep anyone out who's willing to drop their credentials, so it can't stand in for an allow-list.
399
+
400
+ Besides a policy array, `permission` also accepts:
401
+
402
+ - `"allowAnonymous"` — explicitly documents that anonymous callers are allowed. Behaves the same as omitting `permission`, but records the decision so it isn't mistaken for an oversight.
403
+ - Omitted (default) — unchanged: anonymous callers can still reach the resolver.
404
+
405
+ This check is based on `context.user`, the original caller, so it still applies even when `authInvoker` swaps in a machine user for database access.
406
+
353
407
  ## Authentication
354
408
 
355
409
  Specify an `authInvoker` to execute the resolver with machine user credentials. Pass the machine user name as a plain string — it is type-narrowed to the names you defined in your auth config:
package/docs/testing.md CHANGED
@@ -23,7 +23,7 @@ Platform API mocks under `@tailor-platform/sdk/vitest` (for use with the [`tailo
23
23
 
24
24
  - `mockTailordb` — TailorDB query stubs and call recording
25
25
  - `mockWorkflow` — `tailor.workflow` job / wait / resolve mocks
26
- - `mockSecretmanager`, `mockAuthconnection`, `mockIdp`, `mockFile`, `mockIconv`, `mockAigateway` — corresponding platform API mocks
26
+ - `mockSecretmanager`, `mockAuthconnection`, `mockIdp`, `mockFile`, `mockIconv`, `mockAigateway`, `mockLogger` — corresponding platform API mocks
27
27
 
28
28
  For tighter alignment with the production runtime — Node.js module blocking, Web-only globals, and platform API mocks — pair the resolver helpers with the [`tailor-runtime` Vitest environment](#runtime-environment-emulation-beta) below.
29
29
 
@@ -60,7 +60,7 @@ export default defineConfig({
60
60
 
61
61
  ### Acquiring mocks with `using`
62
62
 
63
- Each mock controller (`mockTailordb`, `mockWorkflow`, `mockSecretmanager`, `mockAuthconnection`, `mockIdp`, `mockFile`, `mockIconv`, `mockAigateway`) is a **factory function**. Acquire it inside a test with a [`using` declaration](https://github.com/tc39/proposal-explicit-resource-management) — its state is reset automatically when the test scope exits, so you no longer need `beforeEach(() => mock.reset())`:
63
+ Each mock controller (`mockTailordb`, `mockWorkflow`, `mockSecretmanager`, `mockAuthconnection`, `mockIdp`, `mockFile`, `mockIconv`, `mockAigateway`, `mockLogger`) is a **factory function**. Acquire it inside a test with a [`using` declaration](https://github.com/tc39/proposal-explicit-resource-management) — its state is reset automatically when the test scope exits, so you no longer need `beforeEach(() => mock.reset())`:
64
64
 
65
65
  ```typescript
66
66
  import { mockTailordb } from "@tailor-platform/sdk/vitest";
@@ -328,6 +328,27 @@ test("resolves an AI Gateway URL", async () => {
328
328
 
329
329
  Calling `get` for a name that has not been registered throws. `setUrls` remains available when replacing the complete URL fixture.
330
330
 
331
+ ### Logger Mock
332
+
333
+ Each method is a `vi.fn`, so assert on it directly. `calls` returns the emitted `debug`/`info`/`warn`/`error` entries in order.
334
+
335
+ ```typescript
336
+ import { mockLogger } from "@tailor-platform/sdk/vitest";
337
+
338
+ test("logs the processed order", () => {
339
+ using logger = mockLogger();
340
+
341
+ tailor.logger.info("order processed", { orderId: "o-1" });
342
+
343
+ expect(logger.info).toHaveBeenCalledWith("order processed", { orderId: "o-1" });
344
+ expect(logger.calls).toEqual([
345
+ { severity: "info", message: "order processed", attributes: { orderId: "o-1" } },
346
+ ]);
347
+ });
348
+ ```
349
+
350
+ Without an explicit `mockLogger()`, `tailor.logger.*` calls are no-ops in the `tailor-runtime` environment (they neither throw nor record).
351
+
331
352
  ### Loading Secrets from Config
332
353
 
333
354
  Pass a config path to load `defineSecretManager()` values into the mock:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailor-platform/sdk",
3
- "version": "1.80.1",
3
+ "version": "1.82.0",
4
4
  "description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -141,6 +141,11 @@
141
141
  "types": "./dist/runtime/aigateway.d.mts",
142
142
  "import": "./dist/runtime/aigateway.mjs",
143
143
  "default": "./dist/runtime/aigateway.mjs"
144
+ },
145
+ "./runtime/logger": {
146
+ "types": "./dist/runtime/logger.d.mts",
147
+ "import": "./dist/runtime/logger.mjs",
148
+ "default": "./dist/runtime/logger.mjs"
144
149
  }
145
150
  },
146
151
  "dependencies": {
@@ -171,6 +176,7 @@
171
176
  "date-fns": "4.4.0",
172
177
  "es-toolkit": "1.49.0",
173
178
  "find-up-simple": "1.0.1",
179
+ "get-east-asian-width": "1.6.0",
174
180
  "get-tsconfig": "4.14.0",
175
181
  "globals": "17.7.0",
176
182
  "graphql": "17.0.2",
@@ -179,7 +185,7 @@
179
185
  "madge": "8.0.0",
180
186
  "mime-types": "3.0.2",
181
187
  "open": "11.0.0",
182
- "oxc-parser": "0.139.0",
188
+ "oxc-parser": "0.140.0",
183
189
  "p-limit": "7.3.0",
184
190
  "pathe": "2.0.3",
185
191
  "pgsql-ast-parser": "12.0.2",
@@ -189,7 +195,6 @@
189
195
  "semver": "7.8.5",
190
196
  "sql-highlight": "6.1.0",
191
197
  "std-env": "4.2.0",
192
- "table": "6.9.0",
193
198
  "ts-cron-validator": "1.1.5",
194
199
  "tsx": "4.23.1",
195
200
  "type-fest": "5.8.0",
@@ -205,14 +210,14 @@
205
210
  "@types/semver": "7.7.1",
206
211
  "@typescript/native-preview": "7.0.0-dev.20260707.2",
207
212
  "@vitest/coverage-v8": "4.1.10",
208
- "oxfmt": "0.58.0",
209
- "oxlint": "1.73.0",
213
+ "oxfmt": "0.59.0",
214
+ "oxlint": "1.74.0",
210
215
  "oxlint-tsgolint": "0.25.0",
211
216
  "sonda": "0.14.0",
212
217
  "tsdown": "0.22.9",
213
218
  "typescript": "6.0.3",
214
219
  "vitest": "4.1.10",
215
- "zinfer": "0.2.5",
220
+ "zinfer": "0.2.7",
216
221
  "@tailor-platform/tailor-proto": "^0.0.0"
217
222
  },
218
223
  "peerDependencies": {