@tailor-platform/sdk 2.8.0 → 2.10.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 (33) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/cli/lib.mjs +1 -1
  3. package/dist/cli/main.mjs +1 -1
  4. package/dist/cli/shared/seed-context.d.mts +3 -1
  5. package/dist/completion/zsh-worker.zsh +1 -1
  6. package/dist/configure/config/index.d.mts +2 -1
  7. package/dist/configure/index.d.mts +14 -14
  8. package/dist/configure/index.mjs +1 -1
  9. package/dist/configure/index.mjs.map +1 -1
  10. package/dist/configure/services/aigateway/index.d.mts +1 -3
  11. package/dist/configure/services/idp/index.d.mts +1 -1
  12. package/dist/configure/services/resolver/resolver.d.mts +1 -1
  13. package/dist/configure/services/tailordb/schema.d.mts +22 -13
  14. package/dist/configure/types/index.d.mts +1 -1
  15. package/dist/plugin/builtin/seed/index.mjs +1 -1
  16. package/dist/plugin/types.d.mts +17 -7
  17. package/dist/{register-ts-hook-CQuJ7h5G.mjs → register-ts-hook-D6aNriu3.mjs} +39 -39
  18. package/dist/register-ts-hook-D6aNriu3.mjs.map +1 -0
  19. package/dist/{schema-AYG4OhXY.mjs → schema-6d_OHyZf.mjs} +2 -2
  20. package/dist/schema-6d_OHyZf.mjs.map +1 -0
  21. package/dist/{seed-DwqRFdqP.mjs → seed-CMkupmX8.mjs} +41 -17
  22. package/dist/seed-CMkupmX8.mjs.map +1 -0
  23. package/dist/types/helpers.d.mts +3 -1
  24. package/dist/vitest/index.d.mts +2 -2
  25. package/dist/vitest/index.mjs.map +1 -1
  26. package/dist/vitest/mocks/file.d.mts +1 -1
  27. package/dist/vitest/pglite-kysely.d.mts +29 -7
  28. package/docs/plugin/custom.md +84 -0
  29. package/docs/services/tailordb-migration.md +14 -8
  30. package/package.json +5 -5
  31. package/dist/register-ts-hook-CQuJ7h5G.mjs.map +0 -1
  32. package/dist/schema-AYG4OhXY.mjs.map +0 -1
  33. package/dist/seed-DwqRFdqP.mjs.map +0 -1
@@ -1,6 +1,4 @@
1
- import { AuthNamespaceName } from "../../types/auth-namespace-name.mjs";
2
1
  import { AIGatewayConfig, AIGatewayDefinitionBrand, AIGatewayServiceInput } from "./types.mjs";
3
- import "../../index.mjs";
4
2
  //#region src/configure/services/aigateway/index.d.ts
