+15
packages/emitter/lib/decorators.tsp
+15
packages/emitter/lib/decorators.tsp
···
1
1
import "../dist/tsp-index.js";
2
2
3
+
using TypeSpec.Reflection;
4
+
3
5
/**
4
6
* Specifies the maximum number of graphemes (user-perceived characters) allowed.
5
7
* Used alongside maxLength for proper Unicode text handling.
···
159
161
* ```
160
162
*/
161
163
extern dec errors(target: unknown, ...errors: unknown[]);
164
+
165
+
/**
166
+
* Marks a namespace as external, preventing it from emitting JSON output.
167
+
* This decorator can only be applied to namespaces.
168
+
* Useful for importing definitions from other lexicons without re-emitting them.
169
+
*
170
+
* @example
171
+
* ```typespec
172
+
* @external
173
+
* namespace com.atproto.repo.defs;
174
+
* ```
175
+
*/
176
+
extern dec external(target: Namespace);
+22
packages/emitter/src/decorators.ts
+22
packages/emitter/src/decorators.ts
···
24
24
const inlineKey = Symbol("inline");
25
25
const maxBytesKey = Symbol("maxBytes");
26
26
const minBytesKey = Symbol("minBytes");
27
+
const externalKey = Symbol("external");
27
28
28
29
/**
29
30
* @maxBytes decorator for maximum length of bytes type
···
294
295
export function isReadOnly(program: Program, target: Type): boolean {
295
296
return program.stateSet(readOnlyKey).has(target);
296
297
}
298
+
299
+
/**
300
+
* @external decorator for marking a namespace as external
301
+
* External namespaces are skipped during emission and don't produce JSON files
302
+
*/
303
+
export function $external(context: DecoratorContext, target: Type) {
304
+
if (target.kind !== "Namespace") {
305
+
context.program.reportDiagnostic({
306
+
code: "external-not-on-namespace",
307
+
severity: "error",
308
+
message: "@external decorator can only be applied to namespaces",
309
+
target: target,
310
+
});
311
+
return;
312
+
}
313
+
context.program.stateSet(externalKey).add(target);
314
+
}
315
+
316
+
export function isExternal(program: Program, target: Type): boolean {
317
+
return program.stateSet(externalKey).has(target);
318
+
}
+6
packages/emitter/src/emitter.ts
+6
packages/emitter/src/emitter.ts
···
67
67
isInline,
68
68
getMaxBytes,
69
69
getMinBytes,
70
+
isExternal,
70
71
} from "./decorators.js";
71
72
72
73
export interface EmitterOptions {
···
118
119
for (const [_, childNs] of ns.namespaces) {
119
120
this.processNamespace(childNs);
120
121
}
122
+
return;
123
+
}
124
+
125
+
// Skip external namespaces - they don't emit JSON files
126
+
if (isExternal(this.program, ns)) {
121
127
return;
122
128
}
123
129