cabloy 5.1.100 → 5.1.102

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.cabloy-version CHANGED
@@ -1 +1 @@
1
- 5.1.100
1
+ 5.1.102
package/.gitignore CHANGED
@@ -37,6 +37,7 @@ vona/.zova-rest
37
37
  **/.temp-dynamic-*
38
38
  **/quasar.config.*.temporary.compiled*
39
39
  zova/.zova
40
+ zova/.zova-rest
40
41
  zova/.quasar
41
42
 
42
43
  **/src-cordova/node_modules
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.1.102
4
+
5
+ ### Features
6
+
7
+ - Keep the upgrade dry-run plan for the current version.
8
+ - Extend Cabloy Basic upgrade overwrite suites.
9
+
10
+ ## 5.1.101
11
+
12
+ ### Features
13
+
14
+ - Add update functionality.
15
+ - Add update enhancements.
16
+
3
17
  ## 5.1.100
4
18
 
5
19
  ### Improvements
@@ -347,15 +347,16 @@ Representative files in the Cabloy Basic frontend:
347
347
  - `getUploadPolicy(...)` stays in the model
348
348
  - the query is created as formal state instead of a one-off click helper
349
349
  - `disableSuspenseOnInit: true` skips the automatic init-time `query.suspense()` kick while preserving the query as formal state
350
- - render derives `acceptAttr`, `multiple`, and `pending`
351
- - interaction reuses that state
350
+ - upload policy still uses normal async freshness semantics here because the model method does not set `staleTime: Infinity`
351
+ - render establishes and derives `acceptAttr`, `multiple`, and `pending` from that query-backed state
352
+ - interaction reuses that same state
352
353
  - interaction may still `await query.suspense()` on the already-created query if an edge timing window requires it
353
354
 
354
355
  Why this is a good fit:
355
356
 
356
357
  - upload policy is a real query-backed state
357
- - it is relatively stable within the current frontend process
358
- - every first consumer does not need to auto-kick one eager init-time refresh semantic
358
+ - it is stable enough that every first consumer does not need to auto-kick one eager init-time refresh semantic
359
+ - it should still keep normal async freshness behavior rather than being frozen through `staleTime: Infinity`
359
360
  - the strict-ready moment is the interaction boundary, not every initial render consumer
360
361
 
361
362
  Taken together, Example A and Example B show the most important design contrast on this page:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cabloy",
3
- "version": "5.1.100",
3
+ "version": "5.1.102",
4
4
  "gitHead": "2c5c19284bab738e492856189acb6fad74b8a7b7",
5
5
  "description": "A Node.js fullstack framework",
