@pb33f/cowboy-components 0.1.15 → 0.2.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 (79) hide show
  1. package/dist/assets/rule-documentation.worker-D39NS8Lx.js +1 -0
  2. package/dist/components/editor/editor.d.ts +2 -0
  3. package/dist/components/editor/editor.js +6 -4
  4. package/dist/components/error-banner/error-banner.css.js +1 -1
  5. package/dist/components/manage-ruleset/function-option.css.d.ts +2 -0
  6. package/dist/components/manage-ruleset/function-option.css.js +38 -0
  7. package/dist/components/manage-ruleset/function-option.d.ts +19 -0
  8. package/dist/components/manage-ruleset/function-option.js +117 -0
  9. package/dist/components/manage-ruleset/manage-ruleset.css.d.ts +2 -0
  10. package/dist/components/manage-ruleset/manage-ruleset.css.js +75 -0
  11. package/dist/components/manage-ruleset/manage-ruleset.d.ts +62 -0
  12. package/dist/components/manage-ruleset/manage-ruleset.js +575 -0
  13. package/dist/components/manage-ruleset/rule-action.css.d.ts +2 -0
  14. package/dist/components/manage-ruleset/rule-action.css.js +56 -0
  15. package/dist/components/manage-ruleset/rule-action.d.ts +37 -0
  16. package/dist/components/manage-ruleset/rule-action.js +351 -0
  17. package/dist/components/manage-ruleset/rule-input.d.ts +38 -0
  18. package/dist/components/manage-ruleset/rule-input.js +296 -0
  19. package/dist/components/manage-ruleset/rule.css.d.ts +2 -0
  20. package/dist/components/manage-ruleset/rule.css.js +117 -0
  21. package/dist/components/manage-ruleset/rule.d.ts +31 -0
  22. package/dist/components/manage-ruleset/rule.js +153 -0
  23. package/dist/components/problem-list/details-drawer.d.ts +2 -1
  24. package/dist/components/problem-list/details-drawer.js +7 -0
  25. package/dist/components/problem-list/filter.css.js +2 -3
  26. package/dist/components/problem-list/problem-item.css.js +1 -3
  27. package/dist/components/problem-list/problem-item.js +1 -1
  28. package/dist/components/problem-list/problem-list.css.js +0 -10
  29. package/dist/components/problem-list/problem-list.d.ts +1 -1
  30. package/dist/components/problem-list/problem-list.js +1 -2
  31. package/dist/components/problems-overview/document-statistic.css.js +0 -1
  32. package/dist/components/problems-overview/problem-overview-group.css.js +1 -3
  33. package/dist/components/problems-overview/problem-overview-group.js +2 -2
  34. package/dist/components/problems-overview/problem-statistics.css.js +0 -5
  35. package/dist/components/problems-overview/problems-overview.css.js +0 -4
  36. package/dist/components/the-doctor/feedback.js +3 -3
  37. package/dist/components/the-doctor/status-bar.js +1 -1
  38. package/dist/components/the-doctor/the-doctor.css.js +99 -27
  39. package/dist/components/the-doctor/the-doctor.d.ts +65 -8
  40. package/dist/components/the-doctor/the-doctor.js +663 -63
  41. package/dist/components/toast/toast-component.css.d.ts +2 -0
  42. package/dist/components/toast/toast-component.css.js +151 -0
  43. package/dist/components/toast/toast-component.d.ts +19 -0
  44. package/dist/components/toast/toast-component.js +116 -0
  45. package/dist/components/toast/toast-manager.d.ts +13 -0
  46. package/dist/components/toast/toast-manager.js +54 -0
  47. package/dist/cowboy-components.umd.cjs +1375 -372
  48. package/dist/css/button.css.js +46 -0
  49. package/dist/css/dialog.css.d.ts +2 -0
  50. package/dist/css/dialog.css.js +11 -0
  51. package/dist/css/forms.css.d.ts +2 -0
  52. package/dist/css/forms.css.js +123 -0
  53. package/dist/css/modal.css.d.ts +2 -0
  54. package/dist/css/modal.css.js +15 -0
  55. package/dist/css/pb33f-theme.css +1 -0
  56. package/dist/css/radiogroups.css.d.ts +2 -0
  57. package/dist/css/radiogroups.css.js +26 -0
  58. package/dist/css/spinner.css.d.ts +2 -0
  59. package/dist/css/spinner.css.js +42 -0
  60. package/dist/events/doctor.d.ts +57 -3
  61. package/dist/events/doctor.js +13 -1
  62. package/dist/model/errors.d.ts +10 -0
  63. package/dist/model/rule_documentation.d.ts +8 -2
  64. package/dist/model/rule_documentation.js +5 -1
  65. package/dist/model/toast.d.ts +15 -0
  66. package/dist/model/toast.js +9 -0
  67. package/dist/model/vacuum_rule.d.ts +58 -0
  68. package/dist/model/vacuum_rule.js +1 -0
  69. package/dist/services/linting-service.d.ts +1 -1
  70. package/dist/services/linting-service.js +2 -6
  71. package/dist/services/ruleset-service.d.ts +17 -0
  72. package/dist/services/ruleset-service.js +316 -0
  73. package/dist/style.css +1 -1
  74. package/dist/workers/rule-documentation.worker.d.ts +9 -1
  75. package/dist/workers/rule-documentation.worker.js +97 -7
  76. package/dist/workers/search-problems.worker.d.ts +2 -1
  77. package/dist/workers/search-problems.worker.js +1 -2
  78. package/package.json +1 -1
  79. package/dist/assets/rule-documentation.worker-BFIxMBU8.js +0 -1
