@antasphere/slideless 0.13.14 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin.js +1037 -368
  2. package/package.json +2 -1
package/dist/bin.js CHANGED
@@ -4146,12 +4146,12 @@ var CliAuthClient = class {
4146
4146
  });
4147
4147
  if (res.status === 204)
4148
4148
  return void 0;
4149
- const json2 = await res.json().catch(() => null);
4149
+ const json3 = await res.json().catch(() => null);
4150
4150
  if (!res.ok) {
4151
- const errBody = json2 ?? {};
4151
+ const errBody = json3 ?? {};
4152
4152
  throw new CliAuthError(res.status, errBody.error?.code ?? "unknown_error", errBody.error?.message ?? `Request failed with ${res.status}`, errBody.error?.details);
4153
4153
  }
4154
- return json2;
4154
+ return json3;
4155
4155
  }
4156
4156
  };
4157
4157
 
@@ -4233,12 +4233,12 @@ var CliConnectClient = class {
4233
4233
  if (apiKey)
4234
4234
  headers["authorization"] = `Bearer ${apiKey}`;
4235
4235
  const res = await this.fetchImpl(url2, { method: "POST", headers, body: JSON.stringify(body) });
4236
- const json2 = await res.json().catch(() => null);
4236
+ const json3 = await res.json().catch(() => null);
4237
4237
  if (!res.ok) {
4238
- const errBody = json2 ?? {};
4238
+ const errBody = json3 ?? {};
4239
4239
  throw new CliConnectError(stage, res.status, errBody.error?.code ?? "unknown_error", errBody.error?.message ?? `Request failed with ${res.status}`, errBody.error?.details);
4240
4240
  }
4241
- return json2;
4241
+ return json3;
4242
4242
  }
4243
4243
  };
4244
4244
 