5
3
  /**
6
4
  * Define an AI Gateway configuration for the Tailor SDK.
@@ -11,7 +9,7 @@ import "../../index.mjs";
11
9
  declare function defineAIGateway(name: string, config: Omit<AIGatewayServiceInput, "name">): {
12
10
  readonly name: string;
13
11
  readonly cors?: string[] | undefined;
14
- readonly authNamespace?: AuthNamespaceName;
12
+ readonly authNamespace?: import("@tailor-platform/sdk").AuthNamespaceName;
15
13
  } & AIGatewayDefinitionBrand;
16
14
  //#endregion
17
15
  export { type AIGatewayConfig, defineAIGateway };
@@ -52,7 +52,7 @@ declare function defineIdp<const TClients extends string[]>(name: string, config
52
52
  requestMfaSettingsUrl?: boolean | undefined;
53
53
  unenrollMfa?: boolean | undefined;
54
54
  } | undefined;
55
- readonly emailConfig?: IdPEmailConfig;
55
+ readonly emailConfig?: import("@tailor-platform/sdk").IdPEmailConfig;
56
56
  readonly clients: TClients;
57
57
  readonly permission?: IdPPermission;
58
58
  } & IdpDefinitionBrand;
@@ -3,8 +3,8 @@ import { InferFieldsOutput, output } from "../../../types/helpers.mjs";
3
3
  import { MachineUserName } from "../auth/types.mjs";
4
4
  import { ResolverInput } from "../../../types/resolver.generated.mjs";
5
5
  import { ResolverPermission } from "./permission.mjs";
6
- import { TailorAnyField, TailorField } from "../../types/type.mjs";
7
6
  import "../../types/machine-user.mjs";
7
+ import { TailorAnyField, TailorField } from "../../types/type.mjs";
8
8
  //#region src/configure/services/resolver/resolver.d.ts
9
9
  type Context<Input extends Record<string, TailorAnyField> | undefined> = {
10
10
  input: Input extends Record<string, TailorAnyField> ? InferFieldsOutput<Input> : never;
@@ -1,10 +1,10 @@
1
1
  import { FieldOptions, FieldOutput, FieldValidateInput, TailorFieldType, TailorToTs } from "../../types/field.types.mjs";
2
2
  import { InferredAttributes } from "../../../runtime/types.mjs";
3
- import { InferFieldsOutput, TypeLevelError, output } from "../../../types/helpers.mjs";
3
+ import { InferFieldsOutput, IsUnion, TypeLevelError, UnionToIntersection, output } from "../../../types/helpers.mjs";
4
4
  import { DBFieldMetadata, DefinedDBFieldMetadata, ExcludeDefaultedDBFields, ExcludeHookedDBFields, ExcludeNestedDBFields, Hook, IndexDef, RelationType, SerialConfig, TailorDBField as TailorDBField$1, TailorDBType as TailorDBType$1, TypeFeatures, TypeHook, TypeValidateFn, UpdateHookFn } from "./types.mjs";
5
5
  import { AllowedValues, AllowedValuesOutput } from "../../types/field.mjs";
6
6
  import { FieldParseArgs } from "../../../runtime/field-parse.mjs";
7
- import { PluginConfigs } from "../../../plugin/types.mjs";
7
+ import { PluginConfigs, PluginFieldExtensions } from "../../../plugin/types.mjs";
8
8
  import { TailorTypeGqlPermission, TailorTypePermission } from "./permission.mjs";
9
9
  import { StandardSchemaV1 } from "@standard-schema/spec";
10
10
  //#region src/configure/services/tailordb/schema.d.ts
@@ -123,6 +123,15 @@ type WithDBTypeMetadata<Defined extends DefinedDBTypeMetadata, Key extends keyof
123
123
  type DBTypeDuplicateInputGuard<Defined extends DefinedDBTypeMetadata, Key extends keyof DefinedDBTypeMetadata, Input, Message extends string> = IsAny<Defined> extends true ? Input : Defined extends Record<Key, unknown> ? TypeLevelError<Message> : Input;
124
124
  type DBTypeDuplicateRestGuard<Defined extends DefinedDBTypeMetadata, Key extends keyof DefinedDBTypeMetadata, Input extends unknown[], Message extends string> = IsAny<Defined> extends true ? Input : Defined extends Record<Key, unknown> ? [TypeLevelError<Message>, ...TypeLevelError<Message>[]] : Input;
125
125
  type FileKeyConflictError<Fields extends Record<string, TailorAnyDBField>, User extends object> = Partial<Record<keyof output<TailorDBType<Fields, User>> & string, TypeLevelError<"file keys cannot use existing field names">>>;
126
+ type PluginFieldExtensionFor<Fields extends Record<string, TailorAnyDBField>, Id extends string, IdConfig> = Id extends keyof PluginFieldExtensions<keyof Fields & string, IdConfig> ? PluginFieldExtensions<keyof Fields & string, IdConfig>[Id] : Record<never, never>;
127
+ type PluginFieldExtensionsUnion<Fields extends Record<string, TailorAnyDBField>, Config extends Record<string, unknown>> = { [Id in keyof Config & string]: PluginFieldExtensionFor<Fields, Id, Config[Id]>; }[keyof Config & string];
128
+ type AllExtensionKeys<Ext> = Ext extends unknown ? keyof Ext : never;
129
+ type PluginFieldExtensionShapeError<Fields extends Record<string, TailorAnyDBField>, Config extends Record<string, unknown>, Id extends string> = PluginFieldExtensionFor<Fields, Id, Config[Id & keyof Config]> extends Record<string, TailorAnyDBField> ? false : true;
130
+ type PluginFieldConflict<Fields extends Record<string, TailorAnyDBField>, Config extends Record<string, unknown>, Id extends string, FileKeys extends string> = [AllExtensionKeys<PluginFieldExtensionFor<Fields, Id, Config[Id & keyof Config]>> & (keyof Fields | FileKeys | AllExtensionKeys<PluginFieldExtensionsUnion<Fields, Omit<Config, Id>>>)] extends [never] ? false : true;
131
+ type PluginConfigExcessProps<Fields extends Record<string, TailorAnyDBField>, Config extends Record<string, unknown>, Id extends string> = Record<Exclude<keyof Config[Id & keyof Config], keyof PluginConfigs<keyof Fields & string>[Id & keyof PluginConfigs<keyof Fields & string>]>, never>;
132
+ type PluginExtendedFields<Fields extends Record<string, TailorAnyDBField>, Config extends Record<string, unknown>> = IsAny<Fields> extends true ? Fields // For `Config = {}`, PluginFieldExtensionsUnion is `never`, and
133
+ : Fields & UnionToIntersection<PluginFieldExtensionsUnion<Fields, Config>>;
134
+ type PluginConfigGuard<Fields extends Record<string, TailorAnyDBField>, Config extends Record<string, unknown>, FileKeys extends string> = IsAny<Fields> extends true ? unknown : { [K in keyof Config]: K extends keyof PluginConfigs<keyof Fields & string> ? IsUnion<Config[K]> extends true ? TypeLevelError<"plugin config must be a single object literal, not a union — assign the config to a variable first if it comes from a conditional expression"> : PluginFieldExtensionShapeError<Fields, Config, K & string> extends true ? TypeLevelError<"PluginFieldExtensions entry must be a Record<string, TailorAnyDBField>"> : PluginFieldConflict<Fields, Config, K & string, FileKeys> extends true ? TypeLevelError<"plugin field extension conflicts with an existing field, a file key declared via .files(), or another plugin's field"> : PluginConfigs<keyof Fields & string>[K] & PluginConfigExcessProps<Fields, Config, K & string> : TypeLevelError<"unknown plugin id">; };
126
135
  type DBFieldDescriptionFn<Defined extends DefinedDBFieldMetadata, Output, Nested extends Record<string, TailorAnyDBField>> = (description: string) => TailorDBField<WithDBFieldDescription<Defined>, Output, Nested>;
127
136
  type DBFieldRelationFn<Defined extends DefinedDBFieldMetadata, Output, Nested extends Record<string, TailorAnyDBField>> = {
128
137
  <S extends RelationType, T extends TailorAnyDBType>(config: RelationConfig<S, T>): TailorDBField<WithDBFieldRelation<Defined, S>, Output, Nested>;
@@ -258,22 +267,22 @@ interface TailorDBField<Defined extends DefinedDBFieldMetadata = DefinedDBFieldM
258
267
  * Full TailorDBType interface with builder methods.
259
268
  * Extends the minimal structural interface from types/ with fluent API methods.
260
269
  */
