Skip to content

0.67

Notable changes

tsp install now download and use the configured package manager

In order to detach typespec from any specific package manager, tsp install now uses the package manager configured in packageManager or devEngines.packageManager field of package.json. If the field is not present, it defaults to npm latest version but will log a warning.

package.json
{
// Use npm 11.2.0 with sha512 checksum verification
"packageManager": "npm@11.2.0+sha512.3dc9c50ba813a3d54393155a435fe66404b72685ab0e3008f9ae9ed8d81f6104860f07ed2656dd5748c1322d95f3140fa9b19c59a6bba7750fd12285f81866da",
// Use npm 11.2.0 but skip integrity check
"packageManager": "npm@11.2.0"
}

The field can be automatically set by running tsp install --save-package-manager

Breaking Changes

All packages

  • #5977 Minimum node version is now 20

@typespec/compiler

  • #6231 Remove deprecated items:

    • @deprecated decorator, use #deprecated directive instead

      @deprecated("Message")
      #deprecated "Message"
    • @service versions support. Either migrate to @OpenAPI.info or the versioning library

      @service({version: "1.0"})
      @service
      @OpenAPI.info(#{version: "1.0"})
    • Removed @knownValues. Use a union with a string variant instead

      enum MyKnownValues {a, b}
      @knownValues(MyKnownValues)
      scalar Custom extends string;
      union Custom {
      "a", "b", string
      };
    • Removed @projectedName Migrate to @encodedName instead.

      @projectedName("json", "nbf")
      @encodedName("application/json", "nbf")
      notBefore: int32;
    • CLI configuration value output-path, use output-dir instead.

    • Support for cadlMain in package.json. Migrate to exports["."].tsp instead.

      "cadlMain": "lib/main.tsp",
      "exports": {
      ".": {
      "tsp": "lib/main.tsp"
      }
      }
    • Compiling .cadl files, use .tsp instead.

    • decoratorArgMarshalling flag in $flags was removed and support for the legacy decorator arg marshalling.

    • Using @format on bytes. @format can only be used on string where it defines a known pattern for the string.

    • Javascript functions and typescript types:

      • stringTemplateToString
      • CadlLanguageConfiguration
      • CadlPrettierPlugin
      • NodePackage -> PackageJson
      • CadlValue -> TypeSpecValue
      • createCadlLibrary -> createTypeSpecLibrary
      • setCadlNamespace -> setTypeSpecNamespace
      • CadlLibrary -> TypeSpecLibrary
      • SyntaxKind.CadlScript -> SyntaxKind.TypeSpecScript
      • isCadlValueTypeOf -> isTypeSpecValueTypeOf
      • cadlTypeToJson -> typespecTypeToJson
      • checkFormatCadl -> checkFormatTypeSpec
      • cadlVersion -> typespecVersion
      • CadlManifest -> TypeSpecManifest
      • validateDecoratorTargetIntrinsic -> Use extern dec to define the signature of decorators instead
      • validateDecoratorParamType -> Use extern dec to define the signature of decorators instead
      • createDecoratorDefinition -> Use extern dec to define the signature of decorators instead
      • CompilerOptions#emitters -> Use emit and options field instead.
        emitters: { "my-emitter": options },
        emit: ["my-emitter"],
        options: { "my-emitter": options },
      • Type#templateArguments -> Use templateMapper instead.
      • ModelProperty#default -> Use defaultValue instead.
      • Union#options -> Use variants instead.
      • linter in createTypeSpecLibrary -> Use export const $linter = defineLinter({ ... }) instead.
      • Accessor for removed @knownValues decorator
        • getKnownValues
      • Accessor for removed @projectedName decorator
        • getProjectedNames
        • getProjectedName
        • hasProjectedName
  • #6323 Move AST related APIS to @typespec/compiler/ast package. This is to mark a clear separation for the AST types and APIs which are considered for advanced usage and might change at any time.

    • All *Node types
    • exprIsBareIdentifier
    • getFirstAncestor
    • getIdentifierContext
    • getNodeAtPosition
    • getNodeAtPositionDetail
    • hasParseError
    • isImportStatement
    • parse
    • parseStandaloneTypeReference
    • positionInRange
    • visitChildren
  • #6323 Stop exposing APIs that were not meant for external users. Please file issue if you had legitmate use of some of those APIs.

    • Checker: The check itself should be used very carefully and its wouldn’t be covered under the compatibility guarantees. There is some apis that were explicitly marked as internal while other remained until we provide a better way to do the same thing:

      • getGlobalNamespaceType(); -> program.getGlobalNamespaceType();
      • resolveTypeReference(); -> program.resolveTypeReference();
      • checkProgram(); This isn’t meant to be used by external users.
      • getLiteralType() This isn’t meant to be used by external users.
      • resolveRelatedSymbols() This isn’t meant to be used by external users.
      • resolveCompletions() This isn’t meant to be used by external users.
    • Program: Exposed functions on the program are safe to use but a few have been updated to be internal:

      • mainFile -> Use projectRoot instead.
      • literalTypes This isn’t meant to be used by external users.
      • checker: This is still exposed but to be used carefully, see above.
      • loadTypeSpecScript: This isn’t meant to be used by external users.
      • onValidate: This isn’t meant to be used by external users.
      • reportDuplicateSymbols: This isn’t meant to be used by external users.
    • logVerboseTestOutput Internal test util, not meant for external users

    • validateDecoratorTarget -> migrate to extern dec declaration

    • validateDecoratorParamCount: Same as above

    • altDirectorySeparator: Internal path utils

    • directorySeparator: Internal path utils

    • isIntrinsicType: Internal check

    • getFullyQualifiedSymbolName Symbols are an internal aspect of the compiler

    • Scanner related APIs:

      • createScanner
      • isComment
      • isKeyword
      • isModifier
      • isPunctuation
      • isStatementKeyword
      • isTrivia
      • skipContinuousIdentifier
      • skipTrivia
      • skipTriviaBackward
      • skipWhiteSpace
      • Token
      • TokenFlags
      • typeDocToken,
      • typeScanner,
      • typeStringTemplateToken,
    • Types

      • Sym Symbols are an internal aspect of the compiler
      • SymbolLinks Symbols are an internal aspect of the compiler
      • SymbolTable Symbols are an internal aspect of the compiler
      • SymbolFlags Symbols are an internal aspect of the compiler
      • MutableSymbolTable Symbols are an internal aspect of the compiler
      • ResolutionResult Internal type used in non exposed resolver
      • NodeLinks Internal type used in non exposed resolver
      • ResolutionResultFlags Internal type used in non exposed resolver
      • MetaMemberKey Unused type
      • MetaMembersTable Unused type
      • Dirent Unused type
  • #6410 Remove a legacy behavior of resolving package names which wasn’t inline with node ESM module resolution.

    For example if you were running tsp compile within your node_modules folder(on a test package) and referencing your emitter by name you might need to change this

    Terminal window
    tsp compile . --emit my-emitter
    tsp compile . ../../ # path to your emitter root instead
  • #6286 Removed deprecated use of @discriminator on union. Migrate to @discriminated

    @discriminator("type")
    @discriminated(#{envelope: "none", discriminatorPropertyName: "type"})
    union Pet;
  • #6327 Remove projection. Projection was an experiemental syntax that was too flawed to be included in 1.0 in that current state.

  • #6388 Remove deprecated type to value conversion. Since the introductions of object values(#{}) and array values(#[]) using model expressions or tuple where values were expected has been deprecated. It is now an error with a codefix.

    @service({title: "My service"})
    @service(#{title: "My service"})
  • #6416 Adding new keywords for future use:

    • statemachine
    • macro
    • package
    • metadata
    • env
    • arg
    • declare
    • array
    • struct
    • record
    • module
    • mod
    • pub
    • sub
    • typeref
    • trait
    • this
    • self
    • super
    • keyof
    • with
    • implements
    • impl
    • satisfies
    • flag
    • auto
    • partial
    • private
    • public
    • protected
    • internal
    • sealed
    • local
    • async
  • #6258 Removed deprecated legacy visibility APIs and converted all warnings for using string-based visibility modifiers to errors.

    The removed APIs include:

    • getVisibility: use getVisibilityForClass instead.
    • getParameterVisibility: use getParameterVisibilityFilter instead.
    • getReturnTypeVisibility: use getReturnTypeVisibilityFilter instead.

    Furthermore, the legacy signature of isVisible that accepts an array of strings has been removed. Please use the new signature that accepts EnumMember instead.

    The changed decorators include:

    • @visibility
    • @parameterVisibility
    • @returnTypeVisibility
    • @withVisibility
    • @withDefaultKeyVisibility

    The TypeSpec.DefaultKeyVisibility template also no longer accepts a string as a visibility modifier argument.

    Attempting to pass a string to any of the above decorators or templates will now result in a type-checking error. Please use the Lifecycle visibility modifiers instead.

    If you develop a third-party library and you use any custom visibility modifiers, you will need to instead define a visibility class enum. See: Visibility | TypeSpec.

    Migration steps:

    String-based visibilities can be replaced as follows:

    • "create", "read", "update", "delete", and "query" can be replaced with Lifecycle.Create, Lifecycle.Read, Lifecycle.Update, Lifecycle.Delete, and Lifecycle.Query respectively.
    • @visibility("none") can be replaced with @invisible(Lifecycle).

    For example:

    @visibility("create", "read")
    example: string;

    can be replaced with:

    @visibility(Lifecycle.Create, Lifecycle.Read)
    example: string;
    @visibility("none")
    example: string;

    can be replaced with:

    @invisible(Lifecycle)
    example: string;

    Additionally, @parameterVisibility with no arguments has been made an error. Previously, some specifications used it to disable effective PATCH optionality, but that behavior was an unintended side effect. For example:

    @parameterVisibility
    @patch
    op example(@bodyRoot resource: Resource): Resource;

    If you wish to disable effective PATCH optionality in @typespec/http, preventing it from treating all properties of the request body as effectively optional, you can now do so explicitly:

    @patch(#{ implicitOptionality: false })
    op example(@bodyRoot resource: Resource): Resource;

@typespec/http

  • #6387 Removing deprecated items

  • isContentTypeHeader

  • setLegacyStatusCodeState

Moved to internal

  • setStatusCode

  • #6305 Remove deprecated items:

  • format option from @header and @query decorators. Use explode option instead.

    @header(#{ format: "multi"})
    @query(#{ format: "multi"})
    @header(#{ explode: true })
    @query(#{ explode: true })
  • shared option from @route decorator. Please use @sharedRoute instead.

    @route("/doStuff", { shared: true })
    @sharedRoute
    @route("/doStuff")
  • Javascript functions and typescript types:

    • HeaderOptions.format
    • HeaderFieldOptions.format
    • QueryOptions.format
    • QueryParameterOptions.format
    • MetadataInfo.isEmptied
    • includeInterfaceRoutesInNamespace
    • getAllRoutes -> getAllHttpServices
    • OperationDetails -> HttpOperation
    • ServiceAuthentication -> Authentication
    • HttpOperationParameters.bodyType -> body.type
    • HttpOperationParameters.bodyParameter -> body.parameter
    • StatusCode -> HttpStatusCodesEntry
  • #6433 Stop exposing APIs that were not meant for external users. Please file issue if you had legitmate use of some of those APIs.

    • @includeInapplicableMetadataInPayload decorator was moved to Private namespace and stop exposing the accessor.
    • Functions used in getHttpOperation to resolve the finalized view of the http operation but shouldn’t be used directly.
      • resolvePathAndParameters
    • validateRouteUnique internal api used in http library validation
    • Moved custom route producer related APIs to experimental with unsafe_ prefix. Those APIs are not ready for public use and will change in future.
      • DefaultRouteProducer -> unsafe_DefaultRouteProducer
      • getRouteProducer -> unsafe_getRouteProducer
      • setRouteProducer -> unsafe_setRouteProducer
      • setRouteOptionsForNamespace -> unsafe_setRouteOptionsForNamespace
      • RouteProducer -> unsafe_RouteProducer
      • RouteProducerResult -> unsafe_RouteProducerResult
      • RouteResolutionOptions -> unsafe_RouteResolutionOptions
      • RouteOptions -> unsafe_RouteOptions
  • #6357 Changed the default content-type resolution behavior as follows:

  • As before, if the content-type header is explicitly specified (@header contentType: valueof string), the explicit content type is used (this behavior has not changed).

  • If the type of an HTTP payload body has a Media Type hint (@mediaTypeHint), that media type is preferred as the default content-type for the request.

  • The default content-type for TypeSpec.bytes has been changed to application/octet-stream to avoid serializing the data to base64-encoded JSON.

  • The default content-type for all other scalar types has been changed to text/plain (previously, it was application/json).

  • For multipart payloads, the default content-type of the payload has been changed to multipart/form-data if the @multipartBody parameter has a Model type and multipart/mixed if the multipart payload has a tuple type.

    • The content-type of individual parts in the multipart request has been changed to be the same as for HTTP payload bodies and follows the logic described above.

@typespec/versioning

  • #6327 Remove deprecated versioning projection, switch to the mutator approach

    // Step 1: Update to retrieve the mutation instead of projections
    const versions = buildVersionProjections(program, service.type);
    const versions = getVersioningMutators(program, service.type);
    // Step 2: call mutator instead of projection api
    const projectedProgram = projectProgram(originalProgram, versionRecord.projections);
    const subgraph = unsafe_mutateSubgraphWithNamespace(program, [mutator], service.type);
    subgraph.type // this is the mutated service namespace

Deprecations

@typespec/compiler

  • #6310 Deprecate @typespec/compiler/emitter-framework export in favor of a new package @typespec/asset-emitter

    package.json
    "dependencies": {
    "@typespec/asset-emitter": "0.67.0"
    }
    import { TypeEmitter, ... } from "@typespec/compiler/emitter-framework";
    import { TypeEmitter, ... } from "@typespec/asset-emitter";
  • #6306 Remove the use of deprecated getDiscriminatedUnion

@typespec/http

  • #6464 Deprecate implicit multipart body

    op upload(
    @header contentType: "multipart/form-data",
    @body body: {
    @multipartBody body: {
    name: string;
    name: HttpPart<string>;
    avatar: bytes;
    avatar: HttpPart<bytes>;
    }
    ): void;

@typespec/openapi3

  • #6305 Related changes based on http library deprecation removal.

Features

@typespec/compiler

  • #6411 Introduce a new dryRun compiler option(--dry-run in the cli) that emitters can opt-in to support by setting capabilities.dryRun in their $lib.
  • #6411 Update noEmit compiler option (--no-emit cli flag) to prevent emitter to run. A new dryRun option has been added to achieve a safer similar result where emitters run but do not write output.
  • #6220 tsp install now downloads and uses the configured package manager in devEngines.packageManager or packageManager field of package.json
  • #6357 Add support for @mediaTypeHint to apply a hint for default Media/MIME type (Content-Type in HTTP) to a TypeSpec type.

@typespec/http

  • #6345 Update BasicAuth and BearerAuth types scheme to use standard name for scheme Basic, Bearer
  • #6327 Remove reference to delete projection feature

@typespec/openapi3

  • #6268 @typespec/versioning is now an optional dependency.
  • #6286 Remove support for @discriminator on union
  • #6327 Remove reference to delete projection feature

@typespec/protobuf

  • #6327 Remove reference to delete projection feature

@typespec/html-program-viewer

  • #6327 Remove reference to delete projection feature

typespec-vscode

  • #6178 Update references to JS emitter
  • #5972 Select multiple emitters to generate multiple codes at one time
  • #6295 Improve the “Create TypeSpec Project” user experience
  • #6015 add openapi3 preview
  • #6123 Support telemetry

Bug Fixes

@typespec/compiler

  • #6335 Improvements to the CLI output
  • #6309 Fixed an issue where the --emit-files flag on emitters with nested folders was not generating the correct paths to the files.
  • #6292 Fix tsp init not respecting default selected emitters

@typespec/rest

  • #6326 Updates @autoRoute behavior to apply same HttpOperationParameter filtering to HttpProperty

@typespec/openapi3

  • #6289 Fix utcDateTime and offsetDateTime not using format http-date in header by default as the default http encoding defines
  • #6411 Add support for new dryRun emitter option
  • #6473 Adds support for @encode to specify array encodings for @query parameters

@typespec/protobuf

  • #6411 Add support for new dryRun emitter option

@typespec/json-schema

  • #6411 Add support for new dryRun emitter option