@qvac/sdk 0.11.0 → 0.12.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 (205) hide show
  1. package/NOTICE +1427 -39
  2. package/README.md +2 -0
  3. package/dist/client/api/classify.d.ts +23 -0
  4. package/dist/client/api/classify.js +43 -0
  5. package/dist/client/api/get-model-info.d.ts +1 -1
  6. package/dist/client/api/index.d.ts +4 -0
  7. package/dist/client/api/index.js +4 -0
  8. package/dist/client/api/load-model.js +24 -1
  9. package/dist/client/api/transcribe.d.ts +3 -0
  10. package/dist/client/api/transcribe.js +13 -2
  11. package/dist/client/api/video.d.ts +64 -0
  12. package/dist/client/api/video.js +147 -0
  13. package/dist/client/api/vla-helpers.d.ts +45 -0
  14. package/dist/client/api/vla-helpers.js +130 -0
  15. package/dist/client/api/vla.d.ts +65 -0
  16. package/dist/client/api/vla.js +109 -0
  17. package/dist/client/config-loader/resolve-config.node.d.ts +16 -0
  18. package/dist/client/config-loader/resolve-config.node.js +77 -23
  19. package/dist/client/plugins-factory.d.ts +8 -0
  20. package/dist/client/plugins-factory.js +10 -0
  21. package/dist/client/rpc/bare-client.js +62 -66
  22. package/dist/client/rpc/ensure-worker-ready.d.ts +9 -0
  23. package/dist/client/rpc/ensure-worker-ready.js +17 -0
  24. package/dist/client/rpc/node-rpc-client.js +4 -1
  25. package/dist/client/rpc/rpc-error.js +14 -1
  26. package/dist/commands/bundle/bare-pack.d.ts +13 -0
  27. package/dist/commands/bundle/bare-pack.js +54 -0
  28. package/dist/commands/bundle/constants.d.ts +7 -0
  29. package/dist/commands/bundle/constants.js +23 -0
  30. package/dist/commands/bundle/entry-gen.d.ts +2 -0
  31. package/dist/commands/bundle/entry-gen.js +48 -0
  32. package/dist/commands/bundle/index.d.ts +20 -0
  33. package/dist/commands/bundle/index.js +141 -0
  34. package/dist/commands/bundle/manifest.d.ts +21 -0
  35. package/dist/commands/bundle/manifest.js +193 -0
  36. package/dist/commands/bundle/plugins.d.ts +9 -0
  37. package/dist/commands/bundle/plugins.js +51 -0
  38. package/dist/commands/index.d.ts +5 -0
  39. package/dist/commands/index.js +2 -0
  40. package/dist/commands/verify/abi.d.ts +52 -0
  41. package/dist/commands/verify/abi.js +125 -0
  42. package/dist/commands/verify/addon-source.d.ts +43 -0
  43. package/dist/commands/verify/addon-source.js +75 -0
  44. package/dist/commands/verify/bundle-source.d.ts +12 -0
  45. package/dist/commands/verify/bundle-source.js +53 -0
  46. package/dist/commands/verify/index.d.ts +59 -0
  47. package/dist/commands/verify/index.js +371 -0
  48. package/dist/commands/verify/node-modules-source.d.ts +11 -0
  49. package/dist/commands/verify/node-modules-source.js +76 -0
  50. package/dist/commands/verify/prebuilds.d.ts +15 -0
  51. package/dist/commands/verify/prebuilds.js +39 -0
  52. package/dist/examples/classification/classify-image.d.ts +2 -0
  53. package/dist/examples/classification/classify-image.js +23 -0
  54. package/dist/examples/diffusion-txt2vid.d.ts +2 -0
  55. package/dist/examples/diffusion-txt2vid.js +81 -0
  56. package/dist/examples/plugins.js +3 -7
  57. package/dist/examples/tools/llamacpp-tools-gemma4.js +2 -5
  58. package/dist/examples/tools/llamacpp-tools-qwen35.js +2 -3
  59. package/dist/examples/transcription/parakeet-ctc-filesystem.js +18 -12
  60. package/dist/examples/transcription/parakeet-microphone-record.js +7 -12
  61. package/dist/examples/transcription/parakeet-microphone-stream.d.ts +2 -0
  62. package/dist/examples/transcription/parakeet-microphone-stream.js +79 -0
  63. package/dist/examples/transcription/parakeet-sortformer-streaming.d.ts +2 -0
  64. package/dist/examples/transcription/parakeet-sortformer-streaming.js +121 -0
  65. package/dist/examples/transcription/parakeet-sortformer.js +58 -55
  66. package/dist/examples/transcription/parakeet-tdt-filesystem.js +18 -15
  67. package/dist/examples/transcription/whispercpp-microphone-conversation.js +6 -1
  68. package/dist/examples/tts/chatterbox.js +7 -16
  69. package/dist/examples/tts/llm-to-tts-streaming.js +3 -10
  70. package/dist/examples/tts/supertonic-multilingual.js +4 -12
  71. package/dist/examples/tts/supertonic.js +5 -12
  72. package/dist/examples/vla-smolvla.d.ts +2 -0
  73. package/dist/examples/vla-smolvla.js +75 -0
  74. package/dist/examples/voice-assistant/voice-assistant.js +3 -10
  75. package/dist/expo/plugins/find-in-ancestor-node-modules.d.ts +14 -0
  76. package/dist/expo/plugins/find-in-ancestor-node-modules.js +24 -0
  77. package/dist/expo/plugins/get-project-root.d.ts +22 -0
  78. package/dist/expo/plugins/get-project-root.js +23 -0
  79. package/dist/expo/plugins/index.d.ts +4 -0
  80. package/dist/expo/plugins/index.js +4 -0
  81. package/dist/expo/plugins/resolve-sdk-package-dir.d.ts +9 -2
  82. package/dist/expo/plugins/resolve-sdk-package-dir.js +38 -11
  83. package/dist/expo/plugins/withDeviceInfo.js +2 -1
  84. package/dist/expo/plugins/withMobileBundle.d.ts +2 -17
  85. package/dist/expo/plugins/withMobileBundle.js +31 -85
  86. package/dist/index.d.ts +4 -3
  87. package/dist/index.js +4 -3
  88. package/dist/models/registry/models.d.ts +3711 -368
  89. package/dist/models/registry/models.js +7066 -3562
  90. package/dist/models/update-models/naming.js +22 -8
  91. package/dist/pear/pre.js +6 -2
  92. package/dist/schemas/cancel.d.ts +5 -0
  93. package/dist/schemas/cancel.js +1 -0
  94. package/dist/schemas/classification.d.ts +53 -0
  95. package/dist/schemas/classification.js +33 -0
  96. package/dist/schemas/common.d.ts +1001 -1739
  97. package/dist/schemas/common.js +6 -1
  98. package/dist/schemas/completion-event.d.ts +3 -0
  99. package/dist/schemas/completion-event.js +1 -0
  100. package/dist/schemas/completion-stream.d.ts +1 -0
  101. package/dist/schemas/download-asset.d.ts +13 -3
  102. package/dist/schemas/engine-addon-map.d.ts +3 -0
  103. package/dist/schemas/engine-addon-map.js +18 -5
  104. package/dist/schemas/get-model-info.d.ts +4 -0
  105. package/dist/schemas/get-model-info.js +2 -0
  106. package/dist/schemas/index.d.ts +3 -0
  107. package/dist/schemas/index.js +3 -0
  108. package/dist/schemas/llamacpp-config.d.ts +12 -2
  109. package/dist/schemas/load-model.d.ts +6152 -10764
  110. package/dist/schemas/load-model.js +75 -7
  111. package/dist/schemas/model-src-utils.d.ts +22 -2
  112. package/dist/schemas/model-types.d.ts +46 -6
  113. package/dist/schemas/model-types.js +28 -5
  114. package/dist/schemas/ocr.d.ts +5 -0
  115. package/dist/schemas/plugin.d.ts +20 -5
  116. package/dist/schemas/plugin.js +21 -4
  117. package/dist/schemas/registry.d.ts +44 -0
  118. package/dist/schemas/registry.js +5 -0
  119. package/dist/schemas/reload-config.d.ts +22 -2
  120. package/dist/schemas/sdcpp-config.d.ts +316 -1
  121. package/dist/schemas/sdcpp-config.js +232 -33
  122. package/dist/schemas/sdk-config.d.ts +654 -1324
  123. package/dist/schemas/sdk-config.js +16 -1
  124. package/dist/schemas/sdk-errors-client.d.ts +5 -0
  125. package/dist/schemas/sdk-errors-client.js +26 -1
  126. package/dist/schemas/sdk-errors-server.d.ts +3 -1
  127. package/dist/schemas/sdk-errors-server.js +20 -5
  128. package/dist/schemas/text-to-speech.d.ts +79 -696
  129. package/dist/schemas/text-to-speech.js +46 -19
  130. package/dist/schemas/transcription-config.d.ts +37 -226
  131. package/dist/schemas/transcription-config.js +76 -15
  132. package/dist/schemas/transcription.d.ts +63 -11
  133. package/dist/schemas/transcription.js +56 -2
  134. package/dist/schemas/translation-config.d.ts +60 -10
  135. package/dist/schemas/vla.d.ts +87 -0
  136. package/dist/schemas/vla.js +108 -0
  137. package/dist/scripts/run-unit-tests.js +8 -2
  138. package/dist/server/bare/ops/transcribe.d.ts +2 -1
  139. package/dist/server/bare/ops/transcribe.js +59 -34
  140. package/dist/server/bare/plugins/ggml-classification/ops/classify.d.ts +6 -0
  141. package/dist/server/bare/plugins/ggml-classification/ops/classify.js +30 -0
  142. package/dist/server/bare/plugins/ggml-classification/plugin.d.ts +32 -0
  143. package/dist/server/bare/plugins/ggml-classification/plugin.js +55 -0
  144. package/dist/server/bare/plugins/ggml-vla/ops/vla-hparams.d.ts +3 -0
  145. package/dist/server/bare/plugins/ggml-vla/ops/vla-hparams.js +12 -0
  146. package/dist/server/bare/plugins/ggml-vla/ops/vla-run.d.ts +3 -0
  147. package/dist/server/bare/plugins/ggml-vla/ops/vla-run.js +75 -0
  148. package/dist/server/bare/plugins/ggml-vla/plugin.d.ts +54 -0
  149. package/dist/server/bare/plugins/ggml-vla/plugin.js +57 -0
  150. package/dist/server/bare/plugins/index.d.ts +3 -1
  151. package/dist/server/bare/plugins/index.js +3 -1
  152. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +3 -0
  153. package/dist/server/bare/plugins/llamacpp-completion/ops/context-overflow.d.ts +29 -0
  154. package/dist/server/bare/plugins/llamacpp-completion/ops/context-overflow.js +65 -0
  155. package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +6 -0
  156. package/dist/server/bare/plugins/llamacpp-completion/plugin.js +26 -0
  157. package/dist/server/bare/plugins/nmtcpp-translation/plugin.d.ts +25 -0
  158. package/dist/server/bare/plugins/onnx-ocr/plugin.d.ts +5 -0
  159. package/dist/server/bare/plugins/parakeet-transcription/plugin.d.ts +67 -246
  160. package/dist/server/bare/plugins/parakeet-transcription/plugin.js +66 -97
  161. package/dist/server/bare/plugins/sdcpp-generation/ops/video.d.ts +3 -0
  162. package/dist/server/bare/plugins/sdcpp-generation/ops/video.js +199 -0
  163. package/dist/server/bare/plugins/sdcpp-generation/plugin.d.ts +200 -2
  164. package/dist/server/bare/plugins/sdcpp-generation/plugin.js +61 -8
  165. package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech-stream.js +2 -15
  166. package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech.js +2 -1
  167. package/dist/server/bare/plugins/tts-ggml/plugin.d.ts +75 -0
  168. package/dist/server/bare/plugins/tts-ggml/plugin.js +189 -0
  169. package/dist/server/bare/plugins/whispercpp-transcription/plugin.d.ts +29 -4
  170. package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +12 -1
  171. package/dist/server/bare/registry/model-config-utils.js +7 -0
  172. package/dist/server/bare/runtime/request-context.d.ts +1 -1
  173. package/dist/server/bare/runtime-lifecycle.js +9 -9
  174. package/dist/server/bare/types/addon-responses.d.ts +1 -0
  175. package/dist/server/env.js +4 -1
  176. package/dist/server/plugins/index.d.ts +1 -1
  177. package/dist/server/plugins/index.js +1 -1
  178. package/dist/server/plugins/registry.d.ts +1 -0
  179. package/dist/server/plugins/registry.js +5 -0
  180. package/dist/server/rpc/handler-registry.js +4 -0
  181. package/dist/server/rpc/handler-selection.d.ts +9 -0
  182. package/dist/server/rpc/handler-selection.js +14 -0
  183. package/dist/server/rpc/handler-utils.js +5 -13
  184. package/dist/server/rpc/handlers/classify.d.ts +3 -0
  185. package/dist/server/rpc/handlers/classify.js +4 -0
  186. package/dist/server/rpc/handlers/index.d.ts +2 -0
  187. package/dist/server/rpc/handlers/index.js +2 -0
  188. package/dist/server/rpc/handlers/load-model/handler.js +4 -1
  189. package/dist/server/rpc/handlers/load-model/resolve.js +9 -0
  190. package/dist/server/rpc/handlers/video-stream.d.ts +3 -0
  191. package/dist/server/rpc/handlers/video-stream.js +4 -0
  192. package/dist/server/rpc/profiling/operation-metrics.js +23 -0
  193. package/dist/server/utils/config-transform.js +1 -1
  194. package/dist/server/worker.js +14 -11
  195. package/dist/utils/errors-client.d.ts +15 -0
  196. package/dist/utils/errors-client.js +26 -0
  197. package/dist/utils/errors-server.d.ts +30 -2
  198. package/dist/utils/errors-server.js +51 -3
  199. package/package.json +66 -80
  200. package/dist/server/bare/plugins/onnx-tts/plugin.d.ts +0 -490
  201. package/dist/server/bare/plugins/onnx-tts/plugin.js +0 -272
  202. package/dist/server/bare/plugins/onnx-tts/wav-helper.d.ts +0 -14
  203. package/dist/server/bare/plugins/onnx-tts/wav-helper.js +0 -107
  204. /package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech-stream.d.ts +0 -0
  205. /package/dist/server/bare/plugins/{onnx-tts → tts-ggml}/ops/text-to-speech.d.ts +0 -0
