@tailor-platform/sdk 0.16.3 → 0.17.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.
@@ -2,6 +2,17 @@
2
2
 
3
3
  The SDK uses TypeScript for configuration files. By default, it uses `tailor.config.ts` in the project root. You can specify a different path using the `--config` option.
4
4
 
5
+ For service-specific documentation, see:
6
+
7
+ - [TailorDB](./services/tailordb.md) - Database schema definition
8
+ - [Resolver](./services/resolver.md) - Custom GraphQL resolvers
9
+ - [Executor](./services/executor.md) - Event-driven handlers
10
+ - [Workflow](./services/workflow.md) - Job orchestration
11
+ - [Auth](./services/auth.md) - Authentication and authorization
12
+ - [IdP](./services/idp.md) - Built-in identity provider
13
+ - [Static Website](./services/staticwebsite.md) - Static file hosting
14
+ - [Secret Manager](./services/secret.md) - Secure credential storage
15
+
5
16
  ### Application Settings
6
17
 
7
18
  ```typescript
@@ -53,7 +64,7 @@ export default defineConfig({
53
64
 
54
65
  ### Built-in IdP
55
66
 
56
- Configure the Built-in IdP service using `defineIdp()`. The returned IdP object provides type-safe provider references via `idp.provider()` that can be used in Auth service configuration.
67
+ Configure the Built-in IdP service using `defineIdp()`. See [IdP](./services/idp.md) for full documentation.
57
68
 
58
69
  ```typescript
59
70
  import { defineIdp } from "@tailor-platform/sdk";
@@ -68,13 +79,9 @@ export default defineConfig({
68
79
  });
69
80
  ```
70
81
 
71
- **authorization**: User management permissions (`"insecure"`, `"loggedIn"`, or CEL expression).
72
-
73
- **clients**: OAuth client names for the IdP.
74
-
75
82
  ### Auth Service
76
83
 
77
- Configure Auth service using `defineAuth()`:
84
+ Configure Auth service using `defineAuth()`. See [Auth](./services/auth.md) for full documentation.
78
85
 
79
86
  ```typescript
80
87
  import { defineAuth } from "@tailor-platform/sdk";
@@ -86,17 +93,6 @@ const auth = defineAuth("my-auth", {
86
93
  usernameField: "email",
87
94
  attributes: { role: true },
88
95
  },
89
- machineUsers: {
90
- "admin-machine-user": {
91
- attributes: { role: "ADMIN" },
92
- },
93
- },
94
- oauth2Clients: {
95
- "my-oauth2-client": {
96
- redirectURIs: ["https://example.com/callback"],
97
- grantTypes: ["authorization_code", "refresh_token"],
98
- },
99
- },
100
96
  idProvider: idp.provider("my-provider", "my-client"),
101
97
  });
102
98
 
@@ -105,24 +101,15 @@ export default defineConfig({
105
101
  });
106
102
  ```
107
103
 
108
- **userProfile**: Maps identities to TailorDB type with username field and attributes.
109
-
110
- **machineUsers**: Service accounts with predefined attributes.
111
-
112
- **oauth2Clients**: OAuth 2.0 clients with redirect URIs and grant types.
113
-
114
- **idProvider**: External identity provider (OIDC, SAML, IDToken, or BuiltInIdP).
115
-
116
104
  ### Static Websites
117
105
 
118
- Configure static website hosting using `defineStaticWebSite()`. The returned website object provides a type-safe `url` property that can be used in CORS settings and OAuth2 redirect URIs.
106
+ Configure static website hosting using `defineStaticWebSite()`. See [Static Website](./services/staticwebsite.md) for full documentation.
119
107
 
120
108
  ```typescript
121
109
  import { defineStaticWebSite } from "@tailor-platform/sdk";
122
110
 
123
111
  const website = defineStaticWebSite("my-website", {
124
112
  description: "My Static Website",
125
- allowedIPAddresses: ["192.168.0.0/24"],
126
113
  });
127
114
 
