proschi 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/dist/cli.cjs +1612 -674
- package/dist/render.cjs +219 -219
- package/dist/server.cjs +89 -21
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -242,8 +242,8 @@ var require_scope = __commonJS({
|
|
|
242
242
|
super(nameStr);
|
|
243
243
|
this.prefix = prefix;
|
|
244
244
|
}
|
|
245
|
-
setValue(
|
|
246
|
-
this.value =
|
|
245
|
+
setValue(value2, { property, itemIndex }) {
|
|
246
|
+
this.value = value2;
|
|
247
247
|
this.scopePath = (0, code_1._)`.${new code_1.Name(property)}[${itemIndex}]`;
|
|
248
248
|
}
|
|
249
249
|
};
|
|
@@ -262,13 +262,13 @@ var require_scope = __commonJS({
|
|
|
262
262
|
name(prefix) {
|
|
263
263
|
return new ValueScopeName(prefix, this._newName(prefix));
|
|
264
264
|
}
|
|
265
|
-
value(nameOrPrefix,
|
|
265
|
+
value(nameOrPrefix, value2) {
|
|
266
266
|
var _a;
|
|
267
|
-
if (
|
|
267
|
+
if (value2.ref === void 0)
|
|
268
268
|
throw new Error("CodeGen: ref must be passed in value");
|
|
269
269
|
const name = this.toName(nameOrPrefix);
|
|
270
270
|
const { prefix } = name;
|
|
271
|
-
const valueKey = (_a =
|
|
271
|
+
const valueKey = (_a = value2.key) !== null && _a !== void 0 ? _a : value2.ref;
|
|
272
272
|
let vs = this._values[prefix];
|
|
273
273
|
if (vs) {
|
|
274
274
|
const _name = vs.get(valueKey);
|
|
@@ -280,8 +280,8 @@ var require_scope = __commonJS({
|
|
|
280
280
|
vs.set(valueKey, name);
|
|
281
281
|
const s = this._scope[prefix] || (this._scope[prefix] = []);
|
|
282
282
|
const itemIndex = s.length;
|
|
283
|
-
s[itemIndex] =
|
|
284
|
-
name.setValue(
|
|
283
|
+
s[itemIndex] = value2.ref;
|
|
284
|
+
name.setValue(value2, { property: prefix, itemIndex });
|
|
285
285
|
return name;
|
|
286
286
|
}
|
|
287
287
|
getValue(prefix, keyOrRef) {
|
|
@@ -751,8 +751,8 @@ var require_codegen = __commonJS({
|
|
|
751
751
|
return this._extScope.name(prefix);
|
|
752
752
|
}
|
|
753
753
|
// reserves unique name in the external scope and assigns value to it
|
|
754
|
-
scopeValue(prefixOrName,
|
|
755
|
-
const name = this._extScope.value(prefixOrName,
|
|
754
|
+
scopeValue(prefixOrName, value2) {
|
|
755
|
+
const name = this._extScope.value(prefixOrName, value2);
|
|
756
756
|
const vs = this._values[name.prefix] || (this._values[name.prefix] = /* @__PURE__ */ new Set());
|
|
757
757
|
vs.add(name);
|
|
758
758
|
return name;
|
|
@@ -806,13 +806,13 @@ var require_codegen = __commonJS({
|
|
|
806
806
|
// returns code for object literal for the passed argument list of key-value pairs
|
|
807
807
|
object(...keyValues) {
|
|
808
808
|
const code = ["{"];
|
|
809
|
-
for (const [key,
|
|
809
|
+
for (const [key, value2] of keyValues) {
|
|
810
810
|
if (code.length > 1)
|
|
811
811
|
code.push(",");
|
|
812
812
|
code.push(key);
|
|
813
|
-
if (key !==
|
|
813
|
+
if (key !== value2 || this.opts.es5) {
|
|
814
814
|
code.push(":");
|
|
815
|
-
(0, code_1.addCodeArg)(code,
|
|
815
|
+
(0, code_1.addCodeArg)(code, value2);
|
|
816
816
|
}
|
|
817
817
|
}
|
|
818
818
|
code.push("}");
|
|
@@ -891,10 +891,10 @@ var require_codegen = __commonJS({
|
|
|
891
891
|
return this._leafNode(new Break(label));
|
|
892
892
|
}
|
|
893
893
|
// `return` statement
|
|
894
|
-
return(
|
|
894
|
+
return(value2) {
|
|
895
895
|
const node = new Return();
|
|
896
896
|
this._blockNode(node);
|
|
897
|
-
this.code(
|
|
897
|
+
this.code(value2);
|
|
898
898
|
if (node.nodes.length !== 1)
|
|
899
899
|
throw new Error('CodeGen: "return" should have one node');
|
|
900
900
|
return this._endBlockNode(Return);
|
|
@@ -4200,13 +4200,13 @@ var require_fast_uri = __commonJS({
|
|
|
4200
4200
|
if (typeof uri !== "string" && typeof uri !== "object") {
|
|
4201
4201
|
return void 0;
|
|
4202
4202
|
}
|
|
4203
|
-
let
|
|
4203
|
+
let value2;
|
|
4204
4204
|
try {
|
|
4205
|
-
|
|
4205
|
+
value2 = typeof uri === "string" ? uri : serialize(uri, opts);
|
|
4206
4206
|
} catch {
|
|
4207
4207
|
return void 0;
|
|
4208
4208
|
}
|
|
4209
|
-
const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(
|
|
4209
|
+
const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value2, opts);
|
|
4210
4210
|
return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? void 0 : normalized;
|
|
4211
4211
|
}
|
|
4212
4212
|
var fastUri = {
|
|
@@ -5073,13 +5073,13 @@ var require_ucs2length = __commonJS({
|
|
|
5073
5073
|
const len2 = str.length;
|
|
5074
5074
|
let length = 0;
|
|
5075
5075
|
let pos = 0;
|
|
5076
|
-
let
|
|
5076
|
+
let value2;
|
|
5077
5077
|
while (pos < len2) {
|
|
5078
5078
|
length++;
|
|
5079
|
-
|
|
5080
|
-
if (
|
|
5081
|
-
|
|
5082
|
-
if ((
|
|
5079
|
+
value2 = str.charCodeAt(pos++);
|
|
5080
|
+
if (value2 >= 55296 && value2 <= 56319 && pos < len2) {
|
|
5081
|
+
value2 = str.charCodeAt(pos);
|
|
5082
|
+
if ((value2 & 64512) === 56320)
|
|
5083
5083
|
pos++;
|
|
5084
5084
|
}
|
|
5085
5085
|
}
|
|
@@ -7970,26 +7970,26 @@ var require_toJS = __commonJS({
|
|
|
7970
7970
|
"node_modules/yaml/dist/nodes/toJS.js"(exports2) {
|
|
7971
7971
|
"use strict";
|
|
7972
7972
|
var identity = require_identity();
|
|
7973
|
-
function toJS(
|
|
7974
|
-
if (Array.isArray(
|
|
7975
|
-
return
|
|
7976
|
-
if (
|
|
7977
|
-
if (!ctx || !identity.hasAnchor(
|
|
7978
|
-
return
|
|
7973
|
+
function toJS(value2, arg, ctx) {
|
|
7974
|
+
if (Array.isArray(value2))
|
|
7975
|
+
return value2.map((v, i) => toJS(v, String(i), ctx));
|
|
7976
|
+
if (value2 && typeof value2.toJSON === "function") {
|
|
7977
|
+
if (!ctx || !identity.hasAnchor(value2))
|
|
7978
|
+
return value2.toJSON(arg, ctx);
|
|
7979
7979
|
const data = { aliasCount: 0, count: 1, res: void 0 };
|
|
7980
|
-
ctx.anchors.set(
|
|
7980
|
+
ctx.anchors.set(value2, data);
|
|
7981
7981
|
ctx.onCreate = (res2) => {
|
|
7982
7982
|
data.res = res2;
|
|
7983
7983
|
delete ctx.onCreate;
|
|
7984
7984
|
};
|
|
7985
|
-
const res =
|
|
7985
|
+
const res = value2.toJSON(arg, ctx);
|
|
7986
7986
|
if (ctx.onCreate)
|
|
7987
7987
|
ctx.onCreate(res);
|
|
7988
7988
|
return res;
|
|
7989
7989
|
}
|
|
7990
|
-
if (typeof
|
|
7991
|
-
return Number(
|
|
7992
|
-
return
|
|
7990
|
+
if (typeof value2 === "bigint" && !ctx?.keep)
|
|
7991
|
+
return Number(value2);
|
|
7992
|
+
return value2;
|
|
7993
7993
|
}
|
|
7994
7994
|
exports2.toJS = toJS;
|
|
7995
7995
|
}
|
|
@@ -8161,11 +8161,11 @@ var require_Scalar = __commonJS({
|
|
|
8161
8161
|
var identity = require_identity();
|
|
8162
8162
|
var Node = require_Node();
|
|
8163
8163
|
var toJS = require_toJS();
|
|
8164
|
-
var isScalarValue = (
|
|
8164
|
+
var isScalarValue = (value2) => !value2 || typeof value2 !== "function" && typeof value2 !== "object";
|
|
8165
8165
|
var Scalar = class extends Node.NodeBase {
|
|
8166
|
-
constructor(
|
|
8166
|
+
constructor(value2) {
|
|
8167
8167
|
super(identity.SCALAR);
|
|
8168
|
-
this.value =
|
|
8168
|
+
this.value = value2;
|
|
8169
8169
|
}
|
|
8170
8170
|
toJSON(arg, ctx) {
|
|
8171
8171
|
return ctx?.keep ? this.value : toJS.toJS(this.value, arg, ctx);
|
|
@@ -8192,7 +8192,7 @@ var require_createNode = __commonJS({
|
|
|
8192
8192
|
var identity = require_identity();
|
|
8193
8193
|
var Scalar = require_Scalar();
|
|
8194
8194
|
var defaultTagPrefix = "tag:yaml.org,2002:";
|
|
8195
|
-
function findTagObject(
|
|
8195
|
+
function findTagObject(value2, tagName, tags) {
|
|
8196
8196
|
if (tagName) {
|
|
8197
8197
|
const match = tags.filter((t) => t.tag === tagName);
|
|
8198
8198
|
const tagObj = match.find((t) => !t.format) ?? match[0];
|
|
@@ -8200,53 +8200,53 @@ var require_createNode = __commonJS({
|
|
|
8200
8200
|
throw new Error(`Tag ${tagName} not found`);
|
|
8201
8201
|
return tagObj;
|
|
8202
8202
|
}
|
|
8203
|
-
return tags.find((t) => t.identify?.(
|
|
8203
|
+
return tags.find((t) => t.identify?.(value2) && !t.format);
|
|
8204
8204
|
}
|
|
8205
|
-
function createNode(
|
|
8206
|
-
if (identity.isDocument(
|
|
8207
|
-
|
|
8208
|
-
if (identity.isNode(
|
|
8209
|
-
return
|
|
8210
|
-
if (identity.isPair(
|
|
8205
|
+
function createNode(value2, tagName, ctx) {
|
|
8206
|
+
if (identity.isDocument(value2))
|
|
8207
|
+
value2 = value2.contents;
|
|
8208
|
+
if (identity.isNode(value2))
|
|
8209
|
+
return value2;
|
|
8210
|
+
if (identity.isPair(value2)) {
|
|
8211
8211
|
const map = ctx.schema[identity.MAP].createNode?.(ctx.schema, null, ctx);
|
|
8212
|
-
map.items.push(
|
|
8212
|
+
map.items.push(value2);
|
|
8213
8213
|
return map;
|
|
8214
8214
|
}
|
|
8215
|
-
if (
|
|
8216
|
-
|
|
8215
|
+
if (value2 instanceof String || value2 instanceof Number || value2 instanceof Boolean || typeof BigInt !== "undefined" && value2 instanceof BigInt) {
|
|
8216
|
+
value2 = value2.valueOf();
|
|
8217
8217
|
}
|
|
8218
8218
|
const { aliasDuplicateObjects, onAnchor, onTagObj, schema, sourceObjects } = ctx;
|
|
8219
8219
|
let ref = void 0;
|
|
8220
|
-
if (aliasDuplicateObjects &&
|
|
8221
|
-
ref = sourceObjects.get(
|
|
8220
|
+
if (aliasDuplicateObjects && value2 && typeof value2 === "object") {
|
|
8221
|
+
ref = sourceObjects.get(value2);
|
|
8222
8222
|
if (ref) {
|
|
8223
|
-
ref.anchor ?? (ref.anchor = onAnchor(
|
|
8223
|
+
ref.anchor ?? (ref.anchor = onAnchor(value2));
|
|
8224
8224
|
return new Alias.Alias(ref.anchor);
|
|
8225
8225
|
} else {
|
|
8226
8226
|
ref = { anchor: null, node: null };
|
|
8227
|
-
sourceObjects.set(
|
|
8227
|
+
sourceObjects.set(value2, ref);
|
|
8228
8228
|
}
|
|
8229
8229
|
}
|
|
8230
8230
|
if (tagName?.startsWith("!!"))
|
|
8231
8231
|
tagName = defaultTagPrefix + tagName.slice(2);
|
|
8232
|
-
let tagObj = findTagObject(
|
|
8232
|
+
let tagObj = findTagObject(value2, tagName, schema.tags);
|
|
8233
8233
|
if (!tagObj) {
|
|
8234
|
-
if (
|
|
8235
|
-
|
|
8234
|
+
if (value2 && typeof value2.toJSON === "function") {
|
|
8235
|
+
value2 = value2.toJSON();
|
|
8236
8236
|
}
|
|
8237
|
-
if (!
|
|
8238
|
-
const node2 = new Scalar.Scalar(
|
|
8237
|
+
if (!value2 || typeof value2 !== "object") {
|
|
8238
|
+
const node2 = new Scalar.Scalar(value2);
|
|
8239
8239
|
if (ref)
|
|
8240
8240
|
ref.node = node2;
|
|
8241
8241
|
return node2;
|
|
8242
8242
|
}
|
|
8243
|
-
tagObj =
|
|
8243
|
+
tagObj = value2 instanceof Map ? schema[identity.MAP] : Symbol.iterator in Object(value2) ? schema[identity.SEQ] : schema[identity.MAP];
|
|
8244
8244
|
}
|
|
8245
8245
|
if (onTagObj) {
|
|
8246
8246
|
onTagObj(tagObj);
|
|
8247
8247
|
delete ctx.onTagObj;
|
|
8248
8248
|
}
|
|
8249
|
-
const node = tagObj?.createNode ? tagObj.createNode(ctx.schema,
|
|
8249
|
+
const node = tagObj?.createNode ? tagObj.createNode(ctx.schema, value2, ctx) : typeof tagObj?.nodeClass?.from === "function" ? tagObj.nodeClass.from(ctx.schema, value2, ctx) : new Scalar.Scalar(value2);
|
|
8250
8250
|
if (tagName)
|
|
8251
8251
|
node.tag = tagName;
|
|
8252
8252
|
else if (!tagObj.default)
|
|
@@ -8266,8 +8266,8 @@ var require_Collection = __commonJS({
|
|
|
8266
8266
|
var createNode = require_createNode();
|
|
8267
8267
|
var identity = require_identity();
|
|
8268
8268
|
var Node = require_Node();
|
|
8269
|
-
function collectionFromPath(schema, path,
|
|
8270
|
-
let v =
|
|
8269
|
+
function collectionFromPath(schema, path, value2) {
|
|
8270
|
+
let v = value2;
|
|
8271
8271
|
for (let i = path.length - 1; i >= 0; --i) {
|
|
8272
8272
|
const k = path[i];
|
|
8273
8273
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
@@ -8318,16 +8318,16 @@ var require_Collection = __commonJS({
|
|
|
8318
8318
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
|
8319
8319
|
* that already exists in the map.
|
|
8320
8320
|
*/
|
|
8321
|
-
addIn(path,
|
|
8321
|
+
addIn(path, value2) {
|
|
8322
8322
|
if (isEmptyPath(path))
|
|
8323
|
-
this.add(
|
|
8323
|
+
this.add(value2);
|
|
8324
8324
|
else {
|
|
8325
8325
|
const [key, ...rest] = path;
|
|
8326
8326
|
const node = this.get(key, true);
|
|
8327
8327
|
if (identity.isCollection(node))
|
|
8328
|
-
node.addIn(rest,
|
|
8328
|
+
node.addIn(rest, value2);
|
|
8329
8329
|
else if (node === void 0 && this.schema)
|
|
8330
|
-
this.set(key, collectionFromPath(this.schema, rest,
|
|
8330
|
+
this.set(key, collectionFromPath(this.schema, rest, value2));
|
|
8331
8331
|
else
|
|
8332
8332
|
throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
|
|
8333
8333
|
}
|
|
@@ -8381,16 +8381,16 @@ var require_Collection = __commonJS({
|
|
|
8381
8381
|
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
|
8382
8382
|
* boolean to add/remove the item from the set.
|
|
8383
8383
|
*/
|
|
8384
|
-
setIn(path,
|
|
8384
|
+
setIn(path, value2) {
|
|
8385
8385
|
const [key, ...rest] = path;
|
|
8386
8386
|
if (rest.length === 0) {
|
|
8387
|
-
this.set(key,
|
|
8387
|
+
this.set(key, value2);
|
|
8388
8388
|
} else {
|
|
8389
8389
|
const node = this.get(key, true);
|
|
8390
8390
|
if (identity.isCollection(node))
|
|
8391
|
-
node.setIn(rest,
|
|
8391
|
+
node.setIn(rest, value2);
|
|
8392
8392
|
else if (node === void 0 && this.schema)
|
|
8393
|
-
this.set(key, collectionFromPath(this.schema, rest,
|
|
8393
|
+
this.set(key, collectionFromPath(this.schema, rest, value2));
|
|
8394
8394
|
else
|
|
8395
8395
|
throw new Error(`Expected YAML collection at ${key}. Remaining path: ${rest}`);
|
|
8396
8396
|
}
|
|
@@ -8585,13 +8585,13 @@ var require_stringifyString = __commonJS({
|
|
|
8585
8585
|
}
|
|
8586
8586
|
return true;
|
|
8587
8587
|
}
|
|
8588
|
-
function doubleQuotedString(
|
|
8589
|
-
const json2 = JSON.stringify(
|
|
8588
|
+
function doubleQuotedString(value2, ctx) {
|
|
8589
|
+
const json2 = JSON.stringify(value2);
|
|
8590
8590
|
if (ctx.options.doubleQuotedAsJSON)
|
|
8591
8591
|
return json2;
|
|
8592
8592
|
const { implicitKey } = ctx;
|
|
8593
8593
|
const minMultiLineLength = ctx.options.doubleQuotedMinMultiLineLength;
|
|
8594
|
-
const indent2 = ctx.indent || (containsDocumentMarker(
|
|
8594
|
+
const indent2 = ctx.indent || (containsDocumentMarker(value2) ? " " : "");
|
|
8595
8595
|
let str = "";
|
|
8596
8596
|
let start = 0;
|
|
8597
8597
|
for (let i = 0, ch = json2[i]; ch; ch = json2[++i]) {
|
|
@@ -8665,22 +8665,22 @@ var require_stringifyString = __commonJS({
|
|
|
8665
8665
|
str = start ? str + json2.slice(start) : json2;
|
|
8666
8666
|
return implicitKey ? str : foldFlowLines.foldFlowLines(str, indent2, foldFlowLines.FOLD_QUOTED, getFoldOptions(ctx, false));
|
|
8667
8667
|
}
|
|
8668
|
-
function singleQuotedString(
|
|
8669
|
-
if (ctx.options.singleQuote === false || ctx.implicitKey &&
|
|
8670
|
-
return doubleQuotedString(
|
|
8671
|
-
const indent2 = ctx.indent || (containsDocumentMarker(
|
|
8672
|
-
const res = "'" +
|
|
8668
|
+
function singleQuotedString(value2, ctx) {
|
|
8669
|
+
if (ctx.options.singleQuote === false || ctx.implicitKey && value2.includes("\n") || /[ \t]\n|\n[ \t]/.test(value2))
|
|
8670
|
+
return doubleQuotedString(value2, ctx);
|
|
8671
|
+
const indent2 = ctx.indent || (containsDocumentMarker(value2) ? " " : "");
|
|
8672
|
+
const res = "'" + value2.replace(/'/g, "''").replace(/\n+/g, `$&
|
|
8673
8673
|
${indent2}`) + "'";
|
|
8674
8674
|
return ctx.implicitKey ? res : foldFlowLines.foldFlowLines(res, indent2, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
|
|
8675
8675
|
}
|
|
8676
|
-
function quotedString(
|
|
8676
|
+
function quotedString(value2, ctx) {
|
|
8677
8677
|
const { singleQuote } = ctx.options;
|
|
8678
8678
|
let qs;
|
|
8679
8679
|
if (singleQuote === false)
|
|
8680
8680
|
qs = doubleQuotedString;
|
|
8681
8681
|
else {
|
|
8682
|
-
const hasDouble =
|
|
8683
|
-
const hasSingle =
|
|
8682
|
+
const hasDouble = value2.includes('"');
|
|
8683
|
+
const hasSingle = value2.includes("'");
|
|
8684
8684
|
if (hasDouble && !hasSingle)
|
|
8685
8685
|
qs = singleQuotedString;
|
|
8686
8686
|
else if (hasSingle && !hasDouble)
|
|
@@ -8688,7 +8688,7 @@ ${indent2}`) + "'";
|
|
|
8688
8688
|
else
|
|
8689
8689
|
qs = singleQuote ? singleQuotedString : doubleQuotedString;
|
|
8690
8690
|
}
|
|
8691
|
-
return qs(
|
|
8691
|
+
return qs(value2, ctx);
|
|
8692
8692
|
}
|
|
8693
8693
|
var blockEndNewlines;
|
|
8694
8694
|
try {
|
|
@@ -8696,27 +8696,27 @@ ${indent2}`) + "'";
|
|
|
8696
8696
|
} catch {
|
|
8697
8697
|
blockEndNewlines = /\n+(?!\n|$)/g;
|
|
8698
8698
|
}
|
|
8699
|
-
function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
|
|
8699
|
+
function blockString({ comment, type, value: value2 }, ctx, onComment, onChompKeep) {
|
|
8700
8700
|
const { blockQuote, commentString, lineWidth } = ctx.options;
|
|
8701
|
-
if (!blockQuote || /\n[\t ]+$/.test(
|
|
8702
|
-
return quotedString(
|
|
8701
|
+
if (!blockQuote || /\n[\t ]+$/.test(value2)) {
|
|
8702
|
+
return quotedString(value2, ctx);
|
|
8703
8703
|
}
|
|
8704
|
-
const indent2 = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(
|
|
8705
|
-
const literal = blockQuote === "literal" ? true : blockQuote === "folded" || type === Scalar.Scalar.BLOCK_FOLDED ? false : type === Scalar.Scalar.BLOCK_LITERAL ? true : !lineLengthOverLimit(
|
|
8706
|
-
if (!
|
|
8704
|
+
const indent2 = ctx.indent || (ctx.forceBlockIndent || containsDocumentMarker(value2) ? " " : "");
|
|
8705
|
+
const literal = blockQuote === "literal" ? true : blockQuote === "folded" || type === Scalar.Scalar.BLOCK_FOLDED ? false : type === Scalar.Scalar.BLOCK_LITERAL ? true : !lineLengthOverLimit(value2, lineWidth, indent2.length);
|
|
8706
|
+
if (!value2)
|
|
8707
8707
|
return literal ? "|\n" : ">\n";
|
|
8708
8708
|
let chomp;
|
|
8709
8709
|
let endStart;
|
|
8710
|
-
for (endStart =
|
|
8711
|
-
const ch =
|
|
8710
|
+
for (endStart = value2.length; endStart > 0; --endStart) {
|
|
8711
|
+
const ch = value2[endStart - 1];
|
|
8712
8712
|
if (ch !== "\n" && ch !== " " && ch !== " ")
|
|
8713
8713
|
break;
|
|
8714
8714
|
}
|
|
8715
|
-
let end =
|
|
8715
|
+
let end = value2.substring(endStart);
|
|
8716
8716
|
const endNlPos = end.indexOf("\n");
|
|
8717
8717
|
if (endNlPos === -1) {
|
|
8718
8718
|
chomp = "-";
|
|
8719
|
-
} else if (
|
|
8719
|
+
} else if (value2 === end || endNlPos !== end.length - 1) {
|
|
8720
8720
|
chomp = "+";
|
|
8721
8721
|
if (onChompKeep)
|
|
8722
8722
|
onChompKeep();
|
|
@@ -8724,7 +8724,7 @@ ${indent2}`) + "'";
|
|
|
8724
8724
|
chomp = "";
|
|
8725
8725
|
}
|
|
8726
8726
|
if (end) {
|
|
8727
|
-
|
|
8727
|
+
value2 = value2.slice(0, -end.length);
|
|
8728
8728
|
if (end[end.length - 1] === "\n")
|
|
8729
8729
|
end = end.slice(0, -1);
|
|
8730
8730
|
end = end.replace(blockEndNewlines, `$&${indent2}`);
|
|
@@ -8732,8 +8732,8 @@ ${indent2}`) + "'";
|
|
|
8732
8732
|
let startWithSpace = false;
|
|
8733
8733
|
let startEnd;
|
|
8734
8734
|
let startNlPos = -1;
|
|
8735
|
-
for (startEnd = 0; startEnd <
|
|
8736
|
-
const ch =
|
|
8735
|
+
for (startEnd = 0; startEnd < value2.length; ++startEnd) {
|
|
8736
|
+
const ch = value2[startEnd];
|
|
8737
8737
|
if (ch === " ")
|
|
8738
8738
|
startWithSpace = true;
|
|
8739
8739
|
else if (ch === "\n")
|
|
@@ -8741,9 +8741,9 @@ ${indent2}`) + "'";
|
|
|
8741
8741
|
else
|
|
8742
8742
|
break;
|
|
8743
8743
|
}
|
|
8744
|
-
let start =
|
|
8744
|
+
let start = value2.substring(0, startNlPos < startEnd ? startNlPos + 1 : startEnd);
|
|
8745
8745
|
if (start) {
|
|
8746
|
-
|
|
8746
|
+
value2 = value2.substring(start.length);
|
|
8747
8747
|
start = start.replace(/\n+/g, `$&${indent2}`);
|
|
8748
8748
|
}
|
|
8749
8749
|
const indentSize = indent2 ? "2" : "1";
|
|
@@ -8754,7 +8754,7 @@ ${indent2}`) + "'";
|
|
|
8754
8754
|
onComment();
|
|
8755
8755
|
}
|
|
8756
8756
|
if (!literal) {
|
|
8757
|
-
const foldedValue =
|
|
8757
|
+
const foldedValue = value2.replace(/\n+/g, "\n$&").replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, "$1$2").replace(/\n+/g, `$&${indent2}`);
|
|
8758
8758
|
let literalFallback = false;
|
|
8759
8759
|
const foldOptions = getFoldOptions(ctx, true);
|
|
8760
8760
|
if (blockQuote !== "folded" && type !== Scalar.Scalar.BLOCK_FOLDED) {
|
|
@@ -8767,37 +8767,37 @@ ${indent2}`) + "'";
|
|
|
8767
8767
|
return `>${header}
|
|
8768
8768
|
${indent2}${body}`;
|
|
8769
8769
|
}
|
|
8770
|
-
|
|
8770
|
+
value2 = value2.replace(/\n+/g, `$&${indent2}`);
|
|
8771
8771
|
return `|${header}
|
|
8772
|
-
${indent2}${start}${
|
|
8772
|
+
${indent2}${start}${value2}${end}`;
|
|
8773
8773
|
}
|
|
8774
8774
|
function plainString(item, ctx, onComment, onChompKeep) {
|
|
8775
|
-
const { type, value } = item;
|
|
8775
|
+
const { type, value: value2 } = item;
|
|
8776
8776
|
const { actualString, implicitKey, indent: indent2, indentStep, inFlow } = ctx;
|
|
8777
|
-
if (implicitKey &&
|
|
8778
|
-
return quotedString(
|
|
8777
|
+
if (implicitKey && value2.includes("\n") || inFlow && /[[\]{},]/.test(value2)) {
|
|
8778
|
+
return quotedString(value2, ctx);
|
|
8779
8779
|
}
|
|
8780
|
-
if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(
|
|
8781
|
-
return implicitKey || inFlow || !
|
|
8780
|
+
if (/^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(value2)) {
|
|
8781
|
+
return implicitKey || inFlow || !value2.includes("\n") ? quotedString(value2, ctx) : blockString(item, ctx, onComment, onChompKeep);
|
|
8782
8782
|
}
|
|
8783
|
-
if (!implicitKey && !inFlow && type !== Scalar.Scalar.PLAIN &&
|
|
8783
|
+
if (!implicitKey && !inFlow && type !== Scalar.Scalar.PLAIN && value2.includes("\n")) {
|
|
8784
8784
|
return blockString(item, ctx, onComment, onChompKeep);
|
|
8785
8785
|
}
|
|
8786
|
-
if (containsDocumentMarker(
|
|
8786
|
+
if (containsDocumentMarker(value2)) {
|
|
8787
8787
|
if (indent2 === "") {
|
|
8788
8788
|
ctx.forceBlockIndent = true;
|
|
8789
8789
|
return blockString(item, ctx, onComment, onChompKeep);
|
|
8790
8790
|
} else if (implicitKey && indent2 === indentStep) {
|
|
8791
|
-
return quotedString(
|
|
8791
|
+
return quotedString(value2, ctx);
|
|
8792
8792
|
}
|
|
8793
8793
|
}
|
|
8794
|
-
const str =
|
|
8794
|
+
const str = value2.replace(/\n+/g, `$&
|
|
8795
8795
|
${indent2}`);
|
|
8796
8796
|
if (actualString) {
|
|
8797
8797
|
const test = (tag) => tag.default && tag.tag !== "tag:yaml.org,2002:str" && tag.test?.test(str);
|
|
8798
8798
|
const { compat, tags } = ctx.doc.schema;
|
|
8799
8799
|
if (tags.some(test) || compat?.some(test))
|
|
8800
|
-
return quotedString(
|
|
8800
|
+
return quotedString(value2, ctx);
|
|
8801
8801
|
}
|
|
8802
8802
|
return implicitKey ? str : foldFlowLines.foldFlowLines(str, indent2, foldFlowLines.FOLD_FLOW, getFoldOptions(ctx, false));
|
|
8803
8803
|
}
|
|
@@ -8970,7 +8970,7 @@ var require_stringifyPair = __commonJS({
|
|
|
8970
8970
|
var Scalar = require_Scalar();
|
|
8971
8971
|
var stringify = require_stringify();
|
|
8972
8972
|
var stringifyComment = require_stringifyComment();
|
|
8973
|
-
function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
|
|
8973
|
+
function stringifyPair({ key, value: value2 }, ctx, onComment, onChompKeep) {
|
|
8974
8974
|
const { allNullValues, doc, indent: indent2, indentStep, options: { commentString, indentSeq, simpleKeys } } = ctx;
|
|
8975
8975
|
let keyComment = identity.isNode(key) && key.comment || null;
|
|
8976
8976
|
if (simpleKeys) {
|
|
@@ -8982,7 +8982,7 @@ var require_stringifyPair = __commonJS({
|
|
|
8982
8982
|
throw new Error(msg);
|
|
8983
8983
|
}
|
|
8984
8984
|
}
|
|
8985
|
-
let explicitKey = !simpleKeys && (!key || keyComment &&
|
|
8985
|
+
let explicitKey = !simpleKeys && (!key || keyComment && value2 == null && !ctx.inFlow || identity.isCollection(key) || (identity.isScalar(key) ? key.type === Scalar.Scalar.BLOCK_FOLDED || key.type === Scalar.Scalar.BLOCK_LITERAL : typeof key === "object"));
|
|
8986
8986
|
ctx = Object.assign({}, ctx, {
|
|
8987
8987
|
allNullValues: false,
|
|
8988
8988
|
implicitKey: !explicitKey && (simpleKeys || !allNullValues),
|
|
@@ -8997,12 +8997,12 @@ var require_stringifyPair = __commonJS({
|
|
|
8997
8997
|
explicitKey = true;
|
|
8998
8998
|
}
|
|
8999
8999
|
if (ctx.inFlow) {
|
|
9000
|
-
if (allNullValues ||
|
|
9000
|
+
if (allNullValues || value2 == null) {
|
|
9001
9001
|
if (keyCommentDone && onComment)
|
|
9002
9002
|
onComment();
|
|
9003
9003
|
return str === "" ? "?" : explicitKey ? `? ${str}` : str;
|
|
9004
9004
|
}
|
|
9005
|
-
} else if (allNullValues && !simpleKeys ||
|
|
9005
|
+
} else if (allNullValues && !simpleKeys || value2 == null && explicitKey) {
|
|
9006
9006
|
str = `? ${str}`;
|
|
9007
9007
|
if (keyComment && !keyCommentDone) {
|
|
9008
9008
|
str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
|
|
@@ -9023,26 +9023,26 @@ ${indent2}:`;
|
|
|
9023
9023
|
str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
|
|
9024
9024
|
}
|
|
9025
9025
|
let vsb, vcb, valueComment;
|
|
9026
|
-
if (identity.isNode(
|
|
9027
|
-
vsb = !!
|
|
9028
|
-
vcb =
|
|
9029
|
-
valueComment =
|
|
9026
|
+
if (identity.isNode(value2)) {
|
|
9027
|
+
vsb = !!value2.spaceBefore;
|
|
9028
|
+
vcb = value2.commentBefore;
|
|
9029
|
+
valueComment = value2.comment;
|
|
9030
9030
|
} else {
|
|
9031
9031
|
vsb = false;
|
|
9032
9032
|
vcb = null;
|
|
9033
9033
|
valueComment = null;
|
|
9034
|
-
if (
|
|
9035
|
-
|
|
9034
|
+
if (value2 && typeof value2 === "object")
|
|
9035
|
+
value2 = doc.createNode(value2);
|
|
9036
9036
|
}
|
|
9037
9037
|
ctx.implicitKey = false;
|
|
9038
|
-
if (!explicitKey && !keyComment && identity.isScalar(
|
|
9038
|
+
if (!explicitKey && !keyComment && identity.isScalar(value2))
|
|
9039
9039
|
ctx.indentAtStart = str.length + 1;
|
|
9040
9040
|
chompKeep = false;
|
|
9041
|
-
if (!indentSeq && indentStep.length >= 2 && !ctx.inFlow && !explicitKey && identity.isSeq(
|
|
9041
|
+
if (!indentSeq && indentStep.length >= 2 && !ctx.inFlow && !explicitKey && identity.isSeq(value2) && !value2.flow && !value2.tag && !value2.anchor) {
|
|
9042
9042
|
ctx.indent = ctx.indent.substring(2);
|
|
9043
9043
|
}
|
|
9044
9044
|
let valueCommentDone = false;
|
|
9045
|
-
const valueStr = stringify.stringify(
|
|
9045
|
+
const valueStr = stringify.stringify(value2, ctx, () => valueCommentDone = true, () => chompKeep = true);
|
|
9046
9046
|
let ws = " ";
|
|
9047
9047
|
if (keyComment || vsb || vcb) {
|
|
9048
9048
|
ws = vsb ? "\n" : "";
|
|
@@ -9058,11 +9058,11 @@ ${stringifyComment.indentComment(cs, ctx.indent)}`;
|
|
|
9058
9058
|
ws += `
|
|
9059
9059
|
${ctx.indent}`;
|
|
9060
9060
|
}
|
|
9061
|
-
} else if (!explicitKey && identity.isCollection(
|
|
9061
|
+
} else if (!explicitKey && identity.isCollection(value2)) {
|
|
9062
9062
|
const vs0 = valueStr[0];
|
|
9063
9063
|
const nl0 = valueStr.indexOf("\n");
|
|
9064
9064
|
const hasNewline = nl0 !== -1;
|
|
9065
|
-
const flow = ctx.inFlow ??
|
|
9065
|
+
const flow = ctx.inFlow ?? value2.flow ?? value2.items.length === 0;
|
|
9066
9066
|
if (hasNewline || !flow) {
|
|
9067
9067
|
let hasPropsLine = false;
|
|
9068
9068
|
if (hasNewline && (vs0 === "&" || vs0 === "!")) {
|
|
@@ -9125,7 +9125,7 @@ var require_merge = __commonJS({
|
|
|
9125
9125
|
var Scalar = require_Scalar();
|
|
9126
9126
|
var MERGE_KEY = "<<";
|
|
9127
9127
|
var merge = {
|
|
9128
|
-
identify: (
|
|
9128
|
+
identify: (value2) => value2 === MERGE_KEY || typeof value2 === "symbol" && value2.description === MERGE_KEY,
|
|
9129
9129
|
default: "key",
|
|
9130
9130
|
tag: "tag:yaml.org,2002:merge",
|
|
9131
9131
|
test: /^<<$/,
|
|
@@ -9135,8 +9135,8 @@ var require_merge = __commonJS({
|
|
|
9135
9135
|
stringify: () => MERGE_KEY
|
|
9136
9136
|
};
|
|
9137
9137
|
var isMergeKey = (ctx, key) => (merge.identify(key) || identity.isScalar(key) && (!key.type || key.type === Scalar.Scalar.PLAIN) && merge.identify(key.value)) && ctx?.doc.schema.tags.some((tag) => tag.tag === merge.tag && tag.default);
|
|
9138
|
-
function addMergeToJSMap(ctx, map,
|
|
9139
|
-
const source2 = resolveAliasValue(ctx,
|
|
9138
|
+
function addMergeToJSMap(ctx, map, value2) {
|
|
9139
|
+
const source2 = resolveAliasValue(ctx, value2);
|
|
9140
9140
|
if (identity.isSeq(source2))
|
|
9141
9141
|
for (const it of source2.items)
|
|
9142
9142
|
mergeValue(ctx, map, it);
|
|
@@ -9146,20 +9146,20 @@ var require_merge = __commonJS({
|
|
|
9146
9146
|
else
|
|
9147
9147
|
mergeValue(ctx, map, source2);
|
|
9148
9148
|
}
|
|
9149
|
-
function mergeValue(ctx, map,
|
|
9150
|
-
const source2 = resolveAliasValue(ctx,
|
|
9149
|
+
function mergeValue(ctx, map, value2) {
|
|
9150
|
+
const source2 = resolveAliasValue(ctx, value2);
|
|
9151
9151
|
if (!identity.isMap(source2))
|
|
9152
9152
|
throw new Error("Merge sources must be maps or map aliases");
|
|
9153
9153
|
const srcMap = source2.toJSON(null, ctx, Map);
|
|
9154
|
-
for (const [key,
|
|
9154
|
+
for (const [key, value3] of srcMap) {
|
|
9155
9155
|
if (map instanceof Map) {
|
|
9156
9156
|
if (!map.has(key))
|
|
9157
|
-
map.set(key,
|
|
9157
|
+
map.set(key, value3);
|
|
9158
9158
|
} else if (map instanceof Set) {
|
|
9159
9159
|
map.add(key);
|
|
9160
9160
|
} else if (!Object.prototype.hasOwnProperty.call(map, key)) {
|
|
9161
9161
|
Object.defineProperty(map, key, {
|
|
9162
|
-
value:
|
|
9162
|
+
value: value3,
|
|
9163
9163
|
writable: true,
|
|
9164
9164
|
enumerable: true,
|
|
9165
9165
|
configurable: true
|
|
@@ -9168,8 +9168,8 @@ var require_merge = __commonJS({
|
|
|
9168
9168
|
}
|
|
9169
9169
|
return map;
|
|
9170
9170
|
}
|
|
9171
|
-
function resolveAliasValue(ctx,
|
|
9172
|
-
return ctx && identity.isAlias(
|
|
9171
|
+
function resolveAliasValue(ctx, value2) {
|
|
9172
|
+
return ctx && identity.isAlias(value2) ? value2.resolve(ctx.doc, ctx) : value2;
|
|
9173
9173
|
}
|
|
9174
9174
|
exports2.addMergeToJSMap = addMergeToJSMap;
|
|
9175
9175
|
exports2.isMergeKey = isMergeKey;
|
|
@@ -9186,20 +9186,20 @@ var require_addPairToJSMap = __commonJS({
|
|
|
9186
9186
|
var stringify = require_stringify();
|
|
9187
9187
|
var identity = require_identity();
|
|
9188
9188
|
var toJS = require_toJS();
|
|
9189
|
-
function addPairToJSMap(ctx, map, { key, value }) {
|
|
9189
|
+
function addPairToJSMap(ctx, map, { key, value: value2 }) {
|
|
9190
9190
|
if (identity.isNode(key) && key.addToJSMap)
|
|
9191
|
-
key.addToJSMap(ctx, map,
|
|
9191
|
+
key.addToJSMap(ctx, map, value2);
|
|
9192
9192
|
else if (merge.isMergeKey(ctx, key))
|
|
9193
|
-
merge.addMergeToJSMap(ctx, map,
|
|
9193
|
+
merge.addMergeToJSMap(ctx, map, value2);
|
|
9194
9194
|
else {
|
|
9195
9195
|
const jsKey = toJS.toJS(key, "", ctx);
|
|
9196
9196
|
if (map instanceof Map) {
|
|
9197
|
-
map.set(jsKey, toJS.toJS(
|
|
9197
|
+
map.set(jsKey, toJS.toJS(value2, jsKey, ctx));
|
|
9198
9198
|
} else if (map instanceof Set) {
|
|
9199
9199
|
map.add(jsKey);
|
|
9200
9200
|
} else {
|
|
9201
9201
|
const stringKey = stringifyKey(key, jsKey, ctx);
|
|
9202
|
-
const jsValue = toJS.toJS(
|
|
9202
|
+
const jsValue = toJS.toJS(value2, stringKey, ctx);
|
|
9203
9203
|
if (stringKey in map)
|
|
9204
9204
|
Object.defineProperty(map, stringKey, {
|
|
9205
9205
|
value: jsValue,
|
|
@@ -9249,24 +9249,24 @@ var require_Pair = __commonJS({
|
|
|
9249
9249
|
var stringifyPair = require_stringifyPair();
|
|
9250
9250
|
var addPairToJSMap = require_addPairToJSMap();
|
|
9251
9251
|
var identity = require_identity();
|
|
9252
|
-
function createPair(key,
|
|
9252
|
+
function createPair(key, value2, ctx) {
|
|
9253
9253
|
const k = createNode.createNode(key, void 0, ctx);
|
|
9254
|
-
const v = createNode.createNode(
|
|
9254
|
+
const v = createNode.createNode(value2, void 0, ctx);
|
|
9255
9255
|
return new Pair(k, v);
|
|
9256
9256
|
}
|
|
9257
9257
|
var Pair = class _Pair {
|
|
9258
|
-
constructor(key,
|
|
9258
|
+
constructor(key, value2 = null) {
|
|
9259
9259
|
Object.defineProperty(this, identity.NODE_TYPE, { value: identity.PAIR });
|
|
9260
9260
|
this.key = key;
|
|
9261
|
-
this.value =
|
|
9261
|
+
this.value = value2;
|
|
9262
9262
|
}
|
|
9263
9263
|
clone(schema) {
|
|
9264
|
-
let { key, value } = this;
|
|
9264
|
+
let { key, value: value2 } = this;
|
|
9265
9265
|
if (identity.isNode(key))
|
|
9266
9266
|
key = key.clone(schema);
|
|
9267
|
-
if (identity.isNode(
|
|
9268
|
-
|
|
9269
|
-
return new _Pair(key,
|
|
9267
|
+
if (identity.isNode(value2))
|
|
9268
|
+
value2 = value2.clone(schema);
|
|
9269
|
+
return new _Pair(key, value2);
|
|
9270
9270
|
}
|
|
9271
9271
|
toJSON(_, ctx) {
|
|
9272
9272
|
const pair = ctx?.mapAsMap ? /* @__PURE__ */ new Map() : {};
|
|
@@ -9469,17 +9469,17 @@ var require_YAMLMap = __commonJS({
|
|
|
9469
9469
|
static from(schema, obj, ctx) {
|
|
9470
9470
|
const { keepUndefined, replacer } = ctx;
|
|
9471
9471
|
const map = new this(schema);
|
|
9472
|
-
const add = (key,
|
|
9472
|
+
const add = (key, value2) => {
|
|
9473
9473
|
if (typeof replacer === "function")
|
|
9474
|
-
|
|
9474
|
+
value2 = replacer.call(obj, key, value2);
|
|
9475
9475
|
else if (Array.isArray(replacer) && !replacer.includes(key))
|
|
9476
9476
|
return;
|
|
9477
|
-
if (
|
|
9478
|
-
map.items.push(Pair.createPair(key,
|
|
9477
|
+
if (value2 !== void 0 || keepUndefined)
|
|
9478
|
+
map.items.push(Pair.createPair(key, value2, ctx));
|
|
9479
9479
|
};
|
|
9480
9480
|
if (obj instanceof Map) {
|
|
9481
|
-
for (const [key,
|
|
9482
|
-
add(key,
|
|
9481
|
+
for (const [key, value2] of obj)
|
|
9482
|
+
add(key, value2);
|
|
9483
9483
|
} else if (obj && typeof obj === "object") {
|
|
9484
9484
|
for (const key of Object.keys(obj))
|
|
9485
9485
|
add(key, obj[key]);
|
|
@@ -9537,8 +9537,8 @@ var require_YAMLMap = __commonJS({
|
|
|
9537
9537
|
has(key) {
|
|
9538
9538
|
return !!findPair(this.items, key);
|
|
9539
9539
|
}
|
|
9540
|
-
set(key,
|
|
9541
|
-
this.add(new Pair.Pair(key,
|
|
9540
|
+
set(key, value2) {
|
|
9541
|
+
this.add(new Pair.Pair(key, value2), true);
|
|
9542
9542
|
}
|
|
9543
9543
|
/**
|
|
9544
9544
|
* @param ctx - Conversion context, originally set in Document#toJS()
|
|
@@ -9616,8 +9616,8 @@ var require_YAMLSeq = __commonJS({
|
|
|
9616
9616
|
super(identity.SEQ, schema);
|
|
9617
9617
|
this.items = [];
|
|
9618
9618
|
}
|
|
9619
|
-
add(
|
|
9620
|
-
this.items.push(
|
|
9619
|
+
add(value2) {
|
|
9620
|
+
this.items.push(value2);
|
|
9621
9621
|
}
|
|
9622
9622
|
/**
|
|
9623
9623
|
* Removes a value from the collection.
|
|
@@ -9658,15 +9658,15 @@ var require_YAMLSeq = __commonJS({
|
|
|
9658
9658
|
* If `key` does not contain a representation of an integer, this will throw.
|
|
9659
9659
|
* It may be wrapped in a `Scalar`.
|
|
9660
9660
|
*/
|
|
9661
|
-
set(key,
|
|
9661
|
+
set(key, value2) {
|
|
9662
9662
|
const idx = asItemIndex(key);
|
|
9663
9663
|
if (typeof idx !== "number")
|
|
9664
9664
|
throw new Error(`Expected a valid index, not ${key}.`);
|
|
9665
9665
|
const prev = this.items[idx];
|
|
9666
|
-
if (identity.isScalar(prev) && Scalar.isScalarValue(
|
|
9667
|
-
prev.value =
|
|
9666
|
+
if (identity.isScalar(prev) && Scalar.isScalarValue(value2))
|
|
9667
|
+
prev.value = value2;
|
|
9668
9668
|
else
|
|
9669
|
-
this.items[idx] =
|
|
9669
|
+
this.items[idx] = value2;
|
|
9670
9670
|
}
|
|
9671
9671
|
toJSON(_, ctx) {
|
|
9672
9672
|
const seq = [];
|
|
@@ -9742,7 +9742,7 @@ var require_string = __commonJS({
|
|
|
9742
9742
|
"use strict";
|
|
9743
9743
|
var stringifyString = require_stringifyString();
|
|
9744
9744
|
var string = {
|
|
9745
|
-
identify: (
|
|
9745
|
+
identify: (value2) => typeof value2 === "string",
|
|
9746
9746
|
default: true,
|
|
9747
9747
|
tag: "tag:yaml.org,2002:str",
|
|
9748
9748
|
resolve: (str) => str,
|
|
@@ -9761,7 +9761,7 @@ var require_null = __commonJS({
|
|
|
9761
9761
|
"use strict";
|
|
9762
9762
|
var Scalar = require_Scalar();
|
|
9763
9763
|
var nullTag = {
|
|
9764
|
-
identify: (
|
|
9764
|
+
identify: (value2) => value2 == null,
|
|
9765
9765
|
createNode: () => new Scalar.Scalar(null),
|
|
9766
9766
|
default: true,
|
|
9767
9767
|
tag: "tag:yaml.org,2002:null",
|
|
@@ -9779,18 +9779,18 @@ var require_bool = __commonJS({
|
|
|
9779
9779
|
"use strict";
|
|
9780
9780
|
var Scalar = require_Scalar();
|
|
9781
9781
|
var boolTag = {
|
|
9782
|
-
identify: (
|
|
9782
|
+
identify: (value2) => typeof value2 === "boolean",
|
|
9783
9783
|
default: true,
|
|
9784
9784
|
tag: "tag:yaml.org,2002:bool",
|
|
9785
9785
|
test: /^(?:[Tt]rue|TRUE|[Ff]alse|FALSE)$/,
|
|
9786
9786
|
resolve: (str) => new Scalar.Scalar(str[0] === "t" || str[0] === "T"),
|
|
9787
|
-
stringify({ source: source2, value }, ctx) {
|
|
9787
|
+
stringify({ source: source2, value: value2 }, ctx) {
|
|
9788
9788
|
if (source2 && boolTag.test.test(source2)) {
|
|
9789
9789
|
const sv = source2[0] === "t" || source2[0] === "T";
|
|
9790
|
-
if (
|
|
9790
|
+
if (value2 === sv)
|
|
9791
9791
|
return source2;
|
|
9792
9792
|
}
|
|
9793
|
-
return
|
|
9793
|
+
return value2 ? ctx.options.trueStr : ctx.options.falseStr;
|
|
9794
9794
|
}
|
|
9795
9795
|
};
|
|
9796
9796
|
exports2.boolTag = boolTag;
|
|
@@ -9801,13 +9801,13 @@ var require_bool = __commonJS({
|
|
|
9801
9801
|
var require_stringifyNumber = __commonJS({
|
|
9802
9802
|
"node_modules/yaml/dist/stringify/stringifyNumber.js"(exports2) {
|
|
9803
9803
|
"use strict";
|
|
9804
|
-
function stringifyNumber({ format: format3, minFractionDigits, tag, value }) {
|
|
9805
|
-
if (typeof
|
|
9806
|
-
return String(
|
|
9807
|
-
const num = typeof
|
|
9804
|
+
function stringifyNumber({ format: format3, minFractionDigits, tag, value: value2 }) {
|
|
9805
|
+
if (typeof value2 === "bigint")
|
|
9806
|
+
return String(value2);
|
|
9807
|
+
const num = typeof value2 === "number" ? value2 : Number(value2);
|
|
9808
9808
|
if (!isFinite(num))
|
|
9809
9809
|
return isNaN(num) ? ".nan" : num < 0 ? "-.inf" : ".inf";
|
|
9810
|
-
let n = Object.is(
|
|
9810
|
+
let n = Object.is(value2, -0) ? "-0" : JSON.stringify(value2);
|
|
9811
9811
|
if (!format3 && minFractionDigits && (!tag || tag === "tag:yaml.org,2002:float") && /^-?\d/.test(n) && !n.includes("e")) {
|
|
9812
9812
|
let i = n.indexOf(".");
|
|
9813
9813
|
if (i < 0) {
|
|
@@ -9831,7 +9831,7 @@ var require_float = __commonJS({
|
|
|
9831
9831
|
var Scalar = require_Scalar();
|
|
9832
9832
|
var stringifyNumber = require_stringifyNumber();
|
|
9833
9833
|
var floatNaN = {
|
|
9834
|
-
identify: (
|
|
9834
|
+
identify: (value2) => typeof value2 === "number",
|
|
9835
9835
|
default: true,
|
|
9836
9836
|
tag: "tag:yaml.org,2002:float",
|
|
9837
9837
|
test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
|
|
@@ -9839,7 +9839,7 @@ var require_float = __commonJS({
|
|
|
9839
9839
|
stringify: stringifyNumber.stringifyNumber
|
|
9840
9840
|
};
|
|
9841
9841
|
var floatExp = {
|
|
9842
|
-
identify: (
|
|
9842
|
+
identify: (value2) => typeof value2 === "number",
|
|
9843
9843
|
default: true,
|
|
9844
9844
|
tag: "tag:yaml.org,2002:float",
|
|
9845
9845
|
format: "EXP",
|
|
@@ -9851,7 +9851,7 @@ var require_float = __commonJS({
|
|
|
9851
9851
|
}
|
|
9852
9852
|
};
|
|
9853
9853
|
var float = {
|
|
9854
|
-
identify: (
|
|
9854
|
+
identify: (value2) => typeof value2 === "number",
|
|
9855
9855
|
default: true,
|
|
9856
9856
|
tag: "tag:yaml.org,2002:float",
|
|
9857
9857
|
test: /^[-+]?(?:\.[0-9]+|[0-9]+\.[0-9]*)$/,
|
|
@@ -9875,16 +9875,16 @@ var require_int = __commonJS({
|
|
|
9875
9875
|
"node_modules/yaml/dist/schema/core/int.js"(exports2) {
|
|
9876
9876
|
"use strict";
|
|
9877
9877
|
var stringifyNumber = require_stringifyNumber();
|
|
9878
|
-
var intIdentify = (
|
|
9878
|
+
var intIdentify = (value2) => typeof value2 === "bigint" || Number.isInteger(value2);
|
|
9879
9879
|
var intResolve = (str, offset, radix, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str.substring(offset), radix);
|
|
9880
9880
|
function intStringify(node, radix, prefix) {
|
|
9881
|
-
const { value } = node;
|
|
9882
|
-
if (intIdentify(
|
|
9883
|
-
return prefix +
|
|
9881
|
+
const { value: value2 } = node;
|
|
9882
|
+
if (intIdentify(value2) && value2 >= 0)
|
|
9883
|
+
return prefix + value2.toString(radix);
|
|
9884
9884
|
return stringifyNumber.stringifyNumber(node);
|
|
9885
9885
|
}
|
|
9886
9886
|
var intOct = {
|
|
9887
|
-
identify: (
|
|
9887
|
+
identify: (value2) => intIdentify(value2) && value2 >= 0,
|
|
9888
9888
|
default: true,
|
|
9889
9889
|
tag: "tag:yaml.org,2002:int",
|
|
9890
9890
|
format: "OCT",
|
|
@@ -9901,7 +9901,7 @@ var require_int = __commonJS({
|
|
|
9901
9901
|
stringify: stringifyNumber.stringifyNumber
|
|
9902
9902
|
};
|
|
9903
9903
|
var intHex = {
|
|
9904
|
-
identify: (
|
|
9904
|
+
identify: (value2) => intIdentify(value2) && value2 >= 0,
|
|
9905
9905
|
default: true,
|
|
9906
9906
|
tag: "tag:yaml.org,2002:int",
|
|
9907
9907
|
format: "HEX",
|
|
@@ -9950,20 +9950,20 @@ var require_schema3 = __commonJS({
|
|
|
9950
9950
|
var Scalar = require_Scalar();
|
|
9951
9951
|
var map = require_map();
|
|
9952
9952
|
var seq = require_seq();
|
|
9953
|
-
function intIdentify(
|
|
9954
|
-
return typeof
|
|
9953
|
+
function intIdentify(value2) {
|
|
9954
|
+
return typeof value2 === "bigint" || Number.isInteger(value2);
|
|
9955
9955
|
}
|
|
9956
|
-
var stringifyJSON = ({ value }) => JSON.stringify(
|
|
9956
|
+
var stringifyJSON = ({ value: value2 }) => JSON.stringify(value2);
|
|
9957
9957
|
var jsonScalars = [
|
|
9958
9958
|
{
|
|
9959
|
-
identify: (
|
|
9959
|
+
identify: (value2) => typeof value2 === "string",
|
|
9960
9960
|
default: true,
|
|
9961
9961
|
tag: "tag:yaml.org,2002:str",
|
|
9962
9962
|
resolve: (str) => str,
|
|
9963
9963
|
stringify: stringifyJSON
|
|
9964
9964
|
},
|
|
9965
9965
|
{
|
|
9966
|
-
identify: (
|
|
9966
|
+
identify: (value2) => value2 == null,
|
|
9967
9967
|
createNode: () => new Scalar.Scalar(null),
|
|
9968
9968
|
default: true,
|
|
9969
9969
|
tag: "tag:yaml.org,2002:null",
|
|
@@ -9972,7 +9972,7 @@ var require_schema3 = __commonJS({
|
|
|
9972
9972
|
stringify: stringifyJSON
|
|
9973
9973
|
},
|
|
9974
9974
|
{
|
|
9975
|
-
identify: (
|
|
9975
|
+
identify: (value2) => typeof value2 === "boolean",
|
|
9976
9976
|
default: true,
|
|
9977
9977
|
tag: "tag:yaml.org,2002:bool",
|
|
9978
9978
|
test: /^true$|^false$/,
|
|
@@ -9985,10 +9985,10 @@ var require_schema3 = __commonJS({
|
|
|
9985
9985
|
tag: "tag:yaml.org,2002:int",
|
|
9986
9986
|
test: /^-?(?:0|[1-9][0-9]*)$/,
|
|
9987
9987
|
resolve: (str, _onError, { intAsBigInt }) => intAsBigInt ? BigInt(str) : parseInt(str, 10),
|
|
9988
|
-
stringify: ({ value }) => intIdentify(
|
|
9988
|
+
stringify: ({ value: value2 }) => intIdentify(value2) ? value2.toString() : JSON.stringify(value2)
|
|
9989
9989
|
},
|
|
9990
9990
|
{
|
|
9991
|
-
identify: (
|
|
9991
|
+
identify: (value2) => typeof value2 === "number",
|
|
9992
9992
|
default: true,
|
|
9993
9993
|
tag: "tag:yaml.org,2002:float",
|
|
9994
9994
|
test: /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]*)?(?:[eE][-+]?[0-9]+)?$/,
|
|
@@ -10018,7 +10018,7 @@ var require_binary = __commonJS({
|
|
|
10018
10018
|
var Scalar = require_Scalar();
|
|
10019
10019
|
var stringifyString = require_stringifyString();
|
|
10020
10020
|
var binary = {
|
|
10021
|
-
identify: (
|
|
10021
|
+
identify: (value2) => value2 instanceof Uint8Array,
|
|
10022
10022
|
// Buffer inherits from Uint8Array
|
|
10023
10023
|
default: false,
|
|
10024
10024
|
tag: "tag:yaml.org,2002:binary",
|
|
@@ -10044,10 +10044,10 @@ var require_binary = __commonJS({
|
|
|
10044
10044
|
return src;
|
|
10045
10045
|
}
|
|
10046
10046
|
},
|
|
10047
|
-
stringify({ comment, type, value }, ctx, onComment, onChompKeep) {
|
|
10048
|
-
if (!
|
|
10047
|
+
stringify({ comment, type, value: value2 }, ctx, onComment, onChompKeep) {
|
|
10048
|
+
if (!value2)
|
|
10049
10049
|
return "";
|
|
10050
|
-
const buf =
|
|
10050
|
+
const buf = value2;
|
|
10051
10051
|
let str;
|
|
10052
10052
|
if (typeof node_buffer.Buffer === "function") {
|
|
10053
10053
|
str = buf instanceof node_buffer.Buffer ? buf.toString("base64") : node_buffer.Buffer.from(buf.buffer).toString("base64");
|
|
@@ -10119,25 +10119,25 @@ ${cn.comment}` : item.comment;
|
|
|
10119
10119
|
for (let it of iterable) {
|
|
10120
10120
|
if (typeof replacer === "function")
|
|
10121
10121
|
it = replacer.call(iterable, String(i++), it);
|
|
10122
|
-
let key,
|
|
10122
|
+
let key, value2;
|
|
10123
10123
|
if (Array.isArray(it)) {
|
|
10124
10124
|
if (it.length === 2) {
|
|
10125
10125
|
key = it[0];
|
|
10126
|
-
|
|
10126
|
+
value2 = it[1];
|
|
10127
10127
|
} else
|
|
10128
10128
|
throw new TypeError(`Expected [key, value] tuple: ${it}`);
|
|
10129
10129
|
} else if (it && it instanceof Object) {
|
|
10130
10130
|
const keys = Object.keys(it);
|
|
10131
10131
|
if (keys.length === 1) {
|
|
10132
10132
|
key = keys[0];
|
|
10133
|
-
|
|
10133
|
+
value2 = it[key];
|
|
10134
10134
|
} else {
|
|
10135
10135
|
throw new TypeError(`Expected tuple with one key, not ${keys.length} keys`);
|
|
10136
10136
|
}
|
|
10137
10137
|
} else {
|
|
10138
10138
|
key = it;
|
|
10139
10139
|
}
|
|
10140
|
-
pairs2.items.push(Pair.createPair(key,
|
|
10140
|
+
pairs2.items.push(Pair.createPair(key, value2, ctx));
|
|
10141
10141
|
}
|
|
10142
10142
|
return pairs2;
|
|
10143
10143
|
}
|
|
@@ -10184,16 +10184,16 @@ var require_omap = __commonJS({
|
|
|
10184
10184
|
if (ctx?.onCreate)
|
|
10185
10185
|
ctx.onCreate(map);
|
|
10186
10186
|
for (const pair of this.items) {
|
|
10187
|
-
let key,
|
|
10187
|
+
let key, value2;
|
|
10188
10188
|
if (identity.isPair(pair)) {
|
|
10189
10189
|
key = toJS.toJS(pair.key, "", ctx);
|
|
10190
|
-
|
|
10190
|
+
value2 = toJS.toJS(pair.value, key, ctx);
|
|
10191
10191
|
} else {
|
|
10192
10192
|
key = toJS.toJS(pair, "", ctx);
|
|
10193
10193
|
}
|
|
10194
10194
|
if (map.has(key))
|
|
10195
10195
|
throw new Error("Ordered maps must not include duplicate keys");
|
|
10196
|
-
map.set(key,
|
|
10196
|
+
map.set(key, value2);
|
|
10197
10197
|
}
|
|
10198
10198
|
return map;
|
|
10199
10199
|
}
|
|
@@ -10207,7 +10207,7 @@ var require_omap = __commonJS({
|
|
|
10207
10207
|
YAMLOMap.tag = "tag:yaml.org,2002:omap";
|
|
10208
10208
|
var omap = {
|
|
10209
10209
|
collection: "seq",
|
|
10210
|
-
identify: (
|
|
10210
|
+
identify: (value2) => value2 instanceof Map,
|
|
10211
10211
|
nodeClass: YAMLOMap,
|
|
10212
10212
|
default: false,
|
|
10213
10213
|
tag: "tag:yaml.org,2002:omap",
|
|
@@ -10237,14 +10237,14 @@ var require_bool2 = __commonJS({
|
|
|
10237
10237
|
"node_modules/yaml/dist/schema/yaml-1.1/bool.js"(exports2) {
|
|
10238
10238
|
"use strict";
|
|
10239
10239
|
var Scalar = require_Scalar();
|
|
10240
|
-
function boolStringify({ value, source: source2 }, ctx) {
|
|
10241
|
-
const boolObj =
|
|
10240
|
+
function boolStringify({ value: value2, source: source2 }, ctx) {
|
|
10241
|
+
const boolObj = value2 ? trueTag : falseTag;
|
|
10242
10242
|
if (source2 && boolObj.test.test(source2))
|
|
10243
10243
|
return source2;
|
|
10244
|
-
return
|
|
10244
|
+
return value2 ? ctx.options.trueStr : ctx.options.falseStr;
|
|
10245
10245
|
}
|
|
10246
10246
|
var trueTag = {
|
|
10247
|
-
identify: (
|
|
10247
|
+
identify: (value2) => value2 === true,
|
|
10248
10248
|
default: true,
|
|
10249
10249
|
tag: "tag:yaml.org,2002:bool",
|
|
10250
10250
|
test: /^(?:Y|y|[Yy]es|YES|[Tt]rue|TRUE|[Oo]n|ON)$/,
|
|
@@ -10252,7 +10252,7 @@ var require_bool2 = __commonJS({
|
|
|
10252
10252
|
stringify: boolStringify
|
|
10253
10253
|
};
|
|
10254
10254
|
var falseTag = {
|
|
10255
|
-
identify: (
|
|
10255
|
+
identify: (value2) => value2 === false,
|
|
10256
10256
|
default: true,
|
|
10257
10257
|
tag: "tag:yaml.org,2002:bool",
|
|
10258
10258
|
test: /^(?:N|n|[Nn]o|NO|[Ff]alse|FALSE|[Oo]ff|OFF)$/,
|
|
@@ -10271,7 +10271,7 @@ var require_float2 = __commonJS({
|
|
|
10271
10271
|
var Scalar = require_Scalar();
|
|
10272
10272
|
var stringifyNumber = require_stringifyNumber();
|
|
10273
10273
|
var floatNaN = {
|
|
10274
|
-
identify: (
|
|
10274
|
+
identify: (value2) => typeof value2 === "number",
|
|
10275
10275
|
default: true,
|
|
10276
10276
|
tag: "tag:yaml.org,2002:float",
|
|
10277
10277
|
test: /^(?:[-+]?\.(?:inf|Inf|INF)|\.nan|\.NaN|\.NAN)$/,
|
|
@@ -10279,7 +10279,7 @@ var require_float2 = __commonJS({
|
|
|
10279
10279
|
stringify: stringifyNumber.stringifyNumber
|
|
10280
10280
|
};
|
|
10281
10281
|
var floatExp = {
|
|
10282
|
-
identify: (
|
|
10282
|
+
identify: (value2) => typeof value2 === "number",
|
|
10283
10283
|
default: true,
|
|
10284
10284
|
tag: "tag:yaml.org,2002:float",
|
|
10285
10285
|
format: "EXP",
|
|
@@ -10291,7 +10291,7 @@ var require_float2 = __commonJS({
|
|
|
10291
10291
|
}
|
|
10292
10292
|
};
|
|
10293
10293
|
var float = {
|
|
10294
|
-
identify: (
|
|
10294
|
+
identify: (value2) => typeof value2 === "number",
|
|
10295
10295
|
default: true,
|
|
10296
10296
|
tag: "tag:yaml.org,2002:float",
|
|
10297
10297
|
test: /^[-+]?(?:[0-9][0-9_]*)?\.[0-9_]*$/,
|
|
@@ -10318,7 +10318,7 @@ var require_int2 = __commonJS({
|
|
|
10318
10318
|
"node_modules/yaml/dist/schema/yaml-1.1/int.js"(exports2) {
|
|
10319
10319
|
"use strict";
|
|
10320
10320
|
var stringifyNumber = require_stringifyNumber();
|
|
10321
|
-
var intIdentify = (
|
|
10321
|
+
var intIdentify = (value2) => typeof value2 === "bigint" || Number.isInteger(value2);
|
|
10322
10322
|
function intResolve(str, offset, radix, { intAsBigInt }) {
|
|
10323
10323
|
const sign = str[0];
|
|
10324
10324
|
if (sign === "-" || sign === "+")
|
|
@@ -10343,10 +10343,10 @@ var require_int2 = __commonJS({
|
|
|
10343
10343
|
return sign === "-" ? -1 * n : n;
|
|
10344
10344
|
}
|
|
10345
10345
|
function intStringify(node, radix, prefix) {
|
|
10346
|
-
const { value } = node;
|
|
10347
|
-
if (intIdentify(
|
|
10348
|
-
const str =
|
|
10349
|
-
return
|
|
10346
|
+
const { value: value2 } = node;
|
|
10347
|
+
if (intIdentify(value2)) {
|
|
10348
|
+
const str = value2.toString(radix);
|
|
10349
|
+
return value2 < 0 ? "-" + prefix + str.substr(1) : prefix + str;
|
|
10350
10350
|
}
|
|
10351
10351
|
return stringifyNumber.stringifyNumber(node);
|
|
10352
10352
|
}
|
|
@@ -10424,13 +10424,13 @@ var require_set = __commonJS({
|
|
|
10424
10424
|
const pair = YAMLMap.findPair(this.items, key);
|
|
10425
10425
|
return !keepPair && identity.isPair(pair) ? identity.isScalar(pair.key) ? pair.key.value : pair.key : pair;
|
|
10426
10426
|
}
|
|
10427
|
-
set(key,
|
|
10428
|
-
if (typeof
|
|
10429
|
-
throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof
|
|
10427
|
+
set(key, value2) {
|
|
10428
|
+
if (typeof value2 !== "boolean")
|
|
10429
|
+
throw new Error(`Expected boolean value for set(key, value) in a YAML set, not ${typeof value2}`);
|
|
10430
10430
|
const prev = YAMLMap.findPair(this.items, key);
|
|
10431
|
-
if (prev && !
|
|
10431
|
+
if (prev && !value2) {
|
|
10432
10432
|
this.items.splice(this.items.indexOf(prev), 1);
|
|
10433
|
-
} else if (!prev &&
|
|
10433
|
+
} else if (!prev && value2) {
|
|
10434
10434
|
this.items.push(new Pair.Pair(key));
|
|
10435
10435
|
}
|
|
10436
10436
|
}
|
|
@@ -10449,10 +10449,10 @@ var require_set = __commonJS({
|
|
|
10449
10449
|
const { replacer } = ctx;
|
|
10450
10450
|
const set2 = new this(schema);
|
|
10451
10451
|
if (iterable && Symbol.iterator in Object(iterable))
|
|
10452
|
-
for (let
|
|
10452
|
+
for (let value2 of iterable) {
|
|
10453
10453
|
if (typeof replacer === "function")
|
|
10454
|
-
|
|
10455
|
-
set2.items.push(Pair.createPair(
|
|
10454
|
+
value2 = replacer.call(iterable, value2, value2);
|
|
10455
|
+
set2.items.push(Pair.createPair(value2, null, ctx));
|
|
10456
10456
|
}
|
|
10457
10457
|
return set2;
|
|
10458
10458
|
}
|
|
@@ -10460,7 +10460,7 @@ var require_set = __commonJS({
|
|
|
10460
10460
|
YAMLSet.tag = "tag:yaml.org,2002:set";
|
|
10461
10461
|
var set = {
|
|
10462
10462
|
collection: "map",
|
|
10463
|
-
identify: (
|
|
10463
|
+
identify: (value2) => value2 instanceof Set,
|
|
10464
10464
|
nodeClass: YAMLSet,
|
|
10465
10465
|
default: false,
|
|
10466
10466
|
tag: "tag:yaml.org,2002:set",
|
|
@@ -10494,33 +10494,33 @@ var require_timestamp = __commonJS({
|
|
|
10494
10494
|
return sign === "-" ? num(-1) * res : res;
|
|
10495
10495
|
}
|
|
10496
10496
|
function stringifySexagesimal(node) {
|
|
10497
|
-
let { value } = node;
|
|
10497
|
+
let { value: value2 } = node;
|
|
10498
10498
|
let num = (n) => n;
|
|
10499
|
-
if (typeof
|
|
10499
|
+
if (typeof value2 === "bigint")
|
|
10500
10500
|
num = (n) => BigInt(n);
|
|
10501
|
-
else if (isNaN(
|
|
10501
|
+
else if (isNaN(value2) || !isFinite(value2))
|
|
10502
10502
|
return stringifyNumber.stringifyNumber(node);
|
|
10503
10503
|
let sign = "";
|
|
10504
|
-
if (
|
|
10504
|
+
if (value2 < 0) {
|
|
10505
10505
|
sign = "-";
|
|
10506
|
-
|
|
10506
|
+
value2 *= num(-1);
|
|
10507
10507
|
}
|
|
10508
10508
|
const _60 = num(60);
|
|
10509
|
-
const parts = [
|
|
10510
|
-
if (
|
|
10509
|
+
const parts = [value2 % _60];
|
|
10510
|
+
if (value2 < 60) {
|
|
10511
10511
|
parts.unshift(0);
|
|
10512
10512
|
} else {
|
|
10513
|
-
|
|
10514
|
-
parts.unshift(
|
|
10515
|
-
if (
|
|
10516
|
-
|
|
10517
|
-
parts.unshift(
|
|
10513
|
+
value2 = (value2 - parts[0]) / _60;
|
|
10514
|
+
parts.unshift(value2 % _60);
|
|
10515
|
+
if (value2 >= 60) {
|
|
10516
|
+
value2 = (value2 - parts[0]) / _60;
|
|
10517
|
+
parts.unshift(value2);
|
|
10518
10518
|
}
|
|
10519
10519
|
}
|
|
10520
10520
|
return sign + parts.map((n) => String(n).padStart(2, "0")).join(":").replace(/000000\d*$/, "");
|
|
10521
10521
|
}
|
|
10522
10522
|
var intTime = {
|
|
10523
|
-
identify: (
|
|
10523
|
+
identify: (value2) => typeof value2 === "bigint" || Number.isInteger(value2),
|
|
10524
10524
|
default: true,
|
|
10525
10525
|
tag: "tag:yaml.org,2002:int",
|
|
10526
10526
|
format: "TIME",
|
|
@@ -10529,7 +10529,7 @@ var require_timestamp = __commonJS({
|
|
|
10529
10529
|
stringify: stringifySexagesimal
|
|
10530
10530
|
};
|
|
10531
10531
|
var floatTime = {
|
|
10532
|
-
identify: (
|
|
10532
|
+
identify: (value2) => typeof value2 === "number",
|
|
10533
10533
|
default: true,
|
|
10534
10534
|
tag: "tag:yaml.org,2002:float",
|
|
10535
10535
|
format: "TIME",
|
|
@@ -10538,7 +10538,7 @@ var require_timestamp = __commonJS({
|
|
|
10538
10538
|
stringify: stringifySexagesimal
|
|
10539
10539
|
};
|
|
10540
10540
|
var timestamp = {
|
|
10541
|
-
identify: (
|
|
10541
|
+
identify: (value2) => value2 instanceof Date,
|
|
10542
10542
|
default: true,
|
|
10543
10543
|
tag: "tag:yaml.org,2002:timestamp",
|
|
10544
10544
|
// If the time zone is omitted, the timestamp is assumed to be specified in UTC. The time part
|
|
@@ -10551,17 +10551,17 @@ var require_timestamp = __commonJS({
|
|
|
10551
10551
|
throw new Error("!!timestamp expects a date, starting with yyyy-mm-dd");
|
|
10552
10552
|
const [, year, month, day, hour, minute, second] = match.map(Number);
|
|
10553
10553
|
const millisec = match[7] ? Number((match[7] + "00").substr(1, 3)) : 0;
|
|
10554
|
-
let
|
|
10554
|
+
let date2 = Date.UTC(year, month - 1, day, hour || 0, minute || 0, second || 0, millisec);
|
|
10555
10555
|
const tz = match[8];
|
|
10556
10556
|
if (tz && tz !== "Z") {
|
|
10557
10557
|
let d = parseSexagesimal(tz, false);
|
|
10558
10558
|
if (Math.abs(d) < 30)
|
|
10559
10559
|
d *= 60;
|
|
10560
|
-
|
|
10560
|
+
date2 -= 6e4 * d;
|
|
10561
10561
|
}
|
|
10562
|
-
return new Date(
|
|
10562
|
+
return new Date(date2);
|
|
10563
10563
|
},
|
|
10564
|
-
stringify: ({ value }) =>
|
|
10564
|
+
stringify: ({ value: value2 }) => value2?.toISOString().replace(/(T00:00:00)?\.000Z$/, "") ?? ""
|
|
10565
10565
|
};
|
|
10566
10566
|
exports2.floatTime = floatTime;
|
|
10567
10567
|
exports2.intTime = intTime;
|
|
@@ -10835,7 +10835,7 @@ var require_Document = __commonJS({
|
|
|
10835
10835
|
var createNode = require_createNode();
|
|
10836
10836
|
var directives = require_directives();
|
|
10837
10837
|
var Document = class _Document {
|
|
10838
|
-
constructor(
|
|
10838
|
+
constructor(value2, replacer, options) {
|
|
10839
10839
|
this.commentBefore = null;
|
|
10840
10840
|
this.comment = null;
|
|
10841
10841
|
this.errors = [];
|
|
@@ -10867,7 +10867,7 @@ var require_Document = __commonJS({
|
|
|
10867
10867
|
} else
|
|
10868
10868
|
this.directives = new directives.Directives({ version });
|
|
10869
10869
|
this.setSchema(version, options);
|
|
10870
|
-
this.contents =
|
|
10870
|
+
this.contents = value2 === void 0 ? null : this.createNode(value2, _replacer, options);
|
|
10871
10871
|
}
|
|
10872
10872
|
/**
|
|
10873
10873
|
* Create a deep copy of this Document and its contents.
|
|
@@ -10892,14 +10892,14 @@ var require_Document = __commonJS({
|
|
|
10892
10892
|
return copy;
|
|
10893
10893
|
}
|
|
10894
10894
|
/** Adds a value to the document. */
|
|
10895
|
-
add(
|
|
10895
|
+
add(value2) {
|
|
10896
10896
|
if (assertCollection(this.contents))
|
|
10897
|
-
this.contents.add(
|
|
10897
|
+
this.contents.add(value2);
|
|
10898
10898
|
}
|
|
10899
10899
|
/** Adds a value to the document. */
|
|
10900
|
-
addIn(path,
|
|
10900
|
+
addIn(path, value2) {
|
|
10901
10901
|
if (assertCollection(this.contents))
|
|
10902
|
-
this.contents.addIn(path,
|
|
10902
|
+
this.contents.addIn(path, value2);
|
|
10903
10903
|
}
|
|
10904
10904
|
/**
|
|
10905
10905
|
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
|
@@ -10918,10 +10918,10 @@ var require_Document = __commonJS({
|
|
|
10918
10918
|
}
|
|
10919
10919
|
return new Alias.Alias(node.anchor);
|
|
10920
10920
|
}
|
|
10921
|
-
createNode(
|
|
10921
|
+
createNode(value2, replacer, options) {
|
|
10922
10922
|
let _replacer = void 0;
|
|
10923
10923
|
if (typeof replacer === "function") {
|
|
10924
|
-
|
|
10924
|
+
value2 = replacer.call({ "": value2 }, "", value2);
|
|
10925
10925
|
_replacer = replacer;
|
|
10926
10926
|
} else if (Array.isArray(replacer)) {
|
|
10927
10927
|
const keyToStr = (v) => typeof v === "number" || v instanceof String || v instanceof Number;
|
|
@@ -10948,7 +10948,7 @@ var require_Document = __commonJS({
|
|
|
10948
10948
|
schema: this.schema,
|
|
10949
10949
|
sourceObjects
|
|
10950
10950
|
};
|
|
10951
|
-
const node = createNode.createNode(
|
|
10951
|
+
const node = createNode.createNode(value2, tag, ctx);
|
|
10952
10952
|
if (flow && identity.isCollection(node))
|
|
10953
10953
|
node.flow = true;
|
|
10954
10954
|
setAnchors();
|
|
@@ -10958,9 +10958,9 @@ var require_Document = __commonJS({
|
|
|
10958
10958
|
* Convert a key and a value into a `Pair` using the current schema,
|
|
10959
10959
|
* recursively wrapping all values as `Scalar` or `Collection` nodes.
|
|
10960
10960
|
*/
|
|
10961
|
-
createPair(key,
|
|
10961
|
+
createPair(key, value2, options = {}) {
|
|
10962
10962
|
const k = this.createNode(key, null, options);
|
|
10963
|
-
const v = this.createNode(
|
|
10963
|
+
const v = this.createNode(value2, null, options);
|
|
10964
10964
|
return new Pair.Pair(k, v);
|
|
10965
10965
|
}
|
|
10966
10966
|
/**
|
|
@@ -11019,24 +11019,24 @@ var require_Document = __commonJS({
|
|
|
11019
11019
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
11020
11020
|
* boolean to add/remove the item from the set.
|
|
11021
11021
|
*/
|
|
11022
|
-
set(key,
|
|
11022
|
+
set(key, value2) {
|
|
11023
11023
|
if (this.contents == null) {
|
|
11024
|
-
this.contents = Collection.collectionFromPath(this.schema, [key],
|
|
11024
|
+
this.contents = Collection.collectionFromPath(this.schema, [key], value2);
|
|
11025
11025
|
} else if (assertCollection(this.contents)) {
|
|
11026
|
-
this.contents.set(key,
|
|
11026
|
+
this.contents.set(key, value2);
|
|
11027
11027
|
}
|
|
11028
11028
|
}
|
|
11029
11029
|
/**
|
|
11030
11030
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
11031
11031
|
* boolean to add/remove the item from the set.
|
|
11032
11032
|
*/
|
|
11033
|
-
setIn(path,
|
|
11033
|
+
setIn(path, value2) {
|
|
11034
11034
|
if (Collection.isEmptyPath(path)) {
|
|
11035
|
-
this.contents =
|
|
11035
|
+
this.contents = value2;
|
|
11036
11036
|
} else if (this.contents == null) {
|
|
11037
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(path),
|
|
11037
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path), value2);
|
|
11038
11038
|
} else if (assertCollection(this.contents)) {
|
|
11039
|
-
this.contents.setIn(path,
|
|
11039
|
+
this.contents.setIn(path, value2);
|
|
11040
11040
|
}
|
|
11041
11041
|
}
|
|
11042
11042
|
/**
|
|
@@ -11422,7 +11422,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
11422
11422
|
let offset = bm.offset;
|
|
11423
11423
|
let commentEnd = null;
|
|
11424
11424
|
for (const collItem of bm.items) {
|
|
11425
|
-
const { start, key, sep: sep2, value } = collItem;
|
|
11425
|
+
const { start, key, sep: sep2, value: value2 } = collItem;
|
|
11426
11426
|
const keyProps = resolveProps.resolveProps(start, {
|
|
11427
11427
|
indicator: "explicit-key-ind",
|
|
11428
11428
|
next: key ?? sep2?.[0],
|
|
@@ -11465,7 +11465,7 @@ var require_resolve_block_map = __commonJS({
|
|
|
11465
11465
|
onError(keyStart, "DUPLICATE_KEY", "Map keys must be unique");
|
|
11466
11466
|
const valueProps = resolveProps.resolveProps(sep2 ?? [], {
|
|
11467
11467
|
indicator: "map-value-ind",
|
|
11468
|
-
next:
|
|
11468
|
+
next: value2,
|
|
11469
11469
|
offset: keyNode.range[2],
|
|
11470
11470
|
onError,
|
|
11471
11471
|
parentIndent: bm.indent,
|
|
@@ -11474,14 +11474,14 @@ var require_resolve_block_map = __commonJS({
|
|
|
11474
11474
|
offset = valueProps.end;
|
|
11475
11475
|
if (valueProps.found) {
|
|
11476
11476
|
if (implicitKey) {
|
|
11477
|
-
if (
|
|
11477
|
+
if (value2?.type === "block-map" && !valueProps.hasNewline)
|
|
11478
11478
|
onError(offset, "BLOCK_AS_IMPLICIT_KEY", "Nested mappings are not allowed in compact mappings");
|
|
11479
11479
|
if (ctx.options.strict && keyProps.start < valueProps.found.offset - 1024)
|
|
11480
11480
|
onError(keyNode.range, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit block mapping key");
|
|
11481
11481
|
}
|
|
11482
|
-
const valueNode =
|
|
11482
|
+
const valueNode = value2 ? composeNode(ctx, value2, valueProps, onError) : composeEmptyNode(ctx, offset, sep2, null, valueProps, onError);
|
|
11483
11483
|
if (ctx.schema.compat)
|
|
11484
|
-
utilFlowIndentCheck.flowIndentCheck(bm.indent,
|
|
11484
|
+
utilFlowIndentCheck.flowIndentCheck(bm.indent, value2, onError);
|
|
11485
11485
|
offset = valueNode.range[2];
|
|
11486
11486
|
const pair = new Pair.Pair(keyNode, valueNode);
|
|
11487
11487
|
if (ctx.options.keepSourceTokens)
|
|
@@ -11527,18 +11527,18 @@ var require_resolve_block_seq = __commonJS({
|
|
|
11527
11527
|
ctx.atKey = false;
|
|
11528
11528
|
let offset = bs.offset;
|
|
11529
11529
|
let commentEnd = null;
|
|
11530
|
-
for (const { start, value } of bs.items) {
|
|
11530
|
+
for (const { start, value: value2 } of bs.items) {
|
|
11531
11531
|
const props = resolveProps.resolveProps(start, {
|
|
11532
11532
|
indicator: "seq-item-ind",
|
|
11533
|
-
next:
|
|
11533
|
+
next: value2,
|
|
11534
11534
|
offset,
|
|
11535
11535
|
onError,
|
|
11536
11536
|
parentIndent: bs.indent,
|
|
11537
11537
|
startOnNewline: true
|
|
11538
11538
|
});
|
|
11539
11539
|
if (!props.found) {
|
|
11540
|
-
if (props.anchor || props.tag ||
|
|
11541
|
-
if (
|
|
11540
|
+
if (props.anchor || props.tag || value2) {
|
|
11541
|
+
if (value2?.type === "block-seq")
|
|
11542
11542
|
onError(props.end, "BAD_INDENT", "All sequence items must start at the same column");
|
|
11543
11543
|
else
|
|
11544
11544
|
onError(offset, "MISSING_CHAR", "Sequence item without - indicator");
|
|
@@ -11549,9 +11549,9 @@ var require_resolve_block_seq = __commonJS({
|
|
|
11549
11549
|
continue;
|
|
11550
11550
|
}
|
|
11551
11551
|
}
|
|
11552
|
-
const node =
|
|
11552
|
+
const node = value2 ? composeNode(ctx, value2, props, onError) : composeEmptyNode(ctx, props.end, start, null, props, onError);
|
|
11553
11553
|
if (ctx.schema.compat)
|
|
11554
|
-
utilFlowIndentCheck.flowIndentCheck(bs.indent,
|
|
11554
|
+
utilFlowIndentCheck.flowIndentCheck(bs.indent, value2, onError);
|
|
11555
11555
|
offset = node.range[2];
|
|
11556
11556
|
seq.items.push(node);
|
|
11557
11557
|
}
|
|
@@ -11633,7 +11633,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
11633
11633
|
let offset = fc.offset + fc.start.source.length;
|
|
11634
11634
|
for (let i = 0; i < fc.items.length; ++i) {
|
|
11635
11635
|
const collItem = fc.items[i];
|
|
11636
|
-
const { start, key, sep: sep2, value } = collItem;
|
|
11636
|
+
const { start, key, sep: sep2, value: value2 } = collItem;
|
|
11637
11637
|
const props = resolveProps.resolveProps(start, {
|
|
11638
11638
|
flow: fcName,
|
|
11639
11639
|
indicator: "explicit-key-ind",
|
|
@@ -11644,7 +11644,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
11644
11644
|
startOnNewline: false
|
|
11645
11645
|
});
|
|
11646
11646
|
if (!props.found) {
|
|
11647
|
-
if (!props.anchor && !props.tag && !sep2 && !
|
|
11647
|
+
if (!props.anchor && !props.tag && !sep2 && !value2) {
|
|
11648
11648
|
if (i === 0 && props.comma)
|
|
11649
11649
|
onError(props.comma, "UNEXPECTED_TOKEN", `Unexpected , in ${fcName}`);
|
|
11650
11650
|
else if (i < fc.items.length - 1)
|
|
@@ -11699,10 +11699,10 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
11699
11699
|
}
|
|
11700
11700
|
}
|
|
11701
11701
|
if (!isMap && !sep2 && !props.found) {
|
|
11702
|
-
const valueNode =
|
|
11702
|
+
const valueNode = value2 ? composeNode(ctx, value2, props, onError) : composeEmptyNode(ctx, props.end, sep2, null, props, onError);
|
|
11703
11703
|
coll.items.push(valueNode);
|
|
11704
11704
|
offset = valueNode.range[2];
|
|
11705
|
-
if (isBlock(
|
|
11705
|
+
if (isBlock(value2))
|
|
11706
11706
|
onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
11707
11707
|
} else {
|
|
11708
11708
|
ctx.atKey = true;
|
|
@@ -11714,7 +11714,7 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
11714
11714
|
const valueProps = resolveProps.resolveProps(sep2 ?? [], {
|
|
11715
11715
|
flow: fcName,
|
|
11716
11716
|
indicator: "map-value-ind",
|
|
11717
|
-
next:
|
|
11717
|
+
next: value2,
|
|
11718
11718
|
offset: keyNode.range[2],
|
|
11719
11719
|
onError,
|
|
11720
11720
|
parentIndent: fc.indent,
|
|
@@ -11734,15 +11734,15 @@ var require_resolve_flow_collection = __commonJS({
|
|
|
11734
11734
|
if (props.start < valueProps.found.offset - 1024)
|
|
11735
11735
|
onError(valueProps.found, "KEY_OVER_1024_CHARS", "The : indicator must be at most 1024 chars after the start of an implicit flow sequence key");
|
|
11736
11736
|
}
|
|
11737
|
-
} else if (
|
|
11738
|
-
if ("source" in
|
|
11739
|
-
onError(
|
|
11737
|
+
} else if (value2) {
|
|
11738
|
+
if ("source" in value2 && value2.source?.[0] === ":")
|
|
11739
|
+
onError(value2, "MISSING_CHAR", `Missing space after : in ${fcName}`);
|
|
11740
11740
|
else
|
|
11741
11741
|
onError(valueProps.start, "MISSING_CHAR", `Missing , or : between ${fcName} items`);
|
|
11742
11742
|
}
|
|
11743
|
-
const valueNode =
|
|
11743
|
+
const valueNode = value2 ? composeNode(ctx, value2, valueProps, onError) : valueProps.found ? composeEmptyNode(ctx, valueProps.end, sep2, null, valueProps, onError) : null;
|
|
11744
11744
|
if (valueNode) {
|
|
11745
|
-
if (isBlock(
|
|
11745
|
+
if (isBlock(value2))
|
|
11746
11746
|
onError(valueNode.range, "BLOCK_IN_FLOW", blockMsg);
|
|
11747
11747
|
} else if (valueProps.comment) {
|
|
11748
11748
|
if (keyNode.comment)
|
|
@@ -11885,11 +11885,11 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
11885
11885
|
break;
|
|
11886
11886
|
}
|
|
11887
11887
|
if (chompStart === 0) {
|
|
11888
|
-
const
|
|
11888
|
+
const value3 = header.chomp === "+" && lines.length > 0 ? "\n".repeat(Math.max(1, lines.length - 1)) : "";
|
|
11889
11889
|
let end2 = start + header.length;
|
|
11890
11890
|
if (scalar2.source)
|
|
11891
11891
|
end2 += scalar2.source.length;
|
|
11892
|
-
return { value:
|
|
11892
|
+
return { value: value3, type, comment: header.comment, range: [start, end2, end2] };
|
|
11893
11893
|
}
|
|
11894
11894
|
let trimIndent = scalar2.indent + header.indent;
|
|
11895
11895
|
let offset = scalar2.offset + header.length;
|
|
@@ -11919,11 +11919,11 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
11919
11919
|
if (lines[i][0].length > trimIndent)
|
|
11920
11920
|
chompStart = i + 1;
|
|
11921
11921
|
}
|
|
11922
|
-
let
|
|
11922
|
+
let value2 = "";
|
|
11923
11923
|
let sep2 = "";
|
|
11924
11924
|
let prevMoreIndented = false;
|
|
11925
11925
|
for (let i = 0; i < contentStart; ++i)
|
|
11926
|
-
|
|
11926
|
+
value2 += lines[i][0].slice(trimIndent) + "\n";
|
|
11927
11927
|
for (let i = contentStart; i < chompStart; ++i) {
|
|
11928
11928
|
let [indent2, content] = lines[i];
|
|
11929
11929
|
offset += indent2.length + content.length + 1;
|
|
@@ -11937,23 +11937,23 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
11937
11937
|
indent2 = "";
|
|
11938
11938
|
}
|
|
11939
11939
|
if (type === Scalar.Scalar.BLOCK_LITERAL) {
|
|
11940
|
-
|
|
11940
|
+
value2 += sep2 + indent2.slice(trimIndent) + content;
|
|
11941
11941
|
sep2 = "\n";
|
|
11942
11942
|
} else if (indent2.length > trimIndent || content[0] === " ") {
|
|
11943
11943
|
if (sep2 === " ")
|
|
11944
11944
|
sep2 = "\n";
|
|
11945
11945
|
else if (!prevMoreIndented && sep2 === "\n")
|
|
11946
11946
|
sep2 = "\n\n";
|
|
11947
|
-
|
|
11947
|
+
value2 += sep2 + indent2.slice(trimIndent) + content;
|
|
11948
11948
|
sep2 = "\n";
|
|
11949
11949
|
prevMoreIndented = true;
|
|
11950
11950
|
} else if (content === "") {
|
|
11951
11951
|
if (sep2 === "\n")
|
|
11952
|
-
|
|
11952
|
+
value2 += "\n";
|
|
11953
11953
|
else
|
|
11954
11954
|
sep2 = "\n";
|
|
11955
11955
|
} else {
|
|
11956
|
-
|
|
11956
|
+
value2 += sep2 + content;
|
|
11957
11957
|
sep2 = " ";
|
|
11958
11958
|
prevMoreIndented = false;
|
|
11959
11959
|
}
|
|
@@ -11963,15 +11963,15 @@ var require_resolve_block_scalar = __commonJS({
|
|
|
11963
11963
|
break;
|
|
11964
11964
|
case "+":
|
|
11965
11965
|
for (let i = chompStart; i < lines.length; ++i)
|
|
11966
|
-
|
|
11967
|
-
if (
|
|
11968
|
-
|
|
11966
|
+
value2 += "\n" + lines[i][0].slice(trimIndent);
|
|
11967
|
+
if (value2[value2.length - 1] !== "\n")
|
|
11968
|
+
value2 += "\n";
|
|
11969
11969
|
break;
|
|
11970
11970
|
default:
|
|
11971
|
-
|
|
11971
|
+
value2 += "\n";
|
|
11972
11972
|
}
|
|
11973
11973
|
const end = start + header.length + scalar2.source.length;
|
|
11974
|
-
return { value, type, comment: header.comment, range: [start, end, end] };
|
|
11974
|
+
return { value: value2, type, comment: header.comment, range: [start, end, end] };
|
|
11975
11975
|
}
|
|
11976
11976
|
function parseBlockScalarHeader({ offset, props }, strict, onError) {
|
|
11977
11977
|
if (props[0].type !== "block-scalar-header") {
|
|
@@ -12056,20 +12056,20 @@ var require_resolve_flow_scalar = __commonJS({
|
|
|
12056
12056
|
function resolveFlowScalar(scalar2, strict, onError) {
|
|
12057
12057
|
const { offset, type, source: source2, end } = scalar2;
|
|
12058
12058
|
let _type;
|
|
12059
|
-
let
|
|
12059
|
+
let value2;
|
|
12060
12060
|
const _onError = (rel, code, msg) => onError(offset + rel, code, msg);
|
|
12061
12061
|
switch (type) {
|
|
12062
12062
|
case "scalar":
|
|
12063
12063
|
_type = Scalar.Scalar.PLAIN;
|
|
12064
|
-
|
|
12064
|
+
value2 = plainValue(source2, _onError);
|
|
12065
12065
|
break;
|
|
12066
12066
|
case "single-quoted-scalar":
|
|
12067
12067
|
_type = Scalar.Scalar.QUOTE_SINGLE;
|
|
12068
|
-
|
|
12068
|
+
value2 = singleQuotedValue(source2, _onError);
|
|
12069
12069
|
break;
|
|
12070
12070
|
case "double-quoted-scalar":
|
|
12071
12071
|
_type = Scalar.Scalar.QUOTE_DOUBLE;
|
|
12072
|
-
|
|
12072
|
+
value2 = doubleQuotedValue(source2, _onError);
|
|
12073
12073
|
break;
|
|
12074
12074
|
/* istanbul ignore next should not happen */
|
|
12075
12075
|
default:
|
|
@@ -12084,7 +12084,7 @@ var require_resolve_flow_scalar = __commonJS({
|
|
|
12084
12084
|
const valueEnd = offset + source2.length;
|
|
12085
12085
|
const re = resolveEnd.resolveEnd(end, valueEnd, strict, onError);
|
|
12086
12086
|
return {
|
|
12087
|
-
value,
|
|
12087
|
+
value: value2,
|
|
12088
12088
|
type: _type,
|
|
12089
12089
|
comment: re.comment,
|
|
12090
12090
|
range: [offset, valueEnd, re.offset]
|
|
@@ -12277,28 +12277,28 @@ var require_compose_scalar = __commonJS({
|
|
|
12277
12277
|
var resolveBlockScalar = require_resolve_block_scalar();
|
|
12278
12278
|
var resolveFlowScalar = require_resolve_flow_scalar();
|
|
12279
12279
|
function composeScalar(ctx, token, tagToken, onError) {
|
|
12280
|
-
const { value, type, comment, range } = token.type === "block-scalar" ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError) : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
|
|
12280
|
+
const { value: value2, type, comment, range } = token.type === "block-scalar" ? resolveBlockScalar.resolveBlockScalar(ctx, token, onError) : resolveFlowScalar.resolveFlowScalar(token, ctx.options.strict, onError);
|
|
12281
12281
|
const tagName = tagToken ? ctx.directives.tagName(tagToken.source, (msg) => onError(tagToken, "TAG_RESOLVE_FAILED", msg)) : null;
|
|
12282
12282
|
let tag;
|
|
12283
12283
|
if (ctx.options.stringKeys && ctx.atKey) {
|
|
12284
12284
|
tag = ctx.schema[identity.SCALAR];
|
|
12285
12285
|
} else if (tagName)
|
|
12286
|
-
tag = findScalarTagByName(ctx.schema,
|
|
12286
|
+
tag = findScalarTagByName(ctx.schema, value2, tagName, tagToken, onError);
|
|
12287
12287
|
else if (token.type === "scalar")
|
|
12288
|
-
tag = findScalarTagByTest(ctx,
|
|
12288
|
+
tag = findScalarTagByTest(ctx, value2, token, onError);
|
|
12289
12289
|
else
|
|
12290
12290
|
tag = ctx.schema[identity.SCALAR];
|
|
12291
12291
|
let scalar2;
|
|
12292
12292
|
try {
|
|
12293
|
-
const res = tag.resolve(
|
|
12293
|
+
const res = tag.resolve(value2, (msg) => onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg), ctx.options);
|
|
12294
12294
|
scalar2 = identity.isScalar(res) ? res : new Scalar.Scalar(res);
|
|
12295
12295
|
} catch (error) {
|
|
12296
12296
|
const msg = error instanceof Error ? error.message : String(error);
|
|
12297
12297
|
onError(tagToken ?? token, "TAG_RESOLVE_FAILED", msg);
|
|
12298
|
-
scalar2 = new Scalar.Scalar(
|
|
12298
|
+
scalar2 = new Scalar.Scalar(value2);
|
|
12299
12299
|
}
|
|
12300
12300
|
scalar2.range = range;
|
|
12301
|
-
scalar2.source =
|
|
12301
|
+
scalar2.source = value2;
|
|
12302
12302
|
if (type)
|
|
12303
12303
|
scalar2.type = type;
|
|
12304
12304
|
if (tagName)
|
|
@@ -12309,7 +12309,7 @@ var require_compose_scalar = __commonJS({
|
|
|
12309
12309
|
scalar2.comment = comment;
|
|
12310
12310
|
return scalar2;
|
|
12311
12311
|
}
|
|
12312
|
-
function findScalarTagByName(schema,
|
|
12312
|
+
function findScalarTagByName(schema, value2, tagName, tagToken, onError) {
|
|
12313
12313
|
if (tagName === "!")
|
|
12314
12314
|
return schema[identity.SCALAR];
|
|
12315
12315
|
const matchWithTest = [];
|
|
@@ -12322,7 +12322,7 @@ var require_compose_scalar = __commonJS({
|
|
|
12322
12322
|
}
|
|
12323
12323
|
}
|
|
12324
12324
|
for (const tag of matchWithTest)
|
|
12325
|
-
if (tag.test?.test(
|
|
12325
|
+
if (tag.test?.test(value2))
|
|
12326
12326
|
return tag;
|
|
12327
12327
|
const kt = schema.knownTags[tagName];
|
|
12328
12328
|
if (kt && !kt.collection) {
|
|
@@ -12332,10 +12332,10 @@ var require_compose_scalar = __commonJS({
|
|
|
12332
12332
|
onError(tagToken, "TAG_RESOLVE_FAILED", `Unresolved tag: ${tagName}`, tagName !== "tag:yaml.org,2002:str");
|
|
12333
12333
|
return schema[identity.SCALAR];
|
|
12334
12334
|
}
|
|
12335
|
-
function findScalarTagByTest({ atKey, directives, schema },
|
|
12336
|
-
const tag = schema.tags.find((tag2) => (tag2.default === true || atKey && tag2.default === "key") && tag2.test?.test(
|
|
12335
|
+
function findScalarTagByTest({ atKey, directives, schema }, value2, token, onError) {
|
|
12336
|
+
const tag = schema.tags.find((tag2) => (tag2.default === true || atKey && tag2.default === "key") && tag2.test?.test(value2)) || schema[identity.SCALAR];
|
|
12337
12337
|
if (schema.compat) {
|
|
12338
|
-
const compat = schema.compat.find((tag2) => tag2.default && tag2.test?.test(
|
|
12338
|
+
const compat = schema.compat.find((tag2) => tag2.default && tag2.test?.test(value2)) ?? schema[identity.SCALAR];
|
|
12339
12339
|
if (tag.tag !== compat.tag) {
|
|
12340
12340
|
const ts = directives.tagString(tag.tag);
|
|
12341
12341
|
const cs = directives.tagString(compat.tag);
|
|
@@ -12493,7 +12493,7 @@ var require_compose_doc = __commonJS({
|
|
|
12493
12493
|
var composeNode = require_compose_node();
|
|
12494
12494
|
var resolveEnd = require_resolve_end();
|
|
12495
12495
|
var resolveProps = require_resolve_props();
|
|
12496
|
-
function composeDoc(options, directives, { offset, start, value, end }, onError) {
|
|
12496
|
+
function composeDoc(options, directives, { offset, start, value: value2, end }, onError) {
|
|
12497
12497
|
const opts = Object.assign({ _directives: directives }, options);
|
|
12498
12498
|
const doc = new Document.Document(void 0, opts);
|
|
12499
12499
|
const ctx = {
|
|
@@ -12505,7 +12505,7 @@ var require_compose_doc = __commonJS({
|
|
|
12505
12505
|
};
|
|
12506
12506
|
const props = resolveProps.resolveProps(start, {
|
|
12507
12507
|
indicator: "doc-start",
|
|
12508
|
-
next:
|
|
12508
|
+
next: value2 ?? end?.[0],
|
|
12509
12509
|
offset,
|
|
12510
12510
|
onError,
|
|
12511
12511
|
parentIndent: 0,
|
|
@@ -12513,10 +12513,10 @@ var require_compose_doc = __commonJS({
|
|
|
12513
12513
|
});
|
|
12514
12514
|
if (props.found) {
|
|
12515
12515
|
doc.directives.docStart = true;
|
|
12516
|
-
if (
|
|
12516
|
+
if (value2 && (value2.type === "block-map" || value2.type === "block-seq") && !props.hasNewline)
|
|
12517
12517
|
onError(props.end, "MISSING_CHAR", "Block collection cannot start on same line with directives-end marker");
|
|
12518
12518
|
}
|
|
12519
|
-
doc.contents =
|
|
12519
|
+
doc.contents = value2 ? composeNode.composeNode(ctx, value2, props, onError) : composeNode.composeEmptyNode(ctx, props.end, start, null, props, onError);
|
|
12520
12520
|
const contentEnd = doc.contents.range[2];
|
|
12521
12521
|
const re = resolveEnd.resolveEnd(end, contentEnd, false, onError);
|
|
12522
12522
|
if (re.comment)
|
|
@@ -12764,9 +12764,9 @@ var require_cst_scalar = __commonJS({
|
|
|
12764
12764
|
}
|
|
12765
12765
|
return null;
|
|
12766
12766
|
}
|
|
12767
|
-
function createScalarToken(
|
|
12767
|
+
function createScalarToken(value2, context) {
|
|
12768
12768
|
const { implicitKey = false, indent: indent2, inFlow = false, offset = -1, type = "PLAIN" } = context;
|
|
12769
|
-
const source2 = stringifyString.stringifyString({ type, value }, {
|
|
12769
|
+
const source2 = stringifyString.stringifyString({ type, value: value2 }, {
|
|
12770
12770
|
implicitKey,
|
|
12771
12771
|
indent: indent2 > 0 ? " ".repeat(indent2) : "",
|
|
12772
12772
|
inFlow,
|
|
@@ -12796,7 +12796,7 @@ var require_cst_scalar = __commonJS({
|
|
|
12796
12796
|
return { type: "scalar", offset, indent: indent2, source: source2, end };
|
|
12797
12797
|
}
|
|
12798
12798
|
}
|
|
12799
|
-
function setScalarValue(token,
|
|
12799
|
+
function setScalarValue(token, value2, context = {}) {
|
|
12800
12800
|
let { afterKey = false, implicitKey = false, inFlow = false, type } = context;
|
|
12801
12801
|
let indent2 = "indent" in token ? token.indent : null;
|
|
12802
12802
|
if (afterKey && typeof indent2 === "number")
|
|
@@ -12819,7 +12819,7 @@ var require_cst_scalar = __commonJS({
|
|
|
12819
12819
|
default:
|
|
12820
12820
|
type = "PLAIN";
|
|
12821
12821
|
}
|
|
12822
|
-
const source2 = stringifyString.stringifyString({ type, value }, {
|
|
12822
|
+
const source2 = stringifyString.stringifyString({ type, value: value2 }, {
|
|
12823
12823
|
implicitKey: implicitKey || indent2 === null,
|
|
12824
12824
|
indent: indent2 !== null && indent2 > 0 ? " ".repeat(indent2) : "",
|
|
12825
12825
|
inFlow,
|
|
@@ -12965,7 +12965,7 @@ var require_cst_stringify = __commonJS({
|
|
|
12965
12965
|
}
|
|
12966
12966
|
}
|
|
12967
12967
|
}
|
|
12968
|
-
function stringifyItem({ start, key, sep: sep2, value }) {
|
|
12968
|
+
function stringifyItem({ start, key, sep: sep2, value: value2 }) {
|
|
12969
12969
|
let res = "";
|
|
12970
12970
|
for (const st of start)
|
|
12971
12971
|
res += st.source;
|
|
@@ -12974,8 +12974,8 @@ var require_cst_stringify = __commonJS({
|
|
|
12974
12974
|
if (sep2)
|
|
12975
12975
|
for (const st of sep2)
|
|
12976
12976
|
res += st.source;
|
|
12977
|
-
if (
|
|
12978
|
-
res += stringifyToken(
|
|
12977
|
+
if (value2)
|
|
12978
|
+
res += stringifyToken(value2);
|
|
12979
12979
|
return res;
|
|
12980
12980
|
}
|
|
12981
12981
|
exports2.stringify = stringify;
|
|
@@ -14708,7 +14708,7 @@ var require_public_api = __commonJS({
|
|
|
14708
14708
|
}
|
|
14709
14709
|
return doc.toJS(Object.assign({ reviver: _reviver }, options));
|
|
14710
14710
|
}
|
|
14711
|
-
function stringify(
|
|
14711
|
+
function stringify(value2, replacer, options) {
|
|
14712
14712
|
let _replacer = null;
|
|
14713
14713
|
if (typeof replacer === "function" || Array.isArray(replacer)) {
|
|
14714
14714
|
_replacer = replacer;
|
|
@@ -14721,14 +14721,14 @@ var require_public_api = __commonJS({
|
|
|
14721
14721
|
const indent2 = Math.round(options);
|
|
14722
14722
|
options = indent2 < 1 ? void 0 : indent2 > 8 ? { indent: 8 } : { indent: indent2 };
|
|
14723
14723
|
}
|
|
14724
|
-
if (
|
|
14724
|
+
if (value2 === void 0) {
|
|
14725
14725
|
const { keepUndefined } = options ?? replacer ?? {};
|
|
14726
14726
|
if (!keepUndefined)
|
|
14727
14727
|
return void 0;
|
|
14728
14728
|
}
|
|
14729
|
-
if (identity.isDocument(
|
|
14730
|
-
return
|
|
14731
|
-
return new Document.Document(
|
|
14729
|
+
if (identity.isDocument(value2) && !_replacer)
|
|
14730
|
+
return value2.toString(options);
|
|
14731
|
+
return new Document.Document(value2, _replacer, options).toString(options);
|
|
14732
14732
|
}
|
|
14733
14733
|
exports2.parse = parse2;
|
|
14734
14734
|
exports2.parseAllDocuments = parseAllDocuments;
|
|
@@ -14896,7 +14896,7 @@ var require_lz_string = __commonJS({
|
|
|
14896
14896
|
},
|
|
14897
14897
|
_compress: function(uncompressed, bitsPerChar, getCharFromInt) {
|
|
14898
14898
|
if (uncompressed == null) return "";
|
|
14899
|
-
var i,
|
|
14899
|
+
var i, value2, context_dictionary = {}, context_dictionaryToCreate = {}, context_c = "", context_wc = "", context_w = "", context_enlargeIn = 2, context_dictSize = 3, context_numBits = 2, context_data = [], context_data_val = 0, context_data_position = 0, ii;
|
|
14900
14900
|
for (ii = 0; ii < uncompressed.length; ii += 1) {
|
|
14901
14901
|
context_c = uncompressed.charAt(ii);
|
|
14902
14902
|
if (!Object.prototype.hasOwnProperty.call(context_dictionary, context_c)) {
|
|
@@ -14919,9 +14919,9 @@ var require_lz_string = __commonJS({
|
|
|
14919
14919
|
context_data_position++;
|
|
14920
14920
|
}
|
|
14921
14921
|
}
|
|
14922
|
-
|
|
14922
|
+
value2 = context_w.charCodeAt(0);
|
|
14923
14923
|
for (i = 0; i < 8; i++) {
|
|
14924
|
-
context_data_val = context_data_val << 1 |
|
|
14924
|
+
context_data_val = context_data_val << 1 | value2 & 1;
|
|
14925
14925
|
if (context_data_position == bitsPerChar - 1) {
|
|
14926
14926
|
context_data_position = 0;
|
|
14927
14927
|
context_data.push(getCharFromInt(context_data_val));
|
|
@@ -14929,12 +14929,12 @@ var require_lz_string = __commonJS({
|
|
|
14929
14929
|
} else {
|
|
14930
14930
|
context_data_position++;
|
|
14931
14931
|
}
|
|
14932
|
-
|
|
14932
|
+
value2 = value2 >> 1;
|
|
14933
14933
|
}
|
|
14934
14934
|
} else {
|
|
14935
|
-
|
|
14935
|
+
value2 = 1;
|
|
14936
14936
|
for (i = 0; i < context_numBits; i++) {
|
|
14937
|
-
context_data_val = context_data_val << 1 |
|
|
14937
|
+
context_data_val = context_data_val << 1 | value2;
|
|
14938
14938
|
if (context_data_position == bitsPerChar - 1) {
|
|
14939
14939
|
context_data_position = 0;
|
|
14940
14940
|
context_data.push(getCharFromInt(context_data_val));
|
|
@@ -14942,11 +14942,11 @@ var require_lz_string = __commonJS({
|
|
|
14942
14942
|
} else {
|
|
14943
14943
|
context_data_position++;
|
|
14944
14944
|
}
|
|
14945
|
-
|
|
14945
|
+
value2 = 0;
|
|
14946
14946
|
}
|
|
14947
|
-
|
|
14947
|
+
value2 = context_w.charCodeAt(0);
|
|
14948
14948
|
for (i = 0; i < 16; i++) {
|
|
14949
|
-
context_data_val = context_data_val << 1 |
|
|
14949
|
+
context_data_val = context_data_val << 1 | value2 & 1;
|
|
14950
14950
|
if (context_data_position == bitsPerChar - 1) {
|
|
14951
14951
|
context_data_position = 0;
|
|
14952
14952
|
context_data.push(getCharFromInt(context_data_val));
|
|
@@ -14954,7 +14954,7 @@ var require_lz_string = __commonJS({
|
|
|
14954
14954
|
} else {
|
|
14955
14955
|
context_data_position++;
|
|
14956
14956
|
}
|
|
14957
|
-
|
|
14957
|
+
value2 = value2 >> 1;
|
|
14958
14958
|
}
|
|
14959
14959
|
}
|
|
14960
14960
|
context_enlargeIn--;
|
|
@@ -14964,9 +14964,9 @@ var require_lz_string = __commonJS({
|
|
|
14964
14964
|
}
|
|
14965
14965
|
delete context_dictionaryToCreate[context_w];
|
|
14966
14966
|
} else {
|
|
14967
|
-
|
|
14967
|
+
value2 = context_dictionary[context_w];
|
|
14968
14968
|
for (i = 0; i < context_numBits; i++) {
|
|
14969
|
-
context_data_val = context_data_val << 1 |
|
|
14969
|
+
context_data_val = context_data_val << 1 | value2 & 1;
|
|
14970
14970
|
if (context_data_position == bitsPerChar - 1) {
|
|
14971
14971
|
context_data_position = 0;
|
|
14972
14972
|
context_data.push(getCharFromInt(context_data_val));
|
|
@@ -14974,7 +14974,7 @@ var require_lz_string = __commonJS({
|
|
|
14974
14974
|
} else {
|
|
14975
14975
|
context_data_position++;
|
|
14976
14976
|
}
|
|
14977
|
-
|
|
14977
|
+
value2 = value2 >> 1;
|
|
14978
14978
|
}
|
|
14979
14979
|
}
|
|
14980
14980
|
context_enlargeIn--;
|
|
@@ -14999,9 +14999,9 @@ var require_lz_string = __commonJS({
|
|
|
14999
14999
|
context_data_position++;
|
|
15000
15000
|
}
|
|
15001
15001
|
}
|
|
15002
|
-
|
|
15002
|
+
value2 = context_w.charCodeAt(0);
|
|
15003
15003
|
for (i = 0; i < 8; i++) {
|
|
15004
|
-
context_data_val = context_data_val << 1 |
|
|
15004
|
+
context_data_val = context_data_val << 1 | value2 & 1;
|
|
15005
15005
|
if (context_data_position == bitsPerChar - 1) {
|
|
15006
15006
|
context_data_position = 0;
|
|
15007
15007
|
context_data.push(getCharFromInt(context_data_val));
|
|
@@ -15009,12 +15009,12 @@ var require_lz_string = __commonJS({
|
|
|
15009
15009
|
} else {
|
|
15010
15010
|
context_data_position++;
|
|
15011
15011
|
}
|
|
15012
|
-
|
|
15012
|
+
value2 = value2 >> 1;
|
|
15013
15013
|
}
|
|
15014
15014
|
} else {
|
|
15015
|
-
|
|
15015
|
+
value2 = 1;
|
|
15016
15016
|
for (i = 0; i < context_numBits; i++) {
|
|
15017
|
-
context_data_val = context_data_val << 1 |
|
|
15017
|
+
context_data_val = context_data_val << 1 | value2;
|
|
15018
15018
|
if (context_data_position == bitsPerChar - 1) {
|
|
15019
15019
|
context_data_position = 0;
|
|
15020
15020
|
context_data.push(getCharFromInt(context_data_val));
|
|
@@ -15022,11 +15022,11 @@ var require_lz_string = __commonJS({
|
|
|
15022
15022
|
} else {
|
|
15023
15023
|
context_data_position++;
|
|
15024
15024
|
}
|
|
15025
|
-
|
|
15025
|
+
value2 = 0;
|
|
15026
15026
|
}
|
|
15027
|
-
|
|
15027
|
+
value2 = context_w.charCodeAt(0);
|
|
15028
15028
|
for (i = 0; i < 16; i++) {
|
|
15029
|
-
context_data_val = context_data_val << 1 |
|
|
15029
|
+
context_data_val = context_data_val << 1 | value2 & 1;
|
|
15030
15030
|
if (context_data_position == bitsPerChar - 1) {
|
|
15031
15031
|
context_data_position = 0;
|
|
15032
15032
|
context_data.push(getCharFromInt(context_data_val));
|
|
@@ -15034,7 +15034,7 @@ var require_lz_string = __commonJS({
|
|
|
15034
15034
|
} else {
|
|
15035
15035
|
context_data_position++;
|
|
15036
15036
|
}
|
|
15037
|
-
|
|
15037
|
+
value2 = value2 >> 1;
|
|
15038
15038
|
}
|
|
15039
15039
|
}
|
|
15040
15040
|
context_enlargeIn--;
|
|
@@ -15044,9 +15044,9 @@ var require_lz_string = __commonJS({
|
|
|
15044
15044
|
}
|
|
15045
15045
|
delete context_dictionaryToCreate[context_w];
|
|
15046
15046
|
} else {
|
|
15047
|
-
|
|
15047
|
+
value2 = context_dictionary[context_w];
|
|
15048
15048
|
for (i = 0; i < context_numBits; i++) {
|
|
15049
|
-
context_data_val = context_data_val << 1 |
|
|
15049
|
+
context_data_val = context_data_val << 1 | value2 & 1;
|
|
15050
15050
|
if (context_data_position == bitsPerChar - 1) {
|
|
15051
15051
|
context_data_position = 0;
|
|
15052
15052
|
context_data.push(getCharFromInt(context_data_val));
|
|
@@ -15054,7 +15054,7 @@ var require_lz_string = __commonJS({
|
|
|
15054
15054
|
} else {
|
|
15055
15055
|
context_data_position++;
|
|
15056
15056
|
}
|
|
15057
|
-
|
|
15057
|
+
value2 = value2 >> 1;
|
|
15058
15058
|
}
|
|
15059
15059
|
}
|
|
15060
15060
|
context_enlargeIn--;
|
|
@@ -15063,9 +15063,9 @@ var require_lz_string = __commonJS({
|
|
|
15063
15063
|
context_numBits++;
|
|
15064
15064
|
}
|
|
15065
15065
|
}
|
|
15066
|
-
|
|
15066
|
+
value2 = 2;
|
|
15067
15067
|
for (i = 0; i < context_numBits; i++) {
|
|
15068
|
-
context_data_val = context_data_val << 1 |
|
|
15068
|
+
context_data_val = context_data_val << 1 | value2 & 1;
|
|
15069
15069
|
if (context_data_position == bitsPerChar - 1) {
|
|
15070
15070
|
context_data_position = 0;
|
|
15071
15071
|
context_data.push(getCharFromInt(context_data_val));
|
|
@@ -15073,7 +15073,7 @@ var require_lz_string = __commonJS({
|
|
|
15073
15073
|
} else {
|
|
15074
15074
|
context_data_position++;
|
|
15075
15075
|
}
|
|
15076
|
-
|
|
15076
|
+
value2 = value2 >> 1;
|
|
15077
15077
|
}
|
|
15078
15078
|
while (true) {
|
|
15079
15079
|
context_data_val = context_data_val << 1;
|
|
@@ -15253,8 +15253,8 @@ __export(cli_exports, {
|
|
|
15253
15253
|
run: () => run
|
|
15254
15254
|
});
|
|
15255
15255
|
module.exports = __toCommonJS(cli_exports);
|
|
15256
|
-
var
|
|
15257
|
-
var
|
|
15256
|
+
var import_node_fs15 = require("node:fs");
|
|
15257
|
+
var import_node_path14 = require("node:path");
|
|
15258
15258
|
|
|
15259
15259
|
// src/openapi/config.ts
|
|
15260
15260
|
var import_node_fs2 = require("node:fs");
|
|
@@ -15668,9 +15668,9 @@ function tokenizeLine(text, line) {
|
|
|
15668
15668
|
break;
|
|
15669
15669
|
}
|
|
15670
15670
|
if (ch === '"') {
|
|
15671
|
-
const { value, end, closed } = readString(text, i);
|
|
15671
|
+
const { value: value2, end, closed } = readString(text, i);
|
|
15672
15672
|
if (!closed) error("Unterminated string", start + 1, text.length - start);
|
|
15673
|
-
tokens.push({ kind: "string", value, col: start + 1, length: end - start });
|
|
15673
|
+
tokens.push({ kind: "string", value: value2, col: start + 1, length: end - start });
|
|
15674
15674
|
i = end;
|
|
15675
15675
|
continue;
|
|
15676
15676
|
}
|
|
@@ -15689,9 +15689,9 @@ function tokenizeLine(text, line) {
|
|
|
15689
15689
|
const arrow = ["->>", "-->", "->"].find((a) => text.startsWith(a, i));
|
|
15690
15690
|
const failed = text.startsWith("-x", i) && !IDENT_PART.test(text[i + 2] ?? "");
|
|
15691
15691
|
if (arrow || failed) {
|
|
15692
|
-
const
|
|
15693
|
-
tokens.push({ kind: "arrow", value, col: start + 1, length:
|
|
15694
|
-
i +=
|
|
15692
|
+
const value2 = arrow ?? "-x";
|
|
15693
|
+
tokens.push({ kind: "arrow", value: value2, col: start + 1, length: value2.length });
|
|
15694
|
+
i += value2.length;
|
|
15695
15695
|
continue;
|
|
15696
15696
|
}
|
|
15697
15697
|
if (DIGIT.test(text[i + 1] ?? "")) {
|
|
@@ -15703,15 +15703,15 @@ function tokenizeLine(text, line) {
|
|
|
15703
15703
|
}
|
|
15704
15704
|
if (DIGIT.test(ch)) {
|
|
15705
15705
|
i = readQuantity(text, i);
|
|
15706
|
-
const
|
|
15707
|
-
const kind = /^\d+$/.test(
|
|
15708
|
-
tokens.push({ kind, value, col: start + 1, length: i - start });
|
|
15706
|
+
const value2 = text.slice(start, i).replace(/[ \t]+/g, "");
|
|
15707
|
+
const kind = /^\d+$/.test(value2) ? "number" : "quantity";
|
|
15708
|
+
tokens.push({ kind, value: value2, col: start + 1, length: i - start });
|
|
15709
15709
|
continue;
|
|
15710
15710
|
}
|
|
15711
15711
|
if (ch === "<" || ch === ">") {
|
|
15712
|
-
const
|
|
15713
|
-
tokens.push({ kind: "op", value, col: start + 1, length:
|
|
15714
|
-
i +=
|
|
15712
|
+
const value2 = text[i + 1] === "=" ? ch + "=" : ch;
|
|
15713
|
+
tokens.push({ kind: "op", value: value2, col: start + 1, length: value2.length });
|
|
15714
|
+
i += value2.length;
|
|
15715
15715
|
continue;
|
|
15716
15716
|
}
|
|
15717
15717
|
if (ch === "@") {
|
|
@@ -15764,20 +15764,20 @@ function readQuantity(text, start) {
|
|
|
15764
15764
|
return i;
|
|
15765
15765
|
}
|
|
15766
15766
|
function readString(text, start) {
|
|
15767
|
-
let
|
|
15767
|
+
let value2 = "";
|
|
15768
15768
|
let i = start + 1;
|
|
15769
15769
|
while (i < text.length) {
|
|
15770
15770
|
const ch = text[i];
|
|
15771
15771
|
if (ch === "\\" && i + 1 < text.length) {
|
|
15772
|
-
|
|
15772
|
+
value2 += text[i + 1];
|
|
15773
15773
|
i += 2;
|
|
15774
15774
|
continue;
|
|
15775
15775
|
}
|
|
15776
|
-
if (ch === '"') return { value, end: i + 1, closed: true };
|
|
15777
|
-
|
|
15776
|
+
if (ch === '"') return { value: value2, end: i + 1, closed: true };
|
|
15777
|
+
value2 += ch;
|
|
15778
15778
|
i++;
|
|
15779
15779
|
}
|
|
15780
|
-
return { value, end: text.length, closed: false };
|
|
15780
|
+
return { value: value2, end: text.length, closed: false };
|
|
15781
15781
|
}
|
|
15782
15782
|
function stripTrailingComment(text) {
|
|
15783
15783
|
let depth = 0;
|
|
@@ -15823,6 +15823,19 @@ var BracketCounter = class {
|
|
|
15823
15823
|
return this.depth;
|
|
15824
15824
|
}
|
|
15825
15825
|
};
|
|
15826
|
+
function qualify(tokens) {
|
|
15827
|
+
let out;
|
|
15828
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
15829
|
+
const [t, next] = [tokens[i], tokens[i + 1]];
|
|
15830
|
+
const joined = t.kind === "ident" && next?.kind === "tag" && next.col === t.col + t.length;
|
|
15831
|
+
if (joined && (tokens[i + 2]?.kind === "arrow" || tokens[i - 1]?.kind === "arrow")) {
|
|
15832
|
+
out ??= tokens.slice(0, i);
|
|
15833
|
+
out.push({ ...t, value: `${t.value}.${next.value}`, length: t.length + next.length });
|
|
15834
|
+
i++;
|
|
15835
|
+
} else out?.push(t);
|
|
15836
|
+
}
|
|
15837
|
+
return out ?? tokens;
|
|
15838
|
+
}
|
|
15826
15839
|
|
|
15827
15840
|
// ../frontend/src/dsl/format.ts
|
|
15828
15841
|
function format(source2) {
|
|
@@ -15859,7 +15872,8 @@ function classify(lines) {
|
|
|
15859
15872
|
entries2.push({ kind: "blank", depth, text: "" });
|
|
15860
15873
|
continue;
|
|
15861
15874
|
}
|
|
15862
|
-
const { tokens, diagnostics } = tokenizeLine(raw, i + 1);
|
|
15875
|
+
const { tokens: lexed, diagnostics } = tokenizeLine(raw, i + 1);
|
|
15876
|
+
const tokens = qualify(lexed);
|
|
15863
15877
|
if (diagnostics.some((d) => d.severity === "error") || tokens.length === 0) {
|
|
15864
15878
|
entries2.push({ kind: "line", depth, text: original });
|
|
15865
15879
|
continue;
|
|
@@ -16014,7 +16028,8 @@ function join(raw, tokens) {
|
|
|
16014
16028
|
return out;
|
|
16015
16029
|
}
|
|
16016
16030
|
function sameTokens(text, tokens) {
|
|
16017
|
-
const { tokens:
|
|
16031
|
+
const { tokens: lexed, diagnostics } = tokenizeLine(text, 1);
|
|
16032
|
+
const again = qualify(lexed);
|
|
16018
16033
|
return diagnostics.length === 0 && again.length === tokens.length && again.every((t, i) => t.kind === tokens[i].kind && t.value === tokens[i].value);
|
|
16019
16034
|
}
|
|
16020
16035
|
function reindent(line, delta) {
|
|
@@ -16538,14 +16553,14 @@ var Parser = class _Parser {
|
|
|
16538
16553
|
return index;
|
|
16539
16554
|
}
|
|
16540
16555
|
parseTitle(tokens, line) {
|
|
16541
|
-
const
|
|
16542
|
-
if (!
|
|
16556
|
+
const value2 = tokens[1];
|
|
16557
|
+
if (!value2 || value2.kind !== "string" && value2.kind !== "ident") {
|
|
16543
16558
|
this.error('Expected a title, e.g. title "My System"', this.locOf(tokens[0], line));
|
|
16544
16559
|
return;
|
|
16545
16560
|
}
|
|
16546
16561
|
const summary = tokens[2]?.kind === "string" ? tokens[2] : void 0;
|
|
16547
16562
|
if (this.file === this.rootFile) {
|
|
16548
|
-
this.title =
|
|
16563
|
+
this.title = value2.value;
|
|
16549
16564
|
if (summary) this.summary = summary.value;
|
|
16550
16565
|
}
|
|
16551
16566
|
this.expectEnd(tokens, summary ? 3 : 2, line);
|
|
@@ -16557,13 +16572,13 @@ var Parser = class _Parser {
|
|
|
16557
16572
|
}
|
|
16558
16573
|
/** `direction down|right|up|left`: at the top level for the whole diagram, inside a group for its members. */
|
|
16559
16574
|
parseDirection(tokens, line) {
|
|
16560
|
-
const [keyword,
|
|
16561
|
-
const loc = this.locOf(
|
|
16562
|
-
if (!DIRECTIONS.includes(
|
|
16563
|
-
this.error(`Unknown direction '${
|
|
16575
|
+
const [keyword, value2] = tokens;
|
|
16576
|
+
const loc = this.locOf(value2, line);
|
|
16577
|
+
if (!DIRECTIONS.includes(value2.value)) {
|
|
16578
|
+
this.error(`Unknown direction '${value2.value}'; use direction down, right, up or left`, loc);
|
|
16564
16579
|
return;
|
|
16565
16580
|
}
|
|
16566
|
-
const direction =
|
|
16581
|
+
const direction = value2.value;
|
|
16567
16582
|
const top = this.top();
|
|
16568
16583
|
if (top?.kind === "group") {
|
|
16569
16584
|
const group = this.nodes.get(top.id);
|
|
@@ -16586,10 +16601,10 @@ var Parser = class _Parser {
|
|
|
16586
16601
|
}
|
|
16587
16602
|
/** `layout ordered`: lay edges out by declaration order. */
|
|
16588
16603
|
parseLayoutMode(tokens, line) {
|
|
16589
|
-
const [keyword,
|
|
16590
|
-
const loc = this.locOf(
|
|
16591
|
-
if (
|
|
16592
|
-
this.error(`Unknown layout mode '${
|
|
16604
|
+
const [keyword, value2] = tokens;
|
|
16605
|
+
const loc = this.locOf(value2, line);
|
|
16606
|
+
if (value2.value !== "ordered") {
|
|
16607
|
+
this.error(`Unknown layout mode '${value2.value}'; the only one is layout ordered`, loc);
|
|
16593
16608
|
return;
|
|
16594
16609
|
}
|
|
16595
16610
|
if (this.top()) {
|
|
@@ -16612,22 +16627,22 @@ var Parser = class _Parser {
|
|
|
16612
16627
|
readRank(tokens, i, line, current) {
|
|
16613
16628
|
const t = tokens[i];
|
|
16614
16629
|
if (!isWord(t, "rank")) return 0;
|
|
16615
|
-
const
|
|
16630
|
+
const value2 = tokens[i + 1];
|
|
16616
16631
|
const help = "a layer number from 0 (rank 0, rank 1, \u2026), rank first or rank last";
|
|
16617
16632
|
if (current.rank !== void 0) {
|
|
16618
16633
|
this.error(`A node takes one rank; rank ${current.rank} is already set`, this.locOf(t, line));
|
|
16619
16634
|
return void 0;
|
|
16620
16635
|
}
|
|
16621
|
-
if (
|
|
16622
|
-
current.rank = Number(
|
|
16636
|
+
if (value2?.kind === "number" && /^\d+$/.test(value2.value)) {
|
|
16637
|
+
current.rank = Number(value2.value);
|
|
16623
16638
|
return 2;
|
|
16624
16639
|
}
|
|
16625
|
-
if (
|
|
16626
|
-
current.rank =
|
|
16640
|
+
if (value2?.kind === "ident" && (value2.value === "first" || value2.value === "last")) {
|
|
16641
|
+
current.rank = value2.value;
|
|
16627
16642
|
return 2;
|
|
16628
16643
|
}
|
|
16629
|
-
const numeric =
|
|
16630
|
-
this.error(numeric ? `'${
|
|
16644
|
+
const numeric = value2?.kind === "number" || value2?.kind === "quantity";
|
|
16645
|
+
this.error(numeric ? `'${value2.value}' is not a layer number; use ${help}` : `Expected ${help} after rank`, this.locOf(value2 ?? t, line));
|
|
16631
16646
|
return void 0;
|
|
16632
16647
|
}
|
|
16633
16648
|
parseImport(tokens, line) {
|
|
@@ -16886,11 +16901,11 @@ var Parser = class _Parser {
|
|
|
16886
16901
|
stub.rps = rps;
|
|
16887
16902
|
i++;
|
|
16888
16903
|
} else if (isWord(t, "p99") || isWord(t, "latency") || isWord(t, "availability")) {
|
|
16889
|
-
const
|
|
16890
|
-
if (
|
|
16891
|
-
if (t.value === "p99") stub.p99Ms =
|
|
16892
|
-
else if (t.value === "latency") stub.latencyMs =
|
|
16893
|
-
else stub.availability =
|
|
16904
|
+
const value2 = this.quantityOf(i + 1 < to ? tokens[i + 1] : void 0, t.value === "availability" ? "%" : "ms", t, line);
|
|
16905
|
+
if (value2 === void 0) return;
|
|
16906
|
+
if (t.value === "p99") stub.p99Ms = value2;
|
|
16907
|
+
else if (t.value === "latency") stub.latencyMs = value2;
|
|
16908
|
+
else stub.availability = value2;
|
|
16894
16909
|
i += 2;
|
|
16895
16910
|
} else {
|
|
16896
16911
|
this.error(`Expected ${STUB_HELP}`, this.locOf(t, line));
|
|
@@ -17272,10 +17287,10 @@ var Parser = class _Parser {
|
|
|
17272
17287
|
else if (n < 1) this.error("A fan-out needs at least one call per request: x1, x2, \u2026", at(match[0].length));
|
|
17273
17288
|
else out.multiplier = n;
|
|
17274
17289
|
} else {
|
|
17275
|
-
const
|
|
17290
|
+
const bytes2 = parseSize(size[1]);
|
|
17276
17291
|
if (out.sizeBytes !== void 0) this.error("The payload size is given twice; write one ~<size>", at(match[0].length));
|
|
17277
|
-
else if ("error" in
|
|
17278
|
-
else out.sizeBytes =
|
|
17292
|
+
else if ("error" in bytes2) this.error(bytes2.error, at(match[0].length));
|
|
17293
|
+
else out.sizeBytes = bytes2.value;
|
|
17279
17294
|
}
|
|
17280
17295
|
offset += match[0].length;
|
|
17281
17296
|
offset += label.slice(offset).length - label.slice(offset).trimStart().length;
|
|
@@ -17345,9 +17360,9 @@ var Parser = class _Parser {
|
|
|
17345
17360
|
return 1;
|
|
17346
17361
|
}
|
|
17347
17362
|
if (isWord(t, "color")) {
|
|
17348
|
-
const
|
|
17349
|
-
if (
|
|
17350
|
-
parts.color =
|
|
17363
|
+
const value2 = this.readColor(tokens[i + 1], t, line);
|
|
17364
|
+
if (value2 === void 0) return void 0;
|
|
17365
|
+
parts.color = value2;
|
|
17351
17366
|
return 2;
|
|
17352
17367
|
}
|
|
17353
17368
|
if (isNode && isWord(t, "critical")) {
|
|
@@ -17619,12 +17634,12 @@ var Parser = class _Parser {
|
|
|
17619
17634
|
} else if (isWord(t, "latency") || isWord(t, "availability") || isWord(t, "cost") || isWord(t, "timeout")) {
|
|
17620
17635
|
part = t.value;
|
|
17621
17636
|
const unit = part === "latency" || part === "timeout" ? "ms" : part === "availability" ? "%" : "usd/month";
|
|
17622
|
-
const
|
|
17623
|
-
if (
|
|
17624
|
-
if (part === "latency") override.latencyMs =
|
|
17625
|
-
else if (part === "timeout") override.timeoutMs =
|
|
17626
|
-
else if (part === "availability") override.availability =
|
|
17627
|
-
else override.costUsd =
|
|
17637
|
+
const value2 = this.quantityOf(tokens[i + 1], unit, t, line);
|
|
17638
|
+
if (value2 === void 0) return;
|
|
17639
|
+
if (part === "latency") override.latencyMs = value2;
|
|
17640
|
+
else if (part === "timeout") override.timeoutMs = value2;
|
|
17641
|
+
else if (part === "availability") override.availability = value2;
|
|
17642
|
+
else override.costUsd = value2;
|
|
17628
17643
|
i += 2;
|
|
17629
17644
|
} else if (isWord(t, "durable") || isWord(t, "volatile")) {
|
|
17630
17645
|
part = "durable or volatile";
|
|
@@ -17632,10 +17647,10 @@ var Parser = class _Parser {
|
|
|
17632
17647
|
i++;
|
|
17633
17648
|
} else if (isWord(t, "reads") || isWord(t, "writes")) {
|
|
17634
17649
|
part = t.value;
|
|
17635
|
-
const
|
|
17636
|
-
if (
|
|
17637
|
-
if (part === "reads") override.readRps =
|
|
17638
|
-
else override.writeRps =
|
|
17650
|
+
const value2 = this.quantityOf(tokens[i + 1], "rps", t, line);
|
|
17651
|
+
if (value2 === void 0) return;
|
|
17652
|
+
if (part === "reads") override.readRps = value2;
|
|
17653
|
+
else override.writeRps = value2;
|
|
17639
17654
|
i += 2;
|
|
17640
17655
|
} else if (isWord(t, "shards")) {
|
|
17641
17656
|
part = "shards";
|
|
@@ -17648,33 +17663,33 @@ var Parser = class _Parser {
|
|
|
17648
17663
|
i += 2;
|
|
17649
17664
|
} else if (isWord(t, "size")) {
|
|
17650
17665
|
part = "size";
|
|
17651
|
-
const
|
|
17652
|
-
if (!isWord(
|
|
17653
|
-
this.error(`Expected S, M or L after size${
|
|
17666
|
+
const value2 = tokens[i + 1];
|
|
17667
|
+
if (!isWord(value2, "S") && !isWord(value2, "M") && !isWord(value2, "L")) {
|
|
17668
|
+
this.error(`Expected S, M or L after size${value2 ? `, not ${describe(value2)}` : ""}`, this.locOf(value2 ?? t, line));
|
|
17654
17669
|
return;
|
|
17655
17670
|
}
|
|
17656
|
-
override.size =
|
|
17671
|
+
override.size = value2.value;
|
|
17657
17672
|
i += 2;
|
|
17658
17673
|
} else if (isWord(t, "consistency")) {
|
|
17659
17674
|
part = "consistency";
|
|
17660
|
-
const
|
|
17661
|
-
if (!isWord(
|
|
17662
|
-
this.error(`Expected strong or eventual after consistency${
|
|
17675
|
+
const value2 = tokens[i + 1];
|
|
17676
|
+
if (!isWord(value2, "strong") && !isWord(value2, "eventual")) {
|
|
17677
|
+
this.error(`Expected strong or eventual after consistency${value2 ? `, not ${describe(value2)}` : ""}`, this.locOf(value2 ?? t, line));
|
|
17663
17678
|
return;
|
|
17664
17679
|
}
|
|
17665
|
-
override.consistency =
|
|
17680
|
+
override.consistency = value2.value;
|
|
17666
17681
|
i += 2;
|
|
17667
17682
|
} else if (isWord(t, "bandwidth") || isWord(t, "egress")) {
|
|
17668
17683
|
part = t.value;
|
|
17669
|
-
const
|
|
17670
|
-
if (
|
|
17684
|
+
const value2 = this.quantityOf(tokens[i + 1], part === "bandwidth" ? "MBps" : "usd/GB", t, line);
|
|
17685
|
+
if (value2 === void 0) return;
|
|
17671
17686
|
if (part === "bandwidth") {
|
|
17672
|
-
if (
|
|
17687
|
+
if (value2 <= 0) {
|
|
17673
17688
|
this.error("Bandwidth must be more than 0", this.locOf(tokens[i + 1], line));
|
|
17674
17689
|
return;
|
|
17675
17690
|
}
|
|
17676
|
-
override.bandwidthMBps =
|
|
17677
|
-
} else override.egressUsdPerGb =
|
|
17691
|
+
override.bandwidthMBps = value2;
|
|
17692
|
+
} else override.egressUsdPerGb = value2;
|
|
17678
17693
|
i += 2;
|
|
17679
17694
|
} else {
|
|
17680
17695
|
this.error(`Unexpected ${describe(t)}; expected ${CAPACITY_PARTS}`, this.locOf(t, line));
|
|
@@ -18123,8 +18138,8 @@ var Parser = class _Parser {
|
|
|
18123
18138
|
let id = base;
|
|
18124
18139
|
for (let n = 2; taken.has(id); n++) id = `${base}-${n}`;
|
|
18125
18140
|
taken.add(id);
|
|
18126
|
-
const
|
|
18127
|
-
const entry2 =
|
|
18141
|
+
const steps4 = this.buildSteps(useCase.id, id, path.steps);
|
|
18142
|
+
const entry2 = steps4[0];
|
|
18128
18143
|
const failedEntry = !!entry2 && (entry2.failed || (entry2.statusCode ?? 0) >= 400);
|
|
18129
18144
|
const condition = path.conditions.join(" \xB7 ");
|
|
18130
18145
|
return {
|
|
@@ -18132,22 +18147,22 @@ var Parser = class _Parser {
|
|
|
18132
18147
|
name: path.names.length ? path.names.join(" \u203A ") : useCase.name,
|
|
18133
18148
|
outcome: failedEntry ? "error" : "success",
|
|
18134
18149
|
...condition ? { condition } : {},
|
|
18135
|
-
steps:
|
|
18150
|
+
steps: steps4,
|
|
18136
18151
|
loc: path.locs.at(-1) ?? useCase.loc
|
|
18137
18152
|
};
|
|
18138
18153
|
});
|
|
18139
|
-
const
|
|
18140
|
-
const entry =
|
|
18154
|
+
const steps3 = scenarios[0]?.steps ?? [];
|
|
18155
|
+
const entry = steps3[0];
|
|
18141
18156
|
return {
|
|
18142
18157
|
...useCase,
|
|
18143
18158
|
entryServiceId: entry?.fromServiceId,
|
|
18144
18159
|
endpoint: entry?.httpMethod ? `${entry.httpMethod} ${entry.endpoint}` : void 0,
|
|
18145
|
-
steps:
|
|
18160
|
+
steps: steps3,
|
|
18146
18161
|
scenarios
|
|
18147
18162
|
};
|
|
18148
18163
|
}
|
|
18149
18164
|
buildSteps(useCaseId, scenarioId, raw) {
|
|
18150
|
-
const
|
|
18165
|
+
const steps3 = [];
|
|
18151
18166
|
const answered = /* @__PURE__ */ new Set();
|
|
18152
18167
|
const prefix = scenarioId === "main" ? useCaseId : `${useCaseId}-${scenarioId}`;
|
|
18153
18168
|
for (const step of raw) {
|
|
@@ -18155,7 +18170,7 @@ var Parser = class _Parser {
|
|
|
18155
18170
|
if (step.arrow === "-->") {
|
|
18156
18171
|
const [respFrom] = this.splitRef(step.from);
|
|
18157
18172
|
const [respTo] = this.splitRef(step.to);
|
|
18158
|
-
const request2 = [...
|
|
18173
|
+
const request2 = [...steps3].reverse().find((s) => s.fromServiceId === respTo && s.toServiceId === respFrom && !answered.has(s) && !s.failed);
|
|
18159
18174
|
if (!request2) {
|
|
18160
18175
|
this.warning(`Response has no matching request from '${step.to}' to '${step.from}'`, step.loc);
|
|
18161
18176
|
continue;
|
|
@@ -18179,9 +18194,9 @@ var Parser = class _Parser {
|
|
|
18179
18194
|
const port = toPort ?? this.onlyEntry(to, step.loc);
|
|
18180
18195
|
const target = this.nodes.get(to);
|
|
18181
18196
|
const isAsync = step.arrow === "->>";
|
|
18182
|
-
|
|
18183
|
-
id: `${prefix}-${
|
|
18184
|
-
stepOrder:
|
|
18197
|
+
steps3.push({
|
|
18198
|
+
id: `${prefix}-${steps3.length + 1}`,
|
|
18199
|
+
stepOrder: steps3.length,
|
|
18185
18200
|
stepName: label.name || `${step.from} \u2192 ${step.to}`,
|
|
18186
18201
|
fromServiceId: from,
|
|
18187
18202
|
toServiceId: to,
|
|
@@ -18205,7 +18220,7 @@ var Parser = class _Parser {
|
|
|
18205
18220
|
...fromPort !== void 0 ? { fromPort } : {}
|
|
18206
18221
|
});
|
|
18207
18222
|
}
|
|
18208
|
-
return
|
|
18223
|
+
return steps3;
|
|
18209
18224
|
}
|
|
18210
18225
|
/**
|
|
18211
18226
|
* Warns when a step talks between two nodes the architecture never connects.
|
|
@@ -18357,19 +18372,6 @@ function expand(items) {
|
|
|
18357
18372
|
}
|
|
18358
18373
|
return paths;
|
|
18359
18374
|
}
|
|
18360
|
-
function qualify(tokens) {
|
|
18361
|
-
let out;
|
|
18362
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
18363
|
-
const [t, next] = [tokens[i], tokens[i + 1]];
|
|
18364
|
-
const joined = t.kind === "ident" && next?.kind === "tag" && next.col === t.col + t.length;
|
|
18365
|
-
if (joined && (tokens[i + 2]?.kind === "arrow" || tokens[i - 1]?.kind === "arrow")) {
|
|
18366
|
-
out ??= tokens.slice(0, i);
|
|
18367
|
-
out.push({ ...t, value: `${t.value}.${next.value}`, length: t.length + next.length });
|
|
18368
|
-
i++;
|
|
18369
|
-
} else out?.push(t);
|
|
18370
|
-
}
|
|
18371
|
-
return out ?? tokens;
|
|
18372
|
-
}
|
|
18373
18375
|
function findUseCaseIn(diagram, name) {
|
|
18374
18376
|
const lower = name.toLowerCase();
|
|
18375
18377
|
return diagram.useCases.find((u) => u.name === name) ?? diagram.useCases.find((u) => u.name.toLowerCase() === lower) ?? diagram.useCases.find((u) => u.id === name);
|
|
@@ -18395,8 +18397,8 @@ function splitPayload(input) {
|
|
|
18395
18397
|
const formats = { json: "JSON", xml: "XML", text: "FREE_TEXT" };
|
|
18396
18398
|
const leading = text.match(/^(json|xml|text)\s+([\s\S]+)$/i);
|
|
18397
18399
|
if (leading) return { text: "", format: formats[leading[1].toLowerCase()], body: leading[2].trim() };
|
|
18398
|
-
const
|
|
18399
|
-
if (
|
|
18400
|
+
const keyed2 = text.match(/^([\s\S]*?)\s+(json|xml)\s+([{[<][\s\S]*)$/i);
|
|
18401
|
+
if (keyed2) return { text: keyed2[1].trim(), format: formats[keyed2[2].toLowerCase()], body: keyed2[3].trim() };
|
|
18400
18402
|
const bare = text.search(/(^|\s)[{[<]/);
|
|
18401
18403
|
if (bare !== -1) {
|
|
18402
18404
|
const body = text.slice(bare).trim();
|
|
@@ -18426,9 +18428,9 @@ function parseSize(text) {
|
|
|
18426
18428
|
if (!m) return { error: `Expected a payload size after ~, e.g. ~2MB, ~500KB or ~1.5GB${text ? `, not '~${text}'` : ""}` };
|
|
18427
18429
|
const factor = SIZE_UNITS[m[2]];
|
|
18428
18430
|
if (factor === void 0) return { error: m[2] ? `Unknown size unit '${m[2]}' in '~${text}'; use B, KB, MB, GB or TB` : `'~${text}' needs a unit: B, KB, MB, GB or TB` };
|
|
18429
|
-
const
|
|
18430
|
-
if (
|
|
18431
|
-
return { value };
|
|
18431
|
+
const value2 = Math.round(Number(m[1]) * factor);
|
|
18432
|
+
if (value2 <= 0) return { error: `A payload size must be more than 0, not '~${text}'` };
|
|
18433
|
+
return { value: value2 };
|
|
18432
18434
|
}
|
|
18433
18435
|
function inferProtocol(isAsync, method, target) {
|
|
18434
18436
|
if (isAsync || target?.type === "queue" || target?.type === "broker") return "MESSAGING";
|
|
@@ -18550,8 +18552,8 @@ function nodeLine(node) {
|
|
|
18550
18552
|
if (node.description) parts.push(quote(node.description));
|
|
18551
18553
|
return parts.join(" ");
|
|
18552
18554
|
}
|
|
18553
|
-
function stepLines(
|
|
18554
|
-
for (const step of
|
|
18555
|
+
function stepLines(steps3, indent2, out) {
|
|
18556
|
+
for (const step of steps3) {
|
|
18555
18557
|
if (step.kind === "step") {
|
|
18556
18558
|
out.push(`${indent2}${step.from} ${step.arrow} ${step.to}${step.label ? ` : ${step.label}` : ""}`);
|
|
18557
18559
|
} else if (step.kind === "par") {
|
|
@@ -18787,8 +18789,8 @@ var OpenApiSpec = class {
|
|
|
18787
18789
|
const item = this.resolve(`/paths/${esc(path)}`);
|
|
18788
18790
|
if (!item || !isObject2(item.value)) return void 0;
|
|
18789
18791
|
const m = method.toLowerCase();
|
|
18790
|
-
const
|
|
18791
|
-
return isObject2(
|
|
18792
|
+
const value2 = item.value[m];
|
|
18793
|
+
return isObject2(value2) ? { path, method: method.toUpperCase(), pointer: `${item.pointer}/${m}`, value: value2 } : void 0;
|
|
18792
18794
|
}
|
|
18793
18795
|
/** Documented response keys of an operation: `201`, `4XX`, `default`. */
|
|
18794
18796
|
statuses(op) {
|
|
@@ -18830,23 +18832,23 @@ var OpenApiSpec = class {
|
|
|
18830
18832
|
}
|
|
18831
18833
|
/** Follows local `$ref`s from the value at a JSON pointer; returns the final pointer and value. */
|
|
18832
18834
|
resolve(pointer) {
|
|
18833
|
-
let
|
|
18834
|
-
for (let hops = 0; isObject2(
|
|
18835
|
-
if (!
|
|
18836
|
-
pointer = decodeURIComponent(
|
|
18837
|
-
|
|
18835
|
+
let value2 = this.at(pointer);
|
|
18836
|
+
for (let hops = 0; isObject2(value2) && typeof value2.$ref === "string" && hops < 20; hops++) {
|
|
18837
|
+
if (!value2.$ref.startsWith("#")) return void 0;
|
|
18838
|
+
pointer = decodeURIComponent(value2.$ref.slice(1));
|
|
18839
|
+
value2 = this.at(pointer);
|
|
18838
18840
|
}
|
|
18839
|
-
return
|
|
18841
|
+
return value2 === void 0 ? void 0 : { pointer, value: value2 };
|
|
18840
18842
|
}
|
|
18841
18843
|
at(pointer) {
|
|
18842
|
-
let
|
|
18844
|
+
let value2 = this.doc;
|
|
18843
18845
|
for (const raw of pointer.split("/").slice(1)) {
|
|
18844
18846
|
const key = raw.replace(/~1/g, "/").replace(/~0/g, "~");
|
|
18845
|
-
if (Array.isArray(
|
|
18846
|
-
else if (isObject2(
|
|
18847
|
+
if (Array.isArray(value2)) value2 = value2[Number(key)];
|
|
18848
|
+
else if (isObject2(value2)) value2 = value2[key];
|
|
18847
18849
|
else return void 0;
|
|
18848
18850
|
}
|
|
18849
|
-
return
|
|
18851
|
+
return value2;
|
|
18850
18852
|
}
|
|
18851
18853
|
};
|
|
18852
18854
|
function describeError(e) {
|
|
@@ -18857,11 +18859,11 @@ function describeError(e) {
|
|
|
18857
18859
|
if (e.keyword === "enum" && Array.isArray(p.allowedValues)) message += `: ${p.allowedValues.map((v) => JSON.stringify(v)).join(", ")}`;
|
|
18858
18860
|
return `${where} ${message}`;
|
|
18859
18861
|
}
|
|
18860
|
-
function from30(
|
|
18861
|
-
if (Array.isArray(
|
|
18862
|
-
if (!isObject2(
|
|
18862
|
+
function from30(value2) {
|
|
18863
|
+
if (Array.isArray(value2)) return value2.map(from30);
|
|
18864
|
+
if (!isObject2(value2)) return value2;
|
|
18863
18865
|
const out = {};
|
|
18864
|
-
for (const [k, v] of Object.entries(
|
|
18866
|
+
for (const [k, v] of Object.entries(value2)) out[k] = from30(v);
|
|
18865
18867
|
for (const [bool, bound] of [
|
|
18866
18868
|
["exclusiveMinimum", "minimum"],
|
|
18867
18869
|
["exclusiveMaximum", "maximum"]
|
|
@@ -19019,10 +19021,10 @@ function readConfig(file) {
|
|
|
19019
19021
|
configs.set(file, { mtimeMs, config });
|
|
19020
19022
|
return config;
|
|
19021
19023
|
}
|
|
19022
|
-
function parseSpecFlag(
|
|
19023
|
-
const eq =
|
|
19024
|
-
if (eq <= 0 || eq ===
|
|
19025
|
-
return [
|
|
19024
|
+
function parseSpecFlag(value2) {
|
|
19025
|
+
const eq = value2.indexOf("=");
|
|
19026
|
+
if (eq <= 0 || eq === value2.length - 1) return void 0;
|
|
19027
|
+
return [value2.slice(0, eq), (0, import_node_path3.resolve)(value2.slice(eq + 1))];
|
|
19026
19028
|
}
|
|
19027
19029
|
function openApiDiagnostics(file, diagram, overrides = {}) {
|
|
19028
19030
|
let specs = {};
|
|
@@ -19058,6 +19060,152 @@ var RENDER_HELP = `render Writes the diagram as static files into --out (defaul
|
|
|
19058
19060
|
var import_node_fs3 = require("node:fs");
|
|
19059
19061
|
var import_node_path4 = require("node:path");
|
|
19060
19062
|
|
|
19063
|
+
// ../frontend/src/dsl/diff.ts
|
|
19064
|
+
var byKey2 = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
19065
|
+
function canonical(value2) {
|
|
19066
|
+
return JSON.stringify(value2, (key, v) => {
|
|
19067
|
+
if (key === "loc" || key === "responseLoc") return void 0;
|
|
19068
|
+
if (v && typeof v === "object" && !Array.isArray(v)) return Object.fromEntries(Object.entries(v).sort(([a], [b]) => byKey2(a, b)));
|
|
19069
|
+
return v;
|
|
19070
|
+
});
|
|
19071
|
+
}
|
|
19072
|
+
function keyed(items, key) {
|
|
19073
|
+
const map = /* @__PURE__ */ new Map();
|
|
19074
|
+
for (const item of items) {
|
|
19075
|
+
const base = key(item);
|
|
19076
|
+
let k = base;
|
|
19077
|
+
for (let n = 2; map.has(k); n++) k = `${base}#${n}`;
|
|
19078
|
+
map.set(k, item);
|
|
19079
|
+
}
|
|
19080
|
+
return map;
|
|
19081
|
+
}
|
|
19082
|
+
function fieldChanges(before2, after2) {
|
|
19083
|
+
return [.../* @__PURE__ */ new Set([...Object.keys(before2), ...Object.keys(after2)])].filter((field) => canonical(before2[field]) !== canonical(after2[field])).map((field) => ({ field, before: before2[field], after: after2[field] }));
|
|
19084
|
+
}
|
|
19085
|
+
function diffBy(before2, after2, key, fields, keyAfter = key) {
|
|
19086
|
+
const old = keyed(before2, key);
|
|
19087
|
+
const next = keyed(after2, keyAfter);
|
|
19088
|
+
const diff = { added: [], removed: [], changed: [] };
|
|
19089
|
+
for (const k of [...old.keys()].sort(byKey2)) if (!next.has(k)) diff.removed.push(old.get(k));
|
|
19090
|
+
for (const k of [...next.keys()].sort(byKey2)) {
|
|
19091
|
+
const b = old.get(k);
|
|
19092
|
+
const a = next.get(k);
|
|
19093
|
+
if (b === void 0) {
|
|
19094
|
+
diff.added.push(a);
|
|
19095
|
+
continue;
|
|
19096
|
+
}
|
|
19097
|
+
const changes = fieldChanges(fields(b), fields(a));
|
|
19098
|
+
if (changes.length) diff.changed.push({ key: k, before: b, after: a, changes });
|
|
19099
|
+
}
|
|
19100
|
+
return diff;
|
|
19101
|
+
}
|
|
19102
|
+
function withoutLoc({ loc: _loc, ...rest }) {
|
|
19103
|
+
void _loc;
|
|
19104
|
+
return rest;
|
|
19105
|
+
}
|
|
19106
|
+
function stepText(step) {
|
|
19107
|
+
const arrow = step.failed ? "-x" : step.executionType === "SYNC_REQUEST_RESPONSE" ? "->" : "->>";
|
|
19108
|
+
const prefixes = `${step.multiplier !== void 0 ? `x${step.multiplier} ` : ""}${step.sizeBytes !== void 0 ? `~${step.sizeBytes}B ` : ""}`;
|
|
19109
|
+
const label = `${prefixes}${step.stepName}`.trim();
|
|
19110
|
+
const reply = [step.statusCode, step.responseBody].filter((x) => x !== void 0 && x !== "").join(" ");
|
|
19111
|
+
const flags = `${step.isParallel ? " [par]" : ""}${step.isConditional ? ` [if ${step.conditionExpression ?? ""}]` : ""}`;
|
|
19112
|
+
return `${step.fromServiceId} ${arrow} ${step.toServiceId}${label ? ` : ${label}` : ""}${reply ? ` --> ${reply}` : ""}${flags}`;
|
|
19113
|
+
}
|
|
19114
|
+
var steps2 = (list) => list.map(stepText);
|
|
19115
|
+
var nodeFields = (n) => ({
|
|
19116
|
+
kind: n.kind,
|
|
19117
|
+
name: n.name,
|
|
19118
|
+
type: n.type,
|
|
19119
|
+
techStack: n.techStack,
|
|
19120
|
+
ownerTeam: n.ownerTeam,
|
|
19121
|
+
description: n.description,
|
|
19122
|
+
parent: n.parent,
|
|
19123
|
+
replicas: n.replicas,
|
|
19124
|
+
color: n.color,
|
|
19125
|
+
tag: n.tag,
|
|
19126
|
+
critical: n.critical,
|
|
19127
|
+
rank: n.rank,
|
|
19128
|
+
direction: n.direction,
|
|
19129
|
+
style: n.style,
|
|
19130
|
+
system: n.system,
|
|
19131
|
+
position: n.position
|
|
19132
|
+
});
|
|
19133
|
+
function edgeKey(edges) {
|
|
19134
|
+
const pairs = /* @__PURE__ */ new Map();
|
|
19135
|
+
for (const e of edges) pairs.set(`${e.source}->${e.target}`, (pairs.get(`${e.source}->${e.target}`) ?? 0) + 1);
|
|
19136
|
+
return (e) => {
|
|
19137
|
+
const pair = `${e.source}->${e.target}`;
|
|
19138
|
+
return pairs.get(pair) > 1 ? `${pair} : ${e.label ?? ""}` : pair;
|
|
19139
|
+
};
|
|
19140
|
+
}
|
|
19141
|
+
var edgeFields = (e) => ({ label: e.label, tag: e.tag, style: e.style, sourcePort: e.sourcePort, targetPort: e.targetPort });
|
|
19142
|
+
var useCaseFields = (u) => ({
|
|
19143
|
+
name: u.name,
|
|
19144
|
+
description: u.description,
|
|
19145
|
+
entryServiceId: u.entryServiceId,
|
|
19146
|
+
endpoint: u.endpoint,
|
|
19147
|
+
steps: steps2(u.steps)
|
|
19148
|
+
});
|
|
19149
|
+
var scenarioFields = ({ scenario: s }) => ({ name: s.name, outcome: s.outcome, condition: s.condition, steps: steps2(s.steps) });
|
|
19150
|
+
var scenariosOf = (d) => d.useCases.flatMap((u) => u.scenarios.map((scenario) => ({ useCase: u.id, scenario })));
|
|
19151
|
+
function requirementKey(r) {
|
|
19152
|
+
switch (r.kind) {
|
|
19153
|
+
case "latency":
|
|
19154
|
+
return `latency p${r.percentile} ${r.useCase ?? "*"}${r.scenario ? `/${r.scenario}` : ""}`;
|
|
19155
|
+
case "availability":
|
|
19156
|
+
return `availability ${r.useCase ?? "*"}`;
|
|
19157
|
+
case "durable":
|
|
19158
|
+
return `durable ${r.useCase}`;
|
|
19159
|
+
case "survive":
|
|
19160
|
+
return `survive ${canonical(r.target)}`;
|
|
19161
|
+
case "cost":
|
|
19162
|
+
return "cost";
|
|
19163
|
+
}
|
|
19164
|
+
}
|
|
19165
|
+
function requirementFields(r) {
|
|
19166
|
+
switch (r.kind) {
|
|
19167
|
+
case "latency":
|
|
19168
|
+
return { maxMs: r.maxMs };
|
|
19169
|
+
case "availability":
|
|
19170
|
+
return { minPercent: r.minPercent };
|
|
19171
|
+
case "cost":
|
|
19172
|
+
return { maxUsdPerMonth: r.maxUsdPerMonth };
|
|
19173
|
+
default:
|
|
19174
|
+
return {};
|
|
19175
|
+
}
|
|
19176
|
+
}
|
|
19177
|
+
var systemFields = (s) => ({
|
|
19178
|
+
from: s.from,
|
|
19179
|
+
entries: s.entries.map((e) => `${e.id}${e.name !== e.id ? ` "${e.name}"` : ""}${e.useCase ? ` -> "${e.useCase}"` : ""}`),
|
|
19180
|
+
stub: s.stub && withoutLoc(s.stub)
|
|
19181
|
+
});
|
|
19182
|
+
function diffDiagrams(before2, after2) {
|
|
19183
|
+
return {
|
|
19184
|
+
diagram: fieldChanges({ title: before2.title, summary: before2.summary }, { title: after2.title, summary: after2.summary }),
|
|
19185
|
+
nodes: diffBy(before2.nodes, after2.nodes, (n) => n.id, nodeFields),
|
|
19186
|
+
edges: diffBy(before2.edges, after2.edges, edgeKey(before2.edges), edgeFields, edgeKey(after2.edges)),
|
|
19187
|
+
useCases: diffBy(before2.useCases, after2.useCases, (u) => u.id, useCaseFields),
|
|
19188
|
+
scenarios: diffBy(scenariosOf(before2), scenariosOf(after2), (s) => `${s.useCase}/${s.scenario.id}`, scenarioFields),
|
|
19189
|
+
requirements: diffBy(before2.requirements ?? [], after2.requirements ?? [], requirementKey, requirementFields),
|
|
19190
|
+
traffic: diffBy(before2.traffic ?? [], after2.traffic ?? [], (t) => t.useCase, (t) => ({ rps: t.rps, mix: t.mix })),
|
|
19191
|
+
capacity: diffBy(before2.capacity ?? [], after2.capacity ?? [], (c) => c.node, withoutLoc),
|
|
19192
|
+
systems: diffBy(before2.systems ?? [], after2.systems ?? [], (s) => s.id, systemFields)
|
|
19193
|
+
};
|
|
19194
|
+
}
|
|
19195
|
+
var DIFF_SECTIONS = ["nodes", "edges", "useCases", "scenarios", "requirements", "traffic", "capacity", "systems"];
|
|
19196
|
+
function summarizeDiff(diff) {
|
|
19197
|
+
const total = { added: 0, removed: 0, changed: diff.diagram.length };
|
|
19198
|
+
const counts = { total };
|
|
19199
|
+
for (const section2 of DIFF_SECTIONS) {
|
|
19200
|
+
const { added, removed, changed } = diff[section2];
|
|
19201
|
+
counts[section2] = { added: added.length, removed: removed.length, changed: changed.length };
|
|
19202
|
+
total.added += added.length;
|
|
19203
|
+
total.removed += removed.length;
|
|
19204
|
+
total.changed += changed.length;
|
|
19205
|
+
}
|
|
19206
|
+
return counts;
|
|
19207
|
+
}
|
|
19208
|
+
|
|
19061
19209
|
// ../frontend/src/dsl/sequence.ts
|
|
19062
19210
|
var PAYLOAD_LIMIT = 40;
|
|
19063
19211
|
function shorten(text, max = PAYLOAD_LIMIT) {
|
|
@@ -19109,9 +19257,9 @@ function buildSequence(useCase, scenario, nodes = []) {
|
|
|
19109
19257
|
const depth = stack.map((s) => s.toServiceId).lastIndexOf(from);
|
|
19110
19258
|
while (stack.length > depth + 1) emit(response(stack.pop()));
|
|
19111
19259
|
};
|
|
19112
|
-
const
|
|
19113
|
-
for (let i = 0; i <
|
|
19114
|
-
const step =
|
|
19260
|
+
const steps3 = scenario.steps;
|
|
19261
|
+
for (let i = 0; i < steps3.length; i++) {
|
|
19262
|
+
const step = steps3[i];
|
|
19115
19263
|
if (step.parallelGroup === void 0) {
|
|
19116
19264
|
unwindFor(step.fromServiceId);
|
|
19117
19265
|
emit(request(step));
|
|
@@ -19119,7 +19267,7 @@ function buildSequence(useCase, scenario, nodes = []) {
|
|
|
19119
19267
|
continue;
|
|
19120
19268
|
}
|
|
19121
19269
|
const group = [];
|
|
19122
|
-
while (i <
|
|
19270
|
+
while (i < steps3.length && steps3[i].parallelGroup === step.parallelGroup) group.push(steps3[i++]);
|
|
19123
19271
|
i--;
|
|
19124
19272
|
unwindFor(step.fromServiceId);
|
|
19125
19273
|
items.push({ kind: "par", branches: group.map((s) => hasResponse(s) ? [request(s), response(s)] : [request(s)]) });
|
|
@@ -19134,7 +19282,7 @@ function buildSequence(useCase, scenario, nodes = []) {
|
|
|
19134
19282
|
const node = byId.get(id);
|
|
19135
19283
|
participants.push({ id, name: node?.name ?? id, tech: node && !node.implicit ? node.techStack : void 0 });
|
|
19136
19284
|
};
|
|
19137
|
-
for (const step of
|
|
19285
|
+
for (const step of steps3) {
|
|
19138
19286
|
add(step.fromServiceId);
|
|
19139
19287
|
add(step.toServiceId);
|
|
19140
19288
|
}
|
|
@@ -19622,7 +19770,7 @@ function sharedLoad(root, rootInbound) {
|
|
|
19622
19770
|
}
|
|
19623
19771
|
};
|
|
19624
19772
|
visit(root, "");
|
|
19625
|
-
const
|
|
19773
|
+
const send2 = (d, prefix, inbound) => {
|
|
19626
19774
|
for (const s of d.systems ?? []) {
|
|
19627
19775
|
if (!s.diagram) continue;
|
|
19628
19776
|
const key = teamKey(s);
|
|
@@ -19632,12 +19780,12 @@ function sharedLoad(root, rootInbound) {
|
|
|
19632
19780
|
if (rps > 0) load.callers.push({ path: prefix ? `${prefix}.${s.id}` : s.id, ...d.title !== void 0 ? { from: d.title } : {}, rps });
|
|
19633
19781
|
}
|
|
19634
19782
|
};
|
|
19635
|
-
|
|
19783
|
+
send2(root, "", rootInbound);
|
|
19636
19784
|
for (const key of order.reverse()) {
|
|
19637
19785
|
const { diagram, path, loc } = designs.get(key);
|
|
19638
19786
|
if (!diagram.systems?.length) continue;
|
|
19639
19787
|
const combined = withExtraTraffic(diagram, byFile.get(key)?.useCases ?? /* @__PURE__ */ new Map(), loc);
|
|
19640
|
-
|
|
19788
|
+
send2(diagram, path, inboundLoad(combined, resolveTraffic(combined)));
|
|
19641
19789
|
}
|
|
19642
19790
|
return { byFile, analyses: /* @__PURE__ */ new Map() };
|
|
19643
19791
|
}
|
|
@@ -19755,8 +19903,8 @@ function breachesOf(team, sent, analysis) {
|
|
|
19755
19903
|
if (r.scenario !== void 0 && !scenario) continue;
|
|
19756
19904
|
const what = `${key} of "${u.name}"${scenario ? ` scenario "${scenario.name}"` : ""}`;
|
|
19757
19905
|
const name = `${what} < ${formatMs(r.maxMs)}`;
|
|
19758
|
-
const
|
|
19759
|
-
const saturated =
|
|
19906
|
+
const steps3 = scenario ? scenario.steps : u.scenarios.flatMap((s) => s.steps);
|
|
19907
|
+
const saturated = steps3.map((s) => nodes.get(s.toServiceId)).reduce((best, n) => n?.saturated && (!best || n.utilization > best.utilization) ? n : best, void 0);
|
|
19760
19908
|
if (saturated) {
|
|
19761
19909
|
breaches.push({ requirement: name, message: `${what}: ${saturated.id} is saturated (${usageText(saturated)}) ${under} (limit ${formatMs(r.maxMs)})` });
|
|
19762
19910
|
continue;
|
|
@@ -19848,13 +19996,13 @@ function computeEgressGb(diagram, traffic, kindOf2 = (id) => profileOfId(diagram
|
|
|
19848
19996
|
}
|
|
19849
19997
|
var BANDWIDTH_BOUND = (kind) => !["client", "external", "dns", "other", "storage", "cdn"].includes(kind);
|
|
19850
19998
|
function computeBytesPerSecond(diagram, traffic) {
|
|
19851
|
-
const
|
|
19999
|
+
const bytes2 = /* @__PURE__ */ new Map();
|
|
19852
20000
|
forEachStepRate(diagram, traffic, (step, rate) => {
|
|
19853
20001
|
if (!step.sizeBytes || step.sizeBytes <= 0) return;
|
|
19854
20002
|
const b = rate * multiplierOf(step) * step.sizeBytes;
|
|
19855
|
-
for (const id of /* @__PURE__ */ new Set([step.fromServiceId, step.toServiceId]))
|
|
20003
|
+
for (const id of /* @__PURE__ */ new Set([step.fromServiceId, step.toServiceId])) bytes2.set(id, (bytes2.get(id) ?? 0) + b);
|
|
19856
20004
|
});
|
|
19857
|
-
return
|
|
20005
|
+
return bytes2;
|
|
19858
20006
|
}
|
|
19859
20007
|
function profileOfId(diagram, id) {
|
|
19860
20008
|
const node = diagram.nodes.find((n) => n.id === id);
|
|
@@ -20010,14 +20158,14 @@ function analyze(diagram, options = {}) {
|
|
|
20010
20158
|
const traffic = resolveTraffic(diagram, warnings);
|
|
20011
20159
|
const load = computeLoad(diagram, traffic);
|
|
20012
20160
|
const egress = computeEgressGb(diagram, traffic, kindOf2);
|
|
20013
|
-
const
|
|
20161
|
+
const bytes2 = computeBytesPerSecond(diagram, traffic);
|
|
20014
20162
|
const systems = diagram.systems?.length ? analyzeSystems(diagram, traffic, options) : void 0;
|
|
20015
20163
|
const hops = /* @__PURE__ */ new Map();
|
|
20016
20164
|
const nodeResults = nodes.map((n) => {
|
|
20017
20165
|
const p = profiles.get(n.id);
|
|
20018
20166
|
const replicas = Math.max(1, options.replicas?.get(n.id) ?? replicasOf(n));
|
|
20019
20167
|
const { read, write } = load.get(n.id) ?? { read: 0, write: 0 };
|
|
20020
|
-
const usage = usageOf(p, replicas, read, write,
|
|
20168
|
+
const usage = usageOf(p, replicas, read, write, bytes2.get(n.id) ?? 0);
|
|
20021
20169
|
const servers = serversOf(usage, replicas);
|
|
20022
20170
|
const hop = hopModel(p.latencyMs, usage.utilization, servers);
|
|
20023
20171
|
hops.set(n.id, hop);
|
|
@@ -20193,7 +20341,7 @@ var CATEGORY = {
|
|
|
20193
20341
|
};
|
|
20194
20342
|
var percentileName = (q) => PERCENTILE_KEYS[q];
|
|
20195
20343
|
var lineOf = (loc) => `${loc.file ? `${loc.file}:` : "line "}${loc.line}`;
|
|
20196
|
-
function
|
|
20344
|
+
function stepText2(step) {
|
|
20197
20345
|
const arrow = step.failed ? "-x" : step.executionType === "SYNC_REQUEST_RESPONSE" ? "->" : "->>";
|
|
20198
20346
|
const label = requestLabel(step);
|
|
20199
20347
|
return `${step.fromServiceId} ${arrow} ${step.toServiceId}${label ? ` : ${label}` : ""} at ${lineOf(step.loc)}`;
|
|
@@ -20248,10 +20396,10 @@ function unknownUseCase(run2, name) {
|
|
|
20248
20396
|
const hint = near.length ? `Use one of ${near.map((u) => quote2(u.name)).join(", ")}` : `Add usecase ${quote2(name)} { \u2026 }`;
|
|
20249
20397
|
return { ...fail(`No use case named ${quote2(name)}`, hint), missing: `use case ${name}` };
|
|
20250
20398
|
}
|
|
20251
|
-
function saturatedOn(run2, ids,
|
|
20399
|
+
function saturatedOn(run2, ids, value2, maxMs) {
|
|
20252
20400
|
const n = [...new Set(ids)].map((id) => run2.nodes.get(id)).find((x) => !!x?.saturated);
|
|
20253
20401
|
if (!n) return void 0;
|
|
20254
|
-
const v =
|
|
20402
|
+
const v = value2(n);
|
|
20255
20403
|
return { ...fail(`${v} (limit ${formatMs(maxMs)})`, saturationHint(run2, n)), value: v };
|
|
20256
20404
|
}
|
|
20257
20405
|
function latency(run2, u, q, maxMs) {
|
|
@@ -20262,12 +20410,12 @@ function latency(run2, u, q, maxMs) {
|
|
|
20262
20410
|
const saturated = saturatedOn(run2, touched, (n) => `${key} of ${u.name}: ${n.id} is saturated (${usageText(n)})`, maxMs);
|
|
20263
20411
|
if (saturated) return saturated;
|
|
20264
20412
|
const ms = result.percentiles[key];
|
|
20265
|
-
const
|
|
20266
|
-
const message = `${
|
|
20267
|
-
if (ms < maxMs) return { ...pass(message), value };
|
|
20413
|
+
const value2 = `${key} of ${u.name} is ${formatMs(ms)}${result.rps > 0 ? "" : " with no traffic"}`;
|
|
20414
|
+
const message = `${value2} (limit ${formatMs(maxMs)})`;
|
|
20415
|
+
if (ms < maxMs) return { ...pass(message), value: value2 };
|
|
20268
20416
|
const index = Math.min(result.tailScenario[key] ?? 0, u.scenarios.length - 1);
|
|
20269
20417
|
const lead = u.scenarios.length > 1 ? `The "${u.scenarios[index].name}" path (${formatPercent(result.scenarios[index].share)} of traffic) sets ${key}. ` : "";
|
|
20270
|
-
return { ...fail(message, lead + latencyHint(run2, u, u.scenarios[index])), value };
|
|
20418
|
+
return { ...fail(message, lead + latencyHint(run2, u, u.scenarios[index])), value: value2 };
|
|
20271
20419
|
}
|
|
20272
20420
|
function scenarioLatency(run2, useCase, scenario, q, maxMs) {
|
|
20273
20421
|
const sc = scope(run2, useCase, scenario);
|
|
@@ -20308,14 +20456,14 @@ function latencyHint(run2, u, scenario) {
|
|
|
20308
20456
|
const sized = hops.find((h) => (h.step.sizeBytes ?? 0) > 0);
|
|
20309
20457
|
const node = run2.nodes.get(slowest.target);
|
|
20310
20458
|
if (node && node.utilization > HOT) return `${label} runs at ${formatPercent(node.utilization)} and queues requests; add replicas to it.`;
|
|
20311
|
-
const payload = sized ? ` Payloads add transfer time too (${
|
|
20459
|
+
const payload = sized ? ` Payloads add transfer time too (${stepText2(sized.step)}): send fewer bytes or let the client fetch them from a CDN or storage directly.` : "";
|
|
20312
20460
|
return `Its slowest hop is ${label} at ${formatMs(cost3(slowest))}: put a cache in front of it, run independent calls in par, or move work off the request path with ->>.${payload}`;
|
|
20313
20461
|
}
|
|
20314
20462
|
function availability(run2, u, minPercent) {
|
|
20315
20463
|
const result = run2.useCases.get(u.id);
|
|
20316
|
-
const
|
|
20317
|
-
const message = `${
|
|
20318
|
-
if (result.availability * 100 >= minPercent - 1e-9) return { ...pass(message), value };
|
|
20464
|
+
const value2 = `availability of ${u.name} is ${formatAvailability(result.availability)}`;
|
|
20465
|
+
const message = `${value2} (limit ${minPercent}%)`;
|
|
20466
|
+
if (result.availability * 100 >= minPercent - 1e-9) return { ...pass(message), value: value2 };
|
|
20319
20467
|
const shares = run2.shares.get(u.id) ?? [];
|
|
20320
20468
|
const main = u.scenarios.length ? pathNodes(u, u.scenarios[mainScenarioIndex(shares)]) : [];
|
|
20321
20469
|
const writes = mainWrites(u, shares, run2.isWrite);
|
|
@@ -20323,7 +20471,7 @@ function availability(run2, u, minPercent) {
|
|
|
20323
20471
|
const weakest = main.filter((id) => fallbacksFor(u, id).length === 0).map((id) => run2.nodes.get(id)).filter((n) => !!n && effective(n) < 1).sort((a, b) => effective(a) - effective(b))[0];
|
|
20324
20472
|
const primaryBound = weakest && writes.has(weakest.id) && weakest.writeAvailability < weakest.availability;
|
|
20325
20473
|
const hint = !weakest ? "Add replicas to the nodes on the main path, or fallback scenarios that complete without them" : primaryBound ? `The weakest link is writing to ${nodeLabel(run2.diagram, weakest.id)}: writes need its primary, ${formatAvailability(weakest.writeAvailability)} with failover${weakest.replicas < 2 ? " (none without a second replica; add one)" : ` (a replica takes over, but about ${formatPercent(FAILOVER_SHARE)} of each outage is lost)`}. Move the writes to a partitioned store, or add a fallback scenario that calls it with -x and still completes` : `The weakest link is ${nodeLabel(run2.diagram, weakest.id)} at ${formatAvailability(effective(weakest))}: add a replica (x${weakest.replicas + 1}) or a fallback scenario that calls it with -x and still completes`;
|
|
20326
|
-
return { ...fail(message, hint), value };
|
|
20474
|
+
return { ...fail(message, hint), value: value2 };
|
|
20327
20475
|
}
|
|
20328
20476
|
function writeGap(run2, u, s, accept) {
|
|
20329
20477
|
const { requests, beforeResponse } = requestOrder(u, s);
|
|
@@ -20350,11 +20498,11 @@ function writesCheck(run2, u, scenarios, accept, what) {
|
|
|
20350
20498
|
const text = (s, gap) => {
|
|
20351
20499
|
switch (gap.kind) {
|
|
20352
20500
|
case "async":
|
|
20353
|
-
return `${where(s)} writes to ${what} only asynchronously: ${
|
|
20501
|
+
return `${where(s)} writes to ${what} only asynchronously: ${stepText2(gap.step)}`;
|
|
20354
20502
|
case "after":
|
|
20355
|
-
return `${where(s)} writes to ${what} only after responding: ${
|
|
20503
|
+
return `${where(s)} writes to ${what} only after responding: ${stepText2(gap.step)}`;
|
|
20356
20504
|
case "read":
|
|
20357
|
-
return `${where(s)} only reads from ${what} before responding: ${
|
|
20505
|
+
return `${where(s)} only reads from ${what} before responding: ${stepText2(gap.step)} is a read`;
|
|
20358
20506
|
case "none":
|
|
20359
20507
|
return `${where(s)} never writes to ${what} before responding`;
|
|
20360
20508
|
}
|
|
@@ -20548,7 +20696,7 @@ function calls(run2, a) {
|
|
|
20548
20696
|
const first = calling[0];
|
|
20549
20697
|
const step = called(first)[0];
|
|
20550
20698
|
return fail(
|
|
20551
|
-
`${multi ? quote2(first.name) : sc.label} calls ${nodeLabel(run2.diagram, step.toServiceId)}: ${
|
|
20699
|
+
`${multi ? quote2(first.name) : sc.label} calls ${nodeLabel(run2.diagram, step.toServiceId)}: ${stepText2(step)}`,
|
|
20552
20700
|
`Take the call to ${step.toServiceId} out of ${quote2(first.name)}, e.g. serve it from a cache`
|
|
20553
20701
|
);
|
|
20554
20702
|
}
|
|
@@ -20579,7 +20727,7 @@ function before(run2, a) {
|
|
|
20579
20727
|
if (ix < 0 || ix > iy) {
|
|
20580
20728
|
const where = sc.scenarios.length > 1 || a.scenario ? `In ${quote2(s.name)}` : `In ${quote2(sc.u.name)}`;
|
|
20581
20729
|
return fail(
|
|
20582
|
-
ix < 0 ? `${where}, ${order[iy].to} is called (${
|
|
20730
|
+
ix < 0 ? `${where}, ${order[iy].to} is called (${stepText2(order[iy].step)}) but ${x} never is` : `${where}, ${order[iy].to} is called (${stepText2(order[iy].step)}) before ${order[ix].to} (${stepText2(order[ix].step)})`,
|
|
20583
20731
|
`Call ${x} before the first call to ${y}`
|
|
20584
20732
|
);
|
|
20585
20733
|
}
|
|
@@ -20597,7 +20745,7 @@ function neverWaits(run2, a) {
|
|
|
20597
20745
|
if (hop) {
|
|
20598
20746
|
const where = sc.scenarios.length > 1 ? quote2(s.name) : sc.label;
|
|
20599
20747
|
return fail(
|
|
20600
|
-
`${where} waits for ${nodeLabel(run2.diagram, hop.target)} before responding: ${
|
|
20748
|
+
`${where} waits for ${nodeLabel(run2.diagram, hop.target)} before responding: ${stepText2(hop.step)}${hop.failed ? " times out on the request path" : " is synchronous"}`,
|
|
20601
20749
|
`Send it with ->> (through a queue if it must not be lost), or move it after the line that answers the entry request`
|
|
20602
20750
|
);
|
|
20603
20751
|
}
|
|
@@ -20623,7 +20771,7 @@ function after(run2, a) {
|
|
|
20623
20771
|
if (iy < ix) {
|
|
20624
20772
|
const where = sc.scenarios.length > 1 || a.scenario ? `In ${quote2(s.name)}` : `In ${quote2(sc.u.name)}`;
|
|
20625
20773
|
return fail(
|
|
20626
|
-
`${where}, the last call to ${y} (${
|
|
20774
|
+
`${where}, the last call to ${y} (${stepText2(order[iy].step)}) comes before the first call to ${x} (${stepText2(order[ix].step)})`,
|
|
20627
20775
|
`Call ${y} after ${x}: move the step to ${order[iy].to} below the call to ${order[ix].to}`
|
|
20628
20776
|
);
|
|
20629
20777
|
}
|
|
@@ -20652,9 +20800,9 @@ function senderCalls(run2, a) {
|
|
|
20652
20800
|
const step = s.steps.find((st) => from.has(st.fromServiceId) && to.has(st.toServiceId));
|
|
20653
20801
|
if (!step) continue;
|
|
20654
20802
|
const where = u.scenarios.length > 1 ? `${quote2(u.name)} scenario ${quote2(s.name)}` : quote2(u.name);
|
|
20655
|
-
if (a.quantifier === "some") return pass(`${x} calls ${y}${within}: ${
|
|
20803
|
+
if (a.quantifier === "some") return pass(`${x} calls ${y}${within}: ${stepText2(step)} in ${where}`);
|
|
20656
20804
|
return fail(
|
|
20657
|
-
`${x} calls ${y}${within}: ${
|
|
20805
|
+
`${x} calls ${y}${within}: ${stepText2(step)} in ${where}`,
|
|
20658
20806
|
`Let another node make this call (e.g. the client uploads to storage with a presigned URL), or remove the step`
|
|
20659
20807
|
);
|
|
20660
20808
|
}
|
|
@@ -20675,7 +20823,7 @@ function startsAt(run2, a) {
|
|
|
20675
20823
|
const wrong = entries2.find((s) => !ids.has(s.fromServiceId));
|
|
20676
20824
|
if (wrong) {
|
|
20677
20825
|
return fail(
|
|
20678
|
-
`${quote2(u.name)} starts at ${nodeLabel(run2.diagram, wrong.fromServiceId)}, not ${what}: ${
|
|
20826
|
+
`${quote2(u.name)} starts at ${nodeLabel(run2.diagram, wrong.fromServiceId)}, not ${what}: ${stepText2(wrong)}`,
|
|
20679
20827
|
`Make the first step of "${u.name}" a step sent by ${what}`
|
|
20680
20828
|
);
|
|
20681
20829
|
}
|
|
@@ -20765,6 +20913,10 @@ var import_node_path6 = require("node:path");
|
|
|
20765
20913
|
var ImportError = class extends Error {
|
|
20766
20914
|
name = "ImportError";
|
|
20767
20915
|
};
|
|
20916
|
+
var LATEST_TAG = "latest";
|
|
20917
|
+
var VERSION_TAG = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
20918
|
+
var CLOUD_NAME_SEGMENT = /^[A-Za-z0-9_][A-Za-z0-9._+-]*$/;
|
|
20919
|
+
var MAX_CLOUD_NAME = 200;
|
|
20768
20920
|
var MAX_SPEC_LENGTH = 1024;
|
|
20769
20921
|
var SEGMENT = /^[A-Za-z0-9_][A-Za-z0-9._ +-]*$/;
|
|
20770
20922
|
var HOST = /^[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?)*(?::\d{1,5})?$/;
|
|
@@ -20812,8 +20964,9 @@ function parseRemoteSpec(spec) {
|
|
|
20812
20964
|
checkRef(ref, spec);
|
|
20813
20965
|
return { kind: "git", repo, path, ref };
|
|
20814
20966
|
}
|
|
20967
|
+
if (scheme === "cloud") return parseCloudSpec(spec);
|
|
20815
20968
|
if (scheme === "http") throw new ImportError(`'${spec}' uses http://; only https:// imports are allowed`);
|
|
20816
|
-
if (scheme !== "https") throw new ImportError(`'${spec}' is not a supported import source; use a relative path, git
|
|
20969
|
+
if (scheme !== "https") throw new ImportError(`'${spec}' is not a supported import source; use a relative path, git:, https:// or cloud:`);
|
|
20817
20970
|
let url;
|
|
20818
20971
|
try {
|
|
20819
20972
|
url = new URL(spec);
|
|
@@ -20825,15 +20978,51 @@ function parseRemoteSpec(spec) {
|
|
|
20825
20978
|
if (!HOST.test(url.host)) throw new ImportError(`'${spec}' has an invalid host`);
|
|
20826
20979
|
return { kind: "https", url: url.href };
|
|
20827
20980
|
}
|
|
20981
|
+
function parseCloudSpec(spec) {
|
|
20982
|
+
const body = spec.slice("cloud:".length);
|
|
20983
|
+
const split2 = body.indexOf("//");
|
|
20984
|
+
const head = split2 === -1 ? body : body.slice(0, split2);
|
|
20985
|
+
const parts = head.split(":");
|
|
20986
|
+
if (parts.length > 2) throw new ImportError(`'${spec}' is not a cloud source; write cloud:<name> or cloud:<name>:<tag>`);
|
|
20987
|
+
const name = parts[0].endsWith(".proschi") ? parts[0].slice(0, -".proschi".length) : parts[0];
|
|
20988
|
+
if (!name || name.length > MAX_CLOUD_NAME || name.split("/").some((p) => !CLOUD_NAME_SEGMENT.test(p) || p === "." || p === "..")) {
|
|
20989
|
+
throw new ImportError(
|
|
20990
|
+
`'${spec}' names an invalid diagram '${parts[0]}'; use the diagram's file name (letters, digits, '.', '_', '+', '-' and '/', no spaces), with or without .proschi`
|
|
20991
|
+
);
|
|
20992
|
+
}
|
|
20993
|
+
const tag = parts.length === 2 ? parts[1] : LATEST_TAG;
|
|
20994
|
+
if (!VERSION_TAG.test(tag)) {
|
|
20995
|
+
throw new ImportError(`'${spec}' has an invalid version tag '${tag}'; use up to 64 letters, digits, '.', '_' and '-', starting with a letter or digit, e.g. 2026-11-01`);
|
|
20996
|
+
}
|
|
20997
|
+
if (split2 === -1) return { kind: "cloud", name, tag };
|
|
20998
|
+
return { kind: "cloud", name, tag, path: repoPathSegments(body.slice(split2 + 2), spec).join("/") };
|
|
20999
|
+
}
|
|
20828
21000
|
function formatRemoteSpec(spec) {
|
|
21001
|
+
if (spec.kind === "cloud") return `cloud:${spec.name}:${spec.tag}${spec.path ? `//${spec.path}` : ""}`;
|
|
20829
21002
|
return spec.kind === "git" ? `git:${spec.repo}//${spec.path}@${spec.ref}` : spec.url;
|
|
20830
21003
|
}
|
|
21004
|
+
function cloudDocumentName(spec) {
|
|
21005
|
+
return `${spec.name}.proschi`;
|
|
21006
|
+
}
|
|
20831
21007
|
function resolveImportPath(fromPath, importPath) {
|
|
20832
21008
|
if (importPath.includes("\0")) throw new ImportError(`'${importPath.replace(/\0/g, "")}' contains a NUL character`);
|
|
20833
21009
|
const remote = parseRemoteSpec(importPath);
|
|
21010
|
+
if (remote?.kind === "cloud" && fromPath && isRemoteSpec(fromPath) && parseRemoteSpec(fromPath)?.kind !== "cloud") {
|
|
21011
|
+
throw new ImportError(`'${importPath}' is a cloud import inside ${fromPath}; cloud: sources only work from your own diagrams`);
|
|
21012
|
+
}
|
|
20834
21013
|
if (remote) return formatRemoteSpec(remote);
|
|
20835
21014
|
if (isAbsolutePath(importPath)) throw new ImportError(`'${importPath}' is an absolute path; imports must be relative to the importing file`);
|
|
20836
21015
|
const from = fromPath && isRemoteSpec(fromPath) ? parseRemoteSpec(fromPath) : void 0;
|
|
21016
|
+
if (from?.kind === "cloud") {
|
|
21017
|
+
const parts2 = (from.path ?? "").split("/").slice(0, -1);
|
|
21018
|
+
for (const part of importPath.split("/")) {
|
|
21019
|
+
if (part === "" || part === ".") continue;
|
|
21020
|
+
if (part !== "..") parts2.push(part);
|
|
21021
|
+
else if (parts2.length > 0) parts2.pop();
|
|
21022
|
+
else throw new ImportError(`'${importPath}' leaves the files saved with cloud:${from.name}:${from.tag}`);
|
|
21023
|
+
}
|
|
21024
|
+
return formatRemoteSpec({ ...from, path: repoPathSegments(parts2.join("/"), importPath).join("/") });
|
|
21025
|
+
}
|
|
20837
21026
|
if (from?.kind === "git") {
|
|
20838
21027
|
const parts2 = from.path.split("/").slice(0, -1);
|
|
20839
21028
|
for (const part of importPath.split("/")) {
|
|
@@ -20867,6 +21056,15 @@ function joinImportPath(fromPath, importPath) {
|
|
|
20867
21056
|
throw e;
|
|
20868
21057
|
}
|
|
20869
21058
|
}
|
|
21059
|
+
function isImportKey(key) {
|
|
21060
|
+
if (key.includes("\0")) return false;
|
|
21061
|
+
if (!isRemoteSpec(key)) return !isAbsolutePath(key);
|
|
21062
|
+
try {
|
|
21063
|
+
return resolveImportPath(void 0, key) === key;
|
|
21064
|
+
} catch {
|
|
21065
|
+
return false;
|
|
21066
|
+
}
|
|
21067
|
+
}
|
|
20870
21068
|
function mapResolver(files) {
|
|
20871
21069
|
const paths = Object.keys(files).filter((p) => !isRemoteSpec(p));
|
|
20872
21070
|
return (importPath, fromPath) => {
|
|
@@ -20935,12 +21133,12 @@ function parseArgs(args, styles, err) {
|
|
|
20935
21133
|
for (let i = 0; i < args.length; i++) {
|
|
20936
21134
|
const arg = args[i];
|
|
20937
21135
|
if (arg === "--format") {
|
|
20938
|
-
const
|
|
20939
|
-
if (!styles.includes(
|
|
20940
|
-
err(`Unknown format '${
|
|
21136
|
+
const value2 = args[++i];
|
|
21137
|
+
if (!styles.includes(value2)) {
|
|
21138
|
+
err(`Unknown format '${value2 ?? ""}'; use ${styles.join(", ")}`);
|
|
20941
21139
|
return void 0;
|
|
20942
21140
|
}
|
|
20943
|
-
style =
|
|
21141
|
+
style = value2;
|
|
20944
21142
|
} else if (arg.startsWith("-")) {
|
|
20945
21143
|
err(`Unknown option ${arg}
|
|
20946
21144
|
|
|
@@ -21054,11 +21252,14 @@ var LOCK_FILE = "proschi.lock";
|
|
|
21054
21252
|
var CACHE_DIR = ".proschi/cache";
|
|
21055
21253
|
var HASH = /^[0-9a-f]{64}$/;
|
|
21056
21254
|
var COMMIT = /^[0-9a-f]{40}([0-9a-f]{24})?$/;
|
|
21057
|
-
var emptyLock = () => ({ version: 1, git: {}, https: {} });
|
|
21255
|
+
var emptyLock = () => ({ version: 1, git: {}, https: {}, cloud: {} });
|
|
21058
21256
|
var gitKey = (repo, ref) => `${repo}@${ref}`;
|
|
21257
|
+
var cloudKey = (name, tag) => `${name}:${tag}`;
|
|
21059
21258
|
var remoteError = {
|
|
21060
21259
|
noLock: (spec) => new ImportError(`'${spec}' is a remote import and there is no ${LOCK_FILE}; run proschi imports sync`),
|
|
21061
|
-
notLocked: (spec) => new ImportError(`'${spec}' is not in ${LOCK_FILE}; run proschi imports sync`),
|
|
21260
|
+
notLocked: (spec) => spec.startsWith("cloud:") ? remoteError.cloud(spec) : new ImportError(`'${spec}' is not in ${LOCK_FILE}; run proschi imports sync`),
|
|
21261
|
+
/** A cloud version that is not pinned yet (docs/design/versions-and-cloud.md). */
|
|
21262
|
+
cloud: (spec) => new ImportError(`'${spec}' is a version in your Proschi account; run proschi imports sync to pin it (cloud sources need proschi login)`),
|
|
21062
21263
|
notCached: (spec) => new ImportError(`'${spec}' is not in the import cache (${CACHE_DIR}); run proschi imports sync`),
|
|
21063
21264
|
altered: (spec) => new ImportError(`The cached copy of '${spec}' does not match its hash in ${LOCK_FILE}; run proschi imports sync`)
|
|
21064
21265
|
};
|
|
@@ -21075,7 +21276,8 @@ function parseLock(text) {
|
|
|
21075
21276
|
const lock = emptyLock();
|
|
21076
21277
|
const git = json2.git ?? {};
|
|
21077
21278
|
const https = json2.https ?? {};
|
|
21078
|
-
|
|
21279
|
+
const cloud = json2.cloud ?? {};
|
|
21280
|
+
if (!isRecord(git) || !isRecord(https) || !isRecord(cloud)) throw invalid('"git", "https" and "cloud" must be objects');
|
|
21079
21281
|
for (const [key, entry] of Object.entries(git)) {
|
|
21080
21282
|
const at = key.lastIndexOf("@");
|
|
21081
21283
|
const valid = at > 0 && isRecord(entry) && typeof entry.commit === "string" && COMMIT.test(entry.commit) && isRecord(entry.files) && Object.entries(entry.files).every(([path, hash]) => typeof hash === "string" && HASH.test(hash) && isGitSpec(`git:${key.slice(0, at)}//${path}@${key.slice(at + 1)}`));
|
|
@@ -21086,8 +21288,28 @@ function parseLock(text) {
|
|
|
21086
21288
|
if (typeof hash !== "string" || !HASH.test(hash) || parseRemoteSpec(url)?.kind !== "https") throw invalid(`bad https entry '${url}'`);
|
|
21087
21289
|
lock.https[url] = hash;
|
|
21088
21290
|
}
|
|
21291
|
+
for (const [key, entry] of Object.entries(cloud)) {
|
|
21292
|
+
const hash = (v) => typeof v === "string" && HASH.test(v);
|
|
21293
|
+
const valid = isCanonicalSpec(`cloud:${key}`, "cloud") && isRecord(entry) && typeof entry.tag === "string" && VERSION_TAG.test(entry.tag) && entry.tag !== LATEST_TAG && Number.isSafeInteger(entry.seq) && entry.seq > 0 && hash(entry.sha256) && (entry.source === void 0 || hash(entry.source)) && isRecord(entry.files) && Object.entries(entry.files).every(([path, h]) => hash(h) && isCanonicalSpec(`cloud:${key}//${path}`, "cloud"));
|
|
21294
|
+
if (!valid) throw invalid(`bad cloud entry '${key}'`);
|
|
21295
|
+
lock.cloud[key] = {
|
|
21296
|
+
tag: entry.tag,
|
|
21297
|
+
seq: entry.seq,
|
|
21298
|
+
sha256: entry.sha256,
|
|
21299
|
+
...entry.source === void 0 ? {} : { source: entry.source },
|
|
21300
|
+
files: { ...entry.files }
|
|
21301
|
+
};
|
|
21302
|
+
}
|
|
21089
21303
|
return lock;
|
|
21090
21304
|
}
|
|
21305
|
+
function isCanonicalSpec(spec, kind) {
|
|
21306
|
+
try {
|
|
21307
|
+
const remote = parseRemoteSpec(spec);
|
|
21308
|
+
return remote?.kind === kind && formatRemoteSpec(remote) === spec;
|
|
21309
|
+
} catch {
|
|
21310
|
+
return false;
|
|
21311
|
+
}
|
|
21312
|
+
}
|
|
21091
21313
|
function isGitSpec(spec) {
|
|
21092
21314
|
try {
|
|
21093
21315
|
return parseRemoteSpec(spec)?.kind === "git";
|
|
@@ -21099,18 +21321,23 @@ function lockedHash(lock, spec) {
|
|
|
21099
21321
|
const remote = parseRemoteSpec(spec);
|
|
21100
21322
|
if (remote?.kind === "git") return lock.git[gitKey(remote.repo, remote.ref)]?.files[remote.path];
|
|
21101
21323
|
if (remote?.kind === "https") return lock.https[remote.url];
|
|
21324
|
+
if (remote?.kind === "cloud") {
|
|
21325
|
+
const entry = lock.cloud[cloudKey(remote.name, remote.tag)];
|
|
21326
|
+
return remote.path === void 0 ? entry?.source : entry?.files[remote.path];
|
|
21327
|
+
}
|
|
21102
21328
|
return void 0;
|
|
21103
21329
|
}
|
|
21104
21330
|
|
|
21105
21331
|
// src/lock.ts
|
|
21106
|
-
var sha256 = (
|
|
21332
|
+
var sha256 = (bytes2) => (0, import_node_crypto.createHash)("sha256").update(bytes2).digest("hex");
|
|
21107
21333
|
function readLock(root) {
|
|
21108
21334
|
const file = (0, import_node_path5.join)(root, LOCK_FILE);
|
|
21109
21335
|
return (0, import_node_fs4.existsSync)(file) ? parseLock((0, import_node_fs4.readFileSync)(file, "utf8")) : void 0;
|
|
21110
21336
|
}
|
|
21111
21337
|
var sorted = (o, map = (v) => v) => Object.fromEntries(Object.keys(o).sort().map((k) => [k, map(o[k])]));
|
|
21112
21338
|
function formatLock(lock) {
|
|
21113
|
-
|
|
21339
|
+
const cloud = Object.keys(lock.cloud).length ? { cloud: sorted(lock.cloud, (e) => ({ tag: e.tag, seq: e.seq, sha256: e.sha256, ...e.source ? { source: e.source } : {}, files: sorted(e.files) })) } : {};
|
|
21340
|
+
return JSON.stringify({ version: 1, git: sorted(lock.git, (e) => ({ commit: e.commit, files: sorted(e.files) })), https: sorted(lock.https), ...cloud }, null, 2) + "\n";
|
|
21114
21341
|
}
|
|
21115
21342
|
function writeLock(root, lock) {
|
|
21116
21343
|
(0, import_node_fs4.writeFileSync)((0, import_node_path5.join)(root, LOCK_FILE), formatLock(lock));
|
|
@@ -21120,16 +21347,16 @@ function readCached(root, hash, spec) {
|
|
|
21120
21347
|
if (!HASH.test(hash)) return void 0;
|
|
21121
21348
|
const file = cacheFile(root, hash);
|
|
21122
21349
|
if (!(0, import_node_fs4.existsSync)(file)) return void 0;
|
|
21123
|
-
const
|
|
21124
|
-
if (sha256(
|
|
21125
|
-
return
|
|
21350
|
+
const bytes2 = (0, import_node_fs4.readFileSync)(file);
|
|
21351
|
+
if (sha256(bytes2) !== hash) throw remoteError.altered(spec);
|
|
21352
|
+
return bytes2;
|
|
21126
21353
|
}
|
|
21127
|
-
function writeCached(root,
|
|
21128
|
-
const hash = sha256(
|
|
21354
|
+
function writeCached(root, bytes2) {
|
|
21355
|
+
const hash = sha256(bytes2);
|
|
21129
21356
|
const dir = (0, import_node_path5.join)(root, CACHE_DIR);
|
|
21130
21357
|
(0, import_node_fs4.mkdirSync)(dir, { recursive: true });
|
|
21131
21358
|
const tmp = (0, import_node_path5.join)(dir, `${hash}.${process.pid}.tmp`);
|
|
21132
|
-
(0, import_node_fs4.writeFileSync)(tmp,
|
|
21359
|
+
(0, import_node_fs4.writeFileSync)(tmp, bytes2);
|
|
21133
21360
|
(0, import_node_fs4.renameSync)(tmp, cacheFile(root, hash));
|
|
21134
21361
|
return hash;
|
|
21135
21362
|
}
|
|
@@ -21173,9 +21400,9 @@ function fileResolver({ entry, read = () => void 0, toPath = (p) => p, remote }
|
|
|
21173
21400
|
if (!lock) throw remoteError.noLock(spec);
|
|
21174
21401
|
const hash = lockedHash(lock, spec);
|
|
21175
21402
|
if (!hash) throw remoteError.notLocked(spec);
|
|
21176
|
-
const
|
|
21177
|
-
if (!
|
|
21178
|
-
return
|
|
21403
|
+
const bytes2 = readCached(root, hash, spec);
|
|
21404
|
+
if (!bytes2) throw remoteError.notCached(spec);
|
|
21405
|
+
return bytes2.toString("utf8");
|
|
21179
21406
|
};
|
|
21180
21407
|
const loadRemote = remote ?? fromCache;
|
|
21181
21408
|
const found = (path, source2, level) => {
|
|
@@ -21301,9 +21528,9 @@ function scalar(text, line, inFlow) {
|
|
|
21301
21528
|
return text;
|
|
21302
21529
|
}
|
|
21303
21530
|
function stringItem(text, line, inFlow) {
|
|
21304
|
-
const
|
|
21305
|
-
if (typeof
|
|
21306
|
-
return
|
|
21531
|
+
const value2 = scalar(text, line, inFlow);
|
|
21532
|
+
if (typeof value2 !== "string") throw new FrontMatterError(`List items must be strings; quote ${text}`, line);
|
|
21533
|
+
return value2;
|
|
21307
21534
|
}
|
|
21308
21535
|
function flowItems(inner, line) {
|
|
21309
21536
|
const items = [];
|
|
@@ -21346,9 +21573,9 @@ function parseFrontMatter(text) {
|
|
|
21346
21573
|
const item = raw.match(/^ +- (.*)$/) ?? raw.match(/^ +-()$/);
|
|
21347
21574
|
if (item) {
|
|
21348
21575
|
if (!list) throw new FrontMatterError('A list item must follow a key with no value, e.g. "hints:"', line);
|
|
21349
|
-
const
|
|
21350
|
-
if (
|
|
21351
|
-
list.items.push(stringItem(
|
|
21576
|
+
const value3 = item[1].trim();
|
|
21577
|
+
if (value3 === "") throw new FrontMatterError("Empty list item", line);
|
|
21578
|
+
list.items.push(stringItem(value3, line, false));
|
|
21352
21579
|
continue;
|
|
21353
21580
|
}
|
|
21354
21581
|
if (/^\s/.test(raw)) throw new FrontMatterError(`Unexpected indented line: ${raw.trim()}`, line);
|
|
@@ -21357,19 +21584,19 @@ function parseFrontMatter(text) {
|
|
|
21357
21584
|
if (!m) throw new FrontMatterError(`Expected "key: value", got: ${raw}`, line);
|
|
21358
21585
|
const [, key, rest] = m;
|
|
21359
21586
|
if (Object.prototype.hasOwnProperty.call(data, key)) throw new FrontMatterError(`Duplicate key '${key}'`, line);
|
|
21360
|
-
const
|
|
21361
|
-
if (
|
|
21587
|
+
const value2 = (rest ?? "").trim();
|
|
21588
|
+
if (value2 === "") {
|
|
21362
21589
|
list = { key, items: [] };
|
|
21363
21590
|
data[key] = list.items;
|
|
21364
|
-
} else if (
|
|
21365
|
-
if (!
|
|
21366
|
-
data[key] = flowItems(
|
|
21591
|
+
} else if (value2.startsWith("[")) {
|
|
21592
|
+
if (!value2.endsWith("]")) throw new FrontMatterError(`A list must close on the same line: ${value2}`, line);
|
|
21593
|
+
data[key] = flowItems(value2.slice(1, -1), line);
|
|
21367
21594
|
} else {
|
|
21368
|
-
data[key] = scalar(
|
|
21595
|
+
data[key] = scalar(value2, line, false);
|
|
21369
21596
|
}
|
|
21370
21597
|
}
|
|
21371
|
-
for (const [key,
|
|
21372
|
-
if (Array.isArray(
|
|
21598
|
+
for (const [key, value2] of Object.entries(data)) {
|
|
21599
|
+
if (Array.isArray(value2) && value2.length === 0) {
|
|
21373
21600
|
const line = lines.findIndex((l, i) => i > 0 && i < end && l.startsWith(`${key}:`)) + 1;
|
|
21374
21601
|
throw new FrontMatterError(`'${key}' has no value`, line);
|
|
21375
21602
|
}
|
|
@@ -21444,11 +21671,11 @@ function readMistake(source2) {
|
|
|
21444
21671
|
const m = FIELD_LINE.exec(lines[i]);
|
|
21445
21672
|
if (!m) continue;
|
|
21446
21673
|
const field = m[1];
|
|
21447
|
-
const
|
|
21448
|
-
if (
|
|
21449
|
-
if (field === "explain") values.explain = values.explain ? `${values.explain} ${
|
|
21674
|
+
const value2 = m[2];
|
|
21675
|
+
if (value2 === "") issues.push({ message: `"# ${field}:" is empty`, line: i + 1 });
|
|
21676
|
+
if (field === "explain") values.explain = values.explain ? `${values.explain} ${value2}` : value2;
|
|
21450
21677
|
else if (values[field] !== void 0) issues.push({ message: `"# ${field}:" appears twice`, line: i + 1 });
|
|
21451
|
-
else values[field] =
|
|
21678
|
+
else values[field] = value2;
|
|
21452
21679
|
}
|
|
21453
21680
|
if (values.mistake === void 0) return { issues };
|
|
21454
21681
|
const cards = (values.cards ?? "").split(",").map((c) => c.trim()).filter(Boolean);
|
|
@@ -21929,8 +22156,8 @@ function readSelector(text) {
|
|
|
21929
22156
|
}
|
|
21930
22157
|
function parseGuided(text) {
|
|
21931
22158
|
const issues = [];
|
|
21932
|
-
const
|
|
21933
|
-
if (!text.trim()) return { steps:
|
|
22159
|
+
const steps3 = [];
|
|
22160
|
+
if (!text.trim()) return { steps: steps3, issues: [{ message: "The walkthrough is empty" }] };
|
|
21934
22161
|
const { preamble, parts } = splitAt(numberedLines(text), 2);
|
|
21935
22162
|
if (hasText(preamble)) issues.push({ message: 'Each step is a "## " heading; nothing goes before the first one', line: preamble.find((l) => l.text.trim())?.line });
|
|
21936
22163
|
for (const part of parts) {
|
|
@@ -21964,11 +22191,11 @@ function parseGuided(text) {
|
|
|
21964
22191
|
}
|
|
21965
22192
|
if (meta.size === 0) bad(item.line, "a step needs at least one check (- node, - edge, - usecase, - replicas or - test)");
|
|
21966
22193
|
if (!item.body) bad(item.line, "write what to do and why under the checks");
|
|
21967
|
-
|
|
22194
|
+
steps3.push({ title: item.title, explanation: item.body, checks });
|
|
21968
22195
|
}
|
|
21969
|
-
if (
|
|
21970
|
-
if (
|
|
21971
|
-
return { steps:
|
|
22196
|
+
if (steps3.length < MIN_STEPS) issues.push({ message: `At least ${MIN_STEPS} steps (there are ${steps3.length})` });
|
|
22197
|
+
if (steps3.length > MAX_STEPS) issues.push({ message: `At most ${MAX_STEPS} steps (there are ${steps3.length})` });
|
|
22198
|
+
return { steps: steps3, issues };
|
|
21972
22199
|
}
|
|
21973
22200
|
function matches2(node, s) {
|
|
21974
22201
|
return "id" in s ? node.id === s.id : kindMatches(kindOf(node), s.kind);
|
|
@@ -22032,12 +22259,12 @@ function evaluateChecks(checks, diagram, tests) {
|
|
|
22032
22259
|
});
|
|
22033
22260
|
}
|
|
22034
22261
|
function guidedIssues(text, solution, solutionTests) {
|
|
22035
|
-
const { steps:
|
|
22262
|
+
const { steps: steps3, issues } = parseGuided(text);
|
|
22036
22263
|
const ids = new Set(solution.nodes.map((n) => n.id));
|
|
22037
22264
|
const testNames = new Set((solutionTests ?? []).map((r) => r.name));
|
|
22038
22265
|
const lines = text.split("\n");
|
|
22039
22266
|
const lineOf3 = (title) => lines.findIndex((l) => /^##\s/.test(l) && l.includes(title)) + 1 || void 0;
|
|
22040
|
-
for (const step of
|
|
22267
|
+
for (const step of steps3) {
|
|
22041
22268
|
const line = lineOf3(step.title);
|
|
22042
22269
|
for (const c of step.checks) {
|
|
22043
22270
|
const selectors = c.type === "edge" ? [c.from, c.to] : c.type === "node" || c.type === "replicas" ? [c.node] : [];
|
|
@@ -22307,8 +22534,8 @@ function parseNumber(text) {
|
|
|
22307
22534
|
if (!Object.prototype.hasOwnProperty.call(SUFFIX, suffix)) return void 0;
|
|
22308
22535
|
factor = SUFFIX[suffix];
|
|
22309
22536
|
}
|
|
22310
|
-
const
|
|
22311
|
-
return Number.isFinite(
|
|
22537
|
+
const value2 = Number(digits.replace(/[, _]/g, "")) * 10 ** Number(exponent ?? 0) * factor * (sign === "-" ? -1 : 1);
|
|
22538
|
+
return Number.isFinite(value2) ? value2 : void 0;
|
|
22312
22539
|
}
|
|
22313
22540
|
function hashText(text) {
|
|
22314
22541
|
let h = 2166136261;
|
|
@@ -22798,12 +23025,12 @@ function problemCheck(args, out, err, cwd) {
|
|
|
22798
23025
|
for (let i = 0; i < args.length; i++) {
|
|
22799
23026
|
const arg = args[i];
|
|
22800
23027
|
if (arg === "--format") {
|
|
22801
|
-
const
|
|
22802
|
-
if (
|
|
22803
|
-
err(`Unknown format '${
|
|
23028
|
+
const value2 = args[++i];
|
|
23029
|
+
if (value2 !== "text" && value2 !== "github" && value2 !== "json") {
|
|
23030
|
+
err(`Unknown format '${value2 ?? ""}'; use text, github or json`);
|
|
22804
23031
|
return 2;
|
|
22805
23032
|
}
|
|
22806
|
-
style =
|
|
23033
|
+
style = value2;
|
|
22807
23034
|
} else if (arg.startsWith("-")) {
|
|
22808
23035
|
err(`Unknown option ${arg}
|
|
22809
23036
|
|
|
@@ -23089,12 +23316,12 @@ function parseArgs2(args, err, allowFormat) {
|
|
|
23089
23316
|
for (let i = 0; i < args.length; i++) {
|
|
23090
23317
|
const arg = args[i];
|
|
23091
23318
|
if (allowFormat && arg === "--format") {
|
|
23092
|
-
const
|
|
23093
|
-
if (
|
|
23094
|
-
err(`Unknown format '${
|
|
23319
|
+
const value2 = args[++i];
|
|
23320
|
+
if (value2 !== "text" && value2 !== "github" && value2 !== "json") {
|
|
23321
|
+
err(`Unknown format '${value2 ?? ""}'; use text, github or json`);
|
|
23095
23322
|
return void 0;
|
|
23096
23323
|
}
|
|
23097
|
-
parsed.style =
|
|
23324
|
+
parsed.style = value2;
|
|
23098
23325
|
} else if (allowFormat && arg === "--problems") {
|
|
23099
23326
|
parsed.problems = args[++i];
|
|
23100
23327
|
if (!parsed.problems) {
|
|
@@ -23416,19 +23643,19 @@ function parseArgs3(args, err) {
|
|
|
23416
23643
|
for (let i = 0; i < args.length; i++) {
|
|
23417
23644
|
const arg = args[i];
|
|
23418
23645
|
if (arg === "--format") {
|
|
23419
|
-
const
|
|
23420
|
-
if (
|
|
23421
|
-
err(`Unknown format '${
|
|
23646
|
+
const value2 = args[++i];
|
|
23647
|
+
if (value2 !== "text" && value2 !== "github" && value2 !== "json") {
|
|
23648
|
+
err(`Unknown format '${value2 ?? ""}'; use text, github or json`);
|
|
23422
23649
|
return void 0;
|
|
23423
23650
|
}
|
|
23424
|
-
parsed.style =
|
|
23651
|
+
parsed.style = value2;
|
|
23425
23652
|
} else if (arg === "--problems" || arg === "--cards") {
|
|
23426
|
-
const
|
|
23427
|
-
if (!
|
|
23653
|
+
const value2 = args[++i];
|
|
23654
|
+
if (!value2) {
|
|
23428
23655
|
err(`Expected a directory after ${arg}`);
|
|
23429
23656
|
return void 0;
|
|
23430
23657
|
}
|
|
23431
|
-
parsed[arg === "--problems" ? "problems" : "cards"] =
|
|
23658
|
+
parsed[arg === "--problems" ? "problems" : "cards"] = value2;
|
|
23432
23659
|
} else if (arg.startsWith("-")) {
|
|
23433
23660
|
err(`Unknown option ${arg}
|
|
23434
23661
|
|
|
@@ -23671,26 +23898,26 @@ function compile(scenario, board, components2, useCases, situation = CALM, optio
|
|
|
23671
23898
|
if (situation.bots) {
|
|
23672
23899
|
const chain = chainTo(() => true) ?? [board.nodes.find((n) => n.component === USERS)?.id ?? USERS];
|
|
23673
23900
|
const stop = chain.findIndex((id) => roleOf2(id) === "waf" || roleOf2(id) === "gateway");
|
|
23674
|
-
const
|
|
23901
|
+
const steps3 = [];
|
|
23675
23902
|
const path = stop >= 0 ? chain.slice(0, stop + 1) : chain;
|
|
23676
|
-
for (let i = 0; i + 1 < path.length; i++)
|
|
23903
|
+
for (let i = 0; i + 1 < path.length; i++) steps3.push(` ${path[i]} -> ${path[i + 1]} : GET /random-${i}`);
|
|
23677
23904
|
const last = path[path.length - 1];
|
|
23678
23905
|
if (stop < 0 && roleOf2(last) === "app") {
|
|
23679
23906
|
const db = wired(last, "db");
|
|
23680
|
-
if (db)
|
|
23907
|
+
if (db) steps3.push(` ${last} -> ${db} : SELECT random key`, ` ${db} --> ${last} : nothing`);
|
|
23681
23908
|
}
|
|
23682
23909
|
const status = stop >= 0 ? roleOf2(path[stop]) === "waf" ? 403 : 429 : 404;
|
|
23683
|
-
for (let i = path.length - 1; i > 0; i--)
|
|
23684
|
-
if (
|
|
23910
|
+
for (let i = path.length - 1; i > 0; i--) steps3.push(` ${path[i]} --> ${path[i - 1]} : ${status}`);
|
|
23911
|
+
if (steps3.length) bodies.push(`usecase ${quote4(BOTS)} "Scrapers and credential stuffers" {`, ...steps3, "}", "");
|
|
23685
23912
|
bots = { stoppedBy: stop >= 0 ? path[stop] : void 0, chain: path };
|
|
23686
23913
|
}
|
|
23687
23914
|
function routeUseCase(key, uc, chain, handler) {
|
|
23688
|
-
const
|
|
23915
|
+
const steps3 = uc.steps;
|
|
23689
23916
|
const queue = wired(handler, "queue");
|
|
23690
23917
|
const worker = queue ? wired(queue, "worker", true) : void 0;
|
|
23691
23918
|
const viaWorker = (s) => !!(s.async && queue && worker);
|
|
23692
23919
|
const targets2 = [];
|
|
23693
|
-
for (const s of
|
|
23920
|
+
for (const s of steps3) {
|
|
23694
23921
|
const from = viaWorker(s) ? worker : handler;
|
|
23695
23922
|
const target = s.op === "call" ? wiredTo(from, s.to) ? s.to : void 0 : wired(from, s.to);
|
|
23696
23923
|
if (!target) {
|
|
@@ -23706,9 +23933,9 @@ function compile(scenario, board, components2, useCases, situation = CALM, optio
|
|
|
23706
23933
|
const cacheNode = uc.cache !== void 0 && !uc.strong ? wired(handler, "cache", true) : void 0;
|
|
23707
23934
|
const cacheable = (s) => s.op === "read" && s.to !== "blob" && !viaWorker(s);
|
|
23708
23935
|
const direct = (s) => !!options.presigned && s.op === "write" && s.to === "blob" && !viaWorker(s);
|
|
23709
|
-
const directUpload =
|
|
23936
|
+
const directUpload = steps3.some(direct);
|
|
23710
23937
|
const chainSize = directUpload ? "" : sizeLabel(uc.size, options.payload);
|
|
23711
|
-
const usesCache = cacheNode !== void 0 &&
|
|
23938
|
+
const usesCache = cacheNode !== void 0 && steps3.some(cacheable);
|
|
23712
23939
|
const cacheStates = !usesCache ? ["none"] : down.has(cacheNode) ? ["down"] : ["hit", "miss", "down"];
|
|
23713
23940
|
const regions = situation.global ? [false, true] : [false];
|
|
23714
23941
|
const plans = [];
|
|
@@ -23724,8 +23951,8 @@ function compile(scenario, board, components2, useCases, situation = CALM, optio
|
|
|
23724
23951
|
const verb = s.op === "call" ? "SEND" : STORE_VERB[s.to]?.[write ? 1 : 0] ?? (write ? "WRITE" : "GET");
|
|
23725
23952
|
return `${prefix ? `${prefix} ` : ""}${verb} ${s.entity ?? (s.op === "call" ? "message" : "data")}`;
|
|
23726
23953
|
};
|
|
23727
|
-
const cacheKey =
|
|
23728
|
-
const hasBackground =
|
|
23954
|
+
const cacheKey = steps3.find(cacheable)?.entity ?? "item";
|
|
23955
|
+
const hasBackground = steps3.some(viaWorker);
|
|
23729
23956
|
const scenarioText = (p) => {
|
|
23730
23957
|
const t = [];
|
|
23731
23958
|
const path = p.edge === "hit" ? chain.slice(0, chain.indexOf(cdn) + 1) : chain;
|
|
@@ -23739,7 +23966,7 @@ function compile(scenario, board, components2, useCases, situation = CALM, optio
|
|
|
23739
23966
|
if (p.cache === "hit") t.push(`${handler} -> ${cacheNode} : GET ${cacheKey}`, `${cacheNode} --> ${handler} : hit`);
|
|
23740
23967
|
else if (p.cache === "miss") t.push(`${handler} -> ${cacheNode} : GET ${cacheKey}`, `${cacheNode} --> ${handler} : miss`);
|
|
23741
23968
|
else if (p.cache === "down") t.push(`${handler} -x ${cacheNode} : GET ${cacheKey}`);
|
|
23742
|
-
|
|
23969
|
+
steps3.forEach((s, i) => {
|
|
23743
23970
|
if (viaWorker(s)) return;
|
|
23744
23971
|
if (p.cache === "hit" && cacheable(s)) return;
|
|
23745
23972
|
const write = s.op !== "read";
|
|
@@ -23749,7 +23976,7 @@ function compile(scenario, board, components2, useCases, situation = CALM, optio
|
|
|
23749
23976
|
if (hasBackground) t.push(`${handler} ->> ${queue} : ENQUEUE ${uc.name.replace(/[^A-Za-z0-9 ]/g, "")}`);
|
|
23750
23977
|
}
|
|
23751
23978
|
for (let i = hops.length - 1; i > 0; i--) t.push(`${hops[i]} --> ${hops[i - 1]} : ${uc.status}`);
|
|
23752
|
-
if (p.edge !== "hit")
|
|
23979
|
+
if (p.edge !== "hit") steps3.forEach((s, i) => {
|
|
23753
23980
|
if (direct(s)) t.push(`${hops[0]} -> ${targets2[i]} : ${sizeLabel(s.size ?? uc.size, options.payload)} PUT ${s.entity ?? "file"}`, `${targets2[i]} --> ${hops[0]} : 200`);
|
|
23754
23981
|
});
|
|
23755
23982
|
return t;
|
|
@@ -23766,13 +23993,13 @@ function compile(scenario, board, components2, useCases, situation = CALM, optio
|
|
|
23766
23993
|
text.push("}", "");
|
|
23767
23994
|
let background;
|
|
23768
23995
|
if (hasBackground) {
|
|
23769
|
-
const stalled = down.has(worker) ||
|
|
23996
|
+
const stalled = down.has(worker) || steps3.some((s, i) => viaWorker(s) && (down.has(targets2[i]) || s.op === "write" && writesDown.has(targets2[i])));
|
|
23770
23997
|
const batching = options.writeShare < 1;
|
|
23771
23998
|
const bgName = `${uc.name} (background)`;
|
|
23772
23999
|
const bgScenarios = batching ? [{ name: "Write", writes: true }, { name: "Buffer", writes: false }] : [{ name: "Write", writes: true }];
|
|
23773
24000
|
const bgText = (writes) => {
|
|
23774
24001
|
const t = [`${queue} -> ${worker} : job`];
|
|
23775
|
-
|
|
24002
|
+
steps3.forEach((s, i) => {
|
|
23776
24003
|
if (!viaWorker(s)) return;
|
|
23777
24004
|
if (!writes && s.op === "write") return;
|
|
23778
24005
|
const write = s.op !== "read";
|
|
@@ -24230,7 +24457,7 @@ function eventFromFile(file, text) {
|
|
|
24230
24457
|
const requires = f.list("requires");
|
|
24231
24458
|
for (const r of requires) if (!ROLES.includes(r)) throw new ContentError(file, `"requires:" lists component roles (${ROLES.join(", ")}), not ${r}`);
|
|
24232
24459
|
const target = f.optionalString("target");
|
|
24233
|
-
const
|
|
24460
|
+
const value2 = f.optionalNumber("value");
|
|
24234
24461
|
const from = f.optionalNumber("from");
|
|
24235
24462
|
const then = f.optionalString("then");
|
|
24236
24463
|
return {
|
|
@@ -24242,7 +24469,7 @@ function eventFromFile(file, text) {
|
|
|
24242
24469
|
learn: f.list("learn"),
|
|
24243
24470
|
effect: f.oneOf("effect", EVENT_EFFECTS),
|
|
24244
24471
|
...target !== void 0 ? { target } : {},
|
|
24245
|
-
...
|
|
24472
|
+
...value2 !== void 0 ? { value: value2 } : {},
|
|
24246
24473
|
...values.length ? { values } : {},
|
|
24247
24474
|
duration: f.number("duration", 1),
|
|
24248
24475
|
...from !== void 0 ? { from } : {},
|
|
@@ -24623,14 +24850,14 @@ function indexOf(content) {
|
|
|
24623
24850
|
function mergeRequirements(current, added) {
|
|
24624
24851
|
const out = [...current];
|
|
24625
24852
|
for (const line of added) {
|
|
24626
|
-
const key =
|
|
24627
|
-
const at = out.findIndex((l) =>
|
|
24853
|
+
const key = requirementKey2(line);
|
|
24854
|
+
const at = out.findIndex((l) => requirementKey2(l) === key);
|
|
24628
24855
|
if (at >= 0) out[at] = line;
|
|
24629
24856
|
else out.push(line);
|
|
24630
24857
|
}
|
|
24631
24858
|
return out;
|
|
24632
24859
|
}
|
|
24633
|
-
function
|
|
24860
|
+
function requirementKey2(line) {
|
|
24634
24861
|
const t = line.trim();
|
|
24635
24862
|
const uc = /"([^"]*)"/.exec(t)?.[1] ?? "";
|
|
24636
24863
|
const head = /^(p\d+(?:\.\d+)?|availability|durable|survive|cost)/.exec(t)?.[1] ?? t;
|
|
@@ -26164,9 +26391,9 @@ var Game = class _Game {
|
|
|
26164
26391
|
const jobs = [];
|
|
26165
26392
|
for (const m of this.mode.mechanics) m.shapeUseCases?.(this, useCases, jobs);
|
|
26166
26393
|
const served = [...s.useCases.filter((k) => this.mode.mechanics.every((m) => m.serves?.(this, k) ?? true)), ...jobs.map((j) => j.key)];
|
|
26167
|
-
const
|
|
26168
|
-
this.effectiveCache = { key, value };
|
|
26169
|
-
return
|
|
26394
|
+
const value2 = { useCases, served, jobs };
|
|
26395
|
+
this.effectiveCache = { key, value: value2 };
|
|
26396
|
+
return value2;
|
|
26170
26397
|
}
|
|
26171
26398
|
/** @internal The board compiled to a diagram for a situation, cached. */
|
|
26172
26399
|
compileFor(board, situation) {
|
|
@@ -26698,26 +26925,26 @@ function parseArgs4(args, err) {
|
|
|
26698
26925
|
const a = { style: "text", positional: [] };
|
|
26699
26926
|
for (let i = 0; i < args.length; i++) {
|
|
26700
26927
|
const arg = args[i];
|
|
26701
|
-
const
|
|
26928
|
+
const value2 = () => {
|
|
26702
26929
|
const v = args[++i];
|
|
26703
26930
|
if (v === void 0) err(`Expected a value after ${arg}`);
|
|
26704
26931
|
return v;
|
|
26705
26932
|
};
|
|
26706
26933
|
if (arg === "--format") {
|
|
26707
|
-
const v =
|
|
26934
|
+
const v = value2();
|
|
26708
26935
|
if (v !== "text" && v !== "github" && v !== "json") {
|
|
26709
26936
|
err(`Unknown format '${v ?? ""}'; use text, github or json`);
|
|
26710
26937
|
return void 0;
|
|
26711
26938
|
}
|
|
26712
26939
|
a.style = v;
|
|
26713
26940
|
} else if (arg === "--run") {
|
|
26714
|
-
a.run =
|
|
26941
|
+
a.run = value2();
|
|
26715
26942
|
if (a.run === void 0) return void 0;
|
|
26716
26943
|
} else if (arg === "--seed") {
|
|
26717
|
-
a.seed =
|
|
26944
|
+
a.seed = value2();
|
|
26718
26945
|
if (a.seed === void 0) return void 0;
|
|
26719
26946
|
} else if (arg === "--ascension") {
|
|
26720
|
-
const v = Number(
|
|
26947
|
+
const v = Number(value2());
|
|
26721
26948
|
if (!Number.isInteger(v) || v < 0) {
|
|
26722
26949
|
err("--ascension takes a whole number from 0");
|
|
26723
26950
|
return void 0;
|
|
@@ -26931,12 +27158,12 @@ function runShareLink(args, out, err) {
|
|
|
26931
27158
|
for (let i = 0; i < args.length; i++) {
|
|
26932
27159
|
const arg = args[i];
|
|
26933
27160
|
if (arg === "--base") {
|
|
26934
|
-
const
|
|
26935
|
-
if (!
|
|
26936
|
-
err(`Expected --base <http(s) url>, got '${
|
|
27161
|
+
const value2 = args[++i];
|
|
27162
|
+
if (!value2 || !/^https?:\/\//.test(value2)) {
|
|
27163
|
+
err(`Expected --base <http(s) url>, got '${value2 ?? ""}'`);
|
|
26937
27164
|
return 2;
|
|
26938
27165
|
}
|
|
26939
|
-
base =
|
|
27166
|
+
base = value2;
|
|
26940
27167
|
} else if (arg.startsWith("-")) {
|
|
26941
27168
|
err(`Unknown option ${arg}
|
|
26942
27169
|
|
|
@@ -26997,8 +27224,8 @@ function readFrontMatter(block) {
|
|
|
26997
27224
|
}
|
|
26998
27225
|
block.lines = block.lines.slice(close + 1);
|
|
26999
27226
|
}
|
|
27000
|
-
function unquoteYaml(
|
|
27001
|
-
const v =
|
|
27227
|
+
function unquoteYaml(value2) {
|
|
27228
|
+
const v = value2.trim();
|
|
27002
27229
|
if (v.startsWith('"')) {
|
|
27003
27230
|
try {
|
|
27004
27231
|
return String(JSON.parse(v));
|
|
@@ -27393,12 +27620,12 @@ function readSequence(block, b, start, index) {
|
|
|
27393
27620
|
b.warn(line, `Could not read '${statement}'; left out`);
|
|
27394
27621
|
}
|
|
27395
27622
|
const name = title || block.title || (index === 0 ? "Sequence" : `Sequence ${index + 1}`);
|
|
27396
|
-
const
|
|
27397
|
-
if (!
|
|
27623
|
+
const steps3 = new SequenceConverter(b).convert(root, false);
|
|
27624
|
+
if (!steps3.some(hasStep)) {
|
|
27398
27625
|
b.warn(block.lines[start]?.line, `Sequence diagram '${name}' has no messages; left out`);
|
|
27399
27626
|
return;
|
|
27400
27627
|
}
|
|
27401
|
-
b.design.useCases.push({ name, steps:
|
|
27628
|
+
b.design.useCases.push({ name, steps: steps3, ...scenario ? { scenario } : {} });
|
|
27402
27629
|
}
|
|
27403
27630
|
var hasStep = (s) => s.kind === "step" || (s.kind === "par" ? s.steps.some(hasStep) : s.branches.some((br) => br.steps.some(hasStep)));
|
|
27404
27631
|
var SequenceConverter = class {
|
|
@@ -27427,14 +27654,14 @@ var SequenceConverter = class {
|
|
|
27427
27654
|
for (const br of branches) out.push(...this.convert(br.items, true));
|
|
27428
27655
|
continue;
|
|
27429
27656
|
}
|
|
27430
|
-
const
|
|
27657
|
+
const steps3 = branches.flatMap((br) => {
|
|
27431
27658
|
const converted = this.convert(br.items, true);
|
|
27432
27659
|
if (converted.filter((s) => s.kind === "step" && s.arrow !== "-->").length > 1) {
|
|
27433
27660
|
this.b.warn(line, `A par branch${br.label ? ` ('${br.label}')` : ""} makes several calls; Proschi runs every step of a par block in parallel`);
|
|
27434
27661
|
}
|
|
27435
27662
|
return converted;
|
|
27436
27663
|
});
|
|
27437
|
-
if (
|
|
27664
|
+
if (steps3.length) out.push({ kind: "par", steps: steps3 });
|
|
27438
27665
|
} else {
|
|
27439
27666
|
if (inPar) {
|
|
27440
27667
|
this.b.warn(line, `${type} inside par: only its first branch is imported`);
|
|
@@ -27479,27 +27706,27 @@ var SequenceConverter = class {
|
|
|
27479
27706
|
function mergeScenarios(useCases) {
|
|
27480
27707
|
const out = [];
|
|
27481
27708
|
const alts = /* @__PURE__ */ new Map();
|
|
27482
|
-
const branch = (scenario,
|
|
27483
|
-
for (const { name, description, steps:
|
|
27709
|
+
const branch = (scenario, steps3) => ({ name: scenario.name, ...scenario.when ? { when: scenario.when } : {}, steps: steps3 });
|
|
27710
|
+
for (const { name, description, steps: steps3, scenario } of useCases) {
|
|
27484
27711
|
const alt = scenario && alts.get(name);
|
|
27485
27712
|
if (alt) {
|
|
27486
27713
|
let branchName = scenario.name;
|
|
27487
27714
|
for (let n = 2; alt.branches.some((br) => br.name === branchName); n++) branchName = `${scenario.name} ${n}`;
|
|
27488
|
-
alt.branches.push(branch({ ...scenario, name: branchName },
|
|
27715
|
+
alt.branches.push(branch({ ...scenario, name: branchName }, steps3));
|
|
27489
27716
|
continue;
|
|
27490
27717
|
}
|
|
27491
27718
|
if (scenario && !alts.has(name) && useCases.filter((u) => u.name === name && u.scenario).length > 1) {
|
|
27492
|
-
const created = { kind: "alt", branches: [branch(scenario,
|
|
27719
|
+
const created = { kind: "alt", branches: [branch(scenario, steps3)] };
|
|
27493
27720
|
alts.set(name, created);
|
|
27494
27721
|
out.push({ name, ...description ? { description } : {}, steps: [created] });
|
|
27495
27722
|
continue;
|
|
27496
27723
|
}
|
|
27497
|
-
out.push({ name, ...description ? { description } : {}, steps:
|
|
27724
|
+
out.push({ name, ...description ? { description } : {}, steps: steps3 });
|
|
27498
27725
|
}
|
|
27499
27726
|
return out;
|
|
27500
27727
|
}
|
|
27501
|
-
function connectSteps(b,
|
|
27502
|
-
for (const step of
|
|
27728
|
+
function connectSteps(b, steps3) {
|
|
27729
|
+
for (const step of steps3) {
|
|
27503
27730
|
if (step.kind === "par") connectSteps(b, step.steps);
|
|
27504
27731
|
else if (step.kind === "alt") step.branches.forEach((br) => connectSteps(b, br.steps));
|
|
27505
27732
|
else if (step.arrow !== "-->" && step.from !== step.to && !b.connected(step.from, step.to)) b.edge(step.from, step.to, void 0);
|
|
@@ -27579,13 +27806,327 @@ ${IMPORT_USAGE}`);
|
|
|
27579
27806
|
}
|
|
27580
27807
|
|
|
27581
27808
|
// src/sync.ts
|
|
27582
|
-
var
|
|
27809
|
+
var import_node_fs14 = require("node:fs");
|
|
27583
27810
|
|
|
27584
|
-
// src/
|
|
27585
|
-
var import_node_child_process = require("node:child_process");
|
|
27811
|
+
// src/credentials.ts
|
|
27586
27812
|
var import_node_fs12 = require("node:fs");
|
|
27587
27813
|
var import_node_os = require("node:os");
|
|
27588
27814
|
var import_node_path12 = require("node:path");
|
|
27815
|
+
var DEFAULT_SITE = "https://proschi.app";
|
|
27816
|
+
function credentialsPath(env = process.env, platform = process.platform, home = (0, import_node_os.homedir)()) {
|
|
27817
|
+
if (platform === "win32") return (0, import_node_path12.join)(env.APPDATA || (0, import_node_path12.join)(home, "AppData", "Roaming"), "proschi", "credentials.json");
|
|
27818
|
+
const config = env.XDG_CONFIG_HOME && env.XDG_CONFIG_HOME.startsWith("/") ? env.XDG_CONFIG_HOME : (0, import_node_path12.join)(home, ".config");
|
|
27819
|
+
return (0, import_node_path12.join)(config, "proschi", "credentials.json");
|
|
27820
|
+
}
|
|
27821
|
+
function normalizeBase(value2) {
|
|
27822
|
+
let url;
|
|
27823
|
+
try {
|
|
27824
|
+
url = new URL(value2);
|
|
27825
|
+
} catch {
|
|
27826
|
+
throw new Error(`'${value2}' is not a URL; use e.g. ${DEFAULT_SITE}`);
|
|
27827
|
+
}
|
|
27828
|
+
const local = url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
|
|
27829
|
+
if (url.protocol !== "https:" && !(url.protocol === "http:" && local)) {
|
|
27830
|
+
throw new Error(`'${value2}' is not https; only https:// sites (or http://localhost and http://127.0.0.1 for development) are allowed`);
|
|
27831
|
+
}
|
|
27832
|
+
if (url.username || url.password || url.search || url.hash || url.pathname !== "/" && url.pathname !== "") {
|
|
27833
|
+
throw new Error(`'${value2}' must be the site's address only, like ${DEFAULT_SITE}`);
|
|
27834
|
+
}
|
|
27835
|
+
return url.origin;
|
|
27836
|
+
}
|
|
27837
|
+
var isSession = (v) => !!v && typeof v === "object" && typeof v.accessToken === "string" && typeof v.refreshToken === "string" && typeof v.expiresAt === "number";
|
|
27838
|
+
var CredentialStore = class {
|
|
27839
|
+
constructor(file = credentialsPath()) {
|
|
27840
|
+
this.file = file;
|
|
27841
|
+
}
|
|
27842
|
+
file;
|
|
27843
|
+
read() {
|
|
27844
|
+
if (!(0, import_node_fs12.existsSync)(this.file)) return { version: 1, sessions: {} };
|
|
27845
|
+
let json2;
|
|
27846
|
+
try {
|
|
27847
|
+
json2 = JSON.parse((0, import_node_fs12.readFileSync)(this.file, "utf8"));
|
|
27848
|
+
} catch {
|
|
27849
|
+
throw new Error(`${this.file} is not valid JSON; delete it and run proschi login`);
|
|
27850
|
+
}
|
|
27851
|
+
const sessions = {};
|
|
27852
|
+
const stored = json2?.sessions;
|
|
27853
|
+
if (stored && typeof stored === "object") {
|
|
27854
|
+
for (const [base, s] of Object.entries(stored)) if (isSession(s)) sessions[base] = s;
|
|
27855
|
+
}
|
|
27856
|
+
return { version: 1, sessions };
|
|
27857
|
+
}
|
|
27858
|
+
/** Writes the file with mode 0600 through a temp file in the same folder, so a reader never sees half a file. */
|
|
27859
|
+
write(data) {
|
|
27860
|
+
const dir = (0, import_node_path12.dirname)(this.file);
|
|
27861
|
+
(0, import_node_fs12.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
27862
|
+
const tmp = `${this.file}.${process.pid}.${Date.now()}.tmp`;
|
|
27863
|
+
const fd = (0, import_node_fs12.openSync)(tmp, "wx", 384);
|
|
27864
|
+
try {
|
|
27865
|
+
(0, import_node_fs12.writeSync)(fd, JSON.stringify(data, null, 2) + "\n");
|
|
27866
|
+
} finally {
|
|
27867
|
+
(0, import_node_fs12.closeSync)(fd);
|
|
27868
|
+
}
|
|
27869
|
+
if (process.platform !== "win32") (0, import_node_fs12.chmodSync)(tmp, 384);
|
|
27870
|
+
(0, import_node_fs12.renameSync)(tmp, this.file);
|
|
27871
|
+
}
|
|
27872
|
+
get(base) {
|
|
27873
|
+
return this.read().sessions[base];
|
|
27874
|
+
}
|
|
27875
|
+
set(base, session) {
|
|
27876
|
+
const data = this.read();
|
|
27877
|
+
data.sessions[base] = session;
|
|
27878
|
+
this.write(data);
|
|
27879
|
+
}
|
|
27880
|
+
delete(base) {
|
|
27881
|
+
const data = this.read();
|
|
27882
|
+
if (!(base in data.sessions)) return;
|
|
27883
|
+
delete data.sessions[base];
|
|
27884
|
+
this.write(data);
|
|
27885
|
+
}
|
|
27886
|
+
/**
|
|
27887
|
+
* Runs `fn` holding the lock file next to the credentials, so two
|
|
27888
|
+
* processes never refresh with the same token. A lock older than
|
|
27889
|
+
* `staleMs` (a crashed process) is taken over.
|
|
27890
|
+
*/
|
|
27891
|
+
async locked(fn, { timeoutMs = 15e3, staleMs = 3e4 } = {}) {
|
|
27892
|
+
const lock = `${this.file}.lock`;
|
|
27893
|
+
(0, import_node_fs12.mkdirSync)((0, import_node_path12.dirname)(lock), { recursive: true, mode: 448 });
|
|
27894
|
+
const start = Date.now();
|
|
27895
|
+
for (; ; ) {
|
|
27896
|
+
try {
|
|
27897
|
+
(0, import_node_fs12.closeSync)((0, import_node_fs12.openSync)(lock, "wx", 384));
|
|
27898
|
+
break;
|
|
27899
|
+
} catch (e) {
|
|
27900
|
+
if (e.code !== "EEXIST") throw e;
|
|
27901
|
+
try {
|
|
27902
|
+
if (Date.now() - (0, import_node_fs12.statSync)(lock).mtimeMs > staleMs) (0, import_node_fs12.rmSync)(lock, { force: true });
|
|
27903
|
+
} catch {
|
|
27904
|
+
}
|
|
27905
|
+
if (Date.now() - start > timeoutMs) throw new Error(`Another proschi process holds ${lock}; try again, or delete it if none runs`);
|
|
27906
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
27907
|
+
}
|
|
27908
|
+
}
|
|
27909
|
+
try {
|
|
27910
|
+
return await fn();
|
|
27911
|
+
} finally {
|
|
27912
|
+
(0, import_node_fs12.rmSync)(lock, { force: true });
|
|
27913
|
+
}
|
|
27914
|
+
}
|
|
27915
|
+
};
|
|
27916
|
+
|
|
27917
|
+
// src/api.ts
|
|
27918
|
+
var TIMEOUT_MS = 3e4;
|
|
27919
|
+
var MAX_RESPONSE_BYTES = 4e6;
|
|
27920
|
+
var EXPIRY_MARGIN_MS = 6e4;
|
|
27921
|
+
var NotSignedInError = class extends Error {
|
|
27922
|
+
name = "NotSignedInError";
|
|
27923
|
+
};
|
|
27924
|
+
var ApiError = class extends Error {
|
|
27925
|
+
constructor(message, status, code) {
|
|
27926
|
+
super(message);
|
|
27927
|
+
this.status = status;
|
|
27928
|
+
this.code = code;
|
|
27929
|
+
}
|
|
27930
|
+
status;
|
|
27931
|
+
code;
|
|
27932
|
+
name = "ApiError";
|
|
27933
|
+
};
|
|
27934
|
+
async function readJson(response2) {
|
|
27935
|
+
const reader = response2.body?.getReader();
|
|
27936
|
+
const chunks = [];
|
|
27937
|
+
let size = 0;
|
|
27938
|
+
for (; ; ) {
|
|
27939
|
+
const chunk = reader ? await reader.read() : { done: true, value: void 0 };
|
|
27940
|
+
if (chunk.done) break;
|
|
27941
|
+
size += chunk.value.byteLength;
|
|
27942
|
+
if (size > MAX_RESPONSE_BYTES) {
|
|
27943
|
+
await reader?.cancel();
|
|
27944
|
+
throw new Error("The answer is too large");
|
|
27945
|
+
}
|
|
27946
|
+
chunks.push(chunk.value);
|
|
27947
|
+
}
|
|
27948
|
+
const text = Buffer.concat(chunks).toString("utf8");
|
|
27949
|
+
if (!text) return void 0;
|
|
27950
|
+
try {
|
|
27951
|
+
return JSON.parse(text);
|
|
27952
|
+
} catch {
|
|
27953
|
+
throw new Error(`The answer (HTTP ${response2.status}) is not JSON`);
|
|
27954
|
+
}
|
|
27955
|
+
}
|
|
27956
|
+
async function send(fetchImpl, url, init = {}) {
|
|
27957
|
+
try {
|
|
27958
|
+
return await fetchImpl(url, { ...init, redirect: "error", signal: AbortSignal.timeout(TIMEOUT_MS) });
|
|
27959
|
+
} catch (e) {
|
|
27960
|
+
throw new Error(`Cannot reach ${new URL(url).origin}: ${e.message}`);
|
|
27961
|
+
}
|
|
27962
|
+
}
|
|
27963
|
+
var messageOf = (body) => {
|
|
27964
|
+
if (!body || typeof body !== "object") return {};
|
|
27965
|
+
const { error, message, error_description } = body;
|
|
27966
|
+
return {
|
|
27967
|
+
code: typeof error === "string" ? error : void 0,
|
|
27968
|
+
message: typeof message === "string" ? message.slice(0, 300) : typeof error_description === "string" ? error_description.slice(0, 300) : void 0
|
|
27969
|
+
};
|
|
27970
|
+
};
|
|
27971
|
+
function sessionFrom(body, now = Date.now()) {
|
|
27972
|
+
const b = body ?? {};
|
|
27973
|
+
if (typeof b.access_token !== "string" || !b.access_token || typeof b.refresh_token !== "string" || !b.refresh_token) {
|
|
27974
|
+
throw new Error("The sign-in answer has no tokens");
|
|
27975
|
+
}
|
|
27976
|
+
const expiresIn = typeof b.expires_in === "number" && b.expires_in > 0 ? b.expires_in : 3600;
|
|
27977
|
+
return { accessToken: b.access_token, refreshToken: b.refresh_token, expiresAt: now + expiresIn * 1e3 };
|
|
27978
|
+
}
|
|
27979
|
+
async function requestTokens(fetchImpl, base, body) {
|
|
27980
|
+
const response2 = await send(fetchImpl, `${base}/auth/token`, {
|
|
27981
|
+
method: "POST",
|
|
27982
|
+
headers: { "content-type": "application/json", accept: "application/json" },
|
|
27983
|
+
body: JSON.stringify(body)
|
|
27984
|
+
});
|
|
27985
|
+
const json2 = await readJson(response2).catch(() => void 0);
|
|
27986
|
+
if (!response2.ok) {
|
|
27987
|
+
const { code, message } = messageOf(json2);
|
|
27988
|
+
throw new ApiError(`Sign-in failed (HTTP ${response2.status}${code ? `, ${code}` : ""})${message ? `: ${message}` : ""}`, response2.status, code);
|
|
27989
|
+
}
|
|
27990
|
+
return sessionFrom(json2);
|
|
27991
|
+
}
|
|
27992
|
+
var ApiClient = class {
|
|
27993
|
+
base;
|
|
27994
|
+
store;
|
|
27995
|
+
fetchImpl;
|
|
27996
|
+
now;
|
|
27997
|
+
constructor({ base, store = new CredentialStore(), fetch: fetchImpl = fetch, now = Date.now }) {
|
|
27998
|
+
this.base = base;
|
|
27999
|
+
this.store = store;
|
|
28000
|
+
this.fetchImpl = fetchImpl;
|
|
28001
|
+
this.now = now;
|
|
28002
|
+
}
|
|
28003
|
+
notSignedIn() {
|
|
28004
|
+
return new NotSignedInError(`Not signed in to ${this.base}; run proschi login`);
|
|
28005
|
+
}
|
|
28006
|
+
/** Whether tokens are stored for the site (they may still have expired). */
|
|
28007
|
+
signedIn() {
|
|
28008
|
+
return this.store.get(this.base) !== void 0;
|
|
28009
|
+
}
|
|
28010
|
+
/**
|
|
28011
|
+
* New tokens for the stored refresh token `used`, unless another process
|
|
28012
|
+
* already refreshed it (then its tokens). An invalid refresh token ends
|
|
28013
|
+
* the sign-in.
|
|
28014
|
+
*/
|
|
28015
|
+
async refresh(used2) {
|
|
28016
|
+
return this.store.locked(async () => {
|
|
28017
|
+
const current = this.store.get(this.base);
|
|
28018
|
+
if (!current) throw this.notSignedIn();
|
|
28019
|
+
if (current.refreshToken !== used2.refreshToken) return current;
|
|
28020
|
+
let next;
|
|
28021
|
+
try {
|
|
28022
|
+
next = await requestTokens(this.fetchImpl, this.base, { grant_type: "refresh_token", refresh_token: current.refreshToken });
|
|
28023
|
+
} catch (e) {
|
|
28024
|
+
if (e instanceof ApiError && (e.code === "invalid_grant" || e.status === 401)) {
|
|
28025
|
+
this.store.delete(this.base);
|
|
28026
|
+
throw new NotSignedInError(`The sign-in to ${this.base} has ended; run proschi login`);
|
|
28027
|
+
}
|
|
28028
|
+
throw e;
|
|
28029
|
+
}
|
|
28030
|
+
this.store.set(this.base, next);
|
|
28031
|
+
return next;
|
|
28032
|
+
});
|
|
28033
|
+
}
|
|
28034
|
+
/** GETs a JSON path of the API as the signed-in user; an ApiError for an error answer. */
|
|
28035
|
+
async get(path) {
|
|
28036
|
+
let session = this.store.get(this.base);
|
|
28037
|
+
if (!session) throw this.notSignedIn();
|
|
28038
|
+
if (session.expiresAt - EXPIRY_MARGIN_MS <= this.now()) session = await this.refresh(session);
|
|
28039
|
+
for (let attempt = 0; ; attempt++) {
|
|
28040
|
+
const response2 = await send(this.fetchImpl, `${this.base}${path}`, {
|
|
28041
|
+
headers: { authorization: `Bearer ${session.accessToken}`, accept: "application/json" }
|
|
28042
|
+
});
|
|
28043
|
+
if (response2.status === 401 && attempt === 0) {
|
|
28044
|
+
await response2.body?.cancel();
|
|
28045
|
+
session = await this.refresh(session);
|
|
28046
|
+
continue;
|
|
28047
|
+
}
|
|
28048
|
+
if (response2.status === 401) throw new NotSignedInError(`${this.base} refused the sign-in; run proschi login`);
|
|
28049
|
+
const json2 = await readJson(response2).catch((e) => {
|
|
28050
|
+
if (response2.ok) throw e;
|
|
28051
|
+
return void 0;
|
|
28052
|
+
});
|
|
28053
|
+
if (!response2.ok) {
|
|
28054
|
+
const { code, message } = messageOf(json2);
|
|
28055
|
+
throw new ApiError(message ?? `HTTP ${response2.status}`, response2.status, code);
|
|
28056
|
+
}
|
|
28057
|
+
return json2;
|
|
28058
|
+
}
|
|
28059
|
+
}
|
|
28060
|
+
};
|
|
28061
|
+
|
|
28062
|
+
// src/cloud.ts
|
|
28063
|
+
var import_node_crypto2 = require("node:crypto");
|
|
28064
|
+
function canonicalSha256(source2, imports) {
|
|
28065
|
+
const pairs = Object.entries(imports ?? {}).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
28066
|
+
return (0, import_node_crypto2.createHash)("sha256").update(JSON.stringify([source2, pairs]), "utf8").digest("hex");
|
|
28067
|
+
}
|
|
28068
|
+
function cloudName(name) {
|
|
28069
|
+
if (name.includes(":") || name.includes("//")) throw new Error(`'${name}' is not a diagram name; write it without cloud: or a tag, e.g. orders`);
|
|
28070
|
+
const spec = parseRemoteSpec(`cloud:${name}`);
|
|
28071
|
+
if (spec?.kind !== "cloud") throw new Error(`'${name}' is not a diagram name`);
|
|
28072
|
+
return spec;
|
|
28073
|
+
}
|
|
28074
|
+
var isRecord3 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
28075
|
+
var HASH2 = /^[0-9a-f]{64}$/;
|
|
28076
|
+
async function resolveVersion(client, spec, tag) {
|
|
28077
|
+
const where = `cloud:${spec.name}:${tag}`;
|
|
28078
|
+
let body;
|
|
28079
|
+
try {
|
|
28080
|
+
body = await client.get(`/api/me/versions/resolve?name=${encodeURIComponent(cloudDocumentName(spec))}&tag=${encodeURIComponent(tag)}`);
|
|
28081
|
+
} catch (e) {
|
|
28082
|
+
if (e instanceof ApiError && e.status === 404) throw new Error(`'${where}': your account has no diagram ${cloudDocumentName(spec)} with ${tag === LATEST_TAG ? "a saved version" : `a version tagged ${tag}`}`);
|
|
28083
|
+
if (e instanceof ApiError && e.code === "ambiguous_name") throw new Error(`'${where}': several of your diagrams are named ${cloudDocumentName(spec)}; rename one`);
|
|
28084
|
+
if (e instanceof ApiError) throw new Error(`'${where}': ${e.message}`);
|
|
28085
|
+
throw e;
|
|
28086
|
+
}
|
|
28087
|
+
const b = isRecord3(body) ? body : {};
|
|
28088
|
+
const imports = b.imports ?? {};
|
|
28089
|
+
const valid = typeof b.documentId === "string" && typeof b.name === "string" && typeof b.tag === "string" && VERSION_TAG.test(b.tag) && b.tag !== LATEST_TAG && (tag === LATEST_TAG || b.tag === tag) && Number.isSafeInteger(b.seq) && b.seq > 0 && typeof b.sha256 === "string" && HASH2.test(b.sha256) && typeof b.source === "string" && isRecord3(imports) && Object.entries(imports).every(([k, v]) => typeof v === "string" && isImportKey(k));
|
|
28090
|
+
if (!valid) throw new Error(`'${where}': the versions API gave an answer that is not a version`);
|
|
28091
|
+
const version = { ...b, imports };
|
|
28092
|
+
if (canonicalSha256(version.source, version.imports) !== version.sha256) {
|
|
28093
|
+
throw new Error(`'${where}': the content does not match its sha256 ${version.sha256.slice(0, 12)}; try again`);
|
|
28094
|
+
}
|
|
28095
|
+
return {
|
|
28096
|
+
documentId: version.documentId,
|
|
28097
|
+
name: version.name,
|
|
28098
|
+
tag: version.tag,
|
|
28099
|
+
seq: version.seq,
|
|
28100
|
+
sha256: version.sha256,
|
|
28101
|
+
source: version.source,
|
|
28102
|
+
imports: version.imports
|
|
28103
|
+
};
|
|
28104
|
+
}
|
|
28105
|
+
async function findDocument(client, spec) {
|
|
28106
|
+
const body = await client.get("/api/me/documents");
|
|
28107
|
+
const documents = isRecord3(body) && Array.isArray(body.documents) ? body.documents : [];
|
|
28108
|
+
const wanted = cloudDocumentName(spec);
|
|
28109
|
+
const matches3 = documents.filter(
|
|
28110
|
+
(d) => isRecord3(d) && typeof d.id === "string" && !d.deletedAt && (d.name === spec.name || d.name === wanted)
|
|
28111
|
+
);
|
|
28112
|
+
if (matches3.length === 0) throw new Error(`Your account has no diagram named ${wanted}`);
|
|
28113
|
+
if (matches3.length > 1) throw new Error(`Several of your diagrams are named ${wanted}; rename one`);
|
|
28114
|
+
return { id: matches3[0].id, name: matches3[0].name };
|
|
28115
|
+
}
|
|
28116
|
+
async function listVersions(client, documentId) {
|
|
28117
|
+
const body = await client.get(`/api/me/documents/${encodeURIComponent(documentId)}/versions`);
|
|
28118
|
+
const list = isRecord3(body) && Array.isArray(body.versions) ? body.versions : void 0;
|
|
28119
|
+
const ok = (v) => isRecord3(v) && typeof v.tag === "string" && Number.isSafeInteger(v.seq) && typeof v.createdAt === "number" && typeof v.size === "number" && typeof v.sha256 === "string";
|
|
28120
|
+
if (!list || !list.every(ok)) throw new Error("The versions API gave an answer that is not a list of versions");
|
|
28121
|
+
const limit = isRecord3(body) && typeof body.limit === "number" ? body.limit : void 0;
|
|
28122
|
+
return { versions: list.map((v) => ({ tag: v.tag, seq: v.seq, note: typeof v.note === "string" ? v.note : null, createdAt: v.createdAt, size: v.size, sha256: v.sha256 })), limit };
|
|
28123
|
+
}
|
|
28124
|
+
|
|
28125
|
+
// src/fetchers.ts
|
|
28126
|
+
var import_node_child_process = require("node:child_process");
|
|
28127
|
+
var import_node_fs13 = require("node:fs");
|
|
28128
|
+
var import_node_os2 = require("node:os");
|
|
28129
|
+
var import_node_path13 = require("node:path");
|
|
27589
28130
|
var GIT_TIMEOUT_MS = 12e4;
|
|
27590
28131
|
var HTTPS_TIMEOUT_MS = 3e4;
|
|
27591
28132
|
var MAX_REDIRECTS = 5;
|
|
@@ -27612,11 +28153,11 @@ function gitEnv() {
|
|
|
27612
28153
|
return env;
|
|
27613
28154
|
}
|
|
27614
28155
|
var GitScratch = class {
|
|
27615
|
-
dir = (0,
|
|
27616
|
-
repo = (0,
|
|
27617
|
-
noHooks = (0,
|
|
28156
|
+
dir = (0, import_node_fs13.mkdtempSync)((0, import_node_path13.join)((0, import_node_os2.tmpdir)(), "proschi-git-"));
|
|
28157
|
+
repo = (0, import_node_path13.join)(this.dir, "repo.git");
|
|
28158
|
+
noHooks = (0, import_node_path13.join)(this.dir, "no-hooks");
|
|
27618
28159
|
constructor() {
|
|
27619
|
-
(0,
|
|
28160
|
+
(0, import_node_fs13.mkdirSync)(this.noHooks);
|
|
27620
28161
|
this.git(["init", "--bare", "--quiet", this.repo], false);
|
|
27621
28162
|
}
|
|
27622
28163
|
git(args, inRepo = true, encoding = "utf8") {
|
|
@@ -27650,7 +28191,7 @@ var GitScratch = class {
|
|
|
27650
28191
|
return this.git(["cat-file", "blob", oid], true, "buffer");
|
|
27651
28192
|
}
|
|
27652
28193
|
dispose() {
|
|
27653
|
-
(0,
|
|
28194
|
+
(0, import_node_fs13.rmSync)(this.dir, { recursive: true, force: true });
|
|
27654
28195
|
}
|
|
27655
28196
|
};
|
|
27656
28197
|
async function fetchHttps(url, fetchImpl = fetch) {
|
|
@@ -27690,32 +28231,72 @@ async function fetchHttps(url, fetchImpl = fetch) {
|
|
|
27690
28231
|
}
|
|
27691
28232
|
|
|
27692
28233
|
// src/sync.ts
|
|
27693
|
-
var IMPORTS_USAGE = ` proschi imports sync [--frozen] [<file|dir>...]`;
|
|
28234
|
+
var IMPORTS_USAGE = ` proschi imports sync [--frozen | --update [<cloud:spec>...]] [--base <url>] [<file|dir>...]`;
|
|
27694
28235
|
var IMPORTS_HELP = `imports sync
|
|
27695
|
-
Downloads the git
|
|
27696
|
-
current folder) into .proschi/cache and pins them in proschi.lock
|
|
27697
|
-
|
|
27698
|
-
|
|
28236
|
+
Downloads the git:, https:// and cloud: imports of the files (default:
|
|
28237
|
+
the current folder) into .proschi/cache and pins them in proschi.lock:
|
|
28238
|
+
a git ref to its commit, cloud:<name> (latest) or cloud:<name>:<tag>
|
|
28239
|
+
to the version's tag, seq and sha256. A pinned import stays pinned;
|
|
28240
|
+
--update moves the given cloud:<name> imports (default: all of them)
|
|
28241
|
+
to their newest saved version (a concrete tag never moves). cloud:
|
|
28242
|
+
sources need proschi login (--base: the site, default
|
|
28243
|
+
${DEFAULT_SITE}). No other command fetches imports. --frozen fails
|
|
28244
|
+
instead of changing proschi.lock (for CI).`;
|
|
27699
28245
|
var staleLock = (what) => new ImportError(`${LOCK_FILE} is out of date: ${what}; run proschi imports sync and commit ${LOCK_FILE}`);
|
|
27700
|
-
async function syncImports(entries2, { frozen = false, fetch: fetch2, gitUrl = defaultGitUrl } = {}) {
|
|
28246
|
+
async function syncImports(entries2, { frozen = false, update, fetch: fetch2, gitUrl = defaultGitUrl, api } = {}) {
|
|
28247
|
+
const updated = {};
|
|
27701
28248
|
const roots = [...new Set(entries2.map((e) => projectRoot(e)))];
|
|
27702
28249
|
if (roots.length !== 1) {
|
|
27703
28250
|
const errors2 = roots.length ? [`The files belong to different project roots (${roots.map((r) => displayPath3(r)).join(", ")}); sync each separately`] : ["No .proschi files to sync"];
|
|
27704
|
-
return { root: roots[0] ?? "", lock: emptyLock(), errors: errors2, written: false };
|
|
28251
|
+
return { root: roots[0] ?? "", lock: emptyLock(), errors: errors2, written: false, updated };
|
|
27705
28252
|
}
|
|
27706
28253
|
const [root] = roots;
|
|
27707
28254
|
const lock = emptyLock();
|
|
28255
|
+
const fail2 = (errors2) => ({ root, lock, errors: errors2, written: false, updated });
|
|
28256
|
+
if (frozen && update) return fail2(["--update and --frozen cannot be used together"]);
|
|
28257
|
+
let moving;
|
|
28258
|
+
const asked = [];
|
|
28259
|
+
if (update === true) moving = true;
|
|
28260
|
+
else if (update) {
|
|
28261
|
+
moving = /* @__PURE__ */ new Set();
|
|
28262
|
+
for (const spec of update) {
|
|
28263
|
+
let remote;
|
|
28264
|
+
try {
|
|
28265
|
+
remote = parseRemoteSpec(spec);
|
|
28266
|
+
} catch (e) {
|
|
28267
|
+
return fail2([e.message]);
|
|
28268
|
+
}
|
|
28269
|
+
if (remote?.kind !== "cloud" || remote.path !== void 0) return fail2([`--update takes cloud:<name> imports, not '${spec}'`]);
|
|
28270
|
+
const key = cloudKey(remote.name, remote.tag);
|
|
28271
|
+
asked.push(key);
|
|
28272
|
+
if (remote.tag === LATEST_TAG) moving.add(key);
|
|
28273
|
+
}
|
|
28274
|
+
}
|
|
28275
|
+
const moves = (key) => moving === true ? key.endsWith(`:${LATEST_TAG}`) : !!moving?.has(key);
|
|
27708
28276
|
let old;
|
|
27709
28277
|
try {
|
|
27710
28278
|
old = readLock(root);
|
|
27711
28279
|
} catch (e) {
|
|
27712
|
-
return
|
|
28280
|
+
return fail2([e.message]);
|
|
27713
28281
|
}
|
|
27714
|
-
if (frozen && !old) return
|
|
28282
|
+
if (frozen && !old) return fail2([`${LOCK_FILE} is missing; run proschi imports sync and commit it`]);
|
|
27715
28283
|
const texts = /* @__PURE__ */ new Map();
|
|
27716
28284
|
const failed = /* @__PURE__ */ new Map();
|
|
27717
28285
|
const scratches = /* @__PURE__ */ new Map();
|
|
27718
28286
|
const commits = /* @__PURE__ */ new Map();
|
|
28287
|
+
const versions = /* @__PURE__ */ new Map();
|
|
28288
|
+
const version = (spec, remote, tag) => {
|
|
28289
|
+
const key = cloudKey(remote.name, tag);
|
|
28290
|
+
if (!versions.has(key)) {
|
|
28291
|
+
const client = api ??= new ApiClient({ base: DEFAULT_SITE });
|
|
28292
|
+
const got = client.signedIn() ? resolveVersion(client, remote, tag).catch((e) => {
|
|
28293
|
+
throw e instanceof ImportError ? e : new ImportError(e.message.startsWith("'cloud:") ? e.message : `'${spec}': ${e.message}`);
|
|
28294
|
+
}) : Promise.reject(new ImportError(`'${spec}': cloud: sources need \`proschi login\``));
|
|
28295
|
+
got.catch(() => void 0);
|
|
28296
|
+
versions.set(key, got);
|
|
28297
|
+
}
|
|
28298
|
+
return versions.get(key);
|
|
28299
|
+
};
|
|
27719
28300
|
const obtain = async (spec) => {
|
|
27720
28301
|
const remote = parseRemoteSpec(spec);
|
|
27721
28302
|
const cached = (hash) => {
|
|
@@ -27726,25 +28307,50 @@ async function syncImports(entries2, { frozen = false, fetch: fetch2, gitUrl = d
|
|
|
27726
28307
|
}
|
|
27727
28308
|
};
|
|
27728
28309
|
const changed = (pin) => new ImportError(`'${spec}' does not match its sha256 in ${LOCK_FILE} (${pin}); its content changed. If that is expected, delete its entry from ${LOCK_FILE} and sync again`);
|
|
28310
|
+
if (remote.kind === "cloud") {
|
|
28311
|
+
const key2 = cloudKey(remote.name, remote.tag);
|
|
28312
|
+
const pinned = moves(key2) ? void 0 : old?.cloud[key2];
|
|
28313
|
+
const pinnedHash2 = remote.path === void 0 ? pinned?.source : pinned?.files[remote.path];
|
|
28314
|
+
if (frozen && !pinnedHash2) throw staleLock(`'${spec}' is not locked`);
|
|
28315
|
+
let bytes3 = cached(pinnedHash2);
|
|
28316
|
+
let at = pinned;
|
|
28317
|
+
if (!bytes3) {
|
|
28318
|
+
const got = await version(spec, remote, pinned?.tag ?? remote.tag);
|
|
28319
|
+
if (pinned && (got.sha256 !== pinned.sha256 || got.seq !== pinned.seq)) {
|
|
28320
|
+
throw changed(`version ${pinned.tag}, seq ${pinned.seq}, sha256 ${pinned.sha256.slice(0, 12)}`);
|
|
28321
|
+
}
|
|
28322
|
+
const text2 = remote.path === void 0 ? got.source : got.imports[remote.path];
|
|
28323
|
+
if (text2 === void 0) throw new ImportError(`'${spec}': no file ${remote.path} is saved with cloud:${remote.name}:${got.tag}`);
|
|
28324
|
+
bytes3 = Buffer.from(text2, "utf8");
|
|
28325
|
+
if (pinnedHash2 && sha256(bytes3) !== pinnedHash2) throw changed(`version ${got.tag}`);
|
|
28326
|
+
writeCached(root, bytes3);
|
|
28327
|
+
at = { tag: got.tag, seq: got.seq, sha256: got.sha256, files: {} };
|
|
28328
|
+
if (moves(key2)) updated[key2] = { from: old?.cloud[key2]?.tag, to: got.tag };
|
|
28329
|
+
}
|
|
28330
|
+
const entry = lock.cloud[key2] ??= { tag: at.tag, seq: at.seq, sha256: at.sha256, files: {} };
|
|
28331
|
+
if (remote.path === void 0) entry.source = sha256(bytes3);
|
|
28332
|
+
else entry.files[remote.path] = sha256(bytes3);
|
|
28333
|
+
return bytes3;
|
|
28334
|
+
}
|
|
27729
28335
|
if (remote.kind === "https") {
|
|
27730
28336
|
const pinned = old?.https[remote.url];
|
|
27731
28337
|
if (frozen && !pinned) throw staleLock(`'${spec}' is not locked`);
|
|
27732
|
-
let
|
|
27733
|
-
if (!
|
|
27734
|
-
|
|
27735
|
-
if (pinned && sha256(
|
|
27736
|
-
writeCached(root,
|
|
28338
|
+
let bytes3 = cached(pinned);
|
|
28339
|
+
if (!bytes3) {
|
|
28340
|
+
bytes3 = await fetchHttps(remote.url, fetch2);
|
|
28341
|
+
if (pinned && sha256(bytes3) !== pinned) throw changed(`sha256 ${pinned.slice(0, 12)}`);
|
|
28342
|
+
writeCached(root, bytes3);
|
|
27737
28343
|
}
|
|
27738
|
-
lock.https[remote.url] = sha256(
|
|
27739
|
-
return
|
|
28344
|
+
lock.https[remote.url] = sha256(bytes3);
|
|
28345
|
+
return bytes3;
|
|
27740
28346
|
}
|
|
27741
28347
|
const key = gitKey(remote.repo, remote.ref);
|
|
27742
28348
|
const pinnedEntry = old?.git[key];
|
|
27743
28349
|
const pinnedHash = pinnedEntry?.files[remote.path];
|
|
27744
28350
|
if (frozen && !pinnedHash) throw staleLock(`'${spec}' is not locked`);
|
|
27745
|
-
let
|
|
28351
|
+
let bytes2 = cached(pinnedHash);
|
|
27746
28352
|
let commit = pinnedEntry?.commit;
|
|
27747
|
-
if (!
|
|
28353
|
+
if (!bytes2) {
|
|
27748
28354
|
let scratch = scratches.get(remote.repo);
|
|
27749
28355
|
if (!scratch) scratches.set(remote.repo, scratch = new GitScratch());
|
|
27750
28356
|
if (!commits.has(key)) {
|
|
@@ -27754,13 +28360,13 @@ async function syncImports(entries2, { frozen = false, fetch: fetch2, gitUrl = d
|
|
|
27754
28360
|
commits.set(key, got);
|
|
27755
28361
|
}
|
|
27756
28362
|
commit = commits.get(key);
|
|
27757
|
-
|
|
27758
|
-
if (pinnedHash && sha256(
|
|
27759
|
-
writeCached(root,
|
|
28363
|
+
bytes2 = scratch.read(commit, remote.path, spec);
|
|
28364
|
+
if (pinnedHash && sha256(bytes2) !== pinnedHash) throw changed(`commit ${commit.slice(0, 12)}`);
|
|
28365
|
+
writeCached(root, bytes2);
|
|
27760
28366
|
}
|
|
27761
28367
|
lock.git[key] ??= { commit, files: {} };
|
|
27762
|
-
lock.git[key].files[remote.path] = sha256(
|
|
27763
|
-
return
|
|
28368
|
+
lock.git[key].files[remote.path] = sha256(bytes2);
|
|
28369
|
+
return bytes2;
|
|
27764
28370
|
};
|
|
27765
28371
|
let errors = [];
|
|
27766
28372
|
try {
|
|
@@ -27776,7 +28382,7 @@ async function syncImports(entries2, { frozen = false, fetch: fetch2, gitUrl = d
|
|
|
27776
28382
|
return void 0;
|
|
27777
28383
|
}
|
|
27778
28384
|
});
|
|
27779
|
-
parse((0,
|
|
28385
|
+
parse((0, import_node_fs14.readFileSync)(entry, "utf8"), { path: entry, resolve: resolver });
|
|
27780
28386
|
for (const [where, message] of resolver.errors) {
|
|
27781
28387
|
const from = where.split("\0")[0] || entry;
|
|
27782
28388
|
found.add(`${isRemoteSpec(from) ? from : displayPath3(from)}: ${message}`);
|
|
@@ -27799,15 +28405,18 @@ async function syncImports(entries2, { frozen = false, fetch: fetch2, gitUrl = d
|
|
|
27799
28405
|
for (const scratch of scratches.values()) scratch.dispose();
|
|
27800
28406
|
}
|
|
27801
28407
|
errors.push(...failed.values());
|
|
27802
|
-
if (
|
|
28408
|
+
for (const key of asked) if (!lock.cloud[key]) errors.push(`--update: 'cloud:${key}' is not imported by these files`);
|
|
28409
|
+
if (errors.length) return fail2(errors);
|
|
27803
28410
|
const text = formatLock(lock);
|
|
27804
28411
|
if (old && text !== formatLock(old)) {
|
|
27805
|
-
if (frozen) return
|
|
28412
|
+
if (frozen) return fail2([staleLock("it locks imports that are no longer used").message]);
|
|
27806
28413
|
}
|
|
27807
|
-
const write = !frozen && (old ? text !== formatLock(old) :
|
|
28414
|
+
const write = !frozen && (old ? text !== formatLock(old) : lockedSources(lock) > 0);
|
|
27808
28415
|
if (write) writeLock(root, lock);
|
|
27809
|
-
return { root, lock, errors, written: write };
|
|
28416
|
+
return { root, lock, errors, written: write, updated };
|
|
27810
28417
|
}
|
|
28418
|
+
var lockedSources = (lock) => Object.keys(lock.git).length + Object.keys(lock.https).length + Object.keys(lock.cloud).length;
|
|
28419
|
+
var lockedFiles = (lock) => Object.values(lock.git).reduce((n, g) => n + Object.keys(g.files).length, 0) + Object.keys(lock.https).length + Object.values(lock.cloud).reduce((n, c) => n + Object.keys(c.files).length + (c.source ? 1 : 0), 0);
|
|
27811
28420
|
async function runImports(args, collectFiles2, out, err, options = {}) {
|
|
27812
28421
|
const [sub, ...rest] = args;
|
|
27813
28422
|
if (sub !== "sync") {
|
|
@@ -27816,10 +28425,22 @@ ${IMPORTS_USAGE}`);
|
|
|
27816
28425
|
return 2;
|
|
27817
28426
|
}
|
|
27818
28427
|
let frozen = false;
|
|
28428
|
+
let update;
|
|
28429
|
+
let base;
|
|
27819
28430
|
const paths = [];
|
|
27820
|
-
for (
|
|
28431
|
+
for (let i = 0; i < rest.length; i++) {
|
|
28432
|
+
const arg = rest[i];
|
|
27821
28433
|
if (arg === "--frozen") frozen = true;
|
|
27822
|
-
else if (arg
|
|
28434
|
+
else if (arg === "--update") update ??= true;
|
|
28435
|
+
else if (update && arg.startsWith("cloud:")) update = [...update === true ? [] : update, arg];
|
|
28436
|
+
else if (arg === "--base") {
|
|
28437
|
+
try {
|
|
28438
|
+
base = normalizeBase(rest[++i] ?? "");
|
|
28439
|
+
} catch (e) {
|
|
28440
|
+
err(e.message);
|
|
28441
|
+
return 2;
|
|
28442
|
+
}
|
|
28443
|
+
} else if (arg.startsWith("-")) {
|
|
27823
28444
|
err(`Unknown option ${arg}
|
|
27824
28445
|
|
|
27825
28446
|
Usage:
|
|
@@ -27834,21 +28455,332 @@ ${IMPORTS_USAGE}`);
|
|
|
27834
28455
|
err(String(e.message));
|
|
27835
28456
|
return 2;
|
|
27836
28457
|
}
|
|
27837
|
-
const
|
|
28458
|
+
const api = options.api ?? (base ? new ApiClient({ base }) : void 0);
|
|
28459
|
+
const result = await syncImports(files, { ...options, api, frozen, update });
|
|
27838
28460
|
if (result.errors.length) {
|
|
27839
28461
|
err(result.errors.map((e) => `error: ${e}`).join("\n"));
|
|
27840
28462
|
return 1;
|
|
27841
28463
|
}
|
|
27842
|
-
const
|
|
27843
|
-
const
|
|
28464
|
+
for (const [key, { from, to }] of Object.entries(result.updated)) out(from === to ? `cloud:${key}: ${to} (already the newest)` : `cloud:${key}: ${from ?? "(not pinned)"} -> ${to}`);
|
|
28465
|
+
const sources = lockedSources(result.lock);
|
|
28466
|
+
const filesLocked = lockedFiles(result.lock);
|
|
27844
28467
|
const lockPath = displayPath3(`${result.root}/${LOCK_FILE}`);
|
|
27845
|
-
if (!sources) out("No git
|
|
28468
|
+
if (!sources) out("No git:, https:// or cloud: imports to sync");
|
|
27846
28469
|
else out(`${filesLocked} remote file(s) from ${sources} source(s) ${result.written ? "locked in" : "match"} ${lockPath}`);
|
|
27847
28470
|
return 0;
|
|
27848
28471
|
}
|
|
27849
28472
|
|
|
28473
|
+
// src/login.ts
|
|
28474
|
+
var import_node_child_process2 = require("node:child_process");
|
|
28475
|
+
var import_node_crypto3 = require("node:crypto");
|
|
28476
|
+
var import_node_http = require("node:http");
|
|
28477
|
+
var LOGIN_USAGE = ` proschi login [--provider github|google] [--base <url>]
|
|
28478
|
+
proschi logout [--base <url>]
|
|
28479
|
+
proschi whoami [--base <url>]`;
|
|
28480
|
+
var LOGIN_HELP = `login Signs in to your Proschi account in the browser (the link is printed
|
|
28481
|
+
too, for a machine without one) and stores the tokens in your user's
|
|
28482
|
+
config folder (readable by you only). cloud: imports and proschi
|
|
28483
|
+
versions need it. --base sets the site (default ${DEFAULT_SITE}).
|
|
28484
|
+
logout Ends the sign-in and deletes its tokens.
|
|
28485
|
+
whoami Prints the account you are signed in as.`;
|
|
28486
|
+
var PROVIDERS = ["github", "google"];
|
|
28487
|
+
var LOGIN_TIMEOUT_MS = 5 * 6e4;
|
|
28488
|
+
var base64url = (bytes2) => bytes2.toString("base64url");
|
|
28489
|
+
function openBrowser(url) {
|
|
28490
|
+
const [command, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["rundll32", ["url.dll,FileProtocolHandler", url]] : ["xdg-open", [url]];
|
|
28491
|
+
return new Promise((resolve8, reject) => {
|
|
28492
|
+
const child = (0, import_node_child_process2.execFile)(command, args, { timeout: 1e4, windowsHide: true }, (error) => error ? reject(error) : resolve8());
|
|
28493
|
+
child.on("error", reject);
|
|
28494
|
+
});
|
|
28495
|
+
}
|
|
28496
|
+
var page = (title, text) => `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>${title}</title><meta name="viewport" content="width=device-width,initial-scale=1"><style>body{font:16px/1.5 system-ui,sans-serif;margin:0;min-height:100vh;display:grid;place-items:center;background:#f8fafc;color:#0f172a}main{max-width:28rem;padding:2rem;text-align:center}h1{font-size:1.25rem}@media(prefers-color-scheme:dark){body{background:#0f172a;color:#e2e8f0}}</style></head><body><main><h1>${title}</h1><p>${text}</p></main></body></html>`;
|
|
28497
|
+
var sameText = (a, b) => {
|
|
28498
|
+
const x = Buffer.from(a);
|
|
28499
|
+
const y = Buffer.from(b);
|
|
28500
|
+
return x.length === y.length && (0, import_node_crypto3.timingSafeEqual)(x, y);
|
|
28501
|
+
};
|
|
28502
|
+
async function login({
|
|
28503
|
+
base = DEFAULT_SITE,
|
|
28504
|
+
provider = "github",
|
|
28505
|
+
store = new CredentialStore(),
|
|
28506
|
+
fetch: fetchImpl = fetch,
|
|
28507
|
+
open = openBrowser,
|
|
28508
|
+
print = () => void 0,
|
|
28509
|
+
timeoutMs = LOGIN_TIMEOUT_MS
|
|
28510
|
+
} = {}) {
|
|
28511
|
+
const verifier = base64url((0, import_node_crypto3.randomBytes)(32));
|
|
28512
|
+
const challenge = base64url((0, import_node_crypto3.createHash)("sha256").update(verifier).digest());
|
|
28513
|
+
const state = base64url((0, import_node_crypto3.randomBytes)(24));
|
|
28514
|
+
let settle;
|
|
28515
|
+
const callback = new Promise((resolve8, reject) => settle = { resolve: resolve8, reject });
|
|
28516
|
+
let done = false;
|
|
28517
|
+
const server = (0, import_node_http.createServer)((req, res) => {
|
|
28518
|
+
const reply = (status, title, text) => {
|
|
28519
|
+
res.writeHead(status, { "content-type": "text/html; charset=utf-8", "cache-control": "no-store", "content-security-policy": "default-src 'none'; style-src 'unsafe-inline'" });
|
|
28520
|
+
res.end(page(title, text));
|
|
28521
|
+
};
|
|
28522
|
+
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
28523
|
+
if (done || req.method !== "GET" || url.pathname !== "/callback") return reply(404, "Not found", "Nothing here.");
|
|
28524
|
+
done = true;
|
|
28525
|
+
const got = url.searchParams.get("state") ?? "";
|
|
28526
|
+
const code = url.searchParams.get("code");
|
|
28527
|
+
const error = url.searchParams.get("error");
|
|
28528
|
+
if (!sameText(got, state)) {
|
|
28529
|
+
reply(400, "Sign-in failed", "This sign-in did not come from the proschi login that is waiting. Run proschi login again.");
|
|
28530
|
+
settle.reject(new Error("The sign-in answer does not match this login (state mismatch); run proschi login again"));
|
|
28531
|
+
} else if (error || !code) {
|
|
28532
|
+
reply(400, "Sign-in failed", error === "access_denied" ? "The sign-in was cancelled. You can close this tab." : "The sign-in did not finish. You can close this tab and try again.");
|
|
28533
|
+
settle.reject(new Error(error === "access_denied" ? "The sign-in was cancelled" : `The sign-in failed${error ? ` (${error.replace(/[^\w-]/g, "").slice(0, 40)})` : ""}`));
|
|
28534
|
+
} else {
|
|
28535
|
+
reply(200, "Signed in to Proschi", "You can close this tab and return to the terminal.");
|
|
28536
|
+
settle.resolve(code);
|
|
28537
|
+
}
|
|
28538
|
+
});
|
|
28539
|
+
server.keepAliveTimeout = 1;
|
|
28540
|
+
await new Promise((resolve8, reject) => {
|
|
28541
|
+
server.once("error", reject);
|
|
28542
|
+
server.listen(0, "127.0.0.1", () => resolve8());
|
|
28543
|
+
});
|
|
28544
|
+
const address = server.address();
|
|
28545
|
+
const port = typeof address === "object" && address ? address.port : 0;
|
|
28546
|
+
const redirectUri = `http://127.0.0.1:${port}/callback`;
|
|
28547
|
+
const timer = setTimeout(() => settle.reject(new Error(`No sign-in within ${Math.round(timeoutMs / 6e4) || 1} minute(s); run proschi login again`)), timeoutMs);
|
|
28548
|
+
try {
|
|
28549
|
+
const start = new URL(`${base}/auth/${provider}/start`);
|
|
28550
|
+
start.search = new URLSearchParams({ client: "proschi-cli", redirect_uri: redirectUri, code_challenge: challenge, code_challenge_method: "S256", state }).toString();
|
|
28551
|
+
print(`Opening your browser to sign in to ${base}. If it does not open, visit:
|
|
28552
|
+
|
|
28553
|
+
${start.href}
|
|
28554
|
+
`);
|
|
28555
|
+
open(start.href).catch(() => print("Could not open a browser; open the link above."));
|
|
28556
|
+
const code = await callback;
|
|
28557
|
+
const session = await requestTokens(fetchImpl, base, { grant_type: "authorization_code", code, code_verifier: verifier, redirect_uri: redirectUri });
|
|
28558
|
+
store.set(base, session);
|
|
28559
|
+
} finally {
|
|
28560
|
+
clearTimeout(timer);
|
|
28561
|
+
server.closeAllConnections?.();
|
|
28562
|
+
server.close();
|
|
28563
|
+
}
|
|
28564
|
+
}
|
|
28565
|
+
async function logout({ base = DEFAULT_SITE, store = new CredentialStore(), fetch: fetchImpl = fetch } = {}) {
|
|
28566
|
+
const session = store.get(base);
|
|
28567
|
+
if (!session) return { signedIn: false, revoked: false };
|
|
28568
|
+
let revoked = false;
|
|
28569
|
+
try {
|
|
28570
|
+
const response2 = await send(fetchImpl, `${base}/auth/revoke`, {
|
|
28571
|
+
method: "POST",
|
|
28572
|
+
headers: { "content-type": "application/json" },
|
|
28573
|
+
body: JSON.stringify({ token: session.refreshToken })
|
|
28574
|
+
});
|
|
28575
|
+
await response2.body?.cancel();
|
|
28576
|
+
revoked = response2.ok;
|
|
28577
|
+
} catch {
|
|
28578
|
+
}
|
|
28579
|
+
store.delete(base);
|
|
28580
|
+
return { signedIn: true, revoked };
|
|
28581
|
+
}
|
|
28582
|
+
async function runAuth(command, args, out, err, deps = {}) {
|
|
28583
|
+
let base = DEFAULT_SITE;
|
|
28584
|
+
let provider = "github";
|
|
28585
|
+
for (let i = 0; i < args.length; i++) {
|
|
28586
|
+
const arg = args[i];
|
|
28587
|
+
if (arg === "--base") {
|
|
28588
|
+
try {
|
|
28589
|
+
base = normalizeBase(args[++i] ?? "");
|
|
28590
|
+
} catch (e) {
|
|
28591
|
+
err(e.message);
|
|
28592
|
+
return 2;
|
|
28593
|
+
}
|
|
28594
|
+
} else if (arg === "--provider" && command === "login") {
|
|
28595
|
+
const value2 = args[++i];
|
|
28596
|
+
if (!PROVIDERS.includes(value2)) {
|
|
28597
|
+
err(`Unknown provider '${value2 ?? ""}'; use ${PROVIDERS.join(" or ")}`);
|
|
28598
|
+
return 2;
|
|
28599
|
+
}
|
|
28600
|
+
provider = value2;
|
|
28601
|
+
} else {
|
|
28602
|
+
err(`Unknown option ${arg}
|
|
28603
|
+
|
|
28604
|
+
Usage:
|
|
28605
|
+
${LOGIN_USAGE}`);
|
|
28606
|
+
return 2;
|
|
28607
|
+
}
|
|
28608
|
+
}
|
|
28609
|
+
try {
|
|
28610
|
+
if (command === "login") {
|
|
28611
|
+
await login({ base, provider, ...deps, print: err });
|
|
28612
|
+
out(`Signed in to ${base}`);
|
|
28613
|
+
return 0;
|
|
28614
|
+
}
|
|
28615
|
+
if (command === "logout") {
|
|
28616
|
+
const { signedIn, revoked } = await logout({ base, ...deps });
|
|
28617
|
+
if (!signedIn) out(`Not signed in to ${base}`);
|
|
28618
|
+
else out(revoked ? `Signed out of ${base}` : `Deleted the stored sign-in for ${base} (the site could not be reached to end it; it expires on its own)`);
|
|
28619
|
+
return 0;
|
|
28620
|
+
}
|
|
28621
|
+
const me = await new ApiClient({ base, store: deps.store, fetch: deps.fetch }).get("/api/me");
|
|
28622
|
+
const name = typeof me?.user?.displayName === "string" ? me.user.displayName : "an account without a name";
|
|
28623
|
+
out(`Signed in to ${base} as ${name}`);
|
|
28624
|
+
return 0;
|
|
28625
|
+
} catch (e) {
|
|
28626
|
+
err(`error: ${e.message}`);
|
|
28627
|
+
return 1;
|
|
28628
|
+
}
|
|
28629
|
+
}
|
|
28630
|
+
|
|
28631
|
+
// src/versions.ts
|
|
28632
|
+
var VERSIONS_USAGE = ` proschi versions list [--json] [--base <url>] <name>
|
|
28633
|
+
proschi versions diff [--json] [--base <url>] <name> <base-tag> [<target-tag>|<file.proschi>]`;
|
|
28634
|
+
var VERSIONS_HELP = `versions
|
|
28635
|
+
Reads the saved versions of a diagram in your account (proschi login
|
|
28636
|
+
first; <name> is its file name, with or without .proschi). list
|
|
28637
|
+
prints them, newest first. diff prints what changed from <base-tag>
|
|
28638
|
+
to <target-tag> (default: latest), or to a local file (a target
|
|
28639
|
+
ending in .proschi or containing a /). --json prints the result for
|
|
28640
|
+
scripts. Never changes proschi.lock or the cache.`;
|
|
28641
|
+
var SECTION_TITLES = {
|
|
28642
|
+
nodes: "Nodes",
|
|
28643
|
+
edges: "Edges",
|
|
28644
|
+
useCases: "Use cases",
|
|
28645
|
+
scenarios: "Scenarios",
|
|
28646
|
+
requirements: "Requirements",
|
|
28647
|
+
traffic: "Traffic",
|
|
28648
|
+
capacity: "Capacity",
|
|
28649
|
+
systems: "Systems"
|
|
28650
|
+
};
|
|
28651
|
+
function itemLabel(section2, item) {
|
|
28652
|
+
switch (section2) {
|
|
28653
|
+
case "edges": {
|
|
28654
|
+
const e = item;
|
|
28655
|
+
return `${e.source} -> ${e.target}${e.label ? ` : ${e.label}` : ""}`;
|
|
28656
|
+
}
|
|
28657
|
+
case "scenarios": {
|
|
28658
|
+
const s = item;
|
|
28659
|
+
return `${s.useCase}/${s.scenario.id}`;
|
|
28660
|
+
}
|
|
28661
|
+
case "requirements":
|
|
28662
|
+
return requirementKey(item);
|
|
28663
|
+
case "traffic":
|
|
28664
|
+
return item.useCase;
|
|
28665
|
+
case "capacity":
|
|
28666
|
+
return item.node;
|
|
28667
|
+
case "systems":
|
|
28668
|
+
return item.id;
|
|
28669
|
+
default:
|
|
28670
|
+
return item.id;
|
|
28671
|
+
}
|
|
28672
|
+
}
|
|
28673
|
+
var value = (v) => v === void 0 || v === null ? "(none)" : typeof v === "string" ? JSON.stringify(v) : typeof v === "object" ? JSON.stringify(v) : String(v);
|
|
28674
|
+
function changeLines({ field, before: before2, after: after2 }, indent2) {
|
|
28675
|
+
const list = (v) => Array.isArray(v) && v.every((x) => typeof x === "string");
|
|
28676
|
+
if ((list(before2) || before2 === void 0) && (list(after2) || after2 === void 0) && (before2 !== void 0 || after2 !== void 0)) {
|
|
28677
|
+
const old = before2 ?? [];
|
|
28678
|
+
const next = after2 ?? [];
|
|
28679
|
+
const lines = [`${indent2}${field}:`];
|
|
28680
|
+
for (const line of old) if (!next.includes(line)) lines.push(`${indent2} - ${line}`);
|
|
28681
|
+
for (const line of next) if (!old.includes(line)) lines.push(`${indent2} + ${line}`);
|
|
28682
|
+
if (lines.length === 1) lines.push(`${indent2} (reordered)`);
|
|
28683
|
+
return lines;
|
|
28684
|
+
}
|
|
28685
|
+
return [`${indent2}${field}: ${value(before2)} \u2192 ${value(after2)}`];
|
|
28686
|
+
}
|
|
28687
|
+
function formatDiff(diff, from, to) {
|
|
28688
|
+
const lines = [`${from} \u2192 ${to}`, ""];
|
|
28689
|
+
if (diff.diagram.length) {
|
|
28690
|
+
lines.push("Diagram");
|
|
28691
|
+
for (const c of diff.diagram) lines.push(...changeLines(c, " ~ "));
|
|
28692
|
+
}
|
|
28693
|
+
for (const section2 of DIFF_SECTIONS) {
|
|
28694
|
+
const { added, removed, changed } = diff[section2];
|
|
28695
|
+
if (!added.length && !removed.length && !changed.length) continue;
|
|
28696
|
+
lines.push(SECTION_TITLES[section2]);
|
|
28697
|
+
for (const item of added) lines.push(` + ${itemLabel(section2, item)}`);
|
|
28698
|
+
for (const item of removed) lines.push(` - ${itemLabel(section2, item)}`);
|
|
28699
|
+
for (const item of changed) {
|
|
28700
|
+
lines.push(` ~ ${item.key}`);
|
|
28701
|
+
for (const c of item.changes) lines.push(...changeLines(c, " "));
|
|
28702
|
+
}
|
|
28703
|
+
}
|
|
28704
|
+
const { total } = summarizeDiff(diff);
|
|
28705
|
+
if (lines.length === 2) lines.push("No changes");
|
|
28706
|
+
else lines.push("", `${total.added} added, ${total.removed} removed, ${total.changed} changed`);
|
|
28707
|
+
return lines.join("\n");
|
|
28708
|
+
}
|
|
28709
|
+
var parseVersion = (v) => parse(v.source, { path: v.name, resolve: mapResolver(v.imports) });
|
|
28710
|
+
var date = (ms) => new Date(ms).toISOString().slice(0, 16).replace("T", " ");
|
|
28711
|
+
var bytes = (n) => n < 1024 ? `${n} B` : `${(n / 1024).toFixed(1)} KB`;
|
|
28712
|
+
function formatVersionList(name, versions, limit) {
|
|
28713
|
+
const head = `${name}: ${versions.length} version${versions.length === 1 ? "" : "s"}${limit !== void 0 ? ` (keeps up to ${limit})` : ""}`;
|
|
28714
|
+
if (!versions.length) return `${head}
|
|
28715
|
+
Save one in the editor (Versions) to import it as cloud:${name.replace(/\.proschi$/, "")}:<tag>`;
|
|
28716
|
+
const rows = [["TAG", "SEQ", "SAVED (UTC)", "SIZE", "NOTE"], ...versions.map((v) => [v.tag, `#${v.seq}`, date(v.createdAt), bytes(v.size), v.note ?? ""])];
|
|
28717
|
+
const widths = rows[0].map((_, i) => Math.max(...rows.map((r) => r[i].length)));
|
|
28718
|
+
return [head, ...rows.map((r) => ` ${r.map((c, i) => i === r.length - 1 ? c : c.padEnd(widths[i])).join(" ")}`.trimEnd())].join("\n");
|
|
28719
|
+
}
|
|
28720
|
+
async function runVersions(args, out, err, deps = {}) {
|
|
28721
|
+
const [sub, ...rest] = args;
|
|
28722
|
+
let json2 = false;
|
|
28723
|
+
let base = DEFAULT_SITE;
|
|
28724
|
+
const positional = [];
|
|
28725
|
+
for (let i = 0; i < rest.length; i++) {
|
|
28726
|
+
const arg = rest[i];
|
|
28727
|
+
if (arg === "--json") json2 = true;
|
|
28728
|
+
else if (arg === "--base") {
|
|
28729
|
+
try {
|
|
28730
|
+
base = normalizeBase(rest[++i] ?? "");
|
|
28731
|
+
} catch (e) {
|
|
28732
|
+
err(e.message);
|
|
28733
|
+
return 2;
|
|
28734
|
+
}
|
|
28735
|
+
} else if (arg.startsWith("-")) {
|
|
28736
|
+
err(`Unknown option ${arg}
|
|
28737
|
+
|
|
28738
|
+
Usage:
|
|
28739
|
+
${VERSIONS_USAGE}`);
|
|
28740
|
+
return 2;
|
|
28741
|
+
} else positional.push(arg);
|
|
28742
|
+
}
|
|
28743
|
+
const usage = () => (err(`Usage:
|
|
28744
|
+
${VERSIONS_USAGE}`), 2);
|
|
28745
|
+
if (sub === "list" ? positional.length !== 1 : sub === "diff" ? positional.length < 2 || positional.length > 3 : true) return usage();
|
|
28746
|
+
const client = new ApiClient({ base, store: deps.store, fetch: deps.fetch });
|
|
28747
|
+
try {
|
|
28748
|
+
const spec = cloudName(positional[0]);
|
|
28749
|
+
if (sub === "list") {
|
|
28750
|
+
const doc = await findDocument(client, spec);
|
|
28751
|
+
const { versions, limit } = await listVersions(client, doc.id);
|
|
28752
|
+
out(json2 ? JSON.stringify({ name: doc.name, documentId: doc.id, versions, limit }, null, 2) : formatVersionList(doc.name, versions, limit));
|
|
28753
|
+
return 0;
|
|
28754
|
+
}
|
|
28755
|
+
const [, baseTag, target = LATEST_TAG] = positional;
|
|
28756
|
+
const isFile = target.endsWith(".proschi") || target.includes("/") || target.includes("\\");
|
|
28757
|
+
for (const tag of isFile ? [baseTag] : [baseTag, target]) {
|
|
28758
|
+
if (!VERSION_TAG.test(tag)) throw new Error(`'${tag}' is not a version tag (letters, digits, '.', '_' and '-'), or latest`);
|
|
28759
|
+
}
|
|
28760
|
+
const before2 = await resolveVersion(client, spec, baseTag);
|
|
28761
|
+
const after2 = isFile ? void 0 : await resolveVersion(client, spec, target);
|
|
28762
|
+
const left = parseVersion(before2);
|
|
28763
|
+
const right = after2 ? parseVersion(after2) : parseFile(target);
|
|
28764
|
+
const label = (v, asked) => `cloud:${spec.name}:${v.tag} (#${v.seq}${asked === LATEST_TAG ? ", latest" : ""})`;
|
|
28765
|
+
const toLabel = after2 ? label(after2, target) : displayPath3(target);
|
|
28766
|
+
for (const [what, r] of [[label(before2, baseTag), left], [toLabel, right]]) {
|
|
28767
|
+
const errors = r.diagnostics.filter((d) => d.severity === "error").length;
|
|
28768
|
+
if (errors) err(`warning: ${what} has ${errors} error(s); the diff covers what parsed`);
|
|
28769
|
+
}
|
|
28770
|
+
const diff = diffDiagrams(left.diagram, right.diagram);
|
|
28771
|
+
if (json2) {
|
|
28772
|
+
const side = (v) => ({ tag: v.tag, seq: v.seq, sha256: v.sha256 });
|
|
28773
|
+
out(JSON.stringify({ name: spec.name, base: side(before2), target: after2 ? side(after2) : { file: displayPath3(target) }, summary: summarizeDiff(diff), diff }, null, 2));
|
|
28774
|
+
} else out(formatDiff(diff, label(before2, baseTag), toLabel));
|
|
28775
|
+
return 0;
|
|
28776
|
+
} catch (e) {
|
|
28777
|
+
err(`error: ${e.message}`);
|
|
28778
|
+
return 1;
|
|
28779
|
+
}
|
|
28780
|
+
}
|
|
28781
|
+
|
|
27850
28782
|
// src/cli.ts
|
|
27851
|
-
var VERSION2 = true ? "0.
|
|
28783
|
+
var VERSION2 = true ? "0.14.0" : "dev";
|
|
27852
28784
|
var USAGE = `Usage:
|
|
27853
28785
|
proschi check [--strict] [--format text|github|json] [--openapi <node>=<spec>]... <file|dir>...
|
|
27854
28786
|
proschi parse <file>
|
|
@@ -27862,6 +28794,8 @@ ${GAME_USAGE}
|
|
|
27862
28794
|
${SHARE_USAGE}
|
|
27863
28795
|
${IMPORT_USAGE}
|
|
27864
28796
|
${IMPORTS_USAGE}
|
|
28797
|
+
${LOGIN_USAGE}
|
|
28798
|
+
${VERSIONS_USAGE}
|
|
27865
28799
|
proschi --version
|
|
27866
28800
|
|
|
27867
28801
|
check Reports errors and warnings. Directories are searched for *.proschi files.
|
|
@@ -27881,19 +28815,21 @@ ${ACHIEVEMENTS_HELP}
|
|
|
27881
28815
|
${GAME_HELP}
|
|
27882
28816
|
${SHARE_HELP}
|
|
27883
28817
|
${IMPORT_HELP}
|
|
27884
|
-
${IMPORTS_HELP}
|
|
28818
|
+
${IMPORTS_HELP}
|
|
28819
|
+
${LOGIN_HELP}
|
|
28820
|
+
${VERSIONS_HELP}`;
|
|
27885
28821
|
function collectFiles(paths) {
|
|
27886
28822
|
const out = [];
|
|
27887
28823
|
const walk = (dir) => {
|
|
27888
|
-
for (const entry of (0,
|
|
28824
|
+
for (const entry of (0, import_node_fs15.readdirSync)(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
27889
28825
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
27890
|
-
const full = (0,
|
|
28826
|
+
const full = (0, import_node_path14.join)(dir, entry.name);
|
|
27891
28827
|
if (entry.isDirectory()) walk(full);
|
|
27892
28828
|
else if (entry.name.endsWith(".proschi")) out.push(full);
|
|
27893
28829
|
}
|
|
27894
28830
|
};
|
|
27895
28831
|
for (const p of paths) {
|
|
27896
|
-
if ((0,
|
|
28832
|
+
if ((0, import_node_fs15.statSync)(p).isDirectory()) walk(p);
|
|
27897
28833
|
else out.push(p);
|
|
27898
28834
|
}
|
|
27899
28835
|
return out;
|
|
@@ -27948,6 +28884,8 @@ function run(argv, out = console.log, err = console.error) {
|
|
|
27948
28884
|
if (command === "share-link") return runShareLink(rest, out, err);
|
|
27949
28885
|
if (command === "import") return runImport(rest, out, err);
|
|
27950
28886
|
if (command === "imports") return runImports(rest, collectFiles, out, err);
|
|
28887
|
+
if (command === "login" || command === "logout" || command === "whoami") return runAuth(command, rest, out, err);
|
|
28888
|
+
if (command === "versions") return runVersions(rest, out, err);
|
|
27951
28889
|
if (command === "check") {
|
|
27952
28890
|
let strict = false;
|
|
27953
28891
|
let style = "text";
|
|
@@ -27957,12 +28895,12 @@ function run(argv, out = console.log, err = console.error) {
|
|
|
27957
28895
|
const arg = rest[i];
|
|
27958
28896
|
if (arg === "--strict") strict = true;
|
|
27959
28897
|
else if (arg === "--format") {
|
|
27960
|
-
const
|
|
27961
|
-
if (
|
|
27962
|
-
err(`Unknown format '${
|
|
28898
|
+
const value2 = rest[++i];
|
|
28899
|
+
if (value2 !== "text" && value2 !== "github" && value2 !== "json") {
|
|
28900
|
+
err(`Unknown format '${value2 ?? ""}'; use text, github or json`);
|
|
27963
28901
|
return 2;
|
|
27964
28902
|
}
|
|
27965
|
-
style =
|
|
28903
|
+
style = value2;
|
|
27966
28904
|
} else if (arg === "--openapi") {
|
|
27967
28905
|
const spec = parseSpecFlag(rest[++i] ?? "");
|
|
27968
28906
|
if (!spec) {
|