@tailor-platform/sdk 2.18.0 → 2.19.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.
- package/CHANGELOG.md +14 -0
- package/dist/{application-DEkgf2w1.mjs → application-BYlhYQyh.mjs} +2 -2
- package/dist/{application-DEkgf2w1.mjs.map → application-BYlhYQyh.mjs.map} +1 -1
- package/dist/application-KZRJHv2j.mjs +1 -0
- package/dist/cli/commands/deploy/event-subscriptions.d.mts +1 -0
- package/dist/cli/commands/generate/service.d.mts +1 -0
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/main.mjs +3 -3
- package/dist/cli/services/executor/service.d.mts +1 -0
- package/dist/completion/zsh-worker.zsh +1 -1
- package/dist/configure/index.d.mts +7 -7
- package/dist/configure/index.mjs +1 -1
- package/dist/configure/index.mjs.map +1 -1
- package/dist/configure/types/field.types.d.mts +24 -4
- package/dist/configure/types/type.d.mts +1 -0
- package/dist/date-B7-oyTGE.mjs +2 -0
- package/dist/date-B7-oyTGE.mjs.map +1 -0
- package/dist/field-parse-BbNyotv5.mjs +2 -0
- package/dist/field-parse-BbNyotv5.mjs.map +1 -0
- package/dist/{manager-C26Gi1bX.mjs → manager-qfbUL7ru.mjs} +2 -2
- package/dist/{manager-C26Gi1bX.mjs.map → manager-qfbUL7ru.mjs.map} +1 -1
- package/dist/parser/service/auth/schema.d.mts +1 -0
- package/dist/plugin/index.mjs +1 -1
- package/dist/{register-ts-hook-BD3ArLqY.mjs → register-ts-hook-Djjnj5R8.mjs} +3 -3
- package/dist/{register-ts-hook-BD3ArLqY.mjs.map → register-ts-hook-Djjnj5R8.mjs.map} +1 -1
- package/dist/runtime/date.d.mts +3 -3
- package/dist/runtime/field-parse.d.mts +1 -0
- package/dist/runtime/index.d.mts +2 -1
- package/dist/runtime/index.mjs +1 -1
- package/dist/runtime/temporal.d.mts +31 -0
- package/dist/{schema-DRyQEabV.mjs → schema-BKvcWdVf.mjs} +2 -2
- package/dist/{schema-DRyQEabV.mjs.map → schema-BKvcWdVf.mjs.map} +1 -1
- package/dist/service-BgrEteZ2.mjs +1 -0
- package/dist/service-CuqkHP1r.mjs +7 -0
- package/dist/service-CuqkHP1r.mjs.map +1 -0
- package/dist/types/field.generated.d.mts +1 -1
- package/dist/types/helpers.d.mts +8 -6
- package/dist/utils/test/index.mjs +1 -1
- package/dist/vitest/environment.mjs +1 -1
- package/dist/vitest/environment.mjs.map +1 -1
- package/docs/github-actions.md +22 -15
- package/docs/migration/v3.md +0 -33
- package/docs/services/resolver.md +53 -1
- package/docs/testing.md +17 -0
- package/package.json +5 -3
- package/dist/application-Dl94fzpm.mjs +0 -1
- package/dist/date-CGBZbMW5.mjs +0 -2
- package/dist/date-CGBZbMW5.mjs.map +0 -1
- package/dist/field-parse-CzlKC4b7.mjs +0 -2
- package/dist/field-parse-CzlKC4b7.mjs.map +0 -1
- package/dist/service-B3OiWCYg.mjs +0 -1
- package/dist/service-eM7Fd8zS.mjs +0 -7
- package/dist/service-eM7Fd8zS.mjs.map +0 -1
package/dist/runtime/date.d.mts
CHANGED
|
@@ -6,10 +6,10 @@ type DateField = {
|
|
|
6
6
|
readonly fields: Record<string, DateField>;
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
|
-
* Convert fields using
|
|
10
|
-
* @param field -
|
|
9
|
+
* Convert fields using Date or Temporal representations to date, datetime, or time strings.
|
|
10
|
+
* @param field - Field defining the value's shape
|
|
11
11
|
* @param value - Value to serialize
|
|
12
|
-
* @returns Value with Date fields converted to strings
|
|
12
|
+
* @returns Value with Date and Temporal fields converted to strings
|
|
13
13
|
* @internal
|
|
14
14
|
*/
|
|
15
15
|
export declare function serializeDateFields(field: DateField, value: unknown): unknown;
|
package/dist/runtime/index.d.mts
CHANGED
|
@@ -7,6 +7,7 @@ import { TailorIconvAPI, iconv } from "./iconv.mjs";
|
|
|
7
7
|
import { TailorIdpAPI, idp } from "./idp.mjs";
|
|
8
8
|
import { TailorLoggerAPI, logger } from "./logger.mjs";
|
|
9
9
|
import { TailorSecretmanagerAPI, secretmanager } from "./secretmanager.mjs";
|
|
10
|
+
import { Temporal } from "./temporal.mjs";
|
|
10
11
|
import { serializeDateFields } from "./date.mjs";
|
|
11
12
|
//#region src/runtime/index.d.ts
|
|
12
13
|
/** SQL command type recorded on a {@link TailordbQueryResult}. */
|
|
@@ -46,4 +47,4 @@ export interface TailordbRuntime {
|
|
|
46
47
|
file: TailorDBFileAPI;
|
|
47
48
|
}
|
|
48
49
|
//#endregion
|
|
49
|
-
export { aigateway, authconnection, context, file, iconv, idp, logger, secretmanager, serializeDateFields, workflow };
|
|
50
|
+
export { Temporal, aigateway, authconnection, context, file, iconv, idp, logger, secretmanager, serializeDateFields, workflow };
|
package/dist/runtime/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{n as e}from"../date-
|
|
1
|
+
import{n as e,r as t}from"../date-B7-oyTGE.mjs";import{t as n}from"../iconv-DlFMt2gW.mjs";import{t as r}from"../secretmanager-vHQoXdQz.mjs";import{t as i}from"../authconnection-CynFBIv8.mjs";import{t as a}from"../idp-G_ojPBB5.mjs";import{t as o}from"../workflow-Cs9ISw6j.mjs";import{t as s}from"../context-D0QjfxzD.mjs";import{t as c}from"../file-DKBOj5q4.mjs";import{t as l}from"../aigateway-DsWDjzk4.mjs";import{i as u}from"../logger-DP2BjQ93.mjs";export{t as Temporal,l as aigateway,i as authconnection,s as context,c as file,n as iconv,a as idp,u as logger,r as secretmanager,e as serializeDateFields,o as workflow};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Temporal } from "temporal-spec";
|
|
2
|
+
//#region src/runtime/temporal.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Typed access to the runtime's Temporal API, without installing a polyfill.
|
|
5
|
+
* Constructors are resolved on access so configuration files can load in Node.js.
|
|
6
|
+
* @example
|
|
7
|
+
* import { Temporal } from "@tailor-platform/sdk/runtime";
|
|
8
|
+
* const tomorrow: Temporal.PlainDate = Temporal.Now.plainDateISO().add({ days: 1 });
|
|
9
|
+
*/
|
|
10
|
+
declare const Temporal$1: typeof Temporal;
|
|
11
|
+
/** Temporal instance types supplied by the SDK, independent of TypeScript's lib settings. */
|
|
12
|
+
declare namespace Temporal$1 {
|
|
13
|
+
/** The runtime Temporal.PlainDate instance. */
|
|
14
|
+
type PlainDate = Temporal.PlainDate;
|
|
15
|
+
/** The runtime Temporal.PlainTime instance. */
|
|
16
|
+
type PlainTime = Temporal.PlainTime;
|
|
17
|
+
/** The runtime Temporal.PlainDateTime instance. */
|
|
18
|
+
type PlainDateTime = Temporal.PlainDateTime;
|
|
19
|
+
/** The runtime Temporal.PlainYearMonth instance. */
|
|
20
|
+
type PlainYearMonth = Temporal.PlainYearMonth;
|
|
21
|
+
/** The runtime Temporal.PlainMonthDay instance. */
|
|
22
|
+
type PlainMonthDay = Temporal.PlainMonthDay;
|
|
23
|
+
/** The runtime Temporal.ZonedDateTime instance. */
|
|
24
|
+
type ZonedDateTime = Temporal.ZonedDateTime;
|
|
25
|
+
/** The runtime Temporal.Duration instance. */
|
|
26
|
+
type Duration = Temporal.Duration;
|
|
27
|
+
/** The runtime Temporal.Instant instance. */
|
|
28
|
+
type Instant = Temporal.Instant;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { Temporal$1 as Temporal };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{r as e}from"./field-parse-
|
|
2
|
-
//# sourceMappingURL=schema-
|
|
1
|
+
import{r as e}from"./field-parse-BbNyotv5.mjs";import{t}from"./brand-C8nMKhJC.mjs";import{cloneDeep as n}from"es-toolkit";function mapAllowedValues(e){return e.map(e=>typeof e==`string`?{value:e,description:``}:{...e,description:e.description??``})}function createTailorDBField(e,t,n,r){return createTailorDBFieldRuntime(e,t,n,r)}function createTailorDBFieldRuntime(t,r,i,a){let o={required:!0},s;r&&(r.optional===!0&&(o.required=!1),r.array===!0&&(o.array=!0)),a&&(o.allowedValues=mapAllowedValues(a));function parseInternal$1(t){return e({...t,field:c})}function cloneWith(e){let t=c.clone();return Object.assign(t._metadata,e),t}let c={type:t,fields:i??{},_defined:void 0,_output:void 0,_metadata:o,get metadata(){return{...this._metadata}},get rawRelation(){return s?{...s,toward:{...s.toward}}:void 0},description(e){return cloneWith({description:e})},typeName(e){return cloneWith({typeName:e})},validate(...e){return cloneWith({validate:e})},parse(e){return parseInternal$1({value:e.value,data:e.data,invoker:e.invoker,pathArray:[]})},relation(e){let t=c.clone(),n=e.toward,r=`table`in n?n.table:n.type,i=r===`self`?`self`:r.name;return t._setRawRelation({type:e.type,toward:{table:i,as:e.toward.as,key:e.toward.key},backward:e.backward}),t},index(){return cloneWith({index:!0})},unique(){return cloneWith({unique:!0,index:!0})},vector(){return cloneWith({vector:!0})},default(e){return cloneWith({default:e})},hooks(e){return cloneWith({hooks:e})},serial(e){return cloneWith({serial:e})},clone(e){if(this._metadata.validate?.length&&e?.array!==void 0&&e.array!==(this._metadata.array===!0))throw Error(`Cannot change the array option on a field with custom validation`);let o=i;if(i){let e={};for(let[t,n]of Object.entries(i))e[t]=n.clone();o=e}let c=createTailorDBFieldRuntime(t,r,o,a);return Object.assign(c._metadata,n(this._metadata)),e&&(e.optional!==void 0&&(c._metadata.required=!e.optional),e.array!==void 0&&(c._metadata.array=e.array)),s&&c._setRawRelation(n(s)),c},_setRawRelation(e){s=e}};return c}const r=createTailorDBField;function uuid(e){return r(`uuid`,e)}function string(e){return r(`string`,e)}function bool(e){return r(`boolean`,e)}function int(e){return r(`integer`,e)}function float(e){return r(`float`,e)}function decimal(e){if(e?.scale!==void 0&&(!Number.isInteger(e.scale)||e.scale<0||e.scale>12))throw Error(`scale must be an integer between 0 and 12`);let t=r(`decimal`,e);return e?.scale!==void 0&&(t._metadata.scale=e.scale),t}function date(e){return r(`date`,e)}function datetime(e){return r(`datetime`,e)}function time(e){return r(`time`,e)}function _enum(e,t){return r(`enum`,t,void 0,e)}function object(e,t){return r(`nested`,t,e)}function createTailorDBType(e,n,r){let i=r.description,a={},o=[],s={},c={},l=[],u,d,f=new Set;r.description!==void 0&&f.add(`description`);function runMethodOnce(e,t){if(f.has(e))throw Error(`.${e}() has already been set`);let n=t();return f.add(e),n}if(r.pluralForm){if(e===r.pluralForm)throw Error(`The name and the plural form must be different. name=${e}`);a.pluralForm=r.pluralForm}let p={name:e,fields:{...n},_output:null,_description:i,get metadata(){let e={};return o.length>0&&o.forEach(t=>{let n=t.fields.map(e=>String(e)),r=t.name||`idx_${n.join(`_`)}`;e[r]={fields:n,unique:t.unique}}),{name:this.name,description:i,settings:a,permissions:s,files:c,...Object.keys(e).length>0&&{indexes:e},...u&&{typeHook:u},...d&&{typeValidate:d}}},hooks(e){return runMethodOnce(`hooks`,()=>(u=e,this))},validate(e){return runMethodOnce(`validate`,()=>(d=e,this))},features(e){return runMethodOnce(`features`,()=>(a={...a,...e},this))},indexes(...e){return runMethodOnce(`indexes`,()=>(o=e,this))},files(e){return runMethodOnce(`files`,()=>(c=e,this))},permission(e){return runMethodOnce(`permission`,()=>{let t=this;return s.record=e,t})},gqlPermission(e){return runMethodOnce(`gqlPermission`,()=>{let t=this;return s.gql=e,t})},description(e){return runMethodOnce(`description`,()=>(i=e,this._description=e,this))},pickFields(e,t){let n={};for(let r of e){let e=this.fields[r];if(!e)throw Error(`pickFields(): field "${String(r)}" does not exist on this table yet. If it comes from a plugin's .plugin() call, it is only added to the table after \`tailor generate\` runs.`);n[r]=t?e.clone(t):e}return n},omitFields(e){let t=new Set(e),n={};for(let e in this.fields)Object.hasOwn(this.fields,e)&&!t.has(e)&&(n[e]=this.fields[e]);return n},get plugins(){return l},plugin(e){for(let[t,n]of Object.entries(e))l.push({pluginId:t,config:n});return this}};return t(p,`tailordb-type`)}const i=uuid();function dbTable(e,t,n){let r=Array.isArray(e)?e[0]:e,a=Array.isArray(e)?e[1]:void 0,o,s;return typeof t==`string`?(o=t,s=n):s=t,createTailorDBType(r,{id:i,...s},{pluralForm:a,description:o})}const timestampsUpdatedAtHook=({input:e,now:t})=>e??t,a=Symbol.for(`tailor-platform/sdk:precompiled-script-expr`);timestampsUpdatedAtHook[a]={"hooks.update":`(({ input, now }) => input ?? now)({ input: _value, oldValue: _oldValue, invoker: _principal, now: _now })`};const o={table:dbTable,uuid,string,bool,int,float,decimal,date,datetime,time,enum:_enum,object,fields:{timestamps:()=>({createdAt:datetime().default(`now`).description(`Record creation timestamp`),updatedAt:datetime().default(`now`).hooks({update:timestampsUpdatedAtHook}).description(`Record update timestamp`)})}};export{mapAllowedValues as n,o as t};
|
|
2
|
+
//# sourceMappingURL=schema-BKvcWdVf.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-DRyQEabV.mjs","names":["parseInternal","parseFieldInternal"],"sources":["../src/configure/types/field.ts","../src/configure/services/tailordb/schema.ts"],"sourcesContent":["import type { EnumValue } from \"#/configure/types/field.types\";\n\nexport type AllowedValues = readonly [string | EnumValue, ...(string | EnumValue)[]];\n\n/**\n * Normalize allowed values into EnumValue objects with descriptions.\n * @param values - Allowed values as strings or EnumValue objects\n * @returns Normalized allowed values\n */\nexport function mapAllowedValues(values: AllowedValues): EnumValue[] {\n return values.map((value) => {\n if (typeof value === \"string\") {\n return { value, description: \"\" };\n }\n return { ...value, description: value.description ?? \"\" };\n });\n}\n\nexport type AllowedValuesOutput<V extends AllowedValues> = V[number] extends infer T\n ? T extends string\n ? T\n : T extends { value: infer K }\n ? K\n : never\n : never;\n","import { cloneDeep } from \"es-toolkit\";\nimport {\n type AllowedValues,\n type AllowedValuesOutput,\n mapAllowedValues,\n} from \"#/configure/types/field\";\nimport {\n parseInternal as parseFieldInternal,\n type FieldParseArgs,\n type FieldParseInternalArgs,\n} from \"#/runtime/field-parse\";\nimport { brandValue } from \"#/utils/brand\";\nimport type {\n FieldOptions,\n FieldOutput,\n TailorFieldType,\n TailorToTs,\n FieldValidateInput,\n} from \"#/configure/types/field.types\";\nimport type {\n PrecompiledScriptExprKey,\n PrecompiledScriptExprMap,\n} from \"#/parser/service/tailordb/types\";\nimport type { PluginAttachment, PluginConfigs, PluginFieldExtensions } from \"#/plugin/types\";\nimport type { InferredAttributes } from \"#/runtime/types\";\nimport type {\n output,\n InferFieldsOutput,\n IsUnion,\n TypeLevelError,\n UnionToIntersection,\n} from \"#/types/helpers\";\nimport type { RawPermissions } from \"#/types/tailordb.generated\";\nimport type { TailorTypeGqlPermission, TailorTypePermission } from \"./permission\";\nimport type {\n TailorDBField as TailorDBFieldBase,\n TailorDBType as TailorDBTypeBase,\n DBFieldMetadata,\n DefinedDBFieldMetadata,\n SerialConfig,\n IndexDef,\n TailorDBTypeMetadata,\n RawRelationConfig,\n RelationType,\n Hook,\n TypeHook,\n UpdateHookFn,\n ExcludeNestedDBFields,\n ExcludeHookedDBFields,\n ExcludeDefaultedDBFields,\n TypeFeatures,\n TypeValidateFn,\n} from \"./types\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n// Erased DB fields stay assignable across builder method-state changes.\n// oxlint-disable-next-line no-explicit-any\ntype AnyBuilderMethod = any;\n\nexport type TailorAnyDBField = Omit<\n TailorDBFieldBase<AnyBuilderMethod, AnyBuilderMethod>,\n \"fields\"\n> & {\n readonly fields: Record<string, AnyBuilderMethod>;\n _metadata: DBFieldMetadata;\n parse: AnyBuilderMethod;\n readonly typeName: TypeLevelError<string>;\n description: AnyBuilderMethod;\n relation: AnyBuilderMethod;\n index: AnyBuilderMethod;\n unique: AnyBuilderMethod;\n vector: AnyBuilderMethod;\n default: AnyBuilderMethod;\n hooks: AnyBuilderMethod;\n validate: AnyBuilderMethod;\n serial: AnyBuilderMethod;\n clone: AnyBuilderMethod;\n};\n\n// Helper alias\n// oxlint-disable-next-line no-explicit-any\nexport type TailorAnyDBType = TailorDBType<any, any, any>;\n\ntype IsAny<T> = 0 extends 1 & T ? true : false;\ntype DBFieldTypeNameMethod<Defined extends DefinedDBFieldMetadata> =\n IsAny<Defined> extends true\n ? TypeLevelError<string>\n : TypeLevelError<\"typeName cannot be used on TailorDB fields\">;\n\ntype WithDBFieldDescription<Defined> = Defined & { description: true };\ntype WithDBFieldRelation<Defined, S extends RelationType | RelationSelfConfig> = S extends\n | \"oneToOne\"\n | \"1-1\"\n ? Defined & { unique: true; index: true; relation: true }\n : S extends { type: \"oneToOne\" | \"1-1\" }\n ? Defined & { unique: true; index: true; relation: true }\n : Defined & { index: true; relation: true };\ntype WithDBFieldIndex<Defined> = Defined & { index: true };\ntype WithDBFieldUnique<Defined> = Defined & { unique: true; index: true };\ntype WithDBFieldVector<Defined> = Defined & { vector: true };\ntype WithDBFieldHooks<Defined, H> = Defined & {\n hooks: {\n create: H extends { create: unknown } ? true : false;\n update: H extends { update: unknown } ? true : false;\n };\n serial: false;\n};\ntype WithDBFieldDefault<Defined> = Defined & { default: true };\ntype WithDBFieldValidate<Defined> = Defined & { validate: true };\ntype WithDBFieldSerial<Defined> = Defined & {\n serial: true;\n hooks: { create: false; update: false };\n};\ntype WithDBFieldCloneOptions<Defined extends DefinedDBFieldMetadata, NewOpt extends FieldOptions> =\n IsAny<Defined> extends true\n ? Defined\n : Omit<Defined, \"array\"> & {\n array: NewOpt extends { array: true }\n ? true\n : NewOpt extends { array: false }\n ? false\n : Defined[\"array\"];\n };\ntype NonNullableDBFieldOutput<Output> = Exclude<Output, null>;\ntype DBFieldScalarOutput<Output> =\n NonNullableDBFieldOutput<Output> extends (infer Item)[] ? Item : NonNullableDBFieldOutput<Output>;\ntype DBFieldCloneArrayOutput<Output, NewOpt extends FieldOptions> = NewOpt extends {\n array: true;\n}\n ? DBFieldScalarOutput<Output>[]\n : NewOpt extends { array: false }\n ? DBFieldScalarOutput<Output>\n : NonNullableDBFieldOutput<Output>;\ntype DBFieldCloneOutput<Output, NewOpt extends FieldOptions> = NewOpt extends { optional: true }\n ? DBFieldCloneArrayOutput<Output, NewOpt> | null\n : NewOpt extends { optional: false }\n ? DBFieldCloneArrayOutput<Output, NewOpt>\n : null extends Output\n ? DBFieldCloneArrayOutput<Output, NewOpt> | null\n : DBFieldCloneArrayOutput<Output, NewOpt>;\ntype DBFieldCloneOptions<Defined extends DefinedDBFieldMetadata> = Omit<FieldOptions, \"array\"> & {\n array?: Defined extends { validate: unknown } ? Defined[\"array\"] : boolean;\n};\ntype InvalidValidatedArrayCloneKeys<\n Fields extends Record<string, TailorAnyDBField>,\n K extends keyof Fields,\n Opt extends FieldOptions,\n> = Opt extends { array: infer ArrayOption }\n ? {\n [P in K]: Fields[P] extends TailorDBField<infer Defined, infer _Output>\n ? Defined extends { validate: unknown }\n ? ArrayOption extends Defined[\"array\"]\n ? never\n : P\n : never\n : never;\n }[K]\n : never;\ntype DBFieldsCloneOptionsGuard<\n Fields extends Record<string, TailorAnyDBField>,\n K extends keyof Fields,\n Opt extends FieldOptions,\n> = [InvalidValidatedArrayCloneKeys<Fields, K, Opt>] extends [never]\n ? unknown\n : TypeLevelError<\"array cannot be changed on fields with custom validation\">;\ntype DefinedDBTypeMetadata = {\n hooks?: true;\n validate?: true;\n features?: true;\n indexes?: true;\n files?: true;\n permission?: true;\n gqlPermission?: true;\n description?: true;\n};\ntype WithDBTypeMetadata<\n Defined extends DefinedDBTypeMetadata,\n Key extends keyof DefinedDBTypeMetadata,\n> = Defined & Record<Key, true>;\ntype DBTypeDuplicateInputGuard<\n Defined extends DefinedDBTypeMetadata,\n Key extends keyof DefinedDBTypeMetadata,\n Input,\n Message extends string,\n> =\n IsAny<Defined> extends true\n ? Input\n : Defined extends Record<Key, unknown>\n ? TypeLevelError<Message>\n : Input;\ntype DBTypeDuplicateRestGuard<\n Defined extends DefinedDBTypeMetadata,\n Key extends keyof DefinedDBTypeMetadata,\n Input extends unknown[],\n Message extends string,\n> =\n IsAny<Defined> extends true\n ? Input\n : Defined extends Record<Key, unknown>\n ? [TypeLevelError<Message>, ...TypeLevelError<Message>[]]\n : Input;\ntype FileKeyConflictError<\n Fields extends Record<string, TailorAnyDBField>,\n User extends object,\n> = Partial<\n Record<\n keyof output<TailorDBType<Fields, User>> & string,\n TypeLevelError<\"file keys cannot use existing field names\">\n >\n>;\n// A plugin id with no PluginFieldExtensions entry contributes no keys — using\n// Record<never, never> (rather than Record<string, never>) keeps its `keyof`\n// empty so it can't spuriously collide with every existing field.\ntype PluginFieldExtensionFor<\n Fields extends Record<string, TailorAnyDBField>,\n Id extends string,\n IdConfig,\n> = Id extends keyof PluginFieldExtensions<keyof Fields & string, IdConfig>\n ? PluginFieldExtensions<keyof Fields & string, IdConfig>[Id]\n : Record<never, never>;\ntype PluginFieldExtensionsUnion<\n Fields extends Record<string, TailorAnyDBField>,\n Config extends Record<string, unknown>,\n> = {\n [Id in keyof Config & string]: PluginFieldExtensionFor<Fields, Id, Config[Id]>;\n}[keyof Config & string];\ntype AllExtensionKeys<Ext> = Ext extends unknown ? keyof Ext : never;\n// True when plugin `Id` has a PluginFieldExtensions entry whose type does not\n// extend Record<string, TailorAnyDBField> — e.g. a plugin author registered\n// a non-record shape by mistake. Checked ahead of PluginFieldConflict, since\n// `keyof` on a non-record shape (e.g. `keyof string`) would otherwise produce\n// nonsense candidate keys for the collision check.\n// `Id extends string` (not `keyof Config & string`) deliberately: a mapped\n// type's key variable, used inside a nested conditional branch and then\n// intersected with `string`, does not structurally satisfy a `keyof Config &\n// string`-constrained type parameter under `skipLibCheck: false` (verified\n// against a standalone consumer — TS2344 on both call sites otherwise, even\n// for code that never calls .plugin()). `Config[Id & keyof Config]` recovers\n// the same indexed-access result without that constraint.\ntype PluginFieldExtensionShapeError<\n Fields extends Record<string, TailorAnyDBField>,\n Config extends Record<string, unknown>,\n Id extends string,\n> =\n PluginFieldExtensionFor<Fields, Id, Config[Id & keyof Config]> extends Record<\n string,\n TailorAnyDBField\n >\n ? false\n : true;\n// True when the fields plugin `Id` would inject collide with an existing\n// field, or with a field injected by another plugin id attached in the same\n// .plugin() call.\ntype PluginFieldConflict<\n Fields extends Record<string, TailorAnyDBField>,\n Config extends Record<string, unknown>,\n Id extends string,\n FileKeys extends string,\n> = [\n AllExtensionKeys<PluginFieldExtensionFor<Fields, Id, Config[Id & keyof Config]>> &\n (\n | keyof Fields\n | FileKeys\n | AllExtensionKeys<PluginFieldExtensionsUnion<Fields, Omit<Config, Id>>>\n ),\n] extends [never]\n ? false\n : true;\n// Rejects a property on the caller's config literal for plugin `Id` that\n// isn't part of its registered PluginConfigs shape. `Config` is captured by\n// a `const` type parameter from the argument itself, so intersecting the\n// success branch with `PluginConfigs<...>[Id]` alone would not trigger\n// TypeScript's excess-property check — that check only fires when an object\n// literal is validated directly against a target type, not after its shape\n// has already been inferred through a generic parameter.\ntype PluginConfigExcessProps<\n Fields extends Record<string, TailorAnyDBField>,\n Config extends Record<string, unknown>,\n Id extends string,\n> = Record<\n Exclude<\n keyof Config[Id & keyof Config],\n keyof PluginConfigs<keyof Fields & string>[Id & keyof PluginConfigs<keyof Fields & string>]\n >,\n never\n>;\ntype PluginExtendedFields<\n Fields extends Record<string, TailorAnyDBField>,\n Config extends Record<string, unknown>,\n> =\n IsAny<Fields> extends true\n ? Fields\n : // For `Config = {}`, PluginFieldExtensionsUnion is `never`, and\n // UnionToIntersection<never> is `unknown` (not `never`), so this\n // correctly reduces to `Fields` — see the \"empty config\" test.\n Fields & UnionToIntersection<PluginFieldExtensionsUnion<Fields, Config>>;\n// Validates each key of the passed config object against PluginConfigs and\n// flags field-extension conflicts (see PluginFieldConflict above), keeping\n// type errors localized to the offending plugin id instead of requiring\n// every registered plugin id to be present (as a `P extends keyof\n// PluginConfigs<...>` generic would need, defeating inference of which\n// plugin ids were actually passed).\ntype PluginConfigGuard<\n Fields extends Record<string, TailorAnyDBField>,\n Config extends Record<string, unknown>,\n FileKeys extends string,\n> =\n IsAny<Fields> extends true\n ? unknown\n : {\n [K in keyof Config]: K extends keyof PluginConfigs<keyof Fields & string>\n ? // A union config (e.g. from a ternary passed directly as a plugin's\n // value) distributes through PluginFieldExtensionFor's conditional\n // and silently collapses the injected field to `never` once\n // intersected back together — reject it here instead, before it\n // can produce that confusing downstream error.\n IsUnion<Config[K]> extends true\n ? 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\">\n : PluginFieldExtensionShapeError<Fields, Config, K & string> extends true\n ? TypeLevelError<\"PluginFieldExtensions entry must be a Record<string, TailorAnyDBField>\">\n : PluginFieldConflict<Fields, Config, K & string, FileKeys> extends true\n ? TypeLevelError<\"plugin field extension conflicts with an existing field, a file key declared via .files(), or another plugin's field\">\n : PluginConfigs<keyof Fields & string>[K] &\n PluginConfigExcessProps<Fields, Config, K & string>\n : TypeLevelError<\"unknown plugin id\">;\n };\ntype DBFieldDescriptionFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = (description: string) => TailorDBField<WithDBFieldDescription<Defined>, Output, Nested>;\ntype DBFieldRelationFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = {\n <S extends RelationType, T extends TailorAnyDBType>(\n config: RelationConfig<S, T>,\n ): TailorDBField<WithDBFieldRelation<Defined, S>, Output, Nested>;\n <S extends RelationSelfConfig>(\n config: S,\n ): TailorDBField<WithDBFieldRelation<Defined, S>, Output, Nested>;\n};\ntype DBFieldIndexFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = () => TailorDBField<WithDBFieldIndex<Defined>, Output, Nested>;\ntype DBFieldUniqueFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = () => TailorDBField<WithDBFieldUnique<Defined>, Output, Nested>;\ntype DBFieldVectorFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = () => TailorDBField<WithDBFieldVector<Defined>, Output, Nested>;\ntype DBFieldHooksFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = <\n const H extends Hook<\n Output,\n Defined extends { default: true } ? Output | null | undefined : Output\n >,\n>(\n hooks: H,\n) => TailorDBField<WithDBFieldHooks<Defined, H>, Output, Nested>;\ntype DBFieldValidateFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = (\n ...validate: FieldValidateInput<Output>[]\n) => TailorDBField<WithDBFieldValidate<Defined>, Output, Nested>;\ntype DBFieldSerialFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = (\n config: SerialConfig<Defined[\"type\"] & (\"integer\" | \"string\")>,\n) => TailorDBField<WithDBFieldSerial<Defined>, Output, Nested>;\ntype DBFieldDescriptionMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldDescriptionFn<Defined, Output, Nested>\n : Defined extends { description: unknown }\n ? TypeLevelError<\".description() has already been set\">\n : DBFieldDescriptionFn<Defined, Output, Nested>;\ntype DBFieldRelationMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldRelationFn<Defined, Output, Nested>\n : Defined extends { relation: unknown }\n ? TypeLevelError<\".relation() has already been set\">\n : DBFieldRelationFn<Defined, Output, Nested>;\ntype DBFieldArrayCheck<A extends boolean, Ok, Msg extends string> = A extends true\n ? TypeLevelError<Msg>\n : Ok;\ntype DBFieldIndexMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldIndexFn<Defined, Output, Nested>\n : Defined extends { index: unknown }\n ? TypeLevelError<\".index() has already been set\">\n : DBFieldArrayCheck<\n Defined[\"array\"],\n DBFieldIndexFn<Defined, Output, Nested>,\n \"index cannot be set on array fields\"\n >;\ntype DBFieldUniqueMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldUniqueFn<Defined, Output, Nested>\n : Defined extends { unique: unknown }\n ? TypeLevelError<\".unique() has already been set\">\n : DBFieldArrayCheck<\n Defined[\"array\"],\n DBFieldUniqueFn<Defined, Output, Nested>,\n \"unique cannot be set on array fields\"\n >;\ntype DBFieldVectorMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldVectorFn<Defined, Output, Nested>\n : Defined extends { vector: unknown }\n ? TypeLevelError<\".vector() has already been set\">\n : Defined extends { type: \"string\"; array: false }\n ? DBFieldVectorFn<Defined, Output, Nested>\n : TypeLevelError<\"vector can only be set on non-array string fields\">;\ntype DBFieldHooksMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldHooksFn<Defined, Output, Nested>\n : Defined extends {\n serial: true;\n hooks: { create: false; update: false };\n }\n ? TypeLevelError<\"hooks cannot be set after serial\">\n : Defined extends {\n hooks: unknown;\n }\n ? TypeLevelError<\".hooks() has already been set\">\n : Defined extends { type: \"nested\" }\n ? TypeLevelError<\"hooks cannot be set on nested type fields\">\n : DBFieldHooksFn<Defined, Output, Nested>;\ntype DBFieldValidateMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldValidateFn<Defined, Output, Nested>\n : Defined extends { validate: unknown }\n ? TypeLevelError<\".validate() has already been set\">\n : DBFieldValidateFn<Defined, Output, Nested>;\ntype DBFieldSerialMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldSerialFn<Defined, Output, Nested>\n : Defined extends { serial: true }\n ? TypeLevelError<\".serial() has already been set\">\n : Defined extends { serial: false }\n ? TypeLevelError<\"serial cannot be set after hooks\">\n : IsAny<Output> extends true\n ? Defined extends { type: \"integer\" | \"string\"; array: false }\n ? DBFieldSerialFn<Defined, Output, Nested>\n : TypeLevelError<\"serial can only be set on non-array integer or string fields\">\n : null extends Output\n ? TypeLevelError<\"serial can only be set on non-array integer or string fields\">\n : Defined extends { type: \"integer\" | \"string\"; array: false }\n ? DBFieldSerialFn<Defined, Output, Nested>\n : TypeLevelError<\"serial can only be set on non-array integer or string fields\">;\ntype DBFieldDefaultFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = (\n value: Output extends null ? NonNullable<Output> : Output,\n) => TailorDBField<WithDBFieldDefault<Defined>, Output, Nested>;\ntype DBFieldDefaultMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldDefaultFn<Defined, Output, Nested>\n : Defined extends { default: unknown }\n ? TypeLevelError<\".default() has already been set\">\n : Defined extends { type: \"nested\" }\n ? TypeLevelError<\"default cannot be set on nested type fields\">\n : Defined extends { serial: true }\n ? TypeLevelError<\"default cannot be set on serial fields\">\n : null extends Output\n ? TypeLevelError<\"default cannot be set on optional fields\">\n : DBFieldDefaultFn<Defined, Output, Nested>;\n\n/**\n * Full TailorDBField interface with builder methods.\n * Extends the minimal structural interface from types/ with fluent API methods.\n */\nexport interface TailorDBField<\n Defined extends DefinedDBFieldMetadata = DefinedDBFieldMetadata,\n // oxlint-disable-next-line no-explicit-any\n Output = any,\n // Nested object fields, so a `db.object()` field keeps the shape it was declared with.\n // Every builder method passes it through; dropping it here would erase the shape as\n // soon as one is chained.\n Nested extends Record<string, TailorAnyDBField> = Record<string, TailorAnyDBField>,\n> extends Omit<TailorDBFieldBase<Defined, Output, Nested>, \"fields\"> {\n readonly fields: Nested;\n _metadata: DBFieldMetadata;\n\n /**\n * Parse and validate a value against this field's validation rules\n */\n parse(args: FieldParseArgs): StandardSchemaV1.Result<Output>;\n\n /**\n * typeName is not available on TailorDB fields.\n * Use typeName on pipeline fields (t.enum / t.object) instead.\n */\n typeName: DBFieldTypeNameMethod<Defined>;\n\n /**\n * Set a description for the field\n */\n description: DBFieldDescriptionMethod<Defined, Output, Nested>;\n\n /**\n * Define a relation to another table.\n */\n relation: DBFieldRelationMethod<Defined, Output, Nested>;\n\n /**\n * Add an index to the field\n */\n index: DBFieldIndexMethod<Defined, Output, Nested>;\n\n /**\n * Make the field unique (also adds an index)\n */\n unique: DBFieldUniqueMethod<Defined, Output, Nested>;\n\n /**\n * Enable vector search on the field (string type only)\n */\n vector: DBFieldVectorMethod<Defined, Output, Nested>;\n\n /**\n * Set a default value for the field on create. When the field is required,\n * this makes it optional in the Create input — the default fills in when\n * no value (or a nullish hook result) is provided.\n *\n * For datetime/date/time fields, pass `\"now\"` to use the operation timestamp.\n */\n default: DBFieldDefaultMethod<Defined, Output, Nested>;\n\n /**\n * Add hooks for create/update operations on this field.\n */\n hooks: DBFieldHooksMethod<Defined, Output, Nested>;\n\n /**\n * Add validation functions to the field.\n *\n * Validators receive `{ value, data, user }` and run after hooks and\n * built-in type validation; they are skipped when built-in validation\n * fails. For array fields, `value` is the complete array.\n */\n validate: DBFieldValidateMethod<Defined, Output, Nested>;\n\n /**\n * Configure serial/auto-increment behavior\n */\n serial: DBFieldSerialMethod<Defined, Output, Nested>;\n\n /**\n * Clone the field with optional overrides for field options.\n * The `array` option cannot change on fields with custom validation.\n */\n clone<const NewOpt extends DBFieldCloneOptions<Defined>>(\n options?: NewOpt,\n ): TailorDBField<\n WithDBFieldCloneOptions<Defined, NewOpt>,\n DBFieldCloneOutput<Output, NewOpt>,\n Nested\n >;\n}\n\n/**\n * Full TailorDBType interface with builder methods.\n * Extends the minimal structural interface from types/ with fluent API methods.\n */\nexport interface TailorDBType<\n // oxlint-disable-next-line no-explicit-any\n Fields extends Record<string, TailorAnyDBField> = any,\n User extends object = InferredAttributes,\n // oxlint-disable-next-line no-explicit-any\n Defined extends DefinedDBTypeMetadata = any,\n FileKeys extends string = never,\n> extends TailorDBTypeBase<Fields, User> {\n _description?: string;\n\n hooks(\n hook: DBTypeDuplicateInputGuard<\n Defined,\n \"hooks\",\n TypeHook<Fields>,\n \".hooks() has already been set\"\n >,\n ): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, \"hooks\">, FileKeys>;\n validate(\n fn: DBTypeDuplicateInputGuard<\n Defined,\n \"validate\",\n TypeValidateFn<Fields>,\n \".validate() has already been set\"\n >,\n ): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, \"validate\">, FileKeys>;\n features(\n features: DBTypeDuplicateInputGuard<\n Defined,\n \"features\",\n Omit<TypeFeatures, \"pluralForm\">,\n \".features() has already been set\"\n >,\n ): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, \"features\">, FileKeys>;\n indexes(\n ...indexes: DBTypeDuplicateRestGuard<\n Defined,\n \"indexes\",\n IndexDef<TailorDBType<Fields, User, Defined, FileKeys>>[],\n \".indexes() has already been set\"\n >\n ): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, \"indexes\">, FileKeys>;\n files<const F extends string>(\n files: DBTypeDuplicateInputGuard<\n Defined,\n \"files\",\n Record<F, string> & FileKeyConflictError<Fields, User>,\n \".files() has already been set\"\n >,\n ): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, \"files\">, FileKeys | F>;\n permission<\n U extends object = User,\n P extends TailorTypePermission<U, output<TailorDBType<Fields, User, Defined>>> =\n TailorTypePermission<U, output<TailorDBType<Fields, User, Defined>>>,\n >(\n permission: DBTypeDuplicateInputGuard<\n Defined,\n \"permission\",\n P,\n \".permission() has already been set\"\n >,\n ): TailorDBType<Fields, U, WithDBTypeMetadata<Defined, \"permission\">, FileKeys>;\n gqlPermission<\n U extends object = User,\n P extends TailorTypeGqlPermission<U> = TailorTypeGqlPermission<U>,\n >(\n permission: DBTypeDuplicateInputGuard<\n Defined,\n \"gqlPermission\",\n P,\n \".gqlPermission() has already been set\"\n >,\n ): TailorDBType<Fields, U, WithDBTypeMetadata<Defined, \"gqlPermission\">, FileKeys>;\n description(\n description: DBTypeDuplicateInputGuard<\n Defined,\n \"description\",\n string,\n \".description() has already been set\"\n >,\n ): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, \"description\">, FileKeys>;\n pickFields<K extends keyof Fields>(keys: K[]): Pick<Fields, K>;\n pickFields<K extends keyof Fields, const Opt extends FieldOptions>(\n keys: K[],\n options: Opt & DBFieldsCloneOptionsGuard<Fields, K, Opt>,\n ): {\n [P in K]: Fields[P] extends TailorDBField<infer D, infer O>\n ? TailorDBField<WithDBFieldCloneOptions<D, Opt>, DBFieldCloneOutput<O, Opt>>\n : never;\n };\n omitFields<K extends keyof Fields>(keys: K[]): Omit<Fields, K>;\n plugin<const Config extends Record<string, unknown>>(\n config: Config & PluginConfigGuard<Fields, Config, FileKeys>,\n ): TailorDBType<PluginExtendedFields<Fields, Config>, User, Defined, FileKeys>;\n}\n\nexport type TailorDBInstance<\n // oxlint-disable-next-line no-explicit-any\n Fields extends Record<string, TailorAnyDBField> = any,\n User extends object = InferredAttributes,\n // oxlint-disable-next-line no-explicit-any\n Defined extends DefinedDBTypeMetadata = any,\n FileKeys extends string = never,\n> = TailorDBType<Fields, User, Defined, FileKeys>;\n\ninterface RelationConfig<S extends RelationType, T extends TailorDBType> {\n type: S;\n toward:\n | {\n table: T;\n as?: string;\n key?: keyof T[\"fields\"] & string;\n type?: never;\n }\n | {\n /**\n * @deprecated since 2.6.0 — use `table` instead. codemod: v3/relation-toward-table\n */\n type: T;\n as?: string;\n key?: keyof T[\"fields\"] & string;\n table?: never;\n };\n backward?: string;\n}\n\n// Special config variant for self-referencing relations\ntype RelationSelfConfig = {\n type: RelationType;\n toward:\n | {\n table: \"self\";\n as?: string;\n key?: string;\n type?: never;\n }\n | {\n /**\n * @deprecated since 2.6.0 — use `table` instead. codemod: v3/relation-toward-table\n */\n type: \"self\";\n as?: string;\n key?: string;\n table?: never;\n };\n backward?: string;\n};\n\ntype DBFieldDefined<T extends TailorFieldType, Opt extends FieldOptions> = {\n type: T;\n array: Opt extends { array: true } ? true : false;\n};\ntype DBFieldOutput<\n T extends TailorFieldType,\n Opt extends FieldOptions,\n OutputBase = TailorToTs[T],\n> = FieldOutput<OutputBase, Opt>;\ntype TailorDBFieldInstance<\n T extends TailorFieldType,\n Opt extends FieldOptions,\n OutputBase = TailorToTs[T],\n> = TailorDBField<DBFieldDefined<T, Opt>, DBFieldOutput<T, Opt, OutputBase>>;\ntype TailorDBFieldRuntimeInstance<\n T extends TailorFieldType,\n Opt extends FieldOptions,\n OutputBase = TailorToTs[T],\n> = TailorDBFieldRuntime<DBFieldDefined<T, Opt>, DBFieldOutput<T, Opt, OutputBase>>;\ntype TailorDBFieldRuntime<Defined extends DefinedDBFieldMetadata, Output> = Omit<\n TailorDBFieldBase<Defined, Output>,\n \"fields\"\n> & {\n readonly fields: Record<string, TailorAnyDBField>;\n _metadata: DBFieldMetadata;\n description(description: string): object;\n typeName(typeName: string): object;\n validate(...validate: FieldValidateInput<Output>[]): object;\n relation(config: RelationConfig<RelationType, TailorDBType> | RelationSelfConfig): object;\n index(): object;\n unique(): object;\n vector(): object;\n default(value: unknown): object;\n hooks(hooks: Hook<Output>): object;\n serial(config: SerialConfig): object;\n clone(options?: FieldOptions): TailorDBFieldRuntime<DefinedDBFieldMetadata, AnyBuilderMethod>;\n parse(args: FieldParseArgs): StandardSchemaV1.Result<Output>;\n _setRawRelation(relation: RawRelationConfig): void;\n};\n\n/**\n * Creates a new TailorDBField instance.\n * @param type - Field type\n * @param options - Field options\n * @param fields - Nested fields for object-like types\n * @param values - Allowed values for enum-like fields\n * @returns A new TailorDBField\n */\nfunction createTailorDBField<\n const T extends TailorFieldType,\n const TOptions extends FieldOptions,\n const OutputBase = TailorToTs[T],\n>(\n type: T,\n options?: TOptions,\n fields?: Record<string, TailorAnyDBField>,\n values?: AllowedValues,\n): TailorDBFieldInstance<T, TOptions, OutputBase>;\nfunction createTailorDBField<const T extends TailorFieldType, const TOptions extends FieldOptions>(\n type: T,\n options?: TOptions,\n fields?: Record<string, TailorAnyDBField>,\n values?: AllowedValues,\n): object {\n return createTailorDBFieldRuntime(type, options, fields, values);\n}\n\nfunction createTailorDBFieldRuntime<\n const T extends TailorFieldType,\n const TOptions extends FieldOptions,\n const OutputBase = TailorToTs[T],\n>(\n type: T,\n options?: TOptions,\n fields?: Record<string, TailorAnyDBField>,\n values?: AllowedValues,\n): TailorDBFieldRuntimeInstance<T, TOptions, OutputBase> {\n type FieldValue = DBFieldOutput<T, TOptions, OutputBase>;\n type FieldType = TailorDBFieldRuntimeInstance<T, TOptions, OutputBase>;\n\n const _metadata: DBFieldMetadata = { required: true };\n let _rawRelation: RawRelationConfig | undefined;\n\n if (options) {\n if (options.optional === true) {\n _metadata.required = false;\n }\n if (options.array === true) {\n _metadata.array = true;\n }\n }\n if (values) {\n _metadata.allowedValues = mapAllowedValues(values);\n }\n\n function parseInternal(args: FieldParseInternalArgs): StandardSchemaV1.Result<FieldValue> {\n return parseFieldInternal<T, FieldValue>({\n ...args,\n field,\n });\n }\n\n function cloneWith(metadataUpdates: Partial<DBFieldMetadata>) {\n const cloned = field.clone();\n Object.assign(cloned._metadata, metadataUpdates);\n return cloned;\n }\n\n const field: FieldType = {\n type,\n fields: fields ?? {},\n _defined: undefined as unknown as DBFieldDefined<T, TOptions>,\n _output: undefined as FieldValue,\n _metadata,\n\n get metadata() {\n return { ...this._metadata };\n },\n\n get rawRelation(): Readonly<RawRelationConfig> | undefined {\n return _rawRelation ? { ..._rawRelation, toward: { ..._rawRelation.toward } } : undefined;\n },\n\n description(description: string) {\n return cloneWith({ description });\n },\n\n typeName(typeName: string) {\n return cloneWith({ typeName });\n },\n\n validate(...validateInputs: FieldValidateInput<FieldValue>[]) {\n return cloneWith({ validate: validateInputs });\n },\n\n parse(args: FieldParseArgs): StandardSchemaV1.Result<FieldValue> {\n return parseInternal({\n value: args.value,\n data: args.data,\n invoker: args.invoker,\n pathArray: [],\n });\n },\n\n // TailorDBField specific methods\n relation(config: RelationConfig<RelationType, TailorDBType> | RelationSelfConfig) {\n const cloned = field.clone();\n // The public type is a nested union (RelationConfig | RelationSelfConfig,\n // each with a `{ table } | { type }` toward), which TS's \"in\" narrowing\n // can't discriminate across cleanly. Re-view it as the flat two-branch\n // shape it always is at runtime — the `table?: never` / `type?: never`\n // markers above already forbid both keys from being set together.\n const toward = config.toward as\n | { table: TailorDBType | \"self\" }\n | { type: TailorDBType | \"self\" };\n const towardTarget = \"table\" in toward ? toward.table : toward.type;\n const targetTable = towardTarget === \"self\" ? \"self\" : towardTarget.name;\n cloned._setRawRelation({\n type: config.type,\n toward: {\n table: targetTable,\n as: config.toward.as,\n key: config.toward.key,\n },\n backward: config.backward,\n });\n return cloned;\n },\n\n index() {\n return cloneWith({ index: true });\n },\n\n unique() {\n return cloneWith({ unique: true, index: true });\n },\n\n vector() {\n return cloneWith({ vector: true });\n },\n\n // oxlint-disable-next-line no-explicit-any\n default(value: any) {\n // oxlint-disable-next-line no-explicit-any\n return cloneWith({ default: value }) as any;\n },\n\n hooks(hooks: Hook<FieldValue>) {\n return cloneWith({ hooks });\n },\n\n serial(config: SerialConfig) {\n return cloneWith({ serial: config });\n },\n\n clone(cloneOptions?: FieldOptions) {\n if (\n this._metadata.validate?.length &&\n cloneOptions?.array !== undefined &&\n cloneOptions.array !== (this._metadata.array === true)\n ) {\n throw new Error(\"Cannot change the array option on a field with custom validation\");\n }\n\n // Deep clone nested object fields if present\n let clonedFields = fields;\n if (fields) {\n const cloned: Record<string, TailorAnyDBField> = {};\n for (const [key, field] of Object.entries(fields)) {\n cloned[key] = field.clone();\n }\n clonedFields = cloned;\n }\n\n // Create a new field with cloned configuration\n const clonedField = createTailorDBFieldRuntime(type, options, clonedFields, values);\n\n // Deep copy metadata using cloneDeep (preserves function references)\n Object.assign(clonedField._metadata, cloneDeep(this._metadata));\n\n // Apply new options if provided\n if (cloneOptions) {\n if (cloneOptions.optional !== undefined) {\n clonedField._metadata.required = !cloneOptions.optional;\n }\n if (cloneOptions.array !== undefined) {\n clonedField._metadata.array = cloneOptions.array;\n }\n }\n\n // Copy raw relation if exists\n if (_rawRelation) {\n clonedField._setRawRelation(cloneDeep(_rawRelation));\n }\n\n return clonedField;\n },\n\n _setRawRelation(relation: RawRelationConfig) {\n _rawRelation = relation;\n },\n };\n\n return field;\n}\n\nconst createField = createTailorDBField;\n\n/**\n * Create a UUID field.\n * @param options - Field configuration options\n * @returns A UUID field\n * @example db.uuid()\n * @example db.uuid({ optional: true })\n */\nfunction uuid<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"uuid\", options);\n}\n\n/**\n * Create a string field.\n * @param options - Field configuration options\n * @returns A string field\n * @example db.string()\n * @example db.string({ optional: true })\n */\nfunction string<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"string\", options);\n}\n\n/**\n * Create a boolean field.\n * Note: The method name is `bool` but creates a `boolean` type field.\n * @param options - Field configuration options\n * @returns A boolean field\n * @example db.bool()\n * @example db.bool({ optional: true })\n */\nfunction bool<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"boolean\", options);\n}\n\n/**\n * Create an integer field.\n * @param options - Field configuration options\n * @returns An integer field\n * @example db.int()\n * @example db.int({ optional: true })\n */\nfunction int<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"integer\", options);\n}\n\n/**\n * Create a float (decimal number) field.\n * @param options - Field configuration options\n * @returns A float field\n * @example db.float()\n * @example db.float({ optional: true })\n */\nfunction float<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"float\", options);\n}\n\ninterface DecimalFieldOptions extends FieldOptions {\n scale?: number;\n}\n\n/**\n * Create a decimal field (stored as string for precision).\n * @param options - Field configuration options including optional scale (0-12)\n * @returns A decimal field\n * @example db.decimal()\n * @example db.decimal({ scale: 2 })\n * @example db.decimal({ scale: 2, optional: true })\n */\nfunction decimal<const Opt extends DecimalFieldOptions>(options?: Opt) {\n if (options?.scale !== undefined) {\n if (!Number.isInteger(options.scale) || options.scale < 0 || options.scale > 12) {\n throw new Error(\"scale must be an integer between 0 and 12\");\n }\n }\n const field = createField(\"decimal\", options);\n if (options?.scale !== undefined) {\n field._metadata.scale = options.scale;\n }\n return field;\n}\n\n/**\n * Create a date field (date only, no time component).\n * Format: \"yyyy-MM-dd\"\n * @param options - Field configuration options\n * @returns A date field\n * @example db.date()\n */\nfunction date<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"date\", options);\n}\n\n/**\n * Create a datetime field (date and time).\n * Format: ISO 8601, such as \"yyyy-MM-ddTHH:mm:ssZ\" or \"yyyy-MM-ddTHH:mm:ss+09:00\"\n * @param options - Field configuration options\n * @returns A datetime field\n * @example db.datetime()\n */\nfunction datetime<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"datetime\", options);\n}\n\n/**\n * Create a time field (time only, no date component).\n * Format: \"HH:mm\"\n * @param options - Field configuration options\n * @returns A time field\n * @example db.time()\n */\nfunction time<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"time\", options);\n}\n\n/**\n * Create an enum field with at least one allowed string value.\n * @param values - Array of allowed string values, or array of `{ value, description }` objects\n * @param options - Field configuration options\n * @returns An enum field\n * @example db.enum([\"active\", \"inactive\", \"suspended\"])\n * @example db.enum([\"small\", \"medium\", \"large\"], { optional: true })\n */\nfunction _enum<const V extends AllowedValues, const Opt extends FieldOptions>(\n values: V,\n options?: Opt,\n): TailorDBField<\n { type: \"enum\"; array: Opt extends { array: true } ? true : false },\n FieldOutput<AllowedValuesOutput<V>, Opt>\n> {\n return createField<\"enum\", Opt, AllowedValuesOutput<V>>(\"enum\", options, undefined, values);\n}\n\n/**\n * Create a nested object field with sub-fields.\n * @param fields - Record of nested field definitions\n * @param options - Field configuration options\n * @returns A nested object field\n * @example db.object({ street: db.string(), city: db.string(), zip: db.string() })\n * @example db.object({ name: db.string() }, { optional: true })\n */\nfunction object<\n const F extends Record<string, TailorAnyDBField> &\n ExcludeNestedDBFields<F> &\n ExcludeHookedDBFields<F> &\n ExcludeDefaultedDBFields<F>,\n const Opt extends FieldOptions,\n>(fields: F, options?: Opt) {\n return createField(\"nested\", options, fields) as unknown as TailorDBField<\n { type: \"nested\"; array: Opt extends { array: true } ? true : false },\n FieldOutput<InferFieldsOutput<F>, Opt>,\n F\n >;\n}\n\n/**\n * Creates a new TailorDBType instance.\n * @param name - Table name\n * @param fields - Field definitions\n * @param options - Table options\n * @param options.pluralForm - Optional plural form\n * @param options.description - Optional description\n * @returns A new TailorDBType\n */\nfunction createTailorDBType<\n // oxlint-disable-next-line no-explicit-any\n const Fields extends Record<string, TailorAnyDBField> = any,\n User extends object = InferredAttributes,\n>(\n name: string,\n fields: Fields,\n options: { pluralForm?: string; description?: string },\n): TailorDBType<Fields, User, DefinedDBTypeMetadata> {\n let _description = options.description;\n let _settings: TypeFeatures = {};\n let _indexes: IndexDef<TailorDBType<Fields, User, DefinedDBTypeMetadata>>[] = [];\n const _permissions: RawPermissions = {};\n let _files: Record<string, string> = {};\n const _plugins: PluginAttachment[] = [];\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n let _typeHook: { create?: Function; update?: Function } | undefined;\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n let _typeValidate: Function | undefined;\n const _definedMethods = new Set<keyof DefinedDBTypeMetadata>();\n if (options.description !== undefined) {\n _definedMethods.add(\"description\");\n }\n\n function runMethodOnce<T>(method: keyof DefinedDBTypeMetadata, action: () => T): T {\n if (_definedMethods.has(method)) {\n throw new Error(`.${method}() has already been set`);\n }\n const result = action();\n _definedMethods.add(method);\n return result;\n }\n type TypeAfter<Key extends keyof DefinedDBTypeMetadata> = TailorDBType<\n Fields,\n User,\n WithDBTypeMetadata<DefinedDBTypeMetadata, Key>\n >;\n type TypeAfterUser<\n NextUser extends object,\n Key extends keyof DefinedDBTypeMetadata,\n > = TailorDBType<Fields, NextUser, WithDBTypeMetadata<DefinedDBTypeMetadata, Key>>;\n type TypeAfterPlugin<Config extends Record<string, unknown>> = TailorDBType<\n PluginExtendedFields<Fields, Config>,\n User,\n DefinedDBTypeMetadata\n >;\n\n if (options.pluralForm) {\n if (name === options.pluralForm) {\n throw new Error(`The name and the plural form must be different. name=${name}`);\n }\n _settings.pluralForm = options.pluralForm;\n }\n\n const dbType: TailorDBType<Fields, User, DefinedDBTypeMetadata> = {\n name,\n fields: { ...fields },\n _output: null as unknown as InferFieldsOutput<Fields>,\n _description,\n\n get metadata(): TailorDBTypeMetadata {\n // Convert indexes to the format expected by the manifest\n const indexes: Record<string, { fields: string[]; unique?: boolean }> = {};\n if (_indexes.length > 0) {\n _indexes.forEach((index) => {\n const fieldNames = index.fields.map((field) => String(field));\n const key = index.name || `idx_${fieldNames.join(\"_\")}`;\n indexes[key] = {\n fields: fieldNames,\n unique: index.unique,\n };\n });\n }\n\n return {\n name: this.name,\n description: _description,\n settings: _settings,\n permissions: _permissions,\n files: _files,\n ...(Object.keys(indexes).length > 0 && { indexes }),\n ...(_typeHook && { typeHook: _typeHook }),\n ...(_typeValidate && { typeValidate: _typeValidate }),\n };\n },\n\n hooks(hook: TypeHook<Fields>): TypeAfter<\"hooks\"> {\n return runMethodOnce(\"hooks\", () => {\n _typeHook = hook;\n return this as TypeAfter<\"hooks\">;\n });\n },\n\n validate(fn: TypeValidateFn<Fields>): TypeAfter<\"validate\"> {\n return runMethodOnce(\"validate\", () => {\n _typeValidate = fn;\n return this as TypeAfter<\"validate\">;\n });\n },\n\n features(features: Omit<TypeFeatures, \"pluralForm\">): TypeAfter<\"features\"> {\n return runMethodOnce(\"features\", () => {\n _settings = {\n ..._settings,\n ...features,\n };\n return this as TypeAfter<\"features\">;\n });\n },\n\n indexes(\n ...indexes: IndexDef<TailorDBType<Fields, User, DefinedDBTypeMetadata>>[]\n ): TypeAfter<\"indexes\"> {\n return runMethodOnce(\"indexes\", () => {\n _indexes = indexes;\n return this as TypeAfter<\"indexes\">;\n });\n },\n\n files<const F extends string>(\n files: Record<F, string> & FileKeyConflictError<Fields, User>,\n ): TailorDBType<Fields, User, WithDBTypeMetadata<DefinedDBTypeMetadata, \"files\">, F> {\n return runMethodOnce(\"files\", () => {\n _files = files;\n return this as TailorDBType<\n Fields,\n User,\n WithDBTypeMetadata<DefinedDBTypeMetadata, \"files\">,\n F\n >;\n });\n },\n\n permission<\n U extends object = User,\n P extends TailorTypePermission<U, output<TailorDBType<Fields, User, DefinedDBTypeMetadata>>> =\n TailorTypePermission<U, output<TailorDBType<Fields, User, DefinedDBTypeMetadata>>>,\n >(permission: P): TypeAfterUser<U, \"permission\"> {\n return runMethodOnce(\"permission\", () => {\n const ret = this as unknown as TypeAfterUser<U, \"permission\">;\n _permissions.record = permission as RawPermissions[\"record\"];\n return ret;\n });\n },\n\n gqlPermission<\n U extends object = User,\n P extends TailorTypeGqlPermission<U> = TailorTypeGqlPermission<U>,\n >(permission: P): TypeAfterUser<U, \"gqlPermission\"> {\n return runMethodOnce(\"gqlPermission\", () => {\n const ret = this as unknown as TypeAfterUser<U, \"gqlPermission\">;\n _permissions.gql = permission as RawPermissions[\"gql\"];\n return ret;\n });\n },\n\n description(description: string): TypeAfter<\"description\"> {\n return runMethodOnce(\"description\", () => {\n _description = description;\n this._description = description;\n return this as TypeAfter<\"description\">;\n });\n },\n\n pickFields<K extends keyof Fields, const Opt extends FieldOptions>(keys: K[], options?: Opt) {\n const result = {} as Record<K, TailorAnyDBField>;\n for (const key of keys) {\n const field = this.fields[key] as TailorAnyDBField | undefined;\n if (!field) {\n // A plugin-injected field is only added to `fields` after `tailor\n // generate` runs — see the \"Injecting fields into the attached\n // table's type\" section of the plugin docs.\n throw new Error(\n `pickFields(): field \"${String(key)}\" does not exist on this table yet. If it comes from a plugin's .plugin() call, it is only added to the table after \\`tailor generate\\` runs.`,\n );\n }\n if (options) {\n result[key] = field.clone(options);\n } else {\n result[key] = field;\n }\n }\n // oxlint-disable-next-line no-explicit-any\n return result as any;\n },\n\n omitFields<K extends keyof Fields>(keys: K[]): Omit<Fields, K> {\n const keysSet = new Set(keys);\n const result = {} as Record<string, TailorAnyDBField>;\n for (const key in this.fields) {\n if (Object.hasOwn(this.fields, key) && !keysSet.has(key as unknown as K)) {\n result[key] = this.fields[key] as TailorAnyDBField;\n }\n }\n return result as Omit<Fields, K>;\n },\n\n get plugins(): PluginAttachment[] {\n return _plugins;\n },\n\n plugin<const Config extends Record<string, unknown>>(\n config: Config & PluginConfigGuard<Fields, Config, never>,\n ): TypeAfterPlugin<Config> {\n for (const [pluginId, pluginConfig] of Object.entries(config)) {\n _plugins.push({ pluginId, config: pluginConfig });\n }\n return this as unknown as TypeAfterPlugin<Config>;\n },\n };\n\n return brandValue(dbType, \"tailordb-type\");\n}\n\nconst idField = uuid();\ntype idField = typeof idField;\ntype DBTable<\n F extends { id?: never } & Record<string, TailorAnyDBField>,\n Defined extends DefinedDBTypeMetadata = DefinedDBTypeMetadata,\n> = TailorDBInstance<{ id: idField } & F, InferredAttributes, Defined>;\n\n/**\n * Creates a new database table with the specified fields.\n * An `id` field (UUID) is automatically added to every table.\n * @param name - The name of the table, or a tuple of [name, pluralForm]\n * @param fields - The field definitions for the table\n * @returns A new TailorDB table instance\n * @example\n * export const user = db.table(\"User\", {\n * name: db.string(),\n * email: db.string(),\n * age: db.int({ optional: true }),\n * role: db.enum([\"admin\", \"member\"]),\n * ...db.fields.timestamps(),\n * });\n * // Always export both the value and type:\n * export type user = typeof user;\n */\nfunction dbTable<const F extends { id?: never } & Record<string, TailorAnyDBField>>(\n name: string | [string, string],\n fields: F,\n): DBTable<F>;\n/**\n * Creates a new database table with the specified fields and description.\n * An `id` field (UUID) is automatically added to every table.\n * @param name - The name of the table, or a tuple of [name, pluralForm]\n * @param description - A description of the table\n * @param fields - The field definitions for the table\n * @returns A new TailorDB table instance\n */\nfunction dbTable<const F extends { id?: never } & Record<string, TailorAnyDBField>>(\n name: string | [string, string],\n description: string,\n fields: F,\n): DBTable<F, WithDBTypeMetadata<DefinedDBTypeMetadata, \"description\">>;\nfunction dbTable<const F extends { id?: never } & Record<string, TailorAnyDBField>>(\n name: string | [string, string],\n fieldsOrDescription: string | F,\n fields?: F,\n): DBTable<F> | DBTable<F, WithDBTypeMetadata<DefinedDBTypeMetadata, \"description\">> {\n const typeName = Array.isArray(name) ? name[0] : name;\n const pluralForm = Array.isArray(name) ? name[1] : undefined;\n\n let description: string | undefined;\n let fieldDef: F;\n if (typeof fieldsOrDescription === \"string\") {\n description = fieldsOrDescription;\n fieldDef = fields as F;\n } else {\n fieldDef = fieldsOrDescription;\n }\n return createTailorDBType<{ id: idField } & F>(\n typeName,\n {\n id: idField,\n ...fieldDef,\n },\n { pluralForm, description },\n );\n}\n\n// `Function.prototype.toString()` of this hook is embedded verbatim into deployed\n// schemas and migration diffs (see parser/service/tailordb/hooks-validate-precompiled-expr.ts\n// and field.ts). Its source text depends on how the SDK itself was built (e.g.\n// minification), so a fixed expression is pinned onto it directly here instead -\n// configure cannot import parser's `setPrecompiledScriptExpr` runtime helper across\n// the module boundary, only the symbol registry key and map types. Keep\n// this literal in sync with the \"timestamps() updatedAt hook resolves to the pinned\n// expr\" test in parser/service/tailordb/field.precompiled.test.ts, which fails if it\n// ever drifts from what this hook's own source naturally produces.\ntype TimestampsUpdatedAtHookFn = UpdateHookFn<string | Date | null, string | Date>;\nconst timestampsUpdatedAtHook: TimestampsUpdatedAtHookFn = ({ input, now }) => input ?? now;\nconst PRECOMPILED_EXPR_KEY: PrecompiledScriptExprKey =\n \"tailor-platform/sdk:precompiled-script-expr\";\nconst PRECOMPILED_EXPR_SYMBOL = Symbol.for(PRECOMPILED_EXPR_KEY);\n(timestampsUpdatedAtHook as unknown as Record<symbol, PrecompiledScriptExprMap>)[\n PRECOMPILED_EXPR_SYMBOL\n] = {\n \"hooks.update\":\n \"(({ input, now }) => input ?? now)({ input: _value, oldValue: _oldValue, invoker: _principal, now: _now })\",\n};\n\n/** TailorDB schema builder utilities for defining tables and fields. */\nexport const db = {\n table: dbTable,\n uuid,\n string,\n bool,\n int,\n float,\n decimal,\n date,\n datetime,\n time,\n enum: _enum,\n object,\n fields: {\n /**\n * Creates standard timestamp fields (createdAt, updatedAt) with automatic defaults.\n * Both fields default to the current time on create. updatedAt is also refreshed on update.\n * User-specified values are respected when provided (e.g. seeding historical records).\n * @returns An object with createdAt and updatedAt fields\n * @example\n * const model = db.table(\"Model\", {\n * name: db.string(),\n * ...db.fields.timestamps(),\n * });\n */\n timestamps: () => ({\n createdAt: datetime().default(\"now\").description(\"Record creation timestamp\"),\n updatedAt: datetime()\n .default(\"now\")\n .hooks({ update: timestampsUpdatedAtHook })\n .description(\"Record update timestamp\"),\n }),\n },\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schema-BKvcWdVf.mjs","names":["parseInternal","parseFieldInternal"],"sources":["../src/configure/types/field.ts","../src/configure/services/tailordb/schema.ts"],"sourcesContent":["import type { EnumValue } from \"#/configure/types/field.types\";\n\nexport type AllowedValues = readonly [string | EnumValue, ...(string | EnumValue)[]];\n\n/**\n * Normalize allowed values into EnumValue objects with descriptions.\n * @param values - Allowed values as strings or EnumValue objects\n * @returns Normalized allowed values\n */\nexport function mapAllowedValues(values: AllowedValues): EnumValue[] {\n return values.map((value) => {\n if (typeof value === \"string\") {\n return { value, description: \"\" };\n }\n return { ...value, description: value.description ?? \"\" };\n });\n}\n\nexport type AllowedValuesOutput<V extends AllowedValues> = V[number] extends infer T\n ? T extends string\n ? T\n : T extends { value: infer K }\n ? K\n : never\n : never;\n","import { cloneDeep } from \"es-toolkit\";\nimport {\n type AllowedValues,\n type AllowedValuesOutput,\n mapAllowedValues,\n} from \"#/configure/types/field\";\nimport {\n parseInternal as parseFieldInternal,\n type FieldParseArgs,\n type FieldParseInternalArgs,\n} from \"#/runtime/field-parse\";\nimport { brandValue } from \"#/utils/brand\";\nimport type {\n FieldOptions,\n FieldOutput,\n TailorFieldType,\n TailorToTs,\n FieldValidateInput,\n} from \"#/configure/types/field.types\";\nimport type {\n PrecompiledScriptExprKey,\n PrecompiledScriptExprMap,\n} from \"#/parser/service/tailordb/types\";\nimport type { PluginAttachment, PluginConfigs, PluginFieldExtensions } from \"#/plugin/types\";\nimport type { InferredAttributes } from \"#/runtime/types\";\nimport type {\n output,\n InferFieldsOutput,\n IsUnion,\n TypeLevelError,\n UnionToIntersection,\n} from \"#/types/helpers\";\nimport type { RawPermissions } from \"#/types/tailordb.generated\";\nimport type { TailorTypeGqlPermission, TailorTypePermission } from \"./permission\";\nimport type {\n TailorDBField as TailorDBFieldBase,\n TailorDBType as TailorDBTypeBase,\n DBFieldMetadata,\n DefinedDBFieldMetadata,\n SerialConfig,\n IndexDef,\n TailorDBTypeMetadata,\n RawRelationConfig,\n RelationType,\n Hook,\n TypeHook,\n UpdateHookFn,\n ExcludeNestedDBFields,\n ExcludeHookedDBFields,\n ExcludeDefaultedDBFields,\n TypeFeatures,\n TypeValidateFn,\n} from \"./types\";\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\n\n// Erased DB fields stay assignable across builder method-state changes.\n// oxlint-disable-next-line no-explicit-any\ntype AnyBuilderMethod = any;\n\nexport type TailorAnyDBField = Omit<\n TailorDBFieldBase<AnyBuilderMethod, AnyBuilderMethod>,\n \"fields\"\n> & {\n readonly fields: Record<string, AnyBuilderMethod>;\n _metadata: DBFieldMetadata;\n parse: AnyBuilderMethod;\n readonly typeName: TypeLevelError<string>;\n description: AnyBuilderMethod;\n relation: AnyBuilderMethod;\n index: AnyBuilderMethod;\n unique: AnyBuilderMethod;\n vector: AnyBuilderMethod;\n default: AnyBuilderMethod;\n hooks: AnyBuilderMethod;\n validate: AnyBuilderMethod;\n serial: AnyBuilderMethod;\n clone: AnyBuilderMethod;\n};\n\n// Helper alias\n// oxlint-disable-next-line no-explicit-any\nexport type TailorAnyDBType = TailorDBType<any, any, any>;\n\ntype IsAny<T> = 0 extends 1 & T ? true : false;\ntype DBFieldTypeNameMethod<Defined extends DefinedDBFieldMetadata> =\n IsAny<Defined> extends true\n ? TypeLevelError<string>\n : TypeLevelError<\"typeName cannot be used on TailorDB fields\">;\n\ntype WithDBFieldDescription<Defined> = Defined & { description: true };\ntype WithDBFieldRelation<Defined, S extends RelationType | RelationSelfConfig> = S extends\n | \"oneToOne\"\n | \"1-1\"\n ? Defined & { unique: true; index: true; relation: true }\n : S extends { type: \"oneToOne\" | \"1-1\" }\n ? Defined & { unique: true; index: true; relation: true }\n : Defined & { index: true; relation: true };\ntype WithDBFieldIndex<Defined> = Defined & { index: true };\ntype WithDBFieldUnique<Defined> = Defined & { unique: true; index: true };\ntype WithDBFieldVector<Defined> = Defined & { vector: true };\ntype WithDBFieldHooks<Defined, H> = Defined & {\n hooks: {\n create: H extends { create: unknown } ? true : false;\n update: H extends { update: unknown } ? true : false;\n };\n serial: false;\n};\ntype WithDBFieldDefault<Defined> = Defined & { default: true };\ntype WithDBFieldValidate<Defined> = Defined & { validate: true };\ntype WithDBFieldSerial<Defined> = Defined & {\n serial: true;\n hooks: { create: false; update: false };\n};\ntype WithDBFieldCloneOptions<Defined extends DefinedDBFieldMetadata, NewOpt extends FieldOptions> =\n IsAny<Defined> extends true\n ? Defined\n : Omit<Defined, \"array\"> & {\n array: NewOpt extends { array: true }\n ? true\n : NewOpt extends { array: false }\n ? false\n : Defined[\"array\"];\n };\ntype NonNullableDBFieldOutput<Output> = Exclude<Output, null>;\ntype DBFieldScalarOutput<Output> =\n NonNullableDBFieldOutput<Output> extends (infer Item)[] ? Item : NonNullableDBFieldOutput<Output>;\ntype DBFieldCloneArrayOutput<Output, NewOpt extends FieldOptions> = NewOpt extends {\n array: true;\n}\n ? DBFieldScalarOutput<Output>[]\n : NewOpt extends { array: false }\n ? DBFieldScalarOutput<Output>\n : NonNullableDBFieldOutput<Output>;\ntype DBFieldCloneOutput<Output, NewOpt extends FieldOptions> = NewOpt extends { optional: true }\n ? DBFieldCloneArrayOutput<Output, NewOpt> | null\n : NewOpt extends { optional: false }\n ? DBFieldCloneArrayOutput<Output, NewOpt>\n : null extends Output\n ? DBFieldCloneArrayOutput<Output, NewOpt> | null\n : DBFieldCloneArrayOutput<Output, NewOpt>;\ntype DBFieldCloneOptions<Defined extends DefinedDBFieldMetadata> = Omit<FieldOptions, \"array\"> & {\n array?: Defined extends { validate: unknown } ? Defined[\"array\"] : boolean;\n};\ntype InvalidValidatedArrayCloneKeys<\n Fields extends Record<string, TailorAnyDBField>,\n K extends keyof Fields,\n Opt extends FieldOptions,\n> = Opt extends { array: infer ArrayOption }\n ? {\n [P in K]: Fields[P] extends TailorDBField<infer Defined, infer _Output>\n ? Defined extends { validate: unknown }\n ? ArrayOption extends Defined[\"array\"]\n ? never\n : P\n : never\n : never;\n }[K]\n : never;\ntype DBFieldsCloneOptionsGuard<\n Fields extends Record<string, TailorAnyDBField>,\n K extends keyof Fields,\n Opt extends FieldOptions,\n> = [InvalidValidatedArrayCloneKeys<Fields, K, Opt>] extends [never]\n ? unknown\n : TypeLevelError<\"array cannot be changed on fields with custom validation\">;\ntype DefinedDBTypeMetadata = {\n hooks?: true;\n validate?: true;\n features?: true;\n indexes?: true;\n files?: true;\n permission?: true;\n gqlPermission?: true;\n description?: true;\n};\ntype WithDBTypeMetadata<\n Defined extends DefinedDBTypeMetadata,\n Key extends keyof DefinedDBTypeMetadata,\n> = Defined & Record<Key, true>;\ntype DBTypeDuplicateInputGuard<\n Defined extends DefinedDBTypeMetadata,\n Key extends keyof DefinedDBTypeMetadata,\n Input,\n Message extends string,\n> =\n IsAny<Defined> extends true\n ? Input\n : Defined extends Record<Key, unknown>\n ? TypeLevelError<Message>\n : Input;\ntype DBTypeDuplicateRestGuard<\n Defined extends DefinedDBTypeMetadata,\n Key extends keyof DefinedDBTypeMetadata,\n Input extends unknown[],\n Message extends string,\n> =\n IsAny<Defined> extends true\n ? Input\n : Defined extends Record<Key, unknown>\n ? [TypeLevelError<Message>, ...TypeLevelError<Message>[]]\n : Input;\ntype FileKeyConflictError<\n Fields extends Record<string, TailorAnyDBField>,\n User extends object,\n> = Partial<\n Record<\n keyof output<TailorDBType<Fields, User>> & string,\n TypeLevelError<\"file keys cannot use existing field names\">\n >\n>;\n// A plugin id with no PluginFieldExtensions entry contributes no keys — using\n// Record<never, never> (rather than Record<string, never>) keeps its `keyof`\n// empty so it can't spuriously collide with every existing field.\ntype PluginFieldExtensionFor<\n Fields extends Record<string, TailorAnyDBField>,\n Id extends string,\n IdConfig,\n> = Id extends keyof PluginFieldExtensions<keyof Fields & string, IdConfig>\n ? PluginFieldExtensions<keyof Fields & string, IdConfig>[Id]\n : Record<never, never>;\ntype PluginFieldExtensionsUnion<\n Fields extends Record<string, TailorAnyDBField>,\n Config extends Record<string, unknown>,\n> = {\n [Id in keyof Config & string]: PluginFieldExtensionFor<Fields, Id, Config[Id]>;\n}[keyof Config & string];\ntype AllExtensionKeys<Ext> = Ext extends unknown ? keyof Ext : never;\n// True when plugin `Id` has a PluginFieldExtensions entry whose type does not\n// extend Record<string, TailorAnyDBField> — e.g. a plugin author registered\n// a non-record shape by mistake. Checked ahead of PluginFieldConflict, since\n// `keyof` on a non-record shape (e.g. `keyof string`) would otherwise produce\n// nonsense candidate keys for the collision check.\n// `Id extends string` (not `keyof Config & string`) deliberately: a mapped\n// type's key variable, used inside a nested conditional branch and then\n// intersected with `string`, does not structurally satisfy a `keyof Config &\n// string`-constrained type parameter under `skipLibCheck: false` (verified\n// against a standalone consumer — TS2344 on both call sites otherwise, even\n// for code that never calls .plugin()). `Config[Id & keyof Config]` recovers\n// the same indexed-access result without that constraint.\ntype PluginFieldExtensionShapeError<\n Fields extends Record<string, TailorAnyDBField>,\n Config extends Record<string, unknown>,\n Id extends string,\n> =\n PluginFieldExtensionFor<Fields, Id, Config[Id & keyof Config]> extends Record<\n string,\n TailorAnyDBField\n >\n ? false\n : true;\n// True when the fields plugin `Id` would inject collide with an existing\n// field, or with a field injected by another plugin id attached in the same\n// .plugin() call.\ntype PluginFieldConflict<\n Fields extends Record<string, TailorAnyDBField>,\n Config extends Record<string, unknown>,\n Id extends string,\n FileKeys extends string,\n> = [\n AllExtensionKeys<PluginFieldExtensionFor<Fields, Id, Config[Id & keyof Config]>> &\n (\n | keyof Fields\n | FileKeys\n | AllExtensionKeys<PluginFieldExtensionsUnion<Fields, Omit<Config, Id>>>\n ),\n] extends [never]\n ? false\n : true;\n// Rejects a property on the caller's config literal for plugin `Id` that\n// isn't part of its registered PluginConfigs shape. `Config` is captured by\n// a `const` type parameter from the argument itself, so intersecting the\n// success branch with `PluginConfigs<...>[Id]` alone would not trigger\n// TypeScript's excess-property check — that check only fires when an object\n// literal is validated directly against a target type, not after its shape\n// has already been inferred through a generic parameter.\ntype PluginConfigExcessProps<\n Fields extends Record<string, TailorAnyDBField>,\n Config extends Record<string, unknown>,\n Id extends string,\n> = Record<\n Exclude<\n keyof Config[Id & keyof Config],\n keyof PluginConfigs<keyof Fields & string>[Id & keyof PluginConfigs<keyof Fields & string>]\n >,\n never\n>;\ntype PluginExtendedFields<\n Fields extends Record<string, TailorAnyDBField>,\n Config extends Record<string, unknown>,\n> =\n IsAny<Fields> extends true\n ? Fields\n : // For `Config = {}`, PluginFieldExtensionsUnion is `never`, and\n // UnionToIntersection<never> is `unknown` (not `never`), so this\n // correctly reduces to `Fields` — see the \"empty config\" test.\n Fields & UnionToIntersection<PluginFieldExtensionsUnion<Fields, Config>>;\n// Validates each key of the passed config object against PluginConfigs and\n// flags field-extension conflicts (see PluginFieldConflict above), keeping\n// type errors localized to the offending plugin id instead of requiring\n// every registered plugin id to be present (as a `P extends keyof\n// PluginConfigs<...>` generic would need, defeating inference of which\n// plugin ids were actually passed).\ntype PluginConfigGuard<\n Fields extends Record<string, TailorAnyDBField>,\n Config extends Record<string, unknown>,\n FileKeys extends string,\n> =\n IsAny<Fields> extends true\n ? unknown\n : {\n [K in keyof Config]: K extends keyof PluginConfigs<keyof Fields & string>\n ? // A union config (e.g. from a ternary passed directly as a plugin's\n // value) distributes through PluginFieldExtensionFor's conditional\n // and silently collapses the injected field to `never` once\n // intersected back together — reject it here instead, before it\n // can produce that confusing downstream error.\n IsUnion<Config[K]> extends true\n ? 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\">\n : PluginFieldExtensionShapeError<Fields, Config, K & string> extends true\n ? TypeLevelError<\"PluginFieldExtensions entry must be a Record<string, TailorAnyDBField>\">\n : PluginFieldConflict<Fields, Config, K & string, FileKeys> extends true\n ? TypeLevelError<\"plugin field extension conflicts with an existing field, a file key declared via .files(), or another plugin's field\">\n : PluginConfigs<keyof Fields & string>[K] &\n PluginConfigExcessProps<Fields, Config, K & string>\n : TypeLevelError<\"unknown plugin id\">;\n };\ntype DBFieldDescriptionFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = (description: string) => TailorDBField<WithDBFieldDescription<Defined>, Output, Nested>;\ntype DBFieldRelationFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = {\n <S extends RelationType, T extends TailorAnyDBType>(\n config: RelationConfig<S, T>,\n ): TailorDBField<WithDBFieldRelation<Defined, S>, Output, Nested>;\n <S extends RelationSelfConfig>(\n config: S,\n ): TailorDBField<WithDBFieldRelation<Defined, S>, Output, Nested>;\n};\ntype DBFieldIndexFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = () => TailorDBField<WithDBFieldIndex<Defined>, Output, Nested>;\ntype DBFieldUniqueFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = () => TailorDBField<WithDBFieldUnique<Defined>, Output, Nested>;\ntype DBFieldVectorFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = () => TailorDBField<WithDBFieldVector<Defined>, Output, Nested>;\ntype DBFieldHooksFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = <\n const H extends Hook<\n Output,\n Defined extends { default: true } ? Output | null | undefined : Output\n >,\n>(\n hooks: H,\n) => TailorDBField<WithDBFieldHooks<Defined, H>, Output, Nested>;\ntype DBFieldValidateFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = (\n ...validate: FieldValidateInput<Output>[]\n) => TailorDBField<WithDBFieldValidate<Defined>, Output, Nested>;\ntype DBFieldSerialFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = (\n config: SerialConfig<Defined[\"type\"] & (\"integer\" | \"string\")>,\n) => TailorDBField<WithDBFieldSerial<Defined>, Output, Nested>;\ntype DBFieldDescriptionMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldDescriptionFn<Defined, Output, Nested>\n : Defined extends { description: unknown }\n ? TypeLevelError<\".description() has already been set\">\n : DBFieldDescriptionFn<Defined, Output, Nested>;\ntype DBFieldRelationMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldRelationFn<Defined, Output, Nested>\n : Defined extends { relation: unknown }\n ? TypeLevelError<\".relation() has already been set\">\n : DBFieldRelationFn<Defined, Output, Nested>;\ntype DBFieldArrayCheck<A extends boolean, Ok, Msg extends string> = A extends true\n ? TypeLevelError<Msg>\n : Ok;\ntype DBFieldIndexMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldIndexFn<Defined, Output, Nested>\n : Defined extends { index: unknown }\n ? TypeLevelError<\".index() has already been set\">\n : DBFieldArrayCheck<\n Defined[\"array\"],\n DBFieldIndexFn<Defined, Output, Nested>,\n \"index cannot be set on array fields\"\n >;\ntype DBFieldUniqueMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldUniqueFn<Defined, Output, Nested>\n : Defined extends { unique: unknown }\n ? TypeLevelError<\".unique() has already been set\">\n : DBFieldArrayCheck<\n Defined[\"array\"],\n DBFieldUniqueFn<Defined, Output, Nested>,\n \"unique cannot be set on array fields\"\n >;\ntype DBFieldVectorMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldVectorFn<Defined, Output, Nested>\n : Defined extends { vector: unknown }\n ? TypeLevelError<\".vector() has already been set\">\n : Defined extends { type: \"string\"; array: false }\n ? DBFieldVectorFn<Defined, Output, Nested>\n : TypeLevelError<\"vector can only be set on non-array string fields\">;\ntype DBFieldHooksMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldHooksFn<Defined, Output, Nested>\n : Defined extends {\n serial: true;\n hooks: { create: false; update: false };\n }\n ? TypeLevelError<\"hooks cannot be set after serial\">\n : Defined extends {\n hooks: unknown;\n }\n ? TypeLevelError<\".hooks() has already been set\">\n : Defined extends { type: \"nested\" }\n ? TypeLevelError<\"hooks cannot be set on nested type fields\">\n : DBFieldHooksFn<Defined, Output, Nested>;\ntype DBFieldValidateMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldValidateFn<Defined, Output, Nested>\n : Defined extends { validate: unknown }\n ? TypeLevelError<\".validate() has already been set\">\n : DBFieldValidateFn<Defined, Output, Nested>;\ntype DBFieldSerialMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldSerialFn<Defined, Output, Nested>\n : Defined extends { serial: true }\n ? TypeLevelError<\".serial() has already been set\">\n : Defined extends { serial: false }\n ? TypeLevelError<\"serial cannot be set after hooks\">\n : IsAny<Output> extends true\n ? Defined extends { type: \"integer\" | \"string\"; array: false }\n ? DBFieldSerialFn<Defined, Output, Nested>\n : TypeLevelError<\"serial can only be set on non-array integer or string fields\">\n : null extends Output\n ? TypeLevelError<\"serial can only be set on non-array integer or string fields\">\n : Defined extends { type: \"integer\" | \"string\"; array: false }\n ? DBFieldSerialFn<Defined, Output, Nested>\n : TypeLevelError<\"serial can only be set on non-array integer or string fields\">;\ntype DBFieldDefaultFn<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> = (\n value: Output extends null ? NonNullable<Output> : Output,\n) => TailorDBField<WithDBFieldDefault<Defined>, Output, Nested>;\ntype DBFieldDefaultMethod<\n Defined extends DefinedDBFieldMetadata,\n Output,\n Nested extends Record<string, TailorAnyDBField>,\n> =\n IsAny<Defined> extends true\n ? DBFieldDefaultFn<Defined, Output, Nested>\n : Defined extends { default: unknown }\n ? TypeLevelError<\".default() has already been set\">\n : Defined extends { type: \"nested\" }\n ? TypeLevelError<\"default cannot be set on nested type fields\">\n : Defined extends { serial: true }\n ? TypeLevelError<\"default cannot be set on serial fields\">\n : null extends Output\n ? TypeLevelError<\"default cannot be set on optional fields\">\n : DBFieldDefaultFn<Defined, Output, Nested>;\n\n/**\n * Full TailorDBField interface with builder methods.\n * Extends the minimal structural interface from types/ with fluent API methods.\n */\nexport interface TailorDBField<\n Defined extends DefinedDBFieldMetadata = DefinedDBFieldMetadata,\n // oxlint-disable-next-line no-explicit-any\n Output = any,\n // Nested object fields, so a `db.object()` field keeps the shape it was declared with.\n // Every builder method passes it through; dropping it here would erase the shape as\n // soon as one is chained.\n Nested extends Record<string, TailorAnyDBField> = Record<string, TailorAnyDBField>,\n> extends Omit<TailorDBFieldBase<Defined, Output, Nested>, \"fields\"> {\n readonly fields: Nested;\n _metadata: DBFieldMetadata;\n\n /**\n * Parse and validate a value against this field's validation rules\n */\n parse(args: FieldParseArgs): StandardSchemaV1.Result<Output>;\n\n /**\n * typeName is not available on TailorDB fields.\n * Use typeName on pipeline fields (t.enum / t.object) instead.\n */\n typeName: DBFieldTypeNameMethod<Defined>;\n\n /**\n * Set a description for the field\n */\n description: DBFieldDescriptionMethod<Defined, Output, Nested>;\n\n /**\n * Define a relation to another table.\n */\n relation: DBFieldRelationMethod<Defined, Output, Nested>;\n\n /**\n * Add an index to the field\n */\n index: DBFieldIndexMethod<Defined, Output, Nested>;\n\n /**\n * Make the field unique (also adds an index)\n */\n unique: DBFieldUniqueMethod<Defined, Output, Nested>;\n\n /**\n * Enable vector search on the field (string type only)\n */\n vector: DBFieldVectorMethod<Defined, Output, Nested>;\n\n /**\n * Set a default value for the field on create. When the field is required,\n * this makes it optional in the Create input — the default fills in when\n * no value (or a nullish hook result) is provided.\n *\n * For datetime/date/time fields, pass `\"now\"` to use the operation timestamp.\n */\n default: DBFieldDefaultMethod<Defined, Output, Nested>;\n\n /**\n * Add hooks for create/update operations on this field.\n */\n hooks: DBFieldHooksMethod<Defined, Output, Nested>;\n\n /**\n * Add validation functions to the field.\n *\n * Validators receive `{ value, data, user }` and run after hooks and\n * built-in type validation; they are skipped when built-in validation\n * fails. For array fields, `value` is the complete array.\n */\n validate: DBFieldValidateMethod<Defined, Output, Nested>;\n\n /**\n * Configure serial/auto-increment behavior\n */\n serial: DBFieldSerialMethod<Defined, Output, Nested>;\n\n /**\n * Clone the field with optional overrides for field options.\n * The `array` option cannot change on fields with custom validation.\n */\n clone<const NewOpt extends DBFieldCloneOptions<Defined>>(\n options?: NewOpt,\n ): TailorDBField<\n WithDBFieldCloneOptions<Defined, NewOpt>,\n DBFieldCloneOutput<Output, NewOpt>,\n Nested\n >;\n}\n\n/**\n * Full TailorDBType interface with builder methods.\n * Extends the minimal structural interface from types/ with fluent API methods.\n */\nexport interface TailorDBType<\n // oxlint-disable-next-line no-explicit-any\n Fields extends Record<string, TailorAnyDBField> = any,\n User extends object = InferredAttributes,\n // oxlint-disable-next-line no-explicit-any\n Defined extends DefinedDBTypeMetadata = any,\n FileKeys extends string = never,\n> extends TailorDBTypeBase<Fields, User> {\n _description?: string;\n\n hooks(\n hook: DBTypeDuplicateInputGuard<\n Defined,\n \"hooks\",\n TypeHook<Fields>,\n \".hooks() has already been set\"\n >,\n ): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, \"hooks\">, FileKeys>;\n validate(\n fn: DBTypeDuplicateInputGuard<\n Defined,\n \"validate\",\n TypeValidateFn<Fields>,\n \".validate() has already been set\"\n >,\n ): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, \"validate\">, FileKeys>;\n features(\n features: DBTypeDuplicateInputGuard<\n Defined,\n \"features\",\n Omit<TypeFeatures, \"pluralForm\">,\n \".features() has already been set\"\n >,\n ): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, \"features\">, FileKeys>;\n indexes(\n ...indexes: DBTypeDuplicateRestGuard<\n Defined,\n \"indexes\",\n IndexDef<TailorDBType<Fields, User, Defined, FileKeys>>[],\n \".indexes() has already been set\"\n >\n ): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, \"indexes\">, FileKeys>;\n files<const F extends string>(\n files: DBTypeDuplicateInputGuard<\n Defined,\n \"files\",\n Record<F, string> & FileKeyConflictError<Fields, User>,\n \".files() has already been set\"\n >,\n ): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, \"files\">, FileKeys | F>;\n permission<\n U extends object = User,\n P extends TailorTypePermission<U, output<TailorDBType<Fields, User, Defined>>> =\n TailorTypePermission<U, output<TailorDBType<Fields, User, Defined>>>,\n >(\n permission: DBTypeDuplicateInputGuard<\n Defined,\n \"permission\",\n P,\n \".permission() has already been set\"\n >,\n ): TailorDBType<Fields, U, WithDBTypeMetadata<Defined, \"permission\">, FileKeys>;\n gqlPermission<\n U extends object = User,\n P extends TailorTypeGqlPermission<U> = TailorTypeGqlPermission<U>,\n >(\n permission: DBTypeDuplicateInputGuard<\n Defined,\n \"gqlPermission\",\n P,\n \".gqlPermission() has already been set\"\n >,\n ): TailorDBType<Fields, U, WithDBTypeMetadata<Defined, \"gqlPermission\">, FileKeys>;\n description(\n description: DBTypeDuplicateInputGuard<\n Defined,\n \"description\",\n string,\n \".description() has already been set\"\n >,\n ): TailorDBType<Fields, User, WithDBTypeMetadata<Defined, \"description\">, FileKeys>;\n pickFields<K extends keyof Fields>(keys: K[]): Pick<Fields, K>;\n pickFields<K extends keyof Fields, const Opt extends FieldOptions>(\n keys: K[],\n options: Opt & DBFieldsCloneOptionsGuard<Fields, K, Opt>,\n ): {\n [P in K]: Fields[P] extends TailorDBField<infer D, infer O>\n ? TailorDBField<WithDBFieldCloneOptions<D, Opt>, DBFieldCloneOutput<O, Opt>>\n : never;\n };\n omitFields<K extends keyof Fields>(keys: K[]): Omit<Fields, K>;\n plugin<const Config extends Record<string, unknown>>(\n config: Config & PluginConfigGuard<Fields, Config, FileKeys>,\n ): TailorDBType<PluginExtendedFields<Fields, Config>, User, Defined, FileKeys>;\n}\n\nexport type TailorDBInstance<\n // oxlint-disable-next-line no-explicit-any\n Fields extends Record<string, TailorAnyDBField> = any,\n User extends object = InferredAttributes,\n // oxlint-disable-next-line no-explicit-any\n Defined extends DefinedDBTypeMetadata = any,\n FileKeys extends string = never,\n> = TailorDBType<Fields, User, Defined, FileKeys>;\n\ninterface RelationConfig<S extends RelationType, T extends TailorDBType> {\n type: S;\n toward:\n | {\n table: T;\n as?: string;\n key?: keyof T[\"fields\"] & string;\n type?: never;\n }\n | {\n /**\n * @deprecated since 2.6.0 — use `table` instead. codemod: v3/relation-toward-table\n */\n type: T;\n as?: string;\n key?: keyof T[\"fields\"] & string;\n table?: never;\n };\n backward?: string;\n}\n\n// Special config variant for self-referencing relations\ntype RelationSelfConfig = {\n type: RelationType;\n toward:\n | {\n table: \"self\";\n as?: string;\n key?: string;\n type?: never;\n }\n | {\n /**\n * @deprecated since 2.6.0 — use `table` instead. codemod: v3/relation-toward-table\n */\n type: \"self\";\n as?: string;\n key?: string;\n table?: never;\n };\n backward?: string;\n};\n\ntype DBFieldDefined<T extends TailorFieldType, Opt extends FieldOptions> = {\n type: T;\n array: Opt extends { array: true } ? true : false;\n};\ntype DBFieldOutput<\n T extends TailorFieldType,\n Opt extends FieldOptions,\n OutputBase = TailorToTs[T],\n> = FieldOutput<OutputBase, Opt>;\ntype TailorDBFieldInstance<\n T extends TailorFieldType,\n Opt extends FieldOptions,\n OutputBase = TailorToTs[T],\n> = TailorDBField<DBFieldDefined<T, Opt>, DBFieldOutput<T, Opt, OutputBase>>;\ntype TailorDBFieldRuntimeInstance<\n T extends TailorFieldType,\n Opt extends FieldOptions,\n OutputBase = TailorToTs[T],\n> = TailorDBFieldRuntime<DBFieldDefined<T, Opt>, DBFieldOutput<T, Opt, OutputBase>>;\ntype TailorDBFieldRuntime<Defined extends DefinedDBFieldMetadata, Output> = Omit<\n TailorDBFieldBase<Defined, Output>,\n \"fields\"\n> & {\n readonly fields: Record<string, TailorAnyDBField>;\n _metadata: DBFieldMetadata;\n description(description: string): object;\n typeName(typeName: string): object;\n validate(...validate: FieldValidateInput<Output>[]): object;\n relation(config: RelationConfig<RelationType, TailorDBType> | RelationSelfConfig): object;\n index(): object;\n unique(): object;\n vector(): object;\n default(value: unknown): object;\n hooks(hooks: Hook<Output>): object;\n serial(config: SerialConfig): object;\n clone(options?: FieldOptions): TailorDBFieldRuntime<DefinedDBFieldMetadata, AnyBuilderMethod>;\n parse(args: FieldParseArgs): StandardSchemaV1.Result<Output>;\n _setRawRelation(relation: RawRelationConfig): void;\n};\n\n/**\n * Creates a new TailorDBField instance.\n * @param type - Field type\n * @param options - Field options\n * @param fields - Nested fields for object-like types\n * @param values - Allowed values for enum-like fields\n * @returns A new TailorDBField\n */\nfunction createTailorDBField<\n const T extends TailorFieldType,\n const TOptions extends FieldOptions,\n const OutputBase = TailorToTs[T],\n>(\n type: T,\n options?: TOptions,\n fields?: Record<string, TailorAnyDBField>,\n values?: AllowedValues,\n): TailorDBFieldInstance<T, TOptions, OutputBase>;\nfunction createTailorDBField<const T extends TailorFieldType, const TOptions extends FieldOptions>(\n type: T,\n options?: TOptions,\n fields?: Record<string, TailorAnyDBField>,\n values?: AllowedValues,\n): object {\n return createTailorDBFieldRuntime(type, options, fields, values);\n}\n\nfunction createTailorDBFieldRuntime<\n const T extends TailorFieldType,\n const TOptions extends FieldOptions,\n const OutputBase = TailorToTs[T],\n>(\n type: T,\n options?: TOptions,\n fields?: Record<string, TailorAnyDBField>,\n values?: AllowedValues,\n): TailorDBFieldRuntimeInstance<T, TOptions, OutputBase> {\n type FieldValue = DBFieldOutput<T, TOptions, OutputBase>;\n type FieldType = TailorDBFieldRuntimeInstance<T, TOptions, OutputBase>;\n\n const _metadata: DBFieldMetadata = { required: true };\n let _rawRelation: RawRelationConfig | undefined;\n\n if (options) {\n if (options.optional === true) {\n _metadata.required = false;\n }\n if (options.array === true) {\n _metadata.array = true;\n }\n }\n if (values) {\n _metadata.allowedValues = mapAllowedValues(values);\n }\n\n function parseInternal(args: FieldParseInternalArgs): StandardSchemaV1.Result<FieldValue> {\n return parseFieldInternal<T, FieldValue>({\n ...args,\n field,\n });\n }\n\n function cloneWith(metadataUpdates: Partial<DBFieldMetadata>) {\n const cloned = field.clone();\n Object.assign(cloned._metadata, metadataUpdates);\n return cloned;\n }\n\n const field: FieldType = {\n type,\n fields: fields ?? {},\n _defined: undefined as unknown as DBFieldDefined<T, TOptions>,\n _output: undefined as FieldValue,\n _metadata,\n\n get metadata() {\n return { ...this._metadata };\n },\n\n get rawRelation(): Readonly<RawRelationConfig> | undefined {\n return _rawRelation ? { ..._rawRelation, toward: { ..._rawRelation.toward } } : undefined;\n },\n\n description(description: string) {\n return cloneWith({ description });\n },\n\n typeName(typeName: string) {\n return cloneWith({ typeName });\n },\n\n validate(...validateInputs: FieldValidateInput<FieldValue>[]) {\n return cloneWith({ validate: validateInputs });\n },\n\n parse(args: FieldParseArgs): StandardSchemaV1.Result<FieldValue> {\n return parseInternal({\n value: args.value,\n data: args.data,\n invoker: args.invoker,\n pathArray: [],\n });\n },\n\n // TailorDBField specific methods\n relation(config: RelationConfig<RelationType, TailorDBType> | RelationSelfConfig) {\n const cloned = field.clone();\n // The public type is a nested union (RelationConfig | RelationSelfConfig,\n // each with a `{ table } | { type }` toward), which TS's \"in\" narrowing\n // can't discriminate across cleanly. Re-view it as the flat two-branch\n // shape it always is at runtime — the `table?: never` / `type?: never`\n // markers above already forbid both keys from being set together.\n const toward = config.toward as\n | { table: TailorDBType | \"self\" }\n | { type: TailorDBType | \"self\" };\n const towardTarget = \"table\" in toward ? toward.table : toward.type;\n const targetTable = towardTarget === \"self\" ? \"self\" : towardTarget.name;\n cloned._setRawRelation({\n type: config.type,\n toward: {\n table: targetTable,\n as: config.toward.as,\n key: config.toward.key,\n },\n backward: config.backward,\n });\n return cloned;\n },\n\n index() {\n return cloneWith({ index: true });\n },\n\n unique() {\n return cloneWith({ unique: true, index: true });\n },\n\n vector() {\n return cloneWith({ vector: true });\n },\n\n // oxlint-disable-next-line no-explicit-any\n default(value: any) {\n // oxlint-disable-next-line no-explicit-any\n return cloneWith({ default: value }) as any;\n },\n\n hooks(hooks: Hook<FieldValue>) {\n return cloneWith({ hooks });\n },\n\n serial(config: SerialConfig) {\n return cloneWith({ serial: config });\n },\n\n clone(cloneOptions?: FieldOptions) {\n if (\n this._metadata.validate?.length &&\n cloneOptions?.array !== undefined &&\n cloneOptions.array !== (this._metadata.array === true)\n ) {\n throw new Error(\"Cannot change the array option on a field with custom validation\");\n }\n\n // Deep clone nested object fields if present\n let clonedFields = fields;\n if (fields) {\n const cloned: Record<string, TailorAnyDBField> = {};\n for (const [key, field] of Object.entries(fields)) {\n cloned[key] = field.clone();\n }\n clonedFields = cloned;\n }\n\n // Create a new field with cloned configuration\n const clonedField = createTailorDBFieldRuntime(type, options, clonedFields, values);\n\n // Deep copy metadata using cloneDeep (preserves function references)\n Object.assign(clonedField._metadata, cloneDeep(this._metadata));\n\n // Apply new options if provided\n if (cloneOptions) {\n if (cloneOptions.optional !== undefined) {\n clonedField._metadata.required = !cloneOptions.optional;\n }\n if (cloneOptions.array !== undefined) {\n clonedField._metadata.array = cloneOptions.array;\n }\n }\n\n // Copy raw relation if exists\n if (_rawRelation) {\n clonedField._setRawRelation(cloneDeep(_rawRelation));\n }\n\n return clonedField;\n },\n\n _setRawRelation(relation: RawRelationConfig) {\n _rawRelation = relation;\n },\n };\n\n return field;\n}\n\nconst createField = createTailorDBField;\n\n/**\n * Create a UUID field.\n * @param options - Field configuration options\n * @returns A UUID field\n * @example db.uuid()\n * @example db.uuid({ optional: true })\n */\nfunction uuid<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"uuid\", options);\n}\n\n/**\n * Create a string field.\n * @param options - Field configuration options\n * @returns A string field\n * @example db.string()\n * @example db.string({ optional: true })\n */\nfunction string<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"string\", options);\n}\n\n/**\n * Create a boolean field.\n * Note: The method name is `bool` but creates a `boolean` type field.\n * @param options - Field configuration options\n * @returns A boolean field\n * @example db.bool()\n * @example db.bool({ optional: true })\n */\nfunction bool<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"boolean\", options);\n}\n\n/**\n * Create an integer field.\n * @param options - Field configuration options\n * @returns An integer field\n * @example db.int()\n * @example db.int({ optional: true })\n */\nfunction int<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"integer\", options);\n}\n\n/**\n * Create a float (decimal number) field.\n * @param options - Field configuration options\n * @returns A float field\n * @example db.float()\n * @example db.float({ optional: true })\n */\nfunction float<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"float\", options);\n}\n\ninterface DecimalFieldOptions extends FieldOptions {\n scale?: number;\n}\n\n/**\n * Create a decimal field (stored as string for precision).\n * @param options - Field configuration options including optional scale (0-12)\n * @returns A decimal field\n * @example db.decimal()\n * @example db.decimal({ scale: 2 })\n * @example db.decimal({ scale: 2, optional: true })\n */\nfunction decimal<const Opt extends DecimalFieldOptions>(options?: Opt) {\n if (options?.scale !== undefined) {\n if (!Number.isInteger(options.scale) || options.scale < 0 || options.scale > 12) {\n throw new Error(\"scale must be an integer between 0 and 12\");\n }\n }\n const field = createField(\"decimal\", options);\n if (options?.scale !== undefined) {\n field._metadata.scale = options.scale;\n }\n return field;\n}\n\n/**\n * Create a date field (date only, no time component).\n * Format: \"yyyy-MM-dd\"\n * @param options - Field configuration options\n * @returns A date field\n * @example db.date()\n */\nfunction date<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"date\", options);\n}\n\n/**\n * Create a datetime field (date and time).\n * Format: ISO 8601, such as \"yyyy-MM-ddTHH:mm:ssZ\" or \"yyyy-MM-ddTHH:mm:ss+09:00\"\n * @param options - Field configuration options\n * @returns A datetime field\n * @example db.datetime()\n */\nfunction datetime<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"datetime\", options);\n}\n\n/**\n * Create a time field (time only, no date component).\n * Format: \"HH:mm\"\n * @param options - Field configuration options\n * @returns A time field\n * @example db.time()\n */\nfunction time<const Opt extends FieldOptions>(options?: Opt) {\n return createField(\"time\", options);\n}\n\n/**\n * Create an enum field with at least one allowed string value.\n * @param values - Array of allowed string values, or array of `{ value, description }` objects\n * @param options - Field configuration options\n * @returns An enum field\n * @example db.enum([\"active\", \"inactive\", \"suspended\"])\n * @example db.enum([\"small\", \"medium\", \"large\"], { optional: true })\n */\nfunction _enum<const V extends AllowedValues, const Opt extends FieldOptions>(\n values: V,\n options?: Opt,\n): TailorDBField<\n { type: \"enum\"; array: Opt extends { array: true } ? true : false },\n FieldOutput<AllowedValuesOutput<V>, Opt>\n> {\n return createField<\"enum\", Opt, AllowedValuesOutput<V>>(\"enum\", options, undefined, values);\n}\n\n/**\n * Create a nested object field with sub-fields.\n * @param fields - Record of nested field definitions\n * @param options - Field configuration options\n * @returns A nested object field\n * @example db.object({ street: db.string(), city: db.string(), zip: db.string() })\n * @example db.object({ name: db.string() }, { optional: true })\n */\nfunction object<\n const F extends Record<string, TailorAnyDBField> &\n ExcludeNestedDBFields<F> &\n ExcludeHookedDBFields<F> &\n ExcludeDefaultedDBFields<F>,\n const Opt extends FieldOptions,\n>(fields: F, options?: Opt) {\n return createField(\"nested\", options, fields) as unknown as TailorDBField<\n { type: \"nested\"; array: Opt extends { array: true } ? true : false },\n FieldOutput<InferFieldsOutput<F>, Opt>,\n F\n >;\n}\n\n/**\n * Creates a new TailorDBType instance.\n * @param name - Table name\n * @param fields - Field definitions\n * @param options - Table options\n * @param options.pluralForm - Optional plural form\n * @param options.description - Optional description\n * @returns A new TailorDBType\n */\nfunction createTailorDBType<\n // oxlint-disable-next-line no-explicit-any\n const Fields extends Record<string, TailorAnyDBField> = any,\n User extends object = InferredAttributes,\n>(\n name: string,\n fields: Fields,\n options: { pluralForm?: string; description?: string },\n): TailorDBType<Fields, User, DefinedDBTypeMetadata> {\n let _description = options.description;\n let _settings: TypeFeatures = {};\n let _indexes: IndexDef<TailorDBType<Fields, User, DefinedDBTypeMetadata>>[] = [];\n const _permissions: RawPermissions = {};\n let _files: Record<string, string> = {};\n const _plugins: PluginAttachment[] = [];\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n let _typeHook: { create?: Function; update?: Function } | undefined;\n // oxlint-disable-next-line typescript/no-unsafe-function-type\n let _typeValidate: Function | undefined;\n const _definedMethods = new Set<keyof DefinedDBTypeMetadata>();\n if (options.description !== undefined) {\n _definedMethods.add(\"description\");\n }\n\n function runMethodOnce<T>(method: keyof DefinedDBTypeMetadata, action: () => T): T {\n if (_definedMethods.has(method)) {\n throw new Error(`.${method}() has already been set`);\n }\n const result = action();\n _definedMethods.add(method);\n return result;\n }\n type TypeAfter<Key extends keyof DefinedDBTypeMetadata> = TailorDBType<\n Fields,\n User,\n WithDBTypeMetadata<DefinedDBTypeMetadata, Key>\n >;\n type TypeAfterUser<\n NextUser extends object,\n Key extends keyof DefinedDBTypeMetadata,\n > = TailorDBType<Fields, NextUser, WithDBTypeMetadata<DefinedDBTypeMetadata, Key>>;\n type TypeAfterPlugin<Config extends Record<string, unknown>> = TailorDBType<\n PluginExtendedFields<Fields, Config>,\n User,\n DefinedDBTypeMetadata\n >;\n\n if (options.pluralForm) {\n if (name === options.pluralForm) {\n throw new Error(`The name and the plural form must be different. name=${name}`);\n }\n _settings.pluralForm = options.pluralForm;\n }\n\n const dbType: TailorDBType<Fields, User, DefinedDBTypeMetadata> = {\n name,\n fields: { ...fields },\n _output: null as unknown as InferFieldsOutput<Fields>,\n _description,\n\n get metadata(): TailorDBTypeMetadata {\n // Convert indexes to the format expected by the manifest\n const indexes: Record<string, { fields: string[]; unique?: boolean }> = {};\n if (_indexes.length > 0) {\n _indexes.forEach((index) => {\n const fieldNames = index.fields.map((field) => String(field));\n const key = index.name || `idx_${fieldNames.join(\"_\")}`;\n indexes[key] = {\n fields: fieldNames,\n unique: index.unique,\n };\n });\n }\n\n return {\n name: this.name,\n description: _description,\n settings: _settings,\n permissions: _permissions,\n files: _files,\n ...(Object.keys(indexes).length > 0 && { indexes }),\n ...(_typeHook && { typeHook: _typeHook }),\n ...(_typeValidate && { typeValidate: _typeValidate }),\n };\n },\n\n hooks(hook: TypeHook<Fields>): TypeAfter<\"hooks\"> {\n return runMethodOnce(\"hooks\", () => {\n _typeHook = hook;\n return this as TypeAfter<\"hooks\">;\n });\n },\n\n validate(fn: TypeValidateFn<Fields>): TypeAfter<\"validate\"> {\n return runMethodOnce(\"validate\", () => {\n _typeValidate = fn;\n return this as TypeAfter<\"validate\">;\n });\n },\n\n features(features: Omit<TypeFeatures, \"pluralForm\">): TypeAfter<\"features\"> {\n return runMethodOnce(\"features\", () => {\n _settings = {\n ..._settings,\n ...features,\n };\n return this as TypeAfter<\"features\">;\n });\n },\n\n indexes(\n ...indexes: IndexDef<TailorDBType<Fields, User, DefinedDBTypeMetadata>>[]\n ): TypeAfter<\"indexes\"> {\n return runMethodOnce(\"indexes\", () => {\n _indexes = indexes;\n return this as TypeAfter<\"indexes\">;\n });\n },\n\n files<const F extends string>(\n files: Record<F, string> & FileKeyConflictError<Fields, User>,\n ): TailorDBType<Fields, User, WithDBTypeMetadata<DefinedDBTypeMetadata, \"files\">, F> {\n return runMethodOnce(\"files\", () => {\n _files = files;\n return this as TailorDBType<\n Fields,\n User,\n WithDBTypeMetadata<DefinedDBTypeMetadata, \"files\">,\n F\n >;\n });\n },\n\n permission<\n U extends object = User,\n P extends TailorTypePermission<U, output<TailorDBType<Fields, User, DefinedDBTypeMetadata>>> =\n TailorTypePermission<U, output<TailorDBType<Fields, User, DefinedDBTypeMetadata>>>,\n >(permission: P): TypeAfterUser<U, \"permission\"> {\n return runMethodOnce(\"permission\", () => {\n const ret = this as unknown as TypeAfterUser<U, \"permission\">;\n _permissions.record = permission as RawPermissions[\"record\"];\n return ret;\n });\n },\n\n gqlPermission<\n U extends object = User,\n P extends TailorTypeGqlPermission<U> = TailorTypeGqlPermission<U>,\n >(permission: P): TypeAfterUser<U, \"gqlPermission\"> {\n return runMethodOnce(\"gqlPermission\", () => {\n const ret = this as unknown as TypeAfterUser<U, \"gqlPermission\">;\n _permissions.gql = permission as RawPermissions[\"gql\"];\n return ret;\n });\n },\n\n description(description: string): TypeAfter<\"description\"> {\n return runMethodOnce(\"description\", () => {\n _description = description;\n this._description = description;\n return this as TypeAfter<\"description\">;\n });\n },\n\n pickFields<K extends keyof Fields, const Opt extends FieldOptions>(keys: K[], options?: Opt) {\n const result = {} as Record<K, TailorAnyDBField>;\n for (const key of keys) {\n const field = this.fields[key] as TailorAnyDBField | undefined;\n if (!field) {\n // A plugin-injected field is only added to `fields` after `tailor\n // generate` runs — see the \"Injecting fields into the attached\n // table's type\" section of the plugin docs.\n throw new Error(\n `pickFields(): field \"${String(key)}\" does not exist on this table yet. If it comes from a plugin's .plugin() call, it is only added to the table after \\`tailor generate\\` runs.`,\n );\n }\n if (options) {\n result[key] = field.clone(options);\n } else {\n result[key] = field;\n }\n }\n // oxlint-disable-next-line no-explicit-any\n return result as any;\n },\n\n omitFields<K extends keyof Fields>(keys: K[]): Omit<Fields, K> {\n const keysSet = new Set(keys);\n const result = {} as Record<string, TailorAnyDBField>;\n for (const key in this.fields) {\n if (Object.hasOwn(this.fields, key) && !keysSet.has(key as unknown as K)) {\n result[key] = this.fields[key] as TailorAnyDBField;\n }\n }\n return result as Omit<Fields, K>;\n },\n\n get plugins(): PluginAttachment[] {\n return _plugins;\n },\n\n plugin<const Config extends Record<string, unknown>>(\n config: Config & PluginConfigGuard<Fields, Config, never>,\n ): TypeAfterPlugin<Config> {\n for (const [pluginId, pluginConfig] of Object.entries(config)) {\n _plugins.push({ pluginId, config: pluginConfig });\n }\n return this as unknown as TypeAfterPlugin<Config>;\n },\n };\n\n return brandValue(dbType, \"tailordb-type\");\n}\n\nconst idField = uuid();\ntype idField = typeof idField;\ntype DBTable<\n F extends { id?: never } & Record<string, TailorAnyDBField>,\n Defined extends DefinedDBTypeMetadata = DefinedDBTypeMetadata,\n> = TailorDBInstance<{ id: idField } & F, InferredAttributes, Defined>;\n\n/**\n * Creates a new database table with the specified fields.\n * An `id` field (UUID) is automatically added to every table.\n * @param name - The name of the table, or a tuple of [name, pluralForm]\n * @param fields - The field definitions for the table\n * @returns A new TailorDB table instance\n * @example\n * export const user = db.table(\"User\", {\n * name: db.string(),\n * email: db.string(),\n * age: db.int({ optional: true }),\n * role: db.enum([\"admin\", \"member\"]),\n * ...db.fields.timestamps(),\n * });\n * // Always export both the value and type:\n * export type user = typeof user;\n */\nfunction dbTable<const F extends { id?: never } & Record<string, TailorAnyDBField>>(\n name: string | [string, string],\n fields: F,\n): DBTable<F>;\n/**\n * Creates a new database table with the specified fields and description.\n * An `id` field (UUID) is automatically added to every table.\n * @param name - The name of the table, or a tuple of [name, pluralForm]\n * @param description - A description of the table\n * @param fields - The field definitions for the table\n * @returns A new TailorDB table instance\n */\nfunction dbTable<const F extends { id?: never } & Record<string, TailorAnyDBField>>(\n name: string | [string, string],\n description: string,\n fields: F,\n): DBTable<F, WithDBTypeMetadata<DefinedDBTypeMetadata, \"description\">>;\nfunction dbTable<const F extends { id?: never } & Record<string, TailorAnyDBField>>(\n name: string | [string, string],\n fieldsOrDescription: string | F,\n fields?: F,\n): DBTable<F> | DBTable<F, WithDBTypeMetadata<DefinedDBTypeMetadata, \"description\">> {\n const typeName = Array.isArray(name) ? name[0] : name;\n const pluralForm = Array.isArray(name) ? name[1] : undefined;\n\n let description: string | undefined;\n let fieldDef: F;\n if (typeof fieldsOrDescription === \"string\") {\n description = fieldsOrDescription;\n fieldDef = fields as F;\n } else {\n fieldDef = fieldsOrDescription;\n }\n return createTailorDBType<{ id: idField } & F>(\n typeName,\n {\n id: idField,\n ...fieldDef,\n },\n { pluralForm, description },\n );\n}\n\n// `Function.prototype.toString()` of this hook is embedded verbatim into deployed\n// schemas and migration diffs (see parser/service/tailordb/hooks-validate-precompiled-expr.ts\n// and field.ts). Its source text depends on how the SDK itself was built (e.g.\n// minification), so a fixed expression is pinned onto it directly here instead -\n// configure cannot import parser's `setPrecompiledScriptExpr` runtime helper across\n// the module boundary, only the symbol registry key and map types. Keep\n// this literal in sync with the \"timestamps() updatedAt hook resolves to the pinned\n// expr\" test in parser/service/tailordb/field.precompiled.test.ts, which fails if it\n// ever drifts from what this hook's own source naturally produces.\ntype TimestampsUpdatedAtHookFn = UpdateHookFn<string | Date | null, string | Date>;\nconst timestampsUpdatedAtHook: TimestampsUpdatedAtHookFn = ({ input, now }) => input ?? now;\nconst PRECOMPILED_EXPR_KEY: PrecompiledScriptExprKey =\n \"tailor-platform/sdk:precompiled-script-expr\";\nconst PRECOMPILED_EXPR_SYMBOL = Symbol.for(PRECOMPILED_EXPR_KEY);\n(timestampsUpdatedAtHook as unknown as Record<symbol, PrecompiledScriptExprMap>)[\n PRECOMPILED_EXPR_SYMBOL\n] = {\n \"hooks.update\":\n \"(({ input, now }) => input ?? now)({ input: _value, oldValue: _oldValue, invoker: _principal, now: _now })\",\n};\n\n/** TailorDB schema builder utilities for defining tables and fields. */\nexport const db = {\n table: dbTable,\n uuid,\n string,\n bool,\n int,\n float,\n decimal,\n date,\n datetime,\n time,\n enum: _enum,\n object,\n fields: {\n /**\n * Creates standard timestamp fields (createdAt, updatedAt) with automatic defaults.\n * Both fields default to the current time on create. updatedAt is also refreshed on update.\n * User-specified values are respected when provided (e.g. seeding historical records).\n * @returns An object with createdAt and updatedAt fields\n * @example\n * const model = db.table(\"Model\", {\n * name: db.string(),\n * ...db.fields.timestamps(),\n * });\n */\n timestamps: () => ({\n createdAt: datetime().default(\"now\").description(\"Record creation timestamp\"),\n updatedAt: datetime()\n .default(\"now\")\n .hooks({ update: timestampsUpdatedAtHook })\n .description(\"Record update timestamp\"),\n }),\n },\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./service-CuqkHP1r.mjs";export{e as createExecutorService};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{n as e}from"./brand-C8nMKhJC.mjs";import{i as t,n}from"./logger-72hM4JWZ.mjs";import*as r from"pathe";import{z as i}from"zod";import*as a from"node:fs";import{pathToFileURL as o}from"node:url";const s=i.custom(e=>typeof e==`function`),c=`tailorImportNonce`;let l=0;function beginUserModuleRun(){l+=1}function currentImportNonce(){return l===0?void 0:String(l)}function importUserModule(e){let t=o(e),n=currentImportNonce();return n&&t.searchParams.set(c,n),import(t.href)}const ee=[`**/*.test.ts`,`**/*.spec.ts`],u=new Set;function loadFilesWithIgnores(e,t){if(e.files.length===0)return[];let i=resolveFiles(e,t),a=e.files.every(e=>r.isAbsolute(e));if(i.matchedAnyPattern||t===process.cwd()||a)return i.files;let o=`${t}\0${e.files.join(`\0`)}`;return u.has(o)||(u.add(o),n.warn(`No files matched "${e.files.join(`, `)}" relative to "${t}"; falling back to process.cwd(). Update this config's file patterns to be relative to its own directory before v2, when this fallback will be removed.`)),resolveFiles(e,process.cwd()).files}function resolveFiles(e,t){let i=e.ignores===void 0,o=e.ignores??ee,s=i?o:o.map(e=>r.resolve(t,e)),c=[],l=!1;for(let i of e.files){let e=r.resolve(t,i);try{let t=a.globSync(e);t.length>0&&(l=!0);let n=t.filter(e=>!s.some(t=>r.matchesGlob(e,t)));c.push(...n)}catch(e){l=!0,n.warn(`Failed to glob pattern "${i}": ${String(e)}`)}}return{files:c,matchedAnyPattern:l}}const d=Object.keys({uuid:!0,string:!0,boolean:!0,integer:!0,float:!0,decimal:!0,enum:!0,date:!0,datetime:!0,time:!0,nested:!0}),f=i.enum(d),p={"1-1":`1-1`,oneToOne:`1-1`,"n-1":`n-1`,manyToOne:`n-1`,"N-1":`n-1`,keyOnly:`keyOnly`},m=Object.keys(p);function fieldRef(e){return`Field "${e.fieldName}" on table "${e.tableName}"`}function validateRelationConfig(e,t){if(!e.type)throw Error(`${fieldRef(t)} has a relation but is missing the required 'type' property. Valid values: ${m.join(`, `)}.`);if(!(e.type in p))throw Error(`${fieldRef(t)} has invalid relation type '${e.type}'. Valid values: ${m.join(`, `)}.`);if(e.toward.table!==`self`&&!t.allTableNames.has(e.toward.table))throw Error(`${fieldRef(t)} references unknown table "${e.toward.table}".`)}function processRelationMetadata(e,t,n=!1){let r=p[e.type]===`1-1`,i=e.toward.key??`id`,a=e.toward.table===`self`?t.tableName:e.toward.table,o=!n,s=!n&&r;return{index:o,foreignKey:!0,relationType:e.type,unique:s,foreignKeyType:a,foreignKeyField:i}}function buildRelationInfo(e,t){if(e.type===`keyOnly`)return;let n=p[e.type]===`1-1`,r=e.toward.key??`id`,i=e.toward.table===`self`?t.tableName:e.toward.table,a=e.toward.as;return a||=t.fieldName.replace(/(ID|Id|id)$/u,``),{targetType:i,forwardName:a,backwardName:e.backward??``,key:r,unique:n}}function applyRelationMetadataToFieldConfig(e,t){return{...e,index:t.index,foreignKey:t.foreignKey,unique:t.unique,foreignKeyType:t.foreignKeyType,foreignKeyField:t.foreignKeyField}}function normalizeGqlOperations(e){return e===`query`?{create:!1,update:!1,delete:!1,read:!0}:e}const h=i.union([i.literal(`query`),i.strictObject({create:i.boolean().optional().describe(`Enable create mutation (default: true)`),update:i.boolean().optional().describe(`Enable update mutation (default: true)`),delete:i.boolean().optional().describe(`Enable delete mutation (default: true)`),read:i.boolean().optional().describe(`Enable read queries - get, list, aggregation (default: true)`)})]).describe(`Configuration for GraphQL operations on a TailorDB table.
|
|
2
|
+
All operations are enabled by default (undefined or true = enabled, false = disabled).`).transform(e=>normalizeGqlOperations(e)),g=i.strictObject({value:i.string(),description:i.string().optional()}),_=i.strictObject({required:i.boolean().optional().describe(`Whether the field is required`),array:i.boolean().optional().describe(`Whether the field is an array`),description:i.string().optional().describe(`Field description`),typeName:i.string().optional().describe(`Type name for nested or enum fields`),allowedValues:i.array(g).optional().describe(`Allowed values for enum fields`),index:i.boolean().optional().describe(`Whether the field is indexed for faster queries`),unique:i.boolean().optional().describe(`Whether the field value must be unique`),vector:i.boolean().optional().describe(`Whether the field is a vector field for similarity search`),foreignKey:i.boolean().optional().describe(`Whether the field is a foreign key`),foreignKeyType:i.string().optional().describe(`Target table name for foreign key relations`),foreignKeyField:i.string().optional().describe(`Target field name for foreign key relations`),hooks:i.strictObject({create:s.optional().describe(`Hook function called on record creation`),update:s.optional().describe(`Hook function called on record update`)}).optional().describe(`Lifecycle hooks for the field`),validate:i.array(s).optional().describe(`Validation functions for the field`),serial:i.strictObject({start:i.number().describe(`Starting value for the serial sequence`),maxValue:i.number().optional().describe(`Maximum value for the serial sequence`),format:i.string().optional().describe(`Format string for serial value (string type only)`)}).optional().describe(`Serial (auto-increment) configuration`),scale:i.number().int().min(0).max(12).optional().describe(`Decimal scale (number of digits after decimal point, 0-12)`),default:i.unknown().optional().describe(`Default value for the field on create`)}),te=i.enum(m),ne=i.strictObject({type:te.describe(`Relation cardinality type`),toward:i.strictObject({table:i.string().describe(`Target table name, or 'self' for self-relations`),as:i.string().optional().describe(`Custom forward relation name`),key:i.string().optional().describe(`Target field to join on (default: 'id')`)}),backward:i.string().optional().describe(`Backward relation name on the target table`)}),v=i.lazy(()=>i.object({type:f,fields:i.record(i.string(),v).optional(),metadata:_,rawRelation:ne.optional()})),y=i.strictObject({pluralForm:i.string().optional().describe(`Custom plural form of the table name for GraphQL`),aggregation:i.boolean().optional().describe(`Enable aggregation queries for this table`),bulkUpsert:i.boolean().optional().describe(`Enable bulk upsert mutation for this table`),gqlOperations:h.optional().describe(`Configure GraphQL operations for this table. Use "query" for read-only mode, or an object for granular control.`),publishEvents:i.boolean().optional().describe(`Enable publishing events for this table.
|
|
3
|
+
When enabled, record creation/update/deletion events are published.
|
|
4
|
+
If not specified, this is automatically set to true when an executor uses this table
|
|
5
|
+
with recordCreated/recordUpdated/recordDeleted triggers. If explicitly set to false
|
|
6
|
+
while an executor uses this table, an error will be thrown during apply.`)}),b=i.union([i.strictObject({user:i.string()}),i.string(),i.boolean(),i.array(i.string()),i.array(i.boolean())],{error:e=>{if(typeof e.input==`object`&&e.input!==null){let t=Object.keys(e.input);return t.length===1?`"${t[0]}" operand is not supported in gqlPermission. Use permission() for record-level conditions.`:`Operand object must have exactly 1 key`}return`Invalid operand in gqlPermission`}}),x=i.union([b,i.strictObject({record:i.string()}),i.strictObject({oldRecord:i.string()}),i.strictObject({newRecord:i.string()})]),S=i.enum([`=`,`!=`,`in`,`not in`,`hasAny`,`not hasAny`]),C=i.tuple([x,S,x]).readonly(),re=i.tuple([b,S,b]).readonly(),w=i.union([i.strictObject({conditions:i.union([C,i.array(C).readonly()]),description:i.string().optional(),permit:i.boolean().optional()}),i.tuple([x,S,x]).readonly(),i.tuple([x,S,x,i.boolean()]).readonly(),i.array(i.union([C,i.boolean()])).refine(e=>{let t=e.findIndex(e=>typeof e==`boolean`);return t===-1||t===e.length-1},{message:`Boolean permit flag must only appear at the end`}).readonly()]),ie=i.enum([`read`,`create`,`update`,`delete`,`aggregate`,`bulkUpsert`]),ae=i.strictObject({conditions:i.array(re).readonly(),actions:i.union([i.literal(`all`),i.array(ie).readonly()]),permit:i.boolean().optional(),description:i.string().optional()}),oe=i.strictObject({record:i.strictObject({create:i.array(w).readonly(),read:i.array(w).readonly(),update:i.array(w).readonly(),delete:i.array(w).readonly()}).optional(),gql:i.array(ae).readonly().optional()}),T=i.strictObject({name:i.string(),fields:i.record(i.string(),v),metadata:i.object({name:i.string(),description:i.string().optional(),settings:y.optional(),permissions:oe,files:i.record(i.string(),i.string()),indexes:i.record(i.string(),i.strictObject({fields:i.array(i.string()),unique:i.boolean().optional()})).optional(),typeHook:i.strictObject({create:s.optional(),update:s.optional()}).optional(),typeValidate:s.optional()}).strict()}),E=i.strictObject({directory:i.string().describe(`Directory containing migration files`),machineUser:i.string().optional().describe(`Machine user name for migration execution`)}),D=i.strictObject({files:i.array(i.string()).describe(`Glob patterns for TailorDB table definition files`),ignores:i.array(i.string()).optional().describe(`Glob patterns to exclude from table discovery`),migration:E.optional().describe(`Migration configuration`),gqlOperations:h.optional().describe(`Default GraphQL operations for all tables in this service`)}),O=T.keyof().options;function stripTailorDBTypeBuilderHelpers(t){return e(t,`tailordb-type`)?pickTailorDBTypeSchemaKeys(t):t}function pickTailorDBTypeSchemaKeys(e){if(typeof e!=`object`||!e)return e;let t={},n=e;for(let e of O)Object.prototype.hasOwnProperty.call(n,e)&&(t[e]=n[e]);return t}const k=i.strictObject({providerUrl:i.string().describe(`OAuth2 provider URL`),issuerUrl:i.string().describe(`OAuth2 issuer URL`),clientId:i.string().describe(`OAuth2 client ID`),clientSecret:i.string().describe(`OAuth2 client secret`),authUrl:i.string().optional().describe(`OAuth2 authorization endpoint override`),tokenUrl:i.string().optional().describe(`OAuth2 token endpoint override`)}).extend({type:i.literal(`oauth2`).describe(`Connection type`)}),A=i.strictObject({value:i.string().describe(`The allowed value`),description:i.string().optional().describe(`Description of the allowed value`)}),j=i.strictObject({as:i.enum([`string`,`date`,`temporal`]).optional().describe(`Date value representation`),required:i.boolean().optional().describe(`Whether the field is required`),array:i.boolean().optional().describe(`Whether the field is an array`),description:i.string().optional().describe(`Field description`),allowedValues:i.array(A).optional().describe(`Allowed values for enum fields`),hooks:i.strictObject({create:s.optional().describe(`Hook function called on creation`),update:s.optional().describe(`Hook function called on update`)}).optional().describe(`Lifecycle hooks`),validate:i.array(s).optional().describe(`Validation functions for the field`),typeName:i.string().optional().describe(`Type name for nested or enum fields`),default:i.unknown().optional().describe(`Default value for the field on create`)}),M=i.object({type:f.describe(`Field data type`),metadata:j.describe(`Field metadata configuration`),get fields(){return i.record(i.string(),M)}}),N=i.strictObject({namespace:i.string().describe(`Auth namespace`),machineUserName:i.string().describe(`Machine user name for authentication`)}),P=i.union([i.string().describe(`Machine user name (namespace auto-resolved from auth service)`),N]),F=i.strictObject({vaultName:i.string().describe(`Vault name containing the secret`),secretKey:i.string().describe(`Key of the secret in the vault`)}),I=i.strictObject({name:i.string().describe(`Identity provider name`),kind:i.literal(`OIDC`),clientID:i.string().describe(`OAuth2 client ID`),clientSecret:F.describe(`OAuth2 client secret`),providerURL:i.string().describe(`OIDC provider URL`),issuerURL:i.string().optional().describe(`OIDC issuer URL (defaults to providerURL)`),usernameClaim:i.string().optional().describe(`JWT claim to use as username`)}),L=i.strictObject({name:i.string().describe(`Identity provider name`),kind:i.literal(`SAML`),enableSignRequest:i.boolean().default(!1).describe(`Enable signing of SAML requests`),metadataURL:i.string().optional().describe(`URL to fetch SAML metadata (mutually exclusive with rawMetadata)`),rawMetadata:i.string().optional().describe(`Raw SAML metadata XML (mutually exclusive with metadataURL)`),defaultRedirectURL:i.string().optional().describe(`URL to redirect to when SAML ACS receives a response with an empty RelayState.`)}).refine(e=>e.metadataURL!==void 0!=(e.rawMetadata!==void 0),`Provide either metadataURL or rawMetadata`),R=i.strictObject({name:i.string().describe(`Identity provider name`),kind:i.literal(`IDToken`),providerURL:i.string().describe(`ID token provider URL`),issuerURL:i.string().optional().describe(`ID token issuer URL`),clientID:i.string().describe(`Client ID for ID token validation`),usernameClaim:i.string().optional().describe(`JWT claim to use as username`)}),z=i.strictObject({name:i.string().describe(`Identity provider name`),kind:i.literal(`BuiltInIdP`),namespace:i.string().describe(`IdP namespace`),clientName:i.string().describe(`OAuth2 client name in the IdP`)}),B=i.discriminatedUnion(`kind`,[I,L,R,z]),V=i.union([i.literal(`authorization_code`),i.literal(`refresh_token`)]).describe(`OAuth2 grant type`),H=i.strictObject({description:i.string().optional().describe(`Client description`),grantTypes:i.array(V).default([`authorization_code`,`refresh_token`]).describe(`Allowed OAuth2 grant types`),redirectURIs:i.array(i.union([i.templateLiteral([`https://`,i.string()]),i.templateLiteral([`http://`,i.string()]),i.templateLiteral([i.string(),`:url`]),i.templateLiteral([i.string(),`:url/`,i.string()])])).describe(`Allowed redirect URIs`),clientType:i.union([i.literal(`confidential`),i.literal(`public`),i.literal(`browser`)]).optional().describe(`OAuth2 client type`),accessTokenLifetimeSeconds:i.number().int().min(60,`Minimum access token lifetime is 60 seconds`).max(86400,`Maximum access token lifetime is 1 day (86400 seconds)`).optional().describe(`Access token lifetime in seconds (60-86400)`).transform(e=>e?{seconds:BigInt(e),nanos:0}:void 0),refreshTokenLifetimeSeconds:i.number().int().min(60,`Minimum refresh token lifetime is 60 seconds`).max(604800,`Maximum refresh token lifetime is 7 days (604800 seconds)`).optional().describe(`Refresh token lifetime in seconds (60-604800)`).transform(e=>e?{seconds:BigInt(e),nanos:0}:void 0),requireDpop:i.boolean().optional().describe(`Require DPoP (Demonstrating Proof-of-Possession) for token requests`)}).refine(e=>e.clientType!==`browser`||e.requireDpop!==!0,{message:`requireDpop cannot be set to true for browser clients as they don't support DPoP`,path:[`requireDpop`]}),U=i.strictObject({type:i.union([i.literal(`oauth2`),i.literal(`bearer`)]).describe(`SCIM authorization type`),bearerSecret:F.optional().describe(`Bearer token secret (required for bearer type)`)}),W=i.union([i.literal(`string`),i.literal(`number`),i.literal(`boolean`),i.literal(`datetime`),i.literal(`complex`)]).describe(`SCIM attribute data type`),G=i.strictObject({type:W.describe(`Attribute data type`),name:i.string().describe(`Attribute name`),description:i.string().optional().describe(`Attribute description`),mutability:i.union([i.literal(`readOnly`),i.literal(`readWrite`),i.literal(`writeOnly`)]).optional().describe(`Attribute mutability`),required:i.boolean().optional().describe(`Whether the attribute is required`),multiValued:i.boolean().optional().describe(`Whether the attribute can have multiple values`),uniqueness:i.union([i.literal(`none`),i.literal(`server`),i.literal(`global`)]).optional().describe(`Uniqueness constraint`),canonicalValues:i.array(i.string()).nullable().optional().describe(`List of canonical values`),get subAttributes(){return i.array(G).nullable().optional()}}),K=i.strictObject({name:i.string().describe(`SCIM schema name`),attributes:i.array(G).describe(`Schema attributes`)}),q=i.strictObject({tailorDBField:i.string().describe(`TailorDB field name to map to`),scimPath:i.string().describe(`SCIM attribute path`)}),se=i.strictObject({name:i.string().describe(`SCIM resource name`),tailorDBNamespace:i.string().describe(`TailorDB namespace for the resource`),tailorDBType:i.string().describe(`TailorDB table name for the resource`),coreSchema:K.describe(`Core SCIM schema definition`),attributeMapping:i.array(q).describe(`Attribute mapping configuration`)}),ce=i.strictObject({machineUserName:i.string().describe(`Machine user name for SCIM operations`),authorization:U.describe(`SCIM authorization configuration`),resources:i.array(se).describe(`SCIM resource definitions`)}),le=i.strictObject({namespace:i.string().describe(`TailorDB namespace for the tenant table`),type:i.string().describe(`TailorDB table name for tenants`),signatureField:i.string().describe(`Field used as the tenant signature`)}),ue=i.strictObject({namespace:i.string().optional().describe(`TailorDB namespace where the user table is defined`),type:i.custom().transform(stripTailorDBTypeBuilderHelpers).pipe(T),usernameField:i.string(),attributes:i.record(i.string(),i.literal(!0)).optional(),attributeList:i.array(i.string()).optional()}),de=i.union([i.string(),i.boolean(),i.array(i.string()),i.array(i.boolean())]),fe=i.strictObject({attributes:i.record(i.string(),de.nullish()).transform(e=>Object.fromEntries(Object.entries(e).filter(e=>e[1]!=null))).optional(),attributeList:i.array(i.uuid()).optional()}),pe=i.strictObject({handler:i.function(),invoker:i.string()}),J=i.strictObject({name:i.string().describe(`Auth service name`),hooks:i.strictObject({beforeLogin:pe.optional().describe(`Before login auth hook`)}).optional().describe(`Auth hooks`),machineUsers:i.record(i.string(),fe).optional().describe(`Machine user definitions`),oauth2Clients:i.record(i.string(),H).optional().describe(`OAuth2 client definitions`),idProvider:B.optional().describe(`Identity provider configuration`),scim:ce.optional().describe(`SCIM provisioning configuration`),tenantProvider:le.optional().describe(`Multi-tenant provider configuration`),connections:i.record(i.string(),k).optional().describe(`Auth connection definitions for external OAuth2 providers`),publishSessionEvents:i.boolean().optional().describe(`Enable publishing session events`)}),me=i.xor([J.extend({userProfile:ue.optional().describe(`User profile configuration`),machineUserAttributes:i.undefined().optional()}),J.extend({userProfile:i.undefined().optional(),machineUserAttributes:i.record(i.string(),M).describe(`Machine user attribute fields`)})],{error:e=>{if(e.code===`invalid_union`&&!(e.errors.length<2)&&e.errors.every(e=>e.every(e=>e.path.length===1&&(e.path[0]===`userProfile`||e.path[0]===`machineUserAttributes`))))return"Specify either `userProfile` or `machineUserAttributes`, not both."}}),he=i.strictObject({kind:i.literal(`tailordb`).describe(`TailorDB record event trigger`),events:i.array(i.enum([`tailordb.type_record.created`,`tailordb.type_record.updated`,`tailordb.type_record.deleted`])).min(1).transform(e=>[...new Set(e)]).describe(`TailorDB event types to trigger on`),tableName:i.string().describe(`TailorDB table name to watch for events`),condition:s.optional().describe(`Condition function to filter events`)}),ge=i.strictObject({kind:i.literal(`resolverExecuted`),resolverName:i.string().describe(`Name of the resolver to trigger on`),condition:s.optional().describe(`Condition function to filter events`)}),_e=i.strictObject({kind:i.literal(`schedule`),cron:i.string().describe(`CRON expression for the schedule`),timezone:i.string().optional().default(`UTC`).describe(`Timezone for the CRON schedule (default: UTC)`)}),ve=i.strictObject({body:s.optional().describe(`Function returning the response body`),statusCode:i.number().int().optional().describe(`HTTP status code for the response`)}),ye=i.strictObject({kind:i.literal(`incomingWebhook`),response:ve.optional().describe(`Response configuration`)}),be=i.strictObject({kind:i.literal(`idpUser`).describe(`IdP user event trigger`),events:i.array(i.enum([`idp.user.created`,`idp.user.updated`,`idp.user.deleted`])).min(1).transform(e=>[...new Set(e)]).describe(`IdP user event types to trigger on`),idp:i.string().optional().describe(`IdP namespace name to subscribe to. If omitted, the project's only IdP is used; throws when multiple IdPs exist.`)}),xe=i.strictObject({kind:i.literal(`authAccessToken`).describe(`Auth access token event trigger`),events:i.array(i.enum([`auth.access_token.issued`,`auth.access_token.refreshed`,`auth.access_token.revoked`])).min(1).transform(e=>[...new Set(e)]).describe(`Auth access token event types to trigger on`)}),Y=i.string().refine(e=>e.trim().length>0,`Workflow name cannot be blank`).describe(`Workflow name to subscribe to.`),Se=i.strictObject({kind:i.literal(`workflowExecution`).describe(`Workflow execution event trigger`),events:i.array(i.enum([`workflow.workflow_execution.started`,`workflow.workflow_execution.completed`,`workflow.workflow_execution.retried`,`workflow.workflow_execution.resumed`,`workflow.workflow_execution.wait_started`,`workflow.workflow_execution.wait_resolved`])).min(1).transform(e=>[...new Set(e)]).describe(`Workflow execution event types to trigger on`),workflowName:Y,condition:s.optional().describe(`Condition function to filter events`)}),Ce=i.strictObject({kind:i.literal(`workflowJobExecution`).describe(`Workflow job execution event trigger`),events:i.array(i.enum([`workflow.workflow_execution.job_execution.started`,`workflow.workflow_execution.job_execution.completed`,`workflow.workflow_execution.job_execution.wait_started`,`workflow.workflow_execution.job_execution.wait_resolved`])).min(1).transform(e=>[...new Set(e)]).describe(`Workflow job execution event types to trigger on`),workflowName:Y,condition:s.optional().describe(`Condition function to filter events`)}),X=i.discriminatedUnion(`kind`,[he,ge,_e,ye,be,xe,Se,Ce]),we=i.strictObject({kind:i.enum([`function`,`jobFunction`]),body:s.describe(`Function implementation`),invoker:P.optional().describe(`Invoker for the function execution`)}),Te=i.strictObject({kind:i.literal(`graphql`),appName:i.string().optional().describe(`Target application name for the GraphQL query`),query:i.preprocess(e=>String(e),i.string().describe(`GraphQL query string`)),variables:s.optional().describe(`Function to compute GraphQL variables`),invoker:P.optional().describe(`Invoker for the GraphQL execution`)}),Ee=i.strictObject({kind:i.literal(`webhook`),url:s.describe(`Function returning the webhook URL`),requestBody:s.optional().describe(`Function to compute the request body`),headers:i.record(i.string(),i.union([i.string(),i.strictObject({vault:i.string(),key:i.string()})])).optional().describe(`HTTP headers for the webhook request`)}),Z=i.lazy(()=>i.union([i.string(),i.number(),i.boolean(),i.null(),i.array(Z),i.record(i.string(),Z)])),De=i.union([i.string(),i.number(),i.boolean(),i.array(Z),i.record(i.string(),Z)]),Oe=i.union([De,s]).describe(`Arguments to pass to the workflow`),Q={kind:i.literal(`workflow`),args:Oe.optional(),invoker:P.optional().describe(`Invoker for the workflow execution`)},ke=i.strictObject({...Q,workflowName:i.string().describe(`Name of the workflow to execute`),workflow:i.never().optional()}),Ae=i.strictObject({...Q,workflow:i.looseObject({name:i.string()}),workflowName:i.string().optional()}).transform(({workflow:e,...t})=>({...t,workflowName:e.name})),je=i.union([Ae,ke]),Me=i.union([we,Te,Ee,je]),$=i.strictObject({name:i.string().describe(`Executor name`),description:i.string().optional().describe(`Executor description`),disabled:i.boolean().optional().default(!1).describe(`Whether the executor is disabled`),trigger:X.describe(`Event trigger configuration`),operation:Me.describe(`Operation to execute when triggered`)});function stripExecutorTriggerArgs(t){if(!e(t,`executor`))return t;let n=t.trigger;if(typeof n!=`object`||!n||!(`__args`in n))return t;let{__args:r,...i}=n;return{...t,trigger:i}}async function loadExecutor(e){let t=(await importUserModule(e)).default,n=$.safeParse(stripExecutorTriggerArgs(t));return n.success?n.data:null}function createExecutorService(i){let{config:a,baseDir:o}=i,s={},c=[],l,loadExecutorForFile=async i=>{try{let a=await importUserModule(i),o=$.safeParse(stripExecutorTriggerArgs(a.default));if(o.success){let e=r.relative(process.cwd(),i);return n.debug(`Executor: ${t.successBright(`"${o.data.name}"`)} loaded from ${t.path(e)}`),s[i]=o.data,o.data}if(e(a.default,`executor`))throw o.error}catch(e){let a=r.relative(process.cwd(),i);throw n.error(`Failed to load executor from ${t.bold(a)}`),n.error(String(e)),e}};return{config:a,get executors(){return s},get pluginExecutors(){return c},loadExecutors:async()=>(l||=(async()=>{if(a.files.length===0)return;let e=loadFilesWithIgnores(a,o);return n.newline(),n.log(`Found ${t.highlight(e.length.toString())} executor files`),await Promise.all(e.map(e=>loadExecutorForFile(e))),assertUniqueExecutorNames(s),s})(),await l??(Object.keys(s).length>0?s:void 0)),loadPluginExecutorFiles:async e=>{if(e.length!==0){n.newline(),n.log(`Loading ${t.highlight(e.length.toString())} plugin-generated executor files`);for(let t of e){let e=await loadExecutorForFile(t);e&&c.push({executor:e,pluginId:`plugin-generated`,sourceTableName:void 0})}assertUniqueExecutorNames(s)}}}}function assertUniqueExecutorNames(e){let t=new Map;for(let[n,i]of Object.entries(e)){let e=r.relative(process.cwd(),n),a=t.get(i.name);if(a)throw Error(`Duplicate executor name "${i.name}" found:\n - ${a}\n - ${e}\nEach executor must have a unique name.`);t.set(i.name,e)}}export{c as _,me as a,importUserModule as b,pickTailorDBTypeSchemaKeys as c,T as d,applyRelationMetadataToFieldConfig as f,loadFilesWithIgnores as g,validateRelationConfig as h,$ as i,stripTailorDBTypeBuilderHelpers as l,processRelationMetadata as m,loadExecutor as n,P as o,buildRelationInfo as p,stripExecutorTriggerArgs as r,M as s,createExecutorService as t,D as u,beginUserModuleRun as v,s as x,currentImportNonce as y};
|
|
7
|
+
//# sourceMappingURL=service-CuqkHP1r.mjs.map
|