@@ -0,0 +1,575 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import '@shoelace-style/shoelace/dist/components/radio-group/radio-group.js';
8
+ import '@shoelace-style/shoelace/dist/components/radio-button/radio-button.js';
9
+ import '@shoelace-style/shoelace/dist/components/dialog/dialog.js';
10
+ import { customElement, query } from "lit/decorators.js";
11
+ import { html, LitElement } from "lit";
12
+ import manageRulesetCss from "./manage-ruleset.css.js";
13
+ import { RuleComponent } from "./rule.js";
14
+ import buttonCss from "../../css/button.css.js";
15
+ import spinnerCss from "../../css/spinner.css.js";
16
+ import { AddToast, CustomRulesetEnabled, ExportRuleset, RulesetDirty, RulesetSaved } from "../../events/doctor.js";
17
+ import modalCss from "../../css/modal.css.js";
18
+ import { RulesetService } from "../../services/ruleset-service.js";
19
+ import { ToastType } from "../../model/toast.js";
20
+ import radioGroupsCss from "../../css/radiogroups.css.js";
21
+ const defaultRuleset = "default";
22
+ const owaspRuleset = "owasp";
23
+ const allRuleset = "all";
24
+ const customRuleset = "custom";
25
+ let ManageRuleset = class ManageRuleset extends LitElement {
26
+ constructor() {
27
+ super();
28
+ this._defaultRules = [];
29
+ this._owaspRules = [];
30
+ this._allRules = [];
31
+ this._customRules = [];
32
+ this._rulesetConfig = { ruleMapping: new Map(), allRulesSwitch: true };
33
+ this.currentRuleset = defaultRuleset;
34
+ this.allRulesEnabled = true;
35
+ // @ts-ignore
36
+ this.addEventListener(RulesetDirty, this.dirty.bind(this));
37
+ this.addEventListener(RulesetSaved, this.rulesetUpdated.bind(this));
38
+ }
39
+ rulesetUpdated() {
40
+ this.saveButton.disabled = true;
41
+ this.saveButton.style.display = 'none';
42
+ this.dirtyRules = false;
43
+ }
44
+ exportRuleset() {
45
+ this.dispatchEvent(new CustomEvent(ExportRuleset, {
46
+ bubbles: true,
47
+ composed: true,
48
+ }));
49
+ }
50
+ compileRuleset() {
51
+ const rules = new Map();
52
+ const allRules = new Map();
53
+ // extract rules from components
54
+ this._activeRuleset.forEach(ruleComponent => {
55
+ const rule = ruleComponent.rule;
56
+ if (ruleComponent.ruleActive) {
57
+ ruleComponent.rule.active = true;
58
+ // have to convert the rule action function map into an object
59
+ if (rule && rule.then) {
60
+ if (Array.isArray(rule.then)) {
61
+ for (const action of rule.then) {
62
+ if (action.functionOptions && action.functionOptions instanceof Map) {
63
+ action.functionOptions = Object.fromEntries(action.functionOptions);
64
+ }
65
+ }
66
+ }
67
+ else {
68
+ if (rule.then.functionOptions) {
69
+ if (rule.then.functionOptions && rule.then.functionOptions instanceof Map) {
70
+ rule.then.functionOptions = Object.fromEntries(rule.then.functionOptions);
71
+ }
72
+ }
73
+ }
74
+ }
75
+ rules.set(ruleComponent.rule.id, rule);
76
+ }
77
+ allRules.set(ruleComponent.rule.id, rule);
78
+ });
79
+ const ruleset = { rules: Object.fromEntries(rules) };
80
+ const compiledRules = JSON.stringify(ruleset);
81
+ RulesetService.applyRuleset(compiledRules).then((rs) => {
82
+ this.clearRuleProblems();
83
+ this.rulesetSaved({ rules: allRules }, rs);
84
+ }).catch((error) => {
85
+ const e = error;
86
+ this.dispatchEvent(new CustomEvent(AddToast, {
87
+ bubbles: true,
88
+ composed: true,
89
+ detail: {
90
+ toast: {
91
+ id: crypto.randomUUID(),
92
+ title: `Cannot save / apply ruleset`,
93
+ type: ToastType.ERROR,
94
+ body: `${e.detail}`,
95
+ }
96
+ }
97
+ }));
98
+ if (e.body && e.body.length > 0) {
99
+ this.processBadRules(e.body);
100
+ }
101
+ });
102
+ }
103
+ clearRuleProblems() {
104
+ this._activeRuleset.forEach((ruleComp) => {
105
+ if (ruleComp) {
106
+ ruleComp.error = false;
107
+ ruleComp.ruleErrorFunctionOption = [];
108
+ ruleComp.ruleErrorFunction = [];
109
+ }
110
+ });
111
+ }
112
+ processBadRules(ruleError) {
113
+ ruleError.forEach((err) => {
114
+ const rule = this._activeRuleset.find(r => r.ruleId === err.ruleId);
115
+ if (rule) {
116
+ rule.error = true;
117
+ rule.ruleErrorMessage = [err.ruleError];
118
+ if (err.function) {
119
+ rule.ruleErrorFunction = [err.function];
120
+ }
121
+ if (err.functionOption) {
122
+ rule.ruleErrorFunctionOption = [err.functionOption];
123
+ }
124
+ rule.requestUpdate();
125
+ }
126
+ });
127
+ }
128
+ rulesetSaved(ruleset, returnedRuleset) {
129
+ this.dispatchEvent(new CustomEvent(RulesetSaved, {
130
+ bubbles: true,
131
+ composed: true,
132
+ detail: {
133
+ rules: ruleset,
134
+ config: this._rulesetConfig,
135
+ returnedRules: returnedRuleset
136
+ }
137
+ }));
138
+ this.exportButton.style.display = 'inline-block';
139
+ this.exportButton.disabled = false;
140
+ this.dispatchEvent(new CustomEvent(AddToast, {
141
+ bubbles: true,
142
+ composed: true,
143
+ detail: {
144
+ toast: {
145
+ id: crypto.randomUUID(),
146
+ title: `Ruleset saved / applied`,
147
+ type: ToastType.INFO,
148
+ body: `Ruleset has been saved and applied`,
149
+ }
150
+ }
151
+ }));
152
+ }
153
+ dirty(ruleEvent) {
154
+ if (!this.dirtyRules) {
155
+ this.dirtyRules = true;
156
+ this.saveButton.style.display = 'inline-block';
157
+ this.saveButton.disabled = false;
158
+ this.exportButton.style.display = 'none';
159
+ this.exportButton.disabled = true;
160
+ }
161
+ if (ruleEvent?.detail.rule) {
162
+ this.copyActiveRulesetCustom(ruleEvent.detail.rule);
163
+ }
164
+ else {
165
+ this.copyActiveRulesetCustom();
166
+ }
167
+ }
168
+ copyActiveRulesetCustom(submittedRule) {
169
+ const customRules = [];
170
+ this._activeRuleset.forEach(rule => {
171
+ if (submittedRule && rule.ruleId === submittedRule.rule.id) {
172
+ submittedRule.custom = true;
173
+ customRules.push(submittedRule);
174
+ }
175
+ else {
176
+ rule.custom = true;
177
+ customRules.push(rule);
178
+ }
179
+ });
180
+ this._activeRuleset = customRules;
181
+ this._customRules = customRules;
182
+ // switch to custom ruleset
183
+ this.rulesetSelector.value = customRuleset;
184
+ this.customRulesetSelector.disabled = false;
185
+ this.currentRuleset = customRuleset;
186
+ // iterate through active ruleset and set if the active flag is true, if it is, add it to the config
187
+ let config = this.buildConfig();
188
+ this._rulesetConfig = config;
189
+ this.dispatchEvent(new CustomEvent(CustomRulesetEnabled, {
190
+ bubbles: true,
191
+ composed: true,
192
+ detail: {
193
+ rules: customRules,
194
+ ruleConfig: config
195
+ }
196
+ }));
197
+ this.requestUpdate();
198
+ }
199
+ buildConfig() {
200
+ let config = { ruleMapping: new Map(), allRulesSwitch: this.allRulesEnabled };
201
+ this._activeRuleset.forEach(rule => {
202
+ if (rule.ruleActive) {
203
+ config.ruleMapping.set(rule.ruleId, true);
204
+ }
205
+ else {
206
+ config.ruleMapping.set(rule.ruleId, false);
207
+ }
208
+ });
209
+ return config;
210
+ }
211
+ // private resetConfig() {
212
+ // let config: RuleConfig = {ruleMapping: new Map<string, boolean>(), allRulesSwitch: true};
213
+ // this._allRules.forEach(rule => {
214
+ // config.ruleMapping.set(rule.ruleId, true);
215
+ // });
216
+ // return config;
217
+ // }
218
+ toggleAllRules() {
219
+ let config = this._rulesetConfig;
220
+ if (!config || !config.ruleMapping) {
221
+ config = { ruleMapping: new Map(), allRulesSwitch: true };
222
+ }
223
+ else {
224
+ config.allRulesSwitch = !this.allRulesEnabled;
225
+ }
226
+ if (this.allRulesEnabled) {
227
+ this._activeRuleset.forEach(rule => {
228
+ config?.ruleMapping.set(rule.ruleId, false);
229
+ rule.ruleActive = false;
230
+ });
231
+ config.allRulesSwitch = false;
232
+ }
233
+ else {
234
+ this._activeRuleset.forEach(rule => {
235
+ config?.ruleMapping.set(rule.ruleId, true);
236
+ rule.ruleActive = true;
237
+ });
238
+ config.allRulesSwitch = true;
239
+ }
240
+ this._rulesetConfig = config;
241
+ this.allRulesEnabled = !this.allRulesEnabled;
242
+ this.rulesetSelector.value = customRuleset;
243
+ this.customRulesetSelector.disabled = false;
244
+ this.dirty();
245
+ }
246
+ set defaultRuleset(rs) {
247
+ this._defaultRuleset = rs;
248
+ }
249
+ set owaspRuleset(rs) {
250
+ this._owaspRuleset = rs;
251
+ }
252
+ set allRuleset(rs) {
253
+ this._allRuleset = rs;
254
+ }
255
+ set customRuleset(rs) {
256
+ this._customRuleset = rs;
257
+ this.customRulesetSelector.disabled = false;
258
+ this.rulesetSelector.value = customRuleset;
259
+ this.buildCustomRuleset(false);
260
+ this.currentRuleset = customRuleset;
261
+ }
262
+ set customRulesetManual(rs) {
263
+ this._customRuleset = rs;
264
+ this.customRulesetSelector.disabled = false;
265
+ this.rulesetSelector.value = customRuleset;
266
+ this.buildCustomRuleset(true);
267
+ this.currentRuleset = customRuleset;
268
+ }
269
+ set rulesetConfig(config) {
270
+ this._rulesetConfig = config;
271
+ this.allRulesEnabled = config.allRulesSwitch;
272
+ this.requestUpdate();
273
+ }
274
+ set functions(funcs) {
275
+ this._functions = funcs;
276
+ }
277
+ buildCustomRuleset(dirty = true) {
278
+ if (this._customRuleset) {
279
+ this._customRules = [];
280
+ this._customRuleset.rules.forEach((rule, ruleId) => {
281
+ const builtIn = this._allRules.find(r => r.ruleId === ruleId);
282
+ let customRule = false;
283
+ if (!builtIn) {
284
+ customRule = true;
285
+ }
286
+ this.buildRule(ruleId, rule, this._customRules, customRule);
287
+ });
288
+ this._activeRuleset = this._customRules;
289
+ this.enableOrDisableRules();
290
+ if (dirty)
291
+ this.dirty();
292
+ }
293
+ }
294
+ changeActiveRuleset(event) {
295
+ // if (!this.customWipeDialog.open) {
296
+ const button = event.target;
297
+ if (this.currentRuleset == customRuleset) {
298
+ this.confirmWipeButton.loading = false;
299
+ this.customWipeDialog.show().then(() => {
300
+ this.confirmNewRuleset = button.value; // what we're changing to.
301
+ // this.requestUpdate(); // render modal
302
+ return;
303
+ });
304
+ }
305
+ else {
306
+ this.switchRuleset(button.value);
307
+ this.requestUpdate();
308
+ }
309
+ }
310
+ cancelCustomOverride() {
311
+ // this.confirmWipeActive = false;
312
+ this.customWipeDialog.hide();
313
+ }
314
+ confirmCustomOverride() {
315
+ this.confirmWipeButton.loading = true;
316
+ this.customWipeDialog.hide();
317
+ this.allRulesEnabled = true;
318
+ setTimeout(() => {
319
+ this.confirmWipeActive = false;
320
+ this.rulesetSelector.value = this.confirmNewRuleset;
321
+ this.switchRuleset(this.confirmNewRuleset);
322
+ this._rulesetConfig = null;
323
+ this.dispatchEvent(new CustomEvent(CustomRulesetEnabled, {
324
+ bubbles: true,
325
+ composed: true,
326
+ detail: {
327
+ rules: [],
328
+ ruleConfig: null
329
+ }
330
+ }));
331
+ this._customRules = [];
332
+ this.customRulesetSelector.disabled = true;
333
+ this.dirtyRules = false;
334
+ this.saveButton.style.display = 'none';
335
+ this.saveButton.disabled = true;
336
+ this.exportButton.style.display = 'none';
337
+ this.exportButton.disabled = true;
338
+ this.allRulesSwitch.checked = true;
339
+ this.enableOrDisableRules();
340
+ this.requestUpdate();
341
+ }, 250);
342
+ }
343
+ switchRuleset(button) {
344
+ switch (button) {
345
+ case defaultRuleset:
346
+ this._activeRuleset = this._defaultRules;
347
+ this.currentRuleset = defaultRuleset;
348
+ break;
349
+ case owaspRuleset:
350
+ this._activeRuleset = this._owaspRules;
351
+ this.currentRuleset = owaspRuleset;
352
+ break;
353
+ case allRuleset:
354
+ this._activeRuleset = this._allRules;
355
+ this.currentRuleset = allRuleset;
356
+ break;
357
+ case customRuleset:
358
+ this._activeRuleset = this._customRules;
359
+ this.currentRuleset = customRuleset;
360
+ break;
361
+ }
362
+ }
363
+ buildRulesets() {
364
+ this._defaultRules = [];
365
+ this._owaspRules = [];
366
+ this._allRules = [];
367
+ // this._customRules = [];
368
+ if (this._defaultRuleset) {
369
+ for (const ruleId in this._defaultRuleset.rules) {
370
+ const rule = this._defaultRuleset.rules[ruleId];
371
+ this.buildRule(ruleId, rule, this._defaultRules);
372
+ }
373
+ }
374
+ if (this._owaspRuleset) {
375
+ for (const ruleId in this._owaspRuleset.rules) {
376
+ const rule = this._owaspRuleset.rules[ruleId];
377
+ this.buildRule(ruleId, rule, this._owaspRules);
378
+ }
379
+ }
380
+ if (this._allRuleset) {
381
+ for (const ruleId in this._allRuleset.rules) {
382
+ const rule = this._allRuleset.rules[ruleId];
383
+ this.buildRule(ruleId, rule, this._allRules);
384
+ }
385
+ }
386
+ // if (this._customRuleset) {
387
+ // for (const ruleId in this._customRuleset.rules) {
388
+ // const rule = this._customRuleset.rules[ruleId];
389
+ // this.buildRule(ruleId, rule, this._customRules);
390
+ // }
391
+ // }
392
+ //if (this._customRules.length <= 0) {
393
+ this._activeRuleset = this._defaultRules;
394
+ //} else {
395
+ // this._activeRuleset = this._customRules;
396
+ //}
397
+ // if there is no config, turn on all the rules, otherwise, turn on the rules in the config
398
+ this.requestUpdate();
399
+ }
400
+ enableOrDisableRules() {
401
+ if (this._rulesetConfig && this._rulesetConfig.ruleMapping.size > 0) {
402
+ this._rulesetConfig.ruleMapping.forEach((enabled, key) => {
403
+ const rule = this._activeRuleset.find(r => r.ruleId === key);
404
+ if (rule && !enabled) {
405
+ rule.ruleActive = false;
406
+ }
407
+ });
408
+ }
409
+ else {
410
+ this._allRules.forEach(rule => {
411
+ rule.ruleActive = true;
412
+ });
413
+ this._owaspRules.forEach(rule => {
414
+ rule.ruleActive = true;
415
+ });
416
+ this._defaultRules.forEach(rule => {
417
+ rule.ruleActive = true;
418
+ });
419
+ this.allRulesEnabled = true;
420
+ }
421
+ }
422
+ buildRule(ruleId, rule, rules, custom = false) {
423
+ if (rule && rule.id && rule.id.length <= 0) {
424
+ rule.id = ruleId;
425
+ }
426
+ const ruleComponent = new RuleComponent(rule, ruleId, custom);
427
+ ruleComponent.addEventListener('sl-show', (event) => {
428
+ // @ts-ignore
429
+ const openedRule = event.target?.ruleId;
430
+ for (const r of rules) {
431
+ if (r.ruleId !== openedRule && r.open) {
432
+ r.close();
433
+ }
434
+ }
435
+ });
436
+ if (custom) {
437
+ rules.unshift(ruleComponent);
438
+ }
439
+ else {
440
+ rules.push(ruleComponent);
441
+ }
442
+ return ruleComponent;
443
+ }
444
+ addCustomRule() {
445
+ const ruleId = `custom-rule-${this._activeRuleset.length}`;
446
+ const rule = {
447
+ id: ruleId,
448
+ description: "Custom Rule check if title is defined is defined",
449
+ message: "Please make sure there is a `title` section in the info object",
450
+ given: "$.info",
451
+ resolved: false,
452
+ severity: "info",
453
+ formats: ["oas3_1"],
454
+ category: { id: "validation", name: "Validation" },
455
+ then: [
456
+ {
457
+ field: "title",
458
+ function: "defined",
459
+ },
460
+ ]
461
+ };
462
+ const rc = this.buildRule(ruleId, rule, this._activeRuleset, true);
463
+ this.dirty(new CustomEvent(RulesetDirty, { detail: { rule: rc } }));
464
+ this.requestUpdate();
465
+ setTimeout(() => {
466
+ rc.show();
467
+ });
468
+ }
469
+ render() {
470
+ let selectAll = html ``;
471
+ let numRules = 0;
472
+ if (this._activeRuleset) {
473
+ numRules = this._activeRuleset.length;
474
+ }
475
+ if (numRules > 0) {
476
+ selectAll = html `
477
+ <div class="toggle-allcheck">
478
+ <sl-switch size="small" @sl-change="${this.toggleAllRules}" ?checked="${this.allRulesEnabled}">
479
+ Toggle all
480
+ rules (${numRules})
481
+ </sl-switch>
482
+ </div>
483
+ `;
484
+ }
485
+ let rules = html `
486
+ <div class="pb33f-loader">
487
+ <div class="spin"></div>
488
+ loading rules, please wait a few moments...
489
+ </div>
490
+ `;
491
+ if (this._activeRuleset) {
492
+ rules = this._activeRuleset;
493
+ }
494
+ return html `
495
+ <div class="ruleset">
496
+ <div class="ruleset-header">
497
+ <sl-radio-group label="Select a ruleset" name="ruleset" value="default">
498
+ <sl-radio-button value=${defaultRuleset} @sl-focus="${this.changeActiveRuleset}">Default
499
+ </sl-radio-button>
500
+ <sl-radio-button value=${owaspRuleset} @sl-focus="${this.changeActiveRuleset}">OWASP
501
+ </sl-radio-button>
502
+ <sl-radio-button value=${allRuleset} @sl-focus="${this.changeActiveRuleset}">All
503
+ </sl-radio-button>
504
+ <sl-radio-button value=${customRuleset} disabled id="custom-ruleset"
505
+ @sl-focus="${this.changeActiveRuleset}">Custom
506
+ </sl-radio-button>
507
+ </sl-radio-group>
508
+ <div class="ruleset-controls">
509
+ <sl-tooltip content="Add a custom rule" placement="bottom">
510
+ <sl-icon-button @click="${this.addCustomRule}" name="plus-square" label="Add Custom Rule"
511
+ id="add-button">
512
+ </sl-icon-button>
513
+ </sl-tooltip>
514
+
515
+ <sl-tooltip content="Export / download ruleset" placement="bottom">
516
+ <sl-icon-button @click="${this.exportRuleset}"
517
+ disabled name="cloud-download" label="Export Ruleset" class="hidden"
518
+ id="export-button">
519
+ </sl-icon-button>
520
+ </sl-tooltip>
521
+ <sl-tooltip content="Apply / save ruleset" placement="bottom">
522
+ <sl-icon-button disabled name="floppy" label="Apply Ruleset" class="pulse hidden"
523
+ id="save-button" @click="${this.compileRuleset}">
524
+ </sl-icon-button>
525
+ </sl-tooltip>
526
+
527
+ </div>
528
+ </div>
529
+ <div class="ruleset-body">
530
+ ${selectAll}
531
+ ${rules}
532
+ </div>
533
+ </div>
534
+ <sl-dialog id="confirm-custom-wipe" label="Reset Custom Rules?" class="dialog-overview"
535
+ style="--width: 50vw">
536
+ <h3>You have customized your ruleset.</h3>
537
+
538
+ <p>Are you sure you want to switch to a built-in ruleset?</p>
539
+
540
+ <sl-button @click=${this.cancelCustomOverride} slot="footer" variant="primary" style="float: left">No!
541
+ Cancel
542
+ </sl-button>
543
+ <sl-button id="confirm-override-wipe-button" @click=${this.confirmCustomOverride} slot="footer"
544
+ variant="danger" class="danger">Yes, Reset
545
+ </sl-button>
546
+ </sl-dialog>
547
+ `;
548
+ }
549
+ };
550
+ ManageRuleset.styles = [modalCss, spinnerCss, buttonCss, radioGroupsCss, manageRulesetCss];
551
+ __decorate([
552
+ query('#save-button')
553
+ ], ManageRuleset.prototype, "saveButton", void 0);
554
+ __decorate([
555
+ query('#export-button')
556
+ ], ManageRuleset.prototype, "exportButton", void 0);
557
+ __decorate([
558
+ query('sl-radio-group')
559
+ ], ManageRuleset.prototype, "rulesetSelector", void 0);
560
+ __decorate([
561
+ query('#custom-ruleset')
562
+ ], ManageRuleset.prototype, "customRulesetSelector", void 0);
563
+ __decorate([
564
+ query('sl-dialog#confirm-custom-wipe')
565
+ ], ManageRuleset.prototype, "customWipeDialog", void 0);
566
+ __decorate([
567
+ query('sl-button#confirm-override-wipe-button')
568
+ ], ManageRuleset.prototype, "confirmWipeButton", void 0);
569
+ __decorate([
570
+ query('sl-switch')
571
+ ], ManageRuleset.prototype, "allRulesSwitch", void 0);
572
+ ManageRuleset = __decorate([
573
+ customElement('pb33f-manage-ruleset')
574
+ ], ManageRuleset);
575
+ export { ManageRuleset };
@@ -0,0 +1,2 @@
1
+ declare const _default: import("lit").CSSResult;
2
+ export default _default;
@@ -0,0 +1,56 @@
1
+ import { css } from "lit";
2
+ export default css `
3
+
4
+ sl-input {
5
+ margin-bottom: 10px;
6
+ }
7
+
8
+ sl-select {
9
+ margin-bottom: 10px;
10
+ flex-grow: 2;
11
+ }
12
+ sl-button {
13
+ font-size: 1.2rem;
14
+ margin-bottom: 10px;
15
+ margin-top: 10px;
16
+ }
17
+
18
+ .function-input {
19
+ display: flex;
20
+
21
+ }
22
+
23
+ .function-docs {
24
+ display: inline-block;
25
+ padding-left: 10px;
26
+ padding-top: 25px;
27
+ font-size: 0.8rem;
28
+ }
29
+
30
+ sl-select.error::part(form-control-label) {
31
+ color: var(--error-color);
32
+ }
33
+
34
+ sl-select.error::part(combobox) {
35
+ color: var(--error-color);
36
+ border: 1px solid var(--error-color);
37
+ }
38
+
39
+ .function-options {
40
+
41
+ }
42
+
43
+ .description {
44
+ font-size: 0.7rem;
45
+ }
46
+
47
+ sl-button.danger {
48
+ font-size: 1.2rem;
49
+ float: right;
50
+ margin-bottom: 15px;
51
+ }
52
+
53
+ hr {
54
+ clear: right;
55
+ }
56
+ `;
@@ -0,0 +1,37 @@
1
+ import { LitElement } from "lit";
2
+ import "./function-option.js";
3
+ import { RuleAction } from "../../model/vacuum_rule.js";
4
+ import { RuleActionFunctionOptionRemovedEvent } from "../../events/doctor.js";
5
+ import { RuleComponent } from "./rule.js";
6
+ import { SlDialog, SlInput, SlSelect } from "@shoelace-style/shoelace";
7
+ export declare class RuleActionComponent extends LitElement {
8
+ static styles: import("lit").CSSResult[];
9
+ fieldInput: SlInput;
10
+ fieldFunction: SlSelect;
11
+ addFunctionOptionDialog: SlDialog;
12
+ error: boolean;
13
+ ruleErrorFunction: string;
14
+ ruleErrorFunctionOption: string;
15
+ ruleAction: RuleAction;
16
+ private FunctionsBag;
17
+ private FunctionsSchemaBag;
18
+ private bagManager;
19
+ private functions;
20
+ private functionOptions;
21
+ private functionSchemas;
22
+ private readonly ruleComponent;
23
+ private ruleFunctionSchema;
24
+ constructor(action: RuleAction, rule: RuleComponent);
25
+ buildFunctionOptions(): void;
26
+ changeField(): void;
27
+ changeFunction(): void;
28
+ dirty(): void;
29
+ functionOptionRemoved(evt: CustomEvent<RuleActionFunctionOptionRemovedEvent>): void;
30
+ viewFunctionDocs(): void;
31
+ addFunctionOption(key?: string, value?: string, desc?: string, removeable?: boolean, dirty?: boolean): void;
32
+ removeSelf(): void;
33
+ closeFunctionOption(): void;
34
+ openFunctionOptionDialog(): void;
35
+ addFunctionOptionProperty(prop: string, desc?: string): void;
36
+ render(): import("lit-html").TemplateResult<1>;
37
+ }