@swarm.ing/pieui 2.0.19 → 2.0.21

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 (36) hide show
  1. package/README.md +6 -2
  2. package/dist/cli.js +402 -28
  3. package/dist/code/args.d.ts.map +1 -1
  4. package/dist/code/commands/cardRemote/cardRef.d.ts +3 -0
  5. package/dist/code/commands/cardRemote/cardRef.d.ts.map +1 -1
  6. package/dist/code/commands/cardRemote/history.d.ts +9 -0
  7. package/dist/code/commands/cardRemote/history.d.ts.map +1 -0
  8. package/dist/code/commands/cardRemote/private.d.ts +2 -0
  9. package/dist/code/commands/cardRemote/private.d.ts.map +1 -0
  10. package/dist/code/commands/cardRemote/public.d.ts +2 -0
  11. package/dist/code/commands/cardRemote/public.d.ts.map +1 -0
  12. package/dist/code/commands/cardRemote/pull.d.ts.map +1 -1
  13. package/dist/code/commands/cardRemote/push.d.ts.map +1 -1
  14. package/dist/code/services/models.d.ts +37 -0
  15. package/dist/code/services/models.d.ts.map +1 -1
  16. package/dist/code/services/storage.d.ts +40 -1
  17. package/dist/code/services/storage.d.ts.map +1 -1
  18. package/dist/code/types.d.ts +5 -1
  19. package/dist/code/types.d.ts.map +1 -1
  20. package/dist/components/PieBaseRoot/index.d.ts.map +1 -1
  21. package/dist/components/PieMaxRoot/index.d.ts.map +1 -1
  22. package/dist/components/PieRoot/index.d.ts.map +1 -1
  23. package/dist/components/PieRoot/types/index.d.ts +7 -0
  24. package/dist/components/PieRoot/types/index.d.ts.map +1 -1
  25. package/dist/components/PieTelegramRoot/index.d.ts.map +1 -1
  26. package/dist/index.esm.js +2 -2
  27. package/dist/index.js +2 -2
  28. package/dist/tests/ajaxCommonUtils.test.d.ts +15 -0
  29. package/dist/tests/ajaxCommonUtils.test.d.ts.map +1 -0
  30. package/dist/tests/lazy.test.d.ts +14 -0
  31. package/dist/tests/lazy.test.d.ts.map +1 -0
  32. package/dist/tests/pieName.test.d.ts +12 -0
  33. package/dist/tests/pieName.test.d.ts.map +1 -0
  34. package/dist/tests/waitForSidAvailable.test.d.ts +20 -0
  35. package/dist/tests/waitForSidAvailable.test.d.ts.map +1 -0
  36. package/package.json +1 -1
package/README.md CHANGED
@@ -107,16 +107,20 @@ Create a blank Next.js web app template with PieUI CLI:
107
107
 
108
108
  ```sh
109
109
  bunx pieui create-pie-app my-pie-app
110
+ # or alias:
111
+ bunx pieui create-pieui my-pie-app
110
112
  ```
111
113
 
112
114
  This command:
113
115
 
114
116
  - runs `bun create next-app@latest my-pie-app --yes`
115
- - copies a standard `_shared` folder into the new app (sourced from `ai-exchange-bot`)
117
+ - copies a standard `_shared` folder into the new app (sourced from `ai-exchange-bot` when found)
116
118
  - rewrites `dev/build/start` scripts to `bun --bun next ...`
117
119
  - appends a TODO marker in `app/page.tsx` for future backend (Python Unicorn) linking
118
120
 
119
- If the `_shared` source cannot be found automatically, set:
121
+ If the `_shared` source cannot be found automatically, PieUI now creates a fallback `_shared/simple.tsx` scaffold and continues.
122
+
123
+ To force a specific shared source, set:
120
124
 
