@mnaoumov/obsidian-dev-toolkit 3.2.1 → 3.4.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.
@@ -61,6 +61,20 @@
61
61
  * or a misspelled directive all fail: an exemption nobody can justify, that nothing needs any more, or that
62
62
  * silently does nothing is worse than no exemption at all.
63
63
  *
64
+ * They also check that every `Try it` section — a heading of any level starting `Try it`, up to the next
65
+ * heading of the same or a higher level — holds a `code-button` that performs its setup, because a reader
66
+ * asked to configure things by hand is a reader the demo lost. A section whose steps really cannot be
67
+ * scripted says so with the same directive, naming the `demo-vault-validation/try-it-code-button` rule on
68
+ * the heading, and with the same checks on the directive itself:
69
+ *
70
+ * ```markdown
71
+ * <!-- obsidian-dev-utils-disable-next-line demo-vault-validation/try-it-code-button -- Dragging a file in from outside Obsidian cannot be scripted. -->
72
+ * ## Try it
73
+ * ```
74
+ *
75
+ * That check fails the suite by default; {@link DemoVaultAuthoringSpec.tryItCodeButtons} set to `'warn'`
76
+ * prints the sections instead, for a vault still being brought up to it.
77
+ *
64
78
  * Two layers are exposed:
65
79
  * - {@link DemoVaultCoverageChecker} — a framework-agnostic core that reads the corpus, parses interface /