@@ -4477,12 +4477,12 @@ var ChassisClient = class {
4477
4477
  async parse(res) {
4478
4478
  if (res.status === 204)
4479
4479
  return void 0;
4480
- const json2 = await res.json().catch(() => null);
4480
+ const json3 = await res.json().catch(() => null);
4481
4481
  if (!res.ok) {
4482
- const errBody = json2 ?? {};
4482
+ const errBody = json3 ?? {};
4483
4483
  throw new PlatformApiError(res.status, errBody.error?.code ?? "unknown_error", errBody.error?.message ?? `Request failed with ${res.status}`, errBody.error?.details);
4484
4484
  }
4485
- return json2;
4485
+ return json3;
4486
4486
  }
4487
4487
  /** Append cursor-pagination params to a list path. */
4488
4488
  pathWithQuery(base, params, extra = {}) {
@@ -12218,7 +12218,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
12218
12218
  var NONE = 0;
12219
12219
  var ASSUMED = 1;
12220
12220
  var PROVEN = 2;
12221
- function isRecursive(inst, stack, resolve9) {
12221
+ function isRecursive(inst, stack, resolve10) {
12222
12222
  const cached2 = recursive.get(inst);
12223
12223
  if (cached2 !== void 0)
12224
12224
  return cached2 ? PROVEN : NONE;
@@ -12228,7 +12228,7 @@ function isRecursive(inst, stack, resolve9) {
12228
12228
  let result = NONE;
12229
12229
  const check3 = (child) => {
12230
12230
  if (result !== PROVEN && child?._zod) {
12231
- const answer = isRecursive(child, stack, resolve9);
12231
+ const answer = isRecursive(child, stack, resolve10);
12232
12232
  if (answer > result)
12233
12233
  result = answer;
12234
12234
  }
@@ -12239,7 +12239,7 @@ function isRecursive(inst, stack, resolve9) {
12239
12239
  const desc = Object.getOwnPropertyDescriptor(sh, key);
12240
12240
  if (spread && !desc.enumerable)
12241
12241
  continue;
12242
- const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve9) : NONE;
12242
+ const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve10) : NONE;
12243
12243
  if (child > answer)
12244
12244
  answer = child;
12245
12245
  }
@@ -12303,7 +12303,7 @@ function isRecursive(inst, stack, resolve9) {
12303
12303
  break;
12304
12304
  // `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
12305
12305
  case "lazy": {
12306
- const inner = def._cachedInner ?? (resolve9 ? inst._zod.innerType : void 0);
12306
+ const inner = def._cachedInner ?? (resolve10 ? inst._zod.innerType : void 0);
12307
12307
  merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
12308
12308
  break;
12309
12309
  }
@@ -22798,13 +22798,13 @@ function initializeContext(params) {
22798
22798
  external: params?.external ?? void 0
22799
22799
  };
22800
22800
  }
22801
- function handleUnrepresentable(schema, ctx, json2, params, message) {
22801
+ function handleUnrepresentable(schema, ctx, json3, params, message) {
22802
22802
  const result = typeof ctx.unrepresentable === "function" ? ctx.unrepresentable({ zodSchema: schema, path: params.path, message }) : ctx.unrepresentable;
22803
22803
  if (result === "any")
22804
22804
  return false;
22805
22805
  if (result === void 0 || result === "throw")
22806
22806
  throw new Error(message);
22807
- Object.assign(json2, result);
22807
+ Object.assign(json3, result);
22808
22808
  return true;
22809
22809
  }
22810
22810
  function processSchema(schema, ctx, _params = { path: [], schemaPath: [] }) {
@@ -23040,12 +23040,12 @@ function foldObjects(members2) {
23040
23040
  }
23041
23041
  return folded;
23042
23042
  }
23043
- function foldIntersection(json2) {
23044
- const allOf = json2.allOf;
23043
+ function foldIntersection(json3) {
23044
+ const allOf = json3.allOf;
23045
23045
  if (!Array.isArray(allOf) || allOf.length < 2)
23046
23046
  return;
23047
23047
  for (const key of FOLDABLE_KEYS)
23048
- if (key in json2)
23048
+ if (key in json3)
23049
23049
  return;
23050
23050
  const unions = allOf.filter((m) => UNION_KEYS.some((k) => Array.isArray(m[k])));
23051
23051
  let folded = null;
@@ -23064,8 +23064,8 @@ function foldIntersection(json2) {
23064
23064
  }
23065
23065
  if (!folded)
23066
23066
  return;
23067
- delete json2.allOf;
23068
- assignProps(json2, folded);
23067
+ delete json3.allOf;
23068
+ assignProps(json3, folded);
23069
23069
  }
23070
23070
  function finalize(ctx, schema) {
23071
23071
  const root = ctx.seen.get(schema);
@@ -23147,20 +23147,20 @@ function finalize(ctx, schema) {
23147
23147
  if (ctx.intersections.length) {
23148
23148
  const carriers = /* @__PURE__ */ new Map();
23149
23149
  for (const seen of ctx.seen.values()) {
23150
- for (const json2 of [seen.schema, seen.def]) {
23151
- const allOf = json2?.allOf;
23150
+ for (const json3 of [seen.schema, seen.def]) {
23151
+ const allOf = json3?.allOf;
23152
23152
  if (!Array.isArray(allOf))
23153
23153
  continue;
23154
23154
  const existing = carriers.get(allOf);
23155
23155
  if (existing)
23156
- existing.push(json2);
23156
+ existing.push(json3);
23157
23157
  else
23158
- carriers.set(allOf, [json2]);
23158
+ carriers.set(allOf, [json3]);
23159
23159
  }
23160
23160
  }
23161
23161
  for (const allOf of ctx.intersections) {
23162
- for (const json2 of carriers.get(allOf) ?? [])
23163
- foldIntersection(json2);
23162
+ for (const json3 of carriers.get(allOf) ?? [])
23163
+ foldIntersection(json3);
23164
23164
  }
23165
23165
  }
23166
23166
  }
@@ -23395,29 +23395,29 @@ var exactPatterns = /* @__PURE__ */ new Map([
23395
23395
  ]);
23396
23396
  var exactPattern = (p) => exactPatterns.get(p) ?? p;
23397
23397
  var stringProcessor = (schema, ctx, _json, _params) => {
23398
- const json2 = _json;
23399
- json2.type = "string";
23398
+ const json3 = _json;
23399
+ json3.type = "string";
23400
23400
  const { minimum, maximum, format: format2, patterns, contentEncoding, laxFormat } = aggregateChecks(schema);
23401
23401
  if (typeof minimum === "number")
23402
- json2.minLength = minimum;
23402
+ json3.minLength = minimum;
23403
23403
  if (typeof maximum === "number")
23404
- json2.maxLength = maximum;
23404
+ json3.maxLength = maximum;
23405
23405
  if (format2) {
23406
- json2.format = formatMap[format2] ?? format2;
23407
- if (json2.format === "")
23408
- delete json2.format;
23406
+ json3.format = formatMap[format2] ?? format2;
23407
+ if (json3.format === "")
23408
+ delete json3.format;
23409
23409
  if (format2 === "time" || laxFormat) {
23410
- delete json2.format;
23410
+ delete json3.format;
23411
23411
  }
23412
23412
  }
23413
23413
  if (contentEncoding)
23414
- json2.contentEncoding = contentEncoding;
23414
+ json3.contentEncoding = contentEncoding;
23415
23415
  if (patterns && patterns.size > 0) {
23416
23416
  const patternList = [...patterns].map(exactPattern);
23417
23417
  if (patternList.length === 1)
23418
- json2.pattern = patternList[0].source;
23418
+ json3.pattern = patternList[0].source;
23419
23419
  else if (patternList.length > 1) {
23420
- json2.allOf = [
23420
+ json3.allOf = [
23421
23421
  ...patternList.map((regex2) => ({
23422
23422
  ...ctx.target === "draft-07" || ctx.target === "draft-04" || ctx.target === "openapi-3.0" ? { type: "string" } : {},
23423
23423
  pattern: regex2.source
@@ -23427,31 +23427,31 @@ var stringProcessor = (schema, ctx, _json, _params) => {
23427
23427
  }
23428
23428
  };
23429
23429
  var numberProcessor = (schema, ctx, _json, params) => {
23430
- const json2 = _json;
23430
+ const json3 = _json;
23431
23431
  const { minimum, maximum, multipleOf, exclusiveMaximum, exclusiveMinimum, isInt } = aggregateChecks(schema);
23432
- json2.type = isInt ? "integer" : "number";
23432
+ json3.type = isInt ? "integer" : "number";
23433
23433
  const exMin = typeof exclusiveMinimum === "number" && exclusiveMinimum >= (minimum ?? Number.NEGATIVE_INFINITY);
23434
23434
  const exMax = typeof exclusiveMaximum === "number" && exclusiveMaximum <= (maximum ?? Number.POSITIVE_INFINITY);
23435
23435
  const legacy = ctx.target === "draft-04" || ctx.target === "openapi-3.0";
23436
23436
  if (exMin) {
23437
23437
  if (legacy) {
23438
- json2.minimum = exclusiveMinimum;
23439
- json2.exclusiveMinimum = true;
23438
+ json3.minimum = exclusiveMinimum;
23439
+ json3.exclusiveMinimum = true;
23440
23440
  } else {
23441
- json2.exclusiveMinimum = exclusiveMinimum;
23441
+ json3.exclusiveMinimum = exclusiveMinimum;
23442
23442
  }
23443
23443
  } else if (typeof minimum === "number") {
23444
- json2.minimum = minimum;
23444
+ json3.minimum = minimum;
23445
23445
  }
23446
23446
  if (exMax) {
23447
23447
  if (legacy) {
23448
- json2.maximum = exclusiveMaximum;
23449
- json2.exclusiveMaximum = true;
23448
+ json3.maximum = exclusiveMaximum;
23449
+ json3.exclusiveMaximum = true;
23450
23450
  } else {
23451
- json2.exclusiveMaximum = exclusiveMaximum;
23451
+ json3.exclusiveMaximum = exclusiveMaximum;
23452
23452
  }
23453
23453
  } else if (typeof maximum === "number") {
23454
- json2.maximum = maximum;
23454
+ json3.maximum = maximum;
23455
23455
  }
23456
23456
  if (multipleOf) {
23457
23457
  const divisors = /* @__PURE__ */ new Set();
@@ -23459,75 +23459,75 @@ var numberProcessor = (schema, ctx, _json, params) => {
23459
23459
  if (Number.isFinite(divisor) && divisor !== 0)
23460
23460
  divisors.add(Math.abs(divisor));
23461
23461
  else
23462
- handleUnrepresentable(schema, ctx, json2, params, `A multipleOf divisor of ${divisor} cannot be represented in JSON Schema`);
23462
+ handleUnrepresentable(schema, ctx, json3, params, `A multipleOf divisor of ${divisor} cannot be represented in JSON Schema`);
23463
23463
  }
23464
23464
  const [first, ...rest] = divisors;
23465
23465
  if (first !== void 0)
23466
- json2.multipleOf = first;
23466
+ json3.multipleOf = first;
23467
23467
  if (rest.length)
23468
- json2.allOf = [...json2.allOf ?? [], ...rest.map((m) => ({ multipleOf: m }))];
23468
+ json3.allOf = [...json3.allOf ?? [], ...rest.map((m) => ({ multipleOf: m }))];
23469
23469
  }
23470
23470
  };
23471
- var booleanProcessor = (_schema, _ctx, json2, _params) => {
23472
- json2.type = "boolean";
23471
+ var booleanProcessor = (_schema, _ctx, json3, _params) => {
23472
+ json3.type = "boolean";
23473
23473
  };
23474
- var bigintProcessor = (schema, ctx, json2, params) => {
23475
- handleUnrepresentable(schema, ctx, json2, params, "BigInt cannot be represented in JSON Schema");
23474
+ var bigintProcessor = (schema, ctx, json3, params) => {
23475
+ handleUnrepresentable(schema, ctx, json3, params, "BigInt cannot be represented in JSON Schema");
23476
23476
  };
23477
- var symbolProcessor = (schema, ctx, json2, params) => {
23478
- handleUnrepresentable(schema, ctx, json2, params, "Symbols cannot be represented in JSON Schema");
23477
+ var symbolProcessor = (schema, ctx, json3, params) => {
23478
+ handleUnrepresentable(schema, ctx, json3, params, "Symbols cannot be represented in JSON Schema");
23479
23479
  };
23480
- var nullProcessor = (_schema, ctx, json2, _params) => {
23480
+ var nullProcessor = (_schema, ctx, json3, _params) => {
23481
23481
  if (ctx.target === "openapi-3.0") {
23482
- json2.type = "string";
23483
- json2.nullable = true;
23484
- json2.enum = [null];
23482
+ json3.type = "string";
23483
+ json3.nullable = true;
23484
+ json3.enum = [null];
23485
23485
  } else {
23486
- json2.type = "null";
23486
+ json3.type = "null";
23487
23487
  }
23488
23488
  };
23489
- var undefinedProcessor = (schema, ctx, json2, params) => {
23490
- handleUnrepresentable(schema, ctx, json2, params, "Undefined cannot be represented in JSON Schema");
23489
+ var undefinedProcessor = (schema, ctx, json3, params) => {
23490
+ handleUnrepresentable(schema, ctx, json3, params, "Undefined cannot be represented in JSON Schema");
23491
23491
  };
23492
- var voidProcessor = (schema, ctx, json2, params) => {
23493
- handleUnrepresentable(schema, ctx, json2, params, "Void cannot be represented in JSON Schema");
23492
+ var voidProcessor = (schema, ctx, json3, params) => {
23493
+ handleUnrepresentable(schema, ctx, json3, params, "Void cannot be represented in JSON Schema");
23494
23494
  };
23495
- var neverProcessor = (_schema, _ctx, json2, _params) => {
23496
- json2.not = {};
23495
+ var neverProcessor = (_schema, _ctx, json3, _params) => {
23496
+ json3.not = {};
23497
23497
  };
23498
23498
  var anyProcessor = (_schema, _ctx, _json, _params) => {
23499
23499
  };
23500
23500
  var unknownProcessor = (_schema, _ctx, _json, _params) => {
23501
23501
  };
23502
- var dateProcessor = (schema, ctx, json2, params) => {
23503
- handleUnrepresentable(schema, ctx, json2, params, "Date cannot be represented in JSON Schema");
23502
+ var dateProcessor = (schema, ctx, json3, params) => {
23503
+ handleUnrepresentable(schema, ctx, json3, params, "Date cannot be represented in JSON Schema");
23504
23504
  };
23505
- var enumProcessor = (schema, _ctx, json2, _params) => {
23505
+ var enumProcessor = (schema, _ctx, json3, _params) => {
23506
23506
  const def = schema._zod.def;
23507
23507
  const values = getEnumValues(def.entries);
23508
23508
  if (values.length === 0) {
23509
- json2.not = {};
23509
+ json3.not = {};
23510
23510
  return;
23511
23511
  }
23512
23512
  if (values.every((v) => typeof v === "number"))
23513
- json2.type = "number";
23513
+ json3.type = "number";
23514
23514
  if (values.every((v) => typeof v === "string"))
23515
- json2.type = "string";
23516
- json2.enum = values;
23515
+ json3.type = "string";
23516
+ json3.enum = values;
23517
23517
  };
23518
- var literalProcessor = (schema, ctx, json2, params) => {
23518
+ var literalProcessor = (schema, ctx, json3, params) => {
23519
23519
  const def = schema._zod.def;
23520
23520
  if (def.values.length === 0) {
23521
- json2.not = {};
23521
+ json3.not = {};
23522
23522
  return;
23523
23523
  }
23524
23524
  const vals = [];
23525
23525
  for (const val of def.values) {
23526
23526
  if (val === void 0) {
23527
- if (handleUnrepresentable(schema, ctx, json2, params, "Literal `undefined` cannot be represented in JSON Schema"))
23527
+ if (handleUnrepresentable(schema, ctx, json3, params, "Literal `undefined` cannot be represented in JSON Schema"))
23528
23528
  return;
23529
23529
  } else if (typeof val === "bigint") {
23530
- if (handleUnrepresentable(schema, ctx, json2, params, "BigInt literals cannot be represented in JSON Schema"))
23530
+ if (handleUnrepresentable(schema, ctx, json3, params, "BigInt literals cannot be represented in JSON Schema"))
23531
23531
  return;
23532
23532
  vals.push(Number(val));
23533
23533
  } else {
@@ -23537,37 +23537,37 @@ var literalProcessor = (schema, ctx, json2, params) => {
23537
23537
  if (vals.length === 0) {
23538
23538
  } else if (vals.length === 1) {
23539
23539
  const val = vals[0];
23540
- json2.type = val === null ? "null" : typeof val;
23540
+ json3.type = val === null ? "null" : typeof val;
23541
23541
  if (ctx.target === "draft-04" || ctx.target === "openapi-3.0") {
23542
- json2.enum = [val];
23542
+ json3.enum = [val];
23543
23543
  } else {
23544
- json2.const = val;
23544
+ json3.const = val;
23545
23545
  }
23546
23546
  } else {
23547
23547
  if (vals.every((v) => typeof v === "number"))
23548
- json2.type = "number";
23548
+ json3.type = "number";
23549
23549
  if (vals.every((v) => typeof v === "string"))
23550
- json2.type = "string";
23550
+ json3.type = "string";
23551
23551
  if (vals.every((v) => typeof v === "boolean"))
23552
- json2.type = "boolean";
23552
+ json3.type = "boolean";
23553
23553
  if (vals.every((v) => v === null))
23554
- json2.type = "null";
23555
- json2.enum = vals;
23554
+ json3.type = "null";
23555
+ json3.enum = vals;
23556
23556
  }
23557
23557
  };
23558
- var nanProcessor = (schema, ctx, json2, params) => {
23559
- handleUnrepresentable(schema, ctx, json2, params, "NaN cannot be represented in JSON Schema");
23558
+ var nanProcessor = (schema, ctx, json3, params) => {
23559
+ handleUnrepresentable(schema, ctx, json3, params, "NaN cannot be represented in JSON Schema");
23560
23560
  };
23561
- var templateLiteralProcessor = (schema, _ctx, json2, _params) => {
23562
- const _json = json2;
23561
+ var templateLiteralProcessor = (schema, _ctx, json3, _params) => {
23562
+ const _json = json3;
23563
23563
  const pattern = schema._zod.pattern;
23564
23564
  if (!pattern)
23565
23565
  throw new Error("Pattern not found in template literal");
23566
23566
  _json.type = "string";
23567
23567
  _json.pattern = pattern.source;
23568
23568
  };
23569
- var fileProcessor = (schema, _ctx, json2, _params) => {
23570
- const _json = json2;
23569
+ var fileProcessor = (schema, _ctx, json3, _params) => {
23570
+ const _json = json3;
23571
23571
  _json.type = "string";
23572
23572
  _json.format = "binary";
23573
23573
  _json.contentEncoding = "binary";
@@ -23585,34 +23585,34 @@ var fileProcessor = (schema, _ctx, json2, _params) => {
23585
23585
  else
23586
23586
  _json.anyOf = mime.map((m) => ({ contentMediaType: m }));
23587
23587
  };
23588
- var successProcessor = (_schema, _ctx, json2, _params) => {
23589
- json2.type = "boolean";
23588
+ var successProcessor = (_schema, _ctx, json3, _params) => {
23589
+ json3.type = "boolean";
23590
23590
  };
23591
- var customProcessor = (schema, ctx, json2, params) => {
23592
- handleUnrepresentable(schema, ctx, json2, params, "Custom types cannot be represented in JSON Schema");
23591
+ var customProcessor = (schema, ctx, json3, params) => {
23592
+ handleUnrepresentable(schema, ctx, json3, params, "Custom types cannot be represented in JSON Schema");
23593
23593
  };
23594
- var functionProcessor = (schema, ctx, json2, params) => {
23595
- handleUnrepresentable(schema, ctx, json2, params, "Function types cannot be represented in JSON Schema");
23594
+ var functionProcessor = (schema, ctx, json3, params) => {
23595
+ handleUnrepresentable(schema, ctx, json3, params, "Function types cannot be represented in JSON Schema");
23596
23596
  };
23597
- var transformProcessor = (schema, ctx, json2, params) => {
23598
- handleUnrepresentable(schema, ctx, json2, params, "Transforms cannot be represented in JSON Schema");
23597
+ var transformProcessor = (schema, ctx, json3, params) => {
23598
+ handleUnrepresentable(schema, ctx, json3, params, "Transforms cannot be represented in JSON Schema");
23599
23599
  };
23600
- var mapProcessor = (schema, ctx, json2, params) => {
23601
- handleUnrepresentable(schema, ctx, json2, params, "Map cannot be represented in JSON Schema");
23600
+ var mapProcessor = (schema, ctx, json3, params) => {
23601
+ handleUnrepresentable(schema, ctx, json3, params, "Map cannot be represented in JSON Schema");
23602
23602
  };
23603
- var setProcessor = (schema, ctx, json2, params) => {
23604
- handleUnrepresentable(schema, ctx, json2, params, "Set cannot be represented in JSON Schema");
23603
+ var setProcessor = (schema, ctx, json3, params) => {
23604
+ handleUnrepresentable(schema, ctx, json3, params, "Set cannot be represented in JSON Schema");
23605
23605
  };
23606
23606
  var arrayProcessor = (schema, ctx, _json, params) => {
23607
- const json2 = _json;
23607
+ const json3 = _json;
23608
23608
  const def = schema._zod.def;
23609
23609
  const { minimum, maximum } = aggregateChecks(schema);
23610
23610
  if (typeof minimum === "number")
23611
- json2.minItems = minimum;
23611
+ json3.minItems = minimum;
23612
23612
  if (typeof maximum === "number")
23613
- json2.maxItems = maximum;
23614
- json2.type = "array";
23615
- json2.items = processSchema(def.element, ctx, {
23613
+ json3.maxItems = maximum;
23614
+ json3.type = "array";
23615
+ json3.items = processSchema(def.element, ctx, {
23616
23616
  ...params,
23617
23617
  path: [...params.path, "items"]
23618
23618
  });
@@ -23628,17 +23628,17 @@ function inputOptin(schema) {
23628
23628
  return schema._zod.optin;
23629
23629
  }
23630
23630
  var objectProcessor = (schema, ctx, _json, params) => {
23631
- const json2 = _json;
23631
+ const json3 = _json;
23632
23632
  const def = schema._zod.def;
23633
23633
  const shape = def.shape;
23634
23634
  const symbolKeys = Object.getOwnPropertySymbols(shape);
23635
- if (symbolKeys.length && handleUnrepresentable(schema, ctx, json2, params, "Symbol keys cannot be represented in JSON Schema")) {
23635
+ if (symbolKeys.length && handleUnrepresentable(schema, ctx, json3, params, "Symbol keys cannot be represented in JSON Schema")) {
23636
23636
  return;
23637
23637
  }
23638
- json2.type = "object";
23639
- json2.properties = {};
23638
+ json3.type = "object";
23639
+ json3.properties = {};
23640
23640
  for (const key in shape) {
23641
- assignProp(json2.properties, key, processSchema(shape[key], ctx, {
23641
+ assignProp(json3.properties, key, processSchema(shape[key], ctx, {
23642
23642
  ...params,
23643
23643
  path: [...params.path, "properties", key]
23644
23644
  }));
@@ -23651,21 +23651,21 @@ var objectProcessor = (schema, ctx, _json, params) => {
23651
23651
  }
23652
23652
  }
23653
23653
  if (requiredKeys.length > 0) {
23654
- json2.required = requiredKeys;
23654
+ json3.required = requiredKeys;
23655
23655
  }
23656
23656
  if (def.catchall?._zod.def.type === "never") {
23657
- json2.additionalProperties = false;
23657
+ json3.additionalProperties = false;
23658
23658
  } else if (!def.catchall) {
23659
23659
  if (ctx.io === "output")
23660
- json2.additionalProperties = false;
23660
+ json3.additionalProperties = false;
23661
23661
  } else if (def.catchall) {
23662
- json2.additionalProperties = processSchema(def.catchall, ctx, {
23662
+ json3.additionalProperties = processSchema(def.catchall, ctx, {
23663
23663
  ...params,
23664
23664
  path: [...params.path, "additionalProperties"]
23665
23665
  });
23666
23666
  }
23667
23667
  };
23668
- var unionProcessor = (schema, ctx, json2, params) => {
23668
+ var unionProcessor = (schema, ctx, json3, params) => {
23669
23669
  const def = schema._zod.def;
23670
23670
  const isExclusive = def.inclusive === false;
23671
23671
  const options = def.options.map((x, i) => processSchema(x, ctx, {
@@ -23673,12 +23673,12 @@ var unionProcessor = (schema, ctx, json2, params) => {
23673
23673
  path: [...params.path, isExclusive ? "oneOf" : "anyOf", i]
23674
23674
  }));
23675
23675
  if (isExclusive) {
23676
- json2.oneOf = options;
23676
+ json3.oneOf = options;
23677
23677
  } else {
23678
- json2.anyOf = options;
23678
+ json3.anyOf = options;
23679
23679
  }
23680
23680
  };
23681
- var intersectionProcessor = (schema, ctx, json2, params) => {
23681
+ var intersectionProcessor = (schema, ctx, json3, params) => {
23682
23682
  const def = schema._zod.def;
23683
23683
  const a = processSchema(def.left, ctx, {
23684
23684
  ...params,
@@ -23693,13 +23693,13 @@ var intersectionProcessor = (schema, ctx, json2, params) => {
23693
23693
  ...isSimpleIntersection(a) ? a.allOf : [a],
23694
23694
  ...isSimpleIntersection(b) ? b.allOf : [b]
23695
23695
  ];
23696
- json2.allOf = allOf;
23696
+ json3.allOf = allOf;
23697
23697
  ctx.intersections.push(allOf);
23698
23698
  };
23699
23699
  var tupleProcessor = (schema, ctx, _json, params) => {
23700
- const json2 = _json;
23700
+ const json3 = _json;
23701
23701
  const def = schema._zod.def;
23702
- json2.type = "array";
23702
+ json3.type = "array";
23703
23703
  const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
23704
23704
  const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
23705
23705
  const prefixItems = def.items.map((x, i) => processSchema(x, ctx, {
@@ -23721,70 +23721,70 @@ var tupleProcessor = (schema, ctx, _json, params) => {
23721
23721
  const maxItems = def.items.length;
23722
23722
  const isClosed = !def.rest;
23723
23723
  if (ctx.target === "draft-2020-12") {
23724
- json2.prefixItems = prefixItems;
23724
+ json3.prefixItems = prefixItems;
23725
23725
  if (isClosed) {
23726
- json2.items = false;
23726
+ json3.items = false;
23727
23727
  } else if (rest) {
23728
- json2.items = rest;
23728
+ json3.items = rest;
23729
23729
  }
23730
23730
  if (minItems > 0)
23731
- json2.minItems = minItems;
23731
+ json3.minItems = minItems;
23732
23732
  if (isClosed)
23733
- json2.maxItems = maxItems;
23733
+ json3.maxItems = maxItems;
23734
23734
  } else if (ctx.target === "openapi-3.0") {
23735
- json2.items = {
23735
+ json3.items = {
23736
23736
  anyOf: prefixItems
23737
23737
  };
23738
23738
  if (rest) {
23739
- json2.items.anyOf.push(rest);
23739
+ json3.items.anyOf.push(rest);
23740
23740
  }
23741
23741
  if (minItems > 0)
23742
- json2.minItems = minItems;
23742
+ json3.minItems = minItems;
23743
23743
  if (isClosed)
23744
- json2.maxItems = maxItems;
23744
+ json3.maxItems = maxItems;
23745
23745
  } else {
23746
- json2.items = prefixItems;
23746
+ json3.items = prefixItems;
23747
23747
  if (isClosed) {
23748
- json2.additionalItems = false;
23748
+ json3.additionalItems = false;
23749
23749
  } else if (rest) {
23750
- json2.additionalItems = rest;
23750
+ json3.additionalItems = rest;
23751
23751
  }
23752
23752
  if (minItems > 0)
23753
- json2.minItems = minItems;
23753
+ json3.minItems = minItems;
23754
23754
  if (isClosed)
23755
- json2.maxItems = maxItems;
23755
+ json3.maxItems = maxItems;
23756
23756
  }
23757
23757
  const { minimum, maximum } = aggregateChecks(schema);
23758
23758
  if (typeof minimum === "number")
23759
- json2.minItems = minimum;
23759
+ json3.minItems = minimum;
23760
23760
  if (typeof maximum === "number")
23761
- json2.maxItems = maximum;
23761
+ json3.maxItems = maximum;
23762
23762
  };
23763
- function stringifyKeyNames(bySchema, json2, visited) {
23764
- if (json2.$ref) {
23765
- if (visited.has(json2))
23766
- return json2;
23767
- visited.add(json2);
23768
- const def = bySchema.get(json2)?.def;
23763
+ function stringifyKeyNames(bySchema, json3, visited) {
23764
+ if (json3.$ref) {
23765
+ if (visited.has(json3))
23766
+ return json3;
23767
+ visited.add(json3);
23768
+ const def = bySchema.get(json3)?.def;
23769
23769
  if (!def)
23770
- return json2;
23770
+ return json3;
23771
23771
  const inlined = stringifyKeyNames(bySchema, def, visited);
23772
- return inlined === def ? json2 : inlined;
23772
+ return inlined === def ? json3 : inlined;
23773
23773
  }
23774
23774
  for (const keyword of ["anyOf", "oneOf"]) {
23775
- const branches = json2[keyword];
23775
+ const branches = json3[keyword];
23776
23776
  if (!Array.isArray(branches))
23777
23777
  continue;
23778
23778
  const mapped = branches.map((branch) => stringifyKeyNames(bySchema, branch, visited));
23779
23779
  if (mapped.some((branch, i) => branch !== branches[i]))
23780
- json2 = { ...json2, [keyword]: mapped };
23780
+ json3 = { ...json3, [keyword]: mapped };
23781
23781
  }
23782
- const types = Array.isArray(json2.type) ? json2.type : [json2.type];
23782
+ const types = Array.isArray(json3.type) ? json3.type : [json3.type];
23783
23783
  const numericType = !types.includes("string") && types.some((t) => t === "number" || t === "integer");
23784
- const values = json2.enum ?? (json2.const !== void 0 ? [json2.const] : void 0);
23784
+ const values = json3.enum ?? (json3.const !== void 0 ? [json3.const] : void 0);
23785
23785
  if (!numericType && !values?.some((v) => typeof v === "number"))
23786
- return json2;
23787
- const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format: format2, id: id2, ...rest } = json2;
23786
+ return json3;
23787
+ const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format: format2, id: id2, ...rest } = json3;
23788
23788
  if (rest.enum)
23789
23789
  rest.enum = rest.enum.map((v) => typeof v === "number" ? String(v) : v);
23790
23790
  else if (typeof rest.const === "number")
@@ -23824,9 +23824,9 @@ function rewriteKeyNames(ctx) {
23824
23824
  }
23825
23825
  }
23826
23826
  var recordProcessor = (schema, ctx, _json, params) => {
23827
- const json2 = _json;
23827
+ const json3 = _json;
23828
23828
  const def = schema._zod.def;
23829
- json2.type = "object";
23829
+ json3.type = "object";
23830
23830
  const keyType = def.keyType;
23831
23831
  const patterns = aggregateChecks(keyType).patterns;
23832
23832
  if (def.mode === "loose" && patterns && patterns.size > 0) {
@@ -23834,13 +23834,13 @@ var recordProcessor = (schema, ctx, _json, params) => {
23834
23834
  ...params,
23835
23835
  path: [...params.path, "patternProperties", "*"]
23836
23836
  });
23837
- json2.patternProperties = {};
23837
+ json3.patternProperties = {};
23838
23838
  for (const pattern of patterns) {
23839
- assignProp(json2.patternProperties, exactPattern(pattern).source, valueSchema);
23839
+ assignProp(json3.patternProperties, exactPattern(pattern).source, valueSchema);
23840
23840
  }
23841
23841
  } else {
23842
23842
  if (ctx.target === "draft-07" || ctx.target === "draft-2020-12") {
23843
- json2.propertyNames = processSchema(def.keyType, ctx, {
23843
+ json3.propertyNames = processSchema(def.keyType, ctx, {
23844
23844
  ...params,
23845
23845
  path: [...params.path, "propertyNames"]
23846
23846
  });
@@ -23852,7 +23852,7 @@ var recordProcessor = (schema, ctx, _json, params) => {
23852
23852
  }
23853
23853
  pending.push(schema);
23854
23854
  }
23855
- json2.additionalProperties = processSchema(def.valueType, ctx, {
23855
+ json3.additionalProperties = processSchema(def.valueType, ctx, {
23856
23856
  ...params,
23857
23857
  path: [...params.path, "additionalProperties"]
23858
23858
  });
@@ -23862,19 +23862,19 @@ var recordProcessor = (schema, ctx, _json, params) => {
23862
23862
  if (keyValues && !def.partial && !omittableOnInput) {
23863
23863
  const validKeyValues = [...keyValues].filter((v) => typeof v === "string" || typeof v === "number");
23864
23864
  if (validKeyValues.length > 0) {
23865
- json2.required = validKeyValues.map(String);
23865
+ json3.required = validKeyValues.map(String);
23866
23866
  }
23867
23867
  }
23868
23868
  };
23869
- var nullableProcessor = (schema, ctx, json2, params) => {
23869
+ var nullableProcessor = (schema, ctx, json3, params) => {
23870
23870
  const def = schema._zod.def;
23871
23871
  const inner = processSchema(def.innerType, ctx, params);
23872
23872
  const seen = ctx.seen.get(schema);
23873
23873
  if (ctx.target === "openapi-3.0") {
23874
23874
  seen.ref = def.innerType;
23875
- json2.nullable = true;
23875
+ json3.nullable = true;
23876
23876
  } else {
23877
- json2.anyOf = [inner, { type: "null" }];
23877
+ json3.anyOf = [inner, { type: "null" }];
23878
23878
  }
23879
23879
  };
23880
23880
  var nonoptionalProcessor = (schema, ctx, _json, params) => {
@@ -23884,7 +23884,7 @@ var nonoptionalProcessor = (schema, ctx, _json, params) => {
23884
23884
  seen.ref = def.innerType;
23885
23885
  };
23886
23886
  var UNREPRESENTABLE_DEFAULT = Symbol();
23887
- function serializeDefaultValue(value, schema, ctx, json2, params) {
23887
+ function serializeDefaultValue(value, schema, ctx, json3, params) {
23888
23888
  let unrepresentable = false;
23889
23889
  const serialized = JSON.stringify(value, (_, val) => {
23890
23890
  if (typeof val !== "bigint")
@@ -23894,30 +23894,30 @@ function serializeDefaultValue(value, schema, ctx, json2, params) {
23894
23894
  });
23895
23895
  if (!unrepresentable)
23896
23896
  return JSON.parse(serialized);
23897
- handleUnrepresentable(schema, ctx, json2, params, "BigInt defaults cannot be represented in JSON Schema");
23897
+ handleUnrepresentable(schema, ctx, json3, params, "BigInt defaults cannot be represented in JSON Schema");
23898
23898
  return UNREPRESENTABLE_DEFAULT;
23899
23899
  }
23900
- var defaultProcessor = (schema, ctx, json2, params) => {
23900
+ var defaultProcessor = (schema, ctx, json3, params) => {
23901
23901
  const def = schema._zod.def;
23902
23902
  processSchema(def.innerType, ctx, params);
23903
23903
  const seen = ctx.seen.get(schema);
23904
23904
  seen.ref = def.innerType;
23905
- const value = serializeDefaultValue(def.defaultValue, schema, ctx, json2, params);
23905
+ const value = serializeDefaultValue(def.defaultValue, schema, ctx, json3, params);
23906
23906
  if (value !== UNREPRESENTABLE_DEFAULT)
23907
- json2.default = value;
23907
+ json3.default = value;
23908
23908
  };
23909
- var prefaultProcessor = (schema, ctx, json2, params) => {
23909
+ var prefaultProcessor = (schema, ctx, json3, params) => {
23910
23910
  const def = schema._zod.def;
23911
23911
  processSchema(def.innerType, ctx, params);
23912
23912
  const seen = ctx.seen.get(schema);
23913
23913
  seen.ref = def.innerType;
23914
23914
  if (ctx.io !== "input")
23915
23915
  return;
23916
- const value = serializeDefaultValue(def.defaultValue, schema, ctx, json2, params);
23916
+ const value = serializeDefaultValue(def.defaultValue, schema, ctx, json3, params);
23917
23917
  if (value !== UNREPRESENTABLE_DEFAULT)
23918
- json2._prefault = value;
23918
+ json3._prefault = value;
23919
23919
  };
23920
- var catchProcessor = (schema, ctx, json2, params) => {
23920
+ var catchProcessor = (schema, ctx, json3, params) => {
23921
23921
  const def = schema._zod.def;
23922
23922
  processSchema(def.innerType, ctx, params);
23923
23923
  const seen = ctx.seen.get(schema);
@@ -23926,10 +23926,10 @@ var catchProcessor = (schema, ctx, json2, params) => {
23926
23926
  try {
23927
23927
  catchValue = def.catchValue(void 0);
23928
23928
  } catch {
23929
- handleUnrepresentable(schema, ctx, json2, params, "Dynamic catch values are not supported in JSON Schema");
23929
+ handleUnrepresentable(schema, ctx, json3, params, "Dynamic catch values are not supported in JSON Schema");
23930
23930
  return;
23931
23931
  }
23932
- json2.default = catchValue;
23932
+ json3.default = catchValue;
23933
23933
  };
23934
23934
  var pipeProcessor = (schema, ctx, _json, params) => {
23935
23935
  const def = schema._zod.def;
@@ -23939,12 +23939,12 @@ var pipeProcessor = (schema, ctx, _json, params) => {
23939
23939
  const seen = ctx.seen.get(schema);
23940
23940
  seen.ref = innerType;
23941
23941
  };
23942
- var readonlyProcessor = (schema, ctx, json2, params) => {
23942
+ var readonlyProcessor = (schema, ctx, json3, params) => {
23943
23943
  const def = schema._zod.def;
23944
23944
  processSchema(def.innerType, ctx, params);
23945
23945
  const seen = ctx.seen.get(schema);
23946
23946
  seen.ref = def.innerType;
23947
- json2.readOnly = true;
23947
+ json3.readOnly = true;
23948
23948
  };
23949
23949
  var promiseProcessor = (schema, ctx, _json, params) => {
23950
23950
  const def = schema._zod.def;
@@ -24586,7 +24586,7 @@ var _ZodString = /* @__PURE__ */ $constructor(
24586
24586
  (inst, def) => {
24587
24587
  $ZodString.init(inst, def);
24588
24588
  ZodType.init(inst, def);
24589
- inst._zod.processJSONSchema = (ctx, json2, params) => stringProcessor(inst, ctx, json2, params);
24589
+ inst._zod.processJSONSchema = (ctx, json3, params) => stringProcessor(inst, ctx, json3, params);
24590
24590
  },
24591
24591
  /* @__PURE__ */ util_exports.derived({
24592
24592
  format: (inst) => aggregateChecks(inst).format ?? null,
@@ -24945,7 +24945,7 @@ var ZodNumber = /* @__PURE__ */ $constructor(
24945
24945
  (inst, def) => {
24946
24946
  $ZodNumber.init(inst, def);
24947
24947
  ZodType.init(inst, def);
24948
- inst._zod.processJSONSchema = (ctx, json2, params) => numberProcessor(inst, ctx, json2, params);
24948
+ inst._zod.processJSONSchema = (ctx, json3, params) => numberProcessor(inst, ctx, json3, params);
24949
24949
  inst.isFinite = true;
24950
24950
  },
24951
24951
  /* @__PURE__ */ util_exports.derived({
@@ -25035,7 +25035,7 @@ function uint32(params) {
25035
25035
  var ZodBoolean = /* @__PURE__ */ $constructor("ZodBoolean", (inst, def) => {
25036
25036
  $ZodBoolean.init(inst, def);
25037
25037
  ZodType.init(inst, def);
25038
- inst._zod.processJSONSchema = (ctx, json2, params) => booleanProcessor(inst, ctx, json2, params);
25038
+ inst._zod.processJSONSchema = (ctx, json3, params) => booleanProcessor(inst, ctx, json3, params);
25039
25039
  });
25040
25040
  function boolean2(params) {
25041
25041
  return _boolean(ZodBoolean, params);
@@ -25045,7 +25045,7 @@ var ZodBigInt = /* @__PURE__ */ $constructor(
25045
25045
  (inst, def) => {
25046
25046
  $ZodBigInt.init(inst, def);
25047
25047
  ZodType.init(inst, def);
25048
- inst._zod.processJSONSchema = (ctx, json2, params) => bigintProcessor(inst, ctx, json2, params);
25048
+ inst._zod.processJSONSchema = (ctx, json3, params) => bigintProcessor(inst, ctx, json3, params);
25049
25049
  },
25050
25050
  /* @__PURE__ */ util_exports.derived({
25051
25051
  minValue: (inst) => aggregateChecks(inst).minimum ?? null,
@@ -25103,7 +25103,7 @@ function uint64(params) {
25103
25103
  var ZodSymbol = /* @__PURE__ */ $constructor("ZodSymbol", (inst, def) => {
25104
25104
  $ZodSymbol.init(inst, def);
25105
25105
  ZodType.init(inst, def);
25106
- inst._zod.processJSONSchema = (ctx, json2, params) => symbolProcessor(inst, ctx, json2, params);
25106
+ inst._zod.processJSONSchema = (ctx, json3, params) => symbolProcessor(inst, ctx, json3, params);
25107
25107
  });
25108
25108
  function symbol(params) {
25109
25109
  return _symbol(ZodSymbol, params);
@@ -25111,7 +25111,7 @@ function symbol(params) {
25111
25111
  var ZodUndefined = /* @__PURE__ */ $constructor("ZodUndefined", (inst, def) => {
25112
25112
  $ZodUndefined.init(inst, def);
25113
25113
  ZodType.init(inst, def);
25114
- inst._zod.processJSONSchema = (ctx, json2, params) => undefinedProcessor(inst, ctx, json2, params);
25114
+ inst._zod.processJSONSchema = (ctx, json3, params) => undefinedProcessor(inst, ctx, json3, params);
25115
25115
  });
25116
25116
  function _undefined3(params) {
25117
25117
  return _undefined2(ZodUndefined, params);
@@ -25119,7 +25119,7 @@ function _undefined3(params) {
25119
25119
  var ZodNull = /* @__PURE__ */ $constructor("ZodNull", (inst, def) => {
25120
25120
  $ZodNull.init(inst, def);
25121
25121
  ZodType.init(inst, def);
25122
- inst._zod.processJSONSchema = (ctx, json2, params) => nullProcessor(inst, ctx, json2, params);
25122
+ inst._zod.processJSONSchema = (ctx, json3, params) => nullProcessor(inst, ctx, json3, params);
25123
25123
  });
25124
25124
  function _null3(params) {
25125
25125
  return _null2(ZodNull, params);
@@ -25127,7 +25127,7 @@ function _null3(params) {
25127
25127
  var ZodAny = /* @__PURE__ */ $constructor("ZodAny", (inst, def) => {
25128
25128
  $ZodAny.init(inst, def);
25129
25129
  ZodType.init(inst, def);
25130
- inst._zod.processJSONSchema = (ctx, json2, params) => anyProcessor(inst, ctx, json2, params);
25130
+ inst._zod.processJSONSchema = (ctx, json3, params) => anyProcessor(inst, ctx, json3, params);
25131
25131
  });
25132
25132
  function any() {
25133
25133
  return _any(ZodAny);
@@ -25135,7 +25135,7 @@ function any() {
25135
25135
  var ZodUnknown = /* @__PURE__ */ $constructor("ZodUnknown", (inst, def) => {
25136
25136
  $ZodUnknown.init(inst, def);
25137
25137
  ZodType.init(inst, def);
25138
- inst._zod.processJSONSchema = (ctx, json2, params) => unknownProcessor(inst, ctx, json2, params);
25138
+ inst._zod.processJSONSchema = (ctx, json3, params) => unknownProcessor(inst, ctx, json3, params);
25139
25139
  });
25140
25140
  function unknown() {
25141
25141
  return _unknown(ZodUnknown);
@@ -25143,7 +25143,7 @@ function unknown() {
25143
25143
  var ZodNever = /* @__PURE__ */ $constructor("ZodNever", (inst, def) => {
25144
25144
  $ZodNever.init(inst, def);
25145
25145
  ZodType.init(inst, def);
25146
- inst._zod.processJSONSchema = (ctx, json2, params) => neverProcessor(inst, ctx, json2, params);
25146
+ inst._zod.processJSONSchema = (ctx, json3, params) => neverProcessor(inst, ctx, json3, params);
25147
25147
  });
25148
25148
  function never(params) {
25149
25149
  return _never(ZodNever, params);
@@ -25151,7 +25151,7 @@ function never(params) {
25151
25151
  var ZodVoid = /* @__PURE__ */ $constructor("ZodVoid", (inst, def) => {
25152
25152
  $ZodVoid.init(inst, def);
25153
25153
  ZodType.init(inst, def);
25154
- inst._zod.processJSONSchema = (ctx, json2, params) => voidProcessor(inst, ctx, json2, params);
25154
+ inst._zod.processJSONSchema = (ctx, json3, params) => voidProcessor(inst, ctx, json3, params);
25155
25155
  });
25156
25156
  function _void2(params) {
25157
25157
  return _void(ZodVoid, params);
@@ -25161,7 +25161,7 @@ var ZodDate = /* @__PURE__ */ $constructor(
25161
25161
  (inst, def) => {
25162
25162
  $ZodDate.init(inst, def);
25163
25163
  ZodType.init(inst, def);
25164
- inst._zod.processJSONSchema = (ctx, json2, params) => dateProcessor(inst, ctx, json2, params);
25164
+ inst._zod.processJSONSchema = (ctx, json3, params) => dateProcessor(inst, ctx, json3, params);
25165
25165
  inst.min = (value, params) => inst.check(_gte(value, params));
25166
25166
  inst.max = (value, params) => inst.check(_lte(value, params));
25167
25167
  },
@@ -25183,7 +25183,7 @@ var ZodArray = /* @__PURE__ */ $constructor("ZodArray", (inst, def) => {
25183
25183
  _ensureDefaultMemoizer();
25184
25184
  $ZodArray.init(inst, def);
25185
25185
  ZodType.init(inst, def);
25186
- inst._zod.processJSONSchema = (ctx, json2, params) => arrayProcessor(inst, ctx, json2, params);
25186
+ inst._zod.processJSONSchema = (ctx, json3, params) => arrayProcessor(inst, ctx, json3, params);
25187
25187
  inst.element = def.element;
25188
25188
  }, {
25189
25189
  min(n, params) {
@@ -25213,7 +25213,7 @@ var ZodObject = /* @__PURE__ */ $constructor("ZodObject", (inst, def) => {
25213
25213
  _ensureDefaultMemoizer();
25214
25214
  $ZodObjectJIT.init(inst, def);
25215
25215
  ZodType.init(inst, def);
25216
- inst._zod.processJSONSchema = (ctx, json2, params) => objectProcessor(inst, ctx, json2, params);
25216
+ inst._zod.processJSONSchema = (ctx, json3, params) => objectProcessor(inst, ctx, json3, params);
25217
25217
  util_exports.installLazyProp(inst, "shape", (self2) => self2._zod.def.shape, false);
25218
25218
  }, {
25219
25219
  keyof() {
@@ -25286,7 +25286,7 @@ function looseObject(shape, params) {
25286
25286
  var ZodUnion = /* @__PURE__ */ $constructor("ZodUnion", (inst, def) => {
25287
25287
  $ZodUnion.init(inst, def);
25288
25288
  ZodType.init(inst, def);
25289
- inst._zod.processJSONSchema = (ctx, json2, params) => unionProcessor(inst, ctx, json2, params);
25289
+ inst._zod.processJSONSchema = (ctx, json3, params) => unionProcessor(inst, ctx, json3, params);
25290
25290
  inst.options = def.options;
25291
25291
  });
25292
25292
  function union(options, params) {
@@ -25299,7 +25299,7 @@ function union(options, params) {
25299
25299
  var ZodXor = /* @__PURE__ */ $constructor("ZodXor", (inst, def) => {
25300
25300
  ZodUnion.init(inst, def);
25301
25301
  $ZodXor.init(inst, def);
25302
- inst._zod.processJSONSchema = (ctx, json2, params) => unionProcessor(inst, ctx, json2, params);
25302
+ inst._zod.processJSONSchema = (ctx, json3, params) => unionProcessor(inst, ctx, json3, params);
25303
25303
  inst.options = def.options;
25304
25304
  });
25305
25305
  function xor(options, params) {
@@ -25325,7 +25325,7 @@ function discriminatedUnion(discriminator, options, params) {
25325
25325
  var ZodIntersection = /* @__PURE__ */ $constructor("ZodIntersection", (inst, def) => {
25326
25326
  $ZodIntersection.init(inst, def);
25327
25327
  ZodType.init(inst, def);
25328
- inst._zod.processJSONSchema = (ctx, json2, params) => intersectionProcessor(inst, ctx, json2, params);
25328
+ inst._zod.processJSONSchema = (ctx, json3, params) => intersectionProcessor(inst, ctx, json3, params);
25329
25329
  });
25330
25330
  function intersection(left, right) {
25331
25331
  return new ZodIntersection({
@@ -25338,7 +25338,7 @@ var ZodTuple = /* @__PURE__ */ $constructor("ZodTuple", (inst, def) => {
25338
25338
  _ensureDefaultMemoizer();
25339
25339
  $ZodTuple.init(inst, def);
25340
25340
  ZodType.init(inst, def);
25341
- inst._zod.processJSONSchema = (ctx, json2, params) => tupleProcessor(inst, ctx, json2, params);
25341
+ inst._zod.processJSONSchema = (ctx, json3, params) => tupleProcessor(inst, ctx, json3, params);
25342
25342
  }, {
25343
25343
  rest(rest) {
25344
25344
  return this.clone({
@@ -25371,7 +25371,7 @@ var ZodRecord = /* @__PURE__ */ $constructor("ZodRecord", (inst, def) => {
25371
25371
  _ensureDefaultMemoizer();
25372
25372
  $ZodRecord.init(inst, def);
25373
25373
  ZodType.init(inst, def);
25374
- inst._zod.processJSONSchema = (ctx, json2, params) => recordProcessor(inst, ctx, json2, params);
25374
+ inst._zod.processJSONSchema = (ctx, json3, params) => recordProcessor(inst, ctx, json3, params);
25375
25375
  inst.keyType = def.keyType;
25376
25376
  inst.valueType = def.valueType;
25377
25377
  });
@@ -25413,7 +25413,7 @@ var ZodMap = /* @__PURE__ */ $constructor("ZodMap", (inst, def) => {
25413
25413
  _ensureDefaultMemoizer();
25414
25414
  $ZodMap.init(inst, def);
25415
25415
  ZodType.init(inst, def);
25416
- inst._zod.processJSONSchema = (ctx, json2, params) => mapProcessor(inst, ctx, json2, params);
25416
+ inst._zod.processJSONSchema = (ctx, json3, params) => mapProcessor(inst, ctx, json3, params);
25417
25417
  inst.keyType = def.keyType;
25418
25418
  inst.valueType = def.valueType;
25419
25419
  inst.min = (...args) => inst.check(_minSize(...args));
@@ -25433,7 +25433,7 @@ var ZodSet = /* @__PURE__ */ $constructor("ZodSet", (inst, def) => {
25433
25433
  _ensureDefaultMemoizer();
25434
25434
  $ZodSet.init(inst, def);
25435
25435
  ZodType.init(inst, def);
25436
- inst._zod.processJSONSchema = (ctx, json2, params) => setProcessor(inst, ctx, json2, params);
25436
+ inst._zod.processJSONSchema = (ctx, json3, params) => setProcessor(inst, ctx, json3, params);
25437
25437
  inst.min = (...args) => inst.check(_minSize(...args));
25438
25438
  inst.nonempty = (params) => inst.check(_minSize(1, params));
25439
25439
  inst.max = (...args) => inst.check(_maxSize(...args));
@@ -25449,7 +25449,7 @@ function set(valueType, params) {
25449
25449
  var ZodEnum = /* @__PURE__ */ $constructor("ZodEnum", (inst, def) => {
25450
25450
  $ZodEnum.init(inst, def);
25451
25451
  ZodType.init(inst, def);
25452
- inst._zod.processJSONSchema = (ctx, json2, params) => enumProcessor(inst, ctx, json2, params);
25452
+ inst._zod.processJSONSchema = (ctx, json3, params) => enumProcessor(inst, ctx, json3, params);
25453
25453
  inst.enum = def.entries;
25454
25454
  inst.options = [...inst._zod.values];
25455
25455
  const keys = new Set(Object.keys(def.entries));
@@ -25502,7 +25502,7 @@ function nativeEnum(entries, params) {
25502
25502
  var ZodLiteral = /* @__PURE__ */ $constructor("ZodLiteral", (inst, def) => {
25503
25503
  $ZodLiteral.init(inst, def);
25504
25504
  ZodType.init(inst, def);
25505
- inst._zod.processJSONSchema = (ctx, json2, params) => literalProcessor(inst, ctx, json2, params);
25505
+ inst._zod.processJSONSchema = (ctx, json3, params) => literalProcessor(inst, ctx, json3, params);
25506
25506
  inst.values = new Set(def.values);
25507
25507
  Object.defineProperty(inst, "value", {
25508
25508
  get() {
@@ -25523,7 +25523,7 @@ function literal(value, params) {
25523
25523
  var ZodFile = /* @__PURE__ */ $constructor("ZodFile", (inst, def) => {
25524
25524
  $ZodFile.init(inst, def);
25525
25525
  ZodType.init(inst, def);
25526
- inst._zod.processJSONSchema = (ctx, json2, params) => fileProcessor(inst, ctx, json2, params);
25526
+ inst._zod.processJSONSchema = (ctx, json3, params) => fileProcessor(inst, ctx, json3, params);
25527
25527
  inst.min = (size, params) => inst.check(_minSize(size, params));
25528
25528
  inst.max = (size, params) => inst.check(_maxSize(size, params));
25529
25529
  inst.mime = (types, params) => inst.check(_mime(Array.isArray(types) ? types : [types], params));
@@ -25535,7 +25535,7 @@ var ZodTransform = /* @__PURE__ */ $constructor("ZodTransform", (inst, def) => {
25535
25535
  _ensureDefaultMemoizer();
25536
25536
  $ZodTransform.init(inst, def);
25537
25537
  ZodType.init(inst, def);
25538
- inst._zod.processJSONSchema = (ctx, json2, params) => transformProcessor(inst, ctx, json2, params);
25538
+ inst._zod.processJSONSchema = (ctx, json3, params) => transformProcessor(inst, ctx, json3, params);
25539
25539
  inst._zod.parse = (payload, _ctx) => {
25540
25540
  if (_ctx.direction === "backward") {
25541
25541
  throw new $ZodEncodeError(inst.constructor.name);
@@ -25574,7 +25574,7 @@ function transform(fn) {
25574
25574
  var ZodOptional = /* @__PURE__ */ $constructor("ZodOptional", (inst, def) => {
25575
25575
  $ZodOptional.init(inst, def);
25576
25576
  ZodType.init(inst, def);
25577
- inst._zod.processJSONSchema = (ctx, json2, params) => optionalProcessor(inst, ctx, json2, params);
25577
+ inst._zod.processJSONSchema = (ctx, json3, params) => optionalProcessor(inst, ctx, json3, params);
25578
25578
  inst.unwrap = () => inst._zod.def.innerType;
25579
25579
  });
25580
25580
  function optional(innerType) {
@@ -25586,7 +25586,7 @@ function optional(innerType) {
25586
25586
  var ZodExactOptional = /* @__PURE__ */ $constructor("ZodExactOptional", (inst, def) => {
25587
25587
  $ZodExactOptional.init(inst, def);
25588
25588
  ZodType.init(inst, def);
25589
- inst._zod.processJSONSchema = (ctx, json2, params) => optionalProcessor(inst, ctx, json2, params);
25589
+ inst._zod.processJSONSchema = (ctx, json3, params) => optionalProcessor(inst, ctx, json3, params);
25590
25590
  inst.unwrap = () => inst._zod.def.innerType;
25591
25591
  });
25592
25592
  function exactOptional(innerType) {
@@ -25598,7 +25598,7 @@ function exactOptional(innerType) {
25598
25598
  var ZodNullable = /* @__PURE__ */ $constructor("ZodNullable", (inst, def) => {
25599
25599
  $ZodNullable.init(inst, def);
25600
25600
  ZodType.init(inst, def);
25601
- inst._zod.processJSONSchema = (ctx, json2, params) => nullableProcessor(inst, ctx, json2, params);
25601
+ inst._zod.processJSONSchema = (ctx, json3, params) => nullableProcessor(inst, ctx, json3, params);
25602
25602
  inst.unwrap = () => inst._zod.def.innerType;
25603
25603
  });
25604
25604
  function nullable(innerType) {
@@ -25613,7 +25613,7 @@ function nullish2(innerType) {
25613
25613
  var ZodDefault = /* @__PURE__ */ $constructor("ZodDefault", (inst, def) => {
25614
25614
  $ZodDefault.init(inst, def);
25615
25615
  ZodType.init(inst, def);
25616
- inst._zod.processJSONSchema = (ctx, json2, params) => defaultProcessor(inst, ctx, json2, params);
25616
+ inst._zod.processJSONSchema = (ctx, json3, params) => defaultProcessor(inst, ctx, json3, params);
25617
25617
  inst.unwrap = () => inst._zod.def.innerType;
25618
25618
  inst.removeDefault = inst.unwrap;
25619
25619
  });
@@ -25629,7 +25629,7 @@ function _default2(innerType, defaultValue) {
25629
25629
  var ZodPrefault = /* @__PURE__ */ $constructor("ZodPrefault", (inst, def) => {
25630
25630
  $ZodPrefault.init(inst, def);
25631
25631
  ZodType.init(inst, def);
25632
- inst._zod.processJSONSchema = (ctx, json2, params) => prefaultProcessor(inst, ctx, json2, params);
25632
+ inst._zod.processJSONSchema = (ctx, json3, params) => prefaultProcessor(inst, ctx, json3, params);
25633
25633
  inst.unwrap = () => inst._zod.def.innerType;
25634
25634
  });
25635
25635
  function prefault(innerType, defaultValue) {
@@ -25644,7 +25644,7 @@ function prefault(innerType, defaultValue) {
25644
25644
  var ZodNonOptional = /* @__PURE__ */ $constructor("ZodNonOptional", (inst, def) => {
25645
25645
  $ZodNonOptional.init(inst, def);
25646
25646
  ZodType.init(inst, def);
25647
- inst._zod.processJSONSchema = (ctx, json2, params) => nonoptionalProcessor(inst, ctx, json2, params);
25647
+ inst._zod.processJSONSchema = (ctx, json3, params) => nonoptionalProcessor(inst, ctx, json3, params);
25648
25648
  inst.unwrap = () => inst._zod.def.innerType;
25649
25649
  });
25650
25650
  function nonoptional(innerType, params) {
@@ -25657,7 +25657,7 @@ function nonoptional(innerType, params) {
25657
25657
  var ZodSuccess = /* @__PURE__ */ $constructor("ZodSuccess", (inst, def) => {
25658
25658
  $ZodSuccess.init(inst, def);
25659
25659
  ZodType.init(inst, def);
25660
- inst._zod.processJSONSchema = (ctx, json2, params) => successProcessor(inst, ctx, json2, params);
25660
+ inst._zod.processJSONSchema = (ctx, json3, params) => successProcessor(inst, ctx, json3, params);
25661
25661
  inst.unwrap = () => inst._zod.def.innerType;
25662
25662
  });
25663
25663
  function success(innerType) {
@@ -25669,7 +25669,7 @@ function success(innerType) {
25669
25669
  var ZodCatch = /* @__PURE__ */ $constructor("ZodCatch", (inst, def) => {
25670
25670
  $ZodCatch.init(inst, def);
25671
25671
  ZodType.init(inst, def);
25672
- inst._zod.processJSONSchema = (ctx, json2, params) => catchProcessor(inst, ctx, json2, params);
25672
+ inst._zod.processJSONSchema = (ctx, json3, params) => catchProcessor(inst, ctx, json3, params);
25673
25673
  inst.unwrap = () => inst._zod.def.innerType;
25674
25674
  inst.removeCatch = inst.unwrap;
25675
25675
  });
@@ -25683,7 +25683,7 @@ function _catch2(innerType, catchValue) {
25683
25683
  var ZodNaN = /* @__PURE__ */ $constructor("ZodNaN", (inst, def) => {
25684
25684
  $ZodNaN.init(inst, def);
25685
25685
  ZodType.init(inst, def);
25686
- inst._zod.processJSONSchema = (ctx, json2, params) => nanProcessor(inst, ctx, json2, params);
25686
+ inst._zod.processJSONSchema = (ctx, json3, params) => nanProcessor(inst, ctx, json3, params);
25687
25687
  });
25688
25688
  function nan(params) {
25689
25689
  return _nan(ZodNaN, params);
@@ -25691,7 +25691,7 @@ function nan(params) {
25691
25691
  var ZodPipe = /* @__PURE__ */ $constructor("ZodPipe", (inst, def) => {
25692
25692
  $ZodPipe.init(inst, def);
25693
25693
  ZodType.init(inst, def);
25694
- inst._zod.processJSONSchema = (ctx, json2, params) => pipeProcessor(inst, ctx, json2, params);
25694
+ inst._zod.processJSONSchema = (ctx, json3, params) => pipeProcessor(inst, ctx, json3, params);
25695
25695
  inst.in = def.in;
25696
25696
  inst.out = def.out;
25697
25697
  });
@@ -25733,7 +25733,7 @@ var ZodPreprocess = /* @__PURE__ */ $constructor("ZodPreprocess", (inst, def) =>
25733
25733
  var ZodReadonly = /* @__PURE__ */ $constructor("ZodReadonly", (inst, def) => {
25734
25734
  $ZodReadonly.init(inst, def);
25735
25735
  ZodType.init(inst, def);
25736
- inst._zod.processJSONSchema = (ctx, json2, params) => readonlyProcessor(inst, ctx, json2, params);
25736
+ inst._zod.processJSONSchema = (ctx, json3, params) => readonlyProcessor(inst, ctx, json3, params);
25737
25737
  inst.unwrap = () => inst._zod.def.innerType;
25738
25738
  });
25739
25739
  function readonly(innerType) {
@@ -25745,7 +25745,7 @@ function readonly(innerType) {
25745
25745
  var ZodTemplateLiteral = /* @__PURE__ */ $constructor("ZodTemplateLiteral", (inst, def) => {
25746
25746
  $ZodTemplateLiteral.init(inst, def);
25747
25747
  ZodType.init(inst, def);
25748
- inst._zod.processJSONSchema = (ctx, json2, params) => templateLiteralProcessor(inst, ctx, json2, params);
25748
+ inst._zod.processJSONSchema = (ctx, json3, params) => templateLiteralProcessor(inst, ctx, json3, params);
25749
25749
  });
25750
25750
  function templateLiteral(parts, params) {
25751
25751
  return new ZodTemplateLiteral({
@@ -25757,7 +25757,7 @@ function templateLiteral(parts, params) {
25757
25757
  var ZodLazy = /* @__PURE__ */ $constructor("ZodLazy", (inst, def) => {
25758
25758
  $ZodLazy.init(inst, def);
25759
25759
  ZodType.init(inst, def);
25760
- inst._zod.processJSONSchema = (ctx, json2, params) => lazyProcessor(inst, ctx, json2, params);
25760
+ inst._zod.processJSONSchema = (ctx, json3, params) => lazyProcessor(inst, ctx, json3, params);
25761
25761
  inst.unwrap = () => inst._zod.def.getter();
25762
25762
  });
25763
25763
  function lazy(getter) {
@@ -25769,7 +25769,7 @@ function lazy(getter) {
25769
25769
  var ZodPromise = /* @__PURE__ */ $constructor("ZodPromise", (inst, def) => {
25770
25770
  $ZodPromise.init(inst, def);
25771
25771
  ZodType.init(inst, def);
25772
- inst._zod.processJSONSchema = (ctx, json2, params) => promiseProcessor(inst, ctx, json2, params);
25772
+ inst._zod.processJSONSchema = (ctx, json3, params) => promiseProcessor(inst, ctx, json3, params);
25773
25773
  inst.unwrap = () => inst._zod.def.innerType;
25774
25774
  });
25775
25775
  function promise(innerType) {
@@ -25781,7 +25781,7 @@ function promise(innerType) {
25781
25781
  var ZodFunction = /* @__PURE__ */ $constructor("ZodFunction", (inst, def) => {
25782
25782
  $ZodFunction.init(inst, def);
25783
25783
  ZodType.init(inst, def);
25784
- inst._zod.processJSONSchema = (ctx, json2, params) => functionProcessor(inst, ctx, json2, params);
25784
+ inst._zod.processJSONSchema = (ctx, json3, params) => functionProcessor(inst, ctx, json3, params);
25785
25785
  });
25786
25786
  function _function(params) {
25787
25787
  return new ZodFunction({
@@ -25793,7 +25793,7 @@ function _function(params) {
25793
25793
  var ZodCustom = /* @__PURE__ */ $constructor("ZodCustom", (inst, def) => {
25794
25794
  $ZodCustom.init(inst, def);
25795
25795
  ZodType.init(inst, def);
25796
- inst._zod.processJSONSchema = (ctx, json2, params) => customProcessor(inst, ctx, json2, params);
25796
+ inst._zod.processJSONSchema = (ctx, json3, params) => customProcessor(inst, ctx, json3, params);
25797
25797
  });
25798
25798
  function check(fn) {
25799
25799
  const ch = new $ZodCheck({
@@ -33390,19 +33390,19 @@ async function readLink(rootDir) {
33390
33390
  return null;
33391
33391
  }
33392
33392
  }
33393
- async function writeLink(rootDir, link) {
33394
- await writeFile2(join3(rootDir, LINK_FILENAME), `${JSON.stringify(link, null, 2)}
33393
+ async function writeLink(rootDir, link2) {
33394
+ await writeFile2(join3(rootDir, LINK_FILENAME), `${JSON.stringify(link2, null, 2)}
33395
33395
  `);
33396
33396
  }
33397
33397
  async function linkedDeckId(ctx, rootDir, howElse) {
33398
- const link = await readLink(rootDir);
33399
- if (!link) return null;
33400
- if (link.baseUrl !== ctx.baseUrl) {
33398
+ const link2 = await readLink(rootDir);
33399
+ if (!link2) return null;
33400
+ if (link2.baseUrl !== ctx.baseUrl) {
33401
33401
  throw new CliUsageError(
33402
- `${LINK_FILENAME} links ${rootDir} to ${link.baseUrl}, but you are working against ${ctx.baseUrl}. ${howElse}`
33402
+ `${LINK_FILENAME} links ${rootDir} to ${link2.baseUrl}, but you are working against ${ctx.baseUrl}. ${howElse}`
33403
33403
  );
33404
33404
  }
33405
- return link.presentationId;
33405
+ return link2.presentationId;
33406
33406
  }
33407
33407
 
33408
33408
  // src/references.ts
@@ -33868,8 +33868,8 @@ async function pathExists(path) {
33868
33868
  }
33869
33869
 
33870
33870
  // src/commands/content.ts
33871
- import { readFile as readFile6, mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
33872
- import { dirname as dirname4, join as join5, resolve as resolve6 } from "node:path";
33871
+ import { readFile as readFile7, mkdir as mkdir5, writeFile as writeFile4 } from "node:fs/promises";
33872
+ import { dirname as dirname5, join as join6, resolve as resolve7 } from "node:path";
33873
33873
 
33874
33874
  // src/download.ts
33875
33875
  import { createHash as createHash2 } from "node:crypto";
@@ -33903,10 +33903,247 @@ function sha256Hex(bytes) {
33903
33903
  }
33904
33904
 
33905
33905
  // src/devserver.ts
33906
- import { watch } from "node:fs";
33907
- import { readFile as readFile5, realpath as realpath2, stat as stat3 } from "node:fs/promises";
33906
+ import { randomBytes as randomBytes2 } from "node:crypto";
33907
+ import { createReadStream as createReadStream3, watch } from "node:fs";
33908
+ import { mkdir as mkdir4, readFile as readFile6, realpath as realpath3, stat as stat4 } from "node:fs/promises";
33908
33909
  import { createServer } from "node:http";
33909
- import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve4 } from "node:path";
33910
+ import { isAbsolute as isAbsolute3, relative as relative3, resolve as resolve5 } from "node:path";
33911
+
33912
+ // src/localversions.ts
33913
+ import { createHash as createHash3, randomBytes } from "node:crypto";
33914
+ import { createReadStream as createReadStream2, createWriteStream as createWriteStream2 } from "node:fs";
33915
+ import { link, mkdir as mkdir3, readdir as readdir2, readFile as readFile5, realpath as realpath2, rename, rm, stat as stat3, writeFile as writeFile3 } from "node:fs/promises";
33916
+ import { homedir } from "node:os";
33917
+ import { basename as basename3, dirname as dirname4, isAbsolute as isAbsolute2, join as join5, relative as relative2, resolve as resolve4 } from "node:path";
33918
+ import { pipeline as pipeline3 } from "node:stream/promises";
33919
+ import { Transform } from "node:stream";
33920
+ var LOCAL_STORE_ENV = "SLIDELESS_LOCAL_STORE";
33921
+ var SHA256_RE = /^[0-9a-f]{64}$/;
33922
+ var RECORD_RE = /^([1-9][0-9]{0,8})\.json$/;
33923
+ var MAX_CLAIM_ATTEMPTS = 50;
33924
+ function defaultLocalStore(env = process.env) {
33925
+ const fromEnv = env[LOCAL_STORE_ENV]?.trim();
33926
+ if (fromEnv) return resolve4(fromEnv);
33927
+ if (process.platform === "win32") {
33928
+ const base2 = env.LOCALAPPDATA?.trim() || join5(homedir(), "AppData", "Local");
33929
+ return join5(base2, "antasphere", "slideless", "local");
33930
+ }
33931
+ const base = env.XDG_DATA_HOME?.trim() || join5(homedir(), ".local", "share");
33932
+ return join5(base, "antasphere", "slideless", "local");
33933
+ }
33934
+ async function openLocalStore(target, store, options = {}) {
33935
+ const realRoot = await realpath2(resolve4(target)).catch((err) => {
33936
+ if (err.code === "ENOENT") throw new Error(`No such file or directory: ${target}`);
33937
+ throw err;
33938
+ });
33939
+ const wanted = resolve4(store ?? defaultLocalStore());
33940
+ const realWanted = await realpathOfFuture(wanted);
33941
+ const rootInfo = await stat3(realRoot);
33942
+ const container = rootInfo.isFile() ? dirname4(realRoot) : realRoot;
33943
+ const rel = relative2(container, realWanted);
33944
+ const inside = rel === "" || !rel.startsWith("..") && !isAbsolute2(rel);
33945
+ const hidden = rel !== "" && rel.split(/[\\/]/).some((segment) => segment.startsWith("."));
33946
+ if (inside && !hidden) {
33947
+ throw new Error(
33948
+ `The version store ${realWanted} is inside the folder it would keep versions of; pass a --store outside it (or under a dot-prefixed directory, which is never scanned)`
33949
+ );
33950
+ }
33951
+ if (options.create === false) {
33952
+ const info = await stat3(realWanted).catch(() => null);
33953
+ return { root: realRoot, store: realWanted, exists: Boolean(info?.isDirectory()) };
33954
+ }
33955
+ await mkdir3(wanted, { recursive: true });
33956
+ return { root: realRoot, store: await realpath2(wanted), exists: true };
33957
+ }
33958
+ async function realpathOfFuture(path) {
33959
+ const missing = [];
33960
+ let at = path;
33961
+ for (; ; ) {
33962
+ const real = await realpath2(at).catch(() => null);
33963
+ if (real !== null) return missing.length ? join5(real, ...missing.reverse()) : real;
33964
+ const parent = dirname4(at);
33965
+ if (parent === at) return path;
33966
+ missing.push(basename3(at));
33967
+ at = parent;
33968
+ }
33969
+ }
33970
+ function localVersionsDir(store, realRoot) {
33971
+ return versionsDir(store, realRoot);
33972
+ }
33973
+ function folderKey(realRoot) {
33974
+ return createHash3("sha256").update(realRoot).digest("hex").slice(0, 24);
33975
+ }
33976
+ function folderDir(store, realRoot) {
33977
+ return join5(store, "folders", folderKey(realRoot));
33978
+ }
33979
+ function versionsDir(store, realRoot) {
33980
+ return join5(folderDir(store, realRoot), "versions");
33981
+ }
33982
+ function blobPath(store, sha256) {
33983
+ if (!SHA256_RE.test(sha256)) throw new Error(`Not a sha256: ${sha256}`);
33984
+ return join5(store, "blobs", sha256.slice(0, 2), sha256);
33985
+ }
33986
+ async function versionNumbers(store, realRoot) {
33987
+ const names = await readdir2(versionsDir(store, realRoot)).catch(() => []);
33988
+ const out = [];
33989
+ for (const name of names) {
33990
+ const m = RECORD_RE.exec(name);
33991
+ if (m) out.push(Number(m[1]));
33992
+ }
33993
+ return out.sort((a, b) => a - b);
33994
+ }
33995
+ function parseRecord(raw, expected) {
33996
+ let data;
33997
+ try {
33998
+ data = JSON.parse(raw);
33999
+ } catch {
34000
+ return null;
34001
+ }
34002
+ if (typeof data !== "object" || data === null) return null;
34003
+ const r = data;
34004
+ if (r.v !== 1 || r.version !== expected || typeof r.entryPath !== "string" || !Array.isArray(r.manifest)) {
34005
+ return null;
34006
+ }
34007
+ for (const f of r.manifest) {
34008
+ if (typeof f !== "object" || f === null || typeof f.path !== "string" || typeof f.sha256 !== "string" || !SHA256_RE.test(f.sha256) || typeof f.sizeBytes !== "number" || typeof f.contentType !== "string") {
34009
+ return null;
34010
+ }
34011
+ }
34012
+ return r;
34013
+ }
34014
+ async function readLocalVersion(store, realRoot, version2) {
34015
+ if (!Number.isSafeInteger(version2) || version2 < 1) return null;
34016
+ const raw = await readFile5(join5(versionsDir(store, realRoot), `${version2}.json`), "utf8").catch(() => null);
34017
+ return raw === null ? null : parseRecord(raw, version2);
34018
+ }
34019
+ async function listLocalVersions(store, realRoot) {
34020
+ const out = [];
34021
+ for (const n of await versionNumbers(store, realRoot)) {
34022
+ const record2 = await readLocalVersion(store, realRoot, n);
34023
+ if (!record2) continue;
34024
+ const { manifest: _manifest, v: _v, ...summary } = record2;
34025
+ out.push(summary);
34026
+ }
34027
+ return out;
34028
+ }
34029
+ async function latestRecord(store, realRoot) {
34030
+ const numbers = await versionNumbers(store, realRoot);
34031
+ for (let i = numbers.length - 1; i >= 0; i--) {
34032
+ const record2 = await readLocalVersion(store, realRoot, numbers[i]);
34033
+ if (record2) return record2;
34034
+ }
34035
+ return null;
34036
+ }
34037
+ function sameState(a, b) {
34038
+ if (a.entryPath !== b.entryPath || a.manifest.length !== b.manifest.length) return false;
34039
+ return a.manifest.every((f, i) => f.path === b.manifest[i].path && f.sha256 === b.manifest[i].sha256);
34040
+ }
34041
+ async function storeBlob(store, absPath) {
34042
+ const tmpDir = join5(store, "blobs", "tmp");
34043
+ await mkdir3(tmpDir, { recursive: true });
34044
+ const tmp = join5(tmpDir, `${randomBytes(8).toString("hex")}.part`);
34045
+ const hash2 = createHash3("sha256");
34046
+ let sizeBytes = 0;
34047
+ const tap = new Transform({
34048
+ transform(chunk, _enc, cb) {
34049
+ hash2.update(chunk);
34050
+ sizeBytes += chunk.length;
34051
+ cb(null, chunk);
34052
+ }
34053
+ });
34054
+ try {
34055
+ await pipeline3(createReadStream2(absPath), tap, createWriteStream2(tmp, { flags: "wx" }));
34056
+ const sha256 = hash2.digest("hex");
34057
+ const target = blobPath(store, sha256);
34058
+ const existing = await stat3(target).catch(() => null);
34059
+ if (existing?.isFile() && existing.size === sizeBytes) {
34060
+ await rm(tmp, { force: true });
34061
+ } else {
34062
+ await mkdir3(join5(store, "blobs", sha256.slice(0, 2)), { recursive: true });
34063
+ await rename(tmp, target);
34064
+ }
34065
+ return { sha256, sizeBytes };
34066
+ } catch (err) {
34067
+ await rm(tmp, { force: true });
34068
+ throw err;
34069
+ }
34070
+ }
34071
+ async function snapshot(target, options = {}) {
34072
+ const { root, store } = await openLocalStore(target, options.store);
34073
+ let scan;
34074
+ try {
34075
+ scan = await scanDeck(root);
34076
+ } catch (err) {
34077
+ const message = err.message;
34078
+ throw new Error(
34079
+ message.startsWith("Nothing to push") ? message.replace("Nothing to push", "Nothing to snapshot") : message
34080
+ );
34081
+ }
34082
+ const entryPath = detectEntry(scan, options.entry);
34083
+ const scanned = { entryPath, manifest: scan.files };
34084
+ const latest = await latestRecord(store, root);
34085
+ if (latest && sameState(latest, scanned)) return unchanged(latest, root, store);
34086
+ const manifest = [];
34087
+ for (const file2 of scan.files) {
34088
+ const kept = await storeBlob(store, file2.absPath);
34089
+ manifest.push({
34090
+ path: file2.path,
34091
+ sha256: kept.sha256,
34092
+ sizeBytes: kept.sizeBytes,
34093
+ contentType: file2.contentType
34094
+ });
34095
+ }
34096
+ const sizeBytes = manifest.reduce((sum, f) => sum + f.sizeBytes, 0);
34097
+ const dir = versionsDir(store, root);
34098
+ await mkdir3(dir, { recursive: true });
34099
+ await writeFile3(join5(folderDir(store, root), "folder.json"), `${JSON.stringify({ v: 1, root })}
34100
+ `).catch(
34101
+ () => {
34102
+ }
34103
+ );
34104
+ for (let attempt = 0; attempt < MAX_CLAIM_ATTEMPTS; attempt++) {
34105
+ const current = await latestRecord(store, root);
34106
+ if (current && sameState(current, { entryPath, manifest })) return unchanged(current, root, store);
34107
+ const numbers = await versionNumbers(store, root);
34108
+ const next = (numbers.at(-1) ?? 0) + 1;
34109
+ const record2 = {
34110
+ v: 1,
34111
+ version: next,
34112
+ root,
34113
+ entryPath,
34114
+ createdAt: (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString(),
34115
+ fileCount: manifest.length,
34116
+ sizeBytes,
34117
+ manifest
34118
+ };
34119
+ const tmp = join5(dir, `.${randomBytes(8).toString("hex")}.tmp`);
34120
+ await writeFile3(tmp, `${JSON.stringify(record2)}
34121
+ `, { flag: "wx" });
34122
+ try {
34123
+ await link(tmp, join5(dir, `${next}.json`));
34124
+ } catch (err) {
34125
+ if (err.code === "EEXIST") continue;
34126
+ throw err;
34127
+ } finally {
34128
+ await rm(tmp, { force: true });
34129
+ }
34130
+ return { version: next, created: true, entryPath, fileCount: manifest.length, sizeBytes, root, store };
34131
+ }
34132
+ throw new Error("Could not claim a version number: too many snapshots at once");
34133
+ }
34134
+ function unchanged(record2, root, store) {
34135
+ return {
34136
+ version: record2.version,
34137
+ created: false,
34138
+ entryPath: record2.entryPath,
34139
+ fileCount: record2.fileCount,
34140
+ sizeBytes: record2.sizeBytes,
34141
+ root,
34142
+ store
34143
+ };
34144
+ }
34145
+
34146
+ // src/devserver.ts
33910
34147
  var DEV_SANDBOX_CSP = "sandbox allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-modals allow-downloads";
33911
34148
  var CONTENT_HEADERS = {
33912
34149
  "content-security-policy": DEV_SANDBOX_CSP,
@@ -33914,33 +34151,29 @@ var CONTENT_HEADERS = {
33914
34151
  "referrer-policy": "no-referrer",
33915
34152
  "cache-control": "no-store"
33916
34153
  };
34154
+ var PLAIN_HEADERS = {
34155
+ "x-content-type-options": "nosniff",
34156
+ "referrer-policy": "no-referrer",
34157
+ "cache-control": "no-store"
34158
+ };
34159
+ var DEV_ROUTE_PREFIX = "/__slideless/";
33917
34160
  var RELOAD_PATH = "/__slideless/reload";
33918
- var RELOAD_SNIPPET = `<script>
33919
- (() => {
33920
- const connect = () => {
33921
- const es = new EventSource('${RELOAD_PATH}');
33922
- es.addEventListener('reload', () => location.reload());
33923
- es.onerror = () => { es.close(); setTimeout(connect, 1000); };
33924
- };
33925
- connect();
33926
- })();
33927
- </script>`;
33928
- function injectReload(html) {
33929
- const idx = html.lastIndexOf("</body>");
33930
- if (idx === -1) return html + RELOAD_SNIPPET;
33931
- return html.slice(0, idx) + RELOAD_SNIPPET + html.slice(idx);
33932
- }
34161
+ var VERSIONS_PATH = "/__slideless/versions";
34162
+ var SNAPSHOT_PATH = "/__slideless/snapshot";
34163
+ var VERSION_FILE_RE = /^\/__slideless\/v\/([1-9][0-9]{0,8})\/(.*)$/;
34164
+ var SNAPSHOT_HEADER = "x-slideless";
34165
+ var SNAPSHOT_HEADER_VALUE = "snapshot";
33933
34166
  async function resolveServable(root, relPath) {
33934
- if (relPath === "" || isAbsolute2(relPath)) return null;
34167
+ if (relPath === "" || isAbsolute3(relPath)) return null;
33935
34168
  if (relPath.includes("\\")) return null;
33936
34169
  if (relPath.split("/").some((seg) => seg.startsWith("."))) return null;
33937
- const target = resolve4(root, relPath);
33938
- const lexical = relative2(root, target);
33939
- if (lexical === "" || lexical.startsWith("..") || isAbsolute2(lexical)) return null;
33940
- const real = await realpath2(target).catch(() => null);
34170
+ const target = resolve5(root, relPath);
34171
+ const lexical = relative3(root, target);
34172
+ if (lexical === "" || lexical.startsWith("..") || isAbsolute3(lexical)) return null;
34173
+ const real = await realpath3(target).catch(() => null);
33941
34174
  if (real === null) return null;
33942
- const actual = relative2(root, real);
33943
- if (actual === "" || actual.startsWith("..") || isAbsolute2(actual)) return null;
34175
+ const actual = relative3(root, real);
34176
+ if (actual === "" || actual.startsWith("..") || isAbsolute3(actual)) return null;
33944
34177
  return real;
33945
34178
  }
33946
34179
  function hostAllowed(req, allowed) {
@@ -33963,11 +34196,288 @@ function allowedHosts(host, port) {
33963
34196
  }
33964
34197
  return out;
33965
34198
  }
34199
+ function urlPath(relPath) {
34200
+ return relPath.split("/").map(encodeURIComponent).join("/");
34201
+ }
34202
+ function json2(res, status, body) {
34203
+ res.writeHead(status, { ...PLAIN_HEADERS, "content-type": "application/json; charset=utf-8" }).end(`${JSON.stringify(body)}
34204
+ `);
34205
+ }
34206
+ function wrapperCsp(nonce) {
34207
+ return [
34208
+ "default-src 'none'",
34209
+ `script-src 'nonce-${nonce}'`,
34210
+ `style-src 'nonce-${nonce}'`,
34211
+ "connect-src 'self'",
34212
+ "frame-src 'self'",
34213
+ "img-src 'self' data:",
34214
+ "base-uri 'none'",
34215
+ "form-action 'none'"
34216
+ ].join("; ");
34217
+ }
34218
+ function scriptJson(value) {
34219
+ return JSON.stringify(value).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
34220
+ }
34221
+ function wrapperHtml(nonce, entryPath) {
34222
+ const entryUrl = scriptJson(`/${urlPath(entryPath)}`);
34223
+ const entry = scriptJson(entryPath);
34224
+ return `<!doctype html>
34225
+ <html lang="en">
34226
+ <head>
34227
+ <meta charset="utf-8">
34228
+ <meta name="viewport" content="width=device-width, initial-scale=1">
34229
+ <title>Slideless \xB7 local</title>
34230
+ <style nonce="${nonce}">
34231
+ :root { color-scheme: light dark; --ink: #1d1b16; --muted: #6f6a5f; --ground: #f4f1ea; --line: #ddd7ca; --accent: #2f5bd3; }
34232
+ @media (prefers-color-scheme: dark) { :root { --ink: #ece8df; --muted: #a39d90; --ground: #1c1b18; --line: #34322c; --accent: #8fb0ff; } }
34233
+ html, body { margin: 0; height: 100%; background: var(--ground); color: var(--ink); font: 13px/1.3 system-ui, -apple-system, "Segoe UI", sans-serif; }
34234
+ body { display: flex; flex-direction: column; }
34235
+ #bar { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-bottom: 1px solid var(--line); flex: none; }
34236
+ #bar[hidden] { display: none; }
34237
+ #name { font-weight: 600; white-space: nowrap; }
34238
+ #sel { font: inherit; color: inherit; background: transparent; border: 1px solid var(--line); border-radius: 6px; padding: 3px 6px; max-width: 46ch; }
34239
+ button { font: inherit; color: inherit; background: transparent; border: 1px solid var(--line); border-radius: 6px; padding: 3px 10px; cursor: pointer; }
34240
+ button:hover { border-color: var(--accent); }
34241
+ button[hidden] { display: none; }
34242
+ #status { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
34243
+ #spacer { flex: 1; }
34244
+ #deck { flex: 1; width: 100%; border: 0; background: #fff; }
34245
+ </style>
34246
+ </head>
34247
+ <body>
34248
+ <div id="bar" role="toolbar" aria-label="Versions">
34249
+ <span id="name">Slideless</span>
34250
+ <select id="sel" aria-label="What to show"></select>
34251
+ <button id="back" type="button" hidden>Back to live</button>
34252
+ <span id="spacer"></span>
34253
+ <span id="status" role="status" aria-live="polite"></span>
34254
+ <button id="snap" type="button">Save version</button>
34255
+ </div>
34256
+ <iframe id="deck" title="Deck" sandbox="${VIEWER_IFRAME_SANDBOX}" referrerpolicy="no-referrer"></iframe>
34257
+ <script nonce="${nonce}">
34258
+ (() => {
34259
+ const ENTRY_URL = ${entryUrl};
34260
+ const ENTRY = ${entry};
34261
+ const params = new URLSearchParams(location.search);
34262
+ const bar = document.getElementById('bar');
34263
+ const sel = document.getElementById('sel');
34264
+ const back = document.getElementById('back');
34265
+ const snap = document.getElementById('snap');
34266
+ const status = document.getElementById('status');
34267
+ const frame = document.getElementById('deck');
34268
+ if (params.get('bar') === '0') bar.hidden = true;
34269
+
34270
+ let versions = [];
34271
+ let mode = params.get('v') || 'live';
34272
+ if (mode !== 'live' && mode !== 'latest' && !/^[1-9][0-9]*$/.test(mode)) mode = 'live';
34273
+ let shown = null;
34274
+ // Until the first answer of the versions route, a ?v= mode cannot be
34275
+ // checked: it is kept as asked, never dropped to live.
34276
+ let loaded = false;
34277
+ let versionsOff = false;
34278
+
34279
+ const entryOf = (n) => {
34280
+ const v = versions.find((x) => x.version === n);
34281
+ return v ? v.entryPath : ENTRY;
34282
+ };
34283
+ const versionUrl = (n) =>
34284
+ '/__slideless/v/' + n + '/' + entryOf(n).split('/').map(encodeURIComponent).join('/');
34285
+ const target = () => {
34286
+ if (mode === 'live') return ENTRY_URL;
34287
+ const n = mode === 'latest' ? (versions.length ? versions[versions.length - 1].version : null) : Number(mode);
34288
+ return n ? versionUrl(n) : ENTRY_URL;
34289
+ };
34290
+ const show = (force) => {
34291
+ const url = target();
34292
+ if (force || url !== shown) {
34293
+ shown = url;
34294
+ frame.src = url;
34295
+ }
34296
+ };
34297
+ const when = (iso) => {
34298
+ const d = new Date(iso);
34299
+ return isNaN(d) ? '' : d.toLocaleString([], { day: 'numeric', month: 'short', hour: '2-digit', minute: '2-digit' });
34300
+ };
34301
+ const render = () => {
34302
+ sel.textContent = '';
34303
+ const add = (value, text) => {
34304
+ const o = document.createElement('option');
34305
+ o.value = value;
34306
+ o.text = text;
34307
+ sel.add(o);
34308
+ };
34309
+ add('live', 'Live: the working folder');
34310
+ // Latest stays a choice with no version yet: it shows the live folder
34311
+ // until the first one is saved, then moves to it. With versions off
34312
+ // there is no latest to wait for.
34313
+ if (!versionsOff) add('latest', versions.length ? 'Latest version (v' + versions[versions.length - 1].version + ')' : 'Latest version (none saved yet)');
34314
+ for (let i = versions.length - 1; i >= 0; i--) {
34315
+ const v = versions[i];
34316
+ add(String(v.version), 'v' + v.version + ' \xB7 ' + when(v.createdAt) + ' \xB7 ' + v.fileCount + (v.fileCount === 1 ? ' file' : ' files'));
34317
+ }
34318
+ if (loaded && ![...sel.options].some((o) => o.value === mode)) {
34319
+ mode = 'live';
34320
+ remember();
34321
+ }
34322
+ if (!loaded && mode !== 'live' && ![...sel.options].some((o) => o.value === mode)) {
34323
+ const o = document.createElement('option');
34324
+ o.value = mode;
34325
+ o.text = mode === 'latest' ? 'Latest version' : 'v' + mode;
34326
+ sel.add(o);
34327
+ }
34328
+ sel.value = mode;
34329
+ back.hidden = mode === 'live';
34330
+ };
34331
+ const remember = () => {
34332
+ const p = new URLSearchParams(location.search);
34333
+ if (mode === 'live') p.delete('v');
34334
+ else p.set('v', mode);
34335
+ const q = p.toString();
34336
+ history.replaceState(null, '', location.pathname + (q ? '?' + q : ''));
34337
+ };
34338
+ const load = async () => {
34339
+ try {
34340
+ const res = await fetch('/__slideless/versions', { cache: 'no-store' });
34341
+ const body = await res.json();
34342
+ versions = Array.isArray(body.versions) ? body.versions : [];
34343
+ versionsOff = Boolean(body.error);
34344
+ if (body.error) {
34345
+ snap.hidden = true;
34346
+ status.textContent = 'Versions unavailable';
34347
+ status.title = body.error;
34348
+ }
34349
+ } catch {
34350
+ versions = [];
34351
+ }
34352
+ loaded = true;
34353
+ render();
34354
+ show(false);
34355
+ };
34356
+ sel.addEventListener('change', () => {
34357
+ mode = sel.value;
34358
+ back.hidden = mode === 'live';
34359
+ remember();
34360
+ show(false);
34361
+ });
34362
+ back.addEventListener('click', () => {
34363
+ mode = 'live';
34364
+ sel.value = 'live';
34365
+ back.hidden = true;
34366
+ remember();
34367
+ show(false);
34368
+ });
34369
+ snap.addEventListener('click', async () => {
34370
+ snap.disabled = true;
34371
+ try {
34372
+ const res = await fetch('/__slideless/snapshot', { method: 'POST', headers: { 'x-slideless': 'snapshot' } });
34373
+ const body = await res.json();
34374
+ if (!res.ok) status.textContent = body.error || 'Could not save a version';
34375
+ else status.textContent = body.created ? 'Saved as v' + body.version : 'No change since v' + body.version;
34376
+ } catch {
34377
+ status.textContent = 'Could not save a version';
34378
+ } finally {
34379
+ snap.disabled = false;
34380
+ }
34381
+ });
34382
+ const connect = () => {
34383
+ const es = new EventSource('/__slideless/reload');
34384
+ es.addEventListener('reload', () => {
34385
+ if (mode === 'live' || (mode === 'latest' && versions.length === 0)) show(true);
34386
+ });
34387
+ es.addEventListener('versions', () => {
34388
+ void load();
34389
+ });
34390
+ es.onerror = () => {
34391
+ es.close();
34392
+ setTimeout(connect, 1000);
34393
+ };
34394
+ };
34395
+ render();
34396
+ if (mode === 'live') show(true);
34397
+ void load();
34398
+ connect();
34399
+ })();
34400
+ </script>
34401
+ </body>
34402
+ </html>
34403
+ `;
34404
+ }
33966
34405
  async function startDevServer(options) {
33967
- const root = await realpath2(resolve4(options.root));
34406
+ const root = await realpath3(resolve5(options.root));
33968
34407
  const host = options.host ?? "127.0.0.1";
33969
34408
  const sseClients = /* @__PURE__ */ new Set();
33970
34409
  let allowed = /* @__PURE__ */ new Set();
34410
+ let store = null;
34411
+ let storeError = null;
34412
+ let subject = root;
34413
+ try {
34414
+ const opened = await openLocalStore(options.target ?? root, options.store);
34415
+ store = opened.store;
34416
+ subject = opened.root;
34417
+ } catch (err) {
34418
+ storeError = err.message;
34419
+ }
34420
+ const broadcast = (event2) => {
34421
+ for (const client of sseClients) client.write(`event: ${event2}
34422
+ data: now
34423
+
34424
+ `);
34425
+ };
34426
+ let queue = Promise.resolve();
34427
+ const snapshotNow = () => {
34428
+ const run2 = queue.then(async () => {
34429
+ if (store === null) throw new Error(storeError ?? "Local versions are unavailable");
34430
+ const result = await snapshot(subject, { store, entry: options.entryPath });
34431
+ if (result.created) broadcast("versions");
34432
+ return result;
34433
+ });
34434
+ queue = run2.catch(() => void 0);
34435
+ return run2;
34436
+ };
34437
+ const sameOrigin = (req) => {
34438
+ const origin = req.headers.origin;
34439
+ if (origin === void 0) return true;
34440
+ try {
34441
+ const url2 = new URL(origin);
34442
+ return url2.protocol === "http:" && allowed.has(url2.host.toLowerCase());
34443
+ } catch {
34444
+ return false;
34445
+ }
34446
+ };
34447
+ const serveVersionFile = async (res, n, relPath, head) => {
34448
+ if (store === null) {
34449
+ res.writeHead(404, CONTENT_HEADERS).end("Not found");
34450
+ return;
34451
+ }
34452
+ const record2 = await readLocalVersion(store, subject, n);
34453
+ const wanted = relPath === "" ? record2?.entryPath : relPath;
34454
+ const file2 = record2?.manifest.find((f) => f.path === wanted);
34455
+ if (!record2 || !file2) {
34456
+ res.writeHead(404, CONTENT_HEADERS).end("Not found");
34457
+ return;
34458
+ }
34459
+ const blob = blobPath(store, file2.sha256);
34460
+ const info = await stat4(blob).catch(() => null);
34461
+ if (!info?.isFile()) {
34462
+ res.writeHead(404, CONTENT_HEADERS).end("Not found");
34463
+ return;
34464
+ }
34465
+ const type = file2.contentType === "text/html" ? "text/html; charset=utf-8" : file2.contentType;
34466
+ res.writeHead(200, { ...CONTENT_HEADERS, "content-type": type, "content-length": String(info.size) });
34467
+ if (head) {
34468
+ res.end();
34469
+ return;
34470
+ }
34471
+ await new Promise((done, fail) => {
34472
+ const stream = createReadStream3(blob);
34473
+ stream.on("error", fail);
34474
+ res.on("close", () => {
34475
+ stream.destroy();
34476
+ done();
34477
+ });
34478
+ stream.pipe(res).on("finish", () => done());
34479
+ });
34480
+ };
33971
34481
  const server = createServer((req, res) => {
33972
34482
  void (async () => {
33973
34483
  if (!hostAllowed(req, allowed)) {
@@ -33982,10 +34492,50 @@ async function startDevServer(options) {
33982
34492
  res.writeHead(400, CONTENT_HEADERS).end("Bad request");
33983
34493
  return;
33984
34494
  }
34495
+ const method = req.method ?? "GET";
34496
+ if (pathname === SNAPSHOT_PATH) {
34497
+ if (method !== "POST") {
34498
+ res.writeHead(405, { ...PLAIN_HEADERS, allow: "POST" }).end("Method not allowed");
34499
+ return;
34500
+ }
34501
+ if (req.headers[SNAPSHOT_HEADER] !== SNAPSHOT_HEADER_VALUE || !sameOrigin(req)) {
34502
+ json2(res, 403, { error: "forbidden" });
34503
+ return;
34504
+ }
34505
+ try {
34506
+ const result = await snapshotNow();
34507
+ json2(res, result.created ? 201 : 200, {
34508
+ version: result.version,
34509
+ created: result.created,
34510
+ entryPath: result.entryPath,
34511
+ fileCount: result.fileCount,
34512
+ sizeBytes: result.sizeBytes
34513
+ });
34514
+ } catch (err) {
34515
+ json2(res, 409, { error: err.message });
34516
+ }
34517
+ return;
34518
+ }
34519
+ if (method !== "GET" && method !== "HEAD") {
34520
+ res.writeHead(405, { ...CONTENT_HEADERS, allow: "GET, HEAD" }).end("Method not allowed");
34521
+ return;
34522
+ }
34523
+ const head = method === "HEAD";
34524
+ if (pathname === "/") {
34525
+ const nonce = randomBytes2(16).toString("base64");
34526
+ res.writeHead(200, {
34527
+ ...PLAIN_HEADERS,
34528
+ "content-security-policy": wrapperCsp(nonce),
34529
+ "content-type": "text/html; charset=utf-8"
34530
+ });
34531
+ res.end(head ? void 0 : wrapperHtml(nonce, options.entryPath));
34532
+ return;
34533
+ }
33985
34534
  if (pathname === RELOAD_PATH) {
33986
34535
  res.writeHead(200, {
33987
34536
  "content-type": "text/event-stream",
33988
34537
  "cache-control": "no-store",
34538
+ "x-content-type-options": "nosniff",
33989
34539
  connection: "keep-alive"
33990
34540
  });
33991
34541
  res.write(": connected\n\n");
@@ -33993,25 +34543,43 @@ async function startDevServer(options) {
33993
34543
  req.on("close", () => sseClients.delete(res));
33994
34544
  return;
33995
34545
  }
33996
- const relPath = pathname === "/" ? options.entryPath : pathname.replace(/^\/+/, "");
34546
+ if (pathname === VERSIONS_PATH) {
34547
+ const versions = store === null ? [] : await listLocalVersions(store, subject);
34548
+ json2(res, 200, {
34549
+ cli: options.cliVersion ?? null,
34550
+ entry: options.entryPath,
34551
+ versions: versions.map(({ root: _root, ...v }) => v),
34552
+ ...storeError ? { error: storeError } : {}
34553
+ });
34554
+ return;
34555
+ }
34556
+ const versionFile = VERSION_FILE_RE.exec(pathname);
34557
+ if (versionFile) {
34558
+ await serveVersionFile(res, Number(versionFile[1]), versionFile[2], head);
34559
+ return;
34560
+ }
34561
+ if (pathname.startsWith(DEV_ROUTE_PREFIX)) {
34562
+ res.writeHead(404, CONTENT_HEADERS).end("Not found");
34563
+ return;
34564
+ }
34565
+ const relPath = pathname.replace(/^\/+/, "");
33997
34566
  const target = await resolveServable(root, relPath);
33998
34567
  if (target === null) {
33999
34568
  res.writeHead(404, CONTENT_HEADERS).end("Not found");
34000
34569
  return;
34001
34570
  }
34002
- const info = await stat3(target).catch(() => null);
34571
+ const info = await stat4(target).catch(() => null);
34003
34572
  if (!info || !info.isFile()) {
34004
34573
  res.writeHead(404, CONTENT_HEADERS).end("Not found");
34005
34574
  return;
34006
34575
  }
34007
34576
  const contentType = contentTypeFor(target);
34008
- if (contentType === "text/html") {
34009
- const html = injectReload(await readFile5(target, "utf8"));
34010
- res.writeHead(200, { ...CONTENT_HEADERS, "content-type": "text/html; charset=utf-8" }).end(html);
34011
- return;
34012
- }
34013
- const bytes = await readFile5(target);
34014
- res.writeHead(200, { ...CONTENT_HEADERS, "content-type": contentType }).end(bytes);
34577
+ const bytes = await readFile6(target);
34578
+ res.writeHead(200, {
34579
+ ...CONTENT_HEADERS,
34580
+ "content-type": contentType === "text/html" ? "text/html; charset=utf-8" : contentType
34581
+ });
34582
+ res.end(head ? void 0 : bytes);
34015
34583
  })().catch(() => {
34016
34584
  if (!res.headersSent) res.writeHead(500, CONTENT_HEADERS);
34017
34585
  res.end("Internal error");
@@ -34019,21 +34587,45 @@ async function startDevServer(options) {
34019
34587
  });
34020
34588
  let watcher = null;
34021
34589
  let debounce = null;
34022
- const broadcast = () => {
34590
+ const onChange = (_event, filename) => {
34591
+ const name = filename === null ? "" : filename.toString();
34592
+ if (name && name.split(/[\\/]/).some((seg) => seg.startsWith("."))) return;
34023
34593
  if (debounce) clearTimeout(debounce);
34024
- debounce = setTimeout(() => {
34025
- for (const client of sseClients) client.write("event: reload\ndata: now\n\n");
34026
- }, 100);
34594
+ debounce = setTimeout(() => broadcast("reload"), 100);
34027
34595
  };
34028
34596
  try {
34029
- watcher = watch(root, { recursive: true }, broadcast);
34597
+ watcher = watch(root, { recursive: true }, onChange);
34030
34598
  } catch {
34031
34599
  try {
34032
- watcher = watch(root, broadcast);
34600
+ watcher = watch(root, onChange);
34033
34601
  } catch {
34034
34602
  watcher = null;
34035
34603
  }
34036
34604
  }
34605
+ watcher?.on("error", () => {
34606
+ watcher?.close();
34607
+ watcher = null;
34608
+ });
34609
+ let storeWatcher = null;
34610
+ let storeDebounce = null;
34611
+ if (store !== null) {
34612
+ const dir = localVersionsDir(store, subject);
34613
+ try {
34614
+ await mkdir4(dir, { recursive: true });
34615
+ storeWatcher = watch(dir, (_event, filename) => {
34616
+ const name = filename === null ? "" : filename.toString();
34617
+ if (name && !/^[1-9][0-9]*\.json$/.test(name)) return;
34618
+ if (storeDebounce) clearTimeout(storeDebounce);
34619
+ storeDebounce = setTimeout(() => broadcast("versions"), 100);
34620
+ });
34621
+ storeWatcher.on("error", () => {
34622
+ storeWatcher?.close();
34623
+ storeWatcher = null;
34624
+ });
34625
+ } catch {
34626
+ storeWatcher = null;
34627
+ }
34628
+ }
34037
34629
  await new Promise((resolvePromise, reject) => {
34038
34630
  server.once("error", reject);
34039
34631
  server.listen(options.port, host, () => {
@@ -34047,9 +34639,14 @@ async function startDevServer(options) {
34047
34639
  return {
34048
34640
  url: `http://${host}:${port}/`,
34049
34641
  port,
34642
+ store,
34643
+ storeError,
34644
+ snapshot: snapshotNow,
34050
34645
  close: async () => {
34051
34646
  watcher?.close();
34647
+ storeWatcher?.close();
34052
34648
  if (debounce) clearTimeout(debounce);
34649
+ if (storeDebounce) clearTimeout(storeDebounce);
34053
34650
  for (const client of sseClients) client.end();
34054
34651
  sseClients.clear();
34055
34652
  await new Promise((resolvePromise) => server.close(() => resolvePromise()));
@@ -34065,8 +34662,8 @@ function shouldOpenAfterPush(input2) {
34065
34662
  }
34066
34663
 
34067
34664
  // src/commands/projects.ts
34068
- import { stat as stat4 } from "node:fs/promises";
34069
- import { resolve as resolve5 } from "node:path";
34665
+ import { stat as stat5 } from "node:fs/promises";
34666
+ import { resolve as resolve6 } from "node:path";
34070
34667
  function projectsGroup(program2) {
34071
34668
  const group = program2.commands.find((c) => c.name() === "projects");
34072
34669
  if (!group) {
@@ -34076,7 +34673,7 @@ function projectsGroup(program2) {
34076
34673
  }
34077
34674
  async function isFolder(path) {
34078
34675
  try {
34079
- return (await stat4(path)).isDirectory();
34676
+ return (await stat5(path)).isDirectory();
34080
34677
  } catch {
34081
34678
  return false;
34082
34679
  }
@@ -34084,12 +34681,12 @@ async function isFolder(path) {
34084
34681
  async function resolveDeck(ctx, deck) {
34085
34682
  if (deck !== void 0) {
34086
34683
  if (isDeckId(deck)) return deck;
34087
- if (!await isFolder(resolve5(deck))) {
34684
+ if (!await isFolder(resolve6(deck))) {
34088
34685
  throw new CliUsageError(
34089
34686
  `${deck} is neither a deck id nor a folder. Name the deck by id, or by a folder a push linked.`
34090
34687
  );
34091
34688
  }
34092
- const linked2 = await linkedDeckId(ctx, resolve5(deck), "Name the deck by id instead.");
34689
+ const linked2 = await linkedDeckId(ctx, resolve6(deck), "Name the deck by id instead.");
34093
34690
  if (!linked2) {
34094
34691
  throw new CliUsageError(
34095
34692
  `No ${LINK_FILENAME} in ${deck} \u2014 push that folder first, or name the deck by id.`
@@ -34097,7 +34694,7 @@ async function resolveDeck(ctx, deck) {
34097
34694
  }
34098
34695
  return linked2;
34099
34696
  }
34100
- const linked = await linkedDeckId(ctx, resolve5("."), "Name the deck by id instead.");
34697
+ const linked = await linkedDeckId(ctx, resolve6("."), "Name the deck by id instead.");
34101
34698
  if (!linked) {
34102
34699
  throw new CliUsageError(
34103
34700
  `No deck given and no ${LINK_FILENAME} in the current folder \u2014 name the deck by id, or run this from a folder a push linked.`
@@ -34213,7 +34810,7 @@ function registerProjectDeckCommands(program2, io) {
34213
34810
  io.out.write(brandLines(current.brand));
34214
34811
  return;
34215
34812
  }
34216
- const linked = await isFolder(resolve5(ref)) ? await linkedDeckId(ctx, resolve5(ref), "Name the brand by id or title instead.") : null;
34813
+ const linked = await isFolder(resolve6(ref)) ? await linkedDeckId(ctx, resolve6(ref), "Name the brand by id or title instead.") : null;
34217
34814
  const deckId = linked ?? resolveReference(await listReferences(ctx, "brand"), ref, "brand").id;
34218
34815
  const set2 = await explainedDeckProject("brand", () => ctx.client.setProjectBrand(project, deckId));
34219
34816
  if (ctx.json) return printJson2(io, set2);
@@ -34268,7 +34865,7 @@ async function detectFormNames(scan) {
34268
34865
  const names = /* @__PURE__ */ new Set();
34269
34866
  for (const file2 of scan.files) {
34270
34867
  if (file2.contentType !== "text/html" && file2.contentType !== "text/javascript") continue;
34271
- const html = await readFile6(file2.absPath, "utf8");
34868
+ const html = await readFile7(file2.absPath, "utf8");
34272
34869
  for (const match of html.matchAll(FORM_NAME_RE)) names.add(match[1]);
34273
34870
  }
34274
34871
  return [...names];
@@ -34299,7 +34896,7 @@ async function uploadMissing(ctx, scan) {
34299
34896
  const workers = Array.from({ length: Math.min(UPLOAD_CONCURRENCY, queue.length) }, async () => {
34300
34897
  while (index < queue.length) {
34301
34898
  const file2 = queue[index++];
34302
- const bytes = await readFile6(file2.absPath);
34899
+ const bytes = await readFile7(file2.absPath);
34303
34900
  await ctx.client.uploadAsset(file2.sha256, new Uint8Array(bytes), file2.contentType);
34304
34901
  }
34305
34902
  });
@@ -34323,21 +34920,21 @@ function registerContentCommands(program2, io) {
34323
34920
  printPushResult(ctx, result, opts);
34324
34921
  });
34325
34922
  program2.command("open [path]").description(`Open the linked deck's page in the browser (reads ${LINK_FILENAME}; --json prints the URL)`).action(async (path, _opts, cmd) => {
34326
- const { json: json2 } = resolveContextForDev(cmd, io);
34327
- const rootDir = resolve6(path ?? ".");
34328
- const link = await readLink(rootDir);
34329
- if (!link) {
34923
+ const { json: json3 } = resolveContextForDev(cmd, io);
34924
+ const rootDir = resolve7(path ?? ".");
34925
+ const link2 = await readLink(rootDir);
34926
+ if (!link2) {
34330
34927
  throw new CliUsageError(
34331
34928
  `No ${LINK_FILENAME} in ${rootDir} \u2014 push the folder once (\`slideless push\`) to link it to a deck.`
34332
34929
  );
34333
34930
  }
34334
- if (!isHttpUrl(link.baseUrl)) {
34931
+ if (!isHttpUrl(link2.baseUrl)) {
34335
34932
  throw new CliUsageError(
34336
- `${LINK_FILENAME} names ${JSON.stringify(link.baseUrl)} as the instance, which is not an http(s) URL \u2014 refusing to open it. Fix the file or push the folder again.`
34933
+ `${LINK_FILENAME} names ${JSON.stringify(link2.baseUrl)} as the instance, which is not an http(s) URL \u2014 refusing to open it. Fix the file or push the folder again.`
34337
34934
  );
34338
34935
  }
34339
- const url2 = deckMasterUrl(link.baseUrl, link.presentationId);
34340
- if (json2) return printJson2(io, { presentationId: link.presentationId, baseUrl: link.baseUrl, url: url2 });
34936
+ const url2 = deckMasterUrl(link2.baseUrl, link2.presentationId);
34937
+ if (json3) return printJson2(io, { presentationId: link2.presentationId, baseUrl: link2.baseUrl, url: url2 });
34341
34938
  io.out.write(`${url2}
34342
34939
  `);
34343
34940
  openInBrowser(io, url2);
@@ -34347,13 +34944,13 @@ function registerContentCommands(program2, io) {
34347
34944
  await requireApiKey(ctx);
34348
34945
  let deckId = id2 ?? null;
34349
34946
  if (!deckId) {
34350
- const link = await readLink(resolve6("."));
34351
- if (!link) {
34947
+ const link2 = await readLink(resolve7("."));
34948
+ if (!link2) {
34352
34949
  throw new CliUsageError(
34353
34950
  `No deck id given and no ${LINK_FILENAME} found \u2014 run \`slideless agent-doc <id>\`.`
34354
34951
  );
34355
34952
  }
34356
- deckId = link.presentationId;
34953
+ deckId = link2.presentationId;
34357
34954
  }
34358
34955
  let content;
34359
34956
  try {
@@ -34367,9 +34964,9 @@ function registerContentCommands(program2, io) {
34367
34964
  throw e;
34368
34965
  }
34369
34966
  if (opts.out) {
34370
- const target = resolve6(opts.out);
34371
- await mkdir3(dirname4(target), { recursive: true });
34372
- await writeFile3(target, content);
34967
+ const target = resolve7(opts.out);
34968
+ await mkdir5(dirname5(target), { recursive: true });
34969
+ await writeFile4(target, content);
34373
34970
  if (ctx.json) return printJson2(io, { presentationId: deckId, path: target });
34374
34971
  io.out.write(`Wrote ${AGENT_DOC_PATH} of ${deckId} \u2192 ${target}
34375
34972
  `);
@@ -34390,25 +34987,25 @@ function registerContentCommands(program2, io) {
34390
34987
  let deckId = id2 ?? null;
34391
34988
  let dest = path ?? null;
34392
34989
  if (!deckId) {
34393
- const link = await readLink(resolve6(dest ?? "."));
34394
- if (!link) {
34990
+ const link2 = await readLink(resolve7(dest ?? "."));
34991
+ if (!link2) {
34395
34992
  throw new CliUsageError(
34396
34993
  `No deck id given and no ${LINK_FILENAME} found \u2014 run \`slideless pull <id> [path]\`.`
34397
34994
  );
34398
34995
  }
34399
- if (link.baseUrl !== ctx.baseUrl) throw linkMismatch(link.baseUrl);
34400
- deckId = link.presentationId;
34996
+ if (link2.baseUrl !== ctx.baseUrl) throw linkMismatch(link2.baseUrl);
34997
+ deckId = link2.presentationId;
34401
34998
  dest = dest ?? ".";
34402
34999
  }
34403
35000
  dest = dest ?? deckId;
34404
35001
  {
34405
- const link = await readLink(resolve6(dest));
34406
- if (link && link.baseUrl !== ctx.baseUrl) throw linkMismatch(link.baseUrl);
35002
+ const link2 = await readLink(resolve7(dest));
35003
+ if (link2 && link2.baseUrl !== ctx.baseUrl) throw linkMismatch(link2.baseUrl);
34407
35004
  }
34408
35005
  const deck = await ctx.client.presentation(deckId);
34409
35006
  const version2 = opts.at ?? deck.currentVersion;
34410
35007
  if (version2 < 1) throw new CliUsageError("This deck has no committed versions yet.");
34411
- const destRoot = resolve6(dest);
35008
+ const destRoot = resolve7(dest);
34412
35009
  const detail = await downloadVersionInto(ctx, deckId, version2, destRoot);
34413
35010
  await writeLink(destRoot, { presentationId: deckId, baseUrl: ctx.baseUrl });
34414
35011
  if (ctx.json) {
@@ -34431,11 +35028,11 @@ function registerContentCommands(program2, io) {
34431
35028
  await requireApiKey(ctx);
34432
35029
  let deckId = id2 ?? null;
34433
35030
  if (!deckId) {
34434
- const link = await readLink(resolve6("."));
34435
- if (!link) {
35031
+ const link2 = await readLink(resolve7("."));
35032
+ if (!link2) {
34436
35033
  throw new CliUsageError(`No deck id given and no ${LINK_FILENAME} in the current folder.`);
34437
35034
  }
34438
- deckId = link.presentationId;
35035
+ deckId = link2.presentationId;
34439
35036
  }
34440
35037
  if (opts.status && opts.status !== "open" && opts.status !== "resolved") {
34441
35038
  throw new CliUsageError("--status must be open or resolved");
@@ -34455,7 +35052,7 @@ function registerContentCommands(program2, io) {
34455
35052
  cursor = page.nextCursor;
34456
35053
  } while (cursor);
34457
35054
  if (opts.out) {
34458
- await writeFile3(resolve6(opts.out), `${JSON.stringify(rows, null, 2)}
35055
+ await writeFile4(resolve7(opts.out), `${JSON.stringify(rows, null, 2)}
34459
35056
  `);
34460
35057
  }
34461
35058
  if (ctx.json) return printJson2(io, { annotations: rows });
@@ -34486,8 +35083,11 @@ function registerContentCommands(program2, io) {
34486
35083
  (id2, annotationId, _opts, cmd) => setAnnotationStatus(cmd, io, id2, annotationId, "open")
34487
35084
  );
34488
35085
  program2.command("dev [path]").description(
34489
- "Serve the deck folder locally with the exact viewer sandbox headers + live reload (no backend)"
34490
- ).option("--port <n>", "port to serve on", (v) => parseInt(v, 10), 4173).option("--entry <path>", "entry document (default: index.html, or the only .html)").option("--no-open", "do not open the browser").action(
35086
+ "Serve the deck folder locally under a version bar, with the exact viewer sandbox headers + live reload (no backend)"
35087
+ ).option("--port <n>", "port to serve on", (v) => parseInt(v, 10), 4173).option("--entry <path>", "entry document (default: index.html, or the only .html)").option(
35088
+ "--store <dir>",
35089
+ `where local versions are kept (default: $${LOCAL_STORE_ENV}, else the user data folder)`
35090
+ ).option("--no-open", "do not open the browser").action(
34491
35091
  async (path, opts, cmd) => {
34492
35092
  const ctx = resolveContextForDev(cmd, io);
34493
35093
  const target = path ?? ".";
@@ -34496,16 +35096,29 @@ function registerContentCommands(program2, io) {
34496
35096
  const server = await startDevServer({
34497
35097
  root: scan.rootDir,
34498
35098
  entryPath,
34499
- port: opts.port
35099
+ port: opts.port,
35100
+ target,
35101
+ ...opts.store !== void 0 ? { store: opts.store } : {},
35102
+ cliVersion: cliVersionOf(cmd)
34500
35103
  });
34501
35104
  if (ctx.json) {
34502
- io.out.write(`${JSON.stringify({ url: server.url, entry: entryPath })}
34503
- `);
35105
+ io.out.write(
35106
+ `${JSON.stringify({
35107
+ url: server.url,
35108
+ entry: entryPath,
35109
+ store: server.store,
35110
+ storeError: server.storeError,
35111
+ cli: cliVersionOf(cmd)
35112
+ })}
35113
+ `
35114
+ );
34504
35115
  } else {
34505
35116
  io.out.write(
34506
35117
  `Serving ${scan.rootDir} at ${server.url} (entry: ${entryPath})
34507
35118
  Live reload on; sandbox headers match the public viewer. Ctrl-C to stop.
34508
- `
35119
+ ` + (server.store ? `Local versions in ${server.store}; save one from the bar or with \`slideless snapshot\`.
35120
+ ` : `Local versions are off: ${server.storeError ?? "no store"}
35121
+ `)
34509
35122
  );
34510
35123
  }
34511
35124
  if (opts.open) openInBrowser(io, server.url);
@@ -34518,6 +35131,62 @@ Live reload on; sandbox headers match the public viewer. Ctrl-C to stop.
34518
35131
  });
34519
35132
  }
34520
35133
  );
35134
+ program2.command("snapshot [path]").description(
35135
+ "Save the folder as a new local version on this machine (no instance, no login); no change, no version"
35136
+ ).option("--entry <path>", "entry document (default: index.html, or the only .html)").option(
35137
+ "--store <dir>",
35138
+ `where local versions are kept (default: $${LOCAL_STORE_ENV}, else the user data folder)`
35139
+ ).action(async (path, opts, cmd) => {
35140
+ const ctx = resolveContextForDev(cmd, io);
35141
+ const result = await snapshot(path ?? ".", {
35142
+ ...opts.entry !== void 0 ? { entry: opts.entry } : {},
35143
+ ...opts.store !== void 0 ? { store: opts.store } : {}
35144
+ });
35145
+ if (ctx.json) {
35146
+ io.out.write(`${JSON.stringify(result)}
35147
+ `);
35148
+ return;
35149
+ }
35150
+ io.out.write(
35151
+ result.created ? `Saved ${result.root} as local version ${result.version} (${result.fileCount} file${result.fileCount === 1 ? "" : "s"}, ${formatBytes(result.sizeBytes)})
35152
+ ` : `No change since local version ${result.version} of ${result.root}
35153
+ `
35154
+ );
35155
+ });
35156
+ program2.command("snapshots [path]").description("List the local versions of a folder, oldest first").option(
35157
+ "--store <dir>",
35158
+ `where local versions are kept (default: $${LOCAL_STORE_ENV}, else the user data folder)`
35159
+ ).action(async (path, opts, cmd) => {
35160
+ const ctx = resolveContextForDev(cmd, io);
35161
+ const { root, store, exists } = await openLocalStore(path ?? ".", opts.store, { create: false });
35162
+ const versions = exists ? await listLocalVersions(store, root) : [];
35163
+ if (ctx.json) {
35164
+ io.out.write(`${JSON.stringify({ root, store, versions })}
35165
+ `);
35166
+ return;
35167
+ }
35168
+ if (versions.length === 0) {
35169
+ io.out.write(`No local versions of ${root} yet: \`slideless snapshot\` saves one.
35170
+ `);
35171
+ return;
35172
+ }
35173
+ for (const v of versions) {
35174
+ io.out.write(
35175
+ `v${v.version} ${v.createdAt} ${v.fileCount} file${v.fileCount === 1 ? "" : "s"} ${formatBytes(v.sizeBytes)} ${v.entryPath}
35176
+ `
35177
+ );
35178
+ }
35179
+ });
35180
+ }
35181
+ function cliVersionOf(cmd) {
35182
+ let top = cmd;
35183
+ while (top.parent) top = top.parent;
35184
+ return top.version();
35185
+ }
35186
+ function formatBytes(n) {
35187
+ if (n < 1024) return `${n} B`;
35188
+ if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
35189
+ return `${(n / (1024 * 1024)).toFixed(1)} MB`;
34521
35190
  }
34522
35191
  async function pushDeck(ctx, target, opts) {
34523
35192
  const scan = await scanDeck(target);
@@ -34525,9 +35194,9 @@ async function pushDeck(ctx, target, opts) {
34525
35194
  const manifest = toManifest(scan);
34526
35195
  const totalBytes = scan.files.reduce((sum, f) => sum + f.sizeBytes, 0);
34527
35196
  const attachments = attachmentsOfScan(scan);
34528
- const link = await readLink(scan.rootDir);
35197
+ const link2 = await readLink(scan.rootDir);
34529
35198
  let existingId = opts.id ?? null;
34530
- if (!existingId && !opts.new && link) {
35199
+ if (!existingId && !opts.new && link2) {
34531
35200
  existingId = await linkedDeckId(
34532
35201
  ctx,
34533
35202
  scan.rootDir,
@@ -34664,23 +35333,23 @@ async function resolveProvenance(ctx, rootDir, opts) {
34664
35333
  out.push({ type, id: match.id, version: pinned });
34665
35334
  continue;
34666
35335
  }
34667
- const link = await readReferenceLink(referenceDirFor(rootDir, type));
34668
- if (!link) continue;
34669
- if (link.reference.type !== type) {
35336
+ const link2 = await readReferenceLink(referenceDirFor(rootDir, type));
35337
+ if (!link2) continue;
35338
+ if (link2.reference.type !== type) {
34670
35339
  ctx.io.err.write(
34671
- `Note: the folder ${REFERENCE_DIR}/${type}/ holds a ${link.reference.type}, not a ${type}; it is not recorded on this deck.
35340
+ `Note: the folder ${REFERENCE_DIR}/${type}/ holds a ${link2.reference.type}, not a ${type}; it is not recorded on this deck.
34672
35341
  `
34673
35342
  );
34674
35343
  continue;
34675
35344
  }
34676
- if (link.baseUrl !== ctx.baseUrl) {
35345
+ if (link2.baseUrl !== ctx.baseUrl) {
34677
35346
  ctx.io.err.write(
34678
- `Note: the ${type} in ${REFERENCE_DIR}/${type}/ was pulled from ${link.baseUrl}, not ${ctx.baseUrl}; it is not recorded on this deck.
35347
+ `Note: the ${type} in ${REFERENCE_DIR}/${type}/ was pulled from ${link2.baseUrl}, not ${ctx.baseUrl}; it is not recorded on this deck.
34679
35348
  `
34680
35349
  );
34681
35350
  continue;
34682
35351
  }
34683
- out.push({ type, id: link.presentationId, version: link.reference.version });
35352
+ out.push({ type, id: link2.presentationId, version: link2.reference.version });
34684
35353
  }
34685
35354
  return out;
34686
35355
  }
@@ -34767,7 +35436,7 @@ function printPushResult(ctx, result, opts) {
34767
35436
  created ? `Created "${committed.presentation.title}" at version 1 (${scan.files.length} files, ${fmtBytes(totalBytes)}, ${uploaded} uploaded)
34768
35437
  id: ${committed.presentation.id}
34769
35438
  url: ${url2}
34770
- linked: ${join5(scan.rootDir, LINK_FILENAME)}
35439
+ linked: ${join6(scan.rootDir, LINK_FILENAME)}
34771
35440
  ` : `Pushed "${committed.presentation.title}" \u2192 version ${committed.version.version} (${scan.files.length} files, ${fmtBytes(totalBytes)}, ${uploaded} uploaded)
34772
35441
  id: ${committed.presentation.id}
34773
35442
  url: ${url2}
@@ -34781,8 +35450,8 @@ function printPushResult(ctx, result, opts) {
34781
35450
  const inProjects = projectsOf(committed.presentation);
34782
35451
  if (inProjects.length > 0) io.out.write(` projects: ${projectsLine(inProjects)}
34783
35452
  `);
34784
- for (const link of projectLinks) {
34785
- if (!link.linked) ctx.io.err.write(` project ${link.projectId}: ${link.error}
35453
+ for (const link2 of projectLinks) {
35454
+ if (!link2.linked) ctx.io.err.write(` project ${link2.projectId}: ${link2.error}
34786
35455
  `);
34787
35456
  }
34788
35457
  if (!committed.version.hasAgentDoc) io.out.write(AGENT_DOC_HINT);
@@ -34790,7 +35459,7 @@ function printPushResult(ctx, result, opts) {
34790
35459
  }
34791
35460
  async function downloadVersionInto(ctx, deckId, version2, destRoot) {
34792
35461
  const detail = await ctx.client.presentationVersion(deckId, version2);
34793
- await mkdir3(destRoot, { recursive: true });
35462
+ await mkdir5(destRoot, { recursive: true });
34794
35463
  for (const entry of detail.manifest) {
34795
35464
  if (!isSafeAssetPath(entry.path)) {
34796
35465
  throw new Error(`Refusing to write unsafe manifest path: ${entry.path}`);
@@ -35007,11 +35676,11 @@ ${JSON.stringify(updated.metadata, null, 2)}
35007
35676
  }
35008
35677
 
35009
35678
  // src/commands/references.ts
35010
- import { mkdir as mkdir4, readdir as readdir2, readFile as readFile8, rm, rmdir, stat as stat5 } from "node:fs/promises";
35011
- import { dirname as dirname5, join as join6, resolve as resolve7 } from "node:path";
35679
+ import { mkdir as mkdir6, readdir as readdir3, readFile as readFile9, rm as rm2, rmdir, stat as stat6 } from "node:fs/promises";
35680
+ import { dirname as dirname6, join as join7, resolve as resolve8 } from "node:path";
35012
35681
 
35013
35682
  // src/commands/documents.ts
35014
- import { readFile as readFile7 } from "node:fs/promises";
35683
+ import { readFile as readFile8 } from "node:fs/promises";
35015
35684
  var collect5 = (value, all) => [...all, value];
35016
35685
  function registerTemplateSchemaCommands(root, io) {
35017
35686
  const schema = root.command("schema").description(
@@ -35233,7 +35902,7 @@ async function resolveTemplate(ctx, ref) {
35233
35902
  async function readJsonObject(path, flag) {
35234
35903
  let text;
35235
35904
  try {
35236
- text = await readFile7(path, "utf8");
35905
+ text = await readFile8(path, "utf8");
35237
35906
  } catch {
35238
35907
  throw new CliUsageError(`${flag}: cannot read ${path}.`);
35239
35908
  }
@@ -35368,7 +36037,7 @@ function registerFamily(program2, io, family) {
35368
36037
  const match = await pickReference(ctx, ref, type, noun);
35369
36038
  const matchType = match.reference.type;
35370
36039
  const version2 = versionOf(match, opts.at);
35371
- const dest = resolve7(opts.into ?? referenceDirFor(".", matchType));
36040
+ const dest = resolve8(opts.into ?? referenceDirFor(".", matchType));
35372
36041
  await prepareReferenceDir(dest, ctx.baseUrl, noun);
35373
36042
  const detail = await downloadOrClean(ctx, match.id, version2, dest);
35374
36043
  await writeLink(dest, {
@@ -35386,7 +36055,7 @@ function registerFamily(program2, io, family) {
35386
36055
  }
35387
36056
  io.out.write(
35388
36057
  `Pulled ${matchType} "${match.title}" v${version2} \u2192 ${dest} (${detail.manifest.length} files)
35389
- read ${join6(dest, AGENT_DOC_PATH)} before authoring; a push from the deck folder records this ${matchType}.
36058
+ read ${join7(dest, AGENT_DOC_PATH)} before authoring; a push from the deck folder records this ${matchType}.
35390
36059
  `
35391
36060
  );
35392
36061
  }
@@ -35397,18 +36066,18 @@ function registerFamily(program2, io, family) {
35397
36066
  ),
35398
36067
  "the type to scaffold"
35399
36068
  ).option("--title <title>", "the title written in the frontmatter (default: an invented one)").action(async (dir, opts, cmd) => {
35400
- const { json: json2 } = jsonOnly(cmd);
36069
+ const { json: json3 } = jsonOnly(cmd);
35401
36070
  const type = typeOf(family, opts.type, true);
35402
- const target = resolve7(dir);
36071
+ const target = resolve8(dir);
35403
36072
  if (!await isMissingOrEmptyDir(target)) {
35404
36073
  throw new CliUsageError(`${target} exists and is not empty; scaffold into a new or empty folder.`);
35405
36074
  }
35406
36075
  const scaffold = scaffoldReference(type, opts.title);
35407
- await mkdir4(target, { recursive: true });
35408
- for (const d of scaffold.dirs) await mkdir4(join6(target, d), { recursive: true });
36076
+ await mkdir6(target, { recursive: true });
36077
+ for (const d of scaffold.dirs) await mkdir6(join7(target, d), { recursive: true });
35409
36078
  for (const f of scaffold.files)
35410
- await writeNoFollow(join6(target, f.path), Buffer.from(f.content, "utf8"));
35411
- if (json2)
36079
+ await writeNoFollow(join7(target, f.path), Buffer.from(f.content, "utf8"));
36080
+ if (json3)
35412
36081
  return printJson2(io, {
35413
36082
  path: target,
35414
36083
  type,
@@ -35448,7 +36117,7 @@ function registerFamily(program2, io, family) {
35448
36117
  try {
35449
36118
  result = await pushDeck(ctx, target, pushOpts);
35450
36119
  } catch (e) {
35451
- if (e instanceof PlatformApiError && e.status === 404 && await readReferenceLink(resolve7(target))) {
36120
+ if (e instanceof PlatformApiError && e.status === 404 && await readReferenceLink(resolve8(target))) {
35452
36121
  throw new CliUsageError(
35453
36122
  `This ${noun} is not yours to push: only its owner (or a collaborator with a dev grant) pushes a new version, and the instance answers "not found" to anyone else. Start a deck of your own from it with \`slideless ${family.name} start\`.`
35454
36123
  );
@@ -35539,15 +36208,15 @@ function registerFamily(program2, io, family) {
35539
36208
  const type = typeOf(family, opts.type, false);
35540
36209
  const match = await pickReference(ctx, ref, type, noun);
35541
36210
  const version2 = versionOf(match, opts.at);
35542
- const target = resolve7(dir);
36211
+ const target = resolve8(dir);
35543
36212
  if (!await isMissingOrEmptyDir(target)) {
35544
36213
  throw new CliUsageError(`${target} exists and is not empty; start into a new or empty folder.`);
35545
36214
  }
35546
36215
  const detail = await downloadOrClean(ctx, match.id, version2, target);
35547
- const agentPath = join6(target, AGENT_DOC_PATH);
36216
+ const agentPath = join7(target, AGENT_DOC_PATH);
35548
36217
  const hadAgentDoc = detail.manifest.some((e) => e.path === AGENT_DOC_PATH);
35549
36218
  if (hadAgentDoc) {
35550
- const text = await readFile8(agentPath, "utf8");
36219
+ const text = await readFile9(agentPath, "utf8");
35551
36220
  await writeNoFollow(agentPath, Buffer.from(stripTypeLine(text), "utf8"));
35552
36221
  }
35553
36222
  const from = { type: match.reference.type, id: match.id, version: version2 };
@@ -35615,15 +36284,15 @@ async function patchReference(ctx, match, patch, noun) {
35615
36284
  }
35616
36285
  }
35617
36286
  async function refuseUnlessDeclared(target, type, noun) {
35618
- const abs = resolve7(target);
35619
- const info = await stat5(abs).catch(() => null);
36287
+ const abs = resolve8(target);
36288
+ const info = await stat6(abs).catch(() => null);
35620
36289
  if (!info) throw new CliUsageError(`No such file or directory: ${target}`);
35621
36290
  if (!info.isDirectory()) {
35622
36291
  throw new CliUsageError(
35623
36292
  `A ${noun} is a folder with an ${AGENT_DOC_PATH} at its root; ${target} is a file.`
35624
36293
  );
35625
36294
  }
35626
- const text = await readFile8(join6(abs, AGENT_DOC_PATH), "utf8").catch(() => null);
36295
+ const text = await readFile9(join7(abs, AGENT_DOC_PATH), "utf8").catch(() => null);
35627
36296
  if (text === null) {
35628
36297
  throw new CliUsageError(
35629
36298
  `${target} has no ${AGENT_DOC_PATH}: a ${noun} declares its type in that file's frontmatter (\`slideless ${noun === "reference" ? "reference" : noun} new\` scaffolds one). Nothing was uploaded.`
@@ -35654,41 +36323,41 @@ async function refuseUnlessDeclared(target, type, noun) {
35654
36323
  }
35655
36324
  async function prepareReferenceDir(dest, baseUrl, noun) {
35656
36325
  if (await isMissingOrEmptyDir(dest)) return;
35657
- const info = await stat5(dest);
36326
+ const info = await stat6(dest);
35658
36327
  if (!info.isDirectory()) throw new CliUsageError(`${dest} exists and is not a folder.`);
35659
- const link = await readReferenceLink(dest);
35660
- if (!link) {
36328
+ const link2 = await readReferenceLink(dest);
36329
+ if (!link2) {
35661
36330
  const plain = await readLink(dest);
35662
36331
  throw new CliUsageError(
35663
36332
  plain ? `${dest} is a deck folder linked by ${LINK_FILENAME}, not a pulled ${noun}; pull into another folder (--into).` : `${dest} is not empty and is not a folder a previous pull wrote. Delete it to pull there, or pull into another folder (--into).`
35664
36333
  );
35665
36334
  }
35666
- if (link.baseUrl !== baseUrl) {
36335
+ if (link2.baseUrl !== baseUrl) {
35667
36336
  throw new CliUsageError(
35668
- `${dest} holds a ${link.reference.type} pulled from ${link.baseUrl}, and you are pulling from ${baseUrl}. Delete the folder or pull into another one (--into).`
36337
+ `${dest} holds a ${link2.reference.type} pulled from ${link2.baseUrl}, and you are pulling from ${baseUrl}. Delete the folder or pull into another one (--into).`
35669
36338
  );
35670
36339
  }
35671
- await rm(dest, { recursive: true, force: true });
36340
+ await rm2(dest, { recursive: true, force: true });
35672
36341
  }
35673
36342
  async function downloadOrClean(ctx, deckId, version2, dest) {
35674
36343
  const destExisted = await pathExists(dest);
35675
- let firstExisting = dirname5(dest);
35676
- while (firstExisting !== dirname5(firstExisting) && !await pathExists(firstExisting)) {
35677
- firstExisting = dirname5(firstExisting);
36344
+ let firstExisting = dirname6(dest);
36345
+ while (firstExisting !== dirname6(firstExisting) && !await pathExists(firstExisting)) {
36346
+ firstExisting = dirname6(firstExisting);
35678
36347
  }
35679
36348
  try {
35680
36349
  return await downloadVersionInto(ctx, deckId, version2, dest);
35681
36350
  } catch (e) {
35682
36351
  const removed = [];
35683
36352
  if (destExisted) {
35684
- for (const entry of await readdir2(dest).catch(() => [])) {
35685
- await rm(join6(dest, entry), { recursive: true, force: true }).catch(() => void 0);
35686
- removed.push(join6(dest, entry));
36353
+ for (const entry of await readdir3(dest).catch(() => [])) {
36354
+ await rm2(join7(dest, entry), { recursive: true, force: true }).catch(() => void 0);
36355
+ removed.push(join7(dest, entry));
35687
36356
  }
35688
36357
  } else if (await pathExists(dest)) {
35689
- await rm(dest, { recursive: true, force: true }).catch(() => void 0);
36358
+ await rm2(dest, { recursive: true, force: true }).catch(() => void 0);
35690
36359
  removed.push(dest);
35691
- for (let level = dirname5(dest); level !== firstExisting; level = dirname5(level)) {
36360
+ for (let level = dirname6(dest); level !== firstExisting; level = dirname6(level)) {
35692
36361
  try {
35693
36362
  await rmdir(level);
35694
36363
  } catch {
@@ -35706,10 +36375,10 @@ async function downloadOrClean(ctx, deckId, version2, dest) {
35706
36375
  }
35707
36376
  }
35708
36377
  async function isMissingOrEmptyDir(path) {
35709
- const info = await stat5(path).catch(() => null);
36378
+ const info = await stat6(path).catch(() => null);
35710
36379
  if (!info) return true;
35711
36380
  if (!info.isDirectory()) return false;
35712
- return (await readdir2(path)).length === 0;
36381
+ return (await readdir3(path)).length === 0;
35713
36382
  }
35714
36383
  function jsonOnly(cmd) {
35715
36384
  const opts = cmd.optsWithGlobals();
@@ -36326,15 +36995,15 @@ function csvCell(raw) {
36326
36995
  }
36327
36996
 
36328
36997
  // src/commands/response-files.ts
36329
- import { createWriteStream as createWriteStream2 } from "node:fs";
36330
- import { stat as stat6, unlink as unlink2 } from "node:fs/promises";
36331
- import { basename as basename3, resolve as resolve8, win32 as win322 } from "node:path";
36998
+ import { createWriteStream as createWriteStream3 } from "node:fs";
36999
+ import { stat as stat7, unlink as unlink2 } from "node:fs/promises";
37000
+ import { basename as basename4, resolve as resolve9, win32 as win322 } from "node:path";
36332
37001
  import { Readable as Readable2 } from "node:stream";
36333
- import { pipeline as pipeline3 } from "node:stream/promises";
37002
+ import { pipeline as pipeline4 } from "node:stream/promises";
36334
37003
  var MAX_SEGMENT_CHARS = 120;
36335
37004
  function safePathSegment(raw) {
36336
37005
  const printable = raw.replace(/[\u0000-\u001f\u007f-\u009f]/g, "");
36337
- const name = basename3(win322.basename(printable));
37006
+ const name = basename4(win322.basename(printable));
36338
37007
  const cleaned = truncateKeepingExtension(
36339
37008
  name.replace(/[\\/:*?"<>|]/g, "_").replace(/^\.+/, "_").replace(/[\s.]+$/, ""),
36340
37009
  MAX_SEGMENT_CHARS
@@ -36464,7 +37133,7 @@ function registerResponseFilesCommand(program2, io) {
36464
37133
  } while (cursor);
36465
37134
  }
36466
37135
  const planned = plan(responses, responseId !== void 0);
36467
- const root = resolve8(
37136
+ const root = resolve9(
36468
37137
  opts.out ?? (responseId !== void 0 ? `response-files-${safePathSegment(responseId.slice(0, 8))}` : `form-files-${safePathSegment(id2.slice(0, 8))}`)
36469
37138
  );
36470
37139
  if (planned.length === 0) {
@@ -36527,21 +37196,21 @@ async function zipMode(ctx, io, id2, responseId, filters, zip) {
36527
37196
  let path;
36528
37197
  let sizeBytes;
36529
37198
  if (typeof zip === "string") {
36530
- path = resolve8(zip);
37199
+ path = resolve9(zip);
36531
37200
  try {
36532
- await pipeline3(source, createWriteStream2(path));
37201
+ await pipeline4(source, createWriteStream3(path));
36533
37202
  } catch (e) {
36534
37203
  await unlink2(path).catch(() => void 0);
36535
37204
  throw e;
36536
37205
  }
36537
- sizeBytes = (await stat6(path)).size;
37206
+ sizeBytes = (await stat7(path)).size;
36538
37207
  } else {
36539
37208
  const served = contentDispositionName(res.headers.get("content-disposition"));
36540
37209
  const fallback = `form-files-${safePathSegment((responseId ?? id2).slice(0, 8))}.zip`;
36541
37210
  let name = served ? safePathSegment(served) : fallback;
36542
37211
  if (name === "_") name = fallback;
36543
37212
  if (!/\.zip$/i.test(name)) name = `${name}.zip`;
36544
- ({ path, sizeBytes } = await streamContained(resolve8("."), name, source));
37213
+ ({ path, sizeBytes } = await streamContained(resolve9("."), name, source));
36545
37214
  }
36546
37215
  if (ctx.json) return printJson2(io, { mode: "zip", path, sizeBytes });
36547
37216
  io.out.write(`Form files written to ${path} (${fmtBytes(sizeBytes)})
@@ -36549,7 +37218,7 @@ async function zipMode(ctx, io, id2, responseId, filters, zip) {
36549
37218
  }
36550
37219
 
36551
37220
  // src/index.ts
36552
- var VERSION = "0.13.14";
37221
+ var VERSION = "0.14.1";
36553
37222
  function registerTool(program2, io) {
36554
37223
  registerDeckCommands(program2, io);
36555
37224
  registerContentCommands(program2, io);