npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jdpnielsen/uda-to-typescript

v17.2.1

Published

CLI to convert Umbraco UDA files to typescript definitions

Readme

uda-to-typescript

npm package Build Status Downloads Issues Commitizen Friendly Semantic Release

Command-line tool to convert Umbraco UDA files to Typescript types.

Install

npm install @jdpnielsen/uda-to-typescript

Quick Start

Usage: uda-to-typescript [options]

CLI to convert Umbraco UDA files to typescript definitions

Options:
  -V, --version          output the version number
  -c, --config <string>  Path for config file. Example: --config ./udaconvert.config.ts
  -i, --input <string>   Glob pattern to match. Example: --input ./files/*.uda
  -o, --output <string>  Where to write output file. Example: --output ./file.ts
  --skip-template        Prevent writing of template files. Example: --skip-templates
  -d, --debug            enables verbose logging (default: false)
  -h, --help             display help for command

Examples:

  $ uda-to-typescript --version
  1.0.0

Without config

  $ uda-to-typescript --input ../your-umbraco-project/src/UmbracoProject/umbraco/Deploy/Revision/*.uda --output ./umbraco-sdk/types.ts

With config

 $ uda-to-typescript
 # or
 $ uda-to-typescript --config ./udaconvert.config.ts

Note: uda-to-typescript uses cosmic-config to locate config files.

File udaconvert.config.ts

import { defineConfig } from '@jdpnielsen/uda-to-typescript';

export default defineConfig({
	input: './UmbracoProject/umbraco/Deploy/Revision/*.uda',
	output: './src/umbraco/output.ts',
});

Provide custom datatypes

import { factory } from 'typescript';
import { HandlerConfig, dataTypes, defineConfig } from '@jdpnielsen/uda-to-typescript';

export default defineConfig({
	input: '../umbraco-boilerplate/src/UmbracoProject/umbraco/Deploy/Revision/*.uda',
	output: './src/umbraco/output.ts',
	dataTypes: {
		...dataTypes, // Provide default types
		'Custom.StatementEditor': {
			editorAlias: 'Custom.StatementEditor',
			/**
			 * Used to create any shared setup for the propertyEditor
			 */
			init: () => {
				return 'export type Statement = "key" | "val";';
			},
			/**
			 * Used to generate any dataType specifc types
			 * @example ```ts
			 * type MetatitleTextboxType = {
			 * 	statement: Statement;
			 * 	prop: string;
			 * };
			 * ```
			 */
			build: (dataType) => {
				return `type ${pascalCase(dataType.Name)}Type = {
					statement: Statement;
					prop: ${dataType.DatabaseType === 1 ? 'string' : 'unknown'};
				}`;
			},
			/**
			 * Used to generate any usage specific type/reference
			 * @example ```ts
			 * export type Metadata = BaseDocumentType<'metadata', {
			 * 	meta_title?: MetatitleTextboxType;
			 * }>;
			 * ```
			 */
			reference: (dataType) => `${pascalCase(dataType.Name)}Type`,
		},
	},
});

Umbraco version target

This library targets Umbraco v17 artifact exports and Delivery API v2. Earlier Umbraco exports and Delivery API v1 conventions are not supported.

Test fixtures and examples in this branch use the current fixture set under src/__tests__/__fixtures__/current.

For custom property editors, Umbraco can export a split editor model:

  • EditorAlias can point to a core schema alias (for example Umbraco.Plain.Json)
  • EditorUiAlias carries the UI/editor alias (for example Noa.CustomLinkPicker)

The generator resolves handlers by EditorUiAlias first, then EditorAlias.

Current behavior notes

  1. Register custom datatype handlers by EditorUiAlias when relevant.
  2. Some editor configs contain fewer enumerated values than earlier exports.
  3. Migrated editors using Umbraco.Plain.* can produce broader types unless you provide a custom handler.
  4. Some custom editor configs can omit fields you depended on (for example items) and booleans can appear as '0' / '1' strings.

Data type alias emission (default on)

By default, the generator emits a named type alias for every data type artifact:

export type ApprovedColor = string | null;

This improves discoverability in consumer projects, even when a data type is not currently referenced by a document or media type.

If you need legacy behavior, disable it in config:

export default defineConfig({
	input: '../umbraco/Deploy/Revision/*.uda',
	output: './src/umbraco/types.ts',
	emitDataTypeAliases: false,
});

Custom handler example using EditorUiAlias

import { dataTypes, defineConfig } from '@jdpnielsen/uda-to-typescript';

export default defineConfig({
	input: '../umbraco/Deploy/Revision/*.uda',
	output: './src/umbraco/types.ts',
	dataTypes: {
		...dataTypes,
		'Noa.CustomLinkPicker': {
			editorAlias: 'Noa.CustomLinkPicker',
			build: () => [],
			reference: () => 'UrlItem',
		},
	},
});

Making custom handlers resilient to current config shapes

When migrating custom handlers, avoid assuming config arrays always exist.

const config = dataType.Configuration as {
	multiple?: boolean | '0' | '1';
	items?: Array<{ key: string; value: string }>;
};

const isMultiple = config.multiple === true || config.multiple === '1';
const items = Array.isArray(config.items) ? config.items : [];

if (items.length === 0) {
	return isMultiple ? 'string[]' : 'string';
}

Generated fetchers (Delivery API v2)

Generated fetcher.ts helpers call Delivery API v2 endpoints.

  • buildContentFetcher calls /umbraco/delivery/api/v2/content
  • buildContentItemFetcher calls /umbraco/delivery/api/v2/content/item/{id}
import { buildContentFetcher } from './fetcher';

const getContent = buildContentFetcher<SiteRoot>('https://example.com');

UMBRACO_NO_CACHE runtime flag

Teams commonly use UMBRACO_NO_CACHE in local development and preview environments to bypass response caching while validating content and media changes.

uda-to-typescript does not read environment variables directly in generated fetchers. Instead, pass a custom fetch function and apply cache behavior there.

Recommended semantics:

  • UMBRACO_NO_CACHE=true or UMBRACO_NO_CACHE=1: disable caching (cache: 'no-store') and add a cache-buster query parameter.
  • Any other value (or unset): keep normal/default caching behavior.
import { buildContentFetcher } from './fetcher';
import type { FetchFunction } from './fetcher';

const noCache = process.env.UMBRACO_NO_CACHE === 'true' || process.env.UMBRACO_NO_CACHE === '1';

const fetchFunction: FetchFunction = async <T>({ url, options }) => {
	const nextUrl = new URL(url.toString());

	if (noCache) {
		nextUrl.searchParams.set('_ts', Date.now().toString());
	}

	const response = await fetch(nextUrl, {
		...options,
		cache: noCache ? 'no-store' : options?.cache,
	});

	if (!response.ok) {
		throw new Error(response.statusText);
	}

	return response.json() as Promise<T>;
};

export const getContent = buildContentFetcher<SiteRoot>('https://example.com', fetchFunction);

Practical guidance:

  • Use this flag in development/preview only.
  • Keep it off in production unless you explicitly need real-time freshness over cache efficiency.
  • If your platform adds caching upstream (CDN/reverse proxy), pair this with appropriate cache-control headers in your hosting layer.