@tsonic/cli 0.0.63 → 0.0.64

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 (82) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/aikya/bindings.d.ts +44 -0
  3. package/dist/aikya/bindings.d.ts.map +1 -0
  4. package/dist/aikya/bindings.js +777 -0
  5. package/dist/aikya/bindings.js.map +1 -0
  6. package/dist/aikya/bindings.test.d.ts +2 -0
  7. package/dist/aikya/bindings.test.d.ts.map +1 -0
  8. package/dist/aikya/bindings.test.js +554 -0
  9. package/dist/aikya/bindings.test.js.map +1 -0
  10. package/dist/cli/dispatcher.d.ts.map +1 -1
  11. package/dist/cli/dispatcher.js +15 -0
  12. package/dist/cli/dispatcher.js.map +1 -1
  13. package/dist/cli/help.d.ts.map +1 -1
  14. package/dist/cli/help.js +4 -1
  15. package/dist/cli/help.js.map +1 -1
  16. package/dist/cli/parser.d.ts.map +1 -1
  17. package/dist/cli/parser.js +6 -0
  18. package/dist/cli/parser.js.map +1 -1
  19. package/dist/cli/parser.test.js +10 -0
  20. package/dist/cli/parser.test.js.map +1 -1
  21. package/dist/commands/add-npm.d.ts +3 -2
  22. package/dist/commands/add-npm.d.ts.map +1 -1
  23. package/dist/commands/add-npm.js +69 -177
  24. package/dist/commands/add-npm.js.map +1 -1
  25. package/dist/commands/add-npm.test.js +276 -2
  26. package/dist/commands/add-npm.test.js.map +1 -1
  27. package/dist/commands/build-library-bindings-aliases.test.js +349 -4
  28. package/dist/commands/build-library-bindings-aliases.test.js.map +1 -1
  29. package/dist/commands/build.d.ts.map +1 -1
  30. package/dist/commands/build.js +168 -148
  31. package/dist/commands/build.js.map +1 -1
  32. package/dist/commands/build.test.js +22 -3
  33. package/dist/commands/build.test.js.map +1 -1
  34. package/dist/commands/generate.d.ts.map +1 -1
  35. package/dist/commands/generate.js +5 -0
  36. package/dist/commands/generate.js.map +1 -1
  37. package/dist/commands/init.d.ts +5 -2
  38. package/dist/commands/init.d.ts.map +1 -1
  39. package/dist/commands/init.js +42 -7
  40. package/dist/commands/init.js.map +1 -1
  41. package/dist/commands/init.test.js +82 -2
  42. package/dist/commands/init.test.js.map +1 -1
  43. package/dist/commands/library-bindings-augment.d.ts.map +1 -1
  44. package/dist/commands/library-bindings-augment.js +376 -53
  45. package/dist/commands/library-bindings-augment.js.map +1 -1
  46. package/dist/commands/library-bindings-augment.test.js +460 -2
  47. package/dist/commands/library-bindings-augment.test.js.map +1 -1
  48. package/dist/commands/library-bindings-firstparty-regressions.test.d.ts +2 -0
  49. package/dist/commands/library-bindings-firstparty-regressions.test.d.ts.map +1 -0
  50. package/dist/commands/library-bindings-firstparty-regressions.test.js +217 -0
  51. package/dist/commands/library-bindings-firstparty-regressions.test.js.map +1 -0
  52. package/dist/commands/library-bindings-firstparty.d.ts +3 -0
  53. package/dist/commands/library-bindings-firstparty.d.ts.map +1 -0
  54. package/dist/commands/library-bindings-firstparty.js +2250 -0
  55. package/dist/commands/library-bindings-firstparty.js.map +1 -0
  56. package/dist/commands/restore.d.ts.map +1 -1
  57. package/dist/commands/restore.js +3 -1
  58. package/dist/commands/restore.js.map +1 -1
  59. package/dist/commands/restore.test.js +29 -0
  60. package/dist/commands/restore.test.js.map +1 -1
  61. package/dist/commands/run-build-regressions.test.js +72 -0
  62. package/dist/commands/run-build-regressions.test.js.map +1 -1
  63. package/dist/config.d.ts.map +1 -1
  64. package/dist/config.js +16 -2
  65. package/dist/config.js.map +1 -1
  66. package/dist/config.test.js +57 -0
  67. package/dist/config.test.js.map +1 -1
  68. package/dist/dotnet/runtime-dlls.d.ts +1 -0
  69. package/dist/dotnet/runtime-dlls.d.ts.map +1 -1
  70. package/dist/dotnet/runtime-dlls.js +1 -0
  71. package/dist/dotnet/runtime-dlls.js.map +1 -1
  72. package/dist/surface/profiles.d.ts +10 -0
  73. package/dist/surface/profiles.d.ts.map +1 -0
  74. package/dist/surface/profiles.js +61 -0
  75. package/dist/surface/profiles.js.map +1 -0
  76. package/dist/surface/profiles.test.d.ts +2 -0
  77. package/dist/surface/profiles.test.d.ts.map +1 -0
  78. package/dist/surface/profiles.test.js +49 -0
  79. package/dist/surface/profiles.test.js.map +1 -0
  80. package/dist/types.d.ts +10 -0
  81. package/dist/types.d.ts.map +1 -1
  82. package/package.json +4 -4
