@cloudsnorkel/cdk-github-runners 0.14.24 → 0.15.1

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.
Files changed (142) hide show
  1. package/.jsii +5953 -602
  2. package/API.md +1349 -115
  3. package/README.md +53 -1
  4. package/assets/delete-failed-runner.lambda/index.js +122 -9
  5. package/assets/idle-runner-repear.lambda/index.js +153 -14
  6. package/assets/image-builders/aws-image-builder/delete-resources.lambda/index.js +1 -1
  7. package/assets/image-builders/build-image.lambda/index.js +1 -1
  8. package/assets/providers/ami-root-device.lambda/index.js +1 -1
  9. package/assets/setup.lambda/index.html +7 -7
  10. package/assets/setup.lambda/index.js +118 -8
  11. package/assets/status.lambda/index.js +121 -8
  12. package/assets/token-retriever.lambda/index.js +121 -8
  13. package/assets/warm-runner-manager.lambda/index.js +5909 -0
  14. package/assets/webhook-handler.lambda/index.js +126 -11
  15. package/assets/webhook-redelivery.lambda/index.js +139 -24
  16. package/lib/access.js +1 -1
  17. package/lib/delete-failed-runner.lambda.js +2 -2
  18. package/lib/idle-runner-repear.lambda.js +33 -7
  19. package/lib/image-builders/api.js +1 -1
  20. package/lib/image-builders/aws-image-builder/base-image.d.ts +13 -0
  21. package/lib/image-builders/aws-image-builder/base-image.js +36 -3
  22. package/lib/image-builders/aws-image-builder/builder.js +4 -4
  23. package/lib/image-builders/aws-image-builder/delete-resources.lambda.js +2 -2
  24. package/lib/image-builders/aws-image-builder/deprecated/ami.js +1 -1
  25. package/lib/image-builders/aws-image-builder/deprecated/container.js +1 -1
  26. package/lib/image-builders/aws-image-builder/deprecated/linux-components.js +1 -1
  27. package/lib/image-builders/aws-image-builder/deprecated/windows-components.js +1 -1
  28. package/lib/image-builders/build-image.lambda.js +2 -2
  29. package/lib/image-builders/codebuild-deprecated.js +1 -1
  30. package/lib/image-builders/components.js +3 -3
  31. package/lib/image-builders/static.js +1 -1
  32. package/lib/index.d.ts +1 -0
  33. package/lib/index.js +2 -1
  34. package/lib/lambda-github.d.ts +1 -1
  35. package/lib/lambda-github.js +3 -2
  36. package/lib/lambda-helpers.js +4 -4
  37. package/lib/providers/ami-root-device.lambda.js +2 -2
  38. package/lib/providers/codebuild.d.ts +18 -2
  39. package/lib/providers/codebuild.js +15 -4
  40. package/lib/providers/common.d.ts +47 -3
  41. package/lib/providers/common.js +29 -5
  42. package/lib/providers/composite.js +14 -19
  43. package/lib/providers/ec2.d.ts +9 -2
  44. package/lib/providers/ec2.js +84 -42
  45. package/lib/providers/ecs.d.ts +19 -2
  46. package/lib/providers/ecs.js +49 -44
  47. package/lib/providers/fargate.d.ts +2 -2
  48. package/lib/providers/fargate.js +19 -36
  49. package/lib/providers/lambda.d.ts +2 -2
  50. package/lib/providers/lambda.js +3 -3
  51. package/lib/runner.d.ts +31 -3
  52. package/lib/runner.js +171 -46
  53. package/lib/secrets.js +1 -1
  54. package/lib/setup.lambda.js +2 -2
  55. package/lib/utils.d.ts +10 -1
  56. package/lib/utils.js +15 -1
  57. package/lib/warm-runner-manager-function.d.ts +18 -0
  58. package/lib/warm-runner-manager-function.js +24 -0
  59. package/lib/warm-runner-manager.lambda.d.ts +41 -0
  60. package/lib/warm-runner-manager.lambda.js +487 -0
  61. package/lib/warm-runner.d.ts +155 -0
  62. package/lib/warm-runner.js +217 -0
  63. package/lib/webhook-handler.lambda.js +5 -3
  64. package/lib/webhook-redelivery.lambda.js +17 -16
  65. package/lib/webhook.d.ts +4 -0
  66. package/lib/webhook.js +2 -1
  67. package/node_modules/cron-parser/LICENSE +21 -0
  68. package/node_modules/cron-parser/README.md +408 -0
  69. package/node_modules/cron-parser/dist/CronDate.js +518 -0
  70. package/node_modules/cron-parser/dist/CronExpression.js +520 -0
  71. package/node_modules/cron-parser/dist/CronExpressionParser.js +382 -0
  72. package/node_modules/cron-parser/dist/CronFieldCollection.js +371 -0
  73. package/node_modules/cron-parser/dist/CronFileParser.js +109 -0
  74. package/node_modules/cron-parser/dist/fields/CronDayOfMonth.js +44 -0
  75. package/node_modules/cron-parser/dist/fields/CronDayOfWeek.js +51 -0
  76. package/node_modules/cron-parser/dist/fields/CronField.js +214 -0
  77. package/node_modules/cron-parser/dist/fields/CronHour.js +40 -0
  78. package/node_modules/cron-parser/dist/fields/CronMinute.js +40 -0
  79. package/node_modules/cron-parser/dist/fields/CronMonth.js +44 -0
  80. package/node_modules/cron-parser/dist/fields/CronSecond.js +40 -0
  81. package/node_modules/cron-parser/dist/fields/index.js +24 -0
  82. package/node_modules/cron-parser/dist/fields/types.js +2 -0
  83. package/node_modules/cron-parser/dist/index.js +31 -0
  84. package/node_modules/cron-parser/dist/types/CronDate.d.ts +288 -0
  85. package/node_modules/cron-parser/dist/types/CronExpression.d.ts +118 -0
  86. package/node_modules/cron-parser/dist/types/CronExpressionParser.d.ts +70 -0
  87. package/node_modules/cron-parser/dist/types/CronFieldCollection.d.ts +153 -0
  88. package/node_modules/cron-parser/dist/types/CronFileParser.d.ts +30 -0
  89. package/node_modules/cron-parser/dist/types/fields/CronDayOfMonth.d.ts +25 -0
  90. package/node_modules/cron-parser/dist/types/fields/CronDayOfWeek.d.ts +30 -0
  91. package/node_modules/cron-parser/dist/types/fields/CronField.d.ts +130 -0
  92. package/node_modules/cron-parser/dist/types/fields/CronHour.d.ts +23 -0
  93. package/node_modules/cron-parser/dist/types/fields/CronMinute.d.ts +23 -0
  94. package/node_modules/cron-parser/dist/types/fields/CronMonth.d.ts +24 -0
  95. package/node_modules/cron-parser/dist/types/fields/CronSecond.d.ts +23 -0
  96. package/node_modules/cron-parser/dist/types/fields/index.d.ts +8 -0
  97. package/node_modules/cron-parser/dist/types/fields/types.d.ts +18 -0
  98. package/node_modules/cron-parser/dist/types/index.d.ts +8 -0
  99. package/node_modules/cron-parser/dist/types/utils/random.d.ts +10 -0
  100. package/node_modules/cron-parser/dist/utils/random.js +38 -0
  101. package/node_modules/cron-parser/package.json +117 -0
  102. package/node_modules/luxon/LICENSE.md +7 -0
  103. package/node_modules/luxon/README.md +55 -0
  104. package/node_modules/luxon/build/amd/luxon.js +8741 -0
  105. package/node_modules/luxon/build/amd/luxon.js.map +1 -0
  106. package/node_modules/luxon/build/cjs-browser/luxon.js +8739 -0
  107. package/node_modules/luxon/build/cjs-browser/luxon.js.map +1 -0
  108. package/node_modules/luxon/build/es6/luxon.mjs +8133 -0
  109. package/node_modules/luxon/build/es6/luxon.mjs.map +1 -0
  110. package/node_modules/luxon/build/global/luxon.js +8744 -0
  111. package/node_modules/luxon/build/global/luxon.js.map +1 -0
  112. package/node_modules/luxon/build/global/luxon.min.js +1 -0
  113. package/node_modules/luxon/build/global/luxon.min.js.map +1 -0
  114. package/node_modules/luxon/build/node/luxon.js +7792 -0
  115. package/node_modules/luxon/build/node/luxon.js.map +1 -0
  116. package/node_modules/luxon/package.json +87 -0
  117. package/node_modules/luxon/src/datetime.js +2603 -0
  118. package/node_modules/luxon/src/duration.js +1009 -0
  119. package/node_modules/luxon/src/errors.js +61 -0
  120. package/node_modules/luxon/src/impl/conversions.js +206 -0
  121. package/node_modules/luxon/src/impl/diff.js +95 -0
  122. package/node_modules/luxon/src/impl/digits.js +94 -0
  123. package/node_modules/luxon/src/impl/english.js +233 -0
  124. package/node_modules/luxon/src/impl/formats.js +176 -0
  125. package/node_modules/luxon/src/impl/formatter.js +434 -0
  126. package/node_modules/luxon/src/impl/invalid.js +14 -0
  127. package/node_modules/luxon/src/impl/locale.js +569 -0
  128. package/node_modules/luxon/src/impl/regexParser.js +335 -0
  129. package/node_modules/luxon/src/impl/tokenParser.js +505 -0
  130. package/node_modules/luxon/src/impl/util.js +330 -0
  131. package/node_modules/luxon/src/impl/zoneUtil.js +34 -0
  132. package/node_modules/luxon/src/info.js +205 -0
  133. package/node_modules/luxon/src/interval.js +669 -0
  134. package/node_modules/luxon/src/luxon.js +26 -0
  135. package/node_modules/luxon/src/package.json +4 -0
  136. package/node_modules/luxon/src/settings.js +180 -0
  137. package/node_modules/luxon/src/zone.js +97 -0
  138. package/node_modules/luxon/src/zones/IANAZone.js +235 -0
  139. package/node_modules/luxon/src/zones/fixedOffsetZone.js +150 -0
  140. package/node_modules/luxon/src/zones/invalidZone.js +53 -0
  141. package/node_modules/luxon/src/zones/systemZone.js +61 -0
  142. package/package.json +33 -24
