emoji-styles 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 emoji-styles contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,49 @@
1
+ # emoji-styles
2
+
3
+ Framework-independent emoji resolution with typed providers, explicit fallback
4
+ chains, semantic themes, Unicode metadata, and deterministic asset policies.
5
+
6
+ ## Install
7
+
8
+ ```bash
9
+ npm install emoji-styles
10
+ ```
11
+
12
+ ## Usage
13
+
14
+ ```ts
15
+ import {
16
+ defineEmojiTheme,
17
+ publicProviders,
18
+ resolveEmoji,
19
+ resolveEmojiToken,
20
+ } from "emoji-styles";
21
+
22
+ const theme = defineEmojiTheme({
23
+ "action.deploy": {
24
+ emoji: "🚀",
25
+ label: "Deploy application",
26
+ },
27
+ });
28
+
29
+ const resolved = await resolveEmoji("🚀", {
30
+ provider: publicProviders.fluent3d,
31
+ fallbacks: [publicProviders.twemoji],
32
+ nativeFallback: false,
33
+ });
34
+
35
+ const deploy = await resolveEmojiToken("action.deploy", theme);
36
+ ```
37
+
38
+ Use this package directly in any JavaScript framework, or pair it with
39
+ [`react-emoji-styles`](https://www.npmjs.com/package/react-emoji-styles) or
40
+ [`emoji-styles-web`](https://www.npmjs.com/package/emoji-styles-web).
41
+
42
+ Documentation and the interactive provider explorer are available at
43
+ [emoji-styles.space](https://emoji-styles.space).
44
+
45
+ ## License
46
+
47
+ Source code is MIT licensed. Artwork returned by external providers retains its
48
+ own license and delivery terms; see the repository's
49
+ [license policy](https://github.com/Blancochuy/emoji-styles/blob/master/docs/LICENSE_POLICY.md).
@@ -0,0 +1,411 @@
1
+ import * as emoji_styles_data from 'emoji-styles-data';
2
+ export { EmojiDatasetInfo, EmojiMetadata, EmojiQualification, emojiData, emojiDatasetInfo, isRGIEmoji, normalizeEmoji, toEmojiCodepointSequence } from 'emoji-styles-data';
3
+
4
+ type EmojiStyle = "fluent-animated" | "fluent-3d" | "fluent-color" | "fluent-flat" | "noto" | "serenityos" | "twemoji" | "native";
5
+ type EmojiSize = "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | number;
6
+ type ProviderVisibility = "public" | "custom";
7
+ type EmojiAssetFormat = "png" | "svg" | "webp" | "avif";
8
+ interface ProviderLicense {
9
+ name: string;
10
+ url?: string;
11
+ attribution?: string;
12
+ ownership?: string;
13
+ }
14
+ interface EmojiData {
15
+ /** Stable CLDR-derived identifier used by provider URL formatters. */
16
+ name: string;
17
+ /** Human-readable alt text. */
18
+ alt: string;
19
+ /** Canonical lowercase, hyphen-separated Unicode sequence. */
20
+ codepoint: string;
21
+ /** Enriched fields are present for catalog entries and optional for custom providers. */
22
+ codepoints?: readonly string[];
23
+ sequence?: string;
24
+ unicodeVersion?: string;
25
+ emojiVersion?: string;
26
+ group?: string;
27
+ subgroup?: string;
28
+ qualification?: "fully-qualified" | "component";
29
+ /** Styles that DON'T have this emoji (blacklist) */
30
+ unsupported?: EmojiStyle[];
31
+ }
32
+ interface ProviderConfig {
33
+ name: EmojiStyle;
34
+ baseUrl: string;
35
+ extension: string;
36
+ label: string;
37
+ }
38
+ /** A source of emoji artwork. Custom providers keep asset hosting outside the core. */
39
+ interface EmojiAssetProvider {
40
+ id: string;
41
+ label: string;
42
+ visibility: ProviderVisibility;
43
+ /** Required for v2 providers; optional only while adapting legacy providers. */
44
+ version?: string;
45
+ formats?: readonly EmojiAssetFormat[];
46
+ local?: boolean;
47
+ source?: string;
48
+ license?: ProviderLicense;
49
+ /** Whether the provider can resolve emoji absent from the bundled catalog. */
50
+ supportsUnknownEmoji?: boolean;
51
+ /** @deprecated Implement `resolve` for v2 providers. Retained for synchronous compatibility. */
52
+ getUrl?(data: EmojiData, emoji?: string): string | null;
53
+ resolve?(emoji: NormalizedEmoji): ProviderResolution;
54
+ getCoverage?(): ProviderCoverage | Promise<ProviderCoverage>;
55
+ }
56
+ type EmojiProviderRef = EmojiStyle | EmojiAssetProvider;
57
+ interface NormalizedEmojiMetadata {
58
+ label: string;
59
+ codepoints: readonly string[];
60
+ sequence: string;
61
+ unicodeVersion?: string;
62
+ emojiVersion?: string;
63
+ category?: string;
64
+ subgroup?: string;
65
+ }
66
+ interface NormalizedEmoji {
67
+ input: string;
68
+ normalized: string;
69
+ metadata: NormalizedEmojiMetadata;
70
+ data: EmojiData;
71
+ }
72
+ interface ResolvedEmojiAsset {
73
+ providerId: string;
74
+ providerVersion: string;
75
+ url: string;
76
+ format: EmojiAssetFormat;
77
+ local: boolean;
78
+ width?: number;
79
+ height?: number;
80
+ checksum?: string;
81
+ license?: ProviderLicense;
82
+ }
83
+ type ProviderResolution = ResolvedEmojiAsset | null | Promise<ResolvedEmojiAsset | null>;
84
+ interface EmojiResolutionAttempt {
85
+ providerId: string;
86
+ status: "resolved" | "unsupported" | "native" | "error";
87
+ asset: ResolvedEmojiAsset | null;
88
+ error?: string;
89
+ }
90
+ interface EmojiResolution {
91
+ input: string;
92
+ normalized: string;
93
+ metadata: NormalizedEmojiMetadata;
94
+ selected: ResolvedEmojiAsset | null;
95
+ attempts: EmojiResolutionAttempt[];
96
+ fallbackUsed: boolean;
97
+ nativeFallback: boolean;
98
+ }
99
+ interface ProviderCoverage {
100
+ providerId: string;
101
+ providerVersion: string;
102
+ datasetVersion: string;
103
+ total: number;
104
+ supported: number;
105
+ percentage: number;
106
+ verified: boolean;
107
+ source?: string;
108
+ missing?: readonly string[];
109
+ }
110
+ interface ProviderValidationResult {
111
+ valid: boolean;
112
+ errors: string[];
113
+ warnings: string[];
114
+ }
115
+
116
+ interface CdnProviderOptions {
117
+ id: string;
118
+ label: string;
119
+ baseUrl: string;
120
+ extension: string;
121
+ visibility: ProviderVisibility;
122
+ license?: ProviderLicense;
123
+ filename?: (data: EmojiData) => string;
124
+ version?: string;
125
+ format?: EmojiAssetFormat;
126
+ local?: boolean;
127
+ source?: string;
128
+ supports?: (data: EmojiData, emoji?: string) => boolean;
129
+ coverage?: () => ProviderCoverage | Promise<ProviderCoverage>;
130
+ }
131
+ declare function createCdnProvider(options: CdnProviderOptions): EmojiAssetProvider;
132
+ /** Match Twemoji's asset convention: keep VS16 inside ZWJ sequences, omit it otherwise. */
133
+ declare function getTwemojiAssetId(data: Pick<EmojiData, "codepoint">): string;
134
+ /** Providers whose artwork has an explicit redistribution license. */
135
+ declare const publicProviders: {
136
+ readonly fluentAnimated: EmojiAssetProvider;
137
+ readonly fluent3d: EmojiAssetProvider;
138
+ readonly fluentColor: EmojiAssetProvider;
139
+ readonly fluentFlat: EmojiAssetProvider;
140
+ readonly noto: EmojiAssetProvider;
141
+ readonly serenityOS: EmojiAssetProvider;
142
+ readonly twemoji: EmojiAssetProvider;
143
+ readonly native: {
144
+ id: string;
145
+ label: string;
146
+ visibility: "public";
147
+ version: string;
148
+ formats: never[];
149
+ local: true;
150
+ source: string;
151
+ getUrl: () => null;
152
+ resolve: () => null;
153
+ };
154
+ };
155
+ /**
156
+ * Licensed providers whose upstream delivery is intentionally rolling.
157
+ * Keep these separate from `publicProviders` so production consumers can opt in.
158
+ */
159
+ declare const experimentalProviders: {
160
+ readonly notoAnimated: EmojiAssetProvider;
161
+ };
162
+ /** Built-in providers with documented redistribution terms. */
163
+ declare const providers: Record<EmojiStyle, EmojiAssetProvider>;
164
+ declare const SIZE_MAP: Record<string, number>;
165
+
166
+ type EmojiAssetMap = Readonly<Record<string, string>>;
167
+ interface MappedProviderOptions {
168
+ id?: string;
169
+ label?: string;
170
+ /** Exact Unicode emoji mapped to an application-owned asset URL. */
171
+ assets: EmojiAssetMap;
172
+ /** Used whenever an emoji has no custom asset. */
173
+ fallback?: EmojiAssetProvider;
174
+ license?: ProviderLicense;
175
+ version?: string;
176
+ source?: string;
177
+ format?: EmojiAssetFormat;
178
+ local?: boolean;
179
+ }
180
+ /**
181
+ * Create a partial custom provider without requiring a filename convention.
182
+ * Invalid or empty mappings fail immediately so configuration errors surface
183
+ * during application startup instead of as broken images in production.
184
+ */
185
+ declare function createMappedProvider(options: MappedProviderOptions): EmojiAssetProvider;
186
+
187
+ interface ResolveEmojiOptions {
188
+ provider: EmojiProviderRef;
189
+ fallbacks?: readonly EmojiProviderRef[];
190
+ }
191
+ interface ProviderCoverageOptions {
192
+ includeMissing?: boolean;
193
+ }
194
+ declare function createNormalizedEmoji(input: string): NormalizedEmoji | null;
195
+ declare function getEmojiMetadata(input: string): NormalizedEmojiMetadata | null;
196
+ declare function isEmoji(input: string): boolean;
197
+ declare function resolveEmoji(input: string, options: ResolveEmojiOptions): Promise<EmojiResolution>;
198
+ declare function getProviderCoverage(providerRef: EmojiProviderRef, options?: ProviderCoverageOptions): Promise<ProviderCoverage>;
199
+
200
+ interface LegacyEmojiAssetProvider {
201
+ id: string;
202
+ label: string;
203
+ visibility: ProviderVisibility;
204
+ license?: EmojiAssetProvider["license"];
205
+ supportsUnknownEmoji?: boolean;
206
+ getUrl: NonNullable<EmojiAssetProvider["getUrl"]>;
207
+ }
208
+ interface LegacyProviderAdapterOptions {
209
+ version?: string;
210
+ format?: EmojiAssetFormat;
211
+ local?: boolean;
212
+ source?: string;
213
+ }
214
+ declare function isV2Provider(provider: EmojiAssetProvider): boolean;
215
+ declare function adaptLegacyProvider(legacy: LegacyEmojiAssetProvider, options?: LegacyProviderAdapterOptions): EmojiAssetProvider;
216
+
217
+ interface EmojiProviderManifestAsset {
218
+ file: string;
219
+ sha256?: string;
220
+ width?: number;
221
+ height?: number;
222
+ }
223
+ interface EmojiProviderGenerator {
224
+ type: string;
225
+ model: string;
226
+ createdAt: string;
227
+ }
228
+ interface EmojiProviderManifest {
229
+ $schema?: string;
230
+ id: string;
231
+ label: string;
232
+ version: string;
233
+ format: EmojiAssetFormat;
234
+ basePath: string;
235
+ generated?: boolean;
236
+ generator?: EmojiProviderGenerator;
237
+ license?: ProviderLicense;
238
+ source?: string;
239
+ assets: Record<string, EmojiProviderManifestAsset>;
240
+ }
241
+ interface ManifestProviderOptions {
242
+ baseUrl?: string;
243
+ visibility?: "public" | "custom";
244
+ local?: boolean;
245
+ }
246
+ declare function validateProviderManifest(manifest: EmojiProviderManifest): ProviderValidationResult;
247
+ declare function createManifestProvider(manifest: EmojiProviderManifest, options?: ManifestProviderOptions): EmojiAssetProvider;
248
+ declare function createGeneratedProvider(manifest: EmojiProviderManifest, options?: ManifestProviderOptions): EmojiAssetProvider;
249
+
250
+ interface CompositeProviderOptions {
251
+ id: string;
252
+ label: string;
253
+ version: string;
254
+ providers: readonly EmojiAssetProvider[];
255
+ visibility?: ProviderVisibility;
256
+ license?: ProviderLicense;
257
+ }
258
+ declare function createCompositeProvider(options: CompositeProviderOptions): EmojiAssetProvider;
259
+
260
+ type EmojiConfigProviderRef = EmojiProviderRef | string;
261
+ /** Runtime subset shared by project config files and framework adapters. */
262
+ interface EmojiStylesConfig {
263
+ provider?: EmojiConfigProviderRef;
264
+ fallbacks?: readonly EmojiConfigProviderRef[];
265
+ nativeFallback?: boolean;
266
+ }
267
+ /**
268
+ * Validate and freeze the runtime policy exported by `emoji-styles.config.ts`.
269
+ * Extra CLI-only fields remain structurally compatible when a JSON config is imported.
270
+ */
271
+ declare function defineEmojiConfig<T extends EmojiStylesConfig>(config: T): Readonly<T>;
272
+
273
+ interface EmojiTextToken {
274
+ type: "emoji" | "text";
275
+ value: string;
276
+ }
277
+ /** Split text into supported emoji graphemes and ordinary text. */
278
+ declare function tokenizeEmojiText(text: string): EmojiTextToken[];
279
+
280
+ declare const EMOJI_THEME_SCHEMA_VERSION: 1;
281
+ declare const EMOJI_TOKEN_NAME_PATTERN: RegExp;
282
+ type EmojiThemeProviderRef = EmojiProviderRef | string;
283
+ interface EmojiTokenAsset {
284
+ url: string;
285
+ format: EmojiAssetFormat;
286
+ local?: boolean;
287
+ providerId?: string;
288
+ providerVersion?: string;
289
+ width?: number;
290
+ height?: number;
291
+ checksum?: string;
292
+ license?: ProviderLicense;
293
+ }
294
+ interface EmojiTokenDefinitionInput {
295
+ emoji: string;
296
+ label: string;
297
+ decorative?: boolean;
298
+ labels?: Readonly<Record<string, string>>;
299
+ provider?: EmojiThemeProviderRef;
300
+ /** Stable semantic asset id resolved by a SemanticTokenProvider, or an exact asset. */
301
+ asset?: string | EmojiTokenAsset;
302
+ }
303
+ interface EmojiTokenDefinition extends EmojiTokenDefinitionInput {
304
+ decorative: boolean;
305
+ }
306
+ type EmojiTokenMapInput = Readonly<Record<string, EmojiTokenDefinitionInput>>;
307
+ type EmojiTokenMap = Readonly<Record<string, EmojiTokenDefinition>>;
308
+ interface EmojiTheme {
309
+ schemaVersion: typeof EMOJI_THEME_SCHEMA_VERSION;
310
+ id: string;
311
+ version: string;
312
+ tokens: EmojiTokenMap;
313
+ defaultProvider?: EmojiThemeProviderRef;
314
+ fallbacks?: readonly EmojiThemeProviderRef[];
315
+ /** Whether native OS emoji is appended as the terminal fallback. Defaults to true. */
316
+ nativeFallback?: boolean;
317
+ inherits: readonly string[];
318
+ }
319
+ interface DefineEmojiThemeOptions {
320
+ id?: string;
321
+ version?: string;
322
+ defaultProvider?: EmojiThemeProviderRef;
323
+ fallbacks?: readonly EmojiThemeProviderRef[];
324
+ nativeFallback?: boolean;
325
+ extends?: EmojiTheme | readonly EmojiTheme[];
326
+ /** Preserved ancestry metadata when parsing a flattened serialized theme. */
327
+ inherits?: readonly string[];
328
+ }
329
+ interface EmojiThemeValidationIssue {
330
+ path: string;
331
+ code: string;
332
+ message: string;
333
+ }
334
+ interface EmojiThemeValidationResult {
335
+ valid: boolean;
336
+ errors: string[];
337
+ warnings: string[];
338
+ issues: EmojiThemeValidationIssue[];
339
+ }
340
+ interface ResolveEmojiTokenOptions {
341
+ provider?: EmojiThemeProviderRef;
342
+ fallbacks?: readonly EmojiThemeProviderRef[];
343
+ nativeFallback?: boolean;
344
+ locale?: string;
345
+ providers?: Readonly<Record<string, EmojiAssetProvider>>;
346
+ }
347
+ interface ResolvedEmojiToken {
348
+ token: string;
349
+ themeId: string;
350
+ themeVersion: string;
351
+ emoji: string;
352
+ label: string;
353
+ decorative: boolean;
354
+ locale?: string;
355
+ asset: ResolvedEmojiAsset | null;
356
+ emojiResolution: EmojiResolution | null;
357
+ source: "custom-asset" | "semantic-provider" | "emoji-provider" | "native" | "unresolved";
358
+ }
359
+ interface SemanticTokenResolveContext {
360
+ token: string;
361
+ definition: EmojiTokenDefinition;
362
+ theme: EmojiTheme;
363
+ }
364
+ interface SemanticTokenProvider extends EmojiAssetProvider {
365
+ resolveToken(assetId: string, context: SemanticTokenResolveContext): ProviderResolution;
366
+ }
367
+ interface SemanticTokenProviderOptions {
368
+ id: string;
369
+ label: string;
370
+ version: string;
371
+ assets: Readonly<Record<string, string | EmojiTokenAsset>>;
372
+ fallback?: EmojiAssetProvider;
373
+ format?: EmojiAssetFormat;
374
+ local?: boolean;
375
+ source?: string;
376
+ license?: ProviderLicense;
377
+ visibility?: "public" | "custom";
378
+ }
379
+ interface SerializeEmojiThemeOptions {
380
+ format?: "json" | "typescript";
381
+ space?: number;
382
+ variableName?: string;
383
+ }
384
+ declare function validateEmojiTheme(theme: unknown): EmojiThemeValidationResult;
385
+ declare function defineEmojiTheme(tokens: EmojiTokenMapInput, options?: DefineEmojiThemeOptions): EmojiTheme;
386
+ declare function mergeEmojiThemes(...themes: readonly EmojiTheme[]): EmojiTheme;
387
+ declare function getEmojiTokenDefinition(theme: EmojiTheme, token: string): EmojiTokenDefinition | null;
388
+ declare function getEmojiTokenLabel(definition: EmojiTokenDefinition, locale?: string): string;
389
+ declare function resolveEmojiToken(token: string, theme: EmojiTheme, options?: ResolveEmojiTokenOptions): Promise<ResolvedEmojiToken>;
390
+ declare function createSemanticTokenProvider(options: SemanticTokenProviderOptions): SemanticTokenProvider;
391
+ declare function serializeEmojiTheme(theme: EmojiTheme, options?: SerializeEmojiThemeOptions): string;
392
+ /** Migrate a schema-less v0 theme or parse a current serialized theme. */
393
+ declare function migrateEmojiTheme(input: unknown): EmojiTheme;
394
+ declare const parseEmojiTheme: typeof migrateEmojiTheme;
395
+
396
+ declare function validateProvider(provider: EmojiAssetProvider): ProviderValidationResult;
397
+
398
+ declare function resolveProvider(provider: EmojiProviderRef): EmojiAssetProvider | null;
399
+ /** Resolve an emoji through a built-in style or a custom asset provider. */
400
+ declare function getEmojiUrl(emoji: string, providerRef: EmojiProviderRef): string | null;
401
+ /**
402
+ * Build a fallback chain. The default fallback is the publicly licensed Twemoji
403
+ * provider; callers can supply their own ordered provider list.
404
+ */
405
+ declare function getFallbackChain(emoji: string, primary: EmojiProviderRef, fallbacks?: readonly EmojiProviderRef[]): string[];
406
+ declare function hasEmoji(emoji: string): boolean;
407
+ declare function getAvailableEmojis(): string[];
408
+ /** @deprecated Use getEmojiMetadata for the normalized v2 metadata contract. */
409
+ declare function getEmojiData(emoji: string): emoji_styles_data.EmojiMetadata | null;
410
+
411
+ export { type CdnProviderOptions, type CompositeProviderOptions, type DefineEmojiThemeOptions, EMOJI_THEME_SCHEMA_VERSION, EMOJI_TOKEN_NAME_PATTERN, type EmojiAssetFormat, type EmojiAssetMap, type EmojiAssetProvider, type EmojiConfigProviderRef, type EmojiData, type EmojiProviderGenerator, type EmojiProviderManifest, type EmojiProviderManifestAsset, type EmojiProviderRef, type EmojiResolution, type EmojiResolutionAttempt, type EmojiSize, type EmojiStyle, type EmojiStylesConfig, type EmojiTextToken, type EmojiTheme, type EmojiThemeProviderRef, type EmojiThemeValidationIssue, type EmojiThemeValidationResult, type EmojiTokenAsset, type EmojiTokenDefinition, type EmojiTokenDefinitionInput, type EmojiTokenMap, type EmojiTokenMapInput, type LegacyEmojiAssetProvider, type LegacyProviderAdapterOptions, type ManifestProviderOptions, type MappedProviderOptions, type NormalizedEmoji, type NormalizedEmojiMetadata, type ProviderConfig, type ProviderCoverage, type ProviderCoverageOptions, type ProviderLicense, type ProviderValidationResult, type ProviderVisibility, type ResolveEmojiOptions, type ResolveEmojiTokenOptions, type ResolvedEmojiAsset, type ResolvedEmojiToken, SIZE_MAP, type SemanticTokenProvider, type SemanticTokenProviderOptions, type SemanticTokenResolveContext, type SerializeEmojiThemeOptions, adaptLegacyProvider, createCdnProvider, createCompositeProvider, createGeneratedProvider, createManifestProvider, createMappedProvider, createNormalizedEmoji, createSemanticTokenProvider, defineEmojiConfig, defineEmojiTheme, experimentalProviders, getAvailableEmojis, getEmojiData, getEmojiMetadata, getEmojiTokenDefinition, getEmojiTokenLabel, getEmojiUrl, getFallbackChain, getProviderCoverage, getTwemojiAssetId, hasEmoji, isEmoji, isV2Provider, mergeEmojiThemes, migrateEmojiTheme, parseEmojiTheme, providers, publicProviders, resolveEmoji, resolveEmojiToken, resolveProvider, serializeEmojiTheme, tokenizeEmojiText, validateEmojiTheme, validateProvider, validateProviderManifest };