@tsrx/oxc 0.0.0-trusted-publishing-bootstrap → 0.8.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/LICENSE +21 -0
- package/README.md +141 -0
- package/THIRD_PARTY_NOTICES.md +49 -0
- package/bin/oxc-tsrx +2 -0
- package/bin/oxc-tsrx-fmt +2 -0
- package/bin/oxc-tsrx-lint +2 -0
- package/bin/oxc-tsrx-lsp +2 -0
- package/bin/oxfmt +2 -0
- package/bin/oxlint +2 -0
- package/dist/bin/oxc-tsrx-fmt.js +13 -0
- package/dist/bin/oxc-tsrx-lint.js +13 -0
- package/dist/bin/oxc-tsrx-lsp.js +13 -0
- package/dist/bin/oxc-tsrx.js +115 -0
- package/dist/bin/oxfmt.js +24 -0
- package/dist/bin/oxlint.js +33 -0
- package/dist/canonical-command.d.ts +50 -0
- package/dist/canonical-command.js +196 -0
- package/dist/compat.d.ts +149 -0
- package/dist/compat.js +1615 -0
- package/dist/editor-resolution.js +508 -0
- package/dist/format-cli.js +276 -0
- package/dist/format-invocation.js +97 -0
- package/dist/format.d.ts +1 -0
- package/dist/format.js +56 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +16 -0
- package/dist/lint-cli.js +487 -0
- package/dist/lint-invocation.js +192 -0
- package/dist/lint-js-plugins.js +819 -0
- package/dist/lint-plugins-dev.d.ts +1 -0
- package/dist/lint-plugins-dev.js +2 -0
- package/dist/lint-prestart.js +16 -0
- package/dist/lint.d.ts +1 -0
- package/dist/lint.js +2 -0
- package/dist/native-targets.js +76 -0
- package/dist/oxlint-lsp-multiplexer.js +622 -0
- package/dist/package-binary.js +29 -0
- package/dist/parser.d.ts +216 -0
- package/dist/parser.js +557 -0
- package/dist/process.js +88 -0
- package/dist/provider-resolve.d.ts +160 -0
- package/dist/provider-resolve.js +471 -0
- package/dist/providers-report.js +49 -0
- package/dist/runtime.js +323 -0
- package/dist/spawn-command.d.ts +20 -0
- package/dist/spawn-command.js +87 -0
- package/dist/tsrx-core-compat/facade.js +1184 -0
- package/dist/tsrx-core-compat/index.d.ts +6 -0
- package/dist/tsrx-core-compat/index.js +9 -0
- package/dist/tsrx-core-compat/style.js +525 -0
- package/dist/tsrx-core-compat/types/estree.d.ts +20 -0
- package/dist/tsrx-core-compat/types/index.d.ts +50 -0
- package/dist/tsrx-transfer.js +352 -0
- package/package.json +144 -5
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { DEPENDENCY_FIELDS, extensionOf, findProjectRoot } from "./provider-resolve.js";
|
|
2
|
+
import { spawnCommand } from "./spawn-command.js";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
5
|
+
import { once } from "node:events";
|
|
6
|
+
import { open, readFile } from "node:fs/promises";
|
|
7
|
+
import { dirname, join, resolve } from "node:path";
|
|
8
|
+
import { pathToFileURL } from "node:url";
|
|
9
|
+
//#region src/canonical-command.ts
|
|
10
|
+
/**
|
|
11
|
+
* Arbitration for the canonical command names this package also publishes.
|
|
12
|
+
*
|
|
13
|
+
* `oxc-tsrx` ships `oxlint` and `oxfmt` bins because that is the only thing
|
|
14
|
+
* that makes a plain `npm install @tsrx/oxc` reach released hosts: the installer
|
|
15
|
+
* links `node_modules/.bin/oxlint`, and the released `oxc.oxc-vscode`
|
|
16
|
+
* extension probes exactly that path first. Nothing else about the shipped
|
|
17
|
+
* artifact reaches an unmodified host.
|
|
18
|
+
*
|
|
19
|
+
* The cost is a name collision. When a project *also* declares the official
|
|
20
|
+
* `oxlint` or `oxfmt` package, whichever package wins `node_modules/.bin` is
|
|
21
|
+
* decided by the installer, and installers disagree: npm 11 links this
|
|
22
|
+
* package's launcher and pnpm 10 links the official one. Measured for T016.
|
|
23
|
+
*
|
|
24
|
+
* So the launcher decides for itself instead of inheriting the race. A direct
|
|
25
|
+
* dependency on the official package in the project's own manifest is an
|
|
26
|
+
* explicit statement about what that command name means, and it wins: the
|
|
27
|
+
* launcher hands the whole invocation to the exact binary that package
|
|
28
|
+
* declares. The observable behaviour of `oxlint`/`oxfmt` in such a project is
|
|
29
|
+
* then identical under every installer, and identical to what it was before
|
|
30
|
+
* `oxc-tsrx` was added.
|
|
31
|
+
*
|
|
32
|
+
* A transitive official package (Vite+ depends on `oxlint`, for instance) is
|
|
33
|
+
* not such a statement, so it does not take the command name away.
|
|
34
|
+
*/
|
|
35
|
+
const OWNED_COMMANDS = Object.freeze({
|
|
36
|
+
oxlint: Object.freeze({ leafBin: "oxc-tsrx-lint" }),
|
|
37
|
+
oxfmt: Object.freeze({ leafBin: "oxc-tsrx-fmt" })
|
|
38
|
+
});
|
|
39
|
+
/** The extension this package's provider block claims. */
|
|
40
|
+
const PROVIDED_EXTENSION = ".tsrx";
|
|
41
|
+
function isPlainObject(value) {
|
|
42
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
43
|
+
}
|
|
44
|
+
function declaresDirectly(manifest, name) {
|
|
45
|
+
for (const field of DEPENDENCY_FIELDS) {
|
|
46
|
+
const declared = manifest?.[field];
|
|
47
|
+
if (isPlainObject(declared) && typeof declared[name] === "string") return field;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
function declaredBin(manifest, command) {
|
|
52
|
+
if (typeof manifest.bin === "string") return manifest.name === command ? manifest.bin : null;
|
|
53
|
+
if (!isPlainObject(manifest.bin)) return null;
|
|
54
|
+
const declared = manifest.bin[command];
|
|
55
|
+
return typeof declared === "string" && declared.length > 0 ? declared : null;
|
|
56
|
+
}
|
|
57
|
+
/** True for the package-name facade `oxc-tsrx setup` writes into that slot. */
|
|
58
|
+
function isCompatibilityFacade(manifest) {
|
|
59
|
+
return manifest?.oxcTsrxCompatibility?.provider === "oxc-tsrx";
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Decide who owns `command` for the project `cwd` belongs to.
|
|
63
|
+
*
|
|
64
|
+
* Never throws for an ordinary project: an unreadable or absent manifest simply
|
|
65
|
+
* means nothing took the name away. It throws only for the one genuinely
|
|
66
|
+
* ambiguous case — the project declares the official package and that package
|
|
67
|
+
* is not installed — because guessing there would silently change which linter
|
|
68
|
+
* or formatter a pinned project runs.
|
|
69
|
+
*/
|
|
70
|
+
async function decideCanonicalCommand(command, options = {}) {
|
|
71
|
+
if (OWNED_COMMANDS[command] === void 0) throw new Error(`unknown canonical command: ${command}`);
|
|
72
|
+
const cwd = options.cwd ?? process.cwd();
|
|
73
|
+
let projectRoot;
|
|
74
|
+
let manifest;
|
|
75
|
+
try {
|
|
76
|
+
projectRoot = await findProjectRoot(cwd);
|
|
77
|
+
manifest = JSON.parse(await readFile(join(projectRoot, "package.json"), "utf8"));
|
|
78
|
+
} catch {
|
|
79
|
+
return {
|
|
80
|
+
command,
|
|
81
|
+
owner: "@tsrx/oxc",
|
|
82
|
+
reason: "no-project-manifest",
|
|
83
|
+
projectRoot: null
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const field = declaresDirectly(manifest, command);
|
|
87
|
+
if (field === null) return {
|
|
88
|
+
command,
|
|
89
|
+
owner: "@tsrx/oxc",
|
|
90
|
+
reason: "not-directly-declared",
|
|
91
|
+
projectRoot
|
|
92
|
+
};
|
|
93
|
+
let manifestPath;
|
|
94
|
+
try {
|
|
95
|
+
manifestPath = createRequire(join(projectRoot, "package.json")).resolve(`${command}/package.json`);
|
|
96
|
+
} catch {
|
|
97
|
+
throw new Error(`${projectRoot}/package.json declares the official ${command} package in ${field}, but ${command} is not installed. Install dependencies, or remove that dependency to let oxc-tsrx own the ${command} command.`);
|
|
98
|
+
}
|
|
99
|
+
const officialManifest = JSON.parse(await readFile(manifestPath, "utf8"));
|
|
100
|
+
if (isCompatibilityFacade(officialManifest)) return {
|
|
101
|
+
command,
|
|
102
|
+
owner: "@tsrx/oxc",
|
|
103
|
+
reason: "compatibility-facade",
|
|
104
|
+
projectRoot,
|
|
105
|
+
officialRoot: dirname(manifestPath)
|
|
106
|
+
};
|
|
107
|
+
const declared = declaredBin(officialManifest, command);
|
|
108
|
+
if (declared === null) throw new Error(`${projectRoot}/package.json declares the official ${command} package in ${field}, but the installed ${officialManifest.name ?? command} does not declare a ${command} binary. Remove that dependency to let oxc-tsrx own the ${command} command.`);
|
|
109
|
+
return {
|
|
110
|
+
command,
|
|
111
|
+
owner: "project",
|
|
112
|
+
reason: `declared-in-${field}`,
|
|
113
|
+
projectRoot,
|
|
114
|
+
officialRoot: dirname(manifestPath),
|
|
115
|
+
officialVersion: typeof officialManifest.version === "string" ? officialManifest.version : null,
|
|
116
|
+
binPath: resolve(dirname(manifestPath), declared)
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** Arguments that name a file this package's provider block claims. */
|
|
120
|
+
function providedArguments(args) {
|
|
121
|
+
return args.filter((argument) => typeof argument === "string" && !argument.startsWith("-") && extensionOf(argument) === PROVIDED_EXTENSION);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* One actionable line, only when the caller actually asked about a `.tsrx`
|
|
125
|
+
* file. Silence for every ordinary invocation is the point: a project that
|
|
126
|
+
* pinned official Oxlint or Oxfmt must not gain new output because `oxc-tsrx`
|
|
127
|
+
* is installed somewhere in its tree.
|
|
128
|
+
*/
|
|
129
|
+
function deferralNotice(decision, args) {
|
|
130
|
+
if (decision.owner !== "project") return null;
|
|
131
|
+
const provided = providedArguments(args);
|
|
132
|
+
if (provided.length === 0) return null;
|
|
133
|
+
const owned = OWNED_COMMANDS[decision.command];
|
|
134
|
+
const pinned = decision.officialVersion === null ? `the official ${decision.command} package` : `official ${decision.command} ${decision.officialVersion}`;
|
|
135
|
+
return `${decision.command} (oxc-tsrx): this project depends on ${pinned}, so the ${decision.command} command runs it unchanged and will not read ${provided.join(", ")}. Run \`npx ${owned.leafBin}\` for .tsrx files, or drop the direct ${decision.command} dependency to let oxc-tsrx serve both.`;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* A declared `bin` entry may be a JavaScript wrapper or a native executable.
|
|
139
|
+
* Reading the shebang is a static file read, not an execution of the package.
|
|
140
|
+
*
|
|
141
|
+
* The BOM strip is not decoration. A UTF-8 byte-order mark is common in files
|
|
142
|
+
* authored on Windows, and it sits in front of the `#!`, so without stripping
|
|
143
|
+
* it a perfectly ordinary Node wrapper would be classified as a native
|
|
144
|
+
* executable and spawned — which on Windows fails outright, because an
|
|
145
|
+
* extensionless file is not something `CreateProcess` can run.
|
|
146
|
+
*/
|
|
147
|
+
async function usesNodeInterpreter(path) {
|
|
148
|
+
let handle;
|
|
149
|
+
try {
|
|
150
|
+
handle = await open(path, "r");
|
|
151
|
+
const buffer = Buffer.alloc(128);
|
|
152
|
+
const { bytesRead } = await handle.read(buffer, 0, 128, 0);
|
|
153
|
+
const shebang = buffer.subarray(0, bytesRead).toString("utf8").replace(/^\uFEFF/u, "").split("\n", 1)[0];
|
|
154
|
+
return shebang.startsWith("#!") && /\bnode(?:\.exe)?\b/u.test(shebang);
|
|
155
|
+
} catch {
|
|
156
|
+
return false;
|
|
157
|
+
} finally {
|
|
158
|
+
await handle?.close();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Execute the official binary, preserving its exact behaviour. A Node wrapper
|
|
163
|
+
* runs in this process so argv, stdio, exit code, and signal handling are the
|
|
164
|
+
* program's own; anything else is spawned with inherited stdio and its status
|
|
165
|
+
* is mirrored.
|
|
166
|
+
*
|
|
167
|
+
* `pathToFileURL` is load-bearing rather than tidy: on Windows a bare absolute
|
|
168
|
+
* path such as `C:\project\node_modules\oxlint\bin\oxlint` is not a valid
|
|
169
|
+
* import specifier, and `import()` rejects it with ERR_UNSUPPORTED_ESM_URL_SCHEME
|
|
170
|
+
* because it reads `C:` as a URL scheme. Every host reaches the in-process
|
|
171
|
+
* branch, so this is the difference between the launcher working on Windows and
|
|
172
|
+
* failing on the first `oxlint` in a project that pinned the official package.
|
|
173
|
+
*
|
|
174
|
+
* `spawnCommand` covers the other branch: a declared `bin` may be a `.cmd` or
|
|
175
|
+
* `.bat` launcher, which only a command interpreter can run. See
|
|
176
|
+
* ./spawn-command.js for why that is done inline and without `shell: true`.
|
|
177
|
+
*
|
|
178
|
+
* A spawn that never starts is reported rather than thrown as an unhandled
|
|
179
|
+
* `error` event, so the caller's `catch` turns it into this package's one-line
|
|
180
|
+
* message instead of a stack trace from inside `node:child_process`.
|
|
181
|
+
*/
|
|
182
|
+
async function runOfficialCommand(decision, options = {}) {
|
|
183
|
+
if (await usesNodeInterpreter(decision.binPath)) {
|
|
184
|
+
await import(pathToFileURL(decision.binPath).href);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const spawnProcess = options.spawn ?? spawn;
|
|
188
|
+
const child = spawnCommand(decision.binPath, process.argv.slice(2), { stdio: "inherit" }, spawnProcess);
|
|
189
|
+
let failure = null;
|
|
190
|
+
child.on("error", (error) => failure ??= error);
|
|
191
|
+
const [status, signal] = await once(child, "close").catch(() => [null, null]);
|
|
192
|
+
if (failure !== null) throw new Error(`could not execute ${decision.binPath}, the ${decision.command} binary declared by ${decision.officialRoot ?? "the official package"}: ${failure.message}`);
|
|
193
|
+
process.exitCode = signal === null ? status ?? 0 : 2;
|
|
194
|
+
}
|
|
195
|
+
//#endregion
|
|
196
|
+
export { decideCanonicalCommand, deferralNotice, providedArguments, runOfficialCommand, usesNodeInterpreter };
|
package/dist/compat.d.ts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
export type OxcTsrxCompatibilityState =
|
|
2
|
+
| "missing"
|
|
3
|
+
| "replaceable"
|
|
4
|
+
| "active"
|
|
5
|
+
| "stale"
|
|
6
|
+
| "collision";
|
|
7
|
+
|
|
8
|
+
export interface OxcTsrxCompatibilitySlot {
|
|
9
|
+
readonly name: "oxc-parser" | "oxlint" | "oxfmt";
|
|
10
|
+
readonly capability: "parser" | "lint" | "format";
|
|
11
|
+
readonly path: string;
|
|
12
|
+
readonly state: OxcTsrxCompatibilityState;
|
|
13
|
+
readonly replacedPackage?: {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly version: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The editor slot is not a package. It is the single `oxc.path.oxlint` key in
|
|
21
|
+
* the project's own `.vscode/settings.json`, written only when
|
|
22
|
+
* `node_modules/.bin/oxlint` belongs to another tool.
|
|
23
|
+
*
|
|
24
|
+
* - `unnecessary` — the ordinary lookup already reaches this package.
|
|
25
|
+
* - `missing` — needed, and the key is absent.
|
|
26
|
+
* - `active` — the key points into this package.
|
|
27
|
+
* - `stale` — this package wrote the key and it no longer resolves here.
|
|
28
|
+
* - `collision` — the key is set to something else and is left untouched.
|
|
29
|
+
* - `unreadable` — the settings file is not a single top-level JSON object.
|
|
30
|
+
*/
|
|
31
|
+
export type OxcTsrxEditorSlotState =
|
|
32
|
+
| "unnecessary"
|
|
33
|
+
| "missing"
|
|
34
|
+
| "active"
|
|
35
|
+
| "stale"
|
|
36
|
+
| "collision"
|
|
37
|
+
| "unreadable";
|
|
38
|
+
|
|
39
|
+
export interface OxcTsrxEditorSlot {
|
|
40
|
+
readonly name: "oxc.path.oxlint";
|
|
41
|
+
readonly capability: "editor";
|
|
42
|
+
readonly key: "oxc.path.oxlint";
|
|
43
|
+
/** Absolute path of the project's `.vscode/settings.json`. */
|
|
44
|
+
readonly path: string;
|
|
45
|
+
/** The value this package would write. */
|
|
46
|
+
readonly value: string;
|
|
47
|
+
readonly state: OxcTsrxEditorSlotState;
|
|
48
|
+
readonly currentValue?: string | null;
|
|
49
|
+
readonly linterShim: {
|
|
50
|
+
readonly path: string;
|
|
51
|
+
readonly target: string | null;
|
|
52
|
+
readonly owner: "oxc-tsrx" | "other" | "none" | "unknown";
|
|
53
|
+
readonly resolvedBy:
|
|
54
|
+
| "symlink"
|
|
55
|
+
| "shim-text"
|
|
56
|
+
| "compatibility-facade"
|
|
57
|
+
| "unresolved"
|
|
58
|
+
| "absent";
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* TSRX editor support that this package deliberately does not own. Every field
|
|
64
|
+
* is read-only reporting: nothing here is installed, edited, or configured.
|
|
65
|
+
*/
|
|
66
|
+
export interface OxcTsrxLanguageSupport {
|
|
67
|
+
readonly typescriptPlugin: {
|
|
68
|
+
readonly package: "@tsrx/typescript-plugin";
|
|
69
|
+
readonly present: boolean;
|
|
70
|
+
readonly version: string | null;
|
|
71
|
+
};
|
|
72
|
+
readonly frameworkBinding: {
|
|
73
|
+
readonly candidates: readonly string[];
|
|
74
|
+
readonly present: boolean;
|
|
75
|
+
readonly name: string | null;
|
|
76
|
+
readonly version: string | null;
|
|
77
|
+
};
|
|
78
|
+
readonly tsconfig: {
|
|
79
|
+
readonly path: string | null;
|
|
80
|
+
readonly readable: boolean;
|
|
81
|
+
readonly declaresPlugin: boolean;
|
|
82
|
+
};
|
|
83
|
+
readonly typescript: {
|
|
84
|
+
readonly requirement: ">=5.9 <6";
|
|
85
|
+
readonly present: boolean;
|
|
86
|
+
readonly version: string | null;
|
|
87
|
+
readonly supported: boolean;
|
|
88
|
+
};
|
|
89
|
+
readonly notes: readonly string[];
|
|
90
|
+
readonly ok: boolean;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface OxcTsrxCompatibilityOptions {
|
|
94
|
+
readonly projectRoot?: string;
|
|
95
|
+
readonly userAgent?: string;
|
|
96
|
+
readonly dryRun?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Opt in to `setup` adding the `@tsrx/typescript-plugin` entry under
|
|
99
|
+
* `compilerOptions` in the tsconfig that owns your source. Without it,
|
|
100
|
+
* `setup` reports the missing entry and edits no tsconfig at all.
|
|
101
|
+
*/
|
|
102
|
+
readonly writeTsconfig?: boolean;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface OxcTsrxCompatibilityStatus {
|
|
106
|
+
readonly projectRoot: string;
|
|
107
|
+
readonly packageManager: "npm" | "pnpm" | "yarn" | "bun" | "unknown";
|
|
108
|
+
readonly providerVersion: string;
|
|
109
|
+
readonly selectedFrom: "dependencies" | "devDependencies" | "optionalDependencies";
|
|
110
|
+
readonly slots: readonly OxcTsrxCompatibilitySlot[];
|
|
111
|
+
readonly editorSlot: OxcTsrxEditorSlot;
|
|
112
|
+
readonly languageSupport: OxcTsrxLanguageSupport;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface OxcTsrxTsconfigWrite {
|
|
116
|
+
readonly path: string;
|
|
117
|
+
/** `written` on a fresh entry, `present` when it already named the plugin. */
|
|
118
|
+
readonly state: "written" | "present" | "preview";
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface OxcTsrxSetupResult extends OxcTsrxCompatibilityStatus {
|
|
122
|
+
readonly action: "preview" | "setup";
|
|
123
|
+
/** Present only when `writeTsconfig` was requested. */
|
|
124
|
+
readonly tsconfigWrite?: OxcTsrxTsconfigWrite;
|
|
125
|
+
readonly changed: readonly string[];
|
|
126
|
+
readonly unchanged: readonly string[];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface OxcTsrxRemoveResult extends OxcTsrxCompatibilityStatus {
|
|
130
|
+
readonly action: "preview-remove" | "remove";
|
|
131
|
+
readonly removed: readonly string[];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export declare function findProjectRoot(start?: string): Promise<string>;
|
|
135
|
+
export declare function compatibilityStatus(
|
|
136
|
+
options?: OxcTsrxCompatibilityOptions,
|
|
137
|
+
): Promise<OxcTsrxCompatibilityStatus>;
|
|
138
|
+
export declare function setupCompatibility(
|
|
139
|
+
options?: OxcTsrxCompatibilityOptions,
|
|
140
|
+
): Promise<OxcTsrxSetupResult>;
|
|
141
|
+
export declare function removeCompatibility(
|
|
142
|
+
options?: OxcTsrxCompatibilityOptions,
|
|
143
|
+
): Promise<OxcTsrxRemoveResult>;
|
|
144
|
+
export declare function formatCompatibilityReport(
|
|
145
|
+
result:
|
|
146
|
+
| OxcTsrxCompatibilityStatus
|
|
147
|
+
| OxcTsrxSetupResult
|
|
148
|
+
| OxcTsrxRemoveResult,
|
|
149
|
+
): string;
|