@bbn/bbn 2.0.171 → 2.0.172

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.
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Polyfill for:
3
+ * - Intl.Locale (minimal)
4
+ * - Intl.Locale.prototype.getWeekInfo()
5
+ * - Intl.Locale.prototype.weekInfo
6
+ *
7
+ * It does NOT touch DateTimeFormat / RelativeTimeFormat.
8
+ * Those will be handled by FormatJS in setup-intl.ts.
9
+ */
10
+ export interface WeekInfo {
11
+ /** 1 = Monday, 7 = Sunday */
12
+ firstDay: number;
13
+ /** Weekend days as 1–7 (1 = Monday, 7 = Sunday) */
14
+ weekend: number[];
15
+ /** Minimal days required in the first week of the year */
16
+ minimalDays: number;
17
+ }
18
+ /**
19
+ * Call this once after loading any Intl polyfills (FormatJS, etc.).
20
+ */
21
+ export declare function ensureIntlWeekInfoPolyfill(): void;
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Polyfill for:
3
+ * - Intl.Locale (minimal)
4
+ * - Intl.Locale.prototype.getWeekInfo()
5
+ * - Intl.Locale.prototype.weekInfo
6
+ *
7
+ * It does NOT touch DateTimeFormat / RelativeTimeFormat.
8
+ * Those will be handled by FormatJS in setup-intl.ts.
9
+ */
10
+ /* -------------------------------------------------------------------------- */
11
+ /* Helpers */
12
+ /* -------------------------------------------------------------------------- */
13
+ function parseLocaleTag(tag) {
14
+ const str = String(tag !== null && tag !== void 0 ? tag : '');
15
+ const parts = str.split('-').filter(Boolean);
16
+ if (!parts.length) {
17
+ return { language: 'und' };
18
+ }
19
+ let language = parts[0].toLowerCase();
20
+ let script;
21
+ let region;
22
+ for (let i = 1; i < parts.length; i++) {
23
+ const part = parts[i];
24
+ if (!script && part.length === 4) {
25
+ script = part[0].toUpperCase() + part.slice(1).toLowerCase();
26
+ }
27
+ else if (!region && (part.length === 2 || part.length === 3)) {
28
+ region = part.toUpperCase();
29
+ }
30
+ }
31
+ return { language, script, region };
32
+ }
33
+ const REGION_WEEK_INFO = import('../data/weekinfo-overrides.js');
34
+ function computeWeekInfo(localeInstance) {
35
+ var _a, _b, _c;
36
+ const tag = (_c = (_a = localeInstance.baseName) !== null && _a !== void 0 ? _a : (_b = localeInstance.toString) === null || _b === void 0 ? void 0 : _b.call(localeInstance)) !== null && _c !== void 0 ? _c : 'und';
37
+ const { region } = parseLocaleTag(tag);
38
+ const info = (region && REGION_WEEK_INFO[region]) || {
39
+ firstDay: 1,
40
+ weekend: [6, 7],
41
+ minimalDays: 4,
42
+ };
43
+ return {
44
+ firstDay: info.firstDay,
45
+ weekend: info.weekend.slice(),
46
+ minimalDays: info.minimalDays,
47
+ };
48
+ }
49
+ /* -------------------------------------------------------------------------- */
50
+ /* Polyfill entry */
51
+ /* -------------------------------------------------------------------------- */
52
+ function ensureIntlLocalePolyfill() {
53
+ if (typeof Intl === 'undefined') {
54
+ return;
55
+ }
56
+ const hasNativeLocale = typeof Intl.Locale === 'function';
57
+ if (!hasNativeLocale) {
58
+ class PolyfilledLocale {
59
+ constructor(tag) {
60
+ const t = Array.isArray(tag) ? tag[0] : tag;
61
+ const str = String(t !== null && t !== void 0 ? t : 'und');
62
+ const parsed = parseLocaleTag(str);
63
+ this._tag = str;
64
+ this._language = parsed.language;
65
+ this._script = parsed.script;
66
+ this._region = parsed.region;
67
+ }
68
+ toString() {
69
+ return this._tag;
70
+ }
71
+ get baseName() {
72
+ return this._tag;
73
+ }
74
+ get language() {
75
+ return this._language;
76
+ }
77
+ get script() {
78
+ return this._script;
79
+ }
80
+ get region() {
81
+ return this._region;
82
+ }
83
+ getWeekInfo() {
84
+ return computeWeekInfo(this);
85
+ }
86
+ get weekInfo() {
87
+ return computeWeekInfo(this);
88
+ }
89
+ }
90
+ Intl.Locale = PolyfilledLocale;
91
+ }
92
+ const proto = Intl.Locale.prototype;
93
+ if (typeof proto.getWeekInfo !== 'function') {
94
+ proto.getWeekInfo = function getWeekInfo() {
95
+ return computeWeekInfo(this);
96
+ };
97
+ }
98
+ if (!Object.getOwnPropertyDescriptor(proto, 'weekInfo')) {
99
+ Object.defineProperty(proto, 'weekInfo', {
100
+ configurable: true,
101
+ enumerable: true,
102
+ get() {
103
+ if (typeof this.getWeekInfo === 'function') {
104
+ return this.getWeekInfo();
105
+ }
106
+ return computeWeekInfo(this);
107
+ },
108
+ });
109
+ }
110
+ }
111
+ /**
112
+ * Call this once after loading any Intl polyfills (FormatJS, etc.).
113
+ */
114
+ export function ensureIntlWeekInfoPolyfill() {
115
+ ensureIntlLocalePolyfill();
116
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Call this once at startup *before* your app uses Intl.
3
+ *
4
+ * Example:
5
+ * import { setupIntl } from './setup-intl';
6
+ * await setupIntl();
7
+ */
8
+ export default function setupIntl(): Promise<void>;
@@ -0,0 +1,81 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ // setup-intl.ts
11
+ import { ensureIntlWeekInfoPolyfill } from './intl-weekinfo-polyfill.js';
12
+ // ------------------------------
13
+ // Feature detection
14
+ // ------------------------------
15
+ function needsRelativeTimeFormatPolyfill() {
16
+ return typeof Intl === 'undefined' || typeof Intl.RelativeTimeFormat !== 'function';
17
+ }
18
+ /**
19
+ * We ONLY care about style formats (dateStyle/timeStyle).
20
+ * If creating a DateTimeFormat with dateStyle throws, we polyfill.
21
+ */
22
+ function needsDateTimeStylePolyfill() {
23
+ if (typeof Intl === 'undefined' || typeof Intl.DateTimeFormat !== 'function') {
24
+ return true;
25
+ }
26
+ try {
27
+ // If this works, the engine supports style formats well enough.
28
+ // Chrome / modern Firefox / modern Safari pass this.
29
+ new Intl.DateTimeFormat('en', { dateStyle: 'medium' });
30
+ return false;
31
+ }
32
+ catch (_a) {
33
+ // Old Safari, old Firefox, old Chrome, etc.
34
+ return true;
35
+ }
36
+ }
37
+ // ------------------------------
38
+ // Conditional polyfill loader
39
+ // ------------------------------
40
+ /**
41
+ * Call this once at startup *before* your app uses Intl.
42
+ *
43
+ * Example:
44
+ * import { setupIntl } from './setup-intl';
45
+ * await setupIntl();
46
+ */
47
+ export default function setupIntl() {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ const tasks = [];
50
+ // Polyfill RelativeTimeFormat only if missing (old Safari, old Firefox, etc.)
51
+ if (needsRelativeTimeFormatPolyfill()) {
52
+ tasks.push((() => __awaiter(this, void 0, void 0, function* () {
53
+ const rtModule = yield import('@formatjs/intl-relativetimeformat/polyfill.js');
54
+ // Ensure module is evaluated (rtModule is unused but import side-effect matters)
55
+ void rtModule;
56
+ // Add the locales you actually use:
57
+ yield import('@formatjs/intl-relativetimeformat/locale-data/en.js');
58
+ // await import('@formatjs/intl-relativetimeformat/locale-data/it');
59
+ // ...more locales if needed
60
+ }))());
61
+ }
62
+ // Polyfill DateTimeFormat only when style formats are not supported
63
+ if (needsDateTimeStylePolyfill()) {
64
+ tasks.push((() => __awaiter(this, void 0, void 0, function* () {
65
+ const dtModule = yield import('@formatjs/intl-datetimeformat/polyfill.js');
66
+ void dtModule;
67
+ // Optional but common: locale data
68
+ yield import('@formatjs/intl-datetimeformat/locale-data/en.js');
69
+ // await import('@formatjs/intl-datetimeformat/locale-data/it');
70
+ // If you need full timezone data (heavy!):
71
+ // await import('@formatjs/intl-datetimeformat/add-all-tz');
72
+ }))());
73
+ }
74
+ // Wait for all FormatJS polyfills that are actually needed
75
+ if (tasks.length > 0) {
76
+ yield Promise.all(tasks);
77
+ }
78
+ // Finally, always patch weekInfo (Intl.Locale) – Firefox, Chrome, etc.
79
+ ensureIntlWeekInfoPolyfill();
80
+ });
81
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bbn/bbn",
3
- "version": "2.0.171",
3
+ "version": "2.0.172",
4
4
  "description": "Javascript toolkit",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -61,6 +61,8 @@
61
61
  },
62
62
  "dependencies": {
63
63
  "@formatjs/intl-datetimeformat": "^6.18.2",
64
+ "@formatjs/intl-pluralrules": "^5.4.6",
65
+ "@formatjs/intl-relativetimeformat": "^11.4.13",
64
66
  "cldr-core": "^48.0.0",
65
67
  "temporal-polyfill": "^0.3.0"
66
68
  }