@tailor-platform/sdk 1.14.2 → 1.15.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.
@@ -1,8 +1,7 @@
1
1
  import { t as isPluginGeneratedType } from "./types-b-ig8nW_.mjs";
2
2
  import { t as db } from "./schema-DRYB-nzA.mjs";
3
- import { a as ExecutorSchema, c as TailorFieldSchema, d as tailorUserMap, f as loadFilesWithIgnores, h as symbols, i as createExecutorService, l as functionSchema, m as styles, n as WorkflowJobSchema, o as OAuth2ClientSchema, p as logger, r as WorkflowSchema, s as ResolverSchema, t as defineApplication, u as stringifyFunction } from "./application-DhwHYQ3H.mjs";
3
+ import { a as ExecutorSchema, c as functionSchema, d as loadFilesWithIgnores, f as logger, i as createExecutorService, l as stringifyFunction, m as symbols, n as WorkflowJobSchema, o as OAuth2ClientSchema, p as styles, r as WorkflowSchema, s as ResolverSchema, t as defineApplication, u as tailorUserMap } from "./application-DPunZ4lc.mjs";
4
4
  import { createRequire } from "node:module";
5
- import { cloneDeep } from "es-toolkit";
6
5
  import { arg, defineCommand, runCommand } from "politty";
7
6
  import { z } from "zod";
8
7
  import * as fs$2 from "node:fs";
@@ -29,6 +28,7 @@ import { glob } from "node:fs/promises";
29
28
  import * as rolldown from "rolldown";
30
29
  import { parseSync } from "oxc-parser";
31
30
  import { create, fromJson, toJson } from "@bufbuild/protobuf";
31
+ import * as crypto from "node:crypto";
32
32
  import ora from "ora";
33
33
  import { setTimeout as setTimeout$1 } from "timers/promises";
34
34
  import { spawn } from "node:child_process";
