@fluid-app/fluid-cli-theme-dev 0.1.49 → 0.1.51

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/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Command } from "commander";
2
- import { getAuthToken, readConfig, updateConfig } from "@fluid-app/fluid-cli";
2
+ import { getAuthToken, gitSyncActorFromMe, gitSyncCommitSubject, readConfig, resolveGitSyncActor, summarizeChanges, updateConfig } from "@fluid-app/fluid-cli";
3
3
  import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
4
4
  import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
5
5
  import { createHash, randomBytes } from "node:crypto";
@@ -3974,40 +3974,32 @@ async function migrateLegacyChecksumsIntoShadow(input) {
3974
3974
  }
3975
3975
  //#endregion
3976
3976
  //#region src/theme/sync-identity.ts
3977
- /** Legacy (actor-less) wording per verb. `Push`/`Pull` are byte-
3978
- * compatible with what the CLI has always written. */
3979
- const LEGACY_WORDING = {
3980
- Push: "push",
3981
- Pull: "pull",
3982
- "Baseline from server": "baseline from server",
3983
- "Snapshot before pull": "snapshot before pull"
3984
- };
3985
- /** Human base message per verb, used in the stamped format. */
3977
+ /** Human action per verb, used as the canonical subject's action. */
3986
3978
  const BASE_MESSAGE = {
3987
3979
  Push: "Push from Fluid CLI",
3988
3980
  Pull: "Pull from Fluid CLI",
3989
3981
  "Baseline from server": "Baseline from server",
3990
3982
  "Snapshot before pull": "Snapshot before pull"
3991
3983
  };
3992
- function syncCommitSubject(verb, actor, when = /* @__PURE__ */ new Date()) {
3993
- if (!actor) return `${LEGACY_WORDING[verb]} @ ${when.toISOString()}`;
3994
- const stamp = when.toISOString().slice(0, 19).replace("T", " ");
3995
- const idSuffix = actor.publicId ? ` (${actor.publicId})` : "";
3996
- return `${actor.name}: ${BASE_MESSAGE[verb]} · ${stamp}${idSuffix}`;
3984
+ /**
3985
+ * Build a shadow-repo commit subject.
3986
+ *
3987
+ * `changes` (when supplied) replaces the per-verb constant with a
3988
+ * description of what the sync actually carried, so the shadow log reads
3989
+ * `Update 3 files in templates` rather than `Push from Fluid CLI` on
3990
+ * every entry. Falls back to the constant for an empty change set — a
3991
+ * baseline or a no-op sync still deserves a sensible subject.
3992
+ */
3993
+ function syncCommitSubject(verb, actor, when = /* @__PURE__ */ new Date(), changes = []) {
3994
+ return gitSyncCommitSubject(summarizeChanges(changes) ?? BASE_MESSAGE[verb], actor, when);
3997
3995
  }
3998
3996
  /** Resolve a `/api/me` body to a commit actor. Exported for tests.
3999
- * Name fallback ordering matches the Mist CLI: full_name (or a
4000
- * first+last composition) → email → `user-<id>`; null when none of
4001
- * those exist the caller then uses the legacy wording. */
3997
+ * Delegates to the shared resolver so the name fallback chain
3998
+ * (full_name → first+last → email → `user-<id>`) can't drift between
3999
+ * CLIs. Null when the body carries no usable identity — the caller then
4000
+ * writes a `Fluid:` system commit. */
4002
4001
  function actorFromMe(raw) {
4003
- const user = raw.user ?? raw;
4004
- const composed = [user.first_name, user.last_name].filter(Boolean).join(" ").trim();
4005
- const name = user.full_name && user.full_name.trim() || (composed.length > 0 ? composed : null) || user.email && user.email.trim() || (typeof user.id === "number" && Number.isFinite(user.id) ? `user-${user.id}` : null);
4006
- if (!name) return null;
4007
- return {
4008
- name,
4009
- publicId: user.public_id && user.public_id.trim() || null
4010
- };
4002
+ return gitSyncActorFromMe(raw);
4011
4003
  }
4012
4004
  /**
4013
4005
  * Best-effort fetch of the signed-in user for commit stamping. Races
@@ -4016,6 +4008,9 @@ function actorFromMe(raw) {
4016
4008
  * this off early and await it only at commit time.
4017
4009
  */
4018
4010
  async function fetchSyncActor(api, timeoutMs = 5e3) {
4011
+ return resolveGitSyncActor(() => requestSyncActor(api, timeoutMs));
4012
+ }
4013
+ async function requestSyncActor(api, timeoutMs) {
4019
4014
  try {
4020
4015
  return actorFromMe(await Promise.race([api.get("/api/me"), new Promise((_, reject) => {
4021
4016
  setTimeout(() => reject(/* @__PURE__ */ new Error(`timed out after ${timeoutMs}ms`)), timeoutMs).unref?.();
@@ -4221,7 +4216,16 @@ function createPushCommand() {
4221
4216
  for (const err of errors) console.error(` ${err}`);
4222
4217
  process.exitCode = 1;
4223
4218
  } else spinner.succeed(`Pushed ${uploaded} file(s), saved ${linked} remote asset reference(s)` + (deletedCount > 0 ? `, deleted ${deletedCount} remote file(s).` : "."));
4224
- if (errors.length === 0) await commitPushedState(themeRoot, shadow, syncCommitSubject("Push", await getActor()));
4219
+ if (errors.length === 0) {
4220
+ const pushedChanges = [...changed.map((file) => ({
4221
+ status: "modified",
4222
+ path: file.relativePath
4223
+ })), ...opts.nodelete ? [] : deleted.map((key) => ({
4224
+ status: "deleted",
4225
+ path: key
4226
+ }))];
4227
+ await commitPushedState(themeRoot, shadow, syncCommitSubject("Push", await getActor(), /* @__PURE__ */ new Date(), pushedChanges));
4228
+ }
4225
4229
  await persistConfig();
4226
4230
  /**
4227
4231
  * Persist `.fluid-theme.json`. When a config already exists,