@tailor-platform/sdk 1.14.0 → 1.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +19 -0
  3. package/dist/application-BznueWxG.mjs +4 -0
  4. package/dist/{application-DnWZVbDO.mjs → application-DhwHYQ3H.mjs} +95 -44
  5. package/dist/application-DhwHYQ3H.mjs.map +1 -0
  6. package/dist/cli/index.mjs +4 -4
  7. package/dist/cli/lib.d.mts +13 -49
  8. package/dist/cli/lib.mjs +4 -4
  9. package/dist/cli/skills.d.mts +2 -0
  10. package/dist/cli/skills.mjs +51 -0
  11. package/dist/cli/skills.mjs.map +1 -0
  12. package/dist/configure/index.d.mts +4 -4
  13. package/dist/configure/index.mjs +2 -2
  14. package/dist/configure/index.mjs.map +1 -1
  15. package/dist/index-YzESrtj0.d.mts +396 -0
  16. package/dist/{index-DMoFYBhB.d.mts → index-q3n7wQOs.d.mts} +13 -12
  17. package/dist/{jiti-DuCiUfMj.mjs → jiti-BrELlEYT.mjs} +2 -2
  18. package/dist/{jiti-DuCiUfMj.mjs.map → jiti-BrELlEYT.mjs.map} +1 -1
  19. package/dist/{job-zGAXCidt.mjs → job-XiwGyFJt.mjs} +1 -1
  20. package/dist/{job-zGAXCidt.mjs.map → job-XiwGyFJt.mjs.map} +1 -1
  21. package/dist/plugin/index.d.mts +16 -2
  22. package/dist/plugin/index.mjs +208 -1
  23. package/dist/plugin/index.mjs.map +1 -1
  24. package/dist/{schema-BmKdDzr1.mjs → schema-DRYB-nzA.mjs} +1 -1
  25. package/dist/{schema-BmKdDzr1.mjs.map → schema-DRYB-nzA.mjs.map} +1 -1
  26. package/dist/{src-QNTCsO6J.mjs → src-DMROgdcL.mjs} +2 -2
  27. package/dist/{src-QNTCsO6J.mjs.map → src-DMROgdcL.mjs.map} +1 -1
  28. package/dist/{index-Bw_huFr7.d.mts → types-DbvONSS-.d.mts} +576 -460
  29. package/dist/{types-r-ZratAg.mjs → types-b-ig8nW_.mjs} +1 -1
  30. package/dist/types-b-ig8nW_.mjs.map +1 -0
  31. package/dist/{update-BnKKm4aR.mjs → update-Dm8ERWHJ.mjs} +312 -151
  32. package/dist/update-Dm8ERWHJ.mjs.map +1 -0
  33. package/dist/utils/test/index.d.mts +3 -3
  34. package/dist/utils/test/index.mjs +1 -1
  35. package/docs/plugin/custom.md +105 -49
  36. package/docs/plugin/index.md +2 -2
  37. package/package.json +5 -3
  38. package/skills/tailor-sdk/SKILL.md +34 -0
  39. package/dist/application-DM4zTgXU.mjs +0 -4
  40. package/dist/application-DnWZVbDO.mjs.map +0 -1
  41. package/dist/env-4RO7szrH.d.mts +0 -66
  42. package/dist/types-r-ZratAg.mjs.map +0 -1
  43. package/dist/update-BnKKm4aR.mjs.map +0 -1
  44. /package/dist/{chunk-C3Kl5s5P.mjs → chunk-GMkBE123.mjs} +0 -0
@@ -1,10 +1,10 @@
1
1
  /// <reference path="./../../user-defined.d.ts" />
2
- import { Ft as TailorField, rt as TailorDBType } from "../../index-Bw_huFr7.mjs";
3
- import { G as WORKFLOW_TEST_ENV_KEY, n as output } from "../../index-DMoFYBhB.mjs";
2
+ import { M as TailorDBType, ot as TailorField } from "../../types-DbvONSS-.mjs";
3
+ import "../../index-YzESrtj0.mjs";
4
+ import { G as WORKFLOW_TEST_ENV_KEY, n as output } from "../../index-q3n7wQOs.mjs";
4
5
  import { StandardSchemaV1 } from "@standard-schema/spec";
5
6
 
6
7
  //#region src/utils/test/index.d.ts
7
-
8
8
  /** Represents an unauthenticated user in the Tailor platform. */
