@oscarpalmer/atoms 0.82.1 → 0.84.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/dist/color/hex.js CHANGED
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { anyPattern, getNormalisedHex, hexToRgb } from "./functions.js";
4
+ import { getNormalisedHex, anyPattern, hexToRgb } from "./functions.js";
5
5
  class HexColor {
6
6
  constructor(value) {
7
7
  __publicField(this, "state");
package/dist/i18n.cjs ADDED
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var _a, _b, _c;
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
+ const defaults = {
5
+ delimiter: "",
6
+ languages: {
7
+ fallback: null,
8
+ preferred: null
9
+ }
10
+ };
11
+ function getKey(value, languages) {
12
+ if ((languages == null ? void 0 : languages.fallback) == null && (languages == null ? void 0 : languages.preferred) == null) {
13
+ return;
14
+ }
15
+ const { fallback, preferred } = languages;
16
+ switch (true) {
17
+ case (preferred != null && preferred.full in value):
18
+ return preferred.full;
19
+ case (preferred != null && preferred.region != null && preferred.base in value):
20
+ return preferred.base;
21
+ case (fallback != null && fallback.full in value):
22
+ return fallback.full;
23
+ case (fallback != null && fallback.region != null && fallback.base in value):
24
+ return fallback.base;
25
+ }
26
+ }
27
+ function getLanguage(value) {
28
+ if (typeof value !== "string") {
29
+ return;
30
+ }
31
+ const [full, base, region] = /^([a-z]{2,3})(?:-([A-Z]{2}))?$/.exec(value) ?? [];
32
+ if (full != null) {
33
+ return { base, full, region };
34
+ }
35
+ }
36
+ function getTranslation(value, key, delimiter, languages) {
37
+ if (key != null) {
38
+ return translateValue(value[key], delimiter, languages);
39
+ }
40
+ const asString = value.toString();
41
+ return asString === "[object Object]" ? "" : asString;
42
+ }
43
+ function setLanguage(key, value) {
44
+ const language = getLanguage(value);
45
+ if (language != null) {
46
+ defaults.languages[key] = language;
47
+ }
48
+ }
49
+ function translate(value, options) {
50
+ let delimiter = defaults.delimiter;
51
+ let languages = defaults.languages;
52
+ if (options != null) {
53
+ delimiter = typeof options.delimiter === "string" ? options.delimiter : defaults.delimiter;
54
+ languages = {
55
+ fallback: getLanguage(options.fallback),
56
+ preferred: getLanguage(options.language)
57
+ };
58
+ }
59
+ return translateUnknown(value, delimiter, languages);
60
+ }
61
+ translate.configure = (configuration) => {
62
+ if (typeof configuration.delimiter === "string") {
63
+ defaults.delimiter = configuration.delimiter;
64
+ }
65
+ if (typeof configuration.fallback === "string") {
66
+ setLanguage("fallback", configuration.fallback);
67
+ }
68
+ if (typeof configuration.language === "string") {
69
+ setLanguage("preferred", configuration.language);
70
+ }
71
+ };
72
+ translate.configuration = () => {
73
+ return {
74
+ delimiter: String(defaults.delimiter),
75
+ fallback: String(defaults.languages.fallback.full),
76
+ language: String(defaults.languages.preferred.full)
77
+ };
78
+ };
79
+ function translatePrimitive(value) {
80
+ return value == null ? "" : typeof value === "string" ? value : String(value);
81
+ }
82
+ function translateTranslatable(value, delimiter, languages) {
83
+ if (Array.isArray(value)) {
84
+ return value.map((item) => translateValue(item, delimiter, languages)).filter((translated) => translated.trim().length > 0).join(delimiter);
85
+ }
86
+ return getTranslation(
87
+ value,
88
+ getKey(value, languages) ?? getKey(value, defaults.languages),
89
+ delimiter,
90
+ languages
91
+ );
92
+ }
93
+ function translateUnknown(value, delimiter, languages) {
94
+ return typeof value !== "object" || value == null ? translateValue(value, delimiter, languages) : translateTranslatable(
95
+ value,
96
+ delimiter,
97
+ languages
98
+ );
99
+ }
100
+ function translateValue(value, delimiter, languages) {
101
+ let actual = value;
102
+ if (typeof value === "function") {
103
+ actual = value();
104
+ if (typeof actual === "function") {
105
+ return "";
106
+ }
107
+ }
108
+ if (Array.isArray(actual)) {
109
+ return translateTranslatable(actual, delimiter, languages);
110
+ }
111
+ if (typeof actual === "object" && actual != null) {
112
+ const asString = actual.toString();
113
+ return asString === "[object Object]" ? translateTranslatable(actual, delimiter, languages) : asString;
114
+ }
115
+ return translatePrimitive(actual);
116
+ }
117
+ const defaultLanguage = (((_c = (_b = (_a = document == null ? void 0 : document.documentElement) == null ? void 0 : _a.lang) == null ? void 0 : _b.trim()) == null ? void 0 : _c.length) ?? 0) > 0 ? document.documentElement.lang : (navigator == null ? void 0 : navigator.language) ?? "en";
118
+ setLanguage("fallback", defaultLanguage);
119
+ setLanguage("preferred", defaultLanguage);
120
+ exports.translate = translate;
package/dist/i18n.js ADDED
@@ -0,0 +1,120 @@
1
+ var _a, _b, _c;
2
+ const defaults = {
3
+ delimiter: "",
4
+ languages: {
5
+ fallback: null,
6
+ preferred: null
7
+ }
8
+ };
9
+ function getKey(value, languages) {
10
+ if ((languages == null ? void 0 : languages.fallback) == null && (languages == null ? void 0 : languages.preferred) == null) {
11
+ return;
12
+ }
13
+ const { fallback, preferred } = languages;
14
+ switch (true) {
15
+ case (preferred != null && preferred.full in value):
16
+ return preferred.full;
17
+ case (preferred != null && preferred.region != null && preferred.base in value):
18
+ return preferred.base;
19
+ case (fallback != null && fallback.full in value):
20
+ return fallback.full;
21
+ case (fallback != null && fallback.region != null && fallback.base in value):
22
+ return fallback.base;
23
+ }
24
+ }
25
+ function getLanguage(value) {
26
+ if (typeof value !== "string") {
27
+ return;
28
+ }
29
+ const [full, base, region] = /^([a-z]{2,3})(?:-([A-Z]{2}))?$/.exec(value) ?? [];
30
+ if (full != null) {
31
+ return { base, full, region };
32
+ }
33
+ }
34
+ function getTranslation(value, key, delimiter, languages) {
35
+ if (key != null) {
36
+ return translateValue(value[key], delimiter, languages);
37
+ }
38
+ const asString = value.toString();
39
+ return asString === "[object Object]" ? "" : asString;
40
+ }
41
+ function setLanguage(key, value) {
42
+ const language = getLanguage(value);
43
+ if (language != null) {
44
+ defaults.languages[key] = language;
45
+ }
46
+ }
47
+ function translate(value, options) {
48
+ let delimiter = defaults.delimiter;
49
+ let languages = defaults.languages;
50
+ if (options != null) {
51
+ delimiter = typeof options.delimiter === "string" ? options.delimiter : defaults.delimiter;
52
+ languages = {
53
+ fallback: getLanguage(options.fallback),
54
+ preferred: getLanguage(options.language)
55
+ };
56
+ }
57
+ return translateUnknown(value, delimiter, languages);
58
+ }
59
+ translate.configure = (configuration) => {
60
+ if (typeof configuration.delimiter === "string") {
61
+ defaults.delimiter = configuration.delimiter;
62
+ }
63
+ if (typeof configuration.fallback === "string") {
64
+ setLanguage("fallback", configuration.fallback);
65
+ }
66
+ if (typeof configuration.language === "string") {
67
+ setLanguage("preferred", configuration.language);
68
+ }
69
+ };
70
+ translate.configuration = () => {
71
+ return {
72
+ delimiter: String(defaults.delimiter),
73
+ fallback: String(defaults.languages.fallback.full),
74
+ language: String(defaults.languages.preferred.full)
75
+ };
76
+ };
77
+ function translatePrimitive(value) {
78
+ return value == null ? "" : typeof value === "string" ? value : String(value);
79
+ }
80
+ function translateTranslatable(value, delimiter, languages) {
81
+ if (Array.isArray(value)) {
82
+ return value.map((item) => translateValue(item, delimiter, languages)).filter((translated) => translated.trim().length > 0).join(delimiter);
83
+ }
84
+ return getTranslation(
85
+ value,
86
+ getKey(value, languages) ?? getKey(value, defaults.languages),
87
+ delimiter,
88
+ languages
89
+ );
90
+ }
91
+ function translateUnknown(value, delimiter, languages) {
92
+ return typeof value !== "object" || value == null ? translateValue(value, delimiter, languages) : translateTranslatable(
93
+ value,
94
+ delimiter,
95
+ languages
96
+ );
97
+ }
98
+ function translateValue(value, delimiter, languages) {
99
+ let actual = value;
100
+ if (typeof value === "function") {
101
+ actual = value();
102
+ if (typeof actual === "function") {
103
+ return "";
104
+ }
105
+ }
106
+ if (Array.isArray(actual)) {
107
+ return translateTranslatable(actual, delimiter, languages);
108
+ }
109
+ if (typeof actual === "object" && actual != null) {
110
+ const asString = actual.toString();
111
+ return asString === "[object Object]" ? translateTranslatable(actual, delimiter, languages) : asString;
112
+ }
113
+ return translatePrimitive(actual);
114
+ }
115
+ const defaultLanguage = (((_c = (_b = (_a = document == null ? void 0 : document.documentElement) == null ? void 0 : _a.lang) == null ? void 0 : _b.trim()) == null ? void 0 : _c.length) ?? 0) > 0 ? document.documentElement.lang : (navigator == null ? void 0 : navigator.language) ?? "en";
116
+ setLanguage("fallback", defaultLanguage);
117
+ setLanguage("preferred", defaultLanguage);
118
+ export {
119
+ translate
120
+ };
package/dist/index.cjs CHANGED
@@ -4,6 +4,7 @@ const array_index = require("./array/index.cjs");
4
4
  const color_index = require("./color/index.cjs");
5
5
  const emitter = require("./emitter.cjs");
6
6
  const _function = require("./function.cjs");
7
+ const i18n = require("./i18n.cjs");
7
8
  const is = require("./is.cjs");
8
9
  const logger = require("./logger.cjs");
9
10
  const math = require("./math.cjs");
@@ -54,6 +55,7 @@ exports.debounce = _function.debounce;
54
55
  exports.memoise = _function.memoise;
55
56
  exports.noop = _function.noop;
56
57
  exports.throttle = _function.throttle;
58
+ exports.translate = i18n.translate;
57
59
  exports.isArrayOrPlainObject = is.isArrayOrPlainObject;
58
60
  exports.isEmpty = is.isEmpty;
59
61
  exports.isKey = is.isKey;
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import { flatten, push } from "./array/index.js";
2
2
  import { getForegroundColor } from "./color/index.js";
3
3
  import { emitter } from "./emitter.js";
4
4
  import { debounce, memoise, noop, throttle } from "./function.js";
5
+ import { translate } from "./i18n.js";
5
6
  import { isArrayOrPlainObject, isEmpty, isKey, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isPlainObject, isPrimitive } from "./is.js";
6
7
  import { logger } from "./logger.js";
7
8
  import { average, max, min, round, sum } from "./math.js";
@@ -134,6 +135,7 @@ export {
134
135
  toMap,
135
136
  toQuery,
136
137
  toRecord,
138
+ translate,
137
139
  truncate,
138
140
  unique,
139
141
  unsmush,
package/package.json CHANGED
@@ -9,13 +9,13 @@
9
9
  "description": "Atomic utilities for making your JavaScript better.",
10
10
  "devDependencies": {
11
11
  "@biomejs/biome": "^1.9",
12
- "@types/node": "^22.12",
12
+ "@types/node": "^22.13",
13
13
  "@vitest/coverage-istanbul": "^3",
14
14
  "dts-bundle-generator": "^9.5",
15
15
  "glob": "^11",
16
- "happy-dom": "^16.7",
16
+ "happy-dom": "^17",
17
17
  "typescript": "^5.7",
18
- "vite": "^6",
18
+ "vite": "^6.1",
19
19
  "vitest": "^3"
20
20
  },
21
21
  "exports": {
@@ -70,6 +70,16 @@
70
70
  "default": "./dist/function.cjs"
71
71
  }
72
72
  },
73
+ "./i18n": {
74
+ "import": {
75
+ "types": "./types/i18n.d.ts",
76
+ "default": "./dist/i18n.js"
77
+ },
78
+ "require": {
79
+ "types": "./types/i18n.d.cts",
80
+ "default": "./dist/i18n.cjs"
81
+ }
82
+ },
73
83
  "./is": {
74
84
  "import": {
75
85
  "types": "./types/is.d.ts",
@@ -179,15 +189,8 @@
179
189
  }
180
190
  }
181
191
  },
182
- "files": [
183
- "dist",
184
- "src",
185
- "types"
186
- ],
187
- "keywords": [
188
- "helper",
189
- "utility"
190
- ],
192
+ "files": ["dist", "src", "types"],
193
+ "keywords": ["helper", "utility"],
191
194
  "license": "MIT",
192
195
  "main": "./dist/index.cjs",
193
196
  "module": "./dist/index.js",
@@ -205,5 +208,5 @@
205
208
  },
