@swarm.ing/pieui 2.0.26 → 2.0.29

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 (57) hide show
  1. package/dist/cli.js +1236 -1013
  2. package/dist/code/args.d.ts.map +1 -1
  3. package/dist/code/commands/add.d.ts.map +1 -1
  4. package/dist/code/commands/cardAddStory.d.ts +3 -1
  5. package/dist/code/commands/cardAddStory.d.ts.map +1 -1
  6. package/dist/code/commands/cardDumpMetadata.d.ts.map +1 -1
  7. package/dist/code/commands/cardPull.d.ts.map +1 -1
  8. package/dist/code/commands/cardRemote/pull.d.ts.map +1 -1
  9. package/dist/code/commands/cardRemote/push.d.ts.map +1 -1
  10. package/dist/code/introspection/extractDescription.d.ts +34 -0
  11. package/dist/code/introspection/extractDescription.d.ts.map +1 -0
  12. package/dist/code/introspection/extractEvents.d.ts +1 -1
  13. package/dist/code/introspection/extractEvents.d.ts.map +1 -1
  14. package/dist/code/introspection/index.d.ts +1 -0
  15. package/dist/code/introspection/index.d.ts.map +1 -1
  16. package/dist/code/patchPieCardForwarding.d.ts +5 -2
  17. package/dist/code/patchPieCardForwarding.d.ts.map +1 -1
  18. package/dist/code/services/dumpEnvelope.d.ts +26 -0
  19. package/dist/code/services/dumpEnvelope.d.ts.map +1 -0
  20. package/dist/code/services/storage.d.ts +19 -0
  21. package/dist/code/services/storage.d.ts.map +1 -1
  22. package/dist/code/templates/componentTypes.d.ts.map +1 -1
  23. package/dist/code/templates/pages/components/complexComponent.d.ts.map +1 -1
  24. package/dist/code/templates/pages/components/complexContainerComponent.d.ts.map +1 -1
  25. package/dist/code/templates/pages/components/shared.d.ts.map +1 -1
  26. package/dist/code/templates/pages/components/simpleComponent.d.ts.map +1 -1
  27. package/dist/code/templates/pages/components/simpleContainerComponent.d.ts.map +1 -1
  28. package/dist/code/templates/pages/index.d.ts +1 -1
  29. package/dist/code/templates/pages/index.d.ts.map +1 -1
  30. package/dist/code/types.d.ts +4 -0
  31. package/dist/code/types.d.ts.map +1 -1
  32. package/dist/components/PieCard/index.d.ts +1 -1
  33. package/dist/components/PieCard/index.d.ts.map +1 -1
  34. package/dist/components/PieCard/types/index.d.ts +13 -4
  35. package/dist/components/PieCard/types/index.d.ts.map +1 -1
  36. package/dist/components/index.esm.js +1 -1
  37. package/dist/components/index.js +1 -1
  38. package/dist/index.d.ts +1 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.esm.js +1 -2
  41. package/dist/index.js +1 -2
  42. package/dist/storybook/addon/index.esm.js +1 -1
  43. package/dist/storybook/addon/index.js +1 -1
  44. package/dist/storybook/addon/manager.js +2 -2
  45. package/dist/storybook/index.esm.js +1 -1
  46. package/dist/storybook/index.js +1 -1
  47. package/dist/tests/cardPullJson.test.d.ts +12 -0
  48. package/dist/tests/cardPullJson.test.d.ts.map +1 -0
  49. package/dist/tests/checkSyncConfig.test.d.ts +12 -0
  50. package/dist/tests/checkSyncConfig.test.d.ts.map +1 -0
  51. package/dist/tests/dumpMetadataEnvelope.test.d.ts +13 -0
  52. package/dist/tests/dumpMetadataEnvelope.test.d.ts.map +1 -0
  53. package/dist/tests/extractEventsStrict.test.d.ts +12 -0
  54. package/dist/tests/extractEventsStrict.test.d.ts.map +1 -0
  55. package/dist/types/index.d.ts +12 -0
  56. package/dist/types/index.d.ts.map +1 -1
  57. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -4,15 +4,29 @@ var __getProtoOf = Object.getPrototypeOf;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
7
12
  var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
8
20
  target = mod != null ? __create(__getProtoOf(mod)) : {};
9
21
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
22
  for (let key of __getOwnPropNames(mod))
11
23
  if (!__hasOwnProp.call(to, key))
12
24
  __defProp(to, key, {
13
- get: () => mod[key],
25
+ get: __accessProp.bind(mod, key),
14
26
  enumerable: true
15
27
  });
28
+ if (canCache)
29
+ cache.set(mod, to);
16
30
  return to;
17
31
  };
18
32
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
@@ -574,8 +588,7 @@ var require_index_min = __commonJS((exports2) => {
574
588
  return true;
575
589
  return false;
576
590
  }
577
- debug(...t) {
578
- }
591
+ debug(...t) {}
579
592
  make() {
580
593
  let t = this.pattern, e = this.options;
581
594
  if (!e.nocomment && t.charAt(0) === "#") {
@@ -1105,12 +1118,9 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
1105
1118
  return !!a && !!o && (i || r()) - o > a;
1106
1119
  };
1107
1120
  }
1108
- #C = () => {
1109
- };
1110
- #D = () => {
1111
- };
1112
- #W = () => {
1113
- };
1121
+ #C = () => {};
1122
+ #D = () => {};
1123
+ #W = () => {};
1114
1124
  #_ = () => false;
1115
1125
  #$() {
1116
1126
  let t = new Nt(this.#t);
@@ -1137,10 +1147,8 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
1137
1147
  this.#f += t[e], i && (i.entrySize = s, i.totalCalculatedSize = this.#f);
1138
1148
  };
1139
1149
  }
1140
- #L = (t) => {
1141
- };
1142
- #j = (t, e, s) => {
1143
- };
1150
+ #L = (t) => {};
1151
+ #j = (t, e, s) => {};
1144
1152
  #B = (t, e, s, i) => {
1145
1153
  if (s || i)
1146
1154
  throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");
@@ -1507,8 +1515,7 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
1507
1515
  unpipe() {
1508
1516
  this.dest.removeListener("drain", this.ondrain);
1509
1517
  }
1510
- proxyErrors(t) {
1511
- }
1518
+ proxyErrors(t) {}
1512
1519
  end() {
1513
1520
  this.unpipe(), this.opts.end && this.dest.end();
1514
1521
  }
@@ -1579,8 +1586,7 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
1579
1586
  get aborted() {
1580
1587
  return this[Ut];
1581
1588
  }
1582
- set aborted(t) {
1583
- }
1589
+ set aborted(t) {}
1584
1590
  write(t, e, s) {
1585
1591
  if (this[Ut])
1586
1592
  return false;
@@ -1791,8 +1797,7 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
1791
1797
  });
1792
1798
  }, throw: e, return: e, [Symbol.asyncIterator]() {
1793
1799
  return this;
1794
- }, [Symbol.asyncDispose]: async () => {
1795
- } };
1800
+ }, [Symbol.asyncDispose]: async () => {} };
1796
1801
  }
1797
1802
  [Symbol.iterator]() {
1798
1803
  this[D] = false;
@@ -1804,8 +1809,7 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
1804
1809
  };
1805
1810
  return this.once("end", e), this.once(be, e), this.once(O, e), { next: s, throw: e, return: e, [Symbol.iterator]() {
1806
1811
  return this;
1807
- }, [Symbol.dispose]: () => {
1808
- } };
1812
+ }, [Symbol.dispose]: () => {} };
1809
1813
  }
1810
1814
  destroy(t) {
1811
1815
  if (this[O])
@@ -2256,8 +2260,7 @@ globstar while`, t, d, e, u, m), this.matchOne(t.slice(d), e.slice(u), s))
2256
2260
  if (this.#H)
2257
2261
  await this.#H;
2258
2262
  else {
2259
- let s = () => {
2260
- };
2263
+ let s = () => {};
2261
2264
  this.#H = new Promise((i) => s = i);
2262
2265
  try {
2263
2266
  for (let i of await this.#t.promises.readdir(e, { withFileTypes: true }))
@@ -7291,8 +7294,7 @@ var require_typescript = __commonJS((exports2, module2) => {
7291
7294
  return value2;
7292
7295
  return Debug.fail(`Invalid cast. The supplied value ${value2} did not pass the test '${Debug.getFunctionName(test)}'.`);
7293
7296
  }
7294
- function noop(_) {
7295
- }
7297
+ function noop(_) {}
7296
7298
  function returnFalse() {
7297
7299
  return false;
7298
7300
  }
@@ -7622,8 +7624,7 @@ var require_typescript = __commonJS((exports2, module2) => {
7622
7624
  function not(fn) {
7623
7625
  return (...args) => !fn(...args);
7624
7626
  }
7625
- function assertType(_) {
7626
- }
7627
+ function assertType(_) {}
7627
7628
  function singleElementArray(t) {
7628
7629
  return t === undefined ? undefined : [t];
7629
7630
  }
@@ -7894,8 +7895,7 @@ Verbose Debug Information: ` + (typeof verboseDebugInfo === "string" ? verboseDe
7894
7895
  }
7895
7896
  }
7896
7897
  Debug2.assertMissingNode = assertMissingNode;
7897
- function type(_value) {
7898
- }
7898
+ function type(_value) {}
7899
7899
  Debug2.type = type;