66
80
  * class / enum members and exported functions, and returns diagnostic arrays (what is undemonstrated / stale
@@ -83,7 +97,17 @@ export interface DemoVaultAuthoringSpec {
83
97
  * `00 Start.md`.
84
98
  */
85
99
  readonly startNote?: string;
100
+ /**
101
+ * How a `Try it` section with no `code-button` and no directive explaining why is reported: `'warn'`
102
+ * prints the sections and passes, `'error'` fails the suite. Defaults to `'error'`.
103
+ */
104
+ readonly tryItCodeButtons?: DemoVaultCheckSeverity;
86
105
  }
106
+ /**
107
+ * How a check that is being introduced gradually reports what it finds: `'warn'` prints it and passes,
108
+ * `'error'` fails.
109
+ */
110
+ export type DemoVaultCheckSeverity = 'error' | 'warn';
87
111
  /**
88
112
  * Reflects a config interface whose options are demonstrated by their bare name.
89
113
  */
@@ -268,6 +292,46 @@ export interface DemoVaultNote {
268
292
  */
269
293
  readonly relativePath: string;
270
294
  }
295
+ /**
296
+ * What a note's inline `obsidian-dev-utils-disable…` directives allow, rule by rule, and what is wrong with
297
+ * them.
298
+ */
299
+ export interface DirectiveScan {
300
+ /**
301
+ * For each rule, the zero-based line numbers a directive exempts from it.
302
+ */
303
+ readonly allowedLineIndexesByRule: ReadonlyMap<string, ReadonlySet<number>>;
304
+ /**
305
+ * The directive mistakes found, each phrased for a failing assertion.
306
+ */
307
+ readonly problems: string[];
308
+ }
309
+ /**
310
+ * The running state of a directive scan, threaded through the per-line helpers.
311
+ */
312
+ export interface DirectiveScanState {
313
+ /**
314
+ * For each rule, the lines a directive has exempted from it so far.
315
+ */
316
+ readonly allowedLineIndexesByRule: Map<string, Set<number>>;
317
+ /**
318
+ * For each rule, the region currently open, and whether it has covered a target yet.
319
+ */
320
+ readonly openRegionsByRule: Map<string, OpenDirectiveRegion>;
321
+ /**
322
+ * For each rule, the line a `disable-next-line` was read on, while it still waits for the line it covers.
323
+ */
324
+ readonly pendingNextLineIndexesByRule: Map<string, number>;
325
+ /**
326
+ * The directive mistakes found so far.
327
+ */
328
+ readonly problems: string[];
329
+ /**
330
+ * For each rule, the lines of the note that break it — the lines a directive for it has to cover to be
331
+ * doing any work.
332
+ */
333
+ readonly targetLineIndexesByRule: ReadonlyMap<string, ReadonlySet<number>>;
334
+ }
271
335
  /**
272
336
  * The parsed members of a source interface, class, or enum.
273
337
  */
@@ -302,6 +366,22 @@ export interface NoteLine {
302
366
  /**
303
367
  * A `disable` region that has been opened and not yet enabled again.
304
368
  */
369
+ export interface OpenDirectiveRegion {
370
+ /**
371
+ * Whether the region has covered a line breaking its rule, which is what stops it being reported as
372
+ * pointless.
373
+ */
374
+ isUsed: boolean;
375
+ /**
376
+ * The line the region was opened on.
377
+ */
378
+ readonly lineIndex: number;
379
+ }
380
+ /**
381
+ * A `disable` region that has been opened and not yet enabled again.
382
+ *
383
+ * @deprecated Use {@link OpenDirectiveRegion}: the directives now serve more than the wikilink rule.
384
+ */
305
385
  export interface OpenWikilinkDirectiveRegion {
306
386
  /**
307
387
  * Whether the region has covered a wikilink, which is what stops it being reported as pointless.
@@ -351,6 +431,8 @@ export interface RegisterDemoVaultCoverageSuiteParams {
351
431
  }
352
432
  /**
353
433
  * What a note's inline `obsidian-dev-utils-disable…` directives allow, and what is wrong with them.
434
+ *
435
+ * @deprecated Use {@link DirectiveScan}: the directives now serve more than the wikilink rule.
354
436
  */
355
437
  export interface WikilinkDirectiveScan {
356
438
  /**
@@ -364,6 +446,8 @@ export interface WikilinkDirectiveScan {
364
446
  }
365
447
  /**
366
448
  * The running state of a directive scan, threaded through the per-line helpers.
449
+ *
450
+ * @deprecated Use {@link DirectiveScanState}: the directives now serve more than the wikilink rule.
367
451
  */
368
452
  export interface WikilinkDirectiveScanState {
369
453
  /**
@@ -373,7 +457,7 @@ export interface WikilinkDirectiveScanState {
373
457
  /**
374
458
  * The region currently open, and whether it has covered a wikilink yet.
375
459
  */
376
- openRegion: null | OpenWikilinkDirectiveRegion;
460
+ openRegion: null | OpenDirectiveRegion;
377
461
  /**
378
462
  * The line a `disable-next-line` was read on, while it still waits for the line it covers.
379
463
  */
@@ -448,11 +532,12 @@ export declare class DemoVaultCoverageChecker {
448
532
  */
449
533
  findNotesWithoutIntroProse(): string[];
450
534
  /**
451
- * Finds notes whose wikilink allowance is not doing any work — declared without a reason, or on a note
452
- * that carries no wikilink at all. Both are drift: an exemption nobody can justify, and one nothing needs
453
- * any more, which would go on hiding the next wikilink somebody adds by accident.
535
+ * Finds notes whose exemptions are not doing any work — a wikilink allowance or an inline directive for
536
+ * any rule declared without a reason, misspelled, or covering nothing that breaks its rule. All of them
537
+ * are drift: an exemption nobody can justify, and one nothing needs any more, which would go on hiding
538
+ * the next mistake somebody makes by accident.
454
539
  *
455
- * @returns The relative paths of the offending notes.
540
+ * @returns One `<note>: <problem>` entry per problem found.
456
541
  */
457
542
  findNotesWithUnjustifiedWikilinkAllowance(): string[];
458
543
  /**
@@ -471,6 +556,16 @@ export declare class DemoVaultCoverageChecker {
471
556
  * @returns The distinct stale member names referenced in the demo corpus.
472
557
  */
473
558
  findStaleReferences(params: DemoVaultCoverageCheckerFindStaleReferencesParams): string[];
559
+ /**
560
+ * Finds `Try it` sections with no `code-button` in them. A `Try it` section is a heading of any level
561
+ * starting `Try it`, up to the next heading of the same or a higher level; the setup it asks for is
562
+ * what a button is for, so a section that leaves the reader to do it by hand is the shape this check
563
+ * rejects. A section whose heading a `demo-vault-validation/try-it-code-button` directive covers has
564
+ * stated why it cannot be scripted, and is skipped — see the file overview.
565
+ *
566
+ * @returns One `<note>: line <n>` entry per offending section, naming the line of its heading.
567
+ */
568
+ findTryItSectionsWithoutCodeButton(): string[];
474
569
  /**
475
570
  * Finds members that are not demonstrated anywhere in the demo corpus.
476
571
  *
@@ -36,9 +36,7 @@ __export(index_exports, {
36
36
  bundlers: () => bundlers,
37
37
  "demo-vault": () => demo_vault,
38
38
  "demo-vault-app-json": () => demo_vault_app_json,
39
- "demo-vault-buttons": () => demo_vault_buttons,
40
39
  "demo-vault-cli": () => demo_vault_cli,
41
- "demo-vault-coverage": () => demo_vault_coverage,
42
40
  "docs-site": () => docs_site,
43
41
  formatters: () => formatters,
44
42
  linters: () => linters,
@@ -50,9 +48,7 @@ __export(index_exports, {
50
48
  module.exports = __toCommonJS(index_exports);
51
49
  var bundlers = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./bundlers/index.cjs')), 1);
52
50
  var demo_vault_app_json = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./demo-vault-app-json.cjs')), 1);
53
- var demo_vault_buttons = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./demo-vault-buttons.cjs')), 1);
54
51
  var demo_vault_cli = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./demo-vault-cli.cjs')), 1);
55
- var demo_vault_coverage = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./demo-vault-coverage.cjs')), 1);
56
52
  var demo_vault = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./demo-vault.cjs')), 1);
57
53
  var docs_site = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./docs-site/index.cjs')), 1);
58
54
  var formatters = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./formatters/index.cjs')), 1);
@@ -66,9 +62,7 @@ var version = __toESM(((module) => module && module.__esModule && 'default' in m
66
62
  bundlers,
67
63
  "demo-vault": null,
68
64
  "demo-vault-app-json": null,
69
- "demo-vault-buttons": null,
70
65
  "demo-vault-cli": null,
71
- "demo-vault-coverage": null,
72
66
  "docs-site": null,
73
67
  formatters,
74
68
  linters,
@@ -77,4 +71,4 @@ var version = __toESM(((module) => module && module.__esModule && 'default' in m
77
71
  "test-runners": null,
78
72
  version
79
73
  });
80
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKiBUSElTIElTIEEgR0VORVJBVEVEL0JVTkRMRUQgRklMRSBCWSBCVUlMRCBTQ1JJUFQgKi9cblxuZXhwb3J0ICogYXMgJ2J1bmRsZXJzJyBmcm9tICcuL2J1bmRsZXJzL2luZGV4LnRzJztcbmV4cG9ydCAqIGFzICdkZW1vLXZhdWx0LWFwcC1qc29uJyBmcm9tICcuL2RlbW8tdmF1bHQtYXBwLWpzb24udHMnO1xuZXhwb3J0ICogYXMgJ2RlbW8tdmF1bHQtYnV0dG9ucycgZnJvbSAnLi9kZW1vLXZhdWx0LWJ1dHRvbnMudHMnO1xuZXhwb3J0ICogYXMgJ2RlbW8tdmF1bHQtY2xpJyBmcm9tICcuL2RlbW8tdmF1bHQtY2xpLnRzJztcbmV4cG9ydCAqIGFzICdkZW1vLXZhdWx0LWNvdmVyYWdlJyBmcm9tICcuL2RlbW8tdmF1bHQtY292ZXJhZ2UudHMnO1xuZXhwb3J0ICogYXMgJ2RlbW8tdmF1bHQnIGZyb20gJy4vZGVtby12YXVsdC50cyc7XG5leHBvcnQgKiBhcyAnZG9jcy1zaXRlJyBmcm9tICcuL2RvY3Mtc2l0ZS9pbmRleC50cyc7XG5leHBvcnQgKiBhcyAnZm9ybWF0dGVycycgZnJvbSAnLi9mb3JtYXR0ZXJzL2luZGV4LnRzJztcbmV4cG9ydCAqIGFzICdsaW50ZXJzJyBmcm9tICcuL2xpbnRlcnMvaW5kZXgudHMnO1xuZXhwb3J0ICogYXMgJ29ic2lkaWFuLXBsdWdpbi1yZXBvLXBhdGhzJyBmcm9tICcuL29ic2lkaWFuLXBsdWdpbi1yZXBvLXBhdGhzLnRzJztcbmV4cG9ydCAqIGFzICd0ZW1wbGF0ZXMnIGZyb20gJy4vdGVtcGxhdGVzLnRzJztcbmV4cG9ydCAqIGFzICd0ZXN0LXJ1bm5lcnMnIGZyb20gJy4vdGVzdC1ydW5uZXJzL2luZGV4LnRzJztcbmV4cG9ydCAqIGFzICd2ZXJzaW9uJyBmcm9tICcuL3ZlcnNpb24udHMnO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUEsc0JBQUFBO0FBQUEsRUFBQSw2QkFBQUM7QUFBQSxFQUFBLDRCQUFBQztBQUFBLEVBQUEsd0JBQUFDO0FBQUEsRUFBQSw2QkFBQUM7QUFBQSxFQUFBLG1CQUFBQztBQUFBLEVBQUE7QUFBQTtBQUFBLHNDQUFBQztBQUFBLEVBQUE7QUFBQSx3QkFBQUM7QUFBQSxFQUFBO0FBQUE7QUFBQTtBQUVBLGVBQTRCO0FBQzVCLElBQUFOLHNCQUF1QztBQUN2QyxJQUFBQyxxQkFBc0M7QUFDdEMsSUFBQUMsaUJBQWtDO0FBQ2xDLElBQUFDLHNCQUF1QztBQUN2QyxJQUFBSixhQUE4QjtBQUM5QixJQUFBSyxZQUE2QjtBQUM3QixpQkFBOEI7QUFDOUIsY0FBMkI7QUFDM0IsSUFBQUMsNkJBQThDO0FBQzlDLGdCQUE2QjtBQUM3QixJQUFBQyxlQUFnQztBQUNoQyxjQUEyQjsiLAogICJuYW1lcyI6IFsiZGVtby12YXVsdCIsICJkZW1vLXZhdWx0LWFwcC1qc29uIiwgImRlbW8tdmF1bHQtYnV0dG9ucyIsICJkZW1vLXZhdWx0LWNsaSIsICJkZW1vLXZhdWx0LWNvdmVyYWdlIiwgImRvY3Mtc2l0ZSIsICJvYnNpZGlhbi1wbHVnaW4tcmVwby1wYXRocyIsICJ0ZXN0LXJ1bm5lcnMiXQp9Cg==
74
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKiBUSElTIElTIEEgR0VORVJBVEVEL0JVTkRMRUQgRklMRSBCWSBCVUlMRCBTQ1JJUFQgKi9cblxuZXhwb3J0ICogYXMgJ2J1bmRsZXJzJyBmcm9tICcuL2J1bmRsZXJzL2luZGV4LnRzJztcbmV4cG9ydCAqIGFzICdkZW1vLXZhdWx0LWFwcC1qc29uJyBmcm9tICcuL2RlbW8tdmF1bHQtYXBwLWpzb24udHMnO1xuZXhwb3J0ICogYXMgJ2RlbW8tdmF1bHQtY2xpJyBmcm9tICcuL2RlbW8tdmF1bHQtY2xpLnRzJztcbmV4cG9ydCAqIGFzICdkZW1vLXZhdWx0JyBmcm9tICcuL2RlbW8tdmF1bHQudHMnO1xuZXhwb3J0ICogYXMgJ2RvY3Mtc2l0ZScgZnJvbSAnLi9kb2NzLXNpdGUvaW5kZXgudHMnO1xuZXhwb3J0ICogYXMgJ2Zvcm1hdHRlcnMnIGZyb20gJy4vZm9ybWF0dGVycy9pbmRleC50cyc7XG5leHBvcnQgKiBhcyAnbGludGVycycgZnJvbSAnLi9saW50ZXJzL2luZGV4LnRzJztcbmV4cG9ydCAqIGFzICdvYnNpZGlhbi1wbHVnaW4tcmVwby1wYXRocycgZnJvbSAnLi9vYnNpZGlhbi1wbHVnaW4tcmVwby1wYXRocy50cyc7XG5leHBvcnQgKiBhcyAndGVtcGxhdGVzJyBmcm9tICcuL3RlbXBsYXRlcy50cyc7XG5leHBvcnQgKiBhcyAndGVzdC1ydW5uZXJzJyBmcm9tICcuL3Rlc3QtcnVubmVycy9pbmRleC50cyc7XG5leHBvcnQgKiBhcyAndmVyc2lvbicgZnJvbSAnLi92ZXJzaW9uLnRzJztcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBLHNCQUFBQTtBQUFBLEVBQUEsNkJBQUFDO0FBQUEsRUFBQSx3QkFBQUM7QUFBQSxFQUFBLG1CQUFBQztBQUFBLEVBQUE7QUFBQTtBQUFBLHNDQUFBQztBQUFBLEVBQUE7QUFBQSx3QkFBQUM7QUFBQSxFQUFBO0FBQUE7QUFBQTtBQUVBLGVBQTRCO0FBQzVCLElBQUFKLHNCQUF1QztBQUN2QyxJQUFBQyxpQkFBa0M7QUFDbEMsSUFBQUYsYUFBOEI7QUFDOUIsSUFBQUcsWUFBNkI7QUFDN0IsaUJBQThCO0FBQzlCLGNBQTJCO0FBQzNCLElBQUFDLDZCQUE4QztBQUM5QyxnQkFBNkI7QUFDN0IsSUFBQUMsZUFBZ0M7QUFDaEMsY0FBMkI7IiwKICAibmFtZXMiOiBbImRlbW8tdmF1bHQiLCAiZGVtby12YXVsdC1hcHAtanNvbiIsICJkZW1vLXZhdWx0LWNsaSIsICJkb2NzLXNpdGUiLCAib2JzaWRpYW4tcGx1Z2luLXJlcG8tcGF0aHMiLCAidGVzdC1ydW5uZXJzIl0KfQo=
@@ -5,9 +5,7 @@
5
5
  /// <reference types="node" />
6
6
  export * as 'bundlers' from './bundlers/index.cjs';
7
7
  export * as 'demo-vault-app-json' from './demo-vault-app-json.cjs';
8
- export * as 'demo-vault-buttons' from './demo-vault-buttons.cjs';
9
8
  export * as 'demo-vault-cli' from './demo-vault-cli.cjs';
10
- export * as 'demo-vault-coverage' from './demo-vault-coverage.cjs';
11
9
  export * as 'demo-vault' from './demo-vault.cjs';
12
10
  export * as 'docs-site' from './docs-site/index.cjs';
13
11
  export * as 'formatters' from './formatters/index.cjs';
@@ -36,7 +36,6 @@ __export(test_runners_exports, {
36
36
  "coverage-badge": () => coverage_badge,
37
37
  "coverage-badge-cli": () => coverage_badge_cli,
38
38
  "e2e-runner-support": () => e2e_runner_support,
39
- "integration-test-plugin": () => integration_test_plugin,
40
39
  "jest-config": () => jest_config,
41
40
  "obsidian-test-runner": () => obsidian_test_runner,
42
41
  "performance-eval-cap": () => performance_eval_cap,
@@ -47,7 +46,6 @@ module.exports = __toCommonJS(test_runners_exports);
47
46
  var coverage_badge_cli = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./coverage-badge-cli.cjs')), 1);
48
47
  var coverage_badge = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./coverage-badge.cjs')), 1);
49
48
  var e2e_runner_support = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./e2e-runner-support.cjs')), 1);
50
- var integration_test_plugin = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./integration-test-plugin.cjs')), 1);
51
49
  var jest_config = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./jest-config.cjs')), 1);
52
50
  var obsidian_test_runner = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./obsidian-test-runner.cjs')), 1);
53
51
  var performance_eval_cap = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('./performance-eval-cap.cjs')), 1);
@@ -58,11 +56,10 @@ var wdio_obsidian = __toESM(((module) => module && module.__esModule && 'default
58
56
  "coverage-badge": null,
59
57
  "coverage-badge-cli": null,
60
58
  "e2e-runner-support": null,
61
- "integration-test-plugin": null,
62
59
  "jest-config": null,
63
60
  "obsidian-test-runner": null,
64
61
  "performance-eval-cap": null,
65
62
  "vitest-config": null,
66
63
  "wdio-obsidian": null
67
64
  });
68
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL3Rlc3QtcnVubmVycy9pbmRleC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyogVEhJUyBJUyBBIEdFTkVSQVRFRC9CVU5ETEVEIEZJTEUgQlkgQlVJTEQgU0NSSVBUICovXG5cbmV4cG9ydCAqIGFzICdjb3ZlcmFnZS1iYWRnZS1jbGknIGZyb20gJy4vY292ZXJhZ2UtYmFkZ2UtY2xpLnRzJztcbmV4cG9ydCAqIGFzICdjb3ZlcmFnZS1iYWRnZScgZnJvbSAnLi9jb3ZlcmFnZS1iYWRnZS50cyc7XG5leHBvcnQgKiBhcyAnZTJlLXJ1bm5lci1zdXBwb3J0JyBmcm9tICcuL2UyZS1ydW5uZXItc3VwcG9ydC50cyc7XG5leHBvcnQgKiBhcyAnaW50ZWdyYXRpb24tdGVzdC1wbHVnaW4nIGZyb20gJy4vaW50ZWdyYXRpb24tdGVzdC1wbHVnaW4udHMnO1xuZXhwb3J0ICogYXMgJ2plc3QtY29uZmlnJyBmcm9tICcuL2plc3QtY29uZmlnLnRzJztcbmV4cG9ydCAqIGFzICdvYnNpZGlhbi10ZXN0LXJ1bm5lcicgZnJvbSAnLi9vYnNpZGlhbi10ZXN0LXJ1bm5lci50cyc7XG5leHBvcnQgKiBhcyAncGVyZm9ybWFuY2UtZXZhbC1jYXAnIGZyb20gJy4vcGVyZm9ybWFuY2UtZXZhbC1jYXAudHMnO1xuZXhwb3J0ICogYXMgJ3ZpdGVzdC1jb25maWcnIGZyb20gJy4vdml0ZXN0LWNvbmZpZy50cyc7XG5leHBvcnQgKiBhcyAnd2Rpby1vYnNpZGlhbicgZnJvbSAnLi93ZGlvLW9ic2lkaWFuLnRzJztcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQSwwQkFBQUE7QUFBQSxFQUFBLDRCQUFBQztBQUFBLEVBQUEsNEJBQUFDO0FBQUEsRUFBQSxpQ0FBQUM7QUFBQSxFQUFBLHFCQUFBQztBQUFBLEVBQUEsOEJBQUFDO0FBQUEsRUFBQSw4QkFBQUM7QUFBQSxFQUFBLHVCQUFBQztBQUFBLEVBQUEsdUJBQUFDO0FBQUE7QUFBQTtBQUVBLElBQUFQLHFCQUFzQztBQUN0QyxJQUFBRCxpQkFBa0M7QUFDbEMsSUFBQUUscUJBQXNDO0FBQ3RDLElBQUFDLDBCQUEyQztBQUMzQyxJQUFBQyxjQUErQjtBQUMvQixJQUFBQyx1QkFBd0M7QUFDeEMsSUFBQUMsdUJBQXdDO0FBQ3hDLElBQUFDLGdCQUFpQztBQUNqQyxJQUFBQyxnQkFBaUM7IiwKICAibmFtZXMiOiBbImNvdmVyYWdlLWJhZGdlIiwgImNvdmVyYWdlLWJhZGdlLWNsaSIsICJlMmUtcnVubmVyLXN1cHBvcnQiLCAiaW50ZWdyYXRpb24tdGVzdC1wbHVnaW4iLCAiamVzdC1jb25maWciLCAib2JzaWRpYW4tdGVzdC1ydW5uZXIiLCAicGVyZm9ybWFuY2UtZXZhbC1jYXAiLCAidml0ZXN0LWNvbmZpZyIsICJ3ZGlvLW9ic2lkaWFuIl0KfQo=
65
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL3Rlc3QtcnVubmVycy9pbmRleC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyogVEhJUyBJUyBBIEdFTkVSQVRFRC9CVU5ETEVEIEZJTEUgQlkgQlVJTEQgU0NSSVBUICovXG5cbmV4cG9ydCAqIGFzICdjb3ZlcmFnZS1iYWRnZS1jbGknIGZyb20gJy4vY292ZXJhZ2UtYmFkZ2UtY2xpLnRzJztcbmV4cG9ydCAqIGFzICdjb3ZlcmFnZS1iYWRnZScgZnJvbSAnLi9jb3ZlcmFnZS1iYWRnZS50cyc7XG5leHBvcnQgKiBhcyAnZTJlLXJ1bm5lci1zdXBwb3J0JyBmcm9tICcuL2UyZS1ydW5uZXItc3VwcG9ydC50cyc7XG5leHBvcnQgKiBhcyAnamVzdC1jb25maWcnIGZyb20gJy4vamVzdC1jb25maWcudHMnO1xuZXhwb3J0ICogYXMgJ29ic2lkaWFuLXRlc3QtcnVubmVyJyBmcm9tICcuL29ic2lkaWFuLXRlc3QtcnVubmVyLnRzJztcbmV4cG9ydCAqIGFzICdwZXJmb3JtYW5jZS1ldmFsLWNhcCcgZnJvbSAnLi9wZXJmb3JtYW5jZS1ldmFsLWNhcC50cyc7XG5leHBvcnQgKiBhcyAndml0ZXN0LWNvbmZpZycgZnJvbSAnLi92aXRlc3QtY29uZmlnLnRzJztcbmV4cG9ydCAqIGFzICd3ZGlvLW9ic2lkaWFuJyBmcm9tICcuL3dkaW8tb2JzaWRpYW4udHMnO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBLDBCQUFBQTtBQUFBLEVBQUEsNEJBQUFDO0FBQUEsRUFBQSw0QkFBQUM7QUFBQSxFQUFBLHFCQUFBQztBQUFBLEVBQUEsOEJBQUFDO0FBQUEsRUFBQSw4QkFBQUM7QUFBQSxFQUFBLHVCQUFBQztBQUFBLEVBQUEsdUJBQUFDO0FBQUE7QUFBQTtBQUVBLElBQUFOLHFCQUFzQztBQUN0QyxJQUFBRCxpQkFBa0M7QUFDbEMsSUFBQUUscUJBQXNDO0FBQ3RDLElBQUFDLGNBQStCO0FBQy9CLElBQUFDLHVCQUF3QztBQUN4QyxJQUFBQyx1QkFBd0M7QUFDeEMsSUFBQUMsZ0JBQWlDO0FBQ2pDLElBQUFDLGdCQUFpQzsiLAogICJuYW1lcyI6IFsiY292ZXJhZ2UtYmFkZ2UiLCAiY292ZXJhZ2UtYmFkZ2UtY2xpIiwgImUyZS1ydW5uZXItc3VwcG9ydCIsICJqZXN0LWNvbmZpZyIsICJvYnNpZGlhbi10ZXN0LXJ1bm5lciIsICJwZXJmb3JtYW5jZS1ldmFsLWNhcCIsICJ2aXRlc3QtY29uZmlnIiwgIndkaW8tb2JzaWRpYW4iXQp9Cg==
@@ -2,7 +2,6 @@
2
2
  export * as 'coverage-badge-cli' from './coverage-badge-cli.cjs';
3
3
  export * as 'coverage-badge' from './coverage-badge.cjs';
4
4
  export * as 'e2e-runner-support' from './e2e-runner-support.cjs';
5
- export * as 'integration-test-plugin' from './integration-test-plugin.cjs';
6
5
  export * as 'jest-config' from './jest-config.cjs';
7
6
  export * as 'obsidian-test-runner' from './obsidian-test-runner.cjs';
8
7
  export * as 'performance-eval-cap' from './performance-eval-cap.cjs';
@@ -61,6 +61,20 @@
61
61
  * or a misspelled directive all fail: an exemption nobody can justify, that nothing needs any more, or that
62
62
  * silently does nothing is worse than no exemption at all.
63
63
  *
64
+ * They also check that every `Try it` section — a heading of any level starting `Try it`, up to the next
65
+ * heading of the same or a higher level — holds a `code-button` that performs its setup, because a reader
66
+ * asked to configure things by hand is a reader the demo lost. A section whose steps really cannot be
67
+ * scripted says so with the same directive, naming the `demo-vault-validation/try-it-code-button` rule on
68
+ * the heading, and with the same checks on the directive itself:
69
+ *
70
+ * ```markdown
71
+ * <!-- obsidian-dev-utils-disable-next-line demo-vault-validation/try-it-code-button -- Dragging a file in from outside Obsidian cannot be scripted. -->
72
+ * ## Try it
73
+ * ```
74
+ *
75
+ * That check fails the suite by default; {@link DemoVaultAuthoringSpec.tryItCodeButtons} set to `'warn'`
76
+ * prints the sections instead, for a vault still being brought up to it.
77
+ *
64
78
  * Two layers are exposed:
65
79
  * - {@link DemoVaultCoverageChecker} — a framework-agnostic core that reads the corpus, parses interface /
66
80
  * class / enum members and exported functions, and returns diagnostic arrays (what is undemonstrated / stale
@@ -83,7 +97,17 @@ export interface DemoVaultAuthoringSpec {
83
97
  * `00 Start.md`.
84
98
  */
85
99
  readonly startNote?: string;
100
+ /**
101
+ * How a `Try it` section with no `code-button` and no directive explaining why is reported: `'warn'`
102
+ * prints the sections and passes, `'error'` fails the suite. Defaults to `'error'`.
103
+ */
104
+ readonly tryItCodeButtons?: DemoVaultCheckSeverity;
86
105
  }
106
+ /**
107
+ * How a check that is being introduced gradually reports what it finds: `'warn'` prints it and passes,
108
+ * `'error'` fails.
109
+ */
110
+ export type DemoVaultCheckSeverity = 'error' | 'warn';
87
111
  /**
88
112
  * Reflects a config interface whose options are demonstrated by their bare name.
89
113
  */
@@ -268,6 +292,46 @@ export interface DemoVaultNote {
268
292
  */
269
293
  readonly relativePath: string;
270
294
  }
295
+ /**
296
+ * What a note's inline `obsidian-dev-utils-disable…` directives allow, rule by rule, and what is wrong with
297
+ * them.
298
+ */
299
+ export interface DirectiveScan {
300
+ /**
301
+ * For each rule, the zero-based line numbers a directive exempts from it.
302
+ */
303
+ readonly allowedLineIndexesByRule: ReadonlyMap<string, ReadonlySet<number>>;
304
+ /**
305
+ * The directive mistakes found, each phrased for a failing assertion.
306
+ */
307
+ readonly problems: string[];
308
+ }
309
+ /**
310
+ * The running state of a directive scan, threaded through the per-line helpers.
311
+ */
312
+ export interface DirectiveScanState {
313
+ /**
314
+ * For each rule, the lines a directive has exempted from it so far.
315
+ */
316
+ readonly allowedLineIndexesByRule: Map<string, Set<number>>;
317
+ /**
318
+ * For each rule, the region currently open, and whether it has covered a target yet.
319
+ */
320
+ readonly openRegionsByRule: Map<string, OpenDirectiveRegion>;
321
+ /**
322
+ * For each rule, the line a `disable-next-line` was read on, while it still waits for the line it covers.
323
+ */
324
+ readonly pendingNextLineIndexesByRule: Map<string, number>;
325
+ /**
326
+ * The directive mistakes found so far.
327
+ */
328
+ readonly problems: string[];
329
+ /**
330
+ * For each rule, the lines of the note that break it — the lines a directive for it has to cover to be
331
+ * doing any work.
332
+ */
333
+ readonly targetLineIndexesByRule: ReadonlyMap<string, ReadonlySet<number>>;
334
+ }
271
335
  /**
272
336
  * The parsed members of a source interface, class, or enum.
273
337
  */
@@ -302,6 +366,22 @@ export interface NoteLine {
302
366
  /**
303
367
  * A `disable` region that has been opened and not yet enabled again.
304
368
  */
369
+ export interface OpenDirectiveRegion {
370
+ /**
371
+ * Whether the region has covered a line breaking its rule, which is what stops it being reported as
372
+ * pointless.
373
+ */
374
+ isUsed: boolean;
375
+ /**
376
+ * The line the region was opened on.
377
+ */
378
+ readonly lineIndex: number;
379
+ }
380
+ /**
381
+ * A `disable` region that has been opened and not yet enabled again.
382
+ *
383
+ * @deprecated Use {@link OpenDirectiveRegion}: the directives now serve more than the wikilink rule.
384
+ */
305
385
  export interface OpenWikilinkDirectiveRegion {
306
386
  /**
307
387
  * Whether the region has covered a wikilink, which is what stops it being reported as pointless.
@@ -351,6 +431,8 @@ export interface RegisterDemoVaultCoverageSuiteParams {
351
431
  }
352
432
  /**
353
433
  * What a note's inline `obsidian-dev-utils-disable…` directives allow, and what is wrong with them.
434
+ *
435
+ * @deprecated Use {@link DirectiveScan}: the directives now serve more than the wikilink rule.
354
436
  */
355
437
  export interface WikilinkDirectiveScan {
356
438
  /**
@@ -364,6 +446,8 @@ export interface WikilinkDirectiveScan {
364
446
  }
365
447
  /**
366
448
  * The running state of a directive scan, threaded through the per-line helpers.
449
+ *
450
+ * @deprecated Use {@link DirectiveScanState}: the directives now serve more than the wikilink rule.
367
451
  */
368
452
  export interface WikilinkDirectiveScanState {
369
453
  /**
@@ -373,7 +457,7 @@ export interface WikilinkDirectiveScanState {
373
457
  /**
374
458
  * The region currently open, and whether it has covered a wikilink yet.
375
459
  */
376
- openRegion: null | OpenWikilinkDirectiveRegion;
460
+ openRegion: null | OpenDirectiveRegion;
377
461
  /**
378
462
  * The line a `disable-next-line` was read on, while it still waits for the line it covers.
379
463
  */
@@ -448,11 +532,12 @@ export declare class DemoVaultCoverageChecker {
448
532
  */
449
533
  findNotesWithoutIntroProse(): string[];
450
534
  /**
451
- * Finds notes whose wikilink allowance is not doing any work — declared without a reason, or on a note
452
- * that carries no wikilink at all. Both are drift: an exemption nobody can justify, and one nothing needs
453
- * any more, which would go on hiding the next wikilink somebody adds by accident.
535
+ * Finds notes whose exemptions are not doing any work — a wikilink allowance or an inline directive for
536
+ * any rule declared without a reason, misspelled, or covering nothing that breaks its rule. All of them
537
+ * are drift: an exemption nobody can justify, and one nothing needs any more, which would go on hiding
538
+ * the next mistake somebody makes by accident.
454
539
  *
455
- * @returns The relative paths of the offending notes.
540
+ * @returns One `<note>: <problem>` entry per problem found.
456
541
  */
457
542
  findNotesWithUnjustifiedWikilinkAllowance(): string[];
458
543
  /**
@@ -471,6 +556,16 @@ export declare class DemoVaultCoverageChecker {
471
556
  * @returns The distinct stale member names referenced in the demo corpus.
472
557
  */
473
558
  findStaleReferences(params: DemoVaultCoverageCheckerFindStaleReferencesParams): string[];
559
+ /**
560
+ * Finds `Try it` sections with no `code-button` in them. A `Try it` section is a heading of any level
561
+ * starting `Try it`, up to the next heading of the same or a higher level; the setup it asks for is
562
+ * what a button is for, so a section that leaves the reader to do it by hand is the shape this check
563
+ * rejects. A section whose heading a `demo-vault-validation/try-it-code-button` directive covers has
564
+ * stated why it cannot be scripted, and is skipped — see the file overview.
565
+ *
566
+ * @returns One `<note>: line <n>` entry per offending section, naming the line of its heading.
567
+ */
568
+ findTryItSectionsWithoutCodeButton(): string[];
474
569
  /**
475
570
  * Finds members that are not demonstrated anywhere in the demo corpus.
476
571
  *