@@ -0,0 +1,777 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import { dirname, join } from "node:path";
4
+ import { resolvePackageRoot } from "../commands/add-common.js";
5
+ const AIKYA_DIAGNOSTIC = {
6
+ invalidSchema: "TSN8A01",
7
+ unresolvedRuntime: "TSN8A02",
8
+ conflictingRuntime: "TSN8A03",
9
+ missingBindingsRoot: "TSN8A04",
10
+ missingRuntimeMapping: "TSN8A05",
11
+ };
12
+ const normalizeId = (id) => id.trim().toLowerCase();
13
+ const errorWithCode = (code, message) => {
14
+ return { ok: false, error: `${code}: ${message}` };
15
+ };
16
+ const isSurfaceMode = (value) => value === "clr" || value === "js" || value === "nodejs";
17
+ const readJsonObject = (path, parseErrorCode) => {
18
+ try {
19
+ const parsed = JSON.parse(readFileSync(path, "utf-8"));
20
+ if (parsed === null ||
21
+ typeof parsed !== "object" ||
22
+ Array.isArray(parsed)) {
23
+ return errorWithCode(parseErrorCode, `Expected JSON object at ${path}`);
24
+ }
25
+ return { ok: true, value: parsed };
26
+ }
27
+ catch (error) {
28
+ return errorWithCode(parseErrorCode, `Failed to parse JSON at ${path}: ${error instanceof Error ? error.message : String(error)}`);
29
+ }
30
+ };
31
+ const parseFrameworkReference = (value, path) => {
32
+ if (typeof value === "string" && value.trim().length > 0) {
33
+ return { ok: true, value: value.trim() };
34
+ }
35
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
36
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `${path} must be a string or { id, types? }`);
37
+ }
38
+ const id = value.id;
39
+ const types = value.types;
40
+ if (typeof id !== "string" || id.trim().length === 0) {
41
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `${path}.id must be a non-empty string`);
42
+ }
43
+ if (types !== undefined &&
44
+ types !== false &&
45
+ (typeof types !== "string" || types.trim().length === 0)) {
46
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `${path}.types must be a non-empty string or false`);
47
+ }
48
+ return {
49
+ ok: true,
50
+ value: types === undefined ? { id: id.trim() } : { id: id.trim(), types },
51
+ };
52
+ };
53
+ const parsePackageReference = (value, path) => {
54
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
55
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `${path} must be { id, version, types? }`);
56
+ }
57
+ const id = value.id;
58
+ const version = value.version;
59
+ const types = value.types;
60
+ if (typeof id !== "string" || id.trim().length === 0) {
61
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `${path}.id must be a non-empty string`);
62
+ }
63
+ if (typeof version !== "string" || version.trim().length === 0) {
64
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `${path}.version must be a non-empty string`);
65
+ }
66
+ if (types !== undefined &&
67
+ types !== false &&
68
+ (typeof types !== "string" || types.trim().length === 0)) {
69
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `${path}.types must be a non-empty string or false`);
70
+ }
71
+ return {
72
+ ok: true,
73
+ value: {
74
+ id: id.trim(),
75
+ version: version.trim(),
76
+ ...(types === undefined ? {} : { types }),
77
+ },
78
+ };
79
+ };
80
+ const parseManifestDotnet = (value, path) => {
81
+ if (value === undefined)
82
+ return { ok: true, value: undefined };
83
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
84
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `${path} must be an object`);
85
+ }
86
+ const raw = value;
87
+ let frameworkReferences;
88
+ if (raw.frameworkReferences !== undefined) {
89
+ if (!Array.isArray(raw.frameworkReferences)) {
90
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `${path}.frameworkReferences must be an array`);
91
+ }
92
+ frameworkReferences = [];
93
+ for (const [index, entry] of raw.frameworkReferences.entries()) {
94
+ const parsed = parseFrameworkReference(entry, `${path}.frameworkReferences[${index}]`);
95
+ if (!parsed.ok)
96
+ return parsed;
97
+ frameworkReferences.push(parsed.value);
98
+ }
99
+ }
100
+ let packageReferences;
101
+ if (raw.packageReferences !== undefined) {
102
+ if (!Array.isArray(raw.packageReferences)) {
103
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `${path}.packageReferences must be an array`);
104
+ }
105
+ packageReferences = [];
106
+ for (const [index, entry] of raw.packageReferences.entries()) {
107
+ const parsed = parsePackageReference(entry, `${path}.packageReferences[${index}]`);
108
+ if (!parsed.ok)
109
+ return parsed;
110
+ packageReferences.push(parsed.value);
111
+ }
112
+ }
113
+ let msbuildProperties;
114
+ if (raw.msbuildProperties !== undefined) {
115
+ if (raw.msbuildProperties === null ||
116
+ typeof raw.msbuildProperties !== "object" ||
117
+ Array.isArray(raw.msbuildProperties)) {
118
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `${path}.msbuildProperties must be an object`);
119
+ }
120
+ msbuildProperties = {};
121
+ for (const [key, value] of Object.entries(raw.msbuildProperties)) {
122
+ if (typeof value !== "string") {
123
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `${path}.msbuildProperties.${key} must be a string`);
124
+ }
125
+ msbuildProperties[key] = value;
126
+ }
127
+ }
128
+ const hasFramework = (frameworkReferences?.length ?? 0) > 0;
129
+ const hasPackage = (packageReferences?.length ?? 0) > 0;
130
+ const hasMsbuild = Object.keys(msbuildProperties ?? {}).length > 0;
131
+ if (!hasFramework && !hasPackage && !hasMsbuild) {
132
+ return { ok: true, value: undefined };
133
+ }
134
+ return {
135
+ ok: true,
136
+ value: {
137
+ frameworkReferences,
138
+ packageReferences,
139
+ msbuildProperties,
140
+ },
141
+ };
142
+ };
143
+ const sortFrameworkReferences = (refs) => [...refs].sort((a, b) => {
144
+ const idA = typeof a === "string" ? a : a.id;
145
+ const idB = typeof b === "string" ? b : b.id;
146
+ return normalizeId(idA).localeCompare(normalizeId(idB));
147
+ });
148
+ const sortPackageReferences = (refs) => [...refs].sort((a, b) => {
149
+ const byId = normalizeId(a.id).localeCompare(normalizeId(b.id));
150
+ if (byId !== 0)
151
+ return byId;
152
+ return a.version.localeCompare(b.version);
153
+ });
154
+ const sortMsbuildProperties = (props) => {
155
+ const out = {};
156
+ const keys = Object.keys(props).sort((a, b) => a.localeCompare(b));
157
+ for (const key of keys) {
158
+ const value = props[key];
159
+ if (value !== undefined)
160
+ out[key] = value;
161
+ }
162
+ return out;
163
+ };
164
+ const canonicalizeManifestDotnet = (dotnet) => {
165
+ if (!dotnet)
166
+ return undefined;
167
+ const frameworkReferences = sortFrameworkReferences((dotnet.frameworkReferences ?? []));
168
+ const packageReferences = sortPackageReferences((dotnet.packageReferences ?? []));
169
+ const msbuildProperties = sortMsbuildProperties((dotnet.msbuildProperties ?? {}));
170
+ const hasMsbuild = Object.keys(msbuildProperties).length > 0;
171
+ const hasFramework = frameworkReferences.length > 0;
172
+ const hasPackage = packageReferences.length > 0;
173
+ if (!hasMsbuild && !hasFramework && !hasPackage) {
174
+ return undefined;
175
+ }
176
+ return {
177
+ frameworkReferences: hasFramework ? frameworkReferences : undefined,
178
+ packageReferences: hasPackage ? packageReferences : undefined,
179
+ msbuildProperties: hasMsbuild ? msbuildProperties : undefined,
180
+ };
181
+ };
182
+ export const mergeFrameworkReferences = (existing, incoming, conflictCode = undefined) => {
183
+ const out = [...existing];
184
+ const byId = new Map();
185
+ for (const ref of out) {
186
+ const id = typeof ref === "string" ? ref : ref.id;
187
+ byId.set(normalizeId(id), ref);
188
+ }
189
+ for (const ref of incoming) {
190
+ const id = typeof ref === "string" ? ref : ref.id;
191
+ const key = normalizeId(id);
192
+ const current = byId.get(key);
193
+ if (!current) {
194
+ out.push(ref);
195
+ byId.set(key, ref);
196
+ continue;
197
+ }
198
+ const currentTypes = typeof current === "string" ? undefined : current.types;
199
+ const nextTypes = typeof ref === "string" ? undefined : ref.types;
200
+ if (nextTypes !== undefined &&
201
+ currentTypes !== undefined &&
202
+ currentTypes !== nextTypes) {
203
+ const msg = `Conflicting framework types mapping for '${id}'.\n` +
204
+ `Existing: ${String(currentTypes)}\n` +
205
+ `Incoming: ${String(nextTypes)}\n` +
206
+ `Refusing to merge automatically (airplane-grade).`;
207
+ return conflictCode
208
+ ? errorWithCode(conflictCode, msg)
209
+ : { ok: false, error: msg };
210
+ }
211
+ if (typeof current === "string" && typeof ref !== "string") {
212
+ const idx = out.findIndex((x) => normalizeId(typeof x === "string" ? x : x.id) === normalizeId(current));
213
+ if (idx >= 0)
214
+ out[idx] = { id: current, types: ref.types };
215
+ byId.set(key, out[idx]);
216
+ }
217
+ }
218
+ return { ok: true, value: sortFrameworkReferences(out) };
219
+ };
220
+ export const mergePackageReferences = (existing, incoming, conflictCode = undefined) => {
221
+ const out = [...existing];
222
+ const byId = new Map();
223
+ for (const p of out)
224
+ byId.set(normalizeId(p.id), p);
225
+ for (const p of incoming) {
226
+ const key = normalizeId(p.id);
227
+ const current = byId.get(key);
228
+ if (!current) {
229
+ out.push(p);
230
+ byId.set(key, p);
231
+ continue;
232
+ }
233
+ if (current.version !== p.version) {
234
+ const msg = `NuGet package already present with a different version: ${current.id} ${current.version}\n` +
235
+ `Incoming requested: ${p.id} ${p.version}\n` +
236
+ `Refusing to merge automatically (airplane-grade).`;
237
+ return conflictCode
238
+ ? errorWithCode(conflictCode, msg)
239
+ : { ok: false, error: msg };
240
+ }
241
+ if (p.types !== undefined &&
242
+ current.types !== undefined &&
243
+ current.types !== p.types) {
244
+ const msg = `NuGet package already present with a different types mapping:\n` +
245
+ `- ${current.id} ${current.version}\n` +
246
+ `- existing: ${String(current.types)}\n` +
247
+ `- incoming: ${String(p.types)}\n` +
248
+ `Refusing to merge automatically (airplane-grade).`;
249
+ return conflictCode
250
+ ? errorWithCode(conflictCode, msg)
251
+ : { ok: false, error: msg };
252
+ }
253
+ if (current.types === undefined && p.types !== undefined) {
254
+ const idx = out.findIndex((x) => normalizeId(x.id) === key);
255
+ if (idx >= 0)
256
+ out[idx] = { ...current, types: p.types };
257
+ byId.set(key, out[idx]);
258
+ }
259
+ }
260
+ return { ok: true, value: sortPackageReferences(out) };
261
+ };
262
+ export const mergeMsbuildProperties = (existing, incoming, conflictCode = undefined) => {
263
+ const out = { ...existing };
264
+ for (const [k, v] of Object.entries(incoming)) {
265
+ const current = out[k];
266
+ if (current !== undefined && current !== v) {
267
+ const msg = `Conflicting msbuildProperties for key '${k}'.\n` +
268
+ `Existing: ${current}\n` +
269
+ `Incoming: ${v}\n` +
270
+ `Refusing to merge automatically (airplane-grade).`;
271
+ return conflictCode
272
+ ? errorWithCode(conflictCode, msg)
273
+ : { ok: false, error: msg };
274
+ }
275
+ out[k] = v;
276
+ }
277
+ return { ok: true, value: sortMsbuildProperties(out) };
278
+ };
279
+ const collectNugetDependencies = (dotnet, testDotnet) => {
280
+ const dependencies = [];
281
+ const addFrameworkRefs = (refs, source) => {
282
+ for (const ref of refs ?? []) {
283
+ const id = typeof ref === "string" ? ref : ref.id;
284
+ dependencies.push({ source, id });
285
+ }
286
+ };
287
+ const addPackageRefs = (refs, source) => {
288
+ for (const ref of refs ?? []) {
289
+ dependencies.push({ source, id: ref.id, version: ref.version });
290
+ }
291
+ };
292
+ addFrameworkRefs(dotnet?.frameworkReferences, "dotnet.framework");
293
+ addPackageRefs(dotnet?.packageReferences, "dotnet.package");
294
+ addFrameworkRefs(testDotnet?.frameworkReferences, "testDotnet.framework");
295
+ addPackageRefs(testDotnet?.packageReferences, "testDotnet.package");
296
+ return dependencies.sort((a, b) => {
297
+ const bySource = a.source.localeCompare(b.source);
298
+ if (bySource !== 0)
299
+ return bySource;
300
+ const byId = normalizeId(a.id).localeCompare(normalizeId(b.id));
301
+ if (byId !== 0)
302
+ return byId;
303
+ return (a.version ?? "").localeCompare(b.version ?? "");
304
+ });
305
+ };
306
+ const collectRuntimePackagesFromLegacy = (packageName, runtimePackages, dotnet, testDotnet) => {
307
+ const set = new Set();
308
+ set.add(packageName);
309
+ for (const pkg of runtimePackages ?? []) {
310
+ if (pkg.trim())
311
+ set.add(pkg.trim());
312
+ }
313
+ const collectTypesPackage = (refs) => {
314
+ for (const ref of refs) {
315
+ if (typeof ref === "string")
316
+ continue;
317
+ if (typeof ref.types === "string" && ref.types.trim())
318
+ set.add(ref.types.trim());
319
+ }
320
+ };
321
+ collectTypesPackage((dotnet?.frameworkReferences ?? []));
322
+ collectTypesPackage((dotnet?.packageReferences ?? []));
323
+ collectTypesPackage((testDotnet?.frameworkReferences ??
324
+ []));
325
+ collectTypesPackage((testDotnet?.packageReferences ?? []));
326
+ return [...set].sort((a, b) => normalizeId(a).localeCompare(normalizeId(b)));
327
+ };
328
+ const parseAikyaProducer = (value) => {
329
+ if (value === undefined)
330
+ return { ok: true, value: undefined };
331
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
332
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, "producer must be an object");
333
+ }
334
+ const tool = value.tool;
335
+ const version = value.version;
336
+ const mode = value.mode;
337
+ if (tool !== "tsonic" && tool !== "tsbindgen") {
338
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `producer.tool must be "tsonic" or "tsbindgen"`);
339
+ }
340
+ if (typeof version !== "string" || version.trim().length === 0) {
341
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, "producer.version must be a non-empty string");
342
+ }
343
+ if (mode !== "aikya-firstparty" && mode !== "external-clr") {
344
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `producer.mode must be "aikya-firstparty" or "external-clr"`);
345
+ }
346
+ return {
347
+ ok: true,
348
+ value: {
349
+ tool,
350
+ version: version.trim(),
351
+ mode,
352
+ },
353
+ };
354
+ };
355
+ const parseRuntimeNugetPackages = (value) => {
356
+ if (!Array.isArray(value) || value.length === 0) {
357
+ return errorWithCode(AIKYA_DIAGNOSTIC.missingRuntimeMapping, "runtime.nugetPackages must be a non-empty array");
358
+ }
359
+ const out = [];
360
+ for (const [index, entry] of value.entries()) {
361
+ if (entry === null || typeof entry !== "object" || Array.isArray(entry)) {
362
+ return errorWithCode(AIKYA_DIAGNOSTIC.unresolvedRuntime, `runtime.nugetPackages[${index}] must be { id, version }`);
363
+ }
364
+ const id = entry.id;
365
+ const version = entry.version;
366
+ if (typeof id !== "string" || id.trim().length === 0) {
367
+ return errorWithCode(AIKYA_DIAGNOSTIC.unresolvedRuntime, `runtime.nugetPackages[${index}].id must be a non-empty string`);
368
+ }
369
+ if (typeof version !== "string" || version.trim().length === 0) {
370
+ return errorWithCode(AIKYA_DIAGNOSTIC.unresolvedRuntime, `runtime.nugetPackages[${index}].version must be a non-empty string`);
371
+ }
372
+ out.push({ id: id.trim(), version: version.trim() });
373
+ }
374
+ return { ok: true, value: out };
375
+ };
376
+ const parseRuntimeFrameworkReferences = (value) => {
377
+ if (value === undefined)
378
+ return { ok: true, value: [] };
379
+ if (!Array.isArray(value)) {
380
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, "runtime.frameworkReferences must be an array when present");
381
+ }
382
+ const refs = [];
383
+ for (const [index, entry] of value.entries()) {
384
+ const parsed = parseFrameworkReference(entry, `runtime.frameworkReferences[${index}]`);
385
+ if (!parsed.ok)
386
+ return parsed;
387
+ refs.push(parsed.value);
388
+ }
389
+ return { ok: true, value: refs };
390
+ };
391
+ const parseRuntimePackages = (value) => {
392
+ if (!Array.isArray(value))
393
+ return [];
394
+ return value
395
+ .filter((x) => typeof x === "string")
396
+ .map((x) => x.trim())
397
+ .filter((x) => x.length > 0)
398
+ .sort((a, b) => normalizeId(a).localeCompare(normalizeId(b)));
399
+ };
400
+ const resolveFromAikyaManifest = (packageRoot, packageName, packageVersion) => {
401
+ const path = join(packageRoot, "tsonic", "package-manifest.json");
402
+ if (!existsSync(path))
403
+ return { ok: true, value: null };
404
+ const parsed = readJsonObject(path, AIKYA_DIAGNOSTIC.invalidSchema);
405
+ if (!parsed.ok)
406
+ return parsed;
407
+ const manifest = parsed.value;
408
+ const schemaVersion = manifest.schemaVersion;
409
+ if (schemaVersion !== 1) {
410
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `schemaVersion must be 1 at ${path}`);
411
+ }
412
+ const kind = manifest.kind;
413
+ if (kind !== "tsonic-library") {
414
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `kind must be "tsonic-library" at ${path}`);
415
+ }
416
+ const npmPackage = manifest.npmPackage;
417
+ if (typeof npmPackage !== "string" || npmPackage.trim().length === 0) {
418
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `npmPackage must be a non-empty string at ${path}`);
419
+ }
420
+ if (normalizeId(npmPackage) !== normalizeId(packageName)) {
421
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `npmPackage mismatch in ${path}. Installed: ${packageName}, Manifest: ${npmPackage}`);
422
+ }
423
+ const npmVersion = manifest.npmVersion;
424
+ if (typeof npmVersion !== "string" || npmVersion.trim().length === 0) {
425
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `npmVersion must be a non-empty string at ${path}`);
426
+ }
427
+ if (npmVersion.trim() !== packageVersion) {
428
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `npmVersion mismatch in ${path}. Installed: ${packageVersion}, Manifest: ${npmVersion}`);
429
+ }
430
+ const typing = manifest.typing;
431
+ if (typing === null || typeof typing !== "object" || Array.isArray(typing)) {
432
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `typing must be an object at ${path}`);
433
+ }
434
+ const bindingsRoot = typing
435
+ .bindingsRoot;
436
+ if (typeof bindingsRoot !== "string" || bindingsRoot.trim().length === 0) {
437
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `typing.bindingsRoot must be a non-empty string at ${path}`);
438
+ }
439
+ const bindingsRootPath = join(packageRoot, bindingsRoot);
440
+ if (!existsSync(bindingsRootPath)) {
441
+ return errorWithCode(AIKYA_DIAGNOSTIC.missingBindingsRoot, `typing.bindingsRoot does not exist: ${bindingsRootPath}`);
442
+ }
443
+ const runtime = manifest.runtime;
444
+ if (runtime === null ||
445
+ typeof runtime !== "object" ||
446
+ Array.isArray(runtime)) {
447
+ return errorWithCode(AIKYA_DIAGNOSTIC.missingRuntimeMapping, `runtime must be an object at ${path}`);
448
+ }
449
+ const runtimeNuget = parseRuntimeNugetPackages(runtime.nugetPackages);
450
+ if (!runtimeNuget.ok)
451
+ return runtimeNuget;
452
+ const runtimeFramework = parseRuntimeFrameworkReferences(runtime.frameworkReferences);
453
+ if (!runtimeFramework.ok)
454
+ return runtimeFramework;
455
+ const runtimePackages = parseRuntimePackages(runtime.runtimePackages);
456
+ const producer = parseAikyaProducer(manifest.producer);
457
+ if (!producer.ok)
458
+ return producer;
459
+ const dotnetParsed = parseManifestDotnet(manifest.dotnet, "dotnet");
460
+ if (!dotnetParsed.ok)
461
+ return dotnetParsed;
462
+ const testDotnetParsed = parseManifestDotnet(manifest.testDotnet, "testDotnet");
463
+ if (!testDotnetParsed.ok)
464
+ return testDotnetParsed;
465
+ const mergedDotnetPackages = mergePackageReferences((dotnetParsed.value?.packageReferences ?? []), runtimeNuget.value, AIKYA_DIAGNOSTIC.conflictingRuntime);
466
+ if (!mergedDotnetPackages.ok)
467
+ return mergedDotnetPackages;
468
+ const mergedDotnetFramework = mergeFrameworkReferences((dotnetParsed.value?.frameworkReferences ??
469
+ []), runtimeFramework.value, AIKYA_DIAGNOSTIC.conflictingRuntime);
470
+ if (!mergedDotnetFramework.ok)
471
+ return mergedDotnetFramework;
472
+ const dotnet = canonicalizeManifestDotnet({
473
+ frameworkReferences: mergedDotnetFramework.value,
474
+ packageReferences: mergedDotnetPackages.value,
475
+ msbuildProperties: dotnetParsed.value?.msbuildProperties,
476
+ });
477
+ const testDotnet = canonicalizeManifestDotnet(testDotnetParsed.value);
478
+ const runtimeSet = new Set();
479
+ runtimeSet.add(packageName);
480
+ for (const pkg of runtimePackages)
481
+ runtimeSet.add(pkg);
482
+ return {
483
+ ok: true,
484
+ value: {
485
+ bindingVersion: 1,
486
+ sourceManifest: "aikya",
487
+ packageName,
488
+ packageVersion,
489
+ surfaceMode: "clr",
490
+ bindingsRoot,
491
+ runtimePackages: [...runtimeSet].sort((a, b) => normalizeId(a).localeCompare(normalizeId(b))),
492
+ producer: producer.value,
493
+ dotnet,
494
+ testDotnet,
495
+ nugetDependencies: collectNugetDependencies(dotnet, testDotnet),
496
+ },
497
+ };
498
+ };
499
+ const resolveFromLegacyBindingsManifest = (packageRoot, packageName, packageVersion) => {
500
+ const manifestPath = join(packageRoot, "tsonic.bindings.json");
501
+ if (!existsSync(manifestPath))
502
+ return { ok: true, value: null };
503
+ const parsed = readJsonObject(manifestPath, AIKYA_DIAGNOSTIC.invalidSchema);
504
+ if (!parsed.ok)
505
+ return parsed;
506
+ const manifest = parsed.value;
507
+ const bindingVersion = manifest.bindingVersion;
508
+ if (bindingVersion !== undefined && bindingVersion !== 1) {
509
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `Unsupported tsonic.bindings.json bindingVersion: ${String(bindingVersion)}`);
510
+ }
511
+ const manifestPackageName = manifest.packageName;
512
+ if (manifestPackageName !== undefined) {
513
+ if (typeof manifestPackageName !== "string" ||
514
+ normalizeId(manifestPackageName) !== normalizeId(packageName)) {
515
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `tsonic.bindings.json packageName mismatch. Installed: ${packageName}, Manifest: ${String(manifestPackageName)}`);
516
+ }
517
+ }
518
+ const manifestPackageVersion = manifest.packageVersion;
519
+ if (manifestPackageVersion !== undefined) {
520
+ if (typeof manifestPackageVersion !== "string" ||
521
+ manifestPackageVersion !== packageVersion) {
522
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `tsonic.bindings.json packageVersion mismatch. Installed: ${packageVersion}, Manifest: ${String(manifestPackageVersion)}`);
523
+ }
524
+ }
525
+ const surfaceModeRaw = manifest.surfaceMode;
526
+ if (surfaceModeRaw !== undefined && !isSurfaceMode(surfaceModeRaw)) {
527
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `Invalid tsonic.bindings.json surfaceMode: ${String(surfaceModeRaw)}`);
528
+ }
529
+ const surfaceMode = surfaceModeRaw ?? "clr";
530
+ const dotnetParsed = parseManifestDotnet(manifest.dotnet, "dotnet");
531
+ if (!dotnetParsed.ok)
532
+ return dotnetParsed;
533
+ const testDotnetParsed = parseManifestDotnet(manifest.testDotnet, "testDotnet");
534
+ if (!testDotnetParsed.ok)
535
+ return testDotnetParsed;
536
+ const dotnet = canonicalizeManifestDotnet(dotnetParsed.value);
537
+ const testDotnet = canonicalizeManifestDotnet(testDotnetParsed.value);
538
+ const runtimePackages = Array.isArray(manifest.runtimePackages)
539
+ ? manifest.runtimePackages.filter((x) => typeof x === "string")
540
+ : undefined;
541
+ return {
542
+ ok: true,
543
+ value: {
544
+ bindingVersion: 1,
545
+ sourceManifest: "legacy",
546
+ packageName,
547
+ packageVersion,
548
+ surfaceMode,
549
+ assemblyName: typeof manifest.assemblyName === "string"
550
+ ? manifest.assemblyName
551
+ : undefined,
552
+ assemblyVersion: typeof manifest.assemblyVersion === "string"
553
+ ? manifest.assemblyVersion
554
+ : undefined,
555
+ targetFramework: typeof manifest.targetFramework === "string"
556
+ ? manifest.targetFramework
557
+ : undefined,
558
+ runtimePackages: collectRuntimePackagesFromLegacy(packageName, runtimePackages, dotnet, testDotnet),
559
+ dotnet,
560
+ testDotnet,
561
+ nugetDependencies: collectNugetDependencies(dotnet, testDotnet),
562
+ },
563
+ };
564
+ };
565
+ const readInstalledPackageInfo = (packageRoot) => {
566
+ const packageJsonPath = join(packageRoot, "package.json");
567
+ if (!existsSync(packageJsonPath)) {
568
+ return {
569
+ ok: false,
570
+ error: `package.json not found for installed npm package: ${packageRoot}`,
571
+ };
572
+ }
573
+ const parsed = readJsonObject(packageJsonPath, AIKYA_DIAGNOSTIC.invalidSchema);
574
+ if (!parsed.ok)
575
+ return parsed;
576
+ const name = parsed.value.name;
577
+ const version = parsed.value.version;
578
+ if (typeof name !== "string" || name.trim().length === 0) {
579
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `Invalid package.json (missing name): ${packageJsonPath}`);
580
+ }
581
+ if (typeof version !== "string" || version.trim().length === 0) {
582
+ return errorWithCode(AIKYA_DIAGNOSTIC.invalidSchema, `Invalid package.json (missing version): ${packageJsonPath}`);
583
+ }
584
+ return { ok: true, value: { name: name.trim(), version: version.trim() } };
585
+ };
586
+ export const resolveInstalledPackageBindingsManifest = (packageRoot) => {
587
+ const info = readInstalledPackageInfo(packageRoot);
588
+ if (!info.ok)
589
+ return info;
590
+ const aikya = resolveFromAikyaManifest(packageRoot, info.value.name, info.value.version);
591
+ if (!aikya.ok)
592
+ return aikya;
593
+ if (aikya.value)
594
+ return aikya;
595
+ return resolveFromLegacyBindingsManifest(packageRoot, info.value.name, info.value.version);
596
+ };
597
+ const collectDependencyNames = (value) => {
598
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
599
+ return [];
600
+ }
601
+ return Object.keys(value);
602
+ };
603
+ const listWorkspaceDependencyNames = (workspaceRoot) => {
604
+ const packageJsonPath = join(workspaceRoot, "package.json");
605
+ if (!existsSync(packageJsonPath)) {
606
+ return { ok: true, value: [] };
607
+ }
608
+ const parsed = readJsonObject(packageJsonPath, AIKYA_DIAGNOSTIC.invalidSchema);
609
+ if (!parsed.ok)
610
+ return parsed;
611
+ const dependencies = parsed.value.dependencies;
612
+ const devDependencies = parsed.value.devDependencies;
613
+ const optionalDependencies = parsed.value.optionalDependencies;
614
+ const names = new Set();
615
+ for (const name of collectDependencyNames(dependencies))
616
+ names.add(name);
617
+ for (const name of collectDependencyNames(devDependencies))
618
+ names.add(name);
619
+ for (const name of collectDependencyNames(optionalDependencies))
620
+ names.add(name);
621
+ return {
622
+ ok: true,
623
+ value: [...names].sort((a, b) => normalizeId(a).localeCompare(normalizeId(b))),
624
+ };
625
+ };
626
+ const resolveInstalledPackageRootFrom = (fromDir, dependencyName) => {
627
+ try {
628
+ const req = createRequire(join(fromDir, "package.json"));
629
+ const packageJsonPath = req.resolve(`${dependencyName}/package.json`);
630
+ return dirname(packageJsonPath);
631
+ }
632
+ catch {
633
+ return null;
634
+ }
635
+ };
636
+ const readInstalledPackageDependencyNames = (packageRoot) => {
637
+ const packageJsonPath = join(packageRoot, "package.json");
638
+ const parsed = readJsonObject(packageJsonPath, AIKYA_DIAGNOSTIC.invalidSchema);
639
+ if (!parsed.ok)
640
+ return parsed;
641
+ const dependencies = parsed.value.dependencies;
642
+ const optionalDependencies = parsed.value.optionalDependencies;
643
+ const peerDependencies = parsed.value.peerDependencies;
644
+ const names = new Set();
645
+ for (const name of collectDependencyNames(dependencies))
646
+ names.add(name);
647
+ for (const name of collectDependencyNames(optionalDependencies))
648
+ names.add(name);
649
+ for (const name of collectDependencyNames(peerDependencies))
650
+ names.add(name);
651
+ return {
652
+ ok: true,
653
+ value: [...names].sort((a, b) => normalizeId(a).localeCompare(normalizeId(b))),
654
+ };
655
+ };
656
+ export const discoverWorkspaceBindingsManifests = (workspaceRoot) => {
657
+ const rootDeps = listWorkspaceDependencyNames(workspaceRoot);
658
+ if (!rootDeps.ok)
659
+ return rootDeps;
660
+ const queue = rootDeps.value.map((dependencyName) => ({
661
+ dependencyName,
662
+ fromDir: workspaceRoot,
663
+ rootDependency: true,
664
+ }));
665
+ const seenPackageRoots = new Set();
666
+ const out = [];
667
+ while (queue.length > 0) {
668
+ const current = queue.shift();
669
+ if (!current)
670
+ break;
671
+ let resolvedRoot = null;
672
+ let rootResolutionError;
673
+ if (current.fromDir === workspaceRoot) {
674
+ const rootResolved = resolvePackageRoot(workspaceRoot, current.dependencyName);
675
+ if (rootResolved.ok) {
676
+ resolvedRoot = rootResolved.value;
677
+ }
678
+ else {
679
+ rootResolutionError = rootResolved.error;
680
+ }
681
+ }
682
+ else {
683
+ resolvedRoot = resolveInstalledPackageRootFrom(current.fromDir, current.dependencyName);
684
+ }
685
+ if (!resolvedRoot) {
686
+ if (current.rootDependency) {
687
+ return errorWithCode(AIKYA_DIAGNOSTIC.unresolvedRuntime, `Unable to resolve workspace dependency '${current.dependencyName}' from node_modules.` +
688
+ (rootResolutionError ? `\n${rootResolutionError}` : ""));
689
+ }
690
+ continue;
691
+ }
692
+ const packageRoot = resolvedRoot;
693
+ if (seenPackageRoots.has(packageRoot))
694
+ continue;
695
+ seenPackageRoots.add(packageRoot);
696
+ const manifest = resolveInstalledPackageBindingsManifest(packageRoot);
697
+ if (!manifest.ok)
698
+ return manifest;
699
+ if (manifest.value)
700
+ out.push(manifest.value);
701
+ const childDeps = readInstalledPackageDependencyNames(packageRoot);
702
+ if (!childDeps.ok)
703
+ return childDeps;
704
+ for (const childName of childDeps.value) {
705
+ queue.push({
706
+ dependencyName: childName,
707
+ fromDir: packageRoot,
708
+ rootDependency: false,
709
+ });
710
+ }
711
+ }
712
+ return {
713
+ ok: true,
714
+ value: out.sort((a, b) => normalizeId(a.packageName).localeCompare(normalizeId(b.packageName))),
715
+ };
716
+ };
717
+ export const mergeManifestIntoWorkspaceConfig = (config, manifest, conflictCode = undefined) => {
718
+ const dotnet = config.dotnet ?? {};
719
+ const testDotnet = config.testDotnet ?? {};
720
+ const mergedFramework = mergeFrameworkReferences((dotnet.frameworkReferences ?? []), (manifest.dotnet?.frameworkReferences ?? []), conflictCode);
721
+ if (!mergedFramework.ok)
722
+ return mergedFramework;
723
+ const mergedPackages = mergePackageReferences((dotnet.packageReferences ?? []), (manifest.dotnet?.packageReferences ?? []), conflictCode);
724
+ if (!mergedPackages.ok)
725
+ return mergedPackages;
726
+ const mergedMsbuild = mergeMsbuildProperties((dotnet.msbuildProperties ?? {}), (manifest.dotnet?.msbuildProperties ?? {}), conflictCode);
727
+ if (!mergedMsbuild.ok)
728
+ return mergedMsbuild;
729
+ const mergedTestFramework = mergeFrameworkReferences((testDotnet.frameworkReferences ?? []), (manifest.testDotnet?.frameworkReferences ??
730
+ []), conflictCode);
731
+ if (!mergedTestFramework.ok)
732
+ return mergedTestFramework;
733
+ const mergedTestPackages = mergePackageReferences((testDotnet.packageReferences ?? []), (manifest.testDotnet?.packageReferences ?? []), conflictCode);
734
+ if (!mergedTestPackages.ok)
735
+ return mergedTestPackages;
736
+ const mergedTestMsbuild = mergeMsbuildProperties((testDotnet.msbuildProperties ?? {}), (manifest.testDotnet?.msbuildProperties ?? {}), conflictCode);
737
+ if (!mergedTestMsbuild.ok)
738
+ return mergedTestMsbuild;
739
+ return {
740
+ ok: true,
741
+ value: {
742
+ ...config,
743
+ dotnet: {
744
+ ...dotnet,
745
+ frameworkReferences: mergedFramework.value,
746
+ packageReferences: mergedPackages.value,
747
+ msbuildProperties: Object.keys(mergedMsbuild.value).length > 0
748
+ ? mergedMsbuild.value
749
+ : undefined,
750
+ },
751
+ testDotnet: manifest.testDotnet
752
+ ? {
753
+ ...testDotnet,
754
+ frameworkReferences: mergedTestFramework.value,
755
+ packageReferences: mergedTestPackages.value,
756
+ msbuildProperties: Object.keys(mergedTestMsbuild.value).length > 0
757
+ ? mergedTestMsbuild.value
758
+ : undefined,
759
+ }
760
+ : config.testDotnet,
761
+ },
762
+ };
763
+ };
764
+ export const applyAikyaWorkspaceOverlay = (workspaceRoot, config) => {
765
+ const manifests = discoverWorkspaceBindingsManifests(workspaceRoot);
766
+ if (!manifests.ok)
767
+ return manifests;
768
+ let current = config;
769
+ for (const manifest of manifests.value) {
770
+ const merged = mergeManifestIntoWorkspaceConfig(current, manifest, AIKYA_DIAGNOSTIC.conflictingRuntime);
771
+ if (!merged.ok)
772
+ return merged;
773
+ current = merged.value;
774
+ }
775
+ return { ok: true, value: { config: current, manifests: manifests.value } };
776
+ };
777
+ //# sourceMappingURL=bindings.js.map