@azure-tools/typespec-metadata 0.1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Microsoft Corporation. All rights reserved.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # @azure-tools/typespec-metadata
2
+
3
+ TypeSpec emitter that produces structured metadata snapshots for APIView and other tooling.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install @azure-tools/typespec-metadata
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Add the emitter to your TypeSpec project:
14
+
15
+ ```bash
16
+ tsp compile . --emit @azure-tools/typespec-metadata
17
+ ```
18
+
19
+ Or configure it in your `tspconfig.yaml`:
20
+
21
+ ```yaml
22
+ emit:
23
+ - "@azure-tools/typespec-metadata"
24
+ ```
25
+
26
+ ### Options
27
+
28
+ The emitter supports the following options:
29
+
30
+ - `output-file`: Output filename (default: `typespec-metadata.yaml` for YAML, `typespec-metadata.json` for JSON)
31
+ - `format`: Output format - either `"yaml"` or `"json"` (default: `"yaml"`)
32
+
33
+ Example (YAML output):
34
+
35
+ ```yaml
36
+ emit:
37
+ - "@azure-tools/typespec-metadata"
38
+ options:
39
+ "@azure-tools/typespec-metadata":
40
+ output-file: "api-metadata.yaml"
41
+ format: "yaml"
42
+ ```
43
+
44
+ Example (JSON output):
45
+
46
+ ```yaml
47
+ emit:
48
+ - "@azure-tools/typespec-metadata"
49
+ options:
50
+ "@azure-tools/typespec-metadata":
51
+ output-file: "api-metadata.json"
52
+ format: "json"
53
+ ```
54
+
55
+ ## Output
56
+
57
+ The emitter generates structured metadata in YAML or JSON format. This metadata is used by tools like APIView for API review and comparison.
58
+
59
+ Here is an example using KeyVault Keys:
60
+
61
+ ```yaml
62
+ emitterVersion: 0.1.0
63
+ generatedAt: 2026-01-15T23:14:08.554Z
64
+ typespec:
65
+ namespace: KeyVault
66
+ documentation: The key vault client performs cryptographic key operations and vault operations against the Key Vault service.
67
+ type: data
68
+ languages:
69
+ python:
70
+ emitterName: "@azure-tools/typespec-python"
71
+ packageName: azure-keyvault-keys
72
+ namespace: azure.keyvault.keys
73
+ outputDir: "{output-dir}/sdk/keyvault/azure-keyvault-keys"
74
+ flavor: azure
75
+ serviceDir: sdk/keyvault
76
+ java:
77
+ emitterName: "@azure-tools/typespec-java"
78
+ packageName: azure-security-keyvault-keys
79
+ namespace: com.azure.security.keyvault.keys
80
+ outputDir: "{output-dir}/sdk/keyvault/azure-security-keyvault-keys"
81
+ flavor: azure
82
+ serviceDir: sdk/keyvault
83
+ typescript:
84
+ emitterName: "@azure-tools/typespec-ts"
85
+ packageName: "@azure/keyvault-keys"
86
+ namespace: "@azure/keyvault-keys"
87
+ outputDir: "{output-dir}/sdk/keyvault/keyvault-keys"
88
+ flavor: azure
89
+ serviceDir: sdk/keyvault
90
+ go:
91
+ emitterName: "@azure-tools/typespec-go"
92
+ packageName: sdk/security/keyvault/azkeys
93
+ namespace: sdk/security/keyvault/azkeys
94
+ outputDir: "{output-dir}/sdk/security/keyvault/azkeys"
95
+ serviceDir: sdk/security/keyvault
96
+ rust:
97
+ emitterName: "@azure-tools/typespec-rust"
98
+ packageName: azure_security_keyvault_keys
99
+ namespace: azure_security_keyvault_keys
100
+ outputDir: "{output-dir}/sdk/keyvault/azure_security_keyvault_keys"
101
+ serviceDir: sdk/keyvault
102
+ sourceConfigPath: C:/repos/azure-rest-api-specs/specification/keyvault/Security.KeyVault.Keys/tspconfig.yaml
103
+ ```
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@azure-tools/typespec-metadata",
3
+ "version": "0.1.0",
4
+ "description": "TypeSpec emitter that produces structured metadata snapshots for APIView and other tooling.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Microsoft Corporation",
8
+ "keywords": [
9
+ "typespec",
10
+ "emitter",
11
+ "metadata",
12
+ "apiview"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/Azure/typespec-azure.git"
17
+ },
18
+ "bugs": {
19
+ "url": "https://github.com/Azure/typespec-azure/issues"
20
+ },
21
+ "engines": {
22
+ "node": ">=20.0.0"
23
+ },
24
+ "main": "dist/src/index.js",
25
+ "types": "dist/src/index.d.ts",
26
+ "files": [
27
+ "dist/**",
28
+ "!dist/test/**"
29
+ ],
30
+ "exports": {
31
+ ".": {
32
+ "import": "./dist/src/index.js"
33
+ }
34
+ },
35
+ "scripts": {
36
+ "build": "tsc -p .",
37
+ "watch": "tsc -p . --watch",
38
+ "clean": "rimraf ./dist ./temp",
39
+ "lint": "eslint . --max-warnings=0",
40
+ "lint:fix": "eslint . --fix ",
41
+ "test": "vitest run",
42
+ "test:watch": "vitest -w",
43
+ "test:ui": "vitest --ui",
44
+ "test:ci": "vitest run --coverage --reporter=junit --reporter=default"
45
+ },
46
+ "dependencies": {
47
+ "yaml": "~2.8.2"
48
+ },
49
+ "peerDependencies": {
50
+ "@typespec/compiler": "workspace:^"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "~25.0.2",
54
+ "@typespec/compiler": "workspace:^",
55
+ "@vitest/coverage-v8": "^4.0.15",
56
+ "@vitest/ui": "^4.0.15",
57
+ "c8": "^10.1.3",
58
+ "rimraf": "~6.1.2",
59
+ "typescript": "~5.9.2",
60
+ "vitest": "^4.0.15"
61
+ }
62
+ }
@@ -0,0 +1,9 @@
1
+ import { type Program } from "@typespec/compiler";
2
+ import { LanguagePackageMetadata, TypeSpecMetadata } from "./metadata.js";
3
+ export interface LanguageCollectionResult {
4
+ languages: Record<string, LanguagePackageMetadata>;
5
+ sourceConfigPath?: string;
6
+ }
7
+ export declare function collectLanguagePackages(program: Program, baseOutputDir: string): Promise<LanguageCollectionResult>;
8
+ export declare function buildSpecMetadata(program: Program): TypeSpecMetadata;
9
+ //# sourceMappingURL=collector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../src/collector.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,OAAO,EACb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAwP1E,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IACnD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,wBAAwB,CAAC,CAkBnC;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,gBAAgB,CAsBpE"}
@@ -0,0 +1,435 @@
1
+ import { getDoc, getLocationContext, getNamespaceFullName, getService, normalizePath, } from "@typespec/compiler";
2
+ const PACKAGE_NAME_KEYS = ["package-name", "packageName", "package"];
3
+ const NAMESPACE_KEYS = ["namespace", "namespace-name", "namespaceName"];
4
+ /**
5
+ * Replace {var} placeholders in a string with values from the data object.
6
+ * Recursively resolves nested placeholders.
7
+ */
8
+ function fillVars(value, data) {
9
+ if (typeof value !== "string") {
10
+ return value;
11
+ }
12
+ let prev;
13
+ let current = value;
14
+ while (prev !== current) {
15
+ prev = current;
16
+ current = current.replace(/\{([^{}]+)\}/g, (match, key) => {
17
+ const replacement = data[key];
18
+ return replacement !== undefined && replacement !== null ? String(replacement) : match;
19
+ });
20
+ }
21
+ return current;
22
+ }
23
+ /**
24
+ * Extract parameters from compiler options for variable substitution.
25
+ */
26
+ function extractParameters(optionMap) {
27
+ const params = {};
28
+ // Check if parameters are defined at the root level
29
+ for (const [key, value] of Object.entries(optionMap)) {
30
+ if (key === "parameters" && typeof value === "object" && value !== null) {
31
+ for (const [paramKey, paramValue] of Object.entries(value)) {
32
+ if (typeof paramValue === "object" && paramValue !== null && "default" in paramValue) {
33
+ params[paramKey] = paramValue.default;
34
+ }
35
+ else {
36
+ params[paramKey] = paramValue;
37
+ }
38
+ }
39
+ }
40
+ }
41
+ return params;
42
+ }
43
+ const LANGUAGE_ALIASES = {
44
+ "@azure-tools/typespec-csharp": "csharp",
45
+ "@azure-tools/typespec-java": "java",
46
+ "@azure-tools/typespec-python": "python",
47
+ "@azure-tools/typespec-typescript": "typescript",
48
+ "@azure-tools/typespec-ts": "typescript",
49
+ "@azure-tools/typespec-js": "javascript",
50
+ "@azure-tools/typespec-swift": "swift",
51
+ "@azure-tools/typespec-go": "go",
52
+ "@azure-tools/typespec-rust": "rust",
53
+ };
54
+ /**
55
+ * Python-specific metadata parser.
56
+ * Handles package-name and namespace, with fallback conversion between them.
57
+ * Strips implementation-specific suffixes like ._generated from namespaces.
58
+ */
59
+ function parsePython(options, params) {
60
+ let packageName = options["package-name"] ?? options["package_name"];
61
+ let namespace = options["namespace"];
62
+ // Strip implementation-specific suffixes from namespace
63
+ if (namespace) {
64
+ namespace = String(namespace).replace(/\._generated$/, "");
65
+ }
66
+ // Fallback: derive namespace from package-name
67
+ if (packageName && !namespace) {
68
+ namespace = String(packageName).replace(/-/g, ".");
69
+ }
70
+ else if (namespace && !packageName) {
71
+ packageName = String(namespace).replace(/\./g, "-");
72
+ }
73
+ return {
74
+ packageName: packageName ? String(fillVars(packageName, params)) : undefined,
75
+ namespace: namespace ? String(fillVars(namespace, params)) : undefined,
76
+ };
77
+ }
78
+ /**
79
+ * Java-specific metadata parser.
80
+ * Strips 'com.' prefix from namespace if present for package name derivation.
81
+ */
82
+ function parseJava(options, params) {
83
+ let packageName = options["package-name"] ?? options["package_name"];
84
+ const namespace = options["namespace"];
85
+ if (namespace && !packageName) {
86
+ const ns = String(namespace);
87
+ const stripped = ns.startsWith("com.") ? ns.substring(4) : ns;
88
+ packageName = stripped.replace(/\./g, "-");
89
+ }
90
+ return {
91
+ packageName: packageName ? String(fillVars(packageName, params)) : undefined,
92
+ namespace: namespace ? String(fillVars(namespace, params)) : undefined,
93
+ };
94
+ }
95
+ /**
96
+ * C#-specific metadata parser.
97
+ * Package name and namespace are typically identical.
98
+ */
99
+ function parseCSharp(options, params) {
100
+ let packageName = options["package-name"] ?? options["package_name"];
101
+ let namespace = options["namespace"];
102
+ if (packageName && !namespace) {
103
+ namespace = packageName;
104
+ }
105
+ else if (namespace && !packageName) {
106
+ packageName = namespace;
107
+ }
108
+ return {
109
+ packageName: packageName ? String(fillVars(packageName, params)) : undefined,
110
+ namespace: namespace ? String(fillVars(namespace, params)) : undefined,
111
+ };
112
+ }
113
+ /**
114
+ * TypeScript-specific metadata parser.
115
+ * Extracts from package-details if available.
116
+ */
117
+ function parseTypeScript(options, params) {
118
+ const packageDetails = options["package-details"];
119
+ let packageName;
120
+ let namespace;
121
+ if (packageDetails && typeof packageDetails === "object") {
122
+ const details = packageDetails;
123
+ packageName = details["name"];
124
+ namespace = details["namespace"];
125
+ }
126
+ if (packageName && !namespace) {
127
+ namespace = packageName;
128
+ }
129
+ else if (namespace && !packageName) {
130
+ packageName = namespace;
131
+ }
132
+ return {
133
+ packageName: packageName ? String(fillVars(packageName, params)) : undefined,
134
+ namespace: namespace ? String(fillVars(namespace, params)) : undefined,
135
+ };
136
+ }
137
+ /**
138
+ * Go-specific metadata parser.
139
+ * Extracts from module path, looking for azure-sdk-for-go suffix.
140
+ */
141
+ function parseGo(options, params) {
142
+ let packageName = options["package-name"] ?? options["package_name"];
143
+ let namespace = options["namespace"];
144
+ const module = options["module"];
145
+ if (module) {
146
+ const modulePath = String(fillVars(module, params));
147
+ const sdkIndex = modulePath.indexOf("azure-sdk-for-go/");
148
+ const after = sdkIndex >= 0 ? modulePath.substring(sdkIndex + "azure-sdk-for-go/".length) : modulePath;
149
+ if (!packageName) {
150
+ packageName = after;
151
+ }
152
+ if (!namespace) {
153
+ namespace = after;
154
+ }
155
+ }
156
+ return {
157
+ packageName: packageName ? String(fillVars(packageName, params)) : undefined,
158
+ namespace: namespace ? String(fillVars(namespace, params)) : undefined,
159
+ };
160
+ }
161
+ /**
162
+ * Rust-specific metadata parser.
163
+ * Uses crate-name as the primary identifier.
164
+ */
165
+ function parseRust(options, params) {
166
+ let packageName = options["crate-name"];
167
+ let namespace = options["namespace"];
168
+ if (packageName && !namespace) {
169
+ namespace = packageName;
170
+ }
171
+ else if (namespace && !packageName) {
172
+ packageName = namespace;
173
+ }
174
+ return {
175
+ packageName: packageName ? String(fillVars(packageName, params)) : undefined,
176
+ namespace: namespace ? String(fillVars(namespace, params)) : undefined,
177
+ };
178
+ }
179
+ /**
180
+ * Map of language-specific parsers.
181
+ */
182
+ const LANGUAGE_PARSERS = {
183
+ "@azure-tools/typespec-python": parsePython,
184
+ "@azure-tools/typespec-java": parseJava,
185
+ "@azure-tools/typespec-csharp": parseCSharp,
186
+ "@azure-tools/typespec-typescript": parseTypeScript,
187
+ "@azure-tools/typespec-ts": parseTypeScript,
188
+ "@azure-tools/typespec-go": parseGo,
189
+ "@azure-tools/typespec-rust": parseRust,
190
+ };
191
+ export async function collectLanguagePackages(program, baseOutputDir) {
192
+ const optionMap = program.compilerOptions.options ?? {};
193
+ const params = extractParameters(optionMap);
194
+ // Extract default service-dir from config file parameters
195
+ let defaultServiceDir;
196
+ const configFile = program.compilerOptions.configFile;
197
+ if (configFile?.parameters && "service-dir" in configFile.parameters) {
198
+ const serviceDirParam = configFile.parameters["service-dir"];
199
+ if (serviceDirParam && typeof serviceDirParam === "object" && "default" in serviceDirParam) {
200
+ defaultServiceDir = String(serviceDirParam.default);
201
+ }
202
+ }
203
+ return {
204
+ languages: buildLanguageMetadata(optionMap, params, baseOutputDir, defaultServiceDir),
205
+ sourceConfigPath: program.compilerOptions.config,
206
+ };
207
+ }
208
+ export function buildSpecMetadata(program) {
209
+ const globalNamespace = program.getGlobalNamespaceType();
210
+ // Recursively collect all service namespaces
211
+ const allServiceNamespaces = collectAllServiceNamespaces(program, globalNamespace);
212
+ // Select the primary namespace (prefer @service decorated namespaces)
213
+ const primaryNamespace = selectPrimaryNamespace(allServiceNamespaces, program) ?? globalNamespace;
214
+ const namespaceName = trimOrUndefined(getNamespaceFullName(primaryNamespace)) ?? primaryNamespace.name ?? "(global)";
215
+ const doc = trimOrUndefined(getDoc(program, primaryNamespace));
216
+ // Determine if this is data plane or management plane
217
+ // Check if namespace uses Azure.ResourceManager (management plane)
218
+ const isManagementPlane = checkIfManagementPlane(program, primaryNamespace);
219
+ return {
220
+ namespace: namespaceName,
221
+ documentation: doc,
222
+ type: isManagementPlane ? "management" : "data",
223
+ };
224
+ }
225
+ /**
226
+ * Recursively collects all service namespaces from a given namespace.
227
+ */
228
+ function collectAllServiceNamespaces(program, ns) {
229
+ const result = [];
230
+ for (const childNs of ns.namespaces.values()) {
231
+ if (isServiceNamespace(program, childNs)) {
232
+ result.push(childNs);
233
+ // Recursively collect from children
234
+ result.push(...collectAllServiceNamespaces(program, childNs));
235
+ }
236
+ }
237
+ return result;
238
+ }
239
+ /**
240
+ * Determines if a namespace is a service namespace (not a framework/standard namespace).
241
+ * Uses getLocationContext to check if the namespace was defined in the user's project.
242
+ */
243
+ function isServiceNamespace(program, ns) {
244
+ const locationContext = getLocationContext(program, ns);
245
+ // Only consider namespaces defined in the user's project as service namespaces
246
+ return locationContext.type === "project";
247
+ }
248
+ /**
249
+ * Selects the primary namespace from a list of service namespaces.
250
+ * Prefers namespaces with @service decorator, then non-helper namespaces.
251
+ */
252
+ function selectPrimaryNamespace(namespaces, program) {
253
+ if (namespaces.length === 0) {
254
+ return undefined;
255
+ }
256
+ // Names that indicate helper/customization namespaces (lower priority)
257
+ const helperNamePatterns = [
258
+ "Customizations",
259
+ "Customization",
260
+ "Internal",
261
+ "Private",
262
+ "Helpers",
263
+ "Traits",
264
+ "Common",
265
+ ];
266
+ // First priority: namespaces with @service decorator
267
+ const serviceNamespaces = namespaces.filter((ns) => {
268
+ const service = getService(program, ns);
269
+ return service !== undefined;
270
+ });
271
+ if (serviceNamespaces.length > 0) {
272
+ // If there are multiple @service namespaces, prefer non-helper ones
273
+ const nonHelperServices = serviceNamespaces.filter((ns) => {
274
+ const name = ns.name;
275
+ return !helperNamePatterns.some((pattern) => name.toLowerCase().includes(pattern.toLowerCase()));
276
+ });
277
+ return nonHelperServices.length > 0 ? nonHelperServices[0] : serviceNamespaces[0];
278
+ }
279
+ // Second priority: filter out helper namespaces
280
+ const nonHelperNamespaces = namespaces.filter((ns) => {
281
+ const name = ns.name;
282
+ return !helperNamePatterns.some((pattern) => name.toLowerCase().includes(pattern.toLowerCase()));
283
+ });
284
+ const candidateNamespaces = nonHelperNamespaces.length > 0 ? nonHelperNamespaces : namespaces;
285
+ // Among candidates, prefer the deepest namespace (most specific)
286
+ // Depth is indicated by the number of dots in the full name
287
+ let deepestNamespace = candidateNamespaces[0];
288
+ let maxDepth = getNamespaceFullName(deepestNamespace).split(".").length;
289
+ for (const ns of candidateNamespaces.slice(1)) {
290
+ const fullName = getNamespaceFullName(ns);
291
+ const depth = fullName.split(".").length;
292
+ if (depth > maxDepth) {
293
+ maxDepth = depth;
294
+ deepestNamespace = ns;
295
+ }
296
+ }
297
+ return deepestNamespace;
298
+ }
299
+ /**
300
+ * Checks if a namespace represents a management plane service.
301
+ * Management plane services typically use Azure.ResourceManager.
302
+ */
303
+ function checkIfManagementPlane(program, ns) {
304
+ // Check if the namespace or any of its imports reference Azure.ResourceManager
305
+ const globalNs = program.getGlobalNamespaceType();
306
+ // Look for Azure.ResourceManager namespace
307
+ if (globalNs.namespaces.has("Azure")) {
308
+ const azureNs = globalNs.namespaces.get("Azure");
309
+ if (azureNs?.namespaces.has("ResourceManager")) {
310
+ // If Azure.ResourceManager exists in the program, it's likely management plane
311
+ return true;
312
+ }
313
+ }
314
+ // Default to data plane
315
+ return false;
316
+ }
317
+ function buildLanguageMetadata(optionMap, params, baseOutputDir, defaultServiceDir) {
318
+ const languagesDict = {};
319
+ for (const [emitterName, emitterOptions] of Object.entries(optionMap)) {
320
+ const metadata = createLanguageMetadata(emitterName, emitterOptions ?? {}, params, baseOutputDir, defaultServiceDir);
321
+ const language = inferLanguageFromEmitterName(emitterName);
322
+ languagesDict[language] = metadata;
323
+ }
324
+ return languagesDict;
325
+ }
326
+ function createLanguageMetadata(emitterName, emitterOptions, params, baseOutputDir, defaultServiceDir) {
327
+ const normalizedOptions = normalizeOptionsObject(emitterOptions);
328
+ // Extract common options
329
+ const outputDirRaw = normalizedOptions["emitter-output-dir"] ?? normalizedOptions["emitterOutputDir"];
330
+ const flavor = normalizedOptions["flavor"];
331
+ const languageServiceDir = normalizedOptions["service-dir"];
332
+ // Use language-specific service-dir if present, otherwise use default
333
+ const serviceDir = languageServiceDir ? String(languageServiceDir) : defaultServiceDir;
334
+ // Use language-specific parser if available
335
+ let packageName;
336
+ let namespace;
337
+ const normalizedEmitterName = emitterName.toLowerCase();
338
+ const parser = LANGUAGE_PARSERS[normalizedEmitterName];
339
+ if (parser) {
340
+ const result = parser(normalizedOptions, params);
341
+ packageName = result.packageName;
342
+ namespace = result.namespace;
343
+ }
344
+ else {
345
+ // Fallback to generic extraction
346
+ packageName = extractOption(normalizedOptions, PACKAGE_NAME_KEYS);
347
+ namespace = extractOption(normalizedOptions, NAMESPACE_KEYS);
348
+ }
349
+ // Convert outputDir to use {output-dir} placeholder
350
+ let relativeOutputDir;
351
+ if (outputDirRaw) {
352
+ const absolutePath = String(outputDirRaw);
353
+ const normalizedBase = normalizePath(baseOutputDir).replace(/\/$/, "");
354
+ const normalizedPath = normalizePath(absolutePath);
355
+ // Replace the base output directory with {output-dir} placeholder
356
+ if (normalizedPath.startsWith(normalizedBase + "/")) {
357
+ const relativePart = normalizedPath.substring(normalizedBase.length + 1);
358
+ relativeOutputDir = `{output-dir}/${relativePart}`;
359
+ }
360
+ else if (normalizedPath === normalizedBase) {
361
+ relativeOutputDir = "{output-dir}";
362
+ }
363
+ else {
364
+ // If it doesn't start with base, keep as-is
365
+ relativeOutputDir = absolutePath;
366
+ }
367
+ }
368
+ return {
369
+ emitterName,
370
+ packageName,
371
+ namespace,
372
+ outputDir: relativeOutputDir,
373
+ flavor: flavor ? String(flavor) : undefined,
374
+ serviceDir,
375
+ };
376
+ }
377
+ function normalizeOptionsObject(options) {
378
+ if (!options) {
379
+ return {};
380
+ }
381
+ const normalized = {};
382
+ for (const [key, value] of Object.entries(options)) {
383
+ normalized[key] = value;
384
+ }
385
+ return normalized;
386
+ }
387
+ function extractOption(options, candidates) {
388
+ for (const [key, value] of Object.entries(options)) {
389
+ const normalizedKey = normalizeKey(key);
390
+ for (const candidate of candidates) {
391
+ if (normalizedKey === normalizeKey(candidate)) {
392
+ if (value === undefined || value === null) {
393
+ continue;
394
+ }
395
+ return String(value);
396
+ }
397
+ }
398
+ }
399
+ return undefined;
400
+ }
401
+ function normalizeKey(key) {
402
+ return key.replace(/[^a-z0-9]/gi, "").toLowerCase();
403
+ }
404
+ function inferLanguageFromEmitterName(emitterName) {
405
+ const normalized = emitterName.toLowerCase();
406
+ if (LANGUAGE_ALIASES[normalized]) {
407
+ return LANGUAGE_ALIASES[normalized];
408
+ }
409
+ const basename = normalized.split(/[\\/]/).pop() ?? normalized;
410
+ const cadlIndex = basename.lastIndexOf("cadl-");
411
+ if (cadlIndex >= 0) {
412
+ const suffix = basename.substring(cadlIndex + "cadl-".length);
413
+ if (suffix) {
414
+ return suffix;
415
+ }
416
+ }
417
+ const typespecIndex = basename.lastIndexOf("typespec-");
418
+ if (typespecIndex >= 0) {
419
+ const suffix = basename.substring(typespecIndex + "typespec-".length);
420
+ if (suffix) {
421
+ return suffix;
422
+ }
423
+ }
424
+ const lastDash = basename.lastIndexOf("-");
425
+ if (lastDash >= 0 && lastDash < basename.length - 1) {
426
+ return basename.substring(lastDash + 1);
427
+ }
428
+ const sanitized = basename.replace(/[^a-z]/g, "");
429
+ return sanitized || "unknown";
430
+ }
431
+ function trimOrUndefined(value) {
432
+ const trimmed = value?.trim();
433
+ return trimmed && trimmed.length > 0 ? trimmed : undefined;
434
+ }
435
+ //# sourceMappingURL=collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collector.js","sourceRoot":"","sources":["../../src/collector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type EmitContext } from "@typespec/compiler";
2
+ import { type MetadataEmitterOptions } from "./options.js";
3
+ export declare function $onEmit(context: EmitContext<MetadataEmitterOptions>): Promise<void>;
4
+ //# sourceMappingURL=emitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2C,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAK/F,OAAO,EAEL,KAAK,sBAAsB,EAE5B,MAAM,cAAc,CAAC;AAItB,wBAAsB,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,sBAAsB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBzF"}
@@ -0,0 +1,34 @@
1
+ import { emitFile, getDirectoryPath, resolvePath } from "@typespec/compiler";
2
+ import { stringify as stringifyYaml } from "yaml";
3
+ import packageJson from "../package.json" with { type: "json" };
4
+ import { buildSpecMetadata, collectLanguagePackages } from "./collector.js";
5
+ import { normalizeOptions, } from "./options.js";
6
+ const SNAPSHOT_VERSION = packageJson.version;
7
+ export async function $onEmit(context) {
8
+ const options = normalizeOptions(context.options);
9
+ const typespecMetadata = buildSpecMetadata(context.program);
10
+ // Get the common tsp-output directory (parent of this emitter's output dir)
11
+ const commonOutputDir = getDirectoryPath(getDirectoryPath(context.emitterOutputDir));
12
+ const languageResult = await collectLanguagePackages(context.program, commonOutputDir);
13
+ const snapshot = {
14
+ emitterVersion: SNAPSHOT_VERSION,
15
+ generatedAt: new Date().toISOString(),
16
+ typespec: typespecMetadata,
17
+ languages: languageResult.languages,
18
+ sourceConfigPath: languageResult.sourceConfigPath,
19
+ };
20
+ await writeSnapshot(context, options, snapshot);
21
+ }
22
+ async function writeSnapshot(context, options, snapshot) {
23
+ const serialized = options.format === "json"
24
+ ? JSON.stringify(snapshot, null, 2) + "\n"
25
+ : stringifyYaml(snapshot, {
26
+ lineWidth: 0,
27
+ });
28
+ const outputPath = resolvePath(context.emitterOutputDir, options.outputFile);
29
+ await emitFile(context.program, {
30
+ path: outputPath,
31
+ content: serialized,
32
+ });
33
+ }
34
+ //# sourceMappingURL=emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emitter.js","sourceRoot":"","sources":["../../src/emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAoB,MAAM,oBAAoB,CAAC;AAC/F,OAAO,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,MAAM,CAAC;AAClD,OAAO,WAAW,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAE5E,OAAO,EACL,gBAAgB,GAGjB,MAAM,cAAc,CAAC;AAEtB,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAA4C;IACxE,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE5D,4EAA4E;IAC5E,MAAM,eAAe,GAAG,gBAAgB,CAAC,gBAAgB,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAErF,MAAM,cAAc,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IAEvF,MAAM,QAAQ,GAAqB;QACjC,cAAc,EAAE,gBAAgB;QAChC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,QAAQ,EAAE,gBAAgB;QAC1B,SAAS,EAAE,cAAc,CAAC,SAAS;QACnC,gBAAgB,EAAE,cAAc,CAAC,gBAAgB;KAClD,CAAC;IAEF,MAAM,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,OAA4C,EAC5C,OAAyC,EACzC,QAA0B;IAE1B,MAAM,UAAU,GACd,OAAO,CAAC,MAAM,KAAK,MAAM;QACvB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI;QAC1C,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE;YACtB,SAAS,EAAE,CAAC;SACb,CAAC,CAAC;IACT,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,gBAAgB,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7E,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;QAC9B,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,UAAU;KACpB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { $onEmit } from "./emitter.js";
2
+ export { $lib } from "./lib.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { $onEmit } from "./emitter.js";
2
+ export { $lib } from "./lib.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,23 @@
1
+ export declare const $lib: import("@typespec/compiler").TypeSpecLibrary<{
2
+ "no-types-found": {
3
+ readonly default: "The metadata emitter didn't find any TypeSpec declarations defined in the current project. An empty snapshot will be produced.";
4
+ };
5
+ }, import("./options.js").MetadataEmitterOptions, never>;
6
+ export declare const reportDiagnostic: <C extends "no-types-found", M extends keyof {
7
+ "no-types-found": {
8
+ readonly default: "The metadata emitter didn't find any TypeSpec declarations defined in the current project. An empty snapshot will be produced.";
9
+ };
10
+ }[C]>(program: import("@typespec/compiler").Program, diag: import("@typespec/compiler").DiagnosticReport<{
11
+ "no-types-found": {
12
+ readonly default: "The metadata emitter didn't find any TypeSpec declarations defined in the current project. An empty snapshot will be produced.";
13
+ };
14
+ }, C, M>) => void, createDiagnostic: <C extends "no-types-found", M extends keyof {
15
+ "no-types-found": {
16
+ readonly default: "The metadata emitter didn't find any TypeSpec declarations defined in the current project. An empty snapshot will be produced.";
17
+ };
18
+ }[C]>(diag: import("@typespec/compiler").DiagnosticReport<{
19
+ "no-types-found": {
20
+ readonly default: "The metadata emitter didn't find any TypeSpec declarations defined in the current project. An empty snapshot will be produced.";
21
+ };
22
+ }, C, M>) => import("@typespec/compiler").Diagnostic;
23
+ //# sourceMappingURL=lib.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/lib.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,IAAI;;;;wDAcf,CAAC;AAEH,eAAO,MAAQ,gBAAgB;;;;;;;;mBAAE,gBAAgB;;;;;;;;oDAAS,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { createTypeSpecLibrary } from "@typespec/compiler";
2
+ import { metadataEmitterOptionsSchema } from "./options.js";
3
+ export const $lib = createTypeSpecLibrary({
4
+ name: "typespec-metadata",
5
+ diagnostics: {
6
+ "no-types-found": {
7
+ severity: "warning",
8
+ messages: {
9
+ default: "The metadata emitter didn't find any TypeSpec declarations defined in the current project. An empty snapshot will be produced.",
10
+ },
11
+ },
12
+ },
13
+ emitter: {
14
+ options: metadataEmitterOptionsSchema,
15
+ },
16
+ });
17
+ export const { reportDiagnostic, createDiagnostic } = $lib;
18
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AAE5D,MAAM,CAAC,MAAM,IAAI,GAAG,qBAAqB,CAAC;IACxC,IAAI,EAAE,mBAAmB;IACzB,WAAW,EAAE;QACX,gBAAgB,EAAE;YAChB,QAAQ,EAAE,SAAS;YACnB,QAAQ,EAAE;gBACR,OAAO,EACL,gIAAgI;aACnI;SACF;KACF;IACD,OAAO,EAAE;QACP,OAAO,EAAE,4BAA4B;KACtC;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC"}
@@ -0,0 +1,35 @@
1
+ export interface TypeSpecMetadata {
2
+ /** Fully-qualified namespace, e.g. Contoso.Example. */
3
+ namespace: string;
4
+ /** Documentation from @doc decorator. */
5
+ documentation?: string;
6
+ /** Type of service: 'data' for data plane, 'management' for management plane. */
7
+ type: "data" | "management";
8
+ }
9
+ export interface LanguagePackageMetadata {
10
+ /** Name of the emitter entry in tspconfig (package or path). */
11
+ emitterName: string;
12
+ /** Package/Binary identifier configured for the language emitter. */
13
+ packageName?: string;
14
+ /** Service namespace configured for the language emitter. */
15
+ namespace?: string;
16
+ /** Output directory for the emitter. */
17
+ outputDir?: string;
18
+ /** Flavor of the emitter (e.g., 'azure'). */
19
+ flavor?: string;
20
+ /** Service directory path for this language emitter. */
21
+ serviceDir?: string;
22
+ }
23
+ export interface MetadataSnapshot {
24
+ /** Semantic version for the metadata payload schema. */
25
+ emitterVersion: string;
26
+ /** ISO timestamp to simplify debugging when metadata was produced. */
27
+ generatedAt: string;
28
+ /** TypeSpec-level metadata (namespace, documentation, type). */
29
+ typespec: TypeSpecMetadata;
30
+ /** Per-language package metadata extracted from tspconfig, keyed by language. */
31
+ languages: Record<string, LanguagePackageMetadata>;
32
+ /** Absolute tspconfig path when available. */
33
+ sourceConfigPath?: string;
34
+ }
35
+ //# sourceMappingURL=metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../src/metadata.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;CAC7B;AAED,MAAM,WAAW,uBAAuB;IACtC,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,wDAAwD;IACxD,cAAc,EAAE,MAAM,CAAC;IACvB,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;IACnD,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../src/metadata.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import type { JSONSchemaType } from "@typespec/compiler";
2
+ export type MetadataOutputFormat = "yaml" | "json";
3
+ export interface MetadataEmitterOptions {
4
+ /**
5
+ * Relative path of the emitted metadata file. When omitted, the emitter picks an extension based on the format.
6
+ */
7
+ outputFile?: string;
8
+ /**
9
+ * Serialization format for the metadata snapshot.
10
+ */
11
+ format?: MetadataOutputFormat;
12
+ }
13
+ export interface NormalizedMetadataEmitterOptions {
14
+ outputFile: string;
15
+ format: MetadataOutputFormat;
16
+ }
17
+ export declare const metadataEmitterOptionsSchema: JSONSchemaType<MetadataEmitterOptions>;
18
+ export declare function normalizeOptions(rawOptions: MetadataEmitterOptions | undefined): NormalizedMetadataEmitterOptions;
19
+ //# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B;AAED,MAAM,WAAW,gCAAgC;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAQD,eAAO,MAAM,4BAA4B,EAAE,cAAc,CAAC,sBAAsB,CAO/E,CAAC;AAEF,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,sBAAsB,GAAG,SAAS,GAC7C,gCAAgC,CAQlC"}
@@ -0,0 +1,22 @@
1
+ const DEFAULT_FORMAT = "yaml";
2
+ const FALLBACK_FILENAMES = {
3
+ json: "typespec-metadata.json",
4
+ yaml: "typespec-metadata.yaml",
5
+ };
6
+ export const metadataEmitterOptionsSchema = {
7
+ type: "object",
8
+ additionalProperties: false,
9
+ properties: {
10
+ outputFile: { type: "string", nullable: true },
11
+ format: { type: "string", enum: ["yaml", "json"], nullable: true },
12
+ },
13
+ };
14
+ export function normalizeOptions(rawOptions) {
15
+ const format = rawOptions?.format ?? DEFAULT_FORMAT;
16
+ const sanitizedOutput = rawOptions?.outputFile?.trim();
17
+ return {
18
+ format,
19
+ outputFile: sanitizedOutput && sanitizedOutput.length > 0 ? sanitizedOutput : FALLBACK_FILENAMES[format],
20
+ };
21
+ }
22
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/options.ts"],"names":[],"mappings":"AAoBA,MAAM,cAAc,GAAyB,MAAM,CAAC;AACpD,MAAM,kBAAkB,GAAyC;IAC/D,IAAI,EAAE,wBAAwB;IAC9B,IAAI,EAAE,wBAAwB;CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,4BAA4B,GAA2C;IAClF,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,UAAU,EAAE;QACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC9C,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;KACnE;CACF,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAC9B,UAA8C;IAE9C,MAAM,MAAM,GAAG,UAAU,EAAE,MAAM,IAAI,cAAc,CAAC;IACpD,MAAM,eAAe,GAAG,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IACvD,OAAO;QACL,MAAM;QACN,UAAU,EACR,eAAe,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,kBAAkB,CAAC,MAAM,CAAC;KAC/F,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@azure-tools/typespec-metadata",
3
+ "version": "0.1.0",
4
+ "description": "TypeSpec emitter that produces structured metadata snapshots for APIView and other tooling.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Microsoft Corporation",
8
+ "keywords": [
9
+ "typespec",
10
+ "emitter",
11
+ "metadata",
12
+ "apiview"
13
+ ],
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/Azure/typespec-azure.git"
17
+ },
18
+ "bugs": {
19
+ "url": "https://github.com/Azure/typespec-azure/issues"
20
+ },
21
+ "engines": {
22
+ "node": ">=20.0.0"
23
+ },
24
+ "main": "dist/src/index.js",
25
+ "types": "dist/src/index.d.ts",
26
+ "files": [
27
+ "dist/**",
28
+ "!dist/test/**"
29
+ ],
30
+ "exports": {
31
+ ".": {
32
+ "import": "./dist/src/index.js"
33
+ }
34
+ },
35
+ "dependencies": {
36
+ "yaml": "~2.8.2"
37
+ },
38
+ "peerDependencies": {
39
+ "@typespec/compiler": "^1.8.0"
40
+ },
41
+ "devDependencies": {
42
+ "@types/node": "~25.0.2",
43
+ "@vitest/coverage-v8": "^4.0.15",
44
+ "@vitest/ui": "^4.0.15",
45
+ "c8": "^10.1.3",
46
+ "rimraf": "~6.1.2",
47
+ "typescript": "~5.9.2",
48
+ "vitest": "^4.0.15",
49
+ "@typespec/compiler": "^1.8.0"
50
+ },
51
+ "scripts": {
52
+ "build": "tsc -p .",
53
+ "watch": "tsc -p . --watch",
54
+ "clean": "rimraf ./dist ./temp",
55
+ "lint": "eslint . --max-warnings=0",
56
+ "lint:fix": "eslint . --fix ",
57
+ "test": "vitest run",
58
+ "test:watch": "vitest -w",
59
+ "test:ui": "vitest --ui",
60
+ "test:ci": "vitest run --coverage --reporter=junit --reporter=default"
61
+ }
62
+ }