@observeone/cli 1.10.0 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +46 -2
  2. package/dist/README.md +46 -2
  3. package/dist/commands/ai-check/index.d.ts.map +1 -1
  4. package/dist/commands/ai-check/index.js +1 -0
  5. package/dist/commands/ai-check/index.js.map +1 -1
  6. package/dist/commands/alert-channel.d.ts.map +1 -1
  7. package/dist/commands/alert-channel.js +30 -1
  8. package/dist/commands/alert-channel.js.map +1 -1
  9. package/dist/commands/apply.d.ts.map +1 -1
  10. package/dist/commands/apply.js +114 -80
  11. package/dist/commands/apply.js.map +1 -1
  12. package/dist/commands/check.d.ts.map +1 -1
  13. package/dist/commands/check.js +38 -1
  14. package/dist/commands/check.js.map +1 -1
  15. package/dist/commands/export.d.ts.map +1 -1
  16. package/dist/commands/export.js +2 -13
  17. package/dist/commands/export.js.map +1 -1
  18. package/dist/commands/heartbeat.d.ts.map +1 -1
  19. package/dist/commands/heartbeat.js +1 -0
  20. package/dist/commands/heartbeat.js.map +1 -1
  21. package/dist/commands/monitor.d.ts.map +1 -1
  22. package/dist/commands/monitor.js +40 -3
  23. package/dist/commands/monitor.js.map +1 -1
  24. package/dist/commands/resource-command.factory.d.ts +2 -0
  25. package/dist/commands/resource-command.factory.d.ts.map +1 -1
  26. package/dist/commands/resource-command.factory.js +15 -5
  27. package/dist/commands/resource-command.factory.js.map +1 -1
  28. package/dist/commands/suite/formatters.js +2 -2
  29. package/dist/commands/suite/formatters.js.map +1 -1
  30. package/dist/commands/suite/index.d.ts.map +1 -1
  31. package/dist/commands/suite/index.js +6 -0
  32. package/dist/commands/suite/index.js.map +1 -1
  33. package/dist/commands/suite/pull.d.ts +6 -0
  34. package/dist/commands/suite/pull.d.ts.map +1 -0
  35. package/dist/commands/suite/pull.js +61 -0
  36. package/dist/commands/suite/pull.js.map +1 -0
  37. package/dist/commands/suite/push.d.ts +6 -0
  38. package/dist/commands/suite/push.d.ts.map +1 -0
  39. package/dist/commands/suite/push.js +92 -0
  40. package/dist/commands/suite/push.js.map +1 -0
  41. package/dist/commands/suite/update.d.ts +6 -0
  42. package/dist/commands/suite/update.d.ts.map +1 -0
  43. package/dist/commands/suite/update.js +48 -0
  44. package/dist/commands/suite/update.js.map +1 -0
  45. package/dist/interfaces/api-client.interface.d.ts +4 -1
  46. package/dist/interfaces/api-client.interface.d.ts.map +1 -1
  47. package/dist/package.json +5 -2
  48. package/dist/services/api-client.service.d.ts +40 -1
  49. package/dist/services/api-client.service.d.ts.map +1 -1
  50. package/dist/services/api-client.service.js +103 -16
  51. package/dist/services/api-client.service.js.map +1 -1
  52. package/dist/services/output.service.d.ts.map +1 -1
  53. package/dist/services/output.service.js +23 -8
  54. package/dist/services/output.service.js.map +1 -1
  55. package/dist/types/index.d.ts +21 -2
  56. package/dist/types/index.d.ts.map +1 -1
  57. package/dist/utils/deep-equal.d.ts +6 -0
  58. package/dist/utils/deep-equal.d.ts.map +1 -1
  59. package/dist/utils/deep-equal.js +11 -0
  60. package/dist/utils/deep-equal.js.map +1 -1
  61. package/dist/utils/list-query.d.ts +6 -0
  62. package/dist/utils/list-query.d.ts.map +1 -0
  63. package/dist/utils/list-query.js +32 -0
  64. package/dist/utils/list-query.js.map +1 -0
  65. package/package.json +9 -3
