windmill-cli 1.615.2 → 1.616.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.
@@ -32,7 +32,7 @@ export const OpenAPI = {
32
32
  PASSWORD: undefined,
33
33
  TOKEN: getEnv("WM_TOKEN"),
34
34
  USERNAME: undefined,
35
- VERSION: '1.615.2',
35
+ VERSION: '1.616.0',
36
36
  WITH_CREDENTIALS: true,
37
37
  interceptors: {
38
38
  request: new Interceptors(),
@@ -9042,6 +9042,324 @@ export const testSqsConnection = (data) => {
9042
9042
  mediaType: 'application/json'
9043
9043
  });
9044
9044
  };
9045
+ /**
9046
+ * list available native trigger services
9047
+ * @param data The data for the request.
9048
+ * @param data.workspace
9049
+ * @returns WorkspaceIntegrations native trigger services list
9050
+ * @throws ApiError
9051
+ */
9052
+ export const listNativeTriggerServices = (data) => {
9053
+ return __request(OpenAPI, {
9054
+ method: 'GET',
9055
+ url: '/w/{workspace}/native_triggers/integrations/list',
9056
+ path: {
9057
+ workspace: data.workspace
9058
+ }
9059
+ });
9060
+ };
9061
+ /**
9062
+ * check if integrations for a particular service exists
9063
+ * @param data The data for the request.
9064
+ * @param data.workspace
9065
+ * @param data.serviceName
9066
+ * @returns boolean integration exists
9067
+ * @throws ApiError
9068
+ */
9069
+ export const checkIfNativeTriggersServiceExists = (data) => {
9070
+ return __request(OpenAPI, {
9071
+ method: 'GET',
9072
+ url: '/w/{workspace}/native_triggers/integrations/{service_name}/exists',
9073
+ path: {
9074
+ workspace: data.workspace,
9075
+ service_name: data.serviceName
9076
+ }
9077
+ });
9078
+ };
9079
+ /**
9080
+ * create native trigger service
9081
+ * @param data The data for the request.
9082
+ * @param data.workspace
9083
+ * @param data.serviceName
9084
+ * @param data.requestBody new native trigger service
9085
+ * @returns string native trigger service created
9086
+ * @throws ApiError
9087
+ */
9088
+ export const createNativeTriggerService = (data) => {
9089
+ return __request(OpenAPI, {
9090
+ method: 'POST',
9091
+ url: '/w/{workspace}/native_triggers/integrations/{service_name}/create',
9092
+ path: {
9093
+ workspace: data.workspace,
9094
+ service_name: data.serviceName
9095
+ },
9096
+ body: data.requestBody,
9097
+ mediaType: 'application/json'
9098
+ });
9099
+ };
9100
+ /**
9101
+ * generate connect url for native trigger service
9102
+ * @param data The data for the request.
9103
+ * @param data.workspace
9104
+ * @param data.serviceName
9105
+ * @param data.requestBody redirect_uri
9106
+ * @returns string native trigger service connect url
9107
+ * @throws ApiError
9108
+ */
9109
+ export const generateNativeTriggerServiceConnectUrl = (data) => {
9110
+ return __request(OpenAPI, {
9111
+ method: 'POST',
9112
+ url: '/w/{workspace}/native_triggers/integrations/{service_name}/generate_connect_url',
9113
+ path: {
9114
+ workspace: data.workspace,
9115
+ service_name: data.serviceName
9116
+ },
9117
+ body: data.requestBody,
9118
+ mediaType: 'application/json'
9119
+ });
9120
+ };
9121
+ /**
9122
+ * delete native trigger service
9123
+ * @param data The data for the request.
9124
+ * @param data.workspace
9125
+ * @param data.serviceName
9126
+ * @returns string native trigger service deleted
9127
+ * @throws ApiError
9128
+ */
9129
+ export const deleteNativeTriggerService = (data) => {
9130
+ return __request(OpenAPI, {
9131
+ method: 'DELETE',
9132
+ url: '/w/{workspace}/native_triggers/integrations/{service_name}/delete',
9133
+ path: {
9134
+ workspace: data.workspace,
9135
+ service_name: data.serviceName
9136
+ }
9137
+ });
9138
+ };
9139
+ /**
9140
+ * native trigger service oauth callback
9141
+ * @param data The data for the request.
9142
+ * @param data.workspace
9143
+ * @param data.serviceName
9144
+ * @param data.code
9145
+ * @param data.state
9146
+ * @param data.requestBody redirect_uri
9147
+ * @returns string native trigger service oauth completed
9148
+ * @throws ApiError
9149
+ */
9150
+ export const nativeTriggerServiceCallback = (data) => {
9151
+ return __request(OpenAPI, {
9152
+ method: 'POST',
9153
+ url: '/w/{workspace}/native_triggers/integrations/{service_name}/callback/{code}/{state}',
9154
+ path: {
9155
+ workspace: data.workspace,
9156
+ service_name: data.serviceName,
9157
+ code: data.code,
9158
+ state: data.state
9159
+ },
9160
+ body: data.requestBody,
9161
+ mediaType: 'application/json'
9162
+ });
9163
+ };
9164
+ /**
9165
+ * create native trigger
9166
+ * Creates a new native trigger for the specified service.
9167
+ * Requires write access to the script or flow that the trigger will be associated with.
9168
+ *
9169
+ * @param data The data for the request.
9170
+ * @param data.workspace
9171
+ * @param data.serviceName
9172
+ * @param data.requestBody new native trigger configuration
9173
+ * @returns CreateTriggerResponse native trigger created
9174
+ * @throws ApiError
9175
+ */
9176
+ export const createNativeTrigger = (data) => {
9177
+ return __request(OpenAPI, {
9178
+ method: 'POST',
9179
+ url: '/w/{workspace}/native_triggers/{service_name}/create',
9180
+ path: {
9181
+ workspace: data.workspace,
9182
+ service_name: data.serviceName
9183
+ },
9184
+ body: data.requestBody,
9185
+ mediaType: 'application/json'
9186
+ });
9187
+ };
9188
+ /**
9189
+ * update native trigger
9190
+ * Updates an existing native trigger.
9191
+ * Requires write access to the script or flow that the trigger is associated with.
9192
+ *
9193
+ * @param data The data for the request.
9194
+ * @param data.workspace
9195
+ * @param data.serviceName
9196
+ * @param data.externalId The external ID of the trigger from the external service
9197
+ * @param data.requestBody updated native trigger configuration
9198
+ * @returns string native trigger updated
9199
+ * @throws ApiError
9200
+ */
9201
+ export const updateNativeTrigger = (data) => {
9202
+ return __request(OpenAPI, {
9203
+ method: 'POST',
9204
+ url: '/w/{workspace}/native_triggers/{service_name}/update/{external_id}',
9205
+ path: {
9206
+ workspace: data.workspace,
9207
+ service_name: data.serviceName,
9208
+ external_id: data.externalId
9209
+ },
9210
+ body: data.requestBody,
9211
+ mediaType: 'application/json'
9212
+ });
9213
+ };
9214
+ /**
9215
+ * get native trigger
9216
+ * Retrieves a native trigger by its external ID.
9217
+ * Requires write access to the script or flow that the trigger is associated with.
9218
+ *
9219
+ * @param data The data for the request.
9220
+ * @param data.workspace
9221
+ * @param data.serviceName
9222
+ * @param data.externalId The external ID of the trigger from the external service
9223
+ * @returns NativeTriggerWithExternal native trigger with external configuration
9224
+ * @throws ApiError
9225
+ */
9226
+ export const getNativeTrigger = (data) => {
9227
+ return __request(OpenAPI, {
9228
+ method: 'GET',
9229
+ url: '/w/{workspace}/native_triggers/{service_name}/get/{external_id}',
9230
+ path: {
9231
+ workspace: data.workspace,
9232
+ service_name: data.serviceName,
9233
+ external_id: data.externalId
9234
+ }
9235
+ });
9236
+ };
9237
+ /**
9238
+ * delete native trigger
9239
+ * Deletes a native trigger by its external ID.
9240
+ * Requires write access to the script or flow that the trigger is associated with.
9241
+ *
9242
+ * @param data The data for the request.
9243
+ * @param data.workspace
9244
+ * @param data.serviceName
9245
+ * @param data.externalId The external ID of the trigger from the external service
9246
+ * @returns string native trigger deleted
9247
+ * @throws ApiError
9248
+ */
9249
+ export const deleteNativeTrigger = (data) => {
9250
+ return __request(OpenAPI, {
9251
+ method: 'DELETE',
9252
+ url: '/w/{workspace}/native_triggers/{service_name}/delete/{external_id}',
9253
+ path: {
9254
+ workspace: data.workspace,
9255
+ service_name: data.serviceName,
9256
+ external_id: data.externalId
9257
+ }
9258
+ });
9259
+ };
9260
+ /**
9261
+ * list native triggers
9262
+ * Lists all native triggers for the specified service in the workspace.
9263
+ * @param data The data for the request.
9264
+ * @param data.workspace
9265
+ * @param data.serviceName
9266
+ * @param data.page which page to return (start at 1, default 1)
9267
+ * @param data.perPage number of items to return for a given page (default 30, max 100)
9268
+ * @returns NativeTrigger native triggers list
9269
+ * @throws ApiError
9270
+ */
9271
+ export const listNativeTriggers = (data) => {
9272
+ return __request(OpenAPI, {
9273
+ method: 'GET',
9274
+ url: '/w/{workspace}/native_triggers/{service_name}/list',
9275
+ path: {
9276
+ workspace: data.workspace,
9277
+ service_name: data.serviceName
9278
+ },
9279
+ query: {
9280
+ page: data.page,
9281
+ per_page: data.perPage
9282
+ }
9283
+ });
9284
+ };
9285
+ /**
9286
+ * check if native trigger exists
9287
+ * Checks if a native trigger with the given external ID exists.
9288
+ * @param data The data for the request.
9289
+ * @param data.workspace
9290
+ * @param data.serviceName
9291
+ * @param data.externalId The external ID of the trigger from the external service
9292
+ * @returns boolean whether the native trigger exists
9293
+ * @throws ApiError
9294
+ */
9295
+ export const existsNativeTrigger = (data) => {
9296
+ return __request(OpenAPI, {
9297
+ method: 'GET',
9298
+ url: '/w/{workspace}/native_triggers/{service_name}/exists/{external_id}',
9299
+ path: {
9300
+ workspace: data.workspace,
9301
+ service_name: data.serviceName,
9302
+ external_id: data.externalId
9303
+ }
9304
+ });
9305
+ };
9306
+ /**
9307
+ * sync native triggers with external service
9308
+ * @param data The data for the request.
9309
+ * @param data.workspace
9310
+ * @param data.serviceName
9311
+ * @returns unknown sync completed successfully
9312
+ * @throws ApiError
9313
+ */
9314
+ export const syncNativeTriggers = (data) => {
9315
+ return __request(OpenAPI, {
9316
+ method: 'POST',
9317
+ url: '/w/{workspace}/native_triggers/{service_name}/sync',
9318
+ path: {
9319
+ workspace: data.workspace,
9320
+ service_name: data.serviceName
9321
+ }
9322
+ });
9323
+ };
9324
+ /**
9325
+ * list available NextCloud events
9326
+ * @param data The data for the request.
9327
+ * @param data.workspace
9328
+ * @returns NextCloudEventType list of available NextCloud events
9329
+ * @throws ApiError
9330
+ */
9331
+ export const listNextCloudEvents = (data) => {
9332
+ return __request(OpenAPI, {
9333
+ method: 'GET',
9334
+ url: '/w/{workspace}/native_triggers/nextcloud/events',
9335
+ path: {
9336
+ workspace: data.workspace
9337
+ }
9338
+ });
9339
+ };
9340
+ /**
9341
+ * receive webhook from external native trigger service
9342
+ * @param data The data for the request.
9343
+ * @param data.serviceName
9344
+ * @param data.workspaceId
9345
+ * @param data.internalId The internal database ID of the trigger
9346
+ * @param data.requestBody webhook payload from external service
9347
+ * @returns string webhook received successfully
9348
+ * @throws ApiError
9349
+ */
9350
+ export const nativeTriggerWebhook = (data) => {
9351
+ return __request(OpenAPI, {
9352
+ method: 'POST',
9353
+ url: '/native_triggers/{service_name}/w/{workspace_id}/webhook/{internal_id}',
9354
+ path: {
9355
+ service_name: data.serviceName,
9356
+ workspace_id: data.workspaceId,
9357
+ internal_id: data.internalId
9358
+ },
9359
+ body: data.requestBody,
9360
+ mediaType: 'application/json'
9361
+ });
9362
+ };
9045
9363
  /**
9046
9364
  * create mqtt trigger
9047
9365
  * @param data The data for the request.
@@ -3,7 +3,7 @@ import { requireLogin } from "../../core/auth.js";
3
3
  import { resolveWorkspace } from "../../core/context.js";
4
4
  import { colors, Command, Confirm, ensureDir, log, minimatch, path, SEP, yamlParseContent, yamlStringify, } from "../../../deps.js";
5
5
  import * as wmill from "../../../gen/services.gen.js";
6
- import { getTypeStrFromPath, parseFromPath, pushObj, showConflict, showDiff, } from "../../types.js";
6
+ import { getTypeStrFromPath, parseFromPath, pushObj, showConflict, showDiff, extractNativeTriggerInfo, } from "../../types.js";
7
7
  import { downloadZip } from "./pull.js";
8
8
  import { exts, findContentFile, findResourceFile, handleScriptMetadata, removeExtensionToPath, } from "../script/script.js";
9
9
  import { handleFile } from "../script/script.js";
@@ -1107,7 +1107,8 @@ export async function elementsToMap(els, ignore, json, skips, specificItems, bra
1107
1107
  path.endsWith(".mqtt_trigger" + ext) ||
1108
1108
  path.endsWith(".sqs_trigger" + ext) ||
1109
1109
  path.endsWith(".gcp_trigger" + ext) ||
1110
- path.endsWith(".email_trigger" + ext))) {
1110
+ path.endsWith(".email_trigger" + ext) ||
1111
+ path.endsWith("_native_trigger" + ext))) {
1111
1112
  continue;
1112
1113
  }
1113
1114
  if (!skips.includeUsers && path.endsWith(".user" + ext))
@@ -1424,7 +1425,8 @@ function getOrderFromPath(p) {
1424
1425
  typ == "mqtt_trigger" ||
1425
1426
  typ == "sqs_trigger" ||
1426
1427
  typ == "gcp_trigger" ||
1427
- typ == "email_trigger") {
1428
+ typ == "email_trigger" ||
1429
+ typ == "native_trigger") {
1428
1430
  return 14;
1429
1431
  }
1430
1432
  else {
@@ -2293,6 +2295,18 @@ export async function push(opts) {
2293
2295
  path: removeSuffix(target, ".email_trigger.json"),
2294
2296
  });
2295
2297
  break;
2298
+ case "native_trigger": {
2299
+ const triggerInfo = extractNativeTriggerInfo(change.path);
2300
+ if (!triggerInfo) {
2301
+ throw new Error(`Invalid native trigger path: ${change.path}`);
2302
+ }
2303
+ await wmill.deleteNativeTrigger({
2304
+ workspace: workspaceId,
2305
+ serviceName: triggerInfo.serviceName,
2306
+ externalId: triggerInfo.externalId,
2307
+ });
2308
+ break;
2309
+ }
2296
2310
  case "variable":
2297
2311
  await wmill.deleteVariable({
2298
2312
  workspace: workspaceId,
@@ -1,7 +1,7 @@
1
1
  import * as dntShim from "../../../_dnt.shims.js";
2
2
  import * as wmill from "../../../gen/services.gen.js";
3
3
  import { colors, Command, log, SEP, Table } from "../../../deps.js";
4
- import { isSuperset, parseFromFile, removeType, TRIGGER_TYPES, } from "../../types.js";
4
+ import { isSuperset, parseFromFile, removeType, TRIGGER_TYPES, extractNativeTriggerInfo, } from "../../types.js";
5
5
  import { fromBranchSpecificPath, isBranchSpecificFile, } from "../../core/specific_items.js";
6
6
  import { getCurrentGitBranch } from "../../utils/git.js";
7
7
  import { requireLogin } from "../../core/auth.js";
@@ -94,6 +94,85 @@ export async function pushTrigger(triggerType, workspace, path, trigger, localTr
94
94
  }
95
95
  }
96
96
  }
97
+ export async function pushNativeTrigger(workspace, filePath, _remoteTrigger, localTrigger) {
98
+ const triggerInfo = extractNativeTriggerInfo(filePath);
99
+ if (!triggerInfo) {
100
+ throw new Error(`Invalid native trigger file path: ${filePath}. Expected format: {script_path}.{flow|script}.{external_id}.{service}_native_trigger.json`);
101
+ }
102
+ const { externalId, serviceName } = triggerInfo;
103
+ log.debug(`Processing local native trigger: service=${serviceName}, external_id=${externalId}`);
104
+ let remoteTrigger;
105
+ try {
106
+ const result = await wmill.getNativeTrigger({
107
+ workspace,
108
+ serviceName: serviceName,
109
+ externalId,
110
+ });
111
+ // getNativeTrigger returns NativeTriggerWithExternal, extract NativeTrigger fields
112
+ remoteTrigger = {
113
+ external_id: result.external_id,
114
+ workspace_id: result.workspace_id,
115
+ service_name: result.service_name,
116
+ script_path: result.script_path,
117
+ is_flow: result.is_flow,
118
+ service_config: result.service_config,
119
+ error: result.error,
120
+ };
121
+ log.debug(`Native trigger ${serviceName}/${externalId} exists on remote`);
122
+ }
123
+ catch {
124
+ log.debug(`Native trigger ${serviceName}/${externalId} does not exist on remote`);
125
+ }
126
+ const triggerData = {
127
+ script_path: localTrigger.script_path,
128
+ is_flow: localTrigger.is_flow,
129
+ service_config: localTrigger.service_config,
130
+ };
131
+ if (remoteTrigger) {
132
+ // Compare relevant fields
133
+ const localCompare = {
134
+ script_path: localTrigger.script_path,
135
+ is_flow: localTrigger.is_flow,
136
+ service_config: localTrigger.service_config,
137
+ };
138
+ const remoteCompare = {
139
+ script_path: remoteTrigger.script_path,
140
+ is_flow: remoteTrigger.is_flow,
141
+ service_config: remoteTrigger.service_config,
142
+ };
143
+ if (isSuperset(localCompare, remoteCompare)) {
144
+ log.debug(`Native trigger ${serviceName}/${externalId} is up to date`);
145
+ return;
146
+ }
147
+ log.debug(`Native trigger ${serviceName}/${externalId} is not up-to-date, updating...`);
148
+ try {
149
+ await wmill.updateNativeTrigger({
150
+ workspace,
151
+ serviceName: serviceName,
152
+ externalId,
153
+ requestBody: triggerData,
154
+ });
155
+ }
156
+ catch (e) {
157
+ console.error(e.body);
158
+ throw e;
159
+ }
160
+ }
161
+ else {
162
+ console.log(colors.bold.yellow(`Creating new native trigger: ${serviceName}/${externalId}`));
163
+ try {
164
+ await wmill.createNativeTrigger({
165
+ workspace,
166
+ serviceName: serviceName,
167
+ requestBody: triggerData,
168
+ });
169
+ }
170
+ catch (e) {
171
+ console.error(e.body);
172
+ throw e;
173
+ }
174
+ }
175
+ }
97
176
  async function list(opts) {
98
177
  const workspace = await resolveWorkspace(opts);
99
178
  await requireLogin(opts);
package/esm/src/main.js CHANGED
@@ -40,7 +40,7 @@ export { flow, app, script, workspace, resource, resourceType, user, variable, h
40
40
  // console.error(JSON.stringify(event.error, null, 4));
41
41
  // }
42
42
  // });
43
- export const VERSION = "1.615.2";
43
+ export const VERSION = "1.616.0";
44
44
  // Re-exported from constants.ts to maintain backwards compatibility
45
45
  export { WM_FORK_PREFIX } from "./core/constants.js";
46
46
  const command = new Command()
package/esm/src/types.js CHANGED
@@ -15,7 +15,7 @@ import { pushWorkspaceUser } from "./commands/user/user.js";
15
15
  import { pushGroup } from "./commands/user/user.js";
16
16
  import { pushWorkspaceDependencies } from "./commands/dependencies/dependencies.js";
17
17
  import { pushWorkspaceSettings, pushWorkspaceKey } from "./core/settings.js";
18
- import { pushTrigger } from "./commands/trigger/trigger.js";
18
+ import { pushTrigger, pushNativeTrigger } from "./commands/trigger/trigger.js";
19
19
  import { pushRawApp } from "./commands/app/raw_apps.js";
20
20
  import { isFlowPath, isAppPath, isRawAppPath, extractResourceName, buildFolderPath, } from "./utils/resource_folders.js";
21
21
  export const TRIGGER_TYPES = [
@@ -29,6 +29,7 @@ export const TRIGGER_TYPES = [
29
29
  "gcp",
30
30
  "email",
31
31
  ];
32
+ export const NATIVE_TRIGGER_SERVICES = ["nextcloud"];
32
33
  export function isSuperset(subset, superset) {
33
34
  return Object.keys(subset).every((key) => {
34
35
  const eq = deepEqual(subset[key], superset[key]);
@@ -150,6 +151,9 @@ export async function pushObj(workspace, p, befObj, newObj, plainSecrets, alread
150
151
  else if (typeEnding === "email_trigger") {
151
152
  await pushTrigger("email", workspace, p, befObj, newObj);
152
153
  }
154
+ else if (typeEnding === "native_trigger") {
155
+ await pushNativeTrigger(workspace, p, befObj, newObj);
156
+ }
153
157
  else if (typeEnding === "user") {
154
158
  await pushWorkspaceUser(workspace, p, befObj, newObj);
155
159
  }
@@ -234,6 +238,10 @@ export function getTypeStrFromPath(p) {
234
238
  return "encryption_key";
235
239
  }
236
240
  const typeEnding = parsed.name.split(".").at(-1);
241
+ // Check for native trigger: {service}_native_trigger pattern
242
+ if (typeEnding?.endsWith("_native_trigger")) {
243
+ return "native_trigger";
244
+ }
237
245
  if (typeEnding === "script" ||
238
246
  typeEnding === "variable" ||
239
247
  typeEnding === "resource" ||
@@ -271,6 +279,27 @@ export function removeType(str, type) {
271
279
  }
272
280
  return normalizedStr.slice(0, normalizedStr.length - type.length - 6);
273
281
  }
282
+ /**
283
+ * Extracts native trigger info from a path like:
284
+ * u/admin/script.flow.12345.nextcloud_native_trigger.json
285
+ * Returns { scriptPath: "u/admin/script", isFlow: true, externalId: "12345", serviceName: "nextcloud" }
286
+ */
287
+ export function extractNativeTriggerInfo(p) {
288
+ // Remove extension (.json or .yaml)
289
+ const normalizedPath = path.normalize(p).replaceAll(SEP, "/");
290
+ const withoutExt = normalizedPath.replace(/\.(json|yaml)$/, "");
291
+ // Match pattern: {script_path}.{flow|script}.{external_id}.{service}_native_trigger
292
+ const match = withoutExt.match(/^(.+)\.(flow|script)\.([^.]+)\.(\w+)_native_trigger$/);
293
+ if (!match) {
294
+ return null;
295
+ }
296
+ return {
297
+ scriptPath: match[1],
298
+ isFlow: match[2] === "flow",
299
+ externalId: match[3],
300
+ serviceName: match[4],
301
+ };
302
+ }
274
303
  export function removePathPrefix(str, prefix) {
275
304
  // Normalize paths for cross-platform compatibility and convert to forward slashes for API consistency
276
305
  const normalizedStr = path.normalize(str).replaceAll(SEP, "/");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "windmill-cli",
3
- "version": "1.615.2",
3
+ "version": "1.616.0",
4
4
  "description": "CLI for Windmill",
5
5
  "repository": {
6
6
  "type": "git",