9
9
  declare const unauthenticatedTailorUser: {
10
10
  readonly id: "00000000-0000-0000-0000-000000000000";
@@ -1,4 +1,4 @@
1
- import { t as WORKFLOW_TEST_ENV_KEY } from "../../job-zGAXCidt.mjs";
1
+ import { t as WORKFLOW_TEST_ENV_KEY } from "../../job-XiwGyFJt.mjs";
2
2
 
3
3
  //#region src/utils/test/index.ts
4
4
  /** Represents an unauthenticated user in the Tailor platform. */
@@ -2,12 +2,28 @@
2
2
 
3
3
  > **Beta Feature**: The custom plugin API is in beta and may change in future releases.
4
4
 
5
- Create your own plugins by implementing the `PluginBase` interface.
5
+ Create your own plugins by implementing the `Plugin` interface.
6
6
 
7
- ## PluginBase Interface
7
+ ## Requirements
8
+
9
+ **Plugins must use default export**:
10
+
11
+ ```typescript
12
+ // plugin.ts
13
+ const myPlugin: Plugin = {
14
+ id: "@my-company/my-plugin",
15
+ // ...
16
+ };
17
+
18
+ export default myPlugin; // Required: must be default export
19
+ ```
20
+
21
+ This is required so that generators can use plugin-generated TailorDB types via `getGeneratedType()`.
22
+
23
+ ## Plugin Interface
8
24
 
9
25
  ```typescript
10
- interface PluginBase<PluginConfig = unknown> {
26
+ interface Plugin<PluginConfig = unknown> {
11
27
  /** Unique identifier for the plugin (e.g., "@my-company/soft-delete") */
12
28
  readonly id: string;
13
29
 
@@ -17,7 +33,7 @@ interface PluginBase<PluginConfig = unknown> {
17
33
  /** Import path for generated code to reference */
18
34
  readonly importPath: string;
19
35
 
20
- /** Schema for per-type configuration via .plugin() (required when using process) */
36
+ /** Schema for per-type configuration via .plugin() (required when using processType) */
21
37
  readonly configSchema?: TailorAnyField;
22
38
 
23
39
  /** Schema for plugin-level configuration via definePlugins() (optional) */
@@ -33,7 +49,7 @@ interface PluginBase<PluginConfig = unknown> {
33
49
  readonly configTypeTemplate?: string;
34
50
 
35
51
  /** Process a type with this plugin attached */
36
- process?(context: PluginProcessContext): PluginOutput | Promise<PluginOutput>;
52
+ processType?(context: PluginProcessContext): PluginOutput | Promise<PluginOutput>;
37
53
 
38
54
  /** Process a namespace (plugins without a source type) */
39
55
  processNamespace?(
@@ -45,25 +61,24 @@ interface PluginBase<PluginConfig = unknown> {
45
61
  Notes:
46
62
 
47
63
  - `importPath` should be resolvable from the directory containing `tailor.config.ts`. Code generators use it to import plugin APIs such as `getGeneratedType` and executor modules.
48
- - If you want to attach a plugin via `.plugin()`, you must provide `configSchema` and `process`.
64
+ - If you want to attach a plugin via `.plugin()`, you must provide `configSchema` and `processType`.
49
65
  - Namespace-only plugins can omit `configSchema` and implement `processNamespace` instead.
50
- - `pluginConfig` stores the plugin-level config so it can be read later during processing. If you prefer not to set it manually, you can pass config as a tuple to `definePlugins([plugin, config])`.
51
- - For custom plugins, `pluginConfig` is the expected pattern. The tuple form can also be used to pass config.
66
+ - `pluginConfig` stores the plugin-level config so it can be read later during processing. Set it on the plugin object (e.g., via a factory function) before passing to `definePlugins()`.
52
67
  - `resolve` should return a dynamic import; relative specifiers are resolved from the plugin module.
53
68
  - Per-type config is optional by default. Use `typeConfigRequired: true` to make it mandatory.
54
69
  - To toggle optional/required based on plugin config, provide a function for `typeConfigRequired`.
55
70
 
56
71
  ## PluginProcessContext
57
72
 
58
- Context passed to the `process` method:
73
+ Context passed to the `processType` method:
59
74
 
60
75
  ```typescript
61
- interface PluginProcessContext<Config = unknown, PluginConfig = unknown> {
76
+ interface PluginProcessContext<TypeConfig = unknown, PluginConfig = unknown> {
62
77
  /** The TailorDB type being processed */
63
78
  type: TailorAnyDBType;
64
79
 
65
- /** Per-type configuration from .plugin({ pluginId: config }) */
66
- config: Config;
80
+ /** Per-type configuration from .plugin({ pluginId: typeConfig }) */
81
+ typeConfig: TypeConfig;
67
82
 
68
83
  /** Plugin-level configuration from definePlugins() */
69
84
  pluginConfig: PluginConfig;
@@ -78,38 +93,18 @@ interface PluginProcessContext<Config = unknown, PluginConfig = unknown> {
78
93
  Context passed to the `processNamespace` method:
79
94
 
80
95
  ```typescript
81
- interface PluginNamespaceProcessContext<Config = unknown> {
96
+ interface PluginNamespaceProcessContext<PluginConfig = unknown> {
82
97
  /** Plugin-level configuration from definePlugins() */
83
- pluginConfig: Config;
98
+ pluginConfig: PluginConfig;
84
99
 
85
- /** Namespace of the TailorDB types */
100
+ /** Target namespace for generated types */
86
101
  namespace: string;
87
-
88
- /** TailorDB types in the namespace (after type-attached processing) */
89
- types: TailorAnyDBType[];
90
-
91
- /** Plugin-generated types for type-attached plugins in the namespace */
92
- generatedTypes: Array<{
93
- type: TailorAnyDBType;
94
- pluginId: string;
95
- generatedTypeKind?: string;
96
- originalType: TailorAnyDBType;
97
- }>;
98
102
  }
99
103
  ```
100
104
 
101
- `generatedTypes` includes only type-attached plugin-generated types (so `originalType` is always present), and `types` contains only user-defined types.
102
- For example:
103
-
104
- ```typescript
105
- const changeRequestTypes = context.generatedTypes.filter(
106
- (entry) => entry.pluginId === "@example/change-request",
107
- );
108
- ```
109
-
110
105
  ## PluginOutput
111
106
 
112
- Return value from `process`:
107
+ Return value from `processType`:
113
108
 
114
109
  ```typescript
115
110
  interface PluginOutput {
@@ -136,6 +131,63 @@ interface PluginOutput {
136
131
  type NamespacePluginOutput = Omit<PluginOutput, "extends">;
137
132
  ```
138
133
 
134
+ ## getGeneratedType Helper
135
+
136
+ The SDK provides an async `getGeneratedType()` helper function to retrieve plugin-generated TailorDB types. This enables generators and other tools to work with types generated by plugins.
137
+
138
+ ```typescript
139
+ import { join } from "node:path";
140
+ import { getGeneratedType } from "@tailor-platform/sdk/plugin";
141
+ import { customer } from "./tailordb/customer";
142
+
143
+ const configPath = join(import.meta.dirname, "./tailor.config.ts");
144
+
145
+ // Get the generated type by config path, plugin ID, source type, and kind
146
+ const DeletedCustomer = await getGeneratedType(
147
+ configPath,
148
+ "@example/soft-delete",
149
+ customer,
150
+ "archive",
151
+ );
152
+ ```
153
+
154
+ **Parameters:**
155
+
156
+ - `configPath`: Path to `tailor.config.ts` (absolute or relative to cwd)
157
+ - `pluginId`: The plugin's unique identifier (e.g., `"@example/soft-delete"`)
158
+ - `sourceType`: The TailorDB type that the plugin is attached to (`null` for namespace plugins)
159
+ - `kind`: The generated type kind (e.g., `"archive"`, `"auditLog"`)
160
+
161
+ **How it works:**
162
+
163
+ 1. Loads and caches the config from the given path
164
+ 2. Finds the plugin by ID from `definePlugins()` exports
165
+ 3. Auto-resolves the namespace from config
166
+ 4. Calls the plugin's `processType()` or `processNamespace()` method
167
+ 5. Caches the result to avoid redundant processing
168
+ 6. Returns the generated type matching the specified kind
169
+
170
+ ### Example Usage
171
+
172
+ ```typescript
173
+ import { join } from "node:path";
174
+ import { getGeneratedType } from "@tailor-platform/sdk/plugin";
175
+ import { customer } from "./tailordb/customer";
176
+
177
+ const configPath = join(import.meta.dirname, "./tailor.config.ts");
178
+
179
+ // Type-attached plugin
180
+ const DeletedCustomer = await getGeneratedType(
181
+ configPath,
182
+ "@example/soft-delete",
183
+ customer,
184
+ "archive",
185
+ );
186
+
187
+ // Namespace plugin (pass null as sourceType)
188
+ const AuditLog = await getGeneratedType(configPath, "@example/audit-log", null, "auditLog");
189
+ ```
190
+
139
191
  ## Example: Soft Delete Plugin
140
192
 
141
193
  A complete example of a plugin that adds soft delete functionality:
@@ -145,7 +197,7 @@ A complete example of a plugin that adds soft delete functionality:
145
197
  ```typescript
146
198
  // plugins/soft-delete/plugin.ts
147
199
  import { db, t } from "@tailor-platform/sdk";
148
- import type { PluginBase, PluginProcessContext, PluginOutput } from "@tailor-platform/sdk";
200
+ import type { Plugin, PluginProcessContext, PluginOutput } from "@tailor-platform/sdk";
149
201
 
150
202
  interface SoftDeleteConfig {
151
203
  archiveReason?: boolean;
@@ -174,7 +226,7 @@ const pluginConfigSchema = t.object({
174
226
  function processSoftDelete(
175
227
  context: PluginProcessContext<SoftDeleteConfig, SoftDeletePluginConfig>,
176
228
  ): PluginOutput {
177
- const { type, config, pluginConfig, namespace } = context;
229
+ const { type, typeConfig, pluginConfig, namespace } = context;
178
230
  const prefix = pluginConfig?.archiveTablePrefix ?? "Deleted_";
179
231
 
180
232
  // Generate archive type
@@ -184,7 +236,7 @@ function processSoftDelete(
184
236
  originalData: db.string().description("JSON snapshot of deleted record"),
185
237
  deletedAt: db.datetime().description("When the record was deleted"),
186
238
  deletedBy: db.uuid().description("User who deleted the record"),
187
- ...(config.archiveReason && {
239
+ ...(typeConfig.archiveReason && {
188
240
  reason: db.string({ optional: true }).description("Reason for deletion"),
189
241
  }),
190
242
  ...db.fields.timestamps(),
@@ -213,8 +265,8 @@ function processSoftDelete(
213
265
  };
214
266
  }
215
267
 
216
- // Factory function for plugins with namespace config
217
- export function softDeletePlugin(pluginConfig?: SoftDeletePluginConfig): PluginBase {
268
+ // Factory function for plugins with plugin-level config
269
+ function createSoftDeletePlugin(pluginConfig?: SoftDeletePluginConfig): Plugin {
218
270
  return {
219
271
  id: "@example/soft-delete",
220
272
  description: "Adds soft delete with archive functionality",
@@ -223,9 +275,12 @@ export function softDeletePlugin(pluginConfig?: SoftDeletePluginConfig): PluginB
223
275
  pluginConfigSchema,
224
276
  pluginConfig,
225
277
  typeConfigRequired: (config) => config?.requireTypeConfig === true,
226
- process: processSoftDelete,
278
+ processType: processSoftDelete,
227
279
  };
228
280
  }
281
+
282
+ // Default export is required for getGeneratedType() to work
283
+ export default createSoftDeletePlugin();
229
284
  ```
230
285
 
231
286
  ### Executor with Context
@@ -273,8 +328,9 @@ export default withPluginContext((ctx: SoftDeleteContext) => {
273
328
  ```typescript
274
329
  // tailor.config.ts
275
330
  import { definePlugins } from "@tailor-platform/sdk";
276
- import { softDeletePlugin } from "./plugins/soft-delete";
331
+ import softDeletePlugin from "./plugins/soft-delete";
277
332
 
333
+ // Use a factory function to pass plugin-level config
278
334
  export const plugins = definePlugins(
279
335
  softDeletePlugin({
280
336
  archiveTablePrefix: "Deleted_",
@@ -339,13 +395,13 @@ declare module "@tailor-platform/sdk" {
339
395
 
340
396
  ### Type-Attached Plugins
341
397
 
342
- Implement `process` to handle types with the plugin attached:
398
+ Implement `processType` to handle types with the plugin attached:
343
399
 
344
400
  ```typescript
345
- const plugin: PluginBase = {
401
+ const plugin: Plugin = {
346
402
  id: "@example/my-plugin",
347
403
  // ...
348
- process(context) {
404
+ processType(context) {
349
405
  // Called for each type with .plugin({ "@example/my-plugin": config })
350
406
  return {
351
407
  types: {
@@ -361,7 +417,7 @@ const plugin: PluginBase = {
361
417
  Implement `processNamespace` for plugins that generate types independently:
362
418
 
363
419
  ```typescript
364
- const plugin: PluginBase = {
420
+ const plugin: Plugin = {
365
421
  id: "@example/audit-log",
366
422
  // ...
367
423
  processNamespace(context) {
@@ -376,10 +432,10 @@ const plugin: PluginBase = {
376
432
  Implement both methods for plugins that support both modes:
377
433
 
378
434
  ```typescript
379
- const plugin: PluginBase = {
435
+ const plugin: Plugin = {
380
436
  id: "@example/hybrid",
381
437
  // ...
382
- process(context) {
438
+ processType(context) {
383
439
  // Handle type attachments
384
440
  },
385
441
  processNamespace(context) {
@@ -23,9 +23,9 @@ Define plugins in `tailor.config.ts` using `definePlugins()`:
23
23
 
24
24
  ```typescript
25
25
  import { defineConfig, definePlugins } from "@tailor-platform/sdk";
26
- import { myPlugin } from "./plugins/my-plugin";
26
+ import myPlugin from "./plugins/my-plugin";
27
27
 
28
- export const plugins = definePlugins(myPlugin());
28
+ export const plugins = definePlugins(myPlugin);
29
29
 
30
30
  export default defineConfig({
31
31
  name: "my-app",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailor-platform/sdk",
3
- "version": "1.14.0",
3
+ "version": "1.14.2",
4
4
  "description": "Tailor Platform SDK - The SDK to work with Tailor Platform",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -9,14 +9,16 @@
9
9
  "directory": "packages/sdk"
10
10
  },
11
11
  "bin": {
12
- "tailor-sdk": "./dist/cli/index.mjs"
12
+ "tailor-sdk": "./dist/cli/index.mjs",
13
+ "tailor-sdk-skills": "./dist/cli/skills.mjs"
13
14
  },
14
15
  "files": [
15
16
  "CHANGELOG.md",
16
17
  "dist",
17
18
  "docs",
18
19
  "postinstall.mjs",
19
- "README.md"
20
+ "README.md",
21
+ "skills"
20
22
  ],
21
23
  "type": "module",
22
24
  "main": "./dist/configure/index.mjs",
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: tailor-sdk
3
+ description: Use this skill when working with @tailor-platform/sdk projects, including service configuration, CLI usage, and docs navigation.
4
+ ---
5
+
6
+ # Tailor SDK Knowledge
7
+
8
+ This skill helps with projects using `@tailor-platform/sdk`.
9
+
10
+ ## Primary Sources
11
+
12
+ Use these files as the single source of truth:
13
+
14
+ - `node_modules/@tailor-platform/sdk/README.md`
15
+ - `node_modules/@tailor-platform/sdk/docs/configuration.md`
16
+ - `node_modules/@tailor-platform/sdk/docs/services/*.md`
17
+ - `node_modules/@tailor-platform/sdk/docs/cli-reference.md`
18
+ - `node_modules/@tailor-platform/sdk/docs/cli/*.md`
19
+ - `node_modules/@tailor-platform/sdk/docs/testing.md`
20
+
21
+ ## Working Rules
22
+
23
+ 1. Prefer SDK docs above assumptions. If behavior is unclear, cite the exact doc path used.
24
+ 2. Keep examples compatible with Node.js 22+.
25
+ 3. For CLI questions, verify command and option names from `docs/cli-reference.md` and `docs/cli/*.md`.
26
+ 4. For configuration questions, validate examples against `docs/configuration.md` and related service docs.
27
+
28
+ ## Quick Navigation
29
+
30
+ - Setup and first deploy: `docs/quickstart.md`
31
+ - Core config shape: `docs/configuration.md`
32
+ - Service details: `docs/services/*.md`
33
+ - CLI commands: `docs/cli-reference.md` and `docs/cli/*.md`
34
+ - Testing patterns: `docs/testing.md`
@@ -1,4 +0,0 @@
1
- import "./chunk-C3Kl5s5P.mjs";
2
- import { t as defineApplication } from "./application-DnWZVbDO.mjs";
3
-
4
- export { defineApplication };