Transforms web app manifest files with schema validation and resource dependency resolution for Parcel
npx @tessl/cli install tessl/npm-parcel--transformer-webmanifest@2.15.0Parcel transformer plugin for processing web app manifest files. Validates manifest structure against the Web App Manifest specification and resolves resource dependencies (icons, screenshots) for proper bundling.
npm install @parcel/transformer-webmanifestThis transformer is automatically used by Parcel when processing .webmanifest files. No direct imports are typically needed in user code, as it integrates with Parcel's asset pipeline.
For direct usage (advanced):
import transformer from "@parcel/transformer-webmanifest";CommonJS:
const transformer = require("@parcel/transformer-webmanifest");Dependencies used internally:
import { parse } from "@mischnic/json-sourcemap";
import { getJSONSourceLocation } from "@parcel/diagnostic";
import { Transformer } from "@parcel/plugin";
import { validateSchema } from "@parcel/utils";This transformer is automatically used by Parcel for .webmanifest files. Simply include a web manifest in your project:
// manifest.webmanifest
{
"name": "My Web App",
"short_name": "MyApp",
"start_url": "/",
"display": "standalone",
"icons": [
{
"src": "./icons/icon-192.png",
"sizes": "192x192",
"type": "image/png"
}
],
"screenshots": [
{
"src": "./screenshots/desktop.png",
"sizes": "1280x720",
"type": "image/png"
}
]
}The transformer will:
The main export is a configured Parcel Transformer instance that processes web manifest files.
/**
* Parcel transformer instance for web manifest files
* Automatically validates schema and resolves resource dependencies
*/
export default transformer: Transformer;Core transformation functionality that processes web manifest assets.
/**
* Transforms web manifest JSON with validation and dependency resolution
* @param options - Transform options containing the asset and other context
* @param options.asset - The web manifest asset to transform
* @param options.config - Transformer configuration (if any)
* @param options.resolve - Function to resolve dependencies
* @param options.options - Plugin options
* @param options.logger - Plugin logger instance
* @param options.tracer - Plugin tracer instance
* @returns Promise resolving to array containing the transformed asset
*/
async function transform({
asset,
config,
resolve,
options,
logger,
tracer
}): Promise<Array<MutableAsset>>;Process:
@mischnic/json-sourcemapBuilt-in schema validation for Web App Manifest specification compliance using validateSchema.diagnostic function.
/**
* Validates manifest data against schema with detailed error reporting
* @param schema - Schema entity defining validation rules
* @param data - Data object containing source, map, and filePath
* @param transformerName - Name of the transformer for error context
* @param message - Error message for validation failures
*/
function validateSchema.diagnostic(
schema: SchemaEntity,
data: {
source: string,
map: { data: any, pointers: object },
filePath: string
},
transformerName: string,
message: string
): void;Schema Structure:
/**
* Resource schema for validating icon and screenshot objects
*/
const RESOURCES_SCHEMA: SchemaEntity = {
type: 'array',
items: {
type: 'object',
properties: {
src: {
type: 'string',
__validate: (s) => s.length === 0 ? 'Must not be empty' : undefined
}
},
required: ['src']
}
};
/**
* Main manifest schema for validation
*/
const MANIFEST_SCHEMA: SchemaEntity = {
type: 'object',
properties: {
icons: RESOURCES_SCHEMA,
screenshots: RESOURCES_SCHEMA,
shortcuts: {
type: 'array',
items: {
type: 'object',
properties: {
icons: RESOURCES_SCHEMA
}
}
},
file_handlers: {
type: 'array',
items: {
type: 'object',
properties: {
icons: RESOURCES_SCHEMA
}
}
}
}
};Validated Properties:
icons: Array of resource objects with required src propertyscreenshots: Array of resource objects with required src propertyshortcuts: Array of objects with optional icons propertyfile_handlers: Array of objects with optional icons propertyThe transformer automatically converts resource URLs to Parcel dependencies using addURLDependency with precise source location tracking.
/**
* Utility function to get JSON source location for error reporting
* @param pointer - JSON pointer from source map
* @param type - Type of location ('key' | 'value')
* @returns Source location object with start/end positions
*/
function getJSONSourceLocation(
pointer: object,
type: 'key' | 'value'
): { start: Position, end: Position };
/**
* JSON source map parser from @mischnic/json-sourcemap
* @param source - JSON string to parse
* @returns Parsed data with source map pointers
*/
function parse(source: string): JSONSourceMap;Processing Behavior:
icons and screenshots arrays at the top levelicons within shortcuts and file_handlerssrc URL is converted to a Parcel dependency/icons/0/src for location trackingThe transformer uses internal helper functions for resource processing:
/**
* Internal function to add resource list dependencies to asset
* @param list - Array of resource objects with src properties
* @param parent - Parent JSON pointer path for location tracking
*/
function addResourceListToAsset(list: Array<any>, parent: string): void;Internal Processing Logic:
@mischnic/json-sourcemapMANIFEST_SCHEMA using validateSchema.diagnosticicons and screenshots arraysicons within shortcuts and file_handlerssrc URL to Parcel dependency with precise location/**
* Parcel asset interface for transformation
*/
interface MutableAsset {
/** Get the current code/content of the asset */
getCode(): Promise<string>;
/** Set the code/content of the asset */
setCode(content: string): void;
/** Add a general dependency to the asset */
addDependency(options: DependencyOptions): string;
/** Add a URL dependency to the asset (used for resource references) */
addURLDependency(url: string, options: DependencyOptions): string;
/** The asset's type (initially corresponds to file extension) */
type: string;
/** Absolute file path of the asset */
filePath: string;
/** Optional unique key for the asset */
uniqueKey?: string;
/** Symbol information for the asset */
+symbols: MutableAssetSymbols;
}
/**
* Options for dependency creation
*/
interface DependencyOptions {
/** Source location for error reporting */
loc?: SourceLocation;
/** Environment conditions for the dependency */
env?: EnvironmentOptions;
/** Whether this is an optional dependency */
isOptional?: boolean;
/** Priority of the dependency */
priority?: 'sync' | 'parallel' | 'lazy';
}
/**
* Source location for error reporting and debugging
*/
interface SourceLocation {
filePath: string;
start: Position;
end: Position;
}
/**
* Position information for source locations
*/
interface Position {
line: number;
column: number;
}
/**
* Schema entity for validation rules
*/
interface SchemaEntity {
type: 'object' | 'array' | 'string' | 'number' | 'boolean';
properties?: { [key: string]: SchemaEntity };
items?: SchemaEntity;
required?: string[];
__validate?: (value: any) => string | undefined;
}
/**
* JSON source map parsing result
*/
interface JSONSourceMap {
data: any;
pointers: { [jsonPointer: string]: SourceLocation };
}
/**
* Asset symbols interface for mutable assets
*/
interface MutableAssetSymbols {
ensure(): void;
set(exportSymbol: Symbol, local: Symbol): void;
get(exportSymbol: Symbol): Symbol | null;
hasExportSymbol(exportSymbol: Symbol): boolean;
hasLocalSymbol(local: Symbol): boolean;
exportSymbols(): Iterable<Symbol>;
}The transformer provides detailed error reporting with source location tracking:
Errors are reported through Parcel's diagnostic system with file paths and line/column positions.
.webmanifest files