@tailor-platform/sdk 2.1.0 → 2.2.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 (80) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/{dist/cli/index.mjs → bin/tailor.mjs} +1 -1
  3. package/dist/{application-D77KJFKD.mjs → application-BpLeawBg.mjs} +6 -6
  4. package/dist/{application-D77KJFKD.mjs.map → application-BpLeawBg.mjs.map} +1 -1
  5. package/dist/application-BxLLiLsr.mjs +3 -0
  6. package/dist/cli/commands/deploy/tailordb/index.d.mts +2 -1
  7. package/dist/cli/commands/deploy/types.d.mts +2 -1
  8. package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +11 -4
  9. package/dist/cli/commands/tailordb/migrate/file-state.d.mts +1 -0
  10. package/dist/cli/commands/tailordb/migrate/schema-checks.d.mts +2 -2
  11. package/dist/cli/commands/tailordb/migrate/snapshot-types.d.mts +8 -1
  12. package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +5 -3
  13. package/dist/cli/lib.d.mts +4 -4
  14. package/dist/cli/lib.mjs +3 -482
  15. package/dist/cli/lib.mjs.map +1 -1
  16. package/dist/cli/main.mjs +975 -193
  17. package/dist/cli/main.mjs.map +1 -1
  18. package/dist/completion/zsh-worker.zsh +145 -2
  19. package/dist/configure/index.d.mts +2 -2
  20. package/dist/configure/services/index.d.mts +2 -1
  21. package/dist/configure/services/tailordb/index.d.mts +2 -1
  22. package/dist/configure/services/tailordb/schema.d.mts +46 -46
  23. package/dist/configure/services/tailordb/types.d.mts +30 -4
  24. package/dist/{crashreport-B5LqCTfF.mjs → crashreport-CIIfLnoO.mjs} +2 -2
  25. package/dist/{crashreport-B5LqCTfF.mjs.map → crashreport-CIIfLnoO.mjs.map} +1 -1
  26. package/dist/{crashreport-eI7ty7ok.mjs → crashreport-CINZ5dVN.mjs} +1 -1
  27. package/dist/errors-CWj21238.mjs +75 -0
  28. package/dist/errors-CWj21238.mjs.map +1 -0
  29. package/dist/kysely/index.d.mts +52 -5
  30. package/dist/kysely/index.mjs +7 -2
  31. package/dist/kysely/index.mjs.map +1 -1
  32. package/dist/{logger-CXQq9YIp.mjs → logger-DSdExfor.mjs} +83 -42
  33. package/dist/logger-DSdExfor.mjs.map +1 -0
  34. package/dist/plugin/builtin/seed/index.mjs +1 -1
  35. package/dist/{register-ts-hook-BU18uU44.mjs → register-ts-hook-CTth1eqj.mjs} +1587 -272
  36. package/dist/register-ts-hook-CTth1eqj.mjs.map +1 -0
  37. package/dist/schema--xYWRGfe.mjs.map +1 -1
  38. package/dist/seed/index.d.mts +52 -3
  39. package/dist/seed/index.mjs +200 -44
  40. package/dist/seed/index.mjs.map +1 -1
  41. package/dist/{seed-B-yckgQY.mjs → seed-xqM9WIHP.mjs} +8 -8
  42. package/dist/seed-xqM9WIHP.mjs.map +1 -0
  43. package/dist/{service-B5WynBHQ.mjs → service-CCwl3Avt.mjs} +3 -3
  44. package/dist/{service-B5WynBHQ.mjs.map → service-CCwl3Avt.mjs.map} +1 -1
  45. package/dist/service-_XmjSEGr.mjs +3 -0
  46. package/dist/{service-k1xy_A5G.mjs → service-goqlJJgA.mjs} +2 -2
  47. package/dist/{service-k1xy_A5G.mjs.map → service-goqlJJgA.mjs.map} +1 -1
  48. package/dist/{service_pb-D5--My_M.mjs → service_pb-BEWj1pOV.mjs} +2 -2
  49. package/dist/{service_pb-D5--My_M.mjs.map → service_pb-BEWj1pOV.mjs.map} +1 -1
  50. package/dist/{service_pb-i8CmnQP4.mjs → service_pb-BjlhvK9E.mjs} +1 -1
  51. package/dist/utils/test/index.d.mts +6 -3
  52. package/dist/utils/test/index.mjs +25 -13
  53. package/dist/utils/test/index.mjs.map +1 -1
  54. package/dist/vitest/index.d.mts +2 -1
  55. package/dist/vitest/index.mjs +84 -2
  56. package/dist/vitest/index.mjs.map +1 -1
  57. package/dist/vitest/mocks/file.d.mts +1 -1
  58. package/dist/vitest/pglite-kysely.d.mts +43 -0
  59. package/dist/{workspace_resource_pb-DXnO2AT-.mjs → workspace_resource_pb-HNIL_Vfj.mjs} +10 -2
  60. package/dist/{workspace_resource_pb-DXnO2AT-.mjs.map → workspace_resource_pb-HNIL_Vfj.mjs.map} +1 -1
  61. package/docs/cli/tailordb.md +87 -22
  62. package/docs/cli-reference.md +13 -11
  63. package/docs/configuration.md +1 -1
  64. package/docs/migration/v2.md +1 -1
  65. package/docs/plugin/custom.md +48 -48
  66. package/docs/plugin/index.md +24 -24
  67. package/docs/services/auth.md +10 -10
  68. package/docs/services/executor.md +1 -1
  69. package/docs/services/resolver.md +2 -2
  70. package/docs/services/tailordb-migration.md +375 -76
  71. package/docs/services/tailordb.md +28 -28
  72. package/docs/testing.md +2 -0
  73. package/package.json +12 -7
  74. package/dist/application-Af1zIqSI.mjs +0 -3
  75. package/dist/errors-D7583Zz7.mjs +0 -58
  76. package/dist/errors-D7583Zz7.mjs.map +0 -1
  77. package/dist/logger-CXQq9YIp.mjs.map +0 -1
  78. package/dist/register-ts-hook-BU18uU44.mjs.map +0 -1
  79. package/dist/seed-B-yckgQY.mjs.map +0 -1
  80. package/dist/service-M7OYziQP.mjs +0 -3
@@ -8,22 +8,22 @@ TailorDB provides:
8
8
 
9
9
  - Type-safe schema definitions using TypeScript
10
10
  - Automatic GraphQL API generation (CRUD operations)
11
- - Relations between types with automatic index and foreign key constraints
11
+ - Relations between tables with automatic index and foreign key constraints
12
12
  - Permission system for access control
13
13
  - Field-level hooks and validations
14
14
 
15
15
  For the official Tailor Platform documentation, see [TailorDB Guide](https://docs.tailor.tech/guides/tailordb/overview).
16
16
 
17
- ## Type Definition
17
+ ## Table Definition
18
18
 
19
- Define TailorDB Types in files matching glob patterns specified in `tailor.config.ts`.
19
+ Define TailorDB tables in files matching glob patterns specified in `tailor.config.ts`.
20
20
 
21
21
  **Definition Rules:**
22
22
 
23
- - **Multiple types per file**: You can define multiple TailorDB types in a single file
23
+ - **Multiple tables per file**: You can define multiple TailorDB tables in a single file
24
24
  - **Export method**: Use named exports (`export const`)
25
25
  - **Export both value and type**: Always export both the runtime value and TypeScript type
26
- - **Uniqueness**: Type names must be unique across all TailorDB namespaces in the application
26
+ - **Uniqueness**: Table names must be unique across all TailorDB namespaces in the application
27
27
 
28
28
  ```typescript
29
29
  import { db } from "@tailor-platform/sdk";
@@ -37,7 +37,7 @@ export const user = db.table("User", {
37
37
  });
38
38
  export type user = typeof user;
39
39
 
40
- // You can define multiple types in the same file
40
+ // You can define multiple tables in the same file
41
41
  export const role = db.table("Role", {
42
42
  name: db.string().unique(),
43
43
  });
@@ -254,8 +254,8 @@ type User {
254
254
  }
255
255
  ```
256
256
 
257
- - `toward.as` - Customizes the field name for accessing the related type from this type
258
- - `backward` - Customizes the field name for accessing this type from the related type
257
+ - `toward.as` - Customizes the field name for accessing the related table from this table
258
+ - `backward` - Customizes the field name for accessing this table from the related table
259
259
 
260
260
  Relation names share the same GraphQL field namespace as fields, files, and other relations on
261
261
  the table. The SDK rejects duplicate or empty relation names. When `toward.as` is omitted, the
@@ -356,7 +356,7 @@ export const order = db
356
356
  });