package/README.md CHANGED
@@ -71,8 +71,11 @@ obs export -f my-stack.json
71
71
  ```
72
72
 
73
73
  ### `obs apply`
74
- Sync your local JSON configuration to the ObserveOne backend. The CLI will automatically detect matching resources and perform surgical `create` and `update` API calls.
74
+ Sync your local JSON configuration to the ObserveOne backend. Only changed resources are updated unchanged ones are skipped.
75
75
  ```bash
76
+ # Preview what would change (no writes)
77
+ obs apply --dry-run
78
+
76
79
  # Sync obs.json
77
80
  obs apply
78
81
 
@@ -80,6 +83,19 @@ obs apply
80
83
  obs apply -f my-stack.json
81
84
  ```
82
85
 
86
+ `--dry-run` fetches remote state, runs the full diff, and prints a git-style preview:
87
+ ```
88
+ ~ monitor "Production API"
89
+ - cron_expression: "*/5 * * * *"
90
+ + cron_expression: "*/10 * * * *"
91
+
92
+ + monitor "Staging DB" (new)
93
+
94
+ Monitors: 1 to create, 1 to update, 12 unchanged
95
+
96
+ Run without --dry-run to apply.
97
+ ```
98
+
83
99
  **Example `obs.json` schema:**
84
100
  ```json
85
101
  {
@@ -88,7 +104,7 @@ obs apply -f my-stack.json
88
104
  "name": "Production Website",
89
105
  "description": "Main landing page monitor",
90
106
  "url": "https://example.com",
91
- "interval": "*/5 * * * *",
107
+ "cron_expression": "*/5 * * * *",
92
108
  "alert_on_failure": true
93
109
  }
94
110
  ],
@@ -119,6 +135,7 @@ You can manually create, read, update, delete, and toggle individual resources d
119
135
  ```bash
120
136
  obs monitor create --name "Frontend" --url "https://example.com" --interval "*/5 * * * *"
121
137
  obs monitor list
138
+ obs monitor list --search "Front" --status up --is-active true --limit 10 --page 1 --json
122
139
  obs monitor get <id>
123
140
  obs monitor update <id> --name "Updated Frontend" --interval "*/10 * * * *"
124
141
  obs monitor toggle <id>
@@ -129,6 +146,7 @@ obs monitor delete <id> -y
129
146
  ```bash
130
147
  obs check create --name "Auth API" --url "https://api.example.com/auth" --method "POST"
131
148
  obs check list
149
+ obs check list --search "Auth" --status paused --is-active false --json
132
150
  obs check update <id> --method "GET"
133
151
  obs check toggle <id>
134
152
  obs check delete <id> -y
@@ -138,11 +156,18 @@ obs check delete <id> -y
138
156
  ```bash
139
157
  obs heartbeat create --name "Daily Backup" --period 86400 --grace 3600
140
158
  obs heartbeat list
159
+ obs heartbeat list --search "Backup" --status late --limit 5 --json
141
160
  obs heartbeat update <id> --period 43200
142
161
  obs heartbeat toggle <id>
143
162
  obs heartbeat delete <id> -y
144
163
  ```
145
164
 
165
+ List filtering notes:
166
+ - `--search` matches visible fields server-side.
167
+ - `--status` uses each resource's real status values.
168
+ - `--is-active true|false` filters by activation state separately from status.
169
+ - `--page` and `--limit` enable server-side pagination.
170
+
146
171
  ### Alert Channels
147
172
  ```bash
148
173
  obs alert-channel create --name "Ops Email" --type email --email "ops@example.com"
@@ -283,6 +308,25 @@ Append `--json` to **any** command. The CLI will automatically suppress all huma
283
308
  }
284
309
  ```
285
310
 
311
+ For filtered list commands, the `data` payload is paginated:
312
+ ```json
313
+ {
314
+ "status": "SUCCESS",
315
+ "data": {
316
+ "items": [],
317
+ "pagination": {
318
+ "page": 1,
319
+ "limit": 10,
320
+ "total": 0,
321
+ "totalPages": 0
322
+ }
323
+ },
324
+ "metadata": {
325
+ "timestamp": "2026-04-22T12:00:00.000Z"
326
+ }
327
+ }
328
+ ```
329
+
286
330
  ### Headless Login