121
125
  ```sh
122
126
  PIEUI_SHARED_TEMPLATE_DIR=/absolute/path/to/_shared bunx pieui create-pie-app my-pie-app
package/dist/cli.js CHANGED
@@ -184030,18 +184030,31 @@ var parseArgs = (argv) => {
184030
184030
  componentName = positionalArgs[0];
184031
184031
  }
184032
184032
  }
184033
+ let historyPage;
184034
+ let historyPerPage;
184035
+ let historyFrom;
184036
+ let historyTo;
184033
184037
  if (command === "card" && cardAction === "remote" && argv[2]) {
184034
184038
  const validRemoteActions = [
184035
184039
  "push",
184036
184040
  "pull",
184037
184041
  "list",
184038
- "remove"
184042
+ "remove",
184043
+ "history",
184044
+ "public",
184045
+ "private"
184039
184046
  ];
184040
184047
  const action = argv[2];
184041
184048
  if (validRemoteActions.includes(action)) {
184042
184049
  cardRemoteAction = action;
184043
184050
  const rest = argv.slice(3);
184044
184051
  const flagIndexes = new Set;
184052
+ const parseIntFlag = (name, raw) => {
184053
+ if (!/^-?\d+$/.test(raw)) {
184054
+ throw new Error(`${name} must be an integer, got ${JSON.stringify(raw)}`);
184055
+ }
184056
+ return Number(raw);
184057
+ };
184045
184058
  for (let i = 0;i < rest.length; i++) {
184046
184059
  const tok = rest[i];
184047
184060
  if (tok === "--user" && rest[i + 1]) {
@@ -184054,12 +184067,44 @@ var parseArgs = (argv) => {
184054
184067
  flagIndexes.add(i);
184055
184068
  flagIndexes.add(i + 1);
184056
184069
  i++;
184070
+ } else if (tok === "--page" && rest[i + 1]) {
184071
+ historyPage = parseIntFlag("--page", rest[i + 1]);
184072
+ flagIndexes.add(i);
184073
+ flagIndexes.add(i + 1);
184074
+ i++;
184075
+ } else if (tok === "--per-page" && rest[i + 1]) {
184076
+ historyPerPage = parseIntFlag("--per-page", rest[i + 1]);
184077
+ flagIndexes.add(i);
184078
+ flagIndexes.add(i + 1);
184079
+ i++;
184080
+ } else if (tok === "--from" && rest[i + 1]) {
184081
+ historyFrom = parseIntFlag("--from", rest[i + 1]);
184082
+ flagIndexes.add(i);
184083
+ flagIndexes.add(i + 1);
184084
+ i++;
184085
+ } else if (tok === "--to" && rest[i + 1]) {
184086
+ historyTo = parseIntFlag("--to", rest[i + 1]);
184087
+ flagIndexes.add(i);
184088
+ flagIndexes.add(i + 1);
184089
+ i++;
184057
184090
  } else if (tok?.startsWith("--user=")) {
184058
184091
  remoteUserId = tok.slice("--user=".length);
184059
184092
  flagIndexes.add(i);
184060
184093
  } else if (tok?.startsWith("--project=")) {
184061
184094
  remoteProject = tok.slice("--project=".length);
184062
184095
  flagIndexes.add(i);
184096
+ } else if (tok?.startsWith("--page=")) {
184097
+ historyPage = parseIntFlag("--page", tok.slice("--page=".length));
184098
+ flagIndexes.add(i);
184099
+ } else if (tok?.startsWith("--per-page=")) {
184100
+ historyPerPage = parseIntFlag("--per-page", tok.slice("--per-page=".length));
184101
+ flagIndexes.add(i);
184102
+ } else if (tok?.startsWith("--from=")) {
184103
+ historyFrom = parseIntFlag("--from", tok.slice("--from=".length));
184104
+ flagIndexes.add(i);
184105
+ } else if (tok?.startsWith("--to=")) {
184106
+ historyTo = parseIntFlag("--to", tok.slice("--to=".length));
184107
+ flagIndexes.add(i);
184063
184108
  }
184064
184109
  }
184065
184110
  const positionals = rest.filter((_, i) => !flagIndexes.has(i));
@@ -184109,7 +184154,11 @@ var parseArgs = (argv) => {
184109
184154
  remoteUserId,
184110
184155
  remoteProject,
184111
184156
  pageAction,
184112
- pagePath
184157
+ pagePath,
184158
+ historyPage,
184159
+ historyPerPage,
184160
+ historyFrom,
184161
+ historyTo
184113
184162
  };
184114
184163
  };
184115
184164
  var printUsage = () => {
@@ -184124,9 +184173,14 @@ var printUsage = () => {
184124
184173
  console.log(" card add [type] <ComponentName> [--io] [--ajax] Create a new component in piecomponents directory");
184125
184174
  console.log(" page add <path> Create app/<path>/page.tsx from the standard Pie page template");
184126
184175
  console.log(" card remote push <ComponentName> Upload piecomponents/<Name>/ to PieUI storage (prints new revision)");
184127
- console.log(" card remote pull <ComponentName>[@rev] Download component from PieUI storage into piecomponents/<Name>/ (optional @<revision>)");
184176
+ console.log(" card remote pull <ComponentName>[@rev] Download component from current project (optional @<revision>)");
184177
+ console.log(" card remote pull <project>/<ComponentName>[@rev] Pull from a different project of the current user");
184178
+ console.log(" card remote pull r/<user>/<ComponentName> Pull a public component by another user");
184128
184179
  console.log(" card remote list [--user U] [--project S] List remote components for the configured or specified user/project");
184129
184180
  console.log(" card remote remove <ComponentName> Delete component from PieUI storage");
184181
+ console.log(" card remote history <ComponentName> [--page N] [--per-page N] [--from R] [--to R] Show revision history with per-file diff stats");
184182
+ console.log(" card remote public <ComponentName> Mark a component public (readable without API key as r/<user>/<Name>)");
184183
+ console.log(" card remote private <ComponentName> Make a public component private again");
184130
184184
  console.log(' list-events <ComponentName> List registered methods keys for <PieCard card="ComponentName" ... methods={...} />');
184131
184185
  console.log(' add-event <ComponentName> <event> Add a new methods key with a default handler to <PieCard card="ComponentName" ... methods={...} />');
184132
184186
  console.log(" remove <ComponentName> Remove a component from piecomponents directory");
@@ -184187,10 +184241,17 @@ var printUsage = () => {
184187
184241
  console.log(" pieui list-events ExchangeAlertsCard # Print methods table for that PieCard usage");
184188
184242
  console.log(" pieui add-event ExchangeAlertsCard alert # Add methods.alert with default handler");
184189
184243
  console.log(" pieui card remote push ExchangeAlertsCard # Upload component directory (server assigns new revision)");
184190
- console.log(" pieui card remote pull ExchangeAlertsCard # Download latest revision");
184244
+ console.log(" pieui card remote pull ExchangeAlertsCard # Download latest revision from current project");
184191
184245
  console.log(" pieui card remote pull ExchangeAlertsCard@7 # Download revision 7 snapshot");
184246
+ console.log(" pieui card remote pull other-proj/AlertsCard # Pull from another of your projects");
184247
+ console.log(" pieui card remote pull r/delta37/YetAnotherCard # Pull a public component by user delta37");
184192
184248
  console.log(" pieui card remote list # List remote components");
184193
184249
  console.log(" pieui card remote remove ExchangeAlertsCard # Delete remote component");
184250
+ console.log(" pieui card remote history ExchangeAlertsCard # Full history (newest first)");
184251
+ console.log(" pieui card remote history ExchangeAlertsCard --page 1 --per-page 5 # Paginate");
184252
+ console.log(" pieui card remote history ExchangeAlertsCard --from 12 --to 14 # Revision range");
184253
+ console.log(" pieui card remote public ExchangeAlertsCard # Make this component public");
184254
+ console.log(" pieui card remote private ExchangeAlertsCard # Revert to private");
184194
184255
  };
184195
184256
 
184196
184257
  // src/code/commands/init.ts
@@ -189257,6 +189318,92 @@ var parseComponentObject = (raw) => {
189257
189318
  signedUrl: typeof obj.signed_url === "string" ? obj.signed_url : typeof obj.signedUrl === "string" ? obj.signedUrl : undefined
189258
189319
  };
189259
189320
  };
189321
+ var parsePublicComponentState = (raw) => {
189322
+ const obj = raw ?? {};
189323
+ const pickStr = (...keys) => {
189324
+ for (const k2 of keys) {
189325
+ const v2 = obj[k2];
189326
+ if (typeof v2 === "string")
189327
+ return v2;
189328
+ }
189329
+ return "";
189330
+ };
189331
+ const registry = typeof obj.public_registry_name === "string" ? obj.public_registry_name : typeof obj.publicRegistryName === "string" ? obj.publicRegistryName : null;
189332
+ return {
189333
+ userId: pickStr("user_id", "userId"),
189334
+ project: pickStr("project_slug", "projectSlug"),
189335
+ componentName: pickStr("component_name", "componentName"),
189336
+ isPublic: obj.is_public === true || obj.isPublic === true,
189337
+ publicRegistryName: registry
189338
+ };
189339
+ };
189340
+ var pickString = (obj, ...keys) => {
189341
+ for (const k2 of keys) {
189342
+ const v2 = obj[k2];
189343
+ if (typeof v2 === "string")
189344
+ return v2;
189345
+ }
189346
+ return "";
189347
+ };
189348
+ var pickNumber = (obj, ...keys) => {
189349
+ for (const k2 of keys) {
189350
+ const v2 = obj[k2];
189351
+ if (typeof v2 === "number")
189352
+ return v2;
189353
+ }
189354
+ return null;
189355
+ };
189356
+ var parseHistoryFile = (raw) => {
189357
+ const obj = raw ?? {};
189358
+ const key = typeof obj.key === "string" ? obj.key : "";
189359
+ const status = obj.status;
189360
+ if (status !== "added" && status !== "modified" && status !== "deleted") {
189361
+ return null;
189362
+ }
189363
+ const additions = pickNumber(obj, "additions") ?? 0;
189364
+ const deletions = pickNumber(obj, "deletions") ?? 0;
189365
+ return {
189366
+ key,
189367
+ status,
189368
+ isBinary: obj.is_binary === true || obj.isBinary === true,
189369
+ additions,
189370
+ deletions,
189371
+ patch: typeof obj.patch === "string" ? obj.patch : undefined
189372
+ };
189373
+ };
189374
+ var parseHistoryEntry = (raw) => {
189375
+ const obj = raw ?? {};
189376
+ const revision = pickNumber(obj, "revision");
189377
+ if (revision === null)
189378
+ return null;
189379
+ const diff = obj.diff ?? {};
189380
+ const rawFiles = Array.isArray(diff.files) ? diff.files : [];
189381
+ const files = rawFiles.map(parseHistoryFile).filter((f) => f !== null);
189382
+ return {
189383
+ revision,
189384
+ previousRevision: pickNumber(obj, "previous_revision", "previousRevision"),
189385
+ createdAt: pickString(obj, "created_at", "createdAt"),
189386
+ mutation: pickString(obj, "mutation"),
189387
+ deleted: obj.deleted === true,
189388
+ files
189389
+ };
189390
+ };
189391
+ var parseComponentHistory = (raw) => {
189392
+ const obj = raw ?? {};
189393
+ const rawEntries = Array.isArray(obj.entries) ? obj.entries : [];
189394
+ const entries = rawEntries.map(parseHistoryEntry).filter((e) => e !== null);
189395
+ return {
189396
+ userId: pickString(obj, "user_id", "userId"),
189397
+ project: pickString(obj, "project_slug", "projectSlug"),
189398
+ componentName: pickString(obj, "component_name", "componentName"),
189399
+ page: pickNumber(obj, "page") ?? 1,
189400
+ perPage: pickNumber(obj, "per_page", "perPage") ?? 10,
189401
+ totalRevisions: pickNumber(obj, "total_revisions", "totalRevisions") ?? 0,
189402
+ fromRevision: pickNumber(obj, "from_revision", "fromRevision"),
189403
+ toRevision: pickNumber(obj, "to_revision", "toRevision"),
189404
+ entries
189405
+ };
189406
+ };
189260
189407
  var parseProjectComponentList = (raw) => {
189261
189408
  const obj = raw ?? {};
189262
189409
  const userId = typeof obj.user_id === "string" ? obj.user_id : typeof obj.userId === "string" ? obj.userId : "";
@@ -189336,16 +189483,22 @@ class PieStorageService {
189336
189483
  }
189337
189484
  componentUrl(args) {
189338
189485
  const userId = args.userId ?? this.settings.userId;
189339
- const slug = args.project ?? this.settings.project;
189340
189486
  if (!userId) {
189341
189487
  throw new PieStorageError("user_id is required (configure PIE_USER_ID or pass user_id)");
189342
189488
  }
189489
+ if (args.isPublic) {
189490
+ return `${this.baseUrl}/public-components/${pathPart(userId)}/${pathPart(args.componentName)}`;
189491
+ }
189492
+ const slug = args.project ?? this.settings.project;
189343
189493
  return `${this.baseUrl}/components/${pathPart(userId)}/${pathPart(slug)}/${pathPart(args.componentName)}`;
189344
189494
  }
189345
189495
  languageFileUrl(args) {
189346
189496
  const base = this.componentUrl(args);
189347
189497
  const encodedPath = normalizeObjectPath(args.objectPath);
189348
189498
  if (args.revision !== undefined) {
189499
+ if (args.isPublic) {
189500
+ throw new PieStorageError("revision is not supported for public components");
189501
+ }
189349
189502
  return `${base}/revisions/${args.revision}/${STORAGE_LANGUAGE}/${encodedPath}`;
189350
189503
  }
189351
189504
  return `${base}/${STORAGE_LANGUAGE}/${encodedPath}`;
@@ -189353,6 +189506,9 @@ class PieStorageService {
189353
189506
  componentTreeUrl(args) {
189354
189507
  const base = this.componentUrl(args);
189355
189508
  if (args.revision !== undefined) {
189509
+ if (args.isPublic) {
189510
+ throw new PieStorageError("revision is not supported for public components");
189511
+ }
189356
189512
  return `${base}/revisions/${args.revision}`;
189357
189513
  }
189358
189514
  return base;
@@ -189360,6 +189516,23 @@ class PieStorageService {
189360
189516
  revisionsUrl(args) {
189361
189517
  return `${this.componentUrl(args)}/revisions`;
189362
189518
  }
189519
+ publicMarkUrl(args) {
189520
+ return `${this.componentUrl(args)}/public`;
189521
+ }
189522
+ historyUrl(args) {
189523
+ const base = `${this.componentUrl(args)}/history`;
189524
+ const params = new URLSearchParams;
189525
+ if (args.page !== undefined)
189526
+ params.set("page", String(args.page));
189527
+ if (args.perPage !== undefined)
189528
+ params.set("per_page", String(args.perPage));
189529
+ if (args.from !== undefined)
189530
+ params.set("from", String(args.from));
189531
+ if (args.to !== undefined)
189532
+ params.set("to", String(args.to));
189533
+ const qs2 = params.toString();
189534
+ return qs2 ? `${base}?${qs2}` : base;
189535
+ }
189363
189536
  languageBatchUrl(args) {
189364
189537
  return `${this.componentUrl(args)}/batch/${STORAGE_LANGUAGE}`;
189365
189538
  }
@@ -189373,7 +189546,11 @@ class PieStorageService {
189373
189546
  }
189374
189547
  async listComponent(args) {
189375
189548
  const url = this.componentTreeUrl(args);
189376
- const response = await this.request({ method: "GET", url });
189549
+ const response = await this.request({
189550
+ method: "GET",
189551
+ url,
189552
+ noAuth: args.isPublic
189553
+ });
189377
189554
  const payload = await response.json();
189378
189555
  if (args.revision !== undefined) {
189379
189556
  const inner = payload.tree;
@@ -189387,6 +189564,21 @@ class PieStorageService {
189387
189564
  const response = await this.request({ method: "GET", url });
189388
189565
  return parseComponentRevisionList(await response.json());
189389
189566
  }
189567
+ async markComponentPublic(args) {
189568
+ const url = this.publicMarkUrl(args);
189569
+ const response = await this.request({ method: "PUT", url });
189570
+ return parsePublicComponentState(await response.json());
189571
+ }
189572
+ async markComponentPrivate(args) {
189573
+ const url = this.publicMarkUrl(args);
189574
+ const response = await this.request({ method: "DELETE", url });
189575
+ return parsePublicComponentState(await response.json());
189576
+ }
189577
+ async getHistory(args) {
189578
+ const url = this.historyUrl(args);
189579
+ const response = await this.request({ method: "GET", url });
189580
+ return parseComponentHistory(await response.json());
189581
+ }
189390
189582
  async deleteComponent(args) {
189391
189583
  const url = this.componentUrl(args);
189392
189584
  await this.request({ method: "DELETE", url });
@@ -189488,7 +189680,11 @@ class PieStorageService {
189488
189680
  const fs9 = await import("node:fs");
189489
189681
  const path11 = await import("node:path");
189490
189682
  const url = this.languageFileUrl(args);
189491
- const response = await this.request({ method: "GET", url });
189683
+ const response = await this.request({
189684
+ method: "GET",
189685
+ url,
189686
+ noAuth: args.isPublic
189687
+ });
189492
189688
  const buf = Buffer.from(await response.arrayBuffer());
189493
189689
  fs9.mkdirSync(path11.dirname(args.targetPath), { recursive: true });
189494
189690
  fs9.writeFileSync(args.targetPath, buf);
@@ -189513,9 +189709,9 @@ class PieStorageService {
189513
189709
  }
189514
189710
  return downloaded;
189515
189711
  }
189516
- headers(extra) {
189712
+ headers(extra, noAuth) {
189517
189713
  const base = {};
189518
- if (this.settings.apiKey)
189714
+ if (!noAuth && this.settings.apiKey)
189519
189715
  base["x-api-key"] = this.settings.apiKey;
189520
189716
  return { ...base, ...extra ?? {} };
189521
189717
  }
@@ -189526,7 +189722,7 @@ class PieStorageService {
189526
189722
  try {
189527
189723
  response = await fetch(opts.url, {
189528
189724
  method: opts.method,
189529
- headers: this.headers(opts.headers),
189725
+ headers: this.headers(opts.headers, opts.noAuth),
189530
189726
  body: opts.body,
189531
189727
  signal: controller.signal
189532
189728
  });
@@ -189547,14 +189743,17 @@ ${detail}` : `${opts.method} ${opts.url} failed: ${response.status}`;
189547
189743
  }