@@ -2685,143 +2685,21 @@ function createGeneratorConfigSchema(builtinGenerators$1) {
2685
2685
 
2686
2686
  //#endregion
2687
2687
  //#region src/parser/plugin-config/schema.ts
2688
- const unauthenticatedTailorUser$1 = {
2689
- id: "00000000-0000-0000-0000-000000000000",
2690
- type: "",
2691
- workspaceId: "00000000-0000-0000-0000-000000000000",
2692
- attributes: null,
2693
- attributeList: []
2694
- };
2695
- const PluginGeneratedTypeSchema = z.object({
2696
- name: z.string(),
2697
- fields: z.record(z.string(), z.unknown())
2698
- });
2699
- const PluginGeneratedResolverSchema = z.object({
2700
- name: z.string(),
2701
- operation: z.enum(["query", "mutation"]),
2702
- inputFields: z.record(z.string(), z.unknown()).optional(),
2703
- outputFields: z.record(z.string(), z.unknown()),
2704
- body: z.string()
2705
- });
2706
- const PluginTriggerConfigSchema = z.object({
2707
- kind: z.enum([
2708
- "recordCreated",
2709
- "recordUpdated",
2710
- "recordDeleted",
2711
- "schedule",
2712
- "incomingWebhook"
2713
- ]),
2714
- type: z.string().optional(),
2715
- schedule: z.string().optional()
2716
- });
2717
- const PluginOperationConfigSchema = z.object({
2718
- kind: z.enum([
2719
- "function",
2720
- "webhook",
2721
- "graphql",
2722
- "workflow"
2723
- ]),
2724
- body: z.string().optional(),
2725
- url: z.string().optional(),
2726
- query: z.string().optional()
2727
- });
2728
- const PluginGeneratedExecutorSchema = z.object({
2729
- name: z.string(),
2730
- description: z.string().optional(),
2731
- trigger: PluginTriggerConfigSchema,
2732
- operation: PluginOperationConfigSchema
2733
- });
2734
- z.object({
2735
- types: z.array(PluginGeneratedTypeSchema).optional(),
2736
- resolvers: z.array(PluginGeneratedResolverSchema).optional(),
2737
- executors: z.array(PluginGeneratedExecutorSchema).optional()
2738
- });
2739
- const tailorAnyFieldSchema = z.custom((val) => TailorFieldSchema.safeParse(val).success);
2740
2688
  const CustomPluginSchema = z.object({
2741
2689
  id: z.string(),
2742
2690
  description: z.string(),
2743
2691
  importPath: z.string(),
2744
- configSchema: tailorAnyFieldSchema.optional(),
2745
- pluginConfigSchema: tailorAnyFieldSchema.optional(),
2746
2692
  pluginConfig: z.unknown().optional(),
2747
2693
  processType: functionSchema.optional(),
2748
2694
  processNamespace: functionSchema.optional(),
2749
- typeConfigRequired: z.union([z.boolean(), functionSchema]).optional(),
2750
- configTypeTemplate: z.string().optional()
2751
- }).superRefine((plugin, ctx) => {
2752
- if (plugin.processType && !plugin.configSchema) ctx.addIssue({
2753
- code: z.ZodIssueCode.custom,
2754
- message: "processType requires configSchema to be defined.",
2755
- path: ["configSchema"]
2756
- });
2695
+ typeConfigRequired: z.union([z.boolean(), functionSchema]).optional()
2757
2696
  }).passthrough();
2758
- function normalizePluginConfigSchema(schema) {
2759
- const seen = /* @__PURE__ */ new Set();
2760
- const stack = [schema];
2761
- while (stack.length > 0) {
2762
- const field = stack.pop();
2763
- if (!field || seen.has(field)) continue;
2764
- seen.add(field);
2765
- const requiredExplicit = field._metadata.requiredExplicit === true;
2766
- field._metadata.required = requiredExplicit;
2767
- for (const nestedField of Object.values(field.fields)) stack.push(nestedField);
2768
- }
2769
- return schema;
2770
- }
2771
- function clonePluginConfigSchema(schema) {
2772
- return cloneDeep(schema);
2773
- }
2774
- function normalizePlugin(plugin) {
2775
- let normalized = plugin;
2776
- if (normalized.configSchema) {
2777
- const clonedConfigSchema = clonePluginConfigSchema(normalized.configSchema);
2778
- normalizePluginConfigSchema(clonedConfigSchema);
2779
- normalized = {
2780
- ...normalized,
2781
- configSchema: clonedConfigSchema
2782
- };
2783
- }
2784
- if (normalized.pluginConfigSchema) {
2785
- const pluginConfigSchema = clonePluginConfigSchema(normalized.pluginConfigSchema);
2786
- normalizePluginConfigSchema(pluginConfigSchema);
2787
- normalized = {
2788
- ...normalized,
2789
- pluginConfigSchema
2790
- };
2791
- if (normalized.pluginConfig !== void 0) {
2792
- const validationErrors = validatePluginConfig$1(normalized.pluginConfig, pluginConfigSchema);
2793
- if (validationErrors.length > 0) {
2794
- const errorDetails = validationErrors.map((e) => e.field ? `${e.field}: ${e.message}` : e.message).join("; ");
2795
- throw new Error(`Invalid pluginConfig for plugin "${normalized.id}": ${errorDetails}`);
2796
- }
2797
- }
2798
- }
2799
- return normalized;
2800
- }
2801
- /**
2802
- * Validate plugin config against its schema
2803
- * @param config - The config object to validate
2804
- * @param schema - The schema defining expected fields
2805
- * @returns Array of validation errors (empty if valid)
2806
- */
2807
- function validatePluginConfig$1(config, schema) {
2808
- const result = schema.parse({
2809
- value: config,
2810
- data: config,
2811
- user: unauthenticatedTailorUser$1
2812
- });
2813
- if ("issues" in result && result.issues) return result.issues.map((issue) => ({
2814
- field: Array.isArray(issue.path) ? issue.path.join(".") : "",
2815
- message: issue.message
2816
- }));
2817
- return [];
2818
- }
2819
2697
  /**
2820
2698
  * Creates a PluginConfigSchema for custom plugins
2821
2699
  * @returns Plugin config schema that validates and transforms Plugin instances
2822
2700
  */
2823
2701
  function createPluginConfigSchema() {
2824
- return CustomPluginSchema.transform((plugin) => normalizePlugin(plugin)).brand("Plugin");
2702
+ return CustomPluginSchema.transform((plugin) => plugin).brand("Plugin");
2825
2703
  }
2826
2704
 
2827
2705
  //#endregion
@@ -5017,10 +4895,9 @@ function extractAttributesFromConfig(config) {
5017
4895
  * @param attributeMap - Attribute map configuration
5018
4896
  * @param attributeList - Attribute list configuration
5019
4897
  * @param env - Environment configuration
5020
- * @param pluginConfigs - Plugin configuration entries for PluginConfigs interface
5021
4898
  * @returns Generated type definition source
5022
4899
  */
5023
- function generateTypeDefinition(attributeMap, attributeList, env, pluginConfigs) {
4900
+ function generateTypeDefinition(attributeMap, attributeList, env) {
5024
4901
  const mapFields = attributeMap ? Object.entries(attributeMap).map(([key, value]) => ` ${key}: ${value};`).join("\n") : "";
5025
4902
  const mapBody = !attributeMap || Object.keys(attributeMap).length === 0 ? "{}" : `{
5026
4903
  ${mapFields}
@@ -5041,7 +4918,7 @@ declare module "@tailor-platform/sdk" {
5041
4918
  interface AttributeList ${listBody}
5042
4919
  interface Env ${!env || Object.keys(env).length === 0 ? "{}" : `{
5043
4920
  ${envFields}
5044
- }`}${pluginConfigs && pluginConfigs.length > 0 ? `\n${generatePluginConfigsDefinition(pluginConfigs)}` : ""}${pluginConfigs && pluginConfigs.length > 0 ? `\n${generatePluginMethodOverload(pluginConfigs)}` : ""}
4921
+ }`}
5045
4922
  }
5046
4923
 
5047
4924
  export {};
@@ -5104,7 +4981,7 @@ function resolveTypeDefinitionPath(configPath) {
5104
4981
  * @returns Promise that resolves when types are generated
5105
4982
  */
5106
4983
  async function generateUserTypes(options) {
5107
- const { config, configPath, plugins } = options;
4984
+ const { config, configPath } = options;
5108
4985
  try {
5109
4986
  const { attributeMap, attributeList } = extractAttributesFromConfig(config);
5110
4987
  if (!attributeMap && !attributeList) logger.info("No attributes found in configuration", { mode: "plain" });
@@ -5112,14 +4989,7 @@ async function generateUserTypes(options) {
5112
4989
  if (attributeList) logger.debug(`Extracted AttributeList: ${JSON.stringify(attributeList)}`);
5113
4990
  const env = config.env;
5114
4991
  if (env) logger.debug(`Extracted Env: ${JSON.stringify(env)}`);
5115
- const pluginConfigs = plugins?.filter((p) => p.configSchema !== void 0).map((p) => ({
5116
- id: p.id,
5117
- configSchema: p.configSchema,
5118
- configTypeTemplate: p.configTypeTemplate,
5119
- typeConfigRequired: isTypeConfigRequired(p)
5120
- }));
5121
- if (pluginConfigs && pluginConfigs.length > 0) logger.debug(`Extracted PluginConfigs: ${pluginConfigs.map((p) => p.id).join(", ")}`);
5122
- const typeDefContent = generateTypeDefinition(attributeMap, attributeList, env, pluginConfigs);
4992
+ const typeDefContent = generateTypeDefinition(attributeMap, attributeList, env);
5123
4993
  const outputPath = resolveTypeDefinitionPath(configPath);
5124
4994
  fs$2.mkdirSync(path.dirname(outputPath), { recursive: true });
5125
4995
  fs$2.writeFileSync(outputPath, typeDefContent);
@@ -5148,116 +5018,9 @@ function resolvePackageDirectory(startDir) {
5148
5018
  return null;
5149
5019
  }
5150
5020
  }
5151
- /**
5152
- * Convert a ConfigSchemaField to its TypeScript type string representation.
5153
- * @param field - The field to convert
5154
- * @param indent - Current indentation level
5155
- * @returns TypeScript type string
5156
- */
5157
- function fieldToTypeString(field, indent = 0) {
5158
- const indentStr = " ".repeat(indent);
5159
- const metadata = field.metadata;
5160
- let baseType;
5161
- switch (field.type) {
5162
- case "string":
5163
- case "uuid":
5164
- case "date":
5165
- case "datetime":
5166
- case "time":
5167
- baseType = "string";
5168
- break;
5169
- case "integer":
5170
- case "float":
5171
- baseType = "number";
5172
- break;
5173
- case "boolean":
5174
- baseType = "boolean";
5175
- break;
5176
- case "enum":
5177
- if (metadata.allowedValues && metadata.allowedValues.length > 0) baseType = metadata.allowedValues.map((v) => `"${v.value}"`).join(" | ");
5178
- else baseType = "string";
5179
- break;
5180
- case "nested": {
5181
- const fieldEntries = Object.entries(field.fields);
5182
- if (fieldEntries.length === 0) baseType = "Record<string, unknown>";
5183
- else baseType = `{\n${fieldEntries.map(([name, nestedField]) => {
5184
- const nestedType = fieldToTypeString(nestedField, indent + 1);
5185
- return `${indentStr} ${name}${!nestedField.metadata.required ? "?" : ""}: ${nestedType};`;
5186
- }).join("\n")}\n${indentStr}}`;
5187
- break;
5188
- }
5189
- default: baseType = "unknown";
5190
- }
5191
- if (metadata.array) baseType = `(${baseType})[]`;
5192
- return baseType;
5193
- }
5194
- function isTypeConfigRequired(plugin) {
5195
- const required = plugin.typeConfigRequired;
5196
- if (typeof required === "function") return required(plugin.pluginConfig);
5197
- return required === true;
5198
- }
5199
- /**
5200
- * Generate PluginConfigs interface extension for user-defined.d.ts
5201
- * @param plugins - Array of plugin configurations
5202
- * @returns TypeScript interface extension string, or empty string if no plugins
5203
- */
5204
- function generatePluginConfigsDefinition(plugins) {
5205
- if (plugins.length === 0) return "";
5206
- return ` interface PluginConfigs<Fields extends string> {
5207
- ${plugins.map((plugin) => {
5208
- const typeString = plugin.configTypeTemplate ?? fieldToTypeString(plugin.configSchema, 2);
5209
- const optionalMarker = plugin.typeConfigRequired ? "" : "?";
5210
- return ` "${plugin.id}"${optionalMarker}: ${typeString};`;
5211
- }).join("\n")}
5212
- }`;
5213
- }
5214
- /**
5215
- * Generate TailorDBType.plugin() method overload for IDE completion.
5216
- * This adds an overload that uses `keyof Fields` directly for field-aware types,
5217
- * enabling IDE autocompletion for field names in plugin configs.
5218
- * @param plugins - Array of plugin configurations
5219
- * @returns TypeScript interface extension string
5220
- */
5221
- function generatePluginMethodOverload(plugins) {
5222
- return ` // Overload for .plugin() method to enable IDE completion for field names
5223
- interface TailorDBType<Fields, User> {
5224
- plugin(config: {
5225
- ${plugins.map((plugin) => {
5226
- const typeString = (plugin.configTypeTemplate ?? fieldToTypeString(plugin.configSchema, 3)).replace(/\bFields\b/g, "keyof Fields & string");
5227
- const optionalMarker = plugin.typeConfigRequired ? "" : "?";
5228
- return ` "${plugin.id}"${optionalMarker}: ${typeString};`;
5229
- }).join("\n")}
5230
- }): this;
5231
- }`;
5232
- }
5233
5021
 
5234
5022
  //#endregion
5235
5023
  //#region src/plugin/manager.ts
5236
- const unauthenticatedTailorUser = {
5237
- id: "00000000-0000-0000-0000-000000000000",
5238
- type: "",
5239
- workspaceId: "00000000-0000-0000-0000-000000000000",
5240
- attributes: null,
5241
- attributeList: []
5242
- };
5243
- /**
5244
- * Validate plugin config against its schema
5245
- * @param config - The config object to validate
5246
- * @param schema - The schema defining expected fields
5247
- * @returns Array of validation errors (empty if valid)
5248
- */
5249
- function validatePluginConfig(config, schema) {
5250
- const result = schema.parse({
5251
- value: config,
5252
- data: config,
5253
- user: unauthenticatedTailorUser
5254
- });
5255
- if ("issues" in result && result.issues) return result.issues.map((issue) => ({
5256
- field: Array.isArray(issue.path) ? issue.path.join(".") : "",
5257
- message: issue.message
5258
- }));
5259
- return [];
5260
- }
5261
5024
  /**
5262
5025
  * Manages plugin registration and processing
5263
5026
  */
@@ -5290,16 +5053,6 @@ var PluginManager = class {
5290
5053
  success: false,
5291
5054
  error: `Plugin "${plugin.id}" requires typeConfig, but none was provided for type "${context.type.name}".`
5292
5055
  };
5293
- if (plugin.configSchema) {
5294
- const validationErrors = validatePluginConfig(context.typeConfig, plugin.configSchema);
5295
- if (validationErrors.length > 0) {
5296
- const errorDetails = validationErrors.map((e) => e.field ? `${e.field}: ${e.message}` : e.message).join("; ");
5297
- return {
5298
- success: false,
5299
- error: `Invalid typeConfig for plugin "${plugin.id}" on type "${context.type.name}": ${errorDetails}`
5300
- };
5301
- }
5302
- }
5303
5056
  if (!plugin.processType) return {
5304
5057
  success: false,
5305
5058
  error: `Plugin "${plugin.id}" does not support type-attached processing (missing processType method). Use processNamespace via definePlugins() instead.`
@@ -5353,21 +5106,6 @@ var PluginManager = class {
5353
5106
  for (const [pluginId, plugin] of this.plugins) {
5354
5107
  if (!plugin.processNamespace) continue;
5355
5108
  const config = plugin.pluginConfig;
5356
- if (plugin.pluginConfigSchema && config !== void 0) {
5357
- const validationErrors = validatePluginConfig(config, plugin.pluginConfigSchema);
5358
- if (validationErrors.length > 0) {
5359
- const errorDetails = validationErrors.map((e) => e.field ? `${e.field}: ${e.message}` : e.message).join("; ");
5360
- results.push({
5361
- pluginId,
5362
- config,
5363
- result: {
5364
- success: false,
5365
- error: `Invalid pluginConfig for plugin "${plugin.id}": ${errorDetails}`
5366
- }
5367
- });
5368
- continue;
5369
- }
5370
- }
5371
5109
  const context = {
5372
5110
  pluginConfig: config,
5373
5111
  namespace
@@ -6982,6 +6720,245 @@ async function confirmImportantResourceDeletion(resources, yes) {
6982
6720
  `);
6983
6721
  }
6984
6722
 
6723
+ //#endregion
6724
+ //#region src/cli/apply/services/function-registry.ts
6725
+ const CHUNK_SIZE = 64 * 1024;
6726
+ /**
6727
+ * Compute SHA-256 content hash for a script string.
6728
+ * @param content - Script content to hash
6729
+ * @returns Hex-encoded SHA-256 hash
6730
+ */
6731
+ function computeContentHash(content) {
6732
+ return crypto.createHash("sha256").update(content, "utf-8").digest("hex");
6733
+ }
6734
+ function functionRegistryTrn(workspaceId, name) {
6735
+ return `trn:v1:workspace:${workspaceId}:function_registry:${name}`;
6736
+ }
6737
+ /**
6738
+ * Build a function registry name for a resolver.
6739
+ * @param namespace - Resolver namespace
6740
+ * @param resolverName - Resolver name
6741
+ * @returns Function registry name
6742
+ */
6743
+ function resolverFunctionName(namespace, resolverName) {
6744
+ return `resolver--${namespace}--${resolverName}`;
6745
+ }
6746
+ /**
6747
+ * Build a function registry name for an executor.
6748
+ * @param executorName - Executor name
6749
+ * @returns Function registry name
6750
+ */
6751
+ function executorFunctionName(executorName) {
6752
+ return `executor--${executorName}`;
6753
+ }
6754
+ /**
6755
+ * Build a function registry name for a workflow job.
6756
+ * @param jobName - Workflow job name
6757
+ * @returns Function registry name
6758
+ */
6759
+ function workflowJobFunctionName(jobName) {
6760
+ return `workflow--${jobName}`;
6761
+ }
6762
+ /**
6763
+ * Collect all function entries from bundled scripts for all services.
6764
+ * @param application - Application definition
6765
+ * @param workflowJobs - Collected workflow jobs from config
6766
+ * @returns Array of function entries to register
6767
+ */
6768
+ function collectFunctionEntries(application, workflowJobs) {
6769
+ const entries = [];
6770
+ const distDir = getDistDir();
6771
+ for (const app of application.applications) for (const pipeline of app.resolverServices) for (const resolver of Object.values(pipeline.getResolvers())) {
6772
+ const scriptPath = path.join(distDir, "resolvers", `${resolver.name}.js`);
6773
+ try {
6774
+ const content = fs$2.readFileSync(scriptPath, "utf-8");
6775
+ entries.push({
6776
+ name: resolverFunctionName(pipeline.namespace, resolver.name),
6777
+ scriptContent: content,
6778
+ contentHash: computeContentHash(content),
6779
+ description: `Resolver: ${pipeline.namespace}/${resolver.name}`
6780
+ });
6781
+ } catch {
6782
+ logger.warn(`Function file not found: ${scriptPath}`);
6783
+ }
6784
+ }
6785
+ if (application.executorService) {
6786
+ const executors = application.executorService.getExecutors();
6787
+ for (const executor of Object.values(executors)) if (executor.operation.kind === "function" || executor.operation.kind === "jobFunction") {
6788
+ const scriptPath = path.join(distDir, "executors", `${executor.name}.js`);
6789
+ try {
6790
+ const content = fs$2.readFileSync(scriptPath, "utf-8");
6791
+ entries.push({
6792
+ name: executorFunctionName(executor.name),
6793
+ scriptContent: content,
6794
+ contentHash: computeContentHash(content),
6795
+ description: `Executor: ${executor.name}`
6796
+ });
6797
+ } catch {
6798
+ logger.warn(`Function file not found: ${scriptPath}`);
6799
+ }
6800
+ }
6801
+ }
6802
+ for (const job of workflowJobs) {
6803
+ const scriptPath = path.join(distDir, "workflow-jobs", `${job.name}.js`);
6804
+ try {
6805
+ const content = fs$2.readFileSync(scriptPath, "utf-8");
6806
+ entries.push({
6807
+ name: workflowJobFunctionName(job.name),
6808
+ scriptContent: content,
6809
+ contentHash: computeContentHash(content),
6810
+ description: `Workflow job: ${job.name}`
6811
+ });
6812
+ } catch {
6813
+ logger.warn(`Function file not found: ${scriptPath}`);
6814
+ }
6815
+ }
6816
+ return entries;
6817
+ }
6818
+ /**
6819
+ * Plan function registry changes based on current and desired state.
6820
+ * @param client - Operator client instance
6821
+ * @param workspaceId - Workspace ID
6822
+ * @param appName - Application name
6823
+ * @param entries - Desired function entries
6824
+ * @returns Planned changes
6825
+ */
6826
+ async function planFunctionRegistry(client, workspaceId, appName, entries) {
6827
+ const changeSet = createChangeSet("Function registry");
6828
+ const conflicts = [];
6829
+ const unmanaged = [];
6830
+ const resourceOwners = /* @__PURE__ */ new Set();
6831
+ const existingFunctions = await fetchAll(async (pageToken) => {
6832
+ try {
6833
+ const response = await client.listFunctionRegistries({
6834
+ workspaceId,
6835
+ pageToken
6836
+ });
6837
+ return [response.functions.map((f) => ({
6838
+ name: f.name,
6839
+ contentHash: f.contentHash
6840
+ })), response.nextPageToken];
6841
+ } catch (error) {
6842
+ if (error instanceof ConnectError && error.code === Code.NotFound) return [[], ""];
6843
+ throw error;
6844
+ }
6845
+ });
6846
+ const existingMap = {};
6847
+ await Promise.all(existingFunctions.map(async (func) => {
6848
+ const { metadata } = await client.getMetadata({ trn: functionRegistryTrn(workspaceId, func.name) });
6849
+ existingMap[func.name] = {
6850
+ resource: func,
6851
+ label: metadata?.labels[sdkNameLabelKey]
6852
+ };
6853
+ }));
6854
+ for (const entry of entries) {
6855
+ const existing = existingMap[entry.name];
6856
+ const metaRequest = await buildMetaRequest(functionRegistryTrn(workspaceId, entry.name), appName);
6857
+ if (existing) {
6858
+ if (!existing.label) unmanaged.push({
6859
+ resourceType: "Function registry",
6860
+ resourceName: entry.name
6861
+ });
6862
+ else if (existing.label !== appName) conflicts.push({
6863
+ resourceType: "Function registry",
6864
+ resourceName: entry.name,
6865
+ currentOwner: existing.label
6866
+ });
6867
+ changeSet.updates.push({
6868
+ name: entry.name,
6869
+ entry,
6870
+ metaRequest
6871
+ });
6872
+ delete existingMap[entry.name];
6873
+ } else changeSet.creates.push({
6874
+ name: entry.name,
6875
+ entry,
6876
+ metaRequest
6877
+ });
6878
+ }
6879
+ for (const [name, existing] of Object.entries(existingMap)) {
6880
+ if (!existing) continue;
6881
+ const label = existing.label;
6882
+ if (label && label !== appName) resourceOwners.add(label);
6883
+ if (label === appName) changeSet.deletes.push({
6884
+ name,
6885
+ workspaceId
6886
+ });
6887
+ }
6888
+ changeSet.print();
6889
+ return {
6890
+ changeSet,
6891
+ conflicts,
6892
+ unmanaged,
6893
+ resourceOwners
6894
+ };
6895
+ }
6896
+ /**
6897
+ * Upload a function script to the function registry using client streaming.
6898
+ * @param client - Operator client instance
6899
+ * @param workspaceId - Workspace ID
6900
+ * @param entry - Function entry to upload
6901
+ * @param isCreate - Whether this is a create (true) or update (false)
6902
+ */
6903
+ async function uploadFunctionScript(client, workspaceId, entry, isCreate) {
6904
+ const buffer = Buffer.from(entry.scriptContent, "utf-8");
6905
+ const info = {
6906
+ workspaceId,
6907
+ name: entry.name,
6908
+ description: entry.description,
6909
+ sizeBytes: BigInt(buffer.length),
6910
+ contentHash: entry.contentHash
6911
+ };
6912
+ if (isCreate) {
6913
+ async function* createStream() {
6914
+ yield { payload: {
6915
+ case: "info",
6916
+ value: info
6917
+ } };
6918
+ for (let i = 0; i < buffer.length; i += CHUNK_SIZE) yield { payload: {
6919
+ case: "chunk",
6920
+ value: buffer.subarray(i, Math.min(i + CHUNK_SIZE, buffer.length))
6921
+ } };
6922
+ }
6923
+ await client.createFunctionRegistry(createStream());
6924
+ } else {
6925
+ async function* updateStream() {
6926
+ yield { payload: {
6927
+ case: "info",
6928
+ value: info
6929
+ } };
6930
+ for (let i = 0; i < buffer.length; i += CHUNK_SIZE) yield { payload: {
6931
+ case: "chunk",
6932
+ value: buffer.subarray(i, Math.min(i + CHUNK_SIZE, buffer.length))
6933
+ } };
6934
+ }
6935
+ await client.updateFunctionRegistry(updateStream());
6936
+ }
6937
+ }
6938
+ /**
6939
+ * Apply function registry changes for the given phase.
6940
+ * @param client - Operator client instance
6941
+ * @param workspaceId
6942
+ * @param result - Planned function registry changes
6943
+ * @param phase - Apply phase
6944
+ */
6945
+ async function applyFunctionRegistry(client, workspaceId, result, phase = "create-update") {
6946
+ const { changeSet } = result;
6947
+ if (phase === "create-update") {
6948
+ for (const create$1 of changeSet.creates) {
6949
+ await uploadFunctionScript(client, workspaceId, create$1.entry, true);
6950
+ await client.setMetadata(create$1.metaRequest);
6951
+ }
6952
+ for (const update of changeSet.updates) {
6953
+ await uploadFunctionScript(client, workspaceId, update.entry, false);
6954
+ await client.setMetadata(update.metaRequest);
6955
+ }
6956
+ } else if (phase === "delete") await Promise.all(changeSet.deletes.map((del) => client.deleteFunctionRegistry({
6957
+ workspaceId: del.workspaceId,
6958
+ name: del.name
6959
+ })));
6960
+ }
6961
+
6985
6962
  //#endregion
6986
6963
  //#region src/cli/apply/services/executor.ts
6987
6964
  /**
@@ -7226,22 +7203,19 @@ function protoExecutor(appName, executor, env) {
7226
7203
  } };
7227
7204
  break;
7228
7205
  case "function":
7229
- case "jobFunction": {
7206
+ case "jobFunction":
7230
7207
  if (target.kind === "function") targetType = ExecutorTargetType.FUNCTION;
7231
7208
  else targetType = ExecutorTargetType.JOB_FUNCTION;
7232
- const scriptPath = path.join(getDistDir(), "executors", `${executor.name}.js`);
7233
- const script = fs$2.readFileSync(scriptPath, "utf-8");
7234
7209
  targetConfig = { config: {
7235
7210
  case: "function",
7236
7211
  value: {
7237
- name: `${executor.name}__target`,
7238
- script,
7212
+ name: "operation",
7213
+ scriptRef: executorFunctionName(executor.name),
7239
7214
  variables: { expr: argsExpr },
7240
7215
  invoker: target.authInvoker ?? void 0
7241
7216
  }
7242
7217
  } };
7243
7218
  break;
7244
- }
7245
7219
  case "workflow":
7246
7220
  targetType = ExecutorTargetType.WORKFLOW;
7247
7221
  targetConfig = { config: {
@@ -7459,7 +7433,7 @@ async function planResolvers(client, workspaceId, pipelines, executors, deletedS
7459
7433
  request: {
7460
7434
  workspaceId,
7461
7435
  namespaceName: pipeline.namespace,
7462
- pipelineResolver: processResolver(resolver, executorUsedResolvers, env)
7436
+ pipelineResolver: processResolver(pipeline.namespace, resolver, executorUsedResolvers, env)
7463
7437
  }
7464
7438
  });
7465
7439
  existingNameSet.delete(resolver.name);
@@ -7468,7 +7442,7 @@ async function planResolvers(client, workspaceId, pipelines, executors, deletedS
7468
7442
  request: {
7469
7443
  workspaceId,
7470
7444
  namespaceName: pipeline.namespace,
7471
- pipelineResolver: processResolver(resolver, executorUsedResolvers, env)
7445
+ pipelineResolver: processResolver(pipeline.namespace, resolver, executorUsedResolvers, env)
7472
7446
  }
7473
7447
  });
7474
7448
  existingNameSet.forEach((name) => {
@@ -7494,20 +7468,13 @@ async function planResolvers(client, workspaceId, pipelines, executors, deletedS
7494
7468
  });
7495
7469
  return changeSet;
7496
7470
  }
7497
- function processResolver(resolver, executorUsedResolvers, env) {
7498
- const functionPath = path.join(getDistDir(), "resolvers", `${resolver.name}.js`);
7499
- let functionCode = "";
7500
- try {
7501
- functionCode = fs$2.readFileSync(functionPath, "utf-8");
7502
- } catch {
7503
- logger.warn(`Function file not found: ${functionPath}`);
7504
- }
7471
+ function processResolver(namespace, resolver, executorUsedResolvers, env) {
7505
7472
  const pipelines = [{
7506
7473
  name: "body",
7507
7474
  operationName: "body",
7508
7475
  description: `${resolver.name} function body`,
7509
7476
  operationType: PipelineResolver_OperationType.FUNCTION,
7510
- operationSource: functionCode,
7477
+ operationSourceRef: resolverFunctionName(namespace, resolver.name),
7511
7478
  operationHook: { expr: `({ ...context.pipeline, input: context.args, user: ${tailorUserMap}, env: ${JSON.stringify(env)} });` },
7512
7479
  postScript: `args.body`
7513
7480
  }];
@@ -8594,7 +8561,7 @@ function compareFiles(ctx, typeName, oldFiles, newFiles) {
8594
8561
  * Compare type-level relationships
8595
8562
  * @param {DiffContext} ctx - Diff context
8596
8563
  * @param {string} typeName - Type name
8597
- * @param relationshipType
8564
+ * @param {"forward" | "backward"} relationshipType - Relationship direction to compare
8598
8565
  * @param {Record<string, SnapshotRelationship> | undefined} oldRelationships - Previous relationships
8599
8566
  * @param {Record<string, SnapshotRelationship> | undefined} newRelationships - Current relationships
8600
8567
  * @returns {void}
@@ -9987,11 +9954,7 @@ function generateTailorDBTypeManifest(type, executorUsedTypes, namespaceGqlOpera
9987
9954
  type: fieldType,
9988
9955
  allowedValues: fieldType === "enum" ? fieldConfig.allowedValues || [] : [],
9989
9956
  description: fieldConfig.description || "",
9990
- validate: (fieldConfig.validate || []).map((val) => ({
9991
- action: TailorDBType_PermitAction.DENY,
9992
- errorMessage: val.errorMessage || "",
9993
- ...val.script && { script: { expr: val.script.expr ? `!${val.script.expr}` : "" } }
9994
- })),
9957
+ validate: toProtoFieldValidate(fieldConfig),
9995
9958
  array: fieldConfig.array || false,
9996
9959
  index: fieldConfig.index || false,
9997
9960
  unique: fieldConfig.unique || false,
@@ -10000,10 +9963,7 @@ function generateTailorDBTypeManifest(type, executorUsedTypes, namespaceGqlOpera
10000
9963
  foreignKeyField: fieldConfig.foreignKeyField,
10001
9964
  required: fieldConfig.required !== false,
10002
9965
  vector: fieldConfig.vector || false,
10003
- ...fieldConfig.hooks && { hooks: {
10004
- create: fieldConfig.hooks?.create ? { expr: fieldConfig.hooks.create.expr || "" } : void 0,
10005
- update: fieldConfig.hooks?.update ? { expr: fieldConfig.hooks.update.expr || "" } : void 0
10006
- } },
9966
+ ...toProtoFieldHooks(fieldConfig),
10007
9967
  ...fieldConfig.serial && { serial: {
10008
9968
  start: fieldConfig.serial.start,
10009
9969
  ...fieldConfig.serial.maxValue && { maxValue: fieldConfig.serial.maxValue },
@@ -10060,6 +10020,20 @@ function generateTailorDBTypeManifest(type, executorUsedTypes, namespaceGqlOpera
10060
10020
  }
10061
10021
  };
10062
10022
  }
10023
+ function toProtoFieldValidate(fieldConfig) {
10024
+ return (fieldConfig.validate || []).map((val) => ({
10025
+ action: TailorDBType_PermitAction.DENY,
10026
+ errorMessage: val.errorMessage || "",
10027
+ ...val.script && { script: { expr: val.script.expr ? `!${val.script.expr}` : "" } }
10028
+ }));
10029
+ }
10030
+ function toProtoFieldHooks(fieldConfig) {
10031
+ if (!fieldConfig.hooks) return {};
10032
+ return { hooks: {
10033
+ create: fieldConfig.hooks.create ? { expr: fieldConfig.hooks.create.expr || "" } : void 0,
10034
+ update: fieldConfig.hooks.update ? { expr: fieldConfig.hooks.update.expr || "" } : void 0
10035
+ } };
10036
+ }
10063
10037
  function processNestedFields(fields) {
10064
10038
  const nestedFields = {};
10065
10039
  Object.entries(fields).forEach(([nestedFieldName, nestedFieldConfig]) => {
@@ -10070,26 +10044,28 @@ function processNestedFields(fields) {
10070
10044
  type: "nested",
10071
10045
  allowedValues: nestedFieldConfig.allowedValues || [],
10072
10046
  description: nestedFieldConfig.description || "",
10073
- validate: [],
10047
+ validate: toProtoFieldValidate(nestedFieldConfig),
10074
10048
  required: nestedFieldConfig.required ?? true,
10075
10049
  array: nestedFieldConfig.array ?? false,
10076
10050
  index: false,
10077
10051
  unique: false,
10078
10052
  foreignKey: false,
10079
10053
  vector: false,
10054
+ ...toProtoFieldHooks(nestedFieldConfig),
10080
10055
  fields: deepNestedFields
10081
10056
  };
10082
10057
  } else nestedFields[nestedFieldName] = {
10083
10058
  type: nestedType,
10084
10059
  allowedValues: nestedType === "enum" ? nestedFieldConfig.allowedValues || [] : [],
10085
10060
  description: nestedFieldConfig.description || "",
10086
- validate: [],
10061
+ validate: toProtoFieldValidate(nestedFieldConfig),
10087
10062
  required: nestedFieldConfig.required ?? true,
10088
10063
  array: nestedFieldConfig.array ?? false,
10089
10064
  index: false,
10090
10065
  unique: false,
10091
10066
  foreignKey: false,
10092
10067
  vector: false,
10068
+ ...toProtoFieldHooks(nestedFieldConfig),
10093
10069
  ...nestedFieldConfig.serial && { serial: {
10094
10070
  start: nestedFieldConfig.serial.start,
10095
10071
  ...nestedFieldConfig.serial.maxValue && { maxValue: nestedFieldConfig.serial.maxValue },
@@ -10448,7 +10424,7 @@ async function registerJobFunctions(client, changeSet, appName) {
10448
10424
  const jobFunctionVersions = {};
10449
10425
  const firstWorkflow = changeSet.creates[0] || changeSet.updates[0];
10450
10426
  if (!firstWorkflow) return jobFunctionVersions;
10451
- const { workspaceId, scripts } = firstWorkflow;
10427
+ const { workspaceId } = firstWorkflow;
10452
10428
  const allUsedJobNames = /* @__PURE__ */ new Set();
10453
10429
  for (const item of [...changeSet.creates, ...changeSet.updates]) for (const jobName of item.usedJobNames) allUsedJobNames.add(jobName);
10454
10430
  const existingJobFunctions = await fetchAll(async (pageToken) => {
@@ -10460,16 +10436,14 @@ async function registerJobFunctions(client, changeSet, appName) {
10460
10436
  });
10461
10437
  const existingJobNamesSet = new Set(existingJobFunctions);
10462
10438
  const results = await Promise.all(Array.from(allUsedJobNames).map(async (jobName) => {
10463
- const script = scripts.get(jobName);
10464
- if (!script) throw new Error(`No bundled script found for job "${jobName}". Please run "generate" command before "apply".`);
10465
10439
  const response = existingJobNamesSet.has(jobName) ? await client.updateWorkflowJobFunction({
10466
10440
  workspaceId,
10467
10441
  jobFunctionName: jobName,
10468
- script
10442
+ scriptRef: workflowJobFunctionName(jobName)
10469
10443
  }) : await client.createWorkflowJobFunction({
10470
10444
  workspaceId,
10471
10445
  jobFunctionName: jobName,
10472
- script
10446
+ scriptRef: workflowJobFunctionName(jobName)
10473
10447
  });
10474
10448
  await client.setMetadata(await buildMetaRequest(jobFunctionTrn(workspaceId, jobName), appName));
10475
10449
  return {
@@ -10526,7 +10500,6 @@ async function planWorkflow(client, workspaceId, appName, workflows, mainJobDeps
10526
10500
  label: metadata?.labels[sdkNameLabelKey]
10527
10501
  };
10528
10502
  }));
10529
- const allScripts = await loadWorkflowScripts();
10530
10503
  for (const workflow of Object.values(workflows)) {
10531
10504
  const existing = existingWorkflows[workflow.name];
10532
10505
  const metaRequest = await buildMetaRequest(workflowTrn(workspaceId, workflow.name), appName);
@@ -10546,7 +10519,6 @@ async function planWorkflow(client, workspaceId, appName, workflows, mainJobDeps
10546
10519
  name: workflow.name,
10547
10520
  workspaceId,
10548
10521
  workflow,
10549
- scripts: allScripts,
10550
10522
  usedJobNames,
10551
10523
  metaRequest
10552
10524
  });
@@ -10555,7 +10527,6 @@ async function planWorkflow(client, workspaceId, appName, workflows, mainJobDeps
10555
10527
  name: workflow.name,
10556
10528
  workspaceId,
10557
10529
  workflow,
10558
- scripts: allScripts,
10559
10530
  usedJobNames,
10560
10531
  metaRequest
10561
10532
  });
@@ -10578,19 +10549,6 @@ async function planWorkflow(client, workspaceId, appName, workflows, mainJobDeps
10578
10549
  appName
10579
10550
  };
10580
10551
  }
10581
- async function loadWorkflowScripts() {
10582
- const scripts = /* @__PURE__ */ new Map();
10583
- const jobsDir = path.join(getDistDir(), "workflow-jobs");
10584
- if (!fs$2.existsSync(jobsDir)) return scripts;
10585
- const files = fs$2.readdirSync(jobsDir);
10586
- for (const file of files) if (/^[^.]+\.js$/.test(file)) {
10587
- const jobName = file.replace(/\.js$/, "");
10588
- const scriptPath = path.join(jobsDir, file);
10589
- const script = fs$2.readFileSync(scriptPath, "utf-8");
10590
- scripts.set(jobName, script);
10591
- }
10592
- return scripts;
10593
- }
10594
10552
 
10595
10553
  //#endregion
10596
10554
  //#region src/cli/apply/index.ts
@@ -10608,8 +10566,7 @@ async function apply(options) {
10608
10566
  if (plugins.length > 0) pluginManager = new PluginManager(plugins);
10609
10567
  await generateUserTypes({
10610
10568
  config,
10611
- configPath: config.path,
10612
- plugins
10569
+ configPath: config.path
10613
10570
  });
10614
10571
  const application = defineApplication({
10615
10572
  config,
@@ -10678,6 +10635,7 @@ async function apply(options) {
10678
10635
  }
10679
10636
  if (workflowResult) printLoadedWorkflows(workflowResult);
10680
10637
  logger.newline();
10638
+ const functionEntries = collectFunctionEntries(application, workflowResult?.jobs ?? []);
10681
10639
  const ctx = {
10682
10640
  client,
10683
10641
  workspaceId,
@@ -10686,6 +10644,7 @@ async function apply(options) {
10686
10644
  config,
10687
10645
  noSchemaCheck: options?.noSchemaCheck
10688
10646
  };
10647
+ const functionRegistry = await planFunctionRegistry(client, workspaceId, application.name, functionEntries);
10689
10648
  const tailorDB = await planTailorDB(ctx);
10690
10649
  const staticWebsite = await planStaticWebsite(ctx);
10691
10650
  const idp = await planIdP(ctx);
@@ -10695,6 +10654,7 @@ async function apply(options) {
10695
10654
  const executor = await planExecutor(ctx);
10696
10655
  const workflow = await planWorkflow(client, workspaceId, application.name, workflowResult?.workflows ?? {}, workflowBuildResult?.mainJobDeps ?? {});
10697
10656
  const allConflicts = [
10657
+ ...functionRegistry.conflicts,
10698
10658
  ...tailorDB.conflicts,
10699
10659
  ...staticWebsite.conflicts,
10700
10660
  ...idp.conflicts,
@@ -10705,6 +10665,7 @@ async function apply(options) {
10705
10665
  ];
10706
10666
  await confirmOwnerConflict(allConflicts, application.name, yes);
10707
10667
  await confirmUnmanagedResources([
10668
+ ...functionRegistry.unmanaged,
10708
10669
  ...tailorDB.unmanaged,
10709
10670
  ...staticWebsite.unmanaged,
10710
10671
  ...idp.unmanaged,
@@ -10732,6 +10693,7 @@ async function apply(options) {
10732
10693
  });
10733
10694
  await confirmImportantResourceDeletion(importantDeletions, yes);
10734
10695
  const resourceOwners = new Set([
10696
+ ...functionRegistry.resourceOwners,
10735
10697
  ...tailorDB.resourceOwners,
10736
10698
  ...staticWebsite.resourceOwners,
10737
10699
  ...idp.resourceOwners,
@@ -10752,6 +10714,7 @@ async function apply(options) {
10752
10714
  logger.info("Dry run enabled. No changes applied.");
10753
10715
  return;
10754
10716
  }
10717
+ await applyFunctionRegistry(client, workspaceId, functionRegistry, "create-update");
10755
10718
  await applyStaticWebsite(client, staticWebsite, "create-update");
10756
10719
  await applyIdP(client, idp, "create-update");
10757
10720
  await applyAuth(client, auth, "create-update");
@@ -10771,6 +10734,7 @@ async function apply(options) {
10771
10734
  await applyAuth(client, auth, "delete-services");
10772
10735
  await applyIdP(client, idp, "delete-services");
10773
10736
  await applyTailorDB(client, tailorDB, "delete-services");
10737
+ await applyFunctionRegistry(client, workspaceId, functionRegistry, "delete");
10774
10738
  logger.success("Successfully applied changes.");
10775
10739
  }
10776
10740
  async function buildPipeline(namespace, config, triggerContext) {
@@ -11706,32 +11670,11 @@ function getRunningJobs(execution) {
11706
11670
  function isTerminalStatus(status) {
11707
11671
  return status === WorkflowExecution_Status.SUCCESS || status === WorkflowExecution_Status.FAILED || status === WorkflowExecution_Status.PENDING_RESUME;
11708
11672
  }
11709
- /**
11710
- * Start a workflow and return a handle to wait for completion.
11711
- * @param options - Start options
11712
- * @returns Start result with wait helper
11713
- */
11714
- async function startWorkflow(options) {
11715
- const client = await initOperatorClient(await loadAccessToken({
11716
- useProfile: true,
11717
- profile: options.profile
11718
- }));
11719
- const workspaceId = loadWorkspaceId({
11720
- workspaceId: options.workspaceId,
11721
- profile: options.profile
11722
- });
11723
- const { config } = await loadConfig(options.configPath);
11724
- const { application } = await client.getApplication({
11725
- workspaceId,
11726
- applicationName: config.name
11727
- });
11728
- if (!application?.authNamespace) throw new Error(`Application ${config.name} does not have an auth configuration.`);
11673
+ async function startWorkflowCore(options) {
11674
+ const { client, workspaceId, workflowName } = options;
11729
11675
  try {
11730
- const workflow = await resolveWorkflow(client, workspaceId, options.name);
11731
- const authInvoker = create(AuthInvokerSchema, {
11732
- namespace: application.authNamespace,
11733
- machineUserName: options.machineUser
11734
- });
11676
+ const workflow = await resolveWorkflow(client, workspaceId, workflowName);
11677
+ const authInvoker = create(AuthInvokerSchema, options.authInvoker);
11735
11678
  const arg$1 = options.arg === void 0 ? void 0 : typeof options.arg === "string" ? options.arg : JSON.stringify(options.arg);
11736
11679
  const { executionId } = await client.testStartWorkflow({
11737
11680
  workspaceId,
@@ -11751,10 +11694,54 @@ async function startWorkflow(options) {
11751
11694
  })
11752
11695
  };
11753
11696
  } catch (error) {
11754
- if (error instanceof ConnectError && error.code === Code.NotFound) throw new Error(`Workflow '${options.name}' not found.`);
11697
+ if (error instanceof ConnectError && error.code === Code.NotFound) throw new Error(`Workflow '${workflowName}' not found.`);
11755
11698
  throw error;
11756
11699
  }
11757
11700
  }
11701
+ async function startWorkflowByName(options) {
11702
+ const client = await initOperatorClient(await loadAccessToken({
11703
+ useProfile: true,
11704
+ profile: options.profile
11705
+ }));
11706
+ const workspaceId = loadWorkspaceId({
11707
+ workspaceId: options.workspaceId,
11708
+ profile: options.profile
11709
+ });
11710
+ const { config } = await loadConfig(options.configPath);
11711
+ const { application } = await client.getApplication({
11712
+ workspaceId,
11713
+ applicationName: config.name
11714
+ });
11715
+ if (!application?.authNamespace) throw new Error(`Application ${config.name} does not have an auth configuration.`);
11716
+ return await startWorkflowCore({
11717
+ client,
11718
+ workspaceId,
11719
+ workflowName: options.name,
11720
+ authInvoker: {
11721
+ namespace: application.authNamespace,
11722
+ machineUserName: options.machineUser
11723
+ },
11724
+ arg: options.arg,
11725
+ interval: options.interval
11726
+ });
11727
+ }
11728
+ async function startWorkflow(options) {
11729
+ if ("name" in options) return await startWorkflowByName(options);
11730
+ return await startWorkflowCore({
11731
+ client: await initOperatorClient(await loadAccessToken({
11732
+ useProfile: true,
11733
+ profile: options.profile
11734
+ })),
11735
+ workspaceId: loadWorkspaceId({
11736
+ workspaceId: options.workspaceId,
11737
+ profile: options.profile
11738
+ }),
11739
+ workflowName: options.workflow.name,
11740
+ authInvoker: options.authInvoker,
11741
+ arg: options.arg,
11742
+ interval: options.interval
11743
+ });
11744
+ }
11758
11745
  const startCommand = defineCommand({
11759
11746
  name: "start",
11760
11747
  description: "Start a workflow execution.",
@@ -11774,7 +11761,7 @@ const startCommand = defineCommand({
11774
11761
  ...waitArgs
11775
11762
  }),
11776
11763
  run: withCommonArgs(async (args) => {
11777
- const { executionId, wait } = await startWorkflow({
11764
+ const { executionId, wait } = await startWorkflowByName({
11778
11765
  name: args.name,
11779
11766
  machineUser: args.machineuser,
11780
11767
  arg: args.arg,
@@ -12265,12 +12252,7 @@ const headerArg = z.string().superRefine((val, ctx) => {
12265
12252
  value: val.slice(colonIndex + 1).trim()
12266
12253
  };
12267
12254
  }).refine((h) => h.key.length > 0, { message: "Header name cannot be empty" });
12268
- /**
12269
- * Trigger an executor and return the job ID.
12270
- * @param options - Options for triggering executor
12271
- * @returns Result containing the job ID if available
12272
- */
12273
- async function triggerExecutor(options) {
12255
+ async function triggerExecutorByName(options) {
12274
12256
  const client = await initOperatorClient(await loadAccessToken({
12275
12257
  useProfile: true,
12276
12258
  profile: options.profile
@@ -12291,6 +12273,16 @@ async function triggerExecutor(options) {
12291
12273
  throw error;
12292
12274
  }
12293
12275
  }
12276
+ async function triggerExecutor(options) {
12277
+ if ("executorName" in options) return await triggerExecutorByName(options);
12278
+ if (options.executor.trigger.kind !== "incomingWebhook" && options.payload !== void 0) throw new Error(`Executor '${options.executor.name}' has '${options.executor.trigger.kind}' trigger type. The payload is only available for 'incomingWebhook' trigger type.`);
12279
+ return await triggerExecutorByName({
12280
+ executorName: options.executor.name,
12281
+ payload: options.payload,
12282
+ workspaceId: options.workspaceId,
12283
+ profile: options.profile
12284
+ });
12285
+ }
12294
12286
  const triggerCommand = defineCommand({
12295
12287
  name: "trigger",
12296
12288
  description: "Trigger an executor manually.",
@@ -12384,7 +12376,7 @@ The \`--logs\` option displays logs from the downstream execution when available
12384
12376
  body: body ?? {},
12385
12377
  headers
12386
12378
  };
12387
- const result = await triggerExecutor({
12379
+ const result = await triggerExecutorByName({
12388
12380
  executorName: args.executorName,
12389
12381
  payload,
12390
12382
  workspaceId: args["workspace-id"],
@@ -13227,8 +13219,7 @@ async function generate$1(options) {
13227
13219
  const watch$1 = options?.watch ?? false;
13228
13220
  await generateUserTypes({
13229
13221
  config,
13230
- configPath: config.path,
13231
- plugins
13222
+ configPath: config.path
13232
13223
  });
13233
13224
  const manager = createGenerationManager(config, generators, plugins, config.path);
13234
13225
  await manager.generate(watch$1);
@@ -13570,7 +13561,8 @@ async function execRemove(client, workspaceId, application, config, confirm) {
13570
13561
  const app = await planApplication(ctx);
13571
13562
  const executor = await planExecutor(ctx);
13572
13563
  const workflow = await planWorkflow(client, workspaceId, application.name, {}, {});
13573
- if (tailorDB.changeSet.service.deletes.length === 0 && staticWebsite.changeSet.deletes.length === 0 && idp.changeSet.service.deletes.length === 0 && auth.changeSet.service.deletes.length === 0 && pipeline.changeSet.service.deletes.length === 0 && app.deletes.length === 0 && executor.changeSet.deletes.length === 0 && workflow.changeSet.deletes.length === 0) return;
13564
+ const functionRegistry = await planFunctionRegistry(client, workspaceId, application.name, []);
13565
+ if (tailorDB.changeSet.service.deletes.length === 0 && staticWebsite.changeSet.deletes.length === 0 && idp.changeSet.service.deletes.length === 0 && auth.changeSet.service.deletes.length === 0 && pipeline.changeSet.service.deletes.length === 0 && app.deletes.length === 0 && executor.changeSet.deletes.length === 0 && workflow.changeSet.deletes.length === 0 && functionRegistry.changeSet.deletes.length === 0) return;
13574
13566
  if (confirm) await confirm();
13575
13567
  await applyWorkflow(client, workflow, "delete");
13576
13568
  await applyExecutor(client, executor, "delete");
@@ -13584,6 +13576,7 @@ async function execRemove(client, workspaceId, application, config, confirm) {
13584
13576
  await applyIdP(client, idp, "delete-services");
13585
13577
  await applyTailorDB(client, tailorDB, "delete-resources");
13586
13578
  await applyTailorDB(client, tailorDB, "delete-services");
13579
+ await applyFunctionRegistry(client, workspaceId, functionRegistry, "delete");
13587
13580
  }
13588
13581
  /**
13589
13582
  * Remove all resources managed by the current application.
@@ -14205,7 +14198,7 @@ async function generate(options) {
14205
14198
  if (options.init) await handleInitOption(namespacesWithMigrations, options.yes);
14206
14199
  let pluginManager;
14207
14200
  if (plugins.length > 0) pluginManager = new PluginManager(plugins);
14208
- const { defineApplication: defineApplication$1 } = await import("./application-BznueWxG.mjs");
14201
+ const { defineApplication: defineApplication$1 } = await import("./application-JwJ_-_PQ.mjs");
14209
14202
  const application = defineApplication$1({
14210
14203
  config,
14211
14204
  pluginManager
@@ -15416,4 +15409,4 @@ const updateCommand = defineCommand({
15416
15409
 
15417
15410
  //#endregion
15418
15411
  export { jobsCommand as $, initOperatorClient as $t, generateCommand as A, getMigrationFiles as At, getMachineUserToken as B, generateUserTypes as Bt, resumeCommand as C, compareLocalTypesWithSnapshot as Ct, truncate as D, getLatestMigrationNumber as Dt, listWorkflows as E, formatMigrationNumber as Et, removeCommand$1 as F, formatDiffSummary as Ft, generateCommand$1 as G, fetchLatestToken as Gt, listCommand$5 as H, getDistDir as Ht, listCommand$4 as I, formatMigrationDiff as It, triggerCommand as J, readPlatformConfig as Jt, listWebhookExecutors as K, loadAccessToken as Kt, listOAuth2Clients as L, hasChanges as Lt, show as M, isValidMigrationNumber as Mt, showCommand as N, loadDiff as Nt, truncateCommand as O, getMigrationDirPath as Ot, remove as P, reconstructSnapshotFromMigrations as Pt, getExecutorJob as Q, initOAuth2Client as Qt, getCommand$1 as R, getNamespacesWithMigrations as Rt, healthCommand as S, SCHEMA_FILE_NAME as St, listCommand$3 as T, createSnapshotFromLocalTypes as Tt, listMachineUsers as U, apiCall as Ut, tokenCommand as V, loadConfig as Vt, generate$1 as W, apiCommand as Wt, listCommand$6 as X, fetchAll as Xt, triggerExecutor as Y, writePlatformConfig as Yt, listExecutors as Z, fetchUserInfo as Zt, createCommand as _, bundleMigrationScript as _t, listCommand as a, jsonArgs as an, getWorkflow as at, listCommand$2 as b, INITIAL_SCHEMA_NUMBER as bt, inviteUser as c, listWorkflowExecutions as ct, listCommand$1 as d, apply as dt, readPackageJson as en, listExecutorJobs as et, listWorkspaces as f, applyCommand as ft, deleteWorkspace as g, parseMigrationLabelNumber as gt, deleteCommand as h, MIGRATION_LABEL_KEY as ht, removeUser as i, deploymentArgs as in, getCommand$2 as it, logBetaWarning as j, getNextMigrationNumber as jt, generate as k, getMigrationFilePath as kt, restoreCommand as l, getCommand$3 as lt, getWorkspace as m, waitForExecution$1 as mt, updateUser as n, commonArgs as nn, startCommand as nt, listUsers as o, withCommonArgs as on, executionsCommand as ot, getCommand as p, executeScript as pt, webhookCommand as q, loadWorkspaceId as qt, removeCommand as r, confirmationArgs as rn, startWorkflow as rt, inviteCommand as s, workspaceArgs as sn, getWorkflowExecution as st, updateCommand as t, PATScope as tn, watchExecutorJob as tt, restoreWorkspace as u, getExecutor as ut, createWorkspace as v, DB_TYPES_FILE_NAME as vt, resumeWorkflow as w, compareSnapshots as wt, getAppHealth as x, MIGRATE_FILE_NAME as xt, listApps as y, DIFF_FILE_NAME as yt, getOAuth2Client as z, trnPrefix as zt };
15419
- //# sourceMappingURL=update-Dm8ERWHJ.mjs.map
15412
+ //# sourceMappingURL=update-C_ZTRB63.mjs.map