@@ -0,0 +1,180 @@
1
+ import SystemZone from "./zones/systemZone.js";
2
+ import IANAZone from "./zones/IANAZone.js";
3
+ import Locale from "./impl/locale.js";
4
+ import DateTime from "./datetime.js";
5
+
6
+ import { normalizeZone } from "./impl/zoneUtil.js";
7
+ import { validateWeekSettings } from "./impl/util.js";
8
+ import { resetDigitRegexCache } from "./impl/digits.js";
9
+
10
+ let now = () => Date.now(),
11
+ defaultZone = "system",
12
+ defaultLocale = null,
13
+ defaultNumberingSystem = null,
14
+ defaultOutputCalendar = null,
15
+ twoDigitCutoffYear = 60,
16
+ throwOnInvalid,
17
+ defaultWeekSettings = null;
18
+
19
+ /**
20
+ * Settings contains static getters and setters that control Luxon's overall behavior. Luxon is a simple library with few options, but the ones it does have live here.
21
+ */
22
+ export default class Settings {
23
+ /**
24
+ * Get the callback for returning the current timestamp.
25
+ * @type {function}
26
+ */
27
+ static get now() {
28
+ return now;
29
+ }
30
+
31
+ /**
32
+ * Set the callback for returning the current timestamp.
33
+ * The function should return a number, which will be interpreted as an Epoch millisecond count
34
+ * @type {function}
35
+ * @example Settings.now = () => Date.now() + 3000 // pretend it is 3 seconds in the future
36
+ * @example Settings.now = () => 0 // always pretend it's Jan 1, 1970 at midnight in UTC time
37
+ */
38
+ static set now(n) {
39
+ now = n;
40
+ }
41
+
42
+ /**
43
+ * Set the default time zone to create DateTimes in. Does not affect existing instances.
44
+ * Use the value "system" to reset this value to the system's time zone.
45
+ * @type {string}
46
+ */
47
+ static set defaultZone(zone) {
48
+ defaultZone = zone;
49
+ }
50
+
51
+ /**
52
+ * Get the default time zone object currently used to create DateTimes. Does not affect existing instances.
53
+ * The default value is the system's time zone (the one set on the machine that runs this code).
54
+ * @type {Zone}
55
+ */
56
+ static get defaultZone() {
57
+ return normalizeZone(defaultZone, SystemZone.instance);
58
+ }
59
+
60
+ /**
61
+ * Get the default locale to create DateTimes with. Does not affect existing instances.
62
+ * @type {string}
63
+ */
64
+ static get defaultLocale() {
65
+ return defaultLocale;
66
+ }
67
+
68
+ /**
69
+ * Set the default locale to create DateTimes with. Does not affect existing instances.
70
+ * @type {string}
71
+ */
72
+ static set defaultLocale(locale) {
73
+ defaultLocale = locale;
74
+ }
75
+
76
+ /**
77
+ * Get the default numbering system to create DateTimes with. Does not affect existing instances.
78
+ * @type {string}
79
+ */
80
+ static get defaultNumberingSystem() {
81
+ return defaultNumberingSystem;
82
+ }
83
+
84
+ /**
85
+ * Set the default numbering system to create DateTimes with. Does not affect existing instances.
86
+ * @type {string}
87
+ */
88
+ static set defaultNumberingSystem(numberingSystem) {
89
+ defaultNumberingSystem = numberingSystem;
90
+ }
91
+
92
+ /**
93
+ * Get the default output calendar to create DateTimes with. Does not affect existing instances.
94
+ * @type {string}
95
+ */
96
+ static get defaultOutputCalendar() {
97
+ return defaultOutputCalendar;
98
+ }
99
+
100
+ /**
101
+ * Set the default output calendar to create DateTimes with. Does not affect existing instances.
102
+ * @type {string}
103
+ */
104
+ static set defaultOutputCalendar(outputCalendar) {
105
+ defaultOutputCalendar = outputCalendar;
106
+ }
107
+
108
+ /**
109
+ * @typedef {Object} WeekSettings
110
+ * @property {number} firstDay
111
+ * @property {number} minimalDays
112
+ * @property {number[]} weekend
113
+ */
114
+
115
+ /**
116
+ * @return {WeekSettings|null}
117
+ */
118
+ static get defaultWeekSettings() {
119
+ return defaultWeekSettings;
120
+ }
121
+
122
+ /**
123
+ * Allows overriding the default locale week settings, i.e. the start of the week, the weekend and
124
+ * how many days are required in the first week of a year.
125
+ * Does not affect existing instances.
126
+ *
127
+ * @param {WeekSettings|null} weekSettings
128
+ */
129
+ static set defaultWeekSettings(weekSettings) {
130
+ defaultWeekSettings = validateWeekSettings(weekSettings);
131
+ }
132
+
133
+ /**
134
+ * Get the cutoff year for whether a 2-digit year string is interpreted in the current or previous century. Numbers higher than the cutoff will be considered to mean 19xx and numbers lower or equal to the cutoff will be considered 20xx.
135
+ * @type {number}
136
+ */
137
+ static get twoDigitCutoffYear() {
138
+ return twoDigitCutoffYear;
139
+ }
140
+
141
+ /**
142
+ * Set the cutoff year for whether a 2-digit year string is interpreted in the current or previous century. Numbers higher than the cutoff will be considered to mean 19xx and numbers lower or equal to the cutoff will be considered 20xx.
143
+ * @type {number}
144
+ * @example Settings.twoDigitCutoffYear = 0 // all 'yy' are interpreted as 20th century
145
+ * @example Settings.twoDigitCutoffYear = 99 // all 'yy' are interpreted as 21st century
146
+ * @example Settings.twoDigitCutoffYear = 50 // '49' -> 2049; '50' -> 1950
147
+ * @example Settings.twoDigitCutoffYear = 1950 // interpreted as 50
148
+ * @example Settings.twoDigitCutoffYear = 2050 // ALSO interpreted as 50
149
+ */
150
+ static set twoDigitCutoffYear(cutoffYear) {
151
+ twoDigitCutoffYear = cutoffYear % 100;
152
+ }
153
+
154
+ /**
155
+ * Get whether Luxon will throw when it encounters invalid DateTimes, Durations, or Intervals
156
+ * @type {boolean}
157
+ */
158
+ static get throwOnInvalid() {
159
+ return throwOnInvalid;
160
+ }
161
+
162
+ /**
163
+ * Set whether Luxon will throw when it encounters invalid DateTimes, Durations, or Intervals
164
+ * @type {boolean}
165
+ */
166
+ static set throwOnInvalid(t) {
167
+ throwOnInvalid = t;
168
+ }
169
+
170
+ /**
171
+ * Reset Luxon's global caches. Should only be necessary in testing scenarios.
172
+ * @return {void}
173
+ */
174
+ static resetCaches() {
175
+ Locale.resetCache();
176
+ IANAZone.resetCache();
177
+ DateTime.resetCache();
178
+ resetDigitRegexCache();
179
+ }
180
+ }
@@ -0,0 +1,97 @@
1
+ import { ZoneIsAbstractError } from "./errors.js";
2
+
3
+ /**
4
+ * @interface
5
+ */
6
+ export default class Zone {
7
+ /**
8
+ * The type of zone
9
+ * @abstract
10
+ * @type {string}
11
+ */
12
+ get type() {
13
+ throw new ZoneIsAbstractError();
14
+ }
15
+
16
+ /**
17
+ * The name of this zone.
18
+ * @abstract
19
+ * @type {string}
20
+ */
21
+ get name() {
22
+ throw new ZoneIsAbstractError();
23
+ }
24
+
25
+ /**
26
+ * The IANA name of this zone.
27
+ * Defaults to `name` if not overwritten by a subclass.
28
+ * @abstract
29
+ * @type {string}
30
+ */
31
+ get ianaName() {
32
+ return this.name;
33
+ }
34
+
35
+ /**
36
+ * Returns whether the offset is known to be fixed for the whole year.
37
+ * @abstract
38
+ * @type {boolean}
39
+ */
40
+ get isUniversal() {
41
+ throw new ZoneIsAbstractError();
42
+ }
43
+
44
+ /**
45
+ * Returns the offset's common name (such as EST) at the specified timestamp
46
+ * @abstract
47
+ * @param {number} ts - Epoch milliseconds for which to get the name
48
+ * @param {Object} opts - Options to affect the format
49
+ * @param {string} opts.format - What style of offset to return. Accepts 'long' or 'short'.
50
+ * @param {string} opts.locale - What locale to return the offset name in.
51
+ * @return {string}
52
+ */
53
+ offsetName(ts, opts) {
54
+ throw new ZoneIsAbstractError();
55
+ }
56
+
57
+ /**
58
+ * Returns the offset's value as a string
59
+ * @abstract
60
+ * @param {number} ts - Epoch milliseconds for which to get the offset
61
+ * @param {string} format - What style of offset to return.
62
+ * Accepts 'narrow', 'short', or 'techie'. Returning '+6', '+06:00', or '+0600' respectively
63
+ * @return {string}
64
+ */
65
+ formatOffset(ts, format) {
66
+ throw new ZoneIsAbstractError();
67
+ }
68
+
69
+ /**
70
+ * Return the offset in minutes for this zone at the specified timestamp.
71
+ * @abstract
72
+ * @param {number} ts - Epoch milliseconds for which to compute the offset
73
+ * @return {number}
74
+ */
75
+ offset(ts) {
76
+ throw new ZoneIsAbstractError();
77
+ }
78
+
79
+ /**
80
+ * Return whether this Zone is equal to another zone
81
+ * @abstract
82
+ * @param {Zone} otherZone - the zone to compare
83
+ * @return {boolean}
84
+ */
85
+ equals(otherZone) {
86
+ throw new ZoneIsAbstractError();
87
+ }
88
+
89
+ /**
90
+ * Return whether this Zone is valid.
91
+ * @abstract
92
+ * @type {boolean}
93
+ */
94
+ get isValid() {
95
+ throw new ZoneIsAbstractError();
96
+ }
97
+ }
@@ -0,0 +1,235 @@
1
+ import { formatOffset, parseZoneInfo, isUndefined, objToLocalTS } from "../impl/util.js";
2
+ import Zone from "../zone.js";
3
+
4
+ const dtfCache = new Map();
5
+ function makeDTF(zoneName) {
6
+ let dtf = dtfCache.get(zoneName);
7
+ if (dtf === undefined) {
8
+ dtf = new Intl.DateTimeFormat("en-US", {
9
+ hour12: false,
10
+ timeZone: zoneName,
11
+ year: "numeric",
12
+ month: "2-digit",
13
+ day: "2-digit",
14
+ hour: "2-digit",
15
+ minute: "2-digit",
16
+ second: "2-digit",
17
+ era: "short",
18
+ });
19
+ dtfCache.set(zoneName, dtf);
20
+ }
21
+ return dtf;
22
+ }
23
+
24
+ const typeToPos = {
25
+ year: 0,
26
+ month: 1,
27
+ day: 2,
28
+ era: 3,
29
+ hour: 4,
30
+ minute: 5,
31
+ second: 6,
32
+ };
33
+
34
+ function hackyOffset(dtf, date) {
35
+ const formatted = dtf.format(date).replace(/\u200E/g, ""),
36
+ parsed = /(\d+)\/(\d+)\/(\d+) (AD|BC),? (\d+):(\d+):(\d+)/.exec(formatted),
37
+ [, fMonth, fDay, fYear, fadOrBc, fHour, fMinute, fSecond] = parsed;
38
+ return [fYear, fMonth, fDay, fadOrBc, fHour, fMinute, fSecond];
39
+ }
40
+
41
+ function partsOffset(dtf, date) {
42
+ const formatted = dtf.formatToParts(date);
43
+ const filled = [];
44
+ for (let i = 0; i < formatted.length; i++) {
45
+ const { type, value } = formatted[i];
46
+ const pos = typeToPos[type];
47
+
48
+ if (type === "era") {
49
+ filled[pos] = value;
50
+ } else if (!isUndefined(pos)) {
51
+ filled[pos] = parseInt(value, 10);
52
+ }
53
+ }
54
+ return filled;
55
+ }
56
+
57
+ const ianaZoneCache = new Map();
58
+ /**
59
+ * A zone identified by an IANA identifier, like America/New_York
60
+ * @implements {Zone}
61
+ */
62
+ export default class IANAZone extends Zone {
63
+ /**
64
+ * @param {string} name - Zone name
65
+ * @return {IANAZone}
66
+ */
67
+ static create(name) {
68
+ let zone = ianaZoneCache.get(name);
69
+ if (zone === undefined) {
70
+ ianaZoneCache.set(name, (zone = new IANAZone(name)));
71
+ }
72
+ return zone;
73
+ }
74
+
75
+ /**
76
+ * Reset local caches. Should only be necessary in testing scenarios.
77
+ * @return {void}
78
+ */
79
+ static resetCache() {
80
+ ianaZoneCache.clear();
81
+ dtfCache.clear();
82
+ }
83
+
84
+ /**
85
+ * Returns whether the provided string is a valid specifier. This only checks the string's format, not that the specifier identifies a known zone; see isValidZone for that.
86
+ * @param {string} s - The string to check validity on
87
+ * @example IANAZone.isValidSpecifier("America/New_York") //=> true
88
+ * @example IANAZone.isValidSpecifier("Sport~~blorp") //=> false
89
+ * @deprecated For backward compatibility, this forwards to isValidZone, better use `isValidZone()` directly instead.
90
+ * @return {boolean}
91
+ */
92
+ static isValidSpecifier(s) {
93
+ return this.isValidZone(s);
94
+ }
95
+
96
+ /**
97
+ * Returns whether the provided string identifies a real zone
98
+ * @param {string} zone - The string to check
99
+ * @example IANAZone.isValidZone("America/New_York") //=> true
100
+ * @example IANAZone.isValidZone("Fantasia/Castle") //=> false
101
+ * @example IANAZone.isValidZone("Sport~~blorp") //=> false
102
+ * @return {boolean}
103
+ */
104
+ static isValidZone(zone) {
105
+ if (!zone) {
106
+ return false;
107
+ }
108
+ try {
109
+ new Intl.DateTimeFormat("en-US", { timeZone: zone }).format();
110
+ return true;
111
+ } catch (e) {
112
+ return false;
113
+ }
114
+ }
115
+
116
+ constructor(name) {
117
+ super();
118
+ /** @private **/
119
+ this.zoneName = name;
120
+ /** @private **/
121
+ this.valid = IANAZone.isValidZone(name);
122
+ }
123
+
124
+ /**
125
+ * The type of zone. `iana` for all instances of `IANAZone`.
126
+ * @override
127
+ * @type {string}
128
+ */
129
+ get type() {
130
+ return "iana";
131
+ }
132
+
133
+ /**
134
+ * The name of this zone (i.e. the IANA zone name).
135
+ * @override
136
+ * @type {string}
137
+ */
138
+ get name() {
139
+ return this.zoneName;
140
+ }
141
+
142
+ /**
143
+ * Returns whether the offset is known to be fixed for the whole year:
144
+ * Always returns false for all IANA zones.
145
+ * @override
146
+ * @type {boolean}
147
+ */
148
+ get isUniversal() {
149
+ return false;
150
+ }
151
+
152
+ /**
153
+ * Returns the offset's common name (such as EST) at the specified timestamp
154
+ * @override
155
+ * @param {number} ts - Epoch milliseconds for which to get the name
156
+ * @param {Object} opts - Options to affect the format
157
+ * @param {string} opts.format - What style of offset to return. Accepts 'long' or 'short'.
158
+ * @param {string} opts.locale - What locale to return the offset name in.
159
+ * @return {string}
160
+ */
161
+ offsetName(ts, { format, locale }) {
162
+ return parseZoneInfo(ts, format, locale, this.name);
163
+ }
164
+
165
+ /**
166
+ * Returns the offset's value as a string
167
+ * @override
168
+ * @param {number} ts - Epoch milliseconds for which to get the offset
169
+ * @param {string} format - What style of offset to return.
170
+ * Accepts 'narrow', 'short', or 'techie'. Returning '+6', '+06:00', or '+0600' respectively
171
+ * @return {string}
172
+ */
173
+ formatOffset(ts, format) {
174
+ return formatOffset(this.offset(ts), format);
175
+ }
176
+
177
+ /**
178
+ * Return the offset in minutes for this zone at the specified timestamp.
179
+ * @override
180
+ * @param {number} ts - Epoch milliseconds for which to compute the offset
181
+ * @return {number}
182
+ */
183
+ offset(ts) {
184
+ if (!this.valid) return NaN;
185
+ const date = new Date(ts);
186
+
187
+ if (isNaN(date)) return NaN;
188
+
189
+ const dtf = makeDTF(this.name);
190
+ let [year, month, day, adOrBc, hour, minute, second] = dtf.formatToParts
191
+ ? partsOffset(dtf, date)
192
+ : hackyOffset(dtf, date);
193
+
194
+ if (adOrBc === "BC") {
195
+ year = -Math.abs(year) + 1;
196
+ }
197
+
198
+ // because we're using hour12 and https://bugs.chromium.org/p/chromium/issues/detail?id=1025564&can=2&q=%2224%3A00%22%20datetimeformat
199
+ const adjustedHour = hour === 24 ? 0 : hour;
200
+
201
+ const asUTC = objToLocalTS({
202
+ year,
203
+ month,
204
+ day,
205
+ hour: adjustedHour,
206
+ minute,
207
+ second,
208
+ millisecond: 0,
209
+ });
210
+
211
+ let asTS = +date;
212
+ const over = asTS % 1000;
213
+ asTS -= over >= 0 ? over : 1000 + over;
214
+ return (asUTC - asTS) / (60 * 1000);
215
+ }
216
+
217
+ /**
218
+ * Return whether this Zone is equal to another zone
219
+ * @override
220
+ * @param {Zone} otherZone - the zone to compare
221
+ * @return {boolean}
222
+ */
223
+ equals(otherZone) {
224
+ return otherZone.type === "iana" && otherZone.name === this.name;
225
+ }
226
+
227
+ /**
228
+ * Return whether this Zone is valid.
229
+ * @override
230
+ * @type {boolean}
231
+ */
232
+ get isValid() {
233
+ return this.valid;
234
+ }
235
+ }
@@ -0,0 +1,150 @@
1
+ import { formatOffset, signedOffset } from "../impl/util.js";
2
+ import Zone from "../zone.js";
3
+
4
+ let singleton = null;
5
+
6
+ /**
7
+ * A zone with a fixed offset (meaning no DST)
8
+ * @implements {Zone}
9
+ */
10
+ export default class FixedOffsetZone extends Zone {
11
+ /**
12
+ * Get a singleton instance of UTC
13
+ * @return {FixedOffsetZone}
14
+ */
15
+ static get utcInstance() {
16
+ if (singleton === null) {
17
+ singleton = new FixedOffsetZone(0);
18
+ }
19
+ return singleton;
20
+ }
21
+
22
+ /**
23
+ * Get an instance with a specified offset
24
+ * @param {number} offset - The offset in minutes
25
+ * @return {FixedOffsetZone}
26
+ */
27
+ static instance(offset) {
28
+ return offset === 0 ? FixedOffsetZone.utcInstance : new FixedOffsetZone(offset);
29
+ }
30
+
31
+ /**
32
+ * Get an instance of FixedOffsetZone from a UTC offset string, like "UTC+6"
33
+ * @param {string} s - The offset string to parse
34
+ * @example FixedOffsetZone.parseSpecifier("UTC+6")
35
+ * @example FixedOffsetZone.parseSpecifier("UTC+06")
36
+ * @example FixedOffsetZone.parseSpecifier("UTC-6:00")
37
+ * @return {FixedOffsetZone}
38
+ */
39
+ static parseSpecifier(s) {
40
+ if (s) {
41
+ const r = s.match(/^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$/i);
42
+ if (r) {
43
+ return new FixedOffsetZone(signedOffset(r[1], r[2]));
44
+ }
45
+ }
46
+ return null;
47
+ }
48
+
49
+ constructor(offset) {
50
+ super();
51
+ /** @private **/
52
+ this.fixed = offset;
53
+ }
54
+
55
+ /**
56
+ * The type of zone. `fixed` for all instances of `FixedOffsetZone`.
57
+ * @override
58
+ * @type {string}
59
+ */
60
+ get type() {
61
+ return "fixed";
62
+ }
63
+
64
+ /**
65
+ * The name of this zone.
66
+ * All fixed zones' names always start with "UTC" (plus optional offset)
67
+ * @override
68
+ * @type {string}
69
+ */
70
+ get name() {
71
+ return this.fixed === 0 ? "UTC" : `UTC${formatOffset(this.fixed, "narrow")}`;
72
+ }
73
+
74
+ /**
75
+ * The IANA name of this zone, i.e. `Etc/UTC` or `Etc/GMT+/-nn`
76
+ *
77
+ * @override
78
+ * @type {string}
79
+ */
80
+ get ianaName() {
81
+ if (this.fixed === 0) {
82
+ return "Etc/UTC";
83
+ } else {
84
+ return `Etc/GMT${formatOffset(-this.fixed, "narrow")}`;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Returns the offset's common name at the specified timestamp.
90
+ *
91
+ * For fixed offset zones this equals to the zone name.
92
+ * @override
93
+ */
94
+ offsetName() {
95
+ return this.name;
96
+ }
97
+
98
+ /**
99
+ * Returns the offset's value as a string
100
+ * @override
101
+ * @param {number} ts - Epoch milliseconds for which to get the offset
102
+ * @param {string} format - What style of offset to return.
103
+ * Accepts 'narrow', 'short', or 'techie'. Returning '+6', '+06:00', or '+0600' respectively
104
+ * @return {string}
105
+ */
106
+ formatOffset(ts, format) {
107
+ return formatOffset(this.fixed, format);
108
+ }
109
+
110
+ /**
111
+ * Returns whether the offset is known to be fixed for the whole year:
112
+ * Always returns true for all fixed offset zones.
113
+ * @override
114
+ * @type {boolean}
115
+ */
116
+ get isUniversal() {
117
+ return true;
118
+ }
119
+
120
+ /**
121
+ * Return the offset in minutes for this zone at the specified timestamp.
122
+ *
123
+ * For fixed offset zones, this is constant and does not depend on a timestamp.
124
+ * @override
125
+ * @return {number}
126
+ */
127
+ offset() {
128
+ return this.fixed;
129
+ }
130
+
131
+ /**
132
+ * Return whether this Zone is equal to another zone (i.e. also fixed and same offset)
133
+ * @override
134
+ * @param {Zone} otherZone - the zone to compare
135
+ * @return {boolean}
136
+ */
137
+ equals(otherZone) {
138
+ return otherZone.type === "fixed" && otherZone.fixed === this.fixed;
139
+ }
140
+
141
+ /**
142
+ * Return whether this Zone is valid:
143
+ * All fixed offset zones are valid.
144
+ * @override
145
+ * @type {boolean}
146
+ */
147
+ get isValid() {
148
+ return true;
149
+ }
150
+ }
@@ -0,0 +1,53 @@
1
+ import Zone from "../zone.js";
2
+
3
+ /**
4
+ * A zone that failed to parse. You should never need to instantiate this.
5
+ * @implements {Zone}
6
+ */
7
+ export default class InvalidZone extends Zone {
8
+ constructor(zoneName) {
9
+ super();
10
+ /** @private */
11
+ this.zoneName = zoneName;
12
+ }
13
+
14
+ /** @override **/
15
+ get type() {
16
+ return "invalid";
17
+ }
18
+
19
+ /** @override **/
20
+ get name() {
21
+ return this.zoneName;
22
+ }
23
+
24
+ /** @override **/
25
+ get isUniversal() {
26
+ return false;
27
+ }
28
+
29
+ /** @override **/
30
+ offsetName() {
31
+ return null;
32
+ }
33
+
34
+ /** @override **/
35
+ formatOffset() {
36
+ return "";
37
+ }
38
+
39
+ /** @override **/
40
+ offset() {
41
+ return NaN;
42
+ }
43
+
44
+ /** @override **/
45
+ equals() {
46
+ return false;
47
+ }
48
+
49
+ /** @override **/
50
+ get isValid() {
51
+ return false;
52
+ }
53
+ }