@tikoci/centrs 0.1.3 → 0.1.4
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/CHANGELOG.md +39 -0
- package/GLOSSARY.txt +213 -0
- package/LICENSE +21 -0
- package/README.md +36 -8
- package/commands/AGENTS.md +7 -1
- package/commands/api/README.md +19 -18
- package/commands/api/examples.md +15 -0
- package/commands/btest/README.md +21 -32
- package/commands/check/README.md +6 -1
- package/commands/discover/README.md +5 -11
- package/commands/execute/README.md +41 -29
- package/commands/execute/examples.md +41 -3
- package/commands/explain/README.md +1716 -0
- package/commands/explain/examples.md +606 -0
- package/commands/retrieve/README.md +25 -27
- package/commands/retrieve/examples.md +16 -0
- package/commands/transfer/README.md +28 -20
- package/commands/transfer/examples.md +29 -0
- package/docs/CLI.md +353 -0
- package/docs/CONSTITUTION.md +66 -15
- package/docs/MATRIX.md +38 -1
- package/docs/errors/README.md +3 -0
- package/docs/errors/quickchr/machine-not-found.md +22 -0
- package/docs/errors/quickchr/machine-stopped.md +20 -0
- package/docs/errors/quickchr/package-unavailable.md +27 -0
- package/docs/errors/quickchr/unsupported-via.md +35 -0
- package/docs/errors/quickchr/unsupported.md +35 -0
- package/docs/errors/routeros/version-unsupported.md +26 -0
- package/docs/errors/transport/provider-trust.md +29 -0
- package/docs/errors/usage/stdin-ignored.md +28 -0
- package/docs/errors/validation/unknown-attribute.md +37 -4
- package/package.json +45 -10
- package/src/api-fanout.ts +29 -14
- package/src/api.ts +97 -54
- package/src/cli/api.ts +25 -6
- package/src/cli/btest.ts +18 -2
- package/src/cli/execute.ts +25 -6
- package/src/cli/explain.ts +503 -0
- package/src/cli/retrieve.ts +33 -1
- package/src/cli/selection.ts +71 -11
- package/src/cli/settings.ts +2 -2
- package/src/cli/transfer.ts +23 -6
- package/src/cli.ts +15 -2
- package/src/core/envelope.ts +5 -2
- package/src/core/error-catalog.ts +40 -0
- package/src/core/preflight.ts +306 -0
- package/src/core/routeros-string.ts +24 -0
- package/src/errors.ts +1 -0
- package/src/execute-fanout.ts +29 -14
- package/src/execute.ts +114 -63
- package/src/explain/arg-tokens.ts +114 -0
- package/src/explain/args.ts +1403 -0
- package/src/explain/blocks.ts +132 -0
- package/src/explain/brace-slots.ts +143 -0
- package/src/explain/brace-tokens.ts +38 -0
- package/src/explain/catalog.ts +1345 -0
- package/src/explain/coordinates.ts +329 -0
- package/src/explain/defects.ts +217 -0
- package/src/explain/is-known-menu.ts +17 -0
- package/src/explain/menus.ts +664 -0
- package/src/explain/operator-tokens.ts +310 -0
- package/src/explain/operators.ts +458 -0
- package/src/explain/path-tokens.ts +150 -0
- package/src/explain/pathresolve.ts +1324 -0
- package/src/explain/quoted-string.ts +241 -0
- package/src/explain/scope-brace.ts +308 -0
- package/src/explain/segment.ts +757 -0
- package/src/explain/string-tokens.ts +67 -0
- package/src/explain/symbol-values.ts +520 -0
- package/src/explain/symbols.ts +1597 -0
- package/src/explain/token-ranges.ts +72 -0
- package/src/explain/transport.ts +497 -0
- package/src/explain/value-tokens.ts +80 -0
- package/src/explain/values.ts +357 -0
- package/src/explain/verbs.ts +64 -0
- package/src/explain/verbsplit.ts +813 -0
- package/src/explain/write.ts +815 -0
- package/src/explain.ts +2152 -0
- package/src/index.ts +206 -4
- package/src/protocols/mac-telnet-console.ts +61 -17
- package/src/resolver/facts.ts +1 -1
- package/src/resolver/index.ts +23 -4
- package/src/resolver/quickchr-provider.ts +597 -0
- package/src/resolver/selection.ts +99 -12
- package/src/resolver/service-endpoint.ts +155 -0
- package/src/resolver/target.ts +1 -1
- package/src/retrieve-fanout.ts +26 -12
- package/src/retrieve.ts +81 -18
- package/src/transfer-fanout.ts +42 -25
- package/src/transfer.ts +87 -44
package/src/index.ts
CHANGED
|
@@ -118,6 +118,24 @@ export {
|
|
|
118
118
|
isCommandNode,
|
|
119
119
|
pathTokens,
|
|
120
120
|
} from "./core/inspect.ts";
|
|
121
|
+
export {
|
|
122
|
+
assertCapability,
|
|
123
|
+
type CapabilityRequirement,
|
|
124
|
+
checkCapability,
|
|
125
|
+
compareRouterOsVersion,
|
|
126
|
+
type DeviceVersion,
|
|
127
|
+
type DeviceVersionSource,
|
|
128
|
+
type PreflightState,
|
|
129
|
+
type PreflightVerdict,
|
|
130
|
+
parseRouterOsVersion,
|
|
131
|
+
probeDeviceVersion,
|
|
132
|
+
type RouterOsVersionParts,
|
|
133
|
+
type RouterOsVersionRange,
|
|
134
|
+
renderSupportedRanges,
|
|
135
|
+
routerOsVersionAtLeast,
|
|
136
|
+
versionFactFromComment,
|
|
137
|
+
versionInRange,
|
|
138
|
+
} from "./core/preflight.ts";
|
|
121
139
|
export {
|
|
122
140
|
encodeMndpPacket,
|
|
123
141
|
MNDP_BROADCAST_ADDRESS,
|
|
@@ -276,6 +294,190 @@ export {
|
|
|
276
294
|
executeFanout,
|
|
277
295
|
renderExecuteFanoutEnvelope,
|
|
278
296
|
} from "./execute-fanout.ts";
|
|
297
|
+
// The lexer's own names are module-scoped and read naturally there; at the
|
|
298
|
+
// package root they need the `Explain` prefix every other explain export
|
|
299
|
+
// carries — a bare `Argument` says nothing about which of centrs's surfaces it
|
|
300
|
+
// belongs to. Aliasing at the re-export is the existing pattern here (see
|
|
301
|
+
// `occurrences as explainOccurrences` below).
|
|
302
|
+
//
|
|
303
|
+
// `ExplainArgument` and `ExplainArgumentToken` are the same SHAPE in two
|
|
304
|
+
// coordinate spaces: this one is what `lexArguments` returns, with spans
|
|
305
|
+
// relative to the statement it was handed; the `Token` is that rebased into
|
|
306
|
+
// document space by `explainCommand`. A consumer reading `explainCommand`'s
|
|
307
|
+
// result wants the latter.
|
|
308
|
+
export {
|
|
309
|
+
type Argument as ExplainArgument,
|
|
310
|
+
type ArgumentKind as ExplainArgumentKind,
|
|
311
|
+
type ArgumentReading as ExplainArgumentReading,
|
|
312
|
+
type ArgumentsRead as ExplainArgumentsRead,
|
|
313
|
+
type ArgumentsUnread as ExplainArgumentsUnread,
|
|
314
|
+
lexArguments as lexExplainArguments,
|
|
315
|
+
lexValueAnchors as lexExplainValueAnchors,
|
|
316
|
+
type ValueAnchor as ExplainValueAnchor,
|
|
317
|
+
type ValueAnchorKind as ExplainValueAnchorKind,
|
|
318
|
+
type ValueAnchorReading as ExplainValueAnchorReading,
|
|
319
|
+
} from "./explain/args.ts";
|
|
320
|
+
export {
|
|
321
|
+
DIRECTIVE_BODY,
|
|
322
|
+
HEAD_SCOPED_ARG_NAMES,
|
|
323
|
+
isScopeBrace,
|
|
324
|
+
matchBrace,
|
|
325
|
+
SCOPE_ARG_NAMES,
|
|
326
|
+
type ScopeBlock,
|
|
327
|
+
scopeBlocks,
|
|
328
|
+
scopeBodies,
|
|
329
|
+
scopeNameAt,
|
|
330
|
+
} from "./explain/blocks.ts";
|
|
331
|
+
export {
|
|
332
|
+
analyzeCoordinates,
|
|
333
|
+
byteSpanToRange,
|
|
334
|
+
byteToPosition,
|
|
335
|
+
type CharRun,
|
|
336
|
+
type CoordinateAnalysis,
|
|
337
|
+
coordinateDefects,
|
|
338
|
+
type Position,
|
|
339
|
+
positionToByte,
|
|
340
|
+
type Range,
|
|
341
|
+
runAtByte,
|
|
342
|
+
SUB,
|
|
343
|
+
} from "./explain/coordinates.ts";
|
|
344
|
+
export {
|
|
345
|
+
type Defect,
|
|
346
|
+
type DefectCode,
|
|
347
|
+
defectAt,
|
|
348
|
+
hasStructuralDefect,
|
|
349
|
+
isPositionalFact,
|
|
350
|
+
mergeDefects,
|
|
351
|
+
rebaseDefects,
|
|
352
|
+
} from "./explain/defects.ts";
|
|
353
|
+
export {
|
|
354
|
+
type DocumentAnalysis,
|
|
355
|
+
type Resolution,
|
|
356
|
+
resolveDocument,
|
|
357
|
+
resolveStatements,
|
|
358
|
+
type Span,
|
|
359
|
+
type StatementAnalysis,
|
|
360
|
+
type StatementResolution,
|
|
361
|
+
} from "./explain/pathresolve.ts";
|
|
362
|
+
export {
|
|
363
|
+
maskComments,
|
|
364
|
+
type QuotedStringScan,
|
|
365
|
+
type Segment,
|
|
366
|
+
type SegmentResult,
|
|
367
|
+
scanQuotedString,
|
|
368
|
+
segmentStatements,
|
|
369
|
+
} from "./explain/segment.ts";
|
|
370
|
+
export {
|
|
371
|
+
HIGHLIGHT_CLASS,
|
|
372
|
+
resolveSymbols,
|
|
373
|
+
type SymbolAnalysis,
|
|
374
|
+
type SymbolClass,
|
|
375
|
+
type SymbolOccurrence,
|
|
376
|
+
type SymbolRole,
|
|
377
|
+
} from "./explain/symbols.ts";
|
|
378
|
+
export type {
|
|
379
|
+
ExplainApiCandidateTransport,
|
|
380
|
+
ExplainExecuteTransport,
|
|
381
|
+
ExplainRestMethod,
|
|
382
|
+
ExplainRestRequest,
|
|
383
|
+
ExplainTransport,
|
|
384
|
+
ExplainTransportClassification,
|
|
385
|
+
ExplainUnknownTransport,
|
|
386
|
+
} from "./explain/transport.ts";
|
|
387
|
+
export {
|
|
388
|
+
VALUE_SHAPES,
|
|
389
|
+
type ValueContext as ExplainValueContext,
|
|
390
|
+
type ValueShape as ExplainValueShape,
|
|
391
|
+
type ValueShapeOptions as ExplainValueShapeOptions,
|
|
392
|
+
valueShapeHints as explainValueShapeHints,
|
|
393
|
+
} from "./explain/values.ts";
|
|
394
|
+
export {
|
|
395
|
+
type DocumentVerbSplit,
|
|
396
|
+
describeStatement,
|
|
397
|
+
isDirective,
|
|
398
|
+
type RunToken,
|
|
399
|
+
resolveVerb,
|
|
400
|
+
resolveVerbs,
|
|
401
|
+
runTokens,
|
|
402
|
+
type Sep,
|
|
403
|
+
type Split,
|
|
404
|
+
SUBMENU_DIRECTIVES,
|
|
405
|
+
splitRun,
|
|
406
|
+
VERBS,
|
|
407
|
+
type VerbAnalysis,
|
|
408
|
+
type VerbResolution,
|
|
409
|
+
type VerbSplit,
|
|
410
|
+
type VerbSplitCommandReading,
|
|
411
|
+
type VerbSplitMenuReading,
|
|
412
|
+
type VerbSplitRefusal,
|
|
413
|
+
} from "./explain/verbsplit.ts";
|
|
414
|
+
export {
|
|
415
|
+
classifyVerb,
|
|
416
|
+
containsWrite,
|
|
417
|
+
type Occurrence,
|
|
418
|
+
type OccurrenceClass,
|
|
419
|
+
// `occurrences` is too generic for the library root; the module-local name
|
|
420
|
+
// stays short because inside `write.ts` there is only one kind.
|
|
421
|
+
occurrences as explainOccurrences,
|
|
422
|
+
READ_VERBS,
|
|
423
|
+
ROOT_CMDS,
|
|
424
|
+
ROOT_DYNAMIC,
|
|
425
|
+
ROOT_WRITE,
|
|
426
|
+
WRITE_VERBS,
|
|
427
|
+
type WriteAnalysis,
|
|
428
|
+
type WriteVerdict,
|
|
429
|
+
} from "./explain/write.ts";
|
|
430
|
+
export {
|
|
431
|
+
buildExplainErrorEnvelope,
|
|
432
|
+
buildExplainFacetTip,
|
|
433
|
+
type ExplainArguments,
|
|
434
|
+
type ExplainArgumentToken,
|
|
435
|
+
type ExplainBlock,
|
|
436
|
+
type ExplainCanonical,
|
|
437
|
+
type ExplainCommandOptions,
|
|
438
|
+
type ExplainCommandReading,
|
|
439
|
+
type ExplainData,
|
|
440
|
+
type ExplainDiagnostic,
|
|
441
|
+
type ExplainEnvelope,
|
|
442
|
+
type ExplainEnvelopeOptions,
|
|
443
|
+
type ExplainErrorEnvelope,
|
|
444
|
+
type ExplainEvidence,
|
|
445
|
+
type ExplainFailOn,
|
|
446
|
+
type ExplainInput,
|
|
447
|
+
type ExplainMenuReading,
|
|
448
|
+
type ExplainOperationMeta,
|
|
449
|
+
type ExplainOutputFormat,
|
|
450
|
+
type ExplainPositionMapEntry,
|
|
451
|
+
type ExplainReading,
|
|
452
|
+
type ExplainRefusal,
|
|
453
|
+
type ExplainResolution,
|
|
454
|
+
type ExplainSeverity,
|
|
455
|
+
type ExplainSpan,
|
|
456
|
+
type ExplainSpanClass,
|
|
457
|
+
type ExplainSpanRange,
|
|
458
|
+
type ExplainStatement,
|
|
459
|
+
type ExplainStatementFacts,
|
|
460
|
+
type ExplainStructure,
|
|
461
|
+
type ExplainSubcommand,
|
|
462
|
+
type ExplainSubcommandFacts,
|
|
463
|
+
type ExplainSymbolClass,
|
|
464
|
+
type ExplainSymbolOccurrence,
|
|
465
|
+
type ExplainSymbols,
|
|
466
|
+
type ExplainToken,
|
|
467
|
+
type ExplainTokenClass,
|
|
468
|
+
type ExplainValueFacts,
|
|
469
|
+
type ExplainValueOccurrence,
|
|
470
|
+
type ExplainValueShapeFact,
|
|
471
|
+
type ExplainValues,
|
|
472
|
+
type ExplainValueTypeFact,
|
|
473
|
+
type ExplainVerdict,
|
|
474
|
+
explainCommand,
|
|
475
|
+
explainEnvelope,
|
|
476
|
+
explainExitCode,
|
|
477
|
+
explainFailOnLevels,
|
|
478
|
+
explainOutputFormats,
|
|
479
|
+
renderExplainEnvelope,
|
|
480
|
+
} from "./explain.ts";
|
|
279
481
|
export {
|
|
280
482
|
type ApiVerb,
|
|
281
483
|
createProtocolAdapter,
|
|
@@ -304,9 +506,6 @@ export {
|
|
|
304
506
|
type CdbGroupTarget,
|
|
305
507
|
type CdbResolution,
|
|
306
508
|
type CdbResolveInput,
|
|
307
|
-
type CdbSelectionExpansion,
|
|
308
|
-
type CdbSelectionMember,
|
|
309
|
-
type CdbSelectionResolveInput,
|
|
310
509
|
type CommentKvGeoKey,
|
|
311
510
|
type CommentKvKey,
|
|
312
511
|
type CommentKvLayer,
|
|
@@ -323,7 +522,7 @@ export {
|
|
|
323
522
|
defaultPortForScheme,
|
|
324
523
|
deviceLocation,
|
|
325
524
|
expandCdbGroup,
|
|
326
|
-
|
|
525
|
+
expandSelection,
|
|
327
526
|
isDefaultRecordTarget,
|
|
328
527
|
type NearPredicate,
|
|
329
528
|
type ParsedGpsTuple,
|
|
@@ -351,6 +550,9 @@ export {
|
|
|
351
550
|
resolveOptionalIntegerSetting,
|
|
352
551
|
resolveStringSetting,
|
|
353
552
|
resolveTarget,
|
|
553
|
+
type SelectionExpansion,
|
|
554
|
+
type SelectionMember,
|
|
555
|
+
type SelectionResolveInput,
|
|
354
556
|
type SelectionWhereClause,
|
|
355
557
|
type TargetResolveInput,
|
|
356
558
|
type TargetSelection,
|
|
@@ -39,10 +39,11 @@
|
|
|
39
39
|
* scraped for: `(evl …)` = ok, `syntax error (line …)` = malformed, and
|
|
40
40
|
* `bad parameter <name> (line …)` = unknown attribute. A single console
|
|
41
41
|
* `:parse` therefore covers both the syntax and the unknown-attribute
|
|
42
|
-
* (
|
|
42
|
+
* (name-level) gate — no `/console/inspect` table parsing needed.
|
|
43
43
|
*/
|
|
44
44
|
|
|
45
45
|
import { parseRouterOsPosition } from "../core/routeros-errors.ts";
|
|
46
|
+
import { routerOsStringLiteral } from "../core/routeros-string.ts";
|
|
46
47
|
import { CentrsError } from "../errors.ts";
|
|
47
48
|
import {
|
|
48
49
|
type MacAddress,
|
|
@@ -323,8 +324,11 @@ export class MacTelnetConsole {
|
|
|
323
324
|
* Validate a command without running it, using a single console `:parse`.
|
|
324
325
|
* Throws `validation/syntax` for malformed CLI and
|
|
325
326
|
* `validation/unknown-attribute` for a rejected parameter; returns the parsed
|
|
326
|
-
* form on success. One gate covers both because the console
|
|
327
|
-
*
|
|
327
|
+
* form on success. One gate covers both because the console prints the
|
|
328
|
+
* `:parse` return value, which carries `bad parameter <name>` as well as the
|
|
329
|
+
* `(<%%` / `(line N column M)` syntax diagnostics — see
|
|
330
|
+
* {@link classifyParseResult} for the full grammar and why the matcher is
|
|
331
|
+
* anchored to the diagnostic shape rather than to bare words.
|
|
328
332
|
*/
|
|
329
333
|
async parseGate(cli: string): Promise<string> {
|
|
330
334
|
const { output } = await this.run(parseScriptFor(cli));
|
|
@@ -604,17 +608,61 @@ export function parseScriptFor(cli: string): string {
|
|
|
604
608
|
return `:put [:parse ${routerOsStringLiteral(cli)}]`;
|
|
605
609
|
}
|
|
606
610
|
|
|
611
|
+
/*
|
|
612
|
+
* The `:parse` diagnostic grammar, anchored to where RouterOS actually emits
|
|
613
|
+
* each shape. Anchoring is load-bearing, not cosmetic: an *accepted* return
|
|
614
|
+
* echoes the script body, so `:put "bad parameter x"` comes back as
|
|
615
|
+
* `(evl /putmessage=bad parameter x)`. An unanchored search reads that echoed
|
|
616
|
+
* content as a verdict and refuses to run a valid command (GH#230).
|
|
617
|
+
*
|
|
618
|
+
* Two shapes, both corpus-verified against lsp-routeros-ts
|
|
619
|
+
* `parseil_results.il_text` (2736 rows, RouterOS 7.20.8/7.22.1/7.23rc1):
|
|
620
|
+
*
|
|
621
|
+
* 1. WRAPPED — the diagnostic sits inside the returned value, marked by the
|
|
622
|
+
* `(evl ` / `(<%%` wrapper. It can appear mid-return, because a
|
|
623
|
+
* multi-statement script reports the offending statement in place. Every
|
|
624
|
+
* corpus `bad parameter` (8/8) follows `(evl `, and every `bad command
|
|
625
|
+
* name` (135/135) follows `(<%%`.
|
|
626
|
+
* 2. BARE — the diagnostic *is* the whole return, printed on its own line
|
|
627
|
+
* with RouterOS's position suffix. All 425 corpus rows of this shape are
|
|
628
|
+
* the entire return; none appear embedded. Requiring both line-start and
|
|
629
|
+
* the `(line N column M)` suffix is what separates a real verdict from
|
|
630
|
+
* echoed body text.
|
|
631
|
+
*/
|
|
632
|
+
const WRAPPED_BAD_PARAMETER = /\(evl\s+bad parameter\s+(\S+)/i;
|
|
633
|
+
const WRAPPED_BAD_COMMAND = /\(<%%\s*bad command name\b/i;
|
|
634
|
+
const BARE_BAD_PARAMETER =
|
|
635
|
+
/^[ \t]*bad parameter\s+(\S+)[^\n]*\(line \d+ column \d+\)/im;
|
|
636
|
+
const BARE_SYNTAX =
|
|
637
|
+
/^[ \t]*(?:syntax error|bad command name|expected [a-z]+(?: [a-z]+)*)[^\n]*\(line \d+ column \d+\)/im;
|
|
638
|
+
|
|
607
639
|
/**
|
|
608
|
-
* Classify the
|
|
609
|
-
* `:parse`
|
|
610
|
-
*
|
|
611
|
-
*
|
|
640
|
+
* Classify the printed value of `:put [:parse "<cli>"]`. Grounded on CHR 7.23.3
|
|
641
|
+
* (see GH#230): `:parse` *never* throws — it returns a value whose text carries
|
|
642
|
+
* the verdict. For a bare menu path the accepted form is `(evl /canonical/path)`
|
|
643
|
+
* (abbreviations expanded); for script-shaped input the accepted return echoes
|
|
644
|
+
* the statement body and may contain arbitrary text — including text that looks
|
|
645
|
+
* like a diagnostic. Rejections are therefore matched only in the positions
|
|
646
|
+
* RouterOS emits them (see the grammar note above): wrapped as
|
|
647
|
+
* `(evl bad parameter <name> (line N column M) /path)` /
|
|
648
|
+
* `(<%% bad command name <name> (line N column M) a;b;c)`, or bare and
|
|
649
|
+
* line-initial as `expected … (line N column M)` / `syntax error (line N column
|
|
650
|
+
* M)`. A single `:parse` covers both the syntax and the unknown-attribute
|
|
651
|
+
* (name-level) gate on every transport — REST and native API expose the same text
|
|
652
|
+
* in the `ret` value (HTTP 200 / `as-string`), the console transports print it.
|
|
653
|
+
*
|
|
654
|
+
* Throws the matching `validation/*` error; returns on a clean parse.
|
|
612
655
|
*/
|
|
613
|
-
export function classifyParseResult(
|
|
614
|
-
|
|
656
|
+
export function classifyParseResult(
|
|
657
|
+
output: string,
|
|
658
|
+
cli: string,
|
|
659
|
+
via: string = "mac-telnet",
|
|
660
|
+
): void {
|
|
661
|
+
// The `:parse` rejection carries RouterOS's authoritative byte offset
|
|
615
662
|
// (`… (line N column M)`); surface it as the structured `error.position`.
|
|
616
663
|
const position = parseRouterOsPosition(output);
|
|
617
|
-
const unknown =
|
|
664
|
+
const unknown =
|
|
665
|
+
output.match(WRAPPED_BAD_PARAMETER) ?? output.match(BARE_BAD_PARAMETER);
|
|
618
666
|
if (unknown) {
|
|
619
667
|
throw new CentrsError({
|
|
620
668
|
code: "validation/unknown-attribute",
|
|
@@ -624,13 +672,13 @@ export function classifyParseResult(output: string, cli: string): void {
|
|
|
624
672
|
context: {
|
|
625
673
|
command: cli,
|
|
626
674
|
parameter: cleanToken(unknown[1] ?? ""),
|
|
627
|
-
validationSource:
|
|
675
|
+
validationSource: `:put [:parse ...] over ${via}`,
|
|
628
676
|
detail: output,
|
|
629
677
|
},
|
|
630
678
|
...(position ? { position } : {}),
|
|
631
679
|
});
|
|
632
680
|
}
|
|
633
|
-
if (
|
|
681
|
+
if (WRAPPED_BAD_COMMAND.test(output) || BARE_SYNTAX.test(output)) {
|
|
634
682
|
throw new CentrsError({
|
|
635
683
|
code: "validation/syntax",
|
|
636
684
|
summary: "RouterOS rejected the command syntax while parsing it.",
|
|
@@ -638,7 +686,7 @@ export function classifyParseResult(output: string, cli: string): void {
|
|
|
638
686
|
"Fix the RouterOS CLI syntax (quotes, brackets, attribute form), then retry.",
|
|
639
687
|
context: {
|
|
640
688
|
command: cli,
|
|
641
|
-
validationSource:
|
|
689
|
+
validationSource: `:put [:parse ...] over ${via}`,
|
|
642
690
|
detail: output,
|
|
643
691
|
},
|
|
644
692
|
...(position ? { position } : {}),
|
|
@@ -646,10 +694,6 @@ export function classifyParseResult(output: string, cli: string): void {
|
|
|
646
694
|
}
|
|
647
695
|
}
|
|
648
696
|
|
|
649
|
-
function routerOsStringLiteral(value: string): string {
|
|
650
|
-
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
651
|
-
}
|
|
652
|
-
|
|
653
697
|
function cleanToken(token: string): string {
|
|
654
698
|
return token.replace(/^["'`]+|["'`.,;:)]+$/g, "");
|
|
655
699
|
}
|
package/src/resolver/facts.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Device-class fact extraction + selector matching, shared by the fan-out
|
|
3
|
-
* resolver ({@link ../resolver/selection.ts |
|
|
3
|
+
* resolver ({@link ../resolver/selection.ts | expandSelection}) and
|
|
4
4
|
* `devices list` (`src/devices.ts`) so **both surfaces match `--where` /
|
|
5
5
|
* `--near` / `--bbox` against identical semantics**.
|
|
6
6
|
*
|
package/src/resolver/index.ts
CHANGED
|
@@ -88,14 +88,33 @@ export {
|
|
|
88
88
|
unresolvedMacError,
|
|
89
89
|
} from "./mac.ts";
|
|
90
90
|
export {
|
|
91
|
-
|
|
92
|
-
type
|
|
93
|
-
type
|
|
94
|
-
|
|
91
|
+
assertNoQuickchrOverrideConflict,
|
|
92
|
+
type QuickchrConnection,
|
|
93
|
+
type QuickchrResolution,
|
|
94
|
+
quickchrConnection,
|
|
95
|
+
resolveQuickchrTarget,
|
|
96
|
+
SUPPORTED_DESCRIPTOR_VERSION,
|
|
97
|
+
} from "./quickchr-provider.ts";
|
|
98
|
+
export {
|
|
99
|
+
expandSelection,
|
|
95
100
|
isDefaultRecordTarget,
|
|
101
|
+
type SelectionExpansion,
|
|
102
|
+
type SelectionMember,
|
|
103
|
+
type SelectionResolveInput,
|
|
96
104
|
type SelectionWhereClause,
|
|
97
105
|
type TargetSelection,
|
|
98
106
|
} from "./selection.ts";
|
|
107
|
+
export {
|
|
108
|
+
type AnyServiceEndpoint,
|
|
109
|
+
isEndpointAvailable,
|
|
110
|
+
type ServiceEndpoint,
|
|
111
|
+
type ServiceEndpointAuth,
|
|
112
|
+
type ServiceEndpointMap,
|
|
113
|
+
type ServiceEndpointSource,
|
|
114
|
+
type SshEndpointAuth,
|
|
115
|
+
type SshServiceEndpoint,
|
|
116
|
+
type UnavailableEndpoint,
|
|
117
|
+
} from "./service-endpoint.ts";
|
|
99
118
|
export {
|
|
100
119
|
type CommentKvLayer,
|
|
101
120
|
parseBoolean,
|