206
209
  "type": "module",
207
210
  "types": "./types/index.d.cts",
208
- "version": "0.82.1"
211
+ "version": "0.84.0"
209
212
  }
package/src/i18n.ts ADDED
@@ -0,0 +1,300 @@
1
+ import {isPlainObject} from './is';
2
+ import type {PlainObject, Primitive} from './models';
3
+
4
+ type Defaults = {
5
+ /**
6
+ * Delimiter to use when translating an array of translatable values
7
+ */
8
+ delimiter: string;
9
+ /**
10
+ * Languages to use when translating
11
+ */
12
+ languages: Languages;
13
+ };
14
+
15
+ type Language = {
16
+ /**
17
+ * Language code _(e.g. `en`, `es`, `fr`, `ja`, `zh`)_
18
+ */
19
+ readonly base: string;
20
+ /**
21
+ * Language code with region _(e.g. `en-US`, `es-ES`, `fr-FR`, `ja-JP`, `zh-CN`)_
22
+ */
23
+ readonly full: string;
24
+ /**
25
+ * Region code _(e.g. `US`, `ES`, `FR`, `JP`, `CN`)_
26
+ */
27
+ readonly region?: string;
28
+ };
29
+
30
+ type Languages = {
31
+ /**
32
+ * Language to use when no translation is found
33
+ */
34
+ fallback: Language;
35
+ /**
36
+ * Language to use when translating
37
+ */
38
+ preferred: Language;
39
+ };
40
+
41
+ type TranslateConfiguration = TranslateOptions;
42
+
43
+ export type TranslateOptions = {
44
+ /**
45
+ * Delimiter to use when translating an array of translatable values
46
+ */
47
+ delimiter: string;
48
+ /**
49
+ * Language to use when no translation is found
50
+ */
51
+ fallback: string;
52
+ /**
53
+ * Language to use when translating
54
+ */
55
+ language: string;
56
+ };
57
+
58
+ /**
59
+ * A translatable object
60
+ */
61
+ export type Translatable = Record<string, unknown>;
62
+
63
+ const defaults: Defaults = {
64
+ delimiter: '',
65
+ languages: {
66
+ fallback: null as never,
67
+ preferred: null as never,
68
+ },
69
+ };
70
+
71
+ /**
72
+ * Get translation key for a translatable object
73
+ */
74
+ function getKey(
75
+ value: PlainObject,
76
+ languages: Partial<Languages>,
77
+ ): string | undefined {
78
+ if (languages?.fallback == null && languages?.preferred == null) {
79
+ return;
80
+ }
81
+
82
+ const {fallback, preferred} = languages;
83
+
84
+ switch (true) {
85
+ case preferred != null && preferred.full in value:
86
+ return preferred.full;
87
+
88
+ case preferred != null &&
89
+ preferred.region != null &&
90
+ preferred.base in value:
91
+ return preferred.base;
92
+
93
+ case fallback != null && fallback.full in value:
94
+ return fallback.full;
95
+
96
+ case fallback != null && fallback.region != null && fallback.base in value:
97
+ return fallback.base;
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Get a _Language_ from a value
103
+ */
104
+ function getLanguage(value: unknown): Language | undefined {
105
+ if (typeof value !== 'string') {
106
+ return;
107
+ }
108
+
109
+ const [full, base, region] =
110
+ /^([a-z]{2,3})(?:-([A-Z]{2}))?$/.exec(value) ?? [];
111
+
112
+ if (full != null) {
113
+ return {base, full, region};
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Get translation for a key from a translatable object
119
+ */
120
+ function getTranslation(
121
+ value: PlainObject,
122
+ key: string | undefined,
123
+ delimiter: string,
124
+ languages: Partial<Languages>,
125
+ ): string {
126
+ if (key != null) {
127
+ return translateValue((value as PlainObject)[key], delimiter, languages);
128
+ }
129
+
130
+ const asString = value.toString();
131
+
132
+ return asString === '[object Object]' ? '' : asString;
133
+ }
134
+
135
+ /**
136
+ * Set a _Language_ for a key
137
+ */
138
+ function setLanguage(key: keyof Languages, value: string): void {
139
+ const language = getLanguage(value);
140
+
141
+ if (language != null) {
142
+ defaults.languages[key] = language;
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Translates a value _(with optional options, but defaulting to configuration)_
148
+ */
149
+ export function translate(
150
+ value: unknown,
151
+ options?: Partial<TranslateOptions>,
152
+ ): string;
153
+
154
+ /**
155
+ * Translates an array of values _(with optional options, but defaulting to configuration)_
156
+ */
157
+ export function translate(
158
+ value: unknown[],
159
+ options?: Partial<TranslateOptions>,
160
+ ): string;
161
+
162
+ export function translate(
163
+ value: unknown | unknown[],
164
+ options?: Partial<TranslateOptions>,
165
+ ): string {
166
+ let delimiter = defaults.delimiter;
167
+ let languages: Partial<Languages> = defaults.languages;
168
+
169
+ if (options != null) {
170
+ delimiter =
171
+ typeof options.delimiter === 'string'
172
+ ? options.delimiter
173
+ : defaults.delimiter;
174
+
175
+ languages = {
176
+ fallback: getLanguage(options.fallback),
177
+ preferred: getLanguage(options.language),
178
+ };
179
+ }
180
+
181
+ return translateUnknown(value, delimiter, languages);
182
+ }
183
+
184
+ /**
185
+ * Configures the translation options _(used as defaults when translating)_
186
+ */
187
+ translate.configure = (
188
+ configuration: Partial<TranslateConfiguration>,
189
+ ): void => {
190
+ if (typeof configuration.delimiter === 'string') {
191
+ defaults.delimiter = configuration.delimiter;
192
+ }
193
+
194
+ if (typeof configuration.fallback === 'string') {
195
+ setLanguage('fallback', configuration.fallback);
196
+ }
197
+
198
+ if (typeof configuration.language === 'string') {
199
+ setLanguage('preferred', configuration.language);
200
+ }
201
+ };
202
+
203
+ /**
204
+ * Gets the current translation configuration
205
+ */
206
+ translate.configuration = (): TranslateConfiguration => {
207
+ return {
208
+ delimiter: String(defaults.delimiter),
209
+ fallback: String(defaults.languages.fallback.full),
210
+ language: String(defaults.languages.preferred.full),
211
+ };
212
+ };
213
+
214
+ /**
215
+ * Translates a primitive value into a string
216
+ */
217
+ function translatePrimitive(value: Primitive): string {
218
+ return value == null ? '' : typeof value === 'string' ? value : String(value);
219
+ }
220
+
221
+ /**
222
+ * Translates a translatable object _(or array of translatable objects)_ into a string
223
+ */
224
+ function translateTranslatable(
225
+ value: PlainObject | PlainObject[],
226
+ delimiter: string,
227
+ languages: Partial<Languages>,
228
+ ): string {
229
+ if (Array.isArray(value)) {
230
+ return value
231
+ .map(item => translateValue(item, delimiter, languages))
232
+ .filter(translated => translated.trim().length > 0)
233
+ .join(delimiter);
234
+ }
235
+
236
+ return getTranslation(
237
+ value,
238
+ getKey(value, languages) ?? getKey(value, defaults.languages),
239
+ delimiter,
240
+ languages,
241
+ );
242
+ }
243
+
244
+ /**
245
+ * Translates a value _(into a string)_
246
+ */
247
+ function translateUnknown(
248
+ value: unknown,
249
+ delimiter: string,
250
+ languages: Partial<Languages>,
251
+ ): string {
252
+ return typeof value !== 'object' || value == null
253
+ ? translateValue(value, delimiter, languages)
254
+ : translateTranslatable(
255
+ value as PlainObject | PlainObject[],
256
+ delimiter,
257
+ languages,
258
+ );
259
+ }
260
+
261
+ /**
262
+ * Translates a value _(into a string)_
263
+ */
264
+ function translateValue(
265
+ value: unknown,
266
+ delimiter: string,
267
+ languages: Partial<Languages>,
268
+ ): string {
269
+ let actual = value;
270
+
271
+ if (typeof value === 'function') {
272
+ actual = value();
273
+
274
+ if (typeof actual === 'function') {
275
+ return '';
276
+ }
277
+ }
278
+
279
+ if (Array.isArray(actual)) {
280
+ return translateTranslatable(actual, delimiter, languages);
281
+ }
282
+
283
+ if (typeof actual === 'object' && actual != null) {
284
+ const asString = actual.toString();
285
+
286
+ return asString === '[object Object]'
287
+ ? translateTranslatable(actual as PlainObject, delimiter, languages)
288
+ : asString;
289
+ }
290
+
291
+ return translatePrimitive(actual as Primitive);
292
+ }
293
+
294
+ const defaultLanguage =
295
+ (document?.documentElement?.lang?.trim()?.length ?? 0) > 0
296
+ ? document.documentElement.lang
297
+ : (navigator?.language ?? 'en');
298
+
299
+ setLanguage('fallback', defaultLanguage);
300
+ setLanguage('preferred', defaultLanguage);
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ export * from './array/index';
2
2
  export * from './color/index';
3
3
  export * from './emitter';
4
4
  export * from './function';
5
+ export * from './i18n';
5
6
  export * from './is';
6
7
  export * from './logger';
7
8
  export * from './math';
@@ -0,0 +1,35 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ export type TranslateConfiguration = TranslateOptions;
4
+ export type TranslateOptions = {
5
+ /**
6
+ * Delimiter to use when translating an array of translatable values
7
+ */
8
+ delimiter: string;
9
+ /**
10
+ * Language to use when no translation is found
11
+ */
12
+ fallback: string;
13
+ /**
14
+ * Language to use when translating
15
+ */
16
+ language: string;
17
+ };
18
+ /**
19
+ * A translatable object
20
+ */
21
+ export type Translatable = Record<string, unknown>;
22
+ /**
23
+ * Translates a value _(with optional options, but defaulting to configuration)_
24
+ */
25
+ export declare function translate(value: unknown, options?: Partial<TranslateOptions>): string;
26
+ /**
27
+ * Translates an array of values _(with optional options, but defaulting to configuration)_
28
+ */
29
+ export declare function translate(value: unknown[], options?: Partial<TranslateOptions>): string;
30
+ export declare namespace translate {
31
+ var configure: (configuration: Partial<TranslateConfiguration>) => void;
32
+ var configuration: () => TranslateConfiguration;
33
+ }
34
+
35
+ export {};