pixelkiln 0.70.1 → 0.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -14419,6 +14419,15 @@ var SkeletonAnimationRequestSchema = z8.object({
14419
14419
  /** Replace an existing `keypointsFile` with `set`. */
14420
14420
  overwrite: z8.boolean().optional()
14421
14421
  }).strict();
14422
+ var SkeletonKeypointsUpdateSchema = z8.object({
14423
+ action: z8.literal("update-skeleton-keypoints"),
14424
+ project: z8.string().min(1).optional(),
14425
+ styleId: z8.string().min(1),
14426
+ assetId: z8.string().min(1),
14427
+ /** The file's SHA-256 when the page loaded it; anything else on disk is a concurrent edit. */
14428
+ expectedSha256: z8.string().regex(/^[0-9a-f]{64}$/),
14429
+ set: SkeletonSetSchema
14430
+ }).strict();
14422
14431
  var DEFAULT_ESTIMATE_LIMIT = 10;
14423
14432
  function skeletonSourceFile(spec) {
14424
14433
  if (spec.source) return path26.resolve(spec.root, spec.source);
@@ -14521,6 +14530,26 @@ async function createSkeletonAnimation(manifestPath, request) {
14521
14530
  throw error;
14522
14531
  }
14523
14532
  }
14533
+ async function updateSkeletonKeypoints(ctx, request) {
14534
+ const key = lockKey(request.styleId, request.assetId);
14535
+ const spec = ctx.specs.find((candidate) => lockKey(candidate.styleId, candidate.assetId) === key);
14536
+ if (!spec) throw new ManifestEditError(`"${key}" is not declared by the manifest`);
14537
+ const file = spec.revision?.mode === "animate-skeleton" ? spec.revision.keypointsFile : void 0;
14538
+ if (!file) throw new ManifestEditError(`${key} is not an animate-skeleton revision`);
14539
+ const relative = path26.relative(ctx.loaded.root, file);
14540
+ if (relative.startsWith("..") || path26.isAbsolute(relative)) {
14541
+ throw new ManifestEditError(`${key}'s keypoints file is outside the project; edit it by hand`);
14542
+ }
14543
+ const current = existsSync18(file) ? sha256(await readFile17(file)) : null;
14544
+ if (current !== request.expectedSha256) {
14545
+ throw Object.assign(
14546
+ new Error(`${relative.split(path26.sep).join("/")} changed on disk since this page loaded it; press Refresh and edit again`),
14547
+ { status: 409 }
14548
+ );
14549
+ }
14550
+ await writeFile12(file, JSON.stringify(request.set, null, 2) + "\n");
14551
+ return relative.split(path26.sep).join("/");
14552
+ }
14524
14553
 
14525
14554
  // src/gallery/edit.ts
14526
14555
  var Base64 = z9.string().regex(/^[A-Za-z0-9+/]*={0,2}$/).max(Math.ceil(MAX_HAND_EDIT_BYTES / 3) * 4);
@@ -14597,6 +14626,18 @@ function createGalleryEditHandler(opts) {
14597
14626
  }
14598
14627
  return opts.reload();
14599
14628
  }
14629
+ const poses = SkeletonKeypointsUpdateSchema.safeParse(body);
14630
+ if (poses.success) {
14631
+ if (!opts.loadProject) throw new ManifestEditError("pose edits are not available in this gallery");
14632
+ const written = await updateSkeletonKeypoints(await opts.loadProject(poses.data.project), poses.data);
14633
+ log2(` poses saved: ${written} (${poses.data.styleId}/${poses.data.assetId} is stale until generated again)`);
14634
+ return opts.reload();
14635
+ }
14636
+ if (body?.action === "update-skeleton-keypoints") {
14637
+ throw new ManifestEditError(
14638
+ "invalid pose edit: " + poses.error.issues.slice(0, 3).map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ")
14639
+ );
14640
+ }
14600
14641
  const skeleton = SkeletonAnimationRequestSchema.safeParse(body);
14601
14642
  if (skeleton.success) {
14602
14643
  let manifestPath2;
@@ -15112,7 +15153,8 @@ async function buildGallerySnapshot(opts) {
15112
15153
  mirrorOfKey: spec.mirror ? lockKey(spec.styleId, spec.mirror.sourceAssetId) : entry?.mirror ? lockKey(spec.styleId, entry.mirror.sourceAssetId) : null,
15113
15154
  skeleton: spec.revision?.mode === "animate-skeleton" && spec.revision.keypointsFile ? {
15114
15155
  keypointsFile: portableOutputPath(spec.revision.keypointsFile, root),
15115
- set: spec.revision.skeleton ?? null
15156
+ set: spec.revision.skeleton ?? null,
15157
+ sha256: spec.revision.keypointsSha256 ?? null
15116
15158
  } : null,
15117
15159
  character: describeCharacter(spec, entry),
15118
15160
  outputs,