357
357
  ```
358
358
 
359
- **Note:** `.hooks()` can only be called once on a type. Duplicate type-level calls fail at compile time and throw at runtime.
359
+ **Note:** `.hooks()` can only be called once on a table. Duplicate type-level calls fail at compile time and throw at runtime.
360
360
 
361
361
  ### Validation
362
362
 
@@ -415,7 +415,7 @@ For datetime/date/time fields, pass `"now"` to use the operation timestamp:
415
415
  db.datetime().default("now");
416
416
  ```
417
417
 
418
- **Note:** `.validate()` can only be called once on a type. Duplicate type-level calls fail at compile time and throw at runtime.
418
+ **Note:** `.validate()` can only be called once on a table. Duplicate type-level calls fail at compile time and throw at runtime.
419
419
 
420
420
  ### Vector Search
421
421
 
@@ -448,14 +448,14 @@ export const user = db.table("User", {
448
448
 
449
449
  `db.fields.timestamps()` adds non-null `createdAt` and `updatedAt` datetime fields. Both fields are populated when a record is created; provided values are preserved so seed data can use historical timestamps. `updatedAt` is also refreshed automatically when a record is updated.
450
450
 
451
- ## Type Modifiers
451
+ ## Table Modifiers
452
452
 
453
- Type builder methods that set one type-level configuration can be called only once on the same type. Duplicate calls fail at compile time and throw at runtime. This applies to `.description()`, `.hooks()`, `.validate()`, `.features()`, `.indexes()`, `.files()`, `.permission()`, and `.gqlPermission()`.
453
+ Table builder methods that set one type-level configuration can be called only once on the same table. Duplicate calls fail at compile time and throw at runtime. This applies to `.description()`, `.hooks()`, `.validate()`, `.features()`, `.indexes()`, `.files()`, `.permission()`, and `.gqlPermission()`.
454
454
 
455
455
  Conditional assignment is still supported when only one branch calls the method:
456
456
 
457
457
  ```typescript
458
- let user = db.type("User", {
458
+ let user = db.table("User", {
459
459
  name: db.string(),
460
460
  });
461
461
 
@@ -502,7 +502,7 @@ db.table("User", {
502
502
 
503
503
  #### Event Publishing
504
504
 
505
- Enable event publishing for a type to trigger executors on record changes:
505
+ Enable event publishing for a table to trigger executors on record changes:
506
506
 
507
507
  ```typescript
508
508
  db.table("User", {
@@ -515,15 +515,15 @@ db.table("User", {
515
515
  **Behavior:**
516
516
 
517
517
  - When `publishEvents: true`, record creation/update/deletion events are published
518
- - When not specified, `deploy` sets it from the executors taking part in the same run: `true` while one of them uses this type with `recordCreatedTrigger`, `recordUpdatedTrigger`, or `recordDeletedTrigger`, and `false` once none does. Removing the last such trigger turns publishing back off on the next `deploy`
519
- - When explicitly set to `false` while an executor taking part in the same run uses this type, `deploy` fails
518
+ - When not specified, `deploy` sets it from the executors taking part in the same run: `true` while one of them uses this table with `recordCreatedTrigger`, `recordUpdatedTrigger`, or `recordDeletedTrigger`, and `false` once none does. Removing the last such trigger turns publishing back off on the next `deploy`
519
+ - When explicitly set to `false` while an executor taking part in the same run uses this table, `deploy` fails
520
520
 
521
521
  **Use cases:**
522
522
 
523
523
  1. **Auto-detection (recommended)**: Don't set `publishEvents` - `deploy` enables it while an executor taking part in the same run needs it
524
524
 
525
525
  ```typescript
526
- // publishEvents is automatically enabled because an executor uses this type
526
+ // publishEvents is automatically enabled because an executor uses this table
527
527
  export const order = db.table("Order", {
528
528
  status: db.string(),
529
529
  });
@@ -545,7 +545,7 @@ db.table("User", {
545
545
  });
546
546
  ```
547
547
 
548
- 3. **Explicit disable**: Disable event publishing for a type that doesn't need it (error if an executor taking part in the same run uses it)
548
+ 3. **Explicit disable**: Disable event publishing for a table that doesn't need it (error if an executor taking part in the same run uses it)
549
549
 
550
550
  ```typescript
551
551
  db.table("TempData", {
@@ -555,14 +555,14 @@ db.table("User", {
555
555
  });
556
556
  ```
557
557
 
558
- **Sharing a type across configs:** an executor in another config auto-enables publishing the same way, as long as both configs take part in the same `deploy` (`--config a,b`). `deploy` records that dependency, so deploying the owning config alone later asks for confirmation instead of silently turning publishing off — it fails outright in a non-interactive environment. Set `publishEvents: true` on the type to keep it on regardless of which configs take part.
558
+ **Sharing a table across configs:** an executor in another config auto-enables publishing the same way, as long as both configs take part in the same `deploy` (`--config a,b`). `deploy` records that dependency, so deploying the owning config alone later asks for confirmation instead of silently turning publishing off — it fails outright in a non-interactive environment. Set `publishEvents: true` on the table to keep it on regardless of which configs take part.
559
559
 
560
560
  #### GraphQL Operations
561
561
 
562
- Control which GraphQL operations (`create`, `update`, `delete`, `read`) are exposed for a type. All operations are enabled by default.
562
+ Control which GraphQL operations (`create`, `update`, `delete`, `read`) are exposed for a table. All operations are enabled by default.
563
563
 
564
564
  ```typescript
565
- db.type("Order", {
565
+ db.table("Order", {
566
566
  status: db.string(),
567
567
  }).features({
568
568
  gqlOperations: {
@@ -571,10 +571,10 @@ db.type("Order", {
571
571
  });
572
572
  ```
573
573
 
574
- Use the `"query"` alias to disable all mutations at once (read-only type: `create`/`update`/`delete` false, `read` true):
574
+ Use the `"query"` alias to disable all mutations at once (read-only table: `create`/`update`/`delete` false, `read` true):
575
575
 
576
576
  ```typescript
577
- db.type("AuditLog", {
577
+ db.table("AuditLog", {
578
578
  action: db.string(),
579
579
  }).features({
580
580
  gqlOperations: "query",
@@ -583,7 +583,7 @@ db.type("AuditLog", {
583
583
 
584
584
  **Namespace-level default**
585
585
 
586
- Set a default for every type in a TailorDB namespace in `tailor.config.ts`. A type's own `.features({ gqlOperations })` always takes precedence over this default.
586
+ Set a default for every table in a TailorDB namespace in `tailor.config.ts`. A table's own `.features({ gqlOperations })` always takes precedence over this default.
587
587
 
588
588
  ```typescript
589
589
  // tailor.config.ts
@@ -591,13 +591,13 @@ export default defineConfig({
591
591
  db: {
592
592
  tailordb: {
593
593
  files: ["./tailordb/*.ts"],
594
- gqlOperations: { delete: false }, // Default for every type in this namespace
594
+ gqlOperations: { delete: false }, // Default for every table in this namespace
595
595
  },
596
596
  },
597
597
  });
598
598
  ```
599
599
 
600
- This default is re-evaluated on every `tailor deploy`, so changing it also updates types that already exist on the platform, not only newly created ones.
600
+ This default is re-evaluated on every `tailor deploy`, so changing it also updates tables that already exist on the platform, not only newly created ones.
601
601
 
602
602
  ### Field Extraction (`pickFields` / `omitFields`)
603
603
 
@@ -679,7 +679,7 @@ Configure Permission and GQLPermission. For details, see the [TailorDB Permissio
679
679
 
680
680
  **Important**: Following the secure-by-default principle, all operations are denied if permissions are not configured. You must explicitly grant permissions for each operation (create, read, update, delete).
681
681
 
682
- `generate`/`deploy` reject a type that has no `.permission()`, or no `.gqlPermission()` while GraphQL operations are enabled for it (see [GraphQL Operations](#graphql-operations) above). Disable GraphQL exposure entirely with `.features({ gqlOperations: { create: false, update: false, delete: false, read: false } })` if a type only needs record-level permission.
682
+ `generate`/`deploy` reject a table that has no `.permission()`, or no `.gqlPermission()` while GraphQL operations are enabled for it (see [GraphQL Operations](#graphql-operations) above). Disable GraphQL exposure entirely with `.features({ gqlOperations: { create: false, update: false, delete: false, read: false } })` if a table only needs record-level permission.
683
683
 
684
684
  ```typescript
685
685
  db.table("User", {
@@ -723,6 +723,6 @@ db.table("User", {
723
723
 
724
724
  ## Migrations
725
725
 
726
- When you change a TailorDB type definition, the SDK can generate a migration that captures the diff and, for breaking changes, runs a data transformation script during `tailor deploy`. See the [TailorDB Migrations guide](./tailordb-migration.md) for the full workflow, configuration, supported change types, team coordination, and troubleshooting.
726
+ When you change a TailorDB table definition, the SDK can generate a migration that captures the diff and, for breaking changes, runs a data transformation script during `tailor deploy`. See the [TailorDB Migrations guide](./tailordb-migration.md) for the full workflow, configuration, supported change types, team coordination, and troubleshooting.
727
727
 
728
728
  For the CLI command reference, see [`tailordb migration`](../cli/tailordb.md#tailordb-migration).
package/docs/testing.md CHANGED
@@ -582,6 +582,8 @@ describe("upsertUsers resolver", () => {
582
582
 
583
583
  Reach for [`mockTailordb`](#mocking-the-tailordb-client) instead when you want to drive the raw query sequence at the `tailordb.Client` level rather than at the Kysely layer.
584
584
 
585
+ TailorDB migration scripts (`migrate.ts`) are unit-tested the same way: the generated `db.ts` exports the `Database` interface to type the mock, and `tailor tailordb migration script <N> --with-test` scaffolds a ready-to-fill test. To execute a migration script against real rows in an in-memory Postgres, use `createKyselyPGlite` with `@electric-sql/pglite`. See [Testing Migrations Locally](./services/tailordb-migration.md#testing-migrations-locally).
586
+
585
587
  #### Resolvers that resume a workflow
586
588
 
587
589
  Resolvers that call `waitPoint.resolve(...)` delegate to `tailor.workflow.resolve` at runtime. With the `tailor-runtime` environment active, use `mockWorkflow().waitPoint(definition)` to invoke the callback with the payload that originally suspended the job:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailor-platform/sdk",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -9,9 +9,10 @@
9
9
  "directory": "packages/sdk"
10
10
  },
11
11
  "bin": {
12
- "tailor": "./dist/cli/index.mjs"
12
+ "tailor": "./bin/tailor.mjs"
13
13
  },
14
14
  "files": [
15
+ "bin",
15
16
  "CHANGELOG.md",
16
17
  "dist",
17
18
  "docs",
@@ -172,14 +173,13 @@
172
173
  "@toiroakr/read-multiline": "0.4.1",
173
174
  "@urql/core": "6.0.3",
174
175
  "amaro": "1.1.11",
175
- "chalk": "5.6.2",
176
176
  "confbox": "0.2.4",
177
177
  "date-fns": "4.4.0",
178
178
  "es-toolkit": "1.50.0",
179
179
  "find-up-simple": "1.0.1",
180
180
  "get-east-asian-width": "1.6.0",
181
181
  "get-tsconfig": "4.14.1",
182
- "globals": "17.8.0",
182
+ "globals": "17.9.0",
183
183
  "graphql": "17.0.2",
184
184
  "inflection": "3.0.2",
185
185
  "kysely": "0.29.4",
@@ -204,7 +204,7 @@
204
204
  "@opentelemetry/sdk-trace-base": "2.10.0",
205
205
  "@types/mime-types": "3.0.1",
206
206
  "@types/node": "24.13.3",
207
- "@types/semver": "7.7.1",
207
+ "@types/semver": "7.8.0",
208
208
  "@typescript/native-preview": "7.0.0-dev.20260707.2",
209
209
  "@vitest/coverage-v8": "4.1.10",
210
210
  "eslint-plugin-zod": "4.9.0",
@@ -216,13 +216,18 @@
216
216
  "typescript": "6.0.3",
217
217
  "vitest": "4.1.10",
218
218
  "zinfer": "0.2.7",
219
- "@tailor-platform/tailor-proto": "^0.0.1"
219
+ "@tailor-platform/tailor-proto": "^0.0.1",
220
+ "@tailor-platform/shared": "^0.0.0"
220
221
  },
221
222
  "peerDependencies": {
223
+ "@electric-sql/pglite": ">=0.2.0",
222
224
  "vite": "^6.0.0 || ^7.0.0 || ^8.0.0",
223
225
  "vitest": ">=4"
224
226
  },
225
227
  "peerDependenciesMeta": {
228
+ "@electric-sql/pglite": {
229
+ "optional": true
230
+ },
226
231
  "vite": {
227
232
  "optional": true
228
233
  },
@@ -241,7 +246,7 @@
241
246
  "test:coverage": "vitest --coverage",
242
247
  "docs:check": "vitest run --project=unit* src/cli/docs.test.ts",
243
248
  "docs:update": "POLITTY_DOCS_UPDATE=true vitest run --project=unit* src/cli/docs.test.ts",
244
- "build": "tsdown && politty generate-shim --entry ./main.mjs --program tailor && politty generate-worker --bin dist/cli/main.mjs --program tailor --shell zsh --verify",
249
+ "build": "tsdown && politty generate-shim --entry ../dist/cli/main.mjs --program tailor && politty generate-worker --bin dist/cli/main.mjs --program tailor --shell zsh --verify",
245
250
  "lint": "oxlint --type-aware .",
246
251
  "check:public-api-jsdoc": "node --experimental-strip-types scripts/check-public-api-jsdoc.ts",
247
252
  "check:zod-isolation": "node --experimental-strip-types scripts/check-zod-isolation.ts",
@@ -1,3 +0,0 @@
1
- import { n as generatePluginFilesIfNeeded, r as loadApplication, t as defineApplication } from "./application-D77KJFKD.mjs";
2
-
3
- export { defineApplication, generatePluginFilesIfNeeded };
@@ -1,58 +0,0 @@
1
- import chalk from "chalk";
2
-
3
- //#region src/cli/shared/errors.ts
4
- function shellQuote(value) {
5
- if (process.platform === "win32") {
6
- if (/^[A-Za-z0-9_./:=@+\\-]+$/.test(value)) return value;
7
- return `"${value.replaceAll("\"", "\\\"")}"`;
8
- }
9
- if (/^[A-Za-z0-9_./:=@+-]+$/.test(value)) return value;
10
- return `'${value.replaceAll("'", `'"'"'`)}'`;
11
- }
12
- function formatNextAction(next) {
13
- const argv = [next.command, ...next.args];
14
- if (process.platform === "win32" && argv.some((value) => /[%$!]/.test(value))) return `with argv ${JSON.stringify(argv)}`;
15
- return `\`${argv.map(shellQuote).join(" ")}\``;
16
- }
17
- /**
18
- * Format CLI error for output
19
- * @param error - CLIError instance to format
20
- * @returns Formatted error message
21
- */
22
- function formatError(error) {
23
- const parts = [chalk.red(`Error${error.code ? ` [${error.code}]` : ""}: ${error.message}`)];
24
- if (error.details) parts.push(`\n ${chalk.gray("Details:")} ${error.details}`);
25
- if (error.suggestion) parts.push(`\n ${chalk.cyan("Suggestion:")} ${error.suggestion}`);
26
- if (error.command) parts.push(`\n ${chalk.gray("Help:")} Run \`tailor ${error.command} --help\` for usage information.`);
27
- if (error.next) parts.push(`\n ${chalk.cyan("Next:")} Run ${formatNextAction(error.next)}.`);
28
- return parts.join("");
29
- }
30
- /**
31
- * Create a CLI error with formatted output
32
- * @param options - Options to construct a CLIError
33
- * @returns Constructed CLIError instance
34
- */
35
- function createCLIError(options) {
36
- const error = new Error(options.message);
37
- error.name = "CLIError";
38
- error.code = options.code;
39
- error.details = options.details;
40
- error.suggestion = options.suggestion;
41
- error.command = options.command;
42
- error.next = options.next;
43
- error.context = options.context;
44
- error.format = () => formatError(error);
45
- return error;
46
- }
47
- /**
48
- * Type guard to check if an error is a CLIError
49
- * @param error - Error to check
50
- * @returns True if the error is a CLIError
51
- */
52
- function isCLIError(error) {
53
- return error instanceof Error && error.name === "CLIError";
54
- }
55
-
56
- //#endregion
57
- export { isCLIError as n, createCLIError as t };
58
- //# sourceMappingURL=errors-D7583Zz7.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"errors-D7583Zz7.mjs","names":[],"sources":["../src/cli/shared/errors.ts"],"sourcesContent":["import chalk from \"chalk\";\n\n/**\n * Options for creating a CLI error\n */\nexport interface CLIErrorOptions {\n message: string;\n details?: string;\n suggestion?: string;\n command?: string;\n code?: string;\n next?: CLIErrorNextAction;\n context?: Readonly<Record<string, unknown>>;\n}\n\nexport interface CLIErrorNextAction {\n /** Executable name, such as `tailor`. */\n command: string;\n /** Arguments passed directly to the executable. */\n args: readonly string[];\n}\n\n/**\n * CLI error interface with formatted output\n */\nexport interface CLIError extends Error {\n readonly code?: string;\n readonly details?: string;\n readonly suggestion?: string;\n readonly command?: string;\n readonly next?: CLIErrorNextAction;\n readonly context?: Readonly<Record<string, unknown>>;\n format(): string;\n}\n\ntype CLIErrorInternal = Error & {\n code?: string;\n details?: string;\n suggestion?: string;\n command?: string;\n next?: CLIErrorNextAction;\n context?: Readonly<Record<string, unknown>>;\n format(): string;\n};\n\nfunction shellQuote(value: string): string {\n if (process.platform === \"win32\") {\n if (/^[A-Za-z0-9_./:=@+\\\\-]+$/.test(value)) return value;\n return `\"${value.replaceAll('\"', '\\\\\"')}\"`;\n }\n if (/^[A-Za-z0-9_./:=@+-]+$/.test(value)) return value;\n return `'${value.replaceAll(\"'\", `'\"'\"'`)}'`;\n}\n\nfunction formatNextAction(next: CLIErrorNextAction): string {\n const argv = [next.command, ...next.args];\n if (process.platform === \"win32\" && argv.some((value) => /[%$!]/.test(value))) {\n return `with argv ${JSON.stringify(argv)}`;\n }\n return `\\`${argv.map(shellQuote).join(\" \")}\\``;\n}\n\n/**\n * Format CLI error for output\n * @param error - CLIError instance to format\n * @returns Formatted error message\n */\nfunction formatError(error: CLIError): string {\n const parts: string[] = [\n chalk.red(`Error${error.code ? ` [${error.code}]` : \"\"}: ${error.message}`),\n ];\n\n if (error.details) {\n parts.push(`\\n ${chalk.gray(\"Details:\")} ${error.details}`);\n }\n\n if (error.suggestion) {\n parts.push(`\\n ${chalk.cyan(\"Suggestion:\")} ${error.suggestion}`);\n }\n\n if (error.command) {\n parts.push(\n `\\n ${chalk.gray(\"Help:\")} Run \\`tailor ${error.command} --help\\` for usage information.`,\n );\n }\n\n if (error.next) {\n parts.push(`\\n ${chalk.cyan(\"Next:\")} Run ${formatNextAction(error.next)}.`);\n }\n\n return parts.join(\"\");\n}\n\n/**\n * Create a CLI error with formatted output\n * @param options - Options to construct a CLIError\n * @returns Constructed CLIError instance\n */\nfunction createCLIError(options: CLIErrorOptions): CLIError {\n const error = new Error(options.message) as CLIErrorInternal;\n error.name = \"CLIError\";\n error.code = options.code;\n error.details = options.details;\n error.suggestion = options.suggestion;\n error.command = options.command;\n error.next = options.next;\n error.context = options.context;\n error.format = () => formatError(error);\n return error;\n}\n\n/**\n * Type guard to check if an error is a CLIError\n * @param error - Error to check\n * @returns True if the error is a CLIError\n */\nexport function isCLIError(error: unknown): error is CLIError {\n return error instanceof Error && error.name === \"CLIError\";\n}\n\n// Re-export createCLIError as CLIError for backward compatibility\nexport { createCLIError as CLIError };\n"],"mappings":";;;AA6CA,SAAS,WAAW,OAAuB;CACzC,IAAI,QAAQ,aAAa,SAAS;EAChC,IAAI,2BAA2B,KAAK,KAAK,GAAG,OAAO;EACnD,OAAO,IAAI,MAAM,WAAW,MAAK,MAAK,EAAE;CAC1C;CACA,IAAI,yBAAyB,KAAK,KAAK,GAAG,OAAO;CACjD,OAAO,IAAI,MAAM,WAAW,KAAK,OAAO,EAAE;AAC5C;AAEA,SAAS,iBAAiB,MAAkC;CAC1D,MAAM,OAAO,CAAC,KAAK,SAAS,GAAG,KAAK,IAAI;CACxC,IAAI,QAAQ,aAAa,WAAW,KAAK,MAAM,UAAU,QAAQ,KAAK,KAAK,CAAC,GAC1E,OAAO,aAAa,KAAK,UAAU,IAAI;CAEzC,OAAO,KAAK,KAAK,IAAI,UAAU,CAAC,CAAC,KAAK,GAAG,EAAE;AAC7C;;;;;;AAOA,SAAS,YAAY,OAAyB;CAC5C,MAAM,QAAkB,CACtB,MAAM,IAAI,QAAQ,MAAM,OAAO,KAAK,MAAM,KAAK,KAAK,GAAG,IAAI,MAAM,SAAS,CAC5E;CAEA,IAAI,MAAM,SACR,MAAM,KAAK,OAAO,MAAM,KAAK,UAAU,EAAE,GAAG,MAAM,SAAS;CAG7D,IAAI,MAAM,YACR,MAAM,KAAK,OAAO,MAAM,KAAK,aAAa,EAAE,GAAG,MAAM,YAAY;CAGnE,IAAI,MAAM,SACR,MAAM,KACJ,OAAO,MAAM,KAAK,OAAO,EAAE,gBAAgB,MAAM,QAAQ,iCAC3D;CAGF,IAAI,MAAM,MACR,MAAM,KAAK,OAAO,MAAM,KAAK,OAAO,EAAE,OAAO,iBAAiB,MAAM,IAAI,EAAE,EAAE;CAG9E,OAAO,MAAM,KAAK,EAAE;AACtB;;;;;;AAOA,SAAS,eAAe,SAAoC;CAC1D,MAAM,QAAQ,IAAI,MAAM,QAAQ,OAAO;CACvC,MAAM,OAAO;CACb,MAAM,OAAO,QAAQ;CACrB,MAAM,UAAU,QAAQ;CACxB,MAAM,aAAa,QAAQ;CAC3B,MAAM,UAAU,QAAQ;CACxB,MAAM,OAAO,QAAQ;CACrB,MAAM,UAAU,QAAQ;CACxB,MAAM,eAAe,YAAY,KAAK;CACtC,OAAO;AACT;;;;;;AAOA,SAAgB,WAAW,OAAmC;CAC5D,OAAO,iBAAiB,SAAS,MAAM,SAAS;AAClD"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger-CXQq9YIp.mjs","names":[],"sources":["../src/cli/shared/ascii-table.ts","../src/cli/shared/parse-boolean.ts","../src/cli/shared/logger.ts"],"sourcesContent":["import { eastAsianWidth } from \"get-east-asian-width\";\n\n// eslint-disable-next-line no-control-regex\nconst ANSI_ESCAPE_PATTERN = /\\x1b\\[[0-9;]*m/g;\nconst CARRIAGE_RETURN_PATTERN = /\\r\\n?/g;\n\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n\nexport interface AsciiTableConfig {\n /** Suppress horizontal lines between rows, keeping only the outer border. */\n singleLine?: boolean;\n /** Decide whether to draw the horizontal line at `lineIndex` (range `[0, rowCount]` inclusive). */\n drawHorizontalLine?: (lineIndex: number, rowCount: number) => boolean;\n}\n\ninterface CellLine {\n text: string;\n width: number;\n}\n\nfunction maxOf(values: number[], fallback = 0): number {\n return values.reduce((max, value) => (value > max ? value : max), fallback);\n}\n\nconst TAB_WIDTH = 8;\n\nfunction isStrippableControlCharacter(char: string): boolean {\n const codePoint = char.codePointAt(0) ?? 0;\n if (char === \"\\n\") {\n return false;\n }\n return codePoint <= 0x1f || codePoint === 0x7f;\n}\n\n// Only SGR (color/style) escape sequences are meant to survive; a bare ESC\n// that isn't part of a recognized SGR sequence (e.g. a screen-clear CSI\n// sequence, or a BEL-terminated OSC sequence) is treated like any other\n// control character below and stripped, rather than passed through to the\n// terminal or left with its terminator removed.\nfunction normalizeControlCharacters(value: string): string {\n const sgrSequences = value.match(ANSI_ESCAPE_PATTERN) ?? [];\n return value\n .split(ANSI_ESCAPE_PATTERN)\n .map((segment) => {\n const chars: string[] = [];\n for (const char of segment) {\n if (char === \"\\t\") {\n chars.push(\" \".repeat(TAB_WIDTH));\n } else if (!isStrippableControlCharacter(char)) {\n chars.push(char);\n }\n }\n return chars.join(\"\");\n })\n .reduce((result, segment, i) => result + segment + (sgrSequences[i] ?? \"\"), \"\");\n}\n\nfunction sanitizeCell(cell: unknown): string {\n return normalizeControlCharacters(String(cell ?? \"\").replace(CARRIAGE_RETURN_PATTERN, \"\\n\"));\n}\n\n// Clusters made up entirely of non-printing code points (lone joiners,\n// variation selectors, combining marks, etc.) render with no visible glyph.\nconst ZERO_WIDTH_CLUSTER_PATTERN =\n /^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Format}|\\p{Nonspacing_Mark}|\\p{Enclosing_Mark}|\\p{Surrogate})+$/v;\n// RGI_Emoji covers flags, keycaps, and VS16-forced presentation sequences,\n// which render as 2 columns in terminals even though their first code point\n// alone would measure as narrow/neutral.\nconst RGI_EMOJI_PATTERN = /^\\p{RGI_Emoji}$/v;\n\nfunction displayWidth(value: string): number {\n let width = 0;\n for (const { segment } of graphemeSegmenter.segment(value.replace(ANSI_ESCAPE_PATTERN, \"\"))) {\n if (ZERO_WIDTH_CLUSTER_PATTERN.test(segment)) {\n continue;\n }\n if (RGI_EMOJI_PATTERN.test(segment)) {\n width += 2;\n continue;\n }\n const codePoint = segment.codePointAt(0);\n width += codePoint === undefined ? 0 : eastAsianWidth(codePoint);\n }\n return width;\n}\n\nfunction toCellLines(cell: string): CellLine[] {\n return cell.split(\"\\n\").map((text) => ({ text, width: displayWidth(text) }));\n}\n\nfunction padCell(cellLine: CellLine, width: number): string {\n return cellLine.text + \" \".repeat(Math.max(0, width - cellLine.width));\n}\n\nfunction renderBorder(left: string, join: string, right: string, columnWidths: number[]): string {\n return left + columnWidths.map((width) => \"─\".repeat(width + 2)).join(join) + right;\n}\n\nfunction validateConsistentColumnCount(rows: string[][]): void {\n const columnCount = rows[0]?.length;\n if (columnCount === undefined) {\n return;\n }\n rows.forEach((row, index) => {\n if (row.length !== columnCount) {\n throw new Error(\n `renderTable: all rows must have the same number of columns (expected ${columnCount}, row ${index} has ${row.length}).`,\n );\n }\n });\n}\n\n/**\n * Renders a 2D array of values as a table using single-line Unicode box-drawing borders.\n * Column widths account for East Asian wide characters (measured per grapheme cluster,\n * so combining marks and ZWJ emoji sequences aren't overcounted, non-printing clusters\n * such as a lone joiner or combining mark measure as 0, and flags, keycaps, and\n * VS16-forced emoji presentation are measured as 2 columns) and strip ANSI SGR (color/style)\n * escape codes before measuring. Use this instead of importing a table-rendering package\n * directly.\n * @param data - Table rows; every row must have the same number of columns. Each cell is\n * stringified (`null`/`undefined` become an empty string rather than the literal text\n * \"null\"/\"undefined\"), may contain embedded newlines, has `\\r`/`\\r\\n` normalized to `\\n`,\n * has tabs expanded to spaces, and has other control characters stripped.\n * @param config - Rendering options\n * @returns The rendered table terminated with a trailing newline, or `\"\"` when there are no\n * rows or no columns to display\n */\nexport function renderTable(data: unknown[][], config: AsciiTableConfig = {}): string {\n const rows = data.map((row) => row.map(sanitizeCell));\n validateConsistentColumnCount(rows);\n\n const rowCount = rows.length;\n const columnCount = rows[0]?.length ?? 0;\n if (rowCount === 0 || columnCount === 0) {\n return \"\";\n }\n\n const rowsCellLines = rows.map((row) =>\n Array.from({ length: columnCount }, (_, col) => toCellLines(row[col] ?? \"\")),\n );\n const columnWidths = Array.from({ length: columnCount }, (_, col) =>\n maxOf(rowsCellLines.map((row) => maxOf((row[col] ?? []).map((line) => line.width)))),\n );\n\n const shouldDrawLine = (lineIndex: number): boolean =>\n config.singleLine\n ? lineIndex === 0 || lineIndex === rowCount\n : (config.drawHorizontalLine ?? (() => true))(lineIndex, rowCount);\n\n const lines: string[] = [];\n if (shouldDrawLine(0)) {\n lines.push(renderBorder(\"┌\", \"┬\", \"┐\", columnWidths));\n }\n\n rowsCellLines.forEach((cellLines, rowIndex) => {\n const rowHeight = maxOf(\n cellLines.map((columnLines) => columnLines.length),\n 1,\n );\n for (let line = 0; line < rowHeight; line++) {\n const cells = cellLines.map((columnLines, col) =>\n padCell(columnLines[line] ?? { text: \"\", width: 0 }, columnWidths[col] ?? 0),\n );\n lines.push(`│ ${cells.join(\" │ \")} │`);\n }\n if (rowIndex < rowCount - 1 && shouldDrawLine(rowIndex + 1)) {\n lines.push(renderBorder(\"├\", \"┼\", \"┤\", columnWidths));\n }\n });\n\n if (shouldDrawLine(rowCount)) {\n lines.push(renderBorder(\"└\", \"┴\", \"┘\", columnWidths));\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n","const TRUTHY_VALUES = new Set([\"true\", \"t\", \"yes\", \"y\", \"on\", \"1\"]);\nconst FALSY_VALUES = new Set([\"false\", \"f\", \"no\", \"n\", \"off\", \"0\"]);\n\n/**\n * Parse a string value as a boolean.\n *\n * Recognized values (case-insensitive, trimmed) follow Python's\n * `distutils.util.strtobool` convention:\n * - truthy: `true, t, yes, y, on, 1`\n * - falsy: `false, f, no, n, off, 0`\n *\n * Undefined, empty strings, and unrecognized values return `undefined` so\n * that callers can fall back to their own defaults.\n * @param value - The input string (e.g. an environment variable or CLI flag value)\n * @returns `true`, `false`, or `undefined` when the value is unset or unrecognized\n */\nexport function parseBoolean(value: string | undefined): boolean | undefined {\n if (value === undefined) return undefined;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"\") return undefined;\n if (TRUTHY_VALUES.has(normalized)) return true;\n if (FALSY_VALUES.has(normalized)) return false;\n return undefined;\n}\n","import { formatWithOptions, type InspectOptions } from \"node:util\";\nimport chalk from \"chalk\";\nimport { formatDistanceToNowStrict } from \"date-fns\";\nimport { renderTable } from \"./ascii-table\";\nimport { parseBoolean } from \"./parse-boolean\";\n\n/**\n * Error thrown when a prompt is attempted in a non-interactive environment\n */\nexport class CIPromptError extends Error {\n constructor(message?: string) {\n super(\n message ??\n \"Interactive prompts are not available in this environment. Provide the required options explicitly.\",\n );\n this.name = \"CIPromptError\";\n }\n}\n\n/**\n * Semantic style functions for inline text styling\n */\nexport const styles = {\n // Status colors\n success: chalk.green,\n error: chalk.red,\n warning: chalk.yellow,\n info: chalk.cyan,\n\n // Action colors (for change sets)\n create: chalk.green,\n update: chalk.yellow,\n delete: chalk.red,\n unchanged: chalk.gray,\n\n // Emphasis\n bold: chalk.bold,\n dim: chalk.gray,\n highlight: chalk.cyanBright,\n successBright: chalk.greenBright,\n errorBright: chalk.redBright,\n\n // Resource types\n resourceType: chalk.bold,\n resourceName: chalk.cyan,\n\n // File paths\n path: chalk.cyan,\n\n // Values\n value: chalk.white,\n placeholder: chalk.gray.italic,\n};\n\n/**\n * Standardized symbols for CLI output\n */\nexport const symbols = {\n success: chalk.green(\"\\u2713\"),\n error: chalk.red(\"\\u2716\"),\n warning: chalk.yellow(\"\\u26a0\"),\n info: chalk.cyan(\"i\"),\n create: chalk.green(\"+\"),\n update: chalk.yellow(\"~\"),\n delete: chalk.red(\"-\"),\n replace: chalk.magenta(\"\\u00b1\"),\n bullet: chalk.gray(\"\\u2022\"),\n arrow: chalk.gray(\"\\u2192\"),\n};\n\n/**\n * Log output modes\n */\nexport type LogMode = \"default\" | \"stream\" | \"plain\";\n\nexport interface LogOptions {\n /** Output mode (default: \"default\") */\n mode?: LogMode;\n /** Number of spaces to indent the entire line (default: 0) */\n indent?: number;\n}\n\n/** Field transformer function. null excludes the field from table output. */\nexport type FieldTransformer = ((value: unknown, item: object) => string) | null;\n\nexport interface OutOptions {\n /** Table display field transform/exclude settings. Only applied in table mode (not JSON). */\n display?: Record<string, FieldTransformer>;\n\n /** Show null values in table output (default: false) */\n showNull?: boolean;\n}\n\n// In JSON mode, all logs go to stderr to keep stdout clean for JSON data\nlet _jsonMode = false;\n\n// Type icons for log output\nconst TYPE_ICONS: Record<string, string> = {\n info: \"ℹ\",\n success: \"✔\",\n warn: \"⚠\",\n error: \"✖\",\n debug: \"⚙\",\n trace: \"→\",\n log: \"\",\n};\n\n// Color functions for icon and message text\nconst TYPE_COLORS: Record<string, (text: string) => string> = {\n info: chalk.cyan,\n success: chalk.green,\n warn: chalk.yellow,\n error: chalk.red,\n debug: chalk.gray,\n trace: chalk.gray,\n log: (text) => text,\n};\n\ninterface FormatLogLineOptions {\n mode: string;\n indent: number;\n type: string;\n message: string;\n timestamp?: string;\n}\n\n/**\n * Formats a log line with the appropriate prefix and indentation\n * @param opts - Formatting options\n * @returns Formatted log line\n */\nexport function formatLogLine(opts: FormatLogLineOptions): string {\n const { mode, indent, type, message, timestamp } = opts;\n const indentPrefix = indent > 0 ? \" \".repeat(indent) : \"\";\n const colorFn = TYPE_COLORS[type] || ((text: string) => text);\n\n // Plain mode: color only, no icon, no timestamp\n if (mode === \"plain\") {\n return `${indentPrefix}${colorFn(message)}\\n`;\n }\n\n // Default/Stream mode: with icon and color\n const icon = TYPE_ICONS[type] || \"\";\n const prefix = icon ? `${icon} ` : \"\";\n const coloredOutput = colorFn(`${prefix}${message}`);\n const timestampPrefix = timestamp ?? \"\";\n\n return `${indentPrefix}${timestampPrefix}${coloredOutput}\\n`;\n}\n\n/**\n * Writes a formatted log line to stderr.\n * @param type - Log type (info, success, warn, error, log)\n * @param message - Log message\n * @param opts - Log options (mode and indent)\n */\nfunction writeLog(type: string, message: string, opts?: LogOptions): void {\n const mode = opts?.mode ?? \"default\";\n const indent = opts?.indent ?? 0;\n const inspectOpts: InspectOptions = {\n breakLength: process.stdout.columns || 80,\n };\n const formattedMessage = formatWithOptions(inspectOpts, message);\n const timestamp = mode === \"stream\" ? `${new Date().toLocaleTimeString()} ` : \"\";\n const output = formatLogLine({ mode, indent, type, message: formattedMessage, timestamp });\n process.stderr.write(output);\n}\n\nexport const logger = {\n get jsonMode(): boolean {\n return _jsonMode;\n },\n set jsonMode(value: boolean) {\n _jsonMode = value;\n },\n\n info(message: string, opts?: LogOptions): void {\n writeLog(\"info\", message, opts);\n },\n\n success(message: string, opts?: LogOptions): void {\n writeLog(\"success\", message, opts);\n },\n\n warn(message: string, opts?: LogOptions): void {\n writeLog(\"warn\", message, opts);\n },\n\n error(message: string, opts?: LogOptions): void {\n writeLog(\"error\", message, opts);\n },\n\n log(message: string): void {\n writeLog(\"log\", message, { mode: \"plain\" });\n },\n\n newline(): void {\n process.stderr.write(\"\\n\");\n },\n\n debug(message: string): void {\n if (parseBoolean(process.env.DEBUG) === true) {\n writeLog(\"log\", styles.dim(message), { mode: \"plain\" });\n }\n },\n\n out(data: string | object | object[], options?: OutOptions): void {\n if (typeof data === \"string\") {\n process.stdout.write(data.endsWith(\"\\n\") ? data : data + \"\\n\");\n return;\n }\n\n if (this.jsonMode) {\n // eslint-disable-next-line no-restricted-syntax\n console.log(JSON.stringify(data));\n return;\n }\n\n const display = options?.display;\n\n // Helper to format a value for table display\n const formatValue = (value: unknown, pretty = false): string => {\n if (options?.showNull && value === null) return \"NULL\";\n if (value === null || value === undefined) return \"N/A\";\n if (value instanceof Date) {\n return formatDistanceToNowStrict(value, { addSuffix: true });\n }\n if (typeof value === \"object\") {\n return pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value);\n }\n return String(value);\n };\n\n // Helper to check if field should be excluded\n const isExcluded = (key: string): boolean => {\n return display !== undefined && key in display && display[key] === null;\n };\n\n // Helper to apply transformer or default formatting\n const transformValue = (key: string, value: unknown, item: object, pretty = false): string => {\n if (display && key in display) {\n const transformer = display[key];\n if (transformer) {\n return transformer(value, item);\n }\n }\n return formatValue(value, pretty);\n };\n\n if (!Array.isArray(data)) {\n const entries = Object.entries(data).filter(([key]) => !isExcluded(key));\n const formattedEntries = entries.map(([key, value]) => [\n key,\n transformValue(key, value, data, true),\n ]);\n const t = renderTable(formattedEntries, { singleLine: false });\n process.stdout.write(t);\n return;\n }\n\n if (data.length === 0) {\n return;\n }\n\n const allHeaders = Array.from(new Set(data.flatMap((item) => Object.keys(item))));\n const headers = allHeaders.filter((h) => !isExcluded(h));\n if (headers.length === 0) {\n return;\n }\n const rows = data.map((item) =>\n headers.map((header) =>\n transformValue(header, (item as Record<string, unknown>)[header], item),\n ),\n );\n\n const t = renderTable([headers, ...rows], {\n drawHorizontalLine: (lineIndex, rowCount) => {\n return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount;\n },\n });\n process.stdout.write(t);\n },\n};\n"],"mappings":";;;;;;AAGA,MAAM,sBAAsB;AAC5B,MAAM,0BAA0B;AAEhC,MAAM,oBAAoB,IAAI,KAAK,UAAU,QAAW,EAAE,aAAa,WAAW,CAAC;AAcnF,SAAS,MAAM,QAAkB,WAAW,GAAW;CACrD,OAAO,OAAO,QAAQ,KAAK,UAAW,QAAQ,MAAM,QAAQ,KAAM,QAAQ;AAC5E;AAEA,MAAM,YAAY;AAElB,SAAS,6BAA6B,MAAuB;CAC3D,MAAM,YAAY,KAAK,YAAY,CAAC,KAAK;CACzC,IAAI,SAAS,MACX,OAAO;CAET,OAAO,aAAa,MAAQ,cAAc;AAC5C;AAOA,SAAS,2BAA2B,OAAuB;CACzD,MAAM,eAAe,MAAM,MAAM,mBAAmB,KAAK,CAAC;CAC1D,OAAO,MACJ,MAAM,mBAAmB,CAAC,CAC1B,KAAK,YAAY;EAChB,MAAM,QAAkB,CAAC;EACzB,KAAK,MAAM,QAAQ,SACjB,IAAI,SAAS,KACX,MAAM,KAAK,IAAI,OAAO,SAAS,CAAC;OAC3B,IAAI,CAAC,6BAA6B,IAAI,GAC3C,MAAM,KAAK,IAAI;EAGnB,OAAO,MAAM,KAAK,EAAE;CACtB,CAAC,CAAC,CACD,QAAQ,QAAQ,SAAS,MAAM,SAAS,WAAW,aAAa,MAAM,KAAK,EAAE;AAClF;AAEA,SAAS,aAAa,MAAuB;CAC3C,OAAO,2BAA2B,OAAO,QAAQ,EAAE,CAAC,CAAC,QAAQ,yBAAyB,IAAI,CAAC;AAC7F;AAIA,MAAM,6BACJ;AAIF,MAAM,oBAAoB;AAE1B,SAAS,aAAa,OAAuB;CAC3C,IAAI,QAAQ;CACZ,KAAK,MAAM,EAAE,aAAa,kBAAkB,QAAQ,MAAM,QAAQ,qBAAqB,EAAE,CAAC,GAAG;EAC3F,IAAI,2BAA2B,KAAK,OAAO,GACzC;EAEF,IAAI,kBAAkB,KAAK,OAAO,GAAG;GACnC,SAAS;GACT;EACF;EACA,MAAM,YAAY,QAAQ,YAAY,CAAC;EACvC,SAAS,cAAc,SAAY,IAAI,eAAe,SAAS;CACjE;CACA,OAAO;AACT;AAEA,SAAS,YAAY,MAA0B;CAC7C,OAAO,KAAK,MAAM,IAAI,CAAC,CAAC,KAAK,UAAU;EAAE;EAAM,OAAO,aAAa,IAAI;CAAE,EAAE;AAC7E;AAEA,SAAS,QAAQ,UAAoB,OAAuB;CAC1D,OAAO,SAAS,OAAO,IAAI,OAAO,KAAK,IAAI,GAAG,QAAQ,SAAS,KAAK,CAAC;AACvE;AAEA,SAAS,aAAa,MAAc,MAAc,OAAe,cAAgC;CAC/F,OAAO,OAAO,aAAa,KAAK,UAAU,IAAI,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI;AAChF;AAEA,SAAS,8BAA8B,MAAwB;CAC7D,MAAM,cAAc,KAAK,EAAE,EAAE;CAC7B,IAAI,gBAAgB,QAClB;CAEF,KAAK,SAAS,KAAK,UAAU;EAC3B,IAAI,IAAI,WAAW,aACjB,MAAM,IAAI,MACR,wEAAwE,YAAY,QAAQ,MAAM,OAAO,IAAI,OAAO,GACtH;CAEJ,CAAC;AACH;;;;;;;;;;;;;;;;;AAkBA,SAAgB,YAAY,MAAmB,SAA2B,CAAC,GAAW;CACpF,MAAM,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,YAAY,CAAC;CACpD,8BAA8B,IAAI;CAElC,MAAM,WAAW,KAAK;CACtB,MAAM,cAAc,KAAK,EAAE,EAAE,UAAU;CACvC,IAAI,aAAa,KAAK,gBAAgB,GACpC,OAAO;CAGT,MAAM,gBAAgB,KAAK,KAAK,QAC9B,MAAM,KAAK,EAAE,QAAQ,YAAY,IAAI,GAAG,QAAQ,YAAY,IAAI,QAAQ,EAAE,CAAC,CAC7E;CACA,MAAM,eAAe,MAAM,KAAK,EAAE,QAAQ,YAAY,IAAI,GAAG,QAC3D,MAAM,cAAc,KAAK,QAAQ,OAAO,IAAI,QAAQ,CAAC,EAAC,CAAE,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CACrF;CAEA,MAAM,kBAAkB,cACtB,OAAO,aACH,cAAc,KAAK,cAAc,YAChC,OAAO,6BAA6B,MAAK,CAAE,WAAW,QAAQ;CAErE,MAAM,QAAkB,CAAC;CACzB,IAAI,eAAe,CAAC,GAClB,MAAM,KAAK,aAAa,KAAK,KAAK,KAAK,YAAY,CAAC;CAGtD,cAAc,SAAS,WAAW,aAAa;EAC7C,MAAM,YAAY,MAChB,UAAU,KAAK,gBAAgB,YAAY,MAAM,GACjD,CACF;EACA,KAAK,IAAI,OAAO,GAAG,OAAO,WAAW,QAAQ;GAC3C,MAAM,QAAQ,UAAU,KAAK,aAAa,QACxC,QAAQ,YAAY,SAAS;IAAE,MAAM;IAAI,OAAO;GAAE,GAAG,aAAa,QAAQ,CAAC,CAC7E;GACA,MAAM,KAAK,KAAK,MAAM,KAAK,KAAK,EAAE,GAAG;EACvC;EACA,IAAI,WAAW,WAAW,KAAK,eAAe,WAAW,CAAC,GACxD,MAAM,KAAK,aAAa,KAAK,KAAK,KAAK,YAAY,CAAC;CAExD,CAAC;CAED,IAAI,eAAe,QAAQ,GACzB,MAAM,KAAK,aAAa,KAAK,KAAK,KAAK,YAAY,CAAC;CAGtD,OAAO,GAAG,MAAM,KAAK,IAAI,EAAE;AAC7B;;;;AChLA,MAAM,gCAAgB,IAAI,IAAI;CAAC;CAAQ;CAAK;CAAO;CAAK;CAAM;AAAG,CAAC;AAClE,MAAM,+BAAe,IAAI,IAAI;CAAC;CAAS;CAAK;CAAM;CAAK;CAAO;AAAG,CAAC;;;;;;;;;;;;;;AAelE,SAAgB,aAAa,OAAgD;CAC3E,IAAI,UAAU,QAAW,OAAO;CAChC,MAAM,aAAa,MAAM,KAAK,CAAC,CAAC,YAAY;CAC5C,IAAI,eAAe,IAAI,OAAO;CAC9B,IAAI,cAAc,IAAI,UAAU,GAAG,OAAO;CAC1C,IAAI,aAAa,IAAI,UAAU,GAAG,OAAO;AAE3C;;;;;;;ACdA,IAAa,gBAAb,cAAmC,MAAM;CACvC,YAAY,SAAkB;EAC5B,MACE,WACE,qGACJ;EACA,KAAK,OAAO;CACd;AACF;;;;AAKA,MAAa,SAAS;CAEpB,SAAS,MAAM;CACf,OAAO,MAAM;CACb,SAAS,MAAM;CACf,MAAM,MAAM;CAGZ,QAAQ,MAAM;CACd,QAAQ,MAAM;CACd,QAAQ,MAAM;CACd,WAAW,MAAM;CAGjB,MAAM,MAAM;CACZ,KAAK,MAAM;CACX,WAAW,MAAM;CACjB,eAAe,MAAM;CACrB,aAAa,MAAM;CAGnB,cAAc,MAAM;CACpB,cAAc,MAAM;CAGpB,MAAM,MAAM;CAGZ,OAAO,MAAM;CACb,aAAa,MAAM,KAAK;AAC1B;;;;AAKA,MAAa,UAAU;CACrB,SAAS,MAAM,MAAM,GAAQ;CAC7B,OAAO,MAAM,IAAI,GAAQ;CACzB,SAAS,MAAM,OAAO,GAAQ;CAC9B,MAAM,MAAM,KAAK,GAAG;CACpB,QAAQ,MAAM,MAAM,GAAG;CACvB,QAAQ,MAAM,OAAO,GAAG;CACxB,QAAQ,MAAM,IAAI,GAAG;CACrB,SAAS,MAAM,QAAQ,GAAQ;CAC/B,QAAQ,MAAM,KAAK,GAAQ;CAC3B,OAAO,MAAM,KAAK,GAAQ;AAC5B;AA0BA,IAAI,YAAY;AAGhB,MAAM,aAAqC;CACzC,MAAM;CACN,SAAS;CACT,MAAM;CACN,OAAO;CACP,OAAO;CACP,OAAO;CACP,KAAK;AACP;AAGA,MAAM,cAAwD;CAC5D,MAAM,MAAM;CACZ,SAAS,MAAM;CACf,MAAM,MAAM;CACZ,OAAO,MAAM;CACb,OAAO,MAAM;CACb,OAAO,MAAM;CACb,MAAM,SAAS;AACjB;;;;;;AAeA,SAAgB,cAAc,MAAoC;CAChE,MAAM,EAAE,MAAM,QAAQ,MAAM,SAAS,cAAc;CACnD,MAAM,eAAe,SAAS,IAAI,IAAI,OAAO,MAAM,IAAI;CACvD,MAAM,UAAU,YAAY,WAAW,SAAiB;CAGxD,IAAI,SAAS,SACX,OAAO,GAAG,eAAe,QAAQ,OAAO,EAAE;CAI5C,MAAM,OAAO,WAAW,SAAS;CAEjC,MAAM,gBAAgB,QAAQ,GADf,OAAO,GAAG,KAAK,KAAK,KACO,SAAS;CAGnD,OAAO,GAAG,eAFc,aAAa,KAEM,cAAc;AAC3D;;;;;;;AAQA,SAAS,SAAS,MAAc,SAAiB,MAAyB;CACxE,MAAM,OAAO,MAAM,QAAQ;CAO3B,MAAM,SAAS,cAAc;EAAE;EAAM,QANtB,MAAM,UAAU;EAMc;EAAM,SAF1B,kBAAkB,EAFzC,aAAa,QAAQ,OAAO,WAAW,GAEY,GAAG,OAEmB;EAAG,WAD5D,SAAS,WAAW,oBAAG,IAAI,KAAK,EAAC,CAAC,mBAAmB,EAAE,KAAK;CACU,CAAC;CACzF,QAAQ,OAAO,MAAM,MAAM;AAC7B;AAEA,MAAa,SAAS;CACpB,IAAI,WAAoB;EACtB,OAAO;CACT;CACA,IAAI,SAAS,OAAgB;EAC3B,YAAY;CACd;CAEA,KAAK,SAAiB,MAAyB;EAC7C,SAAS,QAAQ,SAAS,IAAI;CAChC;CAEA,QAAQ,SAAiB,MAAyB;EAChD,SAAS,WAAW,SAAS,IAAI;CACnC;CAEA,KAAK,SAAiB,MAAyB;EAC7C,SAAS,QAAQ,SAAS,IAAI;CAChC;CAEA,MAAM,SAAiB,MAAyB;EAC9C,SAAS,SAAS,SAAS,IAAI;CACjC;CAEA,IAAI,SAAuB;EACzB,SAAS,OAAO,SAAS,EAAE,MAAM,QAAQ,CAAC;CAC5C;CAEA,UAAgB;EACd,QAAQ,OAAO,MAAM,IAAI;CAC3B;CAEA,MAAM,SAAuB;EAC3B,IAAI,aAAa,QAAQ,IAAI,KAAK,MAAM,MACtC,SAAS,OAAO,OAAO,IAAI,OAAO,GAAG,EAAE,MAAM,QAAQ,CAAC;CAE1D;CAEA,IAAI,MAAkC,SAA4B;EAChE,IAAI,OAAO,SAAS,UAAU;GAC5B,QAAQ,OAAO,MAAM,KAAK,SAAS,IAAI,IAAI,OAAO,OAAO,IAAI;GAC7D;EACF;EAEA,IAAI,KAAK,UAAU;GAEjB,QAAQ,IAAI,KAAK,UAAU,IAAI,CAAC;GAChC;EACF;EAEA,MAAM,UAAU,SAAS;EAGzB,MAAM,eAAe,OAAgB,SAAS,UAAkB;GAC9D,IAAI,SAAS,YAAY,UAAU,MAAM,OAAO;GAChD,IAAI,UAAU,QAAQ,UAAU,QAAW,OAAO;GAClD,IAAI,iBAAiB,MACnB,OAAO,0BAA0B,OAAO,EAAE,WAAW,KAAK,CAAC;GAE7D,IAAI,OAAO,UAAU,UACnB,OAAO,SAAS,KAAK,UAAU,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,KAAK;GAEvE,OAAO,OAAO,KAAK;EACrB;EAGA,MAAM,cAAc,QAAyB;GAC3C,OAAO,YAAY,UAAa,OAAO,WAAW,QAAQ,SAAS;EACrE;EAGA,MAAM,kBAAkB,KAAa,OAAgB,MAAc,SAAS,UAAkB;GAC5F,IAAI,WAAW,OAAO,SAAS;IAC7B,MAAM,cAAc,QAAQ;IAC5B,IAAI,aACF,OAAO,YAAY,OAAO,IAAI;GAElC;GACA,OAAO,YAAY,OAAO,MAAM;EAClC;EAEA,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;GAMxB,MAAM,IAAI,YALM,OAAO,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,GAAG,CACvC,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CACrD,KACA,eAAe,KAAK,OAAO,MAAM,IAAI,CACvC,CACqC,GAAG,EAAE,YAAY,MAAM,CAAC;GAC7D,QAAQ,OAAO,MAAM,CAAC;GACtB;EACF;EAEA,IAAI,KAAK,WAAW,GAClB;EAIF,MAAM,UADa,MAAM,KAAK,IAAI,IAAI,KAAK,SAAS,SAAS,OAAO,KAAK,IAAI,CAAC,CAAC,CACtD,CAAC,CAAC,QAAQ,MAAM,CAAC,WAAW,CAAC,CAAC;EACvD,IAAI,QAAQ,WAAW,GACrB;EAQF,MAAM,IAAI,YAAY,CAAC,SAAS,GANnB,KAAK,KAAK,SACrB,QAAQ,KAAK,WACX,eAAe,QAAS,KAAiC,SAAS,IAAI,CACxE,CAGoC,CAAC,GAAG,EACxC,qBAAqB,WAAW,aAAa;GAC3C,OAAO,cAAc,KAAK,cAAc,KAAK,cAAc;EAC7D,EACF,CAAC;EACD,QAAQ,OAAO,MAAM,CAAC;CACxB;AACF"}