189548
189744
 
189549
189745
  // src/code/commands/cardRemote/cardRef.ts
189550
- var parseCardRef = (input) => {
189551
- const atIndex = input.indexOf("@");
189746
+ var parseNameAndRevision = (namePart, raw) => {
189747
+ const atIndex = namePart.indexOf("@");
189552
189748
  if (atIndex === -1)
189553
- return { componentName: input };
189554
- const componentName = input.slice(0, atIndex);
189555
- const revisionPart = input.slice(atIndex + 1);
189749
+ return { componentName: namePart };
189750
+ const componentName = namePart.slice(0, atIndex);
189751
+ const revisionPart = namePart.slice(atIndex + 1);
189752
+ if (!componentName) {
189753
+ throw new Error(`missing component name in ${JSON.stringify(raw)}`);
189754
+ }
189556
189755
  if (!revisionPart) {
189557
- throw new Error(`missing revision after '@' in ${JSON.stringify(input)}`);
189756
+ throw new Error(`missing revision after '@' in ${JSON.stringify(raw)}`);
189558
189757
  }
189559
189758
  if (!/^\d+$/.test(revisionPart)) {
189560
189759
  throw new Error(`revision must be a positive integer, got ${JSON.stringify(revisionPart)}`);
@@ -189565,13 +189764,51 @@ var parseCardRef = (input) => {
189565
189764
  }
189566
189765
  return { componentName, revision };
189567
189766
  };
189767
+ var parseCardRef = (input) => {
189768
+ if (!input) {
189769
+ throw new Error("card ref must not be empty");
189770
+ }
189771
+ if (input.startsWith("r/")) {
189772
+ const rest = input.slice(2);
189773
+ const parts2 = rest.split("/");
189774
+ if (parts2.length !== 2 || !parts2[0] || !parts2[1]) {
189775
+ throw new Error(`expected r/<user>/<Component>, got ${JSON.stringify(input)}`);
189776
+ }
189777
+ const [userId, namePart] = parts2;
189778
+ const { componentName, revision } = parseNameAndRevision(namePart, input);
189779
+ if (revision !== undefined) {
189780
+ throw new Error("revision suffix is not supported for public refs (r/...)");
189781
+ }
189782
+ return { componentName, userId, isPublic: true };
189783
+ }
189784
+ const parts = input.split("/");
189785
+ if (parts.length === 1) {
189786
+ return parseNameAndRevision(input, input);
189787
+ }
189788
+ if (parts.length === 2) {
189789
+ const [project, namePart] = parts;
189790
+ if (!project || !namePart) {
189791
+ throw new Error(`expected <project>/<Component>, got ${JSON.stringify(input)}`);
189792
+ }
189793
+ const { componentName, revision } = parseNameAndRevision(namePart, input);
189794
+ return { componentName, revision, project };
189795
+ }
189796
+ throw new Error(`invalid card ref ${JSON.stringify(input)}: expected <Component>, <project>/<Component>, or r/<user>/<Component>`);
189797
+ };
189568
189798
 
189569
189799
  // src/code/commands/cardRemote/push.ts
189570
189800
  var cardRemotePushCommand = async (cardRef) => {
189571
- const { componentName, revision } = parseCardRef(cardRef);
189572
- if (revision !== undefined) {
189801
+ const ref = parseCardRef(cardRef);
189802
+ if (ref.revision !== undefined) {
189573
189803
  throw new Error("push does not accept a revision suffix");
189574
189804
  }
189805
+ if (ref.isPublic) {
189806
+ throw new Error("push does not accept public refs (r/...)");
189807
+ }
189808
+ if (ref.project || ref.userId) {
189809
+ throw new Error("push does not accept project/user override; pass just <ComponentName>");
189810
+ }
189811
+ const { componentName } = ref;
189575
189812
  if (!/^[A-Z][A-Za-z0-9]+$/.test(componentName)) {
189576
189813
  throw new Error("Component name must start with uppercase letter and contain only letters and numbers");
189577
189814
  }
@@ -189626,12 +189863,15 @@ var latestRevisionNumber = async (service, componentName) => {
189626
189863
  var import_node_fs3 = __toESM(require("node:fs"));
189627
189864
  var import_node_path4 = __toESM(require("node:path"));
189628
189865
  var cardRemotePullCommand = async (cardRef) => {
189629
- const { componentName, revision } = parseCardRef(cardRef);
189866
+ const ref = parseCardRef(cardRef);
189867
+ const { componentName, revision, isPublic } = ref;
189630
189868
  const settings = loadSettings();
189631
- if (!settings.userId) {
189869
+ const effectiveUserId = ref.userId ?? settings.userId;
189870
+ if (!effectiveUserId) {
189632
189871
  throw new Error("user_id is required (set PIE_USER_ID in env or .env; run `pieui login`)");
189633
189872
  }
189634
- if (!settings.project) {
189873
+ const effectiveProject = isPublic ? undefined : ref.project ?? settings.project;
189874
+ if (!isPublic && !effectiveProject) {
189635
189875
  throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG in env or .env)");
189636
189876
  }
189637
189877
  const componentDir = import_node_path4.default.join(settings.componentsDir, componentName);
@@ -189645,23 +189885,27 @@ var cardRemotePullCommand = async (cardRef) => {
189645
189885
  downloaded = await service.downloadComponentDirectory({
189646
189886
  componentName,
189647
189887
  targetDir: tempDir,
189648
- revision
189888
+ revision,
189889
+ userId: effectiveUserId,
189890
+ project: effectiveProject,
189891
+ isPublic
189649
189892
  });
189650
189893
  } catch (error) {
189651
189894
  import_node_fs3.default.rmSync(tempDir, { recursive: true, force: true });
189652
189895
  throw error;
189653
189896
  }
189897
+ const sourceLabel = isPublic ? `r/${effectiveUserId}/${componentName}` : ref.project ? `${effectiveProject}/${componentName}` : componentName;
189898
+ const suffix = revision !== undefined ? `@${revision}` : "";
189654
189899
  if (downloaded.length === 0) {
189655
189900
  import_node_fs3.default.rmSync(tempDir, { recursive: true, force: true });
189656
- const suffix2 = revision !== undefined ? `@${revision}` : "";
189657
- throw new Error(`No typescript files found for remote component ${componentName}${suffix2} (user_id=${settings.userId}, project=${settings.project})`);
189901
+ const where = isPublic ? `user_id=${effectiveUserId} (public)` : `user_id=${effectiveUserId}, project=${effectiveProject}`;
189902
+ throw new Error(`No typescript files found for remote component ${sourceLabel}${suffix} (${where})`);
189658
189903
  }
189659
189904
  if (import_node_fs3.default.existsSync(componentDir)) {
189660
189905
  import_node_fs3.default.rmSync(componentDir, { recursive: true, force: true });
189661
189906
  }
189662
189907
  import_node_fs3.default.renameSync(tempDir, componentDir);
189663
- const suffix = revision !== undefined ? `@${revision}` : "";
189664
- console.log(`[pieui] Pulled card: ${componentName}${suffix}`);
189908
+ console.log(`[pieui] Pulled card: ${sourceLabel}${suffix}`);
189665
189909
  for (const p of downloaded) {
189666
189910
  const relative = import_node_path4.default.relative(tempDir, p);
189667
189911
  console.log(`[pieui] Path: ${import_node_path4.default.join(componentDir, relative)}`);
@@ -189701,6 +189945,114 @@ var cardRemoteRemoveCommand = async (componentName) => {
189701
189945
  console.log(`[pieui] Removed remote component: ${componentName}`);
189702
189946
  };
189703
189947
 
189948
+ // src/code/commands/cardRemote/history.ts
189949
+ var extractPath = (key, componentName) => {
189950
+ const marker = `/${componentName}/${STORAGE_LANGUAGE}/`;
189951
+ const idx = key.indexOf(marker);
189952
+ if (idx === -1)
189953
+ return key;
189954
+ return key.slice(idx + marker.length);
189955
+ };
189956
+ var formatFileBlock = (file, componentName) => {
189957
+ const path13 = extractPath(file.key, componentName);
189958
+ const before = file.status === "added" ? "a//dev/null" : `a/${path13}`;
189959
+ const after = file.status === "deleted" ? "b//dev/null" : `b/${path13}`;
189960
+ const lines = [];
189961
+ lines.push(`diff --git ${before} ${after}`);
189962
+ lines.push(`${file.status} +${file.additions} -${file.deletions} ${path13}`);
189963
+ if (file.isBinary) {
189964
+ lines.push("Binary files differ");
189965
+ } else if (file.patch) {
189966
+ lines.push(file.patch.replace(/\n+$/, ""));
189967
+ }
189968
+ return lines;
189969
+ };
189970
+ var formatRevisionBlock = (entry, componentName) => {
189971
+ const lines = [];
189972
+ lines.push(`revision ${componentName}@${entry.revision}`);
189973
+ lines.push(`date ${entry.createdAt}`);
189974
+ lines.push(`mutation ${entry.mutation}`);
189975
+ if (entry.previousRevision !== null) {
189976
+ lines.push(`previous ${entry.previousRevision}`);
189977
+ }
189978
+ if (entry.deleted) {
189979
+ lines.push("deleted true");
189980
+ }
189981
+ for (const file of entry.files) {
189982
+ lines.push("");
189983
+ lines.push(...formatFileBlock(file, componentName));
189984
+ }
189985
+ return lines;
189986
+ };
189987
+ var cardRemoteHistoryCommand = async (options) => {
189988
+ const settings = loadSettings();
189989
+ if (!settings.userId) {
189990
+ throw new Error("user_id is required (set PIE_USER_ID in env or .env)");
189991
+ }
189992
+ if (!settings.project) {
189993
+ throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG)");
189994
+ }
189995
+ if (options.from !== undefined && options.to !== undefined && options.from > options.to) {
189996
+ throw new Error("--from must be <= --to");
189997
+ }
189998
+ const service = new PieStorageService(settings);
189999
+ const history = await service.getHistory({
190000
+ componentName: options.componentName,
190001
+ page: options.page,
190002
+ perPage: options.perPage,
190003
+ from: options.from,
190004
+ to: options.to
190005
+ });
190006
+ const output = [];
190007
+ output.push(`component ${history.userId}/${history.project}/${history.componentName}`);
190008
+ output.push(`page ${history.page} per-page ${history.perPage} total-revisions ${history.totalRevisions}`);
190009
+ if (history.fromRevision !== null || history.toRevision !== null) {
190010
+ const from = history.fromRevision !== null ? String(history.fromRevision) : "*";
190011
+ const to = history.toRevision !== null ? String(history.toRevision) : "*";
190012
+ output.push(`range ${from}..${to}`);
190013
+ }
190014
+ for (const entry of history.entries) {
190015
+ output.push("");
190016
+ output.push(...formatRevisionBlock(entry, history.componentName));
190017
+ }
190018
+ console.log(output.join(`
190019
+ `));
190020
+ };
190021
+
190022
+ // src/code/commands/cardRemote/public.ts
190023
+ var cardRemotePublicCommand = async (componentName) => {
190024
+ const settings = loadSettings();
190025
+ if (!settings.userId) {
190026
+ throw new Error("user_id is required (set PIE_USER_ID in env or .env)");
190027
+ }
190028
+ if (!settings.project) {
190029
+ throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG)");
190030
+ }
190031
+ const service = new PieStorageService(settings);
190032
+ const state = await service.markComponentPublic({ componentName });
190033
+ console.log(`[pieui] Marked public: ${state.componentName} (user=${state.userId} project=${state.project})`);
190034
+ console.log(`[pieui] is_public: ${state.isPublic}`);
190035
+ if (state.publicRegistryName) {
190036
+ console.log(`[pieui] Public registry name: ${state.publicRegistryName}`);
190037
+ }
190038
+ console.log(`[pieui] Public read URL: <api>/public-components/${state.userId}/${state.componentName}`);
190039
+ };
190040
+
190041
+ // src/code/commands/cardRemote/private.ts
190042
+ var cardRemotePrivateCommand = async (componentName) => {
190043
+ const settings = loadSettings();
190044
+ if (!settings.userId) {
190045
+ throw new Error("user_id is required (set PIE_USER_ID in env or .env)");
190046
+ }
190047
+ if (!settings.project) {
190048
+ throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG)");
190049
+ }
190050
+ const service = new PieStorageService(settings);
190051
+ const state = await service.markComponentPrivate({ componentName });
190052
+ console.log(`[pieui] Marked private: ${state.componentName} (user=${state.userId} project=${state.project})`);
190053
+ console.log(`[pieui] is_public: ${state.isPublic}`);
190054
+ };
190055
+
189704
190056
  // src/code/commands/pageAdd.ts
189705
190057
  var import_fs8 = __toESM(require("fs"));
189706
190058
  var import_path10 = __toESM(require("path"));
@@ -190247,7 +190599,11 @@ var main = async () => {
190247
190599
  remoteUserId,
190248
190600
  remoteProject,
190249
190601
  pageAction,
190250
- pagePath
190602
+ pagePath,
190603
+ historyPage,
190604
+ historyPerPage,
190605
+ historyFrom,
190606
+ historyTo
190251
190607
  } = parseArgs(process.argv.slice(2));
190252
190608
  console.log(`[pieui] CLI started with command: "${command}"`);
190253
190609
  switch (command) {
@@ -190309,7 +190665,25 @@ var main = async () => {
190309
190665
  await cardRemoteRemoveCommand(componentName);
190310
190666
  return;
190311
190667
  }
190312
- console.error("[pieui] Error: Supported card remote subcommands: push, pull, list, remove");
190668
+ if (cardRemoteAction === "history") {
190669
+ await cardRemoteHistoryCommand({
190670
+ componentName,
190671
+ page: historyPage,
190672
+ perPage: historyPerPage,
190673
+ from: historyFrom,
190674
+ to: historyTo
190675
+ });
190676
+ return;
190677
+ }
190678
+ if (cardRemoteAction === "public") {
190679
+ await cardRemotePublicCommand(componentName);
190680
+ return;
190681
+ }
190682
+ if (cardRemoteAction === "private") {
190683
+ await cardRemotePrivateCommand(componentName);
190684
+ return;
190685
+ }
190686
+ console.error("[pieui] Error: Supported card remote subcommands: push, pull, list, remove, history, public, private");
190313
190687
  printUsage();
190314
190688
  process.exit(1);
190315
190689
  }
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/code/args.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAMR,UAAU,EACb,MAAM,SAAS,CAAA;AAEhB,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,KAAG,UAiL1C,CAAA;AAED,eAAO,MAAM,UAAU,YAuKtB,CAAA"}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/code/args.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAMR,UAAU,EACb,MAAM,SAAS,CAAA;AAEhB,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,KAAG,UAoP1C,CAAA;AAED,eAAO,MAAM,UAAU,YA2MtB,CAAA"}
@@ -1,6 +1,9 @@
1
1
  export type CardRef = {
2
2
  componentName: string;
3
3
  revision?: number;
4
+ userId?: string;
5
+ project?: string;
6
+ isPublic?: boolean;
4
7
  };
5
8
  export declare const parseCardRef: (input: string) => CardRef;
6
9
  //# sourceMappingURL=cardRef.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cardRef.d.ts","sourceRoot":"","sources":["../../../../src/code/commands/cardRemote/cardRef.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAElE,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,OAkB5C,CAAA"}
1
+ {"version":3,"file":"cardRef.d.ts","sourceRoot":"","sources":["../../../../src/code/commands/cardRemote/cardRef.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACrB,CAAA;AA4BD,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,OA4C5C,CAAA"}