6
6
  "keywords": [
@@ -47,6 +47,14 @@ const OVERWRITE_DIRS: string[] = [
47
47
  'zova/scripts',
48
48
  ];
49
49
 
50
+ const OVERWRITE_DIRS_CABLOY_BASIC: string[] = [
51
+ 'vona/src/suite/cabloy-basic',
52
+ 'vona/src/suite/a-training',
53
+ 'zova/src/suite/cabloy-basic',
54
+ 'zova/src/suite/a-training',
55
+ 'zova/src/suite/a-devui',
56
+ ];
57
+
50
58
  const MERGE_DIRS: string[] = [
51
59
  // Claude project assets
52
60
  '.claude/commands',
@@ -242,8 +250,12 @@ async function downloadAndExtract(tarballUrl: string): Promise<void> {
242
250
  // --- Step 3: Selective overwrite ---
243
251
 
244
252
  function selectiveOverwrite(dryRun?: boolean): void {
253
+ const overwriteDirs = existsSync(resolve(ROOT_DIR, '__CABLOY_BASIC__'))
254
+ ? [...OVERWRITE_DIRS, ...OVERWRITE_DIRS_CABLOY_BASIC]
255
+ : OVERWRITE_DIRS;
256
+
245
257
  // Overwrite directories
246
- for (const dir of OVERWRITE_DIRS) {
258
+ for (const dir of overwriteDirs) {
247
259
  const src = resolve(TEMP_DIR, dir);
248
260
  const dest = resolve(ROOT_DIR, dir);
249
261
  if (!existsSync(src)) continue;
@@ -316,13 +328,12 @@ function runInitTestData(dryRun: boolean): void {
316
328
  // --- Step 6: Cleanup ---
317
329
 
318
330
  function cleanup(dryRun?: boolean): void {
319
- if (dryRun) {
320
- log(' [dry-run] Remove temp dir: node_modules/.cabloy-upgrade/');
321
- return;
322
- }
323
331
  if (existsSync(TEMP_DIR)) {
324
332
  rmSync(TEMP_DIR, { recursive: true, force: true });
325
333
  }
334
+ if (dryRun) {
335
+ log(' [dry-run] Removed temp dir: node_modules/.cabloy-upgrade/');
336
+ }
326
337
  }
327
338
 
328
339
  // --- Main ---
@@ -350,15 +361,20 @@ async function main(): Promise<void> {
350
361
  if (currentVersion) {
351
362
  const comparison = compareVersions(currentVersion, latestPackageInfo.version);
352
363
  if (comparison === 0) {
353
- log(`Cabloy is already up to date (current: ${currentVersion}). Skipping upgrade.`);
354
- return;
355
- }
356
- if (comparison > 0) {
364
+ if (!dryRun) {
365
+ log(`Cabloy is already up to date (current: ${currentVersion}). Skipping upgrade.`);
366
+ return;
367
+ }
368
+ log(
369
+ `Cabloy is already up to date (current: ${currentVersion}). Continuing dry-run to show overwrite plan.\n`,
370
+ );
371
+ } else if (comparison > 0) {
357
372
  throw new Error(
358
373
  `Project Cabloy version ${currentVersion} is newer than npm latest ${latestPackageInfo.version}. Aborting upgrade.`,
359
374
  );
375
+ } else {
376
+ log(`Upgrading Cabloy from ${currentVersion} to ${latestPackageInfo.version}...\n`);
360
377
  }
361
- log(`Upgrading Cabloy from ${currentVersion} to ${latestPackageInfo.version}...\n`);
362
378
  } else {
363
379
  log(`Upgrading Cabloy to ${latestPackageInfo.version}...\n`);
364
380
  }
@@ -101,11 +101,27 @@ export class TableCellFile extends BeanBase implements ITableCellRender {
101
101
  ) {
102
102
  const fieldTitle = renderContext.$celScope.property?.title ?? renderContext.$celScope.name;
103
103
  const placeholder = this.scope.locale.DownloadFile();
104
+ const selectBackgroundColor = 'var(--color-base-100)';
105
+ const selectColor = 'var(--color-base-content)';
106
+ const optionStyle = {
107
+ backgroundColor: selectBackgroundColor,
108
+ color: selectColor,
109
+ };
110
+ const placeholderOptionStyle = {
111
+ backgroundColor: selectBackgroundColor,
112
+ color: `color-mix(in oklch, ${selectColor} 60%, transparent)`,
113
+ };
114
+ const selectStyle = {
115
+ colorScheme: this.$theme.dark ? 'dark' : 'light',
116
+ backgroundColor: selectBackgroundColor,
117
+ color: selectColor,
118
+ };
104
119
  return (
105
120
  <span class="relative inline-flex min-w-0 max-w-full items-center">
106
121
  <span class="inline-flex min-w-0 max-w-full items-center">{contentNode}</span>
107
122
  <select
108
123
  class="absolute inset-0 h-full w-full cursor-pointer opacity-0"
124
+ style={selectStyle}
109
125
  aria-label={fieldTitle}
110
126
  title={placeholder}
111
127
  onClick={event => {
@@ -125,9 +141,16 @@ export class TableCellFile extends BeanBase implements ITableCellRender {
125
141
  this._openDownloadUrl(selectedItem.downloadUrl);
126
142
  }}
127
143
  >
128
- <option value="">{placeholder}</option>
144
+ <option value="" style={placeholderOptionStyle}>
145
+ {placeholder}
146
+ </option>
129
147
  {items.map(item => (
130
- <option key={item.key} value={item.key} disabled={!item.downloadUrl}>
148
+ <option
149
+ key={item.key}
150
+ value={item.key}
151
+ disabled={!item.downloadUrl}
152
+ style={optionStyle}
153
+ >
131
154
  {item.label}
132
155
  </option>
133
156
  ))}