···11import "../dist/tsp-index.js";
2233+using TypeSpec.Reflection;
44+35/**
46 * Specifies the maximum number of graphemes (user-perceived characters) allowed.
57 * Used alongside maxLength for proper Unicode text handling.
···159161 * ```
160162 */
161163extern dec errors(target: unknown, ...errors: unknown[]);
164164+165165+/**
166166+ * Marks a namespace as external, preventing it from emitting JSON output.
167167+ * This decorator can only be applied to namespaces.
168168+ * Useful for importing definitions from other lexicons without re-emitting them.
169169+ *
170170+ * @example
171171+ * ```typespec
172172+ * @external
173173+ * namespace com.atproto.repo.defs;
174174+ * ```
175175+ */
176176+extern dec external(target: Namespace);
+22
packages/emitter/src/decorators.ts
···2424const inlineKey = Symbol("inline");
2525const maxBytesKey = Symbol("maxBytes");
2626const minBytesKey = Symbol("minBytes");
2727+const externalKey = Symbol("external");
27282829/**
2930 * @maxBytes decorator for maximum length of bytes type
···294295export function isReadOnly(program: Program, target: Type): boolean {
295296 return program.stateSet(readOnlyKey).has(target);
296297}
298298+299299+/**
300300+ * @external decorator for marking a namespace as external
301301+ * External namespaces are skipped during emission and don't produce JSON files
302302+ */
303303+export function $external(context: DecoratorContext, target: Type) {
304304+ if (target.kind !== "Namespace") {
305305+ context.program.reportDiagnostic({
306306+ code: "external-not-on-namespace",
307307+ severity: "error",
308308+ message: "@external decorator can only be applied to namespaces",
309309+ target: target,
310310+ });
311311+ return;
312312+ }
313313+ context.program.stateSet(externalKey).add(target);
314314+}
315315+316316+export function isExternal(program: Program, target: Type): boolean {
317317+ return program.stateSet(externalKey).has(target);
318318+}