261
- interface TailorDBType<Fields extends Record<string, TailorAnyDBField> = any, User extends object = InferredAttributes, Defined extends DefinedDBTypeMetadata = any> extends TailorDBType$1<Fields, User> {
270
+ interface TailorDBType<Fields extends Record<string, TailorAnyDBField> = any, User extends object = InferredAttributes, Defined extends DefinedDBTypeMetadata = any, FileKeys extends string = never> extends TailorDBType$1<Fields, User> {
262
271
  _description?: string;
263
- hooks(hook: DBTypeDuplicateInputGuard<Defined, "hooks", TypeHook<Fields>, ".hooks() has already been set">): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, "hooks">>;
264
- validate(fn: DBTypeDuplicateInputGuard<Defined, "validate", TypeValidateFn<Fields>, ".validate() has already been set">): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, "validate">>;
265
- features(features: DBTypeDuplicateInputGuard<Defined, "features", Omit<TypeFeatures, "pluralForm">, ".features() has already been set">): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, "features">>;
266
- indexes(...indexes: DBTypeDuplicateRestGuard<Defined, "indexes", IndexDef<TailorDBType<Fields, User, Defined>>[], ".indexes() has already been set">): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, "indexes">>;
267
- files<const F extends string>(files: DBTypeDuplicateInputGuard<Defined, "files", Record<F, string> & FileKeyConflictError<Fields, User>, ".files() has already been set">): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, "files">>;
268
- permission<U extends object = User, P extends TailorTypePermission<U, output<TailorDBType<Fields, User, Defined>>> = TailorTypePermission<U, output<TailorDBType<Fields, User, Defined>>>>(permission: DBTypeDuplicateInputGuard<Defined, "permission", P, ".permission() has already been set">): TailorDBType<Fields, U, WithDBTypeMetadata<Defined, "permission">>;
269
- gqlPermission<U extends object = User, P extends TailorTypeGqlPermission<U> = TailorTypeGqlPermission<U>>(permission: DBTypeDuplicateInputGuard<Defined, "gqlPermission", P, ".gqlPermission() has already been set">): TailorDBType<Fields, U, WithDBTypeMetadata<Defined, "gqlPermission">>;
270
- description(description: DBTypeDuplicateInputGuard<Defined, "description", string, ".description() has already been set">): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, "description">>;
272
+ hooks(hook: DBTypeDuplicateInputGuard<Defined, "hooks", TypeHook<Fields>, ".hooks() has already been set">): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, "hooks">, FileKeys>;
273
+ validate(fn: DBTypeDuplicateInputGuard<Defined, "validate", TypeValidateFn<Fields>, ".validate() has already been set">): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, "validate">, FileKeys>;
274
+ features(features: DBTypeDuplicateInputGuard<Defined, "features", Omit<TypeFeatures, "pluralForm">, ".features() has already been set">): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, "features">, FileKeys>;
275
+ indexes(...indexes: DBTypeDuplicateRestGuard<Defined, "indexes", IndexDef<TailorDBType<Fields, User, Defined, FileKeys>>[], ".indexes() has already been set">): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, "indexes">, FileKeys>;
276
+ files<const F extends string>(files: DBTypeDuplicateInputGuard<Defined, "files", Record<F, string> & FileKeyConflictError<Fields, User>, ".files() has already been set">): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, "files">, FileKeys | F>;
277
+ permission<U extends object = User, P extends TailorTypePermission<U, output<TailorDBType<Fields, User, Defined>>> = TailorTypePermission<U, output<TailorDBType<Fields, User, Defined>>>>(permission: DBTypeDuplicateInputGuard<Defined, "permission", P, ".permission() has already been set">): TailorDBType<Fields, U, WithDBTypeMetadata<Defined, "permission">, FileKeys>;
278
+ gqlPermission<U extends object = User, P extends TailorTypeGqlPermission<U> = TailorTypeGqlPermission<U>>(permission: DBTypeDuplicateInputGuard<Defined, "gqlPermission", P, ".gqlPermission() has already been set">): TailorDBType<Fields, U, WithDBTypeMetadata<Defined, "gqlPermission">, FileKeys>;
279
+ description(description: DBTypeDuplicateInputGuard<Defined, "description", string, ".description() has already been set">): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, "description">, FileKeys>;
271
280
  pickFields<K extends keyof Fields>(keys: K[]): Pick<Fields, K>;
272
281
  pickFields<K extends keyof Fields, const Opt extends FieldOptions>(keys: K[], options: Opt & DBFieldsCloneOptionsGuard<Fields, K, Opt>): { [P in K]: Fields[P] extends TailorDBField<infer D, infer O> ? TailorDBField<WithDBFieldCloneOptions<D, Opt>, DBFieldCloneOutput<O, Opt>> : never; };
273
282
  omitFields<K extends keyof Fields>(keys: K[]): Omit<Fields, K>;
274
- plugin<P extends keyof PluginConfigs<keyof Fields & string>>(config: { [K in P]: PluginConfigs<keyof Fields & string>[K]; }): TailorDBType<Fields, User, Defined>;
283
+ plugin<const Config extends Record<string, unknown>>(config: Config & PluginConfigGuard<Fields, Config, FileKeys>): TailorDBType<PluginExtendedFields<Fields, Config>, User, Defined, FileKeys>;
275
284
  }
276
- type TailorDBInstance<Fields extends Record<string, TailorAnyDBField> = any, User extends object = InferredAttributes, Defined extends DefinedDBTypeMetadata = any> = TailorDBType<Fields, User, Defined>;
285
+ type TailorDBInstance<Fields extends Record<string, TailorAnyDBField> = any, User extends object = InferredAttributes, Defined extends DefinedDBTypeMetadata = any, FileKeys extends string = never> = TailorDBType<Fields, User, Defined, FileKeys>;
277
286
  interface RelationConfig<S extends RelationType, T extends TailorDBType> {
278
287
  type: S;
279
288
  toward: {
@@ -1,5 +1,5 @@
1
1
  import { MachineUserName, MachineUserNameRegistry } from "../services/auth/types.mjs";
2
2
  import { AllowedValues, AllowedValuesOutput } from "./field.mjs";
3
- import { TailorAnyField, TailorField } from "./type.mjs";
4
3
  import "./machine-user.mjs";
4
+ import { TailorAnyField, TailorField } from "./type.mjs";
5
5
  export { AllowedValues, AllowedValuesOutput, type MachineUserName, type MachineUserNameRegistry, TailorAnyField, TailorField };
@@ -1 +1 @@
1
- import{n as e,t}from"../../../seed-DwqRFdqP.mjs";export{t as SeedGeneratorID,e as seedPlugin};
1
+ import{n as e,t}from"../../../seed-CMkupmX8.mjs";export{t as SeedGeneratorID,e as seedPlugin};
@@ -119,6 +119,15 @@ type TableConfigRequired<PluginConfig = unknown> = boolean | ((pluginConfig: Plu
119
119
  * Extend this interface via declaration merging to add typed plugin configs.
120
120
  */
121
121
  interface PluginConfigs<Fields extends string = string> {}
122
+ /**
123
+ * Registry mapping a plugin's `id` literal to the fields it injects into the
124
+ * attached table's static type, computed from the literal per-call config
125
+ * passed to `.plugin()`. Extend this interface via declaration merging, keyed
126
+ * by the same `id` used in {@link PluginConfigs}. The value must be a
127
+ * `Record<string, TailorAnyDBField>` of the fields to add — it is merged
128
+ * into the table's existing fields, not a replacement for them.
129
+ */
130
+ interface PluginFieldExtensions<Fields extends string = string, Config = unknown> {}
122
131
  /**
123
132
  * Registry mapping a plugin's `id` literal to its plugin-level config type.
124
133
  * Extend via declaration merging, keyed by the `id` string, from the
@@ -216,34 +225,35 @@ interface PluginGeneratedExecutorLegacy {
216
225
  operation: PluginOperationConfig;
217
226
  }
218
227
  type PluginGeneratedExecutor = PluginGeneratedExecutorWithFile | PluginGeneratedExecutorLegacy;
219
- interface PluginExtends {
220
- fields?: Record<string, TailorAnyDBField>;
228
+ interface PluginExtends<FieldExtension extends Record<string, TailorAnyDBField>> {
229
+ fields?: FieldExtension;
221
230
  }
222
231
  interface PluginOutput {
223
232
  tables?: PluginGeneratedTables;
224
233
  resolvers?: PluginGeneratedResolver[];
225
234
  executors?: PluginGeneratedExecutor[];
226
235
  }
227
- interface TablePluginOutput extends PluginOutput {
228
- extends?: PluginExtends;
236
+ interface TablePluginOutput<FieldExtension extends Record<string, TailorAnyDBField> = Record<string, TailorAnyDBField>> extends PluginOutput {
237
+ extends?: PluginExtends<FieldExtension>;
229
238
  }
230
239
  type NamespacePluginOutput = PluginOutput;
231
240
  /**
232
241
  * Plugin interface that all plugins must implement.
233
242
  * @template TableConfig - Type for per-table configuration passed via .plugin() method
234
243
  * @template PluginConfig - Type for plugin-level configuration passed via definePlugins()
244
+ * @template FieldExtension - Type of the fields injected into the attached table via `extends.fields`. Should match the corresponding {@link PluginFieldExtensions} entry.
235
245
  */
236
- interface Plugin<TableConfig = unknown, PluginConfig = unknown> {
246
+ interface Plugin<TableConfig = unknown, PluginConfig = unknown, FieldExtension extends Record<string, TailorAnyDBField> = Record<string, TailorAnyDBField>> {
237
247
  readonly id: string;
238
248
  readonly description: string;
239
249
  readonly importPath?: string;
240
250
  readonly tableConfigRequired?: TableConfigRequired<PluginConfig>;
241
251
  readonly pluginConfig?: PluginConfig;
242
- onTableLoaded?(context: PluginTableProcessContext<TableConfig, PluginConfig>): TablePluginOutput | Promise<TablePluginOutput>;
252
+ onTableLoaded?(context: PluginTableProcessContext<TableConfig, PluginConfig>): TablePluginOutput<FieldExtension> | Promise<TablePluginOutput<FieldExtension>>;
243
253
  onNamespaceLoaded?(context: PluginNamespaceProcessContext<PluginConfig>): NamespacePluginOutput | Promise<NamespacePluginOutput>;
244
254
  onTailorDBReady?(context: TailorDBReadyContext<PluginConfig>): GeneratorResult | Promise<GeneratorResult>;
245
255
  onResolverReady?(context: ResolverReadyContext<PluginConfig>): GeneratorResult | Promise<GeneratorResult>;
246
256
  onExecutorReady?(context: ExecutorReadyContext<PluginConfig>): GeneratorResult | Promise<GeneratorResult>;
247
257
  }
248
258
  //#endregion
249
- export { ExecutorReadyContext, GeneratorAuthInput, GeneratorResult, NamespacePluginOutput, Plugin, type PluginAttachment, PluginConfigRegistry, PluginConfigs, PluginExecutorContext, PluginExecutorContextBase, PluginGeneratedExecutor, PluginGeneratedExecutorLegacy, PluginGeneratedExecutorWithFile, PluginGeneratedResolver, PluginGeneratedTable, PluginInjectMap, PluginNamespaceProcessContext, PluginOperationConfig, PluginOutput, PluginTableProcessContext, PluginTriggerConfig, ResolverNamespaceData, ResolverReadyContext, TableConfigRequired, TablePluginOutput, TailorDBNamespaceData, TailorDBReadyContext, TailorDBTableForPlugin };
259
+ export { ExecutorReadyContext, GeneratorAuthInput, GeneratorResult, NamespacePluginOutput, Plugin, type PluginAttachment, PluginConfigRegistry, PluginConfigs, PluginExecutorContext, PluginExecutorContextBase, PluginFieldExtensions, PluginGeneratedExecutor, PluginGeneratedExecutorLegacy, PluginGeneratedExecutorWithFile, PluginGeneratedResolver, PluginGeneratedTable, PluginInjectMap, PluginNamespaceProcessContext, PluginOperationConfig, PluginOutput, PluginTableProcessContext, PluginTriggerConfig, ResolverNamespaceData, ResolverReadyContext, TableConfigRequired, TablePluginOutput, TailorDBNamespaceData, TailorDBReadyContext, TailorDBTableForPlugin };