fleetfizz 0.1.0 → 0.2.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.
- package/dist/fleetfizz.mjs +1581 -89
- package/fleet.schema.json +18 -0
- package/package.json +1 -1
package/dist/fleetfizz.mjs
CHANGED
|
@@ -6708,6 +6708,8 @@ const tapEffectCont = function(value) {
|
|
|
6708
6708
|
return new ContImpl(this.payload, succeedPayload, value);
|
|
6709
6709
|
};
|
|
6710
6710
|
/** @internal */
|
|
6711
|
+
const asSome = (self) => map$7(self, some);
|
|
6712
|
+
/** @internal */
|
|
6711
6713
|
const andThen$1 = /*#__PURE__*/ dual(2, (self, f) => new ContImpl(self, isEffect$1(f) ? returnPayload : andThenCont, f));
|
|
6712
6714
|
/** @internal */
|
|
6713
6715
|
const tap$1 = /*#__PURE__*/ dual(2, (self, f) => new ContImpl(self, isEffect$1(f) ? tapEffectCont : tapCont, f));
|
|
@@ -6959,6 +6961,10 @@ const exitPrimitive = /*#__PURE__*/ makePrimitive$1({
|
|
|
6959
6961
|
}
|
|
6960
6962
|
});
|
|
6961
6963
|
/** @internal */
|
|
6964
|
+
const timeoutOrElse$1 = /*#__PURE__*/ dual(2, (self, options) => flatMap$2(timeoutOption(self, options.duration), (option) => isNone(option) ? options.orElse() : succeed$6(option.value)));
|
|
6965
|
+
/** @internal */
|
|
6966
|
+
const timeoutOption = /*#__PURE__*/ dual(2, (self, duration) => raceFirst$1(asSome(self), as$1(sleep$1(duration), none())));
|
|
6967
|
+
/** @internal */
|
|
6962
6968
|
const ScopeTypeId = "~effect/Scope";
|
|
6963
6969
|
/** @internal */
|
|
6964
6970
|
const ScopeCloseableTypeId = "~effect/Scope/Closeable";
|
|
@@ -9379,7 +9385,19 @@ const Proto$7 = {
|
|
|
9379
9385
|
return toDateUtc$1(this).toJSON();
|
|
9380
9386
|
}
|
|
9381
9387
|
};
|
|
9382
|
-
|
|
9388
|
+
const ProtoUtc = {
|
|
9389
|
+
...Proto$7,
|
|
9390
|
+
_tag: "Utc",
|
|
9391
|
+
[symbol$1]() {
|
|
9392
|
+
return number$1(this.epochMilliseconds);
|
|
9393
|
+
},
|
|
9394
|
+
[symbol](that) {
|
|
9395
|
+
return isDateTime$1(that) && that._tag === "Utc" && this.epochMilliseconds === that.epochMilliseconds;
|
|
9396
|
+
},
|
|
9397
|
+
toString() {
|
|
9398
|
+
return `DateTime.Utc(${toDateUtc$1(this).toJSON()})`;
|
|
9399
|
+
}
|
|
9400
|
+
};
|
|
9383
9401
|
({ ...Proto$7 });
|
|
9384
9402
|
const ProtoTimeZone = {
|
|
9385
9403
|
[TimeZoneTypeId]: TimeZoneTypeId,
|
|
@@ -9390,7 +9408,23 @@ const ProtoTimeZone = {
|
|
|
9390
9408
|
({ ...ProtoTimeZone });
|
|
9391
9409
|
({ ...ProtoTimeZone });
|
|
9392
9410
|
/** @internal */
|
|
9411
|
+
const isDateTime$1 = (u) => hasProperty(u, TypeId$27);
|
|
9412
|
+
const makeUtc = (epochMillis) => {
|
|
9413
|
+
const self = Object.create(ProtoUtc);
|
|
9414
|
+
self.epochMilliseconds = epochMillis;
|
|
9415
|
+
Object.defineProperty(self, "partsUtc", {
|
|
9416
|
+
value: void 0,
|
|
9417
|
+
enumerable: false,
|
|
9418
|
+
writable: true
|
|
9419
|
+
});
|
|
9420
|
+
return self;
|
|
9421
|
+
};
|
|
9422
|
+
/** @internal */
|
|
9423
|
+
const now$1 = /*#__PURE__*/ map$7(currentTimeMillis, makeUtc);
|
|
9424
|
+
/** @internal */
|
|
9393
9425
|
const toDateUtc$1 = (self) => new Date(self.epochMilliseconds);
|
|
9426
|
+
/** @internal */
|
|
9427
|
+
const formatIso$1 = (self) => toDateUtc$1(self).toISOString();
|
|
9394
9428
|
globalThis.Number;
|
|
9395
9429
|
/**
|
|
9396
9430
|
* Returns the number rounded with the given precision.
|
|
@@ -11078,6 +11112,35 @@ const ignore = ignore$1;
|
|
|
11078
11112
|
*/
|
|
11079
11113
|
const orElseSucceed = orElseSucceed$1;
|
|
11080
11114
|
/**
|
|
11115
|
+
* Applies a timeout to an effect, lazily evaluating `orElse` after interrupting
|
|
11116
|
+
* the source if the timeout is reached.
|
|
11117
|
+
*
|
|
11118
|
+
* **Example** (Falling back on timeout)
|
|
11119
|
+
*
|
|
11120
|
+
* ```ts import.meta.vitest
|
|
11121
|
+
* import { Effect } from "effect"
|
|
11122
|
+
* const output: Array<unknown> = []
|
|
11123
|
+
*
|
|
11124
|
+
* const program = Effect.timeoutOrElse(Effect.never, {
|
|
11125
|
+
* duration: 0,
|
|
11126
|
+
* orElse: () => Effect.sync(() => { output.push("Query timed out, using cached data") }).pipe(
|
|
11127
|
+
* Effect.as("Cached result")
|
|
11128
|
+
* )
|
|
11129
|
+
* })
|
|
11130
|
+
*
|
|
11131
|
+
* void output.push(await Effect.runPromise(program))
|
|
11132
|
+
* output // => ["Query timed out, using cached data", "Cached result"]
|
|
11133
|
+
* ```
|
|
11134
|
+
*
|
|
11135
|
+
* @see {@link timeout} for failing with a `TimeoutError`.
|
|
11136
|
+
* @see {@link timeoutOption} for returning `Option.none` on timeout.
|
|
11137
|
+
*
|
|
11138
|
+
* @stability stable
|
|
11139
|
+
* @category delays & timeouts
|
|
11140
|
+
* @since 4.0.0
|
|
11141
|
+
*/
|
|
11142
|
+
const timeoutOrElse = timeoutOrElse$1;
|
|
11143
|
+
/**
|
|
11081
11144
|
* Returns an effect that suspends the current fiber for the specified duration
|
|
11082
11145
|
* without blocking a JavaScript thread.
|
|
11083
11146
|
*
|
|
@@ -16538,17 +16601,56 @@ function resolve$1(ast) {
|
|
|
16538
16601
|
return ast.checks ? ast.checks[ast.checks.length - 1].annotations : ast.annotations;
|
|
16539
16602
|
}
|
|
16540
16603
|
/** @internal */
|
|
16604
|
+
function resolveAt(key) {
|
|
16605
|
+
return (ast) => resolve$1(ast)?.[key];
|
|
16606
|
+
}
|
|
16607
|
+
/** @internal */
|
|
16541
16608
|
const STRUCTURAL_ANNOTATION_KEY = "~structural";
|
|
16542
16609
|
/** @internal */
|
|
16610
|
+
const IDENTIFIER_FALLBACK_KEY = "~identifier";
|
|
16611
|
+
/** @internal */
|
|
16543
16612
|
const SENTINELS_ANNOTATION_KEY = "~sentinels";
|
|
16544
16613
|
/** @internal */
|
|
16545
16614
|
const CONSTRUCTOR_ANNOTATION_KEY = "~constructor";
|
|
16546
16615
|
/** @internal */
|
|
16616
|
+
const jsonSchemaAnnotationKeys = [
|
|
16617
|
+
"title",
|
|
16618
|
+
"description",
|
|
16619
|
+
"default",
|
|
16620
|
+
"examples",
|
|
16621
|
+
"readOnly",
|
|
16622
|
+
"writeOnly",
|
|
16623
|
+
"format",
|
|
16624
|
+
"contentEncoding",
|
|
16625
|
+
"contentMediaType",
|
|
16626
|
+
"contentSchema"
|
|
16627
|
+
];
|
|
16628
|
+
/** @internal */
|
|
16629
|
+
const resolveIdentifier = /*#__PURE__*/ resolveAt("identifier");
|
|
16630
|
+
/** @internal */
|
|
16631
|
+
const resolveIdentifierFallback = /*#__PURE__*/ resolveAt(IDENTIFIER_FALLBACK_KEY);
|
|
16632
|
+
/** @internal */
|
|
16547
16633
|
const getExpected = /*#__PURE__*/ memoize((ast) => {
|
|
16548
16634
|
const identifier = resolve$1(ast)?.identifier;
|
|
16549
16635
|
if (typeof identifier === "string") return identifier;
|
|
16550
16636
|
return ast.getExpected(getExpected);
|
|
16551
16637
|
});
|
|
16638
|
+
/** @internal */
|
|
16639
|
+
const annotationExcludedKeys = /*#__PURE__*/ new Set([
|
|
16640
|
+
SENTINELS_ANNOTATION_KEY,
|
|
16641
|
+
STRUCTURAL_ANNOTATION_KEY,
|
|
16642
|
+
"representation",
|
|
16643
|
+
"arbitraryConstraint",
|
|
16644
|
+
"toJsonSchema",
|
|
16645
|
+
"toCode",
|
|
16646
|
+
"toEquivalence",
|
|
16647
|
+
"toFormatter",
|
|
16648
|
+
"toCodec",
|
|
16649
|
+
"toCodecJson",
|
|
16650
|
+
"toCodecStringTree",
|
|
16651
|
+
"toCodecIso",
|
|
16652
|
+
"toCodecArbitrary"
|
|
16653
|
+
]);
|
|
16552
16654
|
//#endregion
|
|
16553
16655
|
//#region ../../node_modules/.pnpm/effect@4.0.2/node_modules/effect/dist/internal/schema/parser.js
|
|
16554
16656
|
/** @internal */
|
|
@@ -17077,6 +17179,48 @@ function getSchemaIssueOrThrow(cause, message) {
|
|
|
17077
17179
|
if (issue === void 0) throw new Error(message, { cause });
|
|
17078
17180
|
return issue;
|
|
17079
17181
|
}
|
|
17182
|
+
/**
|
|
17183
|
+
* Gets the current time using the `Clock` service and converts it to a `DateTime`.
|
|
17184
|
+
*
|
|
17185
|
+
* **Example** (Getting the current DateTime)
|
|
17186
|
+
*
|
|
17187
|
+
* ```ts import.meta.vitest
|
|
17188
|
+
* import { DateTime, Effect } from "effect"
|
|
17189
|
+
* import { TestClock } from "effect/testing"
|
|
17190
|
+
*
|
|
17191
|
+
* await Effect.runPromise(Effect.map(DateTime.now, DateTime.isDateTime)) // => true
|
|
17192
|
+
* ```
|
|
17193
|
+
*
|
|
17194
|
+
* @stability stable
|
|
17195
|
+
* @category constructors
|
|
17196
|
+
* @since 3.6.0
|
|
17197
|
+
*/
|
|
17198
|
+
const now = now$1;
|
|
17199
|
+
/**
|
|
17200
|
+
* Formats a `DateTime` as a UTC ISO string.
|
|
17201
|
+
*
|
|
17202
|
+
* **Details**
|
|
17203
|
+
*
|
|
17204
|
+
* Always returns the UTC representation in ISO 8601 format, ignoring any time zone.
|
|
17205
|
+
*
|
|
17206
|
+
* **Example** (Formatting DateTime values as ISO strings)
|
|
17207
|
+
*
|
|
17208
|
+
* ```ts import.meta.vitest
|
|
17209
|
+
* import { DateTime } from "effect"
|
|
17210
|
+
*
|
|
17211
|
+
* DateTime.formatIso(DateTime.makeUnsafe("2024-01-01T12:30:45.123Z")) // => "2024-01-01T12:30:45.123Z"
|
|
17212
|
+
*
|
|
17213
|
+
* const zoned = DateTime.makeZonedUnsafe("2024-01-01T12:30:45.123Z", {
|
|
17214
|
+
* timeZone: "Europe/London"
|
|
17215
|
+
* })
|
|
17216
|
+
* DateTime.formatIso(zoned) // => "2024-01-01T12:30:45.123Z"
|
|
17217
|
+
* ```
|
|
17218
|
+
*
|
|
17219
|
+
* @stability stable
|
|
17220
|
+
* @category formatting
|
|
17221
|
+
* @since 3.6.0
|
|
17222
|
+
*/
|
|
17223
|
+
const formatIso = formatIso$1;
|
|
17080
17224
|
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
17081
17225
|
const codes = /*#__PURE__*/ (/* @__PURE__ */ new Uint8Array(123)).fill(255);
|
|
17082
17226
|
for (let i = 0; i < 64; i++) codes[/*#__PURE__*/ alphabet.charCodeAt(i)] = i;
|
|
@@ -19470,6 +19614,10 @@ function record(key, value) {
|
|
|
19470
19614
|
function isOptional(ast) {
|
|
19471
19615
|
return ast.context?.isOptional ?? false;
|
|
19472
19616
|
}
|
|
19617
|
+
/** @internal */
|
|
19618
|
+
function isMutable(ast) {
|
|
19619
|
+
return ast.context?.isMutable ?? false;
|
|
19620
|
+
}
|
|
19473
19621
|
function isStructuralCheck(check) {
|
|
19474
19622
|
return check.annotations?.["~structural"] === true || check._tag === "FilterGroup" && check.checks.every(isStructuralCheck);
|
|
19475
19623
|
}
|
|
@@ -19640,6 +19788,11 @@ const parameterFromString = /*#__PURE__*/ applyToSelfOrLastLinkEncodingIdempoten
|
|
|
19640
19788
|
case "Union": return ast.recur(parameterFromString);
|
|
19641
19789
|
}
|
|
19642
19790
|
});
|
|
19791
|
+
/**
|
|
19792
|
+
* any string, including newlines
|
|
19793
|
+
* @internal
|
|
19794
|
+
*/
|
|
19795
|
+
const STRING_PATTERN = "[\\s\\S]*?";
|
|
19643
19796
|
const isStringFiniteRegExp = /*#__PURE__*/ new globalThis.RegExp(`^${FINITE_PATTERN}$`);
|
|
19644
19797
|
const isStringNumberRegExp = /*#__PURE__*/ new globalThis.RegExp(`^(?:${FINITE_PATTERN}|Infinity|-Infinity|NaN)$`);
|
|
19645
19798
|
/** @internal */
|
|
@@ -19750,6 +19903,10 @@ const Json$1 = /*#__PURE__*/ new Declaration([], () => (input, ast, options) =>
|
|
|
19750
19903
|
toCodecJson: () => void 0,
|
|
19751
19904
|
toCodecStringTree: () => unknownToStringTree
|
|
19752
19905
|
});
|
|
19906
|
+
/** @internal */
|
|
19907
|
+
const unknownToJson = /*#__PURE__*/ new Link(Json$1, /*#__PURE__*/ passthrough());
|
|
19908
|
+
/** @internal */
|
|
19909
|
+
const objectKeywordToJson = /*#__PURE__*/ new Link(/*#__PURE__*/ new Union$1([/*#__PURE__*/ new Arrays(false, [], [Json$1]), /*#__PURE__*/ new Objects([], [/*#__PURE__*/ new IndexSignature(string, Json$1)])]), /*#__PURE__*/ passthrough());
|
|
19753
19910
|
/**
|
|
19754
19911
|
* Returns true if the value is a StringTree value.
|
|
19755
19912
|
*
|
|
@@ -22226,7 +22383,223 @@ function make$5(ast, options) {
|
|
|
22226
22383
|
return self;
|
|
22227
22384
|
}
|
|
22228
22385
|
//#endregion
|
|
22386
|
+
//#region ../../node_modules/.pnpm/effect@4.0.2/node_modules/effect/dist/JsonPointer.js
|
|
22387
|
+
/**
|
|
22388
|
+
* Helpers for escaping JSON Pointer path segments and converting JSON Pointer
|
|
22389
|
+
* URI fragments. JSON Pointer uses `/` to separate path tokens inside a JSON
|
|
22390
|
+
* document, so token text must encode literal `~` and `/` characters. URI
|
|
22391
|
+
* fragments additionally apply percent-encoding after JSON Pointer escaping.
|
|
22392
|
+
*
|
|
22393
|
+
* @stability stable
|
|
22394
|
+
* @since 4.0.0
|
|
22395
|
+
*/
|
|
22396
|
+
/**
|
|
22397
|
+
* Escapes a JSON Pointer reference token according to RFC 6901 by encoding special characters so the token can be safely used as a segment in a JSON Pointer.
|
|
22398
|
+
*
|
|
22399
|
+
* **When to use**
|
|
22400
|
+
*
|
|
22401
|
+
* Use when you need to escape a single JSON Pointer path segment.
|
|
22402
|
+
*
|
|
22403
|
+
* **Details**
|
|
22404
|
+
*
|
|
22405
|
+
* - Returns a new escaped string
|
|
22406
|
+
* - Replaces `~` (tilde) with `~0` and `/` (forward slash) with `~1`
|
|
22407
|
+
* - Returns the input unchanged if it contains no special characters
|
|
22408
|
+
* - Empty strings are valid and returned unchanged
|
|
22409
|
+
*
|
|
22410
|
+
* **Gotchas**
|
|
22411
|
+
*
|
|
22412
|
+
* The replacement order matters: `~` is replaced before `/` to prevent double-escaping.
|
|
22413
|
+
*
|
|
22414
|
+
* **Example** (Escaping special characters)
|
|
22415
|
+
*
|
|
22416
|
+
* ```ts import.meta.vitest
|
|
22417
|
+
* import { JsonPointer } from "effect"
|
|
22418
|
+
*
|
|
22419
|
+
* JsonPointer.escapeToken("a/b") // => "a~1b"
|
|
22420
|
+
* JsonPointer.escapeToken("c~d") // => "c~0d"
|
|
22421
|
+
* JsonPointer.escapeToken("path/to~key") // => "path~1to~0key"
|
|
22422
|
+
* ```
|
|
22423
|
+
*
|
|
22424
|
+
* @see {@link unescapeToken} The inverse operation for decoding escaped tokens
|
|
22425
|
+
* @stability stable
|
|
22426
|
+
* @category encoding
|
|
22427
|
+
* @since 4.0.0
|
|
22428
|
+
*/
|
|
22429
|
+
function escapeToken(token) {
|
|
22430
|
+
return token.replace(/~/g, "~0").replace(/\//g, "~1");
|
|
22431
|
+
}
|
|
22432
|
+
/**
|
|
22433
|
+
* Decodes a JSON Pointer reference token according to RFC 6901 escaping rules.
|
|
22434
|
+
*
|
|
22435
|
+
* **When to use**
|
|
22436
|
+
*
|
|
22437
|
+
* Use when you need to decode a single escaped JSON Pointer path segment.
|
|
22438
|
+
*
|
|
22439
|
+
* **Details**
|
|
22440
|
+
*
|
|
22441
|
+
* - Returns a new unescaped string
|
|
22442
|
+
* - Replaces `~1` with `/` (forward slash) and `~0` with `~` (tilde)
|
|
22443
|
+
* - Returns the input unchanged if it contains no escaped sequences
|
|
22444
|
+
* - Empty strings are valid and returned unchanged
|
|
22445
|
+
*
|
|
22446
|
+
* **Gotchas**
|
|
22447
|
+
*
|
|
22448
|
+
* The replacement order matters: `~1` is replaced before `~0` to prevent incorrect decoding.
|
|
22449
|
+
*
|
|
22450
|
+
* **Example** (Unescaping special characters)
|
|
22451
|
+
*
|
|
22452
|
+
* ```ts import.meta.vitest
|
|
22453
|
+
* import { JsonPointer } from "effect"
|
|
22454
|
+
*
|
|
22455
|
+
* JsonPointer.unescapeToken("a~1b") // => "a/b"
|
|
22456
|
+
* JsonPointer.unescapeToken("c~0d") // => "c~d"
|
|
22457
|
+
* JsonPointer.unescapeToken("path~1to~0key") // => "path/to~key"
|
|
22458
|
+
* ```
|
|
22459
|
+
*
|
|
22460
|
+
* @see {@link escapeToken} The inverse operation for encoding tokens
|
|
22461
|
+
* @stability stable
|
|
22462
|
+
* @category decoding
|
|
22463
|
+
* @since 4.0.0
|
|
22464
|
+
*/
|
|
22465
|
+
function unescapeToken(token) {
|
|
22466
|
+
return token.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
22467
|
+
}
|
|
22468
|
+
/** @internal */
|
|
22469
|
+
function formatUriFragmentToken(token) {
|
|
22470
|
+
return encodeURI(escapeToken(token)).replace(/#/g, "%23");
|
|
22471
|
+
}
|
|
22472
|
+
/** @internal */
|
|
22473
|
+
function decodeUriFragment(fragment) {
|
|
22474
|
+
if (fragment.length === 0 || fragment === "#") return "";
|
|
22475
|
+
if (!fragment.startsWith("#")) return void 0;
|
|
22476
|
+
const encoded = fragment.slice(1);
|
|
22477
|
+
try {
|
|
22478
|
+
if (encodeURI(encoded).replace(/%25/g, "%").replace(/#/g, "%23") !== encoded) return void 0;
|
|
22479
|
+
const pointer = decodeURIComponent(encoded);
|
|
22480
|
+
return pointer.startsWith("/") && !/~(?:[^01]|$)/.test(pointer) ? pointer : void 0;
|
|
22481
|
+
} catch {
|
|
22482
|
+
return;
|
|
22483
|
+
}
|
|
22484
|
+
}
|
|
22485
|
+
//#endregion
|
|
22486
|
+
//#region ../../node_modules/.pnpm/effect@4.0.2/node_modules/effect/dist/JsonSchema.js
|
|
22487
|
+
/**
|
|
22488
|
+
* Helpers for normalizing and converting JSON Schema and OpenAPI schema
|
|
22489
|
+
* documents. Supported inputs include JSON Schema Draft-07, Draft 2020-12,
|
|
22490
|
+
* OpenAPI 3.0, and OpenAPI 3.1; conversions normalize through
|
|
22491
|
+
* `Document<"draft-2020-12">` before emitting another dialect, including
|
|
22492
|
+
* JSON Schema Draft-04. The module also defines document types, meta-schema
|
|
22493
|
+
* constants, and OpenAPI component-key helpers.
|
|
22494
|
+
*
|
|
22495
|
+
* @stability stable
|
|
22496
|
+
* @since 4.0.0
|
|
22497
|
+
*/
|
|
22498
|
+
/**
|
|
22499
|
+
* Represents the `$schema` meta-schema URI for JSON Schema Draft 2020-12.
|
|
22500
|
+
*
|
|
22501
|
+
* **When to use**
|
|
22502
|
+
*
|
|
22503
|
+
* Use when you need to populate the `$schema` field while emitting a JSON
|
|
22504
|
+
* Schema document that should declare JSON Schema Draft 2020-12.
|
|
22505
|
+
*
|
|
22506
|
+
* **Details**
|
|
22507
|
+
*
|
|
22508
|
+
* The exported value is the literal string
|
|
22509
|
+
* `https://json-schema.org/draft/2020-12/schema`.
|
|
22510
|
+
*
|
|
22511
|
+
* @see {@link META_SCHEMA_URI_DRAFT_07} for the Draft-07 `$schema` URI
|
|
22512
|
+
*
|
|
22513
|
+
* @stability stable
|
|
22514
|
+
* @category constants
|
|
22515
|
+
* @since 4.0.0
|
|
22516
|
+
*/
|
|
22517
|
+
const META_SCHEMA_URI_DRAFT_2020_12 = "https://json-schema.org/draft/2020-12/schema";
|
|
22518
|
+
function transformSchema(node, transform) {
|
|
22519
|
+
return walk(node, false, true);
|
|
22520
|
+
function walk(node, inheritedResource, isRoot = false) {
|
|
22521
|
+
if (!isObject(node)) return node;
|
|
22522
|
+
const inEmbeddedResource = inheritedResource || !isRoot && createsResource(node.$id);
|
|
22523
|
+
const out = {};
|
|
22524
|
+
for (const key of Object.keys(node)) {
|
|
22525
|
+
const value = node[key];
|
|
22526
|
+
let transformed = value;
|
|
22527
|
+
switch (key) {
|
|
22528
|
+
case "$defs":
|
|
22529
|
+
case "properties":
|
|
22530
|
+
case "patternProperties":
|
|
22531
|
+
case "dependentSchemas":
|
|
22532
|
+
transformed = mapObject(value, (value) => walk(value, inEmbeddedResource)) ?? value;
|
|
22533
|
+
break;
|
|
22534
|
+
case "allOf":
|
|
22535
|
+
case "anyOf":
|
|
22536
|
+
case "oneOf":
|
|
22537
|
+
case "prefixItems":
|
|
22538
|
+
transformed = Array.isArray(value) ? value.map((value) => walk(value, inEmbeddedResource)) : value;
|
|
22539
|
+
break;
|
|
22540
|
+
case "not":
|
|
22541
|
+
case "additionalProperties":
|
|
22542
|
+
case "propertyNames":
|
|
22543
|
+
case "unevaluatedProperties":
|
|
22544
|
+
case "items":
|
|
22545
|
+
case "contains":
|
|
22546
|
+
case "unevaluatedItems":
|
|
22547
|
+
case "if":
|
|
22548
|
+
case "then":
|
|
22549
|
+
case "else":
|
|
22550
|
+
case "contentSchema": transformed = walk(value, inEmbeddedResource);
|
|
22551
|
+
}
|
|
22552
|
+
assignProperty(out, key, transformed);
|
|
22553
|
+
}
|
|
22554
|
+
transform(out, inEmbeddedResource);
|
|
22555
|
+
return out;
|
|
22556
|
+
}
|
|
22557
|
+
}
|
|
22558
|
+
/** @internal */
|
|
22559
|
+
function rewriteRefs(schema, rewrite) {
|
|
22560
|
+
return transformSchema(schema, (schema) => {
|
|
22561
|
+
rewriteSchemaRef(schema, rewrite);
|
|
22562
|
+
});
|
|
22563
|
+
}
|
|
22564
|
+
function rewriteSchemaRef(schema, rewrite) {
|
|
22565
|
+
if (typeof schema.$ref === "string") assignProperty(schema, "$ref", rewrite(schema.$ref, "$ref"));
|
|
22566
|
+
if (typeof schema.$dynamicRef === "string") assignProperty(schema, "$dynamicRef", rewrite(schema.$dynamicRef, "$dynamicRef"));
|
|
22567
|
+
}
|
|
22568
|
+
function mapObject(value, f) {
|
|
22569
|
+
if (!isObject(value)) return void 0;
|
|
22570
|
+
const out = {};
|
|
22571
|
+
for (const key of Object.keys(value)) assignProperty(out, key, f(value[key], key));
|
|
22572
|
+
return out;
|
|
22573
|
+
}
|
|
22574
|
+
function createsResource(id) {
|
|
22575
|
+
return typeof id === "string" && id.length > 0 && id[0] !== "#";
|
|
22576
|
+
}
|
|
22577
|
+
const PRE_2020_TO_2020_COLLISIONS = [
|
|
22578
|
+
"$anchor",
|
|
22579
|
+
"$defs",
|
|
22580
|
+
"$dynamicAnchor",
|
|
22581
|
+
"$dynamicRef",
|
|
22582
|
+
"$vocabulary",
|
|
22583
|
+
"contentSchema",
|
|
22584
|
+
"dependentRequired",
|
|
22585
|
+
"dependentSchemas",
|
|
22586
|
+
"maxContains",
|
|
22587
|
+
"minContains",
|
|
22588
|
+
"prefixItems",
|
|
22589
|
+
"unevaluatedItems",
|
|
22590
|
+
"unevaluatedProperties"
|
|
22591
|
+
];
|
|
22592
|
+
[...PRE_2020_TO_2020_COLLISIONS];
|
|
22593
|
+
[...PRE_2020_TO_2020_COLLISIONS];
|
|
22594
|
+
//#endregion
|
|
22229
22595
|
//#region ../../node_modules/.pnpm/effect@4.0.2/node_modules/effect/dist/internal/schema/toCodec.js
|
|
22596
|
+
/** @internal */
|
|
22597
|
+
const toCodecJsonAST = /*#__PURE__*/ applyToSelfOrLastLinkEncodingIdempotent((ast) => {
|
|
22598
|
+
const out = toCodecJsonASTStep(ast, toCodecJsonAST);
|
|
22599
|
+
const context = ast.context;
|
|
22600
|
+
if (out === ast || context === void 0) return out;
|
|
22601
|
+
return replaceContextLastLink(out, withoutConstructorDefault(context));
|
|
22602
|
+
});
|
|
22230
22603
|
function withoutConstructorDefault(context) {
|
|
22231
22604
|
return context.constructorDefault === void 0 ? context : new Context(context.isOptional, context.isMutable, void 0, context.annotations);
|
|
22232
22605
|
}
|
|
@@ -22240,6 +22613,44 @@ function makeReorder(getPriority) {
|
|
|
22240
22613
|
return sortedTypes;
|
|
22241
22614
|
};
|
|
22242
22615
|
}
|
|
22616
|
+
const toCodecJsonReorder = /*#__PURE__*/ makeReorder((ast) => {
|
|
22617
|
+
switch (ast._tag) {
|
|
22618
|
+
case "BigInt":
|
|
22619
|
+
case "Symbol":
|
|
22620
|
+
case "UniqueSymbol": return 0;
|
|
22621
|
+
default: return 1;
|
|
22622
|
+
}
|
|
22623
|
+
});
|
|
22624
|
+
function toCodecJsonASTStep(ast, recur) {
|
|
22625
|
+
switch (ast._tag) {
|
|
22626
|
+
case "Declaration": {
|
|
22627
|
+
const getLink = ast.annotations?.toCodecJson ?? ast.annotations?.toCodec;
|
|
22628
|
+
if (!isFunction(getLink)) return replaceEncoding(ast, [unknownToJson]);
|
|
22629
|
+
const link = getLink(ast.typeParameters.map((tp) => make$5(toEncoded(tp))));
|
|
22630
|
+
return link === void 0 ? ast : replaceEncoding(ast, [mapLink(link, recur)]);
|
|
22631
|
+
}
|
|
22632
|
+
case "Unknown": return replaceEncoding(ast, [unknownToJson]);
|
|
22633
|
+
case "ObjectKeyword": return replaceEncoding(ast, [objectKeywordToJson]);
|
|
22634
|
+
case "Undefined":
|
|
22635
|
+
case "Void":
|
|
22636
|
+
case "Literal":
|
|
22637
|
+
case "Number": return ast.toCodecJson();
|
|
22638
|
+
case "UniqueSymbol":
|
|
22639
|
+
case "Symbol":
|
|
22640
|
+
case "BigInt": return ast.toCodecStringTree();
|
|
22641
|
+
case "Objects":
|
|
22642
|
+
validateCanonicalObjectPropertyNames(ast);
|
|
22643
|
+
return ast.recur(recur, parameterFromString);
|
|
22644
|
+
case "Union": {
|
|
22645
|
+
const sortedTypes = toCodecJsonReorder(ast.types);
|
|
22646
|
+
if (sortedTypes !== ast.types) return new Union$1(sortedTypes, ast.options, ast.annotations, ast.checks, ast.encoding, ast.context, ast.encodingChecks).recur(recur);
|
|
22647
|
+
return ast.recur(recur);
|
|
22648
|
+
}
|
|
22649
|
+
case "Arrays":
|
|
22650
|
+
case "Suspend": return ast.recur(recur);
|
|
22651
|
+
}
|
|
22652
|
+
return ast;
|
|
22653
|
+
}
|
|
22243
22654
|
/** @internal */
|
|
22244
22655
|
function toCodecStringTree$1(schema) {
|
|
22245
22656
|
return make$5(toCodecStringTreeAST(schema.ast), { schema });
|
|
@@ -22305,6 +22716,849 @@ const toCodecStringTreeAST = /*#__PURE__*/ applyToSelfOrLastLinkEncodingIdempote
|
|
|
22305
22716
|
if (out !== ast && ast.context !== void 0) return replaceContextLastLink(out, withoutConstructorDefault(ast.context));
|
|
22306
22717
|
return out;
|
|
22307
22718
|
}, { stopAt: isCodecArrayFromSingleLink });
|
|
22719
|
+
globalThis.RegExp;
|
|
22720
|
+
/**
|
|
22721
|
+
* Escapes special characters in a regular expression pattern.
|
|
22722
|
+
*
|
|
22723
|
+
* **When to use**
|
|
22724
|
+
*
|
|
22725
|
+
* Use to turn literal text into a safe regular expression pattern fragment.
|
|
22726
|
+
*
|
|
22727
|
+
* **Example** (Escaping a pattern string)
|
|
22728
|
+
*
|
|
22729
|
+
* ```ts import.meta.vitest
|
|
22730
|
+
* import { RegExp } from "effect"
|
|
22731
|
+
*
|
|
22732
|
+
* RegExp.escape("a*b") // => "a\\*b"
|
|
22733
|
+
* ```
|
|
22734
|
+
*
|
|
22735
|
+
* @stability stable
|
|
22736
|
+
* @category transforming
|
|
22737
|
+
* @since 2.0.0
|
|
22738
|
+
*/
|
|
22739
|
+
const escape = (string) => string.replace(/[/\\^$*+?.()|[\]{}]/g, "\\$&");
|
|
22740
|
+
//#endregion
|
|
22741
|
+
//#region ../../node_modules/.pnpm/effect@4.0.2/node_modules/effect/dist/internal/errors.js
|
|
22742
|
+
/** @internal */
|
|
22743
|
+
function errorWithPath(message, path) {
|
|
22744
|
+
if (path.length > 0) message += `\n at ${formatPath(path)}`;
|
|
22745
|
+
return new Error(message);
|
|
22746
|
+
}
|
|
22747
|
+
//#endregion
|
|
22748
|
+
//#region ../../node_modules/.pnpm/effect@4.0.2/node_modules/effect/dist/internal/schema/toJsonSchemaDocument.js
|
|
22749
|
+
function formatDefinitionReference(key) {
|
|
22750
|
+
return `#/$defs/${formatUriFragmentToken(key)}`;
|
|
22751
|
+
}
|
|
22752
|
+
const jsonSchemaAnnotationExcludedKeys = /*#__PURE__*/ new Set([
|
|
22753
|
+
...annotationExcludedKeys,
|
|
22754
|
+
IDENTIFIER_FALLBACK_KEY,
|
|
22755
|
+
...jsonSchemaAnnotationKeys
|
|
22756
|
+
]);
|
|
22757
|
+
function collectJsonSchemaAnnotations(annotations, options) {
|
|
22758
|
+
if (annotations === void 0) return void 0;
|
|
22759
|
+
const out = {};
|
|
22760
|
+
const title = annotations.title;
|
|
22761
|
+
if (typeof title === "string") out.title = title;
|
|
22762
|
+
const description = annotations.description;
|
|
22763
|
+
const expected = annotations.expected;
|
|
22764
|
+
if (typeof description === "string") out.description = description;
|
|
22765
|
+
else if (options?.generateDescriptions === true && typeof expected === "string") out.description = expected;
|
|
22766
|
+
const defaultValue = annotations.default;
|
|
22767
|
+
if (isJson(defaultValue)) out.default = defaultValue;
|
|
22768
|
+
const examples = annotations.examples;
|
|
22769
|
+
if (Array.isArray(examples) && isJson(examples)) out.examples = examples;
|
|
22770
|
+
const readOnly = annotations.readOnly;
|
|
22771
|
+
if (typeof readOnly === "boolean") out.readOnly = readOnly;
|
|
22772
|
+
const writeOnly = annotations.writeOnly;
|
|
22773
|
+
if (typeof writeOnly === "boolean") out.writeOnly = writeOnly;
|
|
22774
|
+
const format = annotations.format;
|
|
22775
|
+
if (typeof format === "string") out.format = format;
|
|
22776
|
+
const contentEncoding = annotations.contentEncoding;
|
|
22777
|
+
if (typeof contentEncoding === "string") out.contentEncoding = contentEncoding;
|
|
22778
|
+
const contentMediaType = annotations.contentMediaType;
|
|
22779
|
+
if (typeof contentMediaType === "string") out.contentMediaType = contentMediaType;
|
|
22780
|
+
const contentSchema = annotations.contentSchema;
|
|
22781
|
+
if (isJson(contentSchema)) out.contentSchema = contentSchema;
|
|
22782
|
+
if (options?.includeAnnotationKey !== void 0) for (const [key, value] of Object.entries(annotations)) {
|
|
22783
|
+
if (jsonSchemaAnnotationExcludedKeys.has(key) || !options.includeAnnotationKey(key)) continue;
|
|
22784
|
+
if (isJson(value)) assignProperty(out, key, value);
|
|
22785
|
+
}
|
|
22786
|
+
return Object.keys(out).length === 0 ? void 0 : out;
|
|
22787
|
+
}
|
|
22788
|
+
function extractJsonSchemaNumberType(schema) {
|
|
22789
|
+
let type = schema.type === "number" || schema.type === "integer" ? schema.type : void 0;
|
|
22790
|
+
let out = schema;
|
|
22791
|
+
if (type !== void 0) {
|
|
22792
|
+
out = { ...schema };
|
|
22793
|
+
delete out.type;
|
|
22794
|
+
}
|
|
22795
|
+
if (Array.isArray(out.allOf)) {
|
|
22796
|
+
const members = [];
|
|
22797
|
+
let changed = false;
|
|
22798
|
+
for (const member of out.allOf) {
|
|
22799
|
+
const extracted = extractJsonSchemaNumberType(member);
|
|
22800
|
+
if (extracted.type !== void 0) {
|
|
22801
|
+
changed = true;
|
|
22802
|
+
if (type === void 0 || extracted.type === "integer") type = extracted.type;
|
|
22803
|
+
}
|
|
22804
|
+
if (Object.keys(extracted.schema).length > 0) members.push(extracted.schema);
|
|
22805
|
+
}
|
|
22806
|
+
if (changed) {
|
|
22807
|
+
const { allOf: _, ...rest } = out;
|
|
22808
|
+
out = members.length === 0 ? rest : {
|
|
22809
|
+
...rest,
|
|
22810
|
+
allOf: members
|
|
22811
|
+
};
|
|
22812
|
+
}
|
|
22813
|
+
}
|
|
22814
|
+
return {
|
|
22815
|
+
type,
|
|
22816
|
+
schema: out
|
|
22817
|
+
};
|
|
22818
|
+
}
|
|
22819
|
+
function isJsonSchemaNumberEncoding(schema) {
|
|
22820
|
+
if (!Array.isArray(schema.anyOf) || schema.anyOf.length !== 2 || schema.anyOf[0]?.type !== "number") return false;
|
|
22821
|
+
const special = schema.anyOf[1];
|
|
22822
|
+
return special?.type === "string" && Array.isArray(special.enum) && special.enum.length === 3 && special.enum.includes("NaN") && special.enum.includes("Infinity") && special.enum.includes("-Infinity");
|
|
22823
|
+
}
|
|
22824
|
+
const inlineableCheckKeywords = "|type|format|pattern|multipleOf|minimum|maximum|exclusiveMinimum|exclusiveMaximum|minLength|maxLength|minItems|maxItems|uniqueItems|minProperties|maxProperties|propertyNames|";
|
|
22825
|
+
function hasOnlyKeywords(schema, allowed) {
|
|
22826
|
+
return Object.keys(schema).every((key) => allowed.includes(`|${key}|`));
|
|
22827
|
+
}
|
|
22828
|
+
function hasNoCollisions(left, rightKeys) {
|
|
22829
|
+
return typeof left.$ref !== "string" && rightKeys.every((key) => !Object.hasOwn(left, key));
|
|
22830
|
+
}
|
|
22831
|
+
const promotableAnnotationKeywords = "|title|description|default|examples|readOnly|writeOnly|";
|
|
22832
|
+
const inlineableAnnotatedCheckKeywords = inlineableCheckKeywords + promotableAnnotationKeywords;
|
|
22833
|
+
function appendJsonSchema(left, right, inlineCheck) {
|
|
22834
|
+
if (Object.keys(left).length === 0) return right;
|
|
22835
|
+
const rightKeys = Object.keys(right);
|
|
22836
|
+
if (rightKeys.length === 0) return left;
|
|
22837
|
+
const leftType = left.type === "number" || left.type === "integer" ? left.type : void 0;
|
|
22838
|
+
const isNumberEncoding = isJsonSchemaNumberEncoding(left);
|
|
22839
|
+
if (leftType !== void 0 || isNumberEncoding) {
|
|
22840
|
+
const extracted = extractJsonSchemaNumberType(right);
|
|
22841
|
+
if (extracted.type !== void 0) {
|
|
22842
|
+
const type = leftType === "integer" || extracted.type === "integer" ? "integer" : "number";
|
|
22843
|
+
const base = {
|
|
22844
|
+
...left,
|
|
22845
|
+
type
|
|
22846
|
+
};
|
|
22847
|
+
if (isNumberEncoding) delete base.anyOf;
|
|
22848
|
+
const extractedKeys = Object.keys(extracted.schema);
|
|
22849
|
+
if (extractedKeys.length === 0) return base;
|
|
22850
|
+
return hasOnlyKeywords(extracted.schema, promotableAnnotationKeywords) && hasNoCollisions(base, extractedKeys) ? {
|
|
22851
|
+
...base,
|
|
22852
|
+
...extracted.schema
|
|
22853
|
+
} : appendJsonSchema(base, extracted.schema, inlineCheck);
|
|
22854
|
+
}
|
|
22855
|
+
}
|
|
22856
|
+
if (inlineCheck && hasNoCollisions(left, rightKeys)) return {
|
|
22857
|
+
...left,
|
|
22858
|
+
...right
|
|
22859
|
+
};
|
|
22860
|
+
const members = Array.isArray(right.allOf) && rightKeys.length === 1 ? right.allOf : [right];
|
|
22861
|
+
if (Array.isArray(left.allOf)) return {
|
|
22862
|
+
...left,
|
|
22863
|
+
allOf: [...left.allOf, ...members]
|
|
22864
|
+
};
|
|
22865
|
+
if (typeof left.$ref === "string") return { allOf: [left, ...members] };
|
|
22866
|
+
return {
|
|
22867
|
+
...left,
|
|
22868
|
+
allOf: members
|
|
22869
|
+
};
|
|
22870
|
+
}
|
|
22871
|
+
function isExact(exactness, seen = /* @__PURE__ */ new Set()) {
|
|
22872
|
+
if (typeof exactness === "boolean") return exactness;
|
|
22873
|
+
if (seen.has(exactness)) return true;
|
|
22874
|
+
seen.add(exactness);
|
|
22875
|
+
return exactness.every((dependency) => isExact(dependency, seen));
|
|
22876
|
+
}
|
|
22877
|
+
function isApproximateCheckOutput(output) {
|
|
22878
|
+
return Array.isArray(output);
|
|
22879
|
+
}
|
|
22880
|
+
function compileJsonSchema(representations, rootPaths, references, options) {
|
|
22881
|
+
const compiledDefinitions = /* @__PURE__ */ new Map();
|
|
22882
|
+
const definitionAliases = /* @__PURE__ */ new Map();
|
|
22883
|
+
const compiledRepresentations = /* @__PURE__ */ new WeakMap();
|
|
22884
|
+
const pendingOneOf = /* @__PURE__ */ new Map();
|
|
22885
|
+
const fallbackDefinitions = /* @__PURE__ */ new Map();
|
|
22886
|
+
const referenceKeys = Object.keys(references);
|
|
22887
|
+
for (const key of referenceKeys) compileDefinition(key, ["references", key]);
|
|
22888
|
+
const compiledSchemas = map$8(representations, (representation, index) => recur(representation, rootPaths[index], []));
|
|
22889
|
+
for (const [branches, schemas] of pendingOneOf.values()) if (!isExact(branches)) {
|
|
22890
|
+
for (const schema of schemas) if (Array.isArray(schema.oneOf)) {
|
|
22891
|
+
schema.anyOf = schema.oneOf;
|
|
22892
|
+
delete schema.oneOf;
|
|
22893
|
+
}
|
|
22894
|
+
}
|
|
22895
|
+
for (const key of referenceKeys) {
|
|
22896
|
+
const representation = references[key];
|
|
22897
|
+
const fallback = getIdentifierFallback(representation);
|
|
22898
|
+
if (fallback === void 0) continue;
|
|
22899
|
+
const schema = compiledDefinitions.get(key)[0];
|
|
22900
|
+
const candidates = fallbackDefinitions.get(fallback);
|
|
22901
|
+
const match = candidates?.find((candidate) => equals$1(compiledDefinitions.get(candidate)[0], schema));
|
|
22902
|
+
if (match === void 0) {
|
|
22903
|
+
if (candidates === void 0) fallbackDefinitions.set(fallback, [key]);
|
|
22904
|
+
else candidates.push(key);
|
|
22905
|
+
} else definitionAliases.set(key, match);
|
|
22906
|
+
}
|
|
22907
|
+
const schemas = map$8(compiledSchemas, finalizeJsonSchema);
|
|
22908
|
+
const definitions = {};
|
|
22909
|
+
for (const key of referenceKeys) if (!definitionAliases.has(key)) assignProperty(definitions, key, finalizeJsonSchema(compiledDefinitions.get(key)[0]));
|
|
22910
|
+
return {
|
|
22911
|
+
dialect: "draft-2020-12",
|
|
22912
|
+
schemas,
|
|
22913
|
+
definitions
|
|
22914
|
+
};
|
|
22915
|
+
function registerPendingOneOf(schema) {
|
|
22916
|
+
if (Array.isArray(schema.oneOf)) pendingOneOf.get(schema.oneOf)?.[1].push(schema);
|
|
22917
|
+
return schema;
|
|
22918
|
+
}
|
|
22919
|
+
function compileDefinition(key, path) {
|
|
22920
|
+
if (!Object.hasOwn(references, key)) throw errorWithPath(`Invalid reference ${key}`, [...path, "$ref"]);
|
|
22921
|
+
const cached = compiledDefinitions.get(key);
|
|
22922
|
+
if (cached !== void 0) return cached;
|
|
22923
|
+
const result = [{}, []];
|
|
22924
|
+
compiledDefinitions.set(key, result);
|
|
22925
|
+
result[0] = recur(references[key], ["references", key], result[1]);
|
|
22926
|
+
return result;
|
|
22927
|
+
}
|
|
22928
|
+
function finalizeJsonSchema(schema) {
|
|
22929
|
+
return rewriteRefs(schema, ($ref) => {
|
|
22930
|
+
const pointer = decodeUriFragment($ref);
|
|
22931
|
+
if (pointer === void 0) {
|
|
22932
|
+
if (/^#(?:\/|%2f)/i.test($ref)) throw new Error(`Invalid JSON Pointer URI fragment ${JSON.stringify($ref)}`);
|
|
22933
|
+
return $ref;
|
|
22934
|
+
}
|
|
22935
|
+
if (!pointer.startsWith("/$defs/")) return $ref;
|
|
22936
|
+
const separator = pointer.indexOf("/", 7);
|
|
22937
|
+
const canonical = definitionAliases.get(unescapeToken(pointer.slice(7, separator < 0 ? void 0 : separator)));
|
|
22938
|
+
if (canonical === void 0) return $ref;
|
|
22939
|
+
return $ref.replace(/^#(?:\/|%2f).*?(?:\/|%2f).*?(?=\/|%2f|$)/i, formatDefinitionReference(canonical));
|
|
22940
|
+
});
|
|
22941
|
+
}
|
|
22942
|
+
function getIdentifierFallback(representation) {
|
|
22943
|
+
if (representation._tag === "Reference") return void 0;
|
|
22944
|
+
const annotations = representation.checks.length === 0 ? representation.annotations : representation.checks[representation.checks.length - 1].annotations;
|
|
22945
|
+
return typeof annotations?.identifier !== "string" && typeof annotations?.["~identifier"] === "string" ? annotations[IDENTIFIER_FALLBACK_KEY] : void 0;
|
|
22946
|
+
}
|
|
22947
|
+
function compileCheck(check, type, path, dependencies) {
|
|
22948
|
+
const annotations = check.annotations;
|
|
22949
|
+
const callback = annotations?.toJsonSchema;
|
|
22950
|
+
if (callback !== void 0) {
|
|
22951
|
+
const result = callback({
|
|
22952
|
+
type,
|
|
22953
|
+
schemas: check.representation?.schemas?.map((schema, index) => recur(schema, [
|
|
22954
|
+
...path,
|
|
22955
|
+
"representation",
|
|
22956
|
+
"schemas",
|
|
22957
|
+
index
|
|
22958
|
+
], dependencies)) ?? []
|
|
22959
|
+
});
|
|
22960
|
+
const approximate = isApproximateCheckOutput(result);
|
|
22961
|
+
if (approximate) dependencies.push(false);
|
|
22962
|
+
const fragment = approximate ? result[0] : result;
|
|
22963
|
+
const ordinary = collectJsonSchemaAnnotations(annotations, options);
|
|
22964
|
+
const schema = ordinary === void 0 ? fragment : {
|
|
22965
|
+
...fragment,
|
|
22966
|
+
...ordinary
|
|
22967
|
+
};
|
|
22968
|
+
const allowed = ordinary === void 0 ? inlineableCheckKeywords : inlineableAnnotatedCheckKeywords;
|
|
22969
|
+
return [schema, check._tag === "Filter" && hasOnlyKeywords(schema, allowed) && (ordinary === void 0 || hasOnlyKeywords(ordinary, promotableAnnotationKeywords)) ? true : void 0];
|
|
22970
|
+
}
|
|
22971
|
+
if (check._tag === "Filter") {
|
|
22972
|
+
dependencies.push(false);
|
|
22973
|
+
return;
|
|
22974
|
+
}
|
|
22975
|
+
const schemas = check.checks.flatMap((child, index) => {
|
|
22976
|
+
const result = compileCheck(child, type, [
|
|
22977
|
+
...path,
|
|
22978
|
+
"checks",
|
|
22979
|
+
index
|
|
22980
|
+
], dependencies);
|
|
22981
|
+
return result === void 0 ? [] : [result[0]];
|
|
22982
|
+
});
|
|
22983
|
+
if (schemas.length === 0) return void 0;
|
|
22984
|
+
const ordinary = collectJsonSchemaAnnotations(annotations, options);
|
|
22985
|
+
const schema = { allOf: schemas };
|
|
22986
|
+
return [ordinary === void 0 ? schema : {
|
|
22987
|
+
...schema,
|
|
22988
|
+
...ordinary
|
|
22989
|
+
}];
|
|
22990
|
+
}
|
|
22991
|
+
function recur(representation, path, dependencies) {
|
|
22992
|
+
if (representation._tag === "Reference") {
|
|
22993
|
+
dependencies.push(compileDefinition(representation.$ref, path)[1]);
|
|
22994
|
+
return { $ref: formatDefinitionReference(representation.$ref) };
|
|
22995
|
+
}
|
|
22996
|
+
const cached = compiledRepresentations.get(representation);
|
|
22997
|
+
if (cached !== void 0) {
|
|
22998
|
+
dependencies.push(cached[1]);
|
|
22999
|
+
return cached[0];
|
|
23000
|
+
}
|
|
23001
|
+
const local = [];
|
|
23002
|
+
dependencies.push(local);
|
|
23003
|
+
let output = on(representation, path, local);
|
|
23004
|
+
const ordinary = collectJsonSchemaAnnotations(representation.annotations, options);
|
|
23005
|
+
if (ordinary !== void 0) output = {
|
|
23006
|
+
...output,
|
|
23007
|
+
...ordinary
|
|
23008
|
+
};
|
|
23009
|
+
for (let index = 0; index < representation.checks.length; index++) {
|
|
23010
|
+
const type = typeof output.type === "string" && isJsonSchemaType(output.type) ? output.type : void 0;
|
|
23011
|
+
const check = compileCheck(representation.checks[index], type, [
|
|
23012
|
+
...path,
|
|
23013
|
+
"checks",
|
|
23014
|
+
index
|
|
23015
|
+
], local);
|
|
23016
|
+
if (check !== void 0) output = appendJsonSchema(output, ...check);
|
|
23017
|
+
}
|
|
23018
|
+
compiledRepresentations.set(representation, [output, local]);
|
|
23019
|
+
return registerPendingOneOf(output);
|
|
23020
|
+
}
|
|
23021
|
+
function on(representation, path, dependencies) {
|
|
23022
|
+
switch (representation._tag) {
|
|
23023
|
+
case "Any":
|
|
23024
|
+
case "Unknown": return {};
|
|
23025
|
+
case "ObjectKeyword": return { anyOf: [{ type: "object" }, { type: "array" }] };
|
|
23026
|
+
case "Void":
|
|
23027
|
+
case "Undefined":
|
|
23028
|
+
case "Null": return { type: "null" };
|
|
23029
|
+
case "BigInt": return {
|
|
23030
|
+
type: "string",
|
|
23031
|
+
allOf: [{ pattern: "^-?\\d+$" }]
|
|
23032
|
+
};
|
|
23033
|
+
case "Symbol": return {
|
|
23034
|
+
type: "string",
|
|
23035
|
+
allOf: [{ pattern: "^Symbol\\(([\\s\\S]*)\\)$" }]
|
|
23036
|
+
};
|
|
23037
|
+
case "UniqueSymbol": return globalThis.Symbol.keyFor(representation.symbol) === void 0 ? { not: {} } : {
|
|
23038
|
+
type: "string",
|
|
23039
|
+
enum: [globalThis.String(representation.symbol)]
|
|
23040
|
+
};
|
|
23041
|
+
case "Declaration":
|
|
23042
|
+
dependencies.push(false);
|
|
23043
|
+
return {};
|
|
23044
|
+
case "Suspend": return recur(representation.thunk, [...path, "thunk"], dependencies);
|
|
23045
|
+
case "Never": return { not: {} };
|
|
23046
|
+
case "String": return { type: "string" };
|
|
23047
|
+
case "Number": return { anyOf: [{ type: "number" }, {
|
|
23048
|
+
type: "string",
|
|
23049
|
+
enum: [
|
|
23050
|
+
"NaN",
|
|
23051
|
+
"Infinity",
|
|
23052
|
+
"-Infinity"
|
|
23053
|
+
]
|
|
23054
|
+
}] };
|
|
23055
|
+
case "Boolean": return { type: "boolean" };
|
|
23056
|
+
case "Literal": {
|
|
23057
|
+
const literal = representation.literal;
|
|
23058
|
+
return typeof literal === "bigint" ? {
|
|
23059
|
+
type: "string",
|
|
23060
|
+
enum: [globalThis.String(literal)]
|
|
23061
|
+
} : {
|
|
23062
|
+
type: typeof literal,
|
|
23063
|
+
enum: [literal]
|
|
23064
|
+
};
|
|
23065
|
+
}
|
|
23066
|
+
case "Enum": {
|
|
23067
|
+
const types = representation.enums.map(([title, literal], index) => {
|
|
23068
|
+
if (typeof literal === "number" && !globalThis.Number.isFinite(literal)) throw errorWithPath(`Invalid numeric enum value ${globalThis.String(literal)}`, [
|
|
23069
|
+
...path,
|
|
23070
|
+
"enums",
|
|
23071
|
+
index,
|
|
23072
|
+
1
|
|
23073
|
+
]);
|
|
23074
|
+
return {
|
|
23075
|
+
type: typeof literal,
|
|
23076
|
+
enum: [literal],
|
|
23077
|
+
title
|
|
23078
|
+
};
|
|
23079
|
+
});
|
|
23080
|
+
return types.length === 0 ? { not: {} } : { anyOf: types };
|
|
23081
|
+
}
|
|
23082
|
+
case "TemplateLiteral": return {
|
|
23083
|
+
type: "string",
|
|
23084
|
+
pattern: `^${representation.parts.map(getPartPattern).join("")}$`
|
|
23085
|
+
};
|
|
23086
|
+
case "Arrays": {
|
|
23087
|
+
if (representation.rest.length > 1) throw errorWithPath("Invalid schema representation document", [...path, "rest"]);
|
|
23088
|
+
const out = { type: "array" };
|
|
23089
|
+
let minItems = representation.elements.length;
|
|
23090
|
+
const prefixItems = representation.elements.map((element, index) => {
|
|
23091
|
+
if (element.isOptional) minItems--;
|
|
23092
|
+
const schema = recur(element.type, [
|
|
23093
|
+
...path,
|
|
23094
|
+
"elements",
|
|
23095
|
+
index,
|
|
23096
|
+
"type"
|
|
23097
|
+
], dependencies);
|
|
23098
|
+
const annotations = collectJsonSchemaAnnotations(element.annotations, options);
|
|
23099
|
+
return annotations === void 0 ? schema : registerPendingOneOf(appendJsonSchema(schema, annotations));
|
|
23100
|
+
});
|
|
23101
|
+
if (prefixItems.length > 0) {
|
|
23102
|
+
out.prefixItems = prefixItems;
|
|
23103
|
+
out.maxItems = representation.elements.length;
|
|
23104
|
+
if (minItems > 0) out.minItems = minItems;
|
|
23105
|
+
} else out.items = false;
|
|
23106
|
+
if (representation.rest.length === 1) {
|
|
23107
|
+
delete out.maxItems;
|
|
23108
|
+
const rest = recur(representation.rest[0], [
|
|
23109
|
+
...path,
|
|
23110
|
+
"rest",
|
|
23111
|
+
0
|
|
23112
|
+
], dependencies);
|
|
23113
|
+
if (Object.keys(rest).length > 0) out.items = rest;
|
|
23114
|
+
else delete out.items;
|
|
23115
|
+
}
|
|
23116
|
+
return out;
|
|
23117
|
+
}
|
|
23118
|
+
case "Objects": {
|
|
23119
|
+
if (representation.propertySignatures.length === 0 && representation.indexSignatures.length === 0) return { not: { type: "null" } };
|
|
23120
|
+
const out = { type: "object" };
|
|
23121
|
+
const properties = {};
|
|
23122
|
+
const required = [];
|
|
23123
|
+
for (let index = 0; index < representation.propertySignatures.length; index++) {
|
|
23124
|
+
const property = representation.propertySignatures[index];
|
|
23125
|
+
if (typeof property.name !== "string") throw errorWithPath("Invalid schema representation document", [
|
|
23126
|
+
...path,
|
|
23127
|
+
"propertySignatures",
|
|
23128
|
+
index,
|
|
23129
|
+
"name"
|
|
23130
|
+
]);
|
|
23131
|
+
const name = property.name;
|
|
23132
|
+
const schema = recur(property.type, [
|
|
23133
|
+
...path,
|
|
23134
|
+
"propertySignatures",
|
|
23135
|
+
index,
|
|
23136
|
+
"type"
|
|
23137
|
+
], dependencies);
|
|
23138
|
+
const annotations = collectJsonSchemaAnnotations(property.annotations, options);
|
|
23139
|
+
assignProperty(properties, name, annotations === void 0 ? schema : registerPendingOneOf(appendJsonSchema(schema, annotations)));
|
|
23140
|
+
if (!property.isOptional) required.push(name);
|
|
23141
|
+
}
|
|
23142
|
+
if (representation.propertySignatures.length > 0) out.properties = properties;
|
|
23143
|
+
if (required.length > 0) out.required = required;
|
|
23144
|
+
const patternProperties = {};
|
|
23145
|
+
const additionalPropertySchemas = [];
|
|
23146
|
+
const indexValueSchemas = [];
|
|
23147
|
+
let hasUnrepresentableIndexPattern = false;
|
|
23148
|
+
for (let index = 0; index < representation.indexSignatures.length; index++) {
|
|
23149
|
+
const signature = representation.indexSignatures[index];
|
|
23150
|
+
let type = recur(signature.type, [
|
|
23151
|
+
...path,
|
|
23152
|
+
"indexSignatures",
|
|
23153
|
+
index,
|
|
23154
|
+
"type"
|
|
23155
|
+
], dependencies);
|
|
23156
|
+
if (equals$1(type, { not: {} })) type = false;
|
|
23157
|
+
indexValueSchemas.push(type);
|
|
23158
|
+
const patterns = getParameterPatterns(signature.parameter, [
|
|
23159
|
+
...path,
|
|
23160
|
+
"indexSignatures",
|
|
23161
|
+
index,
|
|
23162
|
+
"parameter"
|
|
23163
|
+
], /* @__PURE__ */ new Set());
|
|
23164
|
+
if (patterns === void 0) {
|
|
23165
|
+
hasUnrepresentableIndexPattern = true;
|
|
23166
|
+
dependencies.push(false);
|
|
23167
|
+
continue;
|
|
23168
|
+
}
|
|
23169
|
+
if (patterns.length === 0) additionalPropertySchemas.push(type);
|
|
23170
|
+
else for (const pattern of patterns) {
|
|
23171
|
+
const previous = patternProperties[pattern];
|
|
23172
|
+
assignProperty(patternProperties, pattern, previous === void 0 ? type : previous === false || type === false ? false : registerPendingOneOf(appendJsonSchema(previous, type)));
|
|
23173
|
+
}
|
|
23174
|
+
}
|
|
23175
|
+
const hasPatternProperties = Object.keys(patternProperties).length > 0;
|
|
23176
|
+
if (hasPatternProperties) out.patternProperties = patternProperties;
|
|
23177
|
+
if (hasUnrepresentableIndexPattern && options?.onExcessProperty === "error") {
|
|
23178
|
+
const propertyNames = [];
|
|
23179
|
+
if (representation.propertySignatures.length > 0) propertyNames.push({ enum: Object.keys(properties) });
|
|
23180
|
+
for (let index = 0; index < representation.indexSignatures.length; index++) propertyNames.push(recur(representation.indexSignatures[index].parameter, [
|
|
23181
|
+
...path,
|
|
23182
|
+
"indexSignatures",
|
|
23183
|
+
index,
|
|
23184
|
+
"parameter"
|
|
23185
|
+
], dependencies));
|
|
23186
|
+
out.propertyNames = propertyNames.length === 1 ? propertyNames[0] : { anyOf: propertyNames };
|
|
23187
|
+
out.additionalProperties = indexValueSchemas.length === 1 ? indexValueSchemas[0] : { anyOf: indexValueSchemas };
|
|
23188
|
+
if (additionalPropertySchemas.length > 0) out.allOf = additionalPropertySchemas.map((type) => ({
|
|
23189
|
+
type: "object",
|
|
23190
|
+
additionalProperties: type
|
|
23191
|
+
}));
|
|
23192
|
+
} else if (additionalPropertySchemas.length === 0) out.additionalProperties = hasUnrepresentableIndexPattern || options?.onExcessProperty !== "error";
|
|
23193
|
+
else if (additionalPropertySchemas.length === 1 && representation.propertySignatures.length === 0 && !hasPatternProperties) out.additionalProperties = additionalPropertySchemas[0];
|
|
23194
|
+
else if (additionalPropertySchemas.length > 0) out.allOf = additionalPropertySchemas.map((type) => ({
|
|
23195
|
+
type: "object",
|
|
23196
|
+
additionalProperties: type
|
|
23197
|
+
}));
|
|
23198
|
+
if (typeof out.additionalProperties === "object" && out.additionalProperties !== null && Object.keys(out.additionalProperties).length === 0) delete out.additionalProperties;
|
|
23199
|
+
return out;
|
|
23200
|
+
}
|
|
23201
|
+
case "Union": {
|
|
23202
|
+
const branches = [];
|
|
23203
|
+
const types = representation.types.map((type, index) => recur(type, [
|
|
23204
|
+
...path,
|
|
23205
|
+
"types",
|
|
23206
|
+
index
|
|
23207
|
+
], branches));
|
|
23208
|
+
dependencies.push(branches);
|
|
23209
|
+
if (types.length === 0) return { not: {} };
|
|
23210
|
+
const mode = representation.options?.mode ?? "anyOf";
|
|
23211
|
+
if (mode === "anyOf" && types.length > 1) {
|
|
23212
|
+
const compacted = compactEnums(types);
|
|
23213
|
+
if (compacted !== void 0) return compacted;
|
|
23214
|
+
}
|
|
23215
|
+
if (mode === "oneOf") pendingOneOf.set(types, [branches, []]);
|
|
23216
|
+
return { [mode]: types };
|
|
23217
|
+
}
|
|
23218
|
+
}
|
|
23219
|
+
}
|
|
23220
|
+
function getParameterPatterns(parameter, path, seenReferences) {
|
|
23221
|
+
switch (parameter._tag) {
|
|
23222
|
+
case "Reference": {
|
|
23223
|
+
if (!Object.hasOwn(references, parameter.$ref)) throw errorWithPath(`Invalid reference ${parameter.$ref}`, [...path, "$ref"]);
|
|
23224
|
+
compileDefinition(parameter.$ref, path);
|
|
23225
|
+
if (seenReferences.has(parameter.$ref)) return void 0;
|
|
23226
|
+
const next = new Set(seenReferences).add(parameter.$ref);
|
|
23227
|
+
return getParameterPatterns(references[parameter.$ref], ["references", parameter.$ref], next);
|
|
23228
|
+
}
|
|
23229
|
+
case "String": {
|
|
23230
|
+
if (parameter.checks.length === 0) return [];
|
|
23231
|
+
if (parameter.checks.length !== 1 || parameter.checks[0]._tag !== "Filter" || parameter.checks[0].annotations?.toJsonSchema === void 0) return;
|
|
23232
|
+
const dependencies = [];
|
|
23233
|
+
const schema = recur(parameter, path, dependencies);
|
|
23234
|
+
if (!isExact(dependencies)) return void 0;
|
|
23235
|
+
return schema.type === "string" && typeof schema.pattern === "string" && hasOnlyKeywords(schema, "|type|pattern|title|description|default|examples|readOnly|writeOnly|") ? [schema.pattern] : void 0;
|
|
23236
|
+
}
|
|
23237
|
+
case "TemplateLiteral": return parameter.checks.length === 0 ? [`^${parameter.parts.map(getPartPattern).join("")}$`] : void 0;
|
|
23238
|
+
case "Union": {
|
|
23239
|
+
if (parameter.types.length === 0 || parameter.checks.length > 0 || parameter.options?.mode === "oneOf") return;
|
|
23240
|
+
const patterns = [];
|
|
23241
|
+
for (let index = 0; index < parameter.types.length; index++) {
|
|
23242
|
+
const memberPatterns = getParameterPatterns(parameter.types[index], [
|
|
23243
|
+
...path,
|
|
23244
|
+
"types",
|
|
23245
|
+
index
|
|
23246
|
+
], seenReferences);
|
|
23247
|
+
if (memberPatterns === void 0) return void 0;
|
|
23248
|
+
if (memberPatterns.length === 0) return [];
|
|
23249
|
+
patterns.push(...memberPatterns);
|
|
23250
|
+
}
|
|
23251
|
+
return patterns;
|
|
23252
|
+
}
|
|
23253
|
+
default: throw errorWithPath("Invalid schema representation document", path);
|
|
23254
|
+
}
|
|
23255
|
+
}
|
|
23256
|
+
}
|
|
23257
|
+
function isJsonSchemaType(input) {
|
|
23258
|
+
return input === "string" || input === "number" || input === "boolean" || input === "array" || input === "object" || input === "null" || input === "integer";
|
|
23259
|
+
}
|
|
23260
|
+
function compactEnums(schemas) {
|
|
23261
|
+
let sharedType = void 0;
|
|
23262
|
+
const values = [];
|
|
23263
|
+
for (const schema of schemas) {
|
|
23264
|
+
if (Object.keys(schema).length !== 2 || schema.type === void 0 || !Array.isArray(schema.enum) || schema.enum.length === 0) return;
|
|
23265
|
+
if (sharedType === void 0) sharedType = schema.type;
|
|
23266
|
+
else if (schema.type !== sharedType) return void 0;
|
|
23267
|
+
for (const value of schema.enum) {
|
|
23268
|
+
if (values.includes(value)) return void 0;
|
|
23269
|
+
values.push(value);
|
|
23270
|
+
}
|
|
23271
|
+
}
|
|
23272
|
+
return {
|
|
23273
|
+
type: sharedType,
|
|
23274
|
+
enum: values
|
|
23275
|
+
};
|
|
23276
|
+
}
|
|
23277
|
+
function getPartPattern(part) {
|
|
23278
|
+
switch (part._tag) {
|
|
23279
|
+
case "Literal": return escape(globalThis.String(part.literal));
|
|
23280
|
+
case "String": return STRING_PATTERN;
|
|
23281
|
+
case "Number": return FINITE_PATTERN;
|
|
23282
|
+
case "TemplateLiteral": return part.parts.map(getPartPattern).join("");
|
|
23283
|
+
case "Union": return `(?:${part.types.map(getPartPattern).join("|")})`;
|
|
23284
|
+
default: throw errorWithPath("Invalid schema representation document", []);
|
|
23285
|
+
}
|
|
23286
|
+
}
|
|
23287
|
+
/** @internal */
|
|
23288
|
+
function toJsonSchemaDocument$1(document, options) {
|
|
23289
|
+
const output = compileJsonSchema([document.representation], [["representation"]], document.references, options);
|
|
23290
|
+
return {
|
|
23291
|
+
dialect: output.dialect,
|
|
23292
|
+
schema: output.schemas[0],
|
|
23293
|
+
definitions: output.definitions
|
|
23294
|
+
};
|
|
23295
|
+
}
|
|
23296
|
+
//#endregion
|
|
23297
|
+
//#region ../../node_modules/.pnpm/effect@4.0.2/node_modules/effect/dist/internal/schema/toRepresentation.js
|
|
23298
|
+
const defaultReferencePolicy = ({ identifier }) => identifier;
|
|
23299
|
+
function annotationsField(annotations) {
|
|
23300
|
+
return annotations === void 0 ? void 0 : { annotations };
|
|
23301
|
+
}
|
|
23302
|
+
/** @internal */
|
|
23303
|
+
function toRepresentation(ast, options) {
|
|
23304
|
+
const { references, representations } = toRepresentations([ast], options);
|
|
23305
|
+
return {
|
|
23306
|
+
representation: representations[0],
|
|
23307
|
+
references
|
|
23308
|
+
};
|
|
23309
|
+
}
|
|
23310
|
+
/** @internal */
|
|
23311
|
+
function toRepresentations(asts, options) {
|
|
23312
|
+
const references = {};
|
|
23313
|
+
const referenceOwners = /* @__PURE__ */ new Map();
|
|
23314
|
+
const buildingReferences = /* @__PURE__ */ new Set();
|
|
23315
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
23316
|
+
const visitingCandidates = /* @__PURE__ */ new Set();
|
|
23317
|
+
for (const ast of asts) visit(ast);
|
|
23318
|
+
const referencePolicy = options?.referencePolicy ?? defaultReferencePolicy;
|
|
23319
|
+
for (const candidatesByIdentifier of candidates.values()) for (const candidate of candidatesByIdentifier.values()) {
|
|
23320
|
+
const requestedReference = referencePolicy({
|
|
23321
|
+
ast: candidate.ast,
|
|
23322
|
+
occurrences: candidate.occurrences,
|
|
23323
|
+
identifier: candidate.identifier
|
|
23324
|
+
});
|
|
23325
|
+
if (requestedReference !== void 0) candidate.reference = getReference(requestedReference, candidate, requestedReference === candidate.identifier || !requestedReference.endsWith("_") ? "_" : "");
|
|
23326
|
+
else if (candidate.isRecursive) candidate.reference = getReference(`${candidate.ast._tag}_`, candidate, "");
|
|
23327
|
+
}
|
|
23328
|
+
return {
|
|
23329
|
+
representations: map$8(asts, (ast) => recur(ast)),
|
|
23330
|
+
references
|
|
23331
|
+
};
|
|
23332
|
+
function getReference(prefix, owner, separator = "_") {
|
|
23333
|
+
let candidate = prefix;
|
|
23334
|
+
let suffix = 0;
|
|
23335
|
+
while (referenceOwners.has(candidate)) {
|
|
23336
|
+
if (referenceOwners.get(candidate) === owner) return candidate;
|
|
23337
|
+
candidate = `${prefix}${separator}${++suffix}`;
|
|
23338
|
+
}
|
|
23339
|
+
referenceOwners.set(candidate, owner);
|
|
23340
|
+
return candidate;
|
|
23341
|
+
}
|
|
23342
|
+
function annotateReference(ast, candidate, reference) {
|
|
23343
|
+
const fallback = candidate.fallback;
|
|
23344
|
+
if (fallback !== void 0) return resolveIdentifierFallback(ast) === fallback ? ast : annotate$1(ast, { [IDENTIFIER_FALLBACK_KEY]: fallback });
|
|
23345
|
+
return reference === candidate.identifier ? ast : annotate$1(ast, { identifier: reference });
|
|
23346
|
+
}
|
|
23347
|
+
function makeReference(reference, ast) {
|
|
23348
|
+
if (!Object.hasOwn(references, reference) && !buildingReferences.has(reference)) {
|
|
23349
|
+
buildingReferences.add(reference);
|
|
23350
|
+
const representation = on(ast);
|
|
23351
|
+
buildingReferences.delete(reference);
|
|
23352
|
+
assignProperty(references, reference, representation);
|
|
23353
|
+
}
|
|
23354
|
+
return {
|
|
23355
|
+
_tag: "Reference",
|
|
23356
|
+
$ref: reference
|
|
23357
|
+
};
|
|
23358
|
+
}
|
|
23359
|
+
function getCandidate(input) {
|
|
23360
|
+
const ast = getLastEncoding(input);
|
|
23361
|
+
const owner = getContextOwner(ast);
|
|
23362
|
+
let identifier = resolveIdentifier(ast);
|
|
23363
|
+
const fallback = identifier === void 0 ? (ast !== input ? resolveIdentifier(input) : void 0) ?? resolveIdentifierFallback(ast) : void 0;
|
|
23364
|
+
if (fallback !== void 0) identifier = `${fallback}Encoded`;
|
|
23365
|
+
let candidatesByIdentifier = candidates.get(owner);
|
|
23366
|
+
if (candidatesByIdentifier === void 0) {
|
|
23367
|
+
candidatesByIdentifier = /* @__PURE__ */ new Map();
|
|
23368
|
+
candidates.set(owner, candidatesByIdentifier);
|
|
23369
|
+
}
|
|
23370
|
+
let candidate = candidatesByIdentifier.get(identifier);
|
|
23371
|
+
if (candidate === void 0) {
|
|
23372
|
+
candidate = {
|
|
23373
|
+
ast: owner,
|
|
23374
|
+
identifier,
|
|
23375
|
+
fallback,
|
|
23376
|
+
occurrences: 0,
|
|
23377
|
+
isRecursive: false,
|
|
23378
|
+
reference: void 0
|
|
23379
|
+
};
|
|
23380
|
+
candidatesByIdentifier.set(identifier, candidate);
|
|
23381
|
+
}
|
|
23382
|
+
return candidate;
|
|
23383
|
+
}
|
|
23384
|
+
function visit(input) {
|
|
23385
|
+
const candidate = getCandidate(input);
|
|
23386
|
+
const ast = candidate.ast;
|
|
23387
|
+
candidate.occurrences++;
|
|
23388
|
+
if (visitingCandidates.has(candidate)) {
|
|
23389
|
+
candidate.isRecursive = true;
|
|
23390
|
+
return;
|
|
23391
|
+
}
|
|
23392
|
+
if (candidate.occurrences > 1) return;
|
|
23393
|
+
visitingCandidates.add(candidate);
|
|
23394
|
+
visitChecks(ast.checks);
|
|
23395
|
+
switch (ast._tag) {
|
|
23396
|
+
case "Declaration":
|
|
23397
|
+
case "Arrays":
|
|
23398
|
+
case "Objects":
|
|
23399
|
+
case "Union":
|
|
23400
|
+
ast.recur((child) => {
|
|
23401
|
+
visit(child);
|
|
23402
|
+
return child;
|
|
23403
|
+
});
|
|
23404
|
+
break;
|
|
23405
|
+
case "TemplateLiteral":
|
|
23406
|
+
ast.parts.forEach(visit);
|
|
23407
|
+
break;
|
|
23408
|
+
case "Suspend": visit(ast.thunk());
|
|
23409
|
+
}
|
|
23410
|
+
visitingCandidates.delete(candidate);
|
|
23411
|
+
}
|
|
23412
|
+
function visitChecks(checks) {
|
|
23413
|
+
checks?.forEach((check) => {
|
|
23414
|
+
check.annotations?.representation?.schemas?.forEach((schema) => visit(toType(schema)));
|
|
23415
|
+
if (check._tag === "FilterGroup") visitChecks(check.checks);
|
|
23416
|
+
});
|
|
23417
|
+
}
|
|
23418
|
+
function recur(input) {
|
|
23419
|
+
const candidate = getCandidate(input);
|
|
23420
|
+
const ast = candidate.ast;
|
|
23421
|
+
const reference = candidate.reference;
|
|
23422
|
+
if (reference !== void 0) return makeReference(reference, candidate.identifier === void 0 ? ast : annotateReference(ast, candidate, reference));
|
|
23423
|
+
return on(ast);
|
|
23424
|
+
}
|
|
23425
|
+
function on(ast) {
|
|
23426
|
+
const checks = fromChecks(ast.checks);
|
|
23427
|
+
switch (ast._tag) {
|
|
23428
|
+
case "Declaration": return {
|
|
23429
|
+
_tag: "Declaration",
|
|
23430
|
+
typeParameters: ast.typeParameters.map((ast) => recur(ast)),
|
|
23431
|
+
checks,
|
|
23432
|
+
...fromDeclarationAnnotations(ast.annotations)
|
|
23433
|
+
};
|
|
23434
|
+
case "Null":
|
|
23435
|
+
case "Undefined":
|
|
23436
|
+
case "Void":
|
|
23437
|
+
case "Never":
|
|
23438
|
+
case "Unknown":
|
|
23439
|
+
case "Any":
|
|
23440
|
+
case "String":
|
|
23441
|
+
case "Boolean":
|
|
23442
|
+
case "Number":
|
|
23443
|
+
case "BigInt":
|
|
23444
|
+
case "Symbol":
|
|
23445
|
+
case "ObjectKeyword": return {
|
|
23446
|
+
_tag: ast._tag,
|
|
23447
|
+
checks,
|
|
23448
|
+
...annotationsField(ast.annotations)
|
|
23449
|
+
};
|
|
23450
|
+
case "Literal": return {
|
|
23451
|
+
_tag: "Literal",
|
|
23452
|
+
literal: ast.literal,
|
|
23453
|
+
checks,
|
|
23454
|
+
...annotationsField(ast.annotations)
|
|
23455
|
+
};
|
|
23456
|
+
case "UniqueSymbol": return {
|
|
23457
|
+
_tag: "UniqueSymbol",
|
|
23458
|
+
symbol: ast.symbol,
|
|
23459
|
+
checks,
|
|
23460
|
+
...annotationsField(ast.annotations)
|
|
23461
|
+
};
|
|
23462
|
+
case "Enum": return {
|
|
23463
|
+
_tag: "Enum",
|
|
23464
|
+
enums: ast.enums,
|
|
23465
|
+
checks,
|
|
23466
|
+
...annotationsField(ast.annotations)
|
|
23467
|
+
};
|
|
23468
|
+
case "TemplateLiteral": return {
|
|
23469
|
+
_tag: "TemplateLiteral",
|
|
23470
|
+
parts: ast.parts.map((ast) => recur(ast)),
|
|
23471
|
+
checks,
|
|
23472
|
+
...annotationsField(ast.annotations)
|
|
23473
|
+
};
|
|
23474
|
+
case "Arrays": return {
|
|
23475
|
+
_tag: "Arrays",
|
|
23476
|
+
elements: ast.elements.map((element) => {
|
|
23477
|
+
const projected = getLastEncoding(element);
|
|
23478
|
+
const annotations = projected.context?.annotations;
|
|
23479
|
+
return {
|
|
23480
|
+
isOptional: isOptional(projected),
|
|
23481
|
+
type: recur(element),
|
|
23482
|
+
...annotationsField(annotations)
|
|
23483
|
+
};
|
|
23484
|
+
}),
|
|
23485
|
+
rest: ast.rest.map((ast) => recur(ast)),
|
|
23486
|
+
checks,
|
|
23487
|
+
...annotationsField(ast.annotations)
|
|
23488
|
+
};
|
|
23489
|
+
case "Objects": return {
|
|
23490
|
+
_tag: "Objects",
|
|
23491
|
+
propertySignatures: ast.propertySignatures.map((property) => {
|
|
23492
|
+
const projected = getLastEncoding(property.type);
|
|
23493
|
+
const annotations = projected.context?.annotations;
|
|
23494
|
+
return {
|
|
23495
|
+
name: property.name,
|
|
23496
|
+
type: recur(property.type),
|
|
23497
|
+
isOptional: isOptional(projected),
|
|
23498
|
+
isMutable: isMutable(projected),
|
|
23499
|
+
...annotationsField(annotations)
|
|
23500
|
+
};
|
|
23501
|
+
}),
|
|
23502
|
+
indexSignatures: ast.indexSignatures.map((index) => ({
|
|
23503
|
+
parameter: recur(index.parameter),
|
|
23504
|
+
type: recur(index.type)
|
|
23505
|
+
})),
|
|
23506
|
+
checks,
|
|
23507
|
+
...annotationsField(ast.annotations)
|
|
23508
|
+
};
|
|
23509
|
+
case "Union": return {
|
|
23510
|
+
_tag: "Union",
|
|
23511
|
+
types: ast.types.map((ast) => recur(ast)),
|
|
23512
|
+
...ast.options === void 0 ? {} : { options: ast.options },
|
|
23513
|
+
checks,
|
|
23514
|
+
...annotationsField(ast.annotations)
|
|
23515
|
+
};
|
|
23516
|
+
case "Suspend": return {
|
|
23517
|
+
_tag: "Suspend",
|
|
23518
|
+
checks: [],
|
|
23519
|
+
thunk: recur(ast.thunk()),
|
|
23520
|
+
...annotationsField(ast.annotations)
|
|
23521
|
+
};
|
|
23522
|
+
}
|
|
23523
|
+
}
|
|
23524
|
+
function fromChecks(checks) {
|
|
23525
|
+
return checks?.map(fromCheck) ?? [];
|
|
23526
|
+
}
|
|
23527
|
+
function fromCheck(check) {
|
|
23528
|
+
switch (check._tag) {
|
|
23529
|
+
case "Filter": return {
|
|
23530
|
+
_tag: "Filter",
|
|
23531
|
+
aborted: check.aborted,
|
|
23532
|
+
...fromCheckAnnotations(check.annotations)
|
|
23533
|
+
};
|
|
23534
|
+
case "FilterGroup": return {
|
|
23535
|
+
_tag: "FilterGroup",
|
|
23536
|
+
checks: map$8(check.checks, fromCheck),
|
|
23537
|
+
...fromCheckAnnotations(check.annotations)
|
|
23538
|
+
};
|
|
23539
|
+
}
|
|
23540
|
+
}
|
|
23541
|
+
function fromDeclarationAnnotations(annotations) {
|
|
23542
|
+
if (annotations === void 0) return void 0;
|
|
23543
|
+
const { representation, ...ordinary } = annotations;
|
|
23544
|
+
return {
|
|
23545
|
+
...representation === void 0 ? void 0 : { representation },
|
|
23546
|
+
...Object.keys(ordinary).length === 0 ? void 0 : { annotations: ordinary }
|
|
23547
|
+
};
|
|
23548
|
+
}
|
|
23549
|
+
function fromCheckAnnotations(annotations) {
|
|
23550
|
+
if (annotations === void 0) return void 0;
|
|
23551
|
+
const { representation, ...ordinary } = annotations;
|
|
23552
|
+
const projected = representation === void 0 ? void 0 : representation.schemas === void 0 ? representation : {
|
|
23553
|
+
...representation,
|
|
23554
|
+
schemas: representation.schemas.map((schema) => recur(toType(schema)))
|
|
23555
|
+
};
|
|
23556
|
+
return {
|
|
23557
|
+
...projected === void 0 ? void 0 : { representation: projected },
|
|
23558
|
+
...Object.keys(ordinary).length === 0 ? void 0 : { annotations: ordinary }
|
|
23559
|
+
};
|
|
23560
|
+
}
|
|
23561
|
+
}
|
|
22308
23562
|
//#endregion
|
|
22309
23563
|
//#region ../../node_modules/.pnpm/effect@4.0.2/node_modules/effect/dist/Struct.js
|
|
22310
23564
|
/**
|
|
@@ -23599,6 +24853,81 @@ const TaggedError = (identifier) => {
|
|
|
23599
24853
|
};
|
|
23600
24854
|
};
|
|
23601
24855
|
/**
|
|
24856
|
+
* Returns a JSON Schema document using draft 2020-12.
|
|
24857
|
+
*
|
|
24858
|
+
* **When to use**
|
|
24859
|
+
*
|
|
24860
|
+
* Use when you need a draft-2020-12 description of the canonical JSON form of a runtime schema.
|
|
24861
|
+
*
|
|
24862
|
+
* **Details**
|
|
24863
|
+
*
|
|
24864
|
+
* The document describes the encoded side of `Schema.toCodecJson(schema)`.
|
|
24865
|
+
* Use that codec to decode JSON inputs. For example, it decodes JSON `null`
|
|
24866
|
+
* to JavaScript `undefined` for a field defined with `Schema.optional(Schema.String)`.
|
|
24867
|
+
* Decoding the same input with the original schema rejects `null`.
|
|
24868
|
+
*
|
|
24869
|
+
* The `options` parameter controls reference extraction and generation details
|
|
24870
|
+
* such as excess properties and synthesized check descriptions; it does not
|
|
24871
|
+
* change the draft target. The reference policy receives canonical JSON
|
|
24872
|
+
* encoded ASTs. By default, anonymous non-recursive candidates remain inline,
|
|
24873
|
+
* while candidates with resolved identifiers become definitions. Declarations
|
|
24874
|
+
* are lowered through their `toCodecJson` or `toCodec` annotation when
|
|
24875
|
+
* available before the representation document is compiled.
|
|
24876
|
+
*
|
|
24877
|
+
* The generated document is intended for preliminary validation. JSON Schema
|
|
24878
|
+
* and Effect checks do not always have identical semantics, so the Effect
|
|
24879
|
+
* decoder remains the final authority. Passing JSON Schema validation does not
|
|
24880
|
+
* guarantee that Effect decoding will succeed.
|
|
24881
|
+
*
|
|
24882
|
+
* **Gotchas**
|
|
24883
|
+
*
|
|
24884
|
+
* JSON Schema generation is best-effort. String length uses Unicode code points
|
|
24885
|
+
* in JSON Schema and UTF-16 code units in Effect. A generated `pattern` cannot
|
|
24886
|
+
* retain JavaScript RegExp flags. Object property checks apply to the original
|
|
24887
|
+
* input in JSON Schema but to the decoded object in Effect. When a `oneOf`
|
|
24888
|
+
* branch contains a known approximation, the compiler emits `anyOf` so that
|
|
24889
|
+
* the approximation cannot create a false rejection. Unions with only exact
|
|
24890
|
+
* branches retain `oneOf`. Custom `toJsonSchema` callbacks return `[schema, true]` for safe,
|
|
24891
|
+
* looser approximations and are responsible for the semantics they declare. When
|
|
24892
|
+
* canonical JSON derivation adds an artificial transformation, checks and
|
|
24893
|
+
* annotations on its source node are not copied to the JSON target, so they do
|
|
24894
|
+
* not appear in the emitted document. Opaque declarations without a structural
|
|
24895
|
+
* codec are represented by an unconstrained JSON Schema. The default
|
|
24896
|
+
* `onExcessProperty: "ignore"` matches the decoder default and leaves
|
|
24897
|
+
* index-signature keys without exact selectors open. In `"error"` mode, the compiler
|
|
24898
|
+
* constrains those keys with `propertyNames` and applies a permissive choice of
|
|
24899
|
+
* candidate index value schemas. The Effect decoder enforces the exact
|
|
24900
|
+
* key-value association.
|
|
24901
|
+
*
|
|
24902
|
+
* **Example** (Decoding JSON with the matching codec)
|
|
24903
|
+
*
|
|
24904
|
+
* ```ts import.meta.vitest
|
|
24905
|
+
* import { Schema } from "effect"
|
|
24906
|
+
*
|
|
24907
|
+
* const schema = Schema.Struct({
|
|
24908
|
+
* name: Schema.optional(Schema.String)
|
|
24909
|
+
* })
|
|
24910
|
+
*
|
|
24911
|
+
* const document = Schema.toJsonSchemaDocument(schema)
|
|
24912
|
+
* const jsonCodec = Schema.toCodecJson(schema)
|
|
24913
|
+
*
|
|
24914
|
+
* Schema.decodeUnknownResult(schema)({ name: null })._tag // => "Failure"
|
|
24915
|
+
* Schema.decodeUnknownSync(jsonCodec)({ name: null }) // => { name: undefined }
|
|
24916
|
+
* Schema.decodeUnknownSync(jsonCodec)({}) // => {}
|
|
24917
|
+
* Schema.encodeSync(jsonCodec)({ name: undefined }) // => { name: null }
|
|
24918
|
+
* ```
|
|
24919
|
+
*
|
|
24920
|
+
* @see {@link toCodecJson} for decoding and encoding the canonical JSON representation
|
|
24921
|
+
* @see {@link SchemaRepresentation.toJsonSchemaDocument} for compiling an existing live representation document
|
|
24922
|
+
*
|
|
24923
|
+
* @stability stable
|
|
24924
|
+
* @category converting
|
|
24925
|
+
* @since 4.0.0
|
|
24926
|
+
*/
|
|
24927
|
+
function toJsonSchemaDocument(schema, options) {
|
|
24928
|
+
return toJsonSchemaDocument$1(toRepresentation(toCodecJsonAST(schema.ast), options), options);
|
|
24929
|
+
}
|
|
24930
|
+
/**
|
|
23602
24931
|
* Converts a schema to the StringTree canonical codec, where every leaf value
|
|
23603
24932
|
* becomes a string while preserving the original structure.
|
|
23604
24933
|
*
|
|
@@ -30390,7 +31719,7 @@ const runWith = (command, config) => {
|
|
|
30390
31719
|
};
|
|
30391
31720
|
//#endregion
|
|
30392
31721
|
//#region package.json
|
|
30393
|
-
var version = "0.1
|
|
31722
|
+
var version = "0.2.1";
|
|
30394
31723
|
//#endregion
|
|
30395
31724
|
//#region ../../node_modules/.pnpm/effect@4.0.2/node_modules/effect/dist/Ref.js
|
|
30396
31725
|
/**
|
|
@@ -33269,14 +34598,35 @@ const VpSection = Struct({
|
|
|
33269
34598
|
const MachineSettings = Struct({ clones: optionalKey(NonEmptyString) });
|
|
33270
34599
|
const FleetConfig = Struct({
|
|
33271
34600
|
$schema: optionalKey(String$5),
|
|
33272
|
-
|
|
34601
|
+
shippedAt: optionalKey(String$5),
|
|
34602
|
+
shippedFrom: optionalKey(NonEmptyString),
|
|
34603
|
+
shippedTo: optionalKey(Record(NonEmptyString, String$5)),
|
|
34604
|
+
machines: Record(NonEmptyString, MachineSettings).check(makeFilter((machines) => Object.keys(machines).length > 0, {
|
|
34605
|
+
title: "Fleet",
|
|
34606
|
+
description: "at least one Machine"
|
|
34607
|
+
})),
|
|
33273
34608
|
repos: optionalKey(ArraySchema(TrackedRepo)),
|
|
33274
34609
|
vp: optionalKey(VpSection)
|
|
33275
34610
|
});
|
|
33276
34611
|
const repoName = (repo) => repo.name ?? repo.origin.replace("/", "-");
|
|
34612
|
+
const SELF_PACKAGE = "fleetfizz";
|
|
34613
|
+
//#endregion
|
|
34614
|
+
//#region ../../packages/config/src/jsonSchema.ts
|
|
34615
|
+
const fleetConfigJsonSchema = () => {
|
|
34616
|
+
const document = toJsonSchemaDocument(FleetConfig, { onExcessProperty: "error" });
|
|
34617
|
+
return {
|
|
34618
|
+
$schema: META_SCHEMA_URI_DRAFT_2020_12,
|
|
34619
|
+
title: "fleetfizz config",
|
|
34620
|
+
...document.schema,
|
|
34621
|
+
$defs: document.definitions
|
|
34622
|
+
};
|
|
34623
|
+
};
|
|
33277
34624
|
//#endregion
|
|
33278
34625
|
//#region ../../packages/config/src/load.ts
|
|
33279
34626
|
const CONFIG_FILE = "fleet.config.jsonc";
|
|
34627
|
+
const SCHEMA_FILE = "fleet.schema.json";
|
|
34628
|
+
const configDir = (env) => `${env.XDG_CONFIG_HOME || `${env.HOME ?? "~"}/.config`}/fleetfizz`;
|
|
34629
|
+
const configPath = (env) => `${configDir(env)}/${CONFIG_FILE}`;
|
|
33280
34630
|
var ConfigError = class extends TaggedError()("ConfigError", {
|
|
33281
34631
|
path: String$5,
|
|
33282
34632
|
problems: ArraySchema(String$5)
|
|
@@ -33285,23 +34635,11 @@ var ConfigError = class extends TaggedError()("ConfigError", {
|
|
|
33285
34635
|
return [`${this.path}:`, ...this.problems.map((p) => ` ${p}`)].join("\n");
|
|
33286
34636
|
}
|
|
33287
34637
|
};
|
|
33288
|
-
var ConfigNotFound = class extends TaggedError()("ConfigNotFound", {
|
|
34638
|
+
var ConfigNotFound = class extends TaggedError()("ConfigNotFound", { path: String$5 }) {
|
|
33289
34639
|
get message() {
|
|
33290
|
-
return `no
|
|
34640
|
+
return `no config at ${this.path}; write one there (the README has an example) or pass --config`;
|
|
33291
34641
|
}
|
|
33292
34642
|
};
|
|
33293
|
-
const findConfig = fn("findConfig")(function* (start) {
|
|
33294
|
-
const fs = yield* FileSystem;
|
|
33295
|
-
const path = yield* Path$1;
|
|
33296
|
-
let dir = path.resolve(start);
|
|
33297
|
-
for (;;) {
|
|
33298
|
-
const candidate = path.join(dir, CONFIG_FILE);
|
|
33299
|
-
if (yield* fs.exists(candidate)) return candidate;
|
|
33300
|
-
const parent = path.dirname(dir);
|
|
33301
|
-
if (parent === dir) return yield* new ConfigNotFound({ start });
|
|
33302
|
-
dir = parent;
|
|
33303
|
-
}
|
|
33304
|
-
});
|
|
33305
34643
|
const lineOf = (text, offset) => text.slice(0, offset).split("\n").length;
|
|
33306
34644
|
const semanticProblems = (config) => {
|
|
33307
34645
|
const problems = [];
|
|
@@ -33311,6 +34649,7 @@ const semanticProblems = (config) => {
|
|
|
33311
34649
|
if (seen.has(name)) problems.push(`repos: duplicate name "${name}"`);
|
|
33312
34650
|
seen.add(name);
|
|
33313
34651
|
}
|
|
34652
|
+
if (config.vp?.globals?.["fleetfizz"] !== void 0) problems.push(`vp.globals: ${SELF_PACKAGE} is pinned by the running version; remove it`);
|
|
33314
34653
|
return problems;
|
|
33315
34654
|
};
|
|
33316
34655
|
const parseConfig = fn("parseConfig")(function* (path, text) {
|
|
@@ -33333,10 +34672,48 @@ const parseConfig = fn("parseConfig")(function* (path, text) {
|
|
|
33333
34672
|
});
|
|
33334
34673
|
const formatIssue = makeFormatterDefault();
|
|
33335
34674
|
const loadConfig = fn("loadConfig")(function* (path) {
|
|
33336
|
-
const
|
|
34675
|
+
const fs = yield* FileSystem;
|
|
34676
|
+
if (!(yield* fs.exists(path))) return yield* new ConfigNotFound({ path });
|
|
34677
|
+
const text = yield* fs.readFileString(path);
|
|
33337
34678
|
return yield* parseConfig(path, text);
|
|
33338
34679
|
});
|
|
33339
34680
|
//#endregion
|
|
34681
|
+
//#region ../../packages/config/src/stamp.ts
|
|
34682
|
+
const insertAfter = (before) => (properties) => {
|
|
34683
|
+
return before.map((key) => properties.indexOf(key)).reduce((a, b) => Math.max(a, b), -1) + 1;
|
|
34684
|
+
};
|
|
34685
|
+
const STAMP_KEYS = [
|
|
34686
|
+
"$schema",
|
|
34687
|
+
"shippedAt",
|
|
34688
|
+
"shippedFrom",
|
|
34689
|
+
"shippedTo"
|
|
34690
|
+
];
|
|
34691
|
+
const stampText = (text, stamp) => {
|
|
34692
|
+
const options = { formattingOptions: {
|
|
34693
|
+
insertSpaces: true,
|
|
34694
|
+
tabSize: 2
|
|
34695
|
+
} };
|
|
34696
|
+
const set = (current, key, value) => applyEdits(current, modify(current, [key], value, {
|
|
34697
|
+
...options,
|
|
34698
|
+
getInsertionIndex: insertAfter(STAMP_KEYS.slice(0, STAMP_KEYS.indexOf(key)))
|
|
34699
|
+
}));
|
|
34700
|
+
const previous = parse(text, void 0, { allowTrailingComma: true });
|
|
34701
|
+
const shippedTo = {
|
|
34702
|
+
...shippedToOf(previous),
|
|
34703
|
+
...Object.fromEntries(stamp.reached.map((name) => [name, stamp.shippedAt]))
|
|
34704
|
+
};
|
|
34705
|
+
let out = set(text, "shippedAt", stamp.shippedAt);
|
|
34706
|
+
out = set(out, "shippedFrom", stamp.shippedFrom);
|
|
34707
|
+
return set(out, "shippedTo", shippedTo);
|
|
34708
|
+
};
|
|
34709
|
+
const shippedToOf = (config) => {
|
|
34710
|
+
if (typeof config !== "object" || config === null || !("shippedTo" in config)) return {};
|
|
34711
|
+
const value = config.shippedTo;
|
|
34712
|
+
if (typeof value !== "object" || value === null) return {};
|
|
34713
|
+
return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string"));
|
|
34714
|
+
};
|
|
34715
|
+
const isNewer = (remote, local) => remote !== void 0 && (local === void 0 || remote > local);
|
|
34716
|
+
//#endregion
|
|
33340
34717
|
//#region ../../packages/core/src/range.ts
|
|
33341
34718
|
const newest$1 = (available) => available.filter((v) => import_semver.prerelease(v) === null).sort(import_semver.rcompare)[0];
|
|
33342
34719
|
const decideRange = (range, installed, available) => {
|
|
@@ -33417,17 +34794,12 @@ const planVp = (input) => {
|
|
|
33417
34794
|
skipped: [],
|
|
33418
34795
|
failures: []
|
|
33419
34796
|
};
|
|
33420
|
-
const vp = input.config.vp;
|
|
33421
|
-
if (vp === void 0 || !targets(vp, input.machine)) return out;
|
|
33422
34797
|
const { state, machine } = input;
|
|
33423
|
-
|
|
33424
|
-
|
|
33425
|
-
|
|
33426
|
-
|
|
33427
|
-
|
|
33428
|
-
return out;
|
|
33429
|
-
}
|
|
33430
|
-
const installed = state.vp.version;
|
|
34798
|
+
const vp = input.config.vp;
|
|
34799
|
+
const targeted = vp !== void 0 && targets(vp, machine);
|
|
34800
|
+
const missing = state.vp === void 0 || state.vp.version === null;
|
|
34801
|
+
if (missing) out.steps.push({ kind: "bootstrap" });
|
|
34802
|
+
const installed = missing ? void 0 : state.vp?.version ?? void 0;
|
|
33431
34803
|
const decide = (pkg, range, current, shown = pkg) => {
|
|
33432
34804
|
if (range === void 0) return void 0;
|
|
33433
34805
|
const decision = decideRange(range, current, input.versions[pkg] ?? []);
|
|
@@ -33468,31 +34840,35 @@ const planVp = (input) => {
|
|
|
33468
34840
|
}
|
|
33469
34841
|
}
|
|
33470
34842
|
};
|
|
33471
|
-
const
|
|
33472
|
-
|
|
33473
|
-
|
|
33474
|
-
|
|
33475
|
-
|
|
33476
|
-
|
|
33477
|
-
|
|
33478
|
-
|
|
33479
|
-
|
|
33480
|
-
|
|
34843
|
+
const nodeNow = missing ? void 0 : state.node ?? void 0;
|
|
34844
|
+
let nodeTarget;
|
|
34845
|
+
if (targeted) {
|
|
34846
|
+
const vpTarget = decide(VP_PACKAGE, vp.version, installed, "vp");
|
|
34847
|
+
if (vpTarget !== void 0) {
|
|
34848
|
+
if (isHomebrew(state.vp?.path)) out.failures.push({
|
|
34849
|
+
what: "vp",
|
|
34850
|
+
reason: `vp ${installed} was installed with Homebrew; run brew upgrade vite-plus to get ${vpTarget}`
|
|
34851
|
+
});
|
|
34852
|
+
else out.steps.push({
|
|
34853
|
+
kind: "vp",
|
|
34854
|
+
from: installed ?? null,
|
|
34855
|
+
version: vpTarget
|
|
34856
|
+
});
|
|
34857
|
+
}
|
|
34858
|
+
nodeTarget = decide(NODE_PACKAGE, vp.node, nodeNow, "node");
|
|
34859
|
+
if (nodeTarget !== void 0) out.steps.push({
|
|
34860
|
+
kind: "node",
|
|
34861
|
+
from: nodeNow ?? null,
|
|
34862
|
+
version: nodeTarget
|
|
33481
34863
|
});
|
|
33482
34864
|
}
|
|
33483
|
-
const nodeNow = state.node ?? void 0;
|
|
33484
|
-
const nodeTarget = decide(NODE_PACKAGE, vp.node, nodeNow, "node");
|
|
33485
|
-
if (nodeTarget !== void 0) out.steps.push({
|
|
33486
|
-
kind: "node",
|
|
33487
|
-
from: nodeNow ?? null,
|
|
33488
|
-
version: nodeTarget
|
|
33489
|
-
});
|
|
33490
34865
|
const nodeDefault = nodeTarget ?? nodeNow;
|
|
33491
|
-
const byName = new Map(state.globals.map((g) => [g.name, g]));
|
|
34866
|
+
const byName = new Map((missing ? [] : state.globals).map((g) => [g.name, g]));
|
|
33492
34867
|
const installs = [];
|
|
33493
|
-
|
|
34868
|
+
const wanted = Object.entries(targeted ? vp.globals ?? {} : {});
|
|
34869
|
+
for (const [name, range] of [...wanted, [SELF_PACKAGE, input.self]]) {
|
|
33494
34870
|
const current = byName.get(name);
|
|
33495
|
-
const version = decide(name, range, current?.version);
|
|
34871
|
+
const version = name === "fleetfizz" ? decideSelf(current?.version, input.self, out) : decide(name, range, current?.version);
|
|
33496
34872
|
if (version !== void 0) installs.push(current === void 0 ? {
|
|
33497
34873
|
name,
|
|
33498
34874
|
version
|
|
@@ -33513,6 +34889,13 @@ const planVp = (input) => {
|
|
|
33513
34889
|
});
|
|
33514
34890
|
return out;
|
|
33515
34891
|
};
|
|
34892
|
+
const decideSelf = (installed, self, out) => {
|
|
34893
|
+
if (installed === void 0 || import_semver.lt(installed, self)) return self;
|
|
34894
|
+
if (import_semver.gt(installed, self)) out.failures.push({
|
|
34895
|
+
what: SELF_PACKAGE,
|
|
34896
|
+
reason: `runs ${SELF_PACKAGE} ${installed}, newer than this ${self}; upgrade here first`
|
|
34897
|
+
});
|
|
34898
|
+
};
|
|
33516
34899
|
const planRepos = (input) => {
|
|
33517
34900
|
const repos = [];
|
|
33518
34901
|
const failures = [];
|
|
@@ -33631,6 +35014,11 @@ const Fact = Union([
|
|
|
33631
35014
|
name: String$5,
|
|
33632
35015
|
record: InstallRecordSchema
|
|
33633
35016
|
}),
|
|
35017
|
+
Struct({
|
|
35018
|
+
fact: Literal("config"),
|
|
35019
|
+
present: Boolean$4,
|
|
35020
|
+
base64: optionalKey(String$5)
|
|
35021
|
+
}),
|
|
33634
35022
|
Struct({
|
|
33635
35023
|
fact: Literal("output"),
|
|
33636
35024
|
repo: String$5,
|
|
@@ -33645,6 +35033,7 @@ const emptyState = {
|
|
|
33645
35033
|
records: {},
|
|
33646
35034
|
outputs: {}
|
|
33647
35035
|
};
|
|
35036
|
+
const decodeBase64 = (base64) => new TextDecoder().decode(Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)));
|
|
33648
35037
|
const assembleState = (facts) => {
|
|
33649
35038
|
let state = emptyState;
|
|
33650
35039
|
for (const fact of facts) switch (fact.fact) {
|
|
@@ -33714,6 +35103,12 @@ const assembleState = (facts) => {
|
|
|
33714
35103
|
}
|
|
33715
35104
|
};
|
|
33716
35105
|
break;
|
|
35106
|
+
case "config":
|
|
35107
|
+
if (fact.present && fact.base64 !== void 0) state = {
|
|
35108
|
+
...state,
|
|
35109
|
+
config: decodeBase64(fact.base64)
|
|
35110
|
+
};
|
|
35111
|
+
break;
|
|
33717
35112
|
case "output": state = {
|
|
33718
35113
|
...state,
|
|
33719
35114
|
outputs: {
|
|
@@ -33745,6 +35140,7 @@ const fingerprintFn = [
|
|
|
33745
35140
|
"}"
|
|
33746
35141
|
].join("\n");
|
|
33747
35142
|
const RECORDS_DIR = `~/.local/state/fleetfizz/records`;
|
|
35143
|
+
const CONFIG_DIR_SH = "\"${XDG_CONFIG_HOME:-$HOME/.config}/fleetfizz\"";
|
|
33748
35144
|
const gatherScript = (input) => {
|
|
33749
35145
|
const lines = [
|
|
33750
35146
|
prelude,
|
|
@@ -33773,6 +35169,7 @@ const gatherScript = (input) => {
|
|
|
33773
35169
|
const name = quote(repo.name);
|
|
33774
35170
|
lines.push(`ff_r=${quotePath(RECORDS_DIR)}/${quote(`${repo.name}.json`)}`, `if [ -f "$ff_r" ]; then ff_state "{\\"fact\\":\\"record\\",\\"name\\":\\"$(ff_json ${name})\\",\\"record\\":$(tr -d '\\n' < "$ff_r")}"; fi`);
|
|
33775
35171
|
}
|
|
35172
|
+
lines.push(`ff_c=${CONFIG_DIR_SH}/${quote(CONFIG_FILE)}`, `if [ -f "$ff_c" ]; then ff_state "{\\"fact\\":\\"config\\",\\"present\\":true,\\"base64\\":\\"$(base64 < "$ff_c" | tr -d '\\n')\\"}"; else ff_state '{"fact":"config","present":false}'; fi`);
|
|
33776
35173
|
lines.push(`ff_state '{"fact":"end"}'`);
|
|
33777
35174
|
return lines.join("\n");
|
|
33778
35175
|
};
|
|
@@ -33823,10 +35220,19 @@ const jsonString = encodeSync(fromJsonString(String$5));
|
|
|
33823
35220
|
const jsonRecord = encodeSync(fromJsonString(Record(String$5, String$5)));
|
|
33824
35221
|
const stepId = (repo, step) => `repo:${repo}:${step}`;
|
|
33825
35222
|
const vpStepId = (step) => step.kind === "reinstall" ? `vp:reinstall:${step.name}` : step.kind === "globals" ? "vp:globals" : `vp:${step.kind}`;
|
|
35223
|
+
const CONFIG_STEP = "config";
|
|
35224
|
+
const VP_INSTALL = [
|
|
35225
|
+
"curl -fsSL https://vite.plus | bash",
|
|
35226
|
+
`ff_env="\${XDG_CONFIG_HOME:-$HOME/.config}/vite-plus/env"`,
|
|
35227
|
+
`{ [ ! -f "$ff_env" ] || . "$ff_env"; }`,
|
|
35228
|
+
`export PATH="\${VP_HOME:-$HOME/.vite-plus}/bin:\${XDG_DATA_HOME:-$HOME/.local/share}/vite-plus/bin:$PATH"`,
|
|
35229
|
+
"{ hash -r 2>/dev/null || true; }"
|
|
35230
|
+
].join(" && ");
|
|
33826
35231
|
const vpStep = (step) => {
|
|
33827
35232
|
const id = vpStepId(step);
|
|
33828
35233
|
const command = (() => {
|
|
33829
35234
|
switch (step.kind) {
|
|
35235
|
+
case "bootstrap": return VP_INSTALL;
|
|
33830
35236
|
case "vp": return `command vp upgrade ${quote(step.version)}`;
|
|
33831
35237
|
case "node": return `command vp env default ${quote(step.version)}`;
|
|
33832
35238
|
case "reinstall": return `command vp install -g ${quote(`${step.name}@${step.version}`)}`;
|
|
@@ -33835,11 +35241,21 @@ const vpStep = (step) => {
|
|
|
33835
35241
|
})();
|
|
33836
35242
|
return [
|
|
33837
35243
|
stepLine(id),
|
|
33838
|
-
`( ${command} )`,
|
|
35244
|
+
step.kind === "bootstrap" ? command : `( ${command} )`,
|
|
33839
35245
|
`ff_code=$?`,
|
|
33840
35246
|
`if [ "$ff_code" -ne 0 ]; then ${doneLine(id, false, "$ff_code")}; else ${doneLine(id, true)}; fi`
|
|
33841
35247
|
];
|
|
33842
35248
|
};
|
|
35249
|
+
const configStep = () => {
|
|
35250
|
+
const dir = CONFIG_DIR_SH;
|
|
35251
|
+
const write = (variable, file) => `printf '%s' "$${variable}" | base64 -d > ${dir}/${quote(`${file}.tmp`)} && mv -f ${dir}/${quote(`${file}.tmp`)} ${dir}/${quote(file)}`;
|
|
35252
|
+
return [
|
|
35253
|
+
stepLine(CONFIG_STEP),
|
|
35254
|
+
`( mkdir -p ${dir} && ${write("ff_config", CONFIG_FILE)} && ${write("ff_schema", SCHEMA_FILE)} )`,
|
|
35255
|
+
`ff_code=$?`,
|
|
35256
|
+
`if [ "$ff_code" -ne 0 ]; then ${doneLine(CONFIG_STEP, false, "$ff_code")}; else ${doneLine(CONFIG_STEP, true)}; fi`
|
|
35257
|
+
];
|
|
35258
|
+
};
|
|
33843
35259
|
const writeRecord = (repo) => {
|
|
33844
35260
|
return [
|
|
33845
35261
|
`ff_outs=""`,
|
|
@@ -33892,16 +35308,30 @@ const repoSteps = (repo, input) => {
|
|
|
33892
35308
|
"fi"
|
|
33893
35309
|
];
|
|
33894
35310
|
};
|
|
35311
|
+
const applyStdin = (token, config, schema) => [
|
|
35312
|
+
token ?? "",
|
|
35313
|
+
encodeBase64(config),
|
|
35314
|
+
encodeBase64(schema)
|
|
35315
|
+
];
|
|
35316
|
+
const encodeBase64 = (text) => {
|
|
35317
|
+
const bytes = new TextEncoder().encode(text);
|
|
35318
|
+
let binary = "";
|
|
35319
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
35320
|
+
return btoa(binary);
|
|
35321
|
+
};
|
|
33895
35322
|
const applyScript = (input) => {
|
|
33896
35323
|
const lines = [
|
|
33897
35324
|
prelude,
|
|
33898
35325
|
fingerprintFn,
|
|
33899
35326
|
`ff_lit() { printf '%s' "$1"; }`,
|
|
33900
35327
|
`IFS= read -r ff_token || ff_token=""`,
|
|
35328
|
+
`IFS= read -r ff_config || ff_config=""`,
|
|
35329
|
+
`IFS= read -r ff_schema || ff_schema=""`,
|
|
33901
35330
|
`ff_git() { if [ -n "$ff_token" ]; then FF_TOKEN="$ff_token" git -c credential.helper= -c 'credential.helper=!f() { echo username=x-access-token; echo "password=$FF_TOKEN"; }; f' "$@"; else git "$@"; fi; }`,
|
|
33902
35331
|
`ff_root=${quotePath(input.cloneRoot)}`,
|
|
33903
35332
|
...input.cloneRoot.startsWith("~") ? [`mkdir -p "$ff_root"`] : []
|
|
33904
35333
|
];
|
|
35334
|
+
lines.push(...configStep());
|
|
33905
35335
|
for (const step of input.plan.vp) lines.push(...vpStep(step));
|
|
33906
35336
|
for (const repo of input.plan.repos) lines.push(...repoSteps(repo, input));
|
|
33907
35337
|
lines.push(doneLine("end", true));
|
|
@@ -34009,7 +35439,8 @@ const command = (target, script, secrets) => {
|
|
|
34009
35439
|
const options = {
|
|
34010
35440
|
stdin: encodeText(make$18(secrets.map((s) => `${s}\n`).join(""))),
|
|
34011
35441
|
stdout: "pipe",
|
|
34012
|
-
stderr: "pipe"
|
|
35442
|
+
stderr: "pipe",
|
|
35443
|
+
forceKillAfter: "5 seconds"
|
|
34013
35444
|
};
|
|
34014
35445
|
return target.local ? make$13(process.env.SHELL ?? "/bin/sh", ["-lc", script], options) : make$13("tailscale", [
|
|
34015
35446
|
"ssh",
|
|
@@ -34117,13 +35548,17 @@ const runOn = fn("runOn")(function* (target, script, secrets, onLine, ledger) {
|
|
|
34117
35548
|
}
|
|
34118
35549
|
return run;
|
|
34119
35550
|
});
|
|
35551
|
+
const GATHER_TIMEOUT = "2 minutes";
|
|
34120
35552
|
const gather = fn("gather")(function* (target, script, ledger) {
|
|
34121
35553
|
const facts = [];
|
|
34122
35554
|
const output = [];
|
|
34123
35555
|
const run = yield* runOn(target, script, [], (line) => sync(() => {
|
|
34124
35556
|
if (line.kind === "state") facts.push(line.fact);
|
|
34125
35557
|
else if (line.kind === "text" && line.text.trim() !== "") output.push(line.text.trimEnd());
|
|
34126
|
-
}), ledger)
|
|
35558
|
+
}), ledger).pipe(timeoutOrElse({
|
|
35559
|
+
duration: GATHER_TIMEOUT,
|
|
35560
|
+
orElse: () => ledger.fail(target.name, [`gather took more than ${GATHER_TIMEOUT}; something on that Machine is blocking`, ...output]).pipe(as({ kind: "failed" }))
|
|
35561
|
+
}));
|
|
34127
35562
|
if (run.kind !== "ran") return { kind: run.kind };
|
|
34128
35563
|
const state = assembleState(facts);
|
|
34129
35564
|
if (!state.complete) {
|
|
@@ -34135,14 +35570,19 @@ const gather = fn("gather")(function* (target, script, ledger) {
|
|
|
34135
35570
|
state
|
|
34136
35571
|
};
|
|
34137
35572
|
});
|
|
34138
|
-
const runLabels = (p) => Object.fromEntries([
|
|
34139
|
-
|
|
34140
|
-
|
|
34141
|
-
|
|
34142
|
-
|
|
34143
|
-
|
|
34144
|
-
|
|
34145
|
-
|
|
35573
|
+
const runLabels = (p) => Object.fromEntries([
|
|
35574
|
+
[CONFIG_STEP, "config"],
|
|
35575
|
+
...p.vp.map((step) => {
|
|
35576
|
+
switch (step.kind) {
|
|
35577
|
+
case "bootstrap": return [vpStepId(step), "install vp"];
|
|
35578
|
+
case "vp": return [vpStepId(step), `vp upgrade ${step.version}`];
|
|
35579
|
+
case "node": return [vpStepId(step), `node default ${step.version}`];
|
|
35580
|
+
case "reinstall": return [vpStepId(step), `${step.name} reinstall`];
|
|
35581
|
+
case "globals": return [vpStepId(step), `install ${step.packages.map((g) => `${g.name}@${g.version}`).join(" ")}`];
|
|
35582
|
+
}
|
|
35583
|
+
}),
|
|
35584
|
+
...p.repos.map((r) => [stepId(r.name, "install"), `${r.name} install`])
|
|
35585
|
+
]);
|
|
34146
35586
|
const apply = fn("apply")(function* (target, p, script, secrets, ledger) {
|
|
34147
35587
|
const labels = runLabels(p);
|
|
34148
35588
|
let current;
|
|
@@ -34174,16 +35614,20 @@ const apply = fn("apply")(function* (target, p, script, secrets, ledger) {
|
|
|
34174
35614
|
case "text": if (line.text.trim() !== "") (current?.output ?? head).push(line.text.trimEnd());
|
|
34175
35615
|
}
|
|
34176
35616
|
}), ledger);
|
|
34177
|
-
|
|
35617
|
+
const applied = (outcome) => ({
|
|
35618
|
+
outcome,
|
|
35619
|
+
done
|
|
35620
|
+
});
|
|
35621
|
+
if (run.kind !== "ran") return applied(run.kind);
|
|
34178
35622
|
if (current !== void 0) {
|
|
34179
35623
|
yield* ledger.fail(target.name, [`${current.id} did not finish`, ...current.output]);
|
|
34180
|
-
return "failed";
|
|
35624
|
+
return applied("failed");
|
|
34181
35625
|
}
|
|
34182
35626
|
if (!done.includes("end")) {
|
|
34183
35627
|
yield* ledger.fail(target.name, ["apply did not finish", ...head]);
|
|
34184
|
-
return "failed";
|
|
35628
|
+
return applied("failed");
|
|
34185
35629
|
}
|
|
34186
|
-
if (failed.length > 0 || p.failures.length > 0) return "failed";
|
|
35630
|
+
if (failed.length > 0 || p.failures.length > 0) return applied("failed");
|
|
34187
35631
|
const installed = p.repos.filter((r) => done.includes(stepId(r.name, "install")));
|
|
34188
35632
|
const upToDate = p.repos.length - installed.length;
|
|
34189
35633
|
const parts = [
|
|
@@ -34192,7 +35636,7 @@ const apply = fn("apply")(function* (target, p, script, secrets, ledger) {
|
|
|
34192
35636
|
...upToDate > 0 ? [`${upToDate} repo${upToDate === 1 ? "" : "s"} up to date`] : []
|
|
34193
35637
|
];
|
|
34194
35638
|
yield* ledger.line(target.name, "OK", parts.length === 0 ? "up to date" : parts.join(" · "));
|
|
34195
|
-
return "ok";
|
|
35639
|
+
return applied("ok");
|
|
34196
35640
|
});
|
|
34197
35641
|
//#endregion
|
|
34198
35642
|
//#region src/questions.ts
|
|
@@ -34242,6 +35686,7 @@ const askQuestions = fn("askQuestions")(function* (questions, flags, ledger) {
|
|
|
34242
35686
|
const SEP = " · ";
|
|
34243
35687
|
const vpPart = (step) => {
|
|
34244
35688
|
switch (step.kind) {
|
|
35689
|
+
case "bootstrap": return "install vp";
|
|
34245
35690
|
case "vp": return `vp ${step.from ?? "none"} -> ${step.version}`;
|
|
34246
35691
|
case "node": return `node ${step.from ?? "none"} -> ${step.version}`;
|
|
34247
35692
|
case "reinstall": return `${step.name} reinstall on Node`;
|
|
@@ -34252,10 +35697,14 @@ const repoPart = (repo) => {
|
|
|
34252
35697
|
if (repo.decision.run) return `${repo.name} install (${repo.decision.reason})`;
|
|
34253
35698
|
};
|
|
34254
35699
|
const summarize = (plan) => {
|
|
34255
|
-
const parts = [
|
|
35700
|
+
const parts = [
|
|
35701
|
+
"config",
|
|
35702
|
+
...plan.vp.map(vpPart),
|
|
35703
|
+
...plan.repos.map(repoPart).filter((p) => p !== void 0)
|
|
35704
|
+
];
|
|
34256
35705
|
const upToDate = plan.repos.filter((r) => !r.decision.run).length;
|
|
34257
35706
|
if (upToDate > 0) parts.push(`${upToDate} repo${upToDate === 1 ? "" : "s"} up to date`);
|
|
34258
|
-
return parts.
|
|
35707
|
+
return parts.join(SEP);
|
|
34259
35708
|
};
|
|
34260
35709
|
//#endregion
|
|
34261
35710
|
//#region src/ship.ts
|
|
@@ -34265,7 +35714,7 @@ var ShipError = class extends Error {
|
|
|
34265
35714
|
const unknownMachines = (config, tailnet, only) => {
|
|
34266
35715
|
const known = new Set(tailnet.fleet.map((m) => m.name));
|
|
34267
35716
|
const referenced = [
|
|
34268
|
-
...Object.keys(config.machines
|
|
35717
|
+
...Object.keys(config.machines),
|
|
34269
35718
|
...(config.repos ?? []).flatMap((r) => r.machines ?? []),
|
|
34270
35719
|
...config.vp?.machines ?? [],
|
|
34271
35720
|
...only
|
|
@@ -34282,14 +35731,33 @@ const packagesToResolve = (config) => {
|
|
|
34282
35731
|
];
|
|
34283
35732
|
};
|
|
34284
35733
|
const rebuildOf = (flags) => flags.rebuild.length === 0 ? "none" : flags.rebuild.includes("all") ? "all" : flags.rebuild;
|
|
35734
|
+
const staleConfigs = fn("staleConfigs")(function* (local, inputIsLocalFile, gathered, ledger) {
|
|
35735
|
+
const stale = [];
|
|
35736
|
+
for (const { machine, local: isLocal, state } of gathered) {
|
|
35737
|
+
if (isLocal && inputIsLocalFile || state.config === void 0) continue;
|
|
35738
|
+
const parsed = yield* result(parseConfig(machine.name, state.config));
|
|
35739
|
+
if (parsed._tag === "Failure") {
|
|
35740
|
+
yield* ledger.line(machine.name, "INFO", "its config does not parse; it will be overwritten");
|
|
35741
|
+
continue;
|
|
35742
|
+
}
|
|
35743
|
+
const remote = parsed.success;
|
|
35744
|
+
if (isNewer(remote.shippedTo?.[machine.name], local.shippedTo?.[machine.name])) stale.push(`${machine.name} (shipped ${remote.shippedAt} from ${remote.shippedFrom ?? "unknown"})`);
|
|
35745
|
+
}
|
|
35746
|
+
return stale;
|
|
35747
|
+
});
|
|
35748
|
+
const schemaJson = encodeSync(fromJsonString(Unknown, { space: 2 }));
|
|
34285
35749
|
const ship = fn("ship")(function* (flags) {
|
|
34286
|
-
const
|
|
34287
|
-
const
|
|
34288
|
-
const config = yield* loadConfig(
|
|
35750
|
+
const fs = yield* FileSystem;
|
|
35751
|
+
const path = flags.config ?? configPath(process.env);
|
|
35752
|
+
const config = yield* loadConfig(path);
|
|
34289
35753
|
const tailnet = yield* readTailnet();
|
|
34290
35754
|
const unknown = unknownMachines(config, tailnet, flags.only);
|
|
34291
35755
|
if (unknown.length > 0) return yield* fail$1(new ShipError(`unknown Machine: ${unknown.join(", ")} (the tailnet has: ${tailnet.fleet.map((m) => m.name).join(", ")})`));
|
|
34292
|
-
const
|
|
35756
|
+
const fleet = new Set(Object.keys(config.machines));
|
|
35757
|
+
if (!fleet.has(tailnet.self.name)) return yield* fail$1(new ShipError(`this Machine (${tailnet.self.name}) is not in machines in ${path}`));
|
|
35758
|
+
const outsideFleet = flags.only.filter((name) => !fleet.has(name));
|
|
35759
|
+
if (outsideFleet.length > 0) return yield* fail$1(new ShipError(`not in machines in ${path}: ${outsideFleet.join(", ")}`));
|
|
35760
|
+
const targetsList = tailnet.fleet.filter((m) => fleet.has(m.name) && (flags.only.length === 0 || flags.only.includes(m.name)));
|
|
34293
35761
|
const ledger = yield* makeLedger(Math.max(5, ...targetsList.map((m) => m.name.length)));
|
|
34294
35762
|
const count = `${targetsList.length} machine${targetsList.length === 1 ? "" : "s"}`;
|
|
34295
35763
|
yield* ledger.line("fleet", "INFO", [
|
|
@@ -34308,7 +35776,7 @@ const ship = fn("ship")(function* (flags) {
|
|
|
34308
35776
|
yield* ledger.line("fleet", "DONE", `${okWord} ${n("ok")} skipped ${n("skipped")} failed ${n("failed")}`);
|
|
34309
35777
|
if (n("failed") > 0) process.exitCode = 1;
|
|
34310
35778
|
});
|
|
34311
|
-
const cloneRootOf = (machine) => config.machines
|
|
35779
|
+
const cloneRootOf = (machine) => config.machines[machine.name]?.clones ?? "~/.local/share/fleetfizz/clones";
|
|
34312
35780
|
const gatherRepos = (config.repos ?? []).map((r) => ({
|
|
34313
35781
|
name: repoName(r),
|
|
34314
35782
|
outputs: r.outputs ?? []
|
|
@@ -34343,6 +35811,17 @@ const ship = fn("ship")(function* (flags) {
|
|
|
34343
35811
|
state: result.state
|
|
34344
35812
|
};
|
|
34345
35813
|
}), { concurrency: "unbounded" }).pipe(map$5((list) => list.filter((g) => g !== void 0)));
|
|
35814
|
+
const stale = yield* staleConfigs(config, flags.config === void 0, gathered, ledger);
|
|
35815
|
+
if (stale.length > 0) {
|
|
35816
|
+
const what = `newer config on ${stale.join(", ")}`;
|
|
35817
|
+
if (flags.dryRun) yield* ledger.line("fleet", "INFO", `${what}; a Ship would ask before overwriting it`);
|
|
35818
|
+
else if (flags.overwriteConfig) yield* ledger.line("fleet", "INFO", `${what}; overwriting it (--overwrite-config)`);
|
|
35819
|
+
else if (!hasTty()) return yield* fail$1(new ShipError(`${what}; copy it here first, or pass --overwrite-config`));
|
|
35820
|
+
else {
|
|
35821
|
+
yield* ledger.line("fleet", "ASK", what);
|
|
35822
|
+
if (!(yield* run$2(Confirm({ message: "Overwrite it with this Machine's config?" })))) return yield* fail$1(new ShipError("aborted: the config here is older"));
|
|
35823
|
+
}
|
|
35824
|
+
}
|
|
34346
35825
|
const versions = yield* resolveVersions(packagesToResolve(config));
|
|
34347
35826
|
const planAll = (cfg, answers) => gathered.map((g) => ({
|
|
34348
35827
|
...g,
|
|
@@ -34353,21 +35832,22 @@ const ship = fn("ship")(function* (flags) {
|
|
|
34353
35832
|
platform: g.machine.platform
|
|
34354
35833
|
},
|
|
34355
35834
|
state: g.state,
|
|
35835
|
+
self: flags.version,
|
|
34356
35836
|
versions,
|
|
34357
35837
|
rebuild: rebuildOf(flags),
|
|
34358
35838
|
answers
|
|
34359
35839
|
})
|
|
34360
35840
|
}));
|
|
34361
|
-
let
|
|
35841
|
+
let cfg = config;
|
|
35842
|
+
let planned = planAll(cfg, {});
|
|
34362
35843
|
const questions = planned.flatMap((g) => g.plan.questions);
|
|
34363
35844
|
if (questions.length > 0 && !flags.dryRun) {
|
|
34364
35845
|
const decided = yield* askQuestions(questions, flags, ledger);
|
|
34365
|
-
let cfg = config;
|
|
34366
35846
|
for (const [pkg, decision] of Object.entries(decided)) if (decision.kind === "bump") {
|
|
34367
|
-
const range = yield* bumpConfig(
|
|
34368
|
-
yield* ledger.line("fleet", "INFO", `bumped ${pkg} to ${range} in ${
|
|
35847
|
+
const range = yield* bumpConfig(path, pkg, decision.installed);
|
|
35848
|
+
yield* ledger.line("fleet", "INFO", `bumped ${pkg} to ${range} in ${path}`);
|
|
34369
35849
|
}
|
|
34370
|
-
if (Object.values(decided).some((d) => d.kind === "bump")) cfg = yield* loadConfig(
|
|
35850
|
+
if (Object.values(decided).some((d) => d.kind === "bump")) cfg = yield* loadConfig(path);
|
|
34371
35851
|
const answers = Object.fromEntries(Object.entries(decided).flatMap(([pkg, d]) => d.kind === "bump" ? [] : [[pkg, d.kind]]));
|
|
34372
35852
|
planned = planAll(cfg, answers);
|
|
34373
35853
|
}
|
|
@@ -34379,14 +35859,21 @@ const ship = fn("ship")(function* (flags) {
|
|
|
34379
35859
|
yield* record(machine.name, p.failures.length > 0 ? "failed" : "ok");
|
|
34380
35860
|
}
|
|
34381
35861
|
if (flags.dryRun) return yield* finish("planned");
|
|
35862
|
+
const shippedAt = formatIso(yield* now);
|
|
35863
|
+
const original = yield* fs.readFileString(path);
|
|
35864
|
+
const stampWith = (reached) => stampText(original, {
|
|
35865
|
+
shippedAt,
|
|
35866
|
+
shippedFrom: tailnet.self.name,
|
|
35867
|
+
reached: [...reached, ...flags.config === void 0 ? [tailnet.self.name] : []]
|
|
35868
|
+
});
|
|
35869
|
+
const stamped = stampWith(planned.map((g) => g.machine.name));
|
|
35870
|
+
yield* fs.writeFileString(path, stamped);
|
|
35871
|
+
const schema = `${schemaJson(fleetConfigJsonSchema())}\n`;
|
|
34382
35872
|
const lent = planned.some((g) => g.plan.repos.length > 0) ? yield* readLentToken() : { token: void 0 };
|
|
34383
35873
|
if (lent.token === void 0 && lent.reason !== void 0) yield* ledger.line("fleet", "INFO", `no gh token (${lent.reason}); private repos will fail`);
|
|
34384
|
-
const machineNames =
|
|
34385
|
-
|
|
34386
|
-
|
|
34387
|
-
if (p.failures.length === 0) yield* ledger.line(machine.name, "OK", "up to date");
|
|
34388
|
-
return;
|
|
34389
|
-
}
|
|
35874
|
+
const machineNames = [...fleet];
|
|
35875
|
+
const stdin = applyStdin(lent.token, stamped, schema);
|
|
35876
|
+
const delivered = yield* forEach$1(planned, fn("applyOne")(function* ({ machine, local, plan: p }) {
|
|
34390
35877
|
const script = applyScript({
|
|
34391
35878
|
plan: p,
|
|
34392
35879
|
cloneRoot: cloneRootOf(machine),
|
|
@@ -34396,12 +35883,14 @@ const ship = fn("ship")(function* (flags) {
|
|
|
34396
35883
|
machines: machineNames
|
|
34397
35884
|
}
|
|
34398
35885
|
});
|
|
34399
|
-
const
|
|
35886
|
+
const applied = yield* apply({
|
|
34400
35887
|
name: machine.name,
|
|
34401
35888
|
local
|
|
34402
|
-
}, p, script,
|
|
34403
|
-
yield* record(machine.name,
|
|
34404
|
-
|
|
35889
|
+
}, p, script, stdin, ledger);
|
|
35890
|
+
yield* record(machine.name, applied.outcome);
|
|
35891
|
+
return applied.done.includes("config") ? machine.name : void 0;
|
|
35892
|
+
}), { concurrency: "unbounded" }).pipe(map$5((list) => list.filter((name) => name !== void 0)));
|
|
35893
|
+
yield* fs.writeFileString(path, stampWith(delivered));
|
|
34405
35894
|
yield* finish("ok");
|
|
34406
35895
|
});
|
|
34407
35896
|
//#endregion
|
|
@@ -34412,14 +35901,17 @@ const shipCommand = make$1("ship", {
|
|
|
34412
35901
|
rebuild: String$1("rebuild").pipe(atLeast(0), withDescription$1("Run a repo's Install Command even when its record matches; `all` for every repo.")),
|
|
34413
35902
|
bump: Boolean$1("bump").pipe(withDefault(false), withDescription$1("Answer every above-range question by bumping the config.")),
|
|
34414
35903
|
enforce: Boolean$1("enforce").pipe(withDefault(false), withDescription$1("Answer every above-range question by downgrading into the range.")),
|
|
34415
|
-
|
|
35904
|
+
overwriteConfig: Boolean$1("overwrite-config").pipe(withDefault(false), withDescription$1("Ship even when another Machine holds a newer config, overwriting it with this one.")),
|
|
35905
|
+
config: String$1("config").pipe(optional, withDescription$1("Config file. Default: $XDG_CONFIG_HOME/fleetfizz/fleet.config.jsonc."))
|
|
34416
35906
|
}).pipe(withDescription("Ship the config to every reachable Machine."), withHandler((flags) => ship({
|
|
34417
35907
|
dryRun: flags.dryRun,
|
|
34418
35908
|
only: flags.only,
|
|
34419
35909
|
rebuild: flags.rebuild,
|
|
34420
35910
|
bump: flags.bump,
|
|
34421
35911
|
enforce: flags.enforce,
|
|
34422
|
-
|
|
35912
|
+
overwriteConfig: flags.overwriteConfig,
|
|
35913
|
+
config: flags.config._tag === "Some" ? flags.config.value : void 0,
|
|
35914
|
+
version
|
|
34423
35915
|
}).pipe(catch_((e) => gen(function* () {
|
|
34424
35916
|
yield* error(e.message);
|
|
34425
35917
|
process.exitCode = 1;
|