7900
7900
  function getFunctionName(func) {
7901
7901
  if (typeof func !== "function") {
@@ -8906,8 +8906,7 @@ ${lanes.join(`
8906
8906
  performance: performance2
8907
8907
  };
8908
8908
  }
8909
- } catch {
8910
- }
8909
+ } catch {}
8911
8910
  }
8912
8911
  if (typeof performance === "object") {
8913
8912
  return {
@@ -12054,8 +12053,7 @@ ${lanes.join(`
12054
12053
  tryEnableSourceMapsForHost() {
12055
12054
  try {
12056
12055
  (()=>{throw new Error("Cannot require module "+"source-map-support");})().install();
12057
- } catch {
12058
- }
12056
+ } catch {}
12059
12057
  },
12060
12058
  setTimeout,
12061
12059
  clearTimeout,
@@ -12138,8 +12136,7 @@ ${lanes.join(`
12138
12136
  }
12139
12137
  try {
12140
12138
  _fs.mkdirSync(_path.dirname(profilePath), { recursive: true });
12141
- } catch {
12142
- }
12139
+ } catch {}
12143
12140
  _fs.writeFileSync(profilePath, JSON.stringify(cleanupPaths(profile)));
12144
12141
  }
12145
12142
  activeSession = undefined;
@@ -64241,8 +64238,7 @@ ${lanes.join(`
64241
64238
  function getAnonymousPartialType(type2) {
64242
64239
  const members = createSymbolTable();
64243
64240
  for (const prop of getPropertiesOfType(type2)) {
64244
- if (getDeclarationModifierFlagsFromSymbol(prop) & (2 | 4)) {
64245
- } else if (isSpreadableProperty(prop)) {
64241
+ if (getDeclarationModifierFlagsFromSymbol(prop) & (2 | 4)) {} else if (isSpreadableProperty(prop)) {
64246
64242
  const isSetonlyAccessor = prop.flags & 65536 && !(prop.flags & 32768);
64247
64243
  const flags = 4 | 16777216;
64248
64244
  const result = createSymbol(flags, prop.escapedName, getIsLateCheckFlag(prop) | (readonly ? 8 : 0));
@@ -66554,8 +66550,7 @@ ${lanes.join(`
66554
66550
  const id = getRelationKey(source2, target2, intersectionState, relation, false);
66555
66551
  const entry = relation.get(id);
66556
66552
  if (entry !== undefined) {
66557
- if (reportErrors2 && entry & 2 && !(entry & 96)) {
66558
- } else {
66553
+ if (reportErrors2 && entry & 2 && !(entry & 96)) {} else {
66559
66554
  if (outofbandVarianceMarkerHandler) {
66560
66555
  const saved = entry & 24;
66561
66556
  if (saved & 8) {
@@ -71907,8 +71902,7 @@ ${lanes.join(`
71907
71902
  return;
71908
71903
  }
71909
71904
  const symbol = resolveName(exportedName, exportedName.escapedText, 111551 | 788968 | 1920 | 2097152, undefined, true);
71910
- if (symbol && (symbol === undefinedSymbol || symbol === globalThisSymbol || symbol.declarations && isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) {
71911
- } else {
71905
+ if (symbol && (symbol === undefinedSymbol || symbol === globalThisSymbol || symbol.declarations && isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) {} else {
71912
71906
  const target = symbol && (symbol.flags & 2097152 ? resolveAlias(symbol) : symbol);
71913
71907
  if (!target || getSymbolFlags(target) & 111551) {
71914
71908
  markExportAsReferenced(location);
@@ -87940,8 +87934,7 @@ ${lanes.join(`
87940
87934
  if (!links2.hasReportedStatementInAmbientContext) {
87941
87935
  return links2.hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, Diagnostics.Statements_are_not_allowed_in_ambient_contexts);
87942
87936
  }
87943
- } else {
87944
- }
87937
+ } else {}
87945
87938
  }
87946
87939
  return false;
87947
87940
  }
@@ -89206,8 +89199,7 @@ ${lanes.join(`
89206
89199
  if (isRawSourceMap(parsed)) {
89207
89200
  return parsed;
89208
89201
  }
89209
- } catch {
89210
- }
89202
+ } catch {}
89211
89203
  return;
89212
89204
  }
89213
89205
  function decodeMappings(mappings) {
@@ -97406,8 +97398,7 @@ ${lanes.join(`
97406
97398
  ], 2));
97407
97399
  setParentRecursive(requireStatement, false);
97408
97400
  statements = insertStatementAfterCustomPrologue(statements.slice(), requireStatement);
97409
- } else {
97410
- }
97401
+ } else {}
97411
97402
  }
97412
97403
  }
97413
97404
  if (statements !== visited.statements) {
@@ -137184,8 +137175,7 @@ ${newComment.split(`
137184
137175
  var _a, _b, _c, _d;
137185
137176
  if (key === "constructor" && member.valueDeclaration) {
137186
137177
  const prototypeAssignment = (_d = (_c = (_b = (_a = symbol.exports) == null ? undefined : _a.get("prototype")) == null ? undefined : _b.declarations) == null ? undefined : _c[0]) == null ? undefined : _d.parent;
137187
- if (prototypeAssignment && isBinaryExpression(prototypeAssignment) && isObjectLiteralExpression(prototypeAssignment.right) && some(prototypeAssignment.right.properties, isConstructorAssignment)) {
137188
- } else {
137178
+ if (prototypeAssignment && isBinaryExpression(prototypeAssignment) && isObjectLiteralExpression(prototypeAssignment.right) && some(prototypeAssignment.right.properties, isConstructorAssignment)) {} else {
137189
137179
  changes.delete(sourceFile, member.valueDeclaration.parent);
137190
137180
  }
137191
137181
  return;
@@ -143707,8 +143697,7 @@ ${newComment.split(`
143707
143697
  usage.isNumber = true;
143708
143698
  } else if (otherOperandType.flags & 402653316) {
143709
143699
  usage.isString = true;
143710
- } else if (otherOperandType.flags & 1) {
143711
- } else {
143700
+ } else if (otherOperandType.flags & 1) {} else {
143712
143701
  usage.isNumberOrString = true;
143713
143702
  }
143714
143703
  break;
@@ -163169,8 +163158,7 @@ ${options.prefix}` : `
163169
163158
  ScriptTarget12["Latest"] = "esnext";
163170
163159
  return ScriptTarget12;
163171
163160
  })(ScriptTarget11 || {});
163172
- {
163173
- }
163161
+ {}
163174
163162
  var TextStorage = class {
163175
163163
  constructor(host, info, initialVersion) {
163176
163164
  this.host = host;
@@ -164700,24 +164688,24 @@ ${options.prefix}` : `
164700
164688
  }
164701
164689
  filesToStringWorker(writeProjectFileNames, writeFileExplaination, writeFileVersionAndText) {
164702
164690
  if (this.initialLoadPending)
164703
- return `\tFiles (0) InitialLoadPending
164691
+ return ` Files (0) InitialLoadPending
164704
164692
  `;
164705
164693
  if (!this.program)
164706
- return `\tFiles (0) NoProgram
164694
+ return ` Files (0) NoProgram
164707
164695
  `;
164708
164696
  const sourceFiles = this.program.getSourceFiles();
164709
- let strBuilder = `\tFiles (${sourceFiles.length})
164697
+ let strBuilder = ` Files (${sourceFiles.length})
164710
164698
  `;
164711
164699
  if (writeProjectFileNames) {
164712
164700
  for (const file of sourceFiles) {
164713
- strBuilder += `\t${file.fileName}${writeFileVersionAndText ? ` ${file.version} ${JSON.stringify(file.text)}` : ""}
164701
+ strBuilder += ` ${file.fileName}${writeFileVersionAndText ? ` ${file.version} ${JSON.stringify(file.text)}` : ""}
164714
164702
  `;
164715
164703
  }
164716
164704
  if (writeFileExplaination) {
164717
164705
  strBuilder += `
164718
164706
 
164719
164707
  `;
164720
- explainFiles(this.program, (s) => strBuilder += `\t${s}
164708
+ explainFiles(this.program, (s) => strBuilder += ` ${s}
164721
164709
  `);
164722
164710
  }
164723
164711
  }
@@ -166852,8 +166840,8 @@ ${options.prefix}` : `
166852
166840
  this.logger.info("Open files: ");
166853
166841
  this.openFiles.forEach((projectRootPath, path2) => {
166854
166842
  const info = this.getScriptInfoForPath(path2);
166855
- this.logger.info(`\tFileName: ${info.fileName} ProjectRootPath: ${projectRootPath}`);
166856
- this.logger.info(`\t\tProjects: ${info.containingProjects.map((p) => p.getProjectName())}`);
166843
+ this.logger.info(` FileName: ${info.fileName} ProjectRootPath: ${projectRootPath}`);
166844
+ this.logger.info(` Projects: ${info.containingProjects.map((p) => p.getProjectName())}`);
166857
166845
  });
166858
166846
  this.logger.endGroup();
166859
166847
  }
@@ -169833,8 +169821,7 @@ ${json}${newLine}`;
169833
169821
  File text of ${fileRequest.file}:${indent2(text)}
169834
169822
  `;
169835
169823
  }
169836
- } catch {
169837
- }
169824
+ } catch {}
169838
169825
  }
169839
169826
  if (err.ProgramFiles) {
169840
169827
  msg += `
@@ -171274,9 +171261,7 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
171274
171261
  const commands = args.command;
171275
171262
  for (const command of toArray(commands)) {
171276
171263
  const { file, project } = this.getFileAndProject(command);
171277
- project.getLanguageService().applyCodeActionCommand(command, this.getFormatOptions(file)).then((_result) => {
171278
- }, (_error) => {
171279
- });
171264
+ project.getLanguageService().applyCodeActionCommand(command, this.getFormatOptions(file)).then((_result) => {}, (_error) => {});
171280
171265
  }
171281
171266
  return {};
171282
171267
  }
@@ -171494,8 +171479,7 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
171494
171479
  const name = this.host.useCaseSensitiveFileNames ? fileName : toFileNameLowerCase(fileName);
171495
171480
  return normalizePath(name);
171496
171481
  }
171497
- exit() {
171498
- }
171482
+ exit() {}
171499
171483
  notRequired(request) {
171500
171484
  if (request)
171501
171485
  this.doOutput(undefined, request.command, request.seq, true, this.performanceData);
@@ -172694,7 +172678,7 @@ var require_make_error = __commonJS((exports2, module2) => {
172694
172678
  var defineProperty = Object.defineProperty;
172695
172679
  var captureStackTrace = Error.captureStackTrace;
172696
172680
  if (captureStackTrace === undefined) {
172697
- captureStackTrace = function captureStackTrace(error) {
172681
+ captureStackTrace = function captureStackTrace2(error) {
172698
172682
  var container = new Error;
172699
172683
  defineProperty(error, "stack", {
172700
172684
  configurable: true,
@@ -172750,14 +172734,12 @@ var require_make_error = __commonJS((exports2, module2) => {
172750
172734
  });
172751
172735
  }
172752
172736
  try {
172753
- var f = function() {
172754
- };
172737
+ var f = function() {};
172755
172738
  setFunctionName2(f, "foo");
172756
172739
  if (f.name === "foo") {
172757
172740
  return setFunctionName2;
172758
172741
  }
172759
- } catch (_) {
172760
- }
172742
+ } catch (_) {}
172761
172743
  }();
172762
172744
  function makeError(constructor, super_) {
172763
172745
  if (super_ == null || super_ === Error) {
@@ -174078,8 +174060,7 @@ var require_resolver_functions = __commonJS((exports2) => {
174078
174060
  let typesNodePackageJsonPath;
174079
174061
  try {
174080
174062
  typesNodePackageJsonPath = projectLocalResolveHelper("@types/node/package.json", true);
174081
- } catch {
174082
- }
174063
+ } catch {}
174083
174064
  if (typesNodePackageJsonPath) {
174084
174065
  const typeRoots = [(0, path_1.resolve)(typesNodePackageJsonPath, "../..")];
174085
174066
  ({ resolvedTypeReferenceDirective } = ts.resolveTypeReferenceDirective(typeDirectiveName, containingFile, {
@@ -174403,8 +174384,7 @@ var require_node_options = __commonJS((exports2) => {
174403
174384
  function getNodeOptionsEnvArgv() {
174404
174385
  const errors = [];
174405
174386
  const envArgv = ParseNodeOptionsEnvVar(process.env.NODE_OPTIONS || "", errors);
174406
- if (errors.length !== 0) {
174407
- }
174387
+ if (errors.length !== 0) {}
174408
174388
  return envArgv;
174409
174389
  }
174410
174390
  function ParseNodeOptionsEnvVar(node_options, errors) {
@@ -175280,7 +175260,7 @@ var require_acorn = __commonJS((exports2, module2) => {
175280
175260
  }
175281
175261
  return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
175282
175262
  }
175283
- var TokenType = function TokenType(label, conf) {
175263
+ var TokenType = function TokenType2(label, conf) {
175284
175264
  if (conf === undefined)
175285
175265
  conf = {};
175286
175266
  this.label = label;
@@ -175423,14 +175403,14 @@ var require_acorn = __commonJS((exports2, module2) => {
175423
175403
  return String.fromCharCode((code >> 10) + 55296, (code & 1023) + 56320);
175424
175404
  }
175425
175405
  var loneSurrogate = /(?:[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF])/;
175426
- var Position = function Position(line, col) {
175406
+ var Position = function Position2(line, col) {
175427
175407
  this.line = line;
175428
175408
  this.column = col;
175429
175409
  };
175430
175410
  Position.prototype.offset = function offset(n) {
175431
175411
  return new Position(this.line, this.column + n);
175432
175412
  };
175433
- var SourceLocation = function SourceLocation(p, start, end) {
175413
+ var SourceLocation = function SourceLocation2(p, start, end) {
175434
175414
  this.start = start;
175435
175415
  this.end = end;
175436
175416
  if (p.sourceFile !== null) {
@@ -175528,7 +175508,7 @@ Defaulting to 2020, but this will stop working in the future.`);
175528
175508
  return SCOPE_FUNCTION | (async ? SCOPE_ASYNC : 0) | (generator ? SCOPE_GENERATOR : 0);
175529
175509
  }
175530
175510
  var BIND_NONE = 0, BIND_VAR = 1, BIND_LEXICAL = 2, BIND_FUNCTION = 3, BIND_SIMPLE_CATCH = 4, BIND_OUTSIDE = 5;
175531
- var Parser = function Parser(options, input, startPos) {
175511
+ var Parser = function Parser2(options, input, startPos) {
175532
175512
  this.options = options = getOptions(options);
175533
175513
  this.sourceFile = options.sourceFile;
175534
175514
  this.keywords = wordsRegexp(keywords$1[options.ecmaVersion >= 6 ? 6 : options.sourceType === "module" ? "5module" : 5]);
@@ -175578,7 +175558,7 @@ Defaulting to 2020, but this will stop working in the future.`);
175578
175558
  this.privateNameStack = [];
175579
175559
  };
175580
175560
  var prototypeAccessors = { inFunction: { configurable: true }, inGenerator: { configurable: true }, inAsync: { configurable: true }, canAwait: { configurable: true }, allowReturn: { configurable: true }, allowSuper: { configurable: true }, allowDirectSuper: { configurable: true }, treatFunctionsAsVar: { configurable: true }, allowNewDotTarget: { configurable: true }, allowUsing: { configurable: true }, inClassStaticBlock: { configurable: true } };
175581
- Parser.prototype.parse = function parse() {
175561
+ Parser.prototype.parse = function parse2() {
175582
175562
  var node = this.options.program || this.startNode();
175583
175563
  this.nextToken();
175584
175564
  return this.parseTopLevel(node);
@@ -175659,15 +175639,15 @@ Defaulting to 2020, but this will stop working in the future.`);
175659
175639
  }
175660
175640
  return cls;
175661
175641
  };
175662
- Parser.parse = function parse(input, options) {
175642
+ Parser.parse = function parse2(input, options) {
175663
175643
  return new this(options, input).parse();
175664
175644
  };
175665
- Parser.parseExpressionAt = function parseExpressionAt(input, pos, options) {
175645
+ Parser.parseExpressionAt = function parseExpressionAt2(input, pos, options) {
175666
175646
  var parser = new this(options, input, pos);
175667
175647
  parser.nextToken();
175668
175648
  return parser.parseExpression();
175669
175649
  };
175670
- Parser.tokenizer = function tokenizer(input, options) {
175650
+ Parser.tokenizer = function tokenizer2(input, options) {
175671
175651
  return new this(options, input);
175672
175652
  };
175673
175653
  Object.defineProperties(Parser.prototype, prototypeAccessors);
@@ -175754,7 +175734,7 @@ Defaulting to 2020, but this will stop working in the future.`);
175754
175734
  pp$9.unexpected = function(pos) {
175755
175735
  this.raise(pos != null ? pos : this.start, "Unexpected token");
175756
175736
  };
175757
- var DestructuringErrors = function DestructuringErrors() {
175737
+ var DestructuringErrors = function DestructuringErrors2() {
175758
175738
  this.shorthandAssign = this.trailingComma = this.parenthesizedAssign = this.parenthesizedBind = this.doubleProto = -1;
175759
175739
  };
175760
175740
  pp$9.checkPatternErrors = function(refDestructuringErrors, isAssign) {
@@ -177174,7 +177154,7 @@ Defaulting to 2020, but this will stop working in the future.`);
177174
177154
  this.checkLValPattern(expr, bindingType, checkClashes);
177175
177155
  }
177176
177156
  };
177177
- var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
177157
+ var TokContext = function TokContext2(token, isExpr, preserveSpace, override, generator) {
177178
177158
  this.token = token;
177179
177159
  this.isExpr = !!isExpr;
177180
177160
  this.preserveSpace = !!preserveSpace;
@@ -177272,8 +177252,7 @@ Defaulting to 2020, but this will stop working in the future.`);
177272
177252
  this.context.push(statementParens ? types.p_stat : types.p_expr);
177273
177253
  this.exprAllowed = true;
177274
177254
  };
177275
- types$1.incDec.updateContext = function() {
177276
- };
177255
+ types$1.incDec.updateContext = function() {};
177277
177256
  types$1._function.updateContext = types$1._class.updateContext = function(prevType) {
177278
177257
  if (prevType.beforeExpr && prevType !== types$1._else && !(prevType === types$1.semi && this.curContext() !== types.p_stat) && !(prevType === types$1._return && lineBreak.test(this.input.slice(this.lastTokEnd, this.start))) && !((prevType === types$1.colon || prevType === types$1.braceL) && this.curContext() === types.b_stat)) {
177279
177258
  this.context.push(types.f_expr);
@@ -178383,7 +178362,7 @@ Defaulting to 2020, but this will stop working in the future.`);
178383
178362
  }
178384
178363
  };
178385
178364
  var pp$3 = Parser.prototype;
178386
- var Scope = function Scope(flags) {
178365
+ var Scope = function Scope2(flags) {
178387
178366
  this.flags = flags;
178388
178367
  this.var = [];
178389
178368
  this.lexical = [];
@@ -178462,7 +178441,7 @@ Defaulting to 2020, but this will stop working in the future.`);
178462
178441
  }
178463
178442
  }
178464
178443
  };
178465
- var Node = function Node(parser, pos, loc) {
178444
+ var Node = function Node2(parser, pos, loc) {
178466
178445
  this.type = "";
178467
178446
  this.start = pos;
178468
178447
  this.end = 0;
@@ -178566,7 +178545,7 @@ Defaulting to 2020, but this will stop working in the future.`);
178566
178545
  buildUnicodeData(ecmaVersion);
178567
178546
  }
178568
178547
  var pp$1 = Parser.prototype;
178569
- var BranchID = function BranchID(parent, base) {
178548
+ var BranchID = function BranchID2(parent, base) {
178570
178549
  this.parent = parent;
178571
178550
  this.base = base || this;
178572
178551
  };
@@ -178583,7 +178562,7 @@ Defaulting to 2020, but this will stop working in the future.`);
178583
178562
  BranchID.prototype.sibling = function sibling() {
178584
178563
  return new BranchID(this.parent, this.base);
178585
178564
  };
178586
- var RegExpValidationState = function RegExpValidationState(parser) {
178565
+ var RegExpValidationState = function RegExpValidationState2(parser) {
178587
178566
  this.parser = parser;
178588
178567
  this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "") + (parser.options.ecmaVersion >= 13 ? "d" : "") + (parser.options.ecmaVersion >= 15 ? "v" : "");
178589
178568
  this.unicodeProperties = data[parser.options.ecmaVersion >= 14 ? 14 : parser.options.ecmaVersion];
@@ -178779,8 +178758,7 @@ Defaulting to 2020, but this will stop working in the future.`);
178779
178758
  }
178780
178759
  };
178781
178760
  pp$1.regexp_alternative = function(state) {
178782
- while (state.pos < state.source.length && this.regexp_eatTerm(state)) {
178783
- }
178761
+ while (state.pos < state.source.length && this.regexp_eatTerm(state)) {}
178784
178762
  };
178785
178763
  pp$1.regexp_eatTerm = function(state) {
178786
178764
  if (this.regexp_eatAssertion(state)) {
@@ -179660,7 +179638,7 @@ Defaulting to 2020, but this will stop working in the future.`);
179660
179638
  }
179661
179639
  return true;
179662
179640
  };
179663
- var Token = function Token(p) {
179641
+ var Token = function Token2(p) {
179664
179642
  this.type = p.type;
179665
179643
  this.value = p.value;
179666
179644
  this.start = p.start;
@@ -180096,8 +180074,7 @@ Defaulting to 2020, but this will stop working in the future.`);
180096
180074
  var value2 = null;
180097
180075
  try {
180098
180076
  value2 = new RegExp(pattern, flags);
180099
- } catch (e) {
180100
- }
180077
+ } catch (e) {}
180101
180078
  return this.finishToken(types$1.regexp, { pattern, flags, value: value2 });
180102
180079
  };
180103
180080
  pp.readInt = function(radix, len, maybeLegacyOctalNumericLiteral) {
@@ -180581,7 +180558,7 @@ var require_walk = __commonJS((exports2, module2) => {
180581
180558
  return test;
180582
180559
  }
180583
180560
  }
180584
- var Found = function Found(node, state) {
180561
+ var Found = function Found2(node, state) {
180585
180562
  this.node = node;
180586
180563
  this.state = state;
180587
180564
  };
@@ -180716,8 +180693,7 @@ var require_walk = __commonJS((exports2, module2) => {
180716
180693
  function skipThrough(node, st, c) {
180717
180694
  c(node, st);
180718
180695
  }
180719
- function ignore(_node, _st, _c) {
180720
- }
180696
+ function ignore(_node, _st, _c) {}
180721
180697
  function visitNode(baseVisitor, type, node, st, c) {
180722
180698
  if (baseVisitor[type] == null) {
180723
180699
  throw new Error("No walker function defined for node type " + type);
@@ -181228,8 +181204,7 @@ var require_base = __commonJS((exports2) => {
181228
181204
  value: true
181229
181205
  });
181230
181206
  exports2.default = Diff;
181231
- function Diff() {
181232
- }
181207
+ function Diff() {}
181233
181208
  Diff.prototype = {
181234
181209
  diff: function diff(oldString, newString) {
181235
181210
  var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
@@ -181603,11 +181578,11 @@ var require_json = __commonJS((exports2) => {
181603
181578
  }
181604
181579
  function _typeof(obj) {
181605
181580
  if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
181606
- _typeof = function _typeof(obj2) {
181581
+ _typeof = function _typeof2(obj2) {
181607
181582
  return typeof obj2;
181608
181583
  };
181609
181584
  } else {
181610
- _typeof = function _typeof(obj2) {
181585
+ _typeof = function _typeof2(obj2) {
181611
181586
  return obj2 && typeof Symbol === "function" && obj2.constructor === Symbol && obj2 !== Symbol.prototype ? "symbol" : typeof obj2;
181612
181587
  };
181613
181588
  }
@@ -182018,7 +181993,7 @@ var require_create = __commonJS((exports2) => {
182018
181993
  }
182019
181994
  var hunks = [];
182020
181995
  var oldRangeStart = 0, newRangeStart = 0, curRange = [], oldLine = 1, newLine = 1;
182021
- var _loop = function _loop(i2) {
181996
+ var _loop = function _loop2(i2) {
182022
181997
  var current = diff[i2], lines = current.lines || current.value.replace(/\n$/, "").split(`
182023
181998
  `);
182024
181999
  current.lines = lines;
@@ -182816,8 +182791,7 @@ ${getTopLevelAwaitHint()}`;
182816
182791
  _error.stack = (_b2 = _error.stack) === null || _b2 === undefined ? undefined : _b2.replace(/(SyntaxError:.*)/, (_, $1) => `${$1}
182817
182792
 
182818
182793
  ${getTopLevelAwaitHint()}`);
182819
- } catch {
182820
- }
182794
+ } catch {}
182821
182795
  }
182822
182796
  callback(_error);
182823
182797
  }
@@ -182919,8 +182893,7 @@ ${module_1.builtinModules.filter((name) => !name.startsWith("_") && !name.includ
182919
182893
  return composeWith.readFile(path2);
182920
182894
  try {
182921
182895
  return (0, fs_1.readFileSync)(path2, "utf8");
182922
- } catch (err) {
182923
- }
182896
+ } catch (err) {}
182924
182897
  }
182925
182898
  function fileExists(path2) {
182926
182899
  if (path2 === state.path)
@@ -183383,8 +183356,7 @@ var require_swc = __commonJS((exports2) => {
183383
183356
  jsc: { target: swcTargets[swcTargetIndex] }
183384
183357
  });
183385
183358
  break;
183386
- } catch (e) {
183387
- }
183359
+ } catch (e) {}
183388
183360
  }
183389
183361
  swcTarget = swcTargets[swcTargetIndex];
183390
183362
  const keepClassNames = target >= 3;
@@ -184521,8 +184493,7 @@ var require_source_map_support = __commonJS((exports2, module2) => {
184521
184493
  if (!fs2.existsSync || !fs2.readFileSync) {
184522
184494
  fs2 = null;
184523
184495
  }
184524
- } catch (err) {
184525
- }
184496
+ } catch (err) {}
184526
184497
  function dynamicRequire(mod, request) {
184527
184498
  return mod.require(request);
184528
184499
  }
@@ -184668,8 +184639,7 @@ var require_source_map_support = __commonJS((exports2, module2) => {
184668
184639
  } else if (fs2.existsSync(path3)) {
184669
184640
  contents = fs2.readFileSync(path3, "utf8");
184670
184641
  }
184671
- } catch (er) {
184672
- }
184642
+ } catch (er) {}
184673
184643
  return setFileContentsCache(path3, contents);
184674
184644
  });
184675
184645
  function supportRelativeURL(file, url) {
@@ -184737,8 +184707,7 @@ var require_source_map_support = __commonJS((exports2, module2) => {
184737
184707
  if (sourceMapHeader) {
184738
184708
  return sourceMapHeader;
184739
184709
  }
184740
- } catch (e) {
184741
- }
184710
+ } catch (e) {}
184742
184711
  }
184743
184712
  fileData = retrieveFile(tryFileURLToPath(source));
184744
184713
  var re = /(?:\/\/[@#][\s]*sourceMappingURL=([^\s'"]+)[\s]*$)|(?:\/\*[@#][\s]*sourceMappingURL=([^\s*'"]+)[\s]*(?:\*\/)[\s]*$)/mg;
@@ -185157,8 +185126,7 @@ var require_source_map_support = __commonJS((exports2, module2) => {
185157
185126
  if (worker_threads.isMainThread === false) {
185158
185127
  installHandler = false;
185159
185128
  }
185160
- } catch (e) {
185161
- }
185129
+ } catch (e) {}
185162
185130
  if (installHandler && hasGlobalProcessEventEmitter()) {
185163
185131
  shimEmitUncaughtException();
185164
185132
  }
@@ -185269,8 +185237,7 @@ var require_node_internal_modules_esm_resolve = __commonJS((exports2, module2) =
185269
185237
  const { packageSubpath } = parsePackageName(afterNodeModulesPath);
185270
185238
  if (packageSubpath === ".")
185271
185239
  return;
185272
- } catch {
185273
- }
185240
+ } catch {}
185274
185241
  }
185275
185242
  }
185276
185243
  if (emittedPackageWarnings.has(pjsonPath + "|" + match))
@@ -185507,8 +185474,7 @@ var require_node_internal_modules_esm_resolve = __commonJS((exports2, module2) =
185507
185474
  try {
185508
185475
  new URL2(target);
185509
185476
  isURL = true;
185510
- } catch {
185511
- }
185477
+ } catch {}
185512
185478
  if (!isURL) {
185513
185479
  const exportTarget = pattern ? StringPrototypeReplace(target, patternRegEx, subpath) : target + subpath;
185514
185480
  return packageResolve(exportTarget, packageJSONUrl, conditions);
@@ -185832,8 +185798,7 @@ var require_node_internal_modules_esm_resolve = __commonJS((exports2, module2) =
185832
185798
  url: specifier
185833
185799
  };
185834
185800
  }
185835
- } catch {
185836
- }
185801
+ } catch {}
185837
185802
  if (parsed && parsed.protocol === builtinModuleProtocol)
185838
185803
  return { url: specifier };
185839
185804
  if (parsed && parsed.protocol !== "file:" && parsed.protocol !== "data:")
@@ -186036,8 +186001,7 @@ var require_esm = __commonJS((exports2) => {
186036
186001
  try {
186037
186002
  if (specifier.startsWith("file://"))
186038
186003
  cjsSpecifier = (0, url_1.fileURLToPath)(specifier);
186039
- } catch {
186040
- }
186004
+ } catch {}
186041
186005
  const resolution = (0, url_1.pathToFileURL)((0, module_1.createRequire)(process.cwd()).resolve(cjsSpecifier)).toString();
186042
186006
  rememberIsProbablyEntrypoint.add(resolution);
186043
186007
  rememberResolvedViaCommonjsFallback.add(resolution);
@@ -186188,8 +186152,7 @@ var require_dist = __commonJS((exports2) => {
186188
186152
  return repl_1.createRepl;
186189
186153
  } });
186190
186154
  var engineSupportsPackageTypeField = parseInt(process.versions.node.split(".")[0], 10) >= 12;
186191
- var assertScriptCanLoadAsCJS = engineSupportsPackageTypeField ? require_node_internal_modules_cjs_loader().assertScriptCanLoadAsCJSImpl : () => {
186192
- };
186155
+ var assertScriptCanLoadAsCJS = engineSupportsPackageTypeField ? require_node_internal_modules_cjs_loader().assertScriptCanLoadAsCJSImpl : () => {};
186193
186156
  exports2.REGISTER_INSTANCE = Symbol.for("ts-node.register.instance");
186194
186157
  exports2.env = process.env;
186195
186158
  exports2.INSPECT_CUSTOM = util.inspect.custom || "inspect";
@@ -186378,8 +186341,7 @@ ${diagnosticText}`);
186378
186341
  if (experimentalEsmLoader && path2.startsWith("file://")) {
186379
186342
  try {
186380
186343
  path2 = (0, url_1.fileURLToPath)(path2);
186381
- } catch (e) {
186382
- }
186344
+ } catch (e) {}
186383
186345
  }
186384
186346
  path2 = (0, util_1.normalizeSlashes)(path2);
186385
186347
  return ((_a3 = outputCache.get(path2)) === null || _a3 === undefined ? undefined : _a3.content) || "";
@@ -187325,8 +187287,7 @@ var require_typescript_json_schema = __commonJS((exports2) => {
187325
187287
  throw new Error("Not supported: root type undefined");
187326
187288
  }
187327
187289
  definition.type = "undefined";
187328
- } else if (flags & ts.TypeFlags.Any || flags & ts.TypeFlags.Unknown) {
187329
- } else if (propertyTypeString === "Date" && !this.args.rejectDateType) {
187290
+ } else if (flags & ts.TypeFlags.Any || flags & ts.TypeFlags.Unknown) {} else if (propertyTypeString === "Date" && !this.args.rejectDateType) {
187330
187291
  definition.type = "string";
187331
187292
  definition.format = definition.format || "date-time";
187332
187293
  } else if (propertyTypeString === "object") {
@@ -188196,7 +188157,7 @@ var require_typescript_json_schema = __commonJS((exports2) => {
188196
188157
  });
188197
188158
 
188198
188159
  // src/cli.ts
188199
- var import_node_path21 = __toESM(require("node:path"));
188160
+ var import_node_path22 = __toESM(require("node:path"));
188200
188161
 
188201
188162
  // src/code/args.ts
188202
188163
  var VALID_CARD_ACTIONS = [
@@ -188247,6 +188208,8 @@ var consumeFlags = (tokens) => {
188247
188208
  const positionals = [];
188248
188209
  let ajax = false;
188249
188210
  let io = false;
188211
+ let input = false;
188212
+ let force = false;
188250
188213
  for (let i = 0;i < tokens.length; i++) {
188251
188214
  const tok = tokens[i];
188252
188215
  if (tok === "--ajax") {
@@ -188257,6 +188220,14 @@ var consumeFlags = (tokens) => {
188257
188220
  io = true;
188258
188221
  continue;
188259
188222
  }
188223
+ if (tok === "--input") {
188224
+ input = true;
188225
+ continue;
188226
+ }
188227
+ if (tok === "--force" || tok === "-f") {
188228
+ force = true;
188229
+ continue;
188230
+ }
188260
188231
  if (tok === "--user" && tokens[i + 1]) {
188261
188232
  flags.remoteUserId = tokens[i + 1];
188262
188233
  i++;
@@ -188322,7 +188293,7 @@ var consumeFlags = (tokens) => {
188322
188293
  }
188323
188294
  positionals.push(tok);
188324
188295
  }
188325
- return { positionals, flags, boolFlags: { ajax, io } };
188296
+ return { positionals, flags, boolFlags: { ajax, io, input, force } };
188326
188297
  };
188327
188298
  var parseArgs = (argv) => {
188328
188299
  const [command = ""] = argv;
@@ -188372,6 +188343,7 @@ var parseArgs = (argv) => {
188372
188343
  if (action === "add") {
188373
188344
  result.cardAjax = boolFlags.ajax;
188374
188345
  result.cardIo = boolFlags.io;
188346
+ result.cardInput = boolFlags.input;
188375
188347
  if (flags.fromRaw !== undefined)
188376
188348
  result.cardAddFrom = flags.fromRaw;
188377
188349
  if (positionals[0] && VALID_COMPONENT_TYPES.includes(positionals[0])) {
@@ -188402,6 +188374,7 @@ var parseArgs = (argv) => {
188402
188374
  result.componentName = positionals[0];
188403
188375
  } else if (action === "add-story") {
188404
188376
  result.componentName = positionals[0];
188377
+ result.cardAddStoryForce = boolFlags.force;
188405
188378
  } else if (action === "remote") {
188406
188379
  const sub = positionals[0];
188407
188380
  if (sub && VALID_CARD_REMOTE_ACTIONS.includes(sub)) {
@@ -188478,7 +188451,7 @@ var ALL_LINES = [
188478
188451
  " self-upgrade [--pm bun|npm|pnpm|yarn] Upgrade the globally installed pieui CLI to the latest published version",
188479
188452
  "",
188480
188453
  "Card management (mirrors `pie card ...`):",
188481
- " card add [type] <Name> [--io] [--ajax] [--from <ref>]",
188454
+ " card add [type] <Name> [--io] [--ajax] [--input] [--from <ref>]",
188482
188455
  " Create a new component in piecomponents/ (or port from backend via --from)",
188483
188456
  " card list [filter] List registered components",
188484
188457
  " card pull <ref> Pull a card by Name, project/Name, or r/user/Name (public alias)",
@@ -188486,7 +188459,7 @@ var ALL_LINES = [
188486
188459
  " card remove <Name> Remove a component from piecomponents/",
188487
188460
  " card list-events <Name> List methods keys on the registered PieCard",
188488
188461
  " card add-event <Name> <event> Add a new methods key with a default handler",
188489
- " card add-story <Name> Generate a Storybook stories.tsx wired to PieCard methods",
188462
+ " card add-story <Name> [--force] Generate a Storybook stories.tsx wired to PieCard methods",
188490
188463
  " card dump-metadata <Name> [--out file.json] Dump full PieMetadata JSON for the component",
188491
188464
  " card check-sync <Name> Compare TS ↔ Python metadata; prompt for backend project path if not configured",
188492
188465
  " card remote list [--user U] [--project S] List remote components",
@@ -188512,6 +188485,7 @@ var ALL_LINES = [
188512
188485
  "Options for `card add`:",
188513
188486
  " --io Add realtime support fields to the generated data interface",
188514
188487
  " --ajax Add AJAX request fields to the generated data interface",
188488
+ " --input Generate an InputPie*ComponentProps card with a typed `stored` prop",
188515
188489
  " --from <ref> Port from backend (Python card). <ref> can be:",
188516
188490
  " • path to a .py file or PieMetadata JSON file",
188517
188491
  " • a card name (resolved via backendComponentsDir)",
@@ -188548,7 +188522,7 @@ var CARD_LINES = [
188548
188522
  "Usage: pieui card <subcommand> [options]",
188549
188523
  "",
188550
188524
  "Subcommands:",
188551
- " add [type] <Name> [--io] [--ajax] [--from <ref>]",
188525
+ " add [type] <Name> [--io] [--ajax] [--input] [--from <ref>]",
188552
188526
  " Create a new component in piecomponents/ (or port from backend via --from)",
188553
188527
  " list [filter] List registered components",
188554
188528
  " pull <ref> Pull a card by Name, project/Name, or r/user/Name (public alias)",
@@ -188556,7 +188530,7 @@ var CARD_LINES = [
188556
188530
  " remove <Name> Remove a component from piecomponents/",
188557
188531
  " list-events <Name> List methods keys on the registered PieCard",
188558
188532
  " add-event <Name> <event> Add a new methods key with a default handler",
188559
- " add-story <Name> Generate a Storybook stories.tsx wired to PieCard methods",
188533
+ " add-story <Name> [--force] Generate a Storybook stories.tsx wired to PieCard methods (--force overwrites)",
188560
188534
  " dump-metadata <Name> [--out file.json] Dump full PieMetadata JSON for the component",
188561
188535
  " check-sync <Name> Compare TS ↔ Python metadata; prompts for backend project path",
188562
188536
  " remote ... Remote storage operations (see `pieui card remote --help`)",
@@ -188570,6 +188544,7 @@ var CARD_LINES = [
188570
188544
  "Options for `card add`:",
188571
188545
  " --io Add realtime support fields to the generated data interface",
188572
188546
  " --ajax Add AJAX request fields to the generated data interface",
188547
+ " --input Generate an InputPie*ComponentProps card with a typed `stored` prop",
188573
188548
  "",
188574
188549
  "Options for `card list` / `card list-events` / `card add-event`:",
188575
188550
  " --src-dir <dir>, -s <dir> Source directory (default: .)",
@@ -188703,6 +188678,9 @@ var ioFields = ` useSocketioSupport?: boolean
188703
188678
  var ajaxFields = ` pathname?: string
188704
188679
  depsNames: string[]
188705
188680
  kwargs: Record<string, string | number | boolean>`;
188681
+ var storedInterfaceFor = (componentName) => `export interface ${componentName}Stored {
188682
+ // Add the fields you want submitted as the form value (\`stored\` prop)
188683
+ }`;
188706
188684
  var componentTypesTemplate = (componentName, baseInterface, options = {}) => {
188707
188685
  const extraSections = [
188708
188686
  options.io ? ioFields : "",
@@ -188713,6 +188691,10 @@ var componentTypesTemplate = (componentName, baseInterface, options = {}) => {
188713
188691
  const extraFields = extraSections ? `
188714
188692
 
188715
188693
  ${extraSections}` : "";
188694
+ const storedBlock = options.input ? `
188695
+ ${storedInterfaceFor(componentName)}
188696
+ ` : "";
188697
+ const propsAlias = options.input ? `export type ${componentName}Props = ${baseInterface}<${componentName}Data, ${componentName}Stored>` : `export type ${componentName}Props = ${baseInterface}<${componentName}Data>`;
188716
188698
  return `import { ${baseInterface} } from '@swarm.ing/pieui'
188717
188699
 
188718
188700
  export interface ${componentName}Data {
@@ -188720,8 +188702,8 @@ export interface ${componentName}Data {
188720
188702
  // Add your component-specific props here
188721
188703
  ${extraFields}
188722
188704
  }
188723
-
188724
- export type ${componentName}Props = ${baseInterface}<${componentName}Data>
188705
+ ${storedBlock}
188706
+ ${propsAlias}
188725
188707
  `;
188726
188708
  };
188727
188709
 
@@ -188761,7 +188743,6 @@ export default function LoadingScreen() {
188761
188743
  );
188762
188744
  }
188763
188745
  `;
188764
-
188765
188746
  // src/code/templates/rootLayout.ts
188766
188747
  var rootLayoutTemplate = `import type { Metadata } from "next";
188767
188748
  import "./globals.css";
@@ -188859,16 +188840,19 @@ var dataDestructureFor = (options = {}) => {
188859
188840
  } = data`;
188860
188841
  };
188861
188842
  var pieCardOpeningTagFor = (componentName, options = {}) => {
188843
+ const storedAttr = options.input ? " stored={stored}" : "";
188862
188844
  if (!options.io) {
188863
- return `<PieCard card='${componentName}' data={data}>`;
188845
+ return `<PieCard card='${componentName}' data={data}${storedAttr}>`;
188864
188846
  }
188847
+ const storedLine = options.input ? `
188848
+ stored={stored}` : "";
188865
188849
  return `<PieCard
188866
188850
  card='${componentName}'
188867
188851
  data={data}
188868
188852
  useSocketioSupport={useSocketioSupport}
188869
188853
  useCentrifugeSupport={useCentrifugeSupport}
188870
188854
  useMittSupport={useMittSupport}
188871
- centrifugeChannel={centrifugeChannel}
188855
+ centrifugeChannel={centrifugeChannel}${storedLine}
188872
188856
  methods={{
188873
188857
  }}
188874
188858
  >`;
@@ -188887,11 +188871,14 @@ var ajaxSubmitDeclarationFor = (options = {}) => {
188887
188871
  };
188888
188872
 
188889
188873
  // src/code/templates/pages/components/simpleComponent.ts
188890
- var simpleComponentTemplate = (componentName, options = {}) => `import React from 'react'
188874
+ var simpleComponentTemplate = (componentName, options = {}) => {
188875
+ const propsDestructure = options.input ? `{ data, stored${options.ajax ? ", setUiAjaxConfiguration" : ""} }` : `{ data${options.ajax ? ", setUiAjaxConfiguration" : ""} }`;
188876
+ const propsAnnotation = options.ajax ? `${componentName}Props & { setUiAjaxConfiguration?: SetUiAjaxConfigurationType }` : `${componentName}Props`;
188877
+ return `import React from 'react'
188891
188878
  import { PieCard${options.ajax ? ", useAjaxSubmit, type SetUiAjaxConfigurationType" : ""} } from '@swarm.ing/pieui'
188892
188879
  import { ${componentName}Props } from '../types'
188893
188880
 
188894
- const ${componentName} = ({ data${options.ajax ? ", setUiAjaxConfiguration" : ""} }: ${componentName}Props${options.ajax ? " & { setUiAjaxConfiguration?: SetUiAjaxConfigurationType }" : ""}) => {
188881
+ const ${componentName} = (${propsDestructure}: ${propsAnnotation}) => {
188895
188882
  ${dataDestructureFor(options)}
188896
188883
  ${ajaxSubmitDeclarationFor(options)}
188897
188884
 
@@ -188907,12 +188894,15 @@ const ${componentName} = ({ data${options.ajax ? ", setUiAjaxConfiguration" : ""
188907
188894
 
188908
188895
  export default ${componentName}
188909
188896
  `;
188897
+ };
188910
188898
  // src/code/templates/pages/components/complexComponent.ts
188911
- var complexComponentTemplate = (componentName, options = {}) => `import React from 'react'
188899
+ var complexComponentTemplate = (componentName, options = {}) => {
188900
+ const propsDestructure = options.input ? `{ data, stored${options.ajax ? ", setUiAjaxConfiguration" : ""} }` : `{ data${options.ajax ? ", setUiAjaxConfiguration" : ""} }`;
188901
+ return `import React from 'react'
188912
188902
  import { PieCard${options.ajax ? ", useAjaxSubmit" : ""} } from '@swarm.ing/pieui'
188913
188903
  import { ${componentName}Props } from '../types'
188914
188904
 
188915
- const ${componentName} = ({ data${options.ajax ? ", setUiAjaxConfiguration" : ""} }: ${componentName}Props) => {
188905
+ const ${componentName} = (${propsDestructure}: ${componentName}Props) => {
188916
188906
  ${dataDestructureFor(options)}
188917
188907
  ${ajaxSubmitDeclarationFor(options)}
188918
188908
 
@@ -188928,16 +188918,24 @@ const ${componentName} = ({ data${options.ajax ? ", setUiAjaxConfiguration" : ""
188928
188918
 
188929
188919
  export default ${componentName}
188930
188920
  `;
188921
+ };
188931
188922
  // src/code/templates/pages/components/simpleContainerComponent.ts
188932
- var simpleContainerComponentTemplate = (componentName, options = {}) => `import React, { useContext } from 'react'
188933
- import { PieCard, UI, UIRendererContext${options.ajax ? ", useAjaxSubmit" : ""} } from '@swarm.ing/pieui'
188934
- import { ${componentName}Props } from '../types'
188935
-
188936
- const ${componentName} = ({
188923
+ var simpleContainerComponentTemplate = (componentName, options = {}) => {
188924
+ const propsDestructure = options.input ? `{
188937
188925
  data,
188926
+ stored,
188938
188927
  content,
188939
188928
  setUiAjaxConfiguration,
188940
- }: ${componentName}Props) => {
188929
+ }` : `{
188930
+ data,
188931
+ content,
188932
+ setUiAjaxConfiguration,
188933
+ }`;
188934
+ return `import React, { useContext } from 'react'
188935
+ import { PieCard, UI, UIRendererContext${options.ajax ? ", useAjaxSubmit" : ""} } from '@swarm.ing/pieui'
188936
+ import { ${componentName}Props } from '../types'
188937
+
188938
+ const ${componentName} = (${propsDestructure}: ${componentName}Props) => {
188941
188939
  ${dataDestructureFor(options)}
188942
188940
  ${ajaxSubmitDeclarationFor(options)}
188943
188941
  const Renderer = useContext(UIRendererContext) ?? UI
@@ -188960,16 +188958,24 @@ const ${componentName} = ({
188960
188958
 
188961
188959
  export default ${componentName}
188962
188960
  `;
188961
+ };
188963
188962
  // src/code/templates/pages/components/complexContainerComponent.ts
188964
- var complexContainerComponentTemplate = (componentName, options = {}) => `import React, { useContext } from 'react'
188965
- import { PieCard, UI, UIRendererContext${options.ajax ? ", useAjaxSubmit" : ""} } from '@swarm.ing/pieui'
188966
- import { ${componentName}Props } from '../types'
188967
-
188968
- const ${componentName} = ({
188963
+ var complexContainerComponentTemplate = (componentName, options = {}) => {
188964
+ const propsDestructure = options.input ? `{
188965
+ data,
188966
+ stored,
188967
+ content,
188968
+ setUiAjaxConfiguration,
188969
+ }` : `{
188969
188970
  data,
188970
188971
  content,
188971
188972
  setUiAjaxConfiguration,
188972
- }: ${componentName}Props) => {
188973
+ }`;
188974
+ return `import React, { useContext } from 'react'
188975
+ import { PieCard, UI, UIRendererContext${options.ajax ? ", useAjaxSubmit" : ""} } from '@swarm.ing/pieui'
188976
+ import { ${componentName}Props } from '../types'
188977
+
188978
+ const ${componentName} = (${propsDestructure}: ${componentName}Props) => {
188973
188979
  ${dataDestructureFor(options)}
188974
188980
  ${ajaxSubmitDeclarationFor(options)}
188975
188981
  const Renderer = useContext(UIRendererContext) ?? UI
@@ -188993,6 +188999,7 @@ const ${componentName} = ({
188993
188999
 
188994
189000
  export default ${componentName}
188995
189001
  `;
189002
+ };
188996
189003
  // src/code/templates/pages/page.ts
188997
189004
  var pageTemplate = (pageComponentName) => `"use client";
188998
189005
 
@@ -189015,7 +189022,13 @@ var BASE_INTERFACE_BY_TYPE = {
189015
189022
  "simple-container": "PieContainerComponentProps",
189016
189023
  "complex-container": "PieComplexContainerComponentProps"
189017
189024
  };
189018
- var baseInterfaceFor = (componentType) => BASE_INTERFACE_BY_TYPE[componentType];
189025
+ var INPUT_BASE_INTERFACE_BY_TYPE = {
189026
+ simple: "InputPieSimpleComponentProps",
189027
+ complex: "InputPieComplexComponentProps",
189028
+ "simple-container": "InputPieContainerComponentProps",
189029
+ "complex-container": "InputPieComplexContainerComponentProps"
189030
+ };
189031
+ var baseInterfaceFor = (componentType, options = {}) => options.input ? INPUT_BASE_INTERFACE_BY_TYPE[componentType] : BASE_INTERFACE_BY_TYPE[componentType];
189019
189032
  var componentTemplateFor = (componentType, componentName, options = {}) => {
189020
189033
  switch (componentType) {
189021
189034
  case "simple":
@@ -189145,7 +189158,7 @@ var import_node_path2 = __toESM(require("node:path"));
189145
189158
  var import_node_child_process = require("node:child_process");
189146
189159
 
189147
189160
  // src/code/ts.ts
189148
- var TJS = __toESM(require_typescript_json_schema());
189161
+ var TJS = __toESM(require_typescript_json_schema(), 1);
189149
189162
  var ts2 = TJS.ts;
189150
189163
 
189151
189164
  // src/code/storybookIntegration.ts
@@ -189692,7 +189705,7 @@ var addCommand = (componentName, componentType = "complex-container", options =
189692
189705
  import_fs3.default.mkdirSync(import_path3.default.join(componentDir, "ui"), { recursive: true });
189693
189706
  import_fs3.default.mkdirSync(import_path3.default.join(componentDir, "types"), { recursive: true });
189694
189707
  import_fs3.default.writeFileSync(import_path3.default.join(componentDir, "index.ts"), componentIndexTemplate(componentName), "utf8");
189695
- import_fs3.default.writeFileSync(import_path3.default.join(componentDir, "types", "index.ts"), componentTypesTemplate(componentName, baseInterfaceFor(componentType), options), "utf8");
189708
+ import_fs3.default.writeFileSync(import_path3.default.join(componentDir, "types", "index.ts"), componentTypesTemplate(componentName, baseInterfaceFor(componentType, options), options), "utf8");
189696
189709
  import_fs3.default.writeFileSync(import_path3.default.join(componentDir, "ui", `${componentName}.tsx`), componentTemplateFor(componentType, componentName, options), "utf8");
189697
189710
  const registryPath = resolveRegistryPath(pieComponentsDir);
189698
189711
  updateRegistryFile(registryPath, componentName, componentDir);
@@ -189710,6 +189723,7 @@ var addCommand = (componentName, componentType = "complex-container", options =
189710
189723
  console.log(`[pieui] Component type: ${componentType}`);
189711
189724
  console.log(`[pieui] IO fields: ${options.io ? "enabled" : "disabled"}`);
189712
189725
  console.log(`[pieui] AJAX fields: ${options.ajax ? "enabled" : "disabled"}`);
189726
+ console.log(`[pieui] Input (stored): ${options.input ? "enabled" : "disabled"}`);
189713
189727
  switch (componentType) {
189714
189728
  case "simple":
189715
189729
  console.log(" - Props: data only");
@@ -190348,8 +190362,7 @@ var D = class {
190348
190362
  return true;
190349
190363
  return false;
190350
190364
  }
190351
- debug(...t) {
190352
- }
190365
+ debug(...t) {}
190353
190366
  make() {
190354
190367
  let t = this.pattern, e = this.options;
190355
190368
  if (!e.nocomment && t.charAt(0) === "#") {
@@ -190872,12 +190885,9 @@ var ft = class Me {
190872
190885
  return !!a && !!h && (i || r()) - h > a;
190873
190886
  };
190874
190887
  }
190875
- #k = () => {
190876
- };
190877
- #N = () => {
190878
- };
190879
- #j = () => {
190880
- };
190888
+ #k = () => {};
190889
+ #N = () => {};
190890
+ #j = () => {};
190881
190891
  #v = () => false;
190882
190892
  #G() {
190883
190893
  let t = new Tt(this.#t);
@@ -190904,10 +190914,8 @@ var ft = class Me {
190904
190914
  this.#u += t[e], i && (i.entrySize = s, i.totalCalculatedSize = this.#u);
190905
190915
  };
190906
190916
  }
190907
- #P = (t) => {
190908
- };
190909
- #L = (t, e, s) => {
190910
- };
190917
+ #P = (t) => {};
190918
+ #L = (t, e, s) => {};
190911
190919
  #I = (t, e, s, i) => {
190912
190920
  if (s || i)
190913
190921
  throw new TypeError("cannot set size without setting maxSize or maxEntrySize on cache");
@@ -191300,8 +191308,7 @@ var Mt = class {
191300
191308
  unpipe() {
191301
191309
  this.dest.removeListener("drain", this.ondrain);
191302
191310
  }
191303
- proxyErrors(t) {
191304
- }
191311
+ proxyErrors(t) {}
191305
191312
  end() {
191306
191313
  this.unpipe(), this.opts.end && this.dest.end();
191307
191314
  }
@@ -191376,8 +191383,7 @@ var V = class extends import_node_events.EventEmitter {
191376
191383
  get aborted() {
191377
191384
  return this[Dt];
191378
191385
  }
191379
- set aborted(t) {
191380
- }
191386
+ set aborted(t) {}
191381
191387
  write(t, e, s) {
191382
191388
  if (this[Dt])
191383
191389
  return false;
@@ -191588,8 +191594,7 @@ var V = class extends import_node_events.EventEmitter {
191588
191594
  });
191589
191595
  }, throw: e, return: e, [Symbol.asyncIterator]() {
191590
191596
  return this;
191591
- }, [Symbol.asyncDispose]: async () => {
191592
- } };
191597
+ }, [Symbol.asyncDispose]: async () => {} };
191593
191598
  }
191594
191599
  [Symbol.iterator]() {
191595
191600
  this[M] = false;
@@ -191601,8 +191606,7 @@ var V = class extends import_node_events.EventEmitter {
191601
191606
  };
191602
191607
  return this.once("end", e), this.once(Xt, e), this.once(x, e), { next: s, throw: e, return: e, [Symbol.iterator]() {
191603
191608
  return this;
191604
- }, [Symbol.dispose]: () => {
191605
- } };
191609
+ }, [Symbol.dispose]: () => {} };
191606
191610
  }
191607
191611
  destroy(t) {
191608
191612
  if (this[x])
@@ -192055,8 +192059,7 @@ var R = class {
192055
192059
  if (this.#q)
192056
192060
  await this.#q;
192057
192061
  else {
192058
- let s = () => {
192059
- };
192062
+ let s = () => {};
192060
192063
  this.#q = new Promise((i) => s = i);
192061
192064
  try {
192062
192065
  for (let i of await this.#t.promises.readdir(e, { withFileTypes: true }))
@@ -194054,46 +194057,8 @@ var postbuildCommand = async (srcDir, outDir, append) => {
194054
194057
  };
194055
194058
 
194056
194059
  // src/code/commands/cardRemote/push.ts
194057
- var import_node_fs4 = __toESM(require("node:fs"));
194058
- var import_node_path5 = __toESM(require("node:path"));
194059
-
194060
- // src/code/introspection/cardMetadata.ts
194061
- var AJAX_FIELD_NAMES = ["pathname", "depsNames", "kwargs"];
194062
- var IO_FIELD_NAMES = [
194063
- "useSocketioSupport",
194064
- "useCentrifugeSupport",
194065
- "useMittSupport",
194066
- "centrifugeChannel"
194067
- ];
194068
- var containsIdentifier = (source, name) => {
194069
- const pattern = new RegExp(`\\b${name}\\b`);
194070
- return pattern.test(source);
194071
- };
194072
- var extractCardMetadata = (componentName, source) => {
194073
- if (!source) {
194074
- return {
194075
- component: componentName,
194076
- input: false,
194077
- ajax: false,
194078
- io: false
194079
- };
194080
- }
194081
- return {
194082
- component: componentName,
194083
- input: false,
194084
- ajax: AJAX_FIELD_NAMES.some((n7) => containsIdentifier(source, n7)),
194085
- io: IO_FIELD_NAMES.some((n7) => containsIdentifier(source, n7))
194086
- };
194087
- };
194088
- var serializeCardMetadata = (meta) => {
194089
- const entries = Object.entries(meta).sort(([a], [b]) => a.localeCompare(b));
194090
- const obj = {};
194091
- for (const [k2, v2] of entries)
194092
- obj[k2] = v2;
194093
- const text = JSON.stringify(obj) + `
194094
- `;
194095
- return new TextEncoder().encode(text);
194096
- };
194060
+ var import_node_fs7 = __toESM(require("node:fs"));
194061
+ var import_node_path9 = __toESM(require("node:path"));
194097
194062
 
194098
194063
  // src/code/services/settings.ts
194099
194064
  var import_node_fs3 = __toESM(require("node:fs"));
@@ -194334,9 +194299,11 @@ var cleanFetchError = (method, url, error) => {
194334
194299
  class PieStorageService {
194335
194300
  settings;
194336
194301
  baseUrl;
194302
+ v2BaseUrl;
194337
194303
  constructor(settings) {
194338
194304
  this.settings = settings;
194339
194305
  this.baseUrl = settings.apiBaseUrl.replace(/\/+$/, "");
194306
+ this.v2BaseUrl = /\/api$/.test(this.baseUrl) ? this.baseUrl.replace(/\/api$/, "/api/v2") : `${this.baseUrl}/v2`;
194340
194307
  }
194341
194308
  projectComponentsUrl(args) {
194342
194309
  return `${this.baseUrl}/components/${pathPart(args.userId)}/${pathPart(args.project)}`;
@@ -194399,6 +194366,33 @@ class PieStorageService {
194399
194366
  metadataUrl(args) {
194400
194367
  return `${this.componentUrl(args)}/metadata/${encodeURIComponent(args.schemaKind)}`;
194401
194368
  }
194369
+ envelopeUrl(args) {
194370
+ const userId = args.userId ?? this.settings.userId;
194371
+ if (!userId) {
194372
+ throw new PieStorageError("user_id is required (configure PIE_USER_ID or pass user_id)");
194373
+ }
194374
+ const slug = args.project ?? this.settings.project;
194375
+ const base = `${this.v2BaseUrl}/components/${pathPart(userId)}` + `/${pathPart(slug)}/${pathPart(args.componentName)}`;
194376
+ if (args.revision !== undefined) {
194377
+ return `${base}/revisions/${args.revision}/envelope`;
194378
+ }
194379
+ return `${base}/envelope`;
194380
+ }
194381
+ async pushEnvelope(args) {
194382
+ const url = this.envelopeUrl(args);
194383
+ const response = await this.request({
194384
+ method: "PUT",
194385
+ url,
194386
+ headers: { "content-type": "application/json" },
194387
+ body: JSON.stringify(args.body)
194388
+ });
194389
+ return await response.json();
194390
+ }
194391
+ async fetchEnvelope(args) {
194392
+ const url = this.envelopeUrl(args);
194393
+ const response = await this.request({ method: "GET", url });
194394
+ return await response.json();
194395
+ }
194402
194396
  async listProjectComponents(args) {
194403
194397
  const url = this.projectComponentsUrl(args);
194404
194398
  const response = await this.request({ method: "GET", url });
@@ -194602,518 +194596,80 @@ ${detail}` : `${opts.method} ${opts.url} failed: ${response.status}`;
194602
194596
  }
194603
194597
  }
194604
194598
 
194605
- // src/code/commands/cardRemote/cardRef.ts
194606
- var parseNameAndRevision = (namePart, raw) => {
194607
- const atIndex = namePart.indexOf("@");
194608
- if (atIndex === -1)
194609
- return { componentName: namePart };
194610
- const componentName = namePart.slice(0, atIndex);
194611
- const revisionPart = namePart.slice(atIndex + 1);
194612
- if (!componentName) {
194613
- throw new Error(`missing component name in ${JSON.stringify(raw)}`);
194614
- }
194615
- if (!revisionPart) {
194616
- throw new Error(`missing revision after '@' in ${JSON.stringify(raw)}`);
194617
- }
194618
- if (!/^\d+$/.test(revisionPart)) {
194619
- throw new Error(`revision must be a positive integer, got ${JSON.stringify(revisionPart)}`);
194620
- }
194621
- const revision = Number(revisionPart);
194622
- if (revision < 1) {
194623
- throw new Error(`revision must be >= 1, got ${revision}`);
194624
- }
194625
- return { componentName, revision };
194626
- };
194627
- var parseCardRef = (input) => {
194628
- if (!input) {
194629
- throw new Error("card ref must not be empty");
194630
- }
194631
- if (input.startsWith("r/")) {
194632
- const rest = input.slice(2);
194633
- const parts2 = rest.split("/");
194634
- if (parts2.length !== 2 || !parts2[0] || !parts2[1]) {
194635
- throw new Error(`expected r/<user>/<Component>, got ${JSON.stringify(input)}`);
194636
- }
194637
- const [userId, namePart] = parts2;
194638
- const { componentName, revision } = parseNameAndRevision(namePart, input);
194639
- if (revision !== undefined) {
194640
- throw new Error("revision suffix is not supported for public refs (r/...)");
194641
- }
194642
- return { componentName, userId, isPublic: true };
194643
- }
194644
- const parts = input.split("/");
194645
- if (parts.length === 1) {
194646
- return parseNameAndRevision(input, input);
194647
- }
194648
- if (parts.length === 2) {
194649
- const [project, namePart] = parts;
194650
- if (!project || !namePart) {
194651
- throw new Error(`expected <project>/<Component>, got ${JSON.stringify(input)}`);
194652
- }
194653
- const { componentName, revision } = parseNameAndRevision(namePart, input);
194654
- return { componentName, revision, project };
194655
- }
194656
- throw new Error(`invalid card ref ${JSON.stringify(input)}: expected <Component>, <project>/<Component>, or r/<user>/<Component>`);
194657
- };
194658
-
194659
- // src/code/commands/cardRemote/push.ts
194660
- var cardRemotePushCommand = async (cardRef) => {
194661
- const ref = parseCardRef(cardRef);
194662
- if (ref.revision !== undefined) {
194663
- throw new Error("push does not accept a revision suffix");
194664
- }
194665
- if (ref.isPublic) {
194666
- throw new Error("push does not accept public refs (r/...)");
194667
- }
194668
- if (ref.project || ref.userId) {
194669
- throw new Error("push does not accept project/user override; pass just <ComponentName>");
194670
- }
194671
- const { componentName } = ref;
194672
- if (!/^[A-Z][A-Za-z0-9]+$/.test(componentName)) {
194673
- throw new Error("Component name must start with uppercase letter and contain only letters and numbers");
194674
- }
194675
- const settings = loadSettings();
194676
- if (!settings.userId) {
194677
- throw new Error("user_id is required (set PIE_USER_ID in env or .env; run `pieui login`)");
194678
- }
194679
- const componentDir = import_node_path5.default.join(settings.componentsDir, componentName);
194680
- if (!import_node_fs4.default.existsSync(componentDir) || !import_node_fs4.default.statSync(componentDir).isDirectory()) {
194681
- throw new Error(`Component directory not found: ${componentDir}`);
194682
- }
194683
- const service = new PieStorageService(settings);
194684
- const uploaded = await service.uploadComponentDirectory({
194685
- componentName,
194686
- sourceDir: componentDir
194687
- });
194688
- if (uploaded.length === 0) {
194689
- throw new Error(`No files uploaded for component: ${componentName}`);
194690
- }
194691
- const typesPath = import_node_path5.default.join(componentDir, "types", "index.ts");
194692
- const typesSource = import_node_fs4.default.existsSync(typesPath) ? import_node_fs4.default.readFileSync(typesPath, "utf8") : undefined;
194693
- const metadata = extractCardMetadata(componentName, typesSource);
194694
- const metadataResult = await service.uploadMetadataContent({
194695
- componentName,
194696
- schemaKind: "eventSchema",
194697
- content: serializeCardMetadata(metadata)
194698
- });
194699
- const latestRevision = await latestRevisionNumber(service, componentName);
194700
- console.log(`[pieui] Uploaded card: ${componentName}`);
194701
- console.log(`[pieui] Path: ${componentDir}`);
194702
- console.log(`[pieui] Files uploaded: ${uploaded.length}`);
194703
- console.log(`[pieui] Metadata key: ${metadataResult.key}`);
194704
- if (latestRevision !== undefined) {
194705
- console.log(`[pieui] Revision: ${componentName}@${latestRevision}`);
194706
- }
194707
- console.log(`[pieui] Metadata: Input=${metadata.input ? "Yes" : "No"}, ` + `Ajax=${metadata.ajax ? "Yes" : "No"}, IO=${metadata.io ? "Yes" : "No"}`);
194708
- };
194709
- var latestRevisionNumber = async (service, componentName) => {
194710
- try {
194711
- const list = await service.listRevisions({ componentName });
194712
- if (list.revisions.length === 0)
194713
- return;
194714
- return list.revisions.reduce((max, entry) => entry.revision > max ? entry.revision : max, 0);
194715
- } catch (error) {
194716
- if (error instanceof PieStorageError)
194717
- return;
194718
- throw error;
194719
- }
194720
- };
194721
-
194722
- // src/code/commands/cardRemote/pull.ts
194723
- var import_node_fs5 = __toESM(require("node:fs"));
194724
- var import_node_path6 = __toESM(require("node:path"));
194725
- var cardRemotePullCommand = async (cardRef) => {
194726
- const ref = parseCardRef(cardRef);
194727
- const { componentName, revision, isPublic } = ref;
194728
- const settings = loadSettings();
194729
- const effectiveUserId = ref.userId ?? settings.userId;
194730
- if (!effectiveUserId) {
194731
- throw new Error("user_id is required (set PIE_USER_ID in env or .env; run `pieui login`)");
194732
- }
194733
- const effectiveProject = isPublic ? undefined : ref.project ?? settings.project;
194734
- if (!isPublic && !effectiveProject) {
194735
- throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG in env or .env)");
194736
- }
194737
- const componentDir = import_node_path6.default.join(settings.componentsDir, componentName);
194738
- import_node_fs5.default.mkdirSync(settings.componentsDir, { recursive: true });
194739
- const tempDir = `${componentDir}.pieui-tmp-${process.pid}-${Date.now()}`;
194740
- import_node_fs5.default.rmSync(tempDir, { recursive: true, force: true });
194741
- import_node_fs5.default.mkdirSync(tempDir, { recursive: true });
194742
- const service = new PieStorageService(settings);
194743
- let downloaded;
194744
- try {
194745
- downloaded = await service.downloadComponentDirectory({
194746
- componentName,
194747
- targetDir: tempDir,
194748
- revision,
194749
- userId: effectiveUserId,
194750
- project: effectiveProject,
194751
- isPublic
194752
- });
194753
- } catch (error) {
194754
- import_node_fs5.default.rmSync(tempDir, { recursive: true, force: true });
194755
- throw error;
194756
- }
194757
- const sourceLabel = isPublic ? `r/${effectiveUserId}/${componentName}` : ref.project ? `${effectiveProject}/${componentName}` : componentName;
194758
- const suffix = revision !== undefined ? `@${revision}` : "";
194759
- if (downloaded.length === 0) {
194760
- import_node_fs5.default.rmSync(tempDir, { recursive: true, force: true });
194761
- const where = isPublic ? `user_id=${effectiveUserId} (public)` : `user_id=${effectiveUserId}, project=${effectiveProject}`;
194762
- throw new Error(`No typescript files found for remote component ${sourceLabel}${suffix} (${where})`);
194763
- }
194764
- if (import_node_fs5.default.existsSync(componentDir)) {
194765
- import_node_fs5.default.rmSync(componentDir, { recursive: true, force: true });
194766
- }
194767
- import_node_fs5.default.renameSync(tempDir, componentDir);
194768
- console.log(`[pieui] Pulled card: ${sourceLabel}${suffix}`);
194769
- for (const p of downloaded) {
194770
- const relative = import_node_path6.default.relative(tempDir, p);
194771
- console.log(`[pieui] Path: ${import_node_path6.default.join(componentDir, relative)}`);
194772
- }
194773
- };
194774
-
194775
- // src/code/commands/cardRemote/list.ts
194776
- var cardRemoteListCommand = async (options) => {
194777
- const settings = loadSettings();
194778
- const userId = options.userId || settings.userId;
194779
- const project = options.project || settings.project;
194780
- if (!userId) {
194781
- throw new Error("user_id is required (use --user or set PIE_USER_ID in env or .env)");
194782
- }
194783
- if (!project) {
194784
- throw new Error("project is required (use --project or set PIE_PROJECT / PIE_PROJECT_SLUG)");
194785
- }
194786
- const service = new PieStorageService(settings);
194787
- const result = await service.listProjectComponents({ userId, project });
194788
- console.log(`[pieui] Remote components for user_id=${JSON.stringify(result.userId)} project_slug=${JSON.stringify(result.project)}:`);
194789
- for (const entry of [...result.components].sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()))) {
194790
- console.log(entry.name);
194791
- }
194792
- };
194793
-
194794
- // src/code/commands/cardRemote/remove.ts
194795
- var cardRemoteRemoveCommand = async (componentName) => {
194796
- const settings = loadSettings();
194797
- if (!settings.userId) {
194798
- throw new Error("user_id is required (set PIE_USER_ID in env or .env)");
194799
- }
194800
- if (!settings.project) {
194801
- throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG in env or .env)");
194802
- }
194803
- const service = new PieStorageService(settings);
194804
- await service.deleteComponent({ componentName });
194805
- console.log(`[pieui] Removed remote component: ${componentName}`);
194806
- };
194807
-
194808
- // src/code/commands/cardRemote/history.ts
194809
- var extractPath = (key, componentName) => {
194810
- const marker = `/${componentName}/${STORAGE_LANGUAGE}/`;
194811
- const idx = key.indexOf(marker);
194812
- if (idx === -1)
194813
- return key;
194814
- return key.slice(idx + marker.length);
194815
- };
194816
- var formatFileBlock = (file, componentName) => {
194817
- const path15 = extractPath(file.key, componentName);
194818
- const before = file.status === "added" ? "a//dev/null" : `a/${path15}`;
194819
- const after = file.status === "deleted" ? "b//dev/null" : `b/${path15}`;
194820
- const lines = [];
194821
- lines.push(`diff --git ${before} ${after}`);
194822
- lines.push(`${file.status} +${file.additions} -${file.deletions} ${path15}`);
194823
- if (file.isBinary) {
194824
- lines.push("Binary files differ");
194825
- } else if (file.patch) {
194826
- lines.push(file.patch.replace(/\n+$/, ""));
194827
- }
194828
- return lines;
194829
- };
194830
- var formatRevisionBlock = (entry, componentName) => {
194831
- const lines = [];
194832
- lines.push(`revision ${componentName}@${entry.revision}`);
194833
- lines.push(`date ${entry.createdAt}`);
194834
- lines.push(`mutation ${entry.mutation}`);
194835
- if (entry.previousRevision !== null) {
194836
- lines.push(`previous ${entry.previousRevision}`);
194837
- }
194838
- if (entry.deleted) {
194839
- lines.push("deleted true");
194840
- }
194841
- for (const file of entry.files) {
194842
- lines.push("");
194843
- lines.push(...formatFileBlock(file, componentName));
194844
- }
194845
- return lines;
194846
- };
194847
- var cardRemoteHistoryCommand = async (options) => {
194848
- const settings = loadSettings();
194849
- if (!settings.userId) {
194850
- throw new Error("user_id is required (set PIE_USER_ID in env or .env)");
194851
- }
194852
- if (!settings.project) {
194853
- throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG)");
194854
- }
194855
- if (options.from !== undefined && options.to !== undefined && options.from > options.to) {
194856
- throw new Error("--from must be <= --to");
194857
- }
194858
- const service = new PieStorageService(settings);
194859
- const history = await service.getHistory({
194860
- componentName: options.componentName,
194861
- page: options.page,
194862
- perPage: options.perPage,
194863
- from: options.from,
194864
- to: options.to
194865
- });
194866
- const output = [];
194867
- output.push(`component ${history.userId}/${history.project}/${history.componentName}`);
194868
- output.push(`page ${history.page} per-page ${history.perPage} total-revisions ${history.totalRevisions}`);
194869
- if (history.fromRevision !== null || history.toRevision !== null) {
194870
- const from = history.fromRevision !== null ? String(history.fromRevision) : "*";
194871
- const to = history.toRevision !== null ? String(history.toRevision) : "*";
194872
- output.push(`range ${from}..${to}`);
194873
- }
194874
- for (const entry of history.entries) {
194875
- output.push("");
194876
- output.push(...formatRevisionBlock(entry, history.componentName));
194877
- }
194878
- console.log(output.join(`
194879
- `));
194880
- };
194881
-
194882
- // src/code/commands/cardRemote/public.ts
194883
- var cardRemotePublicCommand = async (componentName) => {
194884
- const settings = loadSettings();
194885
- if (!settings.userId) {
194886
- throw new Error("user_id is required (set PIE_USER_ID in env or .env)");
194887
- }
194888
- if (!settings.project) {
194889
- throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG)");
194890
- }
194891
- const service = new PieStorageService(settings);
194892
- const state = await service.markComponentPublic({ componentName });
194893
- console.log(`[pieui] Marked public: ${state.componentName} (user=${state.userId} project=${state.project})`);
194894
- console.log(`[pieui] is_public: ${state.isPublic}`);
194895
- if (state.publicRegistryName) {
194896
- console.log(`[pieui] Public registry name: ${state.publicRegistryName}`);
194897
- }
194898
- console.log(`[pieui] Public read URL: <api>/public-components/${state.userId}/${state.componentName}`);
194899
- };
194900
-
194901
- // src/code/commands/cardRemote/private.ts
194902
- var cardRemotePrivateCommand = async (componentName) => {
194903
- const settings = loadSettings();
194904
- if (!settings.userId) {
194905
- throw new Error("user_id is required (set PIE_USER_ID in env or .env)");
194906
- }
194907
- if (!settings.project) {
194908
- throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG)");
194909
- }
194910
- const service = new PieStorageService(settings);
194911
- const state = await service.markComponentPrivate({ componentName });
194912
- console.log(`[pieui] Marked private: ${state.componentName} (user=${state.userId} project=${state.project})`);
194913
- console.log(`[pieui] is_public: ${state.isPublic}`);
194914
- };
194915
-
194916
- // src/code/commands/cardPull.ts
194599
+ // src/code/commands/cardDumpMetadata.ts
194917
194600
  var import_node_fs6 = __toESM(require("node:fs"));
194918
- var import_node_path7 = __toESM(require("node:path"));
194919
- var isHttpUrl = (ref) => /^https?:\/\//i.test(ref);
194920
- var isLocalJsonPath = (ref) => {
194921
- if (ref.startsWith("./") || ref.startsWith("../") || ref.startsWith("/") || ref.startsWith("~")) {
194922
- return true;
194923
- }
194924
- if (!ref.endsWith(".json"))
194925
- return false;
194926
- return import_node_fs6.default.existsSync(import_node_path7.default.resolve(process.cwd(), ref));
194927
- };
194928
- var fetchJsonText = async (url) => {
194929
- const res = await fetch(url);
194930
- if (!res.ok) {
194931
- throw new Error(`HTTP ${res.status} ${res.statusText} fetching ${url}`);
194601
+ var import_node_path8 = __toESM(require("node:path"));
194602
+ // src/code/introspection/schemaContext.ts
194603
+ var import_node_path5 = __toESM(require("node:path"));
194604
+ var __dirname = "/home/runner/work/pieui/pieui/src/code/introspection";
194605
+ var DEFAULT_COMPILER_OPTIONS = () => ({
194606
+ allowJs: true,
194607
+ jsx: ts2.JsxEmit.ReactJSX,
194608
+ target: ts2.ScriptTarget.ES2020,
194609
+ module: ts2.ModuleKind.NodeNext,
194610
+ moduleResolution: ts2.ModuleResolutionKind.NodeNext,
194611
+ esModuleInterop: true,
194612
+ allowSyntheticDefaultImports: true,
194613
+ skipLibCheck: true
194614
+ });
194615
+ var createSchemaContext = (files) => {
194616
+ const cliSchemaPath = import_node_path5.default.join(__dirname, "..", "commands", "cli-schema.d.ts");
194617
+ const uniqueFiles = Array.from(new Set([cliSchemaPath, ...files]));
194618
+ const program = TJS.getProgramFromFiles(uniqueFiles, DEFAULT_COMPILER_OPTIONS());
194619
+ const checker = program.getTypeChecker();
194620
+ const generator = TJS.buildGenerator(program, {
194621
+ required: true,
194622
+ strictNullChecks: true,
194623
+ excludePrivate: true,
194624
+ ref: false,
194625
+ aliasRef: false,
194626
+ topRef: false,
194627
+ noExtraProps: true,
194628
+ ignoreErrors: true
194629
+ });
194630
+ if (!generator) {
194631
+ throw new Error("Failed to create JSON Schema generator");
194932
194632
  }
194933
- return await res.text();
194633
+ return { program, checker, generator };
194934
194634
  };
194935
- var unwrapTypescript = (parsed) => {
194936
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
194937
- throw new Error("dump-metadata payload is not a JSON object");
194938
- }
194939
- const obj = parsed;
194940
- const inner = obj.typescript;
194941
- if (!inner || typeof inner !== "object" || Array.isArray(inner)) {
194942
- const keys = Object.keys(obj).join(", ") || "(none)";
194943
- throw new Error('dump-metadata payload is missing the "typescript" envelope ' + `(top-level keys: ${keys})`);
194635
+ var findTypeDeclaration = (program, checker, typeName) => {
194636
+ for (const sourceFile of program.getSourceFiles()) {
194637
+ if (sourceFile.isDeclarationFile)
194638
+ continue;
194639
+ let found = null;
194640
+ const visit = (node) => {
194641
+ if (found)
194642
+ return;
194643
+ if ((ts2.isInterfaceDeclaration(node) || ts2.isTypeAliasDeclaration(node)) && node.name.text === typeName) {
194644
+ const symbol = checker.getSymbolAtLocation(node.name);
194645
+ if (symbol) {
194646
+ found = { symbol, declaration: node };
194647
+ }
194648
+ return;
194649
+ }
194650
+ ts2.forEachChild(node, visit);
194651
+ };
194652
+ visit(sourceFile);
194653
+ if (found)
194654
+ return found;
194944
194655
  }
194945
- return inner;
194656
+ return null;
194946
194657
  };
194947
- var pullFromDumpJson = (raw, label) => {
194948
- let parsed;
194658
+ var buildSchemaForType = (ctx, typeName) => {
194949
194659
  try {
194950
- parsed = JSON.parse(raw);
194951
- } catch (e) {
194952
- throw new Error(`${label} is not valid JSON: ${e.message}`);
194953
- }
194954
- const inner = unwrapTypescript(parsed);
194955
- const componentName = inner.name;
194956
- const files = inner.files;
194957
- if (typeof componentName !== "string" || !componentName) {
194958
- throw new Error(`${label}: typescript.name is missing or empty`);
194959
- }
194960
- if (!Array.isArray(files)) {
194961
- throw new Error(`${label}: typescript.files must be an array of {path, content}`);
194962
- }
194963
- const settings = loadSettings();
194964
- import_node_fs6.default.mkdirSync(settings.componentsDir, { recursive: true });
194965
- const componentDir = import_node_path7.default.join(settings.componentsDir, componentName);
194966
- if (import_node_fs6.default.existsSync(componentDir)) {
194967
- import_node_fs6.default.rmSync(componentDir, { recursive: true, force: true });
194968
- }
194969
- const written = [];
194970
- for (const entry of files) {
194971
- if (!entry || typeof entry !== "object" || typeof entry.path !== "string" || typeof entry.content !== "string") {
194972
- throw new Error(`${label}: every files[] entry must be {path: string, content: string}`);
194973
- }
194974
- const fe2 = entry;
194975
- const target = import_node_path7.default.resolve(settings.componentsDir, fe2.path);
194976
- const relCheck = import_node_path7.default.relative(settings.componentsDir, target);
194977
- if (relCheck.startsWith("..") || import_node_path7.default.isAbsolute(relCheck)) {
194978
- throw new Error(`${label}: file path "${fe2.path}" escapes componentsDir`);
194979
- }
194980
- import_node_fs6.default.mkdirSync(import_node_path7.default.dirname(target), { recursive: true });
194981
- import_node_fs6.default.writeFileSync(target, fe2.content, "utf8");
194982
- written.push(target);
194983
- }
194984
- console.log(`[pieui] Pulled card from ${label}: ${componentName}`);
194985
- for (const w of written)
194986
- console.log(`[pieui] Path: ${w}`);
194987
- };
194988
- var cardPullCommand = async (cardRef) => {
194989
- if (isHttpUrl(cardRef)) {
194990
- console.log(`[pieui] Fetching dump from ${cardRef}`);
194991
- const raw = await fetchJsonText(cardRef);
194992
- pullFromDumpJson(raw, cardRef);
194993
- return;
194994
- }
194995
- if (isLocalJsonPath(cardRef)) {
194996
- const abs = import_node_path7.default.resolve(process.cwd(), cardRef);
194997
- if (!import_node_fs6.default.existsSync(abs)) {
194998
- throw new Error(`Pull source not found: ${abs}`);
194999
- }
195000
- if (!import_node_fs6.default.statSync(abs).isFile()) {
195001
- throw new Error(`Pull source is not a file: ${abs}`);
194660
+ const schema = ctx.generator.getSchemaForSymbol(typeName);
194661
+ if (!schema)
194662
+ return null;
194663
+ const decl = findTypeDeclaration(ctx.program, ctx.checker, typeName);
194664
+ if (decl) {
194665
+ const declaredType = ctx.checker.getDeclaredTypeOfSymbol(decl.symbol);
194666
+ patchSchemaForType(declaredType, schema, ctx.checker);
195002
194667
  }
195003
- pullFromDumpJson(import_node_fs6.default.readFileSync(abs, "utf8"), abs);
195004
- return;
195005
- }
195006
- await cardRemotePullCommand(cardRef);
195007
- };
195008
-
195009
- // src/code/commands/cardView.ts
195010
- var import_node_fs7 = __toESM(require("node:fs"));
195011
- var import_node_path8 = __toESM(require("node:path"));
195012
- var AJAX_FIELD_NAMES2 = new Set(["pathname", "deps_names", "kwargs"]);
195013
- var IO_FIELD_RE = /\buse_[A-Za-z0-9_]+_support\b/g;
195014
- var extractInterfaceBody = (source, interfaceName) => {
195015
- const idx = source.indexOf(`interface ${interfaceName}`);
195016
- if (idx === -1)
195017
- return null;
195018
- const braceStart = source.indexOf("{", idx);
195019
- if (braceStart === -1)
194668
+ return schema;
194669
+ } catch {
195020
194670
  return null;
195021
- let depth = 0;
195022
- for (let i = braceStart;i < source.length; i++) {
195023
- const ch = source[i];
195024
- if (ch === "{")
195025
- depth++;
195026
- else if (ch === "}") {
195027
- depth--;
195028
- if (depth === 0)
195029
- return source.slice(braceStart + 1, i);
195030
- }
195031
- }
195032
- return null;
195033
- };
195034
- var parseProps = (body) => {
195035
- const props = [];
195036
- const lineRe = /^[ \t]*([A-Za-z_][A-Za-z0-9_]*)(\?)?\s*:\s*([^;\n]+?)\s*;?\s*$/gm;
195037
- let match;
195038
- while ((match = lineRe.exec(body)) !== null) {
195039
- const [, name, optional, typeRaw] = match;
195040
- props.push({
195041
- name,
195042
- type: typeRaw.trim(),
195043
- default: optional ? "(optional)" : "(required)"
195044
- });
195045
194671
  }
195046
- return props;
195047
- };
195048
- var formatTable = (headers, rows) => {
195049
- const data = [headers, ...rows];
195050
- const widths = headers.map((_2, c) => Math.max(...data.map((row) => (row[c] ?? "").length)));
195051
- const hline = `+${widths.map((w) => "-".repeat(w + 2)).join("+")}+`;
195052
- const fmtRow = (cells) => `|${cells.map((cell, i) => ` ${(cell ?? "").padEnd(widths[i])} `).join("|")}|`;
195053
- return [hline, fmtRow(headers), hline, ...rows.map(fmtRow), hline].join(`
195054
- `);
195055
194672
  };
195056
- var cardViewCommand = (componentName) => {
195057
- const settings = loadSettings();
195058
- const componentDir = import_node_path8.default.join(settings.componentsDir, componentName);
195059
- if (!import_node_fs7.default.existsSync(componentDir)) {
195060
- throw new Error(`Component directory not found: ${componentDir}`);
195061
- }
195062
- const typesPath = import_node_path8.default.join(componentDir, "types.ts");
195063
- const indexPath = import_node_path8.default.join(componentDir, "index.tsx");
195064
- const indexPathTs = import_node_path8.default.join(componentDir, "index.ts");
195065
- const typesSource = import_node_fs7.default.existsSync(typesPath) ? import_node_fs7.default.readFileSync(typesPath, "utf8") : "";
195066
- const indexSource = import_node_fs7.default.existsSync(indexPath) ? import_node_fs7.default.readFileSync(indexPath, "utf8") : import_node_fs7.default.existsSync(indexPathTs) ? import_node_fs7.default.readFileSync(indexPathTs, "utf8") : "";
195067
- const dataInterface = extractInterfaceBody(typesSource, `${componentName}Data`) ?? "";
195068
- const props = parseProps(dataInterface);
195069
- const hasAjax = props.some((p) => AJAX_FIELD_NAMES2.has(p.name));
195070
- const ioFields2 = props.map((p) => p.name).filter((name) => IO_FIELD_RE.test(name));
195071
- IO_FIELD_RE.lastIndex = 0;
195072
- const events = [];
195073
- const eventRe = /\b(?:on|create)([A-Z][A-Za-z0-9]*)Event\b|methods\s*=\s*\{([\s\S]*?)\}/g;
195074
- const methodsMatch = indexSource.match(/methods\s*=\s*\{([\s\S]*?)\}/);
195075
- if (methodsMatch) {
195076
- const inner = methodsMatch[1];
195077
- const keyRe = /([A-Za-z_][A-Za-z0-9_]*)\s*:/g;
195078
- let m;
195079
- while ((m = keyRe.exec(inner)) !== null)
195080
- events.push(m[1]);
195081
- }
195082
- console.log("Name:");
195083
- console.log(componentName);
195084
- console.log("");
195085
- console.log("File:");
195086
- console.log(import_node_path8.default.resolve(componentDir));
195087
- console.log("");
195088
- console.log("Props:");
195089
- if (props.length === 0) {
195090
- console.log("(none)");
195091
- } else {
195092
- console.log(formatTable(["Name", "Type", "Default"], props.map((p) => [p.name, p.type, p.default])));
195093
- }
195094
- console.log("");
195095
- console.log("Ajax:");
195096
- console.log(hasAjax ? "yes" : "no");
195097
- console.log("");
195098
- console.log("IO:");
195099
- if (ioFields2.length === 0) {
195100
- console.log("no");
195101
- } else {
195102
- console.log(formatTable(["name"], ioFields2.map((n7) => [n7])));
195103
- }
195104
- console.log("");
195105
- console.log("Events:");
195106
- if (events.length === 0) {
195107
- console.log("no (run `pieui card list-events " + componentName + "`)");
195108
- } else {
195109
- console.log(formatTable(["event"], events.map((e) => [e])));
195110
- }
195111
- };
195112
-
195113
- // src/code/commands/cardDumpMetadata.ts
195114
- var import_node_fs10 = __toESM(require("node:fs"));
195115
- var import_node_path12 = __toESM(require("node:path"));
195116
-
195117
194673
  // src/code/introspection/errors.ts
195118
194674
  class IntrospectionError extends Error {
195119
194675
  sourceFile;
@@ -195188,77 +194744,6 @@ var errorOptsFromNode = (sourceFile, node) => ({
195188
194744
  ...lineCol(sourceFile, node)
195189
194745
  });
195190
194746
 
195191
- // src/code/introspection/schemaContext.ts
195192
- var import_node_path9 = __toESM(require("node:path"));
195193
- var __dirname = "/home/runner/work/pieui/pieui/src/code/introspection";
195194
- var DEFAULT_COMPILER_OPTIONS = () => ({
195195
- allowJs: true,
195196
- jsx: ts2.JsxEmit.ReactJSX,
195197
- target: ts2.ScriptTarget.ES2020,
195198
- module: ts2.ModuleKind.NodeNext,
195199
- moduleResolution: ts2.ModuleResolutionKind.NodeNext,
195200
- esModuleInterop: true,
195201
- allowSyntheticDefaultImports: true,
195202
- skipLibCheck: true
195203
- });
195204
- var createSchemaContext = (files) => {
195205
- const cliSchemaPath = import_node_path9.default.join(__dirname, "..", "commands", "cli-schema.d.ts");
195206
- const uniqueFiles = Array.from(new Set([cliSchemaPath, ...files]));
195207
- const program = TJS.getProgramFromFiles(uniqueFiles, DEFAULT_COMPILER_OPTIONS());
195208
- const checker = program.getTypeChecker();
195209
- const generator = TJS.buildGenerator(program, {
195210
- required: true,
195211
- strictNullChecks: true,
195212
- excludePrivate: true,
195213
- ref: false,
195214
- aliasRef: false,
195215
- topRef: false,
195216
- noExtraProps: true,
195217
- ignoreErrors: true
195218
- });
195219
- if (!generator) {
195220
- throw new Error("Failed to create JSON Schema generator");
195221
- }
195222
- return { program, checker, generator };
195223
- };
195224
- var findTypeDeclaration = (program, checker, typeName) => {
195225
- for (const sourceFile of program.getSourceFiles()) {
195226
- if (sourceFile.isDeclarationFile)
195227
- continue;
195228
- let found = null;
195229
- const visit = (node) => {
195230
- if (found)
195231
- return;
195232
- if ((ts2.isInterfaceDeclaration(node) || ts2.isTypeAliasDeclaration(node)) && node.name.text === typeName) {
195233
- const symbol = checker.getSymbolAtLocation(node.name);
195234
- if (symbol) {
195235
- found = { symbol, declaration: node };
195236
- }
195237
- return;
195238
- }
195239
- ts2.forEachChild(node, visit);
195240
- };
195241
- visit(sourceFile);
195242
- if (found)
195243
- return found;
195244
- }
195245
- return null;
195246
- };
195247
- var buildSchemaForType = (ctx, typeName) => {
195248
- try {
195249
- const schema = ctx.generator.getSchemaForSymbol(typeName);
195250
- if (!schema)
195251
- return null;
195252
- const decl = findTypeDeclaration(ctx.program, ctx.checker, typeName);
195253
- if (decl) {
195254
- const declaredType = ctx.checker.getDeclaredTypeOfSymbol(decl.symbol);
195255
- patchSchemaForType(declaredType, schema, ctx.checker);
195256
- }
195257
- return schema;
195258
- } catch {
195259
- return null;
195260
- }
195261
- };
195262
194747
  // src/code/introspection/typeToSchema.ts
195263
194748
  var MAX_DEPTH = 12;
195264
194749
  var isOptionalProperty = (sym) => {
@@ -195386,7 +194871,7 @@ var typeToSchema = (type, checker, depth = 0, visited = new Set) => {
195386
194871
  return {};
195387
194872
  };
195388
194873
  // src/code/introspection/collectFiles.ts
195389
- var import_node_path10 = __toESM(require("node:path"));
194874
+ var import_node_path6 = __toESM(require("node:path"));
195390
194875
  var collectComponentFiles = (componentDir) => {
195391
194876
  const patterns = [
195392
194877
  `${componentDir}/**/*.ts`,
@@ -195407,40 +194892,40 @@ var collectComponentFiles = (componentDir) => {
195407
194892
  const out = new Set;
195408
194893
  for (const p of patterns) {
195409
194894
  for (const f of Ze.sync(p, { ignore })) {
195410
- out.add(import_node_path10.default.resolve(f));
194895
+ out.add(import_node_path6.default.resolve(f));
195411
194896
  }
195412
194897
  }
195413
194898
  return Array.from(out).sort();
195414
194899
  };
195415
194900
  // src/code/introspection/extractImports.ts
195416
- var import_node_fs8 = __toESM(require("node:fs"));
195417
- var import_node_path11 = __toESM(require("node:path"));
194901
+ var import_node_fs4 = __toESM(require("node:fs"));
194902
+ var import_node_path7 = __toESM(require("node:path"));
195418
194903
  var createHost = (cwd) => {
195419
194904
  const sys = ts2.sys;
195420
194905
  return {
195421
- fileExists: (name) => sys ? sys.fileExists(name) : import_node_fs8.default.existsSync(name),
194906
+ fileExists: (name) => sys ? sys.fileExists(name) : import_node_fs4.default.existsSync(name),
195422
194907
  readFile: (name) => {
195423
194908
  if (sys)
195424
194909
  return sys.readFile(name);
195425
194910
  try {
195426
- return import_node_fs8.default.readFileSync(name, "utf8");
194911
+ return import_node_fs4.default.readFileSync(name, "utf8");
195427
194912
  } catch {
195428
194913
  return;
195429
194914
  }
195430
194915
  },
195431
- directoryExists: (name) => sys ? sys.directoryExists(name) : import_node_fs8.default.existsSync(name) && import_node_fs8.default.statSync(name).isDirectory(),
195432
- getDirectories: (name) => sys ? sys.getDirectories(name) : import_node_fs8.default.existsSync(name) ? import_node_fs8.default.readdirSync(name, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name) : [],
194916
+ directoryExists: (name) => sys ? sys.directoryExists(name) : import_node_fs4.default.existsSync(name) && import_node_fs4.default.statSync(name).isDirectory(),
194917
+ getDirectories: (name) => sys ? sys.getDirectories(name) : import_node_fs4.default.existsSync(name) ? import_node_fs4.default.readdirSync(name, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name) : [],
195433
194918
  getCurrentDirectory: () => cwd,
195434
194919
  useCaseSensitiveFileNames: sys ? sys.useCaseSensitiveFileNames : true,
195435
194920
  realpath: sys?.realpath
195436
194921
  };
195437
194922
  };
195438
194923
  var readTsconfig = (cwd) => {
195439
- const tsconfigPath = import_node_path11.default.join(cwd, "tsconfig.json");
195440
- if (!import_node_fs8.default.existsSync(tsconfigPath))
194924
+ const tsconfigPath = import_node_path7.default.join(cwd, "tsconfig.json");
194925
+ if (!import_node_fs4.default.existsSync(tsconfigPath))
195441
194926
  return {};
195442
194927
  try {
195443
- const raw = import_node_fs8.default.readFileSync(tsconfigPath, "utf8");
194928
+ const raw = import_node_fs4.default.readFileSync(tsconfigPath, "utf8");
195444
194929
  const result = ts2.parseConfigFileTextToJson(tsconfigPath, raw);
195445
194930
  const parsed = result?.config;
195446
194931
  if (!parsed)
@@ -195456,7 +194941,7 @@ var readTsconfig = (cwd) => {
195456
194941
  var resolveByTsconfigPaths = (spec, cwd, tsconfig) => {
195457
194942
  if (!tsconfig.paths)
195458
194943
  return null;
195459
- const base = tsconfig.baseUrl ? import_node_path11.default.resolve(cwd, tsconfig.baseUrl) : cwd;
194944
+ const base = tsconfig.baseUrl ? import_node_path7.default.resolve(cwd, tsconfig.baseUrl) : cwd;
195460
194945
  for (const pattern of Object.keys(tsconfig.paths)) {
195461
194946
  const targets = tsconfig.paths[pattern];
195462
194947
  if (!targets || targets.length === 0)
@@ -195466,7 +194951,7 @@ var resolveByTsconfigPaths = (spec, cwd, tsconfig) => {
195466
194951
  if (spec !== pattern)
195467
194952
  continue;
195468
194953
  for (const target of targets) {
195469
- const candidate = import_node_path11.default.resolve(base, target);
194954
+ const candidate = import_node_path7.default.resolve(base, target);
195470
194955
  const resolved = tryExtensions(candidate);
195471
194956
  if (resolved)
195472
194957
  return resolved;
@@ -195479,7 +194964,7 @@ var resolveByTsconfigPaths = (spec, cwd, tsconfig) => {
195479
194964
  const matched = spec.slice(prefix.length, spec.length - suffix.length);
195480
194965
  for (const target of targets) {
195481
194966
  const replaced = target.replace("*", matched);
195482
- const candidate = import_node_path11.default.resolve(base, replaced);
194967
+ const candidate = import_node_path7.default.resolve(base, replaced);
195483
194968
  const resolved = tryExtensions(candidate);
195484
194969
  if (resolved)
195485
194970
  return resolved;
@@ -195492,13 +194977,13 @@ var tryExtensions = (candidate) => {
195492
194977
  const exts = ["", ".ts", ".tsx", ".d.ts", ".js", ".jsx"];
195493
194978
  for (const ext of exts) {
195494
194979
  const file = candidate + ext;
195495
- if (import_node_fs8.default.existsSync(file) && import_node_fs8.default.statSync(file).isFile())
194980
+ if (import_node_fs4.default.existsSync(file) && import_node_fs4.default.statSync(file).isFile())
195496
194981
  return file;
195497
194982
  }
195498
- if (import_node_fs8.default.existsSync(candidate) && import_node_fs8.default.statSync(candidate).isDirectory()) {
194983
+ if (import_node_fs4.default.existsSync(candidate) && import_node_fs4.default.statSync(candidate).isDirectory()) {
195499
194984
  for (const ext of ["index.ts", "index.tsx", "index.js"]) {
195500
- const file = import_node_path11.default.join(candidate, ext);
195501
- if (import_node_fs8.default.existsSync(file))
194985
+ const file = import_node_path7.default.join(candidate, ext);
194986
+ if (import_node_fs4.default.existsSync(file))
195502
194987
  return file;
195503
194988
  }
195504
194989
  }
@@ -195515,7 +195000,7 @@ var COMPILER_OPTIONS = (cwd) => {
195515
195000
  esModuleInterop: true,
195516
195001
  allowSyntheticDefaultImports: true,
195517
195002
  skipLibCheck: true,
195518
- baseUrl: tsconfig.baseUrl ? import_node_path11.default.resolve(cwd, tsconfig.baseUrl) : cwd,
195003
+ baseUrl: tsconfig.baseUrl ? import_node_path7.default.resolve(cwd, tsconfig.baseUrl) : cwd,
195519
195004
  paths: tsconfig.paths
195520
195005
  };
195521
195006
  };
@@ -195535,16 +195020,16 @@ var collectImportSpecifiers = (sourceFile) => {
195535
195020
  return out;
195536
195021
  };
195537
195022
  var isInside = (child, parent) => {
195538
- const rel = import_node_path11.default.relative(parent, child);
195539
- return rel !== "" && !rel.startsWith("..") && !import_node_path11.default.isAbsolute(rel);
195023
+ const rel = import_node_path7.default.relative(parent, child);
195024
+ return rel !== "" && !rel.startsWith("..") && !import_node_path7.default.isAbsolute(rel);
195540
195025
  };
195541
- var isNodeModulesPath = (file) => file.includes(`${import_node_path11.default.sep}node_modules${import_node_path11.default.sep}`);
195026
+ var isNodeModulesPath = (file) => file.includes(`${import_node_path7.default.sep}node_modules${import_node_path7.default.sep}`);
195542
195027
  var readPackageDeps = (cwd) => {
195543
- const pkgPath = import_node_path11.default.join(cwd, "package.json");
195544
- if (!import_node_fs8.default.existsSync(pkgPath))
195028
+ const pkgPath = import_node_path7.default.join(cwd, "package.json");
195029
+ if (!import_node_fs4.default.existsSync(pkgPath))
195545
195030
  return {};
195546
195031
  try {
195547
- const raw = import_node_fs8.default.readFileSync(pkgPath, "utf8");
195032
+ const raw = import_node_fs4.default.readFileSync(pkgPath, "utf8");
195548
195033
  const pkg = JSON.parse(raw);
195549
195034
  return {
195550
195035
  ...pkg.dependencies,
@@ -195583,11 +195068,11 @@ var extractImports = (files, cwd = process.cwd()) => {
195583
195068
  const specs = collectImportSpecifiers(sourceFile);
195584
195069
  for (const spec of specs) {
195585
195070
  const resolved = ts2.resolveModuleName(spec, file, options, host);
195586
- let resolvedAbs = resolved?.resolvedModule?.resolvedFileName ? import_node_path11.default.resolve(resolved.resolvedModule.resolvedFileName) : null;
195071
+ let resolvedAbs = resolved?.resolvedModule?.resolvedFileName ? import_node_path7.default.resolve(resolved.resolvedModule.resolvedFileName) : null;
195587
195072
  if (!resolvedAbs) {
195588
195073
  const viaPaths = resolveByTsconfigPaths(spec, cwd, tsconfig);
195589
195074
  if (viaPaths)
195590
- resolvedAbs = import_node_path11.default.resolve(viaPaths);
195075
+ resolvedAbs = import_node_path7.default.resolve(viaPaths);
195591
195076
  }
195592
195077
  if (resolvedAbs && isInside(resolvedAbs, cwd) && !isNodeModulesPath(resolvedAbs)) {
195593
195078
  relativeSet.add(resolvedAbs);
@@ -195611,7 +195096,7 @@ var extractImports = (files, cwd = process.cwd()) => {
195611
195096
  };
195612
195097
  };
195613
195098
  // src/code/introspection/extractEvents.ts
195614
- var import_node_fs9 = __toESM(require("node:fs"));
195099
+ var import_node_fs5 = __toESM(require("node:fs"));
195615
195100
  var PIE_CARD_TAG = "PieCard";
195616
195101
  var METHODS_PROP = "methods";
195617
195102
  var isPieCardJsx = (node) => {
@@ -195647,7 +195132,12 @@ var extractKeysFromObjectLiteral = (objLiteral, sourceFile) => {
195647
195132
  for (const prop of objLiteral.properties) {
195648
195133
  if (ts2.isSpreadAssignment(prop)) {
195649
195134
  const start = ts2.getLineAndCharacterOfPosition(sourceFile, prop.getStart());
195650
- throw new Error(`${sourceFile.fileName}:${start.line + 1}: ` + `<PieCard methods={…}> must be an inline object literal — ` + `spread/rest is not allowed`);
195135
+ throw new IntrospectionError("<PieCard methods={…}> must be an inline object literal — " + "spread/rest is not allowed", {
195136
+ sourceFile: sourceFile.fileName,
195137
+ line: start.line + 1,
195138
+ column: start.character + 1,
195139
+ hint: "list all handler keys explicitly: methods={{ key: fn }}"
195140
+ });
195651
195141
  }
195652
195142
  if (ts2.isPropertyAssignment(prop) || ts2.isShorthandPropertyAssignment(prop) || ts2.isMethodDeclaration(prop)) {
195653
195143
  const name = prop.name;
@@ -195657,7 +195147,12 @@ var extractKeysFromObjectLiteral = (objLiteral, sourceFile) => {
195657
195147
  keys.push(name.text);
195658
195148
  } else if (ts2.isComputedPropertyName(name)) {
195659
195149
  const start = ts2.getLineAndCharacterOfPosition(sourceFile, name.getStart());
195660
- throw new Error(`${sourceFile.fileName}:${start.line + 1}: ` + `<PieCard methods={…}> keys must be static identifiers ` + `or string literals — computed keys are not allowed`);
195150
+ throw new IntrospectionError("<PieCard methods={…}> keys must be static identifiers " + "or string literals — computed keys are not allowed", {
195151
+ sourceFile: sourceFile.fileName,
195152
+ line: start.line + 1,
195153
+ column: start.character + 1,
195154
+ hint: "use a plain identifier or string literal as the key"
195155
+ });
195661
195156
  }
195662
195157
  }
195663
195158
  }
@@ -195668,7 +195163,7 @@ var extractEvents = (files) => {
195668
195163
  for (const file of files) {
195669
195164
  let text;
195670
195165
  try {
195671
- text = import_node_fs9.default.readFileSync(file, "utf8");
195166
+ text = import_node_fs5.default.readFileSync(file, "utf8");
195672
195167
  } catch {
195673
195168
  continue;
195674
195169
  }
@@ -195681,11 +195176,19 @@ var extractEvents = (files) => {
195681
195176
  const init = methodsAttr.initializer;
195682
195177
  if (!ts2.isJsxExpression(init) || !init.expression) {
195683
195178
  const start = ts2.getLineAndCharacterOfPosition(sourceFile, init.getStart());
195684
- throw new Error(`${file}:${start.line + 1}: ` + `<PieCard methods={…}> must be set with an inline object literal`);
195179
+ throw new IntrospectionError("<PieCard methods={…}> must be set with an inline object literal", {
195180
+ sourceFile: file,
195181
+ line: start.line + 1,
195182
+ hint: "use methods={{...}} directly on the PieCard element"
195183
+ });
195685
195184
  }
195686
195185
  if (!ts2.isObjectLiteralExpression(init.expression)) {
195687
195186
  const start = ts2.getLineAndCharacterOfPosition(sourceFile, init.expression.getStart());
195688
- throw new Error(`${file}:${start.line + 1}: ` + `<PieCard methods={…}> must be an inline object literal ` + `(found ${ts2.SyntaxKind[init.expression.kind]})`);
195187
+ throw new IntrospectionError(`<PieCard methods={…}> must be an inline object literal ` + `(found ${ts2.SyntaxKind[init.expression.kind]})`, {
195188
+ sourceFile: file,
195189
+ line: start.line + 1,
195190
+ hint: "inline the handler map directly: methods={{ click: (p) => ... }}"
195191
+ });
195689
195192
  }
195690
195193
  for (const k2 of extractKeysFromObjectLiteral(init.expression, sourceFile)) {
195691
195194
  events.add(k2);
@@ -195962,6 +195465,187 @@ var findStoredAttributeType = (ctx, files) => {
195962
195465
  }
195963
195466
  return null;
195964
195467
  };
195468
+ // src/code/introspection/extractDescription.ts
195469
+ var PIE_CARD_TAG4 = "PieCard";
195470
+ var METHODS_PROP2 = "methods";
195471
+ var stripCommentMarkers = (raw) => {
195472
+ const trimmed = raw.trim();
195473
+ if (trimmed.startsWith("/*")) {
195474
+ let inner = trimmed.startsWith("/**") ? trimmed.slice(3) : trimmed.slice(2);
195475
+ if (inner.endsWith("*/"))
195476
+ inner = inner.slice(0, -2);
195477
+ return inner.split(`
195478
+ `).map((line) => line.replace(/^\s*\*\s?/, "").trimEnd()).join(`
195479
+ `).trim();
195480
+ }
195481
+ return trimmed.split(`
195482
+ `).map((line) => line.replace(/^\s*\/\/\s?/, "").trimEnd()).join(`
195483
+ `).trim();
195484
+ };
195485
+ var leadingComment = (node) => {
195486
+ const sf = node.getSourceFile?.();
195487
+ if (!sf)
195488
+ return null;
195489
+ const ranges = ts2.getLeadingCommentRanges(sf.text, node.getFullStart());
195490
+ if (!ranges || ranges.length === 0)
195491
+ return null;
195492
+ const cleaned = ranges.map((r) => stripCommentMarkers(sf.text.slice(r.pos, r.end))).filter((s) => s.length > 0).join(`
195493
+
195494
+ `);
195495
+ return cleaned || null;
195496
+ };
195497
+ var findComponentDeclarationNode = (sourceFile, name) => {
195498
+ let hit = null;
195499
+ const visit = (node) => {
195500
+ if (hit)
195501
+ return;
195502
+ if (ts2.isFunctionDeclaration(node) && node.name?.text === name) {
195503
+ hit = node;
195504
+ return;
195505
+ }
195506
+ if (ts2.isVariableStatement(node)) {
195507
+ for (const decl of node.declarationList.declarations) {
195508
+ if (ts2.isIdentifier(decl.name) && decl.name.text === name) {
195509
+ hit = node;
195510
+ return;
195511
+ }
195512
+ }
195513
+ }
195514
+ ts2.forEachChild(node, visit);
195515
+ };
195516
+ visit(sourceFile);
195517
+ return hit;
195518
+ };
195519
+ var typeMembers = (declaration) => {
195520
+ if (!declaration)
195521
+ return [];
195522
+ if (ts2.isInterfaceDeclaration(declaration)) {
195523
+ return declaration.members;
195524
+ }
195525
+ if (ts2.isTypeAliasDeclaration(declaration)) {
195526
+ const t = declaration.type;
195527
+ if (ts2.isTypeLiteralNode(t))
195528
+ return t.members;
195529
+ }
195530
+ return [];
195531
+ };
195532
+ var resolveHandlerDeclaration = (ctx, identifier, shorthandParent = null) => {
195533
+ let symbol = null;
195534
+ if (shorthandParent) {
195535
+ symbol = ctx.checker.getShorthandAssignmentValueSymbol(shorthandParent);
195536
+ }
195537
+ if (!symbol)
195538
+ symbol = ctx.checker.getSymbolAtLocation(identifier);
195539
+ if (!symbol)
195540
+ return null;
195541
+ const realSymbol = symbol.flags & ts2.SymbolFlags.Alias ? ctx.checker.getAliasedSymbol(symbol) : symbol;
195542
+ const decls = realSymbol.declarations;
195543
+ if (!decls || decls.length === 0)
195544
+ return null;
195545
+ for (const decl of decls) {
195546
+ if (ts2.isFunctionDeclaration(decl))
195547
+ return decl;
195548
+ if (ts2.isVariableDeclaration(decl)) {
195549
+ let n7 = decl.parent;
195550
+ while (n7 && !ts2.isVariableStatement(n7))
195551
+ n7 = n7.parent;
195552
+ if (n7)
195553
+ return n7;
195554
+ return decl;
195555
+ }
195556
+ if (ts2.isMethodDeclaration(decl) || ts2.isMethodSignature(decl)) {
195557
+ return decl;
195558
+ }
195559
+ }
195560
+ return null;
195561
+ };
195562
+ var collectHandlerComments = (ctx, files, events) => {
195563
+ const eventSet = new Set(events);
195564
+ const perEvent = new Map;
195565
+ const push = (key, c) => {
195566
+ if (!c)
195567
+ return;
195568
+ const arr = perEvent.get(key) ?? [];
195569
+ if (!arr.includes(c))
195570
+ arr.push(c);
195571
+ perEvent.set(key, arr);
195572
+ };
195573
+ for (const file of files) {
195574
+ const sourceFile = ctx.program.getSourceFile(file);
195575
+ if (!sourceFile)
195576
+ continue;
195577
+ const visit = (node) => {
195578
+ const isPieCard = (ts2.isJsxSelfClosingElement(node) || ts2.isJsxOpeningElement(node)) && ts2.isIdentifier(node.tagName) && node.tagName.text === PIE_CARD_TAG4;
195579
+ if (isPieCard && node.attributes?.properties) {
195580
+ for (const attr of node.attributes.properties) {
195581
+ if (ts2.isJsxAttribute(attr) && attr.name && ts2.isIdentifier(attr.name) && attr.name.text === METHODS_PROP2 && attr.initializer && ts2.isJsxExpression(attr.initializer) && attr.initializer.expression && ts2.isObjectLiteralExpression(attr.initializer.expression)) {
195582
+ for (const prop of attr.initializer.expression.properties) {
195583
+ const nameNode = prop.name;
195584
+ let key = null;
195585
+ if (nameNode && ts2.isIdentifier(nameNode))
195586
+ key = nameNode.text;
195587
+ else if (nameNode && ts2.isStringLiteral(nameNode))
195588
+ key = nameNode.text;
195589
+ if (!key || !eventSet.has(key))
195590
+ continue;
195591
+ push(key, leadingComment(prop));
195592
+ if (ts2.isPropertyAssignment(prop) && ts2.isIdentifier(prop.initializer)) {
195593
+ const decl = resolveHandlerDeclaration(ctx, prop.initializer);
195594
+ if (decl)
195595
+ push(key, leadingComment(decl));
195596
+ } else if (ts2.isShorthandPropertyAssignment(prop)) {
195597
+ const decl = resolveHandlerDeclaration(ctx, prop.name, prop);
195598
+ if (decl)
195599
+ push(key, leadingComment(decl));
195600
+ }
195601
+ }
195602
+ }
195603
+ }
195604
+ }
195605
+ ts2.forEachChild(node, visit);
195606
+ };
195607
+ visit(sourceFile);
195608
+ }
195609
+ const out = [];
195610
+ for (const ev of [...events].sort()) {
195611
+ const comments = perEvent.get(ev);
195612
+ if (!comments)
195613
+ continue;
195614
+ for (const c of comments)
195615
+ out.push(c);
195616
+ }
195617
+ return out;
195618
+ };
195619
+ var extractDescription = (ctx, componentName, files, dataDeclaration, events) => {
195620
+ const parts = [];
195621
+ const dataDoc = leadingComment(dataDeclaration);
195622
+ if (dataDoc)
195623
+ parts.push(dataDoc);
195624
+ for (const file of files) {
195625
+ const sf = ctx.program.getSourceFile(file);
195626
+ if (!sf)
195627
+ continue;
195628
+ const node = findComponentDeclarationNode(sf, componentName);
195629
+ if (!node)
195630
+ continue;
195631
+ const c = leadingComment(node);
195632
+ if (c) {
195633
+ parts.push(c);
195634
+ break;
195635
+ }
195636
+ }
195637
+ for (const m of typeMembers(dataDeclaration)) {
195638
+ const c = leadingComment(m);
195639
+ if (c)
195640
+ parts.push(c);
195641
+ }
195642
+ for (const c of collectHandlerComments(ctx, files, events)) {
195643
+ parts.push(c);
195644
+ }
195645
+ return parts.join(`
195646
+
195647
+ `);
195648
+ };
195965
195649
  // src/code/commands/cardDumpMetadata.ts
195966
195650
  var COMPONENT_EXTS3 = [".ts", ".tsx"];
195967
195651
  var stableStringify = (value2) => {
@@ -195985,8 +195669,8 @@ var stableStringify = (value2) => {
195985
195669
  };
195986
195670
  var buildCardMetadata = (componentName) => {
195987
195671
  const settings = loadSettings();
195988
- const componentDir = import_node_path12.default.join(settings.componentsDir, componentName);
195989
- if (!import_node_fs10.default.existsSync(componentDir)) {
195672
+ const componentDir = import_node_path8.default.join(settings.componentsDir, componentName);
195673
+ if (!import_node_fs6.default.existsSync(componentDir)) {
195990
195674
  throw new Error(`Component directory not found: ${componentDir}`);
195991
195675
  }
195992
195676
  const files = collectComponentFiles(componentDir);
@@ -195997,8 +195681,8 @@ var buildCardMetadata = (componentName) => {
195997
195681
  const ctx = createSchemaContext(tsFiles);
195998
195682
  const componentsDir = settings.componentsDir;
195999
195683
  const fileEntries = files.map((absPath) => ({
196000
- path: import_node_path12.default.relative(componentsDir, absPath),
196001
- content: import_node_fs10.default.readFileSync(absPath, "utf8")
195684
+ path: import_node_path8.default.relative(componentsDir, absPath),
195685
+ content: import_node_fs6.default.readFileSync(absPath, "utf8")
196002
195686
  }));
196003
195687
  const dataType = findComponentDataTypeForName(ctx, componentName);
196004
195688
  const propsCode = dataType.declaration.getText();
@@ -196006,6 +195690,7 @@ var buildCardMetadata = (componentName) => {
196006
195690
  const ajaxList = extractAjaxList(dataType.declaration);
196007
195691
  const events = extractEvents(tsFiles);
196008
195692
  const { code: eventsPropsCode, schema: eventsPropsSchema } = extractEventsPayloads(ctx, tsFiles, events);
195693
+ const description = extractDescription(ctx, componentName, tsFiles, dataType.declaration, events);
196009
195694
  const inputType = findStoredAttributeType(ctx, tsFiles);
196010
195695
  const inputPropsCode = inputType ? inputType.declaration.getText() : null;
196011
195696
  let inputPropsSchema = null;
@@ -196029,6 +195714,7 @@ var buildCardMetadata = (componentName) => {
196029
195714
  events,
196030
195715
  propsSchema,
196031
195716
  propsCode,
195717
+ description,
196032
195718
  eventsPropsSchema,
196033
195719
  eventsPropsCode,
196034
195720
  inputPropsCode,
@@ -196038,11 +195724,11 @@ var buildCardMetadata = (componentName) => {
196038
195724
  };
196039
195725
  var DUMP_METADATA_ENVELOPE_KEY = "typescript";
196040
195726
  var mergeEnvelopeIntoFile = (target, envelope) => {
196041
- if (!import_node_fs10.default.existsSync(target))
195727
+ if (!import_node_fs6.default.existsSync(target))
196042
195728
  return envelope;
196043
195729
  let existing;
196044
195730
  try {
196045
- existing = JSON.parse(import_node_fs10.default.readFileSync(target, "utf8"));
195731
+ existing = JSON.parse(import_node_fs6.default.readFileSync(target, "utf8"));
196046
195732
  } catch (e) {
196047
195733
  throw new Error(`[pieui] Cannot merge: existing file ${target} is not valid JSON ` + `(${e.message})`);
196048
195734
  }
@@ -196057,56 +195743,603 @@ var cardDumpMetadataCommand = (componentName, outFile) => {
196057
195743
  [DUMP_METADATA_ENVELOPE_KEY]: meta
196058
195744
  };
196059
195745
  if (outFile) {
196060
- const resolved = import_node_path12.default.resolve(process.cwd(), outFile);
195746
+ const resolved = import_node_path8.default.resolve(process.cwd(), outFile);
196061
195747
  const merged = mergeEnvelopeIntoFile(resolved, envelope);
196062
195748
  const json = stableStringify(merged);
196063
- import_node_fs10.default.mkdirSync(import_node_path12.default.dirname(resolved), { recursive: true });
196064
- import_node_fs10.default.writeFileSync(resolved, json, "utf8");
195749
+ import_node_fs6.default.mkdirSync(import_node_path8.default.dirname(resolved), { recursive: true });
195750
+ import_node_fs6.default.writeFileSync(resolved, json, "utf8");
196065
195751
  console.log(`[pieui] Wrote metadata: ${resolved}`);
196066
195752
  } else {
196067
195753
  process.stdout.write(stableStringify(envelope));
196068
195754
  }
196069
195755
  };
196070
195756
 
196071
- // src/code/commands/cardCheckSync.ts
195757
+ // src/code/commands/cardRemote/cardRef.ts
195758
+ var parseNameAndRevision = (namePart, raw) => {
195759
+ const atIndex = namePart.indexOf("@");
195760
+ if (atIndex === -1)
195761
+ return { componentName: namePart };
195762
+ const componentName = namePart.slice(0, atIndex);
195763
+ const revisionPart = namePart.slice(atIndex + 1);
195764
+ if (!componentName) {
195765
+ throw new Error(`missing component name in ${JSON.stringify(raw)}`);
195766
+ }
195767
+ if (!revisionPart) {
195768
+ throw new Error(`missing revision after '@' in ${JSON.stringify(raw)}`);
195769
+ }
195770
+ if (!/^\d+$/.test(revisionPart)) {
195771
+ throw new Error(`revision must be a positive integer, got ${JSON.stringify(revisionPart)}`);
195772
+ }
195773
+ const revision = Number(revisionPart);
195774
+ if (revision < 1) {
195775
+ throw new Error(`revision must be >= 1, got ${revision}`);
195776
+ }
195777
+ return { componentName, revision };
195778
+ };
195779
+ var parseCardRef = (input) => {
195780
+ if (!input) {
195781
+ throw new Error("card ref must not be empty");
195782
+ }
195783
+ if (input.startsWith("r/")) {
195784
+ const rest = input.slice(2);
195785
+ const parts2 = rest.split("/");
195786
+ if (parts2.length !== 2 || !parts2[0] || !parts2[1]) {
195787
+ throw new Error(`expected r/<user>/<Component>, got ${JSON.stringify(input)}`);
195788
+ }
195789
+ const [userId, namePart] = parts2;
195790
+ const { componentName, revision } = parseNameAndRevision(namePart, input);
195791
+ if (revision !== undefined) {
195792
+ throw new Error("revision suffix is not supported for public refs (r/...)");
195793
+ }
195794
+ return { componentName, userId, isPublic: true };
195795
+ }
195796
+ const parts = input.split("/");
195797
+ if (parts.length === 1) {
195798
+ return parseNameAndRevision(input, input);
195799
+ }
195800
+ if (parts.length === 2) {
195801
+ const [project, namePart] = parts;
195802
+ if (!project || !namePart) {
195803
+ throw new Error(`expected <project>/<Component>, got ${JSON.stringify(input)}`);
195804
+ }
195805
+ const { componentName, revision } = parseNameAndRevision(namePart, input);
195806
+ return { componentName, revision, project };
195807
+ }
195808
+ throw new Error(`invalid card ref ${JSON.stringify(input)}: expected <Component>, <project>/<Component>, or r/<user>/<Component>`);
195809
+ };
195810
+
195811
+ // src/code/commands/cardRemote/push.ts
195812
+ var cardRemotePushCommand = async (cardRef) => {
195813
+ const ref = parseCardRef(cardRef);
195814
+ if (ref.revision !== undefined) {
195815
+ throw new Error("push does not accept a revision suffix");
195816
+ }
195817
+ if (ref.isPublic) {
195818
+ throw new Error("push does not accept public refs (r/...)");
195819
+ }
195820
+ if (ref.project || ref.userId) {
195821
+ throw new Error("push does not accept project/user override; pass just <ComponentName>");
195822
+ }
195823
+ const { componentName } = ref;
195824
+ if (!/^[A-Z][A-Za-z0-9]+$/.test(componentName)) {
195825
+ throw new Error("Component name must start with uppercase letter and contain only letters and numbers");
195826
+ }
195827
+ const settings = loadSettings();
195828
+ if (!settings.userId) {
195829
+ throw new Error("user_id is required (set PIE_USER_ID in env or .env; run `pieui login`)");
195830
+ }
195831
+ const componentDir = import_node_path9.default.join(settings.componentsDir, componentName);
195832
+ if (!import_node_fs7.default.existsSync(componentDir) || !import_node_fs7.default.statSync(componentDir).isDirectory()) {
195833
+ throw new Error(`Component directory not found: ${componentDir}`);
195834
+ }
195835
+ const meta = buildCardMetadata(componentName);
195836
+ const service = new PieStorageService(settings);
195837
+ await service.pushEnvelope({
195838
+ componentName,
195839
+ body: { typescript: meta }
195840
+ });
195841
+ const latestRevision = await latestRevisionNumber(service, componentName);
195842
+ console.log(`[pieui] Uploaded card: ${componentName}`);
195843
+ console.log(`[pieui] Path: ${componentDir}`);
195844
+ console.log(`[pieui] Files: ${meta.files.length}`);
195845
+ if (latestRevision !== undefined) {
195846
+ console.log(`[pieui] Revision: ${componentName}@${latestRevision}`);
195847
+ }
195848
+ };
195849
+ var latestRevisionNumber = async (service, componentName) => {
195850
+ try {
195851
+ const list = await service.listRevisions({ componentName });
195852
+ if (list.revisions.length === 0)
195853
+ return;
195854
+ return list.revisions.reduce((max, entry) => entry.revision > max ? entry.revision : max, 0);
195855
+ } catch (error) {
195856
+ if (error instanceof PieStorageError)
195857
+ return;
195858
+ throw error;
195859
+ }
195860
+ };
195861
+
195862
+ // src/code/commands/cardRemote/pull.ts
195863
+ var import_node_fs9 = __toESM(require("node:fs"));
195864
+ var import_node_path11 = __toESM(require("node:path"));
195865
+
195866
+ // src/code/services/dumpEnvelope.ts
195867
+ var import_node_fs8 = __toESM(require("node:fs"));
195868
+ var import_node_path10 = __toESM(require("node:path"));
195869
+ var unwrapTypescriptEnvelope = (parsed) => {
195870
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
195871
+ throw new Error("dump-metadata payload is not a JSON object");
195872
+ }
195873
+ const obj = parsed;
195874
+ const inner = obj.typescript;
195875
+ if (!inner || typeof inner !== "object" || Array.isArray(inner)) {
195876
+ const keys = Object.keys(obj).join(", ") || "(none)";
195877
+ throw new Error('dump-metadata payload is missing the "typescript" envelope ' + `(top-level keys: {${keys}})`);
195878
+ }
195879
+ return inner;
195880
+ };
195881
+ var restoreComponentFromEnvelope = (envelope, label) => {
195882
+ const inner = unwrapTypescriptEnvelope(envelope);
195883
+ const componentName = inner.name;
195884
+ const files = inner.files;
195885
+ if (typeof componentName !== "string" || !componentName) {
195886
+ throw new Error(`${label}: typescript.name is missing or empty`);
195887
+ }
195888
+ if (!Array.isArray(files)) {
195889
+ throw new Error(`${label}: typescript.files must be an array of {path, content}`);
195890
+ }
195891
+ const settings = loadSettings();
195892
+ const planned = [];
195893
+ for (const entry of files) {
195894
+ if (!entry || typeof entry !== "object" || typeof entry.path !== "string" || typeof entry.content !== "string") {
195895
+ throw new Error(`${label}: every files[] entry must be {path: string, content: string}`);
195896
+ }
195897
+ const fe2 = entry;
195898
+ const target = import_node_path10.default.resolve(settings.componentsDir, fe2.path);
195899
+ const relCheck = import_node_path10.default.relative(settings.componentsDir, target);
195900
+ if (relCheck.startsWith("..") || import_node_path10.default.isAbsolute(relCheck)) {
195901
+ throw new Error(`${label}: file path "${fe2.path}" escapes componentsDir`);
195902
+ }
195903
+ planned.push({ target, content: fe2.content });
195904
+ }
195905
+ import_node_fs8.default.mkdirSync(settings.componentsDir, { recursive: true });
195906
+ const componentDir = import_node_path10.default.join(settings.componentsDir, componentName);
195907
+ if (import_node_fs8.default.existsSync(componentDir)) {
195908
+ import_node_fs8.default.rmSync(componentDir, { recursive: true, force: true });
195909
+ }
195910
+ const written = [];
195911
+ for (const item of planned) {
195912
+ import_node_fs8.default.mkdirSync(import_node_path10.default.dirname(item.target), { recursive: true });
195913
+ import_node_fs8.default.writeFileSync(item.target, item.content, "utf8");
195914
+ written.push(item.target);
195915
+ }
195916
+ return { componentName, written };
195917
+ };
195918
+ var restoreComponentFromEnvelopeText = (raw, label) => {
195919
+ let parsed;
195920
+ try {
195921
+ parsed = JSON.parse(raw);
195922
+ } catch (e) {
195923
+ throw new Error(`${label} is not valid JSON: ${e.message}`);
195924
+ }
195925
+ return restoreComponentFromEnvelope(parsed, label);
195926
+ };
195927
+
195928
+ // src/code/commands/cardRemote/pull.ts
195929
+ var cardRemotePullCommand = async (cardRef) => {
195930
+ const ref = parseCardRef(cardRef);
195931
+ const { componentName, revision, isPublic } = ref;
195932
+ const settings = loadSettings();
195933
+ const effectiveUserId = ref.userId ?? settings.userId;
195934
+ if (!effectiveUserId) {
195935
+ throw new Error("user_id is required (set PIE_USER_ID in env or .env; run `pieui login`)");
195936
+ }
195937
+ const effectiveProject = isPublic ? undefined : ref.project ?? settings.project;
195938
+ if (!isPublic && !effectiveProject) {
195939
+ throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG in env or .env)");
195940
+ }
195941
+ const sourceLabel = isPublic ? `r/${effectiveUserId}/${componentName}` : ref.project ? `${effectiveProject}/${componentName}` : componentName;
195942
+ const suffix = revision !== undefined ? `@${revision}` : "";
195943
+ const service = new PieStorageService(settings);
195944
+ import_node_fs9.default.mkdirSync(settings.componentsDir, { recursive: true });
195945
+ if (isPublic) {
195946
+ await pullPublicViaTree(service, settings.componentsDir, {
195947
+ componentName,
195948
+ userId: effectiveUserId
195949
+ });
195950
+ const componentDir = import_node_path11.default.join(settings.componentsDir, componentName);
195951
+ console.log(`[pieui] Pulled card: ${sourceLabel}${suffix}`);
195952
+ for (const p of walkFiles(componentDir)) {
195953
+ console.log(`[pieui] Path: ${p}`);
195954
+ }
195955
+ return;
195956
+ }
195957
+ const envelope = await service.fetchEnvelope({
195958
+ componentName,
195959
+ userId: effectiveUserId,
195960
+ project: effectiveProject,
195961
+ revision
195962
+ });
195963
+ const { written } = restoreComponentFromEnvelope(envelope, `${sourceLabel}${suffix}`);
195964
+ console.log(`[pieui] Pulled card: ${sourceLabel}${suffix}`);
195965
+ for (const p of written)
195966
+ console.log(`[pieui] Path: ${p}`);
195967
+ };
195968
+ var pullPublicViaTree = async (service, componentsDir, args) => {
195969
+ const componentDir = import_node_path11.default.join(componentsDir, args.componentName);
195970
+ const tempDir = `${componentDir}.pieui-tmp-${process.pid}-${Date.now()}`;
195971
+ import_node_fs9.default.rmSync(tempDir, { recursive: true, force: true });
195972
+ import_node_fs9.default.mkdirSync(tempDir, { recursive: true });
195973
+ let downloaded;
195974
+ try {
195975
+ downloaded = await service.downloadComponentDirectory({
195976
+ componentName: args.componentName,
195977
+ targetDir: tempDir,
195978
+ userId: args.userId,
195979
+ isPublic: true
195980
+ });
195981
+ } catch (error) {
195982
+ import_node_fs9.default.rmSync(tempDir, { recursive: true, force: true });
195983
+ throw error;
195984
+ }
195985
+ if (downloaded.length === 0) {
195986
+ import_node_fs9.default.rmSync(tempDir, { recursive: true, force: true });
195987
+ throw new Error(`No typescript files found for remote component r/${args.userId}/${args.componentName} ` + `(user_id=${args.userId} (public))`);
195988
+ }
195989
+ if (import_node_fs9.default.existsSync(componentDir)) {
195990
+ import_node_fs9.default.rmSync(componentDir, { recursive: true, force: true });
195991
+ }
195992
+ import_node_fs9.default.renameSync(tempDir, componentDir);
195993
+ };
195994
+ var walkFiles = (dir) => {
195995
+ const out = [];
195996
+ if (!import_node_fs9.default.existsSync(dir))
195997
+ return out;
195998
+ const walk = (d) => {
195999
+ for (const entry of import_node_fs9.default.readdirSync(d, { withFileTypes: true })) {
196000
+ const abs = import_node_path11.default.join(d, entry.name);
196001
+ if (entry.isDirectory())
196002
+ walk(abs);
196003
+ else if (entry.isFile())
196004
+ out.push(abs);
196005
+ }
196006
+ };
196007
+ walk(dir);
196008
+ out.sort();
196009
+ return out;
196010
+ };
196011
+
196012
+ // src/code/commands/cardRemote/list.ts
196013
+ var cardRemoteListCommand = async (options) => {
196014
+ const settings = loadSettings();
196015
+ const userId = options.userId || settings.userId;
196016
+ const project = options.project || settings.project;
196017
+ if (!userId) {
196018
+ throw new Error("user_id is required (use --user or set PIE_USER_ID in env or .env)");
196019
+ }
196020
+ if (!project) {
196021
+ throw new Error("project is required (use --project or set PIE_PROJECT / PIE_PROJECT_SLUG)");
196022
+ }
196023
+ const service = new PieStorageService(settings);
196024
+ const result = await service.listProjectComponents({ userId, project });
196025
+ console.log(`[pieui] Remote components for user_id=${JSON.stringify(result.userId)} project_slug=${JSON.stringify(result.project)}:`);
196026
+ for (const entry of [...result.components].sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()))) {
196027
+ console.log(entry.name);
196028
+ }
196029
+ };
196030
+
196031
+ // src/code/commands/cardRemote/remove.ts
196032
+ var cardRemoteRemoveCommand = async (componentName) => {
196033
+ const settings = loadSettings();
196034
+ if (!settings.userId) {
196035
+ throw new Error("user_id is required (set PIE_USER_ID in env or .env)");
196036
+ }
196037
+ if (!settings.project) {
196038
+ throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG in env or .env)");
196039
+ }
196040
+ const service = new PieStorageService(settings);
196041
+ await service.deleteComponent({ componentName });
196042
+ console.log(`[pieui] Removed remote component: ${componentName}`);
196043
+ };
196044
+
196045
+ // src/code/commands/cardRemote/history.ts
196046
+ var extractPath = (key, componentName) => {
196047
+ const marker = `/${componentName}/${STORAGE_LANGUAGE}/`;
196048
+ const idx = key.indexOf(marker);
196049
+ if (idx === -1)
196050
+ return key;
196051
+ return key.slice(idx + marker.length);
196052
+ };
196053
+ var formatFileBlock = (file, componentName) => {
196054
+ const path20 = extractPath(file.key, componentName);
196055
+ const before = file.status === "added" ? "a//dev/null" : `a/${path20}`;
196056
+ const after = file.status === "deleted" ? "b//dev/null" : `b/${path20}`;
196057
+ const lines = [];
196058
+ lines.push(`diff --git ${before} ${after}`);
196059
+ lines.push(`${file.status} +${file.additions} -${file.deletions} ${path20}`);
196060
+ if (file.isBinary) {
196061
+ lines.push("Binary files differ");
196062
+ } else if (file.patch) {
196063
+ lines.push(file.patch.replace(/\n+$/, ""));
196064
+ }
196065
+ return lines;
196066
+ };
196067
+ var formatRevisionBlock = (entry, componentName) => {
196068
+ const lines = [];
196069
+ lines.push(`revision ${componentName}@${entry.revision}`);
196070
+ lines.push(`date ${entry.createdAt}`);
196071
+ lines.push(`mutation ${entry.mutation}`);
196072
+ if (entry.previousRevision !== null) {
196073
+ lines.push(`previous ${entry.previousRevision}`);
196074
+ }
196075
+ if (entry.deleted) {
196076
+ lines.push("deleted true");
196077
+ }
196078
+ for (const file of entry.files) {
196079
+ lines.push("");
196080
+ lines.push(...formatFileBlock(file, componentName));
196081
+ }
196082
+ return lines;
196083
+ };
196084
+ var cardRemoteHistoryCommand = async (options) => {
196085
+ const settings = loadSettings();
196086
+ if (!settings.userId) {
196087
+ throw new Error("user_id is required (set PIE_USER_ID in env or .env)");
196088
+ }
196089
+ if (!settings.project) {
196090
+ throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG)");
196091
+ }
196092
+ if (options.from !== undefined && options.to !== undefined && options.from > options.to) {
196093
+ throw new Error("--from must be <= --to");
196094
+ }
196095
+ const service = new PieStorageService(settings);
196096
+ const history = await service.getHistory({
196097
+ componentName: options.componentName,
196098
+ page: options.page,
196099
+ perPage: options.perPage,
196100
+ from: options.from,
196101
+ to: options.to
196102
+ });
196103
+ const output = [];
196104
+ output.push(`component ${history.userId}/${history.project}/${history.componentName}`);
196105
+ output.push(`page ${history.page} per-page ${history.perPage} total-revisions ${history.totalRevisions}`);
196106
+ if (history.fromRevision !== null || history.toRevision !== null) {
196107
+ const from = history.fromRevision !== null ? String(history.fromRevision) : "*";
196108
+ const to = history.toRevision !== null ? String(history.toRevision) : "*";
196109
+ output.push(`range ${from}..${to}`);
196110
+ }
196111
+ for (const entry of history.entries) {
196112
+ output.push("");
196113
+ output.push(...formatRevisionBlock(entry, history.componentName));
196114
+ }
196115
+ console.log(output.join(`
196116
+ `));
196117
+ };
196118
+
196119
+ // src/code/commands/cardRemote/public.ts
196120
+ var cardRemotePublicCommand = async (componentName) => {
196121
+ const settings = loadSettings();
196122
+ if (!settings.userId) {
196123
+ throw new Error("user_id is required (set PIE_USER_ID in env or .env)");
196124
+ }
196125
+ if (!settings.project) {
196126
+ throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG)");
196127
+ }
196128
+ const service = new PieStorageService(settings);
196129
+ const state = await service.markComponentPublic({ componentName });
196130
+ console.log(`[pieui] Marked public: ${state.componentName} (user=${state.userId} project=${state.project})`);
196131
+ console.log(`[pieui] is_public: ${state.isPublic}`);
196132
+ if (state.publicRegistryName) {
196133
+ console.log(`[pieui] Public registry name: ${state.publicRegistryName}`);
196134
+ }
196135
+ console.log(`[pieui] Public read URL: <api>/public-components/${state.userId}/${state.componentName}`);
196136
+ };
196137
+
196138
+ // src/code/commands/cardRemote/private.ts
196139
+ var cardRemotePrivateCommand = async (componentName) => {
196140
+ const settings = loadSettings();
196141
+ if (!settings.userId) {
196142
+ throw new Error("user_id is required (set PIE_USER_ID in env or .env)");
196143
+ }
196144
+ if (!settings.project) {
196145
+ throw new Error("project is required (set PIE_PROJECT or PIE_PROJECT_SLUG)");
196146
+ }
196147
+ const service = new PieStorageService(settings);
196148
+ const state = await service.markComponentPrivate({ componentName });
196149
+ console.log(`[pieui] Marked private: ${state.componentName} (user=${state.userId} project=${state.project})`);
196150
+ console.log(`[pieui] is_public: ${state.isPublic}`);
196151
+ };
196152
+
196153
+ // src/code/commands/cardPull.ts
196154
+ var import_node_fs10 = __toESM(require("node:fs"));
196155
+ var import_node_path12 = __toESM(require("node:path"));
196156
+ var isHttpUrl = (ref) => /^https?:\/\//i.test(ref);
196157
+ var isLocalJsonPath = (ref) => {
196158
+ if (ref.startsWith("./") || ref.startsWith("../") || ref.startsWith("/") || ref.startsWith("~")) {
196159
+ return true;
196160
+ }
196161
+ if (!ref.endsWith(".json"))
196162
+ return false;
196163
+ return import_node_fs10.default.existsSync(import_node_path12.default.resolve(process.cwd(), ref));
196164
+ };
196165
+ var fetchJsonText = async (url) => {
196166
+ const res = await fetch(url);
196167
+ if (!res.ok) {
196168
+ throw new Error(`HTTP ${res.status} ${res.statusText} fetching ${url}`);
196169
+ }
196170
+ return await res.text();
196171
+ };
196172
+ var printRestoreOutput = (componentName, written, label) => {
196173
+ console.log(`[pieui] Pulled card from ${label}: ${componentName}`);
196174
+ for (const w of written)
196175
+ console.log(`[pieui] Path: ${w}`);
196176
+ };
196177
+ var cardPullCommand = async (cardRef) => {
196178
+ if (isHttpUrl(cardRef)) {
196179
+ console.log(`[pieui] Fetching dump from ${cardRef}`);
196180
+ const raw = await fetchJsonText(cardRef);
196181
+ const { componentName, written } = restoreComponentFromEnvelopeText(raw, cardRef);
196182
+ printRestoreOutput(componentName, written, cardRef);
196183
+ return;
196184
+ }
196185
+ if (isLocalJsonPath(cardRef)) {
196186
+ const abs = import_node_path12.default.resolve(process.cwd(), cardRef);
196187
+ if (!import_node_fs10.default.existsSync(abs)) {
196188
+ throw new Error(`Pull source not found: ${abs}`);
196189
+ }
196190
+ if (!import_node_fs10.default.statSync(abs).isFile()) {
196191
+ throw new Error(`Pull source is not a file: ${abs}`);
196192
+ }
196193
+ const { componentName, written } = restoreComponentFromEnvelopeText(import_node_fs10.default.readFileSync(abs, "utf8"), abs);
196194
+ printRestoreOutput(componentName, written, abs);
196195
+ return;
196196
+ }
196197
+ await cardRemotePullCommand(cardRef);
196198
+ };
196199
+
196200
+ // src/code/commands/cardView.ts
196072
196201
  var import_node_fs11 = __toESM(require("node:fs"));
196073
196202
  var import_node_path13 = __toESM(require("node:path"));
196203
+ var AJAX_FIELD_NAMES = new Set(["pathname", "deps_names", "kwargs"]);
196204
+ var IO_FIELD_RE = /\buse_[A-Za-z0-9_]+_support\b/g;
196205
+ var extractInterfaceBody = (source, interfaceName) => {
196206
+ const idx = source.indexOf(`interface ${interfaceName}`);
196207
+ if (idx === -1)
196208
+ return null;
196209
+ const braceStart = source.indexOf("{", idx);
196210
+ if (braceStart === -1)
196211
+ return null;
196212
+ let depth = 0;
196213
+ for (let i = braceStart;i < source.length; i++) {
196214
+ const ch = source[i];
196215
+ if (ch === "{")
196216
+ depth++;
196217
+ else if (ch === "}") {
196218
+ depth--;
196219
+ if (depth === 0)
196220
+ return source.slice(braceStart + 1, i);
196221
+ }
196222
+ }
196223
+ return null;
196224
+ };
196225
+ var parseProps = (body) => {
196226
+ const props = [];
196227
+ const lineRe = /^[ \t]*([A-Za-z_][A-Za-z0-9_]*)(\?)?\s*:\s*([^;\n]+?)\s*;?\s*$/gm;
196228
+ let match;
196229
+ while ((match = lineRe.exec(body)) !== null) {
196230
+ const [, name, optional, typeRaw] = match;
196231
+ props.push({
196232
+ name,
196233
+ type: typeRaw.trim(),
196234
+ default: optional ? "(optional)" : "(required)"
196235
+ });
196236
+ }
196237
+ return props;
196238
+ };
196239
+ var formatTable = (headers, rows) => {
196240
+ const data = [headers, ...rows];
196241
+ const widths = headers.map((_2, c) => Math.max(...data.map((row) => (row[c] ?? "").length)));
196242
+ const hline = `+${widths.map((w) => "-".repeat(w + 2)).join("+")}+`;
196243
+ const fmtRow = (cells) => `|${cells.map((cell, i) => ` ${(cell ?? "").padEnd(widths[i])} `).join("|")}|`;
196244
+ return [hline, fmtRow(headers), hline, ...rows.map(fmtRow), hline].join(`
196245
+ `);
196246
+ };
196247
+ var cardViewCommand = (componentName) => {
196248
+ const settings = loadSettings();
196249
+ const componentDir = import_node_path13.default.join(settings.componentsDir, componentName);
196250
+ if (!import_node_fs11.default.existsSync(componentDir)) {
196251
+ throw new Error(`Component directory not found: ${componentDir}`);
196252
+ }
196253
+ const typesPath = import_node_path13.default.join(componentDir, "types.ts");
196254
+ const indexPath = import_node_path13.default.join(componentDir, "index.tsx");
196255
+ const indexPathTs = import_node_path13.default.join(componentDir, "index.ts");
196256
+ const typesSource = import_node_fs11.default.existsSync(typesPath) ? import_node_fs11.default.readFileSync(typesPath, "utf8") : "";
196257
+ const indexSource = import_node_fs11.default.existsSync(indexPath) ? import_node_fs11.default.readFileSync(indexPath, "utf8") : import_node_fs11.default.existsSync(indexPathTs) ? import_node_fs11.default.readFileSync(indexPathTs, "utf8") : "";
196258
+ const dataInterface = extractInterfaceBody(typesSource, `${componentName}Data`) ?? "";
196259
+ const props = parseProps(dataInterface);
196260
+ const hasAjax = props.some((p) => AJAX_FIELD_NAMES.has(p.name));
196261
+ const ioFields2 = props.map((p) => p.name).filter((name) => IO_FIELD_RE.test(name));
196262
+ IO_FIELD_RE.lastIndex = 0;
196263
+ const events = [];
196264
+ const eventRe = /\b(?:on|create)([A-Z][A-Za-z0-9]*)Event\b|methods\s*=\s*\{([\s\S]*?)\}/g;
196265
+ const methodsMatch = indexSource.match(/methods\s*=\s*\{([\s\S]*?)\}/);
196266
+ if (methodsMatch) {
196267
+ const inner = methodsMatch[1];
196268
+ const keyRe = /([A-Za-z_][A-Za-z0-9_]*)\s*:/g;
196269
+ let m;
196270
+ while ((m = keyRe.exec(inner)) !== null)
196271
+ events.push(m[1]);
196272
+ }
196273
+ console.log("Name:");
196274
+ console.log(componentName);
196275
+ console.log("");
196276
+ console.log("File:");
196277
+ console.log(import_node_path13.default.resolve(componentDir));
196278
+ console.log("");
196279
+ console.log("Props:");
196280
+ if (props.length === 0) {
196281
+ console.log("(none)");
196282
+ } else {
196283
+ console.log(formatTable(["Name", "Type", "Default"], props.map((p) => [p.name, p.type, p.default])));
196284
+ }
196285
+ console.log("");
196286
+ console.log("Ajax:");
196287
+ console.log(hasAjax ? "yes" : "no");
196288
+ console.log("");
196289
+ console.log("IO:");
196290
+ if (ioFields2.length === 0) {
196291
+ console.log("no");
196292
+ } else {
196293
+ console.log(formatTable(["name"], ioFields2.map((n7) => [n7])));
196294
+ }
196295
+ console.log("");
196296
+ console.log("Events:");
196297
+ if (events.length === 0) {
196298
+ console.log("no (run `pieui card list-events " + componentName + "`)");
196299
+ } else {
196300
+ console.log(formatTable(["event"], events.map((e) => [e])));
196301
+ }
196302
+ };
196303
+
196304
+ // src/code/commands/cardCheckSync.ts
196305
+ var import_node_fs12 = __toESM(require("node:fs"));
196306
+ var import_node_path14 = __toESM(require("node:path"));
196074
196307
  var import_node_child_process2 = require("node:child_process");
196075
196308
  var readline2 = __toESM(require("node:readline/promises"));
196076
196309
  var PIE_CONFIG_DIR2 = ".pie";
196077
196310
  var PIE_CONFIG_FILE2 = "config.json";
196078
196311
  var readConfig = (cwd) => {
196079
- const configPath = import_node_path13.default.join(cwd, PIE_CONFIG_DIR2, PIE_CONFIG_FILE2);
196080
- if (!import_node_fs11.default.existsSync(configPath))
196312
+ const configPath = import_node_path14.default.join(cwd, PIE_CONFIG_DIR2, PIE_CONFIG_FILE2);
196313
+ if (!import_node_fs12.default.existsSync(configPath))
196081
196314
  return {};
196082
196315
  try {
196083
- const parsed = JSON.parse(import_node_fs11.default.readFileSync(configPath, "utf8"));
196316
+ const parsed = JSON.parse(import_node_fs12.default.readFileSync(configPath, "utf8"));
196084
196317
  return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : {};
196085
196318
  } catch {
196086
196319
  return {};
196087
196320
  }
196088
196321
  };
196089
196322
  var writeConfig = (cwd, config) => {
196090
- const dir = import_node_path13.default.join(cwd, PIE_CONFIG_DIR2);
196091
- import_node_fs11.default.mkdirSync(dir, { recursive: true });
196092
- const configPath = import_node_path13.default.join(dir, PIE_CONFIG_FILE2);
196093
- import_node_fs11.default.writeFileSync(configPath, JSON.stringify(config, null, 2) + `
196323
+ const dir = import_node_path14.default.join(cwd, PIE_CONFIG_DIR2);
196324
+ import_node_fs12.default.mkdirSync(dir, { recursive: true });
196325
+ const configPath = import_node_path14.default.join(dir, PIE_CONFIG_FILE2);
196326
+ import_node_fs12.default.writeFileSync(configPath, JSON.stringify(config, null, 2) + `
196094
196327
  `, "utf8");
196095
196328
  };
196096
196329
  var walkUpForPyproject = (start) => {
196097
- let dir = import_node_path13.default.resolve(start);
196098
- while (dir !== import_node_path13.default.dirname(dir)) {
196099
- if (import_node_fs11.default.existsSync(import_node_path13.default.join(dir, "pyproject.toml")))
196330
+ let dir = import_node_path14.default.resolve(start);
196331
+ while (dir !== import_node_path14.default.dirname(dir)) {
196332
+ if (import_node_fs12.default.existsSync(import_node_path14.default.join(dir, "pyproject.toml")))
196100
196333
  return dir;
196101
- dir = import_node_path13.default.dirname(dir);
196334
+ dir = import_node_path14.default.dirname(dir);
196102
196335
  }
196103
196336
  return null;
196104
196337
  };
196105
196338
  var ensureBackendDir = async (cwd) => {
196106
196339
  const config = readConfig(cwd);
196107
196340
  if (config.backendProjectDir) {
196108
- const dir = import_node_path13.default.resolve(cwd, config.backendProjectDir);
196109
- if (import_node_fs11.default.existsSync(dir) && import_node_fs11.default.statSync(dir).isDirectory())
196341
+ const dir = import_node_path14.default.resolve(cwd, config.backendProjectDir);
196342
+ if (import_node_fs12.default.existsSync(dir) && import_node_fs12.default.statSync(dir).isDirectory())
196110
196343
  return dir;
196111
196344
  console.error(`[pieui] Configured backendProjectDir not found: ${dir}`);
196112
196345
  }
@@ -196120,7 +196353,7 @@ var ensureBackendDir = async (cwd) => {
196120
196353
  }
196121
196354
  }
196122
196355
  if (!process.stdin.isTTY) {
196123
- console.error(`[pieui] Non-interactive shell — add "backendProjectDir" to ${import_node_path13.default.join(cwd, PIE_CONFIG_DIR2, PIE_CONFIG_FILE2)}`);
196356
+ console.error(`[pieui] Non-interactive shell — add "backendProjectDir" to ${import_node_path14.default.join(cwd, PIE_CONFIG_DIR2, PIE_CONFIG_FILE2)}`);
196124
196357
  return null;
196125
196358
  }
196126
196359
  const rl = readline2.createInterface({
@@ -196131,15 +196364,15 @@ var ensureBackendDir = async (cwd) => {
196131
196364
  const raw = (await rl.question("[pieui] Path to backend (pie) project: ")).trim();
196132
196365
  if (!raw)
196133
196366
  return null;
196134
- const expanded = raw.startsWith("~") ? import_node_path13.default.join(process.env.HOME || "", raw.slice(1).replace(/^[\\/]/, "")) : raw;
196135
- const absolute = import_node_path13.default.resolve(expanded);
196136
- if (!import_node_fs11.default.existsSync(absolute) || !import_node_fs11.default.statSync(absolute).isDirectory()) {
196367
+ const expanded = raw.startsWith("~") ? import_node_path14.default.join(process.env.HOME || "", raw.slice(1).replace(/^[\\/]/, "")) : raw;
196368
+ const absolute = import_node_path14.default.resolve(expanded);
196369
+ if (!import_node_fs12.default.existsSync(absolute) || !import_node_fs12.default.statSync(absolute).isDirectory()) {
196137
196370
  console.error(`[pieui] Not a directory: ${absolute}`);
196138
196371
  return null;
196139
196372
  }
196140
196373
  config.backendProjectDir = absolute;
196141
196374
  writeConfig(cwd, config);
196142
- console.log(`[pieui] Saved backendProjectDir → ${import_node_path13.default.join(cwd, PIE_CONFIG_DIR2, PIE_CONFIG_FILE2)}`);
196375
+ console.log(`[pieui] Saved backendProjectDir → ${import_node_path14.default.join(cwd, PIE_CONFIG_DIR2, PIE_CONFIG_FILE2)}`);
196143
196376
  return absolute;
196144
196377
  } finally {
196145
196378
  rl.close();
@@ -196150,8 +196383,8 @@ var findVenvPython = (project) => {
196150
196383
  if (override)
196151
196384
  return override;
196152
196385
  for (const sub of [".venv", "venv"]) {
196153
- const candidate = import_node_path13.default.join(project, sub, "bin", "python");
196154
- if (import_node_fs11.default.existsSync(candidate))
196386
+ const candidate = import_node_path14.default.join(project, sub, "bin", "python");
196387
+ if (import_node_fs12.default.existsSync(candidate))
196155
196388
  return candidate;
196156
196389
  }
196157
196390
  return "python3";
@@ -196184,11 +196417,11 @@ var cardCheckSyncCommand = async (componentName) => {
196184
196417
  };
196185
196418
 
196186
196419
  // src/code/commands/cardAddStory.ts
196187
- var import_node_fs13 = __toESM(require("node:fs"));
196188
- var import_node_path14 = __toESM(require("node:path"));
196420
+ var import_node_fs14 = __toESM(require("node:fs"));
196421
+ var import_node_path15 = __toESM(require("node:path"));
196189
196422
 
196190
196423
  // src/code/patchPieCardForwarding.ts
196191
- var import_node_fs12 = __toESM(require("node:fs"));
196424
+ var import_node_fs13 = __toESM(require("node:fs"));
196192
196425
  var IO_FIELDS = [
196193
196426
  "useSocketioSupport",
196194
196427
  "useCentrifugeSupport",
@@ -196197,21 +196430,15 @@ var IO_FIELDS = [
196197
196430
  ];
196198
196431
  var FIELD_DECL_RE = (name) => new RegExp(`(^|[\\s\\{,;])${name}\\s*\\??\\s*:`);
196199
196432
  var detectCardIsIO = (typesPath) => {
196200
- if (!import_node_fs12.default.existsSync(typesPath))
196433
+ if (!import_node_fs13.default.existsSync(typesPath))
196201
196434
  return false;
196202
- const source = import_node_fs12.default.readFileSync(typesPath, "utf8");
196435
+ const source = import_node_fs13.default.readFileSync(typesPath, "utf8");
196203
196436
  return IO_FIELDS.some((field) => FIELD_DECL_RE(field).test(source));
196204
196437
  };
196205
196438
  var forwardingPropsFor = (isIO) => {
196206
- const required = [
196207
- { name: "data", expr: "data" },
196208
- {
196209
- name: "useMittSupport",
196210
- expr: "data.useMittSupport ?? false"
196211
- }
196212
- ];
196213
- if (!isIO)
196214
- return required;
196439
+ if (!isIO) {
196440
+ return [{ name: "data", expr: "data" }];
196441
+ }
196215
196442
  return [
196216
196443
  { name: "data", expr: "data" },
196217
196444
  {
@@ -196246,10 +196473,10 @@ var indentOfFirstAttr = (source, sourceFile, attrs) => {
196246
196473
  return { indent: " ", multiline: false };
196247
196474
  };
196248
196475
  var patchPieCardForwarding = (uiPath, options = { io: false }) => {
196249
- if (!import_node_fs12.default.existsSync(uiPath)) {
196476
+ if (!import_node_fs13.default.existsSync(uiPath)) {
196250
196477
  return { patched: false, addedPerSite: [] };
196251
196478
  }
196252
- const source = import_node_fs12.default.readFileSync(uiPath, "utf8");
196479
+ const source = import_node_fs13.default.readFileSync(uiPath, "utf8");
196253
196480
  const sourceFile = ts2.createSourceFile(uiPath, source, ts2.ScriptTarget.ES2020, true, ts2.ScriptKind.TSX);
196254
196481
  const required = forwardingPropsFor(options.io);
196255
196482
  const insertions = [];
@@ -196293,7 +196520,7 @@ ${indent}${p.name}={${p.expr}}` : ` ${p.name}={${p.expr}}`).join("");
196293
196520
  for (const ins of insertions) {
196294
196521
  result = result.slice(0, ins.pos) + ins.text + result.slice(ins.pos);
196295
196522
  }
196296
- import_node_fs12.default.writeFileSync(uiPath, result, "utf8");
196523
+ import_node_fs13.default.writeFileSync(uiPath, result, "utf8");
196297
196524
  return { patched: true, addedPerSite };
196298
196525
  };
196299
196526
 
@@ -196313,7 +196540,7 @@ var collectComponentFiles2 = (componentDir) => {
196313
196540
  const out = new Set;
196314
196541
  for (const p of patterns) {
196315
196542
  for (const f of Ze.sync(p, { ignore })) {
196316
- out.add(import_node_path14.default.resolve(f));
196543
+ out.add(import_node_path15.default.resolve(f));
196317
196544
  }
196318
196545
  }
196319
196546
  return Array.from(out).sort();
@@ -196357,7 +196584,7 @@ var samplePayloadFromSchema = (schema) => {
196357
196584
  }
196358
196585
  return out;
196359
196586
  };
196360
- var renderStoryFile = (componentName, events, payloads) => {
196587
+ var renderStoryFile = (componentName, events, payloads, options) => {
196361
196588
  const methodsJson = events.map((ev) => ({
196362
196589
  name: ev,
196363
196590
  payloadSchema: payloads.schema[ev] ?? null,
@@ -196367,11 +196594,16 @@ var renderStoryFile = (componentName, events, payloads) => {
196367
196594
  const methodsLiteral = JSON.stringify(methodsJson, null, 4).split(`
196368
196595
  `).map((line, i) => i === 0 ? line : " " + line).join(`
196369
196596
  `);
196597
+ const dataBody = options.io ? ` // Storybook addon fires mitt events; PieCard subscribes only when
196598
+ // useMittSupport === true. Leave this on for the in-storybook play.
196599
+ name: '${componentName}',
196600
+ useMittSupport: true,` : ` name: '${componentName}',`;
196370
196601
  return `import type { Meta, StoryObj } from '@storybook/react'
196371
196602
  import { withPieCard } from '@swarm.ing/pieui/storybook'
196372
- import ${componentName} from './${componentName}'
196603
+ import ${componentName} from './ui/${componentName}'
196373
196604
 
196374
196605
  const meta: Meta<typeof ${componentName}> = {
196606
+ title: 'PieComponents/${componentName}',
196375
196607
  component: ${componentName},
196376
196608
  decorators: [withPieCard],
196377
196609
  parameters: {
@@ -196388,17 +196620,13 @@ type Story = StoryObj<typeof ${componentName}>
196388
196620
  export const Default: Story = {
196389
196621
  args: {
196390
196622
  data: {
196391
- // Storybook addon fires mitt events; PieCard subscribes only when
196392
- // useMittSupport === true. Leave this on for the in-storybook play.
196393
- // @ts-expect-error — base props vary by component type.
196394
- name: '${componentName}',
196395
- useMittSupport: true,
196623
+ ${dataBody}
196396
196624
  },
196397
196625
  },
196398
196626
  }
196399
196627
  `;
196400
196628
  };
196401
- var cardAddStoryCommand = (componentName) => {
196629
+ var cardAddStoryCommand = (componentName, options = {}) => {
196402
196630
  if (!componentName) {
196403
196631
  throw new Error("Component name is required");
196404
196632
  }
@@ -196406,8 +196634,8 @@ var cardAddStoryCommand = (componentName) => {
196406
196634
  throw new Error("Component name must start with uppercase letter and contain only letters and numbers");
196407
196635
  }
196408
196636
  const settings = loadSettings();
196409
- const componentDir = import_node_path14.default.join(settings.componentsDir, componentName);
196410
- if (!import_node_fs13.default.existsSync(componentDir)) {
196637
+ const componentDir = import_node_path15.default.join(settings.componentsDir, componentName);
196638
+ if (!import_node_fs14.default.existsSync(componentDir)) {
196411
196639
  throw new Error(`Component directory not found: ${componentDir}`);
196412
196640
  }
196413
196641
  const tsFiles = collectComponentFiles2(componentDir).filter((f) => COMPONENT_EXTS4.some((e) => f.endsWith(e)));
@@ -196431,21 +196659,22 @@ var cardAddStoryCommand = (componentName) => {
196431
196659
  }
196432
196660
  }
196433
196661
  }
196434
- const storyPath = import_node_path14.default.join(componentDir, "ui", `${componentName}.stories.tsx`);
196435
- if (import_node_fs13.default.existsSync(storyPath)) {
196436
- throw new Error(`Story file already exists: ${storyPath}`);
196437
- }
196438
- import_node_fs13.default.mkdirSync(import_node_path14.default.dirname(storyPath), { recursive: true });
196439
- import_node_fs13.default.writeFileSync(storyPath, renderStoryFile(componentName, events, payloads), "utf8");
196440
- console.log(`[pieui] Story created: ${storyPath}`);
196662
+ const typesPath = import_node_path15.default.join(componentDir, "types", "index.ts");
196663
+ const uiPath = import_node_path15.default.join(componentDir, "ui", `${componentName}.tsx`);
196664
+ const io = detectCardIsIO(typesPath);
196665
+ const storyPath = import_node_path15.default.join(componentDir, `${componentName}.stories.tsx`);
196666
+ const storyExists = import_node_fs14.default.existsSync(storyPath);
196667
+ if (storyExists && !options.force) {
196668
+ throw new Error(`Story file already exists: ${storyPath}
196669
+ ` + `Pass --force to overwrite.`);
196670
+ }
196671
+ import_node_fs14.default.writeFileSync(storyPath, renderStoryFile(componentName, events, payloads, { io }), "utf8");
196672
+ console.log(`[pieui] Story ${storyExists ? "overwritten" : "created"}: ${storyPath}`);
196441
196673
  if (events.length > 0) {
196442
196674
  console.log(`[pieui] Methods wired: ${events.join(", ")}`);
196443
196675
  } else {
196444
196676
  console.log(`[pieui] No <PieCard methods={{…}}/> found — story has no method triggers yet.`);
196445
196677
  }
196446
- const typesPath = import_node_path14.default.join(componentDir, "types", "index.ts");
196447
- const uiPath = import_node_path14.default.join(componentDir, "ui", `${componentName}.tsx`);
196448
- const io = detectCardIsIO(typesPath);
196449
196678
  const result = patchPieCardForwarding(uiPath, { io });
196450
196679
  if (result.patched) {
196451
196680
  const allAdded = Array.from(new Set(result.addedPerSite.flatMap((s) => s.added)));
@@ -196457,8 +196686,8 @@ var cardAddStoryCommand = (componentName) => {
196457
196686
  };
196458
196687
 
196459
196688
  // src/code/commands/cardAddFromMeta.ts
196460
- var import_node_fs14 = __toESM(require("node:fs"));
196461
- var import_node_path15 = __toESM(require("node:path"));
196689
+ var import_node_fs15 = __toESM(require("node:fs"));
196690
+ var import_node_path16 = __toESM(require("node:path"));
196462
196691
  var import_node_child_process3 = require("node:child_process");
196463
196692
 
196464
196693
  // src/code/jsonSchemaToTs.ts
@@ -196539,11 +196768,11 @@ var jsonSchemaToTsType = (schema) => renderType(asSchema(schema), 0);
196539
196768
  // src/code/commands/cardAddFromMeta.ts
196540
196769
  var PIE_CONFIG_PATH = ".pie/config.json";
196541
196770
  var readBackendConfig = () => {
196542
- const configPath = import_node_path15.default.join(process.cwd(), PIE_CONFIG_PATH);
196543
- if (!import_node_fs14.default.existsSync(configPath))
196771
+ const configPath = import_node_path16.default.join(process.cwd(), PIE_CONFIG_PATH);
196772
+ if (!import_node_fs15.default.existsSync(configPath))
196544
196773
  return null;
196545
196774
  try {
196546
- const parsed = JSON.parse(import_node_fs14.default.readFileSync(configPath, "utf8"));
196775
+ const parsed = JSON.parse(import_node_fs15.default.readFileSync(configPath, "utf8"));
196547
196776
  if (typeof parsed !== "object" || parsed === null)
196548
196777
  return null;
196549
196778
  return parsed;
@@ -196560,16 +196789,16 @@ var cardNameToClassFilename = (name) => {
196560
196789
  return snake.endsWith("_card") ? `${snake}.py` : `${snake}_card.py`;
196561
196790
  };
196562
196791
  var resolveSource = (fromRaw, cardName, cfg) => {
196563
- if (fromRaw && import_node_fs14.default.existsSync(fromRaw)) {
196564
- const stat = import_node_fs14.default.statSync(fromRaw);
196565
- const abs = import_node_path15.default.resolve(fromRaw);
196792
+ if (fromRaw && import_node_fs15.default.existsSync(fromRaw)) {
196793
+ const stat = import_node_fs15.default.statSync(fromRaw);
196794
+ const abs = import_node_path16.default.resolve(fromRaw);
196566
196795
  if (stat.isFile() && abs.endsWith(".json")) {
196567
196796
  return { kind: "json-file", path: abs };
196568
196797
  }
196569
196798
  if (stat.isFile() && abs.endsWith(".py")) {
196570
- const componentsDir2 = import_node_path15.default.dirname(abs);
196571
- const backendRoot2 = import_node_path15.default.dirname(componentsDir2);
196572
- const inferred = classFilenameToCardName(import_node_path15.default.basename(abs));
196799
+ const componentsDir2 = import_node_path16.default.dirname(abs);
196800
+ const backendRoot2 = import_node_path16.default.dirname(componentsDir2);
196801
+ const inferred = classFilenameToCardName(import_node_path16.default.basename(abs));
196573
196802
  return {
196574
196803
  kind: "py-file",
196575
196804
  backendRoot: backendRoot2,
@@ -196577,7 +196806,7 @@ var resolveSource = (fromRaw, cardName, cfg) => {
196577
196806
  };
196578
196807
  }
196579
196808
  if (stat.isDirectory()) {
196580
- const backendRoot2 = import_node_path15.default.dirname(abs);
196809
+ const backendRoot2 = import_node_path16.default.dirname(abs);
196581
196810
  return { kind: "name", backendRoot: backendRoot2, cardName };
196582
196811
  }
196583
196812
  throw new Error(`--from path is not a recognized source: ${fromRaw}`);
@@ -196586,18 +196815,18 @@ var resolveSource = (fromRaw, cardName, cfg) => {
196586
196815
  if (!cfg?.backendComponentsDir) {
196587
196816
  throw new Error(`--from "${fromRaw}" is not an existing path and no backendComponentsDir is configured in ${PIE_CONFIG_PATH}`);
196588
196817
  }
196589
- const componentsDir2 = import_node_path15.default.resolve(cfg.backendComponentsDir);
196590
- const backendRoot2 = import_node_path15.default.dirname(componentsDir2);
196818
+ const componentsDir2 = import_node_path16.default.resolve(cfg.backendComponentsDir);
196819
+ const backendRoot2 = import_node_path16.default.dirname(componentsDir2);
196591
196820
  return { kind: "name", backendRoot: backendRoot2, cardName: fromRaw };
196592
196821
  }
196593
196822
  if (!cfg?.backendComponentsDir) {
196594
196823
  throw new Error(`No --from provided and no backendComponentsDir configured in ${PIE_CONFIG_PATH}`);
196595
196824
  }
196596
- const componentsDir = import_node_path15.default.resolve(cfg.backendComponentsDir);
196597
- const backendRoot = import_node_path15.default.dirname(componentsDir);
196825
+ const componentsDir = import_node_path16.default.resolve(cfg.backendComponentsDir);
196826
+ const backendRoot = import_node_path16.default.dirname(componentsDir);
196598
196827
  return { kind: "name", backendRoot, cardName };
196599
196828
  };
196600
- var unwrapTypescriptEnvelope = (parsed) => {
196829
+ var unwrapTypescriptEnvelope2 = (parsed) => {
196601
196830
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
196602
196831
  throw new Error("dump-metadata payload is not a JSON object — expected " + '{"typescript": {...}}');
196603
196832
  }
@@ -196611,8 +196840,8 @@ var unwrapTypescriptEnvelope = (parsed) => {
196611
196840
  };
196612
196841
  var fetchMetadata = (source) => {
196613
196842
  if (source.kind === "json-file") {
196614
- const raw = import_node_fs14.default.readFileSync(source.path, "utf8");
196615
- return unwrapTypescriptEnvelope(JSON.parse(raw));
196843
+ const raw = import_node_fs15.default.readFileSync(source.path, "utf8");
196844
+ return unwrapTypescriptEnvelope2(JSON.parse(raw));
196616
196845
  }
196617
196846
  console.log(`[pieui] Invoking: pie card dump-metadata ${source.cardName} (cwd: ${source.backendRoot})`);
196618
196847
  const result = import_node_child_process3.spawnSync("pie", ["card", "dump-metadata", source.cardName], {
@@ -196628,7 +196857,7 @@ var fetchMetadata = (source) => {
196628
196857
  throw new Error(`pie card dump-metadata exited with status ${result.status}: ${stderr.trim()}`);
196629
196858
  }
196630
196859
  const stdout = result.stdout ? result.stdout.toString() : "";
196631
- return unwrapTypescriptEnvelope(JSON.parse(stdout));
196860
+ return unwrapTypescriptEnvelope2(JSON.parse(stdout));
196632
196861
  };
196633
196862
  var extractTypeName = (code) => {
196634
196863
  if (!code)
@@ -196642,9 +196871,10 @@ var extractTypeName = (code) => {
196642
196871
  return null;
196643
196872
  };
196644
196873
  var renderTypes = (componentName, componentType, meta, dataInterfaceName, inputInterfaceName) => {
196645
- const baseInterface = baseInterfaceFor(componentType);
196874
+ const hasInput = !!(inputInterfaceName && meta.inputPropsSchema);
196875
+ const baseInterface = baseInterfaceFor(componentType, { input: hasInput });
196646
196876
  const dataIface = jsonSchemaToTsInterface(meta.propsSchema, dataInterfaceName);
196647
- const inputIface = inputInterfaceName && meta.inputPropsSchema ? jsonSchemaToTsInterface(meta.inputPropsSchema, inputInterfaceName) : null;
196877
+ const inputIface = hasInput ? jsonSchemaToTsInterface(meta.inputPropsSchema, inputInterfaceName) : null;
196648
196878
  const blocks = [
196649
196879
  `import { ${baseInterface} } from '@swarm.ing/pieui'`,
196650
196880
  "",
@@ -196653,7 +196883,8 @@ var renderTypes = (componentName, componentType, meta, dataInterfaceName, inputI
196653
196883
  if (inputIface) {
196654
196884
  blocks.push("", inputIface);
196655
196885
  }
196656
- blocks.push("", `export type ${componentName}Props = ${baseInterface}<${dataInterfaceName}>`);
196886
+ const propsAlias = hasInput ? `export type ${componentName}Props = ${baseInterface}<${dataInterfaceName}, ${inputInterfaceName}>` : `export type ${componentName}Props = ${baseInterface}<${dataInterfaceName}>`;
196887
+ blocks.push("", propsAlias);
196657
196888
  return blocks.join(`
196658
196889
  `) + `
196659
196890
  `;
@@ -196704,13 +196935,9 @@ var renderUI = (componentName, meta, inputInterfaceName) => {
196704
196935
  }
196705
196936
  const hasInput = !!inputInterfaceName;
196706
196937
  const cardLabel = JSON.stringify(componentName);
196707
- let body = `const ${componentName} = ({ data: _data }: ${componentName}Props) => {
196938
+ const destructure = hasInput ? `{ data: _data, stored }` : `{ data: _data }`;
196939
+ let body = `const ${componentName} = (${destructure}: ${componentName}Props) => {
196708
196940
  `;
196709
- if (hasInput) {
196710
- body += ` const stored: ${inputInterfaceName} | undefined = undefined
196711
-
196712
- `;
196713
- }
196714
196941
  body += ` return (
196715
196942
  `;
196716
196943
  body += ` <PieCard
@@ -196749,10 +196976,10 @@ var renderUI = (componentName, meta, inputInterfaceName) => {
196749
196976
  };
196750
196977
  var updateRegistryFile2 = (componentsDir, componentName) => {
196751
196978
  const registryPath = resolveRegistryPath(componentsDir);
196752
- if (!import_node_fs14.default.existsSync(registryPath)) {
196979
+ if (!import_node_fs15.default.existsSync(registryPath)) {
196753
196980
  throw new Error('registry.ts not found. Run "pieui init" first.');
196754
196981
  }
196755
- let registryContent = import_node_fs14.default.readFileSync(registryPath, "utf8");
196982
+ let registryContent = import_node_fs15.default.readFileSync(registryPath, "utf8");
196756
196983
  const importRegex = new RegExp(`["']@/piecomponents/${componentName}["']`);
196757
196984
  if (importRegex.test(registryContent)) {
196758
196985
  throw new Error(`Component ${componentName} is already registered in registry.ts`);
@@ -196761,17 +196988,17 @@ var updateRegistryFile2 = (componentsDir, componentName) => {
196761
196988
  registryContent = registryContent.trimEnd() + `
196762
196989
  ` + importLine + `
196763
196990
  `;
196764
- import_node_fs14.default.writeFileSync(registryPath, registryContent, "utf8");
196991
+ import_node_fs15.default.writeFileSync(registryPath, registryContent, "utf8");
196765
196992
  };
196766
196993
  var hasBackendSourceFor = (componentName) => {
196767
196994
  const cfg = readBackendConfig();
196768
196995
  if (!cfg?.backendComponentsDir)
196769
196996
  return false;
196770
- const componentsDir = import_node_path15.default.resolve(cfg.backendComponentsDir);
196771
- if (!import_node_fs14.default.existsSync(componentsDir))
196997
+ const componentsDir = import_node_path16.default.resolve(cfg.backendComponentsDir);
196998
+ if (!import_node_fs15.default.existsSync(componentsDir))
196772
196999
  return false;
196773
- const candidate = import_node_path15.default.join(componentsDir, cardNameToClassFilename(componentName));
196774
- return import_node_fs14.default.existsSync(candidate);
197000
+ const candidate = import_node_path16.default.join(componentsDir, cardNameToClassFilename(componentName));
197001
+ return import_node_fs15.default.existsSync(candidate);
196775
197002
  };
196776
197003
  var cardAddFromMetaCommand = (componentName, componentType, fromRaw) => {
196777
197004
  if (!componentName) {
@@ -196783,8 +197010,8 @@ var cardAddFromMetaCommand = (componentName, componentType, fromRaw) => {
196783
197010
  const cfg = readBackendConfig();
196784
197011
  const source = resolveSource(fromRaw, componentName, cfg);
196785
197012
  if (source.kind === "name") {
196786
- const candidate = import_node_path15.default.join(source.backendRoot, import_node_path15.default.basename(import_node_path15.default.resolve(cfg.backendComponentsDir)), cardNameToClassFilename(source.cardName));
196787
- if (!import_node_fs14.default.existsSync(candidate)) {
197013
+ const candidate = import_node_path16.default.join(source.backendRoot, import_node_path16.default.basename(import_node_path16.default.resolve(cfg.backendComponentsDir)), cardNameToClassFilename(source.cardName));
197014
+ if (!import_node_fs15.default.existsSync(candidate)) {
196788
197015
  console.warn(`[pieui] Note: expected backend file ${candidate} not found; relying on pie's resolution`);
196789
197016
  }
196790
197017
  }
@@ -196792,30 +197019,30 @@ var cardAddFromMetaCommand = (componentName, componentType, fromRaw) => {
196792
197019
  console.log(`[pieui] Loaded metadata for "${meta.name}" (${meta.events.length} events, input: ${meta.inputPropsCode ? "yes" : "no"})`);
196793
197020
  const dataInterfaceName = extractTypeName(meta.propsCode) || `${componentName}Data`;
196794
197021
  const inputInterfaceName = meta.inputPropsCode ? extractTypeName(meta.inputPropsCode) || `${componentName}StoredInput` : null;
196795
- const pieComponentsDir = import_node_path15.default.join(process.cwd(), "piecomponents");
196796
- if (!import_node_fs14.default.existsSync(pieComponentsDir)) {
197022
+ const pieComponentsDir = import_node_path16.default.join(process.cwd(), "piecomponents");
197023
+ if (!import_node_fs15.default.existsSync(pieComponentsDir)) {
196797
197024
  throw new Error('piecomponents directory not found. Run "pieui init" first.');
196798
197025
  }
196799
- const componentDir = import_node_path15.default.join(pieComponentsDir, componentName);
196800
- if (import_node_fs14.default.existsSync(componentDir)) {
197026
+ const componentDir = import_node_path16.default.join(pieComponentsDir, componentName);
197027
+ if (import_node_fs15.default.existsSync(componentDir)) {
196801
197028
  throw new Error(`Component ${componentName} already exists`);
196802
197029
  }
196803
197030
  try {
196804
- import_node_fs14.default.mkdirSync(import_node_path15.default.join(componentDir, "ui"), { recursive: true });
196805
- import_node_fs14.default.mkdirSync(import_node_path15.default.join(componentDir, "types"), { recursive: true });
196806
- import_node_fs14.default.writeFileSync(import_node_path15.default.join(componentDir, "index.ts"), componentIndexTemplate(componentName), "utf8");
196807
- import_node_fs14.default.writeFileSync(import_node_path15.default.join(componentDir, "types", "index.ts"), renderTypes(componentName, componentType, meta, dataInterfaceName, inputInterfaceName), "utf8");
196808
- import_node_fs14.default.writeFileSync(import_node_path15.default.join(componentDir, "ui", `${componentName}.tsx`), renderUI(componentName, meta, inputInterfaceName), "utf8");
197031
+ import_node_fs15.default.mkdirSync(import_node_path16.default.join(componentDir, "ui"), { recursive: true });
197032
+ import_node_fs15.default.mkdirSync(import_node_path16.default.join(componentDir, "types"), { recursive: true });
197033
+ import_node_fs15.default.writeFileSync(import_node_path16.default.join(componentDir, "index.ts"), componentIndexTemplate(componentName), "utf8");
197034
+ import_node_fs15.default.writeFileSync(import_node_path16.default.join(componentDir, "types", "index.ts"), renderTypes(componentName, componentType, meta, dataInterfaceName, inputInterfaceName), "utf8");
197035
+ import_node_fs15.default.writeFileSync(import_node_path16.default.join(componentDir, "ui", `${componentName}.tsx`), renderUI(componentName, meta, inputInterfaceName), "utf8");
196809
197036
  updateRegistryFile2(pieComponentsDir, componentName);
196810
197037
  } catch (error) {
196811
- import_node_fs14.default.rmSync(componentDir, { recursive: true, force: true });
197038
+ import_node_fs15.default.rmSync(componentDir, { recursive: true, force: true });
196812
197039
  throw error;
196813
197040
  }
196814
197041
  console.log(`[pieui] Component ${componentName} ported from backend successfully`);
196815
197042
  console.log(`[pieui] Files created:`);
196816
- console.log(` - ${import_node_path15.default.join(componentDir, "index.ts")}`);
196817
- console.log(` - ${import_node_path15.default.join(componentDir, "types", "index.ts")}`);
196818
- console.log(` - ${import_node_path15.default.join(componentDir, "ui", `${componentName}.tsx`)}`);
197043
+ console.log(` - ${import_node_path16.default.join(componentDir, "index.ts")}`);
197044
+ console.log(` - ${import_node_path16.default.join(componentDir, "types", "index.ts")}`);
197045
+ console.log(` - ${import_node_path16.default.join(componentDir, "ui", `${componentName}.tsx`)}`);
196819
197046
  console.log(`[pieui] Data interface: ${dataInterfaceName}`);
196820
197047
  if (inputInterfaceName) {
196821
197048
  console.log(`[pieui] Input interface: ${inputInterfaceName}`);
@@ -196875,8 +197102,8 @@ var pageAddCommand = (pagePath) => {
196875
197102
  };
196876
197103
 
196877
197104
  // src/code/commands/pageView.ts
196878
- var import_node_fs15 = __toESM(require("node:fs"));
196879
- var import_node_path16 = __toESM(require("node:path"));
197105
+ var import_node_fs16 = __toESM(require("node:fs"));
197106
+ var import_node_path17 = __toESM(require("node:path"));
196880
197107
  var normalizePagePath2 = (pagePath) => {
196881
197108
  const trimmed = pagePath.trim();
196882
197109
  if (!trimmed)
@@ -196885,7 +197112,7 @@ var normalizePagePath2 = (pagePath) => {
196885
197112
  const noRel = slashed.replace(/^\.\/+/, "");
196886
197113
  const noApp = noRel.replace(/^app\//, "");
196887
197114
  const noEdge = noApp.replace(/^\/+|\/+$/g, "");
196888
- const normalized = import_node_path16.default.posix.normalize(noEdge);
197115
+ const normalized = import_node_path17.default.posix.normalize(noEdge);
196889
197116
  if (!normalized || normalized === ".") {
196890
197117
  throw new Error("Path is required for page view command");
196891
197118
  }
@@ -196896,11 +197123,11 @@ var normalizePagePath2 = (pagePath) => {
196896
197123
  };
196897
197124
  var pageViewCommand = (pagePath) => {
196898
197125
  const normalized = normalizePagePath2(pagePath);
196899
- const target = import_node_path16.default.join(process.cwd(), "app", normalized, "page.tsx");
196900
- if (!import_node_fs15.default.existsSync(target)) {
197126
+ const target = import_node_path17.default.join(process.cwd(), "app", normalized, "page.tsx");
197127
+ if (!import_node_fs16.default.existsSync(target)) {
196901
197128
  throw new Error(`Page file not found: ${target}`);
196902
197129
  }
196903
- const source = import_node_fs15.default.readFileSync(target, "utf8");
197130
+ const source = import_node_fs16.default.readFileSync(target, "utf8");
196904
197131
  console.log(`[pieui] Path: ${target}`);
196905
197132
  console.log("");
196906
197133
  process.stdout.write(source);
@@ -196910,26 +197137,26 @@ var pageViewCommand = (pagePath) => {
196910
197137
  };
196911
197138
 
196912
197139
  // src/code/commands/pageAjax.ts
196913
- var import_node_fs16 = __toESM(require("node:fs"));
196914
- var import_node_path17 = __toESM(require("node:path"));
197140
+ var import_node_fs17 = __toESM(require("node:fs"));
197141
+ var import_node_path18 = __toESM(require("node:path"));
196915
197142
  var import_node_child_process4 = require("node:child_process");
196916
197143
  var PIE_CONFIG_PATH2 = ".pie/config.json";
196917
197144
  var readBackendRoot = () => {
196918
- const configPath = import_node_path17.default.join(process.cwd(), PIE_CONFIG_PATH2);
196919
- if (!import_node_fs16.default.existsSync(configPath))
197145
+ const configPath = import_node_path18.default.join(process.cwd(), PIE_CONFIG_PATH2);
197146
+ if (!import_node_fs17.default.existsSync(configPath))
196920
197147
  return;
196921
197148
  try {
196922
- const parsed = JSON.parse(import_node_fs16.default.readFileSync(configPath, "utf8"));
197149
+ const parsed = JSON.parse(import_node_fs17.default.readFileSync(configPath, "utf8"));
196923
197150
  if (typeof parsed !== "object" || parsed === null)
196924
197151
  return;
196925
197152
  const config = parsed;
196926
197153
  if (!config.backendPagesDir)
196927
197154
  return;
196928
- const pages = import_node_path17.default.resolve(config.backendPagesDir);
196929
- if (!import_node_fs16.default.existsSync(pages) || !import_node_fs16.default.statSync(pages).isDirectory()) {
197155
+ const pages = import_node_path18.default.resolve(config.backendPagesDir);
197156
+ if (!import_node_fs17.default.existsSync(pages) || !import_node_fs17.default.statSync(pages).isDirectory()) {
196930
197157
  return;
196931
197158
  }
196932
- return import_node_path17.default.dirname(pages);
197159
+ return import_node_path18.default.dirname(pages);
196933
197160
  } catch {
196934
197161
  return;
196935
197162
  }
@@ -197189,8 +197416,7 @@ var updateNextScriptsToBun = (packageJsonPath) => {
197189
197416
  }
197190
197417
  import_fs10.default.writeFileSync(packageJsonPath, `${JSON.stringify(pkg, null, 2)}
197191
197418
  `, "utf8");
197192
- } catch {
197193
- }
197419
+ } catch {}
197194
197420
  };
197195
197421
  var appendBackendLinkComment = (pagePath) => {
197196
197422
  if (!import_fs10.default.existsSync(pagePath))
@@ -197315,47 +197541,47 @@ var createPieAppCommand = (appName) => {
197315
197541
  // src/code/commands/login.ts
197316
197542
  var import_node_child_process5 = require("node:child_process");
197317
197543
  var import_node_crypto = require("node:crypto");
197318
- var import_node_fs18 = __toESM(require("node:fs"));
197319
- var import_node_path19 = __toESM(require("node:path"));
197544
+ var import_node_fs19 = __toESM(require("node:fs"));
197545
+ var import_node_path20 = __toESM(require("node:path"));
197320
197546
 
197321
197547
  // src/code/services/projectLinks.ts
197322
- var import_node_fs17 = __toESM(require("node:fs"));
197323
- var import_node_path18 = __toESM(require("node:path"));
197548
+ var import_node_fs18 = __toESM(require("node:fs"));
197549
+ var import_node_path19 = __toESM(require("node:path"));
197324
197550
  var readline3 = __toESM(require("node:readline/promises"));
197325
197551
  var PIE_CONFIG_DIR3 = ".pie";
197326
197552
  var PIE_CONFIG_FILE3 = "config.json";
197327
- var configPathFor = (cwd) => import_node_path18.default.join(cwd, PIE_CONFIG_DIR3, PIE_CONFIG_FILE3);
197553
+ var configPathFor = (cwd) => import_node_path19.default.join(cwd, PIE_CONFIG_DIR3, PIE_CONFIG_FILE3);
197328
197554
  var readConfig2 = (cwd) => {
197329
197555
  const p = configPathFor(cwd);
197330
- if (!import_node_fs17.default.existsSync(p))
197556
+ if (!import_node_fs18.default.existsSync(p))
197331
197557
  return {};
197332
197558
  try {
197333
- const parsed = JSON.parse(import_node_fs17.default.readFileSync(p, "utf8"));
197559
+ const parsed = JSON.parse(import_node_fs18.default.readFileSync(p, "utf8"));
197334
197560
  return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : {};
197335
197561
  } catch {
197336
197562
  return {};
197337
197563
  }
197338
197564
  };
197339
197565
  var writeConfig2 = (cwd, config) => {
197340
- const dir = import_node_path18.default.join(cwd, PIE_CONFIG_DIR3);
197341
- import_node_fs17.default.mkdirSync(dir, { recursive: true });
197342
- import_node_fs17.default.writeFileSync(configPathFor(cwd), JSON.stringify(config, null, 2) + `
197566
+ const dir = import_node_path19.default.join(cwd, PIE_CONFIG_DIR3);
197567
+ import_node_fs18.default.mkdirSync(dir, { recursive: true });
197568
+ import_node_fs18.default.writeFileSync(configPathFor(cwd), JSON.stringify(config, null, 2) + `
197343
197569
  `, "utf8");
197344
197570
  };
197345
197571
  var walkUpForPyproject2 = (start) => {
197346
- let dir = import_node_path18.default.resolve(start);
197347
- while (dir !== import_node_path18.default.dirname(dir)) {
197348
- if (import_node_fs17.default.existsSync(import_node_path18.default.join(dir, "pyproject.toml")))
197572
+ let dir = import_node_path19.default.resolve(start);
197573
+ while (dir !== import_node_path19.default.dirname(dir)) {
197574
+ if (import_node_fs18.default.existsSync(import_node_path19.default.join(dir, "pyproject.toml")))
197349
197575
  return dir;
197350
- dir = import_node_path18.default.dirname(dir);
197576
+ dir = import_node_path19.default.dirname(dir);
197351
197577
  }
197352
197578
  return null;
197353
197579
  };
197354
197580
  var ensureBackendDir2 = async (cwd) => {
197355
197581
  const config = readConfig2(cwd);
197356
197582
  if (config.backendProjectDir) {
197357
- const dir = import_node_path18.default.resolve(cwd, config.backendProjectDir);
197358
- if (import_node_fs17.default.existsSync(dir) && import_node_fs17.default.statSync(dir).isDirectory())
197583
+ const dir = import_node_path19.default.resolve(cwd, config.backendProjectDir);
197584
+ if (import_node_fs18.default.existsSync(dir) && import_node_fs18.default.statSync(dir).isDirectory())
197359
197585
  return dir;
197360
197586
  console.error(`[pieui] Configured backendProjectDir not found: ${dir}`);
197361
197587
  }
@@ -197380,9 +197606,9 @@ var ensureBackendDir2 = async (cwd) => {
197380
197606
  const raw = (await rl.question("[pieui] Path to backend (pie) project: ")).trim();
197381
197607
  if (!raw)
197382
197608
  return null;
197383
- const expanded = raw.startsWith("~") ? import_node_path18.default.join(process.env.HOME || "", raw.slice(1).replace(/^[\\/]/, "")) : raw;
197384
- const absolute = import_node_path18.default.resolve(expanded);
197385
- if (!import_node_fs17.default.existsSync(absolute) || !import_node_fs17.default.statSync(absolute).isDirectory()) {
197609
+ const expanded = raw.startsWith("~") ? import_node_path19.default.join(process.env.HOME || "", raw.slice(1).replace(/^[\\/]/, "")) : raw;
197610
+ const absolute = import_node_path19.default.resolve(expanded);
197611
+ if (!import_node_fs18.default.existsSync(absolute) || !import_node_fs18.default.statSync(absolute).isDirectory()) {
197386
197612
  console.error(`[pieui] Not a directory: ${absolute}`);
197387
197613
  return null;
197388
197614
  }
@@ -197416,17 +197642,13 @@ var generateCode = (length = CODE_LENGTH) => {
197416
197642
  var tryOpenBrowser = (url) => {
197417
197643
  try {
197418
197644
  if (process.platform === "win32") {
197419
- import_node_child_process5.execFile("cmd", ["/c", "start", "", url], () => {
197420
- });
197645
+ import_node_child_process5.execFile("cmd", ["/c", "start", "", url], () => {});
197421
197646
  } else if (process.platform === "darwin") {
197422
- import_node_child_process5.execFile("open", [url], () => {
197423
- });
197647
+ import_node_child_process5.execFile("open", [url], () => {});
197424
197648
  } else {
197425
- import_node_child_process5.execFile("xdg-open", [url], () => {
197426
- });
197649
+ import_node_child_process5.execFile("xdg-open", [url], () => {});
197427
197650
  }
197428
- } catch {
197429
- }
197651
+ } catch {}
197430
197652
  };
197431
197653
  var defaultSleep = (ms2) => new Promise((resolve) => setTimeout(resolve, ms2));
197432
197654
  var PIE_ENV_MAP = [
@@ -197455,8 +197677,8 @@ var appendPieCredentialsToEnv = (cwd, config) => {
197455
197677
  if (Object.keys(entries).length === 0) {
197456
197678
  return;
197457
197679
  }
197458
- const envPath = import_node_path19.default.join(cwd, ".env");
197459
- let content = import_node_fs18.default.existsSync(envPath) ? import_node_fs18.default.readFileSync(envPath, "utf8") : "";
197680
+ const envPath = import_node_path20.default.join(cwd, ".env");
197681
+ let content = import_node_fs19.default.existsSync(envPath) ? import_node_fs19.default.readFileSync(envPath, "utf8") : "";
197460
197682
  if (content.length > 0 && !content.endsWith(`
197461
197683
  `)) {
197462
197684
  content += `
@@ -197466,7 +197688,7 @@ var appendPieCredentialsToEnv = (cwd, config) => {
197466
197688
  content += `${additions.join(`
197467
197689
  `)}
197468
197690
  `;
197469
- import_node_fs18.default.writeFileSync(envPath, content, "utf8");
197691
+ import_node_fs19.default.writeFileSync(envPath, content, "utf8");
197470
197692
  console.log(`[pie] Appended credentials to ${envPath}`);
197471
197693
  };
197472
197694
  async function loginCommand(options = {}) {
@@ -197486,10 +197708,9 @@ async function loginCommand(options = {}) {
197486
197708
  console.log(connectUrl);
197487
197709
  try {
197488
197710
  openBrowser(connectUrl);
197489
- } catch {
197490
- }
197491
- const pieDir = import_node_path19.default.join(cwd, ".pie");
197492
- const configPath = import_node_path19.default.join(pieDir, "config.json");
197711
+ } catch {}
197712
+ const pieDir = import_node_path20.default.join(cwd, ".pie");
197713
+ const configPath = import_node_path20.default.join(pieDir, "config.json");
197493
197714
  const url = `${credentialsApi}?${new URLSearchParams({ code }).toString()}`;
197494
197715
  let first = true;
197495
197716
  while (true) {
@@ -197523,7 +197744,7 @@ async function loginCommand(options = {}) {
197523
197744
  throw new Error("Login succeeded but response had no 'config' field");
197524
197745
  }
197525
197746
  const credBlob = typeof record.config === "object" && record.config !== null && !Array.isArray(record.config) ? record.config : {};
197526
- import_node_fs18.default.mkdirSync(pieDir, { recursive: true });
197747
+ import_node_fs19.default.mkdirSync(pieDir, { recursive: true });
197527
197748
  mergeConfig(cwd, credBlob);
197528
197749
  console.log(`[pie] Saved credentials to ${configPath}`);
197529
197750
  appendPieCredentialsToEnv(cwd, record.config);
@@ -197539,8 +197760,8 @@ async function loginCommand(options = {}) {
197539
197760
 
197540
197761
  // src/code/commands/selfUpgrade.ts
197541
197762
  var import_node_child_process6 = require("node:child_process");
197542
- var import_node_fs19 = __toESM(require("node:fs"));
197543
- var import_node_path20 = __toESM(require("node:path"));
197763
+ var import_node_fs20 = __toESM(require("node:fs"));
197764
+ var import_node_path21 = __toESM(require("node:path"));
197544
197765
  var __dirname = "/home/runner/work/pieui/pieui/src/code/commands";
197545
197766
  var PACKAGE_NAME = "@swarm.ing/pieui";
197546
197767
  var INSTALL_ARGS = {
@@ -197564,19 +197785,18 @@ var detectPackageManager = () => {
197564
197785
  };
197565
197786
  var readInstalledVersion = () => {
197566
197787
  const candidates = [
197567
- import_node_path20.default.resolve(__dirname, "..", "package.json"),
197568
- import_node_path20.default.resolve(__dirname, "..", "..", "package.json"),
197569
- import_node_path20.default.resolve(__dirname, "..", "..", "..", "package.json")
197788
+ import_node_path21.default.resolve(__dirname, "..", "package.json"),
197789
+ import_node_path21.default.resolve(__dirname, "..", "..", "package.json"),
197790
+ import_node_path21.default.resolve(__dirname, "..", "..", "..", "package.json")
197570
197791
  ];
197571
197792
  for (const file of candidates) {
197572
197793
  try {
197573
- const raw = import_node_fs19.default.readFileSync(file, "utf8");
197794
+ const raw = import_node_fs20.default.readFileSync(file, "utf8");
197574
197795
  const parsed = JSON.parse(raw);
197575
197796
  if (parsed.name === PACKAGE_NAME && parsed.version) {
197576
197797
  return parsed.version;
197577
197798
  }
197578
- } catch {
197579
- }
197799
+ } catch {}
197580
197800
  }
197581
197801
  return null;
197582
197802
  };
@@ -197640,6 +197860,8 @@ var main = async () => {
197640
197860
  cardAction,
197641
197861
  cardAjax,
197642
197862
  cardIo,
197863
+ cardInput,
197864
+ cardAddStoryForce,
197643
197865
  cardRemoteAction,
197644
197866
  cardPullRef,
197645
197867
  remoteUserId,
@@ -197677,8 +197899,8 @@ var main = async () => {
197677
197899
  await selfUpgradeCommand(args.selfUpgradePm);
197678
197900
  return;
197679
197901
  case "postbuild":
197680
- console.log(`[pieui] Source directory: ${import_node_path21.default.resolve(process.cwd(), srcDir)}`);
197681
- console.log(`[pieui] Output directory: ${import_node_path21.default.resolve(process.cwd(), outDir)}`);
197902
+ console.log(`[pieui] Source directory: ${import_node_path22.default.resolve(process.cwd(), srcDir)}`);
197903
+ console.log(`[pieui] Output directory: ${import_node_path22.default.resolve(process.cwd(), outDir)}`);
197682
197904
  console.log(`[pieui] Append mode: ${append}`);
197683
197905
  await postbuildCommand(srcDir, outDir, append);
197684
197906
  return;
@@ -197701,7 +197923,8 @@ var main = async () => {
197701
197923
  }
197702
197924
  addCommand(name, componentType, {
197703
197925
  ajax: cardAjax,
197704
- io: cardIo
197926
+ io: cardIo,
197927
+ input: cardInput
197705
197928
  });
197706
197929
  return;
197707
197930
  }
@@ -197751,7 +197974,7 @@ var main = async () => {
197751
197974
  }
197752
197975
  if (cardAction === "add-story") {
197753
197976
  const name = requireName(componentName, "Component name");
197754
- cardAddStoryCommand(name);
197977
+ cardAddStoryCommand(name, { force: cardAddStoryForce });
197755
197978
  return;
197756
197979
  }
197757
197980
  if (cardAction === "remote") {