Custom Plugins (Beta)

Beta Feature: The custom plugin API is in beta and may change in future releases.

Create your own plugins by implementing the Plugin interface.

Requirements

Plugins must use default export:

<span><span style="color: var(--shiki-token-comment)">// plugin.ts</span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">myPlugin</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Plugin</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  id</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@my-company/my-plugin&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// ...</span></span>
<span><span style="color: var(--shiki-color-text)">};</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">default</span><span style="color: var(--shiki-color-text)"> myPlugin; </span><span style="color: var(--shiki-token-comment)">// Required: must be default export</span></span>
<span></span>

This is required so that generators can use plugin-generated TailorDB types via getGeneratedType().

Plugin Interface

<span><span style="color: var(--shiki-token-keyword)">interface</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Plugin</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">PluginConfig</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">unknown</span><span style="color: var(--shiki-color-text)">&gt; {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Unique identifier for the plugin (e.g., &quot;@my-company/soft-delete&quot;) */</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">readonly</span><span style="color: var(--shiki-color-text)"> id</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Human-readable description */</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">readonly</span><span style="color: var(--shiki-color-text)"> description</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Import path for generated code to reference */</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">readonly</span><span style="color: var(--shiki-color-text)"> importPath</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Schema for per-type configuration via .plugin() (required when using processType) */</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">readonly</span><span style="color: var(--shiki-color-text)"> configSchema</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">TailorAnyField</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Schema for plugin-level configuration via definePlugins() (optional) */</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">readonly</span><span style="color: var(--shiki-color-text)"> pluginConfigSchema</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">TailorAnyField</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Controls whether per-type config is required when attaching via .plugin() */</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">readonly</span><span style="color: var(--shiki-color-text)"> typeConfigRequired</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">boolean</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> ((pluginConfig</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginConfig</span><span style="color: var(--shiki-color-text)">) </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">boolean</span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Plugin-level config passed via definePlugins() */</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">readonly</span><span style="color: var(--shiki-color-text)"> pluginConfig</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginConfig</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Optional template for generating PluginConfigs typing */</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">readonly</span><span style="color: var(--shiki-color-text)"> configTypeTemplate</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Process a type with this plugin attached */</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">processType</span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)">(context</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginProcessContext</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginOutput</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Promise</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">PluginOutput</span><span style="color: var(--shiki-color-text)">&gt;;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Process a namespace (plugins without a source type) */</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">processNamespace</span><span style="color: var(--shiki-token-keyword)">?</span><span style="color: var(--shiki-color-text)">(</span></span>
<span><span style="color: var(--shiki-color-text)">    context</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginNamespaceProcessContext</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  )</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">NamespacePluginOutput</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">|</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Promise</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">NamespacePluginOutput</span><span style="color: var(--shiki-color-text)">&gt;;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Notes:

  • importPath should be resolvable from the directory containing tailor.config.ts. Code generators use it to import plugin APIs such as getGeneratedType and executor modules.
  • If you want to attach a plugin via .plugin(), you must provide configSchema and processType.
  • Namespace-only plugins can omit configSchema and implement processNamespace instead.
  • pluginConfig stores the plugin-level config so it can be read later during processing. Set it on the plugin object (e.g., via a factory function) before passing to definePlugins().
  • resolve should return a dynamic import; relative specifiers are resolved from the plugin module.
  • Per-type config is optional by default. Use typeConfigRequired: true to make it mandatory.
  • To toggle optional/required based on plugin config, provide a function for typeConfigRequired.

PluginProcessContext

Context passed to the processType method:

<span><span style="color: var(--shiki-token-keyword)">interface</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginProcessContext</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">TypeConfig</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">unknown</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginConfig</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">unknown</span><span style="color: var(--shiki-color-text)">&gt; {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** The TailorDB type being processed */</span></span>
<span><span style="color: var(--shiki-color-text)">  type</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">TailorAnyDBType</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Per-type configuration from .plugin({ pluginId: typeConfig }) */</span></span>
<span><span style="color: var(--shiki-color-text)">  typeConfig</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">TypeConfig</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Plugin-level configuration from definePlugins() */</span></span>
<span><span style="color: var(--shiki-color-text)">  pluginConfig</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginConfig</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Namespace of the TailorDB type */</span></span>
<span><span style="color: var(--shiki-color-text)">  namespace</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

PluginNamespaceProcessContext

Context passed to the processNamespace method:

<span><span style="color: var(--shiki-token-keyword)">interface</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginNamespaceProcessContext</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">PluginConfig</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">unknown</span><span style="color: var(--shiki-color-text)">&gt; {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Plugin-level configuration from definePlugins() */</span></span>
<span><span style="color: var(--shiki-color-text)">  pluginConfig</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginConfig</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Target namespace for generated types */</span></span>
<span><span style="color: var(--shiki-color-text)">  namespace</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

PluginOutput

Return value from processType:

<span><span style="color: var(--shiki-token-keyword)">interface</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginOutput</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Additional TailorDB types to generate */</span></span>
<span><span style="color: var(--shiki-color-text)">  types</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Record</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">TailorAnyDBType</span><span style="color: var(--shiki-color-text)">&gt;;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Additional resolvers to generate */</span></span>
<span><span style="color: var(--shiki-color-text)">  resolvers</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginGeneratedResolver</span><span style="color: var(--shiki-color-text)">[];</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Additional executors to generate */</span></span>
<span><span style="color: var(--shiki-color-text)">  executors</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginGeneratedExecutor</span><span style="color: var(--shiki-color-text)">[];</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">/** Extensions to apply to the source type */</span></span>
<span><span style="color: var(--shiki-color-text)">  extends</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">/** Fields to add to the source type */</span></span>
<span><span style="color: var(--shiki-color-text)">    fields</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Record</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">TailorAnyField</span><span style="color: var(--shiki-color-text)">&gt;;</span></span>
<span><span style="color: var(--shiki-color-text)">  };</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

processNamespace returns NamespacePluginOutput (same shape as PluginOutput but without extends):

<span><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">NamespacePluginOutput</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Omit</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">PluginOutput</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;extends&quot;</span><span style="color: var(--shiki-color-text)">&gt;;</span></span>
<span></span>

getGeneratedType Helper

The SDK provides an async getGeneratedType() helper function to retrieve plugin-generated TailorDB types. This enables generators and other tools to work with types generated by plugins.

<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { join } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;node:path&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { getGeneratedType } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@tailor-platform/sdk/plugin&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { customer } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;./tailordb/customer&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">configPath</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">join</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">meta</span><span style="color: var(--shiki-color-text)">.dirname</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;./tailor.config.ts&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>
<span><span style="color: var(--shiki-token-comment)">// Get the generated type by config path, plugin ID, source type, and kind</span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">DeletedCustomer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">await</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">getGeneratedType</span><span style="color: var(--shiki-color-text)">(</span></span>
<span><span style="color: var(--shiki-color-text)">  configPath</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-string-expression)">&quot;@example/soft-delete&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  customer</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-string-expression)">&quot;archive&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>

Parameters:

  • configPath: Path to tailor.config.ts (absolute or relative to cwd)
  • pluginId: The plugin's unique identifier (e.g., "@example/soft-delete")
  • sourceType: The TailorDB type that the plugin is attached to (null for namespace plugins)
  • kind: The generated type kind (e.g., "archive", "auditLog")

How it works:

  1. Loads and caches the config from the given path
  2. Finds the plugin by ID from definePlugins() exports
  3. Auto-resolves the namespace from config
  4. Calls the plugin's processType() or processNamespace() method
  5. Caches the result to avoid redundant processing
  6. Returns the generated type matching the specified kind

Example Usage

<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { join } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;node:path&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { getGeneratedType } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@tailor-platform/sdk/plugin&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { customer } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;./tailordb/customer&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">configPath</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">join</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)">.</span><span style="color: var(--shiki-token-constant)">meta</span><span style="color: var(--shiki-color-text)">.dirname</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;./tailor.config.ts&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>
<span><span style="color: var(--shiki-token-comment)">// Type-attached plugin</span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">DeletedCustomer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">await</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">getGeneratedType</span><span style="color: var(--shiki-color-text)">(</span></span>
<span><span style="color: var(--shiki-color-text)">  configPath</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-string-expression)">&quot;@example/soft-delete&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  customer</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-string-expression)">&quot;archive&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>
<span><span style="color: var(--shiki-token-comment)">// Namespace plugin (pass null as sourceType)</span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">AuditLog</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">await</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">getGeneratedType</span><span style="color: var(--shiki-color-text)">(configPath</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@example/audit-log&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">null</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;auditLog&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>