128
115
  export default defineConfig({
@@ -130,13 +117,9 @@ export default defineConfig({
130
117
  });
131
118
  ```
132
119
 
133
- **description**: Description of the site.
134
-
135
- **allowedIPAddresses**: List of IP addresses allowed to access the site in CIDR format.
136
-
137
120
  ### Environment Variables
138
121
 
139
- Define environment variables that can be accessed in resolvers and executors:
122
+ Define environment variables that can be accessed in resolvers, executors, and workflows:
140
123
 
141
124
  ```typescript
142
125
  export default defineConfig({
@@ -163,6 +146,12 @@ body: ({ input, env }) => {
163
146
  body: ({ newRecord, env }) => {
164
147
  console.log(`Environment: ${env.bar}, User: ${newRecord.name}`);
165
148
  };
149
+
150
+ // In workflow jobs
151
+ body: (input, { env }) => {
152
+ console.log(`Environment: ${env.bar}`);
153
+ return { value: env.foo };
154
+ };
166
155
  ```
167
156
 
168
157
  ### Workflow Service
@@ -181,3 +170,18 @@ export default defineConfig({
181
170
  **files**: Glob patterns to match workflow files. Required.
182
171
 
183
172
  **ignores**: Glob patterns to exclude files. Optional.
173
+
174
+ ### Generators
175
+
176
+ Configure code generators using `defineGenerators()`. Generators must be exported as a named export.
177
+
178
+ ```typescript
179
+ import { defineGenerators } from "@tailor-platform/sdk";
180
+
181
+ export const generators = defineGenerators(
182
+ ["@tailor-platform/kysely-type", { distPath: "./generated/tailordb.ts" }],
183
+ ["@tailor-platform/enum-constants", { distPath: "./generated/enums.ts" }],
184
+ );
185
+ ```
186
+
187
+ See [Generators](./generator/index.md) for full documentation.
@@ -0,0 +1,194 @@
1
+ # Builtin Generators
2
+
3
+ The SDK includes four builtin generators for common code generation tasks.
4
+
5
+ ## @tailor-platform/kysely-type
6
+
7
+ Generates Kysely type definitions and the `getDB()` function for type-safe database access.
8
+
9
+ ### Configuration
10
+
11
+ ```typescript
12
+ ["@tailor-platform/kysely-type", { distPath: "./generated/tailordb.ts" }];
13
+ ```
14
+
15
+ | Option | Type | Description |
16
+ | ---------- | -------- | --------------------------- |
17
+ | `distPath` | `string` | Output file path (required) |
18
+
19
+ ### Prerequisites
20
+
21
+ Install the required runtime dependencies:
22
+
23
+ ```bash
24
+ pnpm add -D @tailor-platform/function-kysely-tailordb @tailor-platform/function-types
25
+ ```
26
+
27
+ ### Output
28
+
29
+ Generates a TypeScript file containing:
30
+
31
+ - Type definitions for all TailorDB types
32
+ - `getDB(namespace)` function to create Kysely instances
33
+ - Utility types for Timestamp and Serial fields
34
+
35
+ ### Usage
36
+
37
+ ```typescript
38
+ import { getDB } from "./generated/tailordb";
39
+
40
+ // In resolvers
41
+ body: async (context) => {
42
+ const db = getDB("tailordb");
43
+ const users = await db
44
+ .selectFrom("User")
45
+ .selectAll()
46
+ .where("email", "=", context.input.email)
47
+ .execute();
48
+ return { users };
49
+ };
50
+
51
+ // In executors
52
+ body: async ({ newRecord }) => {
53
+ const db = getDB("tailordb");
54
+ await db
55
+ .insertInto("AuditLog")
56
+ .values({ userId: newRecord.id, action: "created" })
57
+ .execute();
58
+ };
59
+
60
+ // In workflow jobs
61
+ body: async (input, { env }) => {
62
+ const db = getDB("tailordb");
63
+ return await db
64
+ .selectFrom("Order")
65
+ .selectAll()
66
+ .where("id", "=", input.orderId)
67
+ .executeTakeFirst();
68
+ };
69
+ ```
70
+
71
+ ## @tailor-platform/enum-constants
72
+
73
+ Extracts enum constants from TailorDB type definitions.
74
+
75
+ ### Configuration
76
+
77
+ ```typescript
78
+ ["@tailor-platform/enum-constants", { distPath: "./generated/enums.ts" }];
79
+ ```
80
+
81
+ | Option | Type | Description |
82
+ | ---------- | -------- | --------------------------- |
83
+ | `distPath` | `string` | Output file path (required) |
84
+
85
+ ### Output
86
+
87
+ Generates TypeScript constants for all enum fields:
88
+
89
+ ```typescript
90
+ // Generated output
91
+ export const OrderStatus = {
92
+ PENDING: "PENDING",
93
+ PROCESSING: "PROCESSING",
94
+ COMPLETED: "COMPLETED",
95
+ CANCELLED: "CANCELLED",
96
+ } as const;
97
+
98
+ export type OrderStatus = (typeof OrderStatus)[keyof typeof OrderStatus];
99
+ ```
100
+
101
+ ### Usage
102
+
103
+ ```typescript
104
+ import { OrderStatus } from "./generated/enums";
105
+
106
+ // Type-safe enum usage
107
+ const status: OrderStatus = OrderStatus.PENDING;
108
+
109
+ // In queries
110
+ const orders = await db
111
+ .selectFrom("Order")
112
+ .selectAll()
113
+ .where("status", "=", OrderStatus.COMPLETED)
114
+ .execute();
115
+ ```
116
+
117
+ ## @tailor-platform/file-utils
118
+
119
+ Generates utility functions for handling file-type fields in TailorDB.
120
+
121
+ ### Configuration
122
+
123
+ ```typescript
124
+ ["@tailor-platform/file-utils", { distPath: "./generated/files.ts" }];
125
+ ```
126
+
127
+ | Option | Type | Description |
128
+ | ---------- | -------- | --------------------------- |
129
+ | `distPath` | `string` | Output file path (required) |
130
+
131
+ ### Output
132
+
133
+ Generates TypeScript interfaces and utilities for types with file fields:
134
+
135
+ ```typescript
136
+ // Generated output
137
+ export interface UserFileFields {
138
+ avatar: string;
139
+ documents: string;
140
+ }
141
+
142
+ export function getUserFileFields(): (keyof UserFileFields)[] {
143
+ return ["avatar", "documents"];
144
+ }
145
+ ```
146
+
147
+ ## @tailor-platform/seed
148
+
149
+ Generates seed data configuration files for database initialization.
150
+
151
+ ### Configuration
152
+
153
+ ```typescript
154
+ ["@tailor-platform/seed", { distPath: "./seed" }][
155
+ // With executable script
156
+ ("@tailor-platform/seed", { distPath: "./seed", machineUserName: "admin" })
157
+ ];
158
+ ```
159
+
160
+ | Option | Type | Description |
161
+ | ----------------- | -------- | -------------------------------------------------- |
162
+ | `distPath` | `string` | Output directory path (required) |
163
+ | `machineUserName` | `string` | Machine user name for executable script (optional) |
164
+
165
+ ### Output
166
+
167
+ Generates a seed directory structure:
168
+
169
+ ```
170
+ seed/
171
+ ├── config.yaml # Entity dependencies configuration
172
+ ├── data/
173
+ │ ├── User.jsonl # Seed data files (JSONL format)
174
+ │ └── Product.jsonl
175
+ ├── graphql/
176
+ │ ├── User.graphql # GraphQL mutation files
177
+ │ └── Product.graphql
178
+ ├── mapping/
179
+ │ ├── User.yaml # GraphQL Ingest mapping files
180
+ │ └── Product.yaml
181
+ ├── schema.ts # lines-db schema definitions
182
+ └── exec.mjs # Executable script (if machineUserName provided)
183
+ ```
184
+
185
+ ### Usage
186
+
187
+ If `machineUserName` is provided, an executable script is generated:
188
+
189
+ ```bash
190
+ # Run seed data import
191
+ node seed/exec.mjs
192
+ ```
193
+
194
+ The generated files are compatible with gql-ingest for bulk data import.
@@ -0,0 +1,150 @@
1
+ # Custom Generators (Preview)
2
+
3
+ > **Preview Feature**: The custom generator API is in preview and may change in future releases.
4
+
5
+ Create your own generators by implementing the `CodeGenerator` interface.
6
+
7
+ ## CodeGenerator Interface
8
+
9
+ ```typescript
10
+ interface CodeGenerator<T, R, E, Ts, Rs> {
11
+ id: string;
12
+ description: string;
13
+
14
+ // Process individual items
15
+ processType(args: {
16
+ type: ParsedTailorDBType;
17
+ namespace: string;
18
+ source: { filePath: string; exportName: string };
19
+ }): T | Promise<T>;
20
+
21
+ processResolver(args: {
22
+ resolver: Resolver;
23
+ namespace: string;
24
+ }): R | Promise<R>;
25
+
26
+ processExecutor(executor: Executor): E | Promise<E>;
27
+
28
+ // Aggregate per namespace (optional)
29
+ processTailorDBNamespace?(args: {
30
+ namespace: string;
31
+ types: Record<string, T>;
32
+ }): Ts | Promise<Ts>;
33
+
34
+ processResolverNamespace?(args: {
35
+ namespace: string;
36
+ resolvers: Record<string, R>;
37
+ }): Rs | Promise<Rs>;
38
+
39
+ // Final aggregation
40
+ aggregate(args: {
41
+ input: GeneratorInput<Ts, Rs>;
42
+ executorInputs: E[];
43
+ baseDir: string;
44
+ }): GeneratorResult | Promise<GeneratorResult>;
45
+ }
46
+ ```
47
+
48
+ ## GeneratorResult
49
+
50
+ Generators return a `GeneratorResult` containing files to create:
51
+
52
+ ```typescript
53
+ interface GeneratorResult {
54
+ files: Array<{
55
+ path: string; // Relative path from project root
56
+ content: string; // File content
57
+ skipIfExists?: boolean; // Skip if file already exists (default: false)
58
+ executable?: boolean; // Make file executable (default: false)
59
+ }>;
60
+ errors?: string[];
61
+ }
62
+ ```
63
+
64
+ ## Example: Simple Type List Generator
65
+
66
+ ```typescript
67
+ import type { CodeGenerator, GeneratorResult } from "@tailor-platform/sdk";
68
+
69
+ const typeListGenerator: CodeGenerator<string, null, null, string[], null> = {
70
+ id: "type-list",
71
+ description: "Generates a list of all TailorDB type names",
72
+
73
+ processType({ type }) {
74
+ return type.name;
75
+ },
76
+
77
+ processResolver() {
78
+ return null;
79
+ },
80
+
81
+ processExecutor() {
82
+ return null;
83
+ },
84
+
85
+ processTailorDBNamespace({ types }) {
86
+ return Object.values(types);
87
+ },
88
+
89
+ aggregate({ input }) {
90
+ const allTypes = input.tailordb.flatMap((ns) => ns.types);
91
+ const content = `// Generated type list\nexport const types = ${JSON.stringify(allTypes, null, 2)} as const;\n`;
92
+
93
+ return {
94
+ files: [{ path: "generated/types.ts", content }],
95
+ };
96
+ },
97
+ };
98
+ ```
99
+
100
+ ## Using Custom Generators
101
+
102
+ Pass the generator object directly to `defineGenerators()`:
103
+
104
+ ```typescript
105
+ import { defineGenerators } from "@tailor-platform/sdk";
106
+ import { typeListGenerator } from "./generators/type-list";
107
+
108
+ export const generators = defineGenerators(
109
+ ["@tailor-platform/kysely-type", { distPath: "./generated/tailordb.ts" }],
110
+ typeListGenerator, // Custom generator
111
+ );
112
+ ```
113
+
114
+ ## Available Input Data
115
+
116
+ ### ParsedTailorDBType
117
+
118
+ Contains full type information including:
119
+
120
+ - `name`: Type name
121
+ - `fields`: Field definitions with types, validation, and descriptions
122
+ - `relations`: Relationship definitions
123
+ - `indexes`: Index configurations
124
+ - `permission`: Permission rules
125
+
126
+ ### Resolver
127
+
128
+ Contains resolver configuration:
129
+
130
+ - `name`: Resolver name
131
+ - `operation`: Query or mutation
132
+ - `input`: Input schema
133
+ - `output`: Output schema
134
+
135
+ ### Executor
136
+
137
+ Contains executor configuration:
138
+
139
+ - `name`: Executor name
140
+ - `trigger`: Trigger configuration
141
+ - `operation`: Execution target
142
+
143
+ ### GeneratorAuthInput
144
+
145
+ Contains authentication configuration when available:
146
+
147
+ - `name`: Auth service name
148
+ - `userProfile`: User profile type information
149
+ - `machineUsers`: Machine user definitions
150
+ - `oauth2Clients`: OAuth2 client configurations
@@ -0,0 +1,56 @@
1
+ # Generators
2
+
3
+ Generators analyze your TailorDB types, Resolvers, and Executors to automatically generate TypeScript code.
4
+
5
+ ## Overview
6
+
7
+ When you run `tailor-sdk generate`, the SDK:
8
+
9
+ 1. Loads all TailorDB types, Resolvers, and Executors from your configuration
10
+ 2. Passes each definition to the configured generators
11
+ 3. Aggregates the results and writes output files
12
+
13
+ This enables generators to create derived code based on your application's schema. For example, the `@tailor-platform/kysely-type` generator produces type-safe database access code from your TailorDB definitions.
14
+
15
+ ## Configuration
16
+
17
+ Define generators in `tailor.config.ts` using `defineGenerators()`:
18
+
19
+ ```typescript
20
+ import { defineConfig, defineGenerators } from "@tailor-platform/sdk";
21
+
22
+ export const generators = defineGenerators(
23
+ ["@tailor-platform/kysely-type", { distPath: "./generated/tailordb.ts" }],
24
+ ["@tailor-platform/enum-constants", { distPath: "./generated/enums.ts" }],
25
+ );
26
+
27
+ export default defineConfig({
28
+ name: "my-app",
29
+ // ...
30
+ });
31
+ ```
32
+
33
+ **Important**: The `generators` export must be a named export (not default).
34
+
35
+ ## CLI Commands
36
+
37
+ ### Generate Files
38
+
39
+ ```bash
40
+ tailor-sdk generate
41
+ ```
42
+
43
+ Generates all configured output files.
44
+
45
+ ### Watch Mode
46
+
47
+ ```bash
48
+ tailor-sdk generate --watch
49
+ ```
50
+
51
+ Watches for file changes and regenerates automatically.
52
+
53
+ ## Generator Types
54
+
55
+ - [Builtin Generators](./builtin.md) - Ready-to-use generators included with the SDK
56
+ - [Custom Generators](./custom.md) - Create your own generators (Preview)
@@ -1,6 +1,4 @@
1
- # Tailor Platform SDK
2
-
3
- Development kit for building type-safe applications on the Tailor Platform using TypeScript.
1
+ # Quickstart
4
2
 
5
3
  ## Getting Started
6
4
 
@@ -49,7 +47,7 @@ You can now open the GraphQL Playground and execute the `hello` query:
49
47
 
50
48
  ```graphql
51
49
  query {
52
- hello(input: { name: "sdk" }) {
50
+ hello(name: "sdk") {
53
51
  message
54
52
  }
55
53
  }
@@ -94,3 +92,10 @@ export default createResolver({
94
92
  ```
95
93
 
96
94
  Deploy again to see the response.
95
+
96
+ ## Next Steps
97
+
98
+ - Learn about [TailorDB](./services/tailordb.md) for database schema definition
99
+ - Create custom [Resolvers](./services/resolver.md) with business logic
100
+ - Set up [Executors](./services/executor.md) for event-driven automation
101
+ - Explore [Templates](https://github.com/tailor-platform/sdk/tree/main/packages/create-sdk#available-templates) for more examples