@@ -0,0 +1,43 @@
1
+ export type AddonSourceKind = "bare-pack-bundle" | "node-modules";
2
+ export interface NativeAddon {
3
+ name: string;
4
+ version?: string;
5
+ packageJsonPath: string;
6
+ packageRoot: string;
7
+ enginesBare?: string;
8
+ }
9
+ export interface AddonPackageJson {
10
+ name?: string;
11
+ version?: string;
12
+ addon?: boolean;
13
+ engines?: {
14
+ bare?: string;
15
+ };
16
+ }
17
+ export interface ReadAddonPackageJsonOptions {
18
+ packageJsonPath: string;
19
+ expectedName?: string;
20
+ }
21
+ export interface InvalidPackageJsonRecord {
22
+ packageJsonPath: string;
23
+ expectedName?: string;
24
+ reason: string;
25
+ }
26
+ export interface ReadAddonPackageJsonResult {
27
+ found: boolean;
28
+ isAddon: boolean;
29
+ invalid?: InvalidPackageJsonRecord;
30
+ addon?: NativeAddon;
31
+ }
32
+ export declare function readAddonPackageJson(options: ReadAddonPackageJsonOptions): Promise<ReadAddonPackageJsonResult>;
33
+ export interface CollectDiagnostics {
34
+ invalidPackageJsons: InvalidPackageJsonRecord[];
35
+ emptyResolutions: boolean;
36
+ }
37
+ export declare function createCollectDiagnostics(): CollectDiagnostics;
38
+ export declare function formatAddonId(addon: {
39
+ name: string;
40
+ version?: string;
41
+ }): string;
42
+ export declare function deduplicateAddons(addons: NativeAddon[]): NativeAddon[];
43
+ //# sourceMappingURL=addon-source.d.ts.map
@@ -0,0 +1,75 @@
1
+ import { promises as fsp } from "node:fs";
2
+ import path from "node:path";
3
+ export async function readAddonPackageJson(options) {
4
+ const { packageJsonPath, expectedName } = options;
5
+ let raw;
6
+ try {
7
+ raw = await fsp.readFile(packageJsonPath, "utf8");
8
+ }
9
+ catch {
10
+ return { found: false, isAddon: false };
11
+ }
12
+ let parsed;
13
+ try {
14
+ parsed = JSON.parse(raw);
15
+ }
16
+ catch (error) {
17
+ const reason = error instanceof Error ? error.message : String(error);
18
+ return {
19
+ found: true,
20
+ isAddon: false,
21
+ invalid: buildInvalid(packageJsonPath, expectedName, `malformed JSON: ${reason}`),
22
+ };
23
+ }
24
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
25
+ return {
26
+ found: true,
27
+ isAddon: false,
28
+ invalid: buildInvalid(packageJsonPath, expectedName, "package.json is not a JSON object"),
29
+ };
30
+ }
31
+ const pkg = parsed;
32
+ if (pkg.addon !== true) {
33
+ return { found: true, isAddon: false };
34
+ }
35
+ const name = pkg.name ?? expectedName;
36
+ if (!name) {
37
+ return {
38
+ found: true,
39
+ isAddon: false,
40
+ invalid: buildInvalid(packageJsonPath, expectedName, "addon package.json is missing a `name` field"),
41
+ };
42
+ }
43
+ const addon = {
44
+ name,
45
+ packageJsonPath,
46
+ packageRoot: path.dirname(packageJsonPath),
47
+ };
48
+ if (typeof pkg.version === "string")
49
+ addon.version = pkg.version;
50
+ if (typeof pkg.engines?.bare === "string")
51
+ addon.enginesBare = pkg.engines.bare;
52
+ return { found: true, isAddon: true, addon };
53
+ }
54
+ function buildInvalid(packageJsonPath, expectedName, reason) {
55
+ const record = { packageJsonPath, reason };
56
+ if (expectedName !== undefined)
57
+ record.expectedName = expectedName;
58
+ return record;
59
+ }
60
+ export function createCollectDiagnostics() {
61
+ return { invalidPackageJsons: [], emptyResolutions: false };
62
+ }
63
+ export function formatAddonId(addon) {
64
+ return `${addon.name}@${addon.version ?? "unknown"}`;
65
+ }
66
+ export function deduplicateAddons(addons) {
67
+ const byKey = new Map();
68
+ for (const addon of addons) {
69
+ const key = `${addon.name}@${addon.version ?? "unknown"}::${addon.packageRoot}`;
70
+ if (!byKey.has(key))
71
+ byKey.set(key, addon);
72
+ }
73
+ return [...byKey.values()].sort((a, b) => formatAddonId(a).localeCompare(formatAddonId(b)) ||
74
+ a.packageRoot.localeCompare(b.packageRoot));
75
+ }
@@ -0,0 +1,12 @@
1
+ import { type CollectDiagnostics, type NativeAddon } from "./addon-source";
2
+ export declare class InvalidBundleSourceError extends Error {
3
+ bundlePath: string;
4
+ constructor(bundlePath: string, cause: unknown);
5
+ }
6
+ export interface CollectAddonsFromBundleOptions {
7
+ bundlePath: string;
8
+ projectRoot: string;
9
+ diagnostics?: CollectDiagnostics;
10
+ }
11
+ export declare function collectAddonsFromBundle(options: CollectAddonsFromBundleOptions): Promise<NativeAddon[]>;
12
+ //# sourceMappingURL=bundle-source.d.ts.map
@@ -0,0 +1,53 @@
1
+ import { promises as fsp } from "node:fs";
2
+ import { buildNestedPathIndex, extractBarePackHeader, extractPackedString, } from "../bundle/manifest.js";
3
+ import { deduplicateAddons, readAddonPackageJson, } from "./addon-source.js";
4
+ export class InvalidBundleSourceError extends Error {
5
+ bundlePath;
6
+ constructor(bundlePath, cause) {
7
+ const reason = cause instanceof Error ? cause.message : String(cause);
8
+ super(`Bundle at ${bundlePath} could not be parsed as a bare-pack bundle.\n\n` +
9
+ ` Reason: ${reason}\n\n` +
10
+ " Make sure the path points to a worker.bundle.js generated by bundleSdk.");
11
+ this.name = "InvalidBundleSourceError";
12
+ this.bundlePath = bundlePath;
13
+ }
14
+ }
15
+ export async function collectAddonsFromBundle(options) {
16
+ const { bundlePath, projectRoot, diagnostics } = options;
17
+ let bundleText;
18
+ try {
19
+ bundleText = await fsp.readFile(bundlePath, "utf8");
20
+ }
21
+ catch (error) {
22
+ throw new InvalidBundleSourceError(bundlePath, error);
23
+ }
24
+ let resolutions;
25
+ try {
26
+ const packed = extractPackedString(bundleText);
27
+ const header = extractBarePackHeader(packed);
28
+ resolutions = header.resolutions ?? {};
29
+ }
30
+ catch (error) {
31
+ throw new InvalidBundleSourceError(bundlePath, error);
32
+ }
33
+ if (diagnostics !== undefined && Object.keys(resolutions).length === 0) {
34
+ diagnostics.emptyResolutions = true;
35
+ }
36
+ const pathsByPackage = buildNestedPathIndex(resolutions, projectRoot);
37
+ const addons = [];
38
+ for (const [pkgName, candidates] of pathsByPackage) {
39
+ for (const candidate of candidates) {
40
+ const result = await readAddonPackageJson({
41
+ packageJsonPath: candidate,
42
+ expectedName: pkgName,
43
+ });
44
+ if (result.isAddon && result.addon) {
45
+ addons.push(result.addon);
46
+ }
47
+ else if (result.invalid !== undefined && diagnostics !== undefined) {
48
+ diagnostics.invalidPackageJsons.push(result.invalid);
49
+ }
50
+ }
51
+ }
52
+ return deduplicateAddons(addons);
53
+ }
@@ -0,0 +1,59 @@
1
+ import { type AddonSourceKind, type NativeAddon } from "./addon-source";
2
+ import { type MissingPrebuildIssue } from "./prebuilds";
3
+ import { type AbiIssue, type BareRuntimeResolution } from "./abi";
4
+ export interface VerifyBundleOptions {
5
+ projectRoot: string;
6
+ addonsSource: string;
7
+ hosts: string[];
8
+ bareRuntimeVersion?: string;
9
+ configPath?: string;
10
+ }
11
+ export interface InvalidSourceIssue {
12
+ code: 'invalid-source';
13
+ level: 'error';
14
+ message: string;
15
+ addonsSource: string;
16
+ }
17
+ export interface InvalidRuntimeVersionIssue {
18
+ code: 'invalid-runtime-version';
19
+ level: 'error';
20
+ message: string;
21
+ providedValue: string;
22
+ source: 'flag' | 'config';
23
+ }
24
+ export interface ConfigLoadFailedIssue {
25
+ code: 'config-load-failed';
26
+ level: 'warning';
27
+ message: string;
28
+ configPath: string;
29
+ reason: string;
30
+ }
31
+ export interface InvalidPackageJsonIssue {
32
+ code: 'invalid-package-json';
33
+ level: 'warning';
34
+ message: string;
35
+ packageJsonPath: string;
36
+ expectedName?: string;
37
+ reason: string;
38
+ }
39
+ export interface EmptyBundleResolutionsIssue {
40
+ code: 'empty-bundle-resolutions';
41
+ level: 'warning';
42
+ message: string;
43
+ bundlePath: string;
44
+ }
45
+ export type VerifyBundleIssue = MissingPrebuildIssue | AbiIssue | InvalidSourceIssue | InvalidRuntimeVersionIssue | ConfigLoadFailedIssue | InvalidPackageJsonIssue | EmptyBundleResolutionsIssue;
46
+ export interface VerifyBundleResult {
47
+ addonsSource: string;
48
+ resolvedAddonsSource: string;
49
+ sourceKind: AddonSourceKind | null;
50
+ hosts: string[];
51
+ runtime: BareRuntimeResolution | null;
52
+ addons: NativeAddon[];
53
+ issues: VerifyBundleIssue[];
54
+ }
55
+ export declare function verifyBundle(options: VerifyBundleOptions): Promise<VerifyBundleResult>;
56
+ export declare function hasErrors(result: VerifyBundleResult): boolean;
57
+ export declare function hasWarnings(result: VerifyBundleResult): boolean;
58
+ export declare function formatVerifyBundleResult(result: VerifyBundleResult): string;
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,371 @@
1
+ import { promises as fsp } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { resolveConfigFileInProject, loadConfigFromPath, } from "../../client/config-loader/resolve-config.node.js";
4
+ import { createCollectDiagnostics, formatAddonId, } from "./addon-source.js";
5
+ import { collectAddonsFromBundle, InvalidBundleSourceError, } from "./bundle-source.js";
6
+ import { collectAddonsFromNodeModules, InvalidNodeModulesSourceError, } from "./node-modules-source.js";
7
+ import { checkPrebuilds, } from "./prebuilds.js";
8
+ import { checkAbi, formatConfigLabel, normalizeVersion, resolveBareRuntime, } from "./abi.js";
9
+ export async function verifyBundle(options) {
10
+ const { projectRoot, addonsSource, hosts, bareRuntimeVersion, configPath } = options;
11
+ const resolvedAddonsSource = path.isAbsolute(addonsSource)
12
+ ? addonsSource
13
+ : path.resolve(projectRoot, addonsSource);
14
+ if (hosts.length === 0) {
15
+ return {
16
+ addonsSource,
17
+ resolvedAddonsSource,
18
+ sourceKind: null,
19
+ hosts,
20
+ runtime: null,
21
+ addons: [],
22
+ issues: [
23
+ {
24
+ code: 'invalid-source',
25
+ level: 'error',
26
+ addonsSource,
27
+ message: 'At least one host is required.'
28
+ }
29
+ ]
30
+ };
31
+ }
32
+ let invalidRuntimeVersion = null;
33
+ if (bareRuntimeVersion !== undefined && normalizeVersion(bareRuntimeVersion) === null) {
34
+ invalidRuntimeVersion = {
35
+ code: 'invalid-runtime-version',
36
+ level: 'error',
37
+ providedValue: bareRuntimeVersion,
38
+ source: 'flag',
39
+ message: `bareRuntimeVersion "${bareRuntimeVersion}" is not a valid semver. ` +
40
+ 'Use a version like 1.15.0 (with optional v-prefix and pre-release tag) or omit it to use auto-detection.'
41
+ };
42
+ }
43
+ let configRuntimeVersion;
44
+ let resolvedConfigPath = null;
45
+ let configLoadFailed = null;
46
+ try {
47
+ resolvedConfigPath = await resolveConfigFileInProject(projectRoot, configPath ?? undefined);
48
+ if (resolvedConfigPath !== null) {
49
+ const config = await loadConfigFromPath(resolvedConfigPath);
50
+ if (typeof config.bareRuntimeVersion === "string") {
51
+ configRuntimeVersion = config.bareRuntimeVersion;
52
+ }
53
+ }
54
+ }
55
+ catch (error) {
56
+ const message = error instanceof Error ? error.message : String(error);
57
+ if (configPath !== undefined) {
58
+ return {
59
+ addonsSource,
60
+ resolvedAddonsSource,
61
+ sourceKind: null,
62
+ hosts,
63
+ runtime: null,
64
+ addons: [],
65
+ issues: [
66
+ {
67
+ code: 'invalid-source',
68
+ level: 'error',
69
+ addonsSource,
70
+ message: `Failed to load config from '${configPath}': ${message}`
71
+ }
72
+ ]
73
+ };
74
+ }
75
+ if (resolvedConfigPath !== null) {
76
+ configLoadFailed = {
77
+ code: 'config-load-failed',
78
+ level: 'warning',
79
+ configPath: resolvedConfigPath,
80
+ reason: message,
81
+ message: `Found ${formatConfigLabel(projectRoot, resolvedConfigPath)} but failed to load it: ${message}. ` +
82
+ 'Falling back to auto-detection for Bare runtime; the project-pinned ' +
83
+ '`bareRuntimeVersion` is being ignored. Fix the config file or pass `configPath` explicitly to surface it as an error.'
84
+ };
85
+ }
86
+ }
87
+ if (invalidRuntimeVersion === null &&
88
+ bareRuntimeVersion === undefined &&
89
+ configRuntimeVersion !== undefined &&
90
+ normalizeVersion(configRuntimeVersion) === null) {
91
+ invalidRuntimeVersion = {
92
+ code: 'invalid-runtime-version',
93
+ level: 'error',
94
+ providedValue: configRuntimeVersion,
95
+ source: 'config',
96
+ message: `\`bareRuntimeVersion\` in ${formatConfigLabel(projectRoot, resolvedConfigPath ?? undefined)} ` +
97
+ `"${configRuntimeVersion}" is not a valid semver. ` +
98
+ 'Use a version like 1.15.0 (with optional v-prefix and pre-release tag), or remove the field to use auto-detection.'
99
+ };
100
+ }
101
+ const sourceKind = await detectSourceKind(resolvedAddonsSource);
102
+ if (sourceKind === null) {
103
+ return {
104
+ addonsSource,
105
+ resolvedAddonsSource,
106
+ sourceKind: null,
107
+ hosts,
108
+ runtime: null,
109
+ addons: [],
110
+ issues: [
111
+ {
112
+ code: 'invalid-source',
113
+ level: 'error',
114
+ addonsSource,
115
+ message: `--addons-source ${addonsSource} is not a readable file or directory ` +
116
+ `(resolved to ${resolvedAddonsSource}).`
117
+ }
118
+ ]
119
+ };
120
+ }
121
+ const diagnostics = createCollectDiagnostics();
122
+ let addons;
123
+ try {
124
+ addons = sourceKind === 'bare-pack-bundle'
125
+ ? await collectAddonsFromBundle({
126
+ bundlePath: resolvedAddonsSource,
127
+ projectRoot,
128
+ diagnostics
129
+ })
130
+ : await collectAddonsFromNodeModules({
131
+ nodeModulesRoot: resolvedAddonsSource,
132
+ diagnostics
133
+ });
134
+ }
135
+ catch (error) {
136
+ if (error instanceof InvalidBundleSourceError ||
137
+ error instanceof InvalidNodeModulesSourceError) {
138
+ return {
139
+ addonsSource,
140
+ resolvedAddonsSource,
141
+ sourceKind,
142
+ hosts,
143
+ runtime: null,
144
+ addons: [],
145
+ issues: [
146
+ {
147
+ code: 'invalid-source',
148
+ level: 'error',
149
+ addonsSource,
150
+ message: error.message
151
+ }
152
+ ]
153
+ };
154
+ }
155
+ throw error;
156
+ }
157
+ const issues = [];
158
+ if (configLoadFailed !== null)
159
+ issues.push(configLoadFailed);
160
+ if (invalidRuntimeVersion !== null)
161
+ issues.push(invalidRuntimeVersion);
162
+ issues.push(...buildInvalidPackageJsonIssues(diagnostics.invalidPackageJsons));
163
+ if (sourceKind === 'bare-pack-bundle' && diagnostics.emptyResolutions) {
164
+ issues.push({
165
+ code: 'empty-bundle-resolutions',
166
+ level: 'warning',
167
+ bundlePath: resolvedAddonsSource,
168
+ message: `Bundle at ${resolvedAddonsSource} has no resolutions in its bare-pack header ` +
169
+ '(0 packages discoverable). The verifier cannot inspect any addons in this bundle; ' +
170
+ '`Native addon verification passed` would be vacuous. Regenerate the bundle via ' +
171
+ '`qvac bundle sdk` and re-run, or check for a corrupted/empty bundle file.'
172
+ });
173
+ }
174
+ for (const addon of addons) {
175
+ const prebuildIssues = await checkPrebuilds({ addon, hosts });
176
+ issues.push(...prebuildIssues);
177
+ }
178
+ let runtime = null;
179
+ if (invalidRuntimeVersion === null) {
180
+ const runtimeOptions = { projectRoot };
181
+ if (bareRuntimeVersion !== undefined) {
182
+ runtimeOptions.explicitVersion = bareRuntimeVersion;
183
+ runtimeOptions.explicitSource = 'flag';
184
+ }
185
+ else if (configRuntimeVersion !== undefined) {
186
+ runtimeOptions.explicitVersion = configRuntimeVersion;
187
+ runtimeOptions.explicitSource = 'config';
188
+ }
189
+ runtime = await resolveBareRuntime(runtimeOptions);
190
+ issues.push(...checkAbi({ addons, runtime }));
191
+ }
192
+ return {
193
+ addonsSource,
194
+ resolvedAddonsSource,
195
+ sourceKind,
196
+ hosts,
197
+ runtime,
198
+ addons,
199
+ issues
200
+ };
201
+ }
202
+ function buildInvalidPackageJsonIssues(records) {
203
+ return records.map((record) => {
204
+ const issue = {
205
+ code: 'invalid-package-json',
206
+ level: 'warning',
207
+ packageJsonPath: record.packageJsonPath,
208
+ reason: record.reason,
209
+ message: `Skipping ${record.expectedName ?? record.packageJsonPath}: ` +
210
+ `${record.reason}. The package is being treated as a non-addon; if it ships ` +
211
+ 'native code, the verifier cannot check its prebuilds or ABI. ' +
212
+ 'Fix the package.json or remove the package.'
213
+ };
214
+ if (record.expectedName !== undefined)
215
+ issue.expectedName = record.expectedName;
216
+ return issue;
217
+ });
218
+ }
219
+ async function detectSourceKind(resolvedAddonsSource) {
220
+ try {
221
+ const stat = await fsp.stat(resolvedAddonsSource);
222
+ if (stat.isFile())
223
+ return 'bare-pack-bundle';
224
+ if (stat.isDirectory())
225
+ return 'node-modules';
226
+ return null;
227
+ }
228
+ catch {
229
+ return null;
230
+ }
231
+ }
232
+ export function hasErrors(result) {
233
+ return result.issues.some((issue) => issue.level === 'error');
234
+ }
235
+ export function hasWarnings(result) {
236
+ return result.issues.some((issue) => issue.level === 'warning');
237
+ }
238
+ export function formatVerifyBundleResult(result) {
239
+ const sections = [];
240
+ const hostList = result.hosts.join(', ');
241
+ if (result.issues.length === 0) {
242
+ sections.push(`Native addon verification passed for ${result.addons.length} ` +
243
+ `addon${result.addons.length === 1 ? '' : 's'} across ${result.hosts.length} ` +
244
+ `host${result.hosts.length === 1 ? '' : 's'}: ${hostList}`);
245
+ if (result.addons.length > 0) {
246
+ sections.push('');
247
+ sections.push(' Verified addons:');
248
+ for (const addon of result.addons) {
249
+ sections.push(` - ${formatAddonId(addon)}`);
250
+ }
251
+ }
252
+ return sections.join('\n');
253
+ }
254
+ if (hasErrors(result)) {
255
+ sections.push('Native addon verification failed:');
256
+ }
257
+ else {
258
+ sections.push('Native addon verification produced warnings:');
259
+ }
260
+ sections.push('');
261
+ sections.push(...formatMissingPrebuilds(result.issues));
262
+ sections.push(...formatAbiMismatches(result.issues));
263
+ sections.push(...formatInvalidRuntimeVersions(result.issues));
264
+ sections.push(...formatMalformedEnginesBare(result.issues));
265
+ sections.push(...formatConfigLoadFailed(result.issues));
266
+ sections.push(...formatInvalidPackageJsons(result.issues));
267
+ sections.push(...formatEmptyBundleResolutions(result.issues));
268
+ sections.push(...formatUnknownRuntime(result.issues));
269
+ sections.push(...formatInvalidSources(result.issues));
270
+ return sections.join('\n').trimEnd();
271
+ }
272
+ function formatConfigLoadFailed(issues) {
273
+ const matches = issues.filter((issue) => issue.code === 'config-load-failed');
274
+ if (matches.length === 0)
275
+ return [];
276
+ const lines = [' Config load failed:'];
277
+ for (const issue of matches) {
278
+ lines.push(` - ${issue.message}`);
279
+ }
280
+ lines.push('');
281
+ return lines;
282
+ }
283
+ function formatMissingPrebuilds(issues) {
284
+ const matches = issues.filter((issue) => issue.code === 'missing-prebuild');
285
+ if (matches.length === 0)
286
+ return [];
287
+ const lines = [' Missing prebuild:'];
288
+ for (const issue of matches) {
289
+ lines.push(` - ${issue.addon} for ${issue.host}`);
290
+ }
291
+ lines.push('');
292
+ return lines;
293
+ }
294
+ function formatAbiMismatches(issues) {
295
+ const matches = issues.filter((issue) => issue.code === 'abi-mismatch');
296
+ if (matches.length === 0)
297
+ return [];
298
+ const lines = [' ABI mismatch:'];
299
+ for (const issue of matches) {
300
+ lines.push(` - ${issue.addon} requires bare ${issue.enginesBare}, ` +
301
+ `runtime is ${issue.runtimeVersion}`);
302
+ }
303
+ lines.push('');
304
+ return lines;
305
+ }
306
+ function formatUnknownRuntime(issues) {
307
+ const matches = issues.filter((issue) => issue.code === 'unknown-runtime-version');
308
+ if (matches.length === 0)
309
+ return [];
310
+ const lines = [' Unknown runtime version:'];
311
+ for (const issue of matches) {
312
+ lines.push(` - ${issue.message}`);
313
+ }
314
+ lines.push('');
315
+ return lines;
316
+ }
317
+ function formatMalformedEnginesBare(issues) {
318
+ const matches = issues.filter((issue) => issue.code === 'malformed-engines-bare');
319
+ if (matches.length === 0)
320
+ return [];
321
+ const lines = [' Malformed engines.bare:'];
322
+ for (const issue of matches) {
323
+ lines.push(` - ${issue.message}`);
324
+ }
325
+ lines.push('');
326
+ return lines;
327
+ }
328
+ function formatInvalidSources(issues) {
329
+ const matches = issues.filter((issue) => issue.code === 'invalid-source');
330
+ if (matches.length === 0)
331
+ return [];
332
+ const lines = [' Invalid source:'];
333
+ for (const issue of matches) {
334
+ lines.push(` - ${issue.message}`);
335
+ }
336
+ lines.push('');
337
+ return lines;
338
+ }
339
+ function formatInvalidRuntimeVersions(issues) {
340
+ const matches = issues.filter((issue) => issue.code === 'invalid-runtime-version');
341
+ if (matches.length === 0)
342
+ return [];
343
+ const lines = [' Invalid Bare runtime version:'];
344
+ for (const issue of matches) {
345
+ lines.push(` - ${issue.message}`);
346
+ }
347
+ lines.push('');
348
+ return lines;
349
+ }
350
+ function formatInvalidPackageJsons(issues) {
351
+ const matches = issues.filter((issue) => issue.code === 'invalid-package-json');
352
+ if (matches.length === 0)
353
+ return [];
354
+ const lines = [' Invalid package.json (skipped):'];
355
+ for (const issue of matches) {
356
+ lines.push(` - ${issue.message}`);
357
+ }
358
+ lines.push('');
359
+ return lines;
360
+ }
361
+ function formatEmptyBundleResolutions(issues) {
362
+ const matches = issues.filter((issue) => issue.code === 'empty-bundle-resolutions');
363
+ if (matches.length === 0)
364
+ return [];
365
+ const lines = [' Empty bundle resolutions:'];
366
+ for (const issue of matches) {
367
+ lines.push(` - ${issue.message}`);
368
+ }
369
+ lines.push('');
370
+ return lines;
371
+ }
@@ -0,0 +1,11 @@
1
+ import { type CollectDiagnostics, type NativeAddon } from "./addon-source";
2
+ export declare class InvalidNodeModulesSourceError extends Error {
3
+ nodeModulesPath: string;
4
+ constructor(nodeModulesPath: string, cause: unknown);
5
+ }
6
+ export interface CollectAddonsFromNodeModulesOptions {
7
+ nodeModulesRoot: string;
8
+ diagnostics?: CollectDiagnostics;
9
+ }
10
+ export declare function collectAddonsFromNodeModules(options: CollectAddonsFromNodeModulesOptions): Promise<NativeAddon[]>;
11
+ //# sourceMappingURL=node-modules-source.d.ts.map