287
331
  Agents can authenticate securely using existing credentials:
288
332
  ```bash
package/dist/README.md CHANGED
@@ -71,8 +71,11 @@ obs export -f my-stack.json
71
71
  ```
72
72
 
73
73
  ### `obs apply`
74
- Sync your local JSON configuration to the ObserveOne backend. The CLI will automatically detect matching resources and perform surgical `create` and `update` API calls.
74
+ Sync your local JSON configuration to the ObserveOne backend. Only changed resources are updated unchanged ones are skipped.
75
75
  ```bash
76
+ # Preview what would change (no writes)
77
+ obs apply --dry-run
78
+
76
79
  # Sync obs.json
77
80
  obs apply
78
81
 
@@ -80,6 +83,19 @@ obs apply
80
83
  obs apply -f my-stack.json
81
84
  ```
82
85
 
86
+ `--dry-run` fetches remote state, runs the full diff, and prints a git-style preview:
87
+ ```
88
+ ~ monitor "Production API"
89
+ - cron_expression: "*/5 * * * *"
90
+ + cron_expression: "*/10 * * * *"
91
+
92
+ + monitor "Staging DB" (new)
93
+
94
+ Monitors: 1 to create, 1 to update, 12 unchanged
95
+
96
+ Run without --dry-run to apply.
97
+ ```
98
+
83
99
  **Example `obs.json` schema:**
84
100
  ```json
85
101
  {
@@ -88,7 +104,7 @@ obs apply -f my-stack.json
88
104
  "name": "Production Website",
89
105
  "description": "Main landing page monitor",
90
106
  "url": "https://example.com",
91
- "interval": "*/5 * * * *",
107
+ "cron_expression": "*/5 * * * *",
92
108
  "alert_on_failure": true
93
109
  }
94
110
  ],
@@ -119,6 +135,7 @@ You can manually create, read, update, delete, and toggle individual resources d
119
135
  ```bash
120
136
  obs monitor create --name "Frontend" --url "https://example.com" --interval "*/5 * * * *"
121
137
  obs monitor list
138
+ obs monitor list --search "Front" --status up --is-active true --limit 10 --page 1 --json
122
139
  obs monitor get <id>
123
140
  obs monitor update <id> --name "Updated Frontend" --interval "*/10 * * * *"
124
141
  obs monitor toggle <id>
@@ -129,6 +146,7 @@ obs monitor delete <id> -y
129
146
  ```bash
130
147
  obs check create --name "Auth API" --url "https://api.example.com/auth" --method "POST"
131
148
  obs check list
149
+ obs check list --search "Auth" --status paused --is-active false --json
132
150
  obs check update <id> --method "GET"
133
151
  obs check toggle <id>
134
152
  obs check delete <id> -y
@@ -138,11 +156,18 @@ obs check delete <id> -y
138
156
  ```bash
139
157
  obs heartbeat create --name "Daily Backup" --period 86400 --grace 3600
140
158
  obs heartbeat list
159
+ obs heartbeat list --search "Backup" --status late --limit 5 --json
141
160
  obs heartbeat update <id> --period 43200
142
161
  obs heartbeat toggle <id>
143
162
  obs heartbeat delete <id> -y
144
163
  ```
145
164
 
165
+ List filtering notes:
166
+ - `--search` matches visible fields server-side.
167
+ - `--status` uses each resource's real status values.
168
+ - `--is-active true|false` filters by activation state separately from status.
169
+ - `--page` and `--limit` enable server-side pagination.
170
+
146
171
  ### Alert Channels
147
172
  ```bash
148
173
  obs alert-channel create --name "Ops Email" --type email --email "ops@example.com"
@@ -283,6 +308,25 @@ Append `--json` to **any** command. The CLI will automatically suppress all huma
283
308
  }
