@secondlayer/sentinel 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -79,6 +79,13 @@ class SentinelError extends Error {
79
79
  this.name = "SentinelError";
80
80
  }
81
81
  }
82
+ var runInProgress = (status) => status === "queued" || status === "running";
83
+ function runPhase(run) {
84
+ if (run.status === "queued")
85
+ return "queued";
86
+ const last = run.events.at(-1);
87
+ return last ? [last.name ?? last.kind, last.state].filter(Boolean).join(" ") : "starting";
88
+ }
82
89
  var rowsOf = (intents) => intents.flatMap((i) => i.rows);
83
90
  var subjectKey = (s) => s.kind === "fn" ? `fn:${s.fn}` : s.kind === "group" ? `group:${s.group}` : `asset:${s.asset}`;
84
91
  var CONTROL_NAME = "Control changes";
@@ -226,6 +233,7 @@ function createClient(opts) {
226
233
  }
227
234
  const plan = (id) => `/v1/plans/${encodeURIComponent(id)}`;
228
235
  const appPlan = (id) => `/plan/${encodeURIComponent(id)}`;
236
+ const appProject = (id) => `/projects/${encodeURIComponent(id)}`;
229
237
  return {
230
238
  me: () => call("GET", "/v1/me"),
231
239
  plans: async () => (await call("GET", "/v1/plans")).plans,
@@ -241,6 +249,8 @@ function createClient(opts) {
241
249
  testsFromRepo: (id) => call("POST", `${appPlan(id)}/tests`, { fromRepo: true }),
242
250
  previewPlan: (contractId) => call("POST", "/plan/preview", { contractId }),
243
251
  createPlan: (contractId) => call("POST", "/plan", { contractId }),
252
+ previewImport: (url) => call("POST", "/projects/import/preview", { url }),
253
+ importRepo: (input) => call("POST", "/projects/import", input),
244
254
  billing: () => call("GET", "/billing"),
245
255
  watches: (planId) => call("GET", `${appPlan(planId)}/watches`),
246
256
  setRule: (planId, watchId, rule) => call("POST", `${appPlan(planId)}/watches/${encodeURIComponent(watchId)}/rule`, { rule }),
@@ -257,9 +267,69 @@ function createClient(opts) {
257
267
  watchContract: (contractId) => call("POST", "/contracts/watch", {
258
268
  contractId
259
269
  }),
260
- stopMonitoring: (planId) => call("DELETE", `${appPlan(planId)}/monitor`)
270
+ stopMonitoring: (planId) => call("DELETE", `${appPlan(planId)}/monitor`),
271
+ watchActivity: (planId, intentId, opts = {}) => call("GET", `${appPlan(planId)}/watches/${encodeURIComponent(intentId)}/activity${query(opts)}`),
272
+ functions: async (planId) => (await call("GET", `${appPlan(planId)}/functions`)).functions,
273
+ functionActivity: (planId, fn) => call("GET", `${appPlan(planId)}/functions/${encodeURIComponent(fn)}/activity`),
274
+ alertPreview: (planId, example) => call("GET", `${appPlan(planId)}/alert-preview${query({ example })}`),
275
+ threshold: (planId, asset) => call("GET", `${appPlan(planId)}/watches/asset/${encodeURIComponent(asset)}/threshold`),
276
+ setThreshold: (planId, asset, amount) => call("POST", `${appPlan(planId)}/watches/asset/${encodeURIComponent(asset)}/threshold`, { amount }),
277
+ retryHistory: (planId) => call("POST", `${appPlan(planId)}/history/retry`, {}),
278
+ readAlert: (alertId) => call("POST", `/alerts/${encodeURIComponent(alertId)}/read`),
279
+ readAllAlerts: () => call("POST", "/alerts/read-all"),
280
+ ask: (q) => call("POST", "/ask", { q }),
281
+ acknowledge: (planId, finding, title, reason, note = null) => call("POST", `${appPlan(planId)}/acknowledge`, {
282
+ finding,
283
+ title,
284
+ reason,
285
+ note
286
+ }),
287
+ reopen: (planId, finding, title) => call("POST", `${appPlan(planId)}/reopen`, { finding, title }),
288
+ ackHistory: async (planId) => (await call("GET", `${appPlan(planId)}/acks`)).events,
289
+ notes: async (planId, finding) => (await call("GET", `${appPlan(planId)}/findings/${finding}/notes`)).notes,
290
+ addNote: (planId, finding, title, body) => call("POST", `${appPlan(planId)}/findings/${finding}/notes`, {
291
+ title,
292
+ body
293
+ }),
294
+ tests: (planId, files) => call("POST", `${appPlan(planId)}/tests`, { files }),
295
+ fuzzCheck: (planId, harness) => call("POST", `${appPlan(planId)}/fuzzcheck`, { harness }),
296
+ fuzz: (planId, invariants) => call("POST", `${appPlan(planId)}/fuzz`, { invariants }),
297
+ latestCommit: (planId) => call("GET", `${appPlan(planId)}/latest`),
298
+ updatePlan: (planId, commit) => call("POST", `${appPlan(planId)}/update`, commit ? { commit } : {}),
299
+ setAutoPlan: (planId, auto) => call("POST", `${appPlan(planId)}/wait`, { auto }),
300
+ setLink: (planId, dependency, url) => call("POST", `${appPlan(planId)}/link`, { id: dependency, url }),
301
+ planLinked: (planId) => call("POST", `${appPlan(planId)}/plan-linked`, {}),
302
+ renameContract: (planId, name) => call("POST", `${appPlan(planId)}/settings`, { name }),
303
+ removeContract: (planId, confirm) => call("POST", `${appPlan(planId)}/remove`, {
304
+ confirm
305
+ }),
306
+ projects: () => call("GET", "/projects"),
307
+ project: (projectId) => call("GET", appProject(projectId)),
308
+ projectOverview: (projectId, opts = {}) => call("GET", `${appProject(projectId)}/overview${opts.watches ? "?watches=1" : ""}`),
309
+ renameProject: (projectId, name) => call("POST", `${appProject(projectId)}/rename`, { name }),
310
+ removeProject: (projectId, confirm) => call("POST", `${appProject(projectId)}/remove`, {
311
+ confirm
312
+ }),
313
+ answerMergeSuggestion: (from, into, accept) => call("POST", "/projects/merge", { from, into, accept }),
314
+ mergeProject: (projectId, into) => call("POST", `${appProject(projectId)}/merge-into`, { into }),
315
+ moveProjectContract: (projectId, contractId, into) => call("POST", `${appProject(projectId)}/contracts/${encodeURIComponent(contractId)}/move`, { into }),
316
+ removeProjectContract: (projectId, contractId, confirm) => call("POST", `${appProject(projectId)}/contracts/${encodeURIComponent(contractId)}/remove`, { confirm }),
317
+ previewProjectContract: (projectId, contractId) => call("POST", `${appProject(projectId)}/contracts/preview`, { contractId }),
318
+ addProjectContract: (projectId, contractId, opts = {}) => call("POST", `${appProject(projectId)}/contracts`, { contractId, ...opts }),
319
+ setProjectDestinations: (projectId, dest) => call("POST", `${appProject(projectId)}/destinations`, dest),
320
+ setProjectMonitoring: (projectId, on) => call("POST", `${appProject(projectId)}/monitoring`, { on }),
321
+ projectWatches: (projectId) => call("GET", `${appProject(projectId)}/watches`),
322
+ projectActivity: (projectId, intentId, opts = {}) => call("GET", `${appProject(projectId)}/watches/${encodeURIComponent(intentId)}/activity${query(opts)}`)
261
323
  };
262
324
  }
325
+ function query(params) {
326
+ const q = new URLSearchParams;
327
+ for (const [k, v] of Object.entries(params))
328
+ if (v !== undefined && v !== null)
329
+ q.set(k, String(v));
330
+ const s = q.toString();
331
+ return s ? `?${s}` : "";
332
+ }
263
333
  var HOUR_MS = 3600000;
264
334
  var muteEnd = (hours) => new Date(Date.now() + Math.min(hours * HOUR_MS, 7 * 24 * HOUR_MS - 60000)).toISOString();
265
335
  async function watchContext(client, planId) {
@@ -312,6 +382,8 @@ export {
312
382
  resolveToken,
313
383
  rowsOf,
314
384
  ruleSummary,
385
+ runInProgress,
386
+ runPhase,
315
387
  savedChoices,
316
388
  savedMonitor,
317
389
  sessionPath,