pinme 2.0.9-beta.2 → 2.0.10-beta.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/index.js +456 -204
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -103,8 +103,8 @@ var require_package = __commonJS({
103
103
  // node_modules/.pnpm/dotenv@16.5.0/node_modules/dotenv/lib/main.js
104
104
  var require_main = __commonJS({
105
105
  "node_modules/.pnpm/dotenv@16.5.0/node_modules/dotenv/lib/main.js"(exports2, module2) {
106
- var fs17 = require("fs");
107
- var path18 = require("path");
106
+ var fs18 = require("fs");
107
+ var path19 = require("path");
108
108
  var os6 = require("os");
109
109
  var crypto3 = require("crypto");
110
110
  var packageJson = require_package();
@@ -207,7 +207,7 @@ var require_main = __commonJS({
207
207
  if (options && options.path && options.path.length > 0) {
208
208
  if (Array.isArray(options.path)) {
209
209
  for (const filepath of options.path) {
210
- if (fs17.existsSync(filepath)) {
210
+ if (fs18.existsSync(filepath)) {
211
211
  possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
212
212
  }
213
213
  }
@@ -215,15 +215,15 @@ var require_main = __commonJS({
215
215
  possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
216
216
  }
217
217
  } else {
218
- possibleVaultPath = path18.resolve(process.cwd(), ".env.vault");
218
+ possibleVaultPath = path19.resolve(process.cwd(), ".env.vault");
219
219
  }
220
- if (fs17.existsSync(possibleVaultPath)) {
220
+ if (fs18.existsSync(possibleVaultPath)) {
221
221
  return possibleVaultPath;
222
222
  }
223
223
  return null;
224
224
  }
225
225
  function _resolveHome(envPath) {
226
- return envPath[0] === "~" ? path18.join(os6.homedir(), envPath.slice(1)) : envPath;
226
+ return envPath[0] === "~" ? path19.join(os6.homedir(), envPath.slice(1)) : envPath;
227
227
  }
228
228
  function _configVault(options) {
229
229
  const debug = Boolean(options && options.debug);
@@ -239,7 +239,7 @@ var require_main = __commonJS({
239
239
  return { parsed };
240
240
  }
241
241
  function configDotenv(options) {
242
- const dotenvPath = path18.resolve(process.cwd(), ".env");
242
+ const dotenvPath = path19.resolve(process.cwd(), ".env");
243
243
  let encoding = "utf8";
244
244
  const debug = Boolean(options && options.debug);
245
245
  if (options && options.encoding) {
@@ -262,13 +262,13 @@ var require_main = __commonJS({
262
262
  }
263
263
  let lastError;
264
264
  const parsedAll = {};
265
- for (const path19 of optionPaths) {
265
+ for (const path20 of optionPaths) {
266
266
  try {
267
- const parsed = DotenvModule.parse(fs17.readFileSync(path19, { encoding }));
267
+ const parsed = DotenvModule.parse(fs18.readFileSync(path20, { encoding }));
268
268
  DotenvModule.populate(parsedAll, parsed, options);
269
269
  } catch (e) {
270
270
  if (debug) {
271
- _debug(`Failed to load ${path19} ${e.message}`);
271
+ _debug(`Failed to load ${path20} ${e.message}`);
272
272
  }
273
273
  lastError = e;
274
274
  }
@@ -828,9 +828,9 @@ function isVisitable(thing) {
828
828
  function removeBrackets(key) {
829
829
  return utils_default.endsWith(key, "[]") ? key.slice(0, -2) : key;
830
830
  }
831
- function renderKey(path18, key, dots) {
832
- if (!path18) return key;
833
- return path18.concat(key).map(function each(token, i) {
831
+ function renderKey(path19, key, dots) {
832
+ if (!path19) return key;
833
+ return path19.concat(key).map(function each(token, i) {
834
834
  token = removeBrackets(token);
835
835
  return !dots && i ? "[" + token + "]" : token;
836
836
  }).join(dots ? "." : "");
@@ -872,9 +872,9 @@ function toFormData(obj, formData, options) {
872
872
  }
873
873
  return value;
874
874
  }
875
- function defaultVisitor(value, key, path18) {
875
+ function defaultVisitor(value, key, path19) {
876
876
  let arr = value;
877
- if (value && !path18 && typeof value === "object") {
877
+ if (value && !path19 && typeof value === "object") {
878
878
  if (utils_default.endsWith(key, "{}")) {
879
879
  key = metaTokens ? key : key.slice(0, -2);
880
880
  value = JSON.stringify(value);
@@ -893,7 +893,7 @@ function toFormData(obj, formData, options) {
893
893
  if (isVisitable(value)) {
894
894
  return true;
895
895
  }
896
- formData.append(renderKey(path18, key, dots), convertValue(value));
896
+ formData.append(renderKey(path19, key, dots), convertValue(value));
897
897
  return false;
898
898
  }
899
899
  const stack = [];
@@ -902,10 +902,10 @@ function toFormData(obj, formData, options) {
902
902
  convertValue,
903
903
  isVisitable
904
904
  });
905
- function build(value, path18) {
905
+ function build(value, path19) {
906
906
  if (utils_default.isUndefined(value)) return;
907
907
  if (stack.indexOf(value) !== -1) {
908
- throw Error("Circular reference detected in " + path18.join("."));
908
+ throw Error("Circular reference detected in " + path19.join("."));
909
909
  }
910
910
  stack.push(value);
911
911
  utils_default.forEach(value, function each(el, key) {
@@ -913,11 +913,11 @@ function toFormData(obj, formData, options) {
913
913
  formData,
914
914
  el,
915
915
  utils_default.isString(key) ? key.trim() : key,
916
- path18,
916
+ path19,
917
917
  exposedHelpers
918
918
  );
919
919
  if (result === true) {
920
- build(el, path18 ? path18.concat(key) : [key]);
920
+ build(el, path19 ? path19.concat(key) : [key]);
921
921
  }
922
922
  });
923
923
  stack.pop();
@@ -1137,7 +1137,7 @@ var init_platform = __esm({
1137
1137
  // node_modules/.pnpm/axios@1.3.2/node_modules/axios/lib/helpers/toURLEncodedForm.js
1138
1138
  function toURLEncodedForm(data, options) {
1139
1139
  return toFormData_default(data, new node_default.classes.URLSearchParams(), Object.assign({
1140
- visitor: function(value, key, path18, helpers) {
1140
+ visitor: function(value, key, path19, helpers) {
1141
1141
  if (node_default.isNode && utils_default.isBuffer(value)) {
1142
1142
  this.append(key, value.toString("base64"));
1143
1143
  return false;
@@ -1174,10 +1174,10 @@ function arrayToObject(arr) {
1174
1174
  return obj;
1175
1175
  }
1176
1176
  function formDataToJSON(formData) {
1177
- function buildPath(path18, value, target, index) {
1178
- let name = path18[index++];
1177
+ function buildPath(path19, value, target, index) {
1178
+ let name = path19[index++];
1179
1179
  const isNumericKey = Number.isFinite(+name);
1180
- const isLast = index >= path18.length;
1180
+ const isLast = index >= path19.length;
1181
1181
  name = !name && utils_default.isArray(target) ? target.length : name;
1182
1182
  if (isLast) {
1183
1183
  if (utils_default.hasOwnProp(target, name)) {
@@ -1190,7 +1190,7 @@ function formDataToJSON(formData) {
1190
1190
  if (!target[name] || !utils_default.isObject(target[name])) {
1191
1191
  target[name] = [];
1192
1192
  }
1193
- const result = buildPath(path18, value, target[name], index);
1193
+ const result = buildPath(path19, value, target[name], index);
1194
1194
  if (result && utils_default.isArray(target[name])) {
1195
1195
  target[name] = arrayToObject(target[name]);
1196
1196
  }
@@ -3516,9 +3516,9 @@ var init_http = __esm({
3516
3516
  auth = urlUsername + ":" + urlPassword;
3517
3517
  }
3518
3518
  auth && headers.delete("authorization");
3519
- let path18;
3519
+ let path19;
3520
3520
  try {
3521
- path18 = buildURL(
3521
+ path19 = buildURL(
3522
3522
  parsed.pathname + parsed.search,
3523
3523
  config.params,
3524
3524
  config.paramsSerializer
@@ -3536,7 +3536,7 @@ var init_http = __esm({
3536
3536
  false
3537
3537
  );
3538
3538
  const options = {
3539
- path: path18,
3539
+ path: path19,
3540
3540
  method,
3541
3541
  headers: headers.toJSON(),
3542
3542
  agents: { http: config.httpAgent, https: config.httpsAgent },
@@ -3763,14 +3763,14 @@ var init_cookies = __esm({
3763
3763
  // Standard browser envs support document.cookie
3764
3764
  /* @__PURE__ */ function standardBrowserEnv() {
3765
3765
  return {
3766
- write: function write(name, value, expires, path18, domain, secure) {
3766
+ write: function write(name, value, expires, path19, domain, secure) {
3767
3767
  const cookie = [];
3768
3768
  cookie.push(name + "=" + encodeURIComponent(value));
3769
3769
  if (utils_default.isNumber(expires)) {
3770
3770
  cookie.push("expires=" + new Date(expires).toGMTString());
3771
3771
  }
3772
- if (utils_default.isString(path18)) {
3773
- cookie.push("path=" + path18);
3772
+ if (utils_default.isString(path19)) {
3773
+ cookie.push("path=" + path19);
3774
3774
  }
3775
3775
  if (utils_default.isString(domain)) {
3776
3776
  cookie.push("domain=" + domain);
@@ -5978,7 +5978,7 @@ var import_chalk26 = __toESM(require("chalk"));
5978
5978
  var import_figlet5 = __toESM(require("figlet"));
5979
5979
 
5980
5980
  // package.json
5981
- var version = "2.0.9-beta.2";
5981
+ var version = "2.0.10-beta.1";
5982
5982
 
5983
5983
  // bin/upload.ts
5984
5984
  var import_path7 = __toESM(require("path"));
@@ -6089,6 +6089,8 @@ var import_fs2 = __toESM(require("fs"));
6089
6089
  var import_path4 = __toESM(require("path"));
6090
6090
  var import_child_process2 = require("child_process");
6091
6091
  var REQUEST_TIMEOUT_MS = 1500;
6092
+ var TRACK_VALUE_LIMIT = 200;
6093
+ var TRACK_REASON_LIMIT = 255;
6092
6094
  var DEFAULT_GATEWAY = "https://pinme.dev";
6093
6095
  var DEFAULT_PRODUCT = "pinme-cli";
6094
6096
  var ACTION_OVERRIDES = {
@@ -6106,6 +6108,12 @@ var ACTION_OVERRIDES = {
6106
6108
  upload_history_cleared: "click",
6107
6109
  upload_history_failed: "fail"
6108
6110
  };
6111
+ var EV_OVERRIDES = {
6112
+ upload_success: "upload",
6113
+ upload_failed: "upload",
6114
+ project_save_success: "project_save",
6115
+ project_save_failed: "project_save"
6116
+ };
6109
6117
  var TRACK_CHILD_SCRIPT = `
6110
6118
  const rawUrl = process.argv[1];
6111
6119
  if (!rawUrl) process.exit(0);
@@ -6132,11 +6140,11 @@ function trimTrailingSlash2(value) {
6132
6140
  function shouldDisableTracking() {
6133
6141
  return process.env.PINME_TRACKING_DISABLED === "1" || process.env.DO_NOT_TRACK === "1";
6134
6142
  }
6135
- function sanitizeTrackValue(value) {
6143
+ function sanitizeTrackValue(value, maxLength = TRACK_VALUE_LIMIT) {
6136
6144
  if (value === void 0 || value === null) {
6137
6145
  return void 0;
6138
6146
  }
6139
- return String(value).trim().slice(0, 200);
6147
+ return String(value).trim().slice(0, maxLength);
6140
6148
  }
6141
6149
  function getTrackErrorReason(error) {
6142
6150
  var _a2, _b, _c, _d, _e;
@@ -6171,6 +6179,12 @@ function resolveTrackAction(event, data = {}) {
6171
6179
  }
6172
6180
  return "view";
6173
6181
  }
6182
+ function resolveTrackEvent(event) {
6183
+ return EV_OVERRIDES[event] || event;
6184
+ }
6185
+ function resolveTrackReason(data) {
6186
+ return sanitizeTrackValue(data.re || data.reason, TRACK_REASON_LIMIT);
6187
+ }
6174
6188
  var cachedProjectContext = null;
6175
6189
  var cachedProjectContextCwd = null;
6176
6190
  function resolveProjectContext() {
@@ -6248,6 +6262,7 @@ var Tracker = class _Tracker {
6248
6262
  buildPayload(event, page, data) {
6249
6263
  const projectContext = resolveProjectContext();
6250
6264
  const action = resolveTrackAction(event, data);
6265
+ const ev = resolveTrackEvent(event);
6251
6266
  const payload = {
6252
6267
  ...data,
6253
6268
  u: getUid(),
@@ -6255,9 +6270,10 @@ var Tracker = class _Tracker {
6255
6270
  pd: this.product,
6256
6271
  p: page,
6257
6272
  a: action,
6258
- ev: event,
6273
+ ev,
6259
6274
  event,
6260
- project_name: projectContext.projectName,
6275
+ re: resolveTrackReason(data),
6276
+ project_name: projectContext.projectName || data.project_name,
6261
6277
  project_dir: projectContext.projectDir,
6262
6278
  cli_version: version,
6263
6279
  node_version: process.version,
@@ -6266,7 +6282,10 @@ var Tracker = class _Tracker {
6266
6282
  };
6267
6283
  const filtered = {};
6268
6284
  for (const [key, value] of Object.entries(payload)) {
6269
- const normalized = sanitizeTrackValue(value);
6285
+ const normalized = sanitizeTrackValue(
6286
+ value,
6287
+ key === "re" ? TRACK_REASON_LIMIT : TRACK_VALUE_LIMIT
6288
+ );
6270
6289
  if (normalized) {
6271
6290
  filtered[key] = normalized;
6272
6291
  }
@@ -9035,6 +9054,7 @@ async function loginCmd(options = {}) {
9035
9054
  void tracker_default.trackEvent(TRACK_EVENTS.cliLoginSuccess, TRACK_PAGES.login, {
9036
9055
  a: resolveTrackAction2(TRACK_EVENTS.cliLoginSuccess),
9037
9056
  env,
9057
+ source: "cli",
9038
9058
  has_token_address: true,
9039
9059
  merged_anonymous_history: ok
9040
9060
  });
@@ -9043,6 +9063,7 @@ async function loginCmd(options = {}) {
9043
9063
  void tracker_default.trackEvent(TRACK_EVENTS.cliLoginFailed, TRACK_PAGES.login, {
9044
9064
  a: resolveTrackAction2(TRACK_EVENTS.cliLoginFailed),
9045
9065
  env,
9066
+ source: "cli",
9046
9067
  reason: getTrackErrorReason(e)
9047
9068
  });
9048
9069
  console.log(import_chalk18.default.red(`
@@ -9053,8 +9074,8 @@ Login failed: ${(e == null ? void 0 : e.message) || e}`));
9053
9074
 
9054
9075
  // bin/create.ts
9055
9076
  var import_chalk20 = __toESM(require("chalk"));
9056
- var import_fs_extra6 = __toESM(require("fs-extra"));
9057
- var import_path12 = __toESM(require("path"));
9077
+ var import_fs_extra7 = __toESM(require("fs-extra"));
9078
+ var import_path13 = __toESM(require("path"));
9058
9079
  var import_inquirer8 = __toESM(require("inquirer"));
9059
9080
  init_axios2();
9060
9081
  var import_adm_zip = __toESM(require("adm-zip"));
@@ -9069,8 +9090,10 @@ var import_chalk19 = __toESM(require("chalk"));
9069
9090
  var import_child_process3 = require("child_process");
9070
9091
  var INSTALL_TIMEOUT_MS = 10 * 60 * 1e3;
9071
9092
  var SLOW_INSTALL_NOTICE_MS = 60 * 1e3;
9093
+ var STALE_LOG_ONLY_MARKER_MS = 90 * 1e3;
9072
9094
  var INSTALL_LOG_FILE = ".pinme-install.log";
9073
9095
  var INSTALL_EXITCODE_FILE = ".pinme-install.exitcode";
9096
+ var INSTALL_PID_FILE = ".pinme-install.pid";
9074
9097
  function makeTempCacheDir() {
9075
9098
  return import_fs_extra5.default.mkdtempSync(import_path11.default.join(import_os5.default.tmpdir(), "pinme-npm-cache-"));
9076
9099
  }
@@ -9115,7 +9138,9 @@ function startBackgroundInstall(cwd) {
9115
9138
  const args = getInstallArgs(script, cacheDir);
9116
9139
  const logPath = import_path11.default.join(cwd, INSTALL_LOG_FILE);
9117
9140
  const exitCodePath = import_path11.default.join(cwd, INSTALL_EXITCODE_FILE);
9141
+ const pidPath = import_path11.default.join(cwd, INSTALL_PID_FILE);
9118
9142
  import_fs_extra5.default.removeSync(exitCodePath);
9143
+ import_fs_extra5.default.removeSync(pidPath);
9119
9144
  import_fs_extra5.default.writeFileSync(logPath, `[pinme] ${(/* @__PURE__ */ new Date()).toISOString()} starting "npm ${script}"
9120
9145
  `);
9121
9146
  const npmCmd = process.platform === "win32" ? "npm" : getNpmCommand();
@@ -9150,11 +9175,42 @@ function startBackgroundInstall(cwd) {
9150
9175
  }
9151
9176
  });
9152
9177
  child.unref();
9178
+ if (child.pid) {
9179
+ import_fs_extra5.default.writeFileSync(pidPath, String(child.pid));
9180
+ }
9153
9181
  return { logPath };
9154
9182
  }
9183
+ function isProcessAlive(pid) {
9184
+ try {
9185
+ process.kill(pid, 0);
9186
+ return true;
9187
+ } catch (error) {
9188
+ return (error == null ? void 0 : error.code) === "EPERM";
9189
+ }
9190
+ }
9191
+ function readPidFile(pidPath) {
9192
+ if (!import_fs_extra5.default.existsSync(pidPath)) {
9193
+ return null;
9194
+ }
9195
+ const raw = import_fs_extra5.default.readFileSync(pidPath, "utf-8").trim();
9196
+ const pid = Number.parseInt(raw, 10);
9197
+ if (!Number.isFinite(pid) || pid <= 0) {
9198
+ return null;
9199
+ }
9200
+ return pid;
9201
+ }
9202
+ function isStaleLogOnlyMarker(logPath) {
9203
+ try {
9204
+ const ageMs = Date.now() - import_fs_extra5.default.statSync(logPath).mtimeMs;
9205
+ return ageMs > STALE_LOG_ONLY_MARKER_MS;
9206
+ } catch {
9207
+ return false;
9208
+ }
9209
+ }
9155
9210
  function readBackgroundInstallStatus(cwd) {
9156
9211
  const logPath = import_path11.default.join(cwd, INSTALL_LOG_FILE);
9157
9212
  const exitCodePath = import_path11.default.join(cwd, INSTALL_EXITCODE_FILE);
9213
+ const pidPath = import_path11.default.join(cwd, INSTALL_PID_FILE);
9158
9214
  if (import_fs_extra5.default.existsSync(exitCodePath)) {
9159
9215
  const raw = import_fs_extra5.default.readFileSync(exitCodePath, "utf-8").trim();
9160
9216
  const code = Number.parseInt(raw, 10);
@@ -9164,6 +9220,17 @@ function readBackgroundInstallStatus(cwd) {
9164
9220
  return { status: code === 0 ? "success" : "failed", exitCode: code, logPath };
9165
9221
  }
9166
9222
  if (import_fs_extra5.default.existsSync(logPath)) {
9223
+ const pid = readPidFile(pidPath);
9224
+ if (pid !== null) {
9225
+ return {
9226
+ status: isProcessAlive(pid) ? "running" : "interrupted",
9227
+ exitCode: null,
9228
+ logPath
9229
+ };
9230
+ }
9231
+ if (isStaleLogOnlyMarker(logPath)) {
9232
+ return { status: "interrupted", exitCode: null, logPath };
9233
+ }
9167
9234
  return { status: "running", exitCode: null, logPath };
9168
9235
  }
9169
9236
  return { status: "idle", exitCode: null, logPath };
@@ -9180,8 +9247,172 @@ function readBackgroundInstallLogTail(cwd, maxChars = 1500) {
9180
9247
  // bin/create.ts
9181
9248
  init_cliError();
9182
9249
  init_config();
9250
+
9251
+ // bin/utils/prebuiltDistConfig.ts
9252
+ var import_fs_extra6 = __toESM(require("fs-extra"));
9253
+ var import_path12 = __toESM(require("path"));
9254
+ init_cliError();
9255
+ var PLACEHOLDERS = {
9256
+ apiUrl: "__PINME_VITE_API_URL__",
9257
+ authApiKey: "__PINME_AUTH_API_KEY__",
9258
+ authDomain: "__PINME_AUTH_DOMAIN__",
9259
+ authProjectId: "__PINME_AUTH_PROJECT_ID__",
9260
+ tenantId: "__PINME_TENANT_ID__"
9261
+ };
9262
+ var PATCHABLE_EXTENSIONS = /* @__PURE__ */ new Set([
9263
+ ".html",
9264
+ ".js",
9265
+ ".css",
9266
+ ".json",
9267
+ ".map"
9268
+ ]);
9269
+ function toReplacementValue(value) {
9270
+ if (value === void 0 || value === null) {
9271
+ return "";
9272
+ }
9273
+ return String(value);
9274
+ }
9275
+ function countOccurrences(content, needle) {
9276
+ if (!needle) {
9277
+ return 0;
9278
+ }
9279
+ return content.split(needle).length - 1;
9280
+ }
9281
+ function listPatchableFiles(dir) {
9282
+ const result = [];
9283
+ for (const entry of import_fs_extra6.default.readdirSync(dir, { withFileTypes: true })) {
9284
+ const entryPath = import_path12.default.join(dir, entry.name);
9285
+ if (entry.isDirectory()) {
9286
+ result.push(...listPatchableFiles(entryPath));
9287
+ continue;
9288
+ }
9289
+ if (entry.isFile() && PATCHABLE_EXTENSIONS.has(import_path12.default.extname(entry.name))) {
9290
+ result.push(entryPath);
9291
+ }
9292
+ }
9293
+ return result;
9294
+ }
9295
+ function patchPrebuiltFrontendDist(frontendDistDir, workerData) {
9296
+ if (!workerData.api_domain) {
9297
+ throw createConfigError("`api_domain` is missing from project creation response.", [
9298
+ "Retry `pinme create`.",
9299
+ "If the problem persists, check the `/create_worker` API response."
9300
+ ]);
9301
+ }
9302
+ if (!import_fs_extra6.default.existsSync(frontendDistDir)) {
9303
+ throw createConfigError("Prebuilt frontend output not found: `frontend/dist/`.", [
9304
+ "The template should ship a prebuilt `frontend/dist/`.",
9305
+ "Once dependencies finish installing, run `npm run build:frontend` in the project, then `pinme save`."
9306
+ ]);
9307
+ }
9308
+ const authConfig = workerData.public_client_config ?? {};
9309
+ const replacements = /* @__PURE__ */ new Map([
9310
+ [PLACEHOLDERS.apiUrl, workerData.api_domain],
9311
+ [PLACEHOLDERS.authApiKey, toReplacementValue(authConfig.auth_api_key)],
9312
+ [PLACEHOLDERS.authDomain, toReplacementValue(authConfig.auth_domain)],
9313
+ [PLACEHOLDERS.authProjectId, toReplacementValue(authConfig.auth_project_id)],
9314
+ [PLACEHOLDERS.tenantId, toReplacementValue(authConfig.tenant_id)]
9315
+ ]);
9316
+ const files = listPatchableFiles(frontendDistDir);
9317
+ let filesPatched = 0;
9318
+ let apiUrlReplacements = 0;
9319
+ let authReplacements = 0;
9320
+ for (const filePath of files) {
9321
+ const content = import_fs_extra6.default.readFileSync(filePath, "utf8");
9322
+ let nextContent = content;
9323
+ for (const [placeholder, replacement] of replacements) {
9324
+ const count = countOccurrences(nextContent, placeholder);
9325
+ if (count === 0) {
9326
+ continue;
9327
+ }
9328
+ if (placeholder === PLACEHOLDERS.apiUrl) {
9329
+ apiUrlReplacements += count;
9330
+ } else {
9331
+ authReplacements += count;
9332
+ }
9333
+ nextContent = nextContent.split(placeholder).join(replacement);
9334
+ }
9335
+ if (nextContent !== content) {
9336
+ import_fs_extra6.default.writeFileSync(filePath, nextContent);
9337
+ filesPatched += 1;
9338
+ }
9339
+ }
9340
+ if (apiUrlReplacements === 0) {
9341
+ throw createConfigError("Prebuilt frontend dist is missing required Pinme config placeholder.", [
9342
+ "Expected to find `__PINME_VITE_API_URL__` in `frontend/dist`.",
9343
+ "Rebuild the template frontend from placeholder-enabled source before publishing the template.",
9344
+ "After dependencies finish installing, users can recover by running `npm run build:frontend` and `pinme save`."
9345
+ ]);
9346
+ }
9347
+ return {
9348
+ filesScanned: files.length,
9349
+ filesPatched,
9350
+ apiUrlReplacements,
9351
+ authReplacements
9352
+ };
9353
+ }
9354
+
9355
+ // bin/utils/workerMetadata.ts
9356
+ init_cliError();
9357
+ function parseWorkerMetadata(metadataContent) {
9358
+ try {
9359
+ return JSON.parse(metadataContent);
9360
+ } catch (error) {
9361
+ throw createConfigError("Worker metadata must be valid JSON.", [
9362
+ "The `/create_worker` API should return JSON metadata for backend deployment.",
9363
+ "Retry `pinme create`."
9364
+ ]);
9365
+ }
9366
+ }
9367
+ function isRealBindingValue(value) {
9368
+ if (typeof value !== "string") {
9369
+ return false;
9370
+ }
9371
+ const trimmed = value.trim();
9372
+ return Boolean(trimmed) && trimmed !== "xxx" && trimmed !== "project_name" && !trimmed.startsWith("__PINME_");
9373
+ }
9374
+ function findBinding(metadata, name) {
9375
+ var _a2;
9376
+ return (_a2 = metadata.bindings) == null ? void 0 : _a2.find((binding) => binding.name === name);
9377
+ }
9378
+ function validateWorkerMetadataForCreate(metadataContent, projectName) {
9379
+ const metadata = parseWorkerMetadata(metadataContent);
9380
+ const apiKeyBinding = findBinding(metadata, "API_KEY");
9381
+ const projectNameBinding = findBinding(metadata, "PROJECT_NAME");
9382
+ if (!isRealBindingValue(apiKeyBinding == null ? void 0 : apiKeyBinding.text)) {
9383
+ throw createConfigError("Worker metadata is missing a real API_KEY binding.", [
9384
+ "The template metadata contains placeholder values and cannot be deployed as-is.",
9385
+ "Retry `pinme create` so Pinme can fetch fresh worker metadata from `/create_worker`."
9386
+ ]);
9387
+ }
9388
+ if ((projectNameBinding == null ? void 0 : projectNameBinding.text) !== projectName) {
9389
+ throw createConfigError("Worker metadata is missing a matching PROJECT_NAME binding.", [
9390
+ `Expected PROJECT_NAME binding text to be \`${projectName}\`.`,
9391
+ "Retry `pinme create` so Pinme can fetch fresh worker metadata from `/create_worker`."
9392
+ ]);
9393
+ }
9394
+ if (metadata.project_name && metadata.project_name !== projectName) {
9395
+ throw createConfigError("Worker metadata project_name does not match the created project.", [
9396
+ `Expected metadata project_name to be \`${projectName}\`.`,
9397
+ `Received metadata project_name \`${metadata.project_name}\`.`
9398
+ ]);
9399
+ }
9400
+ }
9401
+ function getValidatedWorkerMetadataContent(metadata, projectName) {
9402
+ if (!metadata) {
9403
+ throw createConfigError("Worker metadata is missing from project creation response.", [
9404
+ "The `/create_worker` API should return backend metadata before the prebuilt worker is deployed.",
9405
+ "Retry `pinme create`."
9406
+ ]);
9407
+ }
9408
+ const metadataContent = typeof metadata === "string" ? metadata : JSON.stringify(metadata, null, 2);
9409
+ validateWorkerMetadataForCreate(metadataContent, projectName);
9410
+ return metadataContent;
9411
+ }
9412
+
9413
+ // bin/create.ts
9183
9414
  var PROJECT_DIR = process.cwd();
9184
- var TEMPLATE_BRANCH = "main";
9415
+ var TEMPLATE_BRANCH = "feat/dev";
9185
9416
  var TEMPLATE_REPO = "glitternetwork/pinme-worker-template";
9186
9417
  var TEMPLATE_REPO_NAME = TEMPLATE_REPO.split("/").pop() || "pinme-worker-template";
9187
9418
  function getTemplateZipUrl(branch) {
@@ -9208,7 +9439,7 @@ ${configExport}
9208
9439
  `;
9209
9440
  }
9210
9441
  function resolveExtractedTemplateDir(extractDir) {
9211
- const entries = import_fs_extra6.default.readdirSync(extractDir, { withFileTypes: true });
9442
+ const entries = import_fs_extra7.default.readdirSync(extractDir, { withFileTypes: true });
9212
9443
  const templateDir = entries.find((entry) => entry.isDirectory() && entry.name.startsWith(`${TEMPLATE_REPO_NAME}-`));
9213
9444
  if (!templateDir) {
9214
9445
  throw createConfigError("Downloaded template archive structure is invalid.", [
@@ -9216,10 +9447,10 @@ function resolveExtractedTemplateDir(extractDir) {
9216
9447
  `Template branch: ${TEMPLATE_BRANCH}`
9217
9448
  ]);
9218
9449
  }
9219
- return import_path12.default.join(extractDir, templateDir.name);
9450
+ return import_path13.default.join(extractDir, templateDir.name);
9220
9451
  }
9221
9452
  function updateFrontendUrlInConfig(configPath, frontendUrl) {
9222
- let config = import_fs_extra6.default.readFileSync(configPath, "utf-8");
9453
+ let config = import_fs_extra7.default.readFileSync(configPath, "utf-8");
9223
9454
  if (config.includes("frontend_url")) {
9224
9455
  config = config.replace(
9225
9456
  /frontend_url\s*=\s*"[^"]*"/,
@@ -9232,7 +9463,7 @@ function updateFrontendUrlInConfig(configPath, frontendUrl) {
9232
9463
  `
9233
9464
  );
9234
9465
  }
9235
- import_fs_extra6.default.writeFileSync(configPath, config);
9466
+ import_fs_extra7.default.writeFileSync(configPath, config);
9236
9467
  }
9237
9468
  function getProjectManagementUrl(projectName) {
9238
9469
  return `${APP_CONFIG.projectPeviewUrl}${projectName}`;
@@ -9265,8 +9496,8 @@ async function createCmd(options) {
9265
9496
  ]);
9266
9497
  projectName = answers.projectName;
9267
9498
  }
9268
- const targetDir = import_path12.default.join(PROJECT_DIR, projectName);
9269
- if (import_fs_extra6.default.existsSync(targetDir) && !options.force) {
9499
+ const targetDir = import_path13.default.join(PROJECT_DIR, projectName);
9500
+ if (import_fs_extra7.default.existsSync(targetDir) && !options.force) {
9270
9501
  console.log(import_chalk20.default.yellow(`
9271
9502
  Directory "${projectName}" already exists.`));
9272
9503
  const answers = await import_inquirer8.default.prompt([
@@ -9281,7 +9512,7 @@ Directory "${projectName}" already exists.`));
9281
9512
  console.log(import_chalk20.default.gray("Cancelled."));
9282
9513
  process.exit(0);
9283
9514
  }
9284
- import_fs_extra6.default.removeSync(targetDir);
9515
+ import_fs_extra7.default.removeSync(targetDir);
9285
9516
  }
9286
9517
  console.log(import_chalk20.default.blue("\n1. Creating worker and database..."));
9287
9518
  const apiUrl = getPinmeApiUrl("/create_worker");
@@ -9316,8 +9547,8 @@ Directory "${projectName}" already exists.`));
9316
9547
  ]);
9317
9548
  }
9318
9549
  console.log(import_chalk20.default.blue("\n2. Downloading template from repository..."));
9319
- const zipPath = import_path12.default.join(PROJECT_DIR, "template.zip");
9320
- const extractDir = import_path12.default.join(PROJECT_DIR, `.pinme-template-${Date.now()}`);
9550
+ const zipPath = import_path13.default.join(PROJECT_DIR, "template.zip");
9551
+ const extractDir = import_path13.default.join(PROJECT_DIR, `.pinme-template-${Date.now()}`);
9321
9552
  const templateZipUrl = getTemplateZipUrl(TEMPLATE_BRANCH);
9322
9553
  let downloadSuccess = false;
9323
9554
  console.log(import_chalk20.default.gray(` Template branch: ${TEMPLATE_BRANCH}`));
@@ -9327,14 +9558,14 @@ Directory "${projectName}" already exists.`));
9327
9558
  (0, import_child_process4.execSync)(`curl -L --retry 3 --retry-delay 2 -o "${zipPath}" "${templateZipUrl}"`, {
9328
9559
  stdio: "inherit"
9329
9560
  });
9330
- if (!import_fs_extra6.default.existsSync(zipPath) || import_fs_extra6.default.statSync(zipPath).size < 100) {
9561
+ if (!import_fs_extra7.default.existsSync(zipPath) || import_fs_extra7.default.statSync(zipPath).size < 100) {
9331
9562
  throw new Error("Downloaded file is too small or empty");
9332
9563
  }
9333
9564
  downloadSuccess = true;
9334
9565
  } catch (downloadError) {
9335
9566
  console.log(import_chalk20.default.yellow(` Attempt ${attempt} failed: ${downloadError.message}`));
9336
- if (import_fs_extra6.default.existsSync(zipPath)) {
9337
- import_fs_extra6.default.removeSync(zipPath);
9567
+ if (import_fs_extra7.default.existsSync(zipPath)) {
9568
+ import_fs_extra7.default.removeSync(zipPath);
9338
9569
  }
9339
9570
  if (attempt === 3) {
9340
9571
  throw new Error(`Failed to download template after 3 attempts: ${downloadError.message}`);
@@ -9342,22 +9573,22 @@ Directory "${projectName}" already exists.`));
9342
9573
  }
9343
9574
  }
9344
9575
  try {
9345
- import_fs_extra6.default.ensureDirSync(extractDir);
9576
+ import_fs_extra7.default.ensureDirSync(extractDir);
9346
9577
  const templateZip = new import_adm_zip.default(zipPath);
9347
9578
  templateZip.extractAllTo(extractDir, true);
9348
9579
  const subDir = resolveExtractedTemplateDir(extractDir);
9349
- import_fs_extra6.default.copySync(subDir, targetDir);
9350
- import_fs_extra6.default.removeSync(zipPath);
9351
- import_fs_extra6.default.removeSync(extractDir);
9352
- const nodeModulesPath = import_path12.default.join(targetDir, "node_modules");
9353
- if (import_fs_extra6.default.existsSync(nodeModulesPath)) {
9580
+ import_fs_extra7.default.copySync(subDir, targetDir);
9581
+ import_fs_extra7.default.removeSync(zipPath);
9582
+ import_fs_extra7.default.removeSync(extractDir);
9583
+ const nodeModulesPath = import_path13.default.join(targetDir, "node_modules");
9584
+ if (import_fs_extra7.default.existsSync(nodeModulesPath)) {
9354
9585
  console.log(import_chalk20.default.gray(" Removing existing node_modules..."));
9355
- import_fs_extra6.default.removeSync(nodeModulesPath);
9586
+ import_fs_extra7.default.removeSync(nodeModulesPath);
9356
9587
  }
9357
- const frontendNodeModules = import_path12.default.join(targetDir, "frontend", "node_modules");
9358
- const backendNodeModules = import_path12.default.join(targetDir, "backend", "node_modules");
9359
- if (import_fs_extra6.default.existsSync(frontendNodeModules)) import_fs_extra6.default.removeSync(frontendNodeModules);
9360
- if (import_fs_extra6.default.existsSync(backendNodeModules)) import_fs_extra6.default.removeSync(backendNodeModules);
9588
+ const frontendNodeModules = import_path13.default.join(targetDir, "frontend", "node_modules");
9589
+ const backendNodeModules = import_path13.default.join(targetDir, "backend", "node_modules");
9590
+ if (import_fs_extra7.default.existsSync(frontendNodeModules)) import_fs_extra7.default.removeSync(frontendNodeModules);
9591
+ if (import_fs_extra7.default.existsSync(backendNodeModules)) import_fs_extra7.default.removeSync(backendNodeModules);
9361
9592
  console.log(import_chalk20.default.green(` Template downloaded to: ${targetDir}`));
9362
9593
  } catch (error) {
9363
9594
  throw createCommandError("template extraction", `extract "${zipPath}" to "${extractDir}"`, error, [
@@ -9365,58 +9596,61 @@ Directory "${projectName}" already exists.`));
9365
9596
  ]);
9366
9597
  }
9367
9598
  console.log(import_chalk20.default.blue("\n3. Updating configuration..."));
9368
- const configPath = import_path12.default.join(targetDir, "pinme.toml");
9369
- const config = import_fs_extra6.default.readFileSync(configPath, "utf-8");
9599
+ const configPath = import_path13.default.join(targetDir, "pinme.toml");
9600
+ const config = import_fs_extra7.default.readFileSync(configPath, "utf-8");
9370
9601
  let updatedConfig = config.replace(
9371
9602
  /project_name = ".*"/,
9372
9603
  `project_name = "${workerData.project_name}"`
9373
9604
  );
9374
- import_fs_extra6.default.writeFileSync(configPath, updatedConfig);
9605
+ import_fs_extra7.default.writeFileSync(configPath, updatedConfig);
9375
9606
  console.log(import_chalk20.default.green(` Updated pinme.toml`));
9376
9607
  console.log(import_chalk20.default.gray(` metadata: ${workerData.metadata}`));
9377
- const backendDir = import_path12.default.join(targetDir, "backend");
9378
- if (import_fs_extra6.default.existsSync(backendDir) && workerData.metadata) {
9379
- const metadataContent = typeof workerData.metadata === "string" ? workerData.metadata : JSON.stringify(workerData.metadata, null, 2);
9380
- import_fs_extra6.default.writeFileSync(
9381
- import_path12.default.join(backendDir, "metadata.json"),
9382
- metadataContent
9608
+ const workerMetadataContent = getValidatedWorkerMetadataContent(
9609
+ workerData.metadata,
9610
+ workerData.project_name
9611
+ );
9612
+ const backendDir = import_path13.default.join(targetDir, "backend");
9613
+ if (import_fs_extra7.default.existsSync(backendDir)) {
9614
+ import_fs_extra7.default.writeFileSync(
9615
+ import_path13.default.join(backendDir, "metadata.json"),
9616
+ workerMetadataContent
9383
9617
  );
9384
9618
  console.log(import_chalk20.default.green(` Saved metadata.json`));
9385
9619
  }
9386
- const wranglerPath = import_path12.default.join(backendDir, "wrangler.toml");
9387
- if (import_fs_extra6.default.existsSync(wranglerPath) && workerData.api_key) {
9388
- let wranglerContent = import_fs_extra6.default.readFileSync(wranglerPath, "utf-8");
9620
+ const wranglerPath = import_path13.default.join(backendDir, "wrangler.toml");
9621
+ if (import_fs_extra7.default.existsSync(wranglerPath) && workerData.api_key) {
9622
+ let wranglerContent = import_fs_extra7.default.readFileSync(wranglerPath, "utf-8");
9389
9623
  wranglerContent = wranglerContent.replace(
9390
9624
  /^name = ".*"$/m,
9391
9625
  `name = "${workerData.project_name}"`
9392
9626
  );
9393
- import_fs_extra6.default.writeFileSync(wranglerPath, wranglerContent);
9627
+ import_fs_extra7.default.writeFileSync(wranglerPath, wranglerContent);
9394
9628
  console.log(import_chalk20.default.green(` Updated backend/wrangler.toml API_KEY`));
9395
9629
  }
9396
- const frontendConfigPath = import_path12.default.join(targetDir, "frontend", "src", "utils", "config.ts");
9630
+ const frontendConfigPath = import_path13.default.join(targetDir, "frontend", "src", "utils", "config.ts");
9397
9631
  if (workerData.public_client_config) {
9398
- const frontendConfigContent = import_fs_extra6.default.existsSync(frontendConfigPath) ? import_fs_extra6.default.readFileSync(frontendConfigPath, "utf-8") : "";
9399
- import_fs_extra6.default.ensureDirSync(import_path12.default.dirname(frontendConfigPath));
9400
- import_fs_extra6.default.writeFileSync(
9632
+ const frontendConfigContent = import_fs_extra7.default.existsSync(frontendConfigPath) ? import_fs_extra7.default.readFileSync(frontendConfigPath, "utf-8") : "";
9633
+ import_fs_extra7.default.ensureDirSync(import_path13.default.dirname(frontendConfigPath));
9634
+ import_fs_extra7.default.writeFileSync(
9401
9635
  frontendConfigPath,
9402
9636
  injectPublicClientConfigIntoFile(frontendConfigContent, workerData.public_client_config)
9403
9637
  );
9404
9638
  console.log(import_chalk20.default.green(` Updated frontend/src/utils/config.ts public_client_config`));
9405
9639
  }
9406
- const envExamplePath = import_path12.default.join(targetDir, "frontend", ".env.example");
9407
- const envPath = import_path12.default.join(targetDir, "frontend", ".env");
9408
- if (import_fs_extra6.default.existsSync(envExamplePath)) {
9409
- let envContent = import_fs_extra6.default.readFileSync(envExamplePath, "utf-8");
9640
+ const envExamplePath = import_path13.default.join(targetDir, "frontend", ".env.example");
9641
+ const envPath = import_path13.default.join(targetDir, "frontend", ".env");
9642
+ if (import_fs_extra7.default.existsSync(envExamplePath)) {
9643
+ let envContent = import_fs_extra7.default.readFileSync(envExamplePath, "utf-8");
9410
9644
  envContent = envContent.replace(/your-project/g, workerData.project_name);
9411
9645
  envContent = envContent.replace(
9412
9646
  /^VITE_API_URL=.*$/m,
9413
9647
  `VITE_API_URL=${workerData.api_domain}`
9414
9648
  );
9415
- import_fs_extra6.default.writeFileSync(envPath, envContent);
9649
+ import_fs_extra7.default.writeFileSync(envPath, envContent);
9416
9650
  console.log(import_chalk20.default.green(` Created frontend/.env file`));
9417
9651
  console.log(import_chalk20.default.gray(` VITE_API_URL: ${workerData.api_domain}`));
9418
9652
  }
9419
- let pinmeConfig = import_fs_extra6.default.readFileSync(configPath, "utf-8");
9653
+ let pinmeConfig = import_fs_extra7.default.readFileSync(configPath, "utf-8");
9420
9654
  if (pinmeConfig.includes("api_url")) {
9421
9655
  pinmeConfig = pinmeConfig.replace(
9422
9656
  /api_url\s*=\s*"[^"]*"/,
@@ -9433,7 +9667,7 @@ Directory "${projectName}" already exists.`));
9433
9667
  }
9434
9668
  pinmeConfig = newLines.join("\n");
9435
9669
  }
9436
- import_fs_extra6.default.writeFileSync(configPath, pinmeConfig);
9670
+ import_fs_extra7.default.writeFileSync(configPath, pinmeConfig);
9437
9671
  console.log(import_chalk20.default.green(` Updated pinme.toml with api_url`));
9438
9672
  console.log(import_chalk20.default.blue("\n4. Installing dependencies in the background..."));
9439
9673
  try {
@@ -9446,27 +9680,27 @@ Directory "${projectName}" already exists.`));
9446
9680
  console.log(import_chalk20.default.yellow(" Run `npm install` inside the project before `pinme save`."));
9447
9681
  }
9448
9682
  console.log(import_chalk20.default.blue("\n5. Preparing backend worker..."));
9449
- const distWorkerDir = import_path12.default.join(targetDir, "dist-worker");
9450
- const workerJsPath = import_path12.default.join(distWorkerDir, "worker.js");
9451
- if (!import_fs_extra6.default.existsSync(distWorkerDir) || !import_fs_extra6.default.existsSync(workerJsPath)) {
9683
+ const distWorkerDir = import_path13.default.join(targetDir, "dist-worker");
9684
+ const workerJsPath = import_path13.default.join(distWorkerDir, "worker.js");
9685
+ if (!import_fs_extra7.default.existsSync(distWorkerDir) || !import_fs_extra7.default.existsSync(workerJsPath)) {
9452
9686
  throw createConfigError("Prebuilt worker output not found: `dist-worker/worker.js`.", [
9453
9687
  "The template should ship a prebuilt `dist-worker/`.",
9454
9688
  "Once dependencies finish installing, run `npm run build:worker` in the project, then `pinme save`."
9455
9689
  ]);
9456
9690
  }
9457
9691
  const modulePaths = [];
9458
- const files = import_fs_extra6.default.readdirSync(distWorkerDir);
9692
+ const files = import_fs_extra7.default.readdirSync(distWorkerDir);
9459
9693
  for (const file of files) {
9460
9694
  if (file.endsWith(".js") && file !== "worker.js") {
9461
- modulePaths.push(import_path12.default.join(distWorkerDir, file));
9695
+ modulePaths.push(import_path13.default.join(distWorkerDir, file));
9462
9696
  }
9463
9697
  }
9464
- const sqlDir = import_path12.default.join(targetDir, "db");
9698
+ const sqlDir = import_path13.default.join(targetDir, "db");
9465
9699
  const sqlFiles = [];
9466
- if (import_fs_extra6.default.existsSync(sqlDir)) {
9467
- const sqlFileNames = import_fs_extra6.default.readdirSync(sqlDir).filter((f) => f.endsWith(".sql")).sort();
9700
+ if (import_fs_extra7.default.existsSync(sqlDir)) {
9701
+ const sqlFileNames = import_fs_extra7.default.readdirSync(sqlDir).filter((f) => f.endsWith(".sql")).sort();
9468
9702
  for (const filename of sqlFileNames) {
9469
- sqlFiles.push(import_path12.default.join(sqlDir, filename));
9703
+ sqlFiles.push(import_path13.default.join(sqlDir, filename));
9470
9704
  console.log(import_chalk20.default.gray(` Including SQL: ${filename}`));
9471
9705
  }
9472
9706
  }
@@ -9477,24 +9711,23 @@ Directory "${projectName}" already exists.`));
9477
9711
  const FormData4 = (await import("formdata-node")).FormData;
9478
9712
  const Blob2 = (await import("formdata-node")).Blob;
9479
9713
  const formData = new FormData4();
9480
- const metadataContent = typeof workerData.metadata === "string" ? workerData.metadata : JSON.stringify(workerData.metadata, null, 2);
9481
- formData.append("metadata", new Blob2([metadataContent], {
9714
+ formData.append("metadata", new Blob2([workerMetadataContent], {
9482
9715
  type: "application/json"
9483
9716
  }), "metadata.json");
9484
- const workerCode = import_fs_extra6.default.readFileSync(workerJsPath, "utf-8");
9717
+ const workerCode = import_fs_extra7.default.readFileSync(workerJsPath, "utf-8");
9485
9718
  formData.append("worker.js", new Blob2([workerCode], {
9486
9719
  type: "application/javascript+module"
9487
9720
  }), "worker.js");
9488
9721
  for (const modulePath of modulePaths) {
9489
- const filename = import_path12.default.basename(modulePath);
9490
- const content = import_fs_extra6.default.readFileSync(modulePath, "utf-8");
9722
+ const filename = import_path13.default.basename(modulePath);
9723
+ const content = import_fs_extra7.default.readFileSync(modulePath, "utf-8");
9491
9724
  formData.append(filename, new Blob2([content], {
9492
9725
  type: "application/javascript+module"
9493
9726
  }), filename);
9494
9727
  }
9495
9728
  for (const sqlFile of sqlFiles) {
9496
- const filename = import_path12.default.basename(sqlFile);
9497
- const content = import_fs_extra6.default.readFileSync(sqlFile, "utf-8");
9729
+ const filename = import_path13.default.basename(sqlFile);
9730
+ const content = import_fs_extra7.default.readFileSync(sqlFile, "utf-8");
9498
9731
  formData.append("sql_file", new Blob2([content], {
9499
9732
  type: "application/sql"
9500
9733
  }), filename);
@@ -9527,15 +9760,20 @@ Directory "${projectName}" already exists.`));
9527
9760
  ]);
9528
9761
  }
9529
9762
  console.log(import_chalk20.default.blue("\n7. Preparing frontend..."));
9530
- const frontendDir = import_path12.default.join(targetDir, "frontend");
9531
- const frontendDistDir = import_path12.default.join(frontendDir, "dist");
9532
- if (import_fs_extra6.default.existsSync(frontendDir)) {
9533
- if (!import_fs_extra6.default.existsSync(frontendDistDir)) {
9763
+ const frontendDir = import_path13.default.join(targetDir, "frontend");
9764
+ const frontendDistDir = import_path13.default.join(frontendDir, "dist");
9765
+ if (import_fs_extra7.default.existsSync(frontendDir)) {
9766
+ if (!import_fs_extra7.default.existsSync(frontendDistDir)) {
9534
9767
  throw createConfigError("Prebuilt frontend output not found: `frontend/dist/`.", [
9535
9768
  "The template should ship a prebuilt `frontend/dist/`.",
9536
9769
  "Once dependencies finish installing, run `npm run build:frontend` in the project, then `pinme save`."
9537
9770
  ]);
9538
9771
  }
9772
+ const patchResult = patchPrebuiltFrontendDist(frontendDistDir, workerData);
9773
+ console.log(import_chalk20.default.green(" Patched prebuilt frontend dist config"));
9774
+ console.log(import_chalk20.default.gray(
9775
+ ` Replacements: API URL ${patchResult.apiUrlReplacements}, auth ${patchResult.authReplacements}`
9776
+ ));
9539
9777
  console.log(import_chalk20.default.blue(" Uploading to IPFS..."));
9540
9778
  try {
9541
9779
  const uploadResult = await uploadPath(frontendDistDir, {
@@ -9545,7 +9783,7 @@ Directory "${projectName}" already exists.`));
9545
9783
  });
9546
9784
  printHighlightedUrl("Frontend URL", uploadResult.publicUrl, "primary");
9547
9785
  updateFrontendUrlInConfig(
9548
- import_path12.default.join(targetDir, "pinme.toml"),
9786
+ import_path13.default.join(targetDir, "pinme.toml"),
9549
9787
  uploadResult.publicUrl
9550
9788
  );
9551
9789
  console.log(import_chalk20.default.green(" Updated pinme.toml with frontend URL"));
@@ -9598,8 +9836,8 @@ Next steps:`));
9598
9836
  // bin/save.ts
9599
9837
  var import_chalk21 = __toESM(require("chalk"));
9600
9838
  var import_ora3 = __toESM(require("ora"));
9601
- var import_fs_extra7 = __toESM(require("fs-extra"));
9602
- var import_path13 = __toESM(require("path"));
9839
+ var import_fs_extra8 = __toESM(require("fs-extra"));
9840
+ var import_path14 = __toESM(require("path"));
9603
9841
  init_axios2();
9604
9842
  var import_child_process5 = require("child_process");
9605
9843
  init_webLogin();
@@ -9609,14 +9847,14 @@ init_cliError();
9609
9847
  init_config();
9610
9848
  var PROJECT_DIR2 = process.cwd();
9611
9849
  function loadConfig() {
9612
- const configPath = import_path13.default.join(PROJECT_DIR2, "pinme.toml");
9613
- if (!import_fs_extra7.default.existsSync(configPath)) {
9850
+ const configPath = import_path14.default.join(PROJECT_DIR2, "pinme.toml");
9851
+ if (!import_fs_extra8.default.existsSync(configPath)) {
9614
9852
  throw createConfigError("`pinme.toml` not found in the current directory.", [
9615
9853
  "Run this command from the Pinme project root.",
9616
9854
  "If the project has not been initialized yet, create or restore `pinme.toml` first."
9617
9855
  ]);
9618
9856
  }
9619
- const configContent = import_fs_extra7.default.readFileSync(configPath, "utf-8");
9857
+ const configContent = import_fs_extra8.default.readFileSync(configPath, "utf-8");
9620
9858
  const projectNameMatch = configContent.match(/project_name\s*=\s*"([^"]+)"/);
9621
9859
  return {
9622
9860
  project_name: (projectNameMatch == null ? void 0 : projectNameMatch[1]) || ""
@@ -9626,12 +9864,12 @@ function getProjectManagementUrl2(projectName) {
9626
9864
  return `${APP_CONFIG.projectPeviewUrl}${projectName}`;
9627
9865
  }
9628
9866
  function getMetadata() {
9629
- const metadataPath = import_path13.default.join(PROJECT_DIR2, "backend", "metadata.json");
9630
- if (!import_fs_extra7.default.existsSync(metadataPath)) {
9867
+ const metadataPath = import_path14.default.join(PROJECT_DIR2, "backend", "metadata.json");
9868
+ if (!import_fs_extra8.default.existsSync(metadataPath)) {
9631
9869
  console.log(import_chalk21.default.yellow(" Warning: metadata.json not found, using empty metadata"));
9632
9870
  return {};
9633
9871
  }
9634
- return import_fs_extra7.default.readJsonSync(metadataPath);
9872
+ return import_fs_extra8.default.readJsonSync(metadataPath);
9635
9873
  }
9636
9874
  function buildWorker() {
9637
9875
  console.log(import_chalk21.default.blue("Building worker..."));
@@ -9653,11 +9891,11 @@ function buildWorker() {
9653
9891
  }
9654
9892
  }
9655
9893
  function dependenciesMissingError(summary, logTail) {
9656
- const installLogPath = import_path13.default.join(PROJECT_DIR2, ".pinme-install.log");
9894
+ const installLogPath = import_path14.default.join(PROJECT_DIR2, ".pinme-install.log");
9657
9895
  const suggestions = [
9658
9896
  "Run `npm install` in the project root, wait for it to finish, then rerun `pinme save`."
9659
9897
  ];
9660
- if (import_fs_extra7.default.existsSync(installLogPath)) {
9898
+ if (import_fs_extra8.default.existsSync(installLogPath)) {
9661
9899
  suggestions.push(
9662
9900
  `Background install log: ${installLogPath}`
9663
9901
  );
@@ -9687,7 +9925,7 @@ function dependenciesPresent() {
9687
9925
  function sleep(ms) {
9688
9926
  return new Promise((resolve) => setTimeout(resolve, ms));
9689
9927
  }
9690
- var WAIT_FOR_INSTALL_TIMEOUT_MS = 12 * 60 * 1e3;
9928
+ var WAIT_FOR_INSTALL_TIMEOUT_MS = 2 * 60 * 1e3;
9691
9929
  var WAIT_POLL_INTERVAL_MS = 2e3;
9692
9930
  async function ensureDependenciesReady() {
9693
9931
  if (dependenciesPresent()) {
@@ -9706,6 +9944,12 @@ async function ensureDependenciesReady() {
9706
9944
  readBackgroundInstallLogTail(PROJECT_DIR2)
9707
9945
  );
9708
9946
  }
9947
+ if (initial.status === "interrupted") {
9948
+ throw dependenciesMissingError(
9949
+ "The background dependency install appears to have been interrupted.",
9950
+ readBackgroundInstallLogTail(PROJECT_DIR2)
9951
+ );
9952
+ }
9709
9953
  const spinner = (0, import_ora3.default)("Waiting for background dependency install to finish...").start();
9710
9954
  const startedAt = Date.now();
9711
9955
  while (true) {
@@ -9722,6 +9966,13 @@ async function ensureDependenciesReady() {
9722
9966
  readBackgroundInstallLogTail(PROJECT_DIR2)
9723
9967
  );
9724
9968
  }
9969
+ if (state.status === "interrupted") {
9970
+ spinner.fail("Background dependency install was interrupted.");
9971
+ throw dependenciesMissingError(
9972
+ "The background dependency install appears to have been interrupted.",
9973
+ readBackgroundInstallLogTail(PROJECT_DIR2)
9974
+ );
9975
+ }
9725
9976
  if (state.status === "success") {
9726
9977
  spinner.succeed("Dependencies installed.");
9727
9978
  return;
@@ -9730,7 +9981,7 @@ async function ensureDependenciesReady() {
9730
9981
  if (elapsedMs > WAIT_FOR_INSTALL_TIMEOUT_MS) {
9731
9982
  spinner.fail("Timed out waiting for the dependency install.");
9732
9983
  throw dependenciesMissingError(
9733
- "Timed out waiting for the background dependency install to finish.",
9984
+ "Timed out waiting for the background dependency install to finish. It may still be running slowly.",
9734
9985
  readBackgroundInstallLogTail(PROJECT_DIR2)
9735
9986
  );
9736
9987
  }
@@ -9739,49 +9990,50 @@ async function ensureDependenciesReady() {
9739
9990
  }
9740
9991
  function cleanupInstallMarkers() {
9741
9992
  try {
9742
- import_fs_extra7.default.removeSync(import_path13.default.join(PROJECT_DIR2, INSTALL_LOG_FILE));
9743
- import_fs_extra7.default.removeSync(import_path13.default.join(PROJECT_DIR2, INSTALL_EXITCODE_FILE));
9993
+ import_fs_extra8.default.removeSync(import_path14.default.join(PROJECT_DIR2, INSTALL_LOG_FILE));
9994
+ import_fs_extra8.default.removeSync(import_path14.default.join(PROJECT_DIR2, INSTALL_EXITCODE_FILE));
9995
+ import_fs_extra8.default.removeSync(import_path14.default.join(PROJECT_DIR2, INSTALL_PID_FILE));
9744
9996
  } catch {
9745
9997
  }
9746
9998
  }
9747
9999
  function hasLocalBinary(name) {
9748
10000
  const binDirs = [
9749
- import_path13.default.join(PROJECT_DIR2, "node_modules", ".bin"),
9750
- import_path13.default.join(PROJECT_DIR2, "backend", "node_modules", ".bin"),
9751
- import_path13.default.join(PROJECT_DIR2, "frontend", "node_modules", ".bin")
10001
+ import_path14.default.join(PROJECT_DIR2, "node_modules", ".bin"),
10002
+ import_path14.default.join(PROJECT_DIR2, "backend", "node_modules", ".bin"),
10003
+ import_path14.default.join(PROJECT_DIR2, "frontend", "node_modules", ".bin")
9752
10004
  ];
9753
10005
  const candidates = process.platform === "win32" ? [name, `${name}.cmd`, `${name}.exe`, `${name}.ps1`] : [name];
9754
- return binDirs.some((dir) => candidates.some((candidate) => import_fs_extra7.default.existsSync(import_path13.default.join(dir, candidate))));
10006
+ return binDirs.some((dir) => candidates.some((candidate) => import_fs_extra8.default.existsSync(import_path14.default.join(dir, candidate))));
9755
10007
  }
9756
10008
  function getBuiltWorker() {
9757
- const distWorkerDir = import_path13.default.join(PROJECT_DIR2, "dist-worker");
9758
- if (!import_fs_extra7.default.existsSync(distWorkerDir)) {
10009
+ const distWorkerDir = import_path14.default.join(PROJECT_DIR2, "dist-worker");
10010
+ if (!import_fs_extra8.default.existsSync(distWorkerDir)) {
9759
10011
  throw createConfigError("Built worker output not found: `dist-worker/`.", [
9760
10012
  "Make sure `npm run build:worker` completed successfully."
9761
10013
  ]);
9762
10014
  }
9763
- const workerJsPath = import_path13.default.join(distWorkerDir, "worker.js");
9764
- if (!import_fs_extra7.default.existsSync(workerJsPath)) {
10015
+ const workerJsPath = import_path14.default.join(distWorkerDir, "worker.js");
10016
+ if (!import_fs_extra8.default.existsSync(workerJsPath)) {
9765
10017
  throw createConfigError("Built worker entry file not found: `dist-worker/worker.js`.", [
9766
10018
  "Check the worker build output and bundler config."
9767
10019
  ]);
9768
10020
  }
9769
10021
  const modulePaths = [];
9770
- const files = import_fs_extra7.default.readdirSync(distWorkerDir);
10022
+ const files = import_fs_extra8.default.readdirSync(distWorkerDir);
9771
10023
  for (const file of files) {
9772
10024
  if (file.endsWith(".js") && file !== "worker.js") {
9773
- modulePaths.push(import_path13.default.join(distWorkerDir, file));
10025
+ modulePaths.push(import_path14.default.join(distWorkerDir, file));
9774
10026
  }
9775
10027
  }
9776
10028
  return { workerJsPath, modulePaths };
9777
10029
  }
9778
10030
  function getSqlFiles() {
9779
- const sqlDir = import_path13.default.join(PROJECT_DIR2, "db");
9780
- if (!import_fs_extra7.default.existsSync(sqlDir)) {
10031
+ const sqlDir = import_path14.default.join(PROJECT_DIR2, "db");
10032
+ if (!import_fs_extra8.default.existsSync(sqlDir)) {
9781
10033
  return [];
9782
10034
  }
9783
- const files = import_fs_extra7.default.readdirSync(sqlDir).filter((f) => f.endsWith(".sql")).sort();
9784
- return files.map((f) => import_path13.default.join(sqlDir, f));
10035
+ const files = import_fs_extra8.default.readdirSync(sqlDir).filter((f) => f.endsWith(".sql")).sort();
10036
+ return files.map((f) => import_path14.default.join(sqlDir, f));
9785
10037
  }
9786
10038
  async function saveWorker(workerJsPath, modulePaths, sqlFiles, metadata, projectName) {
9787
10039
  var _a2, _b;
@@ -9801,20 +10053,20 @@ async function saveWorker(workerJsPath, modulePaths, sqlFiles, metadata, project
9801
10053
  formData.append("metadata", new Blob2([JSON.stringify(metadata)], {
9802
10054
  type: "application/json"
9803
10055
  }), "metadata.json");
9804
- const workerCode = import_fs_extra7.default.readFileSync(workerJsPath, "utf-8");
10056
+ const workerCode = import_fs_extra8.default.readFileSync(workerJsPath, "utf-8");
9805
10057
  formData.append("worker.js", new Blob2([workerCode], {
9806
10058
  type: "application/javascript+module"
9807
10059
  }), "worker.js");
9808
10060
  for (const modulePath of modulePaths) {
9809
- const filename = import_path13.default.basename(modulePath);
9810
- const content = import_fs_extra7.default.readFileSync(modulePath, "utf-8");
10061
+ const filename = import_path14.default.basename(modulePath);
10062
+ const content = import_fs_extra8.default.readFileSync(modulePath, "utf-8");
9811
10063
  formData.append(filename, new Blob2([content], {
9812
10064
  type: "application/javascript+module"
9813
10065
  }), filename);
9814
10066
  }
9815
10067
  for (const sqlFile of sqlFiles) {
9816
- const filename = import_path13.default.basename(sqlFile);
9817
- const content = import_fs_extra7.default.readFileSync(sqlFile, "utf-8");
10068
+ const filename = import_path14.default.basename(sqlFile);
10069
+ const content = import_fs_extra8.default.readFileSync(sqlFile, "utf-8");
9818
10070
  formData.append("sql_file", new Blob2([content], {
9819
10071
  type: "application/sql"
9820
10072
  }), filename);
@@ -9869,7 +10121,7 @@ function buildFrontend() {
9869
10121
  }
9870
10122
  }
9871
10123
  function updateFrontendUrlInConfig2(configPath, frontendUrl) {
9872
- let config = import_fs_extra7.default.readFileSync(configPath, "utf-8");
10124
+ let config = import_fs_extra8.default.readFileSync(configPath, "utf-8");
9873
10125
  if (config.includes("frontend_url")) {
9874
10126
  config = config.replace(
9875
10127
  /frontend_url\s*=\s*"[^"]*"/,
@@ -9882,18 +10134,18 @@ function updateFrontendUrlInConfig2(configPath, frontendUrl) {
9882
10134
  `
9883
10135
  );
9884
10136
  }
9885
- import_fs_extra7.default.writeFileSync(configPath, config);
10137
+ import_fs_extra8.default.writeFileSync(configPath, config);
9886
10138
  }
9887
10139
  async function deployFrontend(projectName) {
9888
10140
  console.log(import_chalk21.default.blue("Deploying frontend to IPFS..."));
9889
10141
  try {
9890
10142
  const headers = getAuthHeaders();
9891
- const uploadResult = await uploadPath(import_path13.default.join(PROJECT_DIR2, "frontend", "dist"), {
10143
+ const uploadResult = await uploadPath(import_path14.default.join(PROJECT_DIR2, "frontend", "dist"), {
9892
10144
  action: "project_save",
9893
10145
  projectName,
9894
10146
  uid: headers["token-address"]
9895
10147
  });
9896
- updateFrontendUrlInConfig2(import_path13.default.join(PROJECT_DIR2, "pinme.toml"), uploadResult.publicUrl);
10148
+ updateFrontendUrlInConfig2(import_path14.default.join(PROJECT_DIR2, "pinme.toml"), uploadResult.publicUrl);
9897
10149
  return {
9898
10150
  contentHash: uploadResult.contentHash,
9899
10151
  publicUrl: uploadResult.publicUrl
@@ -9943,11 +10195,11 @@ async function saveCmd(options) {
9943
10195
  "Run `pinme login` and retry."
9944
10196
  ]);
9945
10197
  }
9946
- const projectDir = options.projectName || options.name ? import_path13.default.join(PROJECT_DIR2, options.projectName || options.name) : PROJECT_DIR2;
9947
- const tokenFileSrc = import_path13.default.join(PROJECT_DIR2, ".token.json");
9948
- const tokenFileDst = import_path13.default.join(projectDir, ".token.json");
9949
- if (import_fs_extra7.default.existsSync(tokenFileSrc) && !import_fs_extra7.default.existsSync(tokenFileDst)) {
9950
- import_fs_extra7.default.copySync(tokenFileSrc, tokenFileDst);
10198
+ const projectDir = options.projectName || options.name ? import_path14.default.join(PROJECT_DIR2, options.projectName || options.name) : PROJECT_DIR2;
10199
+ const tokenFileSrc = import_path14.default.join(PROJECT_DIR2, ".token.json");
10200
+ const tokenFileDst = import_path14.default.join(projectDir, ".token.json");
10201
+ if (import_fs_extra8.default.existsSync(tokenFileSrc) && !import_fs_extra8.default.existsSync(tokenFileDst)) {
10202
+ import_fs_extra8.default.copySync(tokenFileSrc, tokenFileDst);
9951
10203
  }
9952
10204
  console.log(import_chalk21.default.blue("Deploying to platform...\n"));
9953
10205
  console.log(import_chalk21.default.gray(`Project dir: ${PROJECT_DIR2}`));
@@ -10013,40 +10265,40 @@ async function saveCmd(options) {
10013
10265
 
10014
10266
  // bin/updateDb.ts
10015
10267
  var import_chalk22 = __toESM(require("chalk"));
10016
- var import_fs_extra8 = __toESM(require("fs-extra"));
10017
- var import_path14 = __toESM(require("path"));
10268
+ var import_fs_extra9 = __toESM(require("fs-extra"));
10269
+ var import_path15 = __toESM(require("path"));
10018
10270
  init_axios2();
10019
10271
  init_webLogin();
10020
10272
  init_cliError();
10021
10273
  init_config();
10022
10274
  var PROJECT_DIR3 = process.cwd();
10023
10275
  function loadConfig2() {
10024
- const configPath = import_path14.default.join(PROJECT_DIR3, "pinme.toml");
10025
- if (!import_fs_extra8.default.existsSync(configPath)) {
10276
+ const configPath = import_path15.default.join(PROJECT_DIR3, "pinme.toml");
10277
+ if (!import_fs_extra9.default.existsSync(configPath)) {
10026
10278
  throw createConfigError("`pinme.toml` not found in the current directory.", [
10027
10279
  "Run this command from the Pinme project root."
10028
10280
  ]);
10029
10281
  }
10030
- const configContent = import_fs_extra8.default.readFileSync(configPath, "utf-8");
10282
+ const configContent = import_fs_extra9.default.readFileSync(configPath, "utf-8");
10031
10283
  const projectNameMatch = configContent.match(/project_name\s*=\s*"([^"]+)"/);
10032
10284
  return {
10033
10285
  project_name: (projectNameMatch == null ? void 0 : projectNameMatch[1]) || ""
10034
10286
  };
10035
10287
  }
10036
10288
  function getSqlFiles2() {
10037
- const sqlDir = import_path14.default.join(PROJECT_DIR3, "db");
10038
- if (!import_fs_extra8.default.existsSync(sqlDir)) {
10289
+ const sqlDir = import_path15.default.join(PROJECT_DIR3, "db");
10290
+ if (!import_fs_extra9.default.existsSync(sqlDir)) {
10039
10291
  throw createConfigError("SQL directory not found: `db/`.", [
10040
10292
  "Create a `db/` directory and add at least one `.sql` migration file."
10041
10293
  ]);
10042
10294
  }
10043
- const files = import_fs_extra8.default.readdirSync(sqlDir).filter((f) => f.endsWith(".sql")).sort();
10295
+ const files = import_fs_extra9.default.readdirSync(sqlDir).filter((f) => f.endsWith(".sql")).sort();
10044
10296
  if (files.length === 0) {
10045
10297
  throw createConfigError("No `.sql` files were found in `db/`.", [
10046
10298
  "Add one or more migration files before running `pinme update-db`."
10047
10299
  ]);
10048
10300
  }
10049
- return files.map((f) => import_path14.default.join(sqlDir, f));
10301
+ return files.map((f) => import_path15.default.join(sqlDir, f));
10050
10302
  }
10051
10303
  async function updateDb(sqlFiles, projectName) {
10052
10304
  console.log(import_chalk22.default.blue("Importing SQL files to database..."));
@@ -10061,8 +10313,8 @@ async function updateDb(sqlFiles, projectName) {
10061
10313
  const formData = new FormData4();
10062
10314
  let totalSize = 0;
10063
10315
  for (const sqlFile of sqlFiles) {
10064
- const filename = import_path14.default.basename(sqlFile);
10065
- const content = import_fs_extra8.default.readFileSync(sqlFile);
10316
+ const filename = import_path15.default.basename(sqlFile);
10317
+ const content = import_fs_extra9.default.readFileSync(sqlFile);
10066
10318
  totalSize += content.length;
10067
10319
  if (totalSize > 10 * 1024 * 1024) {
10068
10320
  throw createConfigError("Total SQL payload exceeds the 10MB platform limit.", [
@@ -10117,11 +10369,11 @@ async function updateDbCmd(options) {
10117
10369
  "Run `pinme login` and retry."
10118
10370
  ]);
10119
10371
  }
10120
- const projectDir = (options == null ? void 0 : options.projectName) || (options == null ? void 0 : options.name) ? import_path14.default.join(PROJECT_DIR3, options.projectName || options.name) : PROJECT_DIR3;
10121
- const tokenFileSrc = import_path14.default.join(PROJECT_DIR3, ".token.json");
10122
- const tokenFileDst = import_path14.default.join(projectDir, ".token.json");
10123
- if (import_fs_extra8.default.existsSync(tokenFileSrc) && !import_fs_extra8.default.existsSync(tokenFileDst)) {
10124
- import_fs_extra8.default.copySync(tokenFileSrc, tokenFileDst);
10372
+ const projectDir = (options == null ? void 0 : options.projectName) || (options == null ? void 0 : options.name) ? import_path15.default.join(PROJECT_DIR3, options.projectName || options.name) : PROJECT_DIR3;
10373
+ const tokenFileSrc = import_path15.default.join(PROJECT_DIR3, ".token.json");
10374
+ const tokenFileDst = import_path15.default.join(projectDir, ".token.json");
10375
+ if (import_fs_extra9.default.existsSync(tokenFileSrc) && !import_fs_extra9.default.existsSync(tokenFileDst)) {
10376
+ import_fs_extra9.default.copySync(tokenFileSrc, tokenFileDst);
10125
10377
  }
10126
10378
  console.log(import_chalk22.default.blue("Importing SQL to database...\n"));
10127
10379
  console.log(import_chalk22.default.gray(`Project dir: ${PROJECT_DIR3}`));
@@ -10164,8 +10416,8 @@ async function updateDbCmd(options) {
10164
10416
 
10165
10417
  // bin/updateWorker.ts
10166
10418
  var import_chalk23 = __toESM(require("chalk"));
10167
- var import_fs_extra9 = __toESM(require("fs-extra"));
10168
- var import_path15 = __toESM(require("path"));
10419
+ var import_fs_extra10 = __toESM(require("fs-extra"));
10420
+ var import_path16 = __toESM(require("path"));
10169
10421
  init_axios2();
10170
10422
  var import_child_process6 = require("child_process");
10171
10423
  init_webLogin();
@@ -10173,26 +10425,26 @@ init_cliError();
10173
10425
  init_config();
10174
10426
  var PROJECT_DIR4 = process.cwd();
10175
10427
  function loadConfig3() {
10176
- const configPath = import_path15.default.join(PROJECT_DIR4, "pinme.toml");
10177
- if (!import_fs_extra9.default.existsSync(configPath)) {
10428
+ const configPath = import_path16.default.join(PROJECT_DIR4, "pinme.toml");
10429
+ if (!import_fs_extra10.default.existsSync(configPath)) {
10178
10430
  throw createConfigError("`pinme.toml` not found in the current directory.", [
10179
10431
  "Run this command from the Pinme project root."
10180
10432
  ]);
10181
10433
  }
10182
- const configContent = import_fs_extra9.default.readFileSync(configPath, "utf-8");
10434
+ const configContent = import_fs_extra10.default.readFileSync(configPath, "utf-8");
10183
10435
  const projectNameMatch = configContent.match(/project_name\s*=\s*"([^"]+)"/);
10184
10436
  return {
10185
10437
  project_name: (projectNameMatch == null ? void 0 : projectNameMatch[1]) || ""
10186
10438
  };
10187
10439
  }
10188
10440
  function getMetadata2() {
10189
- const metadataPath = import_path15.default.join(PROJECT_DIR4, "backend", "metadata.json");
10190
- if (!import_fs_extra9.default.existsSync(metadataPath)) {
10441
+ const metadataPath = import_path16.default.join(PROJECT_DIR4, "backend", "metadata.json");
10442
+ if (!import_fs_extra10.default.existsSync(metadataPath)) {
10191
10443
  throw createConfigError("`backend/metadata.json` not found.", [
10192
10444
  "Create `backend/metadata.json` or restore it from the project template."
10193
10445
  ]);
10194
10446
  }
10195
- return import_fs_extra9.default.readJsonSync(metadataPath);
10447
+ return import_fs_extra10.default.readJsonSync(metadataPath);
10196
10448
  }
10197
10449
  function buildWorker2() {
10198
10450
  console.log(import_chalk23.default.blue("Building worker..."));
@@ -10209,23 +10461,23 @@ function buildWorker2() {
10209
10461
  }
10210
10462
  }
10211
10463
  function getBuiltWorker2() {
10212
- const distWorkerDir = import_path15.default.join(PROJECT_DIR4, "dist-worker");
10213
- if (!import_fs_extra9.default.existsSync(distWorkerDir)) {
10464
+ const distWorkerDir = import_path16.default.join(PROJECT_DIR4, "dist-worker");
10465
+ if (!import_fs_extra10.default.existsSync(distWorkerDir)) {
10214
10466
  throw createConfigError("Built worker output not found: `dist-worker/`.", [
10215
10467
  "Make sure `npm run build:worker` completed successfully."
10216
10468
  ]);
10217
10469
  }
10218
- const workerJsPath = import_path15.default.join(distWorkerDir, "worker.js");
10219
- if (!import_fs_extra9.default.existsSync(workerJsPath)) {
10470
+ const workerJsPath = import_path16.default.join(distWorkerDir, "worker.js");
10471
+ if (!import_fs_extra10.default.existsSync(workerJsPath)) {
10220
10472
  throw createConfigError("Built worker entry file not found: `dist-worker/worker.js`.", [
10221
10473
  "Check the worker build output and bundler config."
10222
10474
  ]);
10223
10475
  }
10224
10476
  const modulePaths = [];
10225
- const files = import_fs_extra9.default.readdirSync(distWorkerDir);
10477
+ const files = import_fs_extra10.default.readdirSync(distWorkerDir);
10226
10478
  for (const file of files) {
10227
10479
  if (file.endsWith(".js") && file !== "worker.js") {
10228
- modulePaths.push(import_path15.default.join(distWorkerDir, file));
10480
+ modulePaths.push(import_path16.default.join(distWorkerDir, file));
10229
10481
  }
10230
10482
  }
10231
10483
  return { workerJsPath, modulePaths };
@@ -10246,13 +10498,13 @@ async function updateWorker(workerJsPath, modulePaths, metadata, projectName) {
10246
10498
  formData.append("metadata", new Blob2([JSON.stringify(metadata)], {
10247
10499
  type: "application/json"
10248
10500
  }), "metadata.json");
10249
- const workerCode = import_fs_extra9.default.readFileSync(workerJsPath, "utf-8");
10501
+ const workerCode = import_fs_extra10.default.readFileSync(workerJsPath, "utf-8");
10250
10502
  formData.append("worker.js", new Blob2([workerCode], {
10251
10503
  type: "application/javascript+module"
10252
10504
  }), "worker.js");
10253
10505
  for (const modulePath of modulePaths) {
10254
- const filename = import_path15.default.basename(modulePath);
10255
- const content = import_fs_extra9.default.readFileSync(modulePath, "utf-8");
10506
+ const filename = import_path16.default.basename(modulePath);
10507
+ const content = import_fs_extra10.default.readFileSync(modulePath, "utf-8");
10256
10508
  formData.append(filename, new Blob2([content], {
10257
10509
  type: "application/javascript+module"
10258
10510
  }), filename);
@@ -10314,11 +10566,11 @@ async function updateWorkerCmd(options) {
10314
10566
  "Run `pinme login` and retry."
10315
10567
  ]);
10316
10568
  }
10317
- const projectDir = (options == null ? void 0 : options.projectName) || (options == null ? void 0 : options.name) ? import_path15.default.join(PROJECT_DIR4, options.projectName || options.name) : PROJECT_DIR4;
10318
- const tokenFileSrc = import_path15.default.join(PROJECT_DIR4, ".token.json");
10319
- const tokenFileDst = import_path15.default.join(projectDir, ".token.json");
10320
- if (import_fs_extra9.default.existsSync(tokenFileSrc) && !import_fs_extra9.default.existsSync(tokenFileDst)) {
10321
- import_fs_extra9.default.copySync(tokenFileSrc, tokenFileDst);
10569
+ const projectDir = (options == null ? void 0 : options.projectName) || (options == null ? void 0 : options.name) ? import_path16.default.join(PROJECT_DIR4, options.projectName || options.name) : PROJECT_DIR4;
10570
+ const tokenFileSrc = import_path16.default.join(PROJECT_DIR4, ".token.json");
10571
+ const tokenFileDst = import_path16.default.join(projectDir, ".token.json");
10572
+ if (import_fs_extra10.default.existsSync(tokenFileSrc) && !import_fs_extra10.default.existsSync(tokenFileDst)) {
10573
+ import_fs_extra10.default.copySync(tokenFileSrc, tokenFileDst);
10322
10574
  }
10323
10575
  console.log(import_chalk23.default.blue("Updating worker...\n"));
10324
10576
  console.log(import_chalk23.default.gray(`Project dir: ${PROJECT_DIR4}`));
@@ -10366,21 +10618,21 @@ async function updateWorkerCmd(options) {
10366
10618
 
10367
10619
  // bin/updateWeb.ts
10368
10620
  var import_chalk24 = __toESM(require("chalk"));
10369
- var import_fs_extra10 = __toESM(require("fs-extra"));
10370
- var import_path16 = __toESM(require("path"));
10621
+ var import_fs_extra11 = __toESM(require("fs-extra"));
10622
+ var import_path17 = __toESM(require("path"));
10371
10623
  var import_child_process7 = require("child_process");
10372
10624
  init_webLogin();
10373
10625
  init_cliError();
10374
10626
  init_config();
10375
10627
  var PROJECT_DIR5 = process.cwd();
10376
10628
  function loadConfig4() {
10377
- const configPath = import_path16.default.join(PROJECT_DIR5, "pinme.toml");
10378
- if (!import_fs_extra10.default.existsSync(configPath)) {
10629
+ const configPath = import_path17.default.join(PROJECT_DIR5, "pinme.toml");
10630
+ if (!import_fs_extra11.default.existsSync(configPath)) {
10379
10631
  throw createConfigError("`pinme.toml` not found in the current directory.", [
10380
10632
  "Run this command from the Pinme project root."
10381
10633
  ]);
10382
10634
  }
10383
- const configContent = import_fs_extra10.default.readFileSync(configPath, "utf-8");
10635
+ const configContent = import_fs_extra11.default.readFileSync(configPath, "utf-8");
10384
10636
  const projectNameMatch = configContent.match(/project_name\s*=\s*"([^"]+)"/);
10385
10637
  return {
10386
10638
  project_name: (projectNameMatch == null ? void 0 : projectNameMatch[1]) || ""
@@ -10407,7 +10659,7 @@ async function deployFrontend2(projectName) {
10407
10659
  console.log(import_chalk24.default.blue("Deploying frontend to IPFS..."));
10408
10660
  try {
10409
10661
  const headers = getAuthHeaders();
10410
- const uploadResult = await uploadPath(import_path16.default.join(PROJECT_DIR5, "frontend", "dist"), {
10662
+ const uploadResult = await uploadPath(import_path17.default.join(PROJECT_DIR5, "frontend", "dist"), {
10411
10663
  action: "project_update_web",
10412
10664
  projectName,
10413
10665
  uid: headers["token-address"]
@@ -10432,11 +10684,11 @@ async function updateWebCmd(options) {
10432
10684
  "Run `pinme login` and retry."
10433
10685
  ]);
10434
10686
  }
10435
- const projectDir = (options == null ? void 0 : options.projectName) || (options == null ? void 0 : options.name) ? import_path16.default.join(PROJECT_DIR5, options.projectName || options.name) : PROJECT_DIR5;
10436
- const tokenFileSrc = import_path16.default.join(PROJECT_DIR5, ".token.json");
10437
- const tokenFileDst = import_path16.default.join(projectDir, ".token.json");
10438
- if (import_fs_extra10.default.existsSync(tokenFileSrc) && !import_fs_extra10.default.existsSync(tokenFileDst)) {
10439
- import_fs_extra10.default.copySync(tokenFileSrc, tokenFileDst);
10687
+ const projectDir = (options == null ? void 0 : options.projectName) || (options == null ? void 0 : options.name) ? import_path17.default.join(PROJECT_DIR5, options.projectName || options.name) : PROJECT_DIR5;
10688
+ const tokenFileSrc = import_path17.default.join(PROJECT_DIR5, ".token.json");
10689
+ const tokenFileDst = import_path17.default.join(projectDir, ".token.json");
10690
+ if (import_fs_extra11.default.existsSync(tokenFileSrc) && !import_fs_extra11.default.existsSync(tokenFileDst)) {
10691
+ import_fs_extra11.default.copySync(tokenFileSrc, tokenFileDst);
10440
10692
  }
10441
10693
  console.log(import_chalk24.default.blue("Updating web (frontend)...\n"));
10442
10694
  console.log(import_chalk24.default.gray(`Project dir: ${PROJECT_DIR5}`));
@@ -10480,16 +10732,16 @@ async function updateWebCmd(options) {
10480
10732
  var import_chalk25 = __toESM(require("chalk"));
10481
10733
  var import_inquirer9 = __toESM(require("inquirer"));
10482
10734
  init_axios2();
10483
- var import_fs_extra11 = __toESM(require("fs-extra"));
10484
- var import_path17 = __toESM(require("path"));
10735
+ var import_fs_extra12 = __toESM(require("fs-extra"));
10736
+ var import_path18 = __toESM(require("path"));
10485
10737
  init_webLogin();
10486
10738
  init_config();
10487
10739
  function getProjectName() {
10488
- const configPath = import_path17.default.join(process.cwd(), "pinme.toml");
10489
- if (!import_fs_extra11.default.existsSync(configPath)) {
10740
+ const configPath = import_path18.default.join(process.cwd(), "pinme.toml");
10741
+ if (!import_fs_extra12.default.existsSync(configPath)) {
10490
10742
  return null;
10491
10743
  }
10492
- const config = import_fs_extra11.default.readFileSync(configPath, "utf-8");
10744
+ const config = import_fs_extra12.default.readFileSync(configPath, "utf-8");
10493
10745
  const match = config.match(/project_name\s*=\s*"([^"]+)"/);
10494
10746
  return (match == null ? void 0 : match[1]) || null;
10495
10747
  }