Example: Soft Delete Plugin

A complete example of a plugin that adds soft delete functionality:

Plugin Definition

<span><span style="color: var(--shiki-token-comment)">// plugins/soft-delete/plugin.ts</span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { db</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> t } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@tailor-platform/sdk&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> { Plugin</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> PluginProcessContext</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> PluginOutput } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@tailor-platform/sdk&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">interface</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">SoftDeleteConfig</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  archiveReason</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">boolean</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">  retentionDays</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">interface</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">SoftDeletePluginConfig</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  archiveTablePrefix</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">  defaultRetentionDays</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">  requireTypeConfig</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">boolean</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">configSchema</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">t</span><span style="color: var(--shiki-token-function)">.object</span><span style="color: var(--shiki-color-text)">({</span></span>
<span><span style="color: var(--shiki-color-text)">  archiveReason</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">t</span><span style="color: var(--shiki-token-function)">.bool</span><span style="color: var(--shiki-color-text)">({ optional</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)"> })</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  retentionDays</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">t</span><span style="color: var(--shiki-token-function)">.int</span><span style="color: var(--shiki-color-text)">({ optional</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)"> })</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// Use { required: true } to mark fields as required in plugin configs.</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// By default, plugin config fields are optional.</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// token: t.string({ required: true }),</span></span>
<span><span style="color: var(--shiki-color-text)">});</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">pluginConfigSchema</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">t</span><span style="color: var(--shiki-token-function)">.object</span><span style="color: var(--shiki-color-text)">({</span></span>
<span><span style="color: var(--shiki-color-text)">  archiveTablePrefix</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">t</span><span style="color: var(--shiki-token-function)">.string</span><span style="color: var(--shiki-color-text)">({ optional</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)"> })</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  defaultRetentionDays</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">t</span><span style="color: var(--shiki-token-function)">.int</span><span style="color: var(--shiki-color-text)">({ optional</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)"> })</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">});</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">processSoftDelete</span><span style="color: var(--shiki-color-text)">(</span></span>
<span><span style="color: var(--shiki-color-text)">  context</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginProcessContext</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">SoftDeleteConfig</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">SoftDeletePluginConfig</span><span style="color: var(--shiki-color-text)">&gt;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginOutput</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> { </span><span style="color: var(--shiki-token-constant)">type</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">typeConfig</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">pluginConfig</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">namespace</span><span style="color: var(--shiki-color-text)"> } </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> context;</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">prefix</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">pluginConfig</span><span style="color: var(--shiki-color-text)">?.archiveTablePrefix </span><span style="color: var(--shiki-token-keyword)">??</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;Deleted_&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// Generate archive type</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">archiveType</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> db</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-function)">.type</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-color-text)">prefix</span><span style="color: var(--shiki-token-keyword)">}${</span><span style="color: var(--shiki-token-constant)">type</span><span style="color: var(--shiki-color-text)">.name</span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">      originalId</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">db</span><span style="color: var(--shiki-token-function)">.uuid</span><span style="color: var(--shiki-color-text)">()</span><span style="color: var(--shiki-token-function)">.description</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;ID of the deleted record&quot;</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">      originalData</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">db</span><span style="color: var(--shiki-token-function)">.string</span><span style="color: var(--shiki-color-text)">()</span><span style="color: var(--shiki-token-function)">.description</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;JSON snapshot of deleted record&quot;</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">      deletedAt</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">db</span><span style="color: var(--shiki-token-function)">.datetime</span><span style="color: var(--shiki-color-text)">()</span><span style="color: var(--shiki-token-function)">.description</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;When the record was deleted&quot;</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">      deletedBy</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">db</span><span style="color: var(--shiki-token-function)">.uuid</span><span style="color: var(--shiki-color-text)">()</span><span style="color: var(--shiki-token-function)">.description</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;User who deleted the record&quot;</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">      </span><span style="color: var(--shiki-token-keyword)">...</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-constant)">typeConfig</span><span style="color: var(--shiki-color-text)">.archiveReason </span><span style="color: var(--shiki-token-keyword)">&amp;&amp;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">        reason</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">db</span><span style="color: var(--shiki-token-function)">.string</span><span style="color: var(--shiki-color-text)">({ optional</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)"> })</span><span style="color: var(--shiki-token-function)">.description</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Reason for deletion&quot;</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">      })</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">      </span><span style="color: var(--shiki-token-keyword)">...</span><span style="color: var(--shiki-token-constant)">db</span><span style="color: var(--shiki-token-function)">.</span><span style="color: var(--shiki-token-constant)">fields</span><span style="color: var(--shiki-token-function)">.timestamps</span><span style="color: var(--shiki-color-text)">()</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    })</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-function)">.description</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">`Archive for deleted </span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-constant)">type</span><span style="color: var(--shiki-color-text)">.name</span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)"> records`</span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// Extend source type with deletedAt field</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">extendFields</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    deletedAt</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">db</span><span style="color: var(--shiki-token-function)">.datetime</span><span style="color: var(--shiki-color-text)">({ optional</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-color-text)"> })</span><span style="color: var(--shiki-token-function)">.description</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Soft delete timestamp&quot;</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  };</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    types</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> { archive</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> archiveType }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    extends</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> { fields</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> extendFields }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    executors</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> [</span></span>
<span><span style="color: var(--shiki-color-text)">      {</span></span>
<span><span style="color: var(--shiki-color-text)">        name</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-constant)">type</span><span style="color: var(--shiki-token-function)">.</span><span style="color: var(--shiki-token-constant)">name</span><span style="color: var(--shiki-token-function)">.toLowerCase</span><span style="color: var(--shiki-color-text)">()</span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">-on-delete`</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-function)">resolve</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">async</span><span style="color: var(--shiki-color-text)"> () </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">await</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;./executors/on-delete&quot;</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">        context</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">          sourceType</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> type</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">          archiveType</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">          namespace</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">        }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">      }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    ]</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  };</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-comment)">// Factory function for plugins with plugin-level config</span></span>
<span><span style="color: var(--shiki-token-keyword)">function</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">createSoftDeletePlugin</span><span style="color: var(--shiki-color-text)">(pluginConfig</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">SoftDeletePluginConfig</span><span style="color: var(--shiki-color-text)">)</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Plugin</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    id</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@example/soft-delete&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    description</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;Adds soft delete with archive functionality&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    importPath</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;./plugins/soft-delete&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    configSchema</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    pluginConfigSchema</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    pluginConfig</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-function)">typeConfigRequired</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> (config) </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">config</span><span style="color: var(--shiki-color-text)">?.requireTypeConfig </span><span style="color: var(--shiki-token-keyword)">===</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    processType</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> processSoftDelete</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  };</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-comment)">// Default export is required for getGeneratedType() to work</span></span>
<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">default</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">createSoftDeletePlugin</span><span style="color: var(--shiki-color-text)">();</span></span>
<span></span>

Executor with Context

<span><span style="color: var(--shiki-token-comment)">// plugins/soft-delete/executors/on-delete.ts</span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { createExecutor</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> recordDeletedTrigger</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> withPluginContext } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@tailor-platform/sdk&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">type</span><span style="color: var(--shiki-color-text)"> { TailorAnyDBType } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@tailor-platform/sdk&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { getDB } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;generated/tailordb&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">interface</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">SoftDeleteContext</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  sourceType</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">TailorAnyDBType</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">  archiveType</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">TailorAnyDBType</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">  namespace</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>
<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">default</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">withPluginContext</span><span style="color: var(--shiki-color-text)">((ctx</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">SoftDeleteContext</span><span style="color: var(--shiki-color-text)">) </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> { </span><span style="color: var(--shiki-token-constant)">sourceType</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">archiveType</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">namespace</span><span style="color: var(--shiki-color-text)"> } </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> ctx;</span></span>
<span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">createExecutor</span><span style="color: var(--shiki-color-text)">({</span></span>
<span><span style="color: var(--shiki-color-text)">    name</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`</span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-constant)">sourceType</span><span style="color: var(--shiki-token-function)">.</span><span style="color: var(--shiki-token-constant)">name</span><span style="color: var(--shiki-token-function)">.toLowerCase</span><span style="color: var(--shiki-color-text)">()</span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)">-on-delete`</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    description</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">`Archives deleted </span><span style="color: var(--shiki-token-keyword)">${</span><span style="color: var(--shiki-token-constant)">sourceType</span><span style="color: var(--shiki-color-text)">.name</span><span style="color: var(--shiki-token-keyword)">}</span><span style="color: var(--shiki-token-string-expression)"> records`</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    trigger</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">recordDeletedTrigger</span><span style="color: var(--shiki-color-text)">({ type</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> sourceType })</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    operation</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">      kind</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;function&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">      </span><span style="color: var(--shiki-token-function)">body</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">async</span><span style="color: var(--shiki-color-text)"> ({ oldRecord</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> user }) </span><span style="color: var(--shiki-token-keyword)">=&gt;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">db</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">getDB</span><span style="color: var(--shiki-color-text)">(namespace </span><span style="color: var(--shiki-token-keyword)">as</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;tailordb&quot;</span><span style="color: var(--shiki-color-text)">);</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-keyword)">await</span><span style="color: var(--shiki-color-text)"> db</span></span>
<span><span style="color: var(--shiki-color-text)">          </span><span style="color: var(--shiki-token-function)">.insertInto</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-constant)">archiveType</span><span style="color: var(--shiki-color-text)">.name)</span></span>
<span><span style="color: var(--shiki-color-text)">          </span><span style="color: var(--shiki-token-function)">.values</span><span style="color: var(--shiki-color-text)">({</span></span>
<span><span style="color: var(--shiki-color-text)">            originalId</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">oldRecord</span><span style="color: var(--shiki-color-text)">.id</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">            originalData</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">JSON</span><span style="color: var(--shiki-token-function)">.stringify</span><span style="color: var(--shiki-color-text)">(oldRecord)</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">            deletedAt</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">new</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Date</span><span style="color: var(--shiki-color-text)">()</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">            deletedBy</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">user</span><span style="color: var(--shiki-color-text)">?.id </span><span style="color: var(--shiki-token-keyword)">??</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;system&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">          })</span></span>
<span><span style="color: var(--shiki-color-text)">          </span><span style="color: var(--shiki-token-function)">.execute</span><span style="color: var(--shiki-color-text)">();</span></span>
<span><span style="color: var(--shiki-color-text)">      }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  });</span></span>
<span><span style="color: var(--shiki-color-text)">});</span></span>
<span></span>

Usage

<span><span style="color: var(--shiki-token-comment)">// tailor.config.ts</span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> { definePlugins } </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@tailor-platform/sdk&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-token-keyword)">import</span><span style="color: var(--shiki-color-text)"> softDeletePlugin </span><span style="color: var(--shiki-token-keyword)">from</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;./plugins/soft-delete&quot;</span><span style="color: var(--shiki-color-text)">;</span></span>
<span></span>
<span><span style="color: var(--shiki-token-comment)">// Use a factory function to pass plugin-level config</span></span>
<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">plugins</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">definePlugins</span><span style="color: var(--shiki-color-text)">(</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">softDeletePlugin</span><span style="color: var(--shiki-color-text)">({</span></span>
<span><span style="color: var(--shiki-color-text)">    archiveTablePrefix</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;Deleted_&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    defaultRetentionDays</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">90</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  })</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>
<span><span style="color: var(--shiki-token-comment)">// tailordb/customer.ts</span></span>
<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">customer</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> db</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">.type</span><span style="color: var(--shiki-color-text)">(</span><span style="color: var(--shiki-token-string-expression)">&quot;Customer&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">    name</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">db</span><span style="color: var(--shiki-token-function)">.string</span><span style="color: var(--shiki-color-text)">()</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    email</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">db</span><span style="color: var(--shiki-token-function)">.string</span><span style="color: var(--shiki-color-text)">()</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  })</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">.plugin</span><span style="color: var(--shiki-color-text)">({</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-string-expression)">&quot;@example/soft-delete&quot;</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">      archiveReason</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  });</span></span>
<span></span>

If your plugin uses typeConfigRequired as a function, you can toggle whether per-type config is required via pluginConfig:

<span><span style="color: var(--shiki-token-keyword)">export</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">plugins</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">definePlugins</span><span style="color: var(--shiki-color-text)">(</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">softDeletePlugin</span><span style="color: var(--shiki-color-text)">({</span></span>
<span><span style="color: var(--shiki-color-text)">    archiveTablePrefix</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;Deleted_&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    requireTypeConfig</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">true</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  })</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">);</span></span>
<span></span>

Adding Type Safety

To enable type checking for your plugin's configuration, add a declaration merge:

<span><span style="color: var(--shiki-token-comment)">// user-defined.d.ts or your plugin&#39;s types.ts</span></span>
<span><span style="color: var(--shiki-token-keyword)">declare</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">module</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@tailor-platform/sdk&quot;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">interface</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginConfigs</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">Fields</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">&gt; {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-string-expression)">&quot;@example/soft-delete&quot;</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">      archiveReason</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">boolean</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">      retentionDays</span><span style="color: var(--shiki-token-keyword)">?:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">number</span><span style="color: var(--shiki-color-text)">;</span></span>
<span><span style="color: var(--shiki-color-text)">    };</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

The Fields type parameter provides field names from the type being configured, enabling field-aware configurations:

<span><span style="color: var(--shiki-token-keyword)">declare</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">module</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@tailor-platform/sdk&quot;</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-keyword)">interface</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">PluginConfigs</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">Fields</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">extends</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">&gt; {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-string-expression)">&quot;@example/i18n&quot;</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">      labels</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Partial</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">Record</span><span style="color: var(--shiki-color-text)">&lt;</span><span style="color: var(--shiki-token-function)">Fields</span><span style="color: var(--shiki-token-punctuation)">,</span><span style="color: var(--shiki-color-text)"> { ja</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)">; en</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">string</span><span style="color: var(--shiki-color-text)"> }&gt;&gt;;</span></span>
<span><span style="color: var(--shiki-color-text)">    };</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span></span>
<span><span style="color: var(--shiki-color-text)">}</span></span>
<span></span>

Plugin Types

Type-Attached Plugins

Implement processType to handle types with the plugin attached:

<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">plugin</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Plugin</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  id</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@example/my-plugin&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// ...</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">processType</span><span style="color: var(--shiki-color-text)">(context) {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">// Called for each type with .plugin({ &quot;@example/my-plugin&quot;: config })</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">      types</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">        </span><span style="color: var(--shiki-token-comment)">/* generated types */</span></span>
<span><span style="color: var(--shiki-color-text)">      }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">    };</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">};</span></span>
<span></span>

Namespace Plugins

Implement processNamespace for plugins that generate types independently:

<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">plugin</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Plugin</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  id</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@example/audit-log&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// ...</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">processNamespace</span><span style="color: var(--shiki-color-text)">(context) {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">// Called once per namespace, with namespace-level types available</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-keyword)">return</span><span style="color: var(--shiki-color-text)"> { types</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> { auditLog</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-comment)">/* generated type */</span><span style="color: var(--shiki-color-text)"> } };</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">};</span></span>
<span></span>

Hybrid Plugins

Implement both methods for plugins that support both modes:

<span><span style="color: var(--shiki-token-keyword)">const</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-constant)">plugin</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-function)">Plugin</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-keyword)">=</span><span style="color: var(--shiki-color-text)"> {</span></span>
<span><span style="color: var(--shiki-color-text)">  id</span><span style="color: var(--shiki-token-keyword)">:</span><span style="color: var(--shiki-color-text)"> </span><span style="color: var(--shiki-token-string-expression)">&quot;@example/hybrid&quot;</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-comment)">// ...</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">processType</span><span style="color: var(--shiki-color-text)">(context) {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">// Handle type attachments</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">  </span><span style="color: var(--shiki-token-function)">processNamespace</span><span style="color: var(--shiki-color-text)">(context) {</span></span>
<span><span style="color: var(--shiki-color-text)">    </span><span style="color: var(--shiki-token-comment)">// Handle namespace generation</span></span>
<span><span style="color: var(--shiki-color-text)">  }</span><span style="color: var(--shiki-token-punctuation)">,</span></span>
<span><span style="color: var(--shiki-color-text)">};</span></span>
<span></span>