@determinate-systems/detsys-ts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2024 Determinate Systems, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,6 @@
1
+ # detsys-ts
2
+
3
+ TypeScript goodies for DetSys projects.
4
+ Check out the generated documentation [here][typedoc].
5
+
6
+ [typedoc]: https://detsys-ts-docs.netlify.app
@@ -0,0 +1,339 @@
1
+ import { UUID } from "node:crypto";
2
+ import { Got } from "got";
3
+ //#region src/check-in.d.ts
4
+ type CheckIn = {
5
+ status: StatusSummary | null;
6
+ options: {
7
+ [k: string]: Feature;
8
+ };
9
+ };
10
+ type StatusSummary = {
11
+ page: Page;
12
+ incidents: Incident[];
13
+ scheduled_maintenances: Maintenance[];
14
+ };
15
+ type Page = {
16
+ name: string;
17
+ url: string;
18
+ };
19
+ type Incident = {
20
+ name: string;
21
+ status: string;
22
+ impact: string;
23
+ shortlink: string;
24
+ };
25
+ type Maintenance = {
26
+ name: string;
27
+ status: string;
28
+ impact: string;
29
+ shortlink: string;
30
+ scheduled_for: string;
31
+ scheduled_until: string;
32
+ };
33
+ type Feature = {
34
+ variant: boolean | string;
35
+ payload?: string;
36
+ };
37
+ //#endregion
38
+ //#region src/correlation.d.ts
39
+ /**
40
+ * JSON sent to server.
41
+ */
42
+ type CorrelationProperties = {
43
+ $anon_distinct_id: string;
44
+ $groups: Record<string, string | undefined>;
45
+ $session_id?: string;
46
+ correlation_source: string;
47
+ github_repository_hash?: string;
48
+ github_workflow_hash?: string;
49
+ github_workflow_job_hash?: string;
50
+ github_workflow_run_differentiator_hash?: string;
51
+ github_workflow_run_hash?: string;
52
+ is_ci: boolean;
53
+ };
54
+ //#endregion
55
+ //#region src/errors.d.ts
56
+ /**
57
+ * Coerce a value of type `unknown` into a string.
58
+ */
59
+ declare function stringifyError(e: unknown): string;
60
+ //#endregion
61
+ //#region src/ids-host.d.ts
62
+ /**
63
+ * Host information for install.determinate.systems.
64
+ */
65
+ declare class IdsHost {
66
+ private idsProjectName;
67
+ private diagnosticsSuffix?;
68
+ private runtimeDiagnosticsUrl?;
69
+ private prioritizedURLs?;
70
+ private client?;
71
+ private timeout;
72
+ constructor(idsProjectName: string, diagnosticsSuffix: string | undefined, runtimeDiagnosticsUrl: string | undefined, timeout?: number);
73
+ getGot(recordFailoverCallback?: (incitingError: unknown, prevUrl: URL, nextUrl: URL) => void): Promise<Got>;
74
+ markCurrentHostBroken(): void;
75
+ setPrioritizedUrls(urls: URL[]): void;
76
+ isUrlSubjectToDynamicUrls(url: URL): boolean;
77
+ getDynamicRootUrl(): Promise<URL | undefined>;
78
+ getRootUrl(): Promise<URL>;
79
+ getDiagnosticsUrl(): Promise<URL | undefined>;
80
+ private getUrlsByPreference;
81
+ }
82
+ //#endregion
83
+ //#region src/sourcedef.d.ts
84
+ type SourceDef = {
85
+ path?: string;
86
+ url?: string;
87
+ tag?: string;
88
+ pr?: string;
89
+ branch?: string;
90
+ revision?: string;
91
+ };
92
+ declare namespace inputs_d_exports {
93
+ export { Separator, getArrayOfStrings, getArrayOfStringsOrNull, getBool, getBoolOrUndefined, getMultilineStringOrNull, getNumberOrNull, getNumberOrUndefined, getString, getStringOrNull, getStringOrUndefined, handleString };
94
+ }
95
+ /**
96
+ * Get a Boolean input from the Action's configuration by name.
97
+ */
98
+ declare const getBool: (name: string) => boolean;
99
+ /**
100
+ * Get a Boolean input from the Action's configuration by name, or undefined if it is unset.
101
+ */
102
+ declare const getBoolOrUndefined: (name: string) => boolean | undefined;
103
+ /**
104
+ * The character used to separate values in the input string.
105
+ */
106
+ type Separator = "space" | "comma";
107
+ /**
108
+ * Convert a comma-separated string input into an array of strings. If `comma` is selected,
109
+ * all whitespace is removed from the string before converting to an array.
110
+ */
111
+ declare const getArrayOfStrings: (name: string, separator: Separator) => string[];
112
+ /**
113
+ * Convert a string input into an array of strings or `null` if no value is set.
114
+ */
115
+ declare const getArrayOfStringsOrNull: (name: string, separator: Separator) => string[] | null;
116
+ declare const handleString: (input: string, separator: Separator) => string[];
117
+ /**
118
+ * Get a multi-line string input from the Action's configuration by name or return `null` if not set.
119
+ */
120
+ declare const getMultilineStringOrNull: (name: string) => string[] | null;
121
+ /**
122
+ * Get a number input from the Action's configuration by name or return `null` if not set.
123
+ */
124
+ declare const getNumberOrNull: (name: string) => number | null;
125
+ /**
126
+ * Get a Number input from the Action's configuration by name, or undefined if it is unset.
127
+ */
128
+ declare const getNumberOrUndefined: (name: string) => number | undefined;
129
+ /**
130
+ * Get a string input from the Action's configuration.
131
+ */
132
+ declare const getString: (name: string) => string;
133
+ /**
134
+ * Get a string input from the Action's configuration by name or return `null` if not set.
135
+ */
136
+ declare const getStringOrNull: (name: string) => string | null;
137
+ /**
138
+ * Get a string input from the Action's configuration by name or return `undefined` if not set.
139
+ */
140
+ declare const getStringOrUndefined: (name: string) => string | undefined;
141
+ declare namespace platform_d_exports {
142
+ export { getArchOs, getNixPlatform };
143
+ }
144
+ /**
145
+ * Get the current architecture plus OS. Examples include `X64-Linux` and `ARM64-macOS`.
146
+ */
147
+ declare function getArchOs(): string;
148
+ /**
149
+ * Get the current Nix system. Examples include `x86_64-linux` and `aarch64-darwin`.
150
+ */
151
+ declare function getNixPlatform(archOs: string): string;
152
+ //#endregion
153
+ //#region src/index.d.ts
154
+ /**
155
+ * An enum for describing different "fetch suffixes" for i.d.s.
156
+ *
157
+ * - `nix-style` means that system names like `x86_64-linux` and `aarch64-darwin` are used
158
+ * - `gh-env-style` means that names like `X64-Linux` and `ARM64-macOS` are used
159
+ * - `universal` means that the suffix is the static `universal` (for non-system-specific things)
160
+ */
161
+ type FetchSuffixStyle = "nix-style" | "gh-env-style" | "universal";
162
+ /**
163
+ * GitHub Actions has two possible execution phases: `main` and `post`.
164
+ */
165
+ type ExecutionPhase = "main" | "post";
166
+ /**
167
+ * How to handle whether Nix is currently installed on the runner.
168
+ *
169
+ * - `fail` means that the workflow fails if Nix isn't installed
170
+ * - `warn` means that a warning is logged if Nix isn't installed
171
+ * - `ignore` means that Nix will not be checked
172
+ */
173
+ type NixRequirementHandling = "fail" | "warn" | "ignore";
174
+ /**
175
+ * Whether the Nix store on the runner is trusted.
176
+ *
177
+ * - `trusted` means yes
178
+ * - `untrusted` means no
179
+ * - `unknown` means that the status couldn't be determined
180
+ *
181
+ * This is determined via the output of `nix store info --json`.
182
+ */
183
+ type NixStoreTrust = "trusted" | "untrusted" | "unknown";
184
+ type ActionOptions = {
185
+ name: string;
186
+ idsProjectName?: string;
187
+ eventPrefix?: string;
188
+ fetchStyle: FetchSuffixStyle;
189
+ legacySourcePrefix?: string;
190
+ requireNix: NixRequirementHandling;
191
+ diagnosticsSuffix?: string;
192
+ binaryNamePrefixes?: string[];
193
+ binaryNamesDenyList?: string[];
194
+ };
195
+ /**
196
+ * A confident version of Options, where defaults have been resolved into final values.
197
+ */
198
+ type ConfidentActionOptions = {
199
+ name: string;
200
+ idsProjectName: string;
201
+ eventPrefix: string;
202
+ fetchStyle: FetchSuffixStyle;
203
+ legacySourcePrefix?: string;
204
+ requireNix: NixRequirementHandling;
205
+ providedDiagnosticsUrl?: URL;
206
+ binaryNamePrefixes: string[];
207
+ binaryNamesDenyList: string[];
208
+ };
209
+ /**
210
+ * An event to send to the diagnostic endpoint of i.d.s.
211
+ */
212
+ type DiagnosticEvent = {
213
+ name: string;
214
+ distinct_id?: string;
215
+ uuid: UUID;
216
+ timestamp: Date;
217
+ properties: Record<string, unknown>;
218
+ };
219
+ declare abstract class DetSysAction {
220
+ nixStoreTrust: NixStoreTrust;
221
+ strictMode: boolean;
222
+ private actionOptions;
223
+ private exceptionAttachments;
224
+ private archOs;
225
+ private executionPhase;
226
+ private nixSystem;
227
+ private architectureFetchSuffix;
228
+ private sourceParameters;
229
+ private facts;
230
+ private events;
231
+ private identity;
232
+ private idsHost;
233
+ private features;
234
+ private featureEventMetadata;
235
+ private determineExecutionPhase;
236
+ constructor(actionOptions: ActionOptions);
237
+ /**
238
+ * Attach a file to the diagnostics data in error conditions.
239
+ *
240
+ * The file at `location` doesn't need to exist when stapleFile is called.
241
+ *
242
+ * If the file doesn't exist or is unreadable when trying to staple the attachments, the JS error will be stored in a context value at `staple_failure_{name}`.
243
+ * If the file is readable, the file's contents will be stored in a context value at `staple_value_{name}`.
244
+ */
245
+ stapleFile(name: string, location: string): void;
246
+ /**
247
+ * The main execution phase.
248
+ */
249
+ abstract main(): Promise<void>;
250
+ /**
251
+ * The post execution phase.
252
+ */
253
+ abstract post(): Promise<void>;
254
+ /**
255
+ * Execute the Action as defined.
256
+ */
257
+ execute(): void;
258
+ getTemporaryName(): string;
259
+ addFact(key: string, value: string | boolean | number): void;
260
+ getDiagnosticsUrl(): Promise<URL | undefined>;
261
+ getUniqueId(): string;
262
+ getCrossPhaseId(): string;
263
+ getCorrelationHashes(): CorrelationProperties;
264
+ recordEvent(eventName: string, context?: Record<string, boolean | string | number | undefined | Record<string, boolean | string | number | undefined>>): void;
265
+ /**
266
+ * Unpacks the closure returned by `fetchArtifact()`, imports the
267
+ * contents into the Nix store, and returns the path of the executable at
268
+ * `/nix/store/STORE_PATH/bin/${bin}`.
269
+ */
270
+ unpackClosure(bin: string): Promise<string>;
271
+ /**
272
+ * Fetches the executable at the URL determined by the `source-*` inputs and
273
+ * other facts, `chmod`s it, and returns the path to the executable on disk.
274
+ */
275
+ fetchExecutable(): Promise<string>;
276
+ private get isMain();
277
+ private get isPost();
278
+ private executeAsync;
279
+ getClient(): Promise<Got>;
280
+ private checkIn;
281
+ getFeature(name: string): Feature | undefined;
282
+ private recordGroup;
283
+ /**
284
+ * Check in to install.determinate.systems, to accomplish three things:
285
+ *
286
+ * 1. Preflight the server selected from IdsHost, to increase the chances of success.
287
+ * 2. Fetch any incidents and maintenance events to let users know in case things are weird.
288
+ * 3. Get feature flag data so we can gently roll out new features.
289
+ */
290
+ private requestCheckIn;
291
+ private recordPlausibleTimeout;
292
+ /**
293
+ * Fetch an artifact, such as a tarball, from the location determined by the
294
+ * `source-*` inputs. If `source-binary` is specified, this will return a path
295
+ * to a binary on disk; otherwise, the artifact will be downloaded from the
296
+ * URL determined by the other `source-*` inputs (`source-url`, `source-pr`,
297
+ * etc.).
298
+ *
299
+ * When `source-checksums-url` and `source-checksums-sha256` are both set,
300
+ * the downloaded artifact is verified against the per-arch hash in the
301
+ * checksums file, which is itself verified against the pinned
302
+ * `source-checksums-sha256`. Both inputs must be set together.
303
+ */
304
+ private fetchArtifact;
305
+ /**
306
+ * Read the `source-checksums-url` and `source-checksums-sha256` inputs and,
307
+ * if both are set, fetch the checksums file, verify its hash matches the
308
+ * pin, parse it, and return the expected hash for the artifact matching
309
+ * this runner's `${name}-${architectureFetchSuffix}`. Returns `null` when
310
+ * verification is opted out (both inputs unset).
311
+ */
312
+ private resolveExpectedArtifactHash;
313
+ /**
314
+ * Verify a downloaded artifact's SHA-256 matches the expected hash. No-op
315
+ * when `expected` is `null` (verification disabled).
316
+ */
317
+ private verifyArtifactHash;
318
+ /**
319
+ * A helper function for failing on error only if strict mode is enabled.
320
+ * This is intended only for CI environments testing Actions themselves.
321
+ */
322
+ failOnError(msg: string): void;
323
+ private downloadFile;
324
+ private complete;
325
+ private getCheckInUrl;
326
+ private getSourceUrl;
327
+ private cacheKey;
328
+ private getCachedVersion;
329
+ private saveCachedVersion;
330
+ private collectBacktraceSetup;
331
+ private collectBacktraces;
332
+ private preflightRequireNix;
333
+ private preflightNixStoreInfo;
334
+ private preflightNixVersion;
335
+ private submitEvents;
336
+ }
337
+ //#endregion
338
+ export { ActionOptions, type CheckIn, ConfidentActionOptions, type CorrelationProperties, DetSysAction, DiagnosticEvent, ExecutionPhase, type Feature, FetchSuffixStyle, IdsHost, type Incident, type Maintenance, NixRequirementHandling, NixStoreTrust, type Page, type SourceDef, type StatusSummary, inputs_d_exports as inputs, platform_d_exports as platform, stringifyError };
339
+ //# sourceMappingURL=index.d.mts.map