@multisystemsuite/timezone-engine-angular 1.0.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/index.cjs ADDED
@@ -0,0 +1,244 @@
1
+ 'use strict';
2
+
3
+ var core = require('@angular/core');
4
+ var timezoneEngineCore = require('@multisystemsuite/timezone-engine-core');
5
+ var timezoneEngineWorldData = require('@multisystemsuite/timezone-engine-world-data');
6
+ var rxjs = require('rxjs');
7
+ var common = require('@angular/common');
8
+
9
+ var __defProp = Object.defineProperty;
10
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11
+ var __decorateClass = (decorators, target, key, kind) => {
12
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
13
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
14
+ if (decorator = decorators[i])
15
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
16
+ if (kind && result) __defProp(target, key, result);
17
+ return result;
18
+ };
19
+ var TIMEZONE_ENGINE_CONFIG = new core.InjectionToken(
20
+ "TIMEZONE_ENGINE_CONFIG"
21
+ );
22
+ exports.TimezoneService = class TimezoneService {
23
+ config = core.inject(TIMEZONE_ENGINE_CONFIG, { optional: true }) ?? {};
24
+ engine = timezoneEngineCore.createTimezoneEngine(this.config);
25
+ timezoneSubject = new rxjs.BehaviorSubject(
26
+ this.config.defaultTimezone ?? timezoneEngineCore.detectBrowserTimezone().timezone
27
+ );
28
+ timezone$ = this.timezoneSubject.asObservable();
29
+ get timezone() {
30
+ return this.timezoneSubject.value;
31
+ }
32
+ setTimezone(tz) {
33
+ this.timezoneSubject.next(tz);
34
+ this.engine.config.update({ defaultTimezone: tz });
35
+ }
36
+ detectTimezone() {
37
+ return timezoneEngineCore.detectBrowserTimezone().timezone;
38
+ }
39
+ getUserTimezone() {
40
+ return timezoneEngineCore.getUserTimezone();
41
+ }
42
+ formatDate(date, options = {}) {
43
+ return timezoneEngineCore.formatDate(date, { timezone: this.timezone, ...options });
44
+ }
45
+ convertTimezone(sourceTimezone, targetTimezone, date) {
46
+ return timezoneEngineCore.convertTimezone({
47
+ sourceTimezone,
48
+ targetTimezone,
49
+ ...date !== void 0 ? { date } : {}
50
+ });
51
+ }
52
+ compareTimezones(source, target, date) {
53
+ return timezoneEngineCore.compareTimezones(source, target, date);
54
+ }
55
+ getWorldClock(timezones) {
56
+ return timezoneEngineCore.getWorldClock(timezones);
57
+ }
58
+ getCountryTimezones(countryCode) {
59
+ return timezoneEngineWorldData.getCountryTimezones(countryCode);
60
+ }
61
+ getCityTimezone(city) {
62
+ return timezoneEngineWorldData.getCityTimezone(city);
63
+ }
64
+ getEngine() {
65
+ return this.engine;
66
+ }
67
+ };
68
+ exports.TimezoneService = __decorateClass([
69
+ core.Injectable({ providedIn: "root" })
70
+ ], exports.TimezoneService);
71
+ exports.WorldClockService = class WorldClockService {
72
+ timezoneService = core.inject(exports.TimezoneService);
73
+ createLiveClock(timezones, intervalMs = 1e3) {
74
+ return new rxjs.Observable((subscriber) => {
75
+ const updater = timezoneEngineCore.createLiveClockUpdater(
76
+ timezones,
77
+ (clocks) => {
78
+ subscriber.next(clocks);
79
+ },
80
+ intervalMs
81
+ );
82
+ updater.start();
83
+ return () => {
84
+ updater.stop();
85
+ };
86
+ });
87
+ }
88
+ };
89
+ exports.WorldClockService = __decorateClass([
90
+ core.Injectable({ providedIn: "root" })
91
+ ], exports.WorldClockService);
92
+ exports.TeFormatDatePipe = class TeFormatDatePipe {
93
+ timezoneService = core.inject(exports.TimezoneService);
94
+ transform(value, format = "DATETIME", timezone, locale) {
95
+ if (value == null) return "";
96
+ const options = { format };
97
+ if (timezone !== void 0) options.timezone = timezone;
98
+ if (locale !== void 0) options.locale = locale;
99
+ return this.timezoneService.formatDate(value, options);
100
+ }
101
+ };
102
+ exports.TeFormatDatePipe = __decorateClass([
103
+ core.Pipe({ name: "teFormatDate", standalone: true, pure: false })
104
+ ], exports.TeFormatDatePipe);
105
+ exports.TeRelativeTimePipe = class TeRelativeTimePipe {
106
+ transform(value) {
107
+ if (value == null) return "";
108
+ return timezoneEngineCore.formatRelativeTime(value);
109
+ }
110
+ };
111
+ exports.TeRelativeTimePipe = __decorateClass([
112
+ core.Pipe({ name: "teRelativeTime", standalone: true })
113
+ ], exports.TeRelativeTimePipe);
114
+ exports.TeTimezonePipe = class TeTimezonePipe {
115
+ timezoneService = core.inject(exports.TimezoneService);
116
+ transform(value, targetTimezone, sourceTimezone) {
117
+ if (value == null) return null;
118
+ const source = sourceTimezone ?? this.timezoneService.timezone;
119
+ return this.timezoneService.convertTimezone(source, targetTimezone, value);
120
+ }
121
+ };
122
+ exports.TeTimezonePipe = __decorateClass([
123
+ core.Pipe({ name: "teTimezone", standalone: true })
124
+ ], exports.TeTimezonePipe);
125
+ exports.WorldClockComponent = class WorldClockComponent {
126
+ timezones = ["UTC", "America/New_York", "Europe/London", "Asia/Kolkata"];
127
+ intervalMs = 1e3;
128
+ clocks = [];
129
+ worldClockService = core.inject(exports.WorldClockService);
130
+ subscription;
131
+ ngOnInit() {
132
+ this.subscription = this.worldClockService.createLiveClock(this.timezones, this.intervalMs).subscribe((clocks) => {
133
+ this.clocks = clocks;
134
+ });
135
+ }
136
+ ngOnDestroy() {
137
+ this.subscription?.unsubscribe();
138
+ }
139
+ };
140
+ __decorateClass([
141
+ core.Input()
142
+ ], exports.WorldClockComponent.prototype, "timezones", 2);
143
+ __decorateClass([
144
+ core.Input()
145
+ ], exports.WorldClockComponent.prototype, "intervalMs", 2);
146
+ exports.WorldClockComponent = __decorateClass([
147
+ core.Component({
148
+ selector: "te-world-clock",
149
+ standalone: true,
150
+ imports: [common.CommonModule],
151
+ template: `
152
+ <div class="te-clock" data-testid="world-clock">
153
+ @for (clock of clocks; track clock.timezone) {
154
+ <div class="te-clock__entry">
155
+ <strong>{{ clock.label }}</strong>
156
+ <span>{{ clock.formattedTime }}</span>
157
+ <small>{{ clock.utcOffset }}</small>
158
+ </div>
159
+ }
160
+ </div>
161
+ `
162
+ })
163
+ ], exports.WorldClockComponent);
164
+ exports.LiveClockComponent = class LiveClockComponent {
165
+ timezone;
166
+ intervalMs = 1e3;
167
+ display = "";
168
+ timezoneService = core.inject(exports.TimezoneService);
169
+ timerId;
170
+ ngOnInit() {
171
+ const tz = this.timezone ?? this.timezoneService.timezone;
172
+ const update = () => {
173
+ this.display = this.timezoneService.formatDate(/* @__PURE__ */ new Date(), {
174
+ format: "TIME_ONLY",
175
+ timezone: tz
176
+ });
177
+ };
178
+ update();
179
+ this.timerId = setInterval(update, this.intervalMs);
180
+ }
181
+ ngOnDestroy() {
182
+ if (this.timerId !== void 0) clearInterval(this.timerId);
183
+ }
184
+ };
185
+ __decorateClass([
186
+ core.Input()
187
+ ], exports.LiveClockComponent.prototype, "timezone", 2);
188
+ __decorateClass([
189
+ core.Input()
190
+ ], exports.LiveClockComponent.prototype, "intervalMs", 2);
191
+ exports.LiveClockComponent = __decorateClass([
192
+ core.Component({
193
+ selector: "te-live-clock",
194
+ standalone: true,
195
+ template: `<span class="te-live-clock">{{ display }}</span>`
196
+ })
197
+ ], exports.LiveClockComponent);
198
+ exports.SchedulerComponent = class SchedulerComponent {
199
+ participants = [];
200
+ durationMinutes = 60;
201
+ get participantTimezones() {
202
+ return [...new Set(this.participants.map((p) => p.timezone))];
203
+ }
204
+ };
205
+ __decorateClass([
206
+ core.Input()
207
+ ], exports.SchedulerComponent.prototype, "participants", 2);
208
+ __decorateClass([
209
+ core.Input()
210
+ ], exports.SchedulerComponent.prototype, "durationMinutes", 2);
211
+ exports.SchedulerComponent = __decorateClass([
212
+ core.Component({
213
+ selector: "te-scheduler",
214
+ standalone: true,
215
+ imports: [common.CommonModule, exports.WorldClockComponent],
216
+ template: `
217
+ <div class="te-scheduler">
218
+ <h3 class="te-scheduler__title">Meeting Scheduler</h3>
219
+ <p>Duration: {{ durationMinutes }} minutes</p>
220
+ <ul>
221
+ @for (p of participants; track p.name) {
222
+ <li>{{ p.name }} \u2014 {{ p.timezone }}</li>
223
+ }
224
+ </ul>
225
+ <te-world-clock [timezones]="participantTimezones" />
226
+ </div>
227
+ `
228
+ })
229
+ ], exports.SchedulerComponent);
230
+
231
+ // src/index.ts
232
+ var TIMEZONE_ENGINE_IMPORTS = [
233
+ exports.TeFormatDatePipe,
234
+ exports.TeRelativeTimePipe,
235
+ exports.TeTimezonePipe,
236
+ exports.WorldClockComponent,
237
+ exports.LiveClockComponent,
238
+ exports.SchedulerComponent
239
+ ];
240
+
241
+ exports.TIMEZONE_ENGINE_CONFIG = TIMEZONE_ENGINE_CONFIG;
242
+ exports.TIMEZONE_ENGINE_IMPORTS = TIMEZONE_ENGINE_IMPORTS;
243
+ //# sourceMappingURL=index.cjs.map
244
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/timezone.service.ts","../src/pipes.ts","../src/components.ts","../src/index.ts"],"names":["InjectionToken","TimezoneService","inject","createTimezoneEngine","BehaviorSubject","detectBrowserTimezone","getUserTimezone","formatDate","convertTimezone","compareTimezones","getWorldClock","getCountryTimezones","getCityTimezone","Injectable","WorldClockService","Observable","createLiveClockUpdater","TeFormatDatePipe","Pipe","TeRelativeTimePipe","formatRelativeTime","TeTimezonePipe","WorldClockComponent","Input","Component","CommonModule","LiveClockComponent","SchedulerComponent"],"mappings":"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","file":"index.cjs","sourcesContent":["import { Injectable, InjectionToken, inject } from \"@angular/core\";\nimport type {\n FormatDateOptions,\n TimezoneEngineConfig,\n WorldClockEntry,\n} from \"@multisystemsuite/timezone-engine-shared-types\";\nimport {\n createTimezoneEngine,\n detectBrowserTimezone,\n formatDate,\n convertTimezone,\n compareTimezones,\n getWorldClock,\n createLiveClockUpdater,\n getUserTimezone,\n type TimezoneEngine,\n} from \"@multisystemsuite/timezone-engine-core\";\nimport { getCountryTimezones, getCityTimezone } from \"@multisystemsuite/timezone-engine-world-data\";\nimport { BehaviorSubject, Observable } from \"rxjs\";\n\nexport const TIMEZONE_ENGINE_CONFIG = new InjectionToken<TimezoneEngineConfig>(\n \"TIMEZONE_ENGINE_CONFIG\",\n);\n\n/** Injectable timezone engine service for Angular */\n@Injectable({ providedIn: \"root\" })\nexport class TimezoneService {\n private config = inject(TIMEZONE_ENGINE_CONFIG, { optional: true }) ?? {};\n private engine: TimezoneEngine = createTimezoneEngine(this.config);\n private timezoneSubject = new BehaviorSubject<string>(\n this.config.defaultTimezone ?? detectBrowserTimezone().timezone,\n );\n\n readonly timezone$: Observable<string> = this.timezoneSubject.asObservable();\n\n get timezone(): string {\n return this.timezoneSubject.value;\n }\n\n setTimezone(tz: string): void {\n this.timezoneSubject.next(tz);\n this.engine.config.update({ defaultTimezone: tz });\n }\n\n detectTimezone(): string {\n return detectBrowserTimezone().timezone;\n }\n\n getUserTimezone(): string {\n return getUserTimezone();\n }\n\n formatDate(date: Date | string | number, options: FormatDateOptions = {}): string {\n return formatDate(date, { timezone: this.timezone, ...options });\n }\n\n convertTimezone(sourceTimezone: string, targetTimezone: string, date?: Date | string | number): Date {\n return convertTimezone({\n sourceTimezone,\n targetTimezone,\n ...(date !== undefined ? { date } : {}),\n });\n }\n\n compareTimezones(source: string, target: string, date?: Date | string | number) {\n return compareTimezones(source, target, date);\n }\n\n getWorldClock(timezones: string[]): WorldClockEntry[] {\n return getWorldClock(timezones);\n }\n\n getCountryTimezones(countryCode: string) {\n return getCountryTimezones(countryCode);\n }\n\n getCityTimezone(city: string) {\n return getCityTimezone(city);\n }\n\n getEngine(): TimezoneEngine {\n return this.engine;\n }\n}\n\n/** World clock observable stream */\n@Injectable({ providedIn: \"root\" })\nexport class WorldClockService {\n private timezoneService = inject(TimezoneService);\n\n createLiveClock(timezones: string[], intervalMs = 1000): Observable<WorldClockEntry[]> {\n return new Observable((subscriber) => {\n const updater = createLiveClockUpdater(\n timezones,\n (clocks) => {\n subscriber.next(clocks);\n },\n intervalMs,\n );\n updater.start();\n return () => {\n updater.stop();\n };\n });\n }\n}\n","import { Pipe, inject, type PipeTransform } from \"@angular/core\";\nimport type { FormatDateOptions } from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { formatRelativeTime } from \"@multisystemsuite/timezone-engine-core\";\nimport { TimezoneService } from \"./timezone.service.js\";\n\n/** Angular pipe for locale-aware date formatting */\n@Pipe({ name: \"teFormatDate\", standalone: true, pure: false })\nexport class TeFormatDatePipe implements PipeTransform {\n private timezoneService = inject(TimezoneService);\n\n transform(\n value: Date | string | number | null | undefined,\n format: FormatDateOptions[\"format\"] = \"DATETIME\",\n timezone?: string,\n locale?: string,\n ): string {\n if (value == null) return \"\";\n const options: FormatDateOptions = { format };\n if (timezone !== undefined) options.timezone = timezone;\n if (locale !== undefined) options.locale = locale;\n return this.timezoneService.formatDate(value, options);\n }\n}\n\n/** Angular pipe for relative time formatting */\n@Pipe({ name: \"teRelativeTime\", standalone: true })\nexport class TeRelativeTimePipe implements PipeTransform {\n transform(value: Date | string | number | null | undefined): string {\n if (value == null) return \"\";\n return formatRelativeTime(value);\n }\n}\n\n/** Angular pipe for timezone conversion display */\n@Pipe({ name: \"teTimezone\", standalone: true })\nexport class TeTimezonePipe implements PipeTransform {\n private timezoneService = inject(TimezoneService);\n\n transform(\n value: Date | string | number | null | undefined,\n targetTimezone: string,\n sourceTimezone?: string,\n ): Date | null {\n if (value == null) return null;\n const source = sourceTimezone ?? this.timezoneService.timezone;\n return this.timezoneService.convertTimezone(source, targetTimezone, value);\n }\n}\n","import { Component, Input, inject, type OnInit, type OnDestroy } from \"@angular/core\";\nimport { CommonModule } from \"@angular/common\";\nimport type { WorldClockEntry } from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { WorldClockService, TimezoneService } from \"./timezone.service.js\";\nimport type { Subscription } from \"rxjs\";\n\n/** Standalone world clock component for Angular */\n@Component({\n selector: \"te-world-clock\",\n standalone: true,\n imports: [CommonModule],\n template: `\n <div class=\"te-clock\" data-testid=\"world-clock\">\n @for (clock of clocks; track clock.timezone) {\n <div class=\"te-clock__entry\">\n <strong>{{ clock.label }}</strong>\n <span>{{ clock.formattedTime }}</span>\n <small>{{ clock.utcOffset }}</small>\n </div>\n }\n </div>\n `,\n})\nexport class WorldClockComponent implements OnInit, OnDestroy {\n @Input() timezones: string[] = [\"UTC\", \"America/New_York\", \"Europe/London\", \"Asia/Kolkata\"];\n @Input() intervalMs = 1000;\n\n clocks: WorldClockEntry[] = [];\n private worldClockService = inject(WorldClockService);\n private subscription?: Subscription;\n\n ngOnInit(): void {\n this.subscription = this.worldClockService\n .createLiveClock(this.timezones, this.intervalMs)\n .subscribe((clocks) => {\n this.clocks = clocks;\n });\n }\n\n ngOnDestroy(): void {\n this.subscription?.unsubscribe();\n }\n}\n\n/** Standalone live clock component */\n@Component({\n selector: \"te-live-clock\",\n standalone: true,\n template: `<span class=\"te-live-clock\">{{ display }}</span>`,\n})\nexport class LiveClockComponent implements OnInit, OnDestroy {\n @Input() timezone?: string;\n @Input() intervalMs = 1000;\n\n display = \"\";\n private timezoneService = inject(TimezoneService);\n private timerId?: ReturnType<typeof setInterval>;\n\n ngOnInit(): void {\n const tz = this.timezone ?? this.timezoneService.timezone;\n const update = () => {\n this.display = this.timezoneService.formatDate(new Date(), {\n format: \"TIME_ONLY\",\n timezone: tz,\n });\n };\n update();\n this.timerId = setInterval(update, this.intervalMs);\n }\n\n ngOnDestroy(): void {\n if (this.timerId !== undefined) clearInterval(this.timerId);\n }\n}\n\n/** Scheduler display component */\n@Component({\n selector: \"te-scheduler\",\n standalone: true,\n imports: [CommonModule, WorldClockComponent],\n template: `\n <div class=\"te-scheduler\">\n <h3 class=\"te-scheduler__title\">Meeting Scheduler</h3>\n <p>Duration: {{ durationMinutes }} minutes</p>\n <ul>\n @for (p of participants; track p.name) {\n <li>{{ p.name }} — {{ p.timezone }}</li>\n }\n </ul>\n <te-world-clock [timezones]=\"participantTimezones\" />\n </div>\n `,\n})\nexport class SchedulerComponent {\n @Input() participants: { name: string; timezone: string }[] = [];\n @Input() durationMinutes = 60;\n\n get participantTimezones(): string[] {\n return [...new Set(this.participants.map((p) => p.timezone))];\n }\n}\n","export {\n TimezoneService,\n WorldClockService,\n TIMEZONE_ENGINE_CONFIG,\n} from \"./timezone.service.js\";\n\nexport { TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe } from \"./pipes.js\";\n\nexport {\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n} from \"./components.js\";\n\nimport { TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe } from \"./pipes.js\";\nimport {\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n} from \"./components.js\";\n\n/** Standalone imports bundle for Angular 17+ */\nexport const TIMEZONE_ENGINE_IMPORTS = [\n TeFormatDatePipe,\n TeRelativeTimePipe,\n TeTimezonePipe,\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n] as const;\n"]}
@@ -0,0 +1,80 @@
1
+ import * as _multisystemsuite_timezone_engine_shared_types from '@multisystemsuite/timezone-engine-shared-types';
2
+ import { TimezoneEngineConfig, FormatDateOptions, WorldClockEntry } from '@multisystemsuite/timezone-engine-shared-types';
3
+ import { InjectionToken, PipeTransform, OnInit, OnDestroy } from '@angular/core';
4
+ import { TimezoneEngine } from '@multisystemsuite/timezone-engine-core';
5
+ import { Observable } from 'rxjs';
6
+
7
+ declare const TIMEZONE_ENGINE_CONFIG: InjectionToken<TimezoneEngineConfig>;
8
+ /** Injectable timezone engine service for Angular */
9
+ declare class TimezoneService {
10
+ private config;
11
+ private engine;
12
+ private timezoneSubject;
13
+ readonly timezone$: Observable<string>;
14
+ get timezone(): string;
15
+ setTimezone(tz: string): void;
16
+ detectTimezone(): string;
17
+ getUserTimezone(): string;
18
+ formatDate(date: Date | string | number, options?: FormatDateOptions): string;
19
+ convertTimezone(sourceTimezone: string, targetTimezone: string, date?: Date | string | number): Date;
20
+ compareTimezones(source: string, target: string, date?: Date | string | number): _multisystemsuite_timezone_engine_shared_types.TimezoneComparison;
21
+ getWorldClock(timezones: string[]): WorldClockEntry[];
22
+ getCountryTimezones(countryCode: string): _multisystemsuite_timezone_engine_shared_types.CountryTimezoneMapping | undefined;
23
+ getCityTimezone(city: string): _multisystemsuite_timezone_engine_shared_types.CityTimezoneMapping | undefined;
24
+ getEngine(): TimezoneEngine;
25
+ }
26
+ /** World clock observable stream */
27
+ declare class WorldClockService {
28
+ private timezoneService;
29
+ createLiveClock(timezones: string[], intervalMs?: number): Observable<WorldClockEntry[]>;
30
+ }
31
+
32
+ /** Angular pipe for locale-aware date formatting */
33
+ declare class TeFormatDatePipe implements PipeTransform {
34
+ private timezoneService;
35
+ transform(value: Date | string | number | null | undefined, format?: FormatDateOptions["format"], timezone?: string, locale?: string): string;
36
+ }
37
+ /** Angular pipe for relative time formatting */
38
+ declare class TeRelativeTimePipe implements PipeTransform {
39
+ transform(value: Date | string | number | null | undefined): string;
40
+ }
41
+ /** Angular pipe for timezone conversion display */
42
+ declare class TeTimezonePipe implements PipeTransform {
43
+ private timezoneService;
44
+ transform(value: Date | string | number | null | undefined, targetTimezone: string, sourceTimezone?: string): Date | null;
45
+ }
46
+
47
+ /** Standalone world clock component for Angular */
48
+ declare class WorldClockComponent implements OnInit, OnDestroy {
49
+ timezones: string[];
50
+ intervalMs: number;
51
+ clocks: WorldClockEntry[];
52
+ private worldClockService;
53
+ private subscription?;
54
+ ngOnInit(): void;
55
+ ngOnDestroy(): void;
56
+ }
57
+ /** Standalone live clock component */
58
+ declare class LiveClockComponent implements OnInit, OnDestroy {
59
+ timezone?: string;
60
+ intervalMs: number;
61
+ display: string;
62
+ private timezoneService;
63
+ private timerId?;
64
+ ngOnInit(): void;
65
+ ngOnDestroy(): void;
66
+ }
67
+ /** Scheduler display component */
68
+ declare class SchedulerComponent {
69
+ participants: {
70
+ name: string;
71
+ timezone: string;
72
+ }[];
73
+ durationMinutes: number;
74
+ get participantTimezones(): string[];
75
+ }
76
+
77
+ /** Standalone imports bundle for Angular 17+ */
78
+ declare const TIMEZONE_ENGINE_IMPORTS: readonly [typeof TeFormatDatePipe, typeof TeRelativeTimePipe, typeof TeTimezonePipe, typeof WorldClockComponent, typeof LiveClockComponent, typeof SchedulerComponent];
79
+
80
+ export { LiveClockComponent, SchedulerComponent, TIMEZONE_ENGINE_CONFIG, TIMEZONE_ENGINE_IMPORTS, TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe, TimezoneService, WorldClockComponent, WorldClockService };
@@ -0,0 +1,80 @@
1
+ import * as _multisystemsuite_timezone_engine_shared_types from '@multisystemsuite/timezone-engine-shared-types';
2
+ import { TimezoneEngineConfig, FormatDateOptions, WorldClockEntry } from '@multisystemsuite/timezone-engine-shared-types';
3
+ import { InjectionToken, PipeTransform, OnInit, OnDestroy } from '@angular/core';
4
+ import { TimezoneEngine } from '@multisystemsuite/timezone-engine-core';
5
+ import { Observable } from 'rxjs';
6
+
7
+ declare const TIMEZONE_ENGINE_CONFIG: InjectionToken<TimezoneEngineConfig>;
8
+ /** Injectable timezone engine service for Angular */
9
+ declare class TimezoneService {
10
+ private config;
11
+ private engine;
12
+ private timezoneSubject;
13
+ readonly timezone$: Observable<string>;
14
+ get timezone(): string;
15
+ setTimezone(tz: string): void;
16
+ detectTimezone(): string;
17
+ getUserTimezone(): string;
18
+ formatDate(date: Date | string | number, options?: FormatDateOptions): string;
19
+ convertTimezone(sourceTimezone: string, targetTimezone: string, date?: Date | string | number): Date;
20
+ compareTimezones(source: string, target: string, date?: Date | string | number): _multisystemsuite_timezone_engine_shared_types.TimezoneComparison;
21
+ getWorldClock(timezones: string[]): WorldClockEntry[];
22
+ getCountryTimezones(countryCode: string): _multisystemsuite_timezone_engine_shared_types.CountryTimezoneMapping | undefined;
23
+ getCityTimezone(city: string): _multisystemsuite_timezone_engine_shared_types.CityTimezoneMapping | undefined;
24
+ getEngine(): TimezoneEngine;
25
+ }
26
+ /** World clock observable stream */
27
+ declare class WorldClockService {
28
+ private timezoneService;
29
+ createLiveClock(timezones: string[], intervalMs?: number): Observable<WorldClockEntry[]>;
30
+ }
31
+
32
+ /** Angular pipe for locale-aware date formatting */
33
+ declare class TeFormatDatePipe implements PipeTransform {
34
+ private timezoneService;
35
+ transform(value: Date | string | number | null | undefined, format?: FormatDateOptions["format"], timezone?: string, locale?: string): string;
36
+ }
37
+ /** Angular pipe for relative time formatting */
38
+ declare class TeRelativeTimePipe implements PipeTransform {
39
+ transform(value: Date | string | number | null | undefined): string;
40
+ }
41
+ /** Angular pipe for timezone conversion display */
42
+ declare class TeTimezonePipe implements PipeTransform {
43
+ private timezoneService;
44
+ transform(value: Date | string | number | null | undefined, targetTimezone: string, sourceTimezone?: string): Date | null;
45
+ }
46
+
47
+ /** Standalone world clock component for Angular */
48
+ declare class WorldClockComponent implements OnInit, OnDestroy {
49
+ timezones: string[];
50
+ intervalMs: number;
51
+ clocks: WorldClockEntry[];
52
+ private worldClockService;
53
+ private subscription?;
54
+ ngOnInit(): void;
55
+ ngOnDestroy(): void;
56
+ }
57
+ /** Standalone live clock component */
58
+ declare class LiveClockComponent implements OnInit, OnDestroy {
59
+ timezone?: string;
60
+ intervalMs: number;
61
+ display: string;
62
+ private timezoneService;
63
+ private timerId?;
64
+ ngOnInit(): void;
65
+ ngOnDestroy(): void;
66
+ }
67
+ /** Scheduler display component */
68
+ declare class SchedulerComponent {
69
+ participants: {
70
+ name: string;
71
+ timezone: string;
72
+ }[];
73
+ durationMinutes: number;
74
+ get participantTimezones(): string[];
75
+ }
76
+
77
+ /** Standalone imports bundle for Angular 17+ */
78
+ declare const TIMEZONE_ENGINE_IMPORTS: readonly [typeof TeFormatDatePipe, typeof TeRelativeTimePipe, typeof TeTimezonePipe, typeof WorldClockComponent, typeof LiveClockComponent, typeof SchedulerComponent];
79
+
80
+ export { LiveClockComponent, SchedulerComponent, TIMEZONE_ENGINE_CONFIG, TIMEZONE_ENGINE_IMPORTS, TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe, TimezoneService, WorldClockComponent, WorldClockService };
package/dist/index.js ADDED
@@ -0,0 +1,241 @@
1
+ import { InjectionToken, Injectable, Pipe, Input, Component, inject } from '@angular/core';
2
+ import { createLiveClockUpdater, createTimezoneEngine, detectBrowserTimezone, getUserTimezone, formatDate, convertTimezone, compareTimezones, getWorldClock, formatRelativeTime } from '@multisystemsuite/timezone-engine-core';
3
+ import { getCountryTimezones, getCityTimezone } from '@multisystemsuite/timezone-engine-world-data';
4
+ import { Observable, BehaviorSubject } from 'rxjs';
5
+ import { CommonModule } from '@angular/common';
6
+
7
+ var __defProp = Object.defineProperty;
8
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
9
+ var __decorateClass = (decorators, target, key, kind) => {
10
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
11
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
12
+ if (decorator = decorators[i])
13
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
14
+ if (kind && result) __defProp(target, key, result);
15
+ return result;
16
+ };
17
+ var TIMEZONE_ENGINE_CONFIG = new InjectionToken(
18
+ "TIMEZONE_ENGINE_CONFIG"
19
+ );
20
+ var TimezoneService = class {
21
+ config = inject(TIMEZONE_ENGINE_CONFIG, { optional: true }) ?? {};
22
+ engine = createTimezoneEngine(this.config);
23
+ timezoneSubject = new BehaviorSubject(
24
+ this.config.defaultTimezone ?? detectBrowserTimezone().timezone
25
+ );
26
+ timezone$ = this.timezoneSubject.asObservable();
27
+ get timezone() {
28
+ return this.timezoneSubject.value;
29
+ }
30
+ setTimezone(tz) {
31
+ this.timezoneSubject.next(tz);
32
+ this.engine.config.update({ defaultTimezone: tz });
33
+ }
34
+ detectTimezone() {
35
+ return detectBrowserTimezone().timezone;
36
+ }
37
+ getUserTimezone() {
38
+ return getUserTimezone();
39
+ }
40
+ formatDate(date, options = {}) {
41
+ return formatDate(date, { timezone: this.timezone, ...options });
42
+ }
43
+ convertTimezone(sourceTimezone, targetTimezone, date) {
44
+ return convertTimezone({
45
+ sourceTimezone,
46
+ targetTimezone,
47
+ ...date !== void 0 ? { date } : {}
48
+ });
49
+ }
50
+ compareTimezones(source, target, date) {
51
+ return compareTimezones(source, target, date);
52
+ }
53
+ getWorldClock(timezones) {
54
+ return getWorldClock(timezones);
55
+ }
56
+ getCountryTimezones(countryCode) {
57
+ return getCountryTimezones(countryCode);
58
+ }
59
+ getCityTimezone(city) {
60
+ return getCityTimezone(city);
61
+ }
62
+ getEngine() {
63
+ return this.engine;
64
+ }
65
+ };
66
+ TimezoneService = __decorateClass([
67
+ Injectable({ providedIn: "root" })
68
+ ], TimezoneService);
69
+ var WorldClockService = class {
70
+ timezoneService = inject(TimezoneService);
71
+ createLiveClock(timezones, intervalMs = 1e3) {
72
+ return new Observable((subscriber) => {
73
+ const updater = createLiveClockUpdater(
74
+ timezones,
75
+ (clocks) => {
76
+ subscriber.next(clocks);
77
+ },
78
+ intervalMs
79
+ );
80
+ updater.start();
81
+ return () => {
82
+ updater.stop();
83
+ };
84
+ });
85
+ }
86
+ };
87
+ WorldClockService = __decorateClass([
88
+ Injectable({ providedIn: "root" })
89
+ ], WorldClockService);
90
+ var TeFormatDatePipe = class {
91
+ timezoneService = inject(TimezoneService);
92
+ transform(value, format = "DATETIME", timezone, locale) {
93
+ if (value == null) return "";
94
+ const options = { format };
95
+ if (timezone !== void 0) options.timezone = timezone;
96
+ if (locale !== void 0) options.locale = locale;
97
+ return this.timezoneService.formatDate(value, options);
98
+ }
99
+ };
100
+ TeFormatDatePipe = __decorateClass([
101
+ Pipe({ name: "teFormatDate", standalone: true, pure: false })
102
+ ], TeFormatDatePipe);
103
+ var TeRelativeTimePipe = class {
104
+ transform(value) {
105
+ if (value == null) return "";
106
+ return formatRelativeTime(value);
107
+ }
108
+ };
109
+ TeRelativeTimePipe = __decorateClass([
110
+ Pipe({ name: "teRelativeTime", standalone: true })
111
+ ], TeRelativeTimePipe);
112
+ var TeTimezonePipe = class {
113
+ timezoneService = inject(TimezoneService);
114
+ transform(value, targetTimezone, sourceTimezone) {
115
+ if (value == null) return null;
116
+ const source = sourceTimezone ?? this.timezoneService.timezone;
117
+ return this.timezoneService.convertTimezone(source, targetTimezone, value);
118
+ }
119
+ };
120
+ TeTimezonePipe = __decorateClass([
121
+ Pipe({ name: "teTimezone", standalone: true })
122
+ ], TeTimezonePipe);
123
+ var WorldClockComponent = class {
124
+ timezones = ["UTC", "America/New_York", "Europe/London", "Asia/Kolkata"];
125
+ intervalMs = 1e3;
126
+ clocks = [];
127
+ worldClockService = inject(WorldClockService);
128
+ subscription;
129
+ ngOnInit() {
130
+ this.subscription = this.worldClockService.createLiveClock(this.timezones, this.intervalMs).subscribe((clocks) => {
131
+ this.clocks = clocks;
132
+ });
133
+ }
134
+ ngOnDestroy() {
135
+ this.subscription?.unsubscribe();
136
+ }
137
+ };
138
+ __decorateClass([
139
+ Input()
140
+ ], WorldClockComponent.prototype, "timezones", 2);
141
+ __decorateClass([
142
+ Input()
143
+ ], WorldClockComponent.prototype, "intervalMs", 2);
144
+ WorldClockComponent = __decorateClass([
145
+ Component({
146
+ selector: "te-world-clock",
147
+ standalone: true,
148
+ imports: [CommonModule],
149
+ template: `
150
+ <div class="te-clock" data-testid="world-clock">
151
+ @for (clock of clocks; track clock.timezone) {
152
+ <div class="te-clock__entry">
153
+ <strong>{{ clock.label }}</strong>
154
+ <span>{{ clock.formattedTime }}</span>
155
+ <small>{{ clock.utcOffset }}</small>
156
+ </div>
157
+ }
158
+ </div>
159
+ `
160
+ })
161
+ ], WorldClockComponent);
162
+ var LiveClockComponent = class {
163
+ timezone;
164
+ intervalMs = 1e3;
165
+ display = "";
166
+ timezoneService = inject(TimezoneService);
167
+ timerId;
168
+ ngOnInit() {
169
+ const tz = this.timezone ?? this.timezoneService.timezone;
170
+ const update = () => {
171
+ this.display = this.timezoneService.formatDate(/* @__PURE__ */ new Date(), {
172
+ format: "TIME_ONLY",
173
+ timezone: tz
174
+ });
175
+ };
176
+ update();
177
+ this.timerId = setInterval(update, this.intervalMs);
178
+ }
179
+ ngOnDestroy() {
180
+ if (this.timerId !== void 0) clearInterval(this.timerId);
181
+ }
182
+ };
183
+ __decorateClass([
184
+ Input()
185
+ ], LiveClockComponent.prototype, "timezone", 2);
186
+ __decorateClass([
187
+ Input()
188
+ ], LiveClockComponent.prototype, "intervalMs", 2);
189
+ LiveClockComponent = __decorateClass([
190
+ Component({
191
+ selector: "te-live-clock",
192
+ standalone: true,
193
+ template: `<span class="te-live-clock">{{ display }}</span>`
194
+ })
195
+ ], LiveClockComponent);
196
+ var SchedulerComponent = class {
197
+ participants = [];
198
+ durationMinutes = 60;
199
+ get participantTimezones() {
200
+ return [...new Set(this.participants.map((p) => p.timezone))];
201
+ }
202
+ };
203
+ __decorateClass([
204
+ Input()
205
+ ], SchedulerComponent.prototype, "participants", 2);
206
+ __decorateClass([
207
+ Input()
208
+ ], SchedulerComponent.prototype, "durationMinutes", 2);
209
+ SchedulerComponent = __decorateClass([
210
+ Component({
211
+ selector: "te-scheduler",
212
+ standalone: true,
213
+ imports: [CommonModule, WorldClockComponent],
214
+ template: `
215
+ <div class="te-scheduler">
216
+ <h3 class="te-scheduler__title">Meeting Scheduler</h3>
217
+ <p>Duration: {{ durationMinutes }} minutes</p>
218
+ <ul>
219
+ @for (p of participants; track p.name) {
220
+ <li>{{ p.name }} \u2014 {{ p.timezone }}</li>
221
+ }
222
+ </ul>
223
+ <te-world-clock [timezones]="participantTimezones" />
224
+ </div>
225
+ `
226
+ })
227
+ ], SchedulerComponent);
228
+
229
+ // src/index.ts
230
+ var TIMEZONE_ENGINE_IMPORTS = [
231
+ TeFormatDatePipe,
232
+ TeRelativeTimePipe,
233
+ TeTimezonePipe,
234
+ WorldClockComponent,
235
+ LiveClockComponent,
236
+ SchedulerComponent
237
+ ];
238
+
239
+ export { LiveClockComponent, SchedulerComponent, TIMEZONE_ENGINE_CONFIG, TIMEZONE_ENGINE_IMPORTS, TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe, TimezoneService, WorldClockComponent, WorldClockService };
240
+ //# sourceMappingURL=index.js.map
241
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/timezone.service.ts","../src/pipes.ts","../src/components.ts","../src/index.ts"],"names":["inject"],"mappings":"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","file":"index.js","sourcesContent":["import { Injectable, InjectionToken, inject } from \"@angular/core\";\nimport type {\n FormatDateOptions,\n TimezoneEngineConfig,\n WorldClockEntry,\n} from \"@multisystemsuite/timezone-engine-shared-types\";\nimport {\n createTimezoneEngine,\n detectBrowserTimezone,\n formatDate,\n convertTimezone,\n compareTimezones,\n getWorldClock,\n createLiveClockUpdater,\n getUserTimezone,\n type TimezoneEngine,\n} from \"@multisystemsuite/timezone-engine-core\";\nimport { getCountryTimezones, getCityTimezone } from \"@multisystemsuite/timezone-engine-world-data\";\nimport { BehaviorSubject, Observable } from \"rxjs\";\n\nexport const TIMEZONE_ENGINE_CONFIG = new InjectionToken<TimezoneEngineConfig>(\n \"TIMEZONE_ENGINE_CONFIG\",\n);\n\n/** Injectable timezone engine service for Angular */\n@Injectable({ providedIn: \"root\" })\nexport class TimezoneService {\n private config = inject(TIMEZONE_ENGINE_CONFIG, { optional: true }) ?? {};\n private engine: TimezoneEngine = createTimezoneEngine(this.config);\n private timezoneSubject = new BehaviorSubject<string>(\n this.config.defaultTimezone ?? detectBrowserTimezone().timezone,\n );\n\n readonly timezone$: Observable<string> = this.timezoneSubject.asObservable();\n\n get timezone(): string {\n return this.timezoneSubject.value;\n }\n\n setTimezone(tz: string): void {\n this.timezoneSubject.next(tz);\n this.engine.config.update({ defaultTimezone: tz });\n }\n\n detectTimezone(): string {\n return detectBrowserTimezone().timezone;\n }\n\n getUserTimezone(): string {\n return getUserTimezone();\n }\n\n formatDate(date: Date | string | number, options: FormatDateOptions = {}): string {\n return formatDate(date, { timezone: this.timezone, ...options });\n }\n\n convertTimezone(sourceTimezone: string, targetTimezone: string, date?: Date | string | number): Date {\n return convertTimezone({\n sourceTimezone,\n targetTimezone,\n ...(date !== undefined ? { date } : {}),\n });\n }\n\n compareTimezones(source: string, target: string, date?: Date | string | number) {\n return compareTimezones(source, target, date);\n }\n\n getWorldClock(timezones: string[]): WorldClockEntry[] {\n return getWorldClock(timezones);\n }\n\n getCountryTimezones(countryCode: string) {\n return getCountryTimezones(countryCode);\n }\n\n getCityTimezone(city: string) {\n return getCityTimezone(city);\n }\n\n getEngine(): TimezoneEngine {\n return this.engine;\n }\n}\n\n/** World clock observable stream */\n@Injectable({ providedIn: \"root\" })\nexport class WorldClockService {\n private timezoneService = inject(TimezoneService);\n\n createLiveClock(timezones: string[], intervalMs = 1000): Observable<WorldClockEntry[]> {\n return new Observable((subscriber) => {\n const updater = createLiveClockUpdater(\n timezones,\n (clocks) => {\n subscriber.next(clocks);\n },\n intervalMs,\n );\n updater.start();\n return () => {\n updater.stop();\n };\n });\n }\n}\n","import { Pipe, inject, type PipeTransform } from \"@angular/core\";\nimport type { FormatDateOptions } from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { formatRelativeTime } from \"@multisystemsuite/timezone-engine-core\";\nimport { TimezoneService } from \"./timezone.service.js\";\n\n/** Angular pipe for locale-aware date formatting */\n@Pipe({ name: \"teFormatDate\", standalone: true, pure: false })\nexport class TeFormatDatePipe implements PipeTransform {\n private timezoneService = inject(TimezoneService);\n\n transform(\n value: Date | string | number | null | undefined,\n format: FormatDateOptions[\"format\"] = \"DATETIME\",\n timezone?: string,\n locale?: string,\n ): string {\n if (value == null) return \"\";\n const options: FormatDateOptions = { format };\n if (timezone !== undefined) options.timezone = timezone;\n if (locale !== undefined) options.locale = locale;\n return this.timezoneService.formatDate(value, options);\n }\n}\n\n/** Angular pipe for relative time formatting */\n@Pipe({ name: \"teRelativeTime\", standalone: true })\nexport class TeRelativeTimePipe implements PipeTransform {\n transform(value: Date | string | number | null | undefined): string {\n if (value == null) return \"\";\n return formatRelativeTime(value);\n }\n}\n\n/** Angular pipe for timezone conversion display */\n@Pipe({ name: \"teTimezone\", standalone: true })\nexport class TeTimezonePipe implements PipeTransform {\n private timezoneService = inject(TimezoneService);\n\n transform(\n value: Date | string | number | null | undefined,\n targetTimezone: string,\n sourceTimezone?: string,\n ): Date | null {\n if (value == null) return null;\n const source = sourceTimezone ?? this.timezoneService.timezone;\n return this.timezoneService.convertTimezone(source, targetTimezone, value);\n }\n}\n","import { Component, Input, inject, type OnInit, type OnDestroy } from \"@angular/core\";\nimport { CommonModule } from \"@angular/common\";\nimport type { WorldClockEntry } from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { WorldClockService, TimezoneService } from \"./timezone.service.js\";\nimport type { Subscription } from \"rxjs\";\n\n/** Standalone world clock component for Angular */\n@Component({\n selector: \"te-world-clock\",\n standalone: true,\n imports: [CommonModule],\n template: `\n <div class=\"te-clock\" data-testid=\"world-clock\">\n @for (clock of clocks; track clock.timezone) {\n <div class=\"te-clock__entry\">\n <strong>{{ clock.label }}</strong>\n <span>{{ clock.formattedTime }}</span>\n <small>{{ clock.utcOffset }}</small>\n </div>\n }\n </div>\n `,\n})\nexport class WorldClockComponent implements OnInit, OnDestroy {\n @Input() timezones: string[] = [\"UTC\", \"America/New_York\", \"Europe/London\", \"Asia/Kolkata\"];\n @Input() intervalMs = 1000;\n\n clocks: WorldClockEntry[] = [];\n private worldClockService = inject(WorldClockService);\n private subscription?: Subscription;\n\n ngOnInit(): void {\n this.subscription = this.worldClockService\n .createLiveClock(this.timezones, this.intervalMs)\n .subscribe((clocks) => {\n this.clocks = clocks;\n });\n }\n\n ngOnDestroy(): void {\n this.subscription?.unsubscribe();\n }\n}\n\n/** Standalone live clock component */\n@Component({\n selector: \"te-live-clock\",\n standalone: true,\n template: `<span class=\"te-live-clock\">{{ display }}</span>`,\n})\nexport class LiveClockComponent implements OnInit, OnDestroy {\n @Input() timezone?: string;\n @Input() intervalMs = 1000;\n\n display = \"\";\n private timezoneService = inject(TimezoneService);\n private timerId?: ReturnType<typeof setInterval>;\n\n ngOnInit(): void {\n const tz = this.timezone ?? this.timezoneService.timezone;\n const update = () => {\n this.display = this.timezoneService.formatDate(new Date(), {\n format: \"TIME_ONLY\",\n timezone: tz,\n });\n };\n update();\n this.timerId = setInterval(update, this.intervalMs);\n }\n\n ngOnDestroy(): void {\n if (this.timerId !== undefined) clearInterval(this.timerId);\n }\n}\n\n/** Scheduler display component */\n@Component({\n selector: \"te-scheduler\",\n standalone: true,\n imports: [CommonModule, WorldClockComponent],\n template: `\n <div class=\"te-scheduler\">\n <h3 class=\"te-scheduler__title\">Meeting Scheduler</h3>\n <p>Duration: {{ durationMinutes }} minutes</p>\n <ul>\n @for (p of participants; track p.name) {\n <li>{{ p.name }} — {{ p.timezone }}</li>\n }\n </ul>\n <te-world-clock [timezones]=\"participantTimezones\" />\n </div>\n `,\n})\nexport class SchedulerComponent {\n @Input() participants: { name: string; timezone: string }[] = [];\n @Input() durationMinutes = 60;\n\n get participantTimezones(): string[] {\n return [...new Set(this.participants.map((p) => p.timezone))];\n }\n}\n","export {\n TimezoneService,\n WorldClockService,\n TIMEZONE_ENGINE_CONFIG,\n} from \"./timezone.service.js\";\n\nexport { TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe } from \"./pipes.js\";\n\nexport {\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n} from \"./components.js\";\n\nimport { TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe } from \"./pipes.js\";\nimport {\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n} from \"./components.js\";\n\n/** Standalone imports bundle for Angular 17+ */\nexport const TIMEZONE_ENGINE_IMPORTS = [\n TeFormatDatePipe,\n TeRelativeTimePipe,\n TeTimezonePipe,\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n] as const;\n"]}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@multisystemsuite/timezone-engine-angular",
3
+ "version": "1.0.0",
4
+ "description": "Angular services, pipes, and components for @multisystemsuite/timezone-engine",
5
+ "license": "MIT",
6
+ "author": "MultiSystemSuite",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/multisystemsuite/timezone-engine.git",
10
+ "directory": "packages/timezone-angular"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "type": "module",
16
+ "main": "./dist/index.cjs",
17
+ "module": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "exports": {
20
+ ".": {
21
+ "import": {
22
+ "types": "./dist/index.d.ts",
23
+ "default": "./dist/index.js"
24
+ },
25
+ "require": {
26
+ "types": "./dist/index.d.cts",
27
+ "default": "./dist/index.cjs"
28
+ }
29
+ }
30
+ },
31
+ "sideEffects": false,
32
+ "files": [
33
+ "dist"
34
+ ],
35
+ "dependencies": {
36
+ "@multisystemsuite/timezone-engine-shared-types": "1.0.0",
37
+ "@multisystemsuite/timezone-engine-world-data": "1.0.0",
38
+ "@multisystemsuite/timezone-engine-scheduler": "1.0.0",
39
+ "@multisystemsuite/timezone-engine-core": "1.0.0"
40
+ },
41
+ "peerDependencies": {
42
+ "@angular/common": ">=17.0.0",
43
+ "@angular/core": ">=17.0.0"
44
+ },
45
+ "devDependencies": {
46
+ "@angular/common": "^19.0.0",
47
+ "@angular/core": "^19.0.0",
48
+ "rimraf": "^6.0.1",
49
+ "rxjs": "^7.8.1",
50
+ "tsup": "^8.3.5",
51
+ "typescript": "^5.7.2",
52
+ "vitest": "^2.1.8"
53
+ },
54
+ "scripts": {
55
+ "build": "tsup",
56
+ "dev": "tsup --watch",
57
+ "clean": "rimraf dist",
58
+ "typecheck": "tsc --noEmit",
59
+ "lint": "eslint src",
60
+ "lint:fix": "eslint src --fix",
61
+ "test": "vitest run --passWithNoTests"
62
+ }
63
+ }