284
309
  ```
285
310
 
311
+ For filtered list commands, the `data` payload is paginated:
312
+ ```json
313
+ {
314
+ "status": "SUCCESS",
315
+ "data": {
316
+ "items": [],
317
+ "pagination": {
318
+ "page": 1,
319
+ "limit": 10,
320
+ "total": 0,
321
+ "totalPages": 0
322
+ }
323
+ },
324
+ "metadata": {
325
+ "timestamp": "2026-04-22T12:00:00.000Z"
326
+ }
327
+ }
328
+ ```
329
+
286
330
  ### Headless Login
287
331
  Agents can authenticate securely using existing credentials:
288
332
  ```bash
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/ai-check/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAStE,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,cAAc,EAC7B,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,cAAc,GAC5B,OAAO,CAcT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/ai-check/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAStE,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,cAAc,EAC7B,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,cAAc,GAC5B,OAAO,CAeT"}
@@ -8,6 +8,7 @@ import { createAiCheckStatusCommand } from './status.js';
8
8
  import { createAiCheckWaitCommand } from './wait.js';
9
9
  export function createAiCheckCommand(configService, apiClient, outputService) {
10
10
  const aiCheck = new Command('ai-check').description('Manage and run AI-powered tests');
11
+ aiCheck._hidden = true;
11
12
  aiCheck.addCommand(createAiCheckRunCommand(configService, apiClient, outputService), {
12
13
  isDefault: true,
13
14
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/ai-check/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAErD,MAAM,UAAU,oBAAoB,CAClC,aAA6B,EAC7B,SAAqB,EACrB,aAA6B;IAE7B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,iCAAiC,CAAC,CAAC;IAEvF,OAAO,CAAC,UAAU,CAAC,uBAAuB,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,EAAE;QACnF,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;IACH,OAAO,CAAC,UAAU,CAAC,wBAAwB,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IACtF,OAAO,CAAC,UAAU,CAAC,uBAAuB,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IACrF,OAAO,CAAC,UAAU,CAAC,0BAA0B,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IACxF,OAAO,CAAC,UAAU,CAAC,0BAA0B,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IACxF,OAAO,CAAC,UAAU,CAAC,0BAA0B,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IACxF,OAAO,CAAC,UAAU,CAAC,wBAAwB,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IAEtF,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/ai-check/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAErD,MAAM,UAAU,oBAAoB,CAClC,aAA6B,EAC7B,SAAqB,EACrB,aAA6B;IAE7B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,iCAAiC,CAAC,CAAC;IACtF,OAA2C,CAAC,OAAO,GAAG,IAAI,CAAC;IAE5D,OAAO,CAAC,UAAU,CAAC,uBAAuB,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,EAAE;QACnF,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;IACH,OAAO,CAAC,UAAU,CAAC,wBAAwB,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IACtF,OAAO,CAAC,UAAU,CAAC,uBAAuB,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IACrF,OAAO,CAAC,UAAU,CAAC,0BAA0B,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IACxF,OAAO,CAAC,UAAU,CAAC,0BAA0B,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IACxF,OAAO,CAAC,UAAU,CAAC,0BAA0B,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IACxF,OAAO,CAAC,UAAU,CAAC,wBAAwB,CAAC,aAAa,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;IAEtF,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"alert-channel.d.ts","sourceRoot":"","sources":["../../src/commands/alert-channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAmEnE,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,cAAc,EAC7B,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,cAAc,GAC5B,OAAO,CAyHT"}
1
+ {"version":3,"file":"alert-channel.d.ts","sourceRoot":"","sources":["../../src/commands/alert-channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAoEnE,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,cAAc,EAC7B,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,cAAc,GAC5B,OAAO,CAuJT"}
@@ -1,3 +1,4 @@
1
+ import chalk from 'chalk';
1
2
  import inquirer from 'inquirer';
2
3
  import { createResourceCommand } from './resource-command.factory.js';
3
4
  const channelTypes = [
@@ -54,7 +55,7 @@ async function buildConfigFromOptions(type, options, existingConfig) {
54
55
  return config;
55
56
  }
56
57
  export function createAlertChannelCommand(configService, apiClient, outputService) {
57
- return createResourceCommand(configService, apiClient, outputService, {
58
+ const cmd = createResourceCommand(configService, apiClient, outputService, {
58
59
  resourceName: 'alert-channel',
59
60
  pluralName: 'alert channels',
60
61
  description: 'Manage alert channels',
@@ -159,5 +160,33 @@ export function createAlertChannelCommand(configService, apiClient, outputServic
159
160
  };
160
161
  },
161
162
  });
163
+ cmd
164
+ .command('test <id>')
165
+ .description('Send a test notification through an alert channel')
166
+ .action(async (id) => {
167
+ const isJson = process.env.OBS_JSON_OUTPUT === 'true';
168
+ try {
169
+ const channelId = parseInt(id);
170
+ if (isNaN(channelId))
171
+ throw new Error('Invalid channel ID');
172
+ const result = await apiClient.testAlertChannel(channelId);
173
+ if (isJson) {
174
+ outputService.formatJsonOutput({ success: result.success, message: result.message });
175
+ return;
176
+ }
177
+ console.log(chalk.bold(`\n ${result.message}\n`));
178
+ }
179
+ catch (err) {
180
+ const msg = err.message || 'Failed to test alert channel';
181
+ if (isJson) {
182
+ outputService.formatJsonOutput({ status: 'ERROR', error: { message: msg } });
183
+ }
184
+ else {
185
+ console.error(chalk.red(`\n ${msg}\n`));
186
+ }
187
+ process.exit(1);
188
+ }
189
+ });
190
+ return cmd;
162
191
  }
163
192
  //# sourceMappingURL=alert-channel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"alert-channel.js","sourceRoot":"","sources":["../../src/commands/alert-channel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"alert-channel.js","sourceRoot":"","sources":["../../src/commands/alert-channel.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/commands/apply.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAqCnE,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,cAAc,EAC7B,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,cAAc,GAC5B,OAAO,CAicT"}
1
+ {"version":3,"file":"apply.d.ts","sourceRoot":"","sources":["../../src/commands/apply.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AA2FnE,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,cAAc,EAC7B,SAAS,EAAE,UAAU,EACrB,aAAa,EAAE,cAAc,GAC5B,OAAO,CA6aT"}
@@ -1,7 +1,7 @@
1
1
  import { Command } from 'commander';
2
2
  import { readFileSync, existsSync } from 'fs';
3
3
  import ora from 'ora';
4
- import { deepEqual, normalizeResource } from '../utils/deep-equal.js';
4
+ import { deepEqual, normalizeResource, diffObjects } from '../utils/deep-equal.js';
5
5
  const chunkArray = (arr, size) => {
6
6
  const result = [];
7
7
  for (let i = 0; i < arr.length; i += size) {
@@ -10,15 +10,58 @@ const chunkArray = (arr, size) => {
10
10
  return result;
11
11
  };
12
12
  const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
13
+ function printDryRun(entries, summary) {
14
+ const chalk = {
15
+ green: (s) => `\x1b[32m${s}\x1b[0m`,
16
+ red: (s) => `\x1b[31m${s}\x1b[0m`,
17
+ yellow: (s) => `\x1b[33m${s}\x1b[0m`,
18
+ bold: (s) => `\x1b[1m${s}\x1b[0m`,
19
+ dim: (s) => `\x1b[2m${s}\x1b[0m`,
20
+ };
21
+ if (entries.length === 0) {
22
+ console.log(chalk.dim(' No changes. Everything is up to date.'));
23
+ return;
24
+ }
25
+ for (const entry of entries) {
26
+ if (entry.type === 'create') {
27
+ console.log(chalk.green(`+ ${entry.resource} "${entry.name}" (new)`));
28
+ }
29
+ else {
30
+ console.log(chalk.yellow(`~ ${entry.resource} "${entry.name}"`));
31
+ if (entry.diff) {
32
+ for (const [key, { from, to }] of Object.entries(entry.diff)) {
33
+ console.log(chalk.red(` - ${key}: ${JSON.stringify(from)}`));
34
+ console.log(chalk.green(` + ${key}: ${JSON.stringify(to)}`));
35
+ }
36
+ }
37
+ }
38
+ console.log('');
39
+ }
40
+ const totals = [
41
+ ['Monitors', summary.monitors],
42
+ ['API Checks', summary.apiChecks],
43
+ ['Heartbeats', summary.heartbeats],
44
+ ['AI Checks', summary.aiChecks],
45
+ ];
46
+ for (const [label, s] of totals) {
47
+ if (s.created + s.updated + s.unchanged > 0) {
48
+ console.log(` ${label}: ${s.created} to create, ${s.updated} to update, ${s.unchanged} unchanged`);
49
+ }
50
+ }
51
+ console.log('');
52
+ console.log(chalk.dim(' Run without --dry-run to apply.'));
53
+ }
13
54
  export function createApplyCommand(configService, apiClient, outputService) {
14
55
  const apply = new Command('apply')
15
56
  .description('Apply configuration from a JSON file (declarative workflow)')
16
57
  .argument('[file]', 'Path to the JSON configuration file')
17
58
  .option('-f, --file <path>', 'Path to the JSON configuration file')
18
59
  .option('-j, --json', 'Output in JSON format')
60
+ .option('--dry-run', 'Preview changes without applying them')
19
61
  .action(async (fileArg, options) => {
20
62
  const isVerbose = process.env.OBS_VERBOSE === 'true';
21
63
  const isJson = process.env.OBS_JSON_OUTPUT === 'true' || options.json === true;
64
+ const isDryRun = options.dryRun === true;
22
65
  if (isJson) {
23
66
  outputService.enableJsonMode();
24
67
  }
@@ -74,6 +117,7 @@ export function createApplyCommand(configService, apiClient, outputService) {
74
117
  aiChecks: { created: 0, updated: 0, unchanged: 0, errors: 0 },
75
118
  };
76
119
  const errors = [];
120
+ const dryRunEntries = [];
77
121
  const delayMs = 1000; // 1 second between chunks to respect 100 req/min rate limit
78
122
  // 1. Process URL Monitors
79
123
  if (config.monitors && Array.isArray(config.monitors)) {
@@ -95,14 +139,14 @@ export function createApplyCommand(configService, apiClient, outputService) {
95
139
  name: monitorConfig.name,
96
140
  url: monitorConfig.url,
97
141
  timeout_ms: monitorConfig.timeout_ms || 30000,
98
- cron_expression: monitorConfig.interval || monitorConfig.cron_expression,
142
+ interval: monitorConfig.interval,
99
143
  alert_on_failure: monitorConfig.alert_on_failure ?? true,
100
144
  }, { timeout_ms: 30000, alert_on_failure: true });
101
145
  const normalizedRemote = normalizeResource({
102
146
  name: existing.name,
103
147
  url: existing.url,
104
148
  timeout_ms: existing.timeout_ms || 30000,
105
- cron_expression: existing.interval || existing.cron_expression,
149
+ interval: existing.interval,
106
150
  alert_on_failure: existing.alert_on_failure ?? true,
107
151
  }, { timeout_ms: 30000, alert_on_failure: true });
108
152
  // Skip update if no changes
@@ -111,26 +155,40 @@ export function createApplyCommand(configService, apiClient, outputService) {
111
155
  summary.monitors.unchanged++;
112
156
  return;
113
157
  }
158
+ summary.monitors.updated++;
159
+ if (isDryRun) {
160
+ dryRunEntries.push({
161
+ type: 'update',
162
+ resource: 'monitor',
163
+ name: monitorConfig.name,
164
+ diff: diffObjects(normalizedRemote, normalizedLocal),
165
+ });
166
+ return;
167
+ }
114
168
  logProgress(`Updating monitor: ${monitorConfig.name}`);
115
169
  await apiClient.updateUrlMonitor(existing.id, {
116
170
  name: monitorConfig.name || existing.name,
117
171
  url: monitorConfig.url || existing.url,
118
172
  timeout_ms: monitorConfig.timeout_ms || existing.timeout_ms || 30000,
119
- cron_expression: monitorConfig.interval ||
120
- monitorConfig.cron_expression ||
121
- existing.cron_expression,
173
+ interval: monitorConfig.interval || existing.interval,
122
174
  alert_on_failure: monitorConfig.alert_on_failure ?? existing.alert_on_failure ?? true,
123
175
  });
124
- summary.monitors.updated++;
125
176
  }
126
177
  else {
178
+ summary.monitors.created++;
179
+ if (isDryRun) {
180
+ dryRunEntries.push({
181
+ type: 'create',
182
+ resource: 'monitor',
183
+ name: monitorConfig.name,
184
+ });
185
+ return;
186
+ }
127
187
  logProgress(`Creating monitor: ${monitorConfig.name}`);
128
188
  await apiClient.createUrlMonitor({
129
189
  ...monitorConfig,
130
- cron_expression: monitorConfig.interval || monitorConfig.cron_expression,
131
190
  timeout_ms: monitorConfig.timeout_ms || 30000,
132
191
  });
133
- summary.monitors.created++;
134
192
  }
135
193
  }
136
194
  catch (err) {
@@ -182,6 +240,16 @@ export function createApplyCommand(configService, apiClient, outputService) {
182
240
  summary.apiChecks.unchanged++;
183
241
  return;
184
242
  }
243
+ summary.apiChecks.updated++;
244
+ if (isDryRun) {
245
+ dryRunEntries.push({
246
+ type: 'update',
247
+ resource: 'api-check',
248
+ name: checkConfig.name,
249
+ diff: diffObjects(normalizedRemote, normalizedLocal),
250
+ });
251
+ return;
252
+ }
185
253
  logProgress(`Updating API check: ${checkConfig.name}`);
186
254
  await apiClient.updateApiCheck(existing.id, {
187
255
  name: checkConfig.name || existing.name,
@@ -190,16 +258,23 @@ export function createApplyCommand(configService, apiClient, outputService) {
190
258
  timeout_ms: checkConfig.timeout_ms || existing.timeout_ms || 30000,
191
259
  alert_on_failure: checkConfig.alert_on_failure ?? existing.alert_on_failure ?? true,
192
260
  });
193
- summary.apiChecks.updated++;
194
261
  }
195
262
  else {
263
+ summary.apiChecks.created++;
264
+ if (isDryRun) {
265
+ dryRunEntries.push({
266
+ type: 'create',
267
+ resource: 'api-check',
268
+ name: checkConfig.name,
269
+ });
270
+ return;
271
+ }
196
272
  logProgress(`Creating API check: ${checkConfig.name}`);
197
273
  await apiClient.createApiCheck({
198
274
  ...checkConfig,
199
275
  timeout_ms: checkConfig.timeout_ms || 30000,
200
276
  method: checkConfig.method?.toUpperCase() || 'GET',
201
277
  });
202
- summary.apiChecks.created++;
203
278
  }
204
279
  }
205
280
  catch (err) {
@@ -247,6 +322,16 @@ export function createApplyCommand(configService, apiClient, outputService) {
247
322
  summary.heartbeats.unchanged++;
248
323
  return;
249
324
  }
325
+ summary.heartbeats.updated++;
326
+ if (isDryRun) {
327
+ dryRunEntries.push({
328
+ type: 'update',
329
+ resource: 'heartbeat',
330
+ name: hbConfig.name,
331
+ diff: diffObjects(normalizedRemote, normalizedLocal),
332
+ });
333
+ return;
334
+ }
250
335
  logProgress(`Updating heartbeat: ${hbConfig.name}`);
251
336
  await apiClient.updateHeartbeat(existing.id, {
252
337
  name: hbConfig.name || existing.name,
@@ -254,15 +339,22 @@ export function createApplyCommand(configService, apiClient, outputService) {
254
339
  description: hbConfig.description || existing.description || 'Updated via CLI',
255
340
  grace_period: hbConfig.grace_period || existing.grace_period || 60,
256
341
  });
257
- summary.heartbeats.updated++;
258
342
  }
259
343
  else {
344
+ summary.heartbeats.created++;
345
+ if (isDryRun) {
346
+ dryRunEntries.push({
347
+ type: 'create',
348
+ resource: 'heartbeat',
349
+ name: hbConfig.name,
350
+ });
351
+ return;
352
+ }
260
353
  logProgress(`Creating heartbeat: ${hbConfig.name}`);
261
354
  await apiClient.createHeartbeat({
262
355
  name: hbConfig.name,
263
356
  period: hbConfig.period,
264
357
  });
265
- summary.heartbeats.created++;
266
358
  }
267
359
  }
268
360
  catch (err) {
@@ -278,76 +370,18 @@ export function createApplyCommand(configService, apiClient, outputService) {
278
370
  await delay(delayMs);
279
371
  }
280
372
  }
281
- // 4. Process AI Checks
282
- if (config.ai_checks && Array.isArray(config.ai_checks)) {
283
- logProgress('Fetching existing AI checks...');
284
- const existingAiChecks = await apiClient.getTests();
285
- const existingByName = new Map(existingAiChecks.map((t) => [t.name, t]));
286
- const chunks = chunkArray(config.ai_checks, 5);
287
- for (let i = 0; i < chunks.length; i++) {
288
- const chunk = chunks[i];
289
- await Promise.all(chunk.map(async (aiConfig) => {
290
- try {
291
- if (!aiConfig.name || !aiConfig.url || !aiConfig.prompt) {
292
- throw new Error("AI check must have 'name', 'url', and 'prompt'");
293
- }
294
- const existing = existingByName.get(aiConfig.name);
295
- if (existing) {
296
- // Normalize both objects for comparison
297
- const normalizedLocal = normalizeResource({
298
- name: aiConfig.name,
299
- url: aiConfig.url,
300
- prompt: aiConfig.prompt,
301
- description: aiConfig.description || '',
302
- }, { description: '' });
303
- const normalizedRemote = normalizeResource({
304
- name: existing.name,
305
- url: existing.url,
306
- prompt: existing.prompt,
307
- description: existing.description || '',
308
- }, { description: '' });
309
- // Skip update if no changes
310
- if (deepEqual(normalizedLocal, normalizedRemote)) {
311
- logProgress(`AI check unchanged: ${aiConfig.name}`);
312
- summary.aiChecks.unchanged++;
313
- return;
314
- }
315
- logProgress(`Updating AI check: ${aiConfig.name}`);
316
- await apiClient.updateTest(existing.id, {
317
- name: aiConfig.name || existing.name,
318
- url: aiConfig.url || existing.url,
319
- prompt: aiConfig.prompt || existing.prompt,
320
- description: aiConfig.description || existing.description || '',
321
- });
322
- summary.aiChecks.updated++;
323
- }
324
- else {
325
- logProgress(`Creating AI check: ${aiConfig.name}`);
326
- await apiClient.createTest({
327
- name: aiConfig.name,
328
- url: aiConfig.url,
329
- prompt: aiConfig.prompt,
330
- description: aiConfig.description || 'Created via CLI',
331
- });
332
- summary.aiChecks.created++;
333
- }
334
- }
335
- catch (err) {
336
- const errorObj = err;
337
- const details = errorObj.response?.data?.error ||
338
- errorObj.response?.data?.message ||
339
- errorObj.message;
340
- errors.push(`AI Check '${aiConfig.name || 'unknown'}': ${details}`);
341
- summary.aiChecks.errors++;
342
- }
343
- }));
344
- if (i < chunks.length - 1)
345
- await delay(delayMs);
346
- }
373
+ // 4. Browser checks are currently disabled
374
+ if (config.ai_checks && Array.isArray(config.ai_checks) && config.ai_checks.length > 0) {
375
+ outputService.warning('Browser checks are currently disabled. Skipping ai_checks entries.');
347
376
  }
348
377
  if (spinner) {
349
378
  spinner.stop();
350
379
  }
380
+ if (isDryRun) {
381
+ console.log('');
382
+ printDryRun(dryRunEntries, summary);
383
+ return;
384
+ }
351
385
  if (isJson) {
352
386
  outputService.formatJsonOutput({
353
387
  summary,
@@ -368,7 +402,7 @@ export function createApplyCommand(configService, apiClient, outputService) {
368
402
  console.log('');
369
403
  outputService.error('Some resources failed to apply:');
370
404
  errors.forEach((e) => console.log(` - ${e}`));
371
- process.exit(1); // Exit with error if any resource failed
405
+ process.exit(1);
372
406
  }
373
407
  }
374
408
  }