@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.
- package/CHANGELOG.md +27 -0
- package/README.md +19 -0
- package/dist/application-BznueWxG.mjs +4 -0
- package/dist/{application-DnWZVbDO.mjs → application-DhwHYQ3H.mjs} +95 -44
- package/dist/application-DhwHYQ3H.mjs.map +1 -0
- package/dist/cli/index.mjs +4 -4
- package/dist/cli/lib.d.mts +13 -49
- package/dist/cli/lib.mjs +4 -4
- package/dist/cli/skills.d.mts +2 -0
- package/dist/cli/skills.mjs +51 -0
- package/dist/cli/skills.mjs.map +1 -0
- package/dist/configure/index.d.mts +4 -4
- package/dist/configure/index.mjs +2 -2
- package/dist/configure/index.mjs.map +1 -1
- package/dist/index-YzESrtj0.d.mts +396 -0
- package/dist/{index-DMoFYBhB.d.mts → index-q3n7wQOs.d.mts} +13 -12
- package/dist/{jiti-DuCiUfMj.mjs → jiti-BrELlEYT.mjs} +2 -2
- package/dist/{jiti-DuCiUfMj.mjs.map → jiti-BrELlEYT.mjs.map} +1 -1
- package/dist/{job-zGAXCidt.mjs → job-XiwGyFJt.mjs} +1 -1
- package/dist/{job-zGAXCidt.mjs.map → job-XiwGyFJt.mjs.map} +1 -1
- package/dist/plugin/index.d.mts +16 -2
- package/dist/plugin/index.mjs +208 -1
- package/dist/plugin/index.mjs.map +1 -1
- package/dist/{schema-BmKdDzr1.mjs → schema-DRYB-nzA.mjs} +1 -1
- package/dist/{schema-BmKdDzr1.mjs.map → schema-DRYB-nzA.mjs.map} +1 -1
- package/dist/{src-QNTCsO6J.mjs → src-DMROgdcL.mjs} +2 -2
- package/dist/{src-QNTCsO6J.mjs.map → src-DMROgdcL.mjs.map} +1 -1
- package/dist/{index-Bw_huFr7.d.mts → types-DbvONSS-.d.mts} +576 -460
- package/dist/{types-r-ZratAg.mjs → types-b-ig8nW_.mjs} +1 -1
- package/dist/types-b-ig8nW_.mjs.map +1 -0
- package/dist/{update-BnKKm4aR.mjs → update-Dm8ERWHJ.mjs} +312 -151
- package/dist/update-Dm8ERWHJ.mjs.map +1 -0
- package/dist/utils/test/index.d.mts +3 -3
- package/dist/utils/test/index.mjs +1 -1
- package/docs/plugin/custom.md +105 -49
- package/docs/plugin/index.md +2 -2
- package/package.json +5 -3
- package/skills/tailor-sdk/SKILL.md +34 -0
- package/dist/application-DM4zTgXU.mjs +0 -4
- package/dist/application-DnWZVbDO.mjs.map +0 -1
- package/dist/env-4RO7szrH.d.mts +0 -66
- package/dist/types-r-ZratAg.mjs.map +0 -1
- package/dist/update-BnKKm4aR.mjs.map +0 -1
- /package/dist/{chunk-C3Kl5s5P.mjs → chunk-GMkBE123.mjs} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/// <reference path="./../../user-defined.d.ts" />
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
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";
|
package/docs/plugin/custom.md
CHANGED
|
@@ -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 `
|
|
5
|
+
Create your own plugins by implementing the `Plugin` interface.
|
|
6
6
|
|
|
7
|
-
##
|
|
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
|
|
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
|
|
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
|
-
|
|
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 `
|
|
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.
|
|
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 `
|
|
73
|
+
Context passed to the `processType` method:
|
|
59
74
|
|
|
60
75
|
```typescript
|
|
61
|
-
interface PluginProcessContext<
|
|
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:
|
|
66
|
-
|
|
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<
|
|
96
|
+
interface PluginNamespaceProcessContext<PluginConfig = unknown> {
|
|
82
97
|
/** Plugin-level configuration from definePlugins() */
|
|
83
|
-
pluginConfig:
|
|
98
|
+
pluginConfig: PluginConfig;
|
|
84
99
|
|
|
85
|
-
/**
|
|
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 `
|
|
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 {
|
|
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,
|
|
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
|
-
...(
|
|
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
|
|
217
|
-
|
|
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
|
-
|
|
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
|
|
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 `
|
|
398
|
+
Implement `processType` to handle types with the plugin attached:
|
|
343
399
|
|
|
344
400
|
```typescript
|
|
345
|
-
const plugin:
|
|
401
|
+
const plugin: Plugin = {
|
|
346
402
|
id: "@example/my-plugin",
|
|
347
403
|
// ...
|
|
348
|
-
|
|
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:
|
|
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:
|
|
435
|
+
const plugin: Plugin = {
|
|
380
436
|
id: "@example/hybrid",
|
|
381
437
|
// ...
|
|
382
|
-
|
|
438
|
+
processType(context) {
|
|
383
439
|
// Handle type attachments
|
|
384
440
|
},
|
|
385
441
|
processNamespace(context) {
|
package/docs/plugin/index.md
CHANGED
|
@@ -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
|